]> gcc.gnu.org Git - gcc.git/commitdiff
re PR sanitizer/64344 ([UBSAN] ICE with -fsanitize=float-cast-overflow [ICE in -fsani...
authorJakub Jelinek <jakub@redhat.com>
Mon, 5 Jan 2015 21:46:31 +0000 (22:46 +0100)
committerJakub Jelinek <jakub@gcc.gnu.org>
Mon, 5 Jan 2015 21:46:31 +0000 (22:46 +0100)
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.

From-SVN: r219201

gcc/ChangeLog
gcc/c/ChangeLog
gcc/c/c-convert.c
gcc/c/c-typeck.c
gcc/convert.c
gcc/testsuite/ChangeLog
gcc/testsuite/c-c++-common/ubsan/pr64344-1.c [new file with mode: 0644]
gcc/testsuite/c-c++-common/ubsan/pr64344-2.c [new file with mode: 0644]
gcc/ubsan.c
gcc/ubsan.h

index 0557edd8192bd4a453bba993e4aea31e1be2b390..f62aed21f046c5b200c41ecc0d50bf7dc0269290 100644 (file)
@@ -1,5 +1,12 @@
 2015-01-05  Jakub Jelinek  <jakub@redhat.com>
 
+       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.
+
        PR tree-optimization/64465
        * tree-inline.c (redirect_all_calls): During inlining
        clean up EH stmts and EH edges if redirect_call_stmt_to_callee
index 3e5b6703c17ecb11e87d081271c0c8f43a703f08..d6b228902f95bf5a21d841d2fce8e50ef0218a0f 100644 (file)
@@ -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>
index cd78085f7c45efaa6d68236e4aedef9420cbd3ed..c0da134ee80377c56220ab3a856ba5008fb5da98 100644 (file)
@@ -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;
index 04dcfd3fd8f33872db6f4b69f881b38e249e75a1..0db43cc1b63226d1e90e5f7e100d5e314e63d658 100644 (file)
@@ -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;
index c65d013f19d205fcb6788bb9e79ba883c6f1dfef..0491986bd1e375969d48a70a7b71edec01af288d 100644 (file)
@@ -890,7 +890,7 @@ convert_to_integer (tree type, tree expr)
                                DECL_ATTRIBUTES (current_function_decl)))
        {
          expr = save_expr (expr);
-         tree check = ubsan_instrument_float_cast (loc, type, expr);
+         tree check = ubsan_instrument_float_cast (loc, type, expr, expr);
          expr = build1 (FIX_TRUNC_EXPR, type, expr);
          if (check == NULL)
            return expr;
index cda42315f1680859f9de88bf727ad801c100d9af..8633d7e7699e0b6a3a5177d7ed29edc066fc056a 100644 (file)
@@ -1,5 +1,9 @@
 2015-01-05  Jakub Jelinek  <jakub@redhat.com>
 
+       PR sanitizer/64344
+       * c-c++-common/ubsan/pr64344-1.c: New test.
+       * c-c++-common/ubsan/pr64344-2.c: New test.
+
        PR tree-optimization/64465
        * gcc.dg/pr64465.c: New test.
 
diff --git a/gcc/testsuite/c-c++-common/ubsan/pr64344-1.c b/gcc/testsuite/c-c++-common/ubsan/pr64344-1.c
new file mode 100644 (file)
index 0000000..4891beb
--- /dev/null
@@ -0,0 +1,9 @@
+/* PR sanitizer/64344 */
+/* { dg-do compile } */
+/* { dg-options "-fsanitize=float-cast-overflow" } */
+
+int
+foo (float x)
+{
+  return __builtin_log ((double ) x);
+}
diff --git a/gcc/testsuite/c-c++-common/ubsan/pr64344-2.c b/gcc/testsuite/c-c++-common/ubsan/pr64344-2.c
new file mode 100644 (file)
index 0000000..9d1eafd
--- /dev/null
@@ -0,0 +1,11 @@
+/* PR sanitizer/64344 */
+/* { dg-do compile } */
+/* { dg-options "-fsanitize=float-cast-overflow" } */
+
+int
+foo (void)
+{
+  static const int a = 0.5;
+  static const int b = (int) 13.5 + 1;
+  return a + b;
+}
index f9979fc706d965a6ccbe21fad731caac092f749f..5c9355aacb821fcfa33e4ba84474f7891686c783 100644 (file)
@@ -1252,10 +1252,11 @@ instrument_bool_enum_load (gimple_stmt_iterator *gsi)
 }
 
 /* Instrument float point-to-integer conversion.  TYPE is an integer type of
-   destination, EXPR is floating-point expression.  */
+   destination, EXPR is floating-point expression.  ARG is what to pass
+   the libubsan call as value, often EXPR itself.  */
 
 tree
-ubsan_instrument_float_cast (location_t loc, tree type, tree expr)
+ubsan_instrument_float_cast (location_t loc, tree type, tree expr, tree arg)
 {
   tree expr_type = TREE_TYPE (expr);
   tree t, tt, fn, min, max;
@@ -1348,6 +1349,12 @@ ubsan_instrument_float_cast (location_t loc, tree type, tree expr)
   else
     return NULL_TREE;
 
+  t = fold_build2 (UNLE_EXPR, boolean_type_node, expr, min);
+  tt = fold_build2 (UNGE_EXPR, boolean_type_node, expr, max);
+  t = fold_build2 (TRUTH_OR_EXPR, boolean_type_node, t, tt);
+  if (integer_zerop (t))
+    return NULL_TREE;
+
   if (flag_sanitize_undefined_trap_on_error)
     fn = build_call_expr_loc (loc, builtin_decl_explicit (BUILT_IN_TRAP), 0);
   else
@@ -1364,14 +1371,10 @@ ubsan_instrument_float_cast (location_t loc, tree type, tree expr)
       fn = builtin_decl_explicit (bcode);
       fn = build_call_expr_loc (loc, fn, 2,
                                build_fold_addr_expr_loc (loc, data),
-                               ubsan_encode_value (expr, false));
+                               ubsan_encode_value (arg, false));
     }
 
-  t = fold_build2 (UNLE_EXPR, boolean_type_node, expr, min);
-  tt = fold_build2 (UNGE_EXPR, boolean_type_node, expr, max);
-  return fold_build3 (COND_EXPR, void_type_node,
-                     fold_build2 (TRUTH_OR_EXPR, boolean_type_node, t, tt),
-                     fn, integer_zero_node);
+  return fold_build3 (COND_EXPR, void_type_node, t, fn, integer_zero_node);
 }
 
 /* Instrument values passed to function arguments with nonnull attribute.  */
index 453a9eafab7da82d2dcac7ae85aad8adbc42214a..5d9d90933a262e7131daedb6610f46827e961a31 100644 (file)
@@ -47,7 +47,7 @@ extern tree ubsan_type_descriptor (tree, enum ubsan_print_style = UBSAN_PRINT_NO
 extern tree ubsan_encode_value (tree, bool = false);
 extern bool is_ubsan_builtin_p (tree);
 extern tree ubsan_build_overflow_builtin (tree_code, location_t, tree, tree, tree);
-extern tree ubsan_instrument_float_cast (location_t, tree, tree);
+extern tree ubsan_instrument_float_cast (location_t, tree, tree, tree);
 extern tree ubsan_get_source_location_type (void);
 
 #endif  /* GCC_UBSAN_H  */
This page took 0.084487 seconds and 5 git commands to generate.