diff options
author | jason <jason@138bc75d-0d04-0410-961f-82ee72b054a4> | 2009-10-26 19:07:14 +0000 |
---|---|---|
committer | jason <jason@138bc75d-0d04-0410-961f-82ee72b054a4> | 2009-10-26 19:07:14 +0000 |
commit | e8c9f615d3856ee3d8635e8ec92bbd2fa2cfa3a9 (patch) | |
tree | 3a188f1a76fba7e0480a3fadf8f3fd90b1751852 /gcc/cp/method.c | |
parent | 7a7cd28e1bfb950ed3d49723f8e5c98ccfe47bcf (diff) | |
download | gcc-e8c9f615d3856ee3d8635e8ec92bbd2fa2cfa3a9.tar.gz |
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.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@153565 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/cp/method.c')
-rw-r--r-- | gcc/cp/method.c | 82 |
1 files changed, 82 insertions, 0 deletions
diff --git a/gcc/cp/method.c b/gcc/cp/method.c index e8b28d877d7..266406c7cd0 100644 --- a/gcc/cp/method.c +++ b/gcc/cp/method.c @@ -1130,6 +1130,88 @@ implicitly_declare_fn (special_function_kind kind, tree type, bool const_p) return fn; } +/* Gives any errors about defaulted functions which need to be deferred + until the containing class is complete. */ + +void +defaulted_late_check (tree fn) +{ + /* Complain about invalid signature for defaulted fn. */ + tree ctx = DECL_CONTEXT (fn); + special_function_kind kind = special_function_p (fn); + bool fn_const_p = (copy_fn_p (fn) == 2); + tree implicit_fn = implicitly_declare_fn (kind, ctx, fn_const_p); + + if (!same_type_p (TREE_TYPE (TREE_TYPE (fn)), + TREE_TYPE (TREE_TYPE (implicit_fn))) + || !compparms (TYPE_ARG_TYPES (TREE_TYPE (fn)), + TYPE_ARG_TYPES (TREE_TYPE (implicit_fn)))) + { + error ("defaulted declaration %q+D", fn); + error_at (DECL_SOURCE_LOCATION (fn), + "does not match expected signature %qD", implicit_fn); + } +} + +/* Returns true iff FN can be explicitly defaulted, and gives any + errors if defaulting FN is ill-formed. */ + +bool +defaultable_fn_check (tree fn) +{ + special_function_kind kind = sfk_none; + + if (DECL_CONSTRUCTOR_P (fn)) + { + if (FUNCTION_FIRST_USER_PARMTYPE (fn) == void_list_node) + kind = sfk_constructor; + else if (copy_fn_p (fn) > 0 + && (TREE_CHAIN (FUNCTION_FIRST_USER_PARMTYPE (fn)) + == void_list_node)) + kind = sfk_copy_constructor; + else if (move_fn_p (fn)) + kind = sfk_move_constructor; + } + else if (DECL_DESTRUCTOR_P (fn)) + kind = sfk_destructor; + else if (DECL_ASSIGNMENT_OPERATOR_P (fn) + && DECL_OVERLOADED_OPERATOR_P (fn) == NOP_EXPR + && copy_fn_p (fn)) + kind = sfk_assignment_operator; + + if (kind == sfk_none) + { + error ("%qD cannot be defaulted", fn); + return false; + } + else + { + tree t = FUNCTION_FIRST_USER_PARMTYPE (fn); + for (; t && t != void_list_node; t = TREE_CHAIN (t)) + if (TREE_PURPOSE (t)) + { + error ("defaulted function %q+D with default argument", fn); + break; + } + if (TYPE_BEING_DEFINED (DECL_CONTEXT (fn))) + { + if (DECL_NONCONVERTING_P (fn)) + error ("%qD declared explicit cannot be defaulted in the class " + "body", fn); + if (current_access_specifier != access_public_node) + error ("%qD declared with non-public access cannot be defaulted " + "in the class body", fn); + if (TYPE_RAISES_EXCEPTIONS (TREE_TYPE (fn))) + error ("function %q+D defaulted on its first declaration " + "must not have an exception-specification", fn); + } + else if (!processing_template_decl) + defaulted_late_check (fn); + + return true; + } +} + /* Add an implicit declaration to TYPE for the kind of function indicated by SFK. Return the FUNCTION_DECL for the new implicit declaration. */ |