re PR c++/48945 ([C++0x] static constexpr member function cannot be defined out-of...
authorJason Merrill <jason@redhat.com>
Sat, 21 May 2011 22:01:45 +0000 (18:01 -0400)
committerJason Merrill <jason@gcc.gnu.org>
Sat, 21 May 2011 22:01:45 +0000 (18:01 -0400)
PR c++/48945
* decl.c (grokdeclarator): Don't add set const function-cv-qual
for constexpr fns to memfn_quals, just add it to the type.
(revert_static_member_fn): Don't complain about quals.
(check_static_quals): New.
(grokfndecl): Call it.
(start_preparsed_function): Don't call revert_static_member_fn.

From-SVN: r174007

gcc/cp/ChangeLog
gcc/cp/decl.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/cpp0x/constexpr-static7.C

index 65479eabdc3ed1bab6e7c7a701e22608642e0719..d487e84ac5bd77d6f3052c3692b95f8883b5945b 100644 (file)
@@ -1,5 +1,13 @@
 2011-05-20  Jason Merrill  <jason@redhat.com>
 
+       PR c++/48945
+       * decl.c (grokdeclarator): Don't add set const function-cv-qual
+       for constexpr fns to memfn_quals, just add it to the type.
+       (revert_static_member_fn): Don't complain about quals.
+       (check_static_quals): New.
+       (grokfndecl): Call it.
+       (start_preparsed_function): Don't call revert_static_member_fn.
+
        PR c++/48945
        * decl.c (revert_static_member_fn): Ignore const on constexpr fn.
 
index 598af1c482efa8ed4bf3604f63eb90c5a438b408..733157a3dfa7275e98a85ab9e6ca061954678703 100644 (file)
@@ -6960,6 +6960,17 @@ build_this_parm (tree type, cp_cv_quals quals)
   return parm;
 }
 
+/* DECL is a static member function.  Complain if it was declared
+   with function-cv-quals.  */
+
+static void
+check_static_quals (tree decl, cp_cv_quals quals)
+{
+  if (quals != TYPE_UNQUALIFIED)
+    error ("static member function %q#D declared with type qualifiers",
+          decl);
+}
+
 /* CTYPE is class type, or null if non-class.
    TYPE is type this FUNCTION_DECL should have, either FUNCTION_TYPE
    or METHOD_TYPE.
@@ -7241,6 +7252,9 @@ grokfndecl (tree ctype,
   if (decl == error_mark_node)
     return NULL_TREE;
 
+  if (DECL_STATIC_FUNCTION_P (decl))
+    check_static_quals (decl, quals);
+
   if (attrlist)
     {
       cplus_decl_attributes (&decl, *attrlist, 0);
@@ -7290,9 +7304,11 @@ grokfndecl (tree ctype,
 
          if (DECL_STATIC_FUNCTION_P (old_decl)
              && TREE_CODE (TREE_TYPE (decl)) == METHOD_TYPE)
-           /* Remove the `this' parm added by grokclassfn.
-              XXX Isn't this done in start_function, too?  */
-           revert_static_member_fn (decl);
+           {
+             /* Remove the `this' parm added by grokclassfn.  */
+             revert_static_member_fn (decl);
+             check_static_quals (decl, quals);
+           }
          if (DECL_ARTIFICIAL (old_decl))
            {
              error ("definition of implicitly-declared %qD", old_decl);
@@ -9356,12 +9372,6 @@ grokdeclarator (const cp_declarator *declarator,
   if (ctype == NULL_TREE && decl_context == FIELD && friendp == 0)
     ctype = current_class_type;
 
-  /* A constexpr non-static member function is implicitly const.  */
-  if (constexpr_p && ctype && staticp == 0
-      && TREE_CODE (type) == FUNCTION_TYPE
-      && sfk != sfk_constructor && sfk != sfk_destructor)
-    memfn_quals |= TYPE_QUAL_CONST;
-
   /* Now TYPE has the actual type.  */
 
   if (returned_attrs)
@@ -9733,7 +9743,12 @@ grokdeclarator (const cp_declarator *declarator,
 
   if (ctype && TREE_CODE (type) == FUNCTION_TYPE && staticp < 2
       && !NEW_DELETE_OPNAME_P (unqualified_id))
-    type = build_memfn_type (type, ctype, memfn_quals);
+    {
+      cp_cv_quals real_quals = memfn_quals;
+      if (constexpr_p && sfk != sfk_constructor && sfk != sfk_destructor)
+       real_quals |= TYPE_QUAL_CONST;
+      type = build_memfn_type (type, ctype, real_quals);
+    }
 
   {
     tree decl;
@@ -12373,12 +12388,8 @@ start_preparsed_function (tree decl1, tree attrs, int flags)
 
   /* Sometimes we don't notice that a function is a static member, and
      build a METHOD_TYPE for it.  Fix that up now.  */
-  if (ctype != NULL_TREE && DECL_STATIC_FUNCTION_P (decl1)
-      && TREE_CODE (TREE_TYPE (decl1)) == METHOD_TYPE)
-    {
-      revert_static_member_fn (decl1);
-      ctype = NULL_TREE;
-    }
+  gcc_assert (!(ctype != NULL_TREE && DECL_STATIC_FUNCTION_P (decl1)
+               && TREE_CODE (TREE_TYPE (decl1)) == METHOD_TYPE));
 
   /* Set up current_class_type, and enter the scope of the class, if
      appropriate.  */
@@ -13578,14 +13589,8 @@ revert_static_member_fn (tree decl)
   cp_cv_quals quals = type_memfn_quals (stype);
 
   if (quals != TYPE_UNQUALIFIED)
-    {
-      if (quals == TYPE_QUAL_CONST && DECL_DECLARED_CONSTEXPR_P (decl))
-       /* The const was implicit, don't complain.  */;
-      else
-       error ("static member function %q#D declared with type qualifiers",
-              decl);
-      stype = apply_memfn_quals (stype, TYPE_UNQUALIFIED);
-    }
+    stype = apply_memfn_quals (stype, TYPE_UNQUALIFIED);
+
   TREE_TYPE (decl) = stype;
 
   if (DECL_ARGUMENTS (decl))
index 9e01b4e9813cc833e170df70d017dd95b85c64e4..61afdb00e2e02840c603fe3ae3783c60da1b4102 100644 (file)
@@ -1,5 +1,7 @@
 2011-05-20  Jason Merrill  <jason@redhat.com>
 
+       * g++.dg/cpp0x/constexpr-static7.C: Extend.
+
        * g++.dg/cpp0x/constexpr-static7.C: New.
 
        * g++.dg/cpp0x/enum12.C: New.
index ba4a25184076828c7813ab50c3e8a4e15b0e326b..e46ddafd7028b5126cda274de1ba28da74a19038 100644 (file)
@@ -3,6 +3,8 @@
 
 struct A {
   static constexpr bool is();
+  static constexpr bool is_not();
 };
 
 constexpr bool A::is() { return true; }
+constexpr bool A::is_not() const { return true; } // { dg-error "static" }