Commit 34f97b94 by Xinliang David Li Committed by Xinliang David Li

predicate aware uninitialized analysis

From-SVN: r158835
parent 85fac79c
2010-04-28 Xinliang David Li <davidxl@google.com>
PR c/42643
* tree-ssa-uninit.c (can_skip_redundant_opnd): New function.
(compute_uninit_opnds_pos): New function.
(is_non_loop_exit_postdominating): New function.
(compute_control_dep_chain): New function.
(find_pdom): New function.
(convert_control_dep_chain_into_preds): New function.
(find_predicates): New function.
(find_control_equiv_block): New function.
(collect_phi_def_edges): New function.
(find_def_preds): New function.
(find_dom): New function.
(dump_predicates): New function.
(get_cmp_code): New function.
(is_value_included_in): New function.
(find_matching_predicate_in_rest_chains): New function.
(use_pred_not_overlap_with_undef_path_pred): New function.
(is_use_properly_guarded): New function.
(normalize_cond_1): New function.
(is_and_or_or): New function.
(normalize_cond): New function.
(is_gcond_subset_of): New function.
(is_subset_of_any): New function.
(is_or_set_subset_of): New function.
(is_and_set_subset_of): New function.
(is_norm_cond_subset_of): New function.
(is_pred_expr_subset_of): New function.
(is_pred_chain_subset_of): New function.
(is_included_in): New function.
(is_superset_of): New function.
(find_uninit_use): New function.
(warn_uninitialized_phi): New function.
(compute_possibly_undefined_names): New function.
(ssa_undefined_value_p): New function.
(execute_late_warn_uninitialized): New function.
* tree-ssa.c (ssa_undefined_value_p): Removed.
(warn_uninit): Changed to extern.
(warn_uninitialized_phi): Removed.
(warn_uninitialized_vars): Changed to extern.
(execute_late_warn_uninitialized): Removed
* tree-flow.h: Add new prototypes.
* timevar.def: Add new time variable.
* Makefile.in: Add new build file.
2010-04-28 Uros Bizjak <ubizjak@gmail.com> 2010-04-28 Uros Bizjak <ubizjak@gmail.com>
* config/alpha/elf.h (ASM_DECLARE_OBJECT_NAME): Use gnu_unique_object * config/alpha/elf.h (ASM_DECLARE_OBJECT_NAME): Use gnu_unique_object
......
...@@ -1385,6 +1385,7 @@ OBJS-common = \ ...@@ -1385,6 +1385,7 @@ OBJS-common = \
tree-ssa-threadedge.o \ tree-ssa-threadedge.o \
tree-ssa-threadupdate.o \ tree-ssa-threadupdate.o \
tree-ssa-uncprop.o \ tree-ssa-uncprop.o \
tree-ssa-uninit.o \
tree-ssa.o \ tree-ssa.o \
tree-ssanames.o \ tree-ssanames.o \
tree-stdarg.o \ tree-stdarg.o \
...@@ -2288,6 +2289,12 @@ tree-ssa-structalias.o: tree-ssa-structalias.c \ ...@@ -2288,6 +2289,12 @@ tree-ssa-structalias.o: tree-ssa-structalias.c \
$(GIMPLE_H) $(HASHTAB_H) $(FUNCTION_H) $(CGRAPH_H) \ $(GIMPLE_H) $(HASHTAB_H) $(FUNCTION_H) $(CGRAPH_H) \
$(TREE_PASS_H) $(TIMEVAR_H) alloc-pool.h $(SPLAY_TREE_H) $(PARAMS_H) \ $(TREE_PASS_H) $(TIMEVAR_H) alloc-pool.h $(SPLAY_TREE_H) $(PARAMS_H) \
gt-tree-ssa-structalias.h $(CGRAPH_H) $(ALIAS_H) pointer-set.h gt-tree-ssa-structalias.h $(CGRAPH_H) $(ALIAS_H) pointer-set.h
tree-ssa-uninit.o : tree-ssa-uninit.c $(TREE_FLOW_H) $(CONFIG_H) $(SYSTEM_H) \
$(RTL_H) $(TREE_H) $(TM_P_H) $(EXPR_H) output.h $(DIAGNOSTIC_H) \
$(TOPLEV_H) $(FUNCTION_H) $(TIMEVAR_H) $(TM_H) coretypes.h \
$(TREE_DUMP_H) langhooks.h tree-pass.h $(BASIC_BLOCK_H) $(BITMAP_H) \
$(FLAGS_H) $(GGC_H) hard-reg-set.h $(HASHTAB_H) pointer-set.h \
$(GIMPLE_H) $(TREE_INLINE_H) $(VARRAY_H)
tree-ssa.o : tree-ssa.c $(TREE_FLOW_H) $(CONFIG_H) $(SYSTEM_H) \ tree-ssa.o : tree-ssa.c $(TREE_FLOW_H) $(CONFIG_H) $(SYSTEM_H) \
$(RTL_H) $(TREE_H) $(TM_P_H) $(EXPR_H) output.h $(DIAGNOSTIC_H) \ $(RTL_H) $(TREE_H) $(TM_P_H) $(EXPR_H) output.h $(DIAGNOSTIC_H) \
$(TOPLEV_H) $(FUNCTION_H) $(TIMEVAR_H) $(TM_H) coretypes.h \ $(TOPLEV_H) $(FUNCTION_H) $(TIMEVAR_H) $(TM_H) coretypes.h \
......
2010-04-28 Xinliang David Li <davidxl@google.com>
* gcc.dg/uninit-pred-2_b.c: New test.
* gcc.dg/uninit-pred-4_b.c: New test.
* gcc.dg/uninit-pred-3_d.c: New test.
* gcc.dg/uninit-pred-6_b.c: New test.
* gcc.dg/uninit-pred-8_b.c: New test.
* gcc.dg/uninit-pred-3_a.c: New test.
* gcc.dg/uninit-pred-2_c.c: New test.
* gcc.dg/uninit-pred-5_a.c: New test.
* gcc.dg/uninit-pred-3_e.c: New test.
* gcc.dg/uninit-pred-7_a.c: New test.
* gcc.dg/uninit-pred-6_c.c: New test.
* gcc.dg/uninit-pred-9_a.c: New test.
* gcc.dg/uninit-pred-8_c.c: New test.
* gcc.dg/uninit-pred-3_b.c: New test.
* gcc.dg/uninit-pred-5_b.c: New test.
* gcc.dg/uninit-pred-7_b.c: New test.
* gcc.dg/uninit-pred-6_d.c: New test.
* gcc.dg/uninit-pred-9_b.c: New test.
* gcc.dg/uninit-pred-2_a.c: New test.
* gcc.dg/uninit-pred-4_a.c: New test.
* gcc.dg/uninit-pred-3_c.c: New test.
* gcc.dg/uninit-pred-6_a.c: New test.
* gcc.dg/uninit-pred-8_a.c: New test.
* gcc.dg/uninit-pred-7_c.c: New test.
* gcc.dg/uninit-pred-6_e.c: New test.
* g++.dg/uninit-pred-loop-1_b.cc: New test.
* g++.dg/uninit-pred-1_a.C: New test.
* g++.dg/uninit-pred-1_b.C: New test.
* g++.dg/uninit-pred-2_a.C: New test.
* g++.dg/uninit-pred-2_b.C: New test.
* g++.dg/uninit-pred-loop-1_a.cc: New test.
* g++.dg/uninit-pred-loop-1_c.cc: New test.
* g++.dg/uninit-pred-loop_1.cc: New test.
2010-04-28 Martin Jambor <mjambor@suse.cz> 2010-04-28 Martin Jambor <mjambor@suse.cz>
* gcc.dg/lto/20091209-1_0.c: New testcase. * gcc.dg/lto/20091209-1_0.c: New testcase.
......
/* { dg-do compile } */
/* { dg-options "-Wuninitialized -O2" } */
typedef long long int64;
void incr ();
bool is_valid (int);
int get_time ();
class A
{
public:
A ();
~A () {
if (I) delete I;
}
private:
int* I;
};
bool get_url (A *);
class M {
public:
__attribute__ ((always_inline)) int GetC (int *c) {
A details_str;
if (!get_url (&details_str))
{
incr ();
return 1;
}
*c = get_time ();
return -1;
}
void do_sth();
void do_sth2();
void P (int64 t)
{
int cc; /* { dg-bogus "uninitialized" "uninitialized variable warning" } */
if (GetC (&cc) >= 0 )
return;
if (t && cc <= 0 ) /* { dg-bogus "uninitialized" "uninitialized variable warning" } */
{
this->do_sth();
return;
}
do_sth2();
}
};
M* m;
void foo(int x)
{
m = new M;
m->P(x);
}
/* { dg-do compile } */
/* { dg-options "-Wuninitialized -O2" } */
typedef long long int64;
void incr ();
bool is_valid (int);
int get_time ();
class A
{
public:
A ();
~A () {
if (I) delete I;
}
private:
int* I;
};
bool get_url (A *);
class M {
public:
__attribute__ ((always_inline)) int GetC (int *c) {
A details_str;
if (!get_url (&details_str))
{
incr ();
return 1;
}
*c = get_time ();
return -1;
}
void do_sth();
void do_sth2();
void P (int64 t)
{
int cc; /* { dg-excess-errors "note: 'cc' was declared here" } */
if (GetC (&cc) <= 0 ) /* return flag checked wrongly */
return;
if (t && cc <= 0 ) /* { dg-warning "uninitialized" "uninitialized variable warning" } */
{
this->do_sth();
return;
}
do_sth2();
}
};
M* m;
void foo(int x)
{
m = new M;
m->P(x);
}
/* { dg-do compile } */
/* { dg-options "-Wuninitialized -O2" } */
typedef long long int64;
void incr ();
bool is_valid (int);
int get_time ();
class A
{
public:
A ();
~A () {
if (I) delete I;
}
private:
int* I;
};
bool get_url (A *);
class M {
public:
__attribute__ ((always_inline)) bool GetC (int *c) {
A details_str;
if (get_url (&details_str))
{
*c = get_time ();
return true;
}
return false;
}
void do_sth();
void do_sth2();
void P (int64 t)
{
int cc;
if (!GetC (&cc)) /* return flag checked properly */
return;
if (cc <= 0) /* { dg-bogus "uninitialized" "uninitialized variable warning" } */
{
this->do_sth();
return;
}
do_sth2();
}
};
M* m;
void foo(int x)
{
m = new M;
m->P(x);
}
/* { dg-do compile } */
/* { dg-options "-Wuninitialized -O2" } */
typedef long long int64;
void incr ();
bool is_valid (int);
int get_time ();
class A
{
public:
A ();
~A () {
if (I) delete I;
}
private:
int* I;
};
bool get_url (A *);
class M {
public:
__attribute__ ((always_inline)) bool GetC (int *c) {
A details_str;
if (get_url (&details_str))
{
*c = get_time ();
return true;
}
return false;
}
void do_sth();
void do_sth2();
void P (int64 t)
{
int cc; /* { dg-excess-errors "note" } */
if (GetC (&cc)) /* return flag checked wrongly */
return;
if (cc <= 0) /* { dg-warning "uninitialized" "uninitialized variable warning" } */
{
this->do_sth();
return;
}
do_sth2();
}
};
M* m;
void foo(int x)
{
m = new M;
m->P(x);
}
/* { dg-do compile } */
/* { dg-options "-Wuninitialized -O2" } */
extern int bar();
int foo(void)
{
for (;;) {
int err = ({int _err; /* { dg-bogus "uninitialized" "false warning" } */
for (int i = 0; i < 16; ++i) {
_err = 17;
_err = bar();
}
_err; /* { dg-bogus "uninitialized" "false warning" } */
});
if (err == 0) return 17;
}
return 18;
}
/* { dg-do compile } */
/* { dg-options "-Wuninitialized -O2" } */
extern int bar();
int foo(int n)
{
for (;;) {
int err = ({int _err;
for (int i = 0; i < n; ++i) {
_err = 17;
_err = bar();
}
_err;
}); /* { dg-warning "uninitialized" "warn on _err" } */
if (err == 0) return 17;
}
return 18;
}
/* { dg-do compile } */
/* { dg-options "-Wuninitialized -O2" } */
extern int bar();
int foo(int n, int m)
{
for (;;) {
int err = ({int _err;
for (int i = 0; i < 16; ++i) {
if (m+i > n)
break;
_err = 17;
_err = bar();
}
_err;
});
if (err == 0) return 17; }); /* { dg-warning "uninitialized" "warn on _err" } */
}
return 18;
}
/* { dg-do compile } */
/* { dg-options "-Wuninitialized -O2" } */
extern int bar();
int foo(void)
{
for (;;) {
int err = ({int _err; /* { dg-bogus "uninitialized" "false warning" } */
for (int i = 0; i < 16; ++i) {
_err = 17;
_err = bar();
}
_err; /* { dg-bogus "uninitialized" "false warning" } */
});
if (err == 0) return 17;
}
return 18;
}
...@@ -17,10 +17,10 @@ void f2(void) ...@@ -17,10 +17,10 @@ void f2(void)
void f3(int p) void f3(int p)
{ {
int x; /* { dg-warning "may be used" "conditional" } */ int x;
if (p) if (p)
x = p; x = p;
sink = x; sink = x; /* { dg-warning "may be used" "conditional" } */
} }
void f4(int p) void f4(int p)
......
/* Spurious uninitialized-variable warnings. */ /* Spurious uninitialized-variable warnings. */
/* Disable jump threading, etc to test compiler analysis. */
/* { dg-do compile } */ /* { dg-do compile } */
/* { dg-options "-O -Wuninitialized" } */ /* { dg-options "-O -Wuninitialized -fno-tree-dce -fno-tree-vrp -fno-tree-dominator-opts" } */
extern void use(int); extern void use(int);
extern void foo(void); extern void foo(void);
......
/* { dg-do compile } */
/* { dg-options "-Wuninitialized -O2" } */
int g;
void bar (void);
void blah (int);
int foo (int n, int m, int r)
{
int flag = 0;
int v;
if (n)
{
v = r;
flag = 1;
}
if (m)
g++;
else
bar();
if (flag)
blah(v); /* { dg-bogus "uninitialized" "bogus uninitialized var warning" } */
return 0;
}
/* { dg-do compile } */
/* { dg-options "-Wuninitialized -O2" } */
int g;
void bar (void);
void blah (int);
int foo (int n, int m, int r)
{
int flag = 0;
int v;
if (n)
{
v = r;
flag = 1;
}
if (m)
g++;
else
bar();
/* Wrong guard */
if (!flag)
blah(v); /* { dg-warning "uninitialized" "real uninitialized var warning" } */
return 0;
}
/* { dg-do compile } */
/* { dg-options "-Wuninitialized -O2" } */
int g;
void bar (void);
void blah (int);
int foo (int n, int m, int r)
{
int flag = 0;
int v;
if (n)
{
v = r;
flag = 1;
}
if (m) g++;
else bar();
if (flag)
blah(v); /* { dg-bogus "uninitialized" "bogus uninitialized var warning" } */
return 0;
}
int foo_2 (int n, int m, int r)
{
int flag = 0;
int v;
if (n)
{
v = r;
flag = 1;
}
if (m) g++;
else bar();
if (flag)
blah(v); /* { dg-bogus "uninitialized" "bogus uninitialized var warning" } */
else
blah(v); /* { dg-warning "uninitialized" "real uninitialized var warning" } */
return 0;
}
/* { dg-do compile } */
/* { dg-options "-Wuninitialized -O2" } */
int g;
void bar();
void blah(int);
int foo (int n, int m, int r)
{
int flag = 0;
int v;
if (n)
{
v = r;
flag = 1;
}
if (m)
g++;
else
bar();
if (r > 0)
if (flag)
blah(v); /* {dg-bogus "uninitialized" "bogus warning" } */
return 0;
}
/* { dg-do compile } */
/* { dg-options "-Wuninitialized -O2" } */
int g;
void bar();
void blah(int);
int foo (int n, int m, int r)
{
int flag = 0;
int v;
if (n)
{
v = r;
flag = 1;
}
if (m)
g++;
else
bar();
if (r > 0)
goto use;
if (flag)
{
use:
blah(v); /* { dg-warning "uninitialized" "real warning" } */
}
return 0;
}
/* { dg-do compile } */
/* { dg-options "-Wuninitialized -O2" } */
int g;
void bar();
void blah(int);
int foo (int n, int m, int r)
{
int flag = 0;
int v;
if (n)
{
v = r;
flag = -1;
}
if (m)
g++;
else
bar();
if (r > 0)
if (flag < 0)
blah(v); /* {dg-bogus "uninitialized" "bogus warning" } */
return 0;
}
/* { dg-do compile } */
/* { dg-options "-Wuninitialized -O2" } */
int g;
void bar();
void blah(int);
int foo (int n, int m, int r)
{
int flag = 0;
int v;
if (n)
{
v = r;
flag = -1;
}
if (m)
g++;
else
bar();
if (r > 0)
if (flag == -1)
blah(v); /* {dg-bogus "uninitialized" "bogus warning" } */
return 0;
}
/* { dg-do compile } */
/* { dg-options "-Wuninitialized -O2" } */
int g;
void bar();
void blah(int);
int foo (int n, int m, int r)
{
int flag = 0;
int v;
if (n)
{
v = r;
flag = -1;
}
if (m)
g++;
else
bar();
if (r > 0)
if (flag <= 0 )
blah(v); /* { dg-warning "uninitialized" "real warning" } */
return 0;
}
/* { dg-do compile } */
/* { dg-options "-Wuninitialized -O2" } */
int g;
void bar();
void blah(int);
int foo (int n, int m, int r, int t)
{
int flag = 0;
int v;
if (t)
{
if (n)
{
v = r; /* init path 1 */
flag = 1;
}
if (m)
g++;
else
bar();
if (flag) /* properly guarded */
blah(v); /* { dg-bogus "uninitialized" "bogus warning" } */
}
else
{
v = r+1; /* init path 2 */
flag = 2;
}
if (m)
g++;
else
bar();
if (flag) /* properly guarded */
blah(v); /* { dg-bogus "uninitialized" "bogus warning" } */
return 0;
}
/* { dg-do compile } */
/* { dg-options "-Wuninitialized -O2" } */
int g;
void bar();
void blah(int);
int foo (int n, int m, int r, int t)
{
int flag = 0;
int v;
if (t)
{
if (n)
{
v = r; /* init path 1 */
flag = 1;
}
if (m) g++;
else bar();
if (flag) /* properly guarded */
blah(v); /* { dg-bogus "uninitialized" "bogus warning" } */
}
else
{
v = r+1; /* init path 2 */
flag = 2;
}
if (m) g++;
else bar();
if (g) /* guard can not be determined statically to be safe */
blah(v); /* { dg-warning "uninitialized" "real warning" } */
return 0;
}
/* { dg-do compile } */
/* { dg-options "-Wuninitialized -O2" } */
int g;
int bar();
int blah(int);
void t(int);
__attribute__((always_inline))
int foo (int n, int* v, int r)
{
int flag = 0;
if (r > n)
{
*v = bar();
flag = 1;
}
if (n > g)
g++;
else
bar();
return flag;
}
int a[100];
int b[100];
int blah(int n)
{
int i;
for (i = 0 ; i < n; i++)
{
int v;
if (!foo (n, &v, b[i]))
return 0;
t (v); /* { dg-bogus "uninitialized" "bogus warning" } */
}
return 1;
}
/* { dg-do compile } */
/* { dg-options "-Wuninitialized -O2" } */
int g;
int bar();
int blah(int);
void t(int);
__attribute__((always_inline))
int foo (int n, int* v, int r)
{
int flag = 0;
if (r > n)
{
*v = bar();
flag = 1;
}
if (n > g)
g++;
else
bar();
return flag;
}
int a[100];
int b[100];
int blah(int n)
{
int i;
for (i = 0 ; i < n; i++)
{
int v;
if (foo (n, &v, b[i]))
return 0;
t (v); /* { dg-warning "uninitialized" "real warning" } */
}
return 1;
}
/* { dg-do compile } */
/* { dg-options "-Wuninitialized -O2" } */
int g;
void bar();
void blah(int);
int foo (int n, int l, int m, int r)
{
int v;
if (n && l)
v = r;
if (m) g++;
else bar();
if ( n && l)
blah(v); /* { dg-bogus "uninitialized" "bogus warning" } */
return 0;
}
int foo_2 (int n, int l, int m, int r)
{
int v;
if (n && l)
v = r;
if (m) g++;
else bar();
if (n)
blah (v); /* { dg-warning "uninitialized" "warning" } */
return 0;
}
/* { dg-do compile } */
/* { dg-options "-Wuninitialized -O2" } */
int g;
void bar();
void blah(int);
int foo (int n, int l, int m, int r)
{
int v;
if (n)
if (l)
v = r;
if (m) g++;
else bar();
if ( n && l)
blah(v); /* { dg-bogus "uninitialized" "bogus warning" } */
if (l)
if (n)
blah(v); /* { dg-bogus "uninitialized" "bogus warning" } */
return 0;
}
int foo_2 (int n, int l, int m, int r)
{
int v;
if (n)
if (l)
v = r;
if (m) g++;
else bar();
if (n || l)
blah (v); /* { dg-warning "uninitialized" "warning" } */
return 0;
}
/* { dg-do compile } */
/* { dg-options "-Wuninitialized -O2" } */
int g;
void bar();
void blah(int);
int foo (int n, int l, int m, int r)
{
int v;
if (n > 10)
if (l)
v = r;
if (m) g++;
else bar();
if ( (n > 10) && l)
blah(v); /* { dg-bogus "uninitialized" "bogus warning" } */
if (l)
if (n > 12)
blah(v); /* { dg-bogus "uninitialized" "bogus warning" } */
return 0;
}
int foo_2 (int n, int l, int m, int r)
{
int v;
if (n > 10)
if (l)
v = r;
if (m) g++;
else bar();
if (n > 8 )
if (l)
blah (v); /* { dg-warning "uninitialized" "warning" } */
return 0;
}
/* { dg-do compile } */
/* { dg-options "-Wuninitialized -O2" } */
int g;
void bar();
void blah(int);
int foo (int n, int l, int m, int r)
{
int v;
if (n)
v = r;
if (m) g++;
else bar();
if ( n && l)
blah(v); /* { dg-bogus "uninitialized" "bogus warning" } */
return 0;
}
/* { dg-do compile } */
/* { dg-options "-Wuninitialized -O2" } */
int g;
void bar();
void blah(int);
int foo (int n, int l, int m, int r)
{
int v;
if (n > 10)
v = r;
if (m) g++;
else bar();
if ( (n > 10) && (l < 100))
blah(v); /* { dg-bogus "uninitialized" "bogus warning" } */
if ( n > 100 )
blah(v); /* { dg-bogus "uninitialized" "bogus warning" } */
return 0;
}
int foo_2 (int n, int l, int m, int r)
{
int v;
if (n > 10)
v = r;
if (m) g++;
else bar();
if ( n < 10)
blah (v); /* { dg-warning "uninitialized" "warning" } */
return 0;
}
/* { dg-do compile } */
/* { dg-options "-Wuninitialized -O2" } */
int g;
void bar();
void blah(int);
int foo (int n, int l, int m, int r)
{
int v;
if (n || l)
v = r;
if (m) g++;
else bar();
if ( n && l)
blah(v); /* { dg-bogus "uninitialized" "bogus warning" } */
if ( n )
blah(v); /* { dg-bogus "uninitialized" "bogus warning" } */
if ( l )
blah(v); /* { dg-bogus "uninitialized" "bogus warning" } */
return 0;
}
int foo_2 (int n, int l, int m, int r)
{
int v;
if (n || l)
v = r;
if (m) g++;
else bar();
if ( n && l)
blah(v); /* { dg-bogus "uninitialized" "bogus warning" } */
if ( n )
blah(v); /* { dg-bogus "uninitialized" "bogus warning" } */
if (m || l)
blah (v); /* { dg-warning "uninitialized" "warning" } */
if ( l )
blah(v); /* { dg-bogus "uninitialized" "bogus warning" } */
return 0;
}
/* { dg-do compile } */
/* { dg-options "-Wuninitialized -O2" } */
int g;
void bar();
void blah(int);
int foo (int n, int l, int m, int r)
{
int v;
if (n > 10)
v = r;
if (m) g++;
else bar();
if (( n > 10) || (l != 100))
blah (v); /* { dg-warning "uninitialized" "warning" } */
return 0;
}
/* { dg-do compile } */
/* { dg-options "-Wuninitialized -O2" } */
int g;
void bar();
void blah(int);
int foo (int n, int l, int m, int r)
{
int v;
if (n)
v = r;
if (m) g++;
else bar();
if (n )
{
if (l)
g++;
else
goto l;
}
else
{
l:
blah (v); /* { dg-warning "uninitialized" "warning" } */
}
return 0;
}
/* { dg-do compile } */
/* { dg-options "-Wuninitialized -O2" } */
int g;
void bar();
void blah(int);
int foo (int n, int l, int m, int r)
{
int v;
if (n || m || r || l)
v = r;
if (m) g++;
else bar();
if ( n || m || r || l)
blah(v); /* { dg-bogus "uninitialized" "bogus warning" } */
if ( n )
blah(v); /* { dg-bogus "uninitialized" "bogus warning" } */
if ( l )
blah(v); /* { dg-bogus "uninitialized" "bogus warning" } */
return 0;
}
int foo_2 (int n, int l, int m, int r)
{
int v;
if (n || m || r )
v = r;
if (m) g++;
else bar();
if ( n || m || r || l)
blah(v); /* { dg-warning "uninitialized" "warning" } */
return 0;
}
/* { dg-do compile } */
/* { dg-options "-Wuninitialized -O2" } */
int g;
void bar();
void blah(int);
int foo (int n, int l, int m, int r)
{
int v;
if (n < 10 || m > 100 || r < 20 || l)
v = r;
if (m) g++;
else bar();
if ( n < 10 || m > 100 || r < 20 )
blah(v); /* { dg-bogus "uninitialized" "bogus warning" } */
if ( n < 10 || m > 100 || r < 10 )
blah(v); /* { dg-bogus "uninitialized" "bogus warning" } */
return 0;
}
int foo_2 (int n, int l, int m, int r)
{
int v;
if (n < 10 || m > 100 || r < 20 || l)
v = r;
if (m) g++;
else bar();
if ( n < 10 || m > 100 || r < 20 )
blah(v); /* { dg-bogus "uninitialized" "bogus warning" } */
if ( n < 10 || m > 100 || r < 30 )
blah(v); /* { dg-warning "uninitialized" "warning" } */
return 0;
}
/* { dg-do compile } */
/* { dg-options "-Wuninitialized -O2" } */
int g;
void bar();
void blah(int);
int foo (int n, int l, int m, int r)
{
int v;
if (n < 10 && m > 100 && r < 20 )
v = r;
if (m) g++;
else bar();
if ( n <= 8 && m > 101 && r < 19 )
blah(v); /* { dg-bogus "uninitialized" "bogus warning" } */
return 0;
}
int foo_2 (int n, int l, int m, int r)
{
int v;
if (n < 10 && m > 100 && r < 20 )
v = r;
if (m) g++;
else bar();
if ( n <= 8 && m > 99 && r < 19 )
blah(v); /* { dg-warning "uninitialized" "warning" } */
return 0;
}
/* { dg-do compile } */
/* { dg-options "-Wuninitialized -O2" } */
int g;
void bar();
void blah(int);
int foo (int n, int l, int m, int r)
{
int v;
if ( (n < 10) && (m == l) && (r < 20) )
v = r;
if (m) g++;
else bar();
if ( (n <= 8) && (m == l) && (r < 19) )
blah(v); /* { dg-bogus "uninitialized" "bogus warning" } */
return 0;
}
/* { dg-do compile } */
/* { dg-options "-Wuninitialized -O2" } */
int g;
void bar();
void blah(int);
int foo (int n, int l, int m, int r)
{
int v;
if ( (n < 10) && (m != 100) && (r < 20) )
v = r;
if (m) g++;
else bar();
if (l > 100)
if ( (n <= 9) && (m < 100) && (r < 19) )
blah(v); /* { dg-bogus "uninitialized" "bogus warning" } */
if ( (n <= 8) && (m < 99) && (r < 19) )
blah(v); /* { dg-bogus "uninitialized" "bogus warning" } */
return 0;
}
int foo_2 (int n, int l, int m, int r)
{
int v;
if ( (n < 10) && (m != 100) && (r < 20) )
v = r;
if (m) g++;
else bar();
if (l > 100)
if ( (n <= 8) && (m < 101) && (r < 19) )
blah(v); /* { dg-warning "uninitialized" "real warning" } */
return 0;
}
...@@ -219,6 +219,7 @@ DEFTIMEVAR (TV_FINAL , "final") ...@@ -219,6 +219,7 @@ DEFTIMEVAR (TV_FINAL , "final")
DEFTIMEVAR (TV_SYMOUT , "symout") DEFTIMEVAR (TV_SYMOUT , "symout")
DEFTIMEVAR (TV_VAR_TRACKING , "variable tracking") DEFTIMEVAR (TV_VAR_TRACKING , "variable tracking")
DEFTIMEVAR (TV_TREE_IFCOMBINE , "tree if-combine") DEFTIMEVAR (TV_TREE_IFCOMBINE , "tree if-combine")
DEFTIMEVAR (TV_TREE_UNINIT , "uninit var anaysis")
DEFTIMEVAR (TV_PLUGIN_INIT , "plugin initialization") DEFTIMEVAR (TV_PLUGIN_INIT , "plugin initialization")
DEFTIMEVAR (TV_PLUGIN_RUN , "plugin execution") DEFTIMEVAR (TV_PLUGIN_RUN , "plugin execution")
......
...@@ -575,6 +575,8 @@ extern void flush_pending_stmts (edge); ...@@ -575,6 +575,8 @@ extern void flush_pending_stmts (edge);
extern void verify_ssa (bool); extern void verify_ssa (bool);
extern void delete_tree_ssa (void); extern void delete_tree_ssa (void);
extern bool ssa_undefined_value_p (tree); extern bool ssa_undefined_value_p (tree);
extern void warn_uninit (tree, const char *, void *);
extern unsigned int warn_uninitialized_vars (bool);
extern void execute_update_addresses_taken (bool); extern void execute_update_addresses_taken (bool);
/* Call-back function for walk_use_def_chains(). At each reaching /* Call-back function for walk_use_def_chains(). At each reaching
......
...@@ -1603,25 +1603,6 @@ walk_use_def_chains (tree var, walk_use_def_chains_fn fn, void *data, ...@@ -1603,25 +1603,6 @@ walk_use_def_chains (tree var, walk_use_def_chains_fn fn, void *data,
} }
/* Return true if T, an SSA_NAME, has an undefined value. */
bool
ssa_undefined_value_p (tree t)
{
tree var = SSA_NAME_VAR (t);
/* Parameters get their initial value from the function entry. */
if (TREE_CODE (var) == PARM_DECL)
return false;
/* Hard register variables get their initial value from the ether. */
if (TREE_CODE (var) == VAR_DECL && DECL_HARD_REGISTER (var))
return false;
/* The value is undefined iff its definition statement is empty. */
return gimple_nop_p (SSA_NAME_DEF_STMT (t));
}
/* Emit warnings for uninitialized variables. This is done in two passes. /* Emit warnings for uninitialized variables. This is done in two passes.
The first pass notices real uses of SSA names with undefined values. The first pass notices real uses of SSA names with undefined values.
...@@ -1640,7 +1621,7 @@ ssa_undefined_value_p (tree t) ...@@ -1640,7 +1621,7 @@ ssa_undefined_value_p (tree t)
/* Emit a warning for T, an SSA_NAME, being uninitialized. The exact /* 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. */
static void void
warn_uninit (tree t, const char *gmsgid, void *data) warn_uninit (tree t, const char *gmsgid, void *data)
{ {
tree var = SSA_NAME_VAR (t); tree var = SSA_NAME_VAR (t);
...@@ -1770,28 +1751,7 @@ warn_uninitialized_var (tree *tp, int *walk_subtrees, void *data_) ...@@ -1770,28 +1751,7 @@ warn_uninitialized_var (tree *tp, int *walk_subtrees, void *data_)
return NULL_TREE; return NULL_TREE;
} }
/* Look for inputs to PHI that are SSA_NAMEs that have empty definitions unsigned int
and warn about them. */
static void
warn_uninitialized_phi (gimple phi)
{
size_t i, n = gimple_phi_num_args (phi);
/* Don't look at memory tags. */
if (!is_gimple_reg (gimple_phi_result (phi)))
return;
for (i = 0; i < n; ++i)
{
tree op = gimple_phi_arg_def (phi, i);
if (TREE_CODE (op) == SSA_NAME)
warn_uninit (op, "%qD may be used uninitialized in this function",
NULL);
}
}
static unsigned int
warn_uninitialized_vars (bool warn_possibly_uninitialized) warn_uninitialized_vars (bool warn_possibly_uninitialized)
{ {
gimple_stmt_iterator gsi; gimple_stmt_iterator gsi;
...@@ -1800,7 +1760,6 @@ warn_uninitialized_vars (bool warn_possibly_uninitialized) ...@@ -1800,7 +1760,6 @@ warn_uninitialized_vars (bool warn_possibly_uninitialized)
data.warn_possibly_uninitialized = warn_possibly_uninitialized; data.warn_possibly_uninitialized = warn_possibly_uninitialized;
calculate_dominance_info (CDI_POST_DOMINATORS);
FOR_EACH_BB (bb) FOR_EACH_BB (bb)
{ {
...@@ -1818,10 +1777,6 @@ warn_uninitialized_vars (bool warn_possibly_uninitialized) ...@@ -1818,10 +1777,6 @@ warn_uninitialized_vars (bool warn_possibly_uninitialized)
} }
} }
/* Post-dominator information can not be reliably updated. Free it
after the use. */
free_dominance_info (CDI_POST_DOMINATORS);
return 0; return 0;
} }
...@@ -1834,25 +1789,14 @@ execute_early_warn_uninitialized (void) ...@@ -1834,25 +1789,14 @@ execute_early_warn_uninitialized (void)
as possible, thus don't do it here. However, without as possible, thus don't do it here. However, without
optimization we need to warn here about "may be uninitialized". optimization we need to warn here about "may be uninitialized".
*/ */
warn_uninitialized_vars (/*warn_possibly_uninitialized=*/!optimize); calculate_dominance_info (CDI_POST_DOMINATORS);
return 0;
}
static unsigned int
execute_late_warn_uninitialized (void)
{
basic_block bb;
gimple_stmt_iterator gsi;
/* Re-do the plain uninitialized variable check, as optimization may have warn_uninitialized_vars (/*warn_possibly_uninitialized=*/!optimize);
straightened control flow. Do this first so that we don't accidentally
get a "may be" warning when we'd have seen an "is" warning later. */
warn_uninitialized_vars (/*warn_possibly_uninitialized=*/1);
FOR_EACH_BB (bb) /* Post-dominator information can not be reliably updated. Free it
for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi)) after the use. */
warn_uninitialized_phi (gsi_stmt (gsi));
free_dominance_info (CDI_POST_DOMINATORS);
return 0; return 0;
} }
...@@ -1881,25 +1825,6 @@ struct gimple_opt_pass pass_early_warn_uninitialized = ...@@ -1881,25 +1825,6 @@ struct gimple_opt_pass pass_early_warn_uninitialized =
} }
}; };
struct gimple_opt_pass pass_late_warn_uninitialized =
{
{
GIMPLE_PASS,
"*late_warn_uninitialized", /* name */
gate_warn_uninitialized, /* gate */
execute_late_warn_uninitialized, /* execute */
NULL, /* sub */
NULL, /* next */
0, /* static_pass_number */
TV_NONE, /* tv_id */
PROP_ssa, /* properties_required */
0, /* properties_provided */
0, /* properties_destroyed */
0, /* todo_flags_start */
0 /* todo_flags_finish */
}
};
/* Compute TREE_ADDRESSABLE and DECL_GIMPLE_REG_P for local variables. */ /* Compute TREE_ADDRESSABLE and DECL_GIMPLE_REG_P for local variables. */
void void
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment