Skip to content

Commit c7377a3

Browse files
sdkrystiannga888
authored andcommitted
[Clang][Sema] Make UnresolvedLookupExprs in class scope explicit specializations instantiation dependent (#100392)
A class member named by an expression in a member function that may instantiate to a static _or_ non-static member is represented by a `UnresolvedLookupExpr` in order to defer the implicit transformation to a class member access expression until instantiation. Since `ASTContext::getDecltypeType` only creates a `DecltypeType` that has a `DependentDecltypeType` as its canonical type when the operand is instantiation dependent, and since we do not transform types unless they are instantiation dependent, we need to mark the `UnresolvedLookupExpr` as instantiation dependent in order to correctly build a `DecltypeType` using the expression as its operand with a `DependentDecltypeType` canonical type. Fixes #99873. (cherry picked from commit 55ea360)
1 parent d033ae1 commit c7377a3

File tree

13 files changed

+64
-28
lines changed

13 files changed

+64
-28
lines changed

clang/include/clang/AST/ExprCXX.h

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3229,7 +3229,7 @@ class UnresolvedLookupExpr final
32293229
const DeclarationNameInfo &NameInfo, bool RequiresADL,
32303230
const TemplateArgumentListInfo *TemplateArgs,
32313231
UnresolvedSetIterator Begin, UnresolvedSetIterator End,
3232-
bool KnownDependent);
3232+
bool KnownDependent, bool KnownInstantiationDependent);
32333233

32343234
UnresolvedLookupExpr(EmptyShell Empty, unsigned NumResults,
32353235
bool HasTemplateKWAndArgsInfo);
@@ -3248,7 +3248,7 @@ class UnresolvedLookupExpr final
32483248
NestedNameSpecifierLoc QualifierLoc,
32493249
const DeclarationNameInfo &NameInfo, bool RequiresADL,
32503250
UnresolvedSetIterator Begin, UnresolvedSetIterator End,
3251-
bool KnownDependent);
3251+
bool KnownDependent, bool KnownInstantiationDependent);
32523252

32533253
// After canonicalization, there may be dependent template arguments in
32543254
// CanonicalConverted But none of Args is dependent. When any of
@@ -3258,7 +3258,8 @@ class UnresolvedLookupExpr final
32583258
NestedNameSpecifierLoc QualifierLoc, SourceLocation TemplateKWLoc,
32593259
const DeclarationNameInfo &NameInfo, bool RequiresADL,
32603260
const TemplateArgumentListInfo *Args, UnresolvedSetIterator Begin,
3261-
UnresolvedSetIterator End, bool KnownDependent);
3261+
UnresolvedSetIterator End, bool KnownDependent,
3262+
bool KnownInstantiationDependent);
32623263

32633264
static UnresolvedLookupExpr *CreateEmpty(const ASTContext &Context,
32643265
unsigned NumResults,

clang/lib/AST/ASTImporter.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8578,13 +8578,15 @@ ASTNodeImporter::VisitUnresolvedLookupExpr(UnresolvedLookupExpr *E) {
85788578
return UnresolvedLookupExpr::Create(
85798579
Importer.getToContext(), *ToNamingClassOrErr, *ToQualifierLocOrErr,
85808580
*ToTemplateKeywordLocOrErr, ToNameInfo, E->requiresADL(), &ToTAInfo,
8581-
ToDecls.begin(), ToDecls.end(), KnownDependent);
8581+
ToDecls.begin(), ToDecls.end(), KnownDependent,
8582+
/*KnownInstantiationDependent=*/E->isInstantiationDependent());
85828583
}
85838584

85848585
return UnresolvedLookupExpr::Create(
85858586
Importer.getToContext(), *ToNamingClassOrErr, *ToQualifierLocOrErr,
85868587
ToNameInfo, E->requiresADL(), ToDecls.begin(), ToDecls.end(),
8587-
/*KnownDependent=*/E->isTypeDependent());
8588+
/*KnownDependent=*/E->isTypeDependent(),
8589+
/*KnownInstantiationDependent=*/E->isInstantiationDependent());
85888590
}
85898591

85908592
ExpectedStmt

