Author: Valentyn Yukhymenko Date: 2025-01-25T15:01:40+08:00 New Revision: f607e3fd23ef0019b2f3b289b4d46012400b8db5
URL: https://github.com/llvm/llvm-project/commit/f607e3fd23ef0019b2f3b289b4d46012400b8db5 DIFF: https://github.com/llvm/llvm-project/commit/f607e3fd23ef0019b2f3b289b4d46012400b8db5.diff LOG: [Clang][Sema] Reject declaring an alias template with the same name as its template parameter. (#123533) The issue occurred because the template parameter scope was skipped too early, before diagnosing the alias name shadowing. To fix this, the patch moves it to after LookupName, such that the behavior remains consistent with the typedef implementation. Fixes llvm#123423 Added: Modified: clang/docs/ReleaseNotes.rst clang/lib/Sema/SemaDeclCXX.cpp clang/test/CXX/temp/temp.decls/temp.variadic/fixed-expansion.cpp clang/test/SemaCXX/alias-template.cpp Removed: ################################################################################ diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index f110b8cf765075..e9fffddd507c66 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -990,6 +990,7 @@ Bug Fixes to C++ Support - Fix immediate escalation not propagating through inherited constructors. (#GH112677) - Fixed assertions or false compiler diagnostics in the case of C++ modules for lambda functions or inline friend functions defined inside templates (#GH122493). +- Clang now rejects declaring an alias template with the same name as its template parameter. (#GH123423) Bug Fixes to AST Handling ^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp index 839b3a1cccdcc3..08065e3cad2bb3 100644 --- a/clang/lib/Sema/SemaDeclCXX.cpp +++ b/clang/lib/Sema/SemaDeclCXX.cpp @@ -13406,8 +13406,6 @@ Decl *Sema::ActOnAliasDeclaration(Scope *S, AccessSpecifier AS, SourceLocation UsingLoc, UnqualifiedId &Name, const ParsedAttributesView &AttrList, TypeResult Type, Decl *DeclFromDeclSpec) { - // Get the innermost enclosing declaration scope. - S = S->getDeclParent(); if (Type.isInvalid()) return nullptr; @@ -13458,6 +13456,9 @@ Decl *Sema::ActOnAliasDeclaration(Scope *S, AccessSpecifier AS, CheckTypedefForVariablyModifiedType(S, NewTD); Invalid |= NewTD->isInvalidDecl(); + // Get the innermost enclosing declaration scope. + S = S->getDeclParent(); + bool Redeclaration = false; NamedDecl *NewND; diff --git a/clang/test/CXX/temp/temp.decls/temp.variadic/fixed-expansion.cpp b/clang/test/CXX/temp/temp.decls/temp.variadic/fixed-expansion.cpp index a990c82564aa40..ab4c663d24c7d5 100644 --- a/clang/test/CXX/temp/temp.decls/temp.variadic/fixed-expansion.cpp +++ b/clang/test/CXX/temp/temp.decls/temp.variadic/fixed-expansion.cpp @@ -121,8 +121,8 @@ namespace PartialSpecialization { namespace FixedAliasTemplate { template<typename,typename,typename> struct S {}; - template<typename T, typename U> using U = S<T, int, U>; // expected-note 2{{template parameter is declared here}} - template<typename...Ts> U<Ts...> &f(U<Ts...>, Ts...); // expected-error 2{{pack expansion used as argument for non-pack parameter of alias template}} + template<typename T, typename U> using Z = S<T, int, U>; // expected-note 2{{template parameter is declared here}} + template<typename...Ts> Z<Ts...> &f(Z<Ts...>, Ts...); // expected-error 2{{pack expansion used as argument for non-pack parameter of alias template}} S<int, int, double> &s1 = f({}, 0, 0.0); // expected-error {{no matching function}} } diff --git a/clang/test/SemaCXX/alias-template.cpp b/clang/test/SemaCXX/alias-template.cpp index 5189405e23db56..b49d36a6267e66 100644 --- a/clang/test/SemaCXX/alias-template.cpp +++ b/clang/test/SemaCXX/alias-template.cpp @@ -54,18 +54,24 @@ namespace LookupFilter { template<typename U> using S = S<U>*; // ok } -namespace InFunctions { +namespace UnexpandedPack { template<typename...T> struct S0 { template<typename Z> using U = T*; // expected-error {{declaration type contains unexpanded parameter pack 'T'}} U<char> u; }; +} +namespace InvalidType { template<typename Z> using T1 = int; template<typename Z> using T2 = int[-1]; // expected-error {{array size is negative}} +} + +namespace ShadowTemplateParam { template<typename...T> struct S3 { // expected-note {{template parameter is declared here}} template<typename Z> using T = int; // expected-error {{declaration of 'T' shadows template parameter}} }; - template<typename Z> using Z = Z; + template<typename Z> // expected-note {{template parameter is declared here}} + using Z = Z; // expected-error {{declaration of 'Z' shadows template parameter}} } namespace ClassNameRedecl { _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits