[clang] [clang][CodeGen] Emit file-scope compound literals in a constant context (PR #221390)

Eli Friedman via cfe-commits cfe-commits at lists.llvm.org
Thu Sep 10 16:50:12 PDT 2026


================
@@ -7541,18 +7566,54 @@ Sema::BuildCompoundLiteralExpr(SourceLocation LParenLoc, TypeSourceInfo *TInfo,
   //  "If the compound literal occurs outside the body of a function, the
   //  initializer list shall consist of constant expressions."
   if (IsFileScope)
-    if (auto ILE = dyn_cast<InitListExpr>(LiteralExpr))
+    if (auto ILE = dyn_cast<InitListExpr>(LiteralExpr)) {
+      // A default argument or default member initializer containing an
+      // immediate call or source_location is rebuilt at each use site, where
+      // its elements are evaluated (see BuildCXXDefaultArgExpr).
+      bool InDefaultArgOrInit =
+          isCheckingDefaultArgumentOrInitializer() ||
+          InnermostDeclarationWithDelayedImmediateInvocations().has_value();
       for (unsigned i = 0, j = ILE->getNumInits(); i != j; i++) {
         Expr *Init = ILE->getInit(i);
-        if (!Init->isTypeDependent() && !Init->isValueDependent() &&
-            !Init->isConstantInitializer(Context)) {
+        // An immediate invocation is already a ConstantExpr and receives its
+        // value at the end of the full-expression.
+        if (isa<ConstantExpr>(Init))
+          continue;
+        if (Init->isTypeDependent() || Init->isValueDependent()) {
+          ILE->setInit(i, ConstantExpr::Create(Context, Init));
+          continue;
+        }
+        bool IsRef = initializesReferenceMember(ILE, i);
+        if (!Init->isConstantInitializer(Context, IsRef)) {
           Diag(Init->getExprLoc(), diag::err_init_element_not_constant)
               << Init->getSourceBitField();
           return ExprError();
         }
 
-        ILE->setInit(i, ConstantExpr::Create(Context, Init));
+        // Store the value so CodeGen does not re-evaluate the element outside
+        // a constant context.
+        bool DeferToUseSite = false;
----------------
efriedma-quic wrote:

The logic for computing DeferToUseSite is significantly more complicated that I'd hoped for, but I don't have any suggestions for simplifying it off the top of my head.

https://github.com/llvm/llvm-project/pull/221390


More information about the cfe-commits mailing list