diff options
-rw-r--r-- | chart2/source/view/main/VDataSeries.cxx | 3 | ||||
-rw-r--r-- | compilerplugins/clang/check.cxx | 10 | ||||
-rw-r--r-- | compilerplugins/clang/check.hxx | 2 | ||||
-rw-r--r-- | compilerplugins/clang/nullptr.cxx | 9 | ||||
-rw-r--r-- | compilerplugins/clang/test/nullptr.cxx | 6 | ||||
-rw-r--r-- | config_host/config_global.h.in | 3 | ||||
-rw-r--r-- | configure.ac | 23 | ||||
-rw-r--r-- | include/o3tl/compare.hxx | 41 | ||||
-rw-r--r-- | solenv/clang-format/excludelist | 1 |
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 |