Hi! This PR is about forwprop propagating: _17 = __builtin_alloca_with_align (_16, 256); _18 = _17 + 32; __builtin___asan_alloca_poison (_18, _8); _7 = &*_18[4]; __builtin_va_start (_7, 0); to: _17 = __builtin_alloca_with_align (_16, 256); _18 = _17 + 32; __builtin___asan_alloca_poison (_18, _8); _7 = &MEM[(struct [0:D.2257][1] *)_17 + 32B][4]; __builtin_va_start (_7, 0); which is something the verifiers allow and then backend VA_START handling calling build_simple_mem_ref_loc on the ADDR_EXPR it got. get_addr_base_and_unit_offset only looks through a MEM_REF if it has ADDR_EXPR as the first operand, which is not the case here, so nothing sums up the 96 offset from the [4] ARRAY_REF with the extra 32 from the MEM_REF.
Fixed thusly, bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk? 2017-11-29 Jakub Jelinek <ja...@redhat.com> PR middle-end/83185 * tree.c (build_simple_mem_ref_loc): Handle get_addr_base_and_unit_offset returning a MEM_REF. * gcc.dg/asan/pr83185.c: New test. --- gcc/tree.c.jj 2017-11-28 12:11:38.000000000 +0100 +++ gcc/tree.c 2017-11-28 17:22:01.800939050 +0100 @@ -4692,7 +4692,13 @@ build_simple_mem_ref_loc (location_t loc { ptr = get_addr_base_and_unit_offset (TREE_OPERAND (ptr, 0), &offset); gcc_assert (ptr); - ptr = build_fold_addr_expr (ptr); + if (TREE_CODE (ptr) == MEM_REF) + { + offset += mem_ref_offset (ptr).to_short_addr (); + ptr = TREE_OPERAND (ptr, 0); + } + else + ptr = build_fold_addr_expr (ptr); gcc_assert (is_gimple_reg (ptr) || is_gimple_min_invariant (ptr)); } tem = build2 (MEM_REF, TREE_TYPE (ptype), --- gcc/testsuite/gcc.dg/asan/pr83185.c.jj 2017-11-28 17:24:15.540329283 +0100 +++ gcc/testsuite/gcc.dg/asan/pr83185.c 2017-11-28 17:24:19.851277394 +0100 @@ -0,0 +1,14 @@ +/* PR middle-end/83185 */ +/* { dg-do compile } */ + +#include <stdarg.h> + +int bar (void); + +void +foo (int i, ...) +{ + va_list aps[bar()]; + va_start (aps[4], i); + va_end (aps[4]); +} Jakub