re PR middle-end/59125 (gcc triggers wrong strncpy_chk)
authorRichard Biener <rguenther@suse.de>
Mon, 18 Nov 2013 15:25:05 +0000 (15:25 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Mon, 18 Nov 2013 15:25:05 +0000 (15:25 +0000)
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

gcc/ChangeLog
gcc/passes.def
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/builtin-object-size-14.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/builtin-object-size-8.c
gcc/testsuite/gcc.dg/strlenopt-14gf.c
gcc/testsuite/gcc.dg/strlenopt-1f.c
gcc/testsuite/gcc.dg/strlenopt-4gf.c
gcc/tree-object-size.c
gcc/tree-ssa-sccvn.c

index 7220961..f10564b 100644 (file)
@@ -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.
index 8d8dd80..49faf25 100644 (file)
@@ -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
index e5e9ecb..909942b 100644 (file)
@@ -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 (file)
index 0000000..085011e
--- /dev/null
@@ -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;
+}
index 7af64d3..f2d88f9 100644 (file)
@@ -1,4 +1,4 @@
-/* { dg-do run { xfail *-*-* } } */
+/* { dg-do run } */
 /* { dg-options "-O2" } */
 
 typedef __SIZE_TYPE__ size_t;
index 6e5c9b0..8b78538 100644 (file)
    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" } } */
index e0a2c92..50c5f91 100644 (file)
@@ -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" } } */
index 743066f..e176236 100644 (file)
@@ -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" } } */
index 51a5d59..8dcd2aa 100644 (file)
@@ -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));
            }
        }
     }
index 8742e26..26bb190 100644 (file)
@@ -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;
                  }
              }