Patchwork C++ PATCH for c++/48132 (ICE with constexpr and array)

login
register
mail settings
Submitter Jason Merrill
Date March 16, 2011, 8 p.m.
Message ID <4D8116C1.8080602@redhat.com>
Download mbox | patch
Permalink /patch/87298/
State New
Headers show

Comments

Jason Merrill - March 16, 2011, 8 p.m.
Jakub was right that we were failing to add indices to the array 
CONSTRUCTOR along this code path.  It seems appropriate to add them 
earlier, in reshape_init, like we do for classes, so this patch fixes 
the bug that way.

Tested x86_64-pc-linux-gnu, applying to trunk.  Also OK for 4.6.0?  The 
risk is that something else not caught by the testsuite could be 
confused by adding the indices slightly sooner, but that seems unlikely.
commit 4d360926bf71c078e6c6962b7aee997c2e5974e6
Author: Jason Merrill <jason@redhat.com>
Date:   Wed Mar 16 15:15:56 2011 -0400

    	PR c++/48132
    	* decl.c (check_array_designated_initializer): Allow integer index.
    	(reshape_init_array_1): Set index on the elements.
Richard Guenther - March 17, 2011, 8:24 a.m.
On Wed, Mar 16, 2011 at 9:00 PM, Jason Merrill <jason@redhat.com> wrote:
> Jakub was right that we were failing to add indices to the array CONSTRUCTOR
> along this code path.  It seems appropriate to add them earlier, in
> reshape_init, like we do for classes, so this patch fixes the bug that way.
>
> Tested x86_64-pc-linux-gnu, applying to trunk.  Also OK for 4.6.0?  The risk
> is that something else not caught by the testsuite could be confused by
> adding the indices slightly sooner, but that seems unlikely.

Ok for 4.6.0.

Thanks,
Richard.

> commit 4d360926bf71c078e6c6962b7aee997c2e5974e6
> Author: Jason Merrill <jason@redhat.com>
> Date:   Wed Mar 16 15:15:56 2011 -0400
>
>        PR c++/48132
>        * decl.c (check_array_designated_initializer): Allow integer index.
>        (reshape_init_array_1): Set index on the elements.
>
> diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
> index f9d90ad..3139ad8 100644
> --- a/gcc/cp/decl.c
> +++ b/gcc/cp/decl.c
> @@ -4596,6 +4596,9 @@ check_array_designated_initializer (const
> constructor_elt *ce)
>       if (ce->index == error_mark_node)
>        error ("name used in a GNU-style designated "
>               "initializer for an array");
> +      else if (TREE_CODE (ce->index) == INTEGER_CST)
> +       /* An index added by reshape_init.  */
> +       return true;
>       else
>        {
>          gcc_assert (TREE_CODE (ce->index) == IDENTIFIER_NODE);
> @@ -4899,7 +4902,8 @@ reshape_init_array_1 (tree elt_type, tree max_index,
> reshape_iter *d)
>       elt_init = reshape_init_r (elt_type, d,
> /*first_initializer_p=*/false);
>       if (elt_init == error_mark_node)
>        return error_mark_node;
> -      CONSTRUCTOR_APPEND_ELT (CONSTRUCTOR_ELTS (new_init), NULL_TREE,
> elt_init);
> +      CONSTRUCTOR_APPEND_ELT (CONSTRUCTOR_ELTS (new_init),
> +                             size_int (index), elt_init);
>     }
>
>   return new_init;
> diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-array3.C
> b/gcc/testsuite/g++.dg/cpp0x/constexpr-array3.C
> new file mode 100644
> index 0000000..145a430
> --- /dev/null
> +++ b/gcc/testsuite/g++.dg/cpp0x/constexpr-array3.C
> @@ -0,0 +1,14 @@
> +// PR c++/48132
> +// { dg-options -std=c++0x }
> +
> +struct C
> +{
> +  constexpr C (int x) : c (x) {}
> +  int c;
> +};
> +
> +void
> +foo ()
> +{
> +  C a[] = { C (0) };
> +}
>
>

Patch

diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index f9d90ad..3139ad8 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -4596,6 +4596,9 @@  check_array_designated_initializer (const constructor_elt *ce)
       if (ce->index == error_mark_node)
 	error ("name used in a GNU-style designated "
 	       "initializer for an array");
+      else if (TREE_CODE (ce->index) == INTEGER_CST)
+	/* An index added by reshape_init.  */
+	return true;
       else
 	{
 	  gcc_assert (TREE_CODE (ce->index) == IDENTIFIER_NODE);
@@ -4899,7 +4902,8 @@  reshape_init_array_1 (tree elt_type, tree max_index, reshape_iter *d)
       elt_init = reshape_init_r (elt_type, d, /*first_initializer_p=*/false);
       if (elt_init == error_mark_node)
 	return error_mark_node;
-      CONSTRUCTOR_APPEND_ELT (CONSTRUCTOR_ELTS (new_init), NULL_TREE, elt_init);
+      CONSTRUCTOR_APPEND_ELT (CONSTRUCTOR_ELTS (new_init),
+			      size_int (index), elt_init);
     }
 
   return new_init;
diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-array3.C b/gcc/testsuite/g++.dg/cpp0x/constexpr-array3.C
new file mode 100644
index 0000000..145a430
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/constexpr-array3.C
@@ -0,0 +1,14 @@ 
+// PR c++/48132
+// { dg-options -std=c++0x }
+
+struct C
+{
+  constexpr C (int x) : c (x) {}
+  int c;
+};
+
+void
+foo ()
+{
+  C a[] = { C (0) };
+}