diff mbox

[c++-concepts] Diagnostics patch

Message ID CANq5Syt6wrPQd1Y7Ts-LFcgvXSbVRngTqgxu7aj3dQm3WJfH-g@mail.gmail.com
State New
Headers show

Commit Message

Andrew Sutton Oct. 30, 2013, 2:08 p.m. UTC
Applying a patch from Ville that adds diagnostics for the concept
specifier. Thanks Ville!

2013-10-30  Ville Voutilainen  <ville.voutilainen@gmail.com>
        * gcc/cp/decl.c (grokdeclarator): Reject concept keyword
        in typedefs, function parameters, data members, non-static
        member functions and variables. Allow static member functions
        to be concepts.

Andrew Sutton
diff mbox

Patch

Index: gcc/cp/decl.c
===================================================================
--- gcc/cp/decl.c	(revision 204092)
+++ gcc/cp/decl.c	(working copy)
@@ -9074,6 +9074,12 @@ 
   if (name == NULL)
     name = decl_context == PARM ? "parameter" : "type name";
 
+  if (concept_p && typedef_p)
+    {
+      error ("%<concept%> cannot appear in a typedef declaration");
+      return error_mark_node;
+    }
+
   if (constexpr_p && typedef_p)
     {
       error ("%<constexpr%> cannot appear in a typedef declaration");
@@ -9387,9 +9393,12 @@ 
 	       || thread_p)
 	error ("storage class specifiers invalid in parameter declarations");
 
+      /* Function parameters cannot be concept. */
+      if (concept_p)
+          error ("a parameter cannot be declared %<concept%>");
       /* Function parameters cannot be constexpr.  If we saw one, moan
          and pretend it wasn't there.  */
-      if (constexpr_p)
+      else if (constexpr_p)
         {
           error ("a parameter cannot be declared %<constexpr%>");
           constexpr_p = 0;
@@ -10619,6 +10628,11 @@ 
 			   uqname, ctype);
 		    return error_mark_node;
 		  }
+                if (concept_p)
+                  {
+                    error ("a destructor cannot be %<concept%>");
+                    return error_mark_node;
+                  }
                 if (constexpr_p)
                   {
                     error ("a destructor cannot be %<constexpr%>");
@@ -10632,6 +10646,12 @@ 
 		       id_declarator->u.id.unqualified_name);
 		return error_mark_node;
 	      }
+	    if (sfk == sfk_constructor)
+                if (concept_p)
+                  {
+                    error ("a constructor cannot be %<concept%>");
+                    return error_mark_node;
+                  }
 
 	    /* Tell grokfndecl if it needs to set TREE_PUBLIC on the node.  */
 	    function_context = (ctype != NULL_TREE) ?
@@ -10645,7 +10665,7 @@ 
 			       unqualified_id,
 			       virtualp, flags, memfn_quals, rqual, raises,
 			       friendp ? -1 : 0, friendp, publicp,
-                               inlinep | (2 * constexpr_p),
+                               inlinep | (2 * constexpr_p) | (4 * concept_p),
 			       sfk,
 			       funcdef_flag, template_count, in_namespace,
 			       attrlist, declarator->id_loc);
@@ -10739,8 +10759,12 @@ 
 		    if (declspecs->gnu_thread_keyword_p)
 		      DECL_GNU_TLS_P (decl) = true;
 		  }
-
-		if (constexpr_p && !initialized)
+		if (concept_p)
+		  // TODO: This needs to be revisited once variable
+		  // templates are supported
+		    error ("static data member %qE declared %<concept%>",
+			   unqualified_id);
+		else if (constexpr_p && !initialized)
 		  {
 		    error ("constexpr static data member %qD must have an "
 			   "initializer", decl);
@@ -10749,7 +10773,10 @@ 
 	      }
 	    else
 	      {
-                if (constexpr_p)
+		if (concept_p)
+		  error ("non-static data member %qE declared %<concept%>",
+			 unqualified_id);
+                else if (constexpr_p)
 		  {
 		    error ("non-static data member %qE declared %<constexpr%>",
 			   unqualified_id);
@@ -10897,6 +10924,15 @@ 
       {
 	/* It's a variable.  */
 
+	// TODO: This needs to be revisited once variable
+	// templates are supported
+	if (concept_p)
+	  {
+	    error ("variable %qE declared %<concept%>",
+		   unqualified_id);
+	    return error_mark_node;
+	  }
+	
 	/* An uninitialized decl with `extern' is a reference.  */
 	decl = grokvardecl (type, unqualified_id,
 			    declspecs,
Index: gcc/testsuite/g++.dg/concepts/decl-diagnose.C
===================================================================
--- gcc/testsuite/g++.dg/concepts/decl-diagnose.C	(revision 0)
+++ gcc/testsuite/g++.dg/concepts/decl-diagnose.C	(working copy)
@@ -0,0 +1,20 @@ 
+// { dg-options "-std=c++11" }
+typedef concept int CINT; // { dg-error "'concept' cannot appear in a typedef declaration" }
+
+void f(concept int); // { dg-error "a parameter cannot be declared 'concept'" }
+
+concept int f2(); // { dg-error "result must be bool" }
+concept bool f3();
+
+struct X
+{
+  concept int f4(); // { dg-error "result must be bool|declared with function parameters" }
+  concept bool f5(); // { dg-error "declared with function parameters" }
+  static concept bool f6();
+  static concept bool x; // { dg-error "declared 'concept'" }
+  concept int x2; // { dg-error "declared 'concept'" }
+  concept ~X(); // { dg-error "a destructor cannot be 'concept'" }
+  concept X(); // { dg-error "a constructor cannot be 'concept'" }
+};
+
+concept bool X2; // { dg-error "declared 'concept'" }