Skip to content

Commit 696586e

Browse files
SC llvm teamSC llvm team
SC llvm team
authored and
SC llvm team
committed
Merged main:548d67a0393c into amd-gfx:b60b0143910c
Local branch amd-gfx b60b014 Merged main:9370271ec5de into amd-gfx:a9743de9eb8f Remote branch main 548d67a [clang][Sema] Fix a bug when instantiating a lambda with requires clause (llvm#65193)
2 parents b60b014 + 548d67a commit 696586e

File tree

7 files changed

+106
-25
lines changed

7 files changed

+106
-25
lines changed

clang/docs/ReleaseNotes.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -288,6 +288,8 @@ Bug Fixes in This Version
288288
Fixes (`#67603 <https://github.com/llvm/llvm-project/issues/67603>`_)
289289
- Fixes a crash caused by a multidimensional array being captured by a lambda
290290
(`#67722 <https://github.com/llvm/llvm-project/issues/67722>`_).
291+
- Fixes a crash when instantiating a lambda with requires clause.
292+
(`#64462 <https://github.com/llvm/llvm-project/issues/64462>`_)
291293

292294
Bug Fixes to Compiler Builtins
293295
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

clang/include/clang/Sema/Sema.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7383,7 +7383,8 @@ class Sema final {
73837383
public:
73847384
LambdaScopeForCallOperatorInstantiationRAII(
73857385
Sema &SemasRef, FunctionDecl *FD, MultiLevelTemplateArgumentList MLTAL,
7386-
LocalInstantiationScope &Scope);
7386+
LocalInstantiationScope &Scope,
7387+
bool ShouldAddDeclsFromParentScope = true);
73877388
};
73887389

