[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