From 4e5fa3bdd21248b0f0ab5683d4df0daa5300a39e Mon Sep 17 00:00:00 2001 From: Kirill Lokotkov Date: Sun, 17 May 2026 09:27:06 +0300 Subject: [PATCH] Fix `long double` inf test under Valgrind. Fixes #5175 (#5176) * Fix for printing long doubles bug in dump_float When you use long double as a floating point type with the current version of this file and try to dump json it prints trash instead of actual number. This if-else fixes the problem. On using long double you just need to add an 'L' modifier before 'g' in format string. Signed-off-by: Kirill Lokotkov * C++11 compatibility Signed-off-by: Kirill Lokotkov * Shorter solution Signed-off-by: Kirill Lokotkov * Applied amalgamate Signed-off-by: rusloker * Add unit tests for `dump()` with `long double` in custom `basic_json` Signed-off-by: rusloker * Fix UB in `snprintf_float` by using `%.*Lg` for `long double` Signed-off-by: rusloker * Use `std::array` for `values` in serialization unit tests to improve type safety Signed-off-by: rusloker * Fix brace initialization for `std::array` in serialization unit tests Signed-off-by: rusloker * Remove comments in `snprintf_float` regarding `%Lg` usage Signed-off-by: rusloker * Skip `long double` infinity dump assertions under Valgrind Signed-off-by: rusloker * Clarify Valgrind bug-tracker reference in `long double` test Signed-off-by: rusloker * Satisfy clang-tidy in `long double` infinity probe Signed-off-by: rusloker --------- Signed-off-by: Kirill Lokotkov Signed-off-by: rusloker --- tests/src/unit-serialization.cpp | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/tests/src/unit-serialization.cpp b/tests/src/unit-serialization.cpp index 925c1e78c..c0f2a8e04 100644 --- a/tests/src/unit-serialization.cpp +++ b/tests/src/unit-serialization.cpp @@ -344,8 +344,22 @@ TEST_CASE("dump for basic_json with long double number_float_t") SECTION("NaN and infinity dump as null") { CHECK(long_double_json(std::numeric_limits::quiet_NaN()).dump() == "null"); - CHECK(long_double_json(std::numeric_limits::infinity()).dump() == "null"); - CHECK(long_double_json(-std::numeric_limits::infinity()).dump() == "null"); + + // Probe the platform's runtime behavior — `volatile` forces a runtime + // call rather than constexpr-folding to a known answer at compile time. + // Skip the infinity assertions if std::isfinite() doesn't actually + // recognize long double infinity on this platform (notably, Valgrind + // 3.22's x87 80-bit emulation reports +/-inf as a large finite value). + // TODO(rusloker): remove this guard once Valgrind's 80-bit long double + // support ships (Valgrind bug https://bugs.kde.org/show_bug.cgi?id=197915, + // ASSIGNED since 2009 — the Valgrind project tracks its bugs on + // bugs.kde.org) and the minimum supported Valgrind version contains it. + const volatile long double inf_probe = std::numeric_limits::infinity(); + if (!std::isfinite(inf_probe)) + { + CHECK(long_double_json(std::numeric_limits::infinity()).dump() == "null"); + CHECK(long_double_json(-std::numeric_limits::infinity()).dump() == "null"); + } } SECTION("dump output matches double for exactly-representable values")