From: Yury Gribov Date: Mon, 1 Sep 2014 07:47:37 +0000 (+0000) Subject: re PR sanitizer/61897 (sanitizer internal compiler error: in build2_stat, at tree... X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=a2f581e1429356d7074814a514056ed3c23a5881;p=gcc.git re PR sanitizer/61897 (sanitizer internal compiler error: in build2_stat, at tree.c:4160) 2014-09-01 Yury Gribov 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 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 21f804b051d..ad06e2dd09b 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,13 @@ +2014-09-01 Yury Gribov + + 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 * config/mcore/mcore.c (try_constant_tricks): Fix declaration. diff --git a/gcc/asan.c b/gcc/asan.c index 58e77191d33..4ed9344bc9e 100644 --- a/gcc/asan.c +++ b/gcc/asan.c @@ -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); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 953eafd11f5..44bedd84ecd 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,10 @@ +2014-09-01 Yury Gribov + + 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 Tobias Burnus 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 index 00000000000..f0b026de2a3 --- /dev/null +++ b/gcc/testsuite/c-c++-common/asan/pr62140-1.c @@ -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 index 00000000000..0bb2563abac --- /dev/null +++ b/gcc/testsuite/c-c++-common/asan/pr62140-2.c @@ -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; +} +