https://gcc.gnu.org/bugzilla/show_bug.cgi?id=85230
--- Comment #9 from Jakub Jelinek <jakub at gcc dot gnu.org> --- So (completely untested): --- gcc/asan.c.jj 2018-01-09 21:53:38.821577722 +0100 +++ gcc/asan.c 2018-04-12 12:30:43.360840432 +0200 @@ -554,14 +554,14 @@ get_last_alloca_addr () return last_alloca_addr; } -/* Insert __asan_allocas_unpoison (top, bottom) call after +/* Insert __asan_allocas_unpoison (top, bottom) call before __builtin_stack_restore (new_sp) call. The pseudocode of this routine should look like this: - __builtin_stack_restore (new_sp); top = last_alloca_addr; bot = new_sp; __asan_allocas_unpoison (top, bot); last_alloca_addr = new_sp; + __builtin_stack_restore (new_sp); In general, we can't use new_sp as bot parameter because on some architectures SP has non zero offset from dynamic stack area. Moreover, on some architectures this offset (STACK_DYNAMIC_OFFSET) becomes known for each @@ -584,9 +584,9 @@ handle_builtin_stack_restore (gcall *cal tree restored_stack = gimple_call_arg (call, 0); tree fn = builtin_decl_implicit (BUILT_IN_ASAN_ALLOCAS_UNPOISON); gimple *g = gimple_build_call (fn, 2, last_alloca, restored_stack); - gsi_insert_after (iter, g, GSI_NEW_STMT); + gsi_insert_before (iter, g, GSI_SAME_STMT); g = gimple_build_assign (last_alloca, restored_stack); - gsi_insert_after (iter, g, GSI_NEW_STMT); + gsi_insert_before (iter, g, GSI_SAME_STMT); } /* Deploy and poison redzones around __builtin_alloca call. To do this, we ? If the __builtin_stack_restore is at the end of function or isn't even present at all (if __builtin_alloca is used), then it is already doing the right thing. Small testcase: void baz (char *, int); void foo (int n) { baz (__builtin_alloca (n), n); } void bar (int n) { { char a[n]; baz (a, n); } { char b[n + 2]; baz (b, n + 2); } } The patch only changes the order of __asan_allocas_unpoison and stack restore after the first call to baz from bar above, the rest is unchanged.