diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index f110b8cf76507..e9fffddd507c6 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 839b3a1cccdcc..08065e3cad2bb 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 a990c82564aa4..ab4c663d24c7d 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 struct S {}; - template using U = S; // expected-note 2{{template parameter is declared here}} - template U &f(U, Ts...); // expected-error 2{{pack expansion used as argument for non-pack parameter of alias template}} + template using Z = S; // expected-note 2{{template parameter is declared here}} + template Z &f(Z, Ts...); // expected-error 2{{pack expansion used as argument for non-pack parameter of alias template}} S &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 5189405e23db5..b49d36a6267e6 100644 --- a/clang/test/SemaCXX/alias-template.cpp +++ b/clang/test/SemaCXX/alias-template.cpp @@ -54,18 +54,24 @@ namespace LookupFilter { template using S = S*; // ok } -namespace InFunctions { +namespace UnexpandedPack { template struct S0 { template using U = T*; // expected-error {{declaration type contains unexpanded parameter pack 'T'}} U u; }; +} +namespace InvalidType { template using T1 = int; template using T2 = int[-1]; // expected-error {{array size is negative}} +} + +namespace ShadowTemplateParam { template struct S3 { // expected-note {{template parameter is declared here}} template using T = int; // expected-error {{declaration of 'T' shadows template parameter}} }; - template using Z = Z; + template // expected-note {{template parameter is declared here}} + using Z = Z; // expected-error {{declaration of 'Z' shadows template parameter}} } namespace ClassNameRedecl {