Author: Timm Baeder
Date: 2026-05-07T16:50:50+02:00
New Revision: b056c86a4c5b9d20eafdb21131ff2e574bf05f07

URL: 
https://github.com/llvm/llvm-project/commit/b056c86a4c5b9d20eafdb21131ff2e574bf05f07
DIFF: 
https://github.com/llvm/llvm-project/commit/b056c86a4c5b9d20eafdb21131ff2e574bf05f07.diff

LOG: [clang][bytecode] Disallow reading from non-constant, array-typed 
`CompoundLiteralExpr`s (#195675)

Like the current interpreter does.

Added: 
    

Modified: 
    clang/lib/AST/ByteCode/Interp.cpp
    clang/test/SemaTemplate/constexpr-instantiate.cpp

Removed: 
    


################################################################################
diff  --git a/clang/lib/AST/ByteCode/Interp.cpp 
b/clang/lib/AST/ByteCode/Interp.cpp
index 30b54f5dab236..0ac6d2f7737fc 100644
--- a/clang/lib/AST/ByteCode/Interp.cpp
+++ b/clang/lib/AST/ByteCode/Interp.cpp
@@ -832,6 +832,34 @@ bool CheckLoad(InterpState &S, CodePtr OpPC, const Pointer 
&Ptr,
     return false;
   if (isConstexprUnknown(Ptr))
     return false;
+
+  if (!Ptr.isArrayRoot()) {
+    // According to GCC info page:
+    //
+    // 6.28 Compound Literals
+    //
+    // As an optimization, G++ sometimes gives array compound literals
+    // longer lifetimes: when the array either appears outside a function or
+    // has a const-qualified type. If foo and its initializer had elements
+    // of type char *const rather than char *, or if foo were a global
+    // variable, the array would have static storage duration. But it is
+    // probably safest just to avoid the use of array compound literals in
+    // C++ code.
+    //
+    // Obey that rule by checking constness for converted array types.
+    const Descriptor *Desc = Ptr.getFieldDesc();
+    if (const auto *CLE =
+            dyn_cast_if_present<CompoundLiteralExpr>(Desc->asExpr())) {
+      if (QualType CLETy = CLE->getType();
+          CLETy->isArrayType() && !CLETy.isConstant(S.getASTContext())) {
+        S.FFDiag(S.Current->getLocation(OpPC),
+                 diag::note_invalid_subexpr_in_const_expr)
+            << S.Current->getRange(OpPC);
+        S.Note(CLE->getExprLoc(), diag::note_declared_at);
+        return false;
+      }
+    }
+  }
   return true;
 }
 

diff  --git a/clang/test/SemaTemplate/constexpr-instantiate.cpp 
b/clang/test/SemaTemplate/constexpr-instantiate.cpp
index 0a34f63553aae..31723344c4840 100644
--- a/clang/test/SemaTemplate/constexpr-instantiate.cpp
+++ b/clang/test/SemaTemplate/constexpr-instantiate.cpp
@@ -1,4 +1,5 @@
 // RUN: %clang_cc1 -std=c++11 -verify %s
+// RUN: %clang_cc1 -std=c++11 -verify %s 
-fexperimental-new-constant-interpreter
 
 namespace UseBeforeDefinition {
   struct A {


        
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to