Skip to content

Commit c36d825

Browse files
Abseil Teamderekmauro
authored andcommitted
Export of internal Abseil changes
-- 756156bf03da050e8b27539a8247d9af7e44c6a2 by Abseil Team <[email protected]>: Fix a typo in cord.h: "accomodate" => "accommodate" PiperOrigin-RevId: 356168875 -- 638befdb342b608ec28910ee931ee200fdbe1fef by Samuel Benzaquen <[email protected]>: Fix float conversion for PPC. 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. PiperOrigin-RevId: 355857729 -- ff5f893319fa76b273c7785b76ef6c95b1791076 by Abseil Team <[email protected]>: Example usage tweak PiperOrigin-RevId: 355695750 -- 0efc454f90023fa651b226e5e3ba7395a3b60c6d by Benjamin Barenblat <[email protected]>: Remove endian-sensitivity from Abseil’s RNG 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. PiperOrigin-RevId: 355635051 GitOrigin-RevId: 756156bf03da050e8b27539a8247d9af7e44c6a2 Change-Id: Iaaa69767b8e85d626742b9ba56fefb75f07c69ee
1 parent 9c6a50f commit c36d825

File tree

12 files changed

+146
-66
lines changed

12 files changed

+146
-66
lines changed

absl/base/BUILD.bazel

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -479,6 +479,7 @@ cc_library(
479479
copts = ABSL_DEFAULT_COPTS,
480480
linkopts = ABSL_DEFAULT_LINKOPTS,
481481
deps = [
482+
":base",
482483
":config",
483484
":core_headers",
484485
],

absl/base/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -418,6 +418,7 @@ absl_cc_library(
418418
COPTS
419419
${ABSL_DEFAULT_COPTS}
420420
DEPS
421+
absl::base
421422
absl::config
422423
absl::core_headers
423424
PUBLIC

absl/base/internal/endian.h

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
#endif
2727

2828
#include <cstdint>
29+
#include "absl/base/casts.h"
2930
#include "absl/base/config.h"
3031
#include "absl/base/internal/unaligned_access.h"
3132
#include "absl/base/port.h"
@@ -173,6 +174,36 @@ inline constexpr bool IsLittleEndian() { return false; }
173174

174175
#endif /* ENDIAN */
175176

177+
inline uint8_t FromHost(uint8_t x) { return x; }
178+
inline uint16_t FromHost(uint16_t x) { return FromHost16(x); }
179+
inline uint32_t FromHost(uint32_t x) { return FromHost32(x); }
180+
inline uint64_t FromHost(uint64_t x) { return FromHost64(x); }
181+
inline uint8_t ToHost(uint8_t x) { return x; }
182+
inline uint16_t ToHost(uint16_t x) { return ToHost16(x); }
183+
inline uint32_t ToHost(uint32_t x) { return ToHost32(x); }
184+
inline uint64_t ToHost(uint64_t x) { return ToHost64(x); }
185+
186+
inline int8_t FromHost(int8_t x) { return x; }
187+
inline int16_t FromHost(int16_t x) {
188+
return bit_cast<int16_t>(FromHost16(bit_cast<uint16_t>(x)));
189+
}
190+
inline int32_t FromHost(int32_t x) {
191+
return bit_cast<int32_t>(FromHost32(bit_cast<uint32_t>(x)));
192+
}
193+
inline int64_t FromHost(int64_t x) {
194+
return bit_cast<int64_t>(FromHost64(bit_cast<uint64_t>(x)));
195+
}
196+
inline int8_t ToHost(int8_t x) { return x; }
197+
inline int16_t ToHost(int16_t x) {
198+
return bit_cast<int16_t>(ToHost16(bit_cast<uint16_t>(x)));
199+
}
200+
inline int32_t ToHost(int32_t x) {
201+
return bit_cast<int32_t>(ToHost32(bit_cast<uint32_t>(x)));
202+
}
203+
inline int64_t ToHost(int64_t x) {
204+
return bit_cast<int64_t>(ToHost64(bit_cast<uint64_t>(x)));
205+
}
206+
176207
// Functions to do unaligned loads and stores in little-endian order.
177208
inline uint16_t Load16(const void *p) {
178209
return ToHost16(ABSL_INTERNAL_UNALIGNED_LOAD16(p));
@@ -233,6 +264,36 @@ inline constexpr bool IsLittleEndian() { return false; }
233264

234265
#endif /* ENDIAN */
235266

267+
inline uint8_t FromHost(uint8_t x) { return x; }
268+
inline uint16_t FromHost(uint16_t x) { return FromHost16(x); }
269+
inline uint32_t FromHost(uint32_t x) { return FromHost32(x); }
270+
inline uint64_t FromHost(uint64_t x) { return FromHost64(x); }
271+
inline uint8_t ToHost(uint8_t x) { return x; }
272+
inline uint16_t ToHost(uint16_t x) { return ToHost16(x); }
273+
inline uint32_t ToHost(uint32_t x) { return ToHost32(x); }
274+
inline uint64_t ToHost(uint64_t x) { return ToHost64(x); }
275+
276+
inline int8_t FromHost(int8_t x) { return x; }
277+
inline int16_t FromHost(int16_t x) {
278+
return bit_cast<int16_t>(FromHost16(bit_cast<uint16_t>(x)));
279+
}
280+
inline int32_t FromHost(int32_t x) {
281+
return bit_cast<int32_t>(FromHost32(bit_cast<uint32_t>(x)));
282+
}
283+
inline int64_t FromHost(int64_t x) {
284+
return bit_cast<int64_t>(FromHost64(bit_cast<uint64_t>(x)));
285+
}
286+
inline int8_t ToHost(int8_t x) { return x; }
287+
inline int16_t ToHost(int16_t x) {
288+
return bit_cast<int16_t>(ToHost16(bit_cast<uint16_t>(x)));
289+
}
290+
inline int32_t ToHost(int32_t x) {
291+
return bit_cast<int32_t>(ToHost32(bit_cast<uint32_t>(x)));
292+
}
293+
inline int64_t ToHost(int64_t x) {
294+
return bit_cast<int64_t>(ToHost64(bit_cast<uint64_t>(x)));
295+
}
296+
236297
// Functions to do unaligned loads and stores in big-endian order.
237298
inline uint16_t Load16(const void *p) {
238299
return ToHost16(ABSL_INTERNAL_UNALIGNED_LOAD16(p));

absl/random/CMakeLists.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -611,6 +611,7 @@ absl_cc_library(
611611
${ABSL_DEFAULT_LINKOPTS}
612612
DEPS
613613
absl::config
614+
absl::endian
614615
TESTONLY
615616
)
616617

@@ -758,6 +759,7 @@ absl_cc_library(
758759
LINKOPTS
759760
${ABSL_DEFAULT_LINKOPTS}
760761
DEPS
762+
absl::endian
761763
absl::random_internal_iostream_state_saver
762764
absl::random_internal_randen
763765
absl::raw_logging_internal
@@ -1119,6 +1121,7 @@ absl_cc_test(
11191121
LINKOPTS
11201122
${ABSL_DEFAULT_LINKOPTS}
11211123
DEPS
1124+
absl::endian
11221125
absl::random_internal_randen_slow
11231126
gtest_main
11241127
)

absl/random/internal/BUILD.bazel

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,10 @@ cc_library(
124124
],
125125
copts = ABSL_DEFAULT_COPTS,
126126
linkopts = ABSL_DEFAULT_LINKOPTS,
127-
deps = ["//absl/base:config"],
127+
deps = [
128+
"//absl/base:config",
129+
"//absl/base:endian",
130+
],
128131
)
129132

130133
cc_library(
@@ -242,6 +245,7 @@ cc_library(
242245
deps = [
243246
":iostream_state_saver",
244247
":randen",
248+
"//absl/base:endian",
245249
"//absl/meta:type_traits",
246250
],
247251
)
@@ -606,6 +610,7 @@ cc_test(
606610
deps = [
607611
":platform",
608612
":randen_slow",
613+
"//absl/base:endian",
609614
"@com_google_googletest//:gtest_main",
610615
],
611616
)

absl/random/internal/explicit_seed_seq.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#include <vector>
2424

2525
#include "absl/base/config.h"
26+
#include "absl/base/internal/endian.h"
2627

2728
namespace absl {
2829
ABSL_NAMESPACE_BEGIN
@@ -73,7 +74,7 @@ class ExplicitSeedSeq {
7374
template <typename OutIterator>
7475
void generate(OutIterator begin, OutIterator end) {
7576
for (size_t index = 0; begin != end; begin++) {
76-
*begin = state_.empty() ? 0 : state_[index++];
77+
*begin = state_.empty() ? 0 : little_endian::FromHost32(state_[index++]);
7778
if (index >= state_.size()) {
7879
index = 0;
7980
}

absl/random/internal/randen_engine.h

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#include <limits>
2424
#include <type_traits>
2525

26+
#include "absl/base/internal/endian.h"
2627
#include "absl/meta/type_traits.h"
2728
#include "absl/random/internal/iostream_state_saver.h"
2829
#include "absl/random/internal/randen.h"
@@ -76,7 +77,7 @@ class alignas(16) randen_engine {
7677
impl_.Generate(state_);
7778
}
7879

79-
return state_[next_++];
80+
return little_endian::ToHost(state_[next_++]);
8081
}
8182

8283
template <class SeedSequence>
@@ -181,7 +182,8 @@ class alignas(16) randen_engine {
181182
// In the case that `elem` is `uint8_t`, it must be cast to something
182183
// larger so that it prints as an integer rather than a character. For
183184
// simplicity, apply the cast all circumstances.
184-
os << static_cast<numeric_type>(elem) << os.fill();
185+
os << static_cast<numeric_type>(little_endian::FromHost(elem))
186+
<< os.fill();
185187
}
186188
os << engine.next_;
187189
return os;
@@ -200,7 +202,7 @@ class alignas(16) randen_engine {
200202
// necessary to read a wider type and then cast it to uint8_t.
201203
numeric_type value;
202204
is >> value;
203-
elem = static_cast<result_type>(value);
205+
elem = little_endian::ToHost(static_cast<result_type>(value));
204206
}
205207
is >> next;
206208
if (is.fail()) {

absl/random/internal/randen_slow_test.cc

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#include <cstring>
1818

1919
#include "gtest/gtest.h"
20+
#include "absl/base/internal/endian.h"
2021
#include "absl/random/internal/randen_traits.h"
2122

2223
namespace {
@@ -56,7 +57,7 @@ TEST(RandenSlowTest, Default) {
5657

5758
uint64_t* id = d.state;
5859
for (const auto& elem : kGolden) {
59-
EXPECT_EQ(elem, *id++);
60+
EXPECT_EQ(absl::little_endian::FromHost64(elem), *id++);
6061
}
6162
}
6263

absl/strings/cord.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
//
2626
// Because a Cord consists of these chunks, data can be added to or removed from
2727
// a Cord during its lifetime. Chunks may also be shared between Cords. Unlike a
28-
// `std::string`, a Cord can therefore accomodate data that changes over its
28+
// `std::string`, a Cord can therefore accommodate data that changes over its
2929
// lifetime, though it's not quite "mutable"; it can change only in the
3030
// attachment, detachment, or rearrangement of chunks of its constituent data.
3131
//

absl/strings/internal/str_format/convert_test.cc

Lines changed: 43 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -554,7 +554,8 @@ TEST_F(FormatConvertTest, Uint128) {
554554
}
555555

556556
template <typename Floating>
557-
void TestWithMultipleFormatsHelper(const std::vector<Floating> &floats) {
557+
void TestWithMultipleFormatsHelper(const std::vector<Floating> &floats,
558+
const std::set<Floating> &skip_verify) {
558559
const NativePrintfTraits &native_traits = VerifyNativeImplementation();
559560
// Reserve the space to ensure we don't allocate memory in the output itself.
560561
std::string str_format_result;
@@ -602,7 +603,16 @@ void TestWithMultipleFormatsHelper(const std::vector<Floating> &floats) {
602603
AppendPack(&str_format_result, format, absl::MakeSpan(args));
603604
}
604605

605-
if (string_printf_result != str_format_result) {
606+
#ifdef _MSC_VER
607+
// MSVC has a different rounding policy than us so we can't test our
608+
// implementation against the native one there.
609+
continue;
610+
#elif defined(__APPLE__)
611+
// Apple formats NaN differently (+nan) vs. (nan)
612+
if (std::isnan(d)) continue;
613+
#endif
614+
if (string_printf_result != str_format_result &&
615+
skip_verify.find(d) == skip_verify.end()) {
606616
// We use ASSERT_EQ here because failures are usually correlated and a
607617
// bug would print way too many failed expectations causing the test
608618
// to time out.
@@ -616,12 +626,6 @@ void TestWithMultipleFormatsHelper(const std::vector<Floating> &floats) {
616626
}
617627

618628
TEST_F(FormatConvertTest, Float) {
619-
#ifdef _MSC_VER
620-
// MSVC has a different rounding policy than us so we can't test our
621-
// implementation against the native one there.
622-
return;
623-
#endif // _MSC_VER
624-
625629
std::vector<float> floats = {0.0f,
626630
-0.0f,
627631
.9999999f,
@@ -635,7 +639,8 @@ TEST_F(FormatConvertTest, Float) {
635639
std::numeric_limits<float>::epsilon(),
636640
std::numeric_limits<float>::epsilon() + 1.0f,
637641
std::numeric_limits<float>::infinity(),
638-
-std::numeric_limits<float>::infinity()};
642+
-std::numeric_limits<float>::infinity(),
643+
std::nanf("")};
639644

640645
// Some regression tests.
641646
floats.push_back(0.999999989f);
@@ -664,21 +669,14 @@ TEST_F(FormatConvertTest, Float) {
664669
std::sort(floats.begin(), floats.end());
665670
floats.erase(std::unique(floats.begin(), floats.end()), floats.end());
666671

667-
#ifndef __APPLE__
668-
// Apple formats NaN differently (+nan) vs. (nan)
669-
floats.push_back(std::nan(""));
670-
#endif
671-
672-
TestWithMultipleFormatsHelper(floats);
672+
TestWithMultipleFormatsHelper(floats, {});
673673
}
674674

675675
TEST_F(FormatConvertTest, Double) {
676-
#ifdef _MSC_VER
677-
// MSVC has a different rounding policy than us so we can't test our
678-
// implementation against the native one there.
679-
return;
680-
#endif // _MSC_VER
681-
676+
// For values that we know won't match the standard library implementation we
677+
// skip verification, but still run the algorithm to catch asserts/sanitizer
678+
// bugs.
679+
std::set<double> skip_verify;
682680
std::vector<double> doubles = {0.0,
683681
-0.0,
684682
.99999999999999,
@@ -692,7 +690,8 @@ TEST_F(FormatConvertTest, Double) {
692690
std::numeric_limits<double>::epsilon(),
693691
std::numeric_limits<double>::epsilon() + 1,
694692
std::numeric_limits<double>::infinity(),
695-
-std::numeric_limits<double>::infinity()};
693+
-std::numeric_limits<double>::infinity(),
694+
std::nan("")};
696695

697696
// Some regression tests.
698697
doubles.push_back(0.99999999999999989);
@@ -722,33 +721,29 @@ TEST_F(FormatConvertTest, Double) {
722721
"5084551339423045832369032229481658085593321233482747978262041447231"
723722
"68738177180919299881250404026184124858368.000000";
724723

725-
if (!gcc_bug_22142) {
726-
for (int exp = -300; exp <= 300; ++exp) {
727-
const double all_ones_mantissa = 0x1fffffffffffff;
728-
doubles.push_back(std::ldexp(all_ones_mantissa, exp));
724+
for (int exp = -300; exp <= 300; ++exp) {
725+
const double all_ones_mantissa = 0x1fffffffffffff;
726+
doubles.push_back(std::ldexp(all_ones_mantissa, exp));
727+
if (gcc_bug_22142) {
728+
skip_verify.insert(doubles.back());
729729
}
730730
}
731731

732732
if (gcc_bug_22142) {
733-
for (auto &d : doubles) {
734-
using L = std::numeric_limits<double>;
735-
double d2 = std::abs(d);
736-
if (d2 == L::max() || d2 == L::min() || d2 == L::denorm_min()) {
737-
d = 0;
738-
}
739-
}
733+
using L = std::numeric_limits<double>;
734+
skip_verify.insert(L::max());
735+
skip_verify.insert(L::min()); // NOLINT
736+
skip_verify.insert(L::denorm_min());
737+
skip_verify.insert(-L::max());
738+
skip_verify.insert(-L::min()); // NOLINT
739+
skip_verify.insert(-L::denorm_min());
740740
}
741741

742742
// Remove duplicates to speed up the logic below.
743743
std::sort(doubles.begin(), doubles.end());
744744
doubles.erase(std::unique(doubles.begin(), doubles.end()), doubles.end());
745745

746-
#ifndef __APPLE__
747-
// Apple formats NaN differently (+nan) vs. (nan)
748-
doubles.push_back(std::nan(""));
749-
#endif
750-
751-
TestWithMultipleFormatsHelper(doubles);
746+
TestWithMultipleFormatsHelper(doubles, skip_verify);
752747
}
753748

754749
TEST_F(FormatConvertTest, DoubleRound) {
@@ -1069,11 +1064,6 @@ TEST_F(FormatConvertTest, ExtremeWidthPrecision) {
10691064
}
10701065

10711066
TEST_F(FormatConvertTest, LongDouble) {
1072-
#ifdef _MSC_VER
1073-
// MSVC has a different rounding policy than us so we can't test our
1074-
// implementation against the native one there.
1075-
return;
1076-
#endif // _MSC_VER
10771067
const NativePrintfTraits &native_traits = VerifyNativeImplementation();
10781068
const char *const kFormats[] = {"%", "%.3", "%8.5", "%9", "%.5000",
10791069
"%.60", "%+", "% ", "%-10"};
@@ -1134,10 +1124,18 @@ TEST_F(FormatConvertTest, LongDouble) {
11341124
for (auto d : doubles) {
11351125
FormatArgImpl arg(d);
11361126
UntypedFormatSpecImpl format(fmt_str);
1127+
std::string result = FormatPack(format, {&arg, 1});
1128+
1129+
#ifdef _MSC_VER
1130+
// MSVC has a different rounding policy than us so we can't test our
1131+
// implementation against the native one there.
1132+
continue;
1133+
#endif // _MSC_VER
1134+
11371135
// We use ASSERT_EQ here because failures are usually correlated and a
11381136
// bug would print way too many failed expectations causing the test to
11391137
// time out.
1140-
ASSERT_EQ(StrPrint(fmt_str.c_str(), d), FormatPack(format, {&arg, 1}))
1138+
ASSERT_EQ(StrPrint(fmt_str.c_str(), d), result)
11411139
<< fmt_str << " " << StrPrint("%.18Lg", d) << " "
11421140
<< StrPrint("%La", d) << " " << StrPrint("%.1080Lf", d);
11431141
}

0 commit comments

Comments
 (0)