===================================================================
@@ -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,
===================================================================
@@ -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'" }