aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog13
-rw-r--r--gcc/c-family/c-opts.c1
-rw-r--r--gcc/common.opt4
-rw-r--r--gcc/doc/invoke.texi33
-rw-r--r--gcc/opts.c8
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.dg/uninit-suppress.c16
-rw-r--r--gcc/testsuite/gcc.dg/uninit-suppress_2.c16
-rw-r--r--gcc/tree-flow.h2
-rw-r--r--gcc/tree-ssa-uninit.c2
-rw-r--r--gcc/tree-ssa.c13
11 files changed, 88 insertions, 25 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 29296bd..248ba57 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,16 @@
+2011-04-26 Xinliang David Li <davidxl@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-26 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE>
* 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 dd87591..3cd3e56 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 83a61fc..ebc2ba7 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 4377f34..98513fb 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 cd581f6..f00e1b2 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 3630dce..8b00f7a 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2011-04-26 Xinliang David Li <davidxl@google.com>
+
+ * gcc.dg/uninit-suppress.c: New test.
+ * gcc.dg/uninit-suppress.c: New test.
+
2011-04-26 Jakub Jelinek <jakub@redhat.com>
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 0000000..64038a3
--- /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 0000000..a48b182
--- /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 a2fa425..2ac2bbb 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 479ffce..7ddce32 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 7f0a077..9ae280a 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;