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
This commit is contained in:
Richard Guenther 2010-01-28 14:42:17 +00:00 committed by Richard Biener
parent 28e5ca15b7
commit 830bc5507b
5 changed files with 102 additions and 15 deletions

View File

@ -1,3 +1,8 @@
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

View File

@ -1,3 +1,8 @@
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

View File

@ -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 } */

View File

@ -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));
}

View File

@ -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;
/* 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);
if (integer_zerop (val.value))
gimple_cond_make_false (stmt);
else
gimple_cond_make_true (stmt);
return true;
}
return true;
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;
}
/* 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