re PR sanitizer/68418 (ubsan complains about left shifts even with -fwrapv)
authorPaolo Bonzini <bonzini@gnu.org>
Sat, 12 Dec 2015 08:29:27 +0000 (08:29 +0000)
committerPaolo Bonzini <bonzini@gcc.gnu.org>
Sat, 12 Dec 2015 08:29:27 +0000 (08:29 +0000)
gcc:
PR sanitizer/68418
* c-family/c-ubsan.c (ubsan_instrument_shift): Disable
sanitization of left shifts for wrapping signed types as well.

gcc/testsuite:
PR sanitizer/68418
* gcc.dg/ubsan/c99-wrapv-shift-1.c,
gcc.dg/ubsan/c99-wrapv-shift-2.c: New testcases.

From-SVN: r231582

gcc/ChangeLog
gcc/c-family/c-ubsan.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/ubsan/c99-wrapv-shift-1.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/ubsan/c99-wrapv-shift-2.c [new file with mode: 0644]

index 33b08569dff219adfc1634e2d0363e3ab381e919..6d03e1e74f63fca94d9e009ffb61cdd2080a19ef 100644 (file)
@@ -1,3 +1,9 @@
+2015-12-12  Paolo Bonzini  <bonzini@gnu.org>
+
+       PR sanitizer/68418
+       * c-family/c-ubsan.c (ubsan_instrument_shift): Disable
+       sanitization of left shifts for wrapping signed types as well.
+
 2015-12-11  Eric Botcazou  <ebotcazou@adacore.com>
 
        PR middle-end/68215
index d5f71a4a46114ba39cec801c1f0881d9529a15f4..c09a56f04bad279e94c284235cc63ea0b13207cf 100644 (file)
@@ -124,12 +124,17 @@ ubsan_instrument_shift (location_t loc, enum tree_code code,
   t = fold_convert_loc (loc, op1_utype, op1);
   t = fold_build2 (GT_EXPR, boolean_type_node, t, uprecm1);
 
+  /* If this is not a signed operation, don't perform overflow checks.
+     Also punt on bit-fields.  */
+  if (!INTEGRAL_TYPE_P (type0)
+      || TYPE_OVERFLOW_WRAPS (type0)
+      || GET_MODE_BITSIZE (TYPE_MODE (type0)) != TYPE_PRECISION (type0))
+    ;
+
   /* For signed x << y, in C99/C11, the following:
      (unsigned) x >> (uprecm1 - y)
      if non-zero, is undefined.  */
-  if (code == LSHIFT_EXPR
-      && !TYPE_UNSIGNED (type0)
-      && flag_isoc99)
+  else if (code == LSHIFT_EXPR && flag_isoc99 && cxx_dialect < cxx11)
     {
       tree x = fold_build2 (MINUS_EXPR, op1_utype, uprecm1,
                            fold_convert (op1_utype, unshare_expr (op1)));
@@ -142,9 +147,7 @@ ubsan_instrument_shift (location_t loc, enum tree_code code,
   /* For signed x << y, in C++11 and later, the following:
      x < 0 || ((unsigned) x >> (uprecm1 - y))
      if > 1, is undefined.  */
-  if (code == LSHIFT_EXPR
-      && !TYPE_UNSIGNED (type0)
-      && (cxx_dialect >= cxx11))
+  else if (code == LSHIFT_EXPR && cxx_dialect >= cxx11)
     {
       tree x = fold_build2 (MINUS_EXPR, op1_utype, uprecm1,
                            fold_convert (op1_utype, unshare_expr (op1)));
index 3877b19c95ea5f15a661dd926c623ea0d1aaee81..240bd5ddd5b17787f961494ad5800394c0440711 100644 (file)
@@ -1,3 +1,9 @@
+2015-12-12  Paolo Bonzini  <bonzini@gnu.org>
+
+       PR sanitizer/68418
+       * gcc.dg/ubsan/c99-wrapv-shift-1.c,
+       gcc.dg/ubsan/c99-wrapv-shift-2.c: New testcases.
+
 2015-12-11  Jeff Law  <law@redhat.com>
 
        PR tree-optimization/68844
diff --git a/gcc/testsuite/gcc.dg/ubsan/c99-wrapv-shift-1.c b/gcc/testsuite/gcc.dg/ubsan/c99-wrapv-shift-1.c
new file mode 100644 (file)
index 0000000..51910da
--- /dev/null
@@ -0,0 +1,9 @@
+/* { dg-do run } */
+/* { dg-options "-fsanitize=shift -fwrapv -w -std=c99" } */
+
+int
+main (void)
+{
+  int a = -42;
+  a << 1;
+}
diff --git a/gcc/testsuite/gcc.dg/ubsan/c99-wrapv-shift-2.c b/gcc/testsuite/gcc.dg/ubsan/c99-wrapv-shift-2.c
new file mode 100644 (file)
index 0000000..93087d1
--- /dev/null
@@ -0,0 +1,9 @@
+/* { dg-do run } */
+/* { dg-options "-fsanitize=shift -fwrapv -w -std=c99" } */
+
+int
+main (void)
+{
+  int a = 1;
+  a <<= 31;
+}