Commit 4561285b by Jason Merrill Committed by Jason Merrill

DR 1030 PR c++/51253

	DR 1030
	PR c++/51253
	* cp-tree.h (CALL_EXPR_LIST_INIT_P): New.
	* call.c (struct z_candidate): Add flags field.
	(add_candidate): Add flags parm.
	(add_function_candidate, add_conv_candidate, build_builtin_candidate)
	(add_template_candidate_real): Pass it.
	(build_over_call): Set CALL_EXPR_LIST_INIT_P.
	* tree.c (build_aggr_init_expr): Copy it.
	* semantics.c (simplify_aggr_init_expr): Preevaluate args if it's set.

From-SVN: r209309
parent 6602e7fc
2014-04-11 Jason Merrill <jason@redhat.com>
DR 1030
PR c++/51253
* cp-tree.h (CALL_EXPR_LIST_INIT_P): New.
* call.c (struct z_candidate): Add flags field.
(add_candidate): Add flags parm.
(add_function_candidate, add_conv_candidate, build_builtin_candidate)
(add_template_candidate_real): Pass it.
(build_over_call): Set CALL_EXPR_LIST_INIT_P.
* tree.c (build_aggr_init_expr): Copy it.
* semantics.c (simplify_aggr_init_expr): Preevaluate args if it's set.
2014-04-10 Richard Biener <rguenther@suse.de>
Jakub Jelinek <jakub@redhat.com>
......
......@@ -206,7 +206,7 @@ static conversion *maybe_handle_ref_bind (conversion **);
static void maybe_handle_implicit_object (conversion **);
static struct z_candidate *add_candidate
(struct z_candidate **, tree, tree, const vec<tree, va_gc> *, size_t,
conversion **, tree, tree, int, struct rejection_reason *);
conversion **, tree, tree, int, struct rejection_reason *, int);
static tree source_type (conversion *);
static void add_warning (struct z_candidate *, struct z_candidate *);
static bool reference_compatible_p (tree, tree);
......@@ -520,7 +520,6 @@ struct z_candidate {
sequence from the type returned by FN to the desired destination
type. */
conversion *second_conv;
int viable;
struct rejection_reason *reason;
/* If FN is a member function, the binfo indicating the path used to
qualify the name of FN at the call site. This path is used to
......@@ -538,6 +537,10 @@ struct z_candidate {
tree explicit_targs;
candidate_warning *warnings;
z_candidate *next;
int viable;
/* The flags active in add_candidate. */
int flags;
};
/* Returns true iff T is a null pointer constant in the sense of
......@@ -1810,7 +1813,8 @@ add_candidate (struct z_candidate **candidates,
tree fn, tree first_arg, const vec<tree, va_gc> *args,
size_t num_convs, conversion **convs,
tree access_path, tree conversion_path,
int viable, struct rejection_reason *reason)
int viable, struct rejection_reason *reason,
int flags)
{
struct z_candidate *cand = (struct z_candidate *)
conversion_obstack_alloc (sizeof (struct z_candidate));
......@@ -1825,6 +1829,7 @@ add_candidate (struct z_candidate **candidates,
cand->viable = viable;
cand->reason = reason;
cand->next = *candidates;
cand->flags = flags;
*candidates = cand;
return cand;
......@@ -2061,7 +2066,7 @@ add_function_candidate (struct z_candidate **candidates,
out:
return add_candidate (candidates, fn, orig_first_arg, args, len, convs,
access_path, conversion_path, viable, reason);
access_path, conversion_path, viable, reason, flags);
}
/* Create an overload candidate for the conversion function FN which will
......@@ -2163,7 +2168,7 @@ add_conv_candidate (struct z_candidate **candidates, tree fn, tree obj,
}
return add_candidate (candidates, totype, first_arg, arglist, len, convs,
access_path, conversion_path, viable, reason);
access_path, conversion_path, viable, reason, flags);
}
static void
......@@ -2238,7 +2243,7 @@ build_builtin_candidate (struct z_candidate **candidates, tree fnname,
num_convs, convs,
/*access_path=*/NULL_TREE,
/*conversion_path=*/NULL_TREE,
viable, reason);
viable, reason, flags);
}
static bool
......@@ -3056,7 +3061,7 @@ add_template_candidate_real (struct z_candidate **candidates, tree tmpl,
return cand;
fail:
return add_candidate (candidates, tmpl, first_arg, arglist, nargs, NULL,
access_path, conversion_path, 0, reason);
access_path, conversion_path, 0, reason, flags);
}
......@@ -7219,7 +7224,11 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain)
return error_mark_node;
}
return build_cxx_call (fn, nargs, argarray, complain|decltype_flag);
tree call = build_cxx_call (fn, nargs, argarray, complain|decltype_flag);
if (TREE_CODE (call) == CALL_EXPR
&& (cand->flags & LOOKUP_LIST_INIT_CTOR))
CALL_EXPR_LIST_INIT_P (call) = true;
return call;
}
/* Build and return a call to FN, using NARGS arguments in ARGARRAY.
......
......@@ -101,12 +101,14 @@ c-common.h, not after.
FNDECL_USED_AUTO (in FUNCTION_DECL)
DECLTYPE_FOR_LAMBDA_PROXY (in DECLTYPE_TYPE)
REF_PARENTHESIZED_P (in COMPONENT_REF, SCOPE_REF)
AGGR_INIT_ZERO_FIRST (in AGGR_INIT_EXPR)
3: (TREE_REFERENCE_EXPR) (in NON_LVALUE_EXPR) (commented-out).
ICS_BAD_FLAG (in _CONV)
FN_TRY_BLOCK_P (in TRY_BLOCK)
IDENTIFIER_CTOR_OR_DTOR_P (in IDENTIFIER_NODE)
BIND_EXPR_BODY_BLOCK (in BIND_EXPR)
DECL_NON_TRIVIALLY_INITIALIZED_P (in VAR_DECL)
CALL_EXPR_LIST_INIT_P (in CALL_EXPR, AGGR_INIT_EXPR)
4: TREE_HAS_CONSTRUCTOR (in INDIRECT_REF, SAVE_EXPR, CONSTRUCTOR,
or FIELD_DECL).
IDENTIFIER_TYPENAME_P (in IDENTIFIER_NODE)
......@@ -3026,6 +3028,10 @@ extern void decl_shadowed_for_var_insert (tree, tree);
should be performed at instantiation time. */
#define KOENIG_LOOKUP_P(NODE) TREE_LANG_FLAG_0 (CALL_EXPR_CHECK (NODE))
/* True if CALL_EXPR expresses list-initialization of an object. */
#define CALL_EXPR_LIST_INIT_P(NODE) \
TREE_LANG_FLAG_3 (TREE_CHECK2 ((NODE),CALL_EXPR,AGGR_INIT_EXPR))
/* Indicates whether a string literal has been parenthesized. Such
usages are disallowed in certain circumstances. */
......
......@@ -3867,6 +3867,7 @@ simplify_aggr_init_expr (tree *tp)
aggr_init_expr_nargs (aggr_init_expr),
AGGR_INIT_EXPR_ARGP (aggr_init_expr));
TREE_NOTHROW (call_expr) = TREE_NOTHROW (aggr_init_expr);
tree ret = call_expr;
if (style == ctor)
{
......@@ -3882,7 +3883,7 @@ simplify_aggr_init_expr (tree *tp)
expand_call{,_inline}. */
cxx_mark_addressable (slot);
CALL_EXPR_RETURN_SLOT_OPT (call_expr) = true;
call_expr = build2 (INIT_EXPR, TREE_TYPE (call_expr), slot, call_expr);
ret = build2 (INIT_EXPR, TREE_TYPE (ret), slot, ret);
}
else if (style == pcc)
{
......@@ -3890,11 +3891,25 @@ simplify_aggr_init_expr (tree *tp)
need to copy the returned value out of the static buffer into the
SLOT. */
push_deferring_access_checks (dk_no_check);
call_expr = build_aggr_init (slot, call_expr,
DIRECT_BIND | LOOKUP_ONLYCONVERTING,
tf_warning_or_error);
ret = build_aggr_init (slot, ret,
DIRECT_BIND | LOOKUP_ONLYCONVERTING,
tf_warning_or_error);
pop_deferring_access_checks ();
call_expr = build2 (COMPOUND_EXPR, TREE_TYPE (slot), call_expr, slot);
ret = build2 (COMPOUND_EXPR, TREE_TYPE (slot), ret, slot);
}
/* DR 1030 says that we need to evaluate the elements of an
initializer-list in forward order even when it's used as arguments to
a constructor. So if the target wants to evaluate them in reverse
order and there's more than one argument other than 'this', force
pre-evaluation. */
if (PUSH_ARGS_REVERSED && CALL_EXPR_LIST_INIT_P (aggr_init_expr)
&& aggr_init_expr_nargs (aggr_init_expr) > 2)
{
tree preinit;
stabilize_call (call_expr, &preinit);
if (preinit)
ret = build2 (COMPOUND_EXPR, TREE_TYPE (ret), preinit, ret);
}
if (AGGR_INIT_ZERO_FIRST (aggr_init_expr))
......@@ -3902,11 +3917,10 @@ simplify_aggr_init_expr (tree *tp)
tree init = build_zero_init (type, NULL_TREE,
/*static_storage_p=*/false);
init = build2 (INIT_EXPR, void_type_node, slot, init);
call_expr = build2 (COMPOUND_EXPR, TREE_TYPE (call_expr),
init, call_expr);
ret = build2 (COMPOUND_EXPR, TREE_TYPE (ret), init, ret);
}
*tp = call_expr;
*tp = ret;
}
/* Emit all thunks to FN that should be emitted when FN is emitted. */
......
......@@ -453,6 +453,7 @@ build_aggr_init_expr (tree type, tree init)
TREE_SIDE_EFFECTS (rval) = 1;
AGGR_INIT_VIA_CTOR_P (rval) = is_ctor;
TREE_NOTHROW (rval) = TREE_NOTHROW (init);
CALL_EXPR_LIST_INIT_P (rval) = CALL_EXPR_LIST_INIT_P (init);
}
else
rval = init;
......
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