Commit 1eadb567 by Richard Biener Committed by Richard Biener

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
parent 7d362f6c
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> 2013-11-18 Richard Sandiford <rdsandiford@googlemail.com>
* tree.h (tree_to_uhwi): Return an unsigned HOST_WIDE_INT. * 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 ...@@ -142,6 +142,7 @@ along with GCC; see the file COPYING3. If not see
form if possible. */ form if possible. */
NEXT_PASS (pass_phiprop); NEXT_PASS (pass_phiprop);
NEXT_PASS (pass_forwprop); NEXT_PASS (pass_forwprop);
NEXT_PASS (pass_object_sizes);
/* pass_build_alias is a dummy pass that ensures that we /* pass_build_alias is a dummy pass that ensures that we
execute TODO_rebuild_alias at this point. */ execute TODO_rebuild_alias at this point. */
NEXT_PASS (pass_build_alias); NEXT_PASS (pass_build_alias);
...@@ -185,7 +186,6 @@ along with GCC; see the file COPYING3. If not see ...@@ -185,7 +186,6 @@ along with GCC; see the file COPYING3. If not see
NEXT_PASS (pass_dce); NEXT_PASS (pass_dce);
NEXT_PASS (pass_forwprop); NEXT_PASS (pass_forwprop);
NEXT_PASS (pass_phiopt); NEXT_PASS (pass_phiopt);
NEXT_PASS (pass_object_sizes);
NEXT_PASS (pass_strlen); NEXT_PASS (pass_strlen);
NEXT_PASS (pass_ccp); NEXT_PASS (pass_ccp);
/* After CCP we rewrite no longer addressed locals into SSA /* After CCP we rewrite no longer addressed locals into SSA
......
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> 2013-11-18 Eric Botcazou <ebotcazou@adacore.com>
* gnat.dg/volatile11.adb: New test. * gnat.dg/volatile11.adb: New test.
......
/* { 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;
}
/* { dg-do run { xfail *-*-* } } */ /* { dg-do run } */
/* { dg-options "-O2" } */ /* { dg-options "-O2" } */
typedef __SIZE_TYPE__ size_t; typedef __SIZE_TYPE__ size_t;
......
...@@ -11,14 +11,14 @@ ...@@ -11,14 +11,14 @@
memcpy. */ memcpy. */
/* { dg-final { scan-tree-dump-times "strlen \\(" 4 "strlen" } } */ /* { 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 "__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 "__strcpy_chk \\(" 0 "strlen" } } */
/* { dg-final { scan-tree-dump-times "__strcat_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 "strchr \\(" 0 "strlen" } } */
/* { dg-final { scan-tree-dump-times "__stpcpy_chk \\(" 3 "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 \\(" 1 "strlen" } } */
/* { dg-final { scan-tree-dump-times "mempcpy \\(" 0 "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 "strcpy \\(" 0 "strlen" } } */
/* { dg-final { scan-tree-dump-times "strcat \\(" 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" } } */ /* { dg-final { cleanup-tree-dump "strlen" } } */
...@@ -6,12 +6,12 @@ ...@@ -6,12 +6,12 @@
#include "strlenopt-1.c" #include "strlenopt-1.c"
/* { dg-final { scan-tree-dump-times "strlen \\(" 2 "strlen" } } */ /* { 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 "__strcpy_chk \\(" 0 "strlen" } } */
/* { dg-final { scan-tree-dump-times "__strcat_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 "strchr \\(" 0 "strlen" } } */
/* { dg-final { scan-tree-dump-times "__stpcpy_chk \\(" 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 "strcpy \\(" 0 "strlen" } } */
/* { dg-final { scan-tree-dump-times "strcat \\(" 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 \\(" 0 "strlen" } } */
......
...@@ -7,13 +7,13 @@ ...@@ -7,13 +7,13 @@
#include "strlenopt-4.c" #include "strlenopt-4.c"
/* { dg-final { scan-tree-dump-times "strlen \\(" 1 "strlen" } } */ /* { 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 "__memcpy_chk \\(" 0 "strlen" } } */
/* { dg-final { scan-tree-dump-times "__strcpy_chk \\(" 1 "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 "__strcat_chk \\(" 0 "strlen" } } */
/* { dg-final { scan-tree-dump-times "strchr \\(" 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 "__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 "strcpy \\(" 1 "strlen" } } */
/* { dg-final { scan-tree-dump-times "strcat \\(" 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 \\(" 5 "strlen" } } */
/* { dg-final { cleanup-tree-dump "strlen" } } */ /* { dg-final { cleanup-tree-dump "strlen" } } */
...@@ -32,6 +32,8 @@ along with GCC; see the file COPYING3. If not see ...@@ -32,6 +32,8 @@ along with GCC; see the file COPYING3. If not see
#include "tree-ssanames.h" #include "tree-ssanames.h"
#include "tree-pass.h" #include "tree-pass.h"
#include "tree-ssa-propagate.h" #include "tree-ssa-propagate.h"
#include "tree-phinodes.h"
#include "ssa-iterators.h"
struct object_size_info struct object_size_info
{ {
...@@ -1205,16 +1207,9 @@ compute_object_sizes (void) ...@@ -1205,16 +1207,9 @@ compute_object_sizes (void)
gimple_stmt_iterator i; gimple_stmt_iterator i;
for (i = gsi_start_bb (bb); !gsi_end_p (i); gsi_next (&i)) for (i = gsi_start_bb (bb); !gsi_end_p (i); gsi_next (&i))
{ {
tree callee, result; tree result;
gimple call = gsi_stmt (i); gimple call = gsi_stmt (i);
if (!gimple_call_builtin_p (call, BUILT_IN_OBJECT_SIZE))
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)
continue; continue;
init_object_sizes (); init_object_sizes ();
...@@ -1243,20 +1238,32 @@ compute_object_sizes (void) ...@@ -1243,20 +1238,32 @@ compute_object_sizes (void)
continue; continue;
} }
gcc_assert (TREE_CODE (result) == INTEGER_CST);
if (dump_file && (dump_flags & TDF_DETAILS)) if (dump_file && (dump_flags & TDF_DETAILS))
{ {
fprintf (dump_file, "Simplified\n "); fprintf (dump_file, "Simplified\n ");
print_gimple_stmt (dump_file, call, 0, dump_flags); 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)) tree lhs = gimple_call_lhs (call);
gcc_unreachable (); 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 "); use_operand_p use_p;
print_gimple_stmt (dump_file, gsi_stmt (i), 0, dump_flags); FOR_EACH_IMM_USE_ON_STMT (use_p, iter)
fprintf (dump_file, "\n"); 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) ...@@ -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. */ /* For non-calls, store the information that makes up the address. */
tree orig = ref;
while (ref) while (ref)
{ {
vn_reference_op_s temp; vn_reference_op_s temp;
...@@ -810,7 +810,15 @@ copy_reference_ops_from_ref (tree ref, vec<vn_reference_op_s> *result) ...@@ -810,7 +810,15 @@ copy_reference_ops_from_ref (tree ref, vec<vn_reference_op_s> *result)
+ tree_to_double_int (bit_offset) + tree_to_double_int (bit_offset)
.rshift (BITS_PER_UNIT == 8 .rshift (BITS_PER_UNIT == 8
? 3 : exact_log2 (BITS_PER_UNIT)); ? 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; temp.off = off.low;
} }
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment