re PR sanitizer/61897 (sanitizer internal compiler error: in build2_stat, at tree...
authorYury Gribov <y.gribov@samsung.com>
Mon, 1 Sep 2014 07:47:37 +0000 (07:47 +0000)
committerYury Gribov <ygribov@gcc.gnu.org>
Mon, 1 Sep 2014 07:47:37 +0000 (07:47 +0000)
2014-09-01  Yury Gribov  <y.gribov@samsung.com>

PR sanitizer/61897
PR sanitizer/62140

gcc/
* asan.c (asan_mem_ref_get_end): Handle non-ptroff_t lengths.
(build_check_stmt): Likewise.
(instrument_strlen_call): Likewise.
(asan_expand_check_ifn): Likewise and fix types.
(maybe_cast_to_ptrmode): New function.

gcc/testsuite/
* c-c++-common/asan/pr62140-1.c: New test.
* c-c++-common/asan/pr62140-2.c: New test.

From-SVN: r214777

gcc/ChangeLog
gcc/asan.c
gcc/testsuite/ChangeLog
gcc/testsuite/c-c++-common/asan/pr62140-1.c [new file with mode: 0644]
gcc/testsuite/c-c++-common/asan/pr62140-2.c [new file with mode: 0644]

index 21f804b051d2bb59f431292473fc67e6c5271ef2..ad06e2dd09b289a3e4854df41f42684965c97b20 100644 (file)
@@ -1,3 +1,13 @@
+2014-09-01  Yury Gribov  <y.gribov@samsung.com>
+
+       PR sanitizer/61897
+       PR sanitizer/62140
+       * asan.c (asan_mem_ref_get_end): Handle non-ptroff_t lengths.
+       (build_check_stmt): Likewise.
+       (instrument_strlen_call): Likewise.
+       (asan_expand_check_ifn): Likewise and fix types.
+       (maybe_cast_to_ptrmode): New function.
+
 2014-09-01  Jan-Benedict Glaw  <jbglaw@lug-owl.de>
 
        * config/mcore/mcore.c (try_constant_tricks): Fix declaration.
index 58e77191d333b6c46a57117c97a6c0ac4d2a161e..4ed9344bc9e059e4ed4d85b8856181bec0176972 100644 (file)
@@ -318,6 +318,9 @@ asan_mem_ref_get_end (tree start, tree len)
   if (len == NULL_TREE || integer_zerop (len))
     return start;
 
+  if (!ptrofftype_p (len))
+    len = convert_to_ptrofftype (len);
+
   return fold_build2 (POINTER_PLUS_EXPR, TREE_TYPE (start), start, len);
 }
 
@@ -1556,6 +1559,27 @@ maybe_create_ssa_name (location_t loc, tree base, gimple_stmt_iterator *iter,
   return gimple_assign_lhs (g);
 }
 
+/* LEN can already have necessary size and precision;
+   in that case, do not create a new variable.  */
+
+tree
+maybe_cast_to_ptrmode (location_t loc, tree len, gimple_stmt_iterator *iter,
+                      bool before_p)
+{
+  if (ptrofftype_p (len))
+    return len;
+  gimple g
+    = gimple_build_assign_with_ops (NOP_EXPR,
+                                   make_ssa_name (pointer_sized_int_node, NULL),
+                                   len, NULL);
+  gimple_set_location (g, loc);
+  if (before_p)
+    gsi_insert_before (iter, g, GSI_SAME_STMT);
+  else
+    gsi_insert_after (iter, g, GSI_NEW_STMT);
+  return gimple_assign_lhs (g);
+}
+
 /* Instrument the memory access instruction BASE.  Insert new
    statements before or after ITER.
 
@@ -1601,7 +1625,10 @@ build_check_stmt (location_t loc, tree base, tree len,
   base = maybe_create_ssa_name (loc, base, &gsi, before_p);
 
   if (len)
-    len = unshare_expr (len);
+    {
+      len = unshare_expr (len);
+      len = maybe_cast_to_ptrmode (loc, len, iter, before_p);
+    }
   else
     {
       gcc_assert (size_in_bytes != -1);
@@ -1807,6 +1834,7 @@ instrument_mem_region_access (tree base, tree len,
 static bool
 instrument_strlen_call (gimple_stmt_iterator *iter)
 {
+  gimple g;
   gimple call = gsi_stmt (*iter);
   gcc_assert (is_gimple_call (call));
 
@@ -1815,6 +1843,8 @@ instrument_strlen_call (gimple_stmt_iterator *iter)
              && DECL_BUILT_IN_CLASS (callee) == BUILT_IN_NORMAL
              && DECL_FUNCTION_CODE (callee) == BUILT_IN_STRLEN);
 
+  location_t loc = gimple_location (call);
+
   tree len = gimple_call_lhs (call);
   if (len == NULL)
     /* Some passes might clear the return value of the strlen call;
@@ -1823,28 +1853,28 @@ instrument_strlen_call (gimple_stmt_iterator *iter)
     return false;
   gcc_assert (INTEGRAL_TYPE_P (TREE_TYPE (len)));
 
-  location_t loc = gimple_location (call);
+  len = maybe_cast_to_ptrmode (loc, len, iter, /*before_p*/false);
+
   tree str_arg = gimple_call_arg (call, 0);
   bool start_instrumented = has_mem_ref_been_instrumented (str_arg, 1);
 
   tree cptr_type = build_pointer_type (char_type_node);
