diff options
author | Maxim Ostapenko <m.ostapenko@samsung.com> | 2016-04-08 10:46:13 +0000 |
---|---|---|
committer | Maxim Ostapenko <chefmax@gcc.gnu.org> | 2016-04-08 13:46:13 +0300 |
commit | c3da495616f26855ac6b2522e8bbecd7e718074e (patch) | |
tree | d28e1f8c16d17d15af785dbac2a8216e5da79f31 /gcc/asan.c | |
parent | 9f1b833bc3f28a3000f2ce8c076a1930f44bcda9 (diff) | |
download | gcc-c3da495616f26855ac6b2522e8bbecd7e718074e.zip gcc-c3da495616f26855ac6b2522e8bbecd7e718074e.tar.gz gcc-c3da495616f26855ac6b2522e8bbecd7e718074e.tar.bz2 |
re PR sanitizer/70541 (unnoticed invalid dereference when using address sanitizer)
2016-04-08 Maxim Ostapenko <m.ostapenko@samsung.com>
PR sanitizer/70541
* asan.c (instrument_derefs): If we get unknown location, extract it
with EXPR_LOCATION.
(maybe_instrument_call): Instrument gimple_call's arguments if needed.
* c-c++-common/asan/pr70541.c: New test.
From-SVN: r234827
Diffstat (limited to 'gcc/asan.c')
-rw-r--r-- | gcc/asan.c | 28 |
1 files changed, 25 insertions, 3 deletions
@@ -1766,6 +1766,8 @@ instrument_derefs (gimple_stmt_iterator *iter, tree t, tree type, base; HOST_WIDE_INT size_in_bytes; + if (location == UNKNOWN_LOCATION) + location = EXPR_LOCATION (t); type = TREE_TYPE (t); switch (TREE_CODE (t)) @@ -2049,6 +2051,7 @@ maybe_instrument_call (gimple_stmt_iterator *iter) gsi_insert_before (iter, g, GSI_SAME_STMT); } + bool instrumented = false; if (gimple_store_p (stmt)) { tree ref_expr = gimple_call_lhs (stmt); @@ -2056,11 +2059,30 @@ maybe_instrument_call (gimple_stmt_iterator *iter) gimple_location (stmt), /*is_store=*/true); - gsi_next (iter); - return true; + instrumented = true; } - return false; + /* Walk through gimple_call arguments and check them id needed. */ + unsigned args_num = gimple_call_num_args (stmt); + for (unsigned i = 0; i < args_num; ++i) + { + tree arg = gimple_call_arg (stmt, i); + /* If ARG is not a non-aggregate register variable, compiler in general + creates temporary for it and pass it as argument to gimple call. + But in some cases, e.g. when we pass by value a small structure that + fits to register, compiler can avoid extra overhead by pulling out + these temporaries. In this case, we should check the argument. */ + if (!is_gimple_reg (arg) && !is_gimple_min_invariant (arg)) + { + instrument_derefs (iter, arg, + gimple_location (stmt), + /*is_store=*/false); + instrumented = true; + } + } + if (instrumented) + gsi_next (iter); + return instrumented; } /* Walk each instruction of all basic block and instrument those that |