X-Git-Url: http://git.sourceforge.jp/view?p=pf3gnuchains%2Fgcc-fork.git;a=blobdiff_plain;f=gcc%2Fcp%2Fclass.c;h=d737bdf705515a5abf06aa81ddbf1295f9bf00c6;hp=d29d6615f331552c1f502040ba84b0c242ed5923;hb=e8c9f615d3856ee3d8635e8ec92bbd2fa2cfa3a9;hpb=7a7cd28e1bfb950ed3d49723f8e5c98ccfe47bcf diff --git a/gcc/cp/class.c b/gcc/cp/class.c index d29d6615f33..d737bdf7055 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