Commit d0b0fbd9 by Jason Merrill Committed by Jason Merrill

Avoid calling a trivial default constructor.

	* class.c (default_ctor_p): New.
	(in_class_defaulted_default_constructor): Use it.
	(type_has_non_user_provided_default_constructor): Use it.
	* call.c (build_over_call): Handle trivial default constructor.
	* cp-tree.h: Declare default_ctor_p.

From-SVN: r239783
parent 9729a5d5
2016-08-15 Jason Merrill <jason@redhat.com> 2016-08-15 Jason Merrill <jason@redhat.com>
Avoid calling a trivial default constructor.
* class.c (default_ctor_p): New.
(in_class_defaulted_default_constructor): Use it.
(type_has_non_user_provided_default_constructor): Use it.
* call.c (build_over_call): Handle trivial default constructor.
* cp-tree.h: Declare default_ctor_p.
PR c++/57728 PR c++/57728
* pt.c (do_type_instantiation): Don't mess with non-user-provided * pt.c (do_type_instantiation): Don't mess with non-user-provided
member functions. member functions.
......
...@@ -7798,11 +7798,19 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain) ...@@ -7798,11 +7798,19 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain)
return val; return val;
} }
else if (DECL_DESTRUCTOR_P (fn) else if (!DECL_DELETED_FN (fn)
&& trivial_fn_p (fn) && trivial_fn_p (fn))
&& !DECL_DELETED_FN (fn)) {
return fold_convert (void_type_node, argarray[0]); if (DECL_DESTRUCTOR_P (fn))
/* FIXME handle trivial default constructor, too. */ return fold_convert (void_type_node, argarray[0]);
else if (default_ctor_p (fn))
{
if (is_dummy_object (argarray[0]))
return force_target_expr (DECL_CONTEXT (fn), void_node, complain);
else
return cp_build_indirect_ref (argarray[0], RO_NULL, complain);
}
}
/* For calls to a multi-versioned function, overload resolution /* For calls to a multi-versioned function, overload resolution
returns the function with the highest target priority, that is, returns the function with the highest target priority, that is,
......
...@@ -5133,8 +5133,17 @@ set_method_tm_attributes (tree t) ...@@ -5133,8 +5133,17 @@ set_method_tm_attributes (tree t)
} }
} }
/* Returns true iff class T has a user-defined constructor other than /* Returns true if FN is a default constructor. */
the default constructor. */
bool
default_ctor_p (tree fn)
{
return (DECL_CONSTRUCTOR_P (fn)
&& sufficient_parms_p (FUNCTION_FIRST_USER_PARMTYPE (fn)));
}
/* Returns true iff class T has a user-defined constructor that can be called
with more than zero arguments. */
bool bool
type_has_user_nondefault_constructor (tree t) type_has_user_nondefault_constructor (tree t)
...@@ -5163,23 +5172,16 @@ type_has_user_nondefault_constructor (tree t) ...@@ -5163,23 +5172,16 @@ type_has_user_nondefault_constructor (tree t)
tree tree
in_class_defaulted_default_constructor (tree t) in_class_defaulted_default_constructor (tree t)
{ {
tree fns, args;
if (!TYPE_HAS_USER_CONSTRUCTOR (t)) if (!TYPE_HAS_USER_CONSTRUCTOR (t))
return NULL_TREE; return NULL_TREE;
for (fns = CLASSTYPE_CONSTRUCTORS (t); fns; fns = OVL_NEXT (fns)) for (tree fns = CLASSTYPE_CONSTRUCTORS (t); fns; fns = OVL_NEXT (fns))
{ {
tree fn = OVL_CURRENT (fns); tree fn = OVL_CURRENT (fns);
if (DECL_DEFAULTED_IN_CLASS_P (fn)) if (DECL_DEFAULTED_IN_CLASS_P (fn)
{ && default_ctor_p (fn))
args = FUNCTION_FIRST_USER_PARMTYPE (fn); return fn;
while (args && TREE_PURPOSE (args))
args = TREE_CHAIN (args);
if (!args || args == void_list_node)
return fn;
}
} }
return NULL_TREE; return NULL_TREE;
...@@ -5268,8 +5270,8 @@ type_has_non_user_provided_default_constructor (tree t) ...@@ -5268,8 +5270,8 @@ type_has_non_user_provided_default_constructor (tree t)
{ {
tree fn = OVL_CURRENT (fns); tree fn = OVL_CURRENT (fns);
if (TREE_CODE (fn) == FUNCTION_DECL if (TREE_CODE (fn) == FUNCTION_DECL
&& !user_provided_p (fn) && default_ctor_p (fn)
&& sufficient_parms_p (FUNCTION_FIRST_USER_PARMTYPE (fn))) && !user_provided_p (fn))
return true; return true;
} }
......
...@@ -5666,6 +5666,7 @@ extern void determine_key_method (tree); ...@@ -5666,6 +5666,7 @@ extern void determine_key_method (tree);
extern void check_for_override (tree, tree); extern void check_for_override (tree, tree);
extern void push_class_stack (void); extern void push_class_stack (void);
extern void pop_class_stack (void); extern void pop_class_stack (void);
extern bool default_ctor_p (tree);
extern bool type_has_user_nondefault_constructor (tree); extern bool type_has_user_nondefault_constructor (tree);
extern tree in_class_defaulted_default_constructor (tree); extern tree in_class_defaulted_default_constructor (tree);
extern bool user_provided_p (tree); extern bool user_provided_p (tree);
......
...@@ -15,3 +15,5 @@ int main() ...@@ -15,3 +15,5 @@ int main()
{ {
A<int> a; A<int> a;
} }
// { dg-final { scan-assembler-not "_ZN1AIiEC1Ev" } }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment