<table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Issue</th>
<td>
<a href=https://github.com/llvm/llvm-project/issues/142187>142187</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>
C++ mangling/ABI mismatch vs GCC
</td>
</tr>
<tr>
<th>Labels</th>
<td>
clang
</td>
</tr>
<tr>
<th>Assignees</th>
<td>
</td>
</tr>
<tr>
<th>Reporter</th>
<td>
mstorsjo
</td>
</tr>
</table>
<pre>
https://godbolt.org/z/TK7Yr8b6c shows a difference in C++ mangling, or what symbol reference gets generated, between GCC and and Clang.
```c++
#include <type_traits>
namespace rocket {
template<typename charT>
class basic_tinyfmt;
using tinyfmt = basic_tinyfmt<char>;
using ::std::enable_if;
using ::std::is_arithmetic;
using ::std::is_same;
template<typename charT, typename valueT,
typename enable_if<is_arithmetic<valueT>::value
&& !is_same<valueT, charT>::value
>::type* = nullptr>
inline
basic_tinyfmt<charT>&
operator<<(basic_tinyfmt<charT>& fmt, valueT value); //...
extern template tinyfmt& operator<<(tinyfmt&, signed char);
extern template tinyfmt& operator<<(tinyfmt&, signed short);
extern template tinyfmt& operator<<(tinyfmt&, signed int);
extern template tinyfmt& operator<<(tinyfmt&, signed long);
extern template tinyfmt& operator<<(tinyfmt&, signed long long);
} // namespace rocket
void
do_format(::rocket::tinyfmt& fmt, int value)
{
fmt << value;
}
```
```console
$ g++ -S -o - cxx-mismatch.cpp -O2
[...]
_Z9do_formatRN6rocket13basic_tinyfmtIcEEi:
jmp _ZN6rocketlsIciLPv0EEERNS_13basic_tinyfmtIT_EES5_T0_@PLT
$ clang++ -S -o - cxx-mismatch.cpp -O2
_Z9do_formatRN6rocket13basic_tinyfmtIcEEi:
jmp _ZN6rocketlsIciTnPNSt9enable_ifIXaasr13is_arithmeticIT0_EE5valuentsr7is_sameIS2_T_EE5valueEvE4typeELPv0EEERNS_13basic_tinyfmtIS3_EESA_S2_@PLT
```
The generated function name is the same in both cases, `_Z9do_formatRN6rocket13basic_tinyfmtIcEEi`, but GCC references a function named `_ZN6rocketlsIciLPv0EEERNS_13basic_tinyfmtIT_EES5_T0_` while Clang references a function named `_ZN6rocketlsIciTnPNSt9enable_ifIXaasr13is_arithmeticIT0_EE5valuentsr7is_sameIS2_T_EE5valueEvE4typeELPv0EEERNS_13basic_tinyfmtIS3_EESA_S2_`; this can end up causing undefined references. Both symbols demangle into the same, `rocket::basic_tinyfmt<char>& rocket::operator<<<char, int, (void*)0>(rocket::basic_tinyfmt<char>&, int)`.
Issue originally encountered by @lhmouse.
</pre>
<img width="1" height="1" alt="" src="http://email.email.llvm.org/o/eJzEVlGP4jYQ_jXmZQQyTgjwwANkQ4V6up4OHtp7iRxnSHx1bGQ77NFfXzkJsMv1Vtdqpa6yApxvvpnxjL8xd05WGnFFZhsyexrx1tfGrhrnjXVfzagw5WVVe39yJFoTtiVsW5myMMpPjK0I2_5F2Pbw6_wPuygSAa42zw44lPJ4RItaIEgNKWEbwjbQcF0pqSvCUjAWnmvuwV2awiiweMVX6B1UqNFyj2WAFuifETX8kqbAddn9p4rrakLoOjwJ7R_R-wlLLJJaqLZEIFHqLyfMveXSOxJlhK41b9CduECwRvyJHsh803N5bE6KexysAhBEze2hNxSKOwcFd1LkXurLsfEkGkxbJ3UFwyqQ6OkRlwaiwNNZ9PCwq9Ha-bL_gpoXCnN5fAMjXc6t9HWDXoq3cY43eIvvx6mxFG4rZ65aDEvB4rr4Iqz0wX06GIS0gtfuJxC6BsISwhIgbHqLJL2x3zf1bhWM4LYUnBO27jZSt0qdvO1rILWSOoD_aXs7SpYQujan0EHGkigND1u8AYewwtIh-f6DsCWJNgB9008mQ7PhN49Ww3Uzr_UOJN95vL8L5N1BK7vEe-73YHO1sf796KR-RzJlwlF_T7bXlOGZP10rBI-HukecjSwJXZcmPxrbcE_You-vAdT32j2YoROk9vc26PqyUwgAgP50h1AHRLQZEE8vxehRm4x2RmGnTTFUgyKO9zA2MAbx7du4ka7hXtQTcTrB-DcWoLNNaLxZIM6_LG9JfP6Y9OFPo1ddvRNZJkNKfaTh72tzgvzLFa_cTsgPn840y7LPH_f5o_0hz7L9LD_QnMT004fDkASLQQTB_bmo3y_Sg_70ce-XN_nZ_c65s9PolQbtDjTPsllXC-2dnQ9ys9uz_HB7k52zOEhK9kb2-yikv8737EX6r-t5qPE-nODYauGl0V3vgXTgawTXfddQGF-D4A5daCiS0J_fl4R2c6_13cy7zcYwWV-5LHva_1DdhMJzLRX2g_Rfuvgfy5LQIMq-lg4E14C6hPYEgvcTsNUlHmVQi3tCE9iEQvT3DAcldreQUCFvbvUaKvRSE340vFkCL2EP4jXgegXpWNmikyC2JmxJO4LFz7m5kSxJQofps3OuRTBWVlJzpS6AWphWe7RYQnEBElNVN6Z1OBiMylVULqMlH-FqOo8XCUsW8WJUrzCO5jErp_OlKGZJEc_LGAsxo4zjMk7EcSRXjLIZnUV0Oo9pvJgsGE6nyylfCMbndClITLHhUk2UOjfhNjiSIbrVNGbTxXykeIHKdfdKxgb1YOGKaVfBYFy0lQvhSufdncJLr3D1_YVxu97s4Ko1cHbhYIxaqx7vptLXbTERpiFsG0iHj_HJmq8oPGHbLkhH2HaI87xifwcAAP__5haIUw">