llvm-project icon indicating copy to clipboard operation
llvm-project copied to clipboard

Support lvalue statement expressions in C++

Open strimo378 opened this issue 2 years ago • 1 comments

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.

strimo378 avatar Oct 14 '22 15:10 strimo378

@llvm/issue-subscribers-clang-frontend

llvmbot avatar Oct 14 '22 15:10 llvmbot

CC @zygoloid @AaronBallman we usually try to support gcc extensions, is there a reason not to support this?

shafik avatar Dec 17 '23 05:12 shafik

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?

AaronBallman avatar Jan 11 '24 15:01 AaronBallman

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.

rjmccall avatar Jan 11 '24 19:01 rjmccall

Thank you for the background details!

AaronBallman avatar Jan 11 '24 19:01 AaronBallman