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

Eli Friedman via cfe-commits cfe-commits at lists.llvm.org
Fri Apr 25 12:06:42 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:

I'm more concerned about the fact that you're using EvaluateInPlace, as opposed to using EvaluateAsInitializer.  Which... I'm not sure it's actually possible to observe a difference at the moment due to the rule that static compound literals are required to have a constant initializer, but it's fragile.

----

On a sort of related note, I was experimenting with some testcases, and the following crashed:

```
struct A {int x[1]; };
A f();
typedef int *t[];
consteval int* f(int* x) { return x; }
int ** x = (t){f(f().x)};
```

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


More information about the cfe-commits mailing list