From patchwork Thu Oct 18 19:28:39 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: [C++] PR 54501 Date: Thu, 18 Oct 2012 09:28:39 -0000 From: Paolo Carlini X-Patchwork-Id: 192427 Message-Id: <50805867.5000806@oracle.com> To: Jason Merrill Cc: "gcc-patches@gcc.gnu.org" 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 PR c++/54501 * decl.c (reshape_init_array_1): Avoid infinite loops. /testsuite 2012-10-18 Paolo Carlini PR c++/54501 * g++.dg/init/array30.C: New. * g++.dg/init/array31.C: Likewise. 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 };