re PR sanitizer/64289 (ICE with -fsanitize=float-cast-overflow)
authorJakub Jelinek <jakub@redhat.com>
Wed, 17 Dec 2014 09:26:49 +0000 (10:26 +0100)
committerJakub Jelinek <jakub@gcc.gnu.org>
Wed, 17 Dec 2014 09:26:49 +0000 (10:26 +0100)
PR sanitizer/64289
* c-convert.c: Include ubsan.h.
(convert): For real -> integral casts and
-fsanitize=float-cast-overflow don't call convert_to_integer, but
instead instrument the float cast directly.

* c-c++-common/ubsan/pr64289.c: New test.

From-SVN: r218811

gcc/c/ChangeLog
gcc/c/c-convert.c
gcc/testsuite/ChangeLog
gcc/testsuite/c-c++-common/ubsan/pr64289.c [new file with mode: 0644]

index cef3aa186878652f01d3bb00a43f045636eec5c8..ad9b8bc156fb2108b2f97065dce017812618a6a7 100644 (file)
@@ -1,3 +1,11 @@
+2014-12-17  Jakub Jelinek  <jakub@redhat.com>
+
+       PR sanitizer/64289
+       * c-convert.c: Include ubsan.h.
+       (convert): For real -> integral casts and
+       -fsanitize=float-cast-overflow don't call convert_to_integer, but
+       instead instrument the float cast directly.
+
 2014-11-29  Jakub Jelinek  <jakub@redhat.com>
 
        * c-typeck.c (convert_lvalue_to_rvalue, build_atomic_assign,
index 95be453fa3fc619253d9f78d9e501cace0a4a2b2..ba565da12188f1e288019a5976779edc32f2e6ce 100644 (file)
@@ -34,6 +34,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "c-tree.h"
 #include "langhooks.h"
 #include "target.h"
+#include "ubsan.h"
 
 /* Change of width--truncation and extension of integers or reals--
    is represented with NOP_EXPR.  Proper functioning of many things
@@ -109,6 +110,20 @@ convert (tree type, tree expr)
 
     case INTEGER_TYPE:
     case ENUMERAL_TYPE:
+      if (flag_sanitize & SANITIZE_FLOAT_CAST
+         && TREE_CODE (TREE_TYPE (expr)) == REAL_TYPE
+         && COMPLETE_TYPE_P (type)
+         && current_function_decl != NULL_TREE
+         && !lookup_attribute ("no_sanitize_undefined",
+                               DECL_ATTRIBUTES (current_function_decl)))
+       {
+         expr = c_save_expr (expr);
+         tree check = ubsan_instrument_float_cast (loc, type, expr);
+         expr = fold_build1 (FIX_TRUNC_EXPR, type, expr);
+         if (check == NULL)
+           return expr;
+         return fold_build2 (COMPOUND_EXPR, TREE_TYPE (expr), check, expr);
+       }
       ret = convert_to_integer (type, e);
       goto maybe_fold;
 
index e896b0b73ce145269b776b958423f81d6437ef3b..9f6fd3147472150117e97d07ebb3157ebd153d00 100644 (file)
@@ -1,3 +1,8 @@
+2014-12-17  Jakub Jelinek  <jakub@redhat.com>
+
+       PR sanitizer/64289
+       * c-c++-common/ubsan/pr64289.c: New test.
+
 2014-12-16  Paolo Carlini  <paolo.carlini@oracle.com>
 
        PR c++/58650
diff --git a/gcc/testsuite/c-c++-common/ubsan/pr64289.c b/gcc/testsuite/c-c++-common/ubsan/pr64289.c
new file mode 100644 (file)
index 0000000..1e38e6d
--- /dev/null
@@ -0,0 +1,9 @@
+/* PR sanitizer/64289 */
+/* { dg-do compile } */
+/* { dg-options "-fsanitize=float-cast-overflow" } */
+
+int
+foo (int a)
+{
+  return (int) (0 ? 0 : a ? a : 0.5);
+}