diff options
author | Stephan Bergmann <stephan.bergmann@allotropia.de> | 2024-02-07 09:39:27 +0100 |
---|---|---|
committer | Stephan Bergmann <stephan.bergmann@allotropia.de> | 2024-02-07 21:03:46 +0100 |
commit | 56e6d683dba66d4f2f80145064d2bda2ea4b27b1 (patch) | |
tree | a67de3c1f2e841179ad9359740a1db60eda04712 /compilerplugins | |
parent | 43451b31969db882cd6c36054f43915ffbd8f252 (diff) |
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>
Diffstat (limited to 'compilerplugins')
-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 |
4 files changed, 26 insertions, 1 deletions
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: */ |