summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog7
-rw-r--r--gcc/cp/ChangeLog7
-rw-r--r--gcc/cp/cp-gimplify.c21
-rw-r--r--gcc/cp/semantics.c15
-rw-r--r--gcc/gimplify.c2
-rw-r--r--gcc/gimplify.h1
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/initlist86.C18
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();
+}