Skip to content

Commit 7b2f3da

Browse files
committed
Revert "[Clang][Sema] Fix lookup of dependent operator= outside of complete-class contexts (llvm#91498)"
This reverts commit 62b5b61.
1 parent 1494d88 commit 7b2f3da

File tree

3 files changed

+20
-35
lines changed

3 files changed

+20
-35
lines changed

clang/lib/Sema/SemaLookup.cpp

Lines changed: 15 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1267,20 +1267,6 @@ struct FindLocalExternScope {
12671267
LookupResult &R;
12681268
bool OldFindLocalExtern;
12691269
};
1270-
1271-
/// Returns true if 'operator=' should be treated as a dependent name.
1272-
bool isDependentAssignmentOperator(DeclarationName Name,
1273-
DeclContext *LookupContext) {
1274-
const auto *LookupRecord = dyn_cast_if_present<CXXRecordDecl>(LookupContext);
1275-
// If the lookup context is the current instantiation but we are outside a
1276-
// complete-class context, we will never find the implicitly declared
1277-
// copy/move assignment operators because they are declared at the closing '}'
1278-
// of the class specifier. In such cases, we treat 'operator=' like any other
1279-
// unqualified name because the results of name lookup in the template
1280-
// definition/instantiation context will always be the same.
1281-
return Name.getCXXOverloadedOperator() == OO_Equal && LookupRecord &&
1282-
!LookupRecord->isBeingDefined() && LookupRecord->isDependentContext();
1283-
}
12841270
} // end anonymous namespace
12851271

12861272
bool Sema::CppLookupName(LookupResult &R, Scope *S) {
@@ -1289,6 +1275,13 @@ bool Sema::CppLookupName(LookupResult &R, Scope *S) {
12891275
DeclarationName Name = R.getLookupName();
12901276
Sema::LookupNameKind NameKind = R.getLookupKind();
12911277

1278+
// If this is the name of an implicitly-declared special member function,
1279+
// go through the scope stack to implicitly declare
1280+
if (isImplicitlyDeclaredMemberFunctionName(Name)) {
1281+
for (Scope *PreS = S; PreS; PreS = PreS->getParent())
1282+
if (DeclContext *DC = PreS->getEntity())
1283+
DeclareImplicitMemberFunctionsWithName(*this, Name, R.getNameLoc(), DC);
1284+
}
12921285
// C++23 [temp.dep.general]p2:
12931286
// The component name of an unqualified-id is dependent if
12941287
// - it is a conversion-function-id whose conversion-type-id
@@ -1306,8 +1299,9 @@ bool Sema::CppLookupName(LookupResult &R, Scope *S) {
13061299
if (isImplicitlyDeclaredMemberFunctionName(Name)) {
13071300
for (Scope *PreS = S; PreS; PreS = PreS->getParent())
13081301
if (DeclContext *DC = PreS->getEntity()) {
1309-
if (!R.isTemplateNameLookup() &&
1310-
isDependentAssignmentOperator(Name, DC)) {
1302+
if (DC->isDependentContext() && isa<CXXRecordDecl>(DC) &&
1303+
Name.getCXXOverloadedOperator() == OO_Equal &&
1304+
!R.isTemplateNameLookup()) {
13111305
R.setNotFoundInCurrentInstantiation();
13121306
return false;
13131307
}
@@ -2478,6 +2472,8 @@ bool Sema::LookupQualifiedName(LookupResult &R, DeclContext *LookupCtx,
24782472
}
24792473
} QL(LookupCtx);
24802474

2475+
bool TemplateNameLookup = R.isTemplateNameLookup();
2476+
CXXRecordDecl *LookupRec = dyn_cast<CXXRecordDecl>(LookupCtx);
24812477
if (!InUnqualifiedLookup && !R.isForRedeclaration()) {
24822478
// C++23 [temp.dep.type]p5:
24832479
// A qualified name is dependent if
@@ -2490,14 +2486,13 @@ bool Sema::LookupQualifiedName(LookupResult &R, DeclContext *LookupCtx,
24902486
if (DeclarationName Name = R.getLookupName();
24912487
(Name.getNameKind() == DeclarationName::CXXConversionFunctionName &&
24922488
Name.getCXXNameType()->isDependentType()) ||
2493-
(!R.isTemplateNameLookup() &&
2494-
isDependentAssignmentOperator(Name, LookupCtx))) {
2489+
(Name.getCXXOverloadedOperator() == OO_Equal && LookupRec &&
2490+
LookupRec->isDependentContext() && !TemplateNameLookup)) {
24952491
R.setNotFoundInCurrentInstantiation();
24962492
return false;
24972493
}
24982494
}
24992495

2500-
CXXRecordDecl *LookupRec = dyn_cast<CXXRecordDecl>(LookupCtx);
25012496
if (LookupDirect(*this, R, LookupCtx)) {
25022497
R.resolveKind();
25032498
if (LookupRec)
@@ -2609,7 +2604,7 @@ bool Sema::LookupQualifiedName(LookupResult &R, DeclContext *LookupCtx,
26092604
// template, and if the name is used as a template-name, the
26102605
// reference refers to the class template itself and not a
26112606
// specialization thereof, and is not ambiguous.
2612-
if (R.isTemplateNameLookup())
2607+
if (TemplateNameLookup)
26132608
if (auto *TD = getAsTemplateNameDecl(ND))
26142609
ND = TD;
26152610

clang/lib/Sema/SemaTemplate.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -726,7 +726,7 @@ Sema::ActOnDependentIdExpression(const CXXScopeSpec &SS,
726726
const DeclarationNameInfo &NameInfo,
727727
bool isAddressOfOperand,
728728
const TemplateArgumentListInfo *TemplateArgs) {
729-
QualType ThisType = getCurrentThisType();
729+
DeclContext *DC = getFunctionLevelDeclContext();
730730

731731
// C++11 [expr.prim.general]p12:
732732
// An id-expression that denotes a non-static data member or non-static
@@ -748,7 +748,10 @@ Sema::ActOnDependentIdExpression(const CXXScopeSpec &SS,
748748
IsEnum = isa_and_nonnull<EnumType>(NNS->getAsType());
749749

750750
if (!MightBeCxx11UnevalField && !isAddressOfOperand && !IsEnum &&
751-
!ThisType.isNull()) {
751+
isa<CXXMethodDecl>(DC) &&
752+
cast<CXXMethodDecl>(DC)->isImplicitObjectMemberFunction()) {
753+
QualType ThisType = cast<CXXMethodDecl>(DC)->getThisType().getNonReferenceType();
754+
752755
// Since the 'this' expression is synthesized, we don't need to
753756
// perform the double-lookup check.
754757
NamedDecl *FirstQualifierInScope = nullptr;

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

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -471,19 +471,6 @@ namespace N3 {
471471
this->C::operator=(*this);
472472
}
473473
};
474-
475-
template<typename T>
476-
struct D {
477-
auto not_instantiated() -> decltype(operator=(0)); // expected-error {{use of undeclared 'operator='}}
478-
};
479-
480-
template<typename T>
481-
struct E {
482-
auto instantiated(E& e) -> decltype(operator=(e)); // expected-error {{use of undeclared 'operator='}}
483-
};
484-
485-
template struct E<int>; // expected-note {{in instantiation of template class 'N3::E<int>' requested here}}
486-
487474
} // namespace N3
488475

489476
namespace N4 {

0 commit comments

Comments
 (0)