summaryrefslogtreecommitdiff
path: root/gcc/c
diff options
context:
space:
mode:
authorjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>2015-01-05 21:46:31 +0000
committerjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>2015-01-05 21:46:31 +0000
commit823a9dd48593c13a959d2bcf2635b48a36509626 (patch)
tree0fb2cd367e6916c7cd83f6635fec9facebcc58a5 /gcc/c
parentd8a5b68899bb4013ddc0e62e73dbc97aedef0067 (diff)
downloadgcc-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/ChangeLog9
-rw-r--r--gcc/c/c-convert.c14
-rw-r--r--gcc/c/c-typeck.c14
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;