diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 8260626605ba8fa10d473852bf6b3519b1d656e1..a664baf3ed1793a92788de4788ecb4cd7fcfc7cf 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 334d6b1f3c46aa859b56de0b731c707c1d7327f0..6c501a8d0e2c8b2101f7aefea22fd8fc716909eb 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 ef4b04372bc21f30ee34f368d306ad6fb2c2948c..18142bf396ef618d7ee91603dc880c6aab96808b 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 c1c16f49f9301a8068db8b6085677cd81624f361..ca0c34bf6f29dae0e627a2e1377dffd58675e4ea 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 92714b595494bac071c6449579e8f1a11d940cd2..89ae41fb6984e0cee1351ce28a387faa1ea7f195 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 47e72130add6f0c3c331ba4f84d401fb68c15899..5085ccfe554cc54f278a9269e0d48c3cb0deed12 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 0000000000000000000000000000000000000000..16af47636ad187250c71623edf8d9965b5acd264
--- /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();
+}