decl.c (grokfndecl): Handle separately <inline> and <constexpr> error messages.
authorPaolo Carlini <paolo.carlini@oracle.com>
Tue, 26 Mar 2013 10:23:59 +0000 (10:23 +0000)
committerPaolo Carlini <paolo@gcc.gnu.org>
Tue, 26 Mar 2013 10:23:59 +0000 (10:23 +0000)
/cp
2013-03-26  Paolo Carlini  <paolo.carlini@oracle.com>

* decl.c (grokfndecl): Handle separately <inline> and <constexpr>
error messages.

* decl.c (grokdeclarator): Declare typedef_p and use it everywhere.

/testsuite
2013-03-26  Paolo Carlini  <paolo.carlini@oracle.com>

* g++.dg/cpp0x/constexpr-friend-2.C: New.
* g++.dg/cpp0x/constexpr-main.C: Likewise.

From-SVN: r197097

gcc/cp/ChangeLog
gcc/cp/decl.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/cpp0x/constexpr-friend-2.C [new file with mode: 0644]
gcc/testsuite/g++.dg/cpp0x/constexpr-main.C [new file with mode: 0644]

index 6aaf1ddbebc5125f5973186b04dee4446a326573..3dfb31ad4b4eb143a935c4a123b963af697da506 100644 (file)
@@ -1,3 +1,10 @@
+2013-03-26  Paolo Carlini  <paolo.carlini@oracle.com>
+
+       * decl.c (grokfndecl): Handle separately <inline> and <constexpr>
+       error messages.
+
+       * decl.c (grokdeclarator): Declare typedef_p and use it everywhere.
+
 2013-03-25  Jason Merrill  <jason@redhat.com>
 
        PR c++/56699
index 2e5910cf68e91dc679574ed7117b3789fba26088..a82132882159d7fceb4bb6ede9011106a5f8eb18 100644 (file)
@@ -7427,13 +7427,16 @@ grokfndecl (tree ctype,
              return NULL_TREE;
            }
 
+         if (inlinep & 1)
+           error ("%<inline%> is not allowed in declaration of friend "
+                  "template specialization %qD",
+                  decl);
+         if (inlinep & 2)
+           error ("%<constexpr%> is not allowed in declaration of friend "
+                  "template specialization %qD",
+                  decl);
          if (inlinep)
-           {
-             error ("%<inline%> is not allowed in declaration of friend "
-                    "template specialization %qD",
-                    decl);
-             return NULL_TREE;
-           }
+           return NULL_TREE;
        }
     }
 
@@ -7472,8 +7475,10 @@ grokfndecl (tree ctype,
     {
       if (PROCESSING_REAL_TEMPLATE_DECL_P())
        error ("cannot declare %<::main%> to be a template");
-      if (inlinep)
+      if (inlinep & 1)
        error ("cannot declare %<::main%> to be inline");
+      if (inlinep & 2)
+       error ("cannot declare %<::main%> to be constexpr");
       if (!publicp)
        error ("cannot declare %<::main%> to be static");
       inlinep = 0;
@@ -8651,6 +8656,7 @@ grokdeclarator (const cp_declarator *declarator,
   bool parameter_pack_p = declarator? declarator->parameter_pack_p : false;
   bool template_type_arg = false;
   bool template_parm_flag = false;
+  bool typedef_p = decl_spec_seq_has_spec_p (declspecs, ds_typedef);
   bool constexpr_p = decl_spec_seq_has_spec_p (declspecs, ds_constexpr);
   source_location saved_loc = input_location;
   const char *errmsg;
@@ -8862,7 +8868,7 @@ grokdeclarator (const cp_declarator *declarator,
 
   if (dname && IDENTIFIER_OPNAME_P (dname))
     {
-      if (decl_spec_seq_has_spec_p (declspecs, ds_typedef))
+      if (typedef_p)
        {
          error ("declaration of %qD as %<typedef%>", dname);
          return error_mark_node;
@@ -8900,7 +8906,7 @@ grokdeclarator (const cp_declarator *declarator,
   if (name == NULL)
     name = decl_context == PARM ? "parameter" : "type name";
 
-  if (constexpr_p && decl_spec_seq_has_spec_p (declspecs, ds_typedef))
+  if (constexpr_p && typedef_p)
     {
       error ("%<constexpr%> cannot appear in a typedef declaration");
       return error_mark_node;
@@ -9198,7 +9204,7 @@ grokdeclarator (const cp_declarator *declarator,
   /* Issue errors about use of storage classes for parameters.  */
   if (decl_context == PARM)
     {
-      if (decl_spec_seq_has_spec_p (declspecs, ds_typedef))
+      if (typedef_p)
        {
          error ("typedef declaration invalid in parameter declaration");
          return error_mark_node;
@@ -9242,7 +9248,7 @@ grokdeclarator (const cp_declarator *declarator,
       && ((storage_class
           && storage_class != sc_extern
           && storage_class != sc_static)
-         || decl_spec_seq_has_spec_p (declspecs, ds_typedef)))
+         || typedef_p))
     {
       error ("multiple storage classes in declaration of %qs", name);
       thread_p = false;
@@ -9256,7 +9262,7 @@ grokdeclarator (const cp_declarator *declarator,
          && (storage_class == sc_register
              || storage_class == sc_auto))
        ;
-      else if (decl_spec_seq_has_spec_p (declspecs, ds_typedef))
+      else if (typedef_p)
        ;
       else if (decl_context == FIELD
               /* C++ allows static class elements.  */
@@ -9866,8 +9872,7 @@ grokdeclarator (const cp_declarator *declarator,
              return error_mark_node;
            }
        }
-      else if (decl_spec_seq_has_spec_p (declspecs, ds_typedef)
-              && current_class_type)
+      else if (typedef_p && current_class_type)
        {
          error ("cannot declare member %<%T::%s%> within %qT",
                 ctype, name, current_class_type);
@@ -9944,8 +9949,7 @@ grokdeclarator (const cp_declarator *declarator,
          error ("non-member %qs cannot be declared %<mutable%>", name);
          storage_class = sc_none;
        }
-      else if (decl_context == TYPENAME
-              || decl_spec_seq_has_spec_p (declspecs, ds_typedef))
+      else if (decl_context == TYPENAME || typedef_p)
        {
          error ("non-object member %qs cannot be declared %<mutable%>", name);
          storage_class = sc_none;
@@ -9975,7 +9979,7 @@ grokdeclarator (const cp_declarator *declarator,
     }
 
   /* If this is declaring a typedef name, return a TYPE_DECL.  */
-  if (decl_spec_seq_has_spec_p (declspecs, ds_typedef) && decl_context != TYPENAME)
+  if (typedef_p && decl_context != TYPENAME)
     {
       tree decl;
 
index 46ad1ece5a849ed29f49ea8e23c779d6f3ad028b..52a1a8d38d79936748b2bd4a459f31d99e5be72a 100644 (file)
@@ -1,3 +1,8 @@
+2013-03-26  Paolo Carlini  <paolo.carlini@oracle.com>
+
+       * g++.dg/cpp0x/constexpr-friend-2.C: New.
+       * g++.dg/cpp0x/constexpr-main.C: Likewise.
+
 2013-03-25  Paolo Carlini  <paolo.carlini@oracle.com>
 
        PR c++/56722
diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-friend-2.C b/gcc/testsuite/g++.dg/cpp0x/constexpr-friend-2.C
new file mode 100644 (file)
index 0000000..36799b4
--- /dev/null
@@ -0,0 +1,7 @@
+// { dg-do compile { target c++11 } }
+
+template<typename T> void f(T);
+
+template <class T> class A {
+  friend constexpr void f<>(int);  // { dg-error "'constexpr' is not allowed" }
+};
diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-main.C b/gcc/testsuite/g++.dg/cpp0x/constexpr-main.C
new file mode 100644 (file)
index 0000000..42720ad
--- /dev/null
@@ -0,0 +1,3 @@
+// { dg-do compile { target c++11 } }
+
+constexpr int main ();  // { dg-error "constexpr" }