re PR sanitizer/63520 (ICE: in get_biv_step, at loop-iv.c:824 with -fsanitize=undefin...
authorJakub Jelinek <jakub@redhat.com>
Wed, 19 Nov 2014 09:49:18 +0000 (10:49 +0100)
committerJakub Jelinek <jakub@gcc.gnu.org>
Wed, 19 Nov 2014 09:49:18 +0000 (10:49 +0100)
PR sanitizer/63520
* internal-fn.c (expand_ubsan_result_store): New function.
(expand_addsub_overflow, expand_neg_overflow, expand_mul_overflow):
Use it instead of just emit_move_insn.

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

From-SVN: r217758

gcc/ChangeLog
gcc/internal-fn.c
gcc/testsuite/ChangeLog
gcc/testsuite/c-c++-common/ubsan/pr63520.c [new file with mode: 0644]

index 172822d3a60fac221bccaa777c91f4614341cb63..eeae399a676bc2cbc5d689a536ec83d5afc8bd59 100644 (file)
@@ -1,3 +1,10 @@
+2014-11-19  Jakub Jelinek  <jakub@redhat.com>
+
+       PR sanitizer/63520
+       * internal-fn.c (expand_ubsan_result_store): New function.
+       (expand_addsub_overflow, expand_neg_overflow, expand_mul_overflow):
+       Use it instead of just emit_move_insn.
+
 2014-11-19  Richard Biener  <rguenther@suse.de>
 
        PR tree-optimization/63844
index 073d941d8ce5d3de6613e2ca2b8893ec76346f00..0cb15b23ff19f22bd5bed5dbbe645afce253f58b 100644 (file)
@@ -395,6 +395,21 @@ expand_arith_overflow_result_store (tree lhs, rtx target,
   write_complex_part (target, lres, false);
 }
 
+/* Helper for expand_*_overflow.  Store RES into TARGET.  */
+
+static void
+expand_ubsan_result_store (rtx target, rtx res)
+{
+  if (GET_CODE (target) == SUBREG && SUBREG_PROMOTED_VAR_P (target))
+    /* If this is a scalar in a register that is stored in a wider mode   
+       than the declared mode, compute the result into its declared mode
+       and then convert to the wider mode.  Our value is the computed
+       expression.  */
+    convert_move (SUBREG_REG (target), res, SUBREG_PROMOTED_SIGN (target));
+  else
+    emit_move_insn (target, res);
+}
+
 /* Add sub/add overflow checking to the statement STMT.
    CODE says whether the operation is +, or -.  */
 
@@ -809,7 +824,7 @@ expand_addsub_overflow (location_t loc, tree_code code, tree lhs,
   if (lhs)
     {
       if (is_ubsan)
-       emit_move_insn (target, res);
+       expand_ubsan_result_store (target, res);
       else
        {
          if (do_xor)
@@ -904,7 +919,7 @@ expand_neg_overflow (location_t loc, tree lhs, tree arg1, bool is_ubsan)
   if (lhs)
     {
       if (is_ubsan)
-       emit_move_insn (target, res);
+       expand_ubsan_result_store (target, res);
       else
        expand_arith_overflow_result_store (lhs, target, mode, res);
     }
@@ -1590,7 +1605,7 @@ expand_mul_overflow (location_t loc, tree lhs, tree arg0, tree arg1,
   if (lhs)
     {
       if (is_ubsan)
-       emit_move_insn (target, res);
+       expand_ubsan_result_store (target, res);
       else
        expand_arith_overflow_result_store (lhs, target, mode, res);
     }
index c42d725b3e87f47d7d38be5829e2e39d4f1ebe25..c69393c9e9213ec2dcad95826bc749cf3deed1d1 100644 (file)
@@ -1,3 +1,8 @@
+2014-11-19  Jakub Jelinek  <jakub@redhat.com>
+
+       PR sanitizer/63520
+       * c-c++-common/ubsan/pr63520.c: New test.
+
 2014-11-19  Paolo Carlini  <paolo.carlini@oracle.com>
 
        PR c++/57654
diff --git a/gcc/testsuite/c-c++-common/ubsan/pr63520.c b/gcc/testsuite/c-c++-common/ubsan/pr63520.c
new file mode 100644 (file)
index 0000000..66da668
--- /dev/null
@@ -0,0 +1,16 @@
+/* PR sanitizer/63520 */
+/* { dg-do compile } */
+/* { dg-options "-fsanitize=undefined" } */
+
+int a;
+
+void
+foo (void)
+{
+  while (1)
+    {
+      if (a == 1)
+       break;
+      a -= 1;
+    }
+}