diff mbox series

[committed] c-decl: fix "inform" grouping and conditionalization

Message ID 20220616214321.1813697-1-dmalcolm@redhat.com
State New
Headers show
Series [committed] c-decl: fix "inform" grouping and conditionalization | expand

Commit Message

David Malcolm June 16, 2022, 9:43 p.m. UTC
Whilst working on SARIF output I noticed some places where followup notes
weren't being properly associated with their errors/warnings in c-decl.cc.

Whilst fixing those I noticed some places where we "inform" after a
"warning" without checking that the warning was actually emitted.

Fixed the various issues seen in gcc/c/c-decl.cc thusly.

Successfully bootstrapped & regrtested on x86_64-pc-linux-gnu.
Pushed to trunk as r13-1146-gd3e0da54c16e53.

gcc/c/ChangeLog:
	* c-decl.cc (implicitly_declare): Add auto_diagnostic_group to
	group the warning with any note.
	(warn_about_goto): Likewise to group error or warning with note.
	Bail out if the warning wasn't emitted, to avoid emitting orphan
	notes.
	(lookup_label_for_goto): Add auto_diagnostic_group to
	group the error with the note.
	(check_earlier_gotos): Likewise.
	(c_check_switch_jump_warnings): Likewise for any error/warning.
	Conditionalize emission of the notes.
	(diagnose_uninitialized_cst_member): Likewise for warning,
	conditionalizing emission of the note.
	(grokdeclarator): Add auto_diagnostic_group to group the "array
	type has incomplete element type" error with any note.
	(parser_xref_tag): Add auto_diagnostic_group to group warnings
	with their notes.  Conditionalize emission of notes.
	(start_struct): Add auto_diagnostic_group to group the
	"redefinition of" errors with any note.
	(start_enum): Likewise for "redeclaration of %<enum %E%>" error.
	(check_for_loop_decls): Likewise for pre-C99 error.

Signed-off-by: David Malcolm <dmalcolm@redhat.com>
---
 gcc/c/c-decl.cc | 65 ++++++++++++++++++++++++++++++++-----------------
 1 file changed, 42 insertions(+), 23 deletions(-)
diff mbox series

Patch

