<table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Issue</th>
<td>
<a href=https://github.com/llvm/llvm-project/issues/87515>87515</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>
clang-cl and Windows headers define conflicting versions of _m_prefetchw
</td>
</tr>
<tr>
<th>Labels</th>
<td>
</td>
</tr>
<tr>
<th>Assignees</th>
<td>
</td>
</tr>
<tr>
<th>Reporter</th>
<td>
davidben
</td>
</tr>
</table>
<pre>
We got a report in BoringSSL of a conflict between some Windows headers and clang-cl:
https://bugs.chromium.org/p/boringssl/issues/detail?id=717
In short, if you build the following with MSVC's STL, clang-cl, and C++20...
```
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
extern "C++" { // Yes this is odd, see below for why
#include <memory>
}
int main() {}
```
The following error comes up:
```
c:\src\header-conflict>cmake -GNinja -B build -DCMAKE_C_COMPILER="c:/Program Files/Microsoft Visual Studio/2022/Professional/VC/Tools/Llvm/x64/bin/clang-cl.exe" -DCMAKE_CXX_COMPILER="c:/Program Files/Microsoft Visual Studio/2022/Professional/VC/Tools/Llvm/x64/bin/clang-cl.exe"
-- The C compiler identification is Clang 17.0.3 with MSVC-like command-line
-- The CXX compiler identification is Clang 17.0.3 with MSVC-like command-line
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: c:/Program Files/Microsoft Visual Studio/2022/Professional/VC/Tools/Llvm/x64/bin/clang-cl.exe - skipped
-- Detecting C compile features
-- Detecting C compile features - done
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: c:/Program Files/Microsoft Visual Studio/2022/Professional/VC/Tools/Llvm/x64/bin/clang-cl.exe - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Configuring done (3.8s)
-- Generating done (0.0s)
-- Build files have been written to: C:/src/header-conflict/build
c:\src\header-conflict>ninja -C build
ninja: Entering directory `build'
[1/2] Building CXX object CMakeFiles\test.dir\test.cc.obj
FAILED: CMakeFiles/test.dir/test.cc.obj
c:\PROGRA~1\MICROS~3\2022\PROFES~1\VC\Tools\Llvm\x64\bin\clang-cl.exe /nologo -TP /DWIN32 /D_WINDOWS /GR /EHsc /Zi /Ob0 /Od /RTC1 -std:c++20 -MDd /showIncludes /FoCMakeFiles\test.dir\test.cc.obj /FdCMakeFiles\test.dir\ -c -- C:\src\header-conflict\test.cc
In file included from C:\src\header-conflict\test.cc:5:
In file included from C:\Program Files\Microsoft Visual Studio\2022\Professional\VC\Tools\MSVC\14.39.33519\include\memory:14:
In file included from C:\Program Files\Microsoft Visual Studio\2022\Professional\VC\Tools\MSVC\14.39.33519\include\xmemory:12:
In file included from C:\Program Files\Microsoft Visual Studio\2022\Professional\VC\Tools\MSVC\14.39.33519\include\limits:15:
In file included from c:\PROGRA~1\MICROS~3\2022\PROFES~1\VC\Tools\Llvm\x64\lib\clang\17\include\intrin.h:20:
In file included from c:\PROGRA~1\MICROS~3\2022\PROFES~1\VC\Tools\Llvm\x64\lib\clang\17\include\x86intrin.h:19:
In file included from c:\PROGRA~1\MICROS~3\2022\PROFES~1\VC\Tools\Llvm\x64\lib\clang\17\include\mm3dnow.h:14:
c:\PROGRA~1\MICROS~3\2022\PROFES~1\VC\Tools\Llvm\x64\lib\clang\17\include\prfchwintrin.h(50,1): error: declaration of '_m_prefetchw' has a different language linkage
50 | _m_prefetchw(volatile const void *__P)
| ^
C:\Program Files (x86)\Windows Kits\10\\include\10.0.22621.0\\um\winnt.h(3541,1): note: previous declaration is here
3541 | _m_prefetchw (
| ^
1 error generated.
ninja: build stopped: subcommand failed.
```
(This is MSVC's clang-cl, but the reporter also can repro on Clang 18.)
The significance of C++20 mode seems to be that, in older C++ versions, `<windows.h>` does not pull in the Windows copy of the intrinsic. I have not determined why yet. The underlying conflict is language-independent, which is what Windows declares `_m_prefetchw` as:
```
#ifdef __cplusplus
extern "C" {
#endif
...
VOID
_m_prefetchw (
_In_ volatile CONST VOID *Source
);
...
#pragma intrinsic(_m_prefetchw)
```
Whereas Clang declares it this way, with no `extern` block:
```
static __inline__ void __attribute__((__always_inline__, __nodebug__))
_m_prefetchw(volatile const void *__P)
{
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wcast-qual"
__builtin_prefetch ((const void*)__P, 1, 3 /* _MM_HINT_T0 */);
#pragma clang diagnostic pop
}
```
BoringSSL needs to wrap the C++ bits in its headers in `extern "C++"` to undo other projects including our headers inside `extern "C"` blocks, which was too common to clear out. (People don't expect `<openssl/foo.h>` to include C++ code.) C++ headers, including even some STL impls if I recall, do not react well to being included under `extern "C"`. So we have to use `extern "C++"` to restore the default language linkage. However, it seems that restoring the default language linkage explicitly is not quite the same as leaving it undecorated:
https://godbolt.org/z/8r8Mzhbvr
https://godbolt.org/z/aKoGzMof1
Bizarrely, even the static mismatch seems it would be fatal, yet it isn't here. Does clang-cl special-case this somehow?
https://godbolt.org/z/T84eq1j6q
I'm not sure what the right fix is, but given clang-cl is meant to coexist with Windows headers, I suspect the fix should be on the Clang side, one way or another. I'm not sure whether that means to give its intrinsics C linkage, add more quirks to this mismatch allowance, defer defining the intrinsics to Windows headers, or something else altogether.
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJzMWU9v2zgW_zTM5cGCTEW2c8jBUeKOMU1aNEHb3YtASU8WG4p0SSpOepjPvniULdtpmskCg90WjW1JfOTv_f8j4ZxcacRzll6w9PJEdL4x9rwSD7IqUJ8Upno6_4KwMh4EWFwb60FquDBW6tXt7XswNQgoja6VLD0U6DeIGpxpEb5IXZmNgwZFhdaB0BWUSujVqFQsmbP4ksXzxvu1oyu-YHxRdCsXlY01rezayNgV44s13Q_nOacYX0jnOnSMLyr0QiqWLGTFksvpeNrv2H8uNbjGWM94BrKGJ9NB0UlVgW8QaqOU2Ui9go30DVzffs4Ynzq4vXtP6weQPAugM8YvGL_gcRRF2zMm8fZ_f8mTCmupEb4sbxKev7-a3-Tzm8v8-mp-MyyRulRdhcCSbNOLJmpYcnWIGh89Wg2M8-2ZjHNg0wuAXj7wL3TgG-lAOjBVRQgdIhSozAZqY2HTPL10YIutsU_706aXh8dK7aEVUjM-Y_yMDtwveMZp-Lw7kiFaayyUpkUH3XrQ7Iv0JT1OM2dLlma9YYx21sOSq7IV9wijdzdSfxMwutjqbHSZXc__vMqzPPtw_XH5_uoTSy4Z52VvOB-tWVnRwkKqYBjXsrTGmdrDZ-k6oeDWd5U0jC94zHlPUKNz0mhBFkXaX9wZo4j4vXpoGV88Tk7J7kgmi509RPiIpJABztevvwWgXrSjEZBeMtLEWiq0ICvUXtayFF4aTSaTESGMp1EcJXvbHyl5j0TWCl2NlNR4vOPXr__onpfosfRkOQdY5xdLkLo2b1sFI6jMwZZZg-V9b__G3h8TsWQO_we9wAjcvVyvsXqNJahR-M6ie9Oi52wfrD3U0WuyfGndG6R5QPZbynOP71WJvrDsJ-aNruWqo3wTHgDjsySaOcbPhjXvUKMV_nBJHMVHSy5C4KpJMNCIBwrRqGFjpfeowRuSYtZLkYIhXzwPhpQMpaoOY-nfBE_dB80MDgjDPTrrSnvseZIWS2_sE7BJ3K_ku8yZXoxJVyy97PHvZGaKb1h6yK7FPfa6TjOPzkeVtLufZRmZ4lu_0WK-fH91GVjck_DFQLL9eUiy5e3jpw_vPs3_GrM0u15mnz7c_pWwNAvWEx4urm7Dw88ZS7PectIsWE6akeWkGVlOmh1ZDuMLbZRZGRjdfYSQSy9Dog6_8i_Lm8sPX27p4t0n-rz6w5X0_W9Jnx-KOHxV9PnpLhvDyPmKJfNyVxbA6PoyPHWN2Sz7pOvoemHeILKwsPrVQhiVQFb5muqH7YbSh-wOtum_gtqa9q07JPN0yOCvbnTs-2n2K9_fa-_Q959pMFRgaTY-jZKzKEnS8RlLs-2xLB2ql_n49PcD97hHx38_dEq20lOBPf47vf5jHqhksfNAAjY9wiO1t1JT4Tvn8W-B6HE2OQA1PvstQLVtUmmz6SHtjf5_c_ja1mWzGYTCZ2nMeDam9JbM-3KfflRYKmH7OtDUwPg0b_O1xRp92WwYn0IjHAioZF2jRe2BjuvECkFJfS9W26QLaQxsmsEx9ezBKOFJ_qXRzsODkRRj53n-ccizEP4RLUu3nc1LLkb5-XE2IbI023Wlf5JbpNk4Zml2xP04juKI8wkfR9tnHcltI7X2QRpJejo-kIc2Hul7bfFBms4dyUVS-2t3jBLlT6wSul-yM952V6u-4sAqepbX-wbJeRMqo2QOriu2VTfUQqqB4sVGjvHZ3babHJrgw-636HxomPvOHy0I5QyUQtMda8DoXfk_iwat7HtEJ1c69Aq6RDKRoZGG1lRInWvrwBsoEHwj-l5dg1EV2t1aeEBLgc_RQ0L_rHmexFAZdKQFWHdK0QaEeKfm0qyf6Gi611u0k2UEy74oI6oKPdpWaqyoeYYn9FFoezpdoVVPVAMN8w3pBhseSV3hGjX1Q4Rt08iyoQWbRvjh-N4WyAQn8ZF9T2IQ7vVemTr4usIa8rxcq87R3wtjgjAgGChQV7Lur4ZpxecPy203_2u7y5c6h8Hlsg83t3dAdORyt6azJe7XBsO_eHYI48nailUr9mJmfHbs02evmOIX8hOxaycHuUnfzzs24ilImfpLbUicvRBIkIUy5f1else7Oy-8LCHPpaYuNM_7SJLnwnsri85jnoe5xyzPhdqIJzespAPzXJsKi25Fl2cDC_99rDpU0lZQZc-qFCttHIFcd67520VypY1F2p-PvpTC-dH3jropvlNQnlNQ8FIPEKFncA-O8TnjZwFeBhTMIOknTHPIr6_zP5Y3d_kdlb39XG6v7tfAm_Xz4dJLet6PDjViFdx_Y8U6OOjO5wvpHTkyfe2mh1LvlX48ICMT8Ib81YDxDVpYW0MNi9umbnJh09mDrZys8Kft-GBLbu_QG0EQTZhkGGrcoFQoLJjORyTWj2jWCqkNZHzqAR_X1Cn1gcqsUfczy9qYIVx5s6soBn5LUyHFz-HGFmkfEHcs4MNusnp79x5ku1YOZA1LsFgKFeJ1ZUJIsyhKDxtUqo-uRD1UMSGuvch8BLcGNtiHRpKo-1lIxzK36LyxGJRXYS069XOSj-APs8EHtIEbv4v6FCV7ckL32gYkVCVL6dUTxVdi8HsnfX-qEy2CcKBQPAQ2fWCwNCFbPguwx8PmlakKo_x2zPyD8cXMzq5_NMWDfdty8ad59-Pa1OMj-5Y_hLWoQrgKKgsw-yjUStcKcsheCNLDxnSqogRYCy-CDp_Q0wPpeouisBjBJeW4XWYGt8ZSCjUqhcM-PJJZNGbDksXboN_NTvH7-Nvk-9HMnPFpG-TrOot9IgvZX64aD7V8BOl2VcFKEmsDIumgRaF9cBCDj9L5PlY_ewlA5EtwnQtuEmbx8hFcs5OC6cXVJwHyUiIwGin-g7EgdPDwCH7CisHzg1kRkhBYCCT0sWSbkhxkQ_HJMxBVBS0Z8PdO2vtAE8Q56EkoZTZUvgTvwhothEn_zmYPNvbmJWaNDbrxTfBg5RCE8mYV0EYn1XlSnSVn4gTPx9MxH0_GE56eNHT3lJ_Vk3KKxTSe1GMxnU2m40kSJ3GRlsWJPOcxP41P42Q84dM4jQp-xqvJWYkzxLOiKNhpjK2QKlLqIbxJOQnvTc5n03ScnihRoHK7tz72nBaNim7l2GmspPNuT-alV3g-KJrqyucvdrbvPnZVEnG6q9qo9DrMlSedVefPjFP6piui0rSML1Q_BAx4tlH88JVPQP-fAAAA__83j18P">