re PR middle-end/59125 (gcc triggers wrong strncpy_chk)
2013-11-18 Richard Biener <rguenther@suse.de> PR tree-optimization/59125 PR tree-optimization/54570 * tree-ssa-sccvn.c (copy_reference_ops_from_ref): When inlining is not complete do not treat component-references with offset zero but different fields as equal. * tree-object-size.c: Include tree-phinodes.h and ssa-iterators.h. (compute_object_sizes): Apply TLC. Propagate the constant results into all uses and fold their stmts. * passes.def (pass_all_optimizations): Move pass_object_sizes after the first pass_forwprop and before pass_fre. * gcc.dg/builtin-object-size-8.c: Un-xfail. * gcc.dg/builtin-object-size-14.c: New testcase. * gcc.dg/strlenopt-14gf.c: Adjust. * gcc.dg/strlenopt-1f.c: Likewise. * gcc.dg/strlenopt-4gf.c: Likewise. From-SVN: r204966
This commit is contained in:
parent
7d362f6c2b
commit
1eadb567ef
10 changed files with 98 additions and 32 deletions
|
@ -1,3 +1,16 @@
|
|||
2013-11-18 Richard Biener <rguenther@suse.de>
|
||||
|
||||
PR tree-optimization/59125
|
||||
PR tree-optimization/54570
|
||||
* tree-ssa-sccvn.c (copy_reference_ops_from_ref): When inlining
|
||||
is not complete do not treat component-references with offset zero
|
||||
but different fields as equal.
|
||||
* tree-object-size.c: Include tree-phinodes.h and ssa-iterators.h.
|
||||
(compute_object_sizes): Apply TLC. Propagate the constant
|
||||
results into all uses and fold their stmts.
|
||||
* passes.def (pass_all_optimizations): Move pass_object_sizes
|
||||
after the first pass_forwprop and before pass_fre.
|
||||
|
||||
2013-11-18 Richard Sandiford <rdsandiford@googlemail.com>
|
||||
|
||||
* tree.h (tree_to_uhwi): Return an unsigned HOST_WIDE_INT.
|
||||
|
|
|
@ -142,6 +142,7 @@ along with GCC; see the file COPYING3. If not see
|
|||
form if possible. */
|
||||
NEXT_PASS (pass_phiprop);
|
||||
NEXT_PASS (pass_forwprop);
|
||||
NEXT_PASS (pass_object_sizes);
|
||||
/* pass_build_alias is a dummy pass that ensures that we
|
||||
execute TODO_rebuild_alias at this point. */
|
||||
NEXT_PASS (pass_build_alias);
|
||||
|
@ -185,7 +186,6 @@ along with GCC; see the file COPYING3. If not see
|
|||
NEXT_PASS (pass_dce);
|
||||
NEXT_PASS (pass_forwprop);
|
||||
NEXT_PASS (pass_phiopt);
|
||||
NEXT_PASS (pass_object_sizes);
|
||||
NEXT_PASS (pass_strlen);
|
||||
NEXT_PASS (pass_ccp);
|
||||
/* After CCP we rewrite no longer addressed locals into SSA
|
||||
|
|
|
@ -1,3 +1,13 @@
|
|||
2013-11-18 Richard Biener <rguenther@suse.de>
|
||||
|
||||
PR tree-optimization/59125
|
||||
PR tree-optimization/54570
|
||||
* gcc.dg/builtin-object-size-8.c: Un-xfail.
|
||||
* gcc.dg/builtin-object-size-14.c: New testcase.
|
||||
* gcc.dg/strlenopt-14gf.c: Adjust.
|
||||
* gcc.dg/strlenopt-1f.c: Likewise.
|
||||
* gcc.dg/strlenopt-4gf.c: Likewise.
|
||||
|
||||
2013-11-18 Eric Botcazou <ebotcazou@adacore.com>
|
||||
|
||||
* gnat.dg/volatile11.adb: New test.
|
||||
|
|
28
gcc/testsuite/gcc.dg/builtin-object-size-14.c
Normal file
28
gcc/testsuite/gcc.dg/builtin-object-size-14.c
Normal file
|
@ -0,0 +1,28 @@
|
|||
/* { dg-do run } */
|
||||
/* { dg-options "-O2" } */
|
||||
|
||||
extern void abort (void);
|
||||
extern char *strncpy(char *, const char *, __SIZE_TYPE__);
|
||||
|
||||
union u {
|
||||
struct {
|
||||
char vi[8];
|
||||
char pi[16];
|
||||
};
|
||||
char all[8+16+4];
|
||||
};
|
||||
|
||||
void __attribute__((noinline,noclone))
|
||||
f(union u *u)
|
||||
{
|
||||
char vi[8+1];
|
||||
__builtin_strncpy(vi, u->vi, sizeof(u->vi));
|
||||
if (__builtin_object_size (u->all, 1) != -1)
|
||||
abort ();
|
||||
}
|
||||
int main()
|
||||
{
|
||||
union u u;
|
||||
f (&u);
|
||||
return 0;
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
/* { dg-do run { xfail *-*-* } } */
|
||||
/* { dg-do run } */
|
||||
/* { dg-options "-O2" } */
|
||||
|
||||
typedef __SIZE_TYPE__ size_t;
|
||||
|
|
|
@ -11,14 +11,14 @@
|
|||
memcpy. */
|
||||
/* { dg-final { scan-tree-dump-times "strlen \\(" 4 "strlen" } } */
|
||||
/* { dg-final { scan-tree-dump-times "__memcpy_chk \\(" 0 "strlen" } } */
|
||||
/* { dg-final { scan-tree-dump-times "__mempcpy_chk \\(" 2 "strlen" } } */
|
||||
/* { dg-final { scan-tree-dump-times "__mempcpy_chk \\(" 0 "strlen" } } */
|
||||
/* { dg-final { scan-tree-dump-times "__strcpy_chk \\(" 0 "strlen" } } */
|
||||
/* { dg-final { scan-tree-dump-times "__strcat_chk \\(" 0 "strlen" } } */
|
||||
/* { dg-final { scan-tree-dump-times "strchr \\(" 0 "strlen" } } */
|
||||
/* { dg-final { scan-tree-dump-times "__stpcpy_chk \\(" 3 "strlen" } } */
|
||||
/* { dg-final { scan-tree-dump-times "memcpy \\(" 0 "strlen" } } */
|
||||
/* { dg-final { scan-tree-dump-times "mempcpy \\(" 0 "strlen" } } */
|
||||
/* { dg-final { scan-tree-dump-times "__stpcpy_chk \\(" 0 "strlen" } } */
|
||||
/* { dg-final { scan-tree-dump-times "memcpy \\(" 1 "strlen" } } */
|
||||
/* { dg-final { scan-tree-dump-times "mempcpy \\(" 2 "strlen" } } */
|
||||
/* { dg-final { scan-tree-dump-times "strcpy \\(" 0 "strlen" } } */
|
||||
/* { dg-final { scan-tree-dump-times "strcat \\(" 0 "strlen" } } */
|
||||
/* { dg-final { scan-tree-dump-times "stpcpy \\(" 0 "strlen" } } */
|
||||
/* { dg-final { scan-tree-dump-times "stpcpy \\(" 2 "strlen" } } */
|
||||
/* { dg-final { cleanup-tree-dump "strlen" } } */
|
||||
|
|
|
@ -6,12 +6,12 @@
|
|||
#include "strlenopt-1.c"
|
||||
|
||||
/* { dg-final { scan-tree-dump-times "strlen \\(" 2 "strlen" } } */
|
||||
/* { dg-final { scan-tree-dump-times "__memcpy_chk \\(" 4 "strlen" } } */
|
||||
/* { dg-final { scan-tree-dump-times "__memcpy_chk \\(" 0 "strlen" } } */
|
||||
/* { dg-final { scan-tree-dump-times "__strcpy_chk \\(" 0 "strlen" } } */
|
||||
/* { dg-final { scan-tree-dump-times "__strcat_chk \\(" 0 "strlen" } } */
|
||||
/* { dg-final { scan-tree-dump-times "strchr \\(" 0 "strlen" } } */
|
||||
/* { dg-final { scan-tree-dump-times "__stpcpy_chk \\(" 0 "strlen" } } */
|
||||
/* { dg-final { scan-tree-dump-times "memcpy \\(" 0 "strlen" } } */
|
||||
/* { dg-final { scan-tree-dump-times "memcpy \\(" 4 "strlen" } } */
|
||||
/* { dg-final { scan-tree-dump-times "strcpy \\(" 0 "strlen" } } */
|
||||
/* { dg-final { scan-tree-dump-times "strcat \\(" 0 "strlen" } } */
|
||||
/* { dg-final { scan-tree-dump-times "stpcpy \\(" 0 "strlen" } } */
|
||||
|
|
|
@ -7,13 +7,13 @@
|
|||
#include "strlenopt-4.c"
|
||||
|
||||
/* { dg-final { scan-tree-dump-times "strlen \\(" 1 "strlen" } } */
|
||||
/* { dg-final { scan-tree-dump-times "__memcpy_chk \\(" 4 "strlen" } } */
|
||||
/* { dg-final { scan-tree-dump-times "__strcpy_chk \\(" 1 "strlen" } } */
|
||||
/* { dg-final { scan-tree-dump-times "__memcpy_chk \\(" 0 "strlen" } } */
|
||||
/* { dg-final { scan-tree-dump-times "__strcpy_chk \\(" 0 "strlen" } } */
|
||||
/* { dg-final { scan-tree-dump-times "__strcat_chk \\(" 0 "strlen" } } */
|
||||
/* { dg-final { scan-tree-dump-times "strchr \\(" 0 "strlen" } } */
|
||||
/* { dg-final { scan-tree-dump-times "__stpcpy_chk \\(" 5 "strlen" } } */
|
||||
/* { dg-final { scan-tree-dump-times "memcpy \\(" 0 "strlen" } } */
|
||||
/* { dg-final { scan-tree-dump-times "strcpy \\(" 0 "strlen" } } */
|
||||
/* { dg-final { scan-tree-dump-times "__stpcpy_chk \\(" 0 "strlen" } } */
|
||||
/* { dg-final { scan-tree-dump-times "memcpy \\(" 4 "strlen" } } */
|
||||
/* { dg-final { scan-tree-dump-times "strcpy \\(" 1 "strlen" } } */
|
||||
/* { dg-final { scan-tree-dump-times "strcat \\(" 0 "strlen" } } */
|
||||
/* { dg-final { scan-tree-dump-times "stpcpy \\(" 0 "strlen" } } */
|
||||
/* { dg-final { scan-tree-dump-times "stpcpy \\(" 5 "strlen" } } */
|
||||
/* { dg-final { cleanup-tree-dump "strlen" } } */
|
||||
|
|
|
@ -32,6 +32,8 @@ along with GCC; see the file COPYING3. If not see
|
|||
#include "tree-ssanames.h"
|
||||
#include "tree-pass.h"
|
||||
#include "tree-ssa-propagate.h"
|
||||
#include "tree-phinodes.h"
|
||||
#include "ssa-iterators.h"
|
||||
|
||||
struct object_size_info
|
||||
{
|
||||
|
@ -1205,16 +1207,9 @@ compute_object_sizes (void)
|
|||
gimple_stmt_iterator i;
|
||||
for (i = gsi_start_bb (bb); !gsi_end_p (i); gsi_next (&i))
|
||||
{
|
||||
tree callee, result;
|
||||
tree result;
|
||||
gimple call = gsi_stmt (i);
|
||||
|
||||
if (gimple_code (call) != GIMPLE_CALL)
|
||||
continue;
|
||||
|
||||
callee = gimple_call_fndecl (call);
|
||||
if (!callee
|
||||
|| DECL_BUILT_IN_CLASS (callee) != BUILT_IN_NORMAL
|
||||
|| DECL_FUNCTION_CODE (callee) != BUILT_IN_OBJECT_SIZE)
|
||||
if (!gimple_call_builtin_p (call, BUILT_IN_OBJECT_SIZE))
|
||||
continue;
|
||||
|
||||
init_object_sizes ();
|
||||
|
@ -1243,20 +1238,32 @@ compute_object_sizes (void)
|
|||
continue;
|
||||
}
|
||||
|
||||
gcc_assert (TREE_CODE (result) == INTEGER_CST);
|
||||
|
||||
if (dump_file && (dump_flags & TDF_DETAILS))
|
||||
{
|
||||
fprintf (dump_file, "Simplified\n ");
|
||||
print_gimple_stmt (dump_file, call, 0, dump_flags);
|
||||
fprintf (dump_file, " to ");
|
||||
print_generic_expr (dump_file, result, 0);
|
||||
fprintf (dump_file, "\n");
|
||||
}
|
||||
|
||||
if (!update_call_from_tree (&i, result))
|
||||
gcc_unreachable ();
|
||||
tree lhs = gimple_call_lhs (call);
|
||||
if (!lhs)
|
||||
continue;
|
||||
|
||||
if (dump_file && (dump_flags & TDF_DETAILS))
|
||||
/* Propagate into all uses and fold those stmts. */
|
||||
gimple use_stmt;
|
||||
imm_use_iterator iter;
|
||||
FOR_EACH_IMM_USE_STMT (use_stmt, iter, lhs)
|
||||
{
|
||||
fprintf (dump_file, "to\n ");
|
||||
print_gimple_stmt (dump_file, gsi_stmt (i), 0, dump_flags);
|
||||
fprintf (dump_file, "\n");
|
||||
use_operand_p use_p;
|
||||
FOR_EACH_IMM_USE_ON_STMT (use_p, iter)
|
||||
SET_USE (use_p, result);
|
||||
gimple_stmt_iterator gsi = gsi_for_stmt (use_stmt);
|
||||
fold_stmt (&gsi);
|
||||
update_stmt (gsi_stmt (gsi));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -760,7 +760,7 @@ copy_reference_ops_from_ref (tree ref, vec<vn_reference_op_s> *result)
|
|||
}
|
||||
|
||||
/* For non-calls, store the information that makes up the address. */
|
||||
|
||||
tree orig = ref;
|
||||
while (ref)
|
||||
{
|
||||
vn_reference_op_s temp;
|
||||
|
@ -810,7 +810,15 @@ copy_reference_ops_from_ref (tree ref, vec<vn_reference_op_s> *result)
|
|||
+ tree_to_double_int (bit_offset)
|
||||
.rshift (BITS_PER_UNIT == 8
|
||||
? 3 : exact_log2 (BITS_PER_UNIT));
|
||||
if (off.fits_shwi ())
|
||||
if (off.fits_shwi ()
|
||||
/* Probibit value-numbering zero offset components
|
||||
of addresses the same before the pass folding
|
||||
__builtin_object_size had a chance to run
|
||||
(checking cfun->after_inlining does the
|
||||
trick here). */
|
||||
&& (TREE_CODE (orig) != ADDR_EXPR
|
||||
|| !off.is_zero ()
|
||||
|| cfun->after_inlining))
|
||||
temp.off = off.low;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue