aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2011-05-21 18:01:45 -0400
committerJason Merrill <jason@gcc.gnu.org>2011-05-21 18:01:45 -0400
commitfa4a1e468dd4fc44b1d805142d60ff1c3330276e (patch)
tree57ee63c2245a76365777794f04ac71029e7c2bb2
parentb6413764c0dd056f000c6541913e95af9bddbb3e (diff)
downloadgcc-fa4a1e468dd4fc44b1d805142d60ff1c3330276e.zip
gcc-fa4a1e468dd4fc44b1d805142d60ff1c3330276e.tar.gz
gcc-fa4a1e468dd4fc44b1d805142d60ff1c3330276e.tar.bz2
re PR c++/48945 ([C++0x] static constexpr member function cannot be defined out-of class)
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
-rw-r--r--gcc/cp/ChangeLog8
-rw-r--r--gcc/cp/decl.c53
-rw-r--r--gcc/testsuite/ChangeLog2
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/constexpr-static7.C2
4 files changed, 41 insertions, 24 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 65479ea..d487e84 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,6 +1,14 @@
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.
PR c++/48780
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index 598af1c..733157a 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -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))
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 9e01b4e..61afdb0 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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.
diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-static7.C b/gcc/testsuite/g++.dg/cpp0x/constexpr-static7.C
index ba4a251..e46ddaf 100644
--- a/gcc/testsuite/g++.dg/cpp0x/constexpr-static7.C
+++ b/gcc/testsuite/g++.dg/cpp0x/constexpr-static7.C
@@ -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" }