[prev in list] [next in list] [prev in thread] [next in thread]
List: gcc
Subject: Re: Need suggestion about bug 68425
From: Prathamesh Kulkarni <prathamesh.kulkarni () linaro ! org>
Date: 2016-02-21 17:43:45
Message-ID: CAAgBjM=5amudF4pUY7sXVRpHBA+SW2mrVjd5rLqmhVTiU1gu7g () mail ! gmail ! com
[Download RAW message or body]
On 21 February 2016 at 12:32, Prasad Ghangal <prasad.ghangal@gmail.com> wrote:
> I was working on PR68425,
>
> my untested patch :
>
>
> diff --git a/trunk/gcc/c/c-typeck.c b/trunk/gcc/c/c-typeck.c
> --- a/trunk/gcc/c/c-typeck.c (revision 232768)
> +++ b/trunk/gcc/c/c-typeck.c (working copy)
> @@ -5856,7 +5856,7 @@
> component name is taken from the spelling stack. */
>
> static void
> -pedwarn_init (location_t location, int opt, const char *gmsgid)
> +pedwarn_init (location_t location, int opt, const char *gmsgid, ...)
You can't just forward arguments to pedwarn() from pedwarn_init() that way.
You will need to wrap them in va_list.
Perhaps write a version of pedwarn() taking va_list or replicate body of
pedwarn() in pedwarn_init()
> {
> char *ofwhat;
> bool warned;
> @@ -9269,8 +9269,10 @@
> && (tree_int_cst_lt (constructor_max_index, constructor_index)
> || integer_all_onesp (constructor_max_index)))
> {
> - pedwarn_init (loc, 0,
> - "excess elements in array initializer");
> + pedwarn_init (loc, 0, "excess elements in array initializer "
> + "(%lu elements, expected %lu)",
> + tree_to_uhwi (constructor_index) + 1,
> + tree_to_uhwi (constructor_max_index) + 1);
> break;
> }
>
>
>
> for test case:
>
> const int array[2] = { 1, 2, 3};
> const int array1[3] = { 1, 2, 3 ,6};
> const int array2[4] = { 1, 2, 3 ,6 ,89};
> const int array3[5] = { 1, 2, 3 ,6 ,89 ,193};
>
>
> It gives :
>
> 68425.c: In function ‘main':
> 68425.c:3:34: warning: excess elements in array initializer (3
> elements, expected 2)
> const int array[2] = { 1, 2, 3};
> ^
> 68425.c:3:34: note: (near initialization for ‘array')
> 68425.c:4:38: warning: excess elements in array initializer (4
> elements, expected 3)
> const int array1[3] = { 1, 2, 3 ,6};
> ^
> 68425.c:4:38: note: (near initialization for ‘array1')
> 68425.c:5:41: warning: excess elements in array initializer (5
> elements, expected 4)
> const int array2[4] = { 1, 2, 3 ,6 ,89};
> ^~
> 68425.c:5:41: note: (near initialization for ‘array2')
> 68425.c:6:45: warning: excess elements in array initializer (6
> elements, expected 5)
> const int array3[5] = { 1, 2, 3 ,6 ,89 ,193};
> ^~~
> 68425.c:6:45: note: (near initialization for ‘array3')
>
>
>
> Which is as described on https://gcc.gnu.org/bugzilla/show_bug.cgi?id=68425
>
>
>
> But as we discussed in this thread,
>
> for test case like :
>
> int array[3] = { 1, 2, 3 ,6 ,89 ,193};
>
>
> It gives:
>
> 68425_1.c: In function ‘main':
> 68425_1.c:3:31: warning: excess elements in array initializer (4
> elements, expected 3)
> int array[3] = { 1, 2, 3 ,6 ,89 ,193};
> ^
> 68425_1.c:3:31: note: (near initialization for ‘array')
> 68425_1.c:3:34: warning: excess elements in array initializer (4
> elements, expected 3)
> int array[3] = { 1, 2, 3 ,6 ,89 ,193};
> ^~
> 68425_1.c:3:34: note: (near initialization for ‘array')
> 68425_1.c:3:38: warning: excess elements in array initializer (4
> elements, expected 3)
> int array[3] = { 1, 2, 3 ,6 ,89 ,193};
> ^~~
> 68425_1.c:3:38: note: (near initialization for ‘array')
>
>
> Should I submit the patch ?
It would be nice if we can avoid warning multiple times.
It appears to me the warning is emitted multiple times because
process_init_element is called from c_parser_initval, which is called from
c_parser_initelt, which is called in a loop from c_parser_braced_init.
I attached an untested patch that prevents multiple warnings.
eg:
void foo(void)
{
int a[2] = { 1, 2, 3, 4, 5 };
}
c-test.c: In function 'foo':
c-test.c:3:22: warning: excess elements in array initializer
int a[2] = { 1, 2, 3, 4, 5 };
^
c-test.c:3:22: note: (near initialization for 'a')
It uses a flag (warn_extra_init) to see if warning for extra initializer
has already been emitted. Perhaps you can try modifying it to emit
array sizes. There could also be a better way to avoid multiple warnings.
Thanks,
Prathamesh
>
>
>
> On 20 February 2016 at 01:20, Manuel López-Ibáñez <lopezibanez@gmail.com> wrote:
>> On 19 February 2016 at 19:13, David Malcolm <dmalcolm@redhat.com> wrote:
>>>> 68425.c:3:34: warning: excess elements in array initializer (6
>>>> elements,
>>>> expected 2)
>>>> const int array[2] = { 1, 2, 3 ,6 ,89 ,193};
>>>> ^~~~~~~~~~~~~
>>>
>>> Yes, that would be ideal. Unfortunately, not every tree expression
>>> node has a location stored for it, so implementing the underlined range
>>> might be tricky to do. (in particular, INTEGER_CST doesn't. I hope to
>>> look into that for gcc 7, perhaps with a wrapper node to provide
>>> locations for expr nodes that don't have them).
>>
>> Do you think that would be better than storing the locations in the
>> parent expression? That is, instead of adding extra wrapper nodes,
>> with all those tree nodes wasting space just to provide a location,
>> add extra location slots to every tree that may have an operand. Or
>> perhaps you are thinking about adding some lighter wrapper which is
>> just a loc+tree* or something like that.
>>
>> In the case above (for C), struct constructor_stack could keep track
>> of token locations passed by the parser (all tokens have locations,
>> but those locations are not saved in all trees). In fact, I see that
>> there is already a lot of location passing in the corresponding code,
>> but probably all of them refer to input_location or some such.
>>
>> Cheers,
>>
>> Manuel.
>
>
>
> --
> Thanks and Regards,
> Prasad Ghangal
["foo.diff" (text/plain)]
diff --git a/gcc/c/c-parser.c b/gcc/c/c-parser.c
index 7a27244..58708da 100644
--- a/gcc/c/c-parser.c
+++ b/gcc/c/c-parser.c
@@ -1295,9 +1295,9 @@ static struct c_type_name *c_parser_type_name (c_parser *);
static struct c_expr c_parser_initializer (c_parser *);
static struct c_expr c_parser_braced_init (c_parser *, tree, bool,
struct obstack *);
-static void c_parser_initelt (c_parser *, struct obstack *);
+static void c_parser_initelt (c_parser *, struct obstack *, bool *);
static void c_parser_initval (c_parser *, struct c_expr *,
- struct obstack *);
+ struct obstack *, bool *);
static tree c_parser_compound_statement (c_parser *);
static void c_parser_compound_statement_nostart (c_parser *);
static void c_parser_label (c_parser *);
@@ -4352,9 +4352,10 @@ c_parser_braced_init (c_parser *parser, tree type, bool nested_p,
{
/* Parse a non-empty initializer list, possibly with a trailing
comma. */
+ bool warn_extra_init = true;
while (true)
{
- c_parser_initelt (parser, &braced_init_obstack);
+ c_parser_initelt (parser, &braced_init_obstack, &warn_extra_init);
if (parser->error)
break;
if (c_parser_next_token_is (parser, CPP_COMMA))
@@ -4387,7 +4388,7 @@ c_parser_braced_init (c_parser *parser, tree type, bool nested_p,
/* Parse a nested initializer, including designators. */
static void
-c_parser_initelt (c_parser *parser, struct obstack * braced_init_obstack)
+c_parser_initelt (c_parser *parser, struct obstack * braced_init_obstack, bool *warn_extra_init)
{
/* Parse any designator or designator list. A single array
designator may have the subsequent "=" omitted in GNU C, but a
@@ -4439,7 +4440,7 @@ c_parser_initelt (c_parser *parser, struct obstack * braced_init_obstack)
c_parser_error (parser, "expected identifier");
c_parser_skip_until_found (parser, CPP_COMMA, NULL);
process_init_element (input_location, init, false,
- braced_init_obstack);
+ braced_init_obstack);
return;
}
}
@@ -4521,7 +4522,7 @@ c_parser_initelt (c_parser *parser, struct obstack * braced_init_obstack)
/* Now parse and process the remainder of the
initializer, starting with this message
expression as a primary-expression. */
- c_parser_initval (parser, &mexpr, braced_init_obstack);
+ c_parser_initval (parser, &mexpr, braced_init_obstack, warn_extra_init);
return;
}
c_parser_consume_token (parser);
@@ -4575,13 +4576,13 @@ c_parser_initelt (c_parser *parser, struct obstack * braced_init_obstack)
c_parser_error (parser, "expected %<=%>");
c_parser_skip_until_found (parser, CPP_COMMA, NULL);
process_init_element (input_location, init, false,
- braced_init_obstack);
+ braced_init_obstack);
return;
}
}
}
}
- c_parser_initval (parser, NULL, braced_init_obstack);
+ c_parser_initval (parser, NULL, braced_init_obstack, warn_extra_init);
}
/* Parse a nested initializer; as c_parser_initializer but parses
@@ -4592,7 +4593,7 @@ c_parser_initelt (c_parser *parser, struct obstack * braced_init_obstack)
static void
c_parser_initval (c_parser *parser, struct c_expr *after,
- struct obstack * braced_init_obstack)
+ struct obstack * braced_init_obstack, bool *warn_extra_init)
{
struct c_expr init;
gcc_assert (!after || c_dialect_objc ());
@@ -4609,7 +4610,7 @@ c_parser_initval (c_parser *parser, struct c_expr *after,
&& TREE_CODE (init.value) != COMPOUND_LITERAL_EXPR)
init = convert_lvalue_to_rvalue (loc, init, true, true);
}
- process_init_element (loc, init, false, braced_init_obstack);
+ process_init_element (loc, init, false, braced_init_obstack, warn_extra_init);
}
/* Parse a compound statement (possibly a function body) (C90 6.6.2,
diff --git a/gcc/c/c-tree.h b/gcc/c/c-tree.h
index 96ab049..6b9d442 100644
--- a/gcc/c/c-tree.h
+++ b/gcc/c/c-tree.h
@@ -631,7 +631,7 @@ extern struct c_expr pop_init_level (location_t, int, struct obstack *);
extern void set_init_index (location_t, tree, tree, struct obstack *);
extern void set_init_label (location_t, tree, struct obstack *);
extern void process_init_element (location_t, struct c_expr, bool,
- struct obstack *);
+ struct obstack *, bool *warn_extra_init = NULL);
extern tree build_compound_literal (location_t, tree, tree, bool);
extern void check_compound_literal_type (location_t, struct c_type_name *);
extern tree c_start_case (location_t, location_t, tree, bool);
diff --git a/gcc/c/c-typeck.c b/gcc/c/c-typeck.c
index 1122a88..d0cbcfc 100644
--- a/gcc/c/c-typeck.c
+++ b/gcc/c/c-typeck.c
@@ -8967,7 +8967,7 @@ output_pending_init_elements (int all, struct obstack * braced_init_obstack)
void
process_init_element (location_t loc, struct c_expr value, bool implicit,
- struct obstack * braced_init_obstack)
+ struct obstack * braced_init_obstack, bool *warn_extra_init)
{
tree orig_value = value.value;
int string_flag = orig_value != 0 && TREE_CODE (orig_value) == STRING_CST;
@@ -9269,9 +9269,13 @@ process_init_element (location_t loc, struct c_expr value, bool implicit,
&& (tree_int_cst_lt (constructor_max_index, constructor_index)
|| integer_all_onesp (constructor_max_index)))
{
- pedwarn_init (loc, 0,
- "excess elements in array initializer");
- break;
+ if (warn_extra_init && *warn_extra_init == true)
+ {
+ pedwarn_init (loc, 0,
+ "excess elements in array initializer");
+ *warn_extra_init = false;
+ break;
+ }
}
/* Now output the actual element. */
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic