https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81147
--- Comment #8 from Felipe Magno de Almeida <felipe at expertisesolutions dot com.br> --- With GCC 7.2.0 I'm still not seeing the same results as you are. The following is the assembly result, using the same .cpp file and the same command line: .section .text._Z3abcv,"ax",@progbits .global _Z3abcv .type _Z3abcv, @function _Z3abcv: push r28 ; ; 52 pushqi1/1 [length = 1] push r29 ; ; 53 pushqi1/1 [length = 1] in r28,__SP_L__ ; ; 54 *movhi/8 [length = 2] in r29,__SP_H__ ; sbiw r28,15 ; , ; 55 *addhi3/3 [length = 1] in __tmp_reg__,__SREG__ ; 56 movhi_sp_r/3 [length = 5] cli out __SP_H__,r29 ; , out __SREG__,__tmp_reg__ out __SP_L__,r28 ; , /* prologue: function */ /* frame size = 15 */ /* stack size = 17 */ .L__stack_usage = 17 ldi r24,lo8(32) ; D.1843, ; 6 movqi_insn/2 [length = 1] ; test.cpp:19: seq(L l, R r) : l(l), r(r) {} std Y+7,__zero_reg__ ; D.2011.l, ; 37 movqi_insn/3 [length = 1] ldi r25,lo8(97) ; D.1843, ; 42 movqi_insn/2 [length = 1] std Y+8,r25 ; D.2011.l, D.1843 ; 38 movqi_insn/3 [length = 1] std Y+9,r24 ; D.2011.l, D.1843 ; 39 movqi_insn/3 [length = 1] ; test.cpp:25: return { l, r}; std Y+10,r24 ; MEM[(struct seq *)&D.2011 + 4B], D.1843 ; 14 movqi_insn/3 [length = 1] ldi r24,lo8(5) ; tmp47, ; 15 movqi_insn/2 [length = 1] movw r30,r28 ; , ; 45 *movhi/1 [length = 1] adiw r30,6 ; , ; 16 *addhi3/3 [length = 1] movw r26,r28 ; , ; 46 *movhi/1 [length = 1] adiw r26,1 ; , ; 17 *addhi3/3 [length = 1] 0: ; 18 movmem_qi [length = 4] ld r0,Z+ ; st X+,r0 ; dec r24 ; tmp47 brne 0b ldi r24,lo8(5) ; tmp48, ; 19 movqi_insn/2 [length = 1] movw r30,r28 ; , ; 47 *movhi/1 [length = 1] adiw r30,1 ; , ; 20 *addhi3/3 [length = 1] movw r26,r28 ; , ; 48 *movhi/1 [length = 1] adiw r26,6 ; , ; 21 *addhi3/3 [length = 1] 0: ; 22 movmem_qi [length = 4] ld r0,Z+ ; st X+,r0 ; dec r24 ; tmp48 brne 0b ; test.cpp:35: ) ldi r24,lo8(5) ; tmp49, ; 23 movqi_insn/2 [length = 1] movw r30,r28 ; , ; 49 *movhi/1 [length = 1] adiw r30,6 ; , ; 24 *addhi3/3 [length = 1] movw r26,r28 ; , ; 50 *movhi/1 [length = 1] adiw r26,11 ; , ; 25 *addhi3/3 [length = 1] 0: ; 26 movmem_qi [length = 4] ld r0,Z+ ; st X+,r0 ; dec r24 ; tmp49 brne 0b ; test.cpp:37: foo(rule); movw r24,r28 ; , ; 51 *movhi/1 [length = 1] adiw r24,11 ; , ; 28 addhi3_clobber/1 [length = 1] call _Z3fooI3seqIS0_I1AS1_ES1_EEvRT_ ; ; 29 call_insn/2 [length = 2] /* epilogue start */ ; test.cpp:38: } adiw r28,15 ; , ; 59 *addhi3/3 [length = 1] in __tmp_reg__,__SREG__ ; 60 movhi_sp_r/3 [length = 5] cli out __SP_H__,r29 ; , out __SREG__,__tmp_reg__ out __SP_L__,r28 ; , pop r29 ; ; 61 popqi [length = 1] pop r28 ; ; 62 popqi [length = 1] ret ; 63 return_from_epilogue [length = 1] .size _Z3abcv, .-_Z3abcv .ident "GCC: (GNU) 7.2.0" And this is the result if seq no longer inherits from seq_base (which is an empty class): .section .text._Z3abcv,"ax",@progbits .global _Z3abcv .type _Z3abcv, @function _Z3abcv: push r28 ; ; 19 pushqi1/1 [length = 1] push r29 ; ; 20 pushqi1/1 [length = 1] ; SP -= 3 ; ; 24 *addhi3_sp [length = 1] rcall . in r28,__SP_L__ ; ; 25 *movhi/8 [length = 2] in r29,__SP_H__ ; /* prologue: function */ /* frame size = 3 */ /* stack size = 5 */ .L__stack_usage = 5 ; test.cpp:35: ) ldi r24,lo8(97) ; tmp42, ; 5 movqi_insn/2 [length = 1] std Y+1,r24 ; MEM[(struct seq *)&rule], tmp42 ; 6 movqi_insn/3 [length = 1] ldi r24,lo8(32) ; tmp43, ; 7 movqi_insn/2 [length = 1] std Y+2,r24 ; MEM[(struct seq *)&rule + 1B], tmp43 ; 8 movqi_insn/3 [length = 1] std Y+3,r24 ; MEM[(struct seq *)&rule + 2B], tmp43 ; 10 movqi_insn/3 [length = 1] ; test.cpp:37: foo(rule); movw r24,r28 ; , ; 18 *movhi/1 [length = 1] adiw r24,1 ; , ; 11 *addhi3/3 [length = 1] call _Z3fooI3seqIS0_I1AS1_ES1_EEvRT_ ; ; 12 call_insn/2 [length = 2] /* epilogue start */ ; test.cpp:38: } ; SP += 3 ; ; 30 *addhi3_sp [length = 3] pop __tmp_reg__ pop __tmp_reg__ pop __tmp_reg__ pop r29 ; ; 31 popqi [length = 1] pop r28 ; ; 32 popqi [length = 1] ret ; 33 return_from_epilogue [length = 1] .size _Z3abcv, .-_Z3abcv .ident "GCC: (GNU) 7.2.0" Which seems to indicate that in avr backend, when a class inherits from another (be that trivial or not), named return value optimization no longer kicks in and all return types gets copied.