diff --git a/gcc/c/c-decl.cc b/gcc/c/c-decl.cc
index 5266a61b859..ae8990c138f 100644
--- a/gcc/c/c-decl.cc
+++ b/gcc/c/c-decl.cc
@@ -3697,6 +3697,7 @@  implicitly_declare (location_t loc, tree functionid)
 						      (TREE_TYPE (decl)));
 	      if (!comptypes (newtype, TREE_TYPE (decl)))
 		{
+		  auto_diagnostic_group d;
 		  bool warned = warning_at (loc,
 					    OPT_Wbuiltin_declaration_mismatch,
 					    "incompatible implicit "
@@ -3890,12 +3891,14 @@  lookup_label (tree name)
 static void
 warn_about_goto (location_t goto_loc, tree label, tree decl)
 {
+  auto_diagnostic_group d;
   if (variably_modified_type_p (TREE_TYPE (decl), NULL_TREE))
     error_at (goto_loc,
 	      "jump into scope of identifier with variably modified type");
   else
-    warning_at (goto_loc, OPT_Wjump_misses_init,
-		"jump skips variable initialization");
+    if (!warning_at (goto_loc, OPT_Wjump_misses_init,
+		     "jump skips variable initialization"))
+      return;
   inform (DECL_SOURCE_LOCATION (label), "label %qD defined here", label);
   inform (DECL_SOURCE_LOCATION (decl), "%qD declared here", decl);
 }
@@ -3950,6 +3953,7 @@  lookup_label_for_goto (location_t loc, tree name)
 
   if (label_vars->label_bindings.left_stmt_expr)
     {
+      auto_diagnostic_group d;
       error_at (loc, "jump into statement expression");
       inform (DECL_SOURCE_LOCATION (label), "label %qD defined here", label);
     }
@@ -4040,6 +4044,7 @@  check_earlier_gotos (tree label, struct c_label_vars* label_vars)
 
       if (g->goto_bindings.stmt_exprs > 0)
 	{
+	  auto_diagnostic_group d;
 	  error_at (g->loc, "jump into statement expression");
 	  inform (DECL_SOURCE_LOCATION (label), "label %qD defined here",
 		  label);
@@ -4159,19 +4164,26 @@  c_check_switch_jump_warnings (struct c_spot_bindings *switch_bindings,
 	{
 	  if (decl_jump_unsafe (b->decl))
 	    {
+	      auto_diagnostic_group d;
+	      bool emitted;
 	      if (variably_modified_type_p (TREE_TYPE (b->decl), NULL_TREE))
 		{
 		  saw_error = true;
 		  error_at (case_loc,
 			    ("switch jumps into scope of identifier with "
 			     "variably modified type"));
+		  emitted = true;
 		}
 	      else
-		warning_at (case_loc, OPT_Wjump_misses_init,
-			    "switch jumps over variable initialization");
-	      inform (switch_loc, "switch starts here");
-	      inform (DECL_SOURCE_LOCATION (b->decl), "%qD declared here",
-		      b->decl);
+		emitted
+		  = warning_at (case_loc, OPT_Wjump_misses_init,
+				"switch jumps over variable initialization");
+	      if (emitted)
+		{
+		  inform (switch_loc, "switch starts here");
+		  inform (DECL_SOURCE_LOCATION (b->decl), "%qD declared here",
+			  b->decl);
+		}
 	    }
 	}
     }
@@ -4179,6 +4191,7 @@  c_check_switch_jump_warnings (struct c_spot_bindings *switch_bindings,
   if (switch_bindings->stmt_exprs > 0)
     {
       saw_error = true;
+      auto_diagnostic_group d;
       error_at (case_loc, "switch jumps into statement expression");
       inform (switch_loc, "switch starts here");
     }
@@ -5317,10 +5330,11 @@  diagnose_uninitialized_cst_member (tree decl, tree type)
 
       if (TYPE_QUALS (field_type) & TYPE_QUAL_CONST)
       	{
-	  warning_at (DECL_SOURCE_LOCATION (decl), OPT_Wc___compat,
-	  	      "uninitialized const member in %qT is invalid in C++",
-		      strip_array_types (TREE_TYPE (decl)));
-	  inform (DECL_SOURCE_LOCATION (field), "%qD should be initialized", field);
+	  auto_diagnostic_group d;
+	  if (warning_at (DECL_SOURCE_LOCATION (decl), OPT_Wc___compat,
+			  "uninitialized const member in %qT is invalid in C++",
+			  strip_array_types (TREE_TYPE (decl))))
+	    inform (DECL_SOURCE_LOCATION (field), "%qD should be initialized", field);
 	}
 
       if (RECORD_OR_UNION_TYPE_P (field_type))
@@ -6942,6 +6956,7 @@  grokdeclarator (const struct c_declarator *declarator,
 	    /* Complain about arrays of incomplete types.  */
 	    if (!COMPLETE_TYPE_P (type))
 	      {
+		auto_diagnostic_group d;
 		error_at (loc, "array type has incomplete element type %qT",
 			  type);
 		/* See if we can be more helpful.  */
@@ -8201,25 +8216,26 @@  parser_xref_tag (location_t loc, enum tree_code code, tree name,
 	  && loc != UNKNOWN_LOCATION
 	  && warn_cxx_compat)
 	{
+	  auto_diagnostic_group d;
 	  switch (code)
 	    {
 	    case ENUMERAL_TYPE:
-	      warning_at (loc, OPT_Wc___compat,
-			  ("enum type defined in struct or union "
-			   "is not visible in C++"));
-	      inform (refloc, "enum type defined here");
+	      if (warning_at (loc, OPT_Wc___compat,
+			      ("enum type defined in struct or union "
+			       "is not visible in C++")))
+		  inform (refloc, "enum type defined here");
 	      break;
 	    case RECORD_TYPE:
-	      warning_at (loc, OPT_Wc___compat,
-			  ("struct defined in struct or union "
-			   "is not visible in C++"));
-	      inform (refloc, "struct defined here");
+	      if (warning_at (loc, OPT_Wc___compat,
+			      ("struct defined in struct or union "
+			       "is not visible in C++")))
+		inform (refloc, "struct defined here");
 	      break;
 	    case UNION_TYPE:
-	      warning_at (loc, OPT_Wc___compat,
-			  ("union defined in struct or union "
-			   "is not visible in C++"));
-	      inform (refloc, "union defined here");
+	      if (warning_at (loc, OPT_Wc___compat,
+			      ("union defined in struct or union "
+			       "is not visible in C++")))
+		inform (refloc, "union defined here");
 	      break;
 	    default:
 	      gcc_unreachable();
@@ -8295,6 +8311,7 @@  start_struct (location_t loc, enum tree_code code, tree name,
 
       if (TYPE_SIZE (ref))
 	{
+	  auto_diagnostic_group d;
 	  if (code == UNION_TYPE)
 	    error_at (loc, "redefinition of %<union %E%>", name);
 	  else
@@ -9121,6 +9138,7 @@  start_enum (location_t loc, struct c_enum_contents *the_enum, tree name)
   if (TYPE_VALUES (enumtype) != NULL_TREE)
     {
       /* This enum is a named one that has been declared already.  */
+      auto_diagnostic_group d;
       error_at (loc, "redeclaration of %<enum %E%>", name);
       if (enumloc != UNKNOWN_LOCATION)
 	inform (enumloc, "originally defined here");
@@ -10428,6 +10446,7 @@  check_for_loop_decls (location_t loc, bool turn_off_iso_c99_error)
       /* If we get here, declarations have been used in a for loop without
 	 the C99 for loop scope.  This doesn't make much sense, so don't
 	 allow it.  */
+      auto_diagnostic_group d;
       error_at (loc, "%<for%> loop initial declarations "
 		"are only allowed in C99 or C11 mode");
       if (hint)