diff options
author | Claudio Jeker <claudio@cvs.openbsd.org> | 2023-01-18 10:27:06 +0000 |
---|---|---|
committer | Claudio Jeker <claudio@cvs.openbsd.org> | 2023-01-18 10:27:06 +0000 |
commit | 2d518efbe7d05e7089920afb8aec8f416382b5b5 (patch) | |
tree | 8d07251b0692c72f82b27c5f0ee3bcb431f7fdb0 /gnu | |
parent | bf1d2764148186e82a3594a58a29730d0a0360e1 (diff) |
Adjust how gcc4 handles the "missing braces around initializer" warning.
In c99 any value can be initalised using a { 0 } constructor independent
of the type. Now if a struct's first member is another struct then gcc4
issues the above warning but it should not do that.
Move the warning check from push_init_level() to pop_init_level() and
check if either { 0 } or { } was used. If additional implicit braces
were added surpress the warning.
Inspired by gcc PR#64709
OK deraadt@ miod@
Diffstat (limited to 'gnu')
-rw-r--r-- | gnu/gcc/gcc/c-typeck.c | 26 |
1 files changed, 20 insertions, 6 deletions
diff --git a/gnu/gcc/gcc/c-typeck.c b/gnu/gcc/gcc/c-typeck.c index 8d3c228b45a..ce565aab113 100644 --- a/gnu/gcc/gcc/c-typeck.c +++ b/gnu/gcc/gcc/c-typeck.c @@ -4873,6 +4873,9 @@ static int constructor_simple; /* 1 if this constructor is erroneous so far. */ static int constructor_erroneous; +/* 1 if this constructor is a zero init. */ +static int constructor_zeroinit; + /* Structure for managing pending initializer elements, organized as an AVL tree. */ @@ -5032,6 +5035,7 @@ start_init (tree decl, tree asmspec_tree ATTRIBUTE_UNUSED, int top_level) constructor_stack = 0; constructor_range_stack = 0; + constructor_zeroinit = 0; missing_braces_mentioned = 0; spelling_base = 0; @@ -5314,12 +5318,6 @@ push_init_level (int implicit) set_nonincremental_init (); } - if (implicit == 1 && warn_missing_braces && !missing_braces_mentioned) - { - missing_braces_mentioned = 1; - warning_init ("missing braces around initializer"); - } - if (TREE_CODE (constructor_type) == RECORD_TYPE || TREE_CODE (constructor_type) == UNION_TYPE) { @@ -5447,6 +5445,22 @@ pop_init_level (int implicit) } } + if (VEC_length (constructor_elt,constructor_elements) == 0) + constructor_zeroinit = 1; + else if (VEC_length (constructor_elt,constructor_elements) == 1 && + initializer_zerop (VEC_index (constructor_elt,constructor_elements,0)->value)) + constructor_zeroinit = 1; + else + constructor_zeroinit = 0; + + /* only warn for missing braces unless it is { 0 } */ + if (p->implicit == 1 && warn_missing_braces && !missing_braces_mentioned && + !constructor_zeroinit) + { + missing_braces_mentioned = 1; + warning_init ("missing braces around initializer"); + } + /* Warn when some struct elements are implicitly initialized to zero. */ if (warn_missing_field_initializers && constructor_type |