double operator < is not a strict weak ordering due to NaN
...so recent LLVM 19 trunk libc++ in debug mode complained during CppunitTest_chart2_export2 about > ~/llvm/inst/bin/../include/c++/v1/__debug_utils/strict_weak_ordering_check.h:59: assertion __comp(*(__first + __a), *(__first + __b)) failed: Your comparator is not a valid strict-weak ordering at > 5 libsystem_c.dylib 0x0000000183279a40 abort + 180 > 6 libc++.1.0.dylib 0x00000001030f9d98 _ZNSt3__123__cxx_atomic_notify_oneEPVKv + 0 > 7 libchartcorelo.dylib 0x00000002f817f0ec _ZNSt3__135__check_strict_weak_ordering_sortedB8de190000INS_11__wrap_iterIPNS_6vectorIdNS_9allocatorIdEEEEEEN5chart12_GLOBAL__N_116lcl_LessXOfPointEEEvT_SB_RT0_ + 960 > 8 libchartcorelo.dylib 0x00000002f817e6cc _ZNSt3__118__stable_sort_implB8de190000INS_17_ClassicAlgPolicyENS_11__wrap_iterIPNS_6vectorIdNS_9allocatorIdEEEEEEN5chart12_GLOBAL__N_116lcl_LessXOfPointEEEvT0_SC_RT1_ + 268 > 9 libchartcorelo.dylib 0x00000002f8172a90 _ZNSt3__111stable_sortB8de190000INS_11__wrap_iterIPNS_6vectorIdNS_9allocatorIdEEEEEEN5chart12_GLOBAL__N_116lcl_LessXOfPointEEEvT_SB_T0_ + 68 > 10 libchartcorelo.dylib 0x00000002f8172820 _ZN5chart11VDataSeries15doSortByXValuesEv + 508 > 11 libchartcorelo.dylib 0x00000002f8064c44 _ZN5chart9AreaChart12createShapesEv + 1528 > 12 libchartcorelo.dylib 0x00000002f80f2ae0 _ZN5chart9ChartView28impl_createDiagramAndContentERKNS_18CreateShapeParam2DERKN3com3sun4star3awt4SizeE + 4440 > 13 libchartcorelo.dylib 0x00000002f80f77ac _ZN5chart9ChartView14createShapes2DERKN3com3sun4star3awt4SizeE + 2728 > 14 libchartcorelo.dylib 0x00000002f80f58ec _ZN5chart9ChartView12createShapesEv + 692 > 15 libchartcorelo.dylib 0x00000002f80f4598 _ZN5chart9ChartView15impl_updateViewEb + 288 But the introduced use of `std::strong_order(first[0], second[0]) < 0` then triggered a false > lo/core/chart2/source/view/main/VDataSeries.cxx:105:61: error: NullToMemberPointer ValueDependentIsNotNull ZeroLiteral -> nullptr [loplugin:nullptr] > 105 | return std::strong_order(first[0], second[0]) < 0; > | ^ so needed some hack in loplugin:nullptr. And old versions of libc++, still used at least on Android, do not have any implementations of std::strong_order. So detect those cases in configure.ac (checking for std::strong_order for double, which is what is actually being used in the code) and fall back to operator <=> for now, even if that will not provide a strict weak ordering and will thus continue to violate the requirements of std::sort. And then our venerable clang-format 5.0.0 would have broken the token `<=>` into `<= >`, so exclude include/o3tl/compare.hxx from its mis-treatment. Change-Id: I7a64a630eb5f560dce59f3ff9d51ca3d1adc70be Reviewed-on: https://gerrit.libreoffice.org/c/core/+/163075 Tested-by: Jenkins Reviewed-by: Stephan Bergmann <stephan.bergmann@allotropia.de>
This commit is contained in:
parent
43451b3196
commit
56e6d683db
@ -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;
|
||||
}
|
||||
|
@ -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>();
|
||||
|
@ -62,6 +62,8 @@ public:
|
||||
|
||||
TypeCheck Pointer() const;
|
||||
|
||||
TypeCheck MemberPointerOf() const;
|
||||
|
||||
TerminalCheck Enum() const;
|
||||
|
||||
TypeCheck LvalueReference() const;
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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: */
|
||||
|
@ -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
|
||||
|
23
configure.ac
23
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
|
||||
# ===================================================================
|
||||
|
41
include/o3tl/compare.hxx
Normal file
41
include/o3tl/compare.hxx
Normal file
@ -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: */
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user