This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug c++/66666] ARM wrong copy constructor address on multiple inheritance
- From: "jgreenhalgh at gcc dot gnu.org" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: Fri, 03 Jul 2015 15:57:27 +0000
- Subject: [Bug c++/66666] ARM wrong copy constructor address on multiple inheritance
- Auto-submitted: auto-generated
- References: <bug-66666-4 at http dot gcc dot gnu dot org/bugzilla/>
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66666
James Greenhalgh <jgreenhalgh at gcc dot gnu.org> changed:
What |Removed |Added
----------------------------------------------------------------------------
CC| |hubicka at gcc dot gnu.org
--- Comment #17 from James Greenhalgh <jgreenhalgh at gcc dot gnu.org> ---
This feels very similar to pr65236. For your second testbench, we can look at
the output assembly for the fixup thunk for MyObject->getTestReference() for
arm:
---
_ZTv0_n16_N8MyObject16getTestReferenceEv:
.fnstart
.LFB1058:
@ args = 0, pretend = 0, frame = 16
@ frame_needed = 1, uses_anonymous_args = 0
stmfd sp!, {r4, fp, lr} @,
.save {r4, fp, lr}
.setfp fp, sp, #8
add fp, sp, #8 @,,
.pad #20
sub sp, sp, #20 @,,
str r0, [fp, #-16] @ .result_ptr, .result_ptr
str r1, [fp, #-20] @ this, this
ldr r3, [fp, #-20] @ vptr.4, this
ldr r3, [r3] @ vtableaddr.5, *vptr.4_4
sub r3, r3, #16 @ vtableaddr.5, vtableaddr.5,
ldr r3, [r3] @ vcalloffset.6, *vtableaddr.5_6
mov r2, r3 @ D.25213, vcalloffset.6
ldr r3, [fp, #-20] @ tmp116, this
add r3, r3, r2 @ D.25214, tmp116, D.25213
ldr r4, [fp, #-16] @ tmp117, .result_ptr
sub r2, fp, #28 @ tmp118,,
mov r0, r2 @, tmp118
mov r1, r3 @, D.25214
bl .LTHUNK0 @
ldr r3, [fp, #-28] @ tmp119,
str r3, [r4] @ tmp119, <retval>
ldr r0, [fp, #-16] @, .result_ptr
sub sp, fp, #8 @,,
@ sp needed @
ldmfd sp!, {r4, fp, pc} @
.fnend
---
We allocate some stack space for the result (tmp118) and hand it off to the
called function as the return value. The copy constructor is invoked as a copy
to this temporary rather than to the stack slot reserved for
TestReference_clone. When we do return to main, we just do a simple word-wise
copy of the object.
As to your original bug, the root cause is similar, the copy constructor for
list wants to set up pointers to the final list node (I think). But we've given
it an address on the stack which we will soon clobber when we start executing.
You can see the mismatch in expectations if you build an empty list, and check
it is empty with list->empty rather than size.
(gdb) print this->_M_impl._M_node
$3 = {_M_next = 0xbeffef08, _M_prev = 0xbeffef08}
(gdb) print &this->_M_impl._M_node
$4 = (std::__detail::_List_node_base *) 0xbeffef2c
As to why this is target specific... My untested hunch is you'll see it on the
following targets { vax, stormy16, pa, nds32, mmix, frv, cris, arm } - those
being the targets which #define TARGET_ASM_CAN_OUTPUT_MI_THUNK
default_can_output_mi_thunk_no_vcall and go through the generic, heavyweight,
(and apparently broken) thunk code. Enabling return slot optimization would
protect these targets against the current issue - that of the thunk code
constructing a temporary object in a soon-to-die location on the stack.
With all that said, I think backporting Honza's trunk patch for pr65236 looks
like a reasonable thing to do. Though, I'm CCing Honza for his input.