This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [Patch] Fix PR 5582 and 10538, missed uninitialized variable warning
- From: Andrew Pinski <pinskia at physics dot uc dot edu>
- To: Jason Merrill <jason at redhat dot com>
- Cc: Andrew Pinski <pinskia at physics dot uc dot edu>, gcc-patches at gcc dot gnu dot org
- Date: Tue, 19 Aug 2003 14:37:18 -0400
- Subject: Re: [Patch] Fix PR 5582 and 10538, missed uninitialized variable warning
On Tuesday, Aug 19, 2003, at 13:14 US/Eastern, Jason Merrill wrote:
On Mon, 18 Aug 2003 16:52:33 -0400, Andrew Pinski
<pinskia@physics.uc.edu> wrote:
On Monday, Aug 18, 2003, at 16:46 US/Eastern, Jason Merrill wrote:
Hmm. Why do you want this to be language-specific?
Because currently on the mainline walk_tree cannot be used outside of
a
based language.
I know this will change with the tree-ssa branch and I will update the
patch to fix this.
Fair enough.
Here is the updated patch (I will also update it for the tree-ssa when
it gets merged in)
with the suggestions from Neil and Jason and some testcases.
Ok?
ChangeLog:
* langhooks-def.h (lhd_decl_uninit): Declare.
(LANG_HOOKS_DECL_UNINIT): New macro.
(LANG_HOOKS_INITIALIZER): Adjust.
* langhooks.h (struct lang_hooks): Add new field
decl_uninit.
* langhooks.c (lhd_decl_uninit): Define.
* c-common.c (c_decl_uninit_1): New function.
(c_decl_uninit): New function.
(warn_init_self): Define.
* c-common.h (c_decl_uninit): Declare.
(warn_init_self): Declare.
* c.opt: Introduce -Winit-self.
* c-opts.c (c_common_handle_options): Set warn_init_self.
* c-lang.c (LANG_HOOKS_DECL_UNINIT): Define.
* objc/objc-lang.c (LANG_HOOKS_DECL_UNINIT): Define.
* function.c (uninitialized_vars_warning): Call the language hook.
* doc/invoke.texi: Document -Winit-self.
cp/ChangeLog:
* cp/cp-lang.c (LANG_HOOKS_DECL_UNINIT): Define.
testsuite:
* gcc.dg/uninit-D.c: New Test.
* gcc.dg/uninit-E.c: New Test.
* gcc.dg/uninit-F.c: New Test.
* gcc.dg/uninit-G.c: New Test.
Patch:
Index: langhooks-def.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/langhooks-def.h,v
retrieving revision 1.61
diff -u -p -r1.61 langhooks-def.h
--- langhooks-def.h 19 Aug 2003 07:48:44 -0000 1.61
+++ langhooks-def.h 19 Aug 2003 18:33:25 -0000
@@ -63,6 +63,7 @@ extern void lhd_incomplete_type_error (t
extern tree lhd_type_promotes_to (tree);
extern bool lhd_decl_ok_for_sibcall (tree);
extern tree lhd_expr_size (tree);
+extern bool lhd_decl_uninit (tree);
extern size_t lhd_tree_size (enum tree_code);
/* Declarations of default tree inlining hooks. */
@@ -114,6 +115,7 @@ extern void lhd_initialize_diagnostics (
#define LANG_HOOKS_PRINT_ERROR_FUNCTION lhd_print_error_function
#define LANG_HOOKS_DECL_PRINTABLE_NAME lhd_decl_printable_name
#define LANG_HOOKS_EXPR_SIZE lhd_expr_size
+#define LANG_HOOKS_DECL_UNINIT lhd_decl_uninit
#define LANG_HOOKS_TREE_SIZE lhd_tree_size
#define LANG_HOOKS_FUNCTION_INIT lhd_do_nothing_f
@@ -278,6 +280,7 @@ extern int lhd_tree_dump_type_quals (tre
LANG_HOOKS_DECL_PRINTABLE_NAME, \
LANG_HOOKS_PRINT_ERROR_FUNCTION, \
LANG_HOOKS_EXPR_SIZE, \
+ LANG_HOOKS_DECL_UNINIT, \
LANG_HOOKS_ATTRIBUTE_TABLE, \
LANG_HOOKS_COMMON_ATTRIBUTE_TABLE, \
LANG_HOOKS_FORMAT_ATTRIBUTE_TABLE, \
Index: langhooks.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/langhooks.c,v
retrieving revision 1.48
diff -u -p -r1.48 langhooks.c
--- langhooks.c 3 Aug 2003 22:14:47 -0000 1.48
+++ langhooks.c 19 Aug 2003 18:33:25 -0000
@@ -430,6 +430,14 @@ lhd_expr_size (tree exp)
else
return size_in_bytes (TREE_TYPE (exp));
}
+/* lang_hooks.decl_uninit: Find out if a variable is uninitialized
based
+ on DECL_INITIAL. */
+
+bool
+lhd_decl_uninit (tree t ATTRIBUTE_UNUSED)
+{
+ return false;
+}
/* lang_hooks.tree_size: Determine the size of a tree with code C,
which is a language-specific tree code in category 'x'. The
Index: langhooks.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/langhooks.h,v
retrieving revision 1.69
diff -u -p -r1.69 langhooks.h
--- langhooks.h 4 Aug 2003 20:44:13 -0000 1.69
+++ langhooks.h 19 Aug 2003 18:33:25 -0000
@@ -361,6 +361,10 @@ struct lang_hooks
semantics in cases that it doesn't want to handle specially. */
tree (*expr_size) (tree);
+ /* Called from uninitialized_vars_warning to find out if a variable
is
+ uninitialized based on DECL_INITIAL. */
+ bool (*decl_uninit) (tree);
+
/* Pointers to machine-independent attribute tables, for front ends
using attribs.c. If one is NULL, it is ignored. Respectively, a
table of attributes specific to the language, a table of
Index: c-common.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c-common.c,v
retrieving revision 1.445
diff -u -p -r1.445 c-common.c
--- c-common.c 5 Aug 2003 21:15:52 -0000 1.445
+++ c-common.c 19 Aug 2003 18:33:27 -0000
@@ -412,6 +412,11 @@ int warn_main;
int warn_sequence_point;
+/* Nonzero means warn about uninitialized variable when it is
initialized with it self.
+ For example: int i = i;, GCC will not warn about this when
warn_init_self is nonzero. */
+
+int warn_init_self;
+
/* Nonzero means to warn about compile-time division by zero. */
int warn_div_by_zero = 1;
@@ -3530,18 +3535,6 @@ self_promoting_args_p (tree parms)
return 1;
}
-/* Recursively examines the array elements of TYPE, until a non-array
- element type is found. */
-
-tree
-strip_array_types (tree type)
-{
- while (TREE_CODE (type) == ARRAY_TYPE)
- type = TREE_TYPE (type);
-
- return type;
-}
-
static tree expand_unordered_cmp (tree, tree, enum tree_code, enum
tree_code);
/* Expand a call to an unordered comparison function such as
@@ -5727,6 +5720,36 @@ c_estimate_num_insns (tree decl)
int num = 0;
walk_tree_without_duplicates (&DECL_SAVED_TREE (decl),
c_estimate_num_insns_1, &num);
return num;
+}
+
+/* Used by c_decl_uninit to find where expressions like x = x + 1; */
+static tree
+c_decl_uninit_1 (tree *t, int *walk_sub_trees, void *x)
+{
+ /* If x = EXP(&x)EXP, then do not warn about the use of x.
+ FIXME: Should not warn about this: int *x = &(x+2);. */
+ if (TREE_CODE (*t) == ADDR_EXPR && TREE_OPERAND (*t, 0) == x)
+ {
+ *walk_sub_trees = 0;
+ return NULL_TREE;
+ }
+ if (*t == x)
+ return *t;
+ return NULL_TREE;
+}
+
+/* Find out if a variable is uninitialized based on DECL_INITIAL. */
+bool
+c_decl_uninit (tree t)
+{
+ /* int x = x; is GCC extension to turn off this warning, only if not
pedantic. */
+ if (DECL_INITIAL (t) == t)
+ return warn_init_self ? true : false;
+
+ /* Walk the trees look for the variable it self. */
+ if (walk_tree_without_duplicates (&DECL_INITIAL (t),
c_decl_uninit_1, t))
+ return true;
+ return false;
}
#include "gt-c-common.h"
Index: c-common.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c-common.h,v
retrieving revision 1.202
diff -u -p -r1.202 c-common.h
--- c-common.h 5 Aug 2003 21:15:52 -0000 1.202
+++ c-common.h 19 Aug 2003 18:33:27 -0000
@@ -573,6 +573,12 @@ extern int warn_main;
extern int warn_sequence_point;
+/* Nonzero means warn about uninitialized variable when it is
initialized with it self.
+ For example: int i = i;, GCC will not warn about this when
warn_init_self is nonzero. */
+
+extern int warn_init_self;
+
+
/* Nonzero means to warn about compile-time division by zero. */
extern int warn_div_by_zero;
@@ -944,7 +950,6 @@ extern void c_common_parse_file (int);
extern HOST_WIDE_INT c_common_get_alias_set (tree);
extern bool c_promoting_integer_type_p (tree);
extern int self_promoting_args_p (tree);
-extern tree strip_array_types (tree);
/* This function resets the parsers' state in preparation for parsing
a new file. */
@@ -1289,6 +1294,7 @@ extern void builtin_define_with_value (c
extern void c_stddef_cpp_builtins (void);
extern void fe_file_change (const struct line_map *);
extern int c_estimate_num_insns (tree decl);
+extern bool c_decl_uninit (tree t);
/* In c-ppoutput.c */
extern void init_pp_output (FILE *);
Index: c.opt
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c.opt,v
retrieving revision 1.14
diff -u -p -r1.14 c.opt
--- c.opt 5 Aug 2003 21:15:52 -0000 1.14
+++ c.opt 19 Aug 2003 18:33:27 -0000
@@ -238,6 +238,10 @@ C ObjC
Wformat=
C ObjC C++ ObjC++ Joined
+Winit-self
+C ObjC C++ ObjC++
+Warn about variables which are initialized to themselves.
+
Wimplicit
C ObjC C++ ObjC++
Index: c-opts.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c-opts.c,v
retrieving revision 1.87
diff -u -p -r1.87 c-opts.c
--- c-opts.c 9 Aug 2003 22:14:07 -0000 1.87
+++ c-opts.c 19 Aug 2003 18:33:28 -0000
@@ -475,6 +475,10 @@ c_common_handle_option (size_t scode, co
warn_format_zero_length = value;
break;
+ case OPT_Winit_self:
+ warn_init_self = value;
+ break;
+
case OPT_Wimplicit:
set_Wimplicit (value);
break;
Index: c-lang.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c-lang.c,v
retrieving revision 1.114
diff -u -p -r1.114 c-lang.c
--- c-lang.c 19 Aug 2003 07:48:44 -0000 1.114
+++ c-lang.c 19 Aug 2003 18:33:28 -0000
@@ -87,6 +87,8 @@ enum c_language_kind c_language = clk_c;
#define LANG_HOOKS_FUNCTION_LEAVE_NESTED c_pop_function_context
#undef LANG_HOOKS_DUP_LANG_SPECIFIC_DECL
#define LANG_HOOKS_DUP_LANG_SPECIFIC_DECL c_dup_lang_specific_decl
+#undef LANG_HOOKS_DECL_UNINIT
+#define LANG_HOOKS_DECL_UNINIT c_decl_uninit
/* Attribute hooks. */
#undef LANG_HOOKS_COMMON_ATTRIBUTE_TABLE
Index: function.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/function.c,v
retrieving revision 1.449
diff -u -p -r1.449 function.c
--- function.c 25 Jul 2003 09:52:25 -0000 1.449
+++ function.c 19 Aug 2003 18:33:28 -0000
@@ -5564,9 +5564,9 @@ uninitialized_vars_warning (tree block)
with a nonzero DECL_INITIAL had an initializer, so do not
claim it is potentially uninitialized.
- We do not care about the actual value in DECL_INITIAL, so we do
- not worry that it may be a dangling pointer. */
- && DECL_INITIAL (decl) == NULL_TREE
+ When the DECL_INITIAL is NULL call the language hook to tell us
+ if we want to warn. */
+ && (DECL_INITIAL (decl) == NULL_TREE || lang_hooks.decl_uninit
(decl))
&& regno_uninitialized (REGNO (DECL_RTL (decl))))
warning ("%H'%D' might be used uninitialized in this function",
&DECL_SOURCE_LOCATION (decl), decl);
Index: objc/objc-lang.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/objc/objc-lang.c,v
retrieving revision 1.37
diff -u -p -r1.37 objc-lang.c
--- objc/objc-lang.c 4 Aug 2003 20:44:20 -0000 1.37
+++ objc/objc-lang.c 19 Aug 2003 18:33:28 -0000
@@ -79,6 +79,8 @@ enum c_language_kind c_language = clk_ob
#define LANG_HOOKS_DECL_PRINTABLE_NAME objc_printable_name
#undef LANG_HOOKS_WARN_UNUSED_GLOBAL_DECL
#define LANG_HOOKS_WARN_UNUSED_GLOBAL_DECL c_warn_unused_global_decl
+#undef LANG_HOOKS_DECL_UNINIT
+#define LANG_HOOKS_DECL_UNINIT c_decl_uninit
#undef LANG_HOOKS_FUNCTION_ENTER_NESTED
#define LANG_HOOKS_FUNCTION_ENTER_NESTED c_push_function_context
Index: doc/invoke.texi
===================================================================
RCS file: /cvs/gcc/gcc/gcc/doc/invoke.texi,v
retrieving revision 1.328
diff -u -p -r1.328 invoke.texi
--- doc/invoke.texi 5 Aug 2003 21:15:57 -0000 1.328
+++ doc/invoke.texi 19 Aug 2003 18:33:29 -0000
@@ -1,4 +1,4 @@
-@c Copyright (C) 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
1999,
+variable in its own initializer, use @c Copyright (C) 1988, 1989,
1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
@c 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
@c This is part of the GCC manual.
@c For copying conditions, see the file gcc.texi.
@@ -214,7 +214,7 @@ in the following sections.
-Wimplicit -Wimplicit-int @gol
-Wimplicit-function-declaration @gol
-Werror-implicit-function-declaration @gol
--Wimport -Winline -Winvalid-pch -Wno-endif-labels @gol
+-Winit-self Wimport -Winline -Winvalid-pch -Wno-endif-labels @gol
-Wno-invalid-offsetof @gol
-Wlarger-than-@var{len} -Wlong-long @gol
-Wmain -Wmissing-braces @gol
@@ -2055,6 +2055,24 @@ requiring a non-null value by the @code{
@option{-Wnonnull} is included in @option{-Wall} and
@option{-Wformat}. It
can be disabled with the @option{-Wno-nonnull} option.
+@item -Winit-self @r{(C, C++, and Objective-C only)}
+@opindex Winit-self
+Enable warning about uninitialized variables which are initalized with
themselves.
+Note this option can only be used with the @option{-Wuninitialized}
option and
+that only works with @option{-O}.
+
+For an example, the following code will not warn about i being
uninitialized
+without this option:
+@smallexample
+@group
+int f()
+@{
+ int i = i;
+ return i;
+@}
+@end group
+@end smallexample
+
@item -Wimplicit-int
@opindex Wimplicit-int
Warn when a declaration does not specify a type.
@@ -2264,6 +2282,9 @@ These warnings are possible only in opti
because they require data flow information that is computed only
when optimizing. If you don't specify @option{-O}, you simply won't
get these warnings.
+
+If you want to warn about code which uses the uninitialized value of
the
+variable in its own initializer, use the @option{-Winit-self} option.
These warnings occur only for variables that are candidates for
register allocation. Therefore, they do not occur for a variable that
Index: cp/cp-lang.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/cp-lang.c,v
retrieving revision 1.61
diff -u -p -r1.61 cp-lang.c
--- cp/cp-lang.c 19 Aug 2003 07:48:46 -0000 1.61
+++ cp/cp-lang.c 19 Aug 2003 18:33:29 -0000
@@ -106,6 +106,8 @@ static void cxx_initialize_diagnostics (
#define LANG_HOOKS_WARN_UNUSED_GLOBAL_DECL cxx_warn_unused_global_decl
#undef LANG_HOOKS_WRITE_GLOBALS
#define LANG_HOOKS_WRITE_GLOBALS lhd_do_nothing
+#undef LANG_HOOKS_DECL_UNINIT
+#define LANG_HOOKS_DECL_UNINIT c_decl_uninit
#undef LANG_HOOKS_FUNCTION_INIT
TestCases:
::::::::::::::
uninit-D.c
::::::::::::::
/* Test we do not warn about initializing variable with self. */
/* { dg-do compile } */
/* { dg-options "-O -Wuninitialized" } */
int f()
{
int i = i;
return i;
}
::::::::::::::
uninit-E.c
::::::::::::::
/* Test we do warn about initializing variable with self when
-Winit-self is supplied. */
/* { dg-do compile } */
/* { dg-options "-O -Wuninitialized -Winit-self" } */
int f()
{
int i = i;
return i;
}
::::::::::::::
uninit-F.c
::::::::::::::
/* Test we do warn about initializing variable with self in the
initialization. */
/* { dg-do compile } */
/* { dg-options "-O -Wuninitialized" } */
int f()
{
int i = i + 1; /* { dg-warning "i" "uninitialized variable warning" }
*/
return i;
}
::::::::::::::
uninit-G.c
::::::::::::::
/* Test we do not warn about initializing variable with address of self
in the initialization. */
/* { dg-do compile } */
/* { dg-options "-O -Wuninitialized" } */
void *f()
{
void *i = &i;
return i;
}