https://github.com/jcsxky updated https://github.com/llvm/llvm-project/pull/83847
>From e3c4715acdc1ead6596b1368590696a04e559414 Mon Sep 17 00:00:00 2001 From: huqizhi <huqi...@feysh.com> Date: Mon, 4 Mar 2024 21:51:07 +0800 Subject: [PATCH] [Clang][Sema] Allow access to a public template alias declaration that refers to friend's private nested type --- clang/docs/ReleaseNotes.rst | 3 +++ clang/include/clang/Sema/Lookup.h | 5 +++++ clang/lib/Sema/SemaAccess.cpp | 19 +++++++++++++++++++ clang/lib/Sema/SemaTemplate.cpp | 1 + clang/test/SemaTemplate/PR25708.cpp | 23 +++++++++++++++++++++++ 5 files changed, 51 insertions(+) create mode 100644 clang/test/SemaTemplate/PR25708.cpp diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 612b4329727455..02e378cf838a27 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -224,6 +224,9 @@ Bug Fixes in This Version for variables created through copy initialization having side-effects in C++17 and later. Fixes (#GH64356) (#GH79518). +- Allow access to a public template alias declaration that refers to friend's + private nested type (`#29217 <https://github.com/llvm/llvm-project/issues/29217>`). + Bug Fixes to Compiler Builtins ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/clang/include/clang/Sema/Lookup.h b/clang/include/clang/Sema/Lookup.h index 2f2f2607a937fe..a07609bfb7c9bc 100644 --- a/clang/include/clang/Sema/Lookup.h +++ b/clang/include/clang/Sema/Lookup.h @@ -752,6 +752,10 @@ class LookupResult { IDNS &= ~Decl::IDNS_LocalExtern; } + void setNestedNameSpecifier(NestedNameSpecifier *Q) { Qualifier = Q; } + + NestedNameSpecifier *getNestedNameSpecifier() const { return Qualifier; } + private: void diagnoseAccess() { if (!isAmbiguous() && isClassLookup() && @@ -792,6 +796,7 @@ class LookupResult { CXXBasePaths *Paths = nullptr; CXXRecordDecl *NamingClass = nullptr; QualType BaseObjectType; + NestedNameSpecifier *Qualifier = nullptr; // Parameters. Sema *SemaPtr; diff --git a/clang/lib/Sema/SemaAccess.cpp b/clang/lib/Sema/SemaAccess.cpp index 4af3c0f30a8e8a..9077066da29d61 100644 --- a/clang/lib/Sema/SemaAccess.cpp +++ b/clang/lib/Sema/SemaAccess.cpp @@ -254,6 +254,9 @@ struct AccessTarget : public AccessedEntity { namingClass = cast<CXXRecordDecl>(namingClass->getParent()); return namingClass->getCanonicalDecl(); } + void setNestedNameSpecifier(NestedNameSpecifier *Q) { Qualifier = Q; } + + NestedNameSpecifier *getNestedNameSpecifier() const { return Qualifier; } private: void initialize() { @@ -274,6 +277,7 @@ struct AccessTarget : public AccessedEntity { mutable bool CalculatedInstanceContext : 1; mutable const CXXRecordDecl *InstanceContext; const CXXRecordDecl *DeclaringClass; + NestedNameSpecifier *Qualifier = nullptr; }; } @@ -1481,6 +1485,20 @@ static Sema::AccessResult CheckAccess(Sema &S, SourceLocation Loc, } EffectiveContext EC(S.CurContext); + if (Entity.getNestedNameSpecifier()) + if (const Type *Ty = Entity.getNestedNameSpecifier()->getAsType()) + switch (Ty->getTypeClass()) { + case Type::TypeClass::SubstTemplateTypeParm: + if (auto *SubstTemplateTy = Ty->getAs<SubstTemplateTypeParmType>()) + if (auto *D = SubstTemplateTy->getAssociatedDecl()) + if (auto *RD = dyn_cast_or_null<CXXRecordDecl>(D->getDeclContext())) + EC.Records.push_back(RD); + + break; + default: + break; + } + switch (CheckEffectiveAccess(S, EC, Loc, Entity)) { case AR_accessible: return Sema::AR_accessible; case AR_inaccessible: return Sema::AR_inaccessible; @@ -1916,6 +1934,7 @@ void Sema::CheckLookupAccess(const LookupResult &R) { AccessTarget Entity(Context, AccessedEntity::Member, R.getNamingClass(), I.getPair(), R.getBaseObjectType()); + Entity.setNestedNameSpecifier(R.getNestedNameSpecifier()); Entity.setDiag(diag::err_access); CheckAccess(*this, R.getNameLoc(), Entity); } diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp index 873ea10ebe0660..2786a1fa9acbc3 100644 --- a/clang/lib/Sema/SemaTemplate.cpp +++ b/clang/lib/Sema/SemaTemplate.cpp @@ -11273,6 +11273,7 @@ Sema::CheckTypenameType(ElaboratedTypeKeyword Keyword, DeclarationName Name(&II); LookupResult Result(*this, Name, IILoc, LookupOrdinaryName); + Result.setNestedNameSpecifier(QualifierLoc.getNestedNameSpecifier()); if (Ctx) LookupQualifiedName(Result, Ctx, SS); else diff --git a/clang/test/SemaTemplate/PR25708.cpp b/clang/test/SemaTemplate/PR25708.cpp new file mode 100644 index 00000000000000..685c8298c48f6b --- /dev/null +++ b/clang/test/SemaTemplate/PR25708.cpp @@ -0,0 +1,23 @@ +// RUN: %clang_cc1 -std=c++11 -verify %s +// RUN: %clang_cc1 -std=c++14 -verify %s +// RUN: %clang_cc1 -std=c++17 -verify %s +// RUN: %clang_cc1 -std=c++20 -verify %s +// expected-no-diagnostics + +struct FooAccessor +{ + template <typename T> + using Foo = typename T::Foo; +}; + +class Type +{ + friend struct FooAccessor; + + using Foo = int; +}; + +int main() +{ + FooAccessor::Foo<Type> t; +} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits