[clang] 75ebcbf - [Clang][Sema] Revert changes to operator= lookup in templated classes from #91498, #90999, and #90152 (#91620)

via cfe-commits cfe-commits at lists.llvm.org
Thu May 9 13:34:45 PDT 2024


Author: Krystian Stasiowski
Date: 2024-05-09T16:34:40-04:00
New Revision: 75ebcbf24abb2e5b045ec920bc86f667516e4cc6

URL: https://github.com/llvm/llvm-project/commit/75ebcbf24abb2e5b045ec920bc86f667516e4cc6
DIFF: https://github.com/llvm/llvm-project/commit/75ebcbf24abb2e5b045ec920bc86f667516e4cc6.diff

LOG: [Clang][Sema] Revert changes to operator= lookup in templated classes from #91498, #90999, and #90152 (#91620)

This reverts changes in #91498, #90999, and #90152 which make
`operator=` dependent whenever the current class is templated.

Added: 
    

Modified: 
    clang/lib/Sema/SemaExprMember.cpp
    clang/lib/Sema/SemaLookup.cpp
    clang/lib/Sema/SemaTemplate.cpp
    clang/test/CXX/temp/temp.res/temp.dep/temp.dep.type/p4.cpp

Removed: 
    


################################################################################
diff  --git a/clang/lib/Sema/SemaExprMember.cpp b/clang/lib/Sema/SemaExprMember.cpp
index 5facb14a18b7c..9fa69da4f9685 100644
--- a/clang/lib/Sema/SemaExprMember.cpp
+++ b/clang/lib/Sema/SemaExprMember.cpp
@@ -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);

diff  --git a/clang/lib/Sema/SemaLookup.cpp b/clang/lib/Sema/SemaLookup.cpp
index e20de338ebb16..7251aabc6af21 100644
--- a/clang/lib/Sema/SemaLookup.cpp
+++ b/clang/lib/Sema/SemaLookup.cpp
@@ -1267,20 +1267,6 @@ struct FindLocalExternScope {
   LookupResult &R;
   bool OldFindLocalExtern;
 };
