diff options
author | Jason Merrill <jason@redhat.com> | 2009-10-26 15:07:14 -0400 |
---|---|---|
committer | Jason Merrill <jason@gcc.gnu.org> | 2009-10-26 15:07:14 -0400 |
commit | 20f2653ef0f7f2d33ec3e5ce389ab72d4216ec2a (patch) | |
tree | 3a188f1a76fba7e0480a3fadf8f3fd90b1751852 /gcc/cp/class.c | |
parent | f96d6fd02e10a4f266c5c459461562887cbf0c6a (diff) | |
download | gcc-20f2653ef0f7f2d33ec3e5ce389ab72d4216ec2a.zip gcc-20f2653ef0f7f2d33ec3e5ce389ab72d4216ec2a.tar.gz gcc-20f2653ef0f7f2d33ec3e5ce389ab72d4216ec2a.tar.bz2 |
PR c++/38796, Core issue 906
PR c++/38796, Core issue 906
gcc/cp
* cp-tree.h (DECL_DEFAULTED_OUTSIDE_CLASS_P): New.
(DECL_DEFAULTED_IN_CLASS_P): New.
* class.c (user_provided_p): Non-static.
(check_methods): Use it.
(check_bases_and_members): Check defaulted fns.
(defaultable_fn_p): Move and rename to...
* method.c (defaultable_fn_check): ...this.
(defaulted_late_check): New.
* pt.c (tsubst_decl): Call it.
* decl2.c (grokfield): Adjust.
* decl.c (cp_finish_decl): Adjust.
(grok_special_member_properties): Use user_provided_p.
libstdc++-v3
* include/std/future (~Future_result_base): Default outside class
body.
* include/std/system_error (error_category()): Likewise.
* libsupc++/nested_exception.h (nested_exception): Remove
exception specifications from defaulted methods.
From-SVN: r153565
Diffstat (limited to 'gcc/cp/class.c')
-rw-r--r-- | gcc/cp/class.c | 61 |
1 files changed, 31 insertions, 30 deletions
diff --git a/gcc/cp/class.c b/gcc/cp/class.c index d29d661..d737bdf 100644 --- a/gcc/cp/class.c +++ b/gcc/cp/class.c @@ -3843,7 +3843,7 @@ check_methods (tree t) VEC_safe_push (tree, gc, CLASSTYPE_PURE_VIRTUALS (t), x); } /* All user-provided destructors are non-trivial. */ - if (DECL_DESTRUCTOR_P (x) && !DECL_DEFAULTED_FN (x)) + if (DECL_DESTRUCTOR_P (x) && user_provided_p (x)) TYPE_HAS_NONTRIVIAL_DESTRUCTOR (t) = 1; } } @@ -4174,17 +4174,17 @@ type_has_user_nondefault_constructor (tree t) } /* Returns true iff FN is a user-provided function, i.e. user-declared - and not defaulted at its first declaration. */ + and not defaulted at its first declaration; or explicit, private, + protected, or non-const. */ -static bool +bool user_provided_p (tree fn) { if (TREE_CODE (fn) == TEMPLATE_DECL) return true; else return (!DECL_ARTIFICIAL (fn) - && !(DECL_DEFAULTED_FN (fn) - && DECL_INITIALIZED_IN_CLASS_P (fn))); + && !DECL_DEFAULTED_IN_CLASS_P (fn)); } /* Returns true iff class T has a user-provided constructor. */ @@ -4238,31 +4238,6 @@ type_has_user_provided_default_constructor (tree t) return false; } -/* Returns true if FN can be explicitly defaulted. */ - -bool -defaultable_fn_p (tree fn) -{ - if (DECL_CONSTRUCTOR_P (fn)) - { - if (FUNCTION_FIRST_USER_PARMTYPE (fn) == void_list_node) - return true; - else if (copy_fn_p (fn) > 0 - && (TREE_CHAIN (FUNCTION_FIRST_USER_PARMTYPE (fn)) - == void_list_node)) - return true; - else - return false; - } - else if (DECL_DESTRUCTOR_P (fn)) - return true; - else if (DECL_ASSIGNMENT_OPERATOR_P (fn) - && DECL_OVERLOADED_OPERATOR_P (fn) == NOP_EXPR) - return copy_fn_p (fn); - else - return false; -} - /* Remove all zero-width bit-fields from T. */ static void @@ -4356,6 +4331,7 @@ check_bases_and_members (tree t) tree access_decls; bool saved_complex_asn_ref; bool saved_nontrivial_dtor; + tree fn; /* By default, we use const reference arguments and generate default constructors. */ @@ -4453,6 +4429,31 @@ check_bases_and_members (tree t) cant_have_const_ctor, no_const_asn_ref); + /* Check defaulted declarations here so we have cant_have_const_ctor + and don't need to worry about clones. */ + for (fn = TYPE_METHODS (t); fn; fn = TREE_CHAIN (fn)) + if (DECL_DEFAULTED_IN_CLASS_P (fn)) + { + int copy = copy_fn_p (fn); + if (copy > 0) + { + bool imp_const_p + = (DECL_CONSTRUCTOR_P (fn) ? !cant_have_const_ctor + : !no_const_asn_ref); + bool fn_const_p = (copy == 2); + + if (fn_const_p && !imp_const_p) + /* If the function is defaulted outside the class, we just + give the synthesis error. */ + error ("%q+D declared to take const reference, but implicit " + "declaration would take non-const", fn); + else if (imp_const_p && !fn_const_p) + error ("%q+D declared to take non-const reference cannot be " + "defaulted in the class body", fn); + } + defaulted_late_check (fn); + } + if (LAMBDA_TYPE_P (t)) { /* "The closure type associated with a lambda-expression has a deleted |