Skip to content

Commit

Permalink
[Clang][Sema] Partially revert changes to operator= from llvm#90152
Browse files Browse the repository at this point in the history
  • Loading branch information
sdkrystian committed May 9, 2024
1 parent eb65b73 commit d853c33
Show file tree
Hide file tree
Showing 4 changed files with 40 additions and 20 deletions.
5 changes: 4 additions & 1 deletion clang/lib/Sema/SemaExprMember.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -996,7 +996,10 @@ Sema::BuildMemberReferenceExpr(Expr *BaseExpr, QualType BaseExprType,
// build a CXXDependentScopeMemberExpr.
if (R.wasNotFoundInCurrentInstantiation() ||
(IsArrow && !BaseExprType->isPointerType() &&
BaseExprType->isDependentType()))
BaseExprType->isDependentType()) ||
(R.getLookupName().getCXXOverloadedOperator() == OO_Equal &&
(SS.isSet() ? SS.getScopeRep()->isDependent()
: BaseExprType->isDependentType())))
return ActOnDependentMemberExpr(BaseExpr, BaseExprType, IsArrow, OpLoc, SS,
TemplateKWLoc, FirstQualifierInScope,
R.getLookupNameInfo(), TemplateArgs);
Expand Down
21 changes: 3 additions & 18 deletions clang/lib/Sema/SemaLookup.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1282,6 +1282,7 @@ bool Sema::CppLookupName(LookupResult &R, Scope *S) {
if (DeclContext *DC = PreS->getEntity())
DeclareImplicitMemberFunctionsWithName(*this, Name, R.getNameLoc(), DC);
}

// C++23 [temp.dep.general]p2:
// The component name of an unqualified-id is dependent if
// - it is a conversion-function-id whose conversion-type-id
Expand All @@ -1294,20 +1295,6 @@ bool Sema::CppLookupName(LookupResult &R, Scope *S) {
return false;
}

// If this is the name of an implicitly-declared special member function,
// go through the scope stack to implicitly declare
if (isImplicitlyDeclaredMemberFunctionName(Name)) {
for (Scope *PreS = S; PreS; PreS = PreS->getParent())
if (DeclContext *DC = PreS->getEntity()) {
if (DC->isDependentContext() && isa<CXXRecordDecl>(DC) &&
Name.getCXXOverloadedOperator() == OO_Equal) {
R.setNotFoundInCurrentInstantiation();
return false;
}
DeclareImplicitMemberFunctionsWithName(*this, Name, R.getNameLoc(), DC);
}
}

// Implicitly declare member functions with the name we're looking for, if in
// fact we are in a scope where it matters.

Expand Down Expand Up @@ -2485,10 +2472,8 @@ bool Sema::LookupQualifiedName(LookupResult &R, DeclContext *LookupCtx,
// is operator=, or
// - [...]
if (DeclarationName Name = R.getLookupName();
(Name.getNameKind() == DeclarationName::CXXConversionFunctionName &&
Name.getCXXNameType()->isDependentType()) ||
(Name.getCXXOverloadedOperator() == OO_Equal && LookupRec &&
LookupRec->isDependentContext())) {
Name.getNameKind() == DeclarationName::CXXConversionFunctionName &&
Name.getCXXNameType()->isDependentType()) {
R.setNotFoundInCurrentInstantiation();
return false;
}
Expand Down
3 changes: 2 additions & 1 deletion clang/lib/Sema/SemaTemplate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -750,7 +750,8 @@ Sema::ActOnDependentIdExpression(const CXXScopeSpec &SS,
if (!MightBeCxx11UnevalField && !isAddressOfOperand && !IsEnum &&
isa<CXXMethodDecl>(DC) &&
cast<CXXMethodDecl>(DC)->isImplicitObjectMemberFunction()) {
QualType ThisType = cast<CXXMethodDecl>(DC)->getThisType().getNonReferenceType();
QualType ThisType =
cast<CXXMethodDecl>(DC)->getThisType().getNonReferenceType();

// Since the 'this' expression is synthesized, we don't need to
// perform the double-lookup check.
Expand Down
31 changes: 31 additions & 0 deletions clang/test/CXX/temp/temp.res/temp.dep/temp.dep.type/p4.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -453,6 +453,36 @@ namespace N3 {
this->A::operator=(*this);
}
};

template<typename T>
struct C {
template<typename U>
void operator=(int);

void not_instantiated() {
operator=<int>(0);
C::operator=<int>(0);
this->operator=<int>(0);
this->C::operator=<int>(0);

operator=(*this);
C::operator=(*this);
this->operator=(*this);
this->C::operator=(*this);
}
};

template<typename T>
struct D {
auto not_instantiated() -> decltype(operator=(0)); // expected-error {{use of undeclared 'operator='}}
};

template<typename T>
struct E {
auto instantiated(E& e) -> decltype(operator=(e)); // expected-error {{use of undeclared 'operator='}}
};

template struct E<int>; // expected-note {{in instantiation of template class 'N3::E<int>' requested here}}
} // namespace N3

namespace N4 {
Expand Down Expand Up @@ -520,4 +550,5 @@ namespace N4 {
};

template void D<B>::instantiated(D); // expected-note {{in instantiation of}}

} // namespace N4

0 comments on commit d853c33

Please sign in to comment.