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 <jakub@redhat.com> From-SVN: r202886
This commit is contained in:
parent
550dfe7f28
commit
b56e978833
@ -1,3 +1,12 @@
|
||||
2013-09-25 Marek Polacek <polacek@redhat.com>
|
||||
Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
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 <polacek@redhat.com>
|
||||
|
||||
PR sanitizer/58411
|
||||
|
@ -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);
|
||||
|
@ -1,3 +1,11 @@
|
||||
2013-09-25 Marek Polacek <polacek@redhat.com>
|
||||
|
||||
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 <polacek@redhat.com>
|
||||
|
||||
PR c++/58516
|
||||
|
8
gcc/testsuite/c-c++-common/ubsan/div-by-zero-5.c
Normal file
8
gcc/testsuite/c-c++-common/ubsan/div-by-zero-5.c
Normal file
@ -0,0 +1,8 @@
|
||||
/* { dg-do compile} */
|
||||
/* { dg-options "-fsanitize=integer-divide-by-zero" } */
|
||||
|
||||
void
|
||||
foo (void)
|
||||
{
|
||||
int A[-2 / -1] = {};
|
||||
}
|
33
gcc/testsuite/c-c++-common/ubsan/shift-5.c
Normal file
33
gcc/testsuite/c-c++-common/ubsan/shift-5.c
Normal file
@ -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;
|
||||
}
|
30
gcc/testsuite/c-c++-common/ubsan/shift-6.c
Normal file
30
gcc/testsuite/c-c++-common/ubsan/shift-6.c
Normal file
@ -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;
|
||||
}
|
18
gcc/testsuite/gcc.dg/ubsan/c-shift-1.c
Normal file
18
gcc/testsuite/gcc.dg/ubsan/c-shift-1.c
Normal file
@ -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;
|
||||
}
|
Loading…
Reference in New Issue
Block a user