From 2f964ad6d4ec69a76954d90c273db385c807940f Mon Sep 17 00:00:00 2001 From: Xinliang David Li Date: Tue, 26 Apr 2011 16:06:09 +0000 Subject: [PATCH] Implement -Wno-maybe-uninitialized From-SVN: r172978 --- gcc/ChangeLog | 13 ++++++++++ gcc/c-family/c-opts.c | 1 + gcc/common.opt | 4 +++ gcc/doc/invoke.texi | 33 +++++++++++------------- gcc/opts.c | 8 ++++++ gcc/testsuite/ChangeLog | 5 ++++ gcc/testsuite/gcc.dg/uninit-suppress.c | 16 ++++++++++++ gcc/testsuite/gcc.dg/uninit-suppress_2.c | 16 ++++++++++++ gcc/tree-flow.h | 2 +- gcc/tree-ssa-uninit.c | 2 +- gcc/tree-ssa.c | 13 ++++++---- 11 files changed, 88 insertions(+), 25 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/uninit-suppress.c create mode 100644 gcc/testsuite/gcc.dg/uninit-suppress_2.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 29296bd632a..248ba57fa80 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,16 @@ +2011-04-26 Xinliang David Li + + * 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-26 Rainer Orth * config/mips/iris6.h (LOCAL_LABEL_PREFIX): Don't test diff --git a/gcc/c-family/c-opts.c b/gcc/c-family/c-opts.c index dd87591e6c8..3cd3e56ff3a 100644 --- a/gcc/c-family/c-opts.c +++ b/gcc/c-family/c-opts.c @@ -384,6 +384,7 @@ c_common_handle_option (size_t scode, const char *arg, int value, warn_unknown_pragmas = value; warn_uninitialized = value; + warn_maybe_uninitialized = value; if (!c_dialect_cxx ()) { diff --git a/gcc/common.opt b/gcc/common.opt index 83a61fc3312..ebc2ba7dbf8 100644 --- a/gcc/common.opt +++ b/gcc/common.opt @@ -631,6 +631,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. diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index 4377f346c7b..98513fb6944 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -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 @@ -2946,6 +2946,7 @@ Options} and @ref{Objective-C and Objective-C++ Dialect Options}. -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 @@ -3530,8 +3531,15 @@ to compute a value that itself is never used, because such 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: @@ -3554,20 +3562,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 diff --git a/gcc/opts.c b/gcc/opts.c index cd581f6ce69..f00e1b2a6df 100644 --- a/gcc/opts.c +++ b/gcc/opts.c @@ -1680,6 +1680,11 @@ common_handle_option (struct gcc_options *opts, /* 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, int value, unsigned int lang_mask, 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); } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 3630dcef68b..8b00f7ae3b9 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2011-04-26 Xinliang David Li + + * gcc.dg/uninit-suppress.c: New test. + * gcc.dg/uninit-suppress.c: New test. + 2011-04-26 Jakub Jelinek PR debug/48768 diff --git a/gcc/testsuite/gcc.dg/uninit-suppress.c b/gcc/testsuite/gcc.dg/uninit-suppress.c new file mode 100644 index 00000000000..64038a3a239 --- /dev/null +++ b/gcc/testsuite/gcc.dg/uninit-suppress.c @@ -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" } */ +} diff --git a/gcc/testsuite/gcc.dg/uninit-suppress_2.c b/gcc/testsuite/gcc.dg/uninit-suppress_2.c new file mode 100644 index 00000000000..a48b182f8cb --- /dev/null +++ b/gcc/testsuite/gcc.dg/uninit-suppress_2.c @@ -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" } */ +} diff --git a/gcc/tree-flow.h b/gcc/tree-flow.h index a2fa425d2f4..2ac2bbb66f5 100644 --- a/gcc/tree-flow.h +++ b/gcc/tree-flow.h @@ -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); diff --git a/gcc/tree-ssa-uninit.c b/gcc/tree-ssa-uninit.c index 479ffce5ed7..7ddce32a62f 100644 --- a/gcc/tree-ssa-uninit.c +++ b/gcc/tree-ssa-uninit.c @@ -1953,7 +1953,7 @@ warn_uninitialized_phi (gimple phi, VEC(gimple, heap) **worklist, 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); diff --git a/gcc/tree-ssa.c b/gcc/tree-ssa.c index 7f0a077b044..9ae280a7e32 100644 --- a/gcc/tree-ssa.c +++ b/gcc/tree-ssa.c @@ -1617,10 +1617,11 @@ walk_use_def_chains (tree var, walk_use_def_chains_fn fn, void *data, 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; @@ -1644,7 +1645,7 @@ warn_uninit (tree t, const char *gmsgid, void *data) : 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; @@ -1726,10 +1727,12 @@ warn_uninitialized_var (tree *tp, int *walk_subtrees, void *data_) /* 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; -- 2.30.2