diff mbox

[C] Improve column info of initializers (PR c/60114)

Message ID 20140210134420.GV8907@redhat.com
State New
Headers show

Commit Message

Marek Polacek Feb. 10, 2014, 1:44 p.m. UTC
This patch improves location information in a bunch of various
initializers; see the testcase.  Main issue was that digest_init
was getting only input_location.

Regtested/bootstrapped on x86_64-linux, ok for trunk at this stage
or should I queue it for 5.0?

2014-02-10  Marek Polacek  <polacek@redhat.com>

	PR c/60114
c/
	* c-parser.c (c_parser_initelt): Pass input_location to
	process_init_element.
	(c_parser_initval): Pass loc to process_init_element.
	* c-tree.h (process_init_element): Adjust declaration.
	* c-typeck.c (push_init_level): Pass input_location to
	process_init_element.
	(pop_init_level): Likewise.
	(set_designator): Likewise.
	(output_init_element): Add location_t parameter.  Pass loc to
	digest_init.
	(output_pending_init_elements): Pass input_location to
	output_init_element.
	(process_init_element): Add location_t parameter.  Pass loc to
	output_init_element.
testsuite/
	* gcc.dg/pr60114.c: New test.


	Marek

Comments

Jeff Law Feb. 10, 2014, 5:45 p.m. UTC | #1
On 02/10/14 06:44, Marek Polacek wrote:
> This patch improves location information in a bunch of various
> initializers; see the testcase.  Main issue was that digest_init
> was getting only input_location.
>
> Regtested/bootstrapped on x86_64-linux, ok for trunk at this stage
> or should I queue it for 5.0?
>
> 2014-02-10  Marek Polacek  <polacek@redhat.com>
>
> 	PR c/60114
> c/
> 	* c-parser.c (c_parser_initelt): Pass input_location to
> 	process_init_element.
> 	(c_parser_initval): Pass loc to process_init_element.
> 	* c-tree.h (process_init_element): Adjust declaration.
> 	* c-typeck.c (push_init_level): Pass input_location to
> 	process_init_element.
> 	(pop_init_level): Likewise.
> 	(set_designator): Likewise.
> 	(output_init_element): Add location_t parameter.  Pass loc to
> 	digest_init.
> 	(output_pending_init_elements): Pass input_location to
> 	output_init_element.
> 	(process_init_element): Add location_t parameter.  Pass loc to
> 	output_init_element.
> testsuite/
> 	* gcc.dg/pr60114.c: New test.
I'd think this probably should queue for the next stage1.  We're 
probably just ~6wks away at this point anyway.


jeff
Jakub Jelinek Feb. 10, 2014, 6:04 p.m. UTC | #2
On Mon, Feb 10, 2014 at 10:45:24AM -0700, Jeff Law wrote:
> >2014-02-10  Marek Polacek  <polacek@redhat.com>
> >
> >	PR c/60114
> >c/
> >	* c-parser.c (c_parser_initelt): Pass input_location to
> >	process_init_element.
> >	(c_parser_initval): Pass loc to process_init_element.
> >	* c-tree.h (process_init_element): Adjust declaration.
> >	* c-typeck.c (push_init_level): Pass input_location to
> >	process_init_element.
> >	(pop_init_level): Likewise.
> >	(set_designator): Likewise.
> >	(output_init_element): Add location_t parameter.  Pass loc to
> >	digest_init.
> >	(output_pending_init_elements): Pass input_location to
> >	output_init_element.
> >	(process_init_element): Add location_t parameter.  Pass loc to
> >	output_init_element.
> >testsuite/
> >	* gcc.dg/pr60114.c: New test.
> I'd think this probably should queue for the next stage1.  We're
> probably just ~6wks away at this point anyway.

Yeah, agreed, please queue it up for 5.0.

	Jakub
Joseph Myers Feb. 11, 2014, 12:09 a.m. UTC | #3
On Mon, 10 Feb 2014, Marek Polacek wrote:

