re PR sanitizer/59333 (ICE with long long and -m32 -fsanitize=undefined)
authorMarek Polacek <polacek@redhat.com>
Thu, 5 Dec 2013 18:03:44 +0000 (18:03 +0000)
committerMarek Polacek <mpolacek@gcc.gnu.org>
Thu, 5 Dec 2013 18:03:44 +0000 (18:03 +0000)
PR sanitizer/59333
PR sanitizer/59397
* ubsan.c: Include rtl.h and expr.h.
(ubsan_encode_value): Add new parameter.  If expanding, assign
a stack slot for DECL_RTL of the temporary and call expand_assignment.
Handle BOOLEAN_TYPE and ENUMERAL_TYPE.
(ubsan_build_overflow_builtin): Adjust ubsan_encode_value call.
* ubsan.h (ubsan_encode_value): Adjust declaration.
* internal-fn.c (ubsan_expand_si_overflow_addsub_check): Move
ubsan_build_overflow_builtin above expand_normal call.  Surround this call
with push_temp_slots and pop_temp_slots.
(ubsan_expand_si_overflow_neg_check): Likewise.
(ubsan_expand_si_overflow_mul_check): Likewise.
testsuite/
* c-c++-common/ubsan/pr59333.c: New test.
* c-c++-common/ubsan/pr59397.c: New test.

From-SVN: r205714

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

index 58f9782598bb350c64517e7f3c23d44134e9f6c6..55757a06caf59eb532af51d62dcd8829e41f963c 100644 (file)
@@ -1,3 +1,19 @@
+2013-12-05  Marek Polacek  <polacek@redhat.com>
+
+       PR sanitizer/59333
+       PR sanitizer/59397
+       * ubsan.c: Include rtl.h and expr.h.
+       (ubsan_encode_value): Add new parameter.  If expanding, assign
+       a stack slot for DECL_RTL of the temporary and call expand_assignment.
+       Handle BOOLEAN_TYPE and ENUMERAL_TYPE.
+       (ubsan_build_overflow_builtin): Adjust ubsan_encode_value call.
+       * ubsan.h (ubsan_encode_value): Adjust declaration.
+       * internal-fn.c (ubsan_expand_si_overflow_addsub_check): Move
+       ubsan_build_overflow_builtin above expand_normal call.  Surround this call
+       with push_temp_slots and pop_temp_slots.
+       (ubsan_expand_si_overflow_neg_check): Likewise.
+       (ubsan_expand_si_overflow_mul_check): Likewise.
+
 2013-12-05  Yufeng Zhang  <yufeng.zhang@arm.com>
 
        * gimple-ssa-strength-reduction.c (find_basis_for_candidate): Guard
index 527b5ffaf7f8b973e7eadb44983f1ca732ff8e8f..fb1e5784b15bb472b71bc948cd6ad83d0f379440 100644 (file)
@@ -171,8 +171,6 @@ ubsan_expand_si_overflow_addsub_check (tree_code code, gimple stmt)
   arg1 = gimple_call_arg (stmt, 1);
   done_label = gen_label_rtx ();
   do_error = gen_label_rtx ();
-  fn = ubsan_build_overflow_builtin (code, gimple_location (stmt),
-                                    TREE_TYPE (arg0), arg0, arg1);
   do_pending_stack_adjust ();
   op0 = expand_normal (arg0);
   op1 = expand_normal (arg1);
@@ -237,13 +235,17 @@ ubsan_expand_si_overflow_addsub_check (tree_code code, gimple stmt)
                               PROB_VERY_LIKELY);
     }
 
-   emit_label (do_error);
-   /* Expand the ubsan builtin call.  */
-   expand_normal (fn);
-   do_pending_stack_adjust ();
+  emit_label (do_error);
+  /* Expand the ubsan builtin call.  */
+  push_temp_slots ();
+  fn = ubsan_build_overflow_builtin (code, gimple_location (stmt),
+                                    TREE_TYPE (arg0), arg0, arg1);
+  expand_normal (fn);
+  pop_temp_slots ();
+  do_pending_stack_adjust ();
 
-   /* We're done.  */
-   emit_label (done_label);
+  /* We're done.  */
+  emit_label (done_label);
 
   if (lhs)
     emit_move_insn (target, res);
@@ -262,8 +264,6 @@ ubsan_expand_si_overflow_neg_check (gimple stmt)
   arg1 = gimple_call_arg (stmt, 1);
   done_label = gen_label_rtx ();
   do_error = gen_label_rtx ();
