This is an archive of the discontinued LLVM Phabricator instance.

[Clang] Fix evaluation of parameters of lambda call operator attributes
ClosedPublic

Authored by cor3ntin on Mar 21 2023, 9:04 AM.

Details

Summary

Fix a regresion introduced by D124351.
Attributes of lambda call operator were evaluated in the
context of the closure object type rather than its operator,
causing an assertion failure.

This was because we temporarily switch to the class lambda to
produce the mangling of the lambda, but we stayed in that
context too long.

Diff Detail

Event Timeline

cor3ntin created this revision.Mar 21 2023, 9:04 AM
Herald added a project: Restricted Project. · View Herald TranscriptMar 21 2023, 9:04 AM
cor3ntin requested review of this revision.Mar 21 2023, 9:04 AM
Herald added a project: Restricted Project. · View Herald TranscriptMar 21 2023, 9:04 AM
Herald added a subscriber: cfe-commits. · View Herald Transcript

Whether the assertion itself in getCurLambda is still pertinent,
despite no test depending on it does require more analysis.

This comment in SemaExprCXX.cpp dissuaded to try to do more surgery as part of this fix, and in some way, that assertion firing helped us discover the bug this PR fixes, so it was useful

// FIXME: PR 17877 showed that getCurLambda() can return a valid pointer
// even if CurContext is not a lambda call operator. Refer to that Bug Report
// for an example of the code that might cause this asynchrony.
// By ensuring we are in the context of a lambda's call operator
// we can fix the bug (we only need to check whether we need to capture
// if we are within a lambda's body); but per the comments in that
// PR, a proper fix would entail :
//   "Alternative suggestion:
//   - Add to Sema an integer holding the smallest (outermost) scope
//     index that we are *lexically* within, and save/restore/set to
//     FunctionScopes.size() in InstantiatingTemplate's
//     constructor/destructor.
//  - Teach the handful of places that iterate over FunctionScopes to
//    stop at the outermost enclosing lexical scope."

Attributes of lambda call operator were evaluated in the context of the closure object type rather than its operator,

Just for my understanding, what did this affect with regards to the if guard for assert? CurContext or something else? I suspected it had something to do with contexts being incorrect but I wasn't familiar enough with the code to pinpoint where/what exactly.

Attributes of lambda call operator were evaluated in the context of the closure object type rather than its operator,

Just for my understanding, what did this affect with regards to the if guard for assert? CurContext or something else? I suspected it had something to do with contexts being incorrect but I wasn't familiar enough with the code to pinpoint where/what exactly.

Exactly CurContext. For the purpose of mangling lambda the context needs to be the parent of the lambda class, so !CurLSI->Lambda->Encloses(CurContext) - which check that we are actually in the lambda - was (incorrectly) true.

Note that you are right about the assert being fishy to begin with but that's a preexisting thing and i can't quite convince myself than removing it entirely wouldn't break something. That we were in the wrong context is something i broke :(

eandrews accepted this revision.Mar 21 2023, 11:44 AM

Attributes of lambda call operator were evaluated in the context of the closure object type rather than its operator,

Just for my understanding, what did this affect with regards to the if guard for assert? CurContext or something else? I suspected it had something to do with contexts being incorrect but I wasn't familiar enough with the code to pinpoint where/what exactly.

Exactly CurContext. For the purpose of mangling lambda the context needs to be the parent of the lambda class, so !CurLSI->Lambda->Encloses(CurContext) - which check that we are actually in the lambda - was (incorrectly) true.

Note that you are right about the assert being fishy to begin with but that's a preexisting thing and i can't quite convince myself than removing it entirely wouldn't break something. That we were in the wrong context is something i broke :(

Thanks for explaining!

This revision is now accepted and ready to land.Mar 21 2023, 11:44 AM

Can we merge this patch? It will fix regressions introduced by D124351 I see downstream

This revision was landed with ongoing or failed builds.Mar 23 2023, 8:12 AM
This revision was automatically updated to reflect the committed changes.

Sure! I didn't land it sooner because the bots were down. but apparently they were up quite fast. Thanks!