[clang] [clang][CompundLiteralExpr] Don't defer evaluation for CLEs (PR #137163)

Eli Friedman via cfe-commits cfe-commits at lists.llvm.org
Thu May 8 15:07:56 PDT 2025


================
@@ -9125,9 +9126,25 @@ bool
 LValueExprEvaluator::VisitCompoundLiteralExpr(const CompoundLiteralExpr *E) {
   assert((!Info.getLangOpts().CPlusPlus || E->isFileScope()) &&
          "lvalue compound literal in c++?");
-  // Defer visiting the literal until the lvalue-to-rvalue conversion. We can
-  // only see this when folding in C, so there's no standard to follow here.
-  return Success(E);
+  APValue *Lit;
+  // If CompountLiteral has static storage, its value can be used outside
+  // this expression. So evaluate it once and store it in ASTContext.
+  if (E->hasStaticStorage()) {
+    Lit = E->getOrCreateStaticValue(Info.Ctx);
+    Result.set(E);
+    // Reset any previously evaluated state, otherwise evaluation below might
+    // fail.
+    // FIXME: Should we just re-use the previously evaluated value instead?
+    *Lit = APValue();
----------------
efriedma-quic wrote:

Dug into the EvalMode thing... I remember why we added it now.  See https://reviews.llvm.org/D151587 for context.  Roughly, the issue is that, if you constant-evaluate the expression in isolation, you get a different result from what you'd get evaluating the whole expression.  So we can't redo the evaluation in ConstantFold mode: if you do, you'll corrupt the precomputed value, for cases like clang/test/CodeGenCXX/const-init-cxx1y.cpp.

I think compound literals run into similar issues if you allow ConstantFold mode to overwrite the evaluated value.

Maybe we can add some workaround specifically for cases where we immediately do an lvalue-to-rvalue conversion.

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


More information about the cfe-commits mailing list