===================================================================
@@ -0,0 +1,34 @@
+// PR c++/25137
+// { dg-options "-Wmissing-braces" }
+
+struct S { int s[3]; };
+S s1 = { 1, 1, 1 };
+
+struct S1 { int s[3]; };
+struct S2 { struct S1 a; };
+S2 s21 = { 1, 1, 1 };
+
+struct S3 { int s[3]; };
+struct S4 { struct S3 a; int b; };
+S4 s41 = { 1, 1, 1, 1 }; // { dg-warning "missing braces around initializer for 'S3'" }
+
+struct S5 { int s[3]; };
+struct S6 { struct S5 a; int b; };
+S6 s61 = { { 1, 1, 1 }, 1 };
+
+struct S7 { int s[3]; };
+struct S8 { int a; struct S7 b; };
+S8 s81 = { 1, { 1, 1, 1 } };
+
+struct S9 { int s[2]; };
+struct S10 { struct S9 a; struct S9 b; };
+S10 s101 = { { 1, 1 }, 1, 1 }; // { dg-warning "missing braces around initializer for 'S9'" }
+
+struct S11 { int s[2]; };
+struct S12 { struct S11 a; struct S11 b; };
+S12 s121 = { { 1, 1 }, { 1, 1 } };
+
+struct S13 { int i; };
+struct S14 { struct S13 a; };
+struct S15 { struct S14 b; };
+S15 s151 = { 1 };
===================================================================
@@ -4954,7 +4954,7 @@ typedef struct reshape_iterator_t
constructor_elt *end;
} reshape_iter;
-static tree reshape_init_r (tree, reshape_iter *, bool, tsubst_flags_t);
+static tree reshape_init_r (tree, reshape_iter *, bool, bool, tsubst_flags_t);
/* 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
@@ -5014,7 +5014,7 @@ reshape_init_array_1 (tree elt_type, tree max_inde
check_array_designated_initializer (d->cur, index);
elt_init = reshape_init_r (elt_type, d, /*first_initializer_p=*/false,
- complain);
+ /*no_warn_missing_braces=*/false, complain);
if (elt_init == error_mark_node)
return error_mark_node;
CONSTRUCTOR_APPEND_ELT (CONSTRUCTOR_ELTS (new_init),
@@ -5082,6 +5082,7 @@ reshape_init_class (tree type, reshape_iter *d, bo
{
tree field;
tree new_init;
+ bool no_warn_missing_braces;
gcc_assert (CLASS_TYPE_P (type));
@@ -5105,6 +5106,12 @@ reshape_init_class (tree type, reshape_iter *d, bo
return new_init;
}
+ /* If the struct has only one field and that field is an aggregate,
+ don't warn if there is only one set of braces in the initializer. */
+ no_warn_missing_braces
+ = (next_initializable_field (DECL_CHAIN (field)) == NULL_TREE
+ && CP_AGGREGATE_TYPE_P (TREE_TYPE (field)));
+
/* Loop through the initializable fields, gathering initializers. */
while (d->cur != d->end)
{
@@ -5125,7 +5132,10 @@ reshape_init_class (tree type, reshape_iter *d, bo
/* We already reshaped this. */
gcc_assert (d->cur->index == field);
else
- field = lookup_field_1 (type, d->cur->index, /*want_type=*/false);
+ {
+ field = lookup_field_1 (type, d->cur->index, /*want_type=*/false);
+ no_warn_missing_braces = false;
+ }
if (!field || TREE_CODE (field) != FIELD_DECL)
{
@@ -5141,7 +5151,8 @@ reshape_init_class (tree type, reshape_iter *d, bo
break;
field_init = reshape_init_r (TREE_TYPE (field), d,
- /*first_initializer_p=*/false, complain);
+ /*first_initializer_p=*/false,
+ no_warn_missing_braces, complain);
if (field_init == error_mark_node)
return error_mark_node;
@@ -5183,11 +5194,12 @@ has_designator_problem (reshape_iter *d, tsubst_fl
a CONSTRUCTOR). TYPE is the type of the variable being initialized, D is the
iterator within the CONSTRUCTOR which points to the initializer to process.
FIRST_INITIALIZER_P is true if this is the first initializer of the
- outermost CONSTRUCTOR node. */
+ outermost CONSTRUCTOR node. If NO_WARN_MISSING_BRACES is true don't warn
+ about missing braces around initializer. */
static tree
reshape_init_r (tree type, reshape_iter *d, bool first_initializer_p,
- tsubst_flags_t complain)
+ bool no_warn_missing_braces, tsubst_flags_t complain)
{
tree init = d->cur->value;
@@ -5335,8 +5347,9 @@ reshape_init_r (tree type, reshape_iter *d, bool f
}
}
- warning (OPT_Wmissing_braces, "missing braces around initializer for %qT",
- type);
+ if (!no_warn_missing_braces)
+ warning (OPT_Wmissing_braces,
+ "missing braces around initializer for %qT", type);
}
/* Dispatch to specialized routines. */
@@ -5385,7 +5398,8 @@ reshape_init (tree type, tree init, tsubst_flags_t
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, complain);
+ new_init = reshape_init_r (type, &d, true, /*no_warn_missing_braces=*/false,
+ complain);
if (new_init == error_mark_node)
return error_mark_node;