Skip to content

MSVC's C++23 <stdatomic.h> breaks the CoreCLR build #57618

@StephanTLavavej

Description

@StephanTLavavej

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.
  • 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 then dwarf.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:

# 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:

# 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.

Metadata

Metadata

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions