diff --git a/config_host/config_global.h.in b/config_host/config_global.h.in index 5b42b2c5a8bd..6580fdfd0af7 100644 --- a/config_host/config_global.h.in +++ b/config_host/config_global.h.in @@ -13,6 +13,7 @@ Any change in this header will cause a rebuild of almost everything. #define CONFIG_GLOBAL_H #define HAVE_GCC_BUILTIN_ATOMIC 0 +#define HAVE_GCC_WSFINAE_INCOMPLETE 0 #define HAVE_SYSLOG_H 0 // Compiler supports C++20 diff --git a/configure.ac b/configure.ac index f3761d0eeca6..f8433c6655a2 100644 --- a/configure.ac +++ b/configure.ac @@ -8013,6 +8013,21 @@ AC_SUBST(HARDENING_LDFLAGS) AC_SUBST(HARDENING_CFLAGS) AC_SUBST(HARDENING_OPT_CFLAGS) +if test "$GCC" = yes && test "$COM_IS_CLANG" != TRUE; then + AC_MSG_CHECKING([whether $CXX_BASE supports -Wsfinae-incomplete]) + AC_LANG_PUSH([C++]) + save_CXXFLAGS=$CFLAGS + CXXFLAGS="$CXXFLAGS -Werror" + AC_COMPILE_IFELSE([AC_LANG_SOURCE([ + #pragma GCC diagnostic warning "-Wsfinae-incomplete" + ])], [ + AC_DEFINE([HAVE_GCC_WSFINAE_INCOMPLETE]) + AC_MSG_RESULT([yes]) + ], [AC_MSG_RESULT([no])]) + CXXFLAGS=$save_CXXFLAGS + AC_LANG_POP([C++]) +fi + dnl =================================================================== dnl Identify the C++ library dnl =================================================================== diff --git a/include/vcl/vclptr.hxx b/include/vcl/vclptr.hxx index 228a14c27482..8333f1a1b1a4 100644 --- a/include/vcl/vclptr.hxx +++ b/include/vcl/vclptr.hxx @@ -22,6 +22,7 @@ #include +#include #include #include @@ -44,6 +45,24 @@ template constexpr bool isIncompleteOrDerivedFromVclReferenceBase( int (*)[sizeof(T)]) { return std::is_base_of::value; } +// The above isIncompleteOrDerivedFromVclReferenceBase will cause will cause -Wsfinae-incomplete +// warnings when e.g. OutputDevice (include/vcl/outdev.hxx) contains members of type +// VclPtr, so OutputDevice is not yet complete when +// sIncompleteOrDerivedFromVclReferenceBase is instantiated, but will become complete later on +// ("warning: error: defining ‘OutputDevice’, which previously failed to be complete in a SFINAE +// context [-Werror=sfinae-incomplete=]"). A real solution would presumably be using C++26 +// reflection and rewriting the above isIncompleteOrDerivedFromVclReferenceBase as something like +// +// consteval bool isIncompleteOrDerivedFromVclReferenceBase(std::meta::info type) { +// return !std::meta::is_complete_type(type) +// || std::meta::is_base_of_type(^^VclReferenceBase, type); +// } +// +// But until then, use a HACK of (globally) ignoring that warning: +#if defined __GNUC__ && !defined __clang__ && HAVE_GCC_WSFINAE_INCOMPLETE +#pragma GCC diagnostic ignored "-Wsfinae-incomplete" +#endif + } // namespace vcl::detail /**