From b300764434b6e25bbab71e8de38987d288cfd703 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Sat, 12 Dec 2015 08:29:27 +0000 Subject: [PATCH] re PR sanitizer/68418 (ubsan complains about left shifts even with -fwrapv) 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 | 6 ++++++ gcc/c-family/c-ubsan.c | 15 +++++++++------ gcc/testsuite/ChangeLog | 6 ++++++ gcc/testsuite/gcc.dg/ubsan/c99-wrapv-shift-1.c | 9 +++++++++ gcc/testsuite/gcc.dg/ubsan/c99-wrapv-shift-2.c | 9 +++++++++ 5 files changed, 39 insertions(+), 6 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/ubsan/c99-wrapv-shift-1.c create mode 100644 gcc/testsuite/gcc.dg/ubsan/c99-wrapv-shift-2.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 33b0856..6d03e1e 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2015-12-12 Paolo Bonzini + + 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 PR middle-end/68215 diff --git a/gcc/c-family/c-ubsan.c b/gcc/c-family/c-ubsan.c index d5f71a4..c09a56f 100644 --- a/gcc/c-family/c-ubsan.c +++ b/gcc/c-family/c-ubsan.c @@ -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))); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 3877b19..240bd5d 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2015-12-12 Paolo Bonzini + + 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 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 index 0000000..51910da --- /dev/null +++ b/gcc/testsuite/gcc.dg/ubsan/c99-wrapv-shift-1.c @@ -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 index 0000000..93087d1 --- /dev/null +++ b/gcc/testsuite/gcc.dg/ubsan/c99-wrapv-shift-2.c @@ -0,0 +1,9 @@ +/* { dg-do run } */ +/* { dg-options "-fsanitize=shift -fwrapv -w -std=c99" } */ + +int +main (void) +{ + int a = 1; + a <<= 31; +} -- 2.7.4