summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--chart2/source/view/main/VDataSeries.cxx3
-rw-r--r--compilerplugins/clang/check.cxx10
-rw-r--r--compilerplugins/clang/check.hxx2
-rw-r--r--compilerplugins/clang/nullptr.cxx9
-rw-r--r--compilerplugins/clang/test/nullptr.cxx6
-rw-r--r--config_host/config_global.h.in3
-rw-r--r--configure.ac23
-rw-r--r--include/o3tl/compare.hxx41
-rw-r--r--solenv/clang-format/excludelist1
9 files changed, 96 insertions, 2 deletions
diff --git a/chart2/source/view/main/VDataSeries.cxx b/chart2/source/view/main/VDataSeries.cxx
index 455c991b9f89..17dc8f1a3beb 100644
--- a/chart2/source/view/main/VDataSeries.cxx
+++ b/chart2/source/view/main/VDataSeries.cxx
@@ -38,6 +38,7 @@
#include <com/sun/star/chart2/RelativePosition.hpp>
#include <com/sun/star/chart2/RelativeSize.hpp>
+#include <o3tl/compare.hxx>
#include <osl/diagnose.h>
#include <tools/color.hxx>
#include <comphelper/diagnose_ex.hxx>
@@ -101,7 +102,7 @@ struct lcl_LessXOfPoint
{
if( !first.empty() && !second.empty() )
{
- return first[0]<second[0];
+ return o3tl::strong_order(first[0], second[0]) < 0;
}
return false;
}
diff --git a/compilerplugins/clang/check.cxx b/compilerplugins/clang/check.cxx
index 4ff081b6923e..60e476cc37b7 100644
--- a/compilerplugins/clang/check.cxx
+++ b/compilerplugins/clang/check.cxx
@@ -133,6 +133,16 @@ TypeCheck TypeCheck::Pointer() const {
return TypeCheck();
}
+TypeCheck TypeCheck::MemberPointerOf() const {
+ if (!type_.isNull()) {
+ auto const t = type_->getAs<clang::MemberPointerType>();
+ if (t != nullptr) {
+ return TypeCheck(t->getClass());
+ }
+ }
+ return TypeCheck();
+}
+
TerminalCheck TypeCheck::Enum() const {
if (!type_.isNull()) {
auto const t = type_->getAs<clang::EnumType>();
diff --git a/compilerplugins/clang/check.hxx b/compilerplugins/clang/check.hxx
index af6cd355a416..65ee16d77f2c 100644
--- a/compilerplugins/clang/check.hxx
+++ b/compilerplugins/clang/check.hxx
@@ -62,6 +62,8 @@ public:
TypeCheck Pointer() const;
+ TypeCheck MemberPointerOf() const;
+
TerminalCheck Enum() const;
TypeCheck LvalueReference() const;
diff --git a/compilerplugins/clang/nullptr.cxx b/compilerplugins/clang/nullptr.cxx
index 0213b6b05c88..04fb5bf0f9fd 100644
--- a/compilerplugins/clang/nullptr.cxx
+++ b/compilerplugins/clang/nullptr.cxx
@@ -131,11 +131,18 @@ bool Nullptr::VisitImplicitCastExpr(CastExpr const * expr) {
case Expr::NPCK_CXX11_nullptr:
break;
default:
- if (loplugin::TypeCheck(expr->getType()).Typedef("locale_t")
+ auto const tc = loplugin::TypeCheck(expr->getType());
+ if (tc.Typedef("locale_t")
.GlobalNamespace())
{
break; // POSIX locale_t is left unspecified
}
+ // Hack to handle libc++ and stdlibc++ `std::strong_ordering x; x < 0` etc.:
+ if (tc.MemberPointerOf().ClassOrStruct("_CmpUnspecifiedParam").StdNamespace()
+ || tc.Pointer().ClassOrStruct("__unspec").Namespace("__cmp_cat").StdNamespace())
+ {
+ break;
+ }
handleNull(expr->getSubExpr(), expr->getCastKindName(), k);
break;
}
diff --git a/compilerplugins/clang/test/nullptr.cxx b/compilerplugins/clang/test/nullptr.cxx
index bf7376cb6562..392a930bf9b8 100644
--- a/compilerplugins/clang/test/nullptr.cxx
+++ b/compilerplugins/clang/test/nullptr.cxx
@@ -7,6 +7,10 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
+#include "sal/config.h"
+
+#include <compare>
+
struct S
{
void* p;
@@ -18,6 +22,8 @@ int main()
0 // expected-error {{NullToPointer ValueDependentIsNotNull ZeroLiteral -> nullptr [loplugin:nullptr]}}
};
(void)s;
+
+ (void)(std::strong_order(0, 1) < 0);
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/config_host/config_global.h.in b/config_host/config_global.h.in
index dce52798a1fe..5b42b2c5a8bd 100644
--- a/config_host/config_global.h.in
+++ b/config_host/config_global.h.in
@@ -24,6 +24,9 @@ Any change in this header will cause a rebuild of almost everything.
// constexpr", and <https://wg21.link/P1143R2> "Adding the constinit keyword":
#define HAVE_CPP_CONSTINIT_SORTED_VECTOR 0
+// Compiler supports C++20 <compare> std::strong_order:
+#define HAVE_CPP_STRONG_ORDER 0
+
/* "CWG motion 23: P1825R0 'Merged wording for P0527R1 and P1155R3' (DR)" in
<https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/n4829.html> "N4829 Editors' Report --
Programming Languages -- C++" marks
diff --git a/configure.ac b/configure.ac
index 5937983f7ac2..721851c52d87 100644
--- a/configure.ac
+++ b/configure.ac
@@ -14787,6 +14787,29 @@ CXX=$save_CXX
CXXFLAGS=$save_CXXFLAGS
AC_LANG_POP([C++])
+AC_MSG_CHECKING([whether $CXX_BASE supports a working C++20 std::strong_order])
+dnl ...which is known to not be implemented in libc++ prior to
+dnl <https://github.com/llvm/llvm-project/commit/d8380ad977e94498e170b06449c81f1fc27da7b5> "[libc++]
+dnl [P1614] Implement [cmp.alg]'s std::{strong,weak,partial}_order" in LLVM 14:
+AC_LANG_PUSH([C++])
+save_CXX=$CXX
+if test "$COM" = MSC && test "$COM_IS_CLANG" != TRUE; then
+ CXX="env LIB=$ILIB $CXX"
+fi
+save_CXXFLAGS=$CXXFLAGS
+CXXFLAGS="$CXXFLAGS $CXXFLAGS_CXX11"
+AC_LINK_IFELSE([AC_LANG_PROGRAM([
+ #include <compare>
+ ], [
+ (void) (std::strong_order(1.0, 2.0) < 0);
+ ])], [
+ AC_DEFINE([HAVE_CPP_STRONG_ORDER],[1])
+ AC_MSG_RESULT([yes])
+ ], [AC_MSG_RESULT([no])])
+CXX=$save_CXX
+CXXFLAGS=$save_CXXFLAGS
+AC_LANG_POP([C++])
+
# ===================================================================
# Creating bigger shared library to link against
# ===================================================================
diff --git a/include/o3tl/compare.hxx b/include/o3tl/compare.hxx
new file mode 100644
index 000000000000..27c6b31ac647
--- /dev/null
+++ b/include/o3tl/compare.hxx
@@ -0,0 +1,41 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#pragma once
+
+#include <sal/config.h>
+
+#include <compare>
+
+#include <config_global.h>
+
+namespace o3tl
+{
+// A poor approximation of C++20 <compare> std::strong_order, falling back to operator <=> (so e.g.
+// not providing a strict weak ordering for floating-point types with NaN):
+#if HAVE_CPP_STRONG_ORDER
+
+inline constexpr auto strong_order = std::strong_order;
+
+#else
+
+namespace detail
+{
+struct strong_order
+{
+ auto operator()(auto x, auto y) const { return x <=> y; }
+};
+}
+
+inline constexpr auto strong_order = detail::strong_order();
+
+#endif
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/solenv/clang-format/excludelist b/solenv/clang-format/excludelist
index f15ac0ba31f3..e6e95fe011b2 100644
--- a/solenv/clang-format/excludelist
+++ b/solenv/clang-format/excludelist
@@ -5292,6 +5292,7 @@ include/linguistic/lngprophelp.hxx
include/linguistic/misc.hxx
include/linguistic/spelldta.hxx
include/o3tl/any.hxx
+include/o3tl/compare.hxx
include/o3tl/cow_wrapper.hxx
include/o3tl/enumarray.hxx
include/o3tl/enumrange.hxx