http://gcc.gnu.org/bugzilla/show_bug.cgi?id=47265
Michael Matz <matz at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- Status|NEW |ASSIGNED --- Comment #2 from Michael Matz <matz at gcc dot gnu.org> 2011-01-12 17:20:00 UTC --- The underlying problem is that tree-ssa-forwprop.c recursively calls itself on the same statement, updating it in the process. That destroys the imm_use iterator for the outer iteration, making us miss on imm-use. The definition then is removed (under the assumption that all imm-uses are changed), leaving a stale reference to an SSA name in the free list. In detail here's what happens, the situation at first: src_2 = &s_1(D)->b; src_20 = src_2 + 1; src_19 = [cond_expr] iftmp.0_11 != 0 ? src_20 : src_2; forward_propagate_addr_expr (src_2) iterates over the imm-uses of src_2. (1) The first is the def of src_20, which itself is a pointer addition. forward_propagate_addr_expr_1 happily tries to look through that one calling forward_propagate_addr_expr recursively on src_20. The imm-use list of src_20 also contains statement src_19, which is now updated via update_stmt. Unfortunately that will clobber the iterator at (1) to not contain the src_19 statement anymore. So when returning the outer loop on imm-uses(src_2) will now exit as if all imm-uses were handled. Caller will remove def(src_2), leaving us with: src_20 = &MEM[(void *)s_1(D) + 4B]; src_19 = [cond_expr] iftmp.0_11 != 0 ? src_20 : src_2; Boom. Triggered by my patch perhaps, but latent problem. The underlying problem is statements that can be reached over multiple distinct paths of def-use chains. I'll experiment with totally removing the recursion, it possibly isn't necessary anymore since MEMREF because looking through type-casts and the like isn't necessary. And of course as this one shows it's simply not correct to recurse on forward_propagate_addr_expr, at least as long as the destination statement has more than one operand