summaryrefslogtreecommitdiff
path: root/gcc/cp/class.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/cp/class.c')
-rw-r--r--gcc/cp/class.c70
1 files changed, 39 insertions, 31 deletions
diff --git a/gcc/cp/class.c b/gcc/cp/class.c
index d29d6615f33..c798ba2833f 100644
--- a/gcc/cp/class.c
+++ b/gcc/cp/class.c
@@ -2677,7 +2677,8 @@ add_implicitly_declared_members (tree t,
CLASSTYPE_LAZY_COPY_CTOR (t) = 1;
}
- /* Currently only lambdas get a lazy move ctor. */
+ /* Currently only lambdas get a lazy move ctor, but N2987 adds them for
+ other classes. */
if (LAMBDA_TYPE_P (t))
CLASSTYPE_LAZY_MOVE_CTOR (t) = 1;
@@ -3843,7 +3844,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;
}
}
@@ -4103,6 +4104,7 @@ adjust_clone_args (tree decl)
/* A default parameter has been added. Adjust the
clone's parameters. */
tree exceptions = TYPE_RAISES_EXCEPTIONS (TREE_TYPE (clone));
+ tree attrs = TYPE_ATTRIBUTES (TREE_TYPE (clone));
tree basetype = TYPE_METHOD_BASETYPE (TREE_TYPE (clone));
tree type;
@@ -4120,6 +4122,8 @@ adjust_clone_args (tree decl)
clone_parms);
if (exceptions)
type = build_exception_variant (type, exceptions);
+ if (attrs)
+ type = cp_build_type_attribute_variant (type, attrs);
TREE_TYPE (clone) = type;
clone_parms = NULL_TREE;
@@ -4174,17 +4178,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 +4242,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 +4335,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 +4433,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
@@ -5514,6 +5519,9 @@ finish_struct (tree t, tree attributes)
if (DECL_PURE_VIRTUAL_P (x))
VEC_safe_push (tree, gc, CLASSTYPE_PURE_VIRTUALS (t), x);
complete_vars (t);
+
+ /* Remember current #pragma pack value. */
+ TYPE_PRECISION (t) = maximum_field_alignment;
}
else
finish_struct_1 (t);