diff mbox

[C] Another locus improvements (PR c/60257)

Message ID 20140426091512.GA23721@redhat.com
State New
Headers show

Commit Message

Marek Polacek April 26, 2014, 9:15 a.m. UTC
Another column info improvements, this time for initializer
warnings.  warning_init and add_pending_init had to gain new location
parameter.

What is worth mentioning is that the "(near initialization for X)"
message seems next to useless to me now with caret diagnostics (?).

Regtested/bootstrapped on powerpc64-unknown-linux-gnu and
x86_64-unknown-linux-gnu, ok for trunk?

2014-04-25  Marek Polacek  <polacek@redhat.com>

	PR c/60257
	* c-typeck.c (warning_init): Add location_t parameter.  Call
	warning_at instead of warning.
	(push_init_level): Pass input_location to warning_init.
	(add_pending_init): Add location_t parameter.  Pass loc to
	warning_init.
	(set_nonincremental_init): Pass input_location to add_pending_init.
	(set_nonincremental_init_from_string): Likewise.
	(output_init_element): Pass loc to warning_init and to
	add_pending_init.

	* gcc.dg/pr60257.c: New test.


	Marek

Comments

Jeff Law April 30, 2014, 9:18 p.m. UTC | #1
On 04/26/14 03:15, Marek Polacek wrote:
> Another column info improvements, this time for initializer
> warnings.  warning_init and add_pending_init had to gain new location
> parameter.
>
> What is worth mentioning is that the "(near initialization for X)"
> message seems next to useless to me now with caret diagnostics (?).
>
> Regtested/bootstrapped on powerpc64-unknown-linux-gnu and
> x86_64-unknown-linux-gnu, ok for trunk?
>
> 2014-04-25  Marek Polacek  <polacek@redhat.com>
>
> 	PR c/60257
> 	* c-typeck.c (warning_init): Add location_t parameter.  Call
> 	warning_at instead of warning.
> 	(push_init_level): Pass input_location to warning_init.
> 	(add_pending_init): Add location_t parameter.  Pass loc to
> 	warning_init.
> 	(set_nonincremental_init): Pass input_location to add_pending_init.
> 	(set_nonincremental_init_from_string): Likewise.
> 	(output_init_element): Pass loc to warning_init and to
> 	add_pending_init.
>
> 	* gcc.dg/pr60257.c: New test.
OK.  Thanks.

Jeff
Joseph Myers May 2, 2014, 12:11 a.m. UTC | #2
On Sat, 26 Apr 2014, Marek Polacek wrote:

> What is worth mentioning is that the "(near initialization for X)"
> message seems next to useless to me now with caret diagnostics (?).

The caret diagnostics point to the initializer.  "near initialization" 
says (or should say) what field GCC thinks is being initialized, which may 
not be obvious from looking at the initializer (consider a 100-element 
structure where the initializer for one element is missing, resulting in 
errors for subsequent elements having the wrong type; being told which 
element GCC thinks matches the initializer with a bad type may help you 
find where the missing initializer is).
Marek Polacek May 2, 2014, 1:12 p.m. UTC | #3
On Fri, May 02, 2014 at 12:11:02AM +0000, Joseph S. Myers wrote:
> On Sat, 26 Apr 2014, Marek Polacek wrote:
> 
> > What is worth mentioning is that the "(near initialization for X)"
> > message seems next to useless to me now with caret diagnostics (?).
> 
> The caret diagnostics point to the initializer.  "near initialization" 
> says (or should say) what field GCC thinks is being initialized, which may 
> not be obvious from looking at the initializer (consider a 100-element 
> structure where the initializer for one element is missing, resulting in 
> errors for subsequent elements having the wrong type; being told which 
> element GCC thinks matches the initializer with a bad type may help you 
> find where the missing initializer is).

I see, thanks.  It would be nice if we could show the previous
initialization in some note message...

	Marek
diff mbox

Patch

diff --git gcc/c/c-typeck.c gcc/c/c-typeck.c
index a82801f..5a232ec 100644
--- gcc/c/c-typeck.c
+++ gcc/c/c-typeck.c
@@ -100,14 +100,15 @@  static void push_string (const char *);
 static void push_member_name (tree);
 static int spelling_length (void);
 static char *print_spelling (char *);
