AaronBallman wrote:

> @kadircet let's team up tomorrow and poke at what's happening with the 
> smaller reproducer to figure out if this is the right fix?
> 
> @AaronBallman I was initially concerned that it would be incorrect to 
> consider the compound literal expression a full expression even if it fixes 
> the crash. After re-reading the code now, I'm not sure how to properly test 
> that as C++ does not have those (right?) and so I'd probably spend some time 
> poking at GCC and Clang's codegen to see if they exhibit the signs of full 
> expressions.
> 
> If you feel this fix is correct (or at least won't hurt too much), we can 
> definitely land this ASAP. Help with reviewing this or steering it in the 
> right direction is greatly appreciated.

In C:

> A full expression is an expression that is not part of another expression, 
> nor part of a declarator
or abstract declarator. There is also an implicit full expression in which the 
non-constant size
expressions for a variably modified type are evaluated; within that full 
expression, the evaluation of
different size expressions are unsequenced with respect to one another. There 
is a sequence point
between the evaluation of a full expression and the evaluation of the next full 
expression to be
evaluated.

So a compound literal is definitely not a full expression in C. C++'s rules are 
similar: https://eel.is/c++draft/intro.execution#5

What's more, in C, it produces an lvalue whose lifetime is that of the block 
which contains it whereas in C++ it creates a prvalue... most of the time. 
There are a pile of FIXMEs around here:
```
  // In C, compound literals are l-values for some reason.
  // For GCC compatibility, in C++, file-scope array compound literals with
  // constant initializers are also l-values, and compound literals are
  // otherwise prvalues.
  //
  // (GCC also treats C++ list-initialized file-scope array prvalues with
  // constant initializers as l-values, but that's non-conforming, so we don't
  // follow it there.)
  //
  // FIXME: It would be better to handle the lvalue cases as materializing and
  // lifetime-extending a temporary object, but our materialized temporaries
  // representation only supports lifetime extension from a variable, not "out
  // of thin air".
  // FIXME: For C++, we might want to instead lifetime-extend only if a pointer
  // is bound to the result of applying array-to-pointer decay to the compound
  // literal.
  // FIXME: GCC supports compound literals of reference type, which should
  // obviously have a value kind derived from the kind of reference involved.
```
so the correct fix may very well be elsewhere.

https://github.com/llvm/llvm-project/pull/118480
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to