Author: Mariya Podchishchaeva Date: 2023-12-06T11:14:17+01:00 New Revision: 6b1aa319754e76366edd88e10034e0539710d946
URL: https://github.com/llvm/llvm-project/commit/6b1aa319754e76366edd88e10034e0539710d946 DIFF: https://github.com/llvm/llvm-project/commit/6b1aa319754e76366edd88e10034e0539710d946.diff LOG: [clang] Substitute alias templates from correct context (#74335) Current context set to where alias was met, not where it is declared caused incorrect access check in case alias referenced private members of the parent class. Fixes https://github.com/llvm/llvm-project/issues/41693 Added: Modified: clang/docs/ReleaseNotes.rst clang/lib/Sema/SemaCXXScopeSpec.cpp clang/lib/Sema/SemaTemplate.cpp clang/test/CXX/temp/temp.decls/temp.alias/p3.cpp clang/test/SemaCXX/alias-template.cpp Removed: ################################################################################ diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 89ea2f0930cec..b3c7552f2efe6 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -658,6 +658,9 @@ Bug Fixes in This Version Fixes (`#64467 <https://github.com/llvm/llvm-project/issues/64467>`_) - Clang's ``-Wchar-subscripts`` no longer warns on chars whose values are known non-negative constants. Fixes (`#18763 <https://github.com/llvm/llvm-project/issues/18763>`_) +- Fixed false positive error emitted when templated alias inside a class + used private members of the same class. + Fixes (`#41693 <https://github.com/llvm/llvm-project/issues/41693>`_) Bug Fixes to Compiler Builtins ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/clang/lib/Sema/SemaCXXScopeSpec.cpp b/clang/lib/Sema/SemaCXXScopeSpec.cpp index 44a40215b90df..4bd96722a4b67 100644 --- a/clang/lib/Sema/SemaCXXScopeSpec.cpp +++ b/clang/lib/Sema/SemaCXXScopeSpec.cpp @@ -30,6 +30,20 @@ static CXXRecordDecl *getCurrentInstantiationOf(QualType T, return nullptr; const Type *Ty = T->getCanonicalTypeInternal().getTypePtr(); + if (isa<TemplateSpecializationType>(Ty)) { + if (auto *Record = dyn_cast<CXXRecordDecl>(CurContext)) { + if (isa<ClassTemplatePartialSpecializationDecl>(Record) || + Record->getDescribedClassTemplate()) { + const Type *ICNT = Record->getTypeForDecl(); + QualType Injected = + cast<InjectedClassNameType>(ICNT)->getInjectedSpecializationType(); + + if (Ty == Injected->getCanonicalTypeInternal().getTypePtr()) + return Record; + } + } + } + if (const RecordType *RecordTy = dyn_cast<RecordType>(Ty)) { CXXRecordDecl *Record = cast<CXXRecordDecl>(RecordTy->getDecl()); if (!Record->isDependentContext() || @@ -37,10 +51,12 @@ static CXXRecordDecl *getCurrentInstantiationOf(QualType T, return Record; return nullptr; - } else if (isa<InjectedClassNameType>(Ty)) + } + + if (isa<InjectedClassNameType>(Ty)) return cast<InjectedClassNameType>(Ty)->getDecl(); - else - return nullptr; + + return nullptr; } /// Compute the DeclContext that is associated with the given type. diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp index 09bbf14d39af5..a586014e0cb1b 100644 --- a/clang/lib/Sema/SemaTemplate.cpp +++ b/clang/lib/Sema/SemaTemplate.cpp @@ -3990,9 +3990,16 @@ QualType Sema::CheckTemplateIdType(TemplateName Name, if (Inst.isInvalid()) return QualType(); - CanonType = SubstType(Pattern->getUnderlyingType(), - TemplateArgLists, AliasTemplate->getLocation(), - AliasTemplate->getDeclName()); + { + bool ForLambdaCallOperator = false; + if (const auto *Rec = dyn_cast<CXXRecordDecl>(Pattern->getDeclContext())) + ForLambdaCallOperator = Rec->isLambda(); + Sema::ContextRAII SavedContext(*this, Pattern->getDeclContext(), + !ForLambdaCallOperator); + CanonType = + SubstType(Pattern->getUnderlyingType(), TemplateArgLists, + AliasTemplate->getLocation(), AliasTemplate->getDeclName()); + } if (CanonType.isNull()) { // If this was enable_if and we failed to find the nested type // within enable_if in a SFINAE context, dig out the specific diff --git a/clang/test/CXX/temp/temp.decls/temp.alias/p3.cpp b/clang/test/CXX/temp/temp.decls/temp.alias/p3.cpp index 2d46502e1d9b3..2b33a4ef566da 100644 --- a/clang/test/CXX/temp/temp.decls/temp.alias/p3.cpp +++ b/clang/test/CXX/temp/temp.decls/temp.alias/p3.cpp @@ -2,11 +2,12 @@ // The example given in the standard (this is rejected for other reasons anyway). template<class T> struct A; -template<class T> using B = typename A<T>::U; // expected-error {{no type named 'U' in 'A<T>'}} +template<class T> using B = typename A<T>::U; // expected-error {{no type named 'U' in 'A<short>'}} + // expected-note@-1 {{in instantiation of template class 'A<short>' requested here}} template<class T> struct A { typedef B<T> U; // expected-note {{in instantiation of template type alias 'B' requested here}} }; -B<short> b; +B<short> b; // expected-note {{in instantiation of template type alias 'B' requested here}} template<typename T> using U = int; diff --git a/clang/test/SemaCXX/alias-template.cpp b/clang/test/SemaCXX/alias-template.cpp index 5189405e23db5..cd415c6cd4e9b 100644 --- a/clang/test/SemaCXX/alias-template.cpp +++ b/clang/test/SemaCXX/alias-template.cpp @@ -192,3 +192,53 @@ int g = sfinae_me<int>(); // expected-error{{no matching function for call to 's namespace NullExceptionDecl { template<int... I> auto get = []() { try { } catch(...) {}; return I; }; // expected-error{{initializer contains unexpanded parameter pack 'I'}} } + +namespace GH41693 { +struct S { +private: + template <typename> static constexpr void Impl() {} + +public: + template <typename X> using U = decltype(Impl<X>()); +}; + +using X = S::U<void>; +struct Y { +private: + static constexpr int x=0; + + template <typename> + static constexpr int y=0; + + template <typename> + static constexpr int foo(); + +public: + template <typename U> + using bar1 = decltype(foo<U>()); + using bar2 = decltype(x); + template <typename U> + using bar3 = decltype(y<U>); +}; + + +using type1 = Y::bar1<float>; +using type2 = Y::bar2; +using type3 = Y::bar3<float>; + +struct theFriend{ + template<class T> + using theAlias = decltype(&T::i); +}; + +class theC{ + int i; + public: + friend struct theFriend; +}; + +int foo(){ + (void)sizeof(theFriend::theAlias<theC>); +} + +} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits