https://github.com/0x59616e updated https://github.com/llvm/llvm-project/pull/65193
>From 8abb437d97382f517bcbf0b5c4a542172c5ae144 Mon Sep 17 00:00:00 2001 From: Sheng <ox596...@gmail.com> Date: Wed, 30 Aug 2023 11:44:23 +0800 Subject: [PATCH 1/6] [clang][Sema] Fix a bug when instantiating a lambda with requires clause Instantiating a lambda at a scope different from its definition scope will paralyze clang if the trailing require clause refers to local variables of that definition scope. This patch fixes this by re-adding the local variables to `LocalInstantiationScope`. Fixes #64462 --- clang/lib/Sema/SemaConcept.cpp | 59 ++++++++++++++++++++++++++++++++++ clang/test/SemaCXX/pr64462.cpp | 20 ++++++++++++ 2 files changed, 79 insertions(+) create mode 100644 clang/test/SemaCXX/pr64462.cpp diff --git a/clang/lib/Sema/SemaConcept.cpp b/clang/lib/Sema/SemaConcept.cpp index 036548b68247bfa..41af513969c6615 100644 --- a/clang/lib/Sema/SemaConcept.cpp +++ b/clang/lib/Sema/SemaConcept.cpp @@ -584,6 +584,58 @@ bool Sema::addInstantiatedCapturesToScope( return false; } +static void addDeclsFromParentScope(Sema &S, FunctionDecl *FD, + LocalInstantiationScope &Scope) { + assert(isLambdaCallOperator(FD) && "FD must be a lambda call operator"); + + LambdaScopeInfo *LSI = cast<LambdaScopeInfo>(S.getFunctionScopes().back()); + + auto captureVar = [&](VarDecl *VD) { + LSI->addCapture(VD, /*isBlock=*/false, /*isByref=*/false, + /*isNested=*/false, VD->getBeginLoc(), SourceLocation(), + VD->getType(), /*Invalid=*/false); + }; + + FD = dyn_cast<FunctionDecl>(FD->getParent()->getParent()); + + if (!FD || !FD->isTemplateInstantiation()) + return; + + FunctionDecl *Pattern = FD->getPrimaryTemplate()->getTemplatedDecl(); + + for (unsigned I = 0; I < Pattern->getNumParams(); ++I) { + ParmVarDecl *PVD = Pattern->getParamDecl(I); + if (!PVD->isParameterPack()) { + Scope.InstantiatedLocal(PVD, FD->getParamDecl(I)); + captureVar(FD->getParamDecl(I)); + continue; + } + + Scope.MakeInstantiatedLocalArgPack(PVD); + + for (ParmVarDecl *Inst : FD->parameters().drop_front(I)) { + Scope.InstantiatedLocalPackArg(PVD, Inst); + captureVar(Inst); + } + } + + for (auto *decl : Pattern->decls()) { + if (!isa<VarDecl>(decl) || isa<ParmVarDecl>(decl)) + continue; + + IdentifierInfo *II = cast<NamedDecl>(decl)->getIdentifier(); + auto it = llvm::find_if(FD->decls(), [&](Decl *inst) { + VarDecl *VD = dyn_cast<VarDecl>(inst); + return VD && VD->isLocalVarDecl() && VD->getIdentifier() == II; + }); + + assert(it != FD->decls().end() && "Cannot find the instantiated variable."); + + Scope.InstantiatedLocal(decl, *it); + captureVar(cast<VarDecl>(*it)); + } +} + bool Sema::SetupConstraintScope( FunctionDecl *FD, std::optional<ArrayRef<TemplateArgument>> TemplateArgs, MultiLevelTemplateArgumentList MLTAL, LocalInstantiationScope &Scope) { @@ -701,6 +753,7 @@ bool Sema::CheckFunctionConstraints(const FunctionDecl *FD, CtxToSave = CtxToSave->getNonTransparentContext(); } + const bool shouldAddDeclsFromParentScope = !CtxToSave->Encloses(CurContext); ContextRAII SavedContext{*this, CtxToSave}; LocalInstantiationScope Scope(*this, !ForOverloadResolution || isLambdaCallOperator(FD)); @@ -722,6 +775,9 @@ bool Sema::CheckFunctionConstraints(const FunctionDecl *FD, LambdaScopeForCallOperatorInstantiationRAII LambdaScope( *this, const_cast<FunctionDecl *>(FD), *MLTAL, Scope); + if (isLambdaCallOperator(FD) && shouldAddDeclsFromParentScope) + addDeclsFromParentScope(*this, const_cast<FunctionDecl *>(FD), Scope); + return CheckConstraintSatisfaction( FD, {FD->getTrailingRequiresClause()}, *MLTAL, SourceRange(UsageLoc.isValid() ? UsageLoc : FD->getLocation()), @@ -913,6 +969,9 @@ bool Sema::CheckInstantiatedFunctionTemplateConstraints( LambdaScopeForCallOperatorInstantiationRAII LambdaScope( *this, const_cast<FunctionDecl *>(Decl), *MLTAL, Scope); + if (isLambdaCallOperator(Decl)) + addDeclsFromParentScope(*this, Decl, Scope); + llvm::SmallVector<Expr *, 1> Converted; return CheckConstraintSatisfaction(Template, TemplateAC, Converted, *MLTAL, PointOfInstantiation, Satisfaction); diff --git a/clang/test/SemaCXX/pr64462.cpp b/clang/test/SemaCXX/pr64462.cpp new file mode 100644 index 000000000000000..cc8b5510d1a823a --- /dev/null +++ b/clang/test/SemaCXX/pr64462.cpp @@ -0,0 +1,20 @@ +// RUN: %clang_cc1 -verify -std=c++20 -fsyntax-only %s + +auto c1(auto f, auto ...fs) { + constexpr bool a = true; + // expected-note@+2{{because substituted constraint expression is ill-formed: no matching function for call to 'c1'}} + // expected-note@+1{{candidate template ignored: constraints not satisfied [with auto:1 = bool}} + return [](auto) requires a && (c1(fs...)) {}; +} + +auto c2(auto f, auto ...fs) { + constexpr bool a = true; + // expected-note@+2{{because substituted constraint expression is ill-formed: no matching function for call to 'c2'}} + // expected-note@+1{{candidate function not viable: constraints not satisfied}} + return []() requires a && (c2(fs...)) {}; +} + +void foo() { + c1(true)(true); // expected-error {{no matching function for call to object of type}} + c2(true)(); // expected-error {{no matching function for call to object of type}} +} >From e391ab7b2b3bc3aeffd38b5ac7f6c7c2a2e5fc04 Mon Sep 17 00:00:00 2001 From: Sheng <ox596...@gmail.com> Date: Fri, 15 Sep 2023 02:02:34 +0800 Subject: [PATCH 2/6] Add support for nested lambda. --- clang/lib/Sema/SemaConcept.cpp | 78 ++++++++++++++++++++-------------- clang/test/SemaCXX/pr64462.cpp | 25 +++++------ 2 files changed, 59 insertions(+), 44 deletions(-) diff --git a/clang/lib/Sema/SemaConcept.cpp b/clang/lib/Sema/SemaConcept.cpp index 41af513969c6615..fc2ddad4e76eeec 100644 --- a/clang/lib/Sema/SemaConcept.cpp +++ b/clang/lib/Sema/SemaConcept.cpp @@ -584,6 +584,20 @@ bool Sema::addInstantiatedCapturesToScope( return false; } +static FunctionDecl *getPatternFunctionDecl(FunctionDecl *FD) { + if (FD->getTemplatedKind() == FunctionDecl::TK_MemberSpecialization) { + while (FD->getInstantiatedFromMemberFunction()) + FD = FD->getInstantiatedFromMemberFunction(); + return FD; + } + + FunctionTemplateDecl *FTD = FD->getPrimaryTemplate(); + while (FTD->getInstantiatedFromMemberTemplate()) + FTD = FTD->getInstantiatedFromMemberTemplate(); + + return FTD->getTemplatedDecl(); +} + static void addDeclsFromParentScope(Sema &S, FunctionDecl *FD, LocalInstantiationScope &Scope) { assert(isLambdaCallOperator(FD) && "FD must be a lambda call operator"); @@ -596,43 +610,45 @@ static void addDeclsFromParentScope(Sema &S, FunctionDecl *FD, VD->getType(), /*Invalid=*/false); }; - FD = dyn_cast<FunctionDecl>(FD->getParent()->getParent()); - - if (!FD || !FD->isTemplateInstantiation()) - return; + while (true) { + FD = dyn_cast_or_null<FunctionDecl>(FD->getParent()->getParent()); + if (!FD || !FD->isTemplateInstantiation()) + return; - FunctionDecl *Pattern = FD->getPrimaryTemplate()->getTemplatedDecl(); + FunctionDecl *Pattern = getPatternFunctionDecl(FD); - for (unsigned I = 0; I < Pattern->getNumParams(); ++I) { - ParmVarDecl *PVD = Pattern->getParamDecl(I); - if (!PVD->isParameterPack()) { - Scope.InstantiatedLocal(PVD, FD->getParamDecl(I)); - captureVar(FD->getParamDecl(I)); - continue; - } + for (unsigned I = 0; I < Pattern->getNumParams(); ++I) { + ParmVarDecl *PVD = Pattern->getParamDecl(I); + if (!PVD->isParameterPack()) { + Scope.InstantiatedLocal(PVD, FD->getParamDecl(I)); + captureVar(FD->getParamDecl(I)); + continue; + } - Scope.MakeInstantiatedLocalArgPack(PVD); + Scope.MakeInstantiatedLocalArgPack(PVD); - for (ParmVarDecl *Inst : FD->parameters().drop_front(I)) { - Scope.InstantiatedLocalPackArg(PVD, Inst); - captureVar(Inst); + for (ParmVarDecl *Inst : FD->parameters().drop_front(I)) { + Scope.InstantiatedLocalPackArg(PVD, Inst); + captureVar(Inst); + } } - } - for (auto *decl : Pattern->decls()) { - if (!isa<VarDecl>(decl) || isa<ParmVarDecl>(decl)) - continue; + for (auto *decl : Pattern->decls()) { + if (!isa<VarDecl>(decl) || isa<ParmVarDecl>(decl)) + continue; - IdentifierInfo *II = cast<NamedDecl>(decl)->getIdentifier(); - auto it = llvm::find_if(FD->decls(), [&](Decl *inst) { - VarDecl *VD = dyn_cast<VarDecl>(inst); - return VD && VD->isLocalVarDecl() && VD->getIdentifier() == II; - }); + IdentifierInfo *II = cast<NamedDecl>(decl)->getIdentifier(); + auto it = llvm::find_if(FD->decls(), [&](Decl *inst) { + VarDecl *VD = dyn_cast<VarDecl>(inst); + return VD && VD->isLocalVarDecl() && VD->getIdentifier() == II; + }); - assert(it != FD->decls().end() && "Cannot find the instantiated variable."); + if (it == FD->decls().end()) + continue; - Scope.InstantiatedLocal(decl, *it); - captureVar(cast<VarDecl>(*it)); + Scope.InstantiatedLocal(decl, *it); + captureVar(cast<VarDecl>(*it)); + } } } @@ -753,10 +769,8 @@ bool Sema::CheckFunctionConstraints(const FunctionDecl *FD, CtxToSave = CtxToSave->getNonTransparentContext(); } - const bool shouldAddDeclsFromParentScope = !CtxToSave->Encloses(CurContext); ContextRAII SavedContext{*this, CtxToSave}; - LocalInstantiationScope Scope(*this, !ForOverloadResolution || - isLambdaCallOperator(FD)); + LocalInstantiationScope Scope(*this, !ForOverloadResolution); std::optional<MultiLevelTemplateArgumentList> MLTAL = SetupConstraintCheckingTemplateArgumentsAndScope( const_cast<FunctionDecl *>(FD), {}, Scope); @@ -775,7 +789,7 @@ bool Sema::CheckFunctionConstraints(const FunctionDecl *FD, LambdaScopeForCallOperatorInstantiationRAII LambdaScope( *this, const_cast<FunctionDecl *>(FD), *MLTAL, Scope); - if (isLambdaCallOperator(FD) && shouldAddDeclsFromParentScope) + if (isLambdaCallOperator(FD) && ForOverloadResolution) addDeclsFromParentScope(*this, const_cast<FunctionDecl *>(FD), Scope); return CheckConstraintSatisfaction( diff --git a/clang/test/SemaCXX/pr64462.cpp b/clang/test/SemaCXX/pr64462.cpp index cc8b5510d1a823a..7cffb3583dcd408 100644 --- a/clang/test/SemaCXX/pr64462.cpp +++ b/clang/test/SemaCXX/pr64462.cpp @@ -2,19 +2,20 @@ auto c1(auto f, auto ...fs) { constexpr bool a = true; - // expected-note@+2{{because substituted constraint expression is ill-formed: no matching function for call to 'c1'}} - // expected-note@+1{{candidate template ignored: constraints not satisfied [with auto:1 = bool}} - return [](auto) requires a && (c1(fs...)) {}; -} - -auto c2(auto f, auto ...fs) { - constexpr bool a = true; - // expected-note@+2{{because substituted constraint expression is ill-formed: no matching function for call to 'c2'}} - // expected-note@+1{{candidate function not viable: constraints not satisfied}} - return []() requires a && (c2(fs...)) {}; + return [](auto) requires a { + constexpr bool b = true; + return []() requires a && b { + constexpr bool c = true; + return [](auto) requires a && b && c { + constexpr bool d = true; + // expected-note@+2{{because substituted constraint expression is ill-formed: no matching function for call to 'c1'}} + // expected-note@+1{{candidate function not viable: constraints not satisfied}} + return []() requires a && b && c && d && (c1(fs...)) {}; + }; + }(); + }(1); } void foo() { - c1(true)(true); // expected-error {{no matching function for call to object of type}} - c2(true)(); // expected-error {{no matching function for call to object of type}} + c1(true)(1.0)(); // expected-error{{no matching function for call to object of type}} } >From 7edb6a53c0ed412a097367f120b62bdbb2dbf535 Mon Sep 17 00:00:00 2001 From: Sheng <ox596...@gmail.com> Date: Sat, 16 Sep 2023 09:36:08 +0800 Subject: [PATCH 3/6] Move the implementation into LambdaScopeForCallOperatorInstantiationRAII --- clang/include/clang/Sema/Sema.h | 8 +- clang/lib/Sema/SemaConcept.cpp | 77 +------------------ clang/lib/Sema/SemaLambda.cpp | 62 ++++++++++----- .../lib/Sema/SemaTemplateInstantiateDecl.cpp | 30 ++++++++ 4 files changed, 81 insertions(+), 96 deletions(-) diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index 5bef0335f7891c9..b19481182a8a9fc 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -7383,7 +7383,8 @@ class Sema final { public: LambdaScopeForCallOperatorInstantiationRAII( Sema &SemasRef, FunctionDecl *FD, MultiLevelTemplateArgumentList MLTAL, - LocalInstantiationScope &Scope); + LocalInstantiationScope &Scope, + bool shouldAddDeclsFromParentScope = true); }; /// Check whether the given expression is a valid constraint expression. @@ -7409,6 +7410,11 @@ class Sema final { llvm::ContextualFoldingSet<ConstraintSatisfaction, const ASTContext &> SatisfactionCache; + /// Intorduce the instantiated local variables into the local + /// instantiation scope. + void addInstantiatedLocalVarsToScope(FunctionDecl *Function, + const FunctionDecl *PatternDecl, + LocalInstantiationScope &Scope); /// Introduce the instantiated function parameters into the local /// instantiation scope, and set the parameter names to those used /// in the template. diff --git a/clang/lib/Sema/SemaConcept.cpp b/clang/lib/Sema/SemaConcept.cpp index fc2ddad4e76eeec..0ef03293b46ffb7 100644 --- a/clang/lib/Sema/SemaConcept.cpp +++ b/clang/lib/Sema/SemaConcept.cpp @@ -584,74 +584,6 @@ bool Sema::addInstantiatedCapturesToScope( return false; } -static FunctionDecl *getPatternFunctionDecl(FunctionDecl *FD) { - if (FD->getTemplatedKind() == FunctionDecl::TK_MemberSpecialization) { - while (FD->getInstantiatedFromMemberFunction()) - FD = FD->getInstantiatedFromMemberFunction(); - return FD; - } - - FunctionTemplateDecl *FTD = FD->getPrimaryTemplate(); - while (FTD->getInstantiatedFromMemberTemplate()) - FTD = FTD->getInstantiatedFromMemberTemplate(); - - return FTD->getTemplatedDecl(); -} - -static void addDeclsFromParentScope(Sema &S, FunctionDecl *FD, - LocalInstantiationScope &Scope) { - assert(isLambdaCallOperator(FD) && "FD must be a lambda call operator"); - - LambdaScopeInfo *LSI = cast<LambdaScopeInfo>(S.getFunctionScopes().back()); - - auto captureVar = [&](VarDecl *VD) { - LSI->addCapture(VD, /*isBlock=*/false, /*isByref=*/false, - /*isNested=*/false, VD->getBeginLoc(), SourceLocation(), - VD->getType(), /*Invalid=*/false); - }; - - while (true) { - FD = dyn_cast_or_null<FunctionDecl>(FD->getParent()->getParent()); - if (!FD || !FD->isTemplateInstantiation()) - return; - - FunctionDecl *Pattern = getPatternFunctionDecl(FD); - - for (unsigned I = 0; I < Pattern->getNumParams(); ++I) { - ParmVarDecl *PVD = Pattern->getParamDecl(I); - if (!PVD->isParameterPack()) { - Scope.InstantiatedLocal(PVD, FD->getParamDecl(I)); - captureVar(FD->getParamDecl(I)); - continue; - } - - Scope.MakeInstantiatedLocalArgPack(PVD); - - for (ParmVarDecl *Inst : FD->parameters().drop_front(I)) { - Scope.InstantiatedLocalPackArg(PVD, Inst); - captureVar(Inst); - } - } - - for (auto *decl : Pattern->decls()) { - if (!isa<VarDecl>(decl) || isa<ParmVarDecl>(decl)) - continue; - - IdentifierInfo *II = cast<NamedDecl>(decl)->getIdentifier(); - auto it = llvm::find_if(FD->decls(), [&](Decl *inst) { - VarDecl *VD = dyn_cast<VarDecl>(inst); - return VD && VD->isLocalVarDecl() && VD->getIdentifier() == II; - }); - - if (it == FD->decls().end()) - continue; - - Scope.InstantiatedLocal(decl, *it); - captureVar(cast<VarDecl>(*it)); - } - } -} - bool Sema::SetupConstraintScope( FunctionDecl *FD, std::optional<ArrayRef<TemplateArgument>> TemplateArgs, MultiLevelTemplateArgumentList MLTAL, LocalInstantiationScope &Scope) { @@ -787,10 +719,8 @@ bool Sema::CheckFunctionConstraints(const FunctionDecl *FD, CXXThisScopeRAII ThisScope(*this, Record, ThisQuals, Record != nullptr); LambdaScopeForCallOperatorInstantiationRAII LambdaScope( - *this, const_cast<FunctionDecl *>(FD), *MLTAL, Scope); - - if (isLambdaCallOperator(FD) && ForOverloadResolution) - addDeclsFromParentScope(*this, const_cast<FunctionDecl *>(FD), Scope); + *this, const_cast<FunctionDecl *>(FD), *MLTAL, Scope, + ForOverloadResolution); return CheckConstraintSatisfaction( FD, {FD->getTrailingRequiresClause()}, *MLTAL, @@ -983,9 +913,6 @@ bool Sema::CheckInstantiatedFunctionTemplateConstraints( LambdaScopeForCallOperatorInstantiationRAII LambdaScope( *this, const_cast<FunctionDecl *>(Decl), *MLTAL, Scope); - if (isLambdaCallOperator(Decl)) - addDeclsFromParentScope(*this, Decl, Scope); - llvm::SmallVector<Expr *, 1> Converted; return CheckConstraintSatisfaction(Template, TemplateAC, Converted, *MLTAL, PointOfInstantiation, Satisfaction); diff --git a/clang/lib/Sema/SemaLambda.cpp b/clang/lib/Sema/SemaLambda.cpp index 6fd91bda61af5a7..98449c95d6bea32 100644 --- a/clang/lib/Sema/SemaLambda.cpp +++ b/clang/lib/Sema/SemaLambda.cpp @@ -2296,33 +2296,55 @@ ExprResult Sema::BuildBlockForLambdaConversion(SourceLocation CurrentLocation, return BuildBlock; } +static FunctionDecl *getPatternFunctionDecl(FunctionDecl *FD) { + if (FD->getTemplatedKind() == FunctionDecl::TK_MemberSpecialization) { + while (FD->getInstantiatedFromMemberFunction()) + FD = FD->getInstantiatedFromMemberFunction(); + return FD; + } + + if (FD->getTemplatedKind() == FunctionDecl::TK_DependentNonTemplate) + return FD->getInstantiatedFromDecl(); + + FunctionTemplateDecl *FTD = FD->getPrimaryTemplate(); + if (!FTD) + return nullptr; + + while (FTD->getInstantiatedFromMemberTemplate()) + FTD = FTD->getInstantiatedFromMemberTemplate(); + + return FTD->getTemplatedDecl(); +} + Sema::LambdaScopeForCallOperatorInstantiationRAII:: LambdaScopeForCallOperatorInstantiationRAII( - Sema &SemasRef, FunctionDecl *FD, MultiLevelTemplateArgumentList MLTAL, - LocalInstantiationScope &Scope) - : FunctionScopeRAII(SemasRef) { + Sema &SemaRef, FunctionDecl *FD, MultiLevelTemplateArgumentList MLTAL, + LocalInstantiationScope &Scope, bool shouldAddDeclsFromParentScope) + : FunctionScopeRAII(SemaRef) { if (!isLambdaCallOperator(FD)) { FunctionScopeRAII::disable(); return; } - if (FD->isTemplateInstantiation() && FD->getPrimaryTemplate()) { - FunctionTemplateDecl *PrimaryTemplate = FD->getPrimaryTemplate(); - if (const auto *FromMemTempl = - PrimaryTemplate->getInstantiatedFromMemberTemplate()) { - SemasRef.addInstantiatedCapturesToScope( - FD, FromMemTempl->getTemplatedDecl(), Scope, MLTAL); - } - } + SemaRef.RebuildLambdaScopeInfo(cast<CXXMethodDecl>(FD)); - else if (FD->getTemplatedKind() == FunctionDecl::TK_MemberSpecialization || - FD->getTemplatedKind() == FunctionDecl::TK_DependentNonTemplate) { - FunctionDecl *InstantiatedFrom = - FD->getTemplatedKind() == FunctionDecl::TK_MemberSpecialization - ? FD->getInstantiatedFromMemberFunction() - : FD->getInstantiatedFromDecl(); - SemasRef.addInstantiatedCapturesToScope(FD, InstantiatedFrom, Scope, MLTAL); - } + FunctionDecl *Pattern = getPatternFunctionDecl(FD); + if (Pattern) { + SemaRef.addInstantiatedCapturesToScope(FD, Pattern, Scope, MLTAL); + + FunctionDecl *ParentFD = FD; + while (shouldAddDeclsFromParentScope) { + + ParentFD = + dyn_cast<FunctionDecl>(getLambdaAwareParentOfDeclContext(ParentFD)); + Pattern = + dyn_cast<FunctionDecl>(getLambdaAwareParentOfDeclContext(Pattern)); - SemasRef.RebuildLambdaScopeInfo(cast<CXXMethodDecl>(FD)); + if (!FD || !Pattern) + break; + + SemaRef.addInstantiatedParametersToScope(ParentFD, Pattern, Scope, MLTAL); + SemaRef.addInstantiatedLocalVarsToScope(ParentFD, Pattern, Scope); + } + } } diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp index e4974b168482b05..3aaf1dad59b240f 100644 --- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -4523,6 +4523,36 @@ TemplateDeclInstantiator::SubstFunctionType(FunctionDecl *D, return NewTInfo; } +/// Intorduce the instantiated local variables into the local +/// instantiation scope. +void Sema::addInstantiatedLocalVarsToScope(FunctionDecl *Function, + const FunctionDecl *PatternDecl, + LocalInstantiationScope &Scope) { + LambdaScopeInfo *LSI = cast<LambdaScopeInfo>(getFunctionScopes().back()); + + for (auto *decl : PatternDecl->decls()) { + if (!isa<VarDecl>(decl) || isa<ParmVarDecl>(decl)) + continue; + + VarDecl *VD = cast<VarDecl>(decl); + IdentifierInfo *II = VD->getIdentifier(); + + auto it = llvm::find_if(Function->decls(), [&](Decl *inst) { + VarDecl *InstVD = dyn_cast<VarDecl>(inst); + return InstVD && InstVD->isLocalVarDecl() && + InstVD->getIdentifier() == II; + }); + + if (it == Function->decls().end()) + continue; + + Scope.InstantiatedLocal(VD, *it); + LSI->addCapture(cast<VarDecl>(*it), /*isBlock=*/false, /*isByref=*/false, + /*isNested=*/false, VD->getLocation(), SourceLocation(), + VD->getType(), /*Invalid=*/false); + } +} + /// Introduce the instantiated function parameters into the local /// instantiation scope, and set the parameter names to those used /// in the template. >From 22a5a4ede4f48a3d94258aee8acbecdcc2557cc4 Mon Sep 17 00:00:00 2001 From: Sheng <ox596...@gmail.com> Date: Tue, 3 Oct 2023 18:25:06 +0800 Subject: [PATCH 4/6] Fix typo --- clang/include/clang/Sema/Sema.h | 2 +- clang/lib/Sema/SemaTemplateInstantiateDecl.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index b19481182a8a9fc..bc5c100385823d9 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -7410,7 +7410,7 @@ class Sema final { llvm::ContextualFoldingSet<ConstraintSatisfaction, const ASTContext &> SatisfactionCache; - /// Intorduce the instantiated local variables into the local + /// Introduce the instantiated local variables into the local /// instantiation scope. void addInstantiatedLocalVarsToScope(FunctionDecl *Function, const FunctionDecl *PatternDecl, diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp index 3aaf1dad59b240f..0b2b775f19a0166 100644 --- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -4523,7 +4523,7 @@ TemplateDeclInstantiator::SubstFunctionType(FunctionDecl *D, return NewTInfo; } -/// Intorduce the instantiated local variables into the local +/// Introduce the instantiated local variables into the local /// instantiation scope. void Sema::addInstantiatedLocalVarsToScope(FunctionDecl *Function, const FunctionDecl *PatternDecl, >From 1eda43020f23a7458f91a9f82a4363ea6f80eb8a Mon Sep 17 00:00:00 2001 From: Sheng <ox596...@gmail.com> Date: Tue, 3 Oct 2023 18:25:40 +0800 Subject: [PATCH 5/6] Align the code style. --- clang/include/clang/Sema/Sema.h | 2 +- clang/lib/Sema/SemaLambda.cpp | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index bc5c100385823d9..bb05c45391b5473 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -7384,7 +7384,7 @@ class Sema final { LambdaScopeForCallOperatorInstantiationRAII( Sema &SemasRef, FunctionDecl *FD, MultiLevelTemplateArgumentList MLTAL, LocalInstantiationScope &Scope, - bool shouldAddDeclsFromParentScope = true); + bool ShouldAddDeclsFromParentScope = true); }; /// Check whether the given expression is a valid constraint expression. diff --git a/clang/lib/Sema/SemaLambda.cpp b/clang/lib/Sema/SemaLambda.cpp index 98449c95d6bea32..421048aaff5c90c 100644 --- a/clang/lib/Sema/SemaLambda.cpp +++ b/clang/lib/Sema/SemaLambda.cpp @@ -2319,7 +2319,7 @@ static FunctionDecl *getPatternFunctionDecl(FunctionDecl *FD) { Sema::LambdaScopeForCallOperatorInstantiationRAII:: LambdaScopeForCallOperatorInstantiationRAII( Sema &SemaRef, FunctionDecl *FD, MultiLevelTemplateArgumentList MLTAL, - LocalInstantiationScope &Scope, bool shouldAddDeclsFromParentScope) + LocalInstantiationScope &Scope, bool ShouldAddDeclsFromParentScope) : FunctionScopeRAII(SemaRef) { if (!isLambdaCallOperator(FD)) { FunctionScopeRAII::disable(); @@ -2333,7 +2333,7 @@ Sema::LambdaScopeForCallOperatorInstantiationRAII:: SemaRef.addInstantiatedCapturesToScope(FD, Pattern, Scope, MLTAL); FunctionDecl *ParentFD = FD; - while (shouldAddDeclsFromParentScope) { + while (ShouldAddDeclsFromParentScope) { ParentFD = dyn_cast<FunctionDecl>(getLambdaAwareParentOfDeclContext(ParentFD)); >From 6fa1071e09bd69274ba0a69bbafd94d6635b2eb2 Mon Sep 17 00:00:00 2001 From: Sheng <ox596...@gmail.com> Date: Tue, 3 Oct 2023 18:34:11 +0800 Subject: [PATCH 6/6] Add description in release note. --- clang/docs/ReleaseNotes.rst | 2 ++ 1 file changed, 2 insertions(+) diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 6be824771c583be..886d7f2ef6da69d 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -282,6 +282,8 @@ Bug Fixes in This Version Fixes (`#67603 <https://github.com/llvm/llvm-project/issues/67603>`_) - Fixes a crash caused by a multidimensional array being captured by a lambda (`#67722 <https://github.com/llvm/llvm-project/issues/67722>`_). +- Fixes a crash when instantiating a lambda with requires clause. + (`#64462 <https://github.com/llvm/llvm-project/issues/64462>`_) Bug Fixes to Compiler Builtins ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits