llvm-project
llvm-project copied to clipboard
Support lvalue statement expressions in C++
Hi all,
I just discovered that the implementation of GNU statement expressions differs from GCC in C++ mode.
The following C++ code compiles in GCC but not in Clang:
void test(int& a) {
&({ a; });
}
In Clang, statement expressions are always prvalues and for that reason we cannot take the address. That is fine for C.
For C++, I suggest to support lvalue/xvalue statement expressions in the same way as the comma operator or ternary operator.
@llvm/issue-subscribers-clang-frontend
CC @zygoloid @AaronBallman we usually try to support gcc extensions, is there a reason not to support this?
We also don't support that in C mode either (so I edited the title). Interestingly, we're very explicitly treating them as rvalues and have for a long while: https://github.com/llvm/llvm-project/commit/7decc9e4ea6c56ffce14d25f542f5eda3eeba97a#diff-03e60ab06f82e27e971dc7c0816e51e2a984da855607560e33c94094ac1622c9R2569
@rjmccall -- do you remember if there's a reason we don't support these as lvalues?
When we first implemented statement-expressions in Clang, the rule in GCC was that they were always r-values. Apparently this changed in GCC 4.5, and we just never followed along.
I don't know that there's a good reason we couldn't support this. I mean, gl-values persisting across a full-expression boundary is a little bit problematic, but I don't think it's worse than any other lifetime problem you could create for yourself in C/C++. The trickiest part of implementing this is that we'd need to suppress the ignored-value conversions on the final expression-statement; because of the way that Sema is driven by the parser, I don't think we actually know whether it's final at the time it's parsed. Maybe we could specialize how we parse statement-expression blocks and do some lookahead after each expression to see if it's final.
Thank you for the background details!