-  fn = ubsan_build_overflow_builtin (NEGATE_EXPR, gimple_location (stmt),
-                                    TREE_TYPE (arg1), arg1, NULL_TREE);
 
   do_pending_stack_adjust ();
   op1 = expand_normal (arg1);
@@ -313,7 +313,11 @@ ubsan_expand_si_overflow_neg_check (gimple stmt)
 
   emit_label (do_error);
   /* Expand the ubsan builtin call.  */
+  push_temp_slots ();
+  fn = ubsan_build_overflow_builtin (NEGATE_EXPR, gimple_location (stmt),
+                                    TREE_TYPE (arg1), arg1, NULL_TREE);
   expand_normal (fn);
+  pop_temp_slots ();
   do_pending_stack_adjust ();
 
   /* We're done.  */
@@ -337,8 +341,6 @@ ubsan_expand_si_overflow_mul_check (gimple stmt)
   arg1 = gimple_call_arg (stmt, 1);
   done_label = gen_label_rtx ();
   do_error = gen_label_rtx ();
-  fn = ubsan_build_overflow_builtin (MULT_EXPR, gimple_location (stmt),
-                                    TREE_TYPE (arg0), arg0, arg1);
 
   do_pending_stack_adjust ();
   op0 = expand_normal (arg0);
@@ -418,7 +420,11 @@ ubsan_expand_si_overflow_mul_check (gimple stmt)
 
   emit_label (do_error);
   /* Expand the ubsan builtin call.  */
+  push_temp_slots ();
+  fn = ubsan_build_overflow_builtin (MULT_EXPR, gimple_location (stmt),
+                                    TREE_TYPE (arg0), arg0, arg1);
   expand_normal (fn);
+  pop_temp_slots ();
   do_pending_stack_adjust ();
 
   /* We're done.  */
index d9f7de3a38df87d7dd432baac2099c248937fd03..62010b269a420c49b9f8212e35598c5179a46fd7 100644 (file)
@@ -1,3 +1,10 @@
+2013-12-05  Marek Polacek  <polacek@redhat.com>
+
+       PR sanitizer/59333
+       PR sanitizer/59397
+       * c-c++-common/ubsan/pr59333.c: New test.
+       * c-c++-common/ubsan/pr59397.c: New test.
+
 2013-12-05  Tejas Belagod  <tejas.belagod@arm.com>
 
        * gcc.dg/vect/vect-nop-move.c: New test.
diff --git a/gcc/testsuite/c-c++-common/ubsan/pr59333.c b/gcc/testsuite/c-c++-common/ubsan/pr59333.c
new file mode 100644 (file)
index 0000000..af53920
--- /dev/null
@@ -0,0 +1,19 @@
+/* { dg-do run } */
+/* { dg-options "-fsanitize=undefined" } */
+/* { dg-skip-if "" { *-*-* } { "-flto" } { "" } } */
+
+long long int __attribute__ ((noinline, noclone))
+foo (long long int i, long long int j)
+{
+  asm ("");
+  return i + j;
+}
+
+int
+main (void)
+{
+  foo (2LL, __LONG_LONG_MAX__);
+  return 0;
+}
+
+/* { dg-output "signed integer overflow: 2 \\+ 9223372036854775807 cannot be represented in type 'long long int'(\n|\r\n|\r)" } */
diff --git a/gcc/testsuite/c-c++-common/ubsan/pr59397.c b/gcc/testsuite/c-c++-common/ubsan/pr59397.c
new file mode 100644 (file)
index 0000000..0de0258
--- /dev/null
@@ -0,0 +1,10 @@
+/* { dg-do compile } */
+/* { dg-options "-fsanitize=signed-integer-overflow" } */
+
+typedef enum E { A = -1 } e;
+int
+foo (void)
+{
+  e e = A;
+  return e + 1;
+}
index aaf74acb546e3bb6ea9198d5bbecf6f978853353..846e884de52f440006665638726fbd54f71b3f6f 100644 (file)
@@ -27,6 +27,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "cgraph.h"
 #include "tree-pass.h"
 #include "tree-ssa-alias.h"
+#include "tree-pretty-print.h"
 #include "internal-fn.h"
 #include "gimple-expr.h"
 #include "gimple.h"
@@ -40,6 +41,8 @@ along with GCC; see the file COPYING3.  If not see
 #include "cfgloop.h"
 #include "ubsan.h"
 #include "c-family/c-common.h"
+#include "rtl.h"
+#include "expr.h"
 
 /* Map from a tree to a VAR_DECL tree.  */
 
