Hi, and first thanks everyone for the constructive feedbacks! >> And recursively? >> >> So that: >> >> struct A { int i; }; >> struct B { struct A a }; >> struct C { struct B b }; >> struct C c = { 1 }; >> >> does not trigger the warning? > > Sure. > >> >> What if struct B is now: >> >> struct B { struct A a; int j; }; >> >> and I write: >> >> struct C c = { 1, 2 }; > > Then warn. > > I don't mind changing the behavior to not warn so long as all of the > initializers missing braces apply to the same aggregate. So in the > former case they all apply to struct A, whereas in the later case they > do not.
I tried quickly drafting the corresponding patch, attached, which appears to work pretty well (no regressions), please correct me as soon as possible if I misunderstood. For example, this struct S { int s[3]; }; struct S s1 = { 1, 1, 1 }; and this struct S1 { int s[3]; }; struct S2 { struct S1 a; }; struct S2 s22 = { 1, 1, 1 }; and this struct A { int i; }; struct B { struct A a }; struct C { struct B b }; struct C c = { 1 }; do not warn anymore. Whereas, this struct S3 { int s[3]; }; struct S4 { struct S3 a; int b; }; struct S4 s23 = { 1, 1, 1 , 1 }; warns, but only about "missing braces around initializer for ‘S3’", not about "missing braces around initializer for ‘int [3]’", at variance with mainline. Changed the following way doesn't warn: struct S5 { int s[3]; }; struct S5 { struct S5 a; int b; }; struct S5 s34 = { { 1, 1, 1 }, 1 }; This struct A1 { int i; }; struct B1 { struct A1 a; }; struct B1 { struct A1 a; int j; }; struct C1 { struct B1 b; }; struct C1 c2 = { 1, 2 }; likewise only warns about "missing braces around initializer for ‘A1’" In case, the same kind of change should be implemented in the C front-end, right? Thanks, Paolo.
Index: decl.c =================================================================== --- decl.c (revision 154291) +++ decl.c (working copy) @@ -4707,7 +4707,7 @@ constructor_elt *end; } reshape_iter; -static tree reshape_init_r (tree, reshape_iter *, bool); +static tree reshape_init_r (tree, reshape_iter *, bool, bool); /* FIELD is a FIELD_DECL or NULL. In the former case, the value returned is the next FIELD_DECL (possibly FIELD itself) that can be @@ -4765,7 +4765,8 @@ tree elt_init; check_array_designated_initializer (d->cur); - elt_init = reshape_init_r (elt_type, d, /*first_initializer_p=*/false); + elt_init = reshape_init_r (elt_type, d, /*first_initializer_p=*/false, + false); if (elt_init == error_mark_node) return error_mark_node; CONSTRUCTOR_APPEND_ELT (CONSTRUCTOR_ELTS (new_init), NULL_TREE, elt_init); @@ -4857,7 +4858,7 @@ /* Loop through the initializable fields, gathering initializers. */ while (d->cur != d->end) { - tree field_init; + tree field_init, nfield; /* Handle designated initializers, as an extension. */ if (d->cur->index) @@ -4876,8 +4877,9 @@ if (!field) break; + nfield = next_initializable_field (TREE_CHAIN (field)); field_init = reshape_init_r (TREE_TYPE (field), d, - /*first_initializer_p=*/false); + /*first_initializer_p=*/false, !nfield); if (field_init == error_mark_node) return error_mark_node; @@ -4891,7 +4893,7 @@ if (TREE_CODE (type) == UNION_TYPE) break; - field = next_initializable_field (TREE_CHAIN (field)); + field = nfield; } return new_init; @@ -4904,7 +4906,7 @@ outermost CONSTRUCTOR node. */ static tree -reshape_init_r (tree type, reshape_iter *d, bool first_initializer_p) +reshape_init_r (tree type, reshape_iter *d, bool first_initializer_p, bool no_warn) { tree init = d->cur->value; @@ -5016,8 +5018,9 @@ } } - warning (OPT_Wmissing_braces, "missing braces around initializer for %qT", - type); + if (!no_warn) + warning (OPT_Wmissing_braces, "missing braces around initializer " + "for %qT", type); } /* Dispatch to specialized routines. */ @@ -5066,7 +5069,7 @@ d.cur = VEC_index (constructor_elt, v, 0); d.end = d.cur + VEC_length (constructor_elt, v); - new_init = reshape_init_r (type, &d, true); + new_init = reshape_init_r (type, &d, true, false); if (new_init == error_mark_node) return error_mark_node;