-
Notifications
You must be signed in to change notification settings - Fork 5.2k
Description
I work on MSVC's C++ Standard Library implementation, and we regularly build CoreCLR (along with many other open-source projects) to identify compiler/library bugs that would break your project, so we can fix them before shipping. This also allows us to provide advance notice of source-breaking changes - which is the case here.
The paper P0943R6 "Support C atomics in C++" has been accepted for the upcoming C++23 Standard, and we recently implemented it by merging microsoft/STL#2008 from our contributor @AdamBucior. (This will be available in VS 2022 17.1 Preview 1, in addition to being available in the microsoft/STL repo right now; our repo has instructions for how to build and use its implementation of the C++ Standard Library as a replacement for the one that ships in VS.) Our open-source test pass then discovered a CoreCLR build break:
[...toolset path...]\cl.exe /nologo [...many options...] -c F:\gitP\dotnet\runtime\src\coreclr\pal\src\libunwind\src\mi\Gdyn-extract.c
The contents of <stdatomic.h> are available only with C++23 or later.
F:\gitP\dotnet\runtime\src\coreclr\pal\src\libunwind\include\dwarf.h(351): error C2061: syntax error: identifier '_Atomic'
What's happening here is:
- C++23 requires
<stdatomic.h>
to exist and be compile-able as C++ (it wraps C++<atomic>
, provides an_Atomic
macro, and makes various typedefs available in the global namespace). This is what we've implemented. - The MSVC toolset does not yet have an implementation of C11/C17 atomics, although that support is planned for the future.
- Thus, our
<stdatomic.h>
is not usable when compiled as C.- Currently, it emits a message "The contents of
<stdatomic.h>
are available only with C++23 or later." and expands to nothing. This message was intended for users compiling in C++14/17/20 modes. I'm planning to add a#error
when attempting to compile<stdatomic.h>
as C, to make this easier to diagnose, but that won't affect the root cause.
- Currently, it emits a message "The contents of
- The CoreCLR build detects that the
<stdatomic.h>
file is now present, and attempts to compile it as C. This results in the error log above - we emit the "available only with C++23" message, the header expands to nothing, and thendwarf.h
attempts to use C_Atomic
and that's an error because it hasn't been provided.
I believe that the relevant code in the CoreCLR build system is:
runtime/src/coreclr/pal/src/libunwind/configure.cmake
Lines 19 to 24 in a53ec50
# MSVC compiler is currently missing C11 stdatomic.h header | |
# Fake it until support is added | |
check_include_files(stdatomic.h HAVE_STDATOMIC_H) | |
if (NOT HAVE_STDATOMIC_H) | |
configure_file(include/win/fakestdatomic.h.in ${CMAKE_CURRENT_BINARY_DIR}/include/stdatomic.h COPYONLY) | |
endif (NOT HAVE_STDATOMIC_H) |
I'm not a CMake expert, so I don't know what the best way to resolve this would be. It appears that it would be possible to change this logic so that instead of simply detecting whether the <stdatomic.h>
file exists, instead CMake would check for whether simple usage of <stdatomic.h>
and _Atomic
can compile in C mode. This is being done for C11 _Thread_local
immediately below:
runtime/src/coreclr/pal/src/libunwind/configure.cmake
Lines 26 to 27 in a53ec50
# MSVC compiler is currently missing C11 _Thread_local | |
check_c_source_compiles("void main() { _Thread_local int a; }" HAVE_THREAD_LOCAL) |
Hopefully, CoreCLR's include paths are set up such that copying include/win/fakestdatomic.h.in
to ${CMAKE_CURRENT_BINARY_DIR}/include/stdatomic.h
results in that file being preferentially picked up before MSVC's <stdatomic.h>
is considered; if not, additional changes to the build system could be necessary.