[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