-static void warning_init (int, const char *);
+static void warning_init (location_t, int, const char *);
 static tree digest_init (location_t, tree, tree, tree, bool, bool, int);
 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 *);
-static void add_pending_init (tree, tree, tree, bool, struct obstack *);
+static void add_pending_init (location_t, tree, tree, tree, bool,
+			      struct obstack *);
 static void set_nonincremental_init (struct obstack *);
 static void set_nonincremental_init_from_string (tree, struct obstack *);
 static tree find_init_member (tree, struct obstack *);
@@ -6445,15 +6446,15 @@  pedwarn_init (location_t location, int opt, const char *gmsgid)
    component name is taken from the spelling stack.  */
 
 static void
-warning_init (int opt, const char *gmsgid)
+warning_init (location_t loc, int opt, const char *gmsgid)
 {
   char *ofwhat;
 
   /* The gmsgid may be a format string with %< and %>. */
-  warning (opt, gmsgid);
+  warning_at (loc, opt, gmsgid);
   ofwhat = print_spelling ((char *) alloca (spelling_length () + 1));
   if (*ofwhat)
-    warning (opt, "(near initialization for %qs)", ofwhat);
+    warning_at (loc, opt, "(near initialization for %qs)", ofwhat);
 }
 
 /* If TYPE is an array type and EXPR is a parenthesized string
@@ -7299,7 +7300,8 @@  push_init_level (int implicit, struct obstack * braced_init_obstack)
   if (implicit == 1 && warn_missing_braces && !missing_braces_mentioned)
     {
       missing_braces_mentioned = 1;
-      warning_init (OPT_Wmissing_braces, "missing braces around initializer");
+      warning_init (input_location, OPT_Wmissing_braces,
+		    "missing braces around initializer");
     }
 
   if (TREE_CODE (constructor_type) == RECORD_TYPE
@@ -7360,7 +7362,7 @@  push_init_level (int implicit, struct obstack * braced_init_obstack)
   else
     {
       if (constructor_type != error_mark_node)
-	warning_init (0, "braces around scalar initializer");
+	warning_init (input_location, 0, "braces around scalar initializer");
       constructor_fields = constructor_type;
       constructor_unfilled_fields = constructor_type;
     }
@@ -7775,8 +7777,8 @@  set_init_label (tree fieldname, struct obstack * braced_init_obstack)
    existing initializer.  */
 
 static void
