From 267b63546a637da74bc7f024ebdc2ce76d353de8 Mon Sep 17 00:00:00 2001 From: Mikhail Kashkarov Date: Thu, 19 Sep 2019 16:29:10 +0300 Subject: [PATCH] Handle instrumented expr for unsigned-integer-overflow 2019-09-19 Mikhail Kashkarov c-family/ * c-ubsan.c (ubsan_compound_instrumented_expr_p): New function. * c-ubsan.h (ubsan_compound_instrumented_expr_p): New prototype. c/ * c-typeck.c (build_binary_op): Handle instrumented expr for SANITIZE_UI_OVERFLOW. cp/ * typeck.c (cp_build_binary_op): Same. testsuite/ * c-c++-common/isan/invalid-ui-oveflow-1.c: New testcase. Change-Id: I8e0fbf443da866bf8756d848fd7bf2ab7e858f06 --- gcc/c-family/c-ubsan.c | 12 ++++++++++++ gcc/c-family/c-ubsan.h | 1 + gcc/c/c-typeck.c | 3 ++- gcc/cp/typeck.c | 3 ++- .../c-c++-common/isan/invalid-ui-oveflow-1.c | 19 +++++++++++++++++++ 5 files changed, 36 insertions(+), 2 deletions(-) create mode 100644 gcc/testsuite/c-c++-common/isan/invalid-ui-oveflow-1.c diff --git a/gcc/c-family/c-ubsan.c b/gcc/c-family/c-ubsan.c index 82ecc5b..b573040 100644 --- a/gcc/c-family/c-ubsan.c +++ b/gcc/c-family/c-ubsan.c @@ -332,6 +332,18 @@ ubsan_array_ref_instrumented_p (const_tree t) && CALL_EXPR_IFN (TREE_OPERAND (op1, 0)) == IFN_UBSAN_BOUNDS; } +/* Return true iff t is COND_EXPR with arg 2 == VOID_CST. */ + +bool +ubsan_compound_instrumented_expr_p (const_tree t) +{ + if (TREE_CODE (t) != COND_EXPR) + return false; + + return TREE_CODE (TREE_OPERAND (t, 1)) == CALL_EXPR + && TREE_CODE (TREE_OPERAND (t, 2)) == VOID_CST; +} + /* Instrument an ARRAY_REF, if it hasn't already been instrumented. IGNORE_OFF_BY_ONE is true if the ARRAY_REF is inside a ADDR_EXPR. */ diff --git a/gcc/c-family/c-ubsan.h b/gcc/c-family/c-ubsan.h index a8202c0..42b7953 100644 --- a/gcc/c-family/c-ubsan.h +++ b/gcc/c-family/c-ubsan.h @@ -29,6 +29,7 @@ extern tree ubsan_instrument_vla (location_t, tree); extern tree ubsan_instrument_return (location_t); extern tree ubsan_instrument_bounds (location_t, tree, tree *, bool); extern bool ubsan_array_ref_instrumented_p (const_tree); +extern bool ubsan_compound_instrumented_expr_p (const_tree); extern void ubsan_maybe_instrument_array_ref (tree *, bool); extern void ubsan_maybe_instrument_reference (tree); extern void ubsan_maybe_instrument_member_call (tree, bool); diff --git a/gcc/c/c-typeck.c b/gcc/c/c-typeck.c index a4003cf..e4e4980 100644 --- a/gcc/c/c-typeck.c +++ b/gcc/c/c-typeck.c @@ -11688,7 +11688,8 @@ build_binary_op (location_t location, enum tree_code code, if (instrument_expr != NULL) { - if (flag_sanitize & SANITIZE_UI_OVERFLOW) + if ((flag_sanitize & SANITIZE_UI_OVERFLOW) + && !ubsan_compound_instrumented_expr_p (instrument_expr)) { /* Inherit side effects. TODO: what another attributes should be inherited? */ diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index 669c03f..bd90180 100644 --- a/gcc/cp/typeck.c +++ b/gcc/cp/typeck.c @@ -5186,7 +5186,8 @@ cp_build_binary_op (location_t location, if (instrument_expr != NULL) { - if (flag_sanitize & SANITIZE_UI_OVERFLOW) + if ((flag_sanitize & SANITIZE_UI_OVERFLOW) + && !ubsan_compound_instrumented_expr_p (instrument_expr)) { /* Inherit side effects. TODO: what another attributes should be inherited? */ diff --git a/gcc/testsuite/c-c++-common/isan/invalid-ui-oveflow-1.c b/gcc/testsuite/c-c++-common/isan/invalid-ui-oveflow-1.c new file mode 100644 index 0000000..a8e9d35 --- /dev/null +++ b/gcc/testsuite/c-c++-common/isan/invalid-ui-oveflow-1.c @@ -0,0 +1,19 @@ +/* { dg-do compile } */ +/* { dg-options "-fsyntax-only -fsanitize=shift,unsigned-integer-overflow" } */ + +#define CHECK_UI(type) \ +type foo_##type (type n) \ + { \ + type x = n; \ + x <<= n; \ + return x << n; \ +} + +typedef unsigned int uint ; +typedef unsigned int ulong ; + +/* Both singed and unsigned were affected. */ +CHECK_UI(int); +CHECK_UI(uint); +CHECK_UI(long); +CHECK_UI(ulong); -- 2.7.4