<table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Issue</th>
<td>
<a href=https://github.com/llvm/llvm-project/issues/70888>70888</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>
MSVC ABI name mangling for unnamed namespace types only based on input file spelling
</td>
</tr>
<tr>
<th>Labels</th>
<td>
ABI,
platform:windows
</td>
</tr>
<tr>
<th>Assignees</th>
<td>
</td>
</tr>
<tr>
<th>Reporter</th>
<td>
smeenai
</td>
</tr>
</table>
<pre>
In the MSVC ABI, types in unnamed namespaces have a hash of the file name appended to them in their type name mangling, so that a file-private class with the same name in two different source files doesn't compare equal in a string-based type name comparison. clang-cl seems to compute this hash based only on the file name as it was provided on the command line, so two files with the same name can end up with the same hash. Consider the following example:
```
> cd %TMP%\anon1
> type anon.cpp
namespace { struct Anon {}; }
void throwAnon() { throw Anon(); }
> clang-cl /EHsc /c anon.cpp
> cd %TMP%\anon2
> type anon.cpp
#include <stdio.h>
namespace { struct Anon {}; }
void throwAnon();
int main() {
try {
throwAnon();
} catch (Anon &) {
puts("Caught anon");
} catch (...) {
puts("Caught something else");
}
}
> clang-cl /EHsc anon.cpp ..\anon1\anon.obj
> anon
Caught anon
> clang-cl /EHsc anon.cpp ..\anon1\anon.cpp
> anon
> Caught something else
```
In the first case, we compiled both files passing `anon.cpp` as the file name, so the hashes were the same and the exception was incorrectly caught. In the second case, we compiled one file as `anon.cpp` and the other as `..\anon1\anon.cpp`, so the hashes differed.
I don't have an old version of MSVC around to compare its behavior, but it seems like its mangling behavior might have changed in VS 2019 16.2 as a fix for [this bug report](https://developercommunity.visualstudio.com/t/symbol-name-clash-with-anonymous-namespaces/480403). Using cl instead of clang-cl produces "Caught something else" in both cases, and from visually inspecting cl's generated assembly, the hash in the mangling seems to be based on the full path of the source file instead of just the path to it provided on the command line.
I doubt this is a particularly common pattern to begin with, and most users would be using build systems which pass paths to input files relative to the project root, so this shouldn't be an issue in practice, but it's still a deviation from modern MSVC behavior that seemed worth noting.
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJysVkuP4zgO_jXKhYjhyHkecqhHF7YPAywwu3OXJSZWryx5RSnp_PsFZSepdFXXZadQsGOJovjx8ZGKyB494l6snsXqdaZy6kLcU4_olZ21wVz23z2kDuGPP_96gafn70K-QLoMSGA9ZO9Vjwb4SYPSSNCpE4KCTlEH4VCOHqzDIgJqGNAbNJAC7_SsI3VoY1E5yvTKH531R76IWEwlUEXHfIj2pBKCdooIzjZ1RT_xsXKW1Z0DGHs4YESfgEKOerSAwAQkL-QmgQ79oCIC_jcrx6cUUIrWH-etIjbvZs0oaSn4iq_1x7l2QIg9MQbezQkhdZZGyOP54N0Fgv8VPYFNcFYEQwwna4pgkdGh75U34KzHK-5zmMz-BKdWHtAbyMMvu2xDBS_BkzUYx_uDc-Fs_RHwp-oHh6J5EvWrqK_PdT39j5_NN9AGhFz9649_CrkSqxflg1_cd4tzeK3SwzAu3-IPYvPMrsw6wZMPnr_F5lU0z8CvInwK1kDqYjizhJBbIXflXFmD--LDqWLXNQBCvn37B2l-619M-RKF_BKFkI312mWDIJoXSsaGqhPNt78Jo2iex03rE_TKvoM-rgMApHh5XCiLv1HEe2LzClol3YGQ29EcuX5UO-RE5aR8UfnYpQJbSPmlqqqqPhjHfx-UUegxdSW_HOHnaif_3n78PqLXiEBV3TJvfFeh_XE_WCCUr_eY_g_t9yx40M5fnwP9tHjK8_u18CMl0IpKSZ9HLrEODbQhdVNxD0zB_ghiXd_MWNdMFQ_ccSPDscSZFTDive6ZPPgDf2ockg2-0Iz1OsSIOrkL6AKigsk4Qh28-dS64KeLFX0wa7ompA7jtP-5K9f1R5MnWjbVg7PAhJGUx87hITgDJ4zEKMJhbDwqhuzNlXKZum0iaLFTJxsiX9XmxOw6UrOz_xklrs3kJgq95ViWu3Sn_BEN8_9ff4KsFztYrCvJuLjh_IRDiCBWz4Xd23yEiEOISaxehdx2KQ3EVCrfhHwzeEIXBozM5NnbdKlOlrJylDLTiA69kG9JyDe69G1wcw7qnPtYN2cGn7PjLn3INL_3UiHfltt6WTdC7ir4d8kTze2KEirDvrkl-BCDydx-v6hLxlkyj4NO7DMO5yGGHkZb3YV1D6jTeJOQG4IjeowqoQFFhH3rLmUCmKI6NfC7n2-tscVbLxxTOTsHg0q3qeBda34P6UemVPaLbAoc1K_a5Ydkym0a-7HlMA4qJquzU5FrIPR98Kw5YfSjlUfrSw-9-qMPlCATRoJzyM4wkFxc32brDNCFEkM8d1Z3pXyLpQWz9UNOU2FHdCrZE06jDmP4gTpBDCHdSsMSUMe3jBXQlvy3RLmMMkNUOlmN9_QuEaFknQMFBk9WlVovMeyDYVClXG7ZXqYnjgkaOIeYOvCBo1vNzL4xu2anZrhfrHfbbb3ZbTazbt-ucbdYbsxhUS8PcrttW7PerBetXGyXza7ezexe1rJZLOpF3dTrxaZaLZsFNrvlbrlYYbNUYlljr6yrnDv1VYjHWUG039Tb7XbmVIuOysApZZknpZAvQsrBqXQIsRfN09l6E87EW6vXWdyzonmbjySWtbOU6K462eRwfx1OHyfIUr8fRtRpei0j2i1D75EDGtDx6VmObv9Y5UebutxOxcwmTK_5FFwh3wpUrtyC9n8BAAD__8jksN8">