[clang] [Clang] Instantiate the correct lambda call operator (PR #110446)
Chuanqi Xu via cfe-commits
cfe-commits at lists.llvm.org
Mon Oct 7 19:01:21 PDT 2024
================
@@ -1631,13 +1631,39 @@ static bool allLookupResultsAreTheSame(const DeclContext::lookup_result &R) {
static NamedDecl* getLambdaCallOperatorHelper(const CXXRecordDecl &RD) {
if (!RD.isLambda()) return nullptr;
DeclarationName Name =
- RD.getASTContext().DeclarationNames.getCXXOperatorName(OO_Call);
- DeclContext::lookup_result Calls = RD.lookup(Name);
+ RD.getASTContext().DeclarationNames.getCXXOperatorName(OO_Call);
+ DeclContext::lookup_result Calls = RD.lookup(Name);
assert(!Calls.empty() && "Missing lambda call operator!");
assert(allLookupResultsAreTheSame(Calls) &&
"More than one lambda call operator!");
- return Calls.front();
+
+ // If we have multiple call operators, we might be in a situation
+ // where we merged this lambda with one from another module; in that
+ // case, return our method (instead of that of the other lambda).
+ //
+ // This avoids situations where, given two modules A and B, if we
+ // try to instantiate A's call operator in a function in B, anything
+ // in the call operator that relies on local decls in the surrounding
+ // function will crash because it tries to find A's decls, but we only
+ // instantiated B's:
+ //
+ // template <typename>
+ // void f() {
+ // using T = int; // We only instantiate B's version of this.
+ // auto L = [](T) { }; // But A's call operator would want A's here.
+ // }
+ //
+ // Walk the call operator’s redecl chain to find the one that belongs
+ // to this module.
----------------
ChuanqiXu9 wrote:
```suggestion
// to this module.
//
// TODO: We need to fix this properly by https://github.com/llvm/llvm-project/issues/90154
```
https://github.com/llvm/llvm-project/pull/110446
More information about the cfe-commits
mailing list