New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
lambda with this auto
that captures this
in a member function is not an integral constant expression
#80997
Comments
@llvm/issue-subscribers-clang-frontend Author: Hewill Kang (hewillk)
https://godbolt.org/z/azqxac8xE
```cpp
struct S {
int i = 42;
constexpr auto f() {
return [this](this auto) {
return this->i;
}();
};
};
static_assert(S().f() == 42);
<source>:10:15: error: static assertion expression is not an integral constant expression
|
[expr.prim.this] has this to say about
In other words, you can’t use |
Admittedly, the diagnostic is not ideal here:
The problem is not so much that it isn’t |
I don't think so. The struct S {
int i = 42;
constexpr auto f() {
return [this](this auto) {
return this->i;
}();
};
};
int main() {
return S().f();
} |
Right, the |
There is already a GCC Bug report about this. https://gcc.gnu.org/bugzilla/show_bug.cgi?id=113563 |
Accessing captures of lambdas w/ explicit object parameters seems to have some problems currently. This also straight-up asserts: struct S {
int i = 42;
constexpr auto f() {
return [i = this->i] (this auto) {
return i;
}();
};
};
static_assert(S().f() == 42); |
… explicit object parameter in constant evaluator (#81102) There were some bugs wrt explicit object parameters in lambdas in the constant evaluator: - The code evaluating a `CXXThisExpr` wasn’t checking for explicit object parameters at all and thus assumed that there was no `this` in the current context because the lambda didn’t have one, even though we were in a member function and had captured its `this`. - The code retrieving captures as lvalues *did* account for explicit object parameters, but it did not handle the case of the explicit object parameter being passed by value rather than by reference. This fixes #80997. --------- Co-authored-by: cor3ntin <corentinjabot@gmail.com> Co-authored-by: Aaron Ballman <aaron@aaronballman.com>
Note that a lambda-expression is an expression, not a declaration of an explicit object member function -- in context, it's clear that this rule is talking about syntactic function-definitions, member-declarators, and declarators, which a lambda-expression does not have -- so this rule does not apply here. But since Clang and GCC both seem to get this wrong, I've filed cplusplus/draft#6855 asking for a note to clarify. |
Hmm, I’m not sure I’m interpreting this correctly, but for what it’s worth, the reason why we were rejecting this code is because the constant evaluator ostensibly wasn’t handling lambdas with explicit object parameters properly (e.g. it was outright crashing on captures if the explicit object parameter was passed by value), and we were already accepting this code outside of constant evaluation (unless you mean that fixing this and allowing this is us getting it wrong).
Yeah, conceptually, I see nothing wrong w/ using |
I just meant that Clang was (prior to the fix here) not completely handling the case of |
… explicit object parameter in constant evaluator (llvm#81102) There were some bugs wrt explicit object parameters in lambdas in the constant evaluator: - The code evaluating a `CXXThisExpr` wasn’t checking for explicit object parameters at all and thus assumed that there was no `this` in the current context because the lambda didn’t have one, even though we were in a member function and had captured its `this`. - The code retrieving captures as lvalues *did* account for explicit object parameters, but it did not handle the case of the explicit object parameter being passed by value rather than by reference. This fixes llvm#80997. --------- Co-authored-by: cor3ntin <corentinjabot@gmail.com> Co-authored-by: Aaron Ballman <aaron@aaronballman.com>
https://godbolt.org/z/azqxac8xE
Clang rejects the above code with:
If we remove
this auto
then compile fine, the two should be equivalent right?Not really sure what the standards say about this.
The text was updated successfully, but these errors were encountered: