================
@@ -7541,18 +7541,53 @@ 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.
+      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;
+        }
+        // A glvalue element binds a reference member; store its address.
+        bool IsRef = Init->isGLValue();
+        Expr::EvalResult Eval;
+        bool Evaluated =
+            IsRef ? Init->EvaluateAsLValue(Eval, Context,
+                                           /*InConstantContext=*/true)
+                  : Init->EvaluateAsRValue(Eval, Context,
+                                           /*InConstantContext=*/true);
+        Evaluated = Evaluated && !Eval.HasSideEffects && Eval.Val.hasValue();
+        // Not every constant initializer evaluates to a value, e.g. a union
+        // that is non-trivial to destroy; fall back to the structural rules.
+        if (!Evaluated && !Init->isConstantInitializer(Context, IsRef)) {
----------------
akash-manna-sky wrote:

Yeah! May be I didn't think that deeply. Can you please look into it? I think 
the problem was how the element was evaluated: `EvaluateAsRValue` materializes 
a record `prvalue` as a temporary and then counts its un-run non-trivial 
destruction as a side effect. Added `Expr::EvaluateAsConstantInitializer`, 
which evaluates in place like `EvaluateAsConstantExpr` (no temporary; a glvalue 
gives the bound address), and dropped the `isConstantInitializer` fallback. The 
ARC union now evaluates, as does an element of a class with a non-trivial 
destructor; `(RR[1]){1}` with an `int&&` member is now diagnosed instead of 
crashing `CodeGen` (GCC rejects it too). Hope this is fine for you! 
@efriedma-quic 


https://github.com/llvm/llvm-project/pull/221390
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to