> This patch improves location information in a bunch of various
> initializers; see the testcase.  Main issue was that digest_init
> was getting only input_location.
> 
> Regtested/bootstrapped on x86_64-linux, ok for trunk at this stage
> or should I queue it for 5.0?

OK for after 4.9 branches.
Marek Polacek April 25, 2014, 10:50 a.m. UTC | #4
On Tue, Feb 11, 2014 at 12:09:39AM +0000, Joseph S. Myers wrote:
> On Mon, 10 Feb 2014, Marek Polacek wrote:
> 
> > This patch improves location information in a bunch of various
> > initializers; see the testcase.  Main issue was that digest_init
> > was getting only input_location.
> > 
> > Regtested/bootstrapped on x86_64-linux, ok for trunk at this stage
> > or should I queue it for 5.0?
> 
> OK for after 4.9 branches.

I've committed the patch (after another regtest/bootstrap).

	Marek
diff mbox

Patch

diff --git gcc/c/c-parser.c gcc/c/c-parser.c
index 66625aa..75ce935 100644
--- gcc/c/c-parser.c
+++ gcc/c/c-parser.c
@@ -4219,7 +4219,8 @@  c_parser_initelt (c_parser *parser, struct obstack * braced_init_obstack)
 		  init.original_type = NULL;
 		  c_parser_error (parser, "expected identifier");
 		  c_parser_skip_until_found (parser, CPP_COMMA, NULL);
-		  process_init_element (init, false, braced_init_obstack);
+		  process_init_element (input_location, init, false,
+					braced_init_obstack);
 		  return;
 		}
 	    }
@@ -4351,7 +4352,8 @@  c_parser_initelt (c_parser *parser, struct obstack * braced_init_obstack)
 		  init.original_type = NULL;
 		  c_parser_error (parser, "expected %<=%>");
 		  c_parser_skip_until_found (parser, CPP_COMMA, NULL);
-		  process_init_element (init, false, braced_init_obstack);
+		  process_init_element (input_location, init, false,
+					braced_init_obstack);
 		  return;
 		}
 	    }
