Handle instrumented expr for unsigned-integer-overflow 77/214277/4
authorMikhail Kashkarov <m.kashkarov@partner.samsung.com>
Thu, 19 Sep 2019 13:29:10 +0000 (16:29 +0300)
committerDongkyun Son <dongkyun.s@samsung.com>
Wed, 25 Sep 2019 03:50:32 +0000 (03:50 +0000)
2019-09-19  Mikhail Kashkarov  <m.kashkarov@partner.samsung.com>
    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
gcc/c-family/c-ubsan.h
gcc/c/c-typeck.c
gcc/cp/typeck.c
gcc/testsuite/c-c++-common/isan/invalid-ui-oveflow-1.c [new file with mode: 0644]

index 82ecc5b..b573040 100644 (file)
@@ -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.  */
 
index a8202c0..42b7953 100644 (file)
@@ -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);
index a4003cf..e4e4980 100644 (file)
@@ -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?  */
index 669c03f..bd90180 100644 (file)
@@ -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 (file)
index 0000000..a8e9d35
--- /dev/null
@@ -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);