Hi!

This patch fixes the following testcase by folding some ubsan internal fns
we'd either remove anyway during sanopt, or lower into if (cond)
do_something during sanopt where cond would be always false.

Additionally, I've tried to clean up a little bit IFN_UBSAN_OBJECT_SIZE
handling by using variables for the call arguments that make it clear
what the arguments are.

Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

2017-09-01  Jakub Jelinek  <ja...@redhat.com>

        PR sanitizer/81981
        * gimple-fold.c (gimple_fold_call): Optimize away useless UBSAN_PTR
        and UBSAN_BOUNDS internal calls.  Clean up IFN_UBSAN_OBJECT_SIZE
        handling.

        * gcc.dg/ubsan/pr81981.c: New test.

--- gcc/gimple-fold.c.jj        2017-08-10 02:31:21.000000000 +0200
+++ gcc/gimple-fold.c   2017-08-29 18:50:49.993673432 +0200
@@ -3938,11 +3938,23 @@ gimple_fold_call (gimple_stmt_iterator *
                                        gimple_call_arg (stmt, 2));
          break;
        case IFN_UBSAN_OBJECT_SIZE:
-         if (integer_all_onesp (gimple_call_arg (stmt, 2))
-             || (TREE_CODE (gimple_call_arg (stmt, 1)) == INTEGER_CST
-                 && TREE_CODE (gimple_call_arg (stmt, 2)) == INTEGER_CST
-                 && tree_int_cst_le (gimple_call_arg (stmt, 1),
-                                     gimple_call_arg (stmt, 2))))
+         {
+           tree offset = gimple_call_arg (stmt, 1);
+           tree objsize = gimple_call_arg (stmt, 2);
+           if (integer_all_onesp (objsize)
+               || (TREE_CODE (offset) == INTEGER_CST
+                   && TREE_CODE (objsize) == INTEGER_CST
+                   && tree_int_cst_le (offset, objsize)))
+             {
+               gsi_replace (gsi, gimple_build_nop (), false);
+               unlink_stmt_vdef (stmt);
+               release_defs (stmt);
+               return true;
+             }
+         }
+         break;
+       case IFN_UBSAN_PTR:
+         if (integer_zerop (gimple_call_arg (stmt, 1)))
            {
              gsi_replace (gsi, gimple_build_nop (), false);
              unlink_stmt_vdef (stmt);
@@ -3950,6 +3962,25 @@ gimple_fold_call (gimple_stmt_iterator *
              return true;
            }
          break;
+       case IFN_UBSAN_BOUNDS:
+         {
+           tree index = gimple_call_arg (stmt, 1);
+           tree bound = gimple_call_arg (stmt, 2);
+           if (TREE_CODE (index) == INTEGER_CST
+               && TREE_CODE (bound) == INTEGER_CST)
+             {
+               index = fold_convert (TREE_TYPE (bound), index);
+               if (TREE_CODE (index) == INTEGER_CST
+                   && tree_int_cst_le (index, bound))
+                 {
+                   gsi_replace (gsi, gimple_build_nop (), false);
+                   unlink_stmt_vdef (stmt);
+                   release_defs (stmt);
+                   return true;
+                 }
+             }
+         }
+         break;
        case IFN_GOACC_DIM_SIZE:
        case IFN_GOACC_DIM_POS:
          result = fold_internal_goacc_dim (stmt);
--- gcc/testsuite/gcc.dg/ubsan/pr81981.c.jj     2017-08-29 18:54:33.826107761 
+0200
+++ gcc/testsuite/gcc.dg/ubsan/pr81981.c        2017-08-29 18:55:36.721386827 
+0200
@@ -0,0 +1,21 @@
+/* PR sanitizer/81981 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -Wmaybe-uninitialized -fsanitize=undefined 
-ffat-lto-objects" } */
+
+int v;
+
+int
+foo (int i)
+{
+  int t[1], u[1];
+  int n = 0;
+
+  if (i)
+    {
+      t[n] = i;
+      u[0] = i;
+    }
+
+  v = u[0];            /* { dg-warning "may be used uninitialized in this 
function" } */
+  return t[0];         /* { dg-warning "may be used uninitialized in this 
function" } */
+}

        Jakub

Reply via email to