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

Mikhail Maltsev via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Fri Dec 1 02:12:16 PST 2017


miyuki created this revision.

[Parser] Diagnose storage classes in template parameter declarations

According to the C++ Standard [temp.param]p2:

  A storage class shall not be specified in a template-parameter
  declaration.

This patch implements a diagnostic for this restriction.


https://reviews.llvm.org/D40705

Files:
  include/clang/Basic/DiagnosticParseKinds.td
  lib/Parse/ParseTemplate.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: 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 = [&](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<


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D40705.125087.patch
Type: text/x-patch
Size: 2744 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20171201/3e67e67d/attachment.bin>


More information about the cfe-commits mailing list