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);