[clang] e7b0b35 - [clang][bytecode] Create global variables for temporaries... (#195037)
via cfe-commits
cfe-commits at lists.llvm.org
Sun May 3 21:59:05 PDT 2026
Author: Timm Baeder
Date: 2026-05-04T06:58:59+02:00
New Revision: e7b0b3568db78496be2aadb8c731d83cab6d40cf
URL: https://github.com/llvm/llvm-project/commit/e7b0b3568db78496be2aadb8c731d83cab6d40cf
DIFF: https://github.com/llvm/llvm-project/commit/e7b0b3568db78496be2aadb8c731d83cab6d40cf.diff
LOG: [clang][bytecode] Create global variables for temporaries... (#195037)
... that are extended by other global variables.
If the temporary we create is extended by a variable that we index as a
global, create a global for the temporary, even if it's not an
`SD_Static` temporary.
Added:
Modified:
clang/lib/AST/ByteCode/Compiler.cpp
clang/test/AST/ByteCode/builtin-functions.cpp
clang/test/AST/ByteCode/references.cpp
Removed:
################################################################################
diff --git a/clang/lib/AST/ByteCode/Compiler.cpp b/clang/lib/AST/ByteCode/Compiler.cpp
index 626068ce9eee5..9b18155d47ea3 100644
--- a/clang/lib/AST/ByteCode/Compiler.cpp
+++ b/clang/lib/AST/ByteCode/Compiler.cpp
@@ -3231,23 +3231,32 @@ bool Compiler<Emitter>::VisitMaterializeTemporaryExpr(
// FIXME: Find a test case where Adjustments matters.
- // When we're initializing a global variable *or* the storage duration of
+ // When we're extending a global variable *or* the storage duration of
// the temporary is explicitly static, create a global variable.
OptPrimType InnerT = classify(Inner);
- if (E->getStorageDuration() == SD_Static) {
+ const ValueDecl *ExtendingDecl = E->getExtendingDecl();
+ bool IsStatic = E->getStorageDuration() == SD_Static;
+ if (IsStatic ||
+ (ExtendingDecl && Context::shouldBeGloballyIndexed(ExtendingDecl))) {
UnsignedOrNone GlobalIndex = P.createGlobal(E, Inner->getType());
if (!GlobalIndex)
return false;
const LifetimeExtendedTemporaryDecl *TempDecl =
E->getLifetimeExtendedTemporaryDecl();
- assert(TempDecl);
if (InnerT) {
if (!this->visit(Inner))
return false;
- if (!this->emitInitGlobalTemp(*InnerT, *GlobalIndex, TempDecl, E))
- return false;
+
+ if (IsStatic) {
+ assert(TempDecl);
+ if (!this->emitInitGlobalTemp(*InnerT, *GlobalIndex, TempDecl, E))
+ return false;
+ } else {
+ if (!this->emitInitGlobal(*InnerT, *GlobalIndex, E))
+ return false;
+ }
return this->emitGetPtrGlobal(*GlobalIndex, E);
}
@@ -3258,7 +3267,11 @@ bool Compiler<Emitter>::VisitMaterializeTemporaryExpr(
return false;
if (!this->visitInitializer(Inner))
return false;
- return this->emitInitGlobalTempComp(TempDecl, E);
+ if (IsStatic) {
+ assert(TempDecl);
+ return this->emitInitGlobalTempComp(TempDecl, E);
+ }
+ return true;
}
ScopeKind VarScope = E->getStorageDuration() == SD_FullExpression
diff --git a/clang/test/AST/ByteCode/builtin-functions.cpp b/clang/test/AST/ByteCode/builtin-functions.cpp
index f0a41c194189e..97fa1760ee167 100644
--- a/clang/test/AST/ByteCode/builtin-functions.cpp
+++ b/clang/test/AST/ByteCode/builtin-functions.cpp
@@ -1949,6 +1949,16 @@ namespace WithinLifetime {
static_assert(test_dynamic(false));
static_assert(test_dynamic(true)); // both-error {{not an integral constant expression}} \
// both-note {{in call to}}
+
+
+ void LocalGlobal() {
+ constexpr const int &temp = 0; // both-error {{must be initialized by a constant expression}} \
+ // both-note {{reference to temporary is not a constant expression}} \
+ // both-note {{temporary created here}} \
+ // ref-note {{declared here}}
+ static_assert(__builtin_is_within_lifetime(&temp)); // ref-error {{not an integral constant expression}} \
+ // ref-note {{initializer of 'temp' is not a constant expression}}
+ }
}
#ifdef __SIZEOF_INT128__
diff --git a/clang/test/AST/ByteCode/references.cpp b/clang/test/AST/ByteCode/references.cpp
index 3da3996aaca75..a4a8100f5b31e 100644
--- a/clang/test/AST/ByteCode/references.cpp
+++ b/clang/test/AST/ByteCode/references.cpp
@@ -188,9 +188,10 @@ namespace ReadFromNullBlockPtr {
constexpr S s = {&x}; // both-error {{must be initialized by a constant expression}} \
// both-note {{reference to temporary}} \
// both-note {{created here}} \
- // ref-note {{declared here}}
+ // ref-note {{declared here}} \
+ // expected-note {{created here}}
static_assert(s.t == &x, ""); // both-error {{not an integral constant expression}} \
- // expected-note {{read of dereferenced null pointer}} \
+ // expected-note {{read of temporary is not allowed in a constant expression outside the expression that created the temporary}} \
// ref-note {{initializer of 's' is not a constant expression}}
}
}
More information about the cfe-commits
mailing list