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

Timm Baeder via cfe-commits cfe-commits at lists.llvm.org
Mon May 4 08:22:41 PDT 2026


https://github.com/tbaederr created https://github.com/llvm/llvm-project/pull/195675

Like the current interpreter does.

>From 95647e8faec7531928399cfe84387e63b8480a4a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timm=20B=C3=A4der?= <tbaeder at redhat.com>
Date: Mon, 4 May 2026 17:14:23 +0200
Subject: [PATCH] cle

---
 clang/lib/AST/ByteCode/Interp.cpp             | 28 +++++++++++++++++++
 .../SemaTemplate/constexpr-instantiate.cpp    |  1 +
 2 files changed, 29 insertions(+)

diff --git a/clang/lib/AST/ByteCode/Interp.cpp b/clang/lib/AST/ByteCode/Interp.cpp
index 0fa4021cae1f6..70ae794c757cc 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 {



More information about the cfe-commits mailing list