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>
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
* pt.c (do_type_instantiation): Don't mess with non-user-provided
member functions.
......
......@@ -7798,11 +7798,19 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain)
return val;
}
else if (DECL_DESTRUCTOR_P (fn)
&& trivial_fn_p (fn)
&& !DECL_DELETED_FN (fn))
return fold_convert (void_type_node, argarray[0]);
/* FIXME handle trivial default constructor, too. */
else if (!DECL_DELETED_FN (fn)
&& trivial_fn_p (fn))
{
if (DECL_DESTRUCTOR_P (fn))
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
returns the function with the highest target priority, that is,
......
......@@ -5133,8 +5133,17 @@ set_method_tm_attributes (tree t)
}
}
/* Returns true iff class T has a user-defined constructor other than
the default constructor. */
/* Returns true if FN is a 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
type_has_user_nondefault_constructor (tree t)
......@@ -5163,23 +5172,16 @@ type_has_user_nondefault_constructor (tree t)
tree
in_class_defaulted_default_constructor (tree t)
{
tree fns, args;
if (!TYPE_HAS_USER_CONSTRUCTOR (t))
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);
if (DECL_DEFAULTED_IN_CLASS_P (fn))
{
args = FUNCTION_FIRST_USER_PARMTYPE (fn);
while (args && TREE_PURPOSE (args))
args = TREE_CHAIN (args);
if (!args || args == void_list_node)
return fn;
}
if (DECL_DEFAULTED_IN_CLASS_P (fn)
&& default_ctor_p (fn))
return fn;
}
return NULL_TREE;
......@@ -5268,8 +5270,8 @@ type_has_non_user_provided_default_constructor (tree t)
{
tree fn = OVL_CURRENT (fns);
if (TREE_CODE (fn) == FUNCTION_DECL
&& !user_provided_p (fn)
&& sufficient_parms_p (FUNCTION_FIRST_USER_PARMTYPE (fn)))
&& default_ctor_p (fn)
&& !user_provided_p (fn))
return true;
}
......
......@@ -5666,6 +5666,7 @@ extern void determine_key_method (tree);
extern void check_for_override (tree, tree);
extern void push_class_stack (void);
extern void pop_class_stack (void);
extern bool default_ctor_p (tree);
extern bool type_has_user_nondefault_constructor (tree);
extern tree in_class_defaulted_default_constructor (tree);
extern bool user_provided_p (tree);
......
......@@ -15,3 +15,5 @@ int main()
{
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