From dcf70cb0d85d04ff680a361e32d79c326ae8b3fc Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Fri, 1 Oct 2021 14:27:32 +0200 Subject: [PATCH] ubsan: Use -fno{,-}sanitize=float-divide-by-zero for float division by zero recovery [PR102515] We've been using -f{,no-}sanitize-recover=integer-divide-by-zero to decide on the float -fsanitize=float-divide-by-zero instrumentation _abort suffix. This patch fixes it to use -f{,no-}sanitize-recover=float-divide-by-zero for it instead. 2021-10-01 Jakub Jelinek Richard Biener PR sanitizer/102515 gcc/c-family/ * c-ubsan.c (ubsan_instrument_division): Check the right flag_sanitize_recover bit, depending on which sanitization is done. gcc/testsuite/ * c-c++-common/ubsan/float-div-by-zero-2.c: New test. (cherry picked from commit 9c1a633d96926357155d4702b66f8a0ec856a81f) --- gcc/c-family/c-ubsan.c | 10 +++++++--- .../c-c++-common/ubsan/float-div-by-zero-2.c | 18 ++++++++++++++++++ 2 files changed, 25 insertions(+), 3 deletions(-) create mode 100644 gcc/testsuite/c-c++-common/ubsan/float-div-by-zero-2.c diff --git a/gcc/c-family/c-ubsan.c b/gcc/c-family/c-ubsan.c index 12a7bca5c32e..8f831961e0d9 100644 --- a/gcc/c-family/c-ubsan.c +++ b/gcc/c-family/c-ubsan.c @@ -41,6 +41,7 @@ ubsan_instrument_division (location_t loc, tree op0, tree op1) { tree t, tt; tree type = TREE_TYPE (op0); + enum sanitize_code flag = SANITIZE_DIVIDE; /* At this point both operands should have the same type, because they are already converted to RESULT_TYPE. @@ -58,8 +59,11 @@ ubsan_instrument_division (location_t loc, tree op0, tree op1) op1, build_int_cst (type, 0)); else if (TREE_CODE (type) == REAL_TYPE && sanitize_flags_p (SANITIZE_FLOAT_DIVIDE)) - t = fold_build2 (EQ_EXPR, boolean_type_node, - op1, build_real (type, dconst0)); + { + t = fold_build2 (EQ_EXPR, boolean_type_node, + op1, build_real (type, dconst0)); + flag = SANITIZE_FLOAT_DIVIDE; + } else return NULL_TREE; @@ -95,7 +99,7 @@ ubsan_instrument_division (location_t loc, tree op0, tree op1) NULL_TREE); data = build_fold_addr_expr_loc (loc, data); enum built_in_function bcode - = (flag_sanitize_recover & SANITIZE_DIVIDE) + = (flag_sanitize_recover & flag) ? BUILT_IN_UBSAN_HANDLE_DIVREM_OVERFLOW : BUILT_IN_UBSAN_HANDLE_DIVREM_OVERFLOW_ABORT; tt = builtin_decl_explicit (bcode); diff --git a/gcc/testsuite/c-c++-common/ubsan/float-div-by-zero-2.c b/gcc/testsuite/c-c++-common/ubsan/float-div-by-zero-2.c new file mode 100644 index 000000000000..61d050ae23be --- /dev/null +++ b/gcc/testsuite/c-c++-common/ubsan/float-div-by-zero-2.c @@ -0,0 +1,18 @@ +/* { dg-do run } */ +/* { dg-shouldfail "ubsan" } */ +/* { dg-options "-fsanitize=float-divide-by-zero -fno-sanitize-recover=float-divide-by-zero -fsanitize-recover=integer-divide-by-zero" } */ + +int +main (void) +{ + volatile float a = 1.3f; + volatile double b = 0.0; + volatile int c = 4; + volatile float res; + + res = a / b; + + return 0; +} + +/* { dg-output "division by zero" } */ -- 2.47.2