-
-/// Returns true if 'operator=' should be treated as a dependent name.
-bool isDependentAssignmentOperator(DeclarationName Name,
-                                   DeclContext *LookupContext) {
-  const auto *LookupRecord = dyn_cast_if_present<CXXRecordDecl>(LookupContext);
-  // If the lookup context is the current instantiation but we are outside a
-  // complete-class context, we will never find the implicitly declared
-  // copy/move assignment operators because they are declared at the closing '}'
-  // of the class specifier. In such cases, we treat 'operator=' like any other
-  // unqualified name because the results of name lookup in the template
-  // definition/instantiation context will always be the same.
-  return Name.getCXXOverloadedOperator() == OO_Equal && LookupRecord &&
-         !LookupRecord->isBeingDefined() && LookupRecord->isDependentContext();
-}
 } // end anonymous namespace
 
 bool Sema::CppLookupName(LookupResult &R, Scope *S) {
@@ -1289,6 +1275,14 @@ bool Sema::CppLookupName(LookupResult &R, Scope *S) {
   DeclarationName Name = R.getLookupName();
   Sema::LookupNameKind NameKind = R.getLookupKind();
 
+  // 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())
+        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
@@ -1301,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 (!R.isTemplateNameLookup() &&
-            isDependentAssignmentOperator(Name, DC)) {
-          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.
 
@@ -2478,6 +2458,10 @@ bool Sema::LookupQualifiedName(LookupResult &R, DeclContext *LookupCtx,
     }
   } QL(LookupCtx);
 
+  CXXRecordDecl *LookupRec = dyn_cast<CXXRecordDecl>(LookupCtx);
+  // FIXME: Per [temp.dep.general]p2, an unqualified name is also dependent
+  // if it's a dependent conversion-function-id or operator= where the current
+  // class is a templated entity. This should be handled in LookupName.
   if (!InUnqualifiedLookup && !R.isForRedeclaration()) {
     // C++23 [temp.dep.type]p5:
     //   A qualified name is dependent if
@@ -2488,16 +2472,13 @@ bool Sema::LookupQualifiedName(LookupResult &R, DeclContext *LookupCtx,
     //     is operator=, or
     //   - [...]
     if (DeclarationName Name = R.getLookupName();
-        (Name.getNameKind() == DeclarationName::CXXConversionFunctionName &&
-         Name.getCXXNameType()->isDependentType()) ||
-        (!R.isTemplateNameLookup() &&
-         isDependentAssignmentOperator(Name, LookupCtx))) {
+        Name.getNameKind() == DeclarationName::CXXConversionFunctionName &&
+        Name.getCXXNameType()->isDependentType()) {
       R.setNotFoundInCurrentInstantiation();
       return false;
     }
   }
 
-  CXXRecordDecl *LookupRec = dyn_cast<CXXRecordDecl>(LookupCtx);
   if (LookupDirect(*this, R, LookupCtx)) {
     R.resolveKind();
     if (LookupRec)
@@ -2588,6 +2569,8 @@ bool Sema::LookupQualifiedName(LookupResult &R, DeclContext *LookupCtx,
     return true;
   };
 
+  bool TemplateNameLookup = R.isTemplateNameLookup();
+
   // Determine whether two sets of members contain the same members, as
   // required by C++ [class.member.lookup]p6.
   auto HasSameDeclarations = [&](DeclContext::lookup_iterator A,
@@ -2609,7 +2592,7 @@ bool Sema::LookupQualifiedName(LookupResult &R, DeclContext *LookupCtx,
         //   template, and if the name is used as a template-name, the
         //   reference refers to the class template itself and not a
         //   specialization thereof, and is not ambiguous.
-        if (R.isTemplateNameLookup())
+        if (TemplateNameLookup)
           if (auto *TD = getAsTemplateNameDecl(ND))
             ND = TD;
 

diff  --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp
index 480bc74c2001a..2fce2238f9c10 100644
--- a/clang/lib/Sema/SemaTemplate.cpp
+++ b/clang/lib/Sema/SemaTemplate.cpp
@@ -726,7 +726,7 @@ Sema::ActOnDependentIdExpression(const CXXScopeSpec &SS,
                                  const DeclarationNameInfo &NameInfo,
                                  bool isAddressOfOperand,
                            const TemplateArgumentListInfo *TemplateArgs) {
-  QualType ThisType = getCurrentThisType();
+  DeclContext *DC = getFunctionLevelDeclContext();
 
   // C++11 [expr.prim.general]p12:
   //   An id-expression that denotes a non-static data member or non-static
@@ -748,7 +748,11 @@ Sema::ActOnDependentIdExpression(const CXXScopeSpec &SS,
     IsEnum = isa_and_nonnull<EnumType>(NNS->getAsType());
 
   if (!MightBeCxx11UnevalField && !isAddressOfOperand && !IsEnum &&
-      !ThisType.isNull()) {
+      isa<CXXMethodDecl>(DC) &&
+      cast<CXXMethodDecl>(DC)->isImplicitObjectMemberFunction()) {
+    QualType ThisType =
+        cast<CXXMethodDecl>(DC)->getThisType().getNonReferenceType();
+
     // Since the 'this' expression is synthesized, we don't need to
     // perform the double-lookup check.
     NamedDecl *FirstQualifierInScope = nullptr;

diff  --git a/clang/test/CXX/temp/temp.res/temp.dep/temp.dep.type/p4.cpp b/clang/test/CXX/temp/temp.res/temp.dep/temp.dep.type/p4.cpp
index 43053c18c5076..1adbc33a701c1 100644
--- a/clang/test/CXX/temp/temp.res/temp.dep/temp.dep.type/p4.cpp
+++ b/clang/test/CXX/temp/temp.res/temp.dep/temp.dep.type/p4.cpp
@@ -483,7 +483,6 @@ namespace N3 {
   };
 
   template struct E<int>; // expected-note {{in instantiation of template class 'N3::E<int>' requested here}}
-
 } // namespace N3
 
 namespace N4 {
@@ -551,4 +550,5 @@ namespace N4 {
   };
 
   template void D<B>::instantiated(D); // expected-note {{in instantiation of}}
+
 } // namespace N4


        


More information about the cfe-commits mailing list