@@ -102,45 +105,53 @@ decl_for_type_insert (tree type, tree decl)
 
 /* Helper routine, which encodes a value in the pointer_sized_int_node.
    Arguments with precision <= POINTER_SIZE are passed directly,
-   the rest is passed by reference.  T is a value we are to encode.  */
+   the rest is passed by reference.  T is a value we are to encode.
+   IN_EXPAND_P is true if this function is called during expansion.  */
 
 tree
-ubsan_encode_value (tree t)
+ubsan_encode_value (tree t, bool in_expand_p)
 {
   tree type = TREE_TYPE (t);
-  switch (TREE_CODE (type))
-    {
-    case INTEGER_TYPE:
-      if (TYPE_PRECISION (type) <= POINTER_SIZE)
+  const unsigned int bitsize = GET_MODE_BITSIZE (TYPE_MODE (type));
+  if (bitsize <= POINTER_SIZE)
+    switch (TREE_CODE (type))
+      {
+      case BOOLEAN_TYPE:
+      case ENUMERAL_TYPE:
+      case INTEGER_TYPE:
        return fold_build1 (NOP_EXPR, pointer_sized_int_node, t);
+      case REAL_TYPE:
+       {
+         tree itype = build_nonstandard_integer_type (bitsize, true);
+         t = fold_build1 (VIEW_CONVERT_EXPR, itype, t);
+         return fold_convert (pointer_sized_int_node, t);
+       }
+      default:
+       gcc_unreachable ();
+      }
+  else
+    {
+      if (!DECL_P (t) || !TREE_ADDRESSABLE (t))
+       {
+         /* The reason for this is that we don't want to pessimize
+            code by making vars unnecessarily addressable.  */
+         tree var = create_tmp_var (type, NULL);
+         tree tem = build2 (MODIFY_EXPR, void_type_node, var, t);
+         if (in_expand_p)
+           {
+             rtx mem
+               = assign_stack_temp_for_type (TYPE_MODE (type),
+                                             GET_MODE_SIZE (TYPE_MODE (type)),
+                                             type);
+             SET_DECL_RTL (var, mem);
+             expand_assignment (var, t, false);
+             return build_fold_addr_expr (var);
+           }
+         t = build_fold_addr_expr (var);
+         return build2 (COMPOUND_EXPR, TREE_TYPE (t), tem, t);
+       }
       else
        return build_fold_addr_expr (t);
-    case REAL_TYPE:
-      {
-       unsigned int bitsize = GET_MODE_BITSIZE (TYPE_MODE (type));
-       if (bitsize <= POINTER_SIZE)
-         {
-           tree itype = build_nonstandard_integer_type (bitsize, true);
-           t = fold_build1 (VIEW_CONVERT_EXPR, itype, t);
-           return fold_convert (pointer_sized_int_node, t);
-         }
-       else
-         {
-           if (!TREE_ADDRESSABLE (t))
-             {
-               /* The reason for this is that we don't want to pessimize
-                  code by making vars unnecessarily addressable.  */
-               tree var = create_tmp_var (TREE_TYPE (t), NULL);
-               tree tem = build2 (MODIFY_EXPR, void_type_node, var, t);
-               t = build_fold_addr_expr (var);
-               return build2 (COMPOUND_EXPR, TREE_TYPE (t), tem, t);
-             }
-           else
-             return build_fold_addr_expr (t);
-         }
-      }
-    default:
-      gcc_unreachable ();
     }
 }
 
@@ -663,8 +674,9 @@ ubsan_build_overflow_builtin (tree_code code, location_t loc, tree lhstype,
   tree fn = builtin_decl_explicit (fn_code);
   return build_call_expr_loc (loc, fn, 2 + (code != NEGATE_EXPR),
                              build_fold_addr_expr_loc (loc, data),
-                             ubsan_encode_value (op0),
-                             op1 ? ubsan_encode_value (op1) : NULL_TREE);
+                             ubsan_encode_value (op0, true),
+                             op1 ? ubsan_encode_value (op1, true)
+                                 : NULL_TREE);
 }
 
 /* Perform the signed integer instrumentation.  GSI is the iterator
index 0aced4aac67e86a80329e06da433813b8440a92f..fa7698509c4beaab8998389d1800d54b4dc6a2dc 100644 (file)
@@ -41,7 +41,7 @@ extern tree ubsan_instrument_unreachable (location_t);
 extern tree ubsan_create_data (const char *, location_t,
                               const struct ubsan_mismatch_data *, ...);
 extern tree ubsan_type_descriptor (tree, bool);
-extern tree ubsan_encode_value (tree);
+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);