Guard cxxabi.h include with __has_include for clang-cl (#6145)
* fix: guard cxxabi.h include with __has_include for clang-cl
clang-cl on Windows defines __GNUG__ but does not ship <cxxabi.h>,
making detail/typeid.h fail to compile. Introduce PYBIND11_HAS_CXXABI_H,
defined only when <cxxabi.h> is actually available (__has_include with
a fallback for compilers without it, including C++11), and use it to
guard both the include and the abi::__cxa_demangle call site.
Fixes #6129
* docs: explain the __has_include fallback for GCC < 5
---------
Co-authored-by: aidaodedjl <jialiang.dong@ju-shen.com>
diff --git a/include/pybind11/detail/typeid.h b/include/pybind11/detail/typeid.h
index a67b521..fa5bfe1 100644
--- a/include/pybind11/detail/typeid.h
+++ b/include/pybind11/detail/typeid.h
@@ -13,6 +13,16 @@
#include <cstdlib>
#if defined(__GNUG__)
+# if !defined(__has_include)
+// All supported Clang versions provide __has_include, but GCC versions before 5 do not.
+// Preserve the previous unconditional __GNUG__ behavior for those older, still-supported
+// GCC versions (see PR #6145).
+# define PYBIND11_HAS_CXXABI_H
+# elif __has_include(<cxxabi.h>)
+# define PYBIND11_HAS_CXXABI_H
+# endif
+#endif
+#if defined(PYBIND11_HAS_CXXABI_H)
# include <cxxabi.h>
#endif
@@ -33,7 +43,7 @@
}
PYBIND11_NOINLINE void clean_type_id(std::string &name) {
-#if defined(__GNUG__)
+#if defined(PYBIND11_HAS_CXXABI_H)
int status = 0;
std::unique_ptr<char, void (*)(void *)> res{
abi::__cxa_demangle(name.c_str(), nullptr, nullptr, &status), std::free};