diff --git a/libcxx/CMakeLists.txt b/libcxx/CMakeLists.txt index aeaf6b062472a4..9cad2394178dc4 100644 --- a/libcxx/CMakeLists.txt +++ b/libcxx/CMakeLists.txt @@ -832,6 +832,14 @@ function(cxx_add_windows_flags target) # Use the ISO conforming behaviour for conversion # in printf, scanf. _CRT_STDIO_ISO_WIDE_SPECIFIERS) + # Clang-cl shared builds don't support the experimental library. + # To avoid linker errors the format_error destructor is inlined for the + # dylib. Users can never use format in this mode. + # TODO FMT Remove when format becomes mainline. + if (LIBCXX_ENABLE_SHARED) + target_compile_definitions(${target} PRIVATE + _LIBCPP_INLINE_FORMAT_ERROR_DTOR) + endif() endif() endfunction() diff --git a/libcxx/include/__format/format_error.h b/libcxx/include/__format/format_error.h index 2ca527279e0b8b..742b654686ac1a 100644 --- a/libcxx/include/__format/format_error.h +++ b/libcxx/include/__format/format_error.h @@ -31,7 +31,14 @@ class _LIBCPP_EXCEPTION_ABI format_error : public runtime_error { : runtime_error(__s) {} _LIBCPP_HIDE_FROM_ABI explicit format_error(const char* __s) : runtime_error(__s) {} + // TODO FMT Remove when format is no longer experimental. + // Avoids linker errors when building the Clang-cl Windows DLL which doesn't + // support the experimental library. +# ifndef _LIBCPP_INLINE_FORMAT_ERROR_DTOR ~format_error() noexcept override; +# else + ~format_error() noexcept override {} +# endif }; _LIBCPP_NORETURN inline _LIBCPP_HIDE_FROM_ABI void diff --git a/libcxx/src/format.cpp b/libcxx/src/format.cpp index cdbcbf8b058d2e..401cccf17210a9 100644 --- a/libcxx/src/format.cpp +++ b/libcxx/src/format.cpp @@ -10,6 +10,8 @@ _LIBCPP_BEGIN_NAMESPACE_STD +#ifndef _LIBCPP_INLINE_FORMAT_ERROR_DTOR format_error::~format_error() noexcept = default; +#endif _LIBCPP_END_NAMESPACE_STD