llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-clang-codegen Author: mkovacevic99 <details> <summary>Changes</summary> Fixes this github issue: https://github.com/llvm/llvm-project/issues/188058 Fix incorrect cleanup block handling in _EmitGuardedInit_ by tracking the EH stack depth at the start of initialization and popping all cleanups introduced during the guarded init sequence. This ensures that only cleanups associated with the variable initialization are removed, rather than assuming a single cleanup block is sufficient. NFC in behavior for most cases, but fixes incorrect cleanup scoping when multiple EH cleanups are pushed during static/thread-local initialization. --- Full diff: https://github.com/llvm/llvm-project/pull/199508.diff 4 Files Affected: - (modified) clang/docs/ReleaseNotes.rst (+3) - (modified) clang/lib/CodeGen/ItaniumCXXABI.cpp (+5-2) - (modified) clang/lib/CodeGen/MicrosoftCXXABI.cpp (+3-1) - (added) clang/test/CodeGen/block-static-cleanup.cpp (+15) ``````````diff diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 3c1eacfc05dc8..9eae0c605743e 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -861,6 +861,9 @@ Crash and bug fixes - Fixed ``security.VAList`` checker producing false positives when analyzing C23 code where ``va_start`` expands to ``__builtin_c23_va_start``. + +- Fixed cleanup scoping for block-scope static and thread-local variable + initialization with multiple EH cleanups, ensuring correct destructor order. Fixes #188058 .. comment: This is for the Static Analyzer. diff --git a/clang/lib/CodeGen/ItaniumCXXABI.cpp b/clang/lib/CodeGen/ItaniumCXXABI.cpp index 6069d39f520ef..ce1575286a804 100644 --- a/clang/lib/CodeGen/ItaniumCXXABI.cpp +++ b/clang/lib/CodeGen/ItaniumCXXABI.cpp @@ -2878,6 +2878,7 @@ void ItaniumCXXABI::EmitGuardedInit(CodeGenFunction &CGF, CGF.EmitBlock(InitCheckBlock); } + EHScopeStack::stable_iterator InitCleanupDepth; // The semantics of dynamic initialization of variables with static or thread // storage duration depends on whether they are declared at block-scope. The // initialization of such variables at block-scope can be aborted with an @@ -2904,6 +2905,8 @@ void ItaniumCXXABI::EmitGuardedInit(CodeGenFunction &CGF, Builder.CreateCondBr(Builder.CreateIsNotNull(V, "tobool"), InitBlock, EndBlock); + InitCleanupDepth = CGF.EHStack.stable_begin(); + // Call __cxa_guard_abort along the exceptional edge. CGF.EHStack.pushCleanup<CallGuardAbort>(EHCleanup, guard); @@ -2920,8 +2923,8 @@ void ItaniumCXXABI::EmitGuardedInit(CodeGenFunction &CGF, CGF.EmitCXXGlobalVarDeclInit(D, var, shouldPerformInit); if (threadsafe) { - // Pop the guard-abort cleanup if we pushed one. - CGF.PopCleanupBlock(); + // Pop the cleanups that we pushed for this initialization. + CGF.PopCleanupBlocks(InitCleanupDepth); // Call __cxa_guard_release. This cannot throw. CGF.EmitNounwindRuntimeCall(getGuardReleaseFn(CGM, guardPtrTy), diff --git a/clang/lib/CodeGen/MicrosoftCXXABI.cpp b/clang/lib/CodeGen/MicrosoftCXXABI.cpp index 6d8c710c9fe4b..ec34f5ce6363b 100644 --- a/clang/lib/CodeGen/MicrosoftCXXABI.cpp +++ b/clang/lib/CodeGen/MicrosoftCXXABI.cpp @@ -2815,9 +2815,11 @@ void MicrosoftCXXABI::EmitGuardedInit(CodeGenFunction &CGF, const VarDecl &D, // Ok, we ended up getting selected as the initializing thread. CGF.EmitBlock(InitBlock); + EHScopeStack::stable_iterator InitCleanupDepth = CGF.EHStack.stable_begin(); CGF.EHStack.pushCleanup<CallInitThreadAbort>(EHCleanup, GuardAddr); CGF.EmitCXXGlobalVarDeclInit(D, GV, PerformInit); - CGF.PopCleanupBlock(); + // Pop the cleanups that we pushed for this initialization. + CGF.PopCleanupBlocks(InitCleanupDepth); CGF.EmitNounwindRuntimeCall(getInitThreadFooterFn(CGM), GuardAddr.getPointer()); Builder.CreateBr(EndBlock); diff --git a/clang/test/CodeGen/block-static-cleanup.cpp b/clang/test/CodeGen/block-static-cleanup.cpp new file mode 100644 index 0000000000000..864bad0f848db --- /dev/null +++ b/clang/test/CodeGen/block-static-cleanup.cpp @@ -0,0 +1,15 @@ +// RUN: %clang_cc1 -std=c++20 -fblocks -emit-llvm -o - %s + +struct S { + ~S(); +}; + +void test() { + S s1, s2; + + static const int i = ^(void) { + (void)s1; + (void)s2; + return 0; + }(); +} `````````` </details> https://github.com/llvm/llvm-project/pull/199508 _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
