Skip to content

Commit

Permalink
Fix MinGW build with _WIN32_WINNT<0x600, GCC>=13, model=win32
Browse files Browse the repository at this point in the history
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 <memory_resource>,
which uses std::mutex, and thus needs to include <mutex>.  (See
<https://quuxplusone.github.io/blog/2018/06/05/libcpp-memory-resource>,
"Notice that synchronized_pool_resource contains a mutex, which means
that <memory_resource> effectively must include <mutex>.")

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 <experimental/memory_resource> so with this
patch, such a configuration takes that branch and succeeds, because
<experimental/memory_resource> does not include <mutex>.

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.
  • Loading branch information
palves committed Dec 10, 2024
1 parent 73f3cbb commit d6ce051
Showing 1 changed file with 20 additions and 1 deletion.
21 changes: 20 additions & 1 deletion include/ankerl/unordered_dense.h
Original file line number Diff line number Diff line change
Expand Up @@ -98,8 +98,27 @@
# include <cstdlib> // for abort
# endif

// <memory_resource> includes <mutex>, 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
// <cstdint> 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(<memory_resource>)
# if __has_include(<memory_resource>) && !ANKERL_MEMORY_RESOURCE_IS_BAD()
# define ANKERL_UNORDERED_DENSE_PMR std::pmr // NOLINT(cppcoreguidelines-macro-usage)
# include <memory_resource> // for polymorphic_allocator
# elif __has_include(<experimental/memory_resource>)
Expand Down

0 comments on commit d6ce051

Please sign in to comment.