From b56e978833b09ba47ebc4ebdace007164b493266 Mon Sep 17 00:00:00 2001 From: Marek Polacek Date: Wed, 25 Sep 2013 08:58:57 +0000 Subject: [PATCH] re PR sanitizer/58413 (ubsan constant folding) PR sanitizer/58413 c-family/ * c-ubsan.c (ubsan_instrument_shift): Don't instrument an expression if we can prove it is correct. (ubsan_instrument_division): Likewise. Remove unnecessary check. testsuite/ * c-c++-common/ubsan/shift-5.c: New test. * c-c++-common/ubsan/shift-6.c: New test. * c-c++-common/ubsan/div-by-zero-5.c: New test. * gcc.dg/ubsan/c-shift-1.c: New test. Co-Authored-By: Jakub Jelinek From-SVN: r202886 --- gcc/c-family/ChangeLog | 9 +++++ gcc/c-family/c-ubsan.c | 18 +++++----- gcc/testsuite/ChangeLog | 8 +++++ .../c-c++-common/ubsan/div-by-zero-5.c | 8 +++++ gcc/testsuite/c-c++-common/ubsan/shift-5.c | 33 +++++++++++++++++++ gcc/testsuite/c-c++-common/ubsan/shift-6.c | 30 +++++++++++++++++ gcc/testsuite/gcc.dg/ubsan/c-shift-1.c | 18 ++++++++++ 7 files changed, 116 insertions(+), 8 deletions(-) create mode 100644 gcc/testsuite/c-c++-common/ubsan/div-by-zero-5.c create mode 100644 gcc/testsuite/c-c++-common/ubsan/shift-5.c create mode 100644 gcc/testsuite/c-c++-common/ubsan/shift-6.c create mode 100644 gcc/testsuite/gcc.dg/ubsan/c-shift-1.c diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog index 1772ba56b49..c7a8c7872cc 100644 --- a/gcc/c-family/ChangeLog +++ b/gcc/c-family/ChangeLog @@ -1,3 +1,12 @@ +2013-09-25 Marek Polacek + Jakub Jelinek + + PR sanitizer/58413 + * c-ubsan.c (ubsan_instrument_shift): Don't instrument + an expression if we can prove it is correct. + (ubsan_instrument_division): Likewise. Remove unnecessary + check. + 2013-09-18 Marek Polacek PR sanitizer/58411 diff --git a/gcc/c-family/c-ubsan.c b/gcc/c-family/c-ubsan.c index 9f43f6d55b8..0bfc660cdd5 100644 --- a/gcc/c-family/c-ubsan.c +++ b/gcc/c-family/c-ubsan.c @@ -51,14 +51,6 @@ ubsan_instrument_division (location_t loc, tree op0, tree op1) if (TREE_CODE (type) != INTEGER_TYPE) return NULL_TREE; - /* If we *know* that the divisor is not -1 or 0, we don't have to - instrument this expression. - ??? We could use decl_constant_value to cover up more cases. */ - if (TREE_CODE (op1) == INTEGER_CST - && integer_nonzerop (op1) - && !integer_minus_onep (op1)) - return NULL_TREE; - t = fold_build2 (EQ_EXPR, boolean_type_node, op1, build_int_cst (type, 0)); @@ -74,6 +66,11 @@ ubsan_instrument_division (location_t loc, tree op0, tree op1) t = fold_build2 (TRUTH_OR_EXPR, boolean_type_node, t, x); } + /* If the condition was folded to 0, no need to instrument + this expression. */ + if (integer_zerop (t)) + return NULL_TREE; + /* In case we have a SAVE_EXPR in a conditional context, we need to make sure it gets evaluated before the condition. */ t = fold_build2 (COMPOUND_EXPR, TREE_TYPE (t), op0, t); @@ -138,6 +135,11 @@ ubsan_instrument_shift (location_t loc, enum tree_code code, tt = fold_build2 (TRUTH_OR_EXPR, boolean_type_node, x, tt); } + /* If the condition was folded to 0, no need to instrument + this expression. */ + if (integer_zerop (t) && (tt == NULL_TREE || integer_zerop (tt))) + return NULL_TREE; + /* In case we have a SAVE_EXPR in a conditional context, we need to make sure it gets evaluated before the condition. */ t = fold_build2 (COMPOUND_EXPR, TREE_TYPE (t), op0, t); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 68e38cc9419..09644d21037 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,11 @@ +2013-09-25 Marek Polacek + + PR sanitizer/58413 + * c-c++-common/ubsan/shift-5.c: New test. + * c-c++-common/ubsan/shift-6.c: New test. + * c-c++-common/ubsan/div-by-zero-5.c: New test. + * gcc.dg/ubsan/c-shift-1.c: New test. + 2013-09-25 Marek Polacek PR c++/58516 diff --git a/gcc/testsuite/c-c++-common/ubsan/div-by-zero-5.c b/gcc/testsuite/c-c++-common/ubsan/div-by-zero-5.c new file mode 100644 index 00000000000..7a28bacd14b --- /dev/null +++ b/gcc/testsuite/c-c++-common/ubsan/div-by-zero-5.c @@ -0,0 +1,8 @@ +/* { dg-do compile} */ +/* { dg-options "-fsanitize=integer-divide-by-zero" } */ + +void +foo (void) +{ + int A[-2 / -1] = {}; +} diff --git a/gcc/testsuite/c-c++-common/ubsan/shift-5.c b/gcc/testsuite/c-c++-common/ubsan/shift-5.c new file mode 100644 index 00000000000..6f9c52a7288 --- /dev/null +++ b/gcc/testsuite/c-c++-common/ubsan/shift-5.c @@ -0,0 +1,33 @@ +/* { dg-do compile } */ +/* { dg-options "-fsanitize=shift -w" } */ +/* { dg-shouldfail "ubsan" } */ + +int x; +int +foo (void) +{ + /* None of the following should pass. */ + switch (x) + { + case 1 >> -1: +/* { dg-error "case label does not reduce to an integer constant" "" {target c } 12 } */ +/* { dg-error "is not a constant expression" "" { target c++ } 12 } */ + case -1 >> -1: +/* { dg-error "case label does not reduce to an integer constant" "" {target c } 15 } */ +/* { dg-error "is not a constant expression" "" { target c++ } 15 } */ + case 1 << -1: +/* { dg-error "case label does not reduce to an integer constant" "" {target c } 18 } */ +/* { dg-error "is not a constant expression" "" { target c++ } 18 } */ + case -1 << -1: +/* { dg-error "case label does not reduce to an integer constant" "" {target c } 21 } */ +/* { dg-error "is not a constant expression" "" { target c++ } 21 } */ + case -1 >> 200: +/* { dg-error "case label does not reduce to an integer constant" "" {target c } 24 } */ +/* { dg-error "is not a constant expression" "" { target c++ } 24 } */ + case 1 << 200: +/* { dg-error "case label does not reduce to an integer constant" "" {target c } 27 } */ +/* { dg-error "is not a constant expression" "" { target c++ } 27 } */ + return 1; + } + return 0; +} diff --git a/gcc/testsuite/c-c++-common/ubsan/shift-6.c b/gcc/testsuite/c-c++-common/ubsan/shift-6.c new file mode 100644 index 00000000000..a0e2e20acc1 --- /dev/null +++ b/gcc/testsuite/c-c++-common/ubsan/shift-6.c @@ -0,0 +1,30 @@ +/* PR sanitizer/58413 */ +/* { dg-do run { target int32plus } } */ +/* { dg-options "-fsanitize=shift -w" } */ + +int x = 7; +int +main (void) +{ + /* All of the following should pass. */ + int A[128 >> 5] = {}; + int B[128 << 5] = {}; + + static int e = + ((int) + (0x00000000 | ((31 & ((1 << (4)) - 1)) << (((15) + 6) + 4)) | + ((0) << ((15) + 6)) | ((0) << (15)))); + + if (e != 503316480) + __builtin_abort (); + + switch (x) + { + case 1 >> 4: + case 1 << 4: + case 128 << (4 + 1): + case 128 >> (4 + 1): + return 1; + } + return 0; +} diff --git a/gcc/testsuite/gcc.dg/ubsan/c-shift-1.c b/gcc/testsuite/gcc.dg/ubsan/c-shift-1.c new file mode 100644 index 00000000000..61b90105364 --- /dev/null +++ b/gcc/testsuite/gcc.dg/ubsan/c-shift-1.c @@ -0,0 +1,18 @@ +/* { dg-do compile} */ +/* { dg-options "-fsanitize=shift -w" } */ +/* { dg-shouldfail "ubsan" } */ + +int x; +int +main (void) +{ + /* None of the following should pass. */ + int A[1 >> -1] = {}; /* { dg-error "variable-sized object may not be initialized" } */ + int B[-1 >> -1] = {}; /* { dg-error "variable-sized object may not be initialized" } */ + int D[1 << -1] = {}; /* { dg-error "variable-sized object may not be initialized" } */ + int E[-1 << -1] = {}; /* { dg-error "variable-sized object may not be initialized" } */ + int F[-1 >> 200] = {}; /* { dg-error "variable-sized object may not be initialized" } */ + int G[1 << 200] = {}; /* { dg-error "variable-sized object may not be initialized" } */ + + return 0; +} -- 2.30.2