@@ -4372,18 +4374,19 @@  c_parser_initval (c_parser *parser, struct c_expr *after,
 {
   struct c_expr init;
   gcc_assert (!after || c_dialect_objc ());
+  location_t loc = c_parser_peek_token (parser)->location;
+
   if (c_parser_next_token_is (parser, CPP_OPEN_BRACE) && !after)
     init = c_parser_braced_init (parser, NULL_TREE, true);
   else
     {
-      location_t loc = c_parser_peek_token (parser)->location;
       init = c_parser_expr_no_commas (parser, after);
       if (init.value != NULL_TREE
 	  && TREE_CODE (init.value) != STRING_CST
 	  && TREE_CODE (init.value) != COMPOUND_LITERAL_EXPR)
 	init = convert_lvalue_to_rvalue (loc, init, true, true);
     }
-  process_init_element (init, false, braced_init_obstack);
+  process_init_element (loc, init, false, braced_init_obstack);
 }
 
 /* Parse a compound statement (possibly a function body) (C90 6.6.2,
diff --git gcc/c/c-tree.h gcc/c/c-tree.h
index 84d5e0b..ec1fa92 100644
--- gcc/c/c-tree.h
+++ gcc/c/c-tree.h
@@ -612,7 +612,8 @@  extern void push_init_level (int, struct obstack *);
 extern struct c_expr pop_init_level (int, struct obstack *);
 extern void set_init_index (tree, tree, struct obstack *);
 extern void set_init_label (tree, struct obstack *);
-extern void process_init_element (struct c_expr, bool, struct obstack *);
+extern void process_init_element (location_t, struct c_expr, bool,
+				  struct obstack *);
 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);
diff --git gcc/c/c-typeck.c gcc/c/c-typeck.c
index da6a6fc..6953881 100644
--- gcc/c/c-typeck.c
+++ gcc/c/c-typeck.c
@@ -102,8 +102,8 @@  static int spelling_length (void);
 static char *print_spelling (char *);
 static void warning_init (int, const char *);
 static tree digest_init (location_t, tree, tree, tree, bool, bool, int);
-static void output_init_element (tree, tree, bool, tree, tree, int, bool,
-				 struct obstack *);
+static void output_init_element (location_t, tree, tree, bool, tree, tree, int,
+				 bool, struct obstack *);
 static void output_pending_init_elements (int, struct obstack *);
 static int set_designator (int, struct obstack *);
 static void push_range_stack (tree, struct obstack *);
@@ -7161,13 +7161,15 @@  push_init_level (int implicit, struct obstack * braced_init_obstack)
 	  if ((TREE_CODE (constructor_type) == RECORD_TYPE
 	       || TREE_CODE (constructor_type) == UNION_TYPE)
 	      && constructor_fields == 0)
-	    process_init_element (pop_init_level (1, braced_init_obstack),
+	    process_init_element (input_location,
+				  pop_init_level (1, braced_init_obstack),
 				  true, braced_init_obstack);
 	  else if (TREE_CODE (constructor_type) == ARRAY_TYPE
 		   && constructor_max_index
 		   && tree_int_cst_lt (constructor_max_index,
 				       constructor_index))
-	    process_init_element (pop_init_level (1, braced_init_obstack),
+	    process_init_element (input_location,
+				  pop_init_level (1, braced_init_obstack),
 				  true, braced_init_obstack);
 	  else
 	    break;
@@ -7367,10 +7369,9 @@  pop_init_level (int implicit, struct obstack * braced_init_obstack)
       /* When we come to an explicit close brace,
 	 pop any inner levels that didn't have explicit braces.  */
       while (constructor_stack->implicit)
-	{
-	  process_init_element (pop_init_level (1, braced_init_obstack),
-				true, braced_init_obstack);
-	}
+	process_init_element (input_location,
+			      pop_init_level (1, braced_init_obstack),
+			      true, braced_init_obstack);
       gcc_assert (!constructor_range_stack);
     }
 
@@ -7548,10 +7549,9 @@  set_designator (int array, struct obstack * braced_init_obstack)
       /* Designator list starts at the level of closest explicit
 	 braces.  */
       while (constructor_stack->implicit)
-	{
-	  process_init_element (pop_init_level (1, braced_init_obstack),
-				true, braced_init_obstack);
-	}
+	process_init_element (input_location,
+			      pop_init_level (1, braced_init_obstack),
+			      true, braced_init_obstack);
       constructor_designated = 1;
       return 0;
     }
@@ -8171,9 +8171,9 @@  find_init_member (tree field, struct obstack * braced_init_obstack)
    existing initializer.  */
 
 static void
