aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Guenther <rguenther@suse.de>2010-01-28 14:42:17 +0000
committerRichard Biener <rguenth@gcc.gnu.org>2010-01-28 14:42:17 +0000
commit830bc5507b328fa2218e57a5c500336110ce0a40 (patch)
treed5802c4187b203dbc82ac37a400b6beca819643f
parent28e5ca15b76773b91191541d79d67ef15510fdb1 (diff)
downloadgcc-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/ChangeLog5
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.dg/Wobjsize-1.c15
-rw-r--r--gcc/testsuite/gcc.dg/Wobjsize-1.h8
-rw-r--r--gcc/tree-ssa-ccp.c84
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