diff mbox

C++ PATCH for new A{1}

Message ID 4ED83E39.7070004@redhat.com
State New
Headers show

Commit Message

Jason Merrill Dec. 2, 2011, 2:55 a.m. UTC
While looking at 41449, I noticed that in the testcase new A{1,2} was 
failing because it was trying to build a constructor call rather than 
perform aggregate initialization.

Tested x86_64-pc-linux-gnu, applying to trunk.
diff mbox

Patch

commit 947c20c9ffeb28e14676067f2ac21086b0c6342b
Author: Jason Merrill <jason@redhat.com>
Date:   Thu Dec 1 17:15:45 2011 -0500

    	* call.c (build_new_method_call_1): Handle aggregate initialization.
    	* tree.c (stabilize_init): Handle CONSTRUCTOR.

diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index ab06542..53ea61d 100644
--- a/gcc/cp/call.c
+++ b/gcc/cp/call.c
@@ -7193,6 +7193,7 @@  build_new_method_call_1 (tree instance, tree fns, VEC(tree,gc) **args,
       && CONSTRUCTOR_IS_DIRECT_INIT (VEC_index (tree, *args, 0)))
     {
       tree init_list = VEC_index (tree, *args, 0);
+      tree init = NULL_TREE;
 
       gcc_assert (VEC_length (tree, *args) == 1
 		  && !(flags & LOOKUP_ONLYCONVERTING));
@@ -7204,8 +7205,16 @@  build_new_method_call_1 (tree instance, tree fns, VEC(tree,gc) **args,
       if (CONSTRUCTOR_NELTS (init_list) == 0
 	  && TYPE_HAS_DEFAULT_CONSTRUCTOR (basetype)
 	  && !processing_template_decl)
+	init = build_value_init (basetype, complain);
+
+      /* If BASETYPE is an aggregate, we need to do aggregate
+	 initialization.  */
+      else if (CP_AGGREGATE_TYPE_P (basetype))
+	init = digest_init (basetype, init_list, complain);
+
+      if (init)
 	{
-	  tree ob, init = build_value_init (basetype, complain);
+	  tree ob;
 	  if (integer_zerop (instance_ptr))
 	    return get_target_expr_sfinae (init, complain);
 	  ob = build_fold_indirect_ref (instance_ptr);
@@ -7214,6 +7223,7 @@  build_new_method_call_1 (tree instance, tree fns, VEC(tree,gc) **args,
 	  return init;
 	}
 
+      /* Otherwise go ahead with overload resolution.  */
       add_list_candidates (fns, first_mem_arg, init_list,
 			   basetype, explicit_targs, template_only,
 			   conversion_path, access_binfo, flags, &candidates);
diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c
index d206fd2..8d179d8 100644
--- a/gcc/cp/tree.c
+++ b/gcc/cp/tree.c
@@ -3337,6 +3337,7 @@  stabilize_init (tree init, tree *initp)
 
   if (TREE_CODE (t) == INIT_EXPR
       && TREE_CODE (TREE_OPERAND (t, 1)) != TARGET_EXPR
+      && TREE_CODE (TREE_OPERAND (t, 1)) != CONSTRUCTOR
       && TREE_CODE (TREE_OPERAND (t, 1)) != AGGR_INIT_EXPR)
     {
       TREE_OPERAND (t, 1) = stabilize_expr (TREE_OPERAND (t, 1), initp);
diff --git a/gcc/testsuite/g++.dg/cpp0x/initlist61.C b/gcc/testsuite/g++.dg/cpp0x/initlist61.C
new file mode 100644
index 0000000..28eccc2
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/initlist61.C
@@ -0,0 +1,9 @@ 
+// { dg-do compile { target c++11 } }
+
+struct N { N(int); };
+struct A { N i,j; };
+
+int main()
+{
+  A* ap = new A{1,2};
+}