-
Notifications
You must be signed in to change notification settings - Fork 12.7k
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
[Clang][Sema] Tweak tryCaptureVariable for unevaluated lambdas #93206
Changes from 1 commit
658e9d4
60aff76
36d6277
dc2519b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -1036,6 +1036,7 @@ void Sema::ActOnLambdaExpressionAfterIntroducer(LambdaIntroducer &Intro, | |
// be dependent, because there are template parameters in scope. | ||
CXXRecordDecl::LambdaDependencyKind LambdaDependencyKind = | ||
CXXRecordDecl::LDK_Unknown; | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Adding a blank line so I can comment here: I found it interesting that we asserted in line 1033 that There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This looks like dead code from a past refactor, we should remove it |
||
if (LSI->NumExplicitTemplateParams > 0) { | ||
Scope *TemplateParamScope = CurScope->getTemplateParamParent(); | ||
assert(TemplateParamScope && | ||
|
@@ -1046,6 +1047,25 @@ void Sema::ActOnLambdaExpressionAfterIntroducer(LambdaIntroducer &Intro, | |
LambdaDependencyKind = CXXRecordDecl::LDK_AlwaysDependent; | ||
} else if (CurScope->getTemplateParamParent() != nullptr) { | ||
LambdaDependencyKind = CXXRecordDecl::LDK_AlwaysDependent; | ||
} else if (Scope *P = CurScope->getParent()) { | ||
// Given a lambda defined inside a requires expression, | ||
// | ||
// struct S { | ||
// S(auto var) requires requires { [&] -> decltype(var) { }; } | ||
// {} | ||
// }; | ||
// | ||
// The parameter var is not injected into the function Decl at the point of | ||
// parsing lambda. In such scenarios, perceiving it as dependent could | ||
// result in the constraint being evaluated, which matches what GCC does. | ||
while (P->getEntity() && P->getEntity()->isRequiresExprBody()) | ||
P = P->getParent(); | ||
if (P->isFunctionDeclarationScope() && | ||
llvm::any_of(P->decls(), [](Decl *D) { | ||
return isa<ParmVarDecl>(D) && | ||
cast<ParmVarDecl>(D)->getType()->isTemplateTypeParmType(); | ||
})) | ||
LambdaDependencyKind = CXXRecordDecl::LDK_AlwaysDependent; | ||
} | ||
|
||
CXXRecordDecl *Class = createLambdaClosureType( | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there any good reason to do this in 2 places, rather than just delay the above one to here? @cor3ntin ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, looking into
ActOnLambdaClosureQualifiers
, I don't see anything that (currently) depends on lambda parameters. I guess we can combine these two calls? I'd love to open a separate NFC PR for doing so, before landing this patch. :)@erichkeane I retrospected your comment in #78598 (comment) and I appreciate the diagnostics for non-ODR uses - however that's much like a QoI issue to me and would it be OK to leave it as a follow-up? Let me know what you think and I'll add a FIXME then.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think I'd be ok with this as a followup. But @cor3ntin is the one who knows the most about lambda stuff (particularly parsing, etc), so I'd like to see him approve this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, we need to set whether the lambda has a
mutable
keyword as soon as the parameters, if present, are parsed, as that affect the meaning of subsequent id-expressionsWhen there are no parens, there can be a noexcept clause for example, and parsing that does requires knowing whether the lambda is mutable, so that we can adjust the type of any reference-to-capture.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, that makes sense! We currently set
LSI->Mutable
inActOnLambdaClosureQualifiers()
, and while I think it's possible to move it out of the function, I'm not opposed to leaving it as-is.