73897390
/// Check whether the given expression is a valid constraint expression.
@@ -7409,6 +7410,11 @@ class Sema final {
74097410
llvm::ContextualFoldingSet<ConstraintSatisfaction, const ASTContext &>
74107411
SatisfactionCache;
74117412

7413+
/// Introduce the instantiated local variables into the local
7414+
/// instantiation scope.
7415+
void addInstantiatedLocalVarsToScope(FunctionDecl *Function,
7416+
const FunctionDecl *PatternDecl,
7417+
LocalInstantiationScope &Scope);
74127418
/// Introduce the instantiated function parameters into the local
74137419
/// instantiation scope, and set the parameter names to those used
74147420
/// in the template.

clang/lib/Sema/SemaConcept.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -702,8 +702,7 @@ bool Sema::CheckFunctionConstraints(const FunctionDecl *FD,
702702
}
703703

704704
ContextRAII SavedContext{*this, CtxToSave};
705-
LocalInstantiationScope Scope(*this, !ForOverloadResolution ||
706-
isLambdaCallOperator(FD));
705+
LocalInstantiationScope Scope(*this, !ForOverloadResolution);
707706
std::optional<MultiLevelTemplateArgumentList> MLTAL =
708707
SetupConstraintCheckingTemplateArgumentsAndScope(
709708
const_cast<FunctionDecl *>(FD), {}, Scope);
@@ -720,7 +719,8 @@ bool Sema::CheckFunctionConstraints(const FunctionDecl *FD,
720719
CXXThisScopeRAII ThisScope(*this, Record, ThisQuals, Record != nullptr);
721720

722721
LambdaScopeForCallOperatorInstantiationRAII LambdaScope(
723-
*this, const_cast<FunctionDecl *>(FD), *MLTAL, Scope);
722+
*this, const_cast<FunctionDecl *>(FD), *MLTAL, Scope,
723+
ForOverloadResolution);
724724

725725
return CheckConstraintSatisfaction(
726726
FD, {FD->getTrailingRequiresClause()}, *MLTAL,

clang/lib/Sema/SemaLambda.cpp

Lines changed: 42 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -2296,33 +2296,55 @@ ExprResult Sema::BuildBlockForLambdaConversion(SourceLocation CurrentLocation,
22962296
return BuildBlock;
22972297
}
22982298

2299+
static FunctionDecl *getPatternFunctionDecl(FunctionDecl *FD) {
2300+
if (FD->getTemplatedKind() == FunctionDecl::TK_MemberSpecialization) {
2301+
while (FD->getInstantiatedFromMemberFunction())
2302+
FD = FD->getInstantiatedFromMemberFunction();
2303+
return FD;
2304+
}
2305+
2306+
if (FD->getTemplatedKind() == FunctionDecl::TK_DependentNonTemplate)
2307+
return FD->getInstantiatedFromDecl();
2308+
2309+
FunctionTemplateDecl *FTD = FD->getPrimaryTemplate();
2310+
if (!FTD)
2311+
return nullptr;
2312+
2313+
while (FTD->getInstantiatedFromMemberTemplate())
2314+
FTD = FTD->getInstantiatedFromMemberTemplate();
2315+
2316+
return FTD->getTemplatedDecl();
2317+
}
2318+
22992319
Sema::LambdaScopeForCallOperatorInstantiationRAII::
23002320
LambdaScopeForCallOperatorInstantiationRAII(
2301-
Sema &SemasRef, FunctionDecl *FD, MultiLevelTemplateArgumentList MLTAL,
2302-
LocalInstantiationScope &Scope)
2303-
: FunctionScopeRAII(SemasRef) {
2321+
Sema &SemaRef, FunctionDecl *FD, MultiLevelTemplateArgumentList MLTAL,
2322+
LocalInstantiationScope &Scope, bool ShouldAddDeclsFromParentScope)
2323+
: FunctionScopeRAII(SemaRef) {
23042324
if (!isLambdaCallOperator(FD)) {
23052325
FunctionScopeRAII::disable();
23062326
return;
23072327
}
23082328

2309-
if (FD->isTemplateInstantiation() && FD->getPrimaryTemplate()) {
2310-
FunctionTemplateDecl *PrimaryTemplate = FD->getPrimaryTemplate();
2311-
if (const auto *FromMemTempl =
2312-
PrimaryTemplate->getInstantiatedFromMemberTemplate()) {
2313-
SemasRef.addInstantiatedCapturesToScope(
2314-
FD, FromMemTempl->getTemplatedDecl(), Scope, MLTAL);
2315-
}
2316-
}
2329+
SemaRef.RebuildLambdaScopeInfo(cast<CXXMethodDecl>(FD));
23172330

2318-
else if (FD->getTemplatedKind() == FunctionDecl::TK_MemberSpecialization ||
2319-
FD->getTemplatedKind() == FunctionDecl::TK_DependentNonTemplate) {
2320-
FunctionDecl *InstantiatedFrom =
2321-
FD->getTemplatedKind() == FunctionDecl::TK_MemberSpecialization
2322-
? FD->getInstantiatedFromMemberFunction()
2323-
: FD->getInstantiatedFromDecl();
2324-
SemasRef.addInstantiatedCapturesToScope(FD, InstantiatedFrom, Scope, MLTAL);
2325-
}
2331+
FunctionDecl *Pattern = getPatternFunctionDecl(FD);
2332+
if (Pattern) {
2333+
SemaRef.addInstantiatedCapturesToScope(FD, Pattern, Scope, MLTAL);
2334+
2335+
FunctionDecl *ParentFD = FD;
2336+
while (ShouldAddDeclsFromParentScope) {
2337+
2338+
ParentFD =
2339+
dyn_cast<FunctionDecl>(getLambdaAwareParentOfDeclContext(ParentFD));
2340+
Pattern =
2341+
dyn_cast<FunctionDecl>(getLambdaAwareParentOfDeclContext(Pattern));
23262342

2327-
SemasRef.RebuildLambdaScopeInfo(cast<CXXMethodDecl>(FD));
2343+
if (!FD || !Pattern)
2344+
break;
2345+
2346+
SemaRef.addInstantiatedParametersToScope(ParentFD, Pattern, Scope, MLTAL);
2347+
SemaRef.addInstantiatedLocalVarsToScope(ParentFD, Pattern, Scope);
2348+
}
2349+
}
23282350
}

clang/lib/Sema/SemaTemplateInstantiateDecl.cpp

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4523,6 +4523,36 @@ TemplateDeclInstantiator::SubstFunctionType(FunctionDecl *D,
45234523
return NewTInfo;
45244524
}
45254525

4526+
/// Introduce the instantiated local variables into the local
4527+
/// instantiation scope.
4528+
void Sema::addInstantiatedLocalVarsToScope(FunctionDecl *Function,
4529+
const FunctionDecl *PatternDecl,
4530+
LocalInstantiationScope &Scope) {
4531+
LambdaScopeInfo *LSI = cast<LambdaScopeInfo>(getFunctionScopes().back());
4532+
4533+
for (auto *decl : PatternDecl->decls()) {
4534+
if (!isa<VarDecl>(decl) || isa<ParmVarDecl>(decl))
4535+
continue;
4536+
4537+
VarDecl *VD = cast<VarDecl>(decl);
4538+
IdentifierInfo *II = VD->getIdentifier();
4539+
4540+
auto it = llvm::find_if(Function->decls(), [&](Decl *inst) {
4541+
VarDecl *InstVD = dyn_cast<VarDecl>(inst);
4542+
return InstVD && InstVD->isLocalVarDecl() &&
4543+
InstVD->getIdentifier() == II;
4544+
});
4545+
4546+
if (it == Function->decls().end())
4547+
continue;
4548+
4549+
Scope.InstantiatedLocal(VD, *it);
4550+
LSI->addCapture(cast<VarDecl>(*it), /*isBlock=*/false, /*isByref=*/false,
4551+
/*isNested=*/false, VD->getLocation(), SourceLocation(),
4552+
VD->getType(), /*Invalid=*/false);
4553+
}
4554+
}
4555+
45264556
/// Introduce the instantiated function parameters into the local
45274557
/// instantiation scope, and set the parameter names to those used
45284558
/// in the template.

clang/test/SemaCXX/pr64462.cpp

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// RUN: %clang_cc1 -verify -std=c++20 -fsyntax-only %s
2+
3+
auto c1(auto f, auto ...fs) {
4+
constexpr bool a = true;
5+
return [](auto) requires a {
6+
constexpr bool b = true;
7+
return []() requires a && b {
8+
constexpr bool c = true;
9+
return [](auto) requires a && b && c {
10+
constexpr bool d = true;
11+
// expected-note@+2{{because substituted constraint expression is ill-formed: no matching function for call to 'c1'}}
12+
// expected-note@+1{{candidate function not viable: constraints not satisfied}}
13+
return []() requires a && b && c && d && (c1(fs...)) {};
14+
};
15+
}();
16+
}(1);
17+
}
18+
19+
void foo() {
20+
c1(true)(1.0)(); // expected-error{{no matching function for call to object of type}}
21+
}

llvm/include/llvm/Config/llvm-config.h.cmake

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616

1717
/* Indicate that this is LLVM compiled from the amd-gfx branch. */
1818
#define LLVM_HAVE_BRANCH_AMD_GFX
19-
#define LLVM_MAIN_REVISION 476721
19+
#define LLVM_MAIN_REVISION 476722
2020

2121
/* Define if LLVM_ENABLE_DUMP is enabled */
2222
#cmakedefine LLVM_ENABLE_DUMP

0 commit comments

Comments
 (0)