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/4] [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/4] [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 { >From 1fa4a767e4abdd514d6d515e2c8c09be4e9ea03c Mon Sep 17 00:00:00 2001 From: Krystian Stasiowski <sdkryst...@gmail.com> Date: Wed, 8 May 2024 16:02:08 -0400 Subject: [PATCH 3/4] [FOLD] add test where template is not instantiated --- .../test/CXX/temp/temp.res/temp.dep/temp.dep.type/p4.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) 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 00507261406fb..1a62fe688658f 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 @@ -474,10 +474,15 @@ namespace N3 { template<typename T> struct D { - auto instantiated(D& d) -> decltype(operator=(d)); // expected-error {{use of undeclared 'operator='}} + auto not_instantiated() -> decltype(operator=(0)); // expected-error {{use of undeclared 'operator='}} }; - template struct D<int>; // expected-note {{in instantiation of template class 'D<int>' requested here}} + 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 'E<int>' requested here}} } // namespace N3 >From 3731d0a3ff7dfb27b06e969fdc1610bfa1b2d94e Mon Sep 17 00:00:00 2001 From: Krystian Stasiowski <sdkryst...@gmail.com> Date: Wed, 8 May 2024 16:03:55 -0400 Subject: [PATCH 4/4] [FOLD] address review comments --- clang/lib/Sema/SemaLookup.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/clang/lib/Sema/SemaLookup.cpp b/clang/lib/Sema/SemaLookup.cpp index 6bd5932212b92..100249450d5ce 100644 --- a/clang/lib/Sema/SemaLookup.cpp +++ b/clang/lib/Sema/SemaLookup.cpp @@ -1248,6 +1248,13 @@ static DeclContext *findOuterContext(Scope *S) { return nullptr; } +static bool isDependentAssignmentOperator(DeclarationName Name, + DeclContext *LookupContext) { + const auto *LookupRecord = dyn_cast_if_present<CXXRecordDecl>(LookupContext); + return Name.getCXXOverloadedOperator() == OO_Equal && LookupRecord && + !LookupRecord->isBeingDefined() && LookupRecord->isDependentContext(); +} + namespace { /// An RAII object to specify that we want to find block scope extern /// declarations. @@ -1269,13 +1276,6 @@ 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"); _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits