Skip to content

Conversation

@efriedma-quic
Copy link
Collaborator

Transparent InitListExprs have different semantics, so special-case them in Expr::isConstantInitializer.

We probably should move away from isConstantInitializer, in favor of relying more directly on constant evaluation, but this is an easy fix.

Fixes #147949

Transparent InitListExprs have different semantics, so special-case
them in Expr::isConstantInitializer.

We probably should move away from isConstantInitializer, in favor of
relying more directly on constant evaluation, but this is an easy fix.

Fixes llvm#147949
@llvmbot llvmbot added clang Clang issues not falling into any other category clang:frontend Language frontend issues, e.g. anything involving "Sema" labels Jul 10, 2025
@llvmbot
Copy link
Member

llvmbot commented Jul 10, 2025

@llvm/pr-subscribers-clang

Author: Eli Friedman (efriedma-quic)

Changes

Transparent InitListExprs have different semantics, so special-case them in Expr::isConstantInitializer.

We probably should move away from isConstantInitializer, in favor of relying more directly on constant evaluation, but this is an easy fix.

Fixes #147949


Full diff: https://github.com/llvm/llvm-project/pull/148030.diff

3 Files Affected:

  • (modified) clang/lib/AST/Expr.cpp (+4)
  • (modified) clang/test/CodeGenCXX/const-init-cxx11.cpp (+9)
  • (modified) clang/test/SemaCXX/compound-literal.cpp (+8)
diff --git a/clang/lib/AST/Expr.cpp b/clang/lib/AST/Expr.cpp
index 36fd5ee271e03..2e1a9a3d9ad63 100644
--- a/clang/lib/AST/Expr.cpp
+++ b/clang/lib/AST/Expr.cpp
@@ -3393,6 +3393,10 @@ bool Expr::isConstantInitializer(ASTContext &Ctx, bool IsForRef,
     //     an anonymous union, in declaration order.
     const InitListExpr *ILE = cast<InitListExpr>(this);
     assert(ILE->isSemanticForm() && "InitListExpr must be in semantic form");
+
+    if (ILE->isTransparent())
+      return ILE->getInit(0)->isConstantInitializer(Ctx, false, Culprit);
+
     if (ILE->getType()->isArrayType()) {
       unsigned numInits = ILE->getNumInits();
       for (unsigned i = 0; i < numInits; i++) {
diff --git a/clang/test/CodeGenCXX/const-init-cxx11.cpp b/clang/test/CodeGenCXX/const-init-cxx11.cpp
index 7c92af0def527..0795fb534af4b 100644
--- a/clang/test/CodeGenCXX/const-init-cxx11.cpp
+++ b/clang/test/CodeGenCXX/const-init-cxx11.cpp
@@ -638,6 +638,15 @@ struct PR69979 {
   const char (&d)[9];
 } e {"12345678"};
 
+namespace GH147949 {
+  struct Coordinate {};
+  Coordinate Make();
+  void TestBody() {
+    // CHECK: call {{.*}} @_ZN8GH1479494MakeEv
+    const Coordinate x{Make()};
+  }
+}
+
 // VirtualMembers::TemplateClass::templateMethod() must be defined in this TU,
 // not just declared.
 // CHECK: define linkonce_odr void @_ZN14VirtualMembers13TemplateClassIiE14templateMethodEv(ptr {{[^,]*}} %this)
diff --git a/clang/test/SemaCXX/compound-literal.cpp b/clang/test/SemaCXX/compound-literal.cpp
index a62e4f79b5a07..9c7c606838de9 100644
--- a/clang/test/SemaCXX/compound-literal.cpp
+++ b/clang/test/SemaCXX/compound-literal.cpp
@@ -129,3 +129,11 @@ int f();
 #endif
 Foo o = (Foo){ {}, 1, f() };
 }
+
+#if __cplusplus >= 201103L
+namespace GH147949 {
+  // Make sure we handle transparent InitListExprs correctly.
+  struct S { int x : 3; };
+  const S* x = (const S[]){S{S{3}}};
+}
+#endif

Copy link
Contributor

@cor3ntin cor3ntin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you add a release note?
LGTM otherwise

@efriedma-quic efriedma-quic merged commit cffe7cb into llvm:main Jul 13, 2025
8 of 10 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

clang:frontend Language frontend issues, e.g. anything involving "Sema" clang Clang issues not falling into any other category

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Assertion failure in CGDeclCXX.cpp / EmitDeclInit "VarDecl must have global or local (in the case of OpenCL) storage!"

3 participants