-output_init_element (tree value, tree origtype, bool strict_string, tree type,
-		     tree field, int pending, bool implicit,
-		     struct obstack * braced_init_obstack)
+output_init_element (location_t loc, tree value, tree origtype,
+		     bool strict_string, tree type, tree field, int pending,
+		     bool implicit, struct obstack * braced_init_obstack)
 {
   tree semantic_type = NULL_TREE;
   bool maybe_const = true;
@@ -8271,8 +8271,8 @@  output_init_element (tree value, tree origtype, bool strict_string, tree type,
 
   if (semantic_type)
     value = build1 (EXCESS_PRECISION_EXPR, semantic_type, value);
-  value = digest_init (input_location, type, value, origtype, npc,
-      		       strict_string, require_constant_value);
+  value = digest_init (loc, type, value, origtype, npc, strict_string,
+		       require_constant_value);
   if (value == error_mark_node)
     {
       constructor_erroneous = 1;
@@ -8399,8 +8399,8 @@  output_pending_init_elements (int all, struct obstack * braced_init_obstack)
 	{
 	  if (tree_int_cst_equal (elt->purpose,
 				  constructor_unfilled_index))
-	    output_init_element (elt->value, elt->origtype, true,
-				 TREE_TYPE (constructor_type),
+	    output_init_element (input_location, elt->value, elt->origtype,
+				 true, TREE_TYPE (constructor_type),
 				 constructor_unfilled_index, 0, false,
 				 braced_init_obstack);
 	  else if (tree_int_cst_lt (constructor_unfilled_index,
@@ -8454,8 +8454,8 @@  output_pending_init_elements (int all, struct obstack * braced_init_obstack)
 	  if (tree_int_cst_equal (elt_bitpos, ctor_unfilled_bitpos))
 	    {
 	      constructor_unfilled_fields = elt->purpose;
-	      output_init_element (elt->value, elt->origtype, true,
-				   TREE_TYPE (elt->purpose),
+	      output_init_element (input_location, elt->value, elt->origtype,
+				   true, TREE_TYPE (elt->purpose),
 				   elt->purpose, 0, false,
 				   braced_init_obstack);
 	    }
@@ -8528,7 +8528,7 @@  output_pending_init_elements (int all, struct obstack * braced_init_obstack)
    existing initializer.  */
 
 void
-process_init_element (struct c_expr value, bool implicit,
+process_init_element (location_t loc, struct c_expr value, bool implicit,
 		      struct obstack * braced_init_obstack)
 {
   tree orig_value = value.value;
@@ -8572,14 +8572,14 @@  process_init_element (struct c_expr value, bool implicit,
       if ((TREE_CODE (constructor_type) == RECORD_TYPE
 	   || TREE_CODE (constructor_type) == UNION_TYPE)
 	  && constructor_fields == 0)
-	process_init_element (pop_init_level (1, braced_init_obstack),
+	process_init_element (loc, pop_init_level (1, braced_init_obstack),
 			      true, braced_init_obstack);
       else if ((TREE_CODE (constructor_type) == ARRAY_TYPE
 	        || TREE_CODE (constructor_type) == VECTOR_TYPE)
 	       && constructor_max_index
 	       && tree_int_cst_lt (constructor_max_index,
 				   constructor_index))
-	process_init_element (pop_init_level (1, braced_init_obstack),
+	process_init_element (loc, pop_init_level (1, braced_init_obstack),
 			      true, braced_init_obstack);
       else
 	break;
@@ -8657,7 +8657,7 @@  process_init_element (struct c_expr value, bool implicit,
 	  if (value.value)
 	    {
 	      push_member_name (constructor_fields);
-	      output_init_element (value.value, value.original_type,
+	      output_init_element (loc, value.value, value.original_type,
 				   strict_string, fieldtype,
 				   constructor_fields, 1, implicit,
 				   braced_init_obstack);
@@ -8749,7 +8749,7 @@  process_init_element (struct c_expr value, bool implicit,
 	  if (value.value)
 	    {
 	      push_member_name (constructor_fields);
-	      output_init_element (value.value, value.original_type,
+	      output_init_element (loc, value.value, value.original_type,
 				   strict_string, fieldtype,
 				   constructor_fields, 1, implicit,
 				   braced_init_obstack);
@@ -8801,7 +8801,7 @@  process_init_element (struct c_expr value, bool implicit,
 	  if (value.value)
 	    {
 	      push_array_bounds (tree_to_uhwi (constructor_index));
-	      output_init_element (value.value, value.original_type,
+	      output_init_element (loc, value.value, value.original_type,
 				   strict_string, elttype,
 				   constructor_index, 1, implicit,
 				   braced_init_obstack);
@@ -8836,7 +8836,7 @@  process_init_element (struct c_expr value, bool implicit,
 	    {
 	      if (TREE_CODE (value.value) == VECTOR_CST)
 		elttype = TYPE_MAIN_VARIANT (constructor_type);
-	      output_init_element (value.value, value.original_type,
+	      output_init_element (loc, value.value, value.original_type,
 				   strict_string, elttype,
 				   constructor_index, 1, implicit,
 				   braced_init_obstack);
@@ -8865,7 +8865,7 @@  process_init_element (struct c_expr value, bool implicit,
       else
 	{
 	  if (value.value)
-	    output_init_element (value.value, value.original_type,
+	    output_init_element (loc, value.value, value.original_type,
 				 strict_string, constructor_type,
 				 NULL_TREE, 1, implicit,
 				 braced_init_obstack);
@@ -8884,8 +8884,8 @@  process_init_element (struct c_expr value, bool implicit,
 	  while (constructor_stack != range_stack->stack)
 	    {
 	      gcc_assert (constructor_stack->implicit);
-	      process_init_element (pop_init_level (1,
-						    braced_init_obstack),
+	      process_init_element (loc,
+				    pop_init_level (1, braced_init_obstack),
 				    true, braced_init_obstack);
 	    }
 	  for (p = range_stack;
@@ -8893,7 +8893,8 @@  process_init_element (struct c_expr value, bool implicit,
 	       p = p->prev)
 	    {
 	      gcc_assert (constructor_stack->implicit);
-	      process_init_element (pop_init_level (1, braced_init_obstack),
+	      process_init_element (loc,
+				    pop_init_level (1, braced_init_obstack),
 				    true, braced_init_obstack);
 	    }
 
diff --git gcc/testsuite/gcc.dg/pr60114.c gcc/testsuite/gcc.dg/pr60114.c
index e69de29..83f9852 100644
--- gcc/testsuite/gcc.dg/pr60114.c
+++ gcc/testsuite/gcc.dg/pr60114.c
@@ -0,0 +1,31 @@ 
+/* PR c/60114 */
+/* { dg-do compile } */
+/* { dg-options "-Wconversion" } */
+
+struct S { int n, u[2]; };
+const char z[] = {
+  [0] = 0x100, /* { dg-warning "9:overflow in implicit constant conversion" } */
+  [2] = 0x101, /* { dg-warning "9:overflow in implicit constant conversion" } */
+};
+int A[] = {
+            0, 0x80000000, /* { dg-warning "16:conversion of unsigned constant value to negative integer" } */
+            0xA, 0x80000000, /* { dg-warning "18:conversion of unsigned constant value to negative integer" } */
+            0xA, 0xA, 0x80000000 /* { dg-warning "23:conversion of unsigned constant value to negative integer" } */
+          };
+int *p = (int []) { 0x80000000 }; /* { dg-warning "21:conversion of unsigned constant value to negative integer" } */
+union { int k; } u = { .k = 0x80000000 }; /* { dg-warning "29:conversion of unsigned constant value to negative integer" } */
+typedef int H[];
+void
+foo (void)
+{
+  char a[][3] = { { 0x100, /* { dg-warning "21:overflow in implicit constant conversion" } */
+                    1, 0x100 }, /* { dg-warning "24:overflow in implicit constant conversion" } */
+                  { '\0', 0x100, '\0' } /* { dg-warning "27:overflow in implicit constant conversion" } */
+                };
+  (const char []) { 0x100 }; /* { dg-warning "21:overflow in implicit constant conversion" } */
+  (const float []) { 1e0, 1e1, 1e100 }; /* { dg-warning "32:conversion" } */
+  struct S s1 = { 0x80000000 }; /* { dg-warning "19:conversion of unsigned constant value to negative integer" } */
+  struct S s2 = { .n = 0x80000000 }; /* { dg-warning "24:conversion of unsigned constant value to negative integer" } */
+  struct S s3 = { .u[1] = 0x80000000 }; /* { dg-warning "27:conversion of unsigned constant value to negative integer" } */
+  H h = { 1, 2, 0x80000000 }; /* { dg-warning "17:conversion of unsigned constant value to negative integer" } */
+}