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
This commit is contained in:
parent
b6413764c0
commit
fa4a1e468d
|
@ -1,5 +1,13 @@
|
||||||
2011-05-20 Jason Merrill <jason@redhat.com>
|
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
|
PR c++/48945
|
||||||
* decl.c (revert_static_member_fn): Ignore const on constexpr fn.
|
* decl.c (revert_static_member_fn): Ignore const on constexpr fn.
|
||||||
|
|
||||||
|
|
|
@ -6960,6 +6960,17 @@ build_this_parm (tree type, cp_cv_quals quals)
|
||||||
return parm;
|
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.
|
/* CTYPE is class type, or null if non-class.
|
||||||
TYPE is type this FUNCTION_DECL should have, either FUNCTION_TYPE
|
TYPE is type this FUNCTION_DECL should have, either FUNCTION_TYPE
|
||||||
or METHOD_TYPE.
|
or METHOD_TYPE.
|
||||||
|
@ -7241,6 +7252,9 @@ grokfndecl (tree ctype,
|
||||||
if (decl == error_mark_node)
|
if (decl == error_mark_node)
|
||||||
return NULL_TREE;
|
return NULL_TREE;
|
||||||
|
|
||||||
|
if (DECL_STATIC_FUNCTION_P (decl))
|
||||||
|
check_static_quals (decl, quals);
|
||||||
|
|
||||||
if (attrlist)
|
if (attrlist)
|
||||||
{
|
{
|
||||||
cplus_decl_attributes (&decl, *attrlist, 0);
|
cplus_decl_attributes (&decl, *attrlist, 0);
|
||||||
|
@ -7290,9 +7304,11 @@ grokfndecl (tree ctype,
|
||||||
|
|
||||||
if (DECL_STATIC_FUNCTION_P (old_decl)
|
if (DECL_STATIC_FUNCTION_P (old_decl)
|
||||||
&& TREE_CODE (TREE_TYPE (decl)) == METHOD_TYPE)
|
&& TREE_CODE (TREE_TYPE (decl)) == METHOD_TYPE)
|
||||||
/* Remove the `this' parm added by grokclassfn.
|
{
|
||||||
XXX Isn't this done in start_function, too? */
|
/* Remove the `this' parm added by grokclassfn. */
|
||||||
revert_static_member_fn (decl);
|
revert_static_member_fn (decl);
|
||||||
|
check_static_quals (decl, quals);
|
||||||
|
}
|
||||||
if (DECL_ARTIFICIAL (old_decl))
|
if (DECL_ARTIFICIAL (old_decl))
|
||||||
{
|
{
|
||||||
error ("definition of implicitly-declared %qD", 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)
|
if (ctype == NULL_TREE && decl_context == FIELD && friendp == 0)
|
||||||
ctype = current_class_type;
|
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. */
|
/* Now TYPE has the actual type. */
|
||||||
|
|
||||||
if (returned_attrs)
|
if (returned_attrs)
|
||||||
|
@ -9733,7 +9743,12 @@ grokdeclarator (const cp_declarator *declarator,
|
||||||
|
|
||||||
if (ctype && TREE_CODE (type) == FUNCTION_TYPE && staticp < 2
|
if (ctype && TREE_CODE (type) == FUNCTION_TYPE && staticp < 2
|
||||||
&& !NEW_DELETE_OPNAME_P (unqualified_id))
|
&& !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;
|
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
|
/* Sometimes we don't notice that a function is a static member, and
|
||||||
build a METHOD_TYPE for it. Fix that up now. */
|
build a METHOD_TYPE for it. Fix that up now. */
|
||||||
if (ctype != NULL_TREE && DECL_STATIC_FUNCTION_P (decl1)
|
gcc_assert (!(ctype != NULL_TREE && DECL_STATIC_FUNCTION_P (decl1)
|
||||||
&& TREE_CODE (TREE_TYPE (decl1)) == METHOD_TYPE)
|
&& TREE_CODE (TREE_TYPE (decl1)) == METHOD_TYPE));
|
||||||
{
|
|
||||||
revert_static_member_fn (decl1);
|
|
||||||
ctype = NULL_TREE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Set up current_class_type, and enter the scope of the class, if
|
/* Set up current_class_type, and enter the scope of the class, if
|
||||||
appropriate. */
|
appropriate. */
|
||||||
|
@ -13578,14 +13589,8 @@ revert_static_member_fn (tree decl)
|
||||||
cp_cv_quals quals = type_memfn_quals (stype);
|
cp_cv_quals quals = type_memfn_quals (stype);
|
||||||
|
|
||||||
if (quals != TYPE_UNQUALIFIED)
|
if (quals != TYPE_UNQUALIFIED)
|
||||||
{
|
stype = apply_memfn_quals (stype, 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);
|
|
||||||
}
|
|
||||||
TREE_TYPE (decl) = stype;
|
TREE_TYPE (decl) = stype;
|
||||||
|
|
||||||
if (DECL_ARGUMENTS (decl))
|
if (DECL_ARGUMENTS (decl))
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
2011-05-20 Jason Merrill <jason@redhat.com>
|
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/constexpr-static7.C: New.
|
||||||
|
|
||||||
* g++.dg/cpp0x/enum12.C: New.
|
* g++.dg/cpp0x/enum12.C: New.
|
||||||
|
|
|
@ -3,6 +3,8 @@
|
||||||
|
|
||||||
struct A {
|
struct A {
|
||||||
static constexpr bool is();
|
static constexpr bool is();
|
||||||
|
static constexpr bool is_not();
|
||||||
};
|
};
|
||||||
|
|
||||||
constexpr bool A::is() { return true; }
|
constexpr bool A::is() { return true; }
|
||||||
|
constexpr bool A::is_not() const { return true; } // { dg-error "static" }
|
||||||
|
|
Loading…
Reference in New Issue