[PATCH] D40705: [Parser] Diagnose storage classes in template parameter declarations

Mikhail Maltsev via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Mon Dec 18 03:39:20 PST 2017


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

Merged two diagnostics into one


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)
+          << 1 << ParamDecl.getIdentifier() << FixItHint::CreateRemoval(Loc);
+    else
+      Diag(Loc, diag::err_storage_class_template_parameter)
+          << 0 << 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,9 @@
 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%select{| %1}0">;
+
 def ext_extern_template : Extension<
   "extern templates are a C++11 extension">, InGroup<CXX11>;
 def warn_cxx98_compat_extern_template : Warning<


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D40705.127324.patch
Type: text/x-patch
Size: 3221 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20171218/7768db03/attachment.bin>


More information about the cfe-commits mailing list