diff options
-rw-r--r-- | gcc/ChangeLog | 9 | ||||
-rw-r--r-- | gcc/c/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/c/c-convert.c | 12 | ||||
-rw-r--r-- | gcc/convert.c | 4 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/ubsan/float-cast-overflow-atomic.c | 171 | ||||
-rw-r--r-- | gcc/ubsan.c | 10 | ||||
-rw-r--r-- | gcc/ubsan.h | 2 |
8 files changed, 204 insertions, 16 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index d909693..e5b31af 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,12 @@ +2016-01-06 Marek Polacek <polacek@redhat.com> + + PR sanitizer/69099 + * convert.c (convert_to_integer_1): Adjust call to + ubsan_instrument_float_cast. Use NULL_TREE instead of NULL. + * ubsan.c (ubsan_instrument_float_cast): Drop the ARG parameter. Use + EXPR instead of ARG. + * ubsan.h (ubsan_instrument_float_cast): Adjust declaration. + 2016-01-05 Sandra Loosemore <sandra@codesourcery.com> PR 1078 diff --git a/gcc/c/ChangeLog b/gcc/c/ChangeLog index ccb7346..379f002 100644 --- a/gcc/c/ChangeLog +++ b/gcc/c/ChangeLog @@ -1,3 +1,10 @@ +2016-01-06 Marek Polacek <polacek@redhat.com> + + PR sanitizer/69099 + * c-convert.c (convert) [INTEGER_TYPE]: Drop ARG. Don't pass ARG to + ubsan_instrument_float_cast. Fold EXPR. Use NULL_TREE instead of + NULL. + 2016-01-04 Jakub Jelinek <jakub@redhat.com> Update copyright years. diff --git a/gcc/c/c-convert.c b/gcc/c/c-convert.c index 5ee52eb..4167c34 100644 --- a/gcc/c/c-convert.c +++ b/gcc/c/c-convert.c @@ -111,20 +111,16 @@ convert (tree type, tree expr) && COMPLETE_TYPE_P (type) && do_ubsan_in_current_function ()) { - tree arg; if (in_late_binary_op) - { - expr = save_expr (expr); - arg = expr; - } + expr = save_expr (expr); else { expr = c_save_expr (expr); - arg = c_fully_fold (expr, false, NULL); + expr = c_fully_fold (expr, false, NULL); } - tree check = ubsan_instrument_float_cast (loc, type, expr, arg); + tree check = ubsan_instrument_float_cast (loc, type, expr); expr = fold_build1 (FIX_TRUNC_EXPR, type, expr); - if (check == NULL) + if (check == NULL_TREE) return expr; return fold_build2 (COMPOUND_EXPR, TREE_TYPE (expr), check, expr); } diff --git a/gcc/convert.c b/gcc/convert.c index 4b1e1f1..dd7d818 100644 --- a/gcc/convert.c +++ b/gcc/convert.c @@ -920,9 +920,9 @@ convert_to_integer_1 (tree type, tree expr, bool dofold) && do_ubsan_in_current_function ()) { expr = save_expr (expr); - tree check = ubsan_instrument_float_cast (loc, type, expr, expr); + tree check = ubsan_instrument_float_cast (loc, type, expr); expr = build1 (FIX_TRUNC_EXPR, type, expr); - if (check == NULL) + if (check == NULL_TREE) return expr; return maybe_fold_build2_loc (dofold, loc, COMPOUND_EXPR, TREE_TYPE (expr), check, expr); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 53219fe..85d630b 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2016-01-06 Marek Polacek <polacek@redhat.com> + + PR sanitizer/69099 + * gcc.dg/ubsan/float-cast-overflow-atomic.c: New test. + 2016-01-05 Marek Polacek <polacek@redhat.com> PR c/69104 diff --git a/gcc/testsuite/gcc.dg/ubsan/float-cast-overflow-atomic.c b/gcc/testsuite/gcc.dg/ubsan/float-cast-overflow-atomic.c new file mode 100644 index 0000000..0a4fa01 --- /dev/null +++ b/gcc/testsuite/gcc.dg/ubsan/float-cast-overflow-atomic.c @@ -0,0 +1,171 @@ +/* PR sanitizer/69099 */ +/* { dg-do compile } */ +/* { dg-options "-std=c11 -pedantic-errors -fsanitize=float-cast-overflow" } */ +/* This is gcc.dg/atomic/c11-atomic-exec-2.c. */ + +extern void abort (void); +extern void exit (int); + +#define CMPLX(X, Y) __builtin_complex ((X), (Y)) + +#define TEST_COMPOUND(TYPE, LHSVAL, RHSVAL, OP) \ + do \ + { \ + static volatile _Atomic (TYPE) a = (TYPE) (LHSVAL); \ + if ((a OP##= (RHSVAL)) != (TYPE) ((TYPE) (LHSVAL) OP (RHSVAL))) \ + abort (); \ + if (a != (TYPE) ((TYPE) (LHSVAL) OP (RHSVAL))) \ + abort (); \ + } \ + while (0) + +#define TEST_COMPOUND_ARITH(LHSVAL, RHSVAL, OP) \ + do \ + { \ + TEST_COMPOUND (_Bool, (LHSVAL), (RHSVAL), OP); \ + TEST_COMPOUND (char, (LHSVAL), (RHSVAL), OP); \ + TEST_COMPOUND (signed char, (LHSVAL), (RHSVAL), OP); \ + TEST_COMPOUND (unsigned char, (LHSVAL), (RHSVAL), OP); \ + TEST_COMPOUND (signed short, (LHSVAL), (RHSVAL), OP); \ + TEST_COMPOUND (unsigned short, (LHSVAL), (RHSVAL), OP); \ + TEST_COMPOUND (signed int, (LHSVAL), (RHSVAL), OP); \ + TEST_COMPOUND (unsigned int, (LHSVAL), (RHSVAL), OP); \ + TEST_COMPOUND (signed long, (LHSVAL), (RHSVAL), OP); \ + TEST_COMPOUND (unsigned long, (LHSVAL), (RHSVAL), OP); \ + TEST_COMPOUND (signed long long, (LHSVAL), (RHSVAL), OP); \ + TEST_COMPOUND (unsigned long long, (LHSVAL), (RHSVAL), OP); \ + TEST_COMPOUND (float, (LHSVAL), (RHSVAL), OP); \ + TEST_COMPOUND (double, (LHSVAL), (RHSVAL), OP); \ + TEST_COMPOUND (long double, (LHSVAL), (RHSVAL), OP); \ + TEST_COMPOUND (_Complex float, (LHSVAL), (RHSVAL), OP); \ + TEST_COMPOUND (_Complex double, (LHSVAL), (RHSVAL), OP); \ + TEST_COMPOUND (_Complex long double, (LHSVAL), (RHSVAL), OP); \ + } \ + while (0) + +#define TEST_COMPOUND_INT(LHSVAL, RHSVAL, OP) \ + do \ + { \ + TEST_COMPOUND (_Bool, (LHSVAL), (RHSVAL), OP); \ + TEST_COMPOUND (char, (LHSVAL), (RHSVAL), OP); \ + TEST_COMPOUND (signed char, (LHSVAL), (RHSVAL), OP); \ + TEST_COMPOUND (unsigned char, (LHSVAL), (RHSVAL), OP); \ + TEST_COMPOUND (signed short, (LHSVAL), (RHSVAL), OP); \ + TEST_COMPOUND (unsigned short, (LHSVAL), (RHSVAL), OP); \ + TEST_COMPOUND (signed int, (LHSVAL), (RHSVAL), OP); \ + TEST_COMPOUND (unsigned int, (LHSVAL), (RHSVAL), OP); \ + TEST_COMPOUND (signed long, (LHSVAL), (RHSVAL), OP); \ + TEST_COMPOUND (unsigned long, (LHSVAL), (RHSVAL), OP); \ + TEST_COMPOUND (signed long long, (LHSVAL), (RHSVAL), OP); \ + TEST_COMPOUND (unsigned long long, (LHSVAL), (RHSVAL), OP); \ + } \ + while (0) + +static void +test_mult (void) +{ + TEST_COMPOUND_ARITH (1, 2, *); + TEST_COMPOUND_ARITH (-3, 5, *); + TEST_COMPOUND_ARITH (-7, -20, *); + TEST_COMPOUND_ARITH (1.25, 3.5, *); + TEST_COMPOUND_ARITH (CMPLX (1.5, 2.5), CMPLX (3.5, 4.5), *); + TEST_COMPOUND_ARITH (CMPLX (1.5, 2.5), 2, *); +} + +static void +test_div (void) +{ + TEST_COMPOUND_ARITH (1, 2, /); + TEST_COMPOUND_ARITH (-6, 3, /); + TEST_COMPOUND_ARITH (-70, -10, /); + TEST_COMPOUND_ARITH (1.25, 2.5, /); + TEST_COMPOUND_ARITH (CMPLX (1.0, 1.0), CMPLX (0.5, 0.5), /); + TEST_COMPOUND_ARITH (CMPLX (1.5, 2.5), 2, /); +} + +static void +test_mod (void) +{ + TEST_COMPOUND_INT (1, 2, %); + TEST_COMPOUND_INT (-3, 5, %); + TEST_COMPOUND_INT (-7, -2, %); +} + +static void +test_plus (void) +{ + TEST_COMPOUND_ARITH (1, 2, +); + TEST_COMPOUND_ARITH (-3, 5, +); + TEST_COMPOUND_ARITH (-7, -20, +); + TEST_COMPOUND_ARITH (1.25, 3.5, +); + TEST_COMPOUND_ARITH (CMPLX (1.5, 2.5), CMPLX (3.5, 4.5), +); + TEST_COMPOUND_ARITH (CMPLX (1.5, 2.5), 2, +); + static int ia[2]; + TEST_COMPOUND (int *, &ia[1], 1, +); + TEST_COMPOUND (int *, &ia[1], -1, +); +} + +static void +test_minus (void) +{ + TEST_COMPOUND_ARITH (1, 2, -); + TEST_COMPOUND_ARITH (-3, 5, -); + TEST_COMPOUND_ARITH (-7, -20, -); + TEST_COMPOUND_ARITH (3.5, 1.25, -); + TEST_COMPOUND_ARITH (CMPLX (3.5, 4.5), CMPLX (1.5, 2.5), -); + TEST_COMPOUND_ARITH (CMPLX (3.5, 2.5), 2, -); + static int ia[2]; + TEST_COMPOUND (int *, &ia[1], 1, -); + TEST_COMPOUND (int *, &ia[1], -1, -); +} + +static void +test_lshift (void) +{ + TEST_COMPOUND_INT (1, 7, <<); + TEST_COMPOUND_INT (15, 3, <<); +} + +static void +test_rshift (void) +{ + TEST_COMPOUND_INT (1, 1, >>); + TEST_COMPOUND_INT (127, 4, >>); +} + +static void +test_and (void) +{ + TEST_COMPOUND_INT (0x1234, 0x7856, &); + TEST_COMPOUND_INT (-1, 0x12345678, &); +} + +static void +test_xor (void) +{ + TEST_COMPOUND_INT (0x1234, 0x7856, ^); + TEST_COMPOUND_INT (-1, 0x12345678, ^); +} + +static void +test_or (void) +{ + TEST_COMPOUND_INT (0x1234, 0x7856, |); + TEST_COMPOUND_INT (-12345, 0x12345678, |); +} + +int +main (void) +{ + test_mult (); + test_div (); + test_mod (); + test_plus (); + test_minus (); + test_lshift (); + test_rshift (); + test_and (); + test_xor (); + test_or (); + exit (0); +} diff --git a/gcc/ubsan.c b/gcc/ubsan.c index e5b49b2..d3fbfd1 100644 --- a/gcc/ubsan.c +++ b/gcc/ubsan.c @@ -1478,18 +1478,18 @@ ubsan_use_new_style_p (location_t loc) } /* Instrument float point-to-integer conversion. TYPE is an integer type of - destination, EXPR is floating-point expression. ARG is what to pass - the libubsan call as value, often EXPR itself. */ + destination, EXPR is floating-point expression. */ tree -ubsan_instrument_float_cast (location_t loc, tree type, tree expr, tree arg) +ubsan_instrument_float_cast (location_t loc, tree type, tree expr) { tree expr_type = TREE_TYPE (expr); tree t, tt, fn, min, max; machine_mode mode = TYPE_MODE (expr_type); int prec = TYPE_PRECISION (type); bool uns_p = TYPE_UNSIGNED (type); - if (!loc) loc = input_location; + if (loc == UNKNOWN_LOCATION) + loc = input_location; /* Float to integer conversion first truncates toward zero, so even signed char c = 127.875f; is not problematic. @@ -1609,7 +1609,7 @@ ubsan_instrument_float_cast (location_t loc, tree type, tree expr, tree arg) fn = builtin_decl_explicit (bcode); fn = build_call_expr_loc (loc, fn, 2, build_fold_addr_expr_loc (loc, data), - ubsan_encode_value (arg, false)); + ubsan_encode_value (expr, false)); } return fold_build3 (COND_EXPR, void_type_node, t, fn, integer_zero_node); diff --git a/gcc/ubsan.h b/gcc/ubsan.h index d272d62..c66d0af 100644 --- a/gcc/ubsan.h +++ b/gcc/ubsan.h @@ -53,7 +53,7 @@ extern tree ubsan_type_descriptor (tree, enum ubsan_print_style = UBSAN_PRINT_NO extern tree ubsan_encode_value (tree, bool = false); extern bool is_ubsan_builtin_p (tree); extern tree ubsan_build_overflow_builtin (tree_code, location_t, tree, tree, tree); -extern tree ubsan_instrument_float_cast (location_t, tree, tree, tree); +extern tree ubsan_instrument_float_cast (location_t, tree, tree); extern tree ubsan_get_source_location_type (void); #endif /* GCC_UBSAN_H */ |