clang/lib/AST/ExprCXX.cpp

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -402,10 +402,11 @@ UnresolvedLookupExpr::UnresolvedLookupExpr(
402402
NestedNameSpecifierLoc QualifierLoc, SourceLocation TemplateKWLoc,
403403
const DeclarationNameInfo &NameInfo, bool RequiresADL,
404404
const TemplateArgumentListInfo *TemplateArgs, UnresolvedSetIterator Begin,
405-
UnresolvedSetIterator End, bool KnownDependent)
405+
UnresolvedSetIterator End, bool KnownDependent,
406+
bool KnownInstantiationDependent)
406407
: OverloadExpr(UnresolvedLookupExprClass, Context, QualifierLoc,
407408
TemplateKWLoc, NameInfo, TemplateArgs, Begin, End,
408-
KnownDependent, false, false),
409+
KnownDependent, KnownInstantiationDependent, false),
409410
NamingClass(NamingClass) {
410411
UnresolvedLookupExprBits.RequiresADL = RequiresADL;
411412
}
@@ -420,33 +421,35 @@ UnresolvedLookupExpr *UnresolvedLookupExpr::Create(
420421
const ASTContext &Context, CXXRecordDecl *NamingClass,
421422
NestedNameSpecifierLoc QualifierLoc, const DeclarationNameInfo &NameInfo,
422423
bool RequiresADL, UnresolvedSetIterator Begin, UnresolvedSetIterator End,
423-
bool KnownDependent) {
424+
bool KnownDependent, bool KnownInstantiationDependent) {
424425
unsigned NumResults = End - Begin;
425426
unsigned Size = totalSizeToAlloc<DeclAccessPair, ASTTemplateKWAndArgsInfo,
426427
TemplateArgumentLoc>(NumResults, 0, 0);
427428
void *Mem = Context.Allocate(Size, alignof(UnresolvedLookupExpr));
428429
return new (Mem) UnresolvedLookupExpr(
429430
Context, NamingClass, QualifierLoc,
430431
/*TemplateKWLoc=*/SourceLocation(), NameInfo, RequiresADL,
431-
/*TemplateArgs=*/nullptr, Begin, End, KnownDependent);
432+
/*TemplateArgs=*/nullptr, Begin, End, KnownDependent,
433+
KnownInstantiationDependent);
432434
}
433435

434436
UnresolvedLookupExpr *UnresolvedLookupExpr::Create(
435437
const ASTContext &Context, CXXRecordDecl *NamingClass,
436438
NestedNameSpecifierLoc QualifierLoc, SourceLocation TemplateKWLoc,
437439
const DeclarationNameInfo &NameInfo, bool RequiresADL,
438440
const TemplateArgumentListInfo *Args, UnresolvedSetIterator Begin,
439-
UnresolvedSetIterator End, bool KnownDependent) {
441+
UnresolvedSetIterator End, bool KnownDependent,
442+
bool KnownInstantiationDependent) {
440443
unsigned NumResults = End - Begin;
441444
bool HasTemplateKWAndArgsInfo = Args || TemplateKWLoc.isValid();
442445
unsigned NumTemplateArgs = Args ? Args->size() : 0;
443446
unsigned Size = totalSizeToAlloc<DeclAccessPair, ASTTemplateKWAndArgsInfo,
444447
TemplateArgumentLoc>(
445448
NumResults, HasTemplateKWAndArgsInfo, NumTemplateArgs);
446449
void *Mem = Context.Allocate(Size, alignof(UnresolvedLookupExpr));
447-
return new (Mem) UnresolvedLookupExpr(Context, NamingClass, QualifierLoc,
448-
TemplateKWLoc, NameInfo, RequiresADL,
449-
Args, Begin, End, KnownDependent);
450+
return new (Mem) UnresolvedLookupExpr(
451+
Context, NamingClass, QualifierLoc, TemplateKWLoc, NameInfo, RequiresADL,
452+
Args, Begin, End, KnownDependent, KnownInstantiationDependent);
450453
}
451454

452455
UnresolvedLookupExpr *UnresolvedLookupExpr::CreateEmpty(

clang/lib/Sema/SemaCoroutine.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -820,7 +820,8 @@ ExprResult Sema::BuildOperatorCoawaitLookupExpr(Scope *S, SourceLocation Loc) {
820820
Expr *CoawaitOp = UnresolvedLookupExpr::Create(
821821
Context, /*NamingClass*/ nullptr, NestedNameSpecifierLoc(),
822822
DeclarationNameInfo(OpName, Loc), /*RequiresADL*/ true, Functions.begin(),
823-
Functions.end(), /*KnownDependent=*/false);
823+
Functions.end(), /*KnownDependent=*/false,
824+
/*KnownInstantiationDependent=*/false);
824825
assert(CoawaitOp);
825826
return CoawaitOp;
826827
}

clang/lib/Sema/SemaDecl.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1219,7 +1219,7 @@ Sema::NameClassification Sema::ClassifyName(Scope *S, CXXScopeSpec &SS,
12191219
return NameClassification::OverloadSet(UnresolvedLookupExpr::Create(
12201220
Context, Result.getNamingClass(), SS.getWithLocInContext(Context),
12211221
Result.getLookupNameInfo(), ADL, Result.begin(), Result.end(),
1222-
/*KnownDependent=*/false));
1222+
/*KnownDependent=*/false, /*KnownInstantiationDependent=*/false));
12231223
}
12241224

12251225
ExprResult

clang/lib/Sema/SemaDeclCXX.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1289,7 +1289,7 @@ static bool checkTupleLikeDecomposition(Sema &S,
12891289
S.Context, nullptr, NestedNameSpecifierLoc(), SourceLocation(),
12901290
DeclarationNameInfo(GetDN, Loc), /*RequiresADL=*/true, &Args,
12911291
UnresolvedSetIterator(), UnresolvedSetIterator(),
1292-
/*KnownDependent=*/false);
1292+
/*KnownDependent=*/false, /*KnownInstantiationDependent=*/false);
12931293

12941294
Expr *Arg = E.get();
12951295
E = S.BuildCallExpr(nullptr, Get, Loc, Arg, Loc);

clang/lib/Sema/SemaExpr.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3188,7 +3188,7 @@ ExprResult Sema::BuildDeclarationNameExpr(const CXXScopeSpec &SS,
31883188
UnresolvedLookupExpr *ULE = UnresolvedLookupExpr::Create(
31893189
Context, R.getNamingClass(), SS.getWithLocInContext(Context),
31903190
R.getLookupNameInfo(), NeedsADL, R.begin(), R.end(),
3191-
/*KnownDependent=*/false);
3191+
/*KnownDependent=*/false, /*KnownInstantiationDependent=*/false);
31923192

31933193
return ULE;
31943194
}

clang/lib/Sema/SemaExprMember.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -331,7 +331,8 @@ ExprResult Sema::BuildPossibleImplicitMemberExpr(
331331
return UnresolvedLookupExpr::Create(
332332
Context, R.getNamingClass(), SS.getWithLocInContext(Context),
333333
TemplateKWLoc, R.getLookupNameInfo(), /*RequiresADL=*/false,
334-
TemplateArgs, R.begin(), R.end(), /*KnownDependent=*/true);
334+
TemplateArgs, R.begin(), R.end(), /*KnownDependent=*/true,
335+
/*KnownInstantiationDependent=*/true);
335336

336337
case IMA_Error_StaticOrExplicitContext:
337338
case IMA_Error_Unrelated:

clang/lib/Sema/SemaOpenMP.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17968,7 +17968,8 @@ buildDeclareReductionRef(Sema &SemaRef, SourceLocation Loc, SourceRange Range,
1796817968
return UnresolvedLookupExpr::Create(
1796917969
SemaRef.Context, /*NamingClass=*/nullptr,
1797017970
ReductionIdScopeSpec.getWithLocInContext(SemaRef.Context), ReductionId,
17971-
/*ADL=*/true, ResSet.begin(), ResSet.end(), /*KnownDependent=*/false);
17971+
/*ADL=*/true, ResSet.begin(), ResSet.end(), /*KnownDependent=*/false,
17972+
/*KnownInstantiationDependent=*/false);
1797217973
}
1797317974
// Lookup inside the classes.
1797417975
// C++ [over.match.oper]p3:
@@ -20834,7 +20835,8 @@ static ExprResult buildUserDefinedMapperRef(Sema &SemaRef, Scope *S,
2083420835
return UnresolvedLookupExpr::Create(
2083520836
SemaRef.Context, /*NamingClass=*/nullptr,
2083620837
MapperIdScopeSpec.getWithLocInContext(SemaRef.Context), MapperId,
20837-
/*ADL=*/false, URS.begin(), URS.end(), /*KnownDependent=*/false);
20838+
/*ADL=*/false, URS.begin(), URS.end(), /*KnownDependent=*/false,
20839+
/*KnownInstantiationDependent=*/false);
2083820840
}
2083920841
SourceLocation Loc = MapperId.getLoc();
2084020842
// [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions

clang/lib/Sema/SemaOverload.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14083,9 +14083,9 @@ ExprResult Sema::CreateUnresolvedLookupExpr(CXXRecordDecl *NamingClass,
1408314083
DeclarationNameInfo DNI,
1408414084
const UnresolvedSetImpl &Fns,
1408514085
bool PerformADL) {
14086-
return UnresolvedLookupExpr::Create(Context, NamingClass, NNSLoc, DNI,
14087-
PerformADL, Fns.begin(), Fns.end(),
14088-
/*KnownDependent=*/false);
14086+
return UnresolvedLookupExpr::Create(
14087+
Context, NamingClass, NNSLoc, DNI, PerformADL, Fns.begin(), Fns.end(),
14088+
/*KnownDependent=*/false, /*KnownInstantiationDependent=*/false);
1408914089
}
1409014090

1409114091
ExprResult Sema::BuildCXXMemberCallExpr(Expr *E, NamedDecl *FoundDecl,

clang/lib/Sema/SemaTemplate.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4436,7 +4436,8 @@ ExprResult Sema::BuildTemplateIdExpr(const CXXScopeSpec &SS,
44364436
UnresolvedLookupExpr *ULE = UnresolvedLookupExpr::Create(
44374437
Context, R.getNamingClass(), SS.getWithLocInContext(Context),
44384438
TemplateKWLoc, R.getLookupNameInfo(), RequiresADL, TemplateArgs,
4439-
R.begin(), R.end(), KnownDependent);
4439+
R.begin(), R.end(), KnownDependent,
4440+
/*KnownInstantiationDependent=*/false);
44404441

44414442
// Model the templates with UnresolvedTemplateTy. The expression should then
44424443
// either be transformed in an instantiation or be diagnosed in

clang/lib/Sema/TreeTransform.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10541,7 +10541,7 @@ TreeTransform<Derived>::TransformOMPReductionClause(OMPReductionClause *C) {
1054110541
SemaRef.Context, /*NamingClass=*/nullptr,
1054210542
ReductionIdScopeSpec.getWithLocInContext(SemaRef.Context), NameInfo,
1054310543
/*ADL=*/true, Decls.begin(), Decls.end(),
10544-
/*KnownDependent=*/false));
10544+
/*KnownDependent=*/false, /*KnownInstantiationDependent=*/false));
1054510545
} else
1054610546
UnresolvedReductions.push_back(nullptr);
1054710547
}
@@ -10588,7 +10588,7 @@ OMPClause *TreeTransform<Derived>::TransformOMPTaskReductionClause(
1058810588
SemaRef.Context, /*NamingClass=*/nullptr,
1058910589
ReductionIdScopeSpec.getWithLocInContext(SemaRef.Context), NameInfo,
1059010590
/*ADL=*/true, Decls.begin(), Decls.end(),
10591-
/*KnownDependent=*/false));
10591+
/*KnownDependent=*/false, /*KnownInstantiationDependent=*/false));
1059210592
} else
1059310593
UnresolvedReductions.push_back(nullptr);
1059410594
}
@@ -10634,7 +10634,7 @@ TreeTransform<Derived>::TransformOMPInReductionClause(OMPInReductionClause *C) {
1063410634
SemaRef.Context, /*NamingClass=*/nullptr,
1063510635
ReductionIdScopeSpec.getWithLocInContext(SemaRef.Context), NameInfo,
1063610636
/*ADL=*/true, Decls.begin(), Decls.end(),
10637-
/*KnownDependent=*/false));
10637+
/*KnownDependent=*/false, /*KnownInstantiationDependent=*/false));
1063810638
} else
1063910639
UnresolvedReductions.push_back(nullptr);
1064010640
}
@@ -10816,7 +10816,7 @@ bool transformOMPMappableExprListClause(
1081610816
TT.getSema().Context, /*NamingClass=*/nullptr,
1081710817
MapperIdScopeSpec.getWithLocInContext(TT.getSema().Context),
1081810818
MapperIdInfo, /*ADL=*/true, Decls.begin(), Decls.end(),
10819-
/*KnownDependent=*/false));
10819+
/*KnownDependent=*/false, /*KnownInstantiationDependent=*/false));
1082010820
} else {
1082110821
UnresolvedMappers.push_back(nullptr);
1082210822
}

clang/test/SemaCXX/decltype.cpp

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,31 @@ namespace GH58674 {
139139
}
140140
}
141141

142+
namespace GH99873 {
143+
struct B {
144+
int x;
145+
};
146+
147+
template<typename T>
148+
struct A {
149+
template<typename U>
150+
constexpr int f() const {
151+
return 1;
152+
}
153+
154+
template<>
155+
constexpr int f<int>() const {
156+
return decltype(B::x)();
157+
}
158+
};
159+
160+
// This shouldn't crash.
161+
static_assert(A<int>().f<int>() == 0, "");
162+
// The result should not be dependent.
163+
static_assert(A<int>().f<int>() != 0, ""); // expected-error {{static assertion failed due to requirement 'GH99873::A<int>().f<int>() != 0'}}
164+
// expected-note@-1 {{expression evaluates to '0 != 0'}}
165+
}
166+
142167
template<typename>
143168
class conditional {
144169
};

0 commit comments

Comments
 (0)