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 <[email protected]>
* 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 <[email protected]>
* 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);