r192846 - PR17592: Ensure we diagnose shadowing a template parameter with a local extern

Richard Smith richard-llvm at metafoo.co.uk
Wed Oct 16 14:12:00 PDT 2013


Author: rsmith
Date: Wed Oct 16 16:12:00 2013
New Revision: 192846

URL: http://llvm.org/viewvc/llvm-project?rev=192846&view=rev
Log:
PR17592: Ensure we diagnose shadowing a template parameter with a local extern
declaration.

Added:
    cfe/trunk/test/CXX/temp/temp.res/temp.local/p6.cpp
Modified:
    cfe/trunk/lib/Sema/SemaLookup.cpp

Modified: cfe/trunk/lib/Sema/SemaLookup.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaLookup.cpp?rev=192846&r1=192845&r2=192846&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaLookup.cpp (original)
+++ cfe/trunk/lib/Sema/SemaLookup.cpp Wed Oct 16 16:12:00 2013
@@ -930,8 +930,10 @@ bool Sema::CppLookupName(LookupResult &R
             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;
           }

Added: cfe/trunk/test/CXX/temp/temp.res/temp.local/p6.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/temp/temp.res/temp.local/p6.cpp?rev=192846&view=auto
==============================================================================
--- cfe/trunk/test/CXX/temp/temp.res/temp.local/p6.cpp (added)
+++ cfe/trunk/test/CXX/temp/temp.res/temp.local/p6.cpp Wed Oct 16 16:12:00 2013
@@ -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;
+}





More information about the cfe-commits mailing list