<table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Issue</th>
<td>
<a href=https://github.com/llvm/llvm-project/issues/135910>135910</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>
clang++ incompatibility with libstdc++ gcc4-compatible ABI on Windows
</td>
</tr>
<tr>
<th>Labels</th>
<td>
clang
</td>
</tr>
<tr>
<th>Assignees</th>
<td>
</td>
</tr>
<tr>
<th>Reporter</th>
<td>
jeremyd2019
</td>
</tr>
</table>
<pre>
This was first seen on Cygwin (x86_64-pc-windows-cygnus), where GCC is built with `--with-default-libstdcxx-abi=gcc4-compatible`, but I reproduced it on x86_64-pc-windows-gnu as well, so I decided to report here.
Start with a mingw-w64 gcc built without `--enable-fully-dynamic-string` configure argument, and possibly with `--with-default-libstdcxx-abi=gcc4-compatible`. It should be possible to switch to the gcc4-compatible ABI with `-D_GLIBCXX_USE_CXX11_ABI=0` if not built with that option.
The following test program aborts when built with `-O2`, unless built with `-std=c++20` or newer:
```c++
#include <stdio.h>
#include <string>
class foo
{
public:
foo() { m_str.assign("hello"); }
std::string m_str;
} bar;
int main()
{
printf("%ld - %s\n", __cplusplus, bar.m_str.c_str());
return 0;
}
```
Output of `clang++ -O2 -S -o test.clang.s test.cpp`
[test.clang.s.txt](https://github.com/user-attachments/files/19770539/test.clang.s.txt)
output of `g++ -O2 -S -o test.gcc.s test.cpp`
[test.gcc.s.txt](https://github.com/user-attachments/files/19770543/test.gcc.s.txt)
relevant difference:
```asm
leaq _ZNSs4_Rep20_S_empty_rep_storageE(%rip), %rdx
cmpq %rdx, %rcx
...
.section .bss$_ZNSs4_Rep20_S_empty_rep_storageE,"bw",discard,_ZNSs4_Rep20_S_empty_rep_storageE
.globl _ZNSs4_Rep20_S_empty_rep_storageE # @_ZNSs4_Rep20_S_empty_rep_storageE
.p2align 4, 0x0
_ZNSs4_Rep20_S_empty_rep_storageE:
.zero 32
```
vs
```asm
cmpq .refptr._ZNSs4_Rep20_S_empty_rep_storageE(%rip), %rcx
...
.section .rdata$.refptr._ZNSs4_Rep20_S_empty_rep_storageE, "dr"
.globl .refptr._ZNSs4_Rep20_S_empty_rep_storageE
.linkonce discard
.refptr._ZNSs4_Rep20_S_empty_rep_storageE:
.quad _ZNSs4_Rep20_S_empty_rep_storageE
```
relevant bit of libstdc++ header:
```c++
// Inhibit implicit instantiations for required instantiations,
// which are defined via explicit instantiations elsewhere.
#if _GLIBCXX_EXTERN_TEMPLATE
// The explicit instantiation definitions in src/c++11/string-inst.cc and
// src/c++17/string-inst.cc only instantiate the members required for C++17
// and earlier standards (so not C++20's starts_with and ends_with).
// Suppress the explicit instantiation declarations for C++20, so C++20
// code will implicitly instantiate std::string and std::wstring as needed.
# if __cplusplus <= 201703L && _GLIBCXX_EXTERN_TEMPLATE > 0
extern template class basic_string<char>;
# elif ! _GLIBCXX_USE_CXX11_ABI
// Still need to prevent implicit instantiation of the COW empty rep,
// to ensure the definition in libstdc++.so is unique (PR 86138).
extern template basic_string<char>::size_type
basic_string<char>::_Rep::_S_empty_rep_storage[];
# elif _GLIBCXX_EXTERN_TEMPLATE > 0
// Export _M_replace_cold even for C++20.
extern template void
basic_string<char>::_M_replace_cold(char *, size_type, const char*,
const size_type, const size_type);
# endif
```
`_GLIBCXX_EXTERN_TEMPLATE` is 1, and the issue manifests when `_GLIBCXX_USE_CXX11_ABI` is 0 and `__cplusplus` is <= 201703.
see msys2/MSYS2-packages#5329 for history of the investigation.
/cc @mstorsjo
</pre>
<img width="1" height="1" alt="" src="http://email.email.llvm.org/o/eJysV0tv4zgS_jXMpSBDpvzSwQfHSQYBpqcHnV5M714MiixJ7KFINUnF8fz6RUmKo7x6soMFElgSWV-9ya9ECLqyiFu2vGTLqwvRxdr57Xf02JwUT-f5ReHUafu11gGOIkCpfYgQEC04C_tTddQWGN88bFaH1SJpZXLUVrljSOSpsl1gPGd8D8caPcIv-z3oAEWnTYSjjjWwVZok9JQoLEVnYmJ0EaKSDw-JKDTLriopF4l0TSuiLgyyVUp4RRfhFjy23qlOogIdyZ7XVlS2AxHgiMaQXHBwCwqlVqggOkJwPgJZN2PpjqW7uyj8aJyARtvqmBxXC6iknNjtujiYjlYUBpOyM-aUqJMVjZZJiF7biq1SkM6Wuuo8gvBV16CNZISwCloXgi7M6Z-HYQa3EULtOqOgwEdAJK_CUUdZ01OsEV6Iwu7y9knr1eGXX28v99--Hf51d33Yf_s2nx92l7csu0rJAV2CdXGasViLCK6N2tkxYl9rhNIZ447aVhAxRGi9q7xoQBTOx0DZty-z_pmPqeyswfCqKEJULLuSjF8yfsl7W5wHi0f0LCOtJN3_jXvoE8-0laZTCCzbh6i0m9Usu35jqU_QsJLupBEhQOkcva4Jqe0Ko-WgCPoVvmE8B7a-hOYQop8NjdN_5jUa4xjnVOvZJbD11YAL0HuxY9lu0DjIsuxyWGfrKyjE07u2ERqhB9T8bAxA67WN5aCM8aVRkADjy8CWe9t_2sPhIFvTBfrv-0P42WCo7FUOiL19PaLH2HkL6ah7sPgxooM1n7vYdhFcSfmQRthqCDQknzkkd5C4PtezfmkWxpe2HQGWl9PVWXyIbHnF-KaOsQ0UFH7D-E2lY90VM-kaxm-6gD4RMQpZU6sExm9KbZB-5_l6nS6znPGbV7BDqNKdmxr8jrGVlO-a2q_9fwxdZI-GPoE-munR4L2wEZQuS_RoJb6oaBGafmtuUPxgaX74z293YXH4gi1PD3cHbNp4OnhsDyE6Lyq87tO79LodT1t6UQ8Dhmxawhg_jYuSFmezoYHzWUBJ_UyPRQiMLz6gcc84L45D9SkdpPCK8f3fCw4aK-MK8xHXgPEM2CL9KHDLhaHGTPMFOZs-UIb_XnhIQJrP_kLvWJpn_EVD3Ic3MzRGd-axbKOf_aNMvZ8Mr0QUjC_-B3iC5MpTXp5H-uMYg5zR9k9HtZnmj-lNdx8HOQf0RyfUh2r41QF0bpRC9109XoljY9co1E_uAoChb-HW1poAdNMaLenBhihs1IKiTMe-B48_Ou2JRTxboyKfIB1rLWsQHkFhqS0quNcC8OFtXDQBj2dewTNdwvmqvf729frLb4ev159-_3X39XqqhC7TtyEHrXpA1xaCl4zfjB7P54zfDJdMQlIzKYlmTJGf71-_3u-sOU1UYk8eGmwK9OEpRBSv_Rlkgk-sBoU3Gj0QhhJeBaKGwfUcYn--y_k60A4fw2HgWSRp1fDGeD6bwt51beuJIMSfRUYa4ScJnejqOd_T-wRZOoVw1Maca-OF_y9vb7Lz_O34-DGARVSoxjwTZZpcxkQ3WHYFPJ2v0-xXYHzF-OrdUgCWXcNgJT5E9BYiNq0hawaWUoig-yu9JzB7WRN_uB6vcZ4BGl0C43N4h9dNIxvJdzKemGLr8R7te31C_UcJ2H_-A_reJeb8oj-iA7SByC7tfKpWKtZnvTsLjsaAzuofHVKF_P4FNqt5tjnn_qXv73ndJ0f_hYd4apEkf7aRDp_x6Y0DaBiAXgTyA2kanb9-6AeJwyfCNELiQTqjgGL6vCJ7B1_6d-_00Kvwcw-eozO-oWVgfNfX-TkQfE-TR4jQS_erw2k8_Rt2vCE0-ZRP4mGVLl8f0myVvnus0fwQYP448lBV6BA6hEZYXWJ4nAymGM-rdUBIe3HaNSG5w9Kz7hrnkYAITTgFzvjNp7t_3_GkFfJPURE_y5YZz_uE1JoSf3osbG3vMURdiclgQ8elJPLR0Nbw3cGF2mYqz3Jxgdv5erFYrzfZZn5Rb3Mp87QUxUYu5stFVirM07xYLYVALjYiv9BbnvJlupiv0kWWL-YzVOlS8VLN5-t8zldLtkixEdrMjLlvZs5XF32stvNsmc_TCyMKNKEf0zkf2Tinid1vSSApuiqwRWp0iOEJIupocDsl79o-ToLa6DiOn89v1rfmRWfhj2Givui82f6EG5Pu8SdpvfuOMjJ-0_vS8-PBnfst_28AAAD__596MoU">