diff options
Diffstat (limited to 'debian/patches')
-rw-r--r-- | debian/patches/configure.diff | 115 | ||||
-rw-r--r-- | debian/patches/cpu-frequency.diff | 54 | ||||
-rw-r--r-- | debian/patches/disable-double-double-tests.diff | 489 | ||||
-rw-r--r-- | debian/patches/endian-hash.diff | 111 | ||||
-rw-r--r-- | debian/patches/endian-random.diff | 249 | ||||
-rw-r--r-- | debian/patches/fix-hppa.diff | 26 | ||||
-rw-r--r-- | debian/patches/fma-contraction.diff | 63 | ||||
-rw-r--r-- | debian/patches/latomic.diff | 20 | ||||
-rw-r--r-- | debian/patches/nan-narrowing.diff | 25 | ||||
-rw-r--r-- | debian/patches/ppc-float-conversion.diff | 268 | ||||
-rw-r--r-- | debian/patches/series | 11 | ||||
-rw-r--r-- | debian/patches/std-hash.diff | 46 |
12 files changed, 1477 insertions, 0 deletions
diff --git a/debian/patches/configure.diff b/debian/patches/configure.diff new file mode 100644 index 00000000..5c47b152 --- /dev/null +++ b/debian/patches/configure.diff @@ -0,0 +1,115 @@ +From: Benjamin Barenblat <bbaren@google.com> +Subject: Set package configuration options +Forwarded: not-needed + +Configure Abseil for Debian. + + - Set the SONAME appropriately. + + - To minimize the possibility of future ABI breakage, treat absl::any, + absl::optional, absl::string_view, and absl::variant as their own types + (rather than aliases for the std:: versions), and compile everything in an + inline namespace. + + - Enable upstream's hardened build mode. + + - Disable Intel SSE2 on i386, since Debian supports some i386 processors + without that extension. Keep it enabled on amd64, since all amd64 processors + have it. + + - Disable Intel SSSE3 entirely, since no i386 processor supports it and Debian + supports amd64 processors without it. + +--- a/CMake/AbseilHelpers.cmake ++++ b/CMake/AbseilHelpers.cmake +@@ -217,6 +217,9 @@ + OUTPUT_NAME "absl_${_NAME}" + ) + endif() ++ ++ set_property(TARGET ${_NAME} PROPERTY SOVERSION 20200923) ++ set_property(TARGET ${_NAME} PROPERTY VERSION "20200923.0.1") + else() + # Generating header-only library + add_library(${_NAME} INTERFACE) +--- a/absl/base/options.h ++++ b/absl/base/options.h +@@ -100,7 +100,7 @@ + // User code should not inspect this macro. To check in the preprocessor if + // absl::any is a typedef of std::any, use the feature macro ABSL_USES_STD_ANY. + +-#define ABSL_OPTION_USE_STD_ANY 2 ++#define ABSL_OPTION_USE_STD_ANY 0 + + + // ABSL_OPTION_USE_STD_OPTIONAL +@@ -127,7 +127,7 @@ + // absl::optional is a typedef of std::optional, use the feature macro + // ABSL_USES_STD_OPTIONAL. + +-#define ABSL_OPTION_USE_STD_OPTIONAL 2 ++#define ABSL_OPTION_USE_STD_OPTIONAL 0 + + + // ABSL_OPTION_USE_STD_STRING_VIEW +@@ -154,7 +154,7 @@ + // absl::string_view is a typedef of std::string_view, use the feature macro + // ABSL_USES_STD_STRING_VIEW. + +-#define ABSL_OPTION_USE_STD_STRING_VIEW 2 ++#define ABSL_OPTION_USE_STD_STRING_VIEW 0 + + // ABSL_OPTION_USE_STD_VARIANT + // +@@ -180,7 +180,7 @@ + // absl::variant is a typedef of std::variant, use the feature macro + // ABSL_USES_STD_VARIANT. + +-#define ABSL_OPTION_USE_STD_VARIANT 2 ++#define ABSL_OPTION_USE_STD_VARIANT 0 + + + // ABSL_OPTION_USE_INLINE_NAMESPACE +@@ -206,7 +206,7 @@ + // allowed. + + #define ABSL_OPTION_USE_INLINE_NAMESPACE 1 +-#define ABSL_OPTION_INLINE_NAMESPACE_NAME lts_2020_09_23 ++#define ABSL_OPTION_INLINE_NAMESPACE_NAME debian1 + + // ABSL_OPTION_HARDENED + // +@@ -233,6 +233,6 @@ + // checks enabled by this option may abort the program in a different way and + // log additional information when `NDEBUG` is not defined. + +-#define ABSL_OPTION_HARDENED 0 ++#define ABSL_OPTION_HARDENED 1 + + #endif // ABSL_BASE_OPTIONS_H_ +--- a/absl/container/internal/have_sse.h ++++ b/absl/container/internal/have_sse.h +@@ -17,22 +17,14 @@ + #define ABSL_CONTAINER_INTERNAL_HAVE_SSE_H_ + + #ifndef ABSL_INTERNAL_RAW_HASH_SET_HAVE_SSE2 +-#if defined(__SSE2__) || \ +- (defined(_MSC_VER) && \ +- (defined(_M_X64) || (defined(_M_IX86) && _M_IX86_FP >= 2))) ++#if defined(__x86_64__) || (defined(_MSC_VER) && defined(_M_X64)) + #define ABSL_INTERNAL_RAW_HASH_SET_HAVE_SSE2 1 + #else + #define ABSL_INTERNAL_RAW_HASH_SET_HAVE_SSE2 0 + #endif + #endif + +-#ifndef ABSL_INTERNAL_RAW_HASH_SET_HAVE_SSSE3 +-#ifdef __SSSE3__ +-#define ABSL_INTERNAL_RAW_HASH_SET_HAVE_SSSE3 1 +-#else + #define ABSL_INTERNAL_RAW_HASH_SET_HAVE_SSSE3 0 +-#endif +-#endif + + #if ABSL_INTERNAL_RAW_HASH_SET_HAVE_SSSE3 && \ + !ABSL_INTERNAL_RAW_HASH_SET_HAVE_SSE2 diff --git a/debian/patches/cpu-frequency.diff b/debian/patches/cpu-frequency.diff new file mode 100644 index 00000000..adfba7e0 --- /dev/null +++ b/debian/patches/cpu-frequency.diff @@ -0,0 +1,54 @@ +From: Benjamin Barenblat <bbaren@google.com> +Subject: Ignore missing CPU frequency on more architectures +Forwarded: yes +Applied-Upstream: https://github.com/abseil/abseil-cpp/commit/1918ad2ae38aa32c74b558b322479a8efdd76363 + +Linux on MIPS, PA-RISC, RISC-V, and SystemZ doesn’t expose the nominal CPU +frequency via /sys, so don’t worry if `NominalCPUFrequency` returns 1.0 on those +platforms. + +Some POWER machines expose the CPU frequency; others do not. Since we can’t +predict which type of machine the tests will run on, simply disable testing for +`NominalCPUFrequency` on POWER. + +The author works at Google. Upstream applied this patch as Piper revision +347079873 and exported it to GitHub; the Applied-Upstream URL above points to +the exported commit. + +--- a/absl/base/internal/sysinfo_test.cc ++++ b/absl/base/internal/sysinfo_test.cc +@@ -37,17 +37,28 @@ TEST(SysinfoTest, NumCPUs) { + << "NumCPUs() should not have the default value of 0"; + } + ++// Ensure that NominalCPUFrequency returns a reasonable value, or 1.00 on ++// platforms where the CPU frequency is not available through sysfs. ++// ++// POWER is particularly problematic here; some Linux kernels expose the CPU ++// frequency, while others do not. Since we can't predict a priori what a given ++// machine is going to do, just disable this test on POWER on Linux. ++#if !(defined(__linux) && (defined(__ppc64__) || defined(__PPC64__))) + TEST(SysinfoTest, NominalCPUFrequency) { +-#if !(defined(__aarch64__) && defined(__linux__)) && !defined(__EMSCRIPTEN__) +- EXPECT_GE(NominalCPUFrequency(), 1000.0) +- << "NominalCPUFrequency() did not return a reasonable value"; +-#else +- // Aarch64 cannot read the CPU frequency from sysfs, so we get back 1.0. +- // Emscripten does not have a sysfs to read from at all. ++ // Linux only exposes the CPU frequency on certain architectures, and ++ // Emscripten doesn't expose it at all. ++#if defined(__linux__) && \ ++ (defined(__aarch64__) || defined(__hppa__) || defined(__mips__) || \ ++ defined(__riscv) || defined(__s390x__)) || \ ++ defined(__EMSCRIPTEN__) + EXPECT_EQ(NominalCPUFrequency(), 1.0) + << "CPU frequency detection was fixed! Please update unittest."; ++#else ++ EXPECT_GE(NominalCPUFrequency(), 1000.0) ++ << "NominalCPUFrequency() did not return a reasonable value"; + #endif + } ++#endif + + TEST(SysinfoTest, GetTID) { + EXPECT_EQ(GetTID(), GetTID()); // Basic compile and equality test. diff --git a/debian/patches/disable-double-double-tests.diff b/debian/patches/disable-double-double-tests.diff new file mode 100644 index 00000000..e80a8a78 --- /dev/null +++ b/debian/patches/disable-double-double-tests.diff @@ -0,0 +1,489 @@ +From: Benjamin Barenblat <bbaren@google.com> +Subject: Stop testing with double-double random variables +Forwarded: yes +Applied-Upstream: https://github.com/abseil/abseil-cpp/commit/ab21820d47e4f83875dda008b600514d3520fd35 + +On POWER, long double is often represented as a pair of doubles added +together (double-double arithmetic). We’ve already special-cased +double-double arithmetic in a number of tests, but compiler +bugs [1, 2, 3] have now triggered both false positives and false +negatives, which suggests testing with double doubles is unlikely to +yield useful signal. Remove the special casing and detect if we’re on a +double-double system; if so, just don’t test long doubles. + +[1] https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99048 +[2] https://bugs.llvm.org/show_bug.cgi?id=49131 +[3] https://bugs.llvm.org/show_bug.cgi?id=49132 + +The author works at Google. Upstream applied this patch as Piper +revision 360793161 and exported it to GitHub; the the Applied-Upstream +URL above points to the exported commit. + +--- a/CMake/AbseilDll.cmake ++++ b/CMake/AbseilDll.cmake +@@ -126,6 +126,7 @@ set(ABSL_INTERNAL_DLL_FILES + "meta/type_traits.h" + "numeric/int128.cc" + "numeric/int128.h" ++ "numeric/internal/representation.h" + "random/bernoulli_distribution.h" + "random/beta_distribution.h" + "random/bit_gen_ref.h" +--- a/absl/numeric/BUILD.bazel ++++ b/absl/numeric/BUILD.bazel +@@ -72,3 +72,15 @@ + "@com_github_google_benchmark//:benchmark_main", + ], + ) ++ ++cc_library( ++ name = "representation", ++ hdrs = [ ++ "internal/representation.h", ++ ], ++ copts = ABSL_DEFAULT_COPTS, ++ linkopts = ABSL_DEFAULT_LINKOPTS, ++ deps = [ ++ "//absl/base:config", ++ ], ++) +--- a/absl/numeric/CMakeLists.txt ++++ b/absl/numeric/CMakeLists.txt +@@ -59,3 +59,15 @@ + absl::int128 + PUBLIC + ) ++ ++absl_cc_library( ++ NAME ++ numeric_representation ++ HDRS ++ "internal/representation.h" ++ COPTS ++ ${ABSL_DEFAULT_COPTS} ++ DEPS ++ absl::config ++ PUBLIC ++) +--- /dev/null ++++ b/absl/numeric/internal/representation.h +@@ -0,0 +1,55 @@ ++// Copyright 2021 The Abseil Authors ++// ++// Licensed under the Apache License, Version 2.0 (the "License"); ++// you may not use this file except in compliance with the License. ++// You may obtain a copy of the License at ++// ++// https://www.apache.org/licenses/LICENSE-2.0 ++// ++// Unless required by applicable law or agreed to in writing, software ++// distributed under the License is distributed on an "AS IS" BASIS, ++// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ++// See the License for the specific language governing permissions and ++// limitations under the License. ++ ++#ifndef ABSL_NUMERIC_INTERNAL_REPRESENTATION_H_ ++#define ABSL_NUMERIC_INTERNAL_REPRESENTATION_H_ ++ ++#include <limits> ++ ++#include "absl/base/config.h" ++ ++namespace absl { ++ABSL_NAMESPACE_BEGIN ++namespace numeric_internal { ++ ++// Returns true iff long double is represented as a pair of doubles added ++// together. ++inline constexpr bool IsDoubleDouble() { ++ // A double-double value always has exactly twice the precision of a double ++ // value--one double carries the high digits and one double carries the low ++ // digits. This property is not shared with any other common floating-point ++ // representation, so this test won't trigger false positives. For reference, ++ // this table gives the number of bits of precision of each common ++ // floating-point representation: ++ // ++ // type precision ++ // IEEE single 24 b ++ // IEEE double 53 ++ // x86 long double 64 ++ // double-double 106 ++ // IEEE quadruple 113 ++ // ++ // Note in particular that a quadruple-precision float has greater precision ++ // than a double-double float despite taking up the same amount of memory; the ++ // quad has more of its bits allocated to the mantissa than the double-double ++ // has. ++ return std::numeric_limits<long double>::digits == ++ 2 * std::numeric_limits<double>::digits; ++} ++ ++} // namespace numeric_internal ++ABSL_NAMESPACE_END ++} // namespace absl ++ ++#endif // ABSL_NUMERIC_INTERNAL_REPRESENTATION_H_ +--- a/absl/random/BUILD.bazel ++++ b/absl/random/BUILD.bazel +@@ -187,6 +187,7 @@ cc_test(name = "beta_distribution_test", + ":distributions", + ":random", + "//absl/base:raw_logging_internal", ++ "//absl/numeric:representation", + "//absl/random/internal:distribution_test_util", + "//absl/random/internal:pcg_engine", + "//absl/random/internal:sequence_urbg", +@@ -307,6 +308,7 @@ cc_test(name = "exponential_distribution_test", + ":random", + "//absl/base:core_headers", + "//absl/base:raw_logging_internal", ++ "//absl/numeric:representation", + "//absl/random/internal:distribution_test_util", + "//absl/random/internal:pcg_engine", + "//absl/random/internal:sequence_urbg", +@@ -330,6 +332,7 @@ cc_test(name = "gaussian_distribution_test", + ":random", + "//absl/base:core_headers", + "//absl/base:raw_logging_internal", ++ "//absl/numeric:representation", + "//absl/random/internal:distribution_test_util", + "//absl/random/internal:sequence_urbg", + "//absl/strings", +@@ -376,6 +379,7 @@ cc_test(name = "uniform_real_distribution_test", + ":distributions", + ":random", + "//absl/base:raw_logging_internal", ++ "//absl/numeric:representation", + "//absl/random/internal:distribution_test_util", + "//absl/random/internal:pcg_engine", + "//absl/random/internal:sequence_urbg", +--- a/absl/random/CMakeLists.txt ++++ b/absl/random/CMakeLists.txt +@@ -259,6 +259,7 @@ absl_cc_test(NAME random_beta_distribution_test + LINKOPTS + ${ABSL_DEFAULT_LINKOPTS} + DEPS ++ absl::numeric_representation + absl::random_distributions + absl::random_random + absl::random_internal_distribution_test_util +@@ -381,6 +382,7 @@ absl_cc_test(NAME random_exponential_distribution_test + ${ABSL_DEFAULT_LINKOPTS} + DEPS + absl::core_headers ++ absl::numeric_representation + absl::random_distributions + absl::random_internal_distribution_test_util + absl::random_internal_pcg_engine +@@ -404,6 +406,7 @@ absl_cc_test(NAME random_gaussian_distribution_test + ${ABSL_DEFAULT_LINKOPTS} + DEPS + absl::core_headers ++ absl::numeric_representation + absl::random_distributions + absl::random_internal_distribution_test_util + absl::random_internal_sequence_urbg +@@ -446,6 +449,7 @@ absl_cc_test(NAME random_uniform_real_distribution_test + LINKOPTS + ${ABSL_DEFAULT_LINKOPTS} + DEPS ++ absl::numeric_representation + absl::random_distributions + absl::random_internal_distribution_test_util + absl::random_internal_pcg_engine +--- a/absl/random/beta_distribution_test.cc ++++ b/absl/random/beta_distribution_test.cc +@@ -21,12 +21,14 @@ + #include <random> + #include <sstream> + #include <string> ++#include <type_traits> + #include <unordered_map> + #include <vector> + + #include "gmock/gmock.h" + #include "gtest/gtest.h" + #include "absl/base/internal/raw_logging.h" ++#include "absl/numeric/internal/representation.h" + #include "absl/random/internal/chi_square.h" + #include "absl/random/internal/distribution_test_util.h" + #include "absl/random/internal/pcg_engine.h" +@@ -42,7 +44,15 @@ + template <typename IntType> + class BetaDistributionInterfaceTest : public ::testing::Test {}; + +-using RealTypes = ::testing::Types<float, double, long double>; ++// double-double arithmetic is not supported well by either GCC or Clang; see ++// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99048, ++// https://bugs.llvm.org/show_bug.cgi?id=49131, and ++// https://bugs.llvm.org/show_bug.cgi?id=49132. Don't bother running these tests ++// with double doubles until compiler support is better. ++using RealTypes = ++ std::conditional<absl::numeric_internal::IsDoubleDouble(), ++ ::testing::Types<float, double>, ++ ::testing::Types<float, double, long double>>::type; + TYPED_TEST_CASE(BetaDistributionInterfaceTest, RealTypes); + + TYPED_TEST(BetaDistributionInterfaceTest, SerializeTest) { +@@ -53,9 +63,6 @@ TYPED_TEST(BetaDistributionInterfaceTest, SerializeTest { + const TypeParam kLargeA = + std::exp(std::log((std::numeric_limits<TypeParam>::max)()) - + std::log(std::log((std::numeric_limits<TypeParam>::max)()))); +- const TypeParam kLargeAPPC = std::exp( +- std::log((std::numeric_limits<TypeParam>::max)()) - +- std::log(std::log((std::numeric_limits<TypeParam>::max)())) - 10.0f); + using param_type = typename absl::beta_distribution<TypeParam>::param_type; + + constexpr int kCount = 1000; +@@ -76,9 +83,6 @@ TYPED_TEST(BetaDistributionInterfaceTest, SerializeTest { + kLargeA, // + std::nextafter(kLargeA, TypeParam(0)), // + std::nextafter(kLargeA, std::numeric_limits<TypeParam>::max()), +- kLargeAPPC, // +- std::nextafter(kLargeAPPC, TypeParam(0)), +- std::nextafter(kLargeAPPC, std::numeric_limits<TypeParam>::max()), + // Boundary cases. + std::numeric_limits<TypeParam>::max(), + std::numeric_limits<TypeParam>::epsilon(), +@@ -125,28 +129,6 @@ TYPED_TEST(BetaDistributionInterfaceTest, SerializeTest { + + ss >> after; + +-#if defined(__powerpc64__) || defined(__PPC64__) || defined(__powerpc__) || \ +- defined(__ppc__) || defined(__PPC__) +- if (std::is_same<TypeParam, long double>::value) { +- // Roundtripping floating point values requires sufficient precision +- // to reconstruct the exact value. It turns out that long double +- // has some errors doing this on ppc. +- if (alpha <= std::numeric_limits<double>::max() && +- alpha >= std::numeric_limits<double>::lowest()) { +- EXPECT_EQ(static_cast<double>(before.alpha()), +- static_cast<double>(after.alpha())) +- << ss.str(); +- } +- if (beta <= std::numeric_limits<double>::max() && +- beta >= std::numeric_limits<double>::lowest()) { +- EXPECT_EQ(static_cast<double>(before.beta()), +- static_cast<double>(after.beta())) +- << ss.str(); +- } +- continue; +- } +-#endif +- + EXPECT_EQ(before.alpha(), after.alpha()); + EXPECT_EQ(before.beta(), after.beta()); + EXPECT_EQ(before, after) // +--- a/absl/random/exponential_distribution_test.cc ++++ b/absl/random/exponential_distribution_test.cc +@@ -30,6 +30,7 @@ + #include "gtest/gtest.h" + #include "absl/base/internal/raw_logging.h" + #include "absl/base/macros.h" ++#include "absl/numeric/internal/representation.h" + #include "absl/random/internal/chi_square.h" + #include "absl/random/internal/distribution_test_util.h" + #include "absl/random/internal/pcg_engine.h" +@@ -50,7 +51,15 @@ + #if defined(__EMSCRIPTEN__) + using RealTypes = ::testing::Types<float, double>; + #else +-using RealTypes = ::testing::Types<float, double, long double>; ++// double-double arithmetic is not supported well by either GCC or Clang; see ++// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99048, ++// https://bugs.llvm.org/show_bug.cgi?id=49131, and ++// https://bugs.llvm.org/show_bug.cgi?id=49132. Don't bother running these tests ++// with double doubles until compiler support is better. ++using RealTypes = ++ std::conditional<absl::numeric_internal::IsDoubleDouble(), ++ ::testing::Types<float, double>, ++ ::testing::Types<float, double, long double>>::type; + #endif // defined(__EMSCRIPTEN__) + TYPED_TEST_CASE(ExponentialDistributionTypedTest, RealTypes); + +@@ -130,23 +139,6 @@ TYPED_TEST(ExponentialDistributionTypedTest, SerializeTest) { + + ss >> after; + +-#if defined(__powerpc64__) || defined(__PPC64__) || defined(__powerpc__) || \ +- defined(__ppc__) || defined(__PPC__) +- if (std::is_same<TypeParam, long double>::value) { +- // Roundtripping floating point values requires sufficient precision to +- // reconstruct the exact value. It turns out that long double has some +- // errors doing this on ppc, particularly for values +- // near {1.0 +/- epsilon}. +- if (lambda <= std::numeric_limits<double>::max() && +- lambda >= std::numeric_limits<double>::lowest()) { +- EXPECT_EQ(static_cast<double>(before.lambda()), +- static_cast<double>(after.lambda())) +- << ss.str(); +- } +- continue; +- } +-#endif +- + EXPECT_EQ(before.lambda(), after.lambda()) // + << ss.str() << " " // + << (ss.good() ? "good " : "") // +--- a/absl/random/gaussian_distribution_test.cc ++++ b/absl/random/gaussian_distribution_test.cc +@@ -21,12 +21,14 @@ + #include <iterator> + #include <random> + #include <string> ++#include <type_traits> + #include <vector> + + #include "gmock/gmock.h" + #include "gtest/gtest.h" + #include "absl/base/internal/raw_logging.h" + #include "absl/base/macros.h" ++#include "absl/numeric/internal/representation.h" + #include "absl/random/internal/chi_square.h" + #include "absl/random/internal/distribution_test_util.h" + #include "absl/random/internal/sequence_urbg.h" +@@ -43,7 +45,15 @@ + template <typename RealType> + class GaussianDistributionInterfaceTest : public ::testing::Test {}; + +-using RealTypes = ::testing::Types<float, double, long double>; ++// double-double arithmetic is not supported well by either GCC or Clang; see ++// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99048, ++// https://bugs.llvm.org/show_bug.cgi?id=49131, and ++// https://bugs.llvm.org/show_bug.cgi?id=49132. Don't bother running these tests ++// with double doubles until compiler support is better. ++using RealTypes = ++ std::conditional<absl::numeric_internal::IsDoubleDouble(), ++ ::testing::Types<float, double>, ++ ::testing::Types<float, double, long double>>::type; + TYPED_TEST_CASE(GaussianDistributionInterfaceTest, RealTypes); + + TYPED_TEST(GaussianDistributionInterfaceTest, SerializeTest) { +@@ -129,32 +139,6 @@ TYPED_TEST(GaussianDistributionInterfaceTest, SerializeTest) { + + ss >> after; + +-#if defined(__powerpc64__) || defined(__PPC64__) || defined(__powerpc__) || \ +- defined(__ppc__) || defined(__PPC__) || defined(__EMSCRIPTEN__) +- if (std::is_same<TypeParam, long double>::value) { +- // Roundtripping floating point values requires sufficient precision +- // to reconstruct the exact value. It turns out that long double +- // has some errors doing this on ppc, particularly for values +- // near {1.0 +/- epsilon}. +- // +- // Emscripten is even worse, implementing long double as a 128-bit +- // type, but shipping with a strtold() that doesn't support that. +- if (mean <= std::numeric_limits<double>::max() && +- mean >= std::numeric_limits<double>::lowest()) { +- EXPECT_EQ(static_cast<double>(before.mean()), +- static_cast<double>(after.mean())) +- << ss.str(); +- } +- if (stddev <= std::numeric_limits<double>::max() && +- stddev >= std::numeric_limits<double>::lowest()) { +- EXPECT_EQ(static_cast<double>(before.stddev()), +- static_cast<double>(after.stddev())) +- << ss.str(); +- } +- continue; +- } +-#endif +- + EXPECT_EQ(before.mean(), after.mean()); + EXPECT_EQ(before.stddev(), after.stddev()) // + << ss.str() << " " // +--- a/absl/random/uniform_real_distribution_test.cc ++++ b/absl/random/uniform_real_distribution_test.cc +@@ -20,11 +20,13 @@ + #include <random> + #include <sstream> + #include <string> ++#include <type_traits> + #include <vector> + + #include "gmock/gmock.h" + #include "gtest/gtest.h" + #include "absl/base/internal/raw_logging.h" ++#include "absl/numeric/internal/representation.h" + #include "absl/random/internal/chi_square.h" + #include "absl/random/internal/distribution_test_util.h" + #include "absl/random/internal/pcg_engine.h" +@@ -58,7 +60,15 @@ + #if defined(__EMSCRIPTEN__) + using RealTypes = ::testing::Types<float, double>; + #else +-using RealTypes = ::testing::Types<float, double, long double>; ++// double-double arithmetic is not supported well by either GCC or Clang; see ++// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99048, ++// https://bugs.llvm.org/show_bug.cgi?id=49131, and ++// https://bugs.llvm.org/show_bug.cgi?id=49132. Don't bother running these tests ++// with double doubles until compiler support is better. ++using RealTypes = ++ std::conditional<absl::numeric_internal::IsDoubleDouble(), ++ ::testing::Types<float, double>, ++ ::testing::Types<float, double, long double>>::type; + #endif // defined(__EMSCRIPTEN__) + + TYPED_TEST_SUITE(UniformRealDistributionTest, RealTypes); +--- a/absl/strings/BUILD.bazel ++++ b/absl/strings/BUILD.bazel +@@ -645,6 +645,7 @@ cc_library(name = "str_format_internal", + "//absl/functional:function_ref", + "//absl/meta:type_traits", + "//absl/numeric:int128", ++ "//absl/numeric:representation", + "//absl/types:optional", + "//absl/types:span", + ], +--- a/absl/strings/CMakeLists.txt ++++ b/absl/strings/CMakeLists.txt +@@ -396,6 +396,7 @@ absl_cc_library(NAME str_format_internal + absl::strings + absl::config + absl::core_headers ++ absl::numeric_representation + absl::type_traits + absl::int128 + absl::span +--- a/absl/strings/internal/str_format/float_conversion.cc ++++ b/absl/strings/internal/str_format/float_conversion.cc +@@ -15,6 +15,7 @@ + #include "absl/functional/function_ref.h" + #include "absl/meta/type_traits.h" + #include "absl/numeric/int128.h" ++#include "absl/numeric/internal/representation.h" + #include "absl/strings/numbers.h" + #include "absl/types/optional.h" + #include "absl/types/span.h" +@@ -25,6 +26,8 @@ + + namespace { + ++using ::absl::numeric_internal::IsDoubleDouble; ++ + // The code below wants to avoid heap allocations. + // To do so it needs to allocate memory on the stack. + // `StackArray` will allocate memory on the stack in the form of a uint32_t +@@ -98,13 +101,6 @@ + return next_carry % divisor; + } + +-constexpr bool IsDoubleDouble() { +- // This is the `double-double` representation of `long double`. +- // We do not handle it natively. Fallback to snprintf. +- return std::numeric_limits<long double>::digits == +- 2 * std::numeric_limits<double>::digits; +-} +- + using MaxFloatType = + typename std::conditional<IsDoubleDouble(), double, long double>::type; + +@@ -1391,6 +1387,8 @@ + bool ConvertFloatImpl(long double v, const FormatConversionSpecImpl &conv, + FormatSinkImpl *sink) { + if (IsDoubleDouble()) { ++ // This is the `double-double` representation of `long double`. We do not ++ // handle it natively. Fallback to snprintf. + return FallbackToSnprintf(v, conv, sink); + } + diff --git a/debian/patches/endian-hash.diff b/debian/patches/endian-hash.diff new file mode 100644 index 00000000..01c1b6b0 --- /dev/null +++ b/debian/patches/endian-hash.diff @@ -0,0 +1,111 @@ +From: Benjamin Barenblat <bbaren@google.com> +Subject: Remove endian-sensitivity from hash slow path +Forwarded: yes +Applied-Upstream: https://github.com/abseil/abseil-cpp/commit/9c6a50fdd80bb39fabd95faeda84f04062685ff3 + +Prior to this commit, the Abseil hash fast path was endian-agnostic, but +the slow path assumed a little-endian platform. Change the slow path to +be endian-correct, ensuring that values produced by the fast and slow +paths are equal even on big-endian systems. + +The author works at Google. Upstream applied this patch as Piper revision +355424258 and exported it to GitHub; the Applied-Upstream URL above points to +the exported commit. + +--- a/absl/hash/BUILD.bazel ++++ b/absl/hash/BUILD.bazel +@@ -37,6 +37,7 @@ cc_library(name = "hash", + linkopts = ABSL_DEFAULT_LINKOPTS, + deps = [ + ":city", ++ "//absl/base:config", + "//absl/base:core_headers", + "//absl/base:endian", + "//absl/container:fixed_array", +--- a/absl/hash/CMakeLists.txt ++++ b/absl/hash/CMakeLists.txt +@@ -25,6 +25,7 @@ absl_cc_library(NAME hash + COPTS + ${ABSL_DEFAULT_COPTS} + DEPS ++ absl::config + absl::core_headers + absl::endian + absl::fixed_array +--- a/absl/hash/internal/hash.h ++++ b/absl/hash/internal/hash.h +@@ -38,7 +38,8 @@ + #include <utility> + #include <vector> + +-#include "absl/base/internal/endian.h" ++#include "absl/base/config.h" ++#include "absl/base/internal/unaligned_access.h" + #include "absl/base/port.h" + #include "absl/container/fixed_array.h" + #include "absl/meta/type_traits.h" +@@ -804,26 +805,54 @@ class ABSL_DLL CityHashState + size_t len); + + // Reads 9 to 16 bytes from p. +- // The first 8 bytes are in .first, the rest (zero padded) bytes are in +- // .second. ++ // The least significant 8 bytes are in .first, the rest (zero padded) bytes ++ // are in .second. + static std::pair<uint64_t, uint64_t> Read9To16(const unsigned char* p, + size_t len) { +- uint64_t high = little_endian::Load64(p + len - 8); +- return {little_endian::Load64(p), high >> (128 - len * 8)}; ++ uint64_t low_mem = absl::base_internal::UnalignedLoad64(p); ++ uint64_t high_mem = absl::base_internal::UnalignedLoad64(p + len - 8); ++#ifdef ABSL_IS_LITTLE_ENDIAN ++ uint64_t most_significant = high_mem; ++ uint64_t least_significant = low_mem; ++#else ++ uint64_t most_significant = low_mem; ++ uint64_t least_significant = high_mem; ++#endif ++ return {least_significant, most_significant >> (128 - len * 8)}; + } + + // Reads 4 to 8 bytes from p. Zero pads to fill uint64_t. + static uint64_t Read4To8(const unsigned char* p, size_t len) { +- return (static_cast<uint64_t>(little_endian::Load32(p + len - 4)) +- << (len - 4) * 8) | +- little_endian::Load32(p); ++ uint32_t low_mem = absl::base_internal::UnalignedLoad32(p); ++ uint32_t high_mem = absl::base_internal::UnalignedLoad32(p + len - 4); ++#ifdef ABSL_IS_LITTLE_ENDIAN ++ uint32_t most_significant = high_mem; ++ uint32_t least_significant = low_mem; ++#else ++ uint32_t most_significant = low_mem; ++ uint32_t least_significant = high_mem; ++#endif ++ return (static_cast<uint64_t>(most_significant) << (len - 4) * 8) | ++ least_significant; + } + + // Reads 1 to 3 bytes from p. Zero pads to fill uint32_t. + static uint32_t Read1To3(const unsigned char* p, size_t len) { +- return static_cast<uint32_t>((p[0]) | // +- (p[len / 2] << (len / 2 * 8)) | // +- (p[len - 1] << ((len - 1) * 8))); ++ unsigned char mem0 = p[0]; ++ unsigned char mem1 = p[len / 2]; ++ unsigned char mem2 = p[len - 1]; ++#ifdef ABSL_IS_LITTLE_ENDIAN ++ unsigned char significant2 = mem2; ++ unsigned char significant1 = mem1; ++ unsigned char significant0 = mem0; ++#else ++ unsigned char significant2 = mem0; ++ unsigned char significant1 = mem1; ++ unsigned char significant0 = mem2; ++#endif ++ return static_cast<uint32_t>(significant0 | // ++ (significant1 << (len / 2 * 8)) | // ++ (significant2 << ((len - 1) * 8))); + } + + ABSL_ATTRIBUTE_ALWAYS_INLINE static uint64_t Mix(uint64_t state, uint64_t v) { diff --git a/debian/patches/endian-random.diff b/debian/patches/endian-random.diff new file mode 100644 index 00000000..9fe2b166 --- /dev/null +++ b/debian/patches/endian-random.diff @@ -0,0 +1,249 @@ +From: Benjamin Barenblat <bbaren@google.com> +Subject: Remove endian-sensitivity from Abseil's RNG +Forwarded: yes +Applied-Upstream: https://github.com/abseil/abseil-cpp/commit/c36d825d9a5443f81d2656685ae021d6326da90c + +Ensure that the Abseil random number generator produces identical output +on both big- and little-endian platforms by byte-swapping appropriately +on big-endian systems. + +The author works at Google. Upstream applied this patch as Piper +revision 355635051 and exported it to GitHub; the Applied-Upstream URL +above points to the exported commit. + +--- a/absl/base/BUILD.bazel ++++ b/absl/base/BUILD.bazel +@@ -479,6 +479,7 @@ + copts = ABSL_DEFAULT_COPTS, + linkopts = ABSL_DEFAULT_LINKOPTS, + deps = [ ++ ":base", + ":config", + ":core_headers", + ], +--- a/absl/base/CMakeLists.txt ++++ b/absl/base/CMakeLists.txt +@@ -418,6 +418,7 @@ + COPTS + ${ABSL_DEFAULT_COPTS} + DEPS ++ absl::base + absl::config + absl::core_headers + PUBLIC +--- a/absl/base/internal/endian.h ++++ b/absl/base/internal/endian.h +@@ -26,6 +26,7 @@ + #endif + + #include <cstdint> ++#include "absl/base/casts.h" + #include "absl/base/config.h" + #include "absl/base/internal/unaligned_access.h" + #include "absl/base/port.h" +@@ -173,6 +174,36 @@ + + #endif /* ENDIAN */ + ++inline uint8_t FromHost(uint8_t x) { return x; } ++inline uint16_t FromHost(uint16_t x) { return FromHost16(x); } ++inline uint32_t FromHost(uint32_t x) { return FromHost32(x); } ++inline uint64_t FromHost(uint64_t x) { return FromHost64(x); } ++inline uint8_t ToHost(uint8_t x) { return x; } ++inline uint16_t ToHost(uint16_t x) { return ToHost16(x); } ++inline uint32_t ToHost(uint32_t x) { return ToHost32(x); } ++inline uint64_t ToHost(uint64_t x) { return ToHost64(x); } ++ ++inline int8_t FromHost(int8_t x) { return x; } ++inline int16_t FromHost(int16_t x) { ++ return bit_cast<int16_t>(FromHost16(bit_cast<uint16_t>(x))); ++} ++inline int32_t FromHost(int32_t x) { ++ return bit_cast<int32_t>(FromHost32(bit_cast<uint32_t>(x))); ++} ++inline int64_t FromHost(int64_t x) { ++ return bit_cast<int64_t>(FromHost64(bit_cast<uint64_t>(x))); ++} ++inline int8_t ToHost(int8_t x) { return x; } ++inline int16_t ToHost(int16_t x) { ++ return bit_cast<int16_t>(ToHost16(bit_cast<uint16_t>(x))); ++} ++inline int32_t ToHost(int32_t x) { ++ return bit_cast<int32_t>(ToHost32(bit_cast<uint32_t>(x))); ++} ++inline int64_t ToHost(int64_t x) { ++ return bit_cast<int64_t>(ToHost64(bit_cast<uint64_t>(x))); ++} ++ + // Functions to do unaligned loads and stores in little-endian order. + inline uint16_t Load16(const void *p) { + return ToHost16(ABSL_INTERNAL_UNALIGNED_LOAD16(p)); +@@ -233,6 +264,36 @@ + + #endif /* ENDIAN */ + ++inline uint8_t FromHost(uint8_t x) { return x; } ++inline uint16_t FromHost(uint16_t x) { return FromHost16(x); } ++inline uint32_t FromHost(uint32_t x) { return FromHost32(x); } ++inline uint64_t FromHost(uint64_t x) { return FromHost64(x); } ++inline uint8_t ToHost(uint8_t x) { return x; } ++inline uint16_t ToHost(uint16_t x) { return ToHost16(x); } ++inline uint32_t ToHost(uint32_t x) { return ToHost32(x); } ++inline uint64_t ToHost(uint64_t x) { return ToHost64(x); } ++ ++inline int8_t FromHost(int8_t x) { return x; } ++inline int16_t FromHost(int16_t x) { ++ return bit_cast<int16_t>(FromHost16(bit_cast<uint16_t>(x))); ++} ++inline int32_t FromHost(int32_t x) { ++ return bit_cast<int32_t>(FromHost32(bit_cast<uint32_t>(x))); ++} ++inline int64_t FromHost(int64_t x) { ++ return bit_cast<int64_t>(FromHost64(bit_cast<uint64_t>(x))); ++} ++inline int8_t ToHost(int8_t x) { return x; } ++inline int16_t ToHost(int16_t x) { ++ return bit_cast<int16_t>(ToHost16(bit_cast<uint16_t>(x))); ++} ++inline int32_t ToHost(int32_t x) { ++ return bit_cast<int32_t>(ToHost32(bit_cast<uint32_t>(x))); ++} ++inline int64_t ToHost(int64_t x) { ++ return bit_cast<int64_t>(ToHost64(bit_cast<uint64_t>(x))); ++} ++ + // Functions to do unaligned loads and stores in big-endian order. + inline uint16_t Load16(const void *p) { + return ToHost16(ABSL_INTERNAL_UNALIGNED_LOAD16(p)); +--- a/absl/random/CMakeLists.txt ++++ b/absl/random/CMakeLists.txt +@@ -611,6 +611,7 @@ + ${ABSL_DEFAULT_LINKOPTS} + DEPS + absl::config ++ absl::endian + TESTONLY + ) + +@@ -758,6 +759,7 @@ + LINKOPTS + ${ABSL_DEFAULT_LINKOPTS} + DEPS ++ absl::endian + absl::random_internal_iostream_state_saver + absl::random_internal_randen + absl::raw_logging_internal +@@ -1119,6 +1121,7 @@ + LINKOPTS + ${ABSL_DEFAULT_LINKOPTS} + DEPS ++ absl::endian + absl::random_internal_randen_slow + gtest_main + ) +--- a/absl/random/internal/BUILD.bazel ++++ b/absl/random/internal/BUILD.bazel +@@ -124,7 +124,10 @@ + ], + copts = ABSL_DEFAULT_COPTS, + linkopts = ABSL_DEFAULT_LINKOPTS, +- deps = ["//absl/base:config"], ++ deps = [ ++ "//absl/base:config", ++ "//absl/base:endian", ++ ], + ) + + cc_library( +@@ -241,6 +244,7 @@ + deps = [ + ":iostream_state_saver", + ":randen", ++ "//absl/base:endian", + "//absl/meta:type_traits", + ], + ) +@@ -606,6 +610,7 @@ + ":platform", + ":randen_slow", + "@com_google_googletest//:gtest_main", ++ "//absl/base:endian", + ], + ) + +--- a/absl/random/internal/explicit_seed_seq.h ++++ b/absl/random/internal/explicit_seed_seq.h +@@ -23,6 +23,7 @@ + #include <vector> + + #include "absl/base/config.h" ++#include "absl/base/internal/endian.h" + + namespace absl { + ABSL_NAMESPACE_BEGIN +@@ -73,7 +74,7 @@ + template <typename OutIterator> + void generate(OutIterator begin, OutIterator end) { + for (size_t index = 0; begin != end; begin++) { +- *begin = state_.empty() ? 0 : state_[index++]; ++ *begin = state_.empty() ? 0 : little_endian::FromHost32(state_[index++]); + if (index >= state_.size()) { + index = 0; + } +--- a/absl/random/internal/randen_engine.h ++++ b/absl/random/internal/randen_engine.h +@@ -23,6 +23,7 @@ + #include <limits> + #include <type_traits> + ++#include "absl/base/internal/endian.h" + #include "absl/meta/type_traits.h" + #include "absl/random/internal/iostream_state_saver.h" + #include "absl/random/internal/randen.h" +@@ -76,7 +77,7 @@ + impl_.Generate(state_); + } + +- return state_[next_++]; ++ return little_endian::ToHost(state_[next_++]); + } + + template <class SeedSequence> +@@ -181,7 +182,8 @@ + // In the case that `elem` is `uint8_t`, it must be cast to something + // larger so that it prints as an integer rather than a character. For + // simplicity, apply the cast all circumstances. +- os << static_cast<numeric_type>(elem) << os.fill(); ++ os << static_cast<numeric_type>(little_endian::FromHost(elem)) ++ << os.fill(); + } + os << engine.next_; + return os; +@@ -200,7 +202,7 @@ + // necessary to read a wider type and then cast it to uint8_t. + numeric_type value; + is >> value; +- elem = static_cast<result_type>(value); ++ elem = little_endian::ToHost(static_cast<result_type>(value)); + } + is >> next; + if (is.fail()) { +--- a/absl/random/internal/randen_slow_test.cc ++++ b/absl/random/internal/randen_slow_test.cc +@@ -17,6 +17,7 @@ + #include <cstring> + + #include "gtest/gtest.h" ++#include "absl/base/internal/endian.h" + #include "absl/random/internal/randen_traits.h" + + namespace { +@@ -56,7 +57,7 @@ + + uint64_t* id = d.state; + for (const auto& elem : kGolden) { +- EXPECT_EQ(elem, *id++); ++ EXPECT_EQ(absl::little_endian::FromHost64(elem), *id++); + } + } + diff --git a/debian/patches/fix-hppa.diff b/debian/patches/fix-hppa.diff new file mode 100644 index 00000000..915efff4 --- /dev/null +++ b/debian/patches/fix-hppa.diff @@ -0,0 +1,26 @@ +From: John David Anglin <dave.anglin@bell.net> +Subject: Fix build on hppa +Bug-Debian: https://bugs.debian.org/971768 +Reviewed-by: Benjamin Barenblat <bbaren@debian.org> + +--- a/absl/base/internal/direct_mmap.h ++++ b/absl/base/internal/direct_mmap.h +@@ -74,6 +74,7 @@ + inline void* DirectMmap(void* start, size_t length, int prot, int flags, int fd, + off64_t offset) noexcept { + #if defined(__i386__) || defined(__ARM_ARCH_3__) || defined(__ARM_EABI__) || \ ++ (defined(__hppa__) && !defined(__LP64__)) || \ + (defined(__mips__) && _MIPS_SIM == _MIPS_SIM_ABI32) || \ + (defined(__PPC__) && !defined(__PPC64__)) || \ + (defined(__riscv) && __riscv_xlen == 32) || \ +--- a/absl/debugging/internal/examine_stack.cc ++++ b/absl/debugging/internal/examine_stack.cc +@@ -48,6 +48,8 @@ + return reinterpret_cast<void*>(context->uc_mcontext.pc); + #elif defined(__arm__) + return reinterpret_cast<void*>(context->uc_mcontext.arm_pc); ++#elif defined(__hppa__) ++ return reinterpret_cast<void*>(context->uc_mcontext.sc_iaoq[0]); + #elif defined(__i386__) + if (14 < ABSL_ARRAYSIZE(context->uc_mcontext.gregs)) + return reinterpret_cast<void*>(context->uc_mcontext.gregs[14]); diff --git a/debian/patches/fma-contraction.diff b/debian/patches/fma-contraction.diff new file mode 100644 index 00000000..95181a36 --- /dev/null +++ b/debian/patches/fma-contraction.diff @@ -0,0 +1,63 @@ +From: Benjamin Barenblat <bbaren@google.com> +Subject: Make tests tolerant of FMA contraction +Forwarded: yes +Applied-Upstream: https://github.com/abseil/abseil-cpp/commit/b0735979d778a768caee207f01f327535cbd2140 + +Weaken Duration.ToDoubleSecondsCheckEdgeCases and +Duration.ToDoubleSecondsCheckRandom to make them less sensitive to fused +multiply/add contraction. + +The author works at Google. Upstream applied this patch as Piper +revision 360297653 and exported it to GitHub; the the Applied-Upstream URL +above points to the exported commit. + +--- a/absl/time/duration_test.cc ++++ b/absl/time/duration_test.cc +@@ -1369,10 +1369,13 @@ + EXPECT_THAT(ToTimeval(absl::Nanoseconds(2000)), TimevalMatcher(tv)); + } + +-void VerifySameAsMul(double time_as_seconds, int* const misses) { ++void VerifyApproxSameAsMul(double time_as_seconds, int* const misses) { + auto direct_seconds = absl::Seconds(time_as_seconds); + auto mul_by_one_second = time_as_seconds * absl::Seconds(1); +- if (direct_seconds != mul_by_one_second) { ++ // These are expected to differ by up to one tick due to fused multiply/add ++ // contraction. ++ if (absl::AbsDuration(direct_seconds - mul_by_one_second) > ++ absl::time_internal::MakeDuration(0, 1u)) { + if (*misses > 10) return; + ASSERT_LE(++(*misses), 10) << "Too many errors, not reporting more."; + EXPECT_EQ(direct_seconds, mul_by_one_second) +@@ -1384,7 +1387,8 @@ + // For a variety of interesting durations, we find the exact point + // where one double converts to that duration, and the very next double + // converts to the next duration. For both of those points, verify that +-// Seconds(point) returns the same duration as point * Seconds(1.0) ++// Seconds(point) returns a duration near point * Seconds(1.0). (They may ++// not be exactly equal due to fused multiply/add contraction.) + TEST(Duration, ToDoubleSecondsCheckEdgeCases) { + constexpr uint32_t kTicksPerSecond = absl::time_internal::kTicksPerSecond; + constexpr auto duration_tick = absl::time_internal::MakeDuration(0, 1u); +@@ -1423,8 +1427,8 @@ + } + // Now low_edge is the highest double that converts to Duration d, + // and high_edge is the lowest double that converts to Duration after_d. +- VerifySameAsMul(low_edge, &misses); +- VerifySameAsMul(high_edge, &misses); ++ VerifyApproxSameAsMul(low_edge, &misses); ++ VerifyApproxSameAsMul(high_edge, &misses); + } + } + } +@@ -1444,8 +1448,8 @@ + int misses = 0; + for (int i = 0; i < 1000000; ++i) { + double d = std::exp(uniform(gen)); +- VerifySameAsMul(d, &misses); +- VerifySameAsMul(-d, &misses); ++ VerifyApproxSameAsMul(d, &misses); ++ VerifyApproxSameAsMul(-d, &misses); + } + } + diff --git a/debian/patches/latomic.diff b/debian/patches/latomic.diff new file mode 100644 index 00000000..d78c7469 --- /dev/null +++ b/debian/patches/latomic.diff @@ -0,0 +1,20 @@ +From: Benjamin Barenblat <bbaren@google.com> +Subject: Use libatomic if necessary +Bug-Debian: https://bugs.debian.org/973492 + +On some architectures, notably armel, Abseil needs symbols defined in +libatomic. Abseil does not currently have a well-developed system to +declare external library dependencies, so just have the linker determine +if anything needs libatomic and add the DT_NEEDED entry where necessary. + +--- a/absl/copts/AbseilConfigureCopts.cmake ++++ b/absl/copts/AbseilConfigureCopts.cmake +@@ -64,4 +64,8 @@ + set(ABSL_TEST_COPTS "") + endif() + ++list(APPEND ABSL_DEFAULT_LINKOPTS ++ "-Wl,--as-needed" "-latomic" "-Wl,--no-as-needed" ++) ++ + set(ABSL_CXX_STANDARD "${CMAKE_CXX_STANDARD}") diff --git a/debian/patches/nan-narrowing.diff b/debian/patches/nan-narrowing.diff new file mode 100644 index 00000000..c7ec9325 --- /dev/null +++ b/debian/patches/nan-narrowing.diff @@ -0,0 +1,25 @@ +From: Benjamin Barenblat <bbaren@google.com> +Subject: Avoid libgcc -NaN narrowing bug +Forwarded: yes +Applied-Upstream: https://github.com/abseil/abseil-cpp/commit/1bae23e32ba1f1af7c7d1488a69a351ec96dc98d + +When testing -NaN parsing, avoid narrowing -NaN from double to float. This +avoids a bug in libgcc (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=98251). + +The author works at Google. Upstream applied this patch as Piper revision +347654751 and exported it to GitHub; the Applied-Upstream URL above points to +the exported commit. + +--- a/absl/strings/charconv_test.cc ++++ b/absl/strings/charconv_test.cc +@@ -653,7 +653,9 @@ TEST(FromChars, NaNFloats) { + negative_from_chars_float); + EXPECT_TRUE(std::signbit(negative_from_chars_float)); + EXPECT_FALSE(Identical(negative_from_chars_float, from_chars_float)); +- from_chars_float = std::copysign(from_chars_float, -1.0); ++ // Use the (float, float) overload of std::copysign to prevent narrowing; ++ // see https://gcc.gnu.org/bugzilla/show_bug.cgi?id=98251. ++ from_chars_float = std::copysign(from_chars_float, -1.0f); + EXPECT_TRUE(Identical(negative_from_chars_float, from_chars_float)); + } + } diff --git a/debian/patches/ppc-float-conversion.diff b/debian/patches/ppc-float-conversion.diff new file mode 100644 index 00000000..f0ff9595 --- /dev/null +++ b/debian/patches/ppc-float-conversion.diff @@ -0,0 +1,268 @@ +From: Samuel Benzaquen <sbenza@google.com> +Subject: Fix float conversion for PPC. +Origin: backport, https://github.com/abseil/abseil-cpp/commit/c36d825d9a5443f81d2656685ae021d6326da90c + +In PPC `long double` is a double-double representation which behaves weirdly +wrt numeric_limits. Don't take `long double` into account when we are not +handling `long double` natively anyway. + +Fix the convert test to always run the conversion even if we are not going to +compare against libc's printf result. This allows exercising the code itself to +make sure we don't trigger assertions or UB found by sanitizers. + +The author works at Google. Upstream applied this patch as Piper revision +355857729 and exported it to GitHub; the Applied-Upstream URL above points to +the exported commit. + +--- a/absl/strings/internal/str_format/convert_test.cc ++++ b/absl/strings/internal/str_format/convert_test.cc +@@ -540,7 +540,8 @@ + } + + template <typename Floating> +-void TestWithMultipleFormatsHelper(const std::vector<Floating> &floats) { ++void TestWithMultipleFormatsHelper(const std::vector<Floating> &floats, ++ const std::set<Floating> &skip_verify) { + const NativePrintfTraits &native_traits = VerifyNativeImplementation(); + // Reserve the space to ensure we don't allocate memory in the output itself. + std::string str_format_result; +@@ -588,7 +589,16 @@ + AppendPack(&str_format_result, format, absl::MakeSpan(args)); + } + +- if (string_printf_result != str_format_result) { ++#ifdef _MSC_VER ++ // MSVC has a different rounding policy than us so we can't test our ++ // implementation against the native one there. ++ continue; ++#elif defined(__APPLE__) ++ // Apple formats NaN differently (+nan) vs. (nan) ++ if (std::isnan(d)) continue; ++#endif ++ if (string_printf_result != str_format_result && ++ skip_verify.find(d) == skip_verify.end()) { + // We use ASSERT_EQ here because failures are usually correlated and a + // bug would print way too many failed expectations causing the test + // to time out. +@@ -602,12 +612,6 @@ + } + + TEST_F(FormatConvertTest, Float) { +-#ifdef _MSC_VER +- // MSVC has a different rounding policy than us so we can't test our +- // implementation against the native one there. +- return; +-#endif // _MSC_VER +- + std::vector<float> floats = {0.0f, + -0.0f, + .9999999f, +@@ -621,7 +625,8 @@ + std::numeric_limits<float>::epsilon(), + std::numeric_limits<float>::epsilon() + 1.0f, + std::numeric_limits<float>::infinity(), +- -std::numeric_limits<float>::infinity()}; ++ -std::numeric_limits<float>::infinity(), ++ std::nanf("")}; + + // Some regression tests. + floats.push_back(0.999999989f); +@@ -650,21 +655,14 @@ + std::sort(floats.begin(), floats.end()); + floats.erase(std::unique(floats.begin(), floats.end()), floats.end()); + +-#ifndef __APPLE__ +- // Apple formats NaN differently (+nan) vs. (nan) +- floats.push_back(std::nan("")); +-#endif +- +- TestWithMultipleFormatsHelper(floats); ++ TestWithMultipleFormatsHelper(floats, {}); + } + + TEST_F(FormatConvertTest, Double) { +-#ifdef _MSC_VER +- // MSVC has a different rounding policy than us so we can't test our +- // implementation against the native one there. +- return; +-#endif // _MSC_VER +- ++ // For values that we know won't match the standard library implementation we ++ // skip verification, but still run the algorithm to catch asserts/sanitizer ++ // bugs. ++ std::set<double> skip_verify; + std::vector<double> doubles = {0.0, + -0.0, + .99999999999999, +@@ -678,7 +676,8 @@ + std::numeric_limits<double>::epsilon(), + std::numeric_limits<double>::epsilon() + 1, + std::numeric_limits<double>::infinity(), +- -std::numeric_limits<double>::infinity()}; ++ -std::numeric_limits<double>::infinity(), ++ std::nan("")}; + + // Some regression tests. + doubles.push_back(0.99999999999999989); +@@ -708,33 +707,29 @@ + "5084551339423045832369032229481658085593321233482747978262041447231" + "68738177180919299881250404026184124858368.000000"; + +- if (!gcc_bug_22142) { +- for (int exp = -300; exp <= 300; ++exp) { +- const double all_ones_mantissa = 0x1fffffffffffff; +- doubles.push_back(std::ldexp(all_ones_mantissa, exp)); ++ for (int exp = -300; exp <= 300; ++exp) { ++ const double all_ones_mantissa = 0x1fffffffffffff; ++ doubles.push_back(std::ldexp(all_ones_mantissa, exp)); ++ if (gcc_bug_22142) { ++ skip_verify.insert(doubles.back()); + } + } + + if (gcc_bug_22142) { +- for (auto &d : doubles) { +- using L = std::numeric_limits<double>; +- double d2 = std::abs(d); +- if (d2 == L::max() || d2 == L::min() || d2 == L::denorm_min()) { +- d = 0; +- } +- } ++ using L = std::numeric_limits<double>; ++ skip_verify.insert(L::max()); ++ skip_verify.insert(L::min()); // NOLINT ++ skip_verify.insert(L::denorm_min()); ++ skip_verify.insert(-L::max()); ++ skip_verify.insert(-L::min()); // NOLINT ++ skip_verify.insert(-L::denorm_min()); + } + + // Remove duplicates to speed up the logic below. + std::sort(doubles.begin(), doubles.end()); + doubles.erase(std::unique(doubles.begin(), doubles.end()), doubles.end()); + +-#ifndef __APPLE__ +- // Apple formats NaN differently (+nan) vs. (nan) +- doubles.push_back(std::nan("")); +-#endif +- +- TestWithMultipleFormatsHelper(doubles); ++ TestWithMultipleFormatsHelper(doubles, skip_verify); + } + + TEST_F(FormatConvertTest, DoubleRound) { +@@ -1055,11 +1050,6 @@ + } + + TEST_F(FormatConvertTest, LongDouble) { +-#ifdef _MSC_VER +- // MSVC has a different rounding policy than us so we can't test our +- // implementation against the native one there. +- return; +-#endif // _MSC_VER + const NativePrintfTraits &native_traits = VerifyNativeImplementation(); + const char *const kFormats[] = {"%", "%.3", "%8.5", "%9", "%.5000", + "%.60", "%+", "% ", "%-10"}; +@@ -1120,10 +1110,18 @@ + for (auto d : doubles) { + FormatArgImpl arg(d); + UntypedFormatSpecImpl format(fmt_str); ++ std::string result = FormatPack(format, {&arg, 1}); ++ ++#ifdef _MSC_VER ++ // MSVC has a different rounding policy than us so we can't test our ++ // implementation against the native one there. ++ continue; ++#endif // _MSC_VER ++ + // We use ASSERT_EQ here because failures are usually correlated and a + // bug would print way too many failed expectations causing the test to + // time out. +- ASSERT_EQ(StrPrint(fmt_str.c_str(), d), FormatPack(format, {&arg, 1})) ++ ASSERT_EQ(StrPrint(fmt_str.c_str(), d), result) + << fmt_str << " " << StrPrint("%.18Lg", d) << " " + << StrPrint("%La", d) << " " << StrPrint("%.1080Lf", d); + } +--- a/absl/strings/internal/str_format/float_conversion.cc ++++ b/absl/strings/internal/str_format/float_conversion.cc +@@ -98,12 +98,22 @@ + return next_carry % divisor; + } + ++constexpr bool IsDoubleDouble() { ++ // This is the `double-double` representation of `long double`. ++ // We do not handle it natively. Fallback to snprintf. ++ return std::numeric_limits<long double>::digits == ++ 2 * std::numeric_limits<double>::digits; ++} ++ ++using MaxFloatType = ++ typename std::conditional<IsDoubleDouble(), double, long double>::type; ++ + // Generates the decimal representation for an integer of the form `v * 2^exp`, + // where `v` and `exp` are both positive integers. + // It generates the digits from the left (ie the most significant digit first) + // to allow for direct printing into the sink. + // +-// Requires `0 <= exp` and `exp <= numeric_limits<long double>::max_exponent`. ++// Requires `0 <= exp` and `exp <= numeric_limits<MaxFloatType>::max_exponent`. + class BinaryToDecimal { + static constexpr int ChunksNeeded(int exp) { + // We will left shift a uint128 by `exp` bits, so we need `128+exp` total +@@ -118,10 +128,10 @@ + static void RunConversion(uint128 v, int exp, + absl::FunctionRef<void(BinaryToDecimal)> f) { + assert(exp > 0); +- assert(exp <= std::numeric_limits<long double>::max_exponent); ++ assert(exp <= std::numeric_limits<MaxFloatType>::max_exponent); + static_assert( + StackArray::kMaxCapacity >= +- ChunksNeeded(std::numeric_limits<long double>::max_exponent), ++ ChunksNeeded(std::numeric_limits<MaxFloatType>::max_exponent), + ""); + + StackArray::RunWithCapacity( +@@ -218,14 +228,14 @@ + + // Converts a value of the form `x * 2^-exp` into a sequence of decimal digits. + // Requires `-exp < 0` and +-// `-exp >= limits<long double>::min_exponent - limits<long double>::digits`. ++// `-exp >= limits<MaxFloatType>::min_exponent - limits<MaxFloatType>::digits`. + class FractionalDigitGenerator { + public: + // Run the conversion for `v * 2^exp` and call `f(generator)`. + // This function will allocate enough stack space to perform the conversion. + static void RunConversion( + uint128 v, int exp, absl::FunctionRef<void(FractionalDigitGenerator)> f) { +- using Limits = std::numeric_limits<long double>; ++ using Limits = std::numeric_limits<MaxFloatType>; + assert(-exp < 0); + assert(-exp >= Limits::min_exponent - 128); + static_assert(StackArray::kMaxCapacity >= +@@ -858,10 +868,10 @@ + // This buffer holds the "0x1.ab1de3" portion of "0x1.ab1de3pe+2". Compute the + // size with long double which is the largest of the floats. + constexpr size_t kBufSizeForHexFloatRepr = +- 2 // 0x +- + std::numeric_limits<long double>::digits / 4 // number of hex digits +- + 1 // round up +- + 1; // "." (dot) ++ 2 // 0x ++ + std::numeric_limits<MaxFloatType>::digits / 4 // number of hex digits ++ + 1 // round up ++ + 1; // "." (dot) + char digits_buffer[kBufSizeForHexFloatRepr]; + char *digits_iter = digits_buffer; + const char *const digits = +@@ -1380,10 +1390,7 @@ + + bool ConvertFloatImpl(long double v, const FormatConversionSpecImpl &conv, + FormatSinkImpl *sink) { +- if (std::numeric_limits<long double>::digits == +- 2 * std::numeric_limits<double>::digits) { +- // This is the `double-double` representation of `long double`. +- // We do not handle it natively. Fallback to snprintf. ++ if (IsDoubleDouble()) { + return FallbackToSnprintf(v, conv, sink); + } + diff --git a/debian/patches/series b/debian/patches/series new file mode 100644 index 00000000..efe60449 --- /dev/null +++ b/debian/patches/series @@ -0,0 +1,11 @@ +configure.diff +fix-hppa.diff +std-hash.diff +latomic.diff +cpu-frequency.diff +nan-narrowing.diff +endian-hash.diff +endian-random.diff +ppc-float-conversion.diff +fma-contraction.diff +disable-double-double-tests.diff diff --git a/debian/patches/std-hash.diff b/debian/patches/std-hash.diff new file mode 100644 index 00000000..52096742 --- /dev/null +++ b/debian/patches/std-hash.diff @@ -0,0 +1,46 @@ +From: Benjamin Barenblat <bbaren@google.com> +Subject: Work around broken std::hash on s390x +Forwarded: no +Bug-Debian: https://bugs.debian.org/977638 + +On s390x, std::hash hashes large classes of data to the same value, which +violates assumptions made by the Abseil tests. #ifdef out the test code that +depends on those assumptions. + +--- a/absl/hash/hash_test.cc ++++ b/absl/hash/hash_test.cc +@@ -358,6 +358,8 @@ + TEST(HashValueTest, StdBitset) { + EXPECT_TRUE((is_hashable<std::bitset<257>>::value)); + ++ // The following assertions fail on s390x (https://bugs.debian.org/977638). ++#ifndef __s390x__ + EXPECT_TRUE(absl::VerifyTypeImplementsAbslHashCorrectly( + {std::bitset<2>("00"), std::bitset<2>("01"), std::bitset<2>("10"), + std::bitset<2>("11")})); +@@ -379,6 +381,7 @@ + std::bitset<kNumBits>(bit_strings[3].c_str()), + std::bitset<kNumBits>(bit_strings[4].c_str()), + std::bitset<kNumBits>(bit_strings[5].c_str())})); ++#endif + } // namespace + + template <typename T> +@@ -400,10 +403,15 @@ + } + + REGISTER_TYPED_TEST_CASE_P(HashValueSequenceTest, BasicUsage); ++// std::vector<bool> tests fail on s390x, so exclude them. See ++// https://bugs.debian.org/977638. + using IntSequenceTypes = + testing::Types<std::deque<int>, std::forward_list<int>, std::list<int>, +- std::vector<int>, std::vector<bool>, std::set<int>, +- std::multiset<int>>; ++ std::vector<int>, ++#ifndef __s390x__ ++ std::vector<bool>, ++#endif ++ std::set<int>, std::multiset<int>>; + INSTANTIATE_TYPED_TEST_CASE_P(My, HashValueSequenceTest, IntSequenceTypes); + + // Private type that only supports AbslHashValue to make sure our chosen hash |