diff options
-rw-r--r-- | gcc/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/cp/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/cp/cp-gimplify.c | 21 | ||||
-rw-r--r-- | gcc/cp/semantics.c | 15 | ||||
-rw-r--r-- | gcc/gimplify.c | 2 | ||||
-rw-r--r-- | gcc/gimplify.h | 1 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp0x/initlist86.C | 18 |
7 files changed, 56 insertions, 15 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 8260626605b..a664baf3ed1 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -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 diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 334d6b1f3c4..6c501a8d0e2 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -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 diff --git a/gcc/cp/cp-gimplify.c b/gcc/cp/cp-gimplify.c index ef4b04372bc..18142bf396e 100644 --- a/gcc/cp/cp-gimplify.c +++ b/gcc/cp/cp-gimplify.c @@ -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; diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index c1c16f49f93..ca0c34bf6f2 100644 --- a/gcc/cp/semantics.c +++ b/gcc/cp/semantics.c @@ -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, diff --git a/gcc/gimplify.c b/gcc/gimplify.c index 92714b59549..89ae41fb698 100644 --- a/gcc/gimplify.c +++ b/gcc/gimplify.c @@ -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); diff --git a/gcc/gimplify.h b/gcc/gimplify.h index 47e72130add..5085ccfe554 100644 --- a/gcc/gimplify.h +++ b/gcc/gimplify.h @@ -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 *); diff --git a/gcc/testsuite/g++.dg/cpp0x/initlist86.C b/gcc/testsuite/g++.dg/cpp0x/initlist86.C new file mode 100644 index 00000000000..16af47636ad --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/initlist86.C @@ -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(); +} |