Hi,

the following patch implements the option to fine control the emitted
warnings --
1) allow suppressing warnings for use of values that may be
uninitialized.  Definitely uninitialized values that may be used
warning is not affected
2) allow fine grain control on promotion of warnings to errors:
-Wno-error=maybe-uninitialized

This is useful for users who only care about definite uninitialized
variable warnings.

Ok for trunk?

thanks,

David


2011-04-07  Xinliang David Li  <davi...@google.com>

        * tree-ssa-uninit.c (warn_uninitialized_phi): Pass
        warning code.
        * c-family/c-opts.c (c_common_handle_option): Set
        warn_maybe_uninitialized.
        * opts.c (common_handle_option): Ditto.
        * common.opt:  New option.
        * tree-ssa.c (warn_uninit): Add one more parameter.
        (warn_uninitialized_var): Pass warning code.
        * tree-flow.h: Interface change.



2011-04-07  Xinliang David Li  <davi...@google.com>

        * gcc.dg/uninit-suppress.c: New test.
        * gcc.dg/uninit-suppress_2.c: New test.
Index: doc/invoke.texi
===================================================================
--- doc/invoke.texi	(revision 171959)
+++ doc/invoke.texi	(working copy)
@@ -246,11 +246,11 @@ Objective-C and Objective-C++ Dialects}.
 -Wformat-security  -Wformat-y2k @gol
 -Wframe-larger-than=@var{len} -Wjump-misses-init -Wignored-qualifiers @gol
 -Wimplicit  -Wimplicit-function-declaration  -Wimplicit-int @gol
--Winit-self  -Winline @gol
+-Winit-self  -Winline -Wmaybe-uninitialized @gol
 -Wno-int-to-pointer-cast -Wno-invalid-offsetof @gol
 -Winvalid-pch -Wlarger-than=@var{len}  -Wunsafe-loop-optimizations @gol
 -Wlogical-op -Wlong-long @gol
--Wmain  -Wmissing-braces  -Wmissing-field-initializers @gol
+-Wmain -Wmaybe-uninitialized -Wmissing-braces  -Wmissing-field-initializers @gol
 -Wmissing-format-attribute  -Wmissing-include-dirs @gol
 -Wno-mudflap @gol
 -Wno-multichar  -Wnonnull  -Wno-overflow @gol
