re PR c++/51253 ([C++11][DR 1030] Evaluation order (sequenced-before relation) among initializer-clauses in braced-init-list)

PR c++/51253
	PR c++/61382
gcc/
	* gimplify.c (gimplify_arg): Non-static.
	* gimplify.h: Declare it.
gcc/cp/
	* cp-gimplify.c (cp_gimplify_expr): Handle CALL_EXPR_LIST_INIT_P here.
	* semantics.c (simplify_aggr_init_expr): Not here, just copy it.

From-SVN: r211235
This commit is contained in:
Jason Merrill 2014-06-04 11:51:01 -04:00 committed by Jason Merrill
parent 38af3208d5
commit fe6ebcf193
7 changed files with 56 additions and 15 deletions

View File

@ -1,3 +1,10 @@
2014-06-04 Jason Merrill <jason@redhat.com>
PR c++/51253
PR c++/61382
* gimplify.c (gimplify_arg): Non-static.
* gimplify.h: Declare it.
2014-06-04 Richard Biener <rguenther@suse.de>
* tree.h (may_be_aliased): Trust TREE_ADDRESSABLE from

View File

@ -1,3 +1,10 @@
2014-06-04 Jason Merrill <jason@redhat.com>
PR c++/51253
PR c++/61382
* cp-gimplify.c (cp_gimplify_expr): Handle CALL_EXPR_LIST_INIT_P here.
* semantics.c (simplify_aggr_init_expr): Not here, just copy it.
2014-06-04 Igor Zamyatin <igor.zamyatin@intel.com>
PR c/58942

View File

@ -723,6 +723,27 @@ cp_gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
&& !seen_error ())
return (enum gimplify_status) gimplify_cilk_spawn (expr_p);
/* 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', gimplify
them in order. */
ret = GS_OK;
if (PUSH_ARGS_REVERSED && CALL_EXPR_LIST_INIT_P (*expr_p)
&& call_expr_nargs (*expr_p) > 2)
{
int nargs = call_expr_nargs (*expr_p);
location_t loc = EXPR_LOC_OR_LOC (*expr_p, input_location);
for (int i = 1; i < nargs; ++i)
{
enum gimplify_status t
= gimplify_arg (&CALL_EXPR_ARG (*expr_p, i), pre_p, loc);
if (t == GS_ERROR)
ret = GS_ERROR;
}
}
break;
default:
ret = (enum gimplify_status) c_gimplify_expr (expr_p, pre_p, post_p);
break;

View File

@ -3869,6 +3869,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);
CALL_EXPR_LIST_INIT_P (call_expr) = CALL_EXPR_LIST_INIT_P (aggr_init_expr);
tree ret = call_expr;
if (style == ctor)
@ -3900,20 +3901,6 @@ simplify_aggr_init_expr (tree *tp)
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))
{
tree init = build_zero_init (type, NULL_TREE,

View File

@ -2170,7 +2170,7 @@ maybe_with_size_expr (tree *expr_p)
Store any side-effects in PRE_P. CALL_LOCATION is the location of
the CALL_EXPR. */
static enum gimplify_status
enum gimplify_status
gimplify_arg (tree *arg_p, gimple_seq *pre_p, location_t call_location)
{
bool (*test) (tree);

View File

@ -77,6 +77,7 @@ extern enum gimplify_status gimplify_expr (tree *, gimple_seq *, gimple_seq *,
extern void gimplify_type_sizes (tree, gimple_seq *);
extern void gimplify_one_sizepos (tree *, gimple_seq *);
extern gimple gimplify_body (tree, bool);
extern enum gimplify_status gimplify_arg (tree *, gimple_seq *, location_t);
extern void gimplify_function_tree (tree);
extern enum gimplify_status gimplify_va_arg_expr (tree *, gimple_seq *,
gimple_seq *);

View File

@ -0,0 +1,18 @@
// PR c++/61382
// { dg-do run { target c++11 } }
struct A
{
int i,j;
A(int i,int j):i(i),j(j){}
};
extern "C" int printf (const char *, ...);
int main()
{
int i;
A a{i++,i++};
if (a.i != 0 || a.j != 1)
__builtin_abort();
}