miyuki updated this revision to Diff 126325.
miyuki added a comment.

Added a test for thead_local.


https://reviews.llvm.org/D40705

Files:
  include/clang/Basic/DiagnosticParseKinds.td
  lib/Parse/ParseTemplate.cpp
  test/CXX/temp/temp.param/p2-cpp11.cpp
  test/CXX/temp/temp.param/p2.cpp


Index: test/CXX/temp/temp.param/p2.cpp
===================================================================
--- test/CXX/temp/temp.param/p2.cpp
+++ test/CXX/temp/temp.param/p2.cpp
@@ -1,5 +1,4 @@
 // RUN: %clang_cc1 -fsyntax-only -verify %s
-// expected-no-diagnostics
 
 // There is no semantic difference between class and typename in a
 // template-parameter. typename followed by an unqualified-id names a
@@ -13,7 +12,8 @@
 template<typename T, typename X<T>::type Value> struct Y1;
 
 // A storage class shall not be specified in a template-parameter declaration.
-template<static int Value> struct Z; // FIXME: expect an error
+template<static int Value> struct Z0; // expected-error {{storage class 
specified for template parameter 'Value'}}
+template<extern int> struct Z1; // expected-error {{storage class specified 
for template parameter}}
 
 // Make sure that we properly disambiguate non-type template parameters that
 // start with 'class'.
Index: test/CXX/temp/temp.param/p2-cpp11.cpp
===================================================================
--- /dev/null
+++ test/CXX/temp/temp.param/p2-cpp11.cpp
@@ -0,0 +1,5 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
+
+// A storage class shall not be specified in a template-parameter declaration.
+template<thread_local int Value> struct Z0; // expected-error {{storage class 
specified for template parameter 'Value'}}
+template<thread_local int> struct Z1; // expected-error {{storage class 
specified for template parameter}}
Index: lib/Parse/ParseTemplate.cpp
===================================================================
--- lib/Parse/ParseTemplate.cpp
+++ lib/Parse/ParseTemplate.cpp
@@ -686,6 +686,22 @@
     return nullptr;
   }
 
+  // C++ [temp.param]p2:
+  //   A storage class shall not be specified in a template-parameter
+  //   declaration.
+  auto ReportStorageClass = [this, &ParamDecl](SourceLocation Loc) {
+    if (ParamDecl.getIdentifier())
+      Diag(Loc, diag::err_storage_class_template_parameter)
+        << ParamDecl.getIdentifier() << FixItHint::CreateRemoval(Loc);
+    else
+      Diag(Loc, diag::err_storage_class_template_parameter_anon)
+        << FixItHint::CreateRemoval(Loc);
+  };
+  if (DS.getStorageClassSpec() != DeclSpec::SCS_unspecified)
+    ReportStorageClass(DS.getStorageClassSpecLoc());
+  if (DS.getThreadStorageClassSpec() != DeclSpec::TSCS_unspecified)
+    ReportStorageClass(DS.getThreadStorageClassSpecLoc());
+
   // Recover from misplaced ellipsis.
   SourceLocation EllipsisLoc;
   if (TryConsumeToken(tok::ellipsis, EllipsisLoc))
Index: include/clang/Basic/DiagnosticParseKinds.td
===================================================================
--- include/clang/Basic/DiagnosticParseKinds.td
+++ include/clang/Basic/DiagnosticParseKinds.td
@@ -668,6 +668,11 @@
 def warn_missing_dependent_template_keyword : ExtWarn<
   "use 'template' keyword to treat '%0' as a dependent template name">;
 
+def err_storage_class_template_parameter : Error<
+  "storage class specified for template parameter %0">;
+def err_storage_class_template_parameter_anon : Error<
+  "storage class specified for template parameter">;
+
 def ext_extern_template : Extension<
   "extern templates are a C++11 extension">, InGroup<CXX11>;
 def warn_cxx98_compat_extern_template : Warning<


Index: test/CXX/temp/temp.param/p2.cpp
===================================================================
--- test/CXX/temp/temp.param/p2.cpp
+++ test/CXX/temp/temp.param/p2.cpp
@@ -1,5 +1,4 @@
 // RUN: %clang_cc1 -fsyntax-only -verify %s
-// expected-no-diagnostics
 
 // There is no semantic difference between class and typename in a
 // template-parameter. typename followed by an unqualified-id names a
@@ -13,7 +12,8 @@
 template<typename T, typename X<T>::type Value> struct Y1;
 
 // A storage class shall not be specified in a template-parameter declaration.
-template<static int Value> struct Z; // FIXME: expect an error
+template<static int Value> struct Z0; // expected-error {{storage class specified for template parameter 'Value'}}
+template<extern int> struct Z1; // expected-error {{storage class specified for template parameter}}
 
 // Make sure that we properly disambiguate non-type template parameters that
 // start with 'class'.
Index: test/CXX/temp/temp.param/p2-cpp11.cpp
===================================================================
--- /dev/null
+++ test/CXX/temp/temp.param/p2-cpp11.cpp
@@ -0,0 +1,5 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
+
+// A storage class shall not be specified in a template-parameter declaration.
+template<thread_local int Value> struct Z0; // expected-error {{storage class specified for template parameter 'Value'}}
+template<thread_local int> struct Z1; // expected-error {{storage class specified for template parameter}}
Index: lib/Parse/ParseTemplate.cpp
===================================================================
--- lib/Parse/ParseTemplate.cpp
+++ lib/Parse/ParseTemplate.cpp
@@ -686,6 +686,22 @@
     return nullptr;
   }
 
+  // C++ [temp.param]p2:
+  //   A storage class shall not be specified in a template-parameter
+  //   declaration.
+  auto ReportStorageClass = [this, &ParamDecl](SourceLocation Loc) {
+    if (ParamDecl.getIdentifier())
+      Diag(Loc, diag::err_storage_class_template_parameter)
+        << ParamDecl.getIdentifier() << FixItHint::CreateRemoval(Loc);
+    else
+      Diag(Loc, diag::err_storage_class_template_parameter_anon)
+        << FixItHint::CreateRemoval(Loc);
+  };
+  if (DS.getStorageClassSpec() != DeclSpec::SCS_unspecified)
+    ReportStorageClass(DS.getStorageClassSpecLoc());
+  if (DS.getThreadStorageClassSpec() != DeclSpec::TSCS_unspecified)
+    ReportStorageClass(DS.getThreadStorageClassSpecLoc());
+
   // Recover from misplaced ellipsis.
   SourceLocation EllipsisLoc;
   if (TryConsumeToken(tok::ellipsis, EllipsisLoc))
Index: include/clang/Basic/DiagnosticParseKinds.td
===================================================================
--- include/clang/Basic/DiagnosticParseKinds.td
+++ include/clang/Basic/DiagnosticParseKinds.td
@@ -668,6 +668,11 @@
 def warn_missing_dependent_template_keyword : ExtWarn<
   "use 'template' keyword to treat '%0' as a dependent template name">;
 
+def err_storage_class_template_parameter : Error<
+  "storage class specified for template parameter %0">;
+def err_storage_class_template_parameter_anon : Error<
+  "storage class specified for template parameter">;
+
 def ext_extern_template : Extension<
   "extern templates are a C++11 extension">, InGroup<CXX11>;
 def warn_cxx98_compat_extern_template : Warning<
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to