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:
parent
28e5ca15b7
commit
830bc5507b
@ -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
|
||||
|
@ -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
|
||||
|
15
gcc/testsuite/gcc.dg/Wobjsize-1.c
Normal file
15
gcc/testsuite/gcc.dg/Wobjsize-1.c
Normal 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 } */
|
8
gcc/testsuite/gcc.dg/Wobjsize-1.h
Normal file
8
gcc/testsuite/gcc.dg/Wobjsize-1.h
Normal 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));
|
||||
}
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user