Author: Timm Baeder Date: 2026-06-05T15:06:01+02:00 New Revision: 07bd30557f2b00225d4eb7c125e74188b54f1faa
URL: https://github.com/llvm/llvm-project/commit/07bd30557f2b00225d4eb7c125e74188b54f1faa DIFF: https://github.com/llvm/llvm-project/commit/07bd30557f2b00225d4eb7c125e74188b54f1faa.diff LOG: [clang][bytecode] Fix conditional operator scoping (#201777) The code and the comment are correct, but they also applied to the conditional operator condition, which they shouldn't. Added: Modified: clang/lib/AST/ByteCode/Compiler.cpp clang/test/AST/ByteCode/cxx20.cpp Removed: ################################################################################ diff --git a/clang/lib/AST/ByteCode/Compiler.cpp b/clang/lib/AST/ByteCode/Compiler.cpp index 6279b2fb5a38e..76688e30a0acd 100644 --- a/clang/lib/AST/ByteCode/Compiler.cpp +++ b/clang/lib/AST/ByteCode/Compiler.cpp @@ -2836,16 +2836,6 @@ bool Compiler<Emitter>::VisitAbstractConditionalOperator( return this->delegate(FalseExpr); } - // Force-init the scope, which creates a InitScope op. This is necessary so - // the scope is not only initialized in one arm of the conditional operator. - this->VarScope->forceInit(); - // The TrueExpr and FalseExpr of a conditional operator do _not_ create a - // scope, which means the local variables created within them unconditionally - // always exist. However, we need to later diff erentiate which branch was - // taken and only destroy the varibles of the active branch. This is what the - // "enabled" flags on local variables are used for. - llvm::SaveAndRestore LAAA(this->VarScope->LocalsAlwaysEnabled, - /*NewValue=*/false); bool IsBcpCall = false; if (const auto *CE = dyn_cast<CallExpr>(Condition->IgnoreParenCasts()); CE && CE->getBuiltinCallee() == Builtin::BI__builtin_constant_p) { @@ -2873,6 +2863,17 @@ bool Compiler<Emitter>::VisitAbstractConditionalOperator( return false; } + // Force-init the scope, which creates a InitScope op. This is necessary so + // the scope is not only initialized in one arm of the conditional operator. + this->VarScope->forceInit(); + // The TrueExpr and FalseExpr of a conditional operator do _not_ create a + // scope, which means the local variables created within them unconditionally + // always exist. However, we need to later diff erentiate which branch was + // taken and only destroy the varibles of the active branch. This is what the + // "enabled" flags on local variables are used for. + llvm::SaveAndRestore LAAA(this->VarScope->LocalsAlwaysEnabled, + /*NewValue=*/false); + if (!this->jumpFalse(LabelFalse, E)) return false; if (!this->delegate(TrueExpr)) diff --git a/clang/test/AST/ByteCode/cxx20.cpp b/clang/test/AST/ByteCode/cxx20.cpp index ab49b597344c3..b55d274f2408c 100644 --- a/clang/test/AST/ByteCode/cxx20.cpp +++ b/clang/test/AST/ByteCode/cxx20.cpp @@ -1262,6 +1262,23 @@ namespace ConditionalTemporaries { } static_assert(foo(false)== 13); static_assert(foo(true)== 12); + + struct S { + int *p; + constexpr S() { p = new int(); } + constexpr ~S() { delete p; } + }; + + constexpr bool func(S &s1, S s2) { + return true; + } + + constexpr bool test() { + S s1; + func(s1, {}) ? void() : void(); + return true; + } + static_assert(test()); } namespace PointerCmp { _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
