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

            Bug ID: 81855
           Summary: [mingw-w64] dllexport-ed explicit template
                    instantiation has no symbol in DLL when the compile
                    unit has non-template symbol
           Product: gcc
           Version: 7.1.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: lanxingcan at gmail dot com
  Target Milestone: ---

I'm cross building a library for Windows, but encounterd an issue about
dllexport and explicit template instantiation.

I tested with MinGW-W64 GCC/7.1.0 cross compiler on either macOS serria (from
homebrew/core/mingw-w64) as well as Fedora 26 (from stock repository).

Here is a small reproducible.

test.cpp:
```cpp

template<typename T>
struct __declspec(dllexport) Template
{
        ~Template() noexcept(false) { throw 1; }
};

extern template struct __declspec(dllexport) Template<void>;
template struct Template<void>;

#ifdef WITH_NON_TEMPLATE

struct __declspec(dllexport) NonTemplate
{
        ~NonTemplate();
};

NonTemplate::~NonTemplate() = default;
#endif

```

Compiles with:
x86_64-w64-mingw32-g++ test.cpp -shared -o libtest1.dll
-Wl,--out-implib,libtest1.dll.a
x86_64-w64-mingw32-g++ test.cpp -DWITH_NON_TEMPLATE -shared -o libtest2.dll
-Wl,--out-implib,libtest2.dll.a

Check exported symbol in libtest1.dll : 
```
$ x86_64-w64-mingw32-objdump -d libtest1.dll.a | x86_64-w64-mingw32-c++filt
In archive libtest1.dll.a:

d000005.o:     file format pe-x86-64


d000002.o:     file format pe-x86-64


d000004.o:     file format pe-x86-64


Disassembly of section .text:

0000000000000000 <Template<void>::~Template()>:
   0:   ff 25 00 00 00 00       jmpq   *0x0(%rip)        # 6
<Template<void>::~Template()+0x6>
   6:   90                      nop
   7:   90                      nop

d000003.o:     file format pe-x86-64


Disassembly of section .text:

0000000000000000 <Template<void>::~Template()>:
   0:   ff 25 00 00 00 00       jmpq   *0x0(%rip)        # 6
<Template<void>::~Template()+0x6>
   6:   90                      nop
   7:   90                      nop
```

Check exported symbol in libtest2.dll:
```
$ x86_64-w64-mingw32-objdump -d libtest2.dll.a | x86_64-w64-mingw32-c++filt 
In archive libtest2.dll.a:

d000005.o:     file format pe-x86-64


d000002.o:     file format pe-x86-64


d000004.o:     file format pe-x86-64


Disassembly of section .text:

0000000000000000 <NonTemplate::~NonTemplate()>:
   0:   ff 25 00 00 00 00       jmpq   *0x0(%rip)        # 6
<NonTemplate::~NonTemplate()+0x6>
   6:   90                      nop
   7:   90                      nop

d000003.o:     file format pe-x86-64


Disassembly of section .text:

0000000000000000 <NonTemplate::~NonTemplate()>:
   0:   ff 25 00 00 00 00       jmpq   *0x0(%rip)        # 6
<NonTemplate::~NonTemplate()+0x6>
   6:   90                      nop
   7:   90                      nop
```

the symbols for `Template<void>` is anyway missing in libtest2.dll. 

I'm confusing its behavior and believe it's a bug.

Reply via email to