commit e3324d8d3528f0cb1a56e784f0887a4743a3e0f2 Author: Yury Gribov Date: Wed Aug 20 13:56:03 2014 +0400 2014-08-22 Yury Gribov gcc/ 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. gcc/testsuite/ PR sanitizer/62140 * c-c++-common/asan/pr62140-1.c: New test. * c-c++-common/asan/pr62140-2.c: New test. diff --git a/gcc/asan.c b/gcc/asan.c index 15c0737..ea1d3eb 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); } @@ -1553,6 +1556,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. @@ -1598,7 +1622,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); @@ -1804,6 +1831,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)); @@ -1812,6 +1840,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; @@ -1820,28 +1850,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); @@ -2470,9 +2500,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); @@ -2566,14 +2593,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/c-c++-common/asan/pr62140-1.c b/gcc/testsuite/c-c++-common/asan/pr62140-1.c new file mode 100644 index 0000000..f0b026d --- /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 0000000..0bb2563 --- /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; +} +