[clang] [clang] Fix isConstantInitializer handling of transparent init lists. (PR #148030)
Eli Friedman via cfe-commits
cfe-commits at lists.llvm.org
Thu Jul 10 11:47:52 PDT 2025
https://github.com/efriedma-quic created https://github.com/llvm/llvm-project/pull/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
>From 5c279209bff277e008866e5d5e5192cf99cdcf8d Mon Sep 17 00:00:00 2001
From: Eli Friedman <efriedma at quicinc.com>
Date: Thu, 10 Jul 2025 11:37:50 -0700
Subject: [PATCH] [clang] Fix isConstantInitializer handling of transparent
init lists.
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
---
clang/lib/AST/Expr.cpp | 4 ++++
clang/test/CodeGenCXX/const-init-cxx11.cpp | 9 +++++++++
clang/test/SemaCXX/compound-literal.cpp | 8 ++++++++
3 files changed, 21 insertions(+)
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
More information about the cfe-commits
mailing list