https://gcc.gnu.org/bugzilla/show_bug.cgi?id=79671
--- Comment #14 from Richard Biener <rguenth at gcc dot gnu.org> --- Seems to be void move_assign(function10& f) { if (&f == this) return; { try { if (!f.empty()) { this->vtable = f.vtable; if (this->has_trivial_copy_and_destroy()) this->functor = f.functor; ^^^ for the aggregate copy but lineno info looks confused for the aliasing store. It points at operator=(Functor f) { self_type(f).swap(*this); return *this; } the boost code for function looks quite convoluted with its vtable handling... It looks like ESRA creates that piecewise store, but it's hard to track down exactly where it comes from. Example transform looks like + char f$p$subject$subject$right$ch; struct parser_binder f; bool D.611696; struct parser_binder f; @@ -15343,7 +11698,8 @@ <bb 2> [100.00%]: <&0x7f50d29d3d70> f = f; - <&0x7f50d29d3dc0> f = f; + <&0x7f50d2a16050> f$p$subject$subject$right$ch_16 = MEM[(struct parser_binder *)&f + 1B]; + <&0x7f50d2a160a0> MEM[(struct parser_binder *)&f + 1B] = f$p$subject$subject$right$ch_16; <&0x7f50d2a14240> _13 = boost::detail::function::has_empty_target (&f); there's no offset 5 one at this point so inlining eventually comes up with <bb 2> [100.00%]: <&0x7f50d2a16b40> f = f; <&0x7f50d2a314b0> f$1_39 = MEM[(struct parser_binder *)&f + 1B]; <&0x7f50d2a16b90> f$1_11 = f$1_39; <&0x7f50d2a16be0> MEM[(struct &)&D.573835] ={v} {CLOBBER}; <&0x7f50d2a16c30> MEM[(struct function_base *)&D.573835].vtable = 0B; <&0x7f50d2a16c80> MEM[(struct parser_binder *)&f + 1B] = f$1_11; <&0x7f50d2a28bd0> _12 = boost::detail::function::has_empty_target (&f); <&0x7f50d2a16cd0> if (_12 != 0) goto <bb 4>; [46.00%] else goto <bb 3>; [54.00%] <bb 3> [54.00%]: <&0x7f50d2a16d20> MEM[(struct parser_binder *)&D.573835 + 5B] = f$1_11; note that .original shows size_t value = (size_t) &stored_vtable.base; <<cleanup_point size_t value = (size_t) &stored_vtable.base;>>; <<cleanup_point <<< Unknown tree: expr_stmt (void) (value = value | 1) >>>>>; <<cleanup_point <<< Unknown tree: expr_stmt (void) (((struct function4 *) this)->D.542200.vtable = (struct vtable_base *) value) >>>>>; and thus questionable casts. The question ultimatively boils down to validity of the testcase.