https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67529
--- Comment #2 from Eric <ericns1 at spirilis dot net> --- A little more sleuthing, using --save-temps -dP... The "inherited", bug-ridden case has the following before JSR R10: ;(call_insn 16 15 19 (parallel [ ; (call (mem:QI (reg/f:SI 10 r10 [orig:25 D.2187 ] [25]) [0 *OBJ_TYPE_REF(_7;(struct MyTemplate)this_2(D)->1) S1 A8]) ; (const_int 0 [0])) ; (clobber (reg:CC 16 cc)) ; ]) my_template.h:34 18 {call_internal} ; (nil) ; (expr_list:SI (use (reg:SI 1 r1)) ; (nil))) jsr r10 ; 16 call_internal/1 [length = 2] The non-inherited version: ;(call_insn 12 11 15 (parallel [ ; (call (mem:QI (symbol_ref/i:SI ("_ZN10MyTemplate5checkEv") [flags 0x3] <function_decl 0x7f64af2f5e58 check>) [0 check S1 A8]) ; (const_int 0 [0])) ; (clobber (reg:CC 16 cc)) ; ]) my_template.h:34 18 {call_internal} ; (expr_list:REG_EH_REGION (const_int 0 [0]) ; (nil)) ; (expr_list:SI (use (reg:SI 1 r1)) ; (nil))) bsr __ZN10MyTemplate5checkEv ; 12 call_internal/2 [length = 4] So I'm not too familiar with this lingo, but clearly the compiler knows what it's doing, and for some reason it's interpreting the execution of the overridden method in terms relative to the location of the class's instance struct, whereas without inheritance it's looking for the method correctly. I don't *think* that is right... at least the eventual behavior experienced doesn't match what the code should do.