llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-clang Author: Mariya Podchishchaeva (Fznamznon) <details> <summary>Changes</summary> 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 --- Full diff: https://github.com/llvm/llvm-project/pull/74335.diff 5 Files Affected: - (modified) clang/docs/ReleaseNotes.rst (+3) - (modified) clang/lib/Sema/SemaCXXScopeSpec.cpp (+20-3) - (modified) clang/lib/Sema/SemaTemplate.cpp (+8-3) - (modified) clang/test/CXX/temp/temp.decls/temp.alias/p3.cpp (+3-2) - (modified) clang/test/SemaCXX/alias-template.cpp (+50) ``````````diff diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 683d0026bb345..18a7afda3c8b0 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -653,6 +653,9 @@ Bug Fixes in This Version Fixes (`#13826 <https://github.com/llvm/llvm-project/issues/13826>`_) - 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..56f83be78266f 100644 --- a/clang/lib/Sema/SemaCXXScopeSpec.cpp +++ b/clang/lib/Sema/SemaCXXScopeSpec.cpp @@ -30,6 +30,21 @@ 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 +52,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..23a175da6bc4d 100644 --- a/clang/lib/Sema/SemaTemplate.cpp +++ b/clang/lib/Sema/SemaTemplate.cpp @@ -3990,9 +3990,14 @@ 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>); +} + +} `````````` </details> https://github.com/llvm/llvm-project/pull/74335 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits