<table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Issue</th>
<td>
<a href=https://github.com/llvm/llvm-project/issues/54425>54425</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>
multiversioned static functions collision across translation units
</td>
</tr>
<tr>
<th>Labels</th>
<td>
new issue
</td>
</tr>
<tr>
<th>Assignees</th>
<td>
</td>
</tr>
<tr>
<th>Reporter</th>
<td>
chrocapix
</td>
</tr>
</table>
<pre>
So, I was playing around with multi-versioned functions and, if I understand correctly, if there are two static multi-versioned functions:
- with the same name
- in separate compilation units,
one of them doesn't make its way to the final executable, and any call to it becomes a call the other.
Example ([static-mv.zip](https://github.com/llvm/llvm-project/files/8288671/static-mv.zip)): `foo.c`
```
__attribute__((target("default"))) static const char* boom(void) { return __FILE__ " default"; }
__attribute__((target("avx"))) static const char* boom(void) { return __FILE__ " avx"; }
const char* foo(void) { return boom(); }
```
`bar.c`:
```
#include <stdio.h>
__attribute__((target("default"))) static const char* boom(void) { return __FILE__ " default"; }
__attribute__((target("avx"))) static const char* boom(void) { return __FILE__ " avx"; }
const char* foo(void);
const char* bar(void) { return boom(); }
int main(void) {
puts(foo());
puts(bar());
}
```
Compile & run with `clang *.c && ./a.out`
Expected output (assuming avx is available):
```
foo.c avx
bar.c avx
```
Actual output:
```
bar.c avx
bar.c avx
```
We called from `foo.c` a static function defined in `bar.c`!
Tested with clang 10.0.0, 11.0.0 (from ubuntu in WSL2) and 13.0.0 (compiled by me from git.)
Looking at `nm a.out | grep boom`, it seems to be a name mangling issue:
```
0000000000201190 t boom
0000000000201210 t boom
00000000002011a0 t boom.avx
0000000000201220 t boom.avx
0000000000201020 i boom.ifunc
00000000002011b0 W boom.resolver
```
I would expect to see `boom_foo` and `boom_bar` or something to that effect.
Same issue with compiling the files as C++ with `clang++`:
```
$ clang++ *.c && ./a.out && nm a.out | grep boom
clang-13: warning: treating 'c' input as 'c++' when in C++ mode, this behavior is deprecated [-Wdeprecated]
clang-13: warning: treating 'c' input as 'c++' when in C++ mode, this behavior is deprecated [-Wdeprecated]
bar.c avx
bar.c avx
0000000000201190 t _ZL4boomv
0000000000201210 t _ZL4boomv
00000000002011a0 t _ZL4boomv.avx
0000000000201220 t _ZL4boomv.avx
0000000000201020 i _ZL4boomv.ifunc
00000000002011b0 W _ZL4boomv.resolver
```
`g++` (9.4) emits two different names/aliases and the expected output:
```
$ g++ *.c && ./a.out && nm a.out | grep boom
foo.c avx
bar.c avx
00000000000017b9 t _ZL4boomv
0000000000001845 t _ZL4boomv
0000000000001813 i _ZL4boomv._GLOBAL____Z3barv.ifunc
0000000000001876 i _ZL4boomv._GLOBAL____Z3foov.ifunc
00000000000017ca t _ZL4boomv.avx
0000000000001856 t _ZL4boomv.avx
0000000000001813 t _ZL4boomv.resolver
0000000000001876 t _ZL4boomv.resolver
```
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJztV0tv4zYQ_jXyhYggUX7p4EOexQIBetgCAfYiUBJts0uJBkXZcX99v6H8kJPIyaI99FBFkSlyODOcxzej3JT7xXcT8Hv2je1EwzZa7FW9YsKati7ZTrk1q1rt1M1W2kaZWpZs2daFw7Bhoi5pq1piN8hB4TDFCmOtLJzeHxbdWloJlpK5nWGgcaoY5hokt0H0EES3N6yTj-2sEZVkNR6nJVWzRm6EFU5CYLVRWtB26KFcA8EdYfeEAGa8HhUrjWzqgM8cq8RPyUCMg--ZM17OUtVCM_kqi9aJXEs6AR1J1HtWCK2JTjmWS4iUMMBhEjsNnTLsS-2ej6-i2mjJAj4PJnfd4W-qbfiX2gSTB8yundv4Q_Mn3CucuM1DsMeL1tvjz83Gmj9hVLwulZY44dOcz-fTWYzRJVee0p3csmAaLY0JC_weNMKgu_1rlgnnrMpbJ7OM9ONzJ-xKOj_mpVwKOAmjA0ueHp1XwE-OFWthA37LckPazrdGlUQTzO6Yla61Ncuyp2_Pj1mG03PW45fcgerhS1qI7eu_psGBV19697zkBqN9zOwgxpu3z-PSrBjkwnZmP8byWxKeqLrQbYm4SO4bVyoTroPksa_T_975gndA_RFNTj-_4kH_VDWBgqovt3ZrDNemJWSZdwoc0-z9eif8zfpgsPjnvQcwAokps23d4R5oCi0AxjhRWNAaLYfIdxGa1r1hcUSbDUACcAoCqEOoI5qmrTymb1-ZAmZtBbDSY1s6FJ8eNrxD_KsP5_Prh0e4LVwL6OzkDvF9w-g63xfp0ZVqgzVVH82Au4dAO1YNCl9FZQRloZ9_PO7r-IdsyDbeup1p4yjEH6F8HNOIDOaltXlbu5bYvXx_pgD3ZSBOjkRdyQGzfM9QmvweYHdIRu1JfDbmp7e9I7XqinnXIazu2crKTRePU68AykojZdVQiclRLn25QzzWK00cFNwoh-wanS4exXEaMddxfr_I4yuLsTguhienXO7mnxDgn6mOQJFvPhKSR-ylI7GyMRotwIdnQkNiWl2iGFNIk1VgHu9cbM0oCSkQ4JTjFOUdpoxlDYqzW5PVfFmH8eVyCSYhY33nfCcDe7seQsL71G_zrYCmCt-w-4Df4b5Mym7uKsSPWY9yIImPEwOR0UEbcbmJEyrpO2FrKEhDZyVSwMPDrMA_YpUyHgp3E14_TO_WsqY4Ph6jMqVva2CgBoG2FlsFk2Fcyg3aNkEZgk7l5uX8To3Kf02V61DyQUJkP57HZNTtYFZco-hS40RxNT8-o-qS5Ex1PVPOdFfT5TR5Dk3CqTQcE3jJihpdar9LhVSwEqWO8IX6SKGVaKTv5n3gy8saci3A_3lwX680Ue-KZ3l6zUmgmI8nn1HEyYXps9-ef7-7fc5w_UggfMAZtHM2Hd6JUwzvnBXis6Ag_pPpV6igvxsMiXcKD5OenDkqF0mZJqkYOeW0XPjvsvNn2Zs62wAktVa0yERhTYOgsqJu-h9fo9bqxS9_1XgcpnCcjMd8Mlov5DJJizSfReNlmaQ85dPpNBVzHufLKFnmfIQmRupmAYBA21jL3aFEooWcPIzUgkfIxiSexbNJymdhzMsoT-dgOJnMJ3kUjCOJZk-HpEdo7GpkF16lvF01WMQhXXNeRBelVrWUXhz4i9atjV0Ua2sKsVGvIy984ZX_G-zjc_U">