https://gcc.gnu.org/bugzilla/show_bug.cgi?id=120125

--- Comment #6 from Nathaniel Shead <nshead at gcc dot gnu.org> ---
Created attachment 61367
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=61367&action=edit
clone-4_b.s

This is the testcase I've been using:

$ cat ~/t/modules/clone-4_a.C
// PR c++/120125
// { dg-additional-options "-fmodules -fdeclone-ctor-dtor" }
// { dg-module-cmi M }

export module M;

void foo();
export extern "C++" template <typename _Tp> struct __shared_ptr {
  __shared_ptr() { foo(); }
};

template class __shared_ptr<int>;

$ cat ~/t/modules/clone-4_b.C
// PR c++/120125
// { dg-additional-options "-fmodules -fdeclone-ctor-dtor -fno-module-lazy" }

import M;

int main() {
  __shared_ptr<int> s;
}

$ ./xg++ -B. -fmodules -std=c++23 -fdeclone-ctor-dtor -S ~/t/modules/clone-4_*

With modules, typically an explicit instantiation emitted in a named module
should be considered as an extern template in importers; there's no need to
emit it there because we know a definition already exists.

The assembly for 'clone-4_a.s' that's generated seems reasonable, and matches
what I would expect in a non-modules context; we emit one declaration

_ZN12__shared_ptrIiEC2Ev:
        pushq   %rbp
        movq    %rsp, %rbp
        subq    $16, %rsp
        movq    %rdi, -8(%rbp)
        call    _ZW1M3foov
        nop
        leave
        ret

However, 'clone-4_b.s' (attached) doesn't look right.  It emits a declaration
for _ZN12__shared_ptrIiEC2Ev, and that declaration doesn't match:

_ZN12__shared_ptrIiEC2Ev:
        pushq   %rbp
        movq    %rsp, %rbp
        subq    $16, %rsp
        movq    %rdi, -8(%rbp)
        movq    -8(%rbp), %rax
        movq    %rax, %rdi
        call    _ZN12__shared_ptrIiEC4Ev
        nop
        leave
        ret

It seems like the '-fdeclone-ctor-dtor' is being ignored here somehow, since we
also generate all the other constructor clones, I assume because of an
interaction with how the modules streaming rebuilds the clones on stream-in.

This should be fine for 14 (where we didn't handle ABI for explicit
instantiations properly anyway), since whichever definition of
_ZN12__shared_ptrIiEC2Ev is chosen by the linker should still behave the same. 
But for 15/16 I would like to avoid this, though I probably won't be able to
look properly at this until next week.

Reply via email to