From d6ce0512eec23df92bfddf8370960914b04693ef Mon Sep 17 00:00:00 2001 From: Pedro Alves Date: Tue, 10 Dec 2024 19:41:23 +0000 Subject: [PATCH] Fix MinGW build with _WIN32_WINNT<0x600, GCC>=13, model=win32 unordered_dense.h fails to compile on Windows/MinGW with GCC >= 13 with thread model win32, and _WIN32_WINNT < 0x600 (Vista), in CFLAGS/CXXFLAGS. E.g., GDB defines _WIN32_WINNT to 0x501, and it fails to build with GCC 14.2 like so: CXX ada-exp.o In file included from /opt/xpack-mingw-w64-gcc-14.2.0-1/x86_64-w64-mingw32/include/c++/14.2.0/shared_mutex:42, from /opt/xpack-mingw-w64-gcc-14.2.0-1/x86_64-w64-mingw32/include/c++/14.2.0/memory_resource:66, from /home/pedro/gdb/src/gdb/../gdbsupport/unordered_dense.h:104, from /home/pedro/gdb/src/gdb/../gdbsupport/unordered_map.h:21, from /home/pedro/gdb/src/gdb/gdbtypes.h:53, from /home/pedro/gdb/src/gdb/expression.h:23, from /home/pedro/gdb/src/gdb/ada-exp.y:40: /opt/xpack-mingw-w64-gcc-14.2.0-1/x86_64-w64-mingw32/include/c++/14.2.0/bits/std_mutex.h:164:5: error: '__gthread_cond_t' does not name a type; did you mean '__gthread_once_t'? 164 | __gthread_cond_t* native_handle() noexcept { return &_M_cond; } | ^~~~~~~~~~~~~~~~ | __gthread_once_t (... snip other instances of same ...) The problem is that unordered_dense.h includes , which uses std::mutex, and thus needs to include . (See , "Notice that synchronized_pool_resource contains a mutex, which means that effectively must include .") GCC 13 rewrote the win32 thread model support, and in that rewrite, support for __gthread_cond_t in std_mutex.h became conditional on _WIN32_WINNT >= 0x600. GCC/libstdc++ also has so with this patch, such a configuration takes that branch and succeeds, because does not include . Tested with MinGW-w64 GCC 14.2, posix and win32 models. Tested with MinGW-w64 GCC 10.1, posix and win32 models. Tested with GNU/Linux GCC 11.4.0. --- include/ankerl/unordered_dense.h | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/include/ankerl/unordered_dense.h b/include/ankerl/unordered_dense.h index 13484a9..51413c2 100644 --- a/include/ankerl/unordered_dense.h +++ b/include/ankerl/unordered_dense.h @@ -98,8 +98,27 @@ # include // for abort # endif +// includes , which fails to compile if +// targeting GCC >= 13 with the (rewritten) win32 thread model, and +// targeting Windows earlier than Vista (0x600). GCC predefines +// _REENTRANT when using the 'posix' model, and doesn't when using the +// 'win32' model. +# if defined __MINGW64__ && defined __GNUC__ && __GNUC__ >= 13 && !defined _REENTRANT +// _WIN32_WINNT is guaranteed to be defined here because of the +// inclusion above. +# ifndef _WIN32_WINNT +# error "_WIN32_WINNT not defined" +# endif +# if _WIN32_WINNT < 0x600 +# define ANKERL_MEMORY_RESOURCE_IS_BAD() 1 // NOLINT(cppcoreguidelines-macro-usage) +# endif +# endif +# ifndef ANKERL_MEMORY_RESOURCE_IS_BAD +# define ANKERL_MEMORY_RESOURCE_IS_BAD() 0 // NOLINT(cppcoreguidelines-macro-usage) +# endif + # if defined(__has_include) && !defined(ANKERL_UNORDERED_DENSE_DISABLE_PMR) -# if __has_include() +# if __has_include() && !ANKERL_MEMORY_RESOURCE_IS_BAD() # define ANKERL_UNORDERED_DENSE_PMR std::pmr // NOLINT(cppcoreguidelines-macro-usage) # include // for polymorphic_allocator # elif __has_include()