Author: Eli Friedman
Date: 2025-07-13T16:02:52-07:00
New Revision: cffe7cb745a1d18508b620c5e6d339fe51b8f9bf

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

LOG: [clang] Fix isConstantInitializer handling of transparent init lists. 
(#148030)

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

Added: 
    

Modified: 
    clang/docs/ReleaseNotes.rst
    clang/lib/AST/Expr.cpp
    clang/test/CodeGenCXX/const-init-cxx11.cpp
    clang/test/SemaCXX/compound-literal.cpp

Removed: 
    


################################################################################
diff  --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index e3fd730002b55..7b6069624c26c 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -956,6 +956,8 @@ Bug Fixes to C++ Support
   (#GH135281)
 - Fix a crash in the presence of invalid base classes. (#GH147186)
 - Fix a crash with NTTP when instantiating local class.
+- Fixed a crash involving list-initialization of an empty class with a
+  non-empty initializer list. (#GH147949)
 
 Bug Fixes to AST Handling
 ^^^^^^^^^^^^^^^^^^^^^^^^^

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


        
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to