-add_pending_init (tree purpose, tree value, tree origtype, bool implicit,
-		  struct obstack * braced_init_obstack)
+add_pending_init (location_t loc, tree purpose, tree value, tree origtype,
+		  bool implicit, struct obstack *braced_init_obstack)
 {
   struct init_node *p, **q, *r;
 
@@ -7797,9 +7799,12 @@  add_pending_init (tree purpose, tree value, tree origtype, bool implicit,
 	      if (!implicit)
 		{
 		  if (TREE_SIDE_EFFECTS (p->value))
-		    warning_init (0, "initialized field with side-effects overwritten");
+		    warning_init (loc, 0,
+				  "initialized field with side-effects "
+				  "overwritten");
 		  else if (warn_override_init)
-		    warning_init (OPT_Woverride_init, "initialized field overwritten");
+		    warning_init (loc, OPT_Woverride_init,
+				  "initialized field overwritten");
 		}
 	      p->value = value;
 	      p->origtype = origtype;
@@ -7824,9 +7829,12 @@  add_pending_init (tree purpose, tree value, tree origtype, bool implicit,
 	      if (!implicit)
 		{
 		  if (TREE_SIDE_EFFECTS (p->value))
-		    warning_init (0, "initialized field with side-effects overwritten");
+		    warning_init (loc, 0,
+				  "initialized field with side-effects "
+				  "overwritten");
 		  else if (warn_override_init)
-		    warning_init (OPT_Woverride_init, "initialized field overwritten");
+		    warning_init (loc, OPT_Woverride_init,
+				  "initialized field overwritten");
 		}
 	      p->value = value;
 	      p->origtype = origtype;
@@ -8015,10 +8023,8 @@  set_nonincremental_init (struct obstack * braced_init_obstack)
     return;
 
   FOR_EACH_CONSTRUCTOR_ELT (constructor_elements, ix, index, value)
-    {
-      add_pending_init (index, value, NULL_TREE, true,
-			braced_init_obstack);
-    }
+    add_pending_init (input_location, index, value, NULL_TREE, true,
+		      braced_init_obstack);
   constructor_elements = NULL;
   if (TREE_CODE (constructor_type) == RECORD_TYPE)
     {
@@ -8111,7 +8117,7 @@  set_nonincremental_init_from_string (tree str,
 	}
 
       value = build_int_cst_wide (type, val[1], val[0]);
-      add_pending_init (purpose, value, NULL_TREE, true,
+      add_pending_init (input_location, purpose, value, NULL_TREE, true,
                         braced_init_obstack);
     }
 
@@ -8277,7 +8283,7 @@  output_init_element (location_t loc, tree value, tree origtype,
       if (checktype != error_mark_node
 	  && (TYPE_MAIN_VARIANT (checktype)
 	      != TYPE_MAIN_VARIANT (DECL_BIT_FIELD_TYPE (field))))
-	warning_init (OPT_Wc___compat,
+	warning_init (loc, OPT_Wc___compat,
 		      "enum conversion in initialization is invalid in C++");
     }
 
@@ -8313,7 +8319,7 @@  output_init_element (location_t loc, tree value, tree origtype,
 	  && tree_int_cst_lt (field, constructor_unfilled_index))
 	set_nonincremental_init (braced_init_obstack);
 
-      add_pending_init (field, value, origtype, implicit,
+      add_pending_init (loc, field, value, origtype, implicit,
 			braced_init_obstack);
       return;
     }
@@ -8340,7 +8346,7 @@  output_init_element (location_t loc, tree value, tree origtype,
 	    }
 	}
 
-      add_pending_init (field, value, origtype, implicit,
+      add_pending_init (loc, field, value, origtype, implicit,
 			braced_init_obstack);
       return;
     }
@@ -8350,10 +8356,11 @@  output_init_element (location_t loc, tree value, tree origtype,
       if (!implicit)
 	{
 	  if (TREE_SIDE_EFFECTS (constructor_elements->last ().value))
-	    warning_init (0,
+	    warning_init (loc, 0,
 			  "initialized field with side-effects overwritten");
 	  else if (warn_override_init)
-	    warning_init (OPT_Woverride_init, "initialized field overwritten");
+	    warning_init (loc, OPT_Woverride_init,
+			  "initialized field overwritten");
 	}
 
       /* We can have just one union field set.  */
diff --git gcc/testsuite/gcc.dg/pr60257.c gcc/testsuite/gcc.dg/pr60257.c
index e69de29..46c29b0 100644
--- gcc/testsuite/gcc.dg/pr60257.c
+++ gcc/testsuite/gcc.dg/pr60257.c
@@ -0,0 +1,37 @@ 
+/* PR c/60257 */
+/* { dg-do compile } */
+/* { dg-options "-Wc++-compat -Woverride-init" } */
+/* { dg-prune-output ".*near initialization for.*" } */
+
+enum E1 { A };
+enum E2 { B };
+
+struct S
+{
+  enum E1 e: 3;
+};
+
+struct S s[] =
+{
+  { B } /* { dg-warning "5:enum conversion in initialization is invalid in C\[+\]\[+\]" } */
+};
+
+union U {
+  int i;
+  long long int l;
+};
+
+struct R {
+  int a;
+};
+
+void
+foo (int i)
+{
+  union U u = { .i = ++i, .l = 1 }; /* { dg-warning "32:initialized field with side-effects overwritten" } */
+  union U u2 = { .i = 1, .l = 3 }; /* { dg-warning "31:initialized field overwritten" } */
+  int a[] = { i++, [0] = 1 }; /* { dg-warning "26:initialized field with side-effects overwritten" } */
+  int a2[] = { i, [0] = 1 }; /* { dg-warning "25:initialized field overwritten" } */
+  struct R r = { 1, .a = 2 }; /* { dg-warning "26:initialized field overwritten" } */
+  struct R r2 = { ++i, .a = 2 }; /* { dg-warning "29:initialized field with side-effects overwritten" } */
+}