diff options
author | jakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4> | 2015-01-05 21:46:31 +0000 |
---|---|---|
committer | jakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4> | 2015-01-05 21:46:31 +0000 |
commit | 823a9dd48593c13a959d2bcf2635b48a36509626 (patch) | |
tree | 0fb2cd367e6916c7cd83f6635fec9facebcc58a5 /gcc/c | |
parent | d8a5b68899bb4013ddc0e62e73dbc97aedef0067 (diff) | |
download | gcc-823a9dd48593c13a959d2bcf2635b48a36509626.tar.gz |
PR sanitizer/64344
* ubsan.h (ubsan_instrument_float_cast): Add ARG argument.
* ubsan.c (ubsan_instrument_float_cast): Add ARG argument, pass
it to libubsan handler instead of EXPR. Fold comparisons earlier,
if the result is integer_zerop, return NULL_TREE.
* convert.c (convert_to_integer): Pass expr as ARG.
c/
* c-typeck.c (convert_for_assignment, c_finish_return): For
-fsanitize=float-cast-overflow casts from REAL_TYPE to integer/enum
types also set in_late_binary_op around convert call.
* c-convert.c (convert): For -fsanitize=float-cast-overflow REAL_TYPE
to integral type casts, if not in_late_binary_op, pass c_fully_fold
result on expr as last argument to ubsan_instrument_float_cast,
if in_late_binary_op, don't use c_save_expr but save_expr.
testsuite/
* c-c++-common/ubsan/pr64344-1.c: New test.
* c-c++-common/ubsan/pr64344-2.c: New test.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@219201 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/c')
-rw-r--r-- | gcc/c/ChangeLog | 9 | ||||
-rw-r--r-- | gcc/c/c-convert.c | 14 | ||||
-rw-r--r-- | gcc/c/c-typeck.c | 14 |
3 files changed, 31 insertions, 6 deletions
diff --git a/gcc/c/ChangeLog b/gcc/c/ChangeLog index 3e5b6703c17..d6b228902f9 100644 --- a/gcc/c/ChangeLog +++ b/gcc/c/ChangeLog @@ -1,5 +1,14 @@ 2015-01-05 Jakub Jelinek <jakub@redhat.com> + PR sanitizer/64344 + * c-typeck.c (convert_for_assignment, c_finish_return): For + -fsanitize=float-cast-overflow casts from REAL_TYPE to integer/enum + types also set in_late_binary_op around convert call. + * c-convert.c (convert): For -fsanitize=float-cast-overflow REAL_TYPE + to integral type casts, if not in_late_binary_op, pass c_fully_fold + result on expr as last argument to ubsan_instrument_float_cast, + if in_late_binary_op, don't use c_save_expr but save_expr. + Update copyright years. 2015-01-05 Marek Polacek <polacek@redhat.com> diff --git a/gcc/c/c-convert.c b/gcc/c/c-convert.c index cd78085f7c4..c0da134ee80 100644 --- a/gcc/c/c-convert.c +++ b/gcc/c/c-convert.c @@ -117,8 +117,18 @@ convert (tree type, tree expr) && !lookup_attribute ("no_sanitize_undefined", DECL_ATTRIBUTES (current_function_decl))) { - expr = c_save_expr (expr); - tree check = ubsan_instrument_float_cast (loc, type, expr); + tree arg; + if (in_late_binary_op) + { + expr = save_expr (expr); + arg = expr; + } + else + { + expr = c_save_expr (expr); + arg = c_fully_fold (expr, false, NULL); + } + tree check = ubsan_instrument_float_cast (loc, type, expr, arg); expr = fold_build1 (FIX_TRUNC_EXPR, type, expr); if (check == NULL) return expr; diff --git a/gcc/c/c-typeck.c b/gcc/c/c-typeck.c index 04dcfd3fd8f..0db43cc1b63 100644 --- a/gcc/c/c-typeck.c +++ b/gcc/c/c-typeck.c @@ -5885,12 +5885,14 @@ convert_for_assignment (location_t location, location_t expr_loc, tree type, { tree ret; bool save = in_late_binary_op; - if (codel == BOOLEAN_TYPE || codel == COMPLEX_TYPE) + if (codel == BOOLEAN_TYPE || codel == COMPLEX_TYPE + || (coder == REAL_TYPE + && (codel == INTEGER_TYPE || codel == ENUMERAL_TYPE) + && (flag_sanitize & SANITIZE_FLOAT_CAST))) in_late_binary_op = true; ret = convert_and_check (expr_loc != UNKNOWN_LOCATION ? expr_loc : location, type, orig_rhs); - if (codel == BOOLEAN_TYPE || codel == COMPLEX_TYPE) - in_late_binary_op = save; + in_late_binary_op = save; return ret; } @@ -9369,7 +9371,11 @@ c_finish_return (location_t loc, tree retval, tree origtype) save = in_late_binary_op; if (TREE_CODE (TREE_TYPE (res)) == BOOLEAN_TYPE - || TREE_CODE (TREE_TYPE (res)) == COMPLEX_TYPE) + || TREE_CODE (TREE_TYPE (res)) == COMPLEX_TYPE + || (TREE_CODE (TREE_TYPE (t)) == REAL_TYPE + && (TREE_CODE (TREE_TYPE (res)) == INTEGER_TYPE + || TREE_CODE (TREE_TYPE (res)) == ENUMERAL_TYPE) + && (flag_sanitize & SANITIZE_FLOAT_CAST))) in_late_binary_op = true; inner = t = convert (TREE_TYPE (res), t); in_late_binary_op = save; |