[clang] 07bd305 - [clang][bytecode] Fix conditional operator scoping (#201777)
via cfe-commits
cfe-commits at lists.llvm.org
Fri Jun 5 06:06:07 PDT 2026
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 {
More information about the cfe-commits
mailing list