diff options
| -rw-r--r-- | clang/lib/Sema/SemaLookup.cpp | 6 | ||||
| -rw-r--r-- | clang/test/CXX/temp/temp.res/temp.local/p6.cpp | 69 | 
2 files changed, 73 insertions, 2 deletions
| diff --git a/clang/lib/Sema/SemaLookup.cpp b/clang/lib/Sema/SemaLookup.cpp index 6185e232c59..3029283e7c4 100644 --- a/clang/lib/Sema/SemaLookup.cpp +++ b/clang/lib/Sema/SemaLookup.cpp @@ -930,8 +930,10 @@ bool Sema::CppLookupName(LookupResult &R, Scope *S) {              LeftStartingScope = true;            // If we found something outside of our starting scope that -          // does not have linkage, skip it. -          if (LeftStartingScope && !((*I)->hasLinkage())) { +          // does not have linkage, skip it. If it's a template parameter, +          // we still find it, so we can diagnose the invalid redeclaration. +          if (LeftStartingScope && !((*I)->hasLinkage()) && +              !(*I)->isTemplateParameter()) {              R.setShadowed();              continue;            } diff --git a/clang/test/CXX/temp/temp.res/temp.local/p6.cpp b/clang/test/CXX/temp/temp.res/temp.local/p6.cpp new file mode 100644 index 00000000000..eccbb899321 --- /dev/null +++ b/clang/test/CXX/temp/temp.res/temp.local/p6.cpp @@ -0,0 +1,69 @@ +// RUN: %clang_cc1 -verify %s -fcxx-exceptions -std=c++1y + +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 15{{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}} +  }; +  struct C { +    template<typename> void T(); // expected-error {{declaration of 'T' shadows template parameter}} +  }; +  struct D { +    struct T {}; // expected-error {{declaration of 'T' shadows template parameter}} +  }; +  struct E { +    typedef int T; // expected-error {{declaration of 'T' shadows template parameter}} +  }; +  struct F { +    using T = int; // expected-error {{declaration of 'T' shadows template parameter}} +  }; +  struct G { +    int T; // expected-error {{declaration of 'T' shadows template parameter}} +  }; +  struct H { +    static int T; // expected-error {{declaration of 'T' shadows template parameter}} +  }; +  struct I { +    void T(); // expected-error {{declaration of 'T' shadows template parameter}} +  }; +  struct J { +    enum T { e }; // expected-error {{declaration of 'T' shadows template parameter}} +  }; +  struct K { +    enum E { T }; // expected-error {{declaration of 'T' shadows template parameter}} +  }; + +  void a() { +    extern int T; // expected-error {{declaration of 'T' shadows template parameter}} +  } +  void b() { +    int T; // expected-error {{declaration of 'T' shadows template parameter}} +  } +  void c() { +    try {} +    catch (int T) {} // expected-error {{declaration of 'T' shadows template parameter}} +  } +  void d() { +    void T(); // expected-error {{declaration of 'T' shadows template parameter}} +  } + +  friend struct T; // expected-error {{declaration of 'T' shadows template parameter}} +}; + +template<typename T> // expected-note {{declared here}} +void f(int T) {} // expected-error {{declaration of 'T' shadows template parameter}} + +// 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 {}; +} +namespace B { +  template<typename T> void T() {} +} +namespace C { +  template<typename T> int T; +} | 

