diff options
-rw-r--r-- | clang/lib/Sema/SemaTemplate.cpp | 14 | ||||
-rw-r--r-- | clang/test/CXX/temp/temp.res/temp.local/p6.cpp | 21 |
2 files changed, 24 insertions, 11 deletions
diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp index 73b5c44b599..2ea242fc956 100644 --- a/clang/lib/Sema/SemaTemplate.cpp +++ b/clang/lib/Sema/SemaTemplate.cpp @@ -929,6 +929,13 @@ Sema::CheckClassTemplate(Scope *S, unsigned TagSpec, TagUseKind TUK, if (Previous.begin() != Previous.end()) PrevDecl = (*Previous.begin())->getUnderlyingDecl(); + if (PrevDecl && PrevDecl->isTemplateParameter()) { + // Maybe we will complain about the shadowed template parameter. + DiagnoseTemplateParameterShadow(NameLoc, PrevDecl); + // Just pretend that we didn't see the previous declaration. + PrevDecl = nullptr; + } + // If there is a previous declaration with the same name, check // whether this is a valid redeclaration. ClassTemplateDecl *PrevClassTemplate @@ -1054,12 +1061,7 @@ Sema::CheckClassTemplate(Scope *S, unsigned TagSpec, TagUseKind TUK, // definition, as part of error recovery? return true; } - } - } else if (PrevDecl && PrevDecl->isTemplateParameter()) { - // Maybe we will complain about the shadowed template parameter. - DiagnoseTemplateParameterShadow(NameLoc, PrevDecl); - // Just pretend that we didn't see the previous declaration. - PrevDecl = nullptr; + } } else if (PrevDecl) { // C++ [temp]p5: // A class template shall not have the same name as any other diff --git a/clang/test/CXX/temp/temp.res/temp.local/p6.cpp b/clang/test/CXX/temp/temp.res/temp.local/p6.cpp index 843b45543fc..e2aa0ff3442 100644 --- a/clang/test/CXX/temp/temp.res/temp.local/p6.cpp +++ b/clang/test/CXX/temp/temp.res/temp.local/p6.cpp @@ -5,11 +5,11 @@ namespace N {} template<typename T, // expected-note {{declared here}} typename T> struct X {}; // expected-error {{declaration of 'T' shadows template parameter}} -template<typename T> struct Y { // expected-note 17{{declared here}} +template<typename T> struct Y { // expected-note 18{{declared here}} template<typename T> struct A {}; // expected-error {{declaration of 'T' shadows template parameter}} struct B { - template<typename> struct T {}; // FIXME: desired-error {{declaration of 'T' shadows template parameter}} + template<typename> struct T {}; // expected-error {{declaration of 'T' shadows template parameter}} }; struct C { template<typename> void T(); // expected-error {{declaration of 'T' shadows template parameter}} @@ -65,11 +65,11 @@ template<typename T> struct Y { // expected-note 17{{declared here}} friend struct T; // expected-error {{declaration of 'T' shadows template parameter}} }; -template<int T> struct Z { // expected-note 15{{declared here}} +template<int T> struct Z { // expected-note 16{{declared here}} template<typename T> struct A {}; // expected-error {{declaration of 'T' shadows template parameter}} struct B { - template<typename> struct T {}; // FIXME: desired-error {{declaration of 'T' shadows template parameter}} + template<typename> struct T {}; // expected-error {{declaration of 'T' shadows template parameter}} }; struct C { template<typename> void T(); // expected-error {{declaration of 'T' shadows template parameter}} @@ -129,7 +129,8 @@ void f(int T) {} // expected-error {{declaration of 'T' shadows template paramet // FIXME: These are ill-formed: a template-parameter shall not have the same name as the template name. namespace A { - template<typename T> struct T {}; + template<typename T> struct T {}; // expected-error{{declaration of 'T' shadows template parameter}} + // expected-note@-1{{template parameter is declared here}} } namespace B { template<typename T> void T() {} @@ -137,3 +138,13 @@ namespace B { namespace C { template<typename T> int T; } + +namespace PR28023 { +template<int V> // expected-note{{template parameter is declared here}} +struct A { + struct B { + template <int> friend struct V; // expected-error{{declaration of 'V' shadows template parameter}} + }; +}; +A<0>::B a; +} |