Skip to content

Commit 55ea360

Browse files
authored
[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.
1 parent b7cd564 commit 55ea360

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
@@ -8633,13 +8633,15 @@ ASTNodeImporter::VisitUnresolvedLookupExpr(UnresolvedLookupExpr *E) {
86338633
return UnresolvedLookupExpr::Create(
86348634
Importer.getToContext(), *ToNamingClassOrErr, *ToQualifierLocOrErr,
86358635
*ToTemplateKeywordLocOrErr, ToNameInfo, E->requiresADL(), &ToTAInfo,
8636-
ToDecls.begin(), ToDecls.end(), KnownDependent);
8636+
ToDecls.begin(), ToDecls.end(), KnownDependent,
8637+
/*KnownInstantiationDependent=*/E->isInstantiationDependent());
86378638
}
86388639

86398640
return UnresolvedLookupExpr::Create(
86408641
Importer.getToContext(), *ToNamingClassOrErr, *ToQualifierLocOrErr,
86418642
ToNameInfo, E->requiresADL(), ToDecls.begin(), ToDecls.end(),
8642-
/*KnownDependent=*/E->isTypeDependent());
8643+
/*KnownDependent=*/E->isTypeDependent(),
8644+
/*KnownInstantiationDependent=*/E->isInstantiationDependent());
86438645
}
86448646

86458647
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
@@ -838,7 +838,8 @@ ExprResult Sema::BuildOperatorCoawaitLookupExpr(Scope *S, SourceLocation Loc) {
838838
Expr *CoawaitOp = UnresolvedLookupExpr::Create(
839839
Context, /*NamingClass*/ nullptr, NestedNameSpecifierLoc(),
840840
DeclarationNameInfo(OpName, Loc), /*RequiresADL*/ true, Functions.begin(),
841-
Functions.end(), /*KnownDependent=*/false);
841+
Functions.end(), /*KnownDependent=*/false,
842+
/*KnownInstantiationDependent=*/false);
842843
assert(CoawaitOp);
843844
return CoawaitOp;
844845
}

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
@@ -17932,7 +17932,8 @@ buildDeclareReductionRef(Sema &SemaRef, SourceLocation Loc, SourceRange Range,
1793217932
return UnresolvedLookupExpr::Create(
1793317933
SemaRef.Context, /*NamingClass=*/nullptr,
1793417934
ReductionIdScopeSpec.getWithLocInContext(SemaRef.Context), ReductionId,
17935-
/*ADL=*/true, ResSet.begin(), ResSet.end(), /*KnownDependent=*/false);
17935+
/*ADL=*/true, ResSet.begin(), ResSet.end(), /*KnownDependent=*/false,
17936+
/*KnownInstantiationDependent=*/false);
1793617937
}
1793717938
// Lookup inside the classes.
1793817939
// C++ [over.match.oper]p3:
@@ -20798,7 +20799,8 @@ static ExprResult buildUserDefinedMapperRef(Sema &SemaRef, Scope *S,
2079820799
return UnresolvedLookupExpr::Create(
2079920800
SemaRef.Context, /*NamingClass=*/nullptr,
2080020801
MapperIdScopeSpec.getWithLocInContext(SemaRef.Context), MapperId,
20801-
/*ADL=*/false, URS.begin(), URS.end(), /*KnownDependent=*/false);
20802+
/*ADL=*/false, URS.begin(), URS.end(), /*KnownDependent=*/false,
20803+
/*KnownInstantiationDependent=*/false);
2080220804
}
2080320805
SourceLocation Loc = MapperId.getLoc();
2080420806
// [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
@@ -14093,9 +14093,9 @@ ExprResult Sema::CreateUnresolvedLookupExpr(CXXRecordDecl *NamingClass,
1409314093
DeclarationNameInfo DNI,
1409414094
const UnresolvedSetImpl &Fns,
1409514095
bool PerformADL) {
14096-
return UnresolvedLookupExpr::Create(Context, NamingClass, NNSLoc, DNI,
14097-
PerformADL, Fns.begin(), Fns.end(),
14098-
/*KnownDependent=*/false);
14096+
return UnresolvedLookupExpr::Create(
14097+
Context, NamingClass, NNSLoc, DNI, PerformADL, Fns.begin(), Fns.end(),
14098+
/*KnownDependent=*/false, /*KnownInstantiationDependent=*/false);
1409914099
}
1410014100

1410114101
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
@@ -10687,7 +10687,7 @@ TreeTransform<Derived>::TransformOMPReductionClause(OMPReductionClause *C) {
1068710687
SemaRef.Context, /*NamingClass=*/nullptr,
1068810688
ReductionIdScopeSpec.getWithLocInContext(SemaRef.Context), NameInfo,
1068910689
/*ADL=*/true, Decls.begin(), Decls.end(),
10690-
/*KnownDependent=*/false));
10690+
/*KnownDependent=*/false, /*KnownInstantiationDependent=*/false));
1069110691
} else
1069210692
UnresolvedReductions.push_back(nullptr);
1069310693
}
@@ -10734,7 +10734,7 @@ OMPClause *TreeTransform<Derived>::TransformOMPTaskReductionClause(
1073410734
SemaRef.Context, /*NamingClass=*/nullptr,
1073510735
ReductionIdScopeSpec.getWithLocInContext(SemaRef.Context), NameInfo,
1073610736
/*ADL=*/true, Decls.begin(), Decls.end(),
10737-
/*KnownDependent=*/false));
10737+
/*KnownDependent=*/false, /*KnownInstantiationDependent=*/false));
1073810738
} else
1073910739
UnresolvedReductions.push_back(nullptr);
1074010740
}
@@ -10780,7 +10780,7 @@ TreeTransform<Derived>::TransformOMPInReductionClause(OMPInReductionClause *C) {
1078010780
SemaRef.Context, /*NamingClass=*/nullptr,
1078110781
ReductionIdScopeSpec.getWithLocInContext(SemaRef.Context), NameInfo,
1078210782
/*ADL=*/true, Decls.begin(), Decls.end(),
10783-
/*KnownDependent=*/false));
10783+
/*KnownDependent=*/false, /*KnownInstantiationDependent=*/false));
1078410784
} else
1078510785
UnresolvedReductions.push_back(nullptr);
1078610786
}
@@ -10962,7 +10962,7 @@ bool transformOMPMappableExprListClause(
1096210962
TT.getSema().Context, /*NamingClass=*/nullptr,
1096310963
MapperIdScopeSpec.getWithLocInContext(TT.getSema().Context),
1096410964
MapperIdInfo, /*ADL=*/true, Decls.begin(), Decls.end(),
10965-
/*KnownDependent=*/false));
10965+
/*KnownDependent=*/false, /*KnownInstantiationDependent=*/false));
1096610966
} else {
1096710967
UnresolvedMappers.push_back(nullptr);
1096810968
}

clang/test/SemaCXX/decltype.cpp

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,31 @@ namespace GH97646 {
147147
}
148148
}
149149

150+
namespace GH99873 {
151+
struct B {
152+
int x;
153+
};
154+
155+
template<typename T>
156+
struct A {
157+
template<typename U>
158+
constexpr int f() const {
159+
return 1;
160+
}
161+
162+
template<>
163+
constexpr int f<int>() const {
164+
return decltype(B::x)();
165+
}
166+
};
167+
168+
// This shouldn't crash.
169+
static_assert(A<int>().f<int>() == 0, "");
170+
// The result should not be dependent.
171+
static_assert(A<int>().f<int>() != 0, ""); // expected-error {{static assertion failed due to requirement 'GH99873::A<int>().f<int>() != 0'}}
172+
// expected-note@-1 {{expression evaluates to '0 != 0'}}
173+
}
174+
150175
template<typename>
151176
class conditional {
152177
};

0 commit comments

Comments
 (0)