-  gimple str_arg_ssa =
-    gimple_build_assign_with_ops (NOP_EXPR,
-                                 make_ssa_name (cptr_type, NULL),
-                                 str_arg, NULL);
-  gimple_set_location (str_arg_ssa, loc);
-  gsi_insert_before (iter, str_arg_ssa, GSI_SAME_STMT);
-
-  build_check_stmt (loc, gimple_assign_lhs (str_arg_ssa), NULL_TREE, 1, iter,
+  g = gimple_build_assign_with_ops (NOP_EXPR,
+                                   make_ssa_name (cptr_type, NULL),
+                                   str_arg, NULL);
+  gimple_set_location (g, loc);
+  gsi_insert_before (iter, g, GSI_SAME_STMT);
+  str_arg = gimple_assign_lhs (g);
+
+  build_check_stmt (loc, str_arg, NULL_TREE, 1, iter,
                    /*is_non_zero_len*/true, /*before_p=*/true,
                    /*is_store=*/false, /*is_scalar_access*/true, /*align*/0,
                    start_instrumented, start_instrumented);
 
-  gimple g =
-    gimple_build_assign_with_ops (POINTER_PLUS_EXPR,
-                                 make_ssa_name (cptr_type, NULL),
-                                 gimple_assign_lhs (str_arg_ssa),
-                                 len);
+  g = gimple_build_assign_with_ops (POINTER_PLUS_EXPR,
+                                   make_ssa_name (cptr_type, NULL),
+                                   str_arg,
+                                   len);
   gimple_set_location (g, loc);
   gsi_insert_after (iter, g, GSI_NEW_STMT);
 
@@ -2473,9 +2503,6 @@ asan_expand_check_ifn (gimple_stmt_iterator *iter, bool use_calls)
 
   HOST_WIDE_INT real_size_in_bytes = size_in_bytes == -1 ? 1 : size_in_bytes;
 
-  tree uintptr_type
-    = build_nonstandard_integer_type (TYPE_PRECISION (TREE_TYPE (base)), 1);
-
   tree shadow_ptr_type = shadow_ptr_types[real_size_in_bytes == 16 ? 1 : 0];
   tree shadow_type = TREE_TYPE (shadow_ptr_type);
 
@@ -2569,14 +2596,14 @@ asan_expand_check_ifn (gimple_stmt_iterator *iter, bool use_calls)
       if (size_in_bytes == -1 && !end_instrumented)
        {
          g = gimple_build_assign_with_ops (MINUS_EXPR,
-                                           make_ssa_name (uintptr_type, NULL),
+                                           make_ssa_name (pointer_sized_int_node, NULL),
                                            len,
-                                           build_int_cst (uintptr_type, 1));
+                                           build_int_cst (pointer_sized_int_node, 1));
          gimple_set_location (g, loc);
          gsi_insert_after (&gsi, g, GSI_NEW_STMT);
          tree last = gimple_assign_lhs (g);
          g = gimple_build_assign_with_ops (PLUS_EXPR,
-                                           make_ssa_name (uintptr_type, NULL),
+                                           make_ssa_name (pointer_sized_int_node, NULL),
                                            base_addr,
                                            last);
          gimple_set_location (g, loc);
index 953eafd11f53ca69f943b122e27df778bf181d23..44bedd84ecd2b3bc6ba9501608d9e71b7670cf03 100644 (file)
@@ -1,3 +1,10 @@
+2014-09-01  Yury Gribov  <y.gribov@samsung.com>
+
+       PR sanitizer/61897
+       PR sanitizer/62140
+       * c-c++-common/asan/pr62140-1.c: New test.
+       * c-c++-common/asan/pr62140-2.c: New test.
+
 2014-08-31  Fritz Reese  <Reese-Fritz@zai.com>
            Tobias Burnus  <burnus@net-b.de>
 
diff --git a/gcc/testsuite/c-c++-common/asan/pr62140-1.c b/gcc/testsuite/c-c++-common/asan/pr62140-1.c
new file mode 100644 (file)
index 0000000..f0b026d
--- /dev/null
@@ -0,0 +1,10 @@
+/* { dg-do compile } */
+/* { dg-options "-w -fpermissive" } */
+
+int memcmp (const void *p, const void *q, int len);
+
+int f (int *p, int *q, int len)
+{
+    return memcmp (p, q, len);
+}
+
diff --git a/gcc/testsuite/c-c++-common/asan/pr62140-2.c b/gcc/testsuite/c-c++-common/asan/pr62140-2.c
new file mode 100644 (file)
index 0000000..0bb2563
--- /dev/null
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-options "-w -fpermissive" } */
+
+int strlen (const char *p);
+
+int f (char *p)
+{
+    int x = strlen (p);
+    return x;
+}
+