Patchwork [C++] PR 54501

login
register
mail settings
Submitter Paolo Carlini
Date Oct. 18, 2012, 7:28 p.m.
Message ID <50805867.5000806@oracle.com>
Download mbox | patch
Permalink /patch/192427/
State New
Headers show

Comments

Paolo Carlini - Oct. 18, 2012, 7:28 p.m.
Hi again,

On 10/18/2012 06:02 PM, Jason Merrill wrote:
> On 10/18/2012 01:15 AM, Paolo Carlini wrote:
>> If I understand correctly your hesitations, I don't think there are
>> exceptions to the general rule that if the size of the array is zero
>> there can be no initializers.
>
> I'm thinking of a testcase like this, which is currently accepted:
>
> struct A
> {
>   int i[0];
>   int j;
> };
>
> struct A a = { 1 };
>
> Here, since i has no elements, we should skip over it and apply the 
> one initializer to j.
Thus, I looked into what you did lately for c++/54441, and the below is 
what I regtested so far: I'm directly recognizing the situations leading 
to infinite loops. Note, I don't exclude that formally the whole 
iteration could be streamlined a bit, but like this it seems still quite 
understandable.

Tested x86_64-linux as usual..

Thanks,
Paolo.

///////////////////////////
/cp
2012-10-18  Paolo Carlini  <paolo.carlini@oracle.com>

	PR c++/54501
	* decl.c (reshape_init_array_1): Avoid infinite loops.

/testsuite
2012-10-18  Paolo Carlini  <paolo.carlini@oracle.com>

	PR c++/54501
	* g++.dg/init/array30.C: New.
	* g++.dg/init/array31.C: Likewise.
Jason Merrill - Oct. 18, 2012, 10:31 p.m.
OK.

Jason

Patch

Index: cp/decl.c
===================================================================
--- cp/decl.c	(revision 192569)
+++ cp/decl.c	(working copy)
@@ -5040,6 +5040,7 @@  reshape_init_array_1 (tree elt_type, tree max_inde
        ++index)
     {
       tree elt_init;
+      constructor_elt *old_cur = d->cur;
 
       check_array_designated_initializer (d->cur, index);
       elt_init = reshape_init_r (elt_type, d, /*first_initializer_p=*/false,
@@ -5050,6 +5051,10 @@  reshape_init_array_1 (tree elt_type, tree max_inde
 			      size_int (index), elt_init);
       if (!TREE_CONSTANT (elt_init))
 	TREE_CONSTANT (new_init) = false;
+
+      /* This can happen with an invalid initializer (c++/54501).  */
+      if (d->cur == old_cur && !sized_array_p)
+	break;
     }
 
   return new_init;
Index: testsuite/g++.dg/init/array30.C
===================================================================
--- testsuite/g++.dg/init/array30.C	(revision 0)
+++ testsuite/g++.dg/init/array30.C	(working copy)
@@ -0,0 +1,7 @@ 
+// PR c++/54501
+// { dg-options "" }
+
+int main()
+{
+  int a[][0] = {0};  // { dg-error "too many" }
+}
Index: testsuite/g++.dg/init/array31.C
===================================================================
--- testsuite/g++.dg/init/array31.C	(revision 0)
+++ testsuite/g++.dg/init/array31.C	(working copy)
@@ -0,0 +1,10 @@ 
+// PR c++/54501
+// { dg-options "" }
+
+struct A
+{
+  int i[0];
+  int j;
+};
+
+struct A a = { 1 };