aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorRichard Biener <rguenther@suse.de>2013-11-18 15:25:05 +0000
committerRichard Biener <rguenth@gcc.gnu.org>2013-11-18 15:25:05 +0000
commit1eadb567eff34df82355c8b5d56e32b76282bad2 (patch)
tree4fdadcce61fa5e47e03e25659386ced8080d70b9 /gcc
parent7d362f6c2b99e2b0cedf44e52194c578bdf00053 (diff)
downloadgcc-1eadb567eff34df82355c8b5d56e32b76282bad2.zip
gcc-1eadb567eff34df82355c8b5d56e32b76282bad2.tar.gz
gcc-1eadb567eff34df82355c8b5d56e32b76282bad2.tar.bz2
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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog13
-rw-r--r--gcc/passes.def2
-rw-r--r--gcc/testsuite/ChangeLog10
-rw-r--r--gcc/testsuite/gcc.dg/builtin-object-size-14.c28
-rw-r--r--gcc/testsuite/gcc.dg/builtin-object-size-8.c2
-rw-r--r--gcc/testsuite/gcc.dg/strlenopt-14gf.c10
-rw-r--r--gcc/testsuite/gcc.dg/strlenopt-1f.c4
-rw-r--r--gcc/testsuite/gcc.dg/strlenopt-4gf.c12
-rw-r--r--gcc/tree-object-size.c37
-rw-r--r--gcc/tree-ssa-sccvn.c12
10 files changed, 98 insertions, 32 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 7220961..f10564b 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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.
diff --git a/gcc/passes.def b/gcc/passes.def
index 8d8dd80..49faf25 100644
--- a/gcc/passes.def
+++ b/gcc/passes.def
@@ -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
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index e5e9ecb..909942b 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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.
diff --git a/gcc/testsuite/gcc.dg/builtin-object-size-14.c b/gcc/testsuite/gcc.dg/builtin-object-size-14.c
new file mode 100644
index 0000000..085011e
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/builtin-object-size-14.c
@@ -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;
+}
diff --git a/gcc/testsuite/gcc.dg/builtin-object-size-8.c b/gcc/testsuite/gcc.dg/builtin-object-size-8.c
index 7af64d3..f2d88f9 100644
--- a/gcc/testsuite/gcc.dg/builtin-object-size-8.c
+++ b/gcc/testsuite/gcc.dg/builtin-object-size-8.c
@@ -1,4 +1,4 @@
-/* { dg-do run { xfail *-*-* } } */
+/* { dg-do run } */
/* { dg-options "-O2" } */
typedef __SIZE_TYPE__ size_t;
diff --git a/gcc/testsuite/gcc.dg/strlenopt-14gf.c b/gcc/testsuite/gcc.dg/strlenopt-14gf.c
index 6e5c9b0..8b78538 100644
--- a/gcc/testsuite/gcc.dg/strlenopt-14gf.c
+++ b/gcc/testsuite/gcc.dg/strlenopt-14gf.c
@@ -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" } } */
diff --git a/gcc/testsuite/gcc.dg/strlenopt-1f.c b/gcc/testsuite/gcc.dg/strlenopt-1f.c
index e0a2c92..50c5f91 100644
--- a/gcc/testsuite/gcc.dg/strlenopt-1f.c
+++ b/gcc/testsuite/gcc.dg/strlenopt-1f.c
@@ -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" } } */
diff --git a/gcc/testsuite/gcc.dg/strlenopt-4gf.c b/gcc/testsuite/gcc.dg/strlenopt-4gf.c
index 743066f..e176236 100644
--- a/gcc/testsuite/gcc.dg/strlenopt-4gf.c
+++ b/gcc/testsuite/gcc.dg/strlenopt-4gf.c
@@ -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" } } */
diff --git a/gcc/tree-object-size.c b/gcc/tree-object-size.c
index 51a5d59..8dcd2aa 100644
--- a/gcc/tree-object-size.c
+++ b/gcc/tree-object-size.c
@@ -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));
}
}
}
diff --git a/gcc/tree-ssa-sccvn.c b/gcc/tree-ssa-sccvn.c
index 8742e26..26bb190 100644
--- a/gcc/tree-ssa-sccvn.c
+++ b/gcc/tree-ssa-sccvn.c
@@ -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;
}
}