This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: C++ PATCH for c++/46289 (ICE on invalid mem-init-list in constexpr ctor)


On 11/03/2010 03:01 PM, Jason Merrill wrote:
The testcase in the PR ought to be valid, but even on an invalid
initializer we shouldn't ICE. This patch just fixes the ICE.

And this patch fixes the error.


Tested x86_64-pc-linux-gnu, applied to trunk.

commit 806ad75a68d2a2ecede77d1857cc1404d395e6a6
Author: Jason Merrill <jason@redhat.com>
Date:   Wed Nov 3 18:28:18 2010 -0400

    	PR c++/46289
    	* call.c (can_convert_array): New fn.
    	(build_aggr_conv): Use it.

diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index a1c8682..4507f3d 100644
--- a/gcc/cp/call.c
+++ b/gcc/cp/call.c
@@ -639,6 +639,29 @@ build_list_conv (tree type, tree ctor, int flags)
   return t;
 }
 
+/* Subroutine of build_aggr_conv: check whether CTOR, a braced-init-list,
+   is a valid aggregate initializer for array type ATYPE.  */
+
+static bool
+can_convert_array (tree atype, tree ctor, int flags)
+{
+  unsigned i;
+  tree elttype = TREE_TYPE (atype);
+  for (i = 0; i < CONSTRUCTOR_NELTS (ctor); ++i)
+    {
+      tree val = CONSTRUCTOR_ELT (ctor, i)->value;
+      bool ok;
+      if (TREE_CODE (elttype) == ARRAY_TYPE
+	  && TREE_CODE (val) == CONSTRUCTOR)
+	ok = can_convert_array (elttype, val, flags);
+      else
+	ok = can_convert_arg (elttype, TREE_TYPE (val), val, flags);
+      if (!ok)
+	return false;
+    }
+  return true;
+}
+
 /* Represent a conversion from CTOR, a braced-init-list, to TYPE, an
    aggregate class, if such a conversion is possible.  */
 
@@ -652,24 +675,31 @@ build_aggr_conv (tree type, tree ctor, int flags)
 
   for (; field; field = next_initializable_field (DECL_CHAIN (field)))
     {
+      tree ftype = TREE_TYPE (field);
+      tree val;
+      bool ok;
+
       if (i < CONSTRUCTOR_NELTS (ctor))
-	{
-	  constructor_elt *ce = CONSTRUCTOR_ELT (ctor, i);
-	  if (!can_convert_arg (TREE_TYPE (field), TREE_TYPE (ce->value),
-				ce->value, flags))
-	    return NULL;
-	  ++i;
-	  if (TREE_CODE (type) == UNION_TYPE)
-	    break;
-	}
+	val = CONSTRUCTOR_ELT (ctor, i)->value;
       else
 	{
 	  if (empty_ctor == NULL_TREE)
 	    empty_ctor = build_constructor (init_list_type_node, NULL);
-	  if (!can_convert_arg (TREE_TYPE (field), TREE_TYPE (empty_ctor),
-				empty_ctor, flags))
-	    return NULL;
+	  val = empty_ctor;
 	}
+      ++i;
+
+      if (TREE_CODE (ftype) == ARRAY_TYPE
+	  && TREE_CODE (val) == CONSTRUCTOR)
+	ok = can_convert_array (ftype, val, flags);
+      else
+	ok = can_convert_arg (ftype, TREE_TYPE (val), val, flags);
+
+      if (!ok)
+	return NULL;
+
+      if (TREE_CODE (type) == UNION_TYPE)
+	break;
     }
 
   if (i < CONSTRUCTOR_NELTS (ctor))
diff --git a/gcc/testsuite/g++.dg/cpp0x/initlist45.C b/gcc/testsuite/g++.dg/cpp0x/initlist45.C
new file mode 100644
index 0000000..0e34bc1
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/initlist45.C
@@ -0,0 +1,13 @@
+// PR c++/46289
+// { dg-options -std=c++0x }
+
+struct A
+{
+  int i[2];
+};
+
+struct B
+{
+  A a;
+  B(): a({{1,2}}) { }
+};

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]