https://github.com/sdkrystian updated https://github.com/llvm/llvm-project/pull/91498
>From 60d2030216403c7cfa8272396497d31aed314288 Mon Sep 17 00:00:00 2001 From: Krystian Stasiowski <sdkryst...@gmail.com> Date: Wed, 8 May 2024 12:18:49 -0400 Subject: [PATCH 1/2] [Clang][Sema] Fix lookup of dependent operator= outside of complete-class contexts --- clang/lib/Sema/SemaLookup.cpp | 28 +++++++++++++--------------- clang/lib/Sema/SemaTemplate.cpp | 7 ++----- 2 files changed, 15 insertions(+), 20 deletions(-) diff --git a/clang/lib/Sema/SemaLookup.cpp b/clang/lib/Sema/SemaLookup.cpp index e63da5875d2c9..6bd5932212b92 100644 --- a/clang/lib/Sema/SemaLookup.cpp +++ b/clang/lib/Sema/SemaLookup.cpp @@ -1269,19 +1269,19 @@ struct FindLocalExternScope { }; } // end anonymous namespace +static bool isDependentAssignmentOperator(DeclarationName Name, + DeclContext *LookupContext) { + auto *LookupRecord = dyn_cast_if_present<CXXRecordDecl>(LookupContext); + return Name.getCXXOverloadedOperator() == OO_Equal && LookupRecord && + !LookupRecord->isBeingDefined() && LookupRecord->isDependentContext(); +} + bool Sema::CppLookupName(LookupResult &R, Scope *S) { assert(getLangOpts().CPlusPlus && "Can perform only C++ lookup"); 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 @@ -1299,9 +1299,8 @@ bool Sema::CppLookupName(LookupResult &R, Scope *S) { 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.isTemplateNameLookup()) { + if (!R.isTemplateNameLookup() && + isDependentAssignmentOperator(Name, DC)) { R.setNotFoundInCurrentInstantiation(); return false; } @@ -2472,8 +2471,6 @@ bool Sema::LookupQualifiedName(LookupResult &R, DeclContext *LookupCtx, } } QL(LookupCtx); - bool TemplateNameLookup = R.isTemplateNameLookup(); - CXXRecordDecl *LookupRec = dyn_cast<CXXRecordDecl>(LookupCtx); if (!InUnqualifiedLookup && !R.isForRedeclaration()) { // C++23 [temp.dep.type]p5: // A qualified name is dependent if @@ -2486,13 +2483,14 @@ bool Sema::LookupQualifiedName(LookupResult &R, DeclContext *LookupCtx, if (DeclarationName Name = R.getLookupName(); (Name.getNameKind() == DeclarationName::CXXConversionFunctionName && Name.getCXXNameType()->isDependentType()) || - (Name.getCXXOverloadedOperator() == OO_Equal && LookupRec && - LookupRec->isDependentContext() && !TemplateNameLookup)) { + (!R.isTemplateNameLookup() && + isDependentAssignmentOperator(Name, LookupCtx))) { R.setNotFoundInCurrentInstantiation(); return false; } } + CXXRecordDecl *LookupRec = dyn_cast<CXXRecordDecl>(LookupCtx); if (LookupDirect(*this, R, LookupCtx)) { R.resolveKind(); if (LookupRec) @@ -2604,7 +2602,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 (TemplateNameLookup) + if (R.isTemplateNameLookup()) if (auto *TD = getAsTemplateNameDecl(ND)) ND = TD; diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp index 7e57fa0696725..480bc74c2001a 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) { - DeclContext *DC = getFunctionLevelDeclContext(); + QualType ThisType = getCurrentThisType(); // C++11 [expr.prim.general]p12: // An id-expression that denotes a non-static data member or non-static @@ -748,10 +748,7 @@ Sema::ActOnDependentIdExpression(const CXXScopeSpec &SS, IsEnum = isa_and_nonnull<EnumType>(NNS->getAsType()); if (!MightBeCxx11UnevalField && !isAddressOfOperand && !IsEnum && - isa<CXXMethodDecl>(DC) && - cast<CXXMethodDecl>(DC)->isImplicitObjectMemberFunction()) { - QualType ThisType = cast<CXXMethodDecl>(DC)->getThisType().getNonReferenceType(); - + !ThisType.isNull()) { // Since the 'this' expression is synthesized, we don't need to // perform the double-lookup check. NamedDecl *FirstQualifierInScope = nullptr; >From 75c5e42ebc01299924c26b9fc03eaa2621696c8e Mon Sep 17 00:00:00 2001 From: Krystian Stasiowski <sdkryst...@gmail.com> Date: Wed, 8 May 2024 15:11:02 -0400 Subject: [PATCH 2/2] [FOLD] add test --- .../test/CXX/temp/temp.res/temp.dep/temp.dep.type/p4.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) 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 46dd52f8c4c13..00507261406fb 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 @@ -471,6 +471,14 @@ namespace N3 { this->C::operator=(*this); } }; + + template<typename T> + struct D { + auto instantiated(D& d) -> decltype(operator=(d)); // expected-error {{use of undeclared 'operator='}} + }; + + template struct D<int>; // expected-note {{in instantiation of template class 'D<int>' requested here}} + } // namespace N3 namespace N4 { _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits