[ubsan] Fix ICE 79/136679/7 accepted/tizen/base/20170901.225743 submit/tizen_base/20170823.100418
authorDenis Khalikov <d.khalikov@partner.samsung.com>
Sun, 2 Jul 2017 15:47:03 +0000 (18:47 +0300)
committerDongkyun Son <dongkyun.s@samsung.com>
Wed, 23 Aug 2017 09:53:08 +0000 (09:53 +0000)
   While we have a current_function_decl in this case,
   still create_tmp_var's called gimple_add_tmp_var and
   mark_addressable don't work too well when the current
   function is a C++ ctor or dtor that the FE then duplicates

   2017-06-27  Jakub Jelinek  <jakub@redhat.com>

   PR sanitizer/81209
   * ubsan.c (ubsan_encode_value): Initialize DECL_CONTEXT on var.
   * g++.dg/ubsan/pr81209.C: New test.

   2017-06-20  Jakub Jelinek  <jakub@redhat.com>

   PR sanitizer/81125
   * ubsan.h (ubsan_encode_value): Workaround buggy clang++ parser
   by removing enum keyword.
   (ubsan_type_descriptor): Likewise.  Formatting fix.

   2017-06-19  Jakub Jelinek  <jakub@redhat.com>

   PR sanitizer/81125
   * ubsan.h (enum ubsan_encode_value_phase): New.
   (ubsan_encode_value): Change second argument to
   enum ubsan_encode_value_phase with default value of
   UBSAN_ENCODE_VALUE_GENERIC.
   * ubsan.c (ubsan_encode_value): Change second argument to
   enum ubsan_encode_value_phase PHASE from bool IN_EXPAND_P,
   adjust uses, for UBSAN_ENCODE_VALUE_GENERIC use just
   create_tmp_var_raw instead of create_tmp_var and use a
   TARGET_EXPR.
   (ubsan_expand_bounds_ifn, ubsan_build_overflow_builtin,
   instrument_bool_enum_load, ubsan_instrument_float_cast): Adjust
   ubsan_encode_value callers.

   PR sanitizer/81111
   * ubsan.c (ubsan_encode_value): If current_function_decl is NULL,
   use create_tmp_var_raw instead of create_tmp_var, mark it addressable
   just by setting TREE_ADDRESSABLE on the result and use a TARGET_EXPR.

   PR sanitizer/81125
   * g++.dg/ubsan/pr81125.C: New test.

   PR sanitizer/81111
   * g++.dg/ubsan/pr81111.C: New test.

   git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/gcc-7-branch@249480 138bc75d-0d04-0410-961f-82ee72b054a4

Change-Id: I3b7816b4f9b1bb5916adf3684dcbcc5284e50954

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/ubsan/pr81111.C [new file with mode: 0644]
gcc/testsuite/g++.dg/ubsan/pr81125.C [new file with mode: 0644]
gcc/testsuite/g++.dg/ubsan/pr81209.C [new file with mode: 0644]
gcc/ubsan.c
gcc/ubsan.h

index a41c141..4c5f9a6 100644 (file)
        (asan_global_struct): Increase the size of fields.
        (asan_add_global): Add new field constructor.
 
+2017-06-27  Jakub Jelinek  <jakub@redhat.com>
+
+       PR sanitizer/81209
+       * ubsan.c (ubsan_encode_value): Initialize DECL_CONTEXT on var.
+
+2017-06-21  Jakub Jelinek  <jakub@redhat.com>
+
+       Backported from mainline
+       2017-06-20  Jakub Jelinek  <jakub@redhat.com>
+
+       PR sanitizer/81125
+       * ubsan.h (ubsan_encode_value): Workaround buggy clang++ parser
+       by removing enum keyword.
+       (ubsan_type_descriptor): Likewise.  Formatting fix.
+
+       2017-06-19  Jakub Jelinek  <jakub@redhat.com>
+
+       PR sanitizer/81125
+       * ubsan.h (enum ubsan_encode_value_phase): New.
+       (ubsan_encode_value): Change second argument to
+       enum ubsan_encode_value_phase with default value of
+       UBSAN_ENCODE_VALUE_GENERIC.
+       * ubsan.c (ubsan_encode_value): Change second argument to
+       enum ubsan_encode_value_phase PHASE from bool IN_EXPAND_P,
+       adjust uses, for UBSAN_ENCODE_VALUE_GENERIC use just
+       create_tmp_var_raw instead of create_tmp_var and use a
+       TARGET_EXPR.
+       (ubsan_expand_bounds_ifn, ubsan_build_overflow_builtin,
+       instrument_bool_enum_load, ubsan_instrument_float_cast): Adjust
+       ubsan_encode_value callers.
+
+       PR sanitizer/81111
+       * ubsan.c (ubsan_encode_value): If current_function_decl is NULL,
+       use create_tmp_var_raw instead of create_tmp_var, mark it addressable
+       just by setting TREE_ADDRESSABLE on the result and use a TARGET_EXPR.
+
+
 2017-04-13  Denis Khalikov <d.khalikov@partner.samsung.com>
 
         PR sanitizer/80414
index 0123658..0cfd70f 100644 (file)
@@ -1,4 +1,3 @@
-
 2017-07-06  Vyacheslav Barinov  <v.barinov@samsung.com>
 
        * g++.dg/ext/statement-list-end.C: New.
@@ -7,6 +6,19 @@
 
        * c-c++-common/asan/null-deref-1.c: Adjust testcase.
 
+2017-06-27  Jakub Jelinek  <jakub@redhat.com>
+
+       PR sanitizer/81209
+       * g++.dg/ubsan/pr81209.C: New test.
+
+2017-06-19  Jakub Jelinek  <jakub@redhat.com>
+
+       PR sanitizer/81125
+       * g++.dg/ubsan/pr81125.C: New test.
+
+       PR sanitizer/81111
+       * g++.dg/ubsan/pr81111.C: New test.
+
 2017-04-13  Denis Khalikov  <d.khalikov@partner.samsung.com>
 
         PR sanitizer/80414
diff --git a/gcc/testsuite/g++.dg/ubsan/pr81111.C b/gcc/testsuite/g++.dg/ubsan/pr81111.C
new file mode 100644 (file)
index 0000000..6d54a2f
--- /dev/null
@@ -0,0 +1,45 @@
+// PR sanitizer/81111
+// { dg-do compile }
+// { dg-options "-fsanitize=shift" }
+
+template <typename V>
+struct N
+{
+  static const V m = (((V)(-1) < 0)
+                     ? (V)1 << (sizeof(V) * __CHAR_BIT__ - ((V)(-1) < 0))
+                     : (V) 0);
+};
+
+template<typename V>
+const V N<V>::m;
+
+template <typename V>
+struct O
+{
+  static const V m = (V)1 << sizeof(V) * __CHAR_BIT__;
+};
+
+template<typename V>
+const V O<V>::m;
+
+void
+foo ()
+{
+  N<long long>::m;
+  N<unsigned long long>::m;
+#ifdef __SIZEOF_INT128__
+  N<__int128>::m;
+  N<unsigned __int128>::m;
+#endif
+}
+
+void
+bar ()
+{
+  O<long long>::m;
+  O<unsigned long long>::m;
+#ifdef __SIZEOF_INT128__
+  O<__int128>::m;
+  O<unsigned __int128>::m;
+#endif
+}
diff --git a/gcc/testsuite/g++.dg/ubsan/pr81125.C b/gcc/testsuite/g++.dg/ubsan/pr81125.C
new file mode 100644 (file)
index 0000000..c91ddc7
--- /dev/null
@@ -0,0 +1,20 @@
+// PR sanitizer/81125
+// { dg-do compile }
+// { dg-options "-fsanitize=undefined" }
+
+#ifdef __SIZEOF_INT128__
+typedef __int128 T;
+#else
+typedef long long int T;
+#endif
+
+struct A
+{
+  A (long);
+  T a;
+};
+
+A::A (long c)
+{
+  long b = a % c;
+}
diff --git a/gcc/testsuite/g++.dg/ubsan/pr81209.C b/gcc/testsuite/g++.dg/ubsan/pr81209.C
new file mode 100644 (file)
index 0000000..3f2a576
--- /dev/null
@@ -0,0 +1,21 @@
+// PR sanitizer/81209
+// { dg-do compile }
+// { dg-options "-fsanitize=undefined -fno-declone-ctor-dtor" }
+
+#ifdef __SIZEOF_INT128__
+typedef __int128 T;
+#else
+typedef long long int T;
+#endif
+
+struct B {};
+struct A : virtual public B
+{
+  A (long);
+  T a;
+};
+
+A::A (long c)
+{
+  long b = a % c;
+}
index cbb46ec..7b0a3f1 100644 (file)
@@ -113,10 +113,10 @@ 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.
-   IN_EXPAND_P is true if this function is called during expansion.  */
+   PHASE determines when this function is called.  */
 
 tree