@@ -2945,6 +2945,7 @@ Options} and @ref{Objective-C and Object
 -Wcomment  @gol
 -Wformat   @gol
 -Wmain @r{(only for C/ObjC and unless} @option{-ffreestanding}@r{)}  @gol
+-Wmaybe-uninitialized @gol
 -Wmissing-braces  @gol
 -Wnonnull  @gol
 -Wparentheses  @gol
@@ -3529,8 +3530,15 @@ to compute a value that itself is never 
 computations may be deleted by data flow analysis before the warnings
 are printed.
 
-These warnings are made optional because GCC is not smart
-enough to see all the reasons why the code might be correct
+@item -Wmaybe-uninitialized
+@opindex Wmaybe-uninitialized
+@opindex Wno-maybe-uninitialized
+For an automatic variable, if there exists a path from the function
+entry to a use of the variable that is initialized, but there exist
+some other paths the variable is not initialized, the compiler will
+emit a warning if it can not prove the uninitialized paths do not
+happen at runtime. These warnings are made optional because GCC is 
+not smart enough to see all the reasons why the code might be correct
 despite appearing to have an error.  Here is one example of how
 this can happen:
 
@@ -3553,20 +3561,9 @@ this can happen:
 
 @noindent
 If the value of @code{y} is always 1, 2 or 3, then @code{x} is
-always initialized, but GCC doesn't know this.  Here is
-another common case:
-
-@smallexample
-@{
-  int save_y;
-  if (change_y) save_y = y, y = new_y;
-  @dots{}
-  if (change_y) y = save_y;
-@}
-@end smallexample
-
-@noindent
-This has no bug because @code{save_y} is used only if it is set.
+always initialized, but GCC doesn't know this. To suppress the
+warning, the user needs to provide a default case with assert(0) or
+similar code.
 
 @cindex @code{longjmp} warnings
 This option also warns when a non-volatile automatic variable might be
Index: tree-ssa-uninit.c
===================================================================
--- tree-ssa-uninit.c	(revision 171959)
+++ tree-ssa-uninit.c	(working copy)
@@ -1955,7 +1955,7 @@ warn_uninitialized_phi (gimple phi, VEC(
     return;
 
   uninit_op = gimple_phi_arg_def (phi, MASK_FIRST_SET_BIT (uninit_opnds));
-  warn_uninit (uninit_op,
+  warn_uninit (OPT_Wmaybe_uninitialized, uninit_op,
                "%qD may be used uninitialized in this function",
                uninit_use_stmt);
 
Index: c-family/c-opts.c
===================================================================
--- c-family/c-opts.c	(revision 171959)
+++ c-family/c-opts.c	(working copy)
@@ -379,6 +379,7 @@ c_common_handle_option (size_t scode, co
       warn_unknown_pragmas = value;
 
       warn_uninitialized = value;
+      warn_maybe_uninitialized = value;
 
       if (!c_dialect_cxx ())
 	{
Index: testsuite/gcc.dg/uninit-suppress.c
===================================================================
--- testsuite/gcc.dg/uninit-suppress.c	(revision 0)
+++ testsuite/gcc.dg/uninit-suppress.c	(revision 0)
@@ -0,0 +1,16 @@
+/* { dg-do compile } */
+/* { dg-options "-fno-tree-ccp -O2 -Wuninitialized -Wno-maybe-uninitialized" } */
+void blah();
+int gflag;
+
+void foo()
+{
+   int v;
+   if (gflag)
+     v = 10;
+
+   blah(); /* *gflag may be killed, but compiler won't know */
+
+   if (gflag)
+    bar(v);   /* { dg-bogus "uninitialized" "should be suppressed" } */
+}
Index: testsuite/gcc.dg/uninit-suppress_2.c
===================================================================
--- testsuite/gcc.dg/uninit-suppress_2.c	(revision 0)
+++ testsuite/gcc.dg/uninit-suppress_2.c	(revision 0)
@@ -0,0 +1,16 @@
+/* { dg-do compile } */
+/* { dg-options "-fno-tree-ccp -O2 -Wuninitialized -Werror=uninitialized -Wno-error=maybe-uninitialized" } */
+void blah();
+int gflag;
+
+void foo()
+{
+   int v;
+   if (gflag)
+     v = 10;
+
+   blah(); /* *gflag may be killed, but compiler won't know */
+
+   if (gflag)
+    bar(v);   /* { dg-warning "uninitialized" "should not be promoted to error" } */
+}
Index: opts.c
===================================================================
--- opts.c	(revision 171959)
+++ opts.c	(working copy)
@@ -1680,6 +1680,11 @@ common_handle_option (struct gcc_options
       /* No-op. Used by the driver and passed to us because it starts with f.*/
       break;
 
+    case OPT_Wuninitialized:
+      /* Also turn on maybe uninitialized warning.  */
+      warn_maybe_uninitialized = value;
+      break;
+
     default:
       /* If the flag was handled in a standard way, assume the lack of
 	 processing here is intentional.  */
@@ -1958,6 +1963,9 @@ enable_warning_as_error (const char *arg
       control_warning_option (option_index, (int) kind, value,
 			      loc, lang_mask,
 			      handlers, opts, opts_set, dc);
+      if (option_index == OPT_Wuninitialized)
+        enable_warning_as_error ("maybe-uninitialized", value, lang_mask,
+	                         handlers, opts, opts_set, loc, dc);
     }
   free (new_option);
 }
Index: common.opt
===================================================================
--- common.opt	(revision 171959)
+++ common.opt	(working copy)
@@ -622,6 +622,10 @@ Wuninitialized
 Common Var(warn_uninitialized) Init(-1) Warning
 Warn about uninitialized automatic variables
 
+Wmaybe-uninitialized
+Common Var(warn_maybe_uninitialized) Warning
+Warn about maybe uninitialized automatic variables
+
 Wunreachable-code
 Common Ignore
 Does nothing. Preserved for backward compatibility.
Index: tree-ssa.c
===================================================================
--- tree-ssa.c	(revision 171959)
+++ tree-ssa.c	(working copy)
@@ -1622,10 +1622,11 @@ walk_use_def_chains (tree var, walk_use_
    changed conditionally uninitialized to unconditionally uninitialized.  */
 
 /* Emit a warning for T, an SSA_NAME, being uninitialized.  The exact
-   warning text is in MSGID and LOCUS may contain a location or be null.  */
+   warning text is in MSGID and LOCUS may contain a location or be null.
+   WC is the warning code.  */
 
 void
-warn_uninit (tree t, const char *gmsgid, void *data)
+warn_uninit (enum opt_code wc, tree t, const char *gmsgid, void *data)
 {
   tree var = SSA_NAME_VAR (t);
   gimple context = (gimple) data;
@@ -1649,7 +1650,7 @@ warn_uninit (tree t, const char *gmsgid,
 	     : DECL_SOURCE_LOCATION (var);
   xloc = expand_location (location);
   floc = expand_location (DECL_SOURCE_LOCATION (cfun->decl));
-  if (warning_at (location, OPT_Wuninitialized, gmsgid, var))
+  if (warning_at (location, wc, gmsgid, var))
     {
       TREE_NO_WARNING (var) = 1;
 
@@ -1731,10 +1732,12 @@ warn_uninitialized_var (tree *tp, int *w
       /* We only do data flow with SSA_NAMEs, so that's all we
 	 can warn about.  */
       if (data->always_executed)
-        warn_uninit (t, "%qD is used uninitialized in this function",
+        warn_uninit (OPT_Wuninitialized,
+	             t, "%qD is used uninitialized in this function",
 		     data->stmt);
       else if (data->warn_possibly_uninitialized)
-        warn_uninit (t, "%qD may be used uninitialized in this function",
+        warn_uninit (OPT_Wuninitialized,
+	             t, "%qD may be used uninitialized in this function",
 		     data->stmt);
       *walk_subtrees = 0;
       break;
Index: tree-flow.h
===================================================================
--- tree-flow.h	(revision 171959)
+++ tree-flow.h	(working copy)
@@ -546,7 +546,7 @@ extern void flush_pending_stmts (edge);
 extern void verify_ssa (bool);
 extern void delete_tree_ssa (void);
 extern bool ssa_undefined_value_p (tree);
-extern void warn_uninit (tree, const char *, void *);
+extern void warn_uninit (enum opt_code, tree, const char *, void *);
 extern unsigned int warn_uninitialized_vars (bool);
 extern void execute_update_addresses_taken (void);
 

Reply via email to