[clang] [Clang] Instantiate the correct lambda call operator (PR #110446)
via cfe-commits
cfe-commits at lists.llvm.org
Mon Sep 30 08:35:41 PDT 2024
================
@@ -1631,9 +1631,32 @@ 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);
+
+ // 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 wants A's here.
+ // }
+ //
+ // To mitigate this, search our own decls first.
+ // FIXME: This feels like a hack; is there a better way of doing this?
+ for (CXXMethodDecl *M : RD.methods())
+ if (M->getDeclName() == Name)
+ return M;
+ // Otherwise, do a full lookup to find external decls too.
+ DeclContext::lookup_result Calls = RD.lookup(Name);
----------------
Sirraide wrote:
Yeah, that worked, thanks!
https://github.com/llvm/llvm-project/pull/110446
More information about the cfe-commits
mailing list