-ubsan_encode_value (tree t, bool in_expand_p)
+ubsan_encode_value (tree t, enum ubsan_encode_value_phase phase)
 {
   tree type = TREE_TYPE (t);
   const unsigned int bitsize = GET_MODE_BITSIZE (TYPE_MODE (type));
@@ -142,10 +142,19 @@ ubsan_encode_value (tree t, bool in_expand_p)
        {
          /* The reason for this is that we don't want to pessimize
             code by making vars unnecessarily addressable.  */
-         tree var = create_tmp_var (type);
-         tree tem = build2 (MODIFY_EXPR, void_type_node, var, t);
-         mark_addressable (var);
-         if (in_expand_p)
+         tree var;
+         if (phase != UBSAN_ENCODE_VALUE_GENERIC)
+           {
+             var = create_tmp_var (type);
+             mark_addressable (var);
+           }
+         else
+           {
+             var = create_tmp_var_raw (type);
+             TREE_ADDRESSABLE (var) = 1;
+             DECL_CONTEXT (var) = current_function_decl;
+           }
+         if (phase == UBSAN_ENCODE_VALUE_RTL)
            {
              rtx mem
                = assign_stack_temp_for_type (TYPE_MODE (type),
@@ -155,8 +164,17 @@ ubsan_encode_value (tree t, bool in_expand_p)
              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);
+         if (phase != UBSAN_ENCODE_VALUE_GENERIC)
+           {
+             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
+           {
+             var = build4 (TARGET_EXPR, type, var, t, NULL_TREE, NULL_TREE);
+             return build_fold_addr_expr (var);
+           }
        }
       else
        return build_fold_addr_expr (t);
@@ -701,9 +719,9 @@ ubsan_expand_bounds_ifn (gimple_stmt_iterator *gsi)
          ? BUILT_IN_UBSAN_HANDLE_OUT_OF_BOUNDS
          : BUILT_IN_UBSAN_HANDLE_OUT_OF_BOUNDS_ABORT;
       tree fn = builtin_decl_explicit (bcode);
-      tree val
-       = force_gimple_operand_gsi (gsi, ubsan_encode_value (orig_index), true,
-                                   NULL_TREE, true, GSI_SAME_STMT);
+      tree val = ubsan_encode_value (orig_index, UBSAN_ENCODE_VALUE_GIMPLE);
+      val = force_gimple_operand_gsi (gsi, val, true, NULL_TREE, true,
+                                     GSI_SAME_STMT);
       g = gimple_build_call (fn, 2, data, val);
     }
   gimple_set_location (g, loc);
@@ -1253,9 +1271,11 @@ 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, true),
-                             op1 ? ubsan_encode_value (op1, true)
-                                 : NULL_TREE);
+                             ubsan_encode_value (op0, UBSAN_ENCODE_VALUE_RTL),
+                             op1
+                             ? ubsan_encode_value (op1,
+                                                   UBSAN_ENCODE_VALUE_RTL)
+                             : NULL_TREE);
 }
 
 /* Perform the signed integer instrumentation.  GSI is the iterator
@@ -1444,9 +1464,9 @@ instrument_bool_enum_load (gimple_stmt_iterator *gsi)
          : BUILT_IN_UBSAN_HANDLE_LOAD_INVALID_VALUE_ABORT;
       tree fn = builtin_decl_explicit (bcode);
 
-      tree val = force_gimple_operand_gsi (&gsi2, ubsan_encode_value (urhs),
-                                          true, NULL_TREE, true,
-                                          GSI_SAME_STMT);
+      tree val = ubsan_encode_value (urhs, UBSAN_ENCODE_VALUE_GIMPLE);
+      val = force_gimple_operand_gsi (&gsi2, val, true, NULL_TREE, true,
+                                     GSI_SAME_STMT);
       g = gimple_build_call (fn, 2, data, val);
     }
   gimple_set_location (g, loc);
@@ -1611,7 +1631,7 @@ 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 (expr));
     }
 
   return fold_build3 (COND_EXPR, void_type_node, t, fn, integer_zero_node);
index c66d0af..04aa31f 100644 (file)
@@ -42,6 +42,13 @@ enum ubsan_print_style {
   UBSAN_PRINT_ARRAY
 };
 
+/* This controls ubsan_encode_value behavior.  */
+enum ubsan_encode_value_phase {
+  UBSAN_ENCODE_VALUE_GENERIC,
+  UBSAN_ENCODE_VALUE_GIMPLE,
+  UBSAN_ENCODE_VALUE_RTL
+};
+
 extern bool do_ubsan_in_current_function (void);
 extern bool ubsan_expand_bounds_ifn (gimple_stmt_iterator *);
 extern bool ubsan_expand_null_ifn (gimple_stmt_iterator *);
@@ -49,8 +56,10 @@ extern bool ubsan_expand_objsize_ifn (gimple_stmt_iterator *);
 extern bool ubsan_expand_vptr_ifn (gimple_stmt_iterator *);
 extern bool ubsan_instrument_unreachable (gimple_stmt_iterator *);
 extern tree ubsan_create_data (const char *, int, const location_t *, ...);
-extern tree ubsan_type_descriptor (tree, enum ubsan_print_style = UBSAN_PRINT_NORMAL);
-extern tree ubsan_encode_value (tree, bool = false);
+extern tree ubsan_type_descriptor (tree, ubsan_print_style
+                                        = UBSAN_PRINT_NORMAL);
+extern tree ubsan_encode_value (tree, ubsan_encode_value_phase
+                                     = UBSAN_ENCODE_VALUE_GENERIC);
 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);