diff options
author | Richard Guenther <rguenther@suse.de> | 2010-01-28 14:42:17 +0000 |
---|---|---|
committer | Richard Biener <rguenth@gcc.gnu.org> | 2010-01-28 14:42:17 +0000 |
commit | 830bc5507b328fa2218e57a5c500336110ce0a40 (patch) | |
tree | d5802c4187b203dbc82ac37a400b6beca819643f | |
parent | 28e5ca15b76773b91191541d79d67ef15510fdb1 (diff) | |
download | gcc-830bc5507b328fa2218e57a5c500336110ce0a40.zip gcc-830bc5507b328fa2218e57a5c500336110ce0a40.tar.gz gcc-830bc5507b328fa2218e57a5c500336110ce0a40.tar.bz2 |
tree-ssa-ccp.c (ccp_fold_stmt): Fold calls and propagate into call arguments.
2010-01-28 Richard Guenther <rguenther@suse.de>
* tree-ssa-ccp.c (ccp_fold_stmt): Fold calls and propagate
into call arguments.
* gcc.dg/Wobjsize-1.h: New testcase.
* gcc.dg/Wobjsize-1.c: Likewise.
From-SVN: r156323
-rw-r--r-- | gcc/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/Wobjsize-1.c | 15 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/Wobjsize-1.h | 8 | ||||
-rw-r--r-- | gcc/tree-ssa-ccp.c | 84 |
5 files changed, 102 insertions, 15 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index a96de7e..23cc577 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,10 @@ 2010-01-28 Richard Guenther <rguenther@suse.de> + * tree-ssa-ccp.c (ccp_fold_stmt): Fold calls and propagate + into call arguments. + +2010-01-28 Richard Guenther <rguenther@suse.de> + PR middle-end/42883 * tree-cfgcleanup.c (remove_forwarder_block): Do not remove the forwarder if the destination is an EH landing pad. diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 7706f87..a1c2ba3 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,10 @@ 2010-01-28 Richard Guenther <rguenther@suse.de> + * gcc.dg/Wobjsize-1.h: New testcase. + * gcc.dg/Wobjsize-1.c: Likewise. + +2010-01-28 Richard Guenther <rguenther@suse.de> + PR middle-end/42883 * g++.dg/torture/pr42883.C: New testcase. diff --git a/gcc/testsuite/gcc.dg/Wobjsize-1.c b/gcc/testsuite/gcc.dg/Wobjsize-1.c new file mode 100644 index 0000000..17e554b --- /dev/null +++ b/gcc/testsuite/gcc.dg/Wobjsize-1.c @@ -0,0 +1,15 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -Wall" } */ + +#include "Wobjsize-1.h" + +char buf[6]; +int main(int argc, char **argv) +{ + strcpy (buf,"hello "); + return 0; +} + +/* { dg-warning "will always overflow destination buffer" "" { target *-*-* } 6 } */ +/* { dg-message "file included" "" { target *-*-* } 0 } */ +/* { dg-message "inlined from" "" { target *-*-* } 0 } */ diff --git a/gcc/testsuite/gcc.dg/Wobjsize-1.h b/gcc/testsuite/gcc.dg/Wobjsize-1.h new file mode 100644 index 0000000..a879f6d --- /dev/null +++ b/gcc/testsuite/gcc.dg/Wobjsize-1.h @@ -0,0 +1,8 @@ +#pragma GCC system_header + +extern __inline __attribute__ ((__always_inline__,__artificial__,__gnu_inline__)) char * +__attribute__ ((__nothrow__)) strcpy (char *__restrict __dest, __const char *__restrict __src) +{ + return __builtin___strcpy_chk (__dest, __src, __builtin_object_size (__dest, 2 > 1)); +} + diff --git a/gcc/tree-ssa-ccp.c b/gcc/tree-ssa-ccp.c index b40dba3..f6380eb 100644 --- a/gcc/tree-ssa-ccp.c +++ b/gcc/tree-ssa-ccp.c @@ -1480,25 +1480,79 @@ static bool ccp_fold_stmt (gimple_stmt_iterator *gsi) { gimple stmt = gsi_stmt (*gsi); - prop_value_t val; - if (gimple_code (stmt) != GIMPLE_COND) - return false; + switch (gimple_code (stmt)) + { + case GIMPLE_COND: + { + prop_value_t val; + /* Statement evaluation will handle type mismatches in constants + more gracefully than the final propagation. This allows us to + fold more conditionals here. */ + val = evaluate_stmt (stmt); + if (val.lattice_val != CONSTANT + || TREE_CODE (val.value) != INTEGER_CST) + return false; + + if (integer_zerop (val.value)) + gimple_cond_make_false (stmt); + else + gimple_cond_make_true (stmt); - /* Statement evaluation will handle type mismatches in constants - more gracefully than the final propagation. This allows us to - fold more conditionals here. */ - val = evaluate_stmt (stmt); - if (val.lattice_val != CONSTANT - || TREE_CODE (val.value) != INTEGER_CST) - return false; + return true; + } - if (integer_zerop (val.value)) - gimple_cond_make_false (stmt); - else - gimple_cond_make_true (stmt); + case GIMPLE_CALL: + { + tree lhs = gimple_call_lhs (stmt); + prop_value_t *val; + tree argt; + bool changed = false; + unsigned i; + + /* If the call was folded into a constant make sure it goes + away even if we cannot propagate into all uses because of + type issues. */ + if (lhs + && TREE_CODE (lhs) == SSA_NAME + && (val = get_value (lhs)) + && val->lattice_val == CONSTANT) + { + tree new_rhs = val->value; + if (!useless_type_conversion_p (TREE_TYPE (lhs), + TREE_TYPE (new_rhs))) + new_rhs = fold_convert (TREE_TYPE (lhs), new_rhs); + update_call_from_tree (gsi, new_rhs); + return true; + } - return true; + /* Propagate into the call arguments. Compared to replace_uses_in + this can use the argument slot types for type verification + instead of the current argument type. We also can safely + drop qualifiers here as we are dealing with constants anyway. */ + argt = TYPE_ARG_TYPES (TREE_TYPE (TREE_TYPE (gimple_call_fn (stmt)))); + for (i = 0; i < gimple_call_num_args (stmt) && argt; + ++i, argt = TREE_CHAIN (argt)) + { + tree arg = gimple_call_arg (stmt, i); + if (TREE_CODE (arg) == SSA_NAME + && (val = get_value (arg)) + && val->lattice_val == CONSTANT + && useless_type_conversion_p + (TYPE_MAIN_VARIANT (TREE_VALUE (argt)), + TYPE_MAIN_VARIANT (TREE_TYPE (val->value)))) + { + gimple_call_set_arg (stmt, i, val->value); + changed = true; + } + } + + return changed; + } + + default: + return false; + } } /* Visit the assignment statement STMT. Set the value of its LHS to the |