Skip to content

Commit 3191e0b

Browse files
authored
[Clang][Sema] Fix template name lookup for operator= (llvm#90999)
This fixes a bug in llvm#90152 where `operator=` was never looked up in the current instantiation, resulting in `<` never being interpreted as the start of a template argument list. Since function templates are not copy/move assignment operators, the fix is accomplished by allowing lookup in the current instantiation for `operator=` when looking up a template name.
1 parent 0397226 commit 3191e0b

File tree

2 files changed

+22
-7
lines changed

2 files changed

+22
-7
lines changed

clang/lib/Sema/SemaLookup.cpp

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1300,7 +1300,8 @@ bool Sema::CppLookupName(LookupResult &R, Scope *S) {
13001300
for (Scope *PreS = S; PreS; PreS = PreS->getParent())
13011301
if (DeclContext *DC = PreS->getEntity()) {
13021302
if (DC->isDependentContext() && isa<CXXRecordDecl>(DC) &&
1303-
Name.getCXXOverloadedOperator() == OO_Equal) {
1303+
Name.getCXXOverloadedOperator() == OO_Equal &&
1304+
!R.isTemplateNameLookup()) {
13041305
R.setNotFoundInCurrentInstantiation();
13051306
return false;
13061307
}
@@ -2471,10 +2472,8 @@ bool Sema::LookupQualifiedName(LookupResult &R, DeclContext *LookupCtx,
24712472
}
24722473
} QL(LookupCtx);
24732474

2475+
bool TemplateNameLookup = R.isTemplateNameLookup();
24742476
CXXRecordDecl *LookupRec = dyn_cast<CXXRecordDecl>(LookupCtx);
2475-
// FIXME: Per [temp.dep.general]p2, an unqualified name is also dependent
2476-
// if it's a dependent conversion-function-id or operator= where the current
2477-
// class is a templated entity. This should be handled in LookupName.
24782477
if (!InUnqualifiedLookup && !R.isForRedeclaration()) {
24792478
// C++23 [temp.dep.type]p5:
24802479
// A qualified name is dependent if
@@ -2488,7 +2487,7 @@ bool Sema::LookupQualifiedName(LookupResult &R, DeclContext *LookupCtx,
24882487
(Name.getNameKind() == DeclarationName::CXXConversionFunctionName &&
24892488
Name.getCXXNameType()->isDependentType()) ||
24902489
(Name.getCXXOverloadedOperator() == OO_Equal && LookupRec &&
2491-
LookupRec->isDependentContext())) {
2490+
LookupRec->isDependentContext() && !TemplateNameLookup)) {
24922491
R.setNotFoundInCurrentInstantiation();
24932492
return false;
24942493
}
@@ -2584,8 +2583,6 @@ bool Sema::LookupQualifiedName(LookupResult &R, DeclContext *LookupCtx,
25842583
return true;
25852584
};
25862585

2587-
bool TemplateNameLookup = R.isTemplateNameLookup();
2588-
25892586
// Determine whether two sets of members contain the same members, as
25902587
// required by C++ [class.member.lookup]p6.
25912588
auto HasSameDeclarations = [&](DeclContext::lookup_iterator A,

clang/test/CXX/temp/temp.res/temp.dep/temp.dep.type/p4.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -453,6 +453,24 @@ namespace N3 {
453453
this->A::operator=(*this);
454454
}
455455
};
456+
457+
template<typename T>
458+
struct C {
459+
template<typename U>
460+
void operator=(int);
461+
462+
void not_instantiated() {
463+
operator=<int>(0);
464+
C::operator=<int>(0);
465+
this->operator=<int>(0);
466+
this->C::operator=<int>(0);
467+
468+
operator=(*this);
469+
C::operator=(*this);
470+
this->operator=(*this);
471+
this->C::operator=(*this);
472+
}
473+
};
456474
} // namespace N3
457475

458476
namespace N4 {

0 commit comments

Comments
 (0)