This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Bug c++/66666] ARM wrong copy constructor address on multiple inheritance


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.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]