summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--absl/base/thread_annotations.h5
-rw-r--r--absl/debugging/internal/vdso_support.cc12
-rw-r--r--absl/debugging/symbolize_elf.inc6
-rw-r--r--absl/strings/cord.cc3
-rw-r--r--absl/strings/internal/str_format/convert_test.cc82
-rw-r--r--absl/strings/internal/str_format/float_conversion.cc14
-rw-r--r--absl/time/time_test.cc44
7 files changed, 123 insertions, 43 deletions
diff --git a/absl/base/thread_annotations.h b/absl/base/thread_annotations.h
index 5f51c0c2..6a7112df 100644
--- a/absl/base/thread_annotations.h
+++ b/absl/base/thread_annotations.h
@@ -34,6 +34,7 @@
#ifndef ABSL_BASE_THREAD_ANNOTATIONS_H_
#define ABSL_BASE_THREAD_ANNOTATIONS_H_
+#include "absl/base/attributes.h"
#include "absl/base/config.h"
// TODO(mbonadei): Remove after the backward compatibility period.
#include "absl/base/internal/thread_annotations.h" // IWYU pragma: export
@@ -151,8 +152,12 @@
// Documents a function that returns a mutex without acquiring it. For example,
// a public getter method that returns a pointer to a private mutex should
// be annotated with ABSL_LOCK_RETURNED.
+#if ABSL_HAVE_ATTRIBUTE(lock_returned)
#define ABSL_LOCK_RETURNED(x) \
ABSL_INTERNAL_THREAD_ANNOTATION_ATTRIBUTE(lock_returned(x))
+#else
+#define ABSL_LOCK_RETURNED(x)
+#endif
// ABSL_LOCKABLE
//
diff --git a/absl/debugging/internal/vdso_support.cc b/absl/debugging/internal/vdso_support.cc
index 1e8a78ac..19deb3cf 100644
--- a/absl/debugging/internal/vdso_support.cc
+++ b/absl/debugging/internal/vdso_support.cc
@@ -175,18 +175,6 @@ int GetCPU() {
return ret_code == 0 ? cpu : ret_code;
}
-// We need to make sure VDSOSupport::Init() is called before
-// InitGoogle() does any setuid or chroot calls. If VDSOSupport
-// is used in any global constructor, this will happen, since
-// VDSOSupport's constructor calls Init. But if not, we need to
-// ensure it here, with a global constructor of our own. This
-// is an allowed exception to the normal rule against non-trivial
-// global constructors.
-static class VDSOInitHelper {
- public:
- VDSOInitHelper() { VDSOSupport::Init(); }
-} vdso_init_helper;
-
} // namespace debugging_internal
ABSL_NAMESPACE_END
} // namespace absl
diff --git a/absl/debugging/symbolize_elf.inc b/absl/debugging/symbolize_elf.inc
index 328869f1..b7f8663c 100644
--- a/absl/debugging/symbolize_elf.inc
+++ b/absl/debugging/symbolize_elf.inc
@@ -83,6 +83,12 @@ ABSL_NAMESPACE_BEGIN
static char *argv0_value = nullptr;
void InitializeSymbolizer(const char *argv0) {
+#ifdef ABSL_HAVE_VDSO_SUPPORT
+ // We need to make sure VDSOSupport::Init() is called before any setuid or
+ // chroot calls, so InitializeSymbolizer() should be called very early in the
+ // life of a program.
+ absl::debugging_internal::VDSOSupport::Init();
+#endif
if (argv0_value != nullptr) {
free(argv0_value);
argv0_value = nullptr;
diff --git a/absl/strings/cord.cc b/absl/strings/cord.cc
index 8ecffc4b..70c399c1 100644
--- a/absl/strings/cord.cc
+++ b/absl/strings/cord.cc
@@ -493,10 +493,7 @@ static CordRep* NewSubstring(CordRep* child, size_t offset, size_t length) {
// --------------------------------------------------------------------
// Cord::InlineRep functions
-// This will trigger LNK2005 in MSVC.
-#ifndef COMPILER_MSVC
constexpr unsigned char Cord::InlineRep::kMaxInline;
-#endif // COMPILER_MSVC
inline void Cord::InlineRep::set_data(const char* data, size_t n,
bool nullify_tail) {
diff --git a/absl/strings/internal/str_format/convert_test.cc b/absl/strings/internal/str_format/convert_test.cc
index 488d4cd4..5ee5fbc9 100644
--- a/absl/strings/internal/str_format/convert_test.cc
+++ b/absl/strings/internal/str_format/convert_test.cc
@@ -947,6 +947,88 @@ TEST_F(FormatConvertTest, DoubleRoundA) {
EXPECT_EQ(format("%.21a", hex_value2), "0x1.081828384858600000000p+3");
}
+TEST_F(FormatConvertTest, LongDoubleRoundA) {
+ if (std::numeric_limits<long double>::digits % 4 != 0) {
+ // This test doesn't really make sense to run on platforms where a long
+ // double has a different mantissa size (mod 4) than Prod, since then the
+ // leading digit will be formatted differently.
+ return;
+ }
+ const NativePrintfTraits &native_traits = VerifyNativeImplementation();
+ std::string s;
+ const auto format = [&](const char *fmt, long double d) -> std::string & {
+ s.clear();
+ FormatArgImpl args[1] = {FormatArgImpl(d)};
+ AppendPack(&s, UntypedFormatSpecImpl(fmt), absl::MakeSpan(args));
+ if (native_traits.hex_float_has_glibc_rounding &&
+ native_traits.hex_float_optimizes_leading_digit_bit_count) {
+ EXPECT_EQ(StrPrint(fmt, d), s);
+ }
+ return s;
+ };
+
+ // 0x8.8p+4
+ const long double on_boundary_even = 136.0;
+ EXPECT_EQ(format("%.0La", on_boundary_even), "0x8p+4");
+ EXPECT_EQ(format("%.1La", on_boundary_even), "0x8.8p+4");
+ EXPECT_EQ(format("%.2La", on_boundary_even), "0x8.80p+4");
+ EXPECT_EQ(format("%.3La", on_boundary_even), "0x8.800p+4");
+ EXPECT_EQ(format("%.4La", on_boundary_even), "0x8.8000p+4");
+ EXPECT_EQ(format("%.5La", on_boundary_even), "0x8.80000p+4");
+ EXPECT_EQ(format("%.6La", on_boundary_even), "0x8.800000p+4");
+
+ // 0x9.8p+4
+ const long double on_boundary_odd = 152.0;
+ EXPECT_EQ(format("%.0La", on_boundary_odd), "0xap+4");
+ EXPECT_EQ(format("%.1La", on_boundary_odd), "0x9.8p+4");
+ EXPECT_EQ(format("%.2La", on_boundary_odd), "0x9.80p+4");
+ EXPECT_EQ(format("%.3La", on_boundary_odd), "0x9.800p+4");
+ EXPECT_EQ(format("%.4La", on_boundary_odd), "0x9.8000p+4");
+ EXPECT_EQ(format("%.5La", on_boundary_odd), "0x9.80000p+4");
+ EXPECT_EQ(format("%.6La", on_boundary_odd), "0x9.800000p+4");
+
+ // 0x8.80001p+24
+ const long double slightly_over = 142606352.0;
+ EXPECT_EQ(format("%.0La", slightly_over), "0x9p+24");
+ EXPECT_EQ(format("%.1La", slightly_over), "0x8.8p+24");
+ EXPECT_EQ(format("%.2La", slightly_over), "0x8.80p+24");
+ EXPECT_EQ(format("%.3La", slightly_over), "0x8.800p+24");
+ EXPECT_EQ(format("%.4La", slightly_over), "0x8.8000p+24");
+ EXPECT_EQ(format("%.5La", slightly_over), "0x8.80001p+24");
+ EXPECT_EQ(format("%.6La", slightly_over), "0x8.800010p+24");
+
+ // 0x8.7ffffp+24
+ const long double slightly_under = 142606320.0;
+ EXPECT_EQ(format("%.0La", slightly_under), "0x8p+24");
+ EXPECT_EQ(format("%.1La", slightly_under), "0x8.8p+24");
+ EXPECT_EQ(format("%.2La", slightly_under), "0x8.80p+24");
+ EXPECT_EQ(format("%.3La", slightly_under), "0x8.800p+24");
+ EXPECT_EQ(format("%.4La", slightly_under), "0x8.8000p+24");
+ EXPECT_EQ(format("%.5La", slightly_under), "0x8.7ffffp+24");
+ EXPECT_EQ(format("%.6La", slightly_under), "0x8.7ffff0p+24");
+ EXPECT_EQ(format("%.7La", slightly_under), "0x8.7ffff00p+24");
+
+ // 0xc.0828384858688000p+128
+ const long double eights = 4094231060438608800781871108094404067328.0;
+ EXPECT_EQ(format("%.0La", eights), "0xcp+128");
+ EXPECT_EQ(format("%.1La", eights), "0xc.1p+128");
+ EXPECT_EQ(format("%.2La", eights), "0xc.08p+128");
+ EXPECT_EQ(format("%.3La", eights), "0xc.083p+128");
+ EXPECT_EQ(format("%.4La", eights), "0xc.0828p+128");
+ EXPECT_EQ(format("%.5La", eights), "0xc.08284p+128");
+ EXPECT_EQ(format("%.6La", eights), "0xc.082838p+128");
+ EXPECT_EQ(format("%.7La", eights), "0xc.0828385p+128");
+ EXPECT_EQ(format("%.8La", eights), "0xc.08283848p+128");
+ EXPECT_EQ(format("%.9La", eights), "0xc.082838486p+128");
+ EXPECT_EQ(format("%.10La", eights), "0xc.0828384858p+128");
+ EXPECT_EQ(format("%.11La", eights), "0xc.08283848587p+128");
+ EXPECT_EQ(format("%.12La", eights), "0xc.082838485868p+128");
+ EXPECT_EQ(format("%.13La", eights), "0xc.0828384858688p+128");
+ EXPECT_EQ(format("%.14La", eights), "0xc.08283848586880p+128");
+ EXPECT_EQ(format("%.15La", eights), "0xc.082838485868800p+128");
+ EXPECT_EQ(format("%.16La", eights), "0xc.0828384858688000p+128");
+}
+
// We don't actually store the results. This is just to exercise the rest of the
// machinery.
struct NullSink {
diff --git a/absl/strings/internal/str_format/float_conversion.cc b/absl/strings/internal/str_format/float_conversion.cc
index 6eb7b9fc..cafa479b 100644
--- a/absl/strings/internal/str_format/float_conversion.cc
+++ b/absl/strings/internal/str_format/float_conversion.cc
@@ -738,7 +738,8 @@ constexpr int HexFloatLeadingDigitSizeInBits() {
// point that is not followed by 800000..., it disregards the parity and rounds
// up if > 8 and rounds down if < 8.
template <typename Int>
-bool HexFloatNeedsRoundUp(Int mantissa, int final_nibble_displayed) {
+bool HexFloatNeedsRoundUp(Int mantissa, int final_nibble_displayed,
+ uint8_t leading) {
// If the last nibble (hex digit) to be displayed is the lowest on in the
// mantissa then that means that we don't have any further nibbles to inform
// rounding, so don't round.
@@ -755,11 +756,10 @@ bool HexFloatNeedsRoundUp(Int mantissa, int final_nibble_displayed) {
return mantissa_up_to_rounding_nibble_inclusive > eight;
}
// Nibble in question == 8.
- uint8_t should_round_at_8 =
- (final_nibble_displayed >= kTotalNibbles)
- ? true
- : (GetNibble(mantissa, final_nibble_displayed) % 2 == 1);
- return should_round_at_8;
+ uint8_t round_if_odd = (final_nibble_displayed == kTotalNibbles)
+ ? leading
+ : GetNibble(mantissa, final_nibble_displayed);
+ return round_if_odd % 2 == 1;
}
// Stores values associated with a Float type needed by the FormatA
@@ -788,7 +788,7 @@ void FormatARound(bool precision_specified, const FormatState &state,
// Index of the last nibble that we could display given precision.
int final_nibble_displayed =
precision_specified ? std::max(0, (kTotalNibbles - state.precision)) : 0;
- if (HexFloatNeedsRoundUp(*mantissa, final_nibble_displayed)) {
+ if (HexFloatNeedsRoundUp(*mantissa, final_nibble_displayed, *leading)) {
// Need to round up.
bool overflow = IncrementNibble(final_nibble_displayed, mantissa);
*leading += (overflow ? 1 : 0);
diff --git a/absl/time/time_test.cc b/absl/time/time_test.cc
index 6f89672c..b28a99fb 100644
--- a/absl/time/time_test.cc
+++ b/absl/time/time_test.cc
@@ -58,8 +58,7 @@ const char kZoneAbbrRE[] = "[A-Za-z]{3,4}|[-+][0-9]{2}([0-9]{2})?";
// timespec ts1, ts2;
// EXPECT_THAT(ts1, TimespecMatcher(ts2));
MATCHER_P(TimespecMatcher, ts, "") {
- if (ts.tv_sec == arg.tv_sec && ts.tv_nsec == arg.tv_nsec)
- return true;
+ if (ts.tv_sec == arg.tv_sec && ts.tv_nsec == arg.tv_nsec) return true;
*result_listener << "expected: {" << ts.tv_sec << ", " << ts.tv_nsec << "} ";
*result_listener << "actual: {" << arg.tv_sec << ", " << arg.tv_nsec << "}";
return false;
@@ -69,8 +68,7 @@ MATCHER_P(TimespecMatcher, ts, "") {
// timeval tv1, tv2;
// EXPECT_THAT(tv1, TimevalMatcher(tv2));
MATCHER_P(TimevalMatcher, tv, "") {
- if (tv.tv_sec == arg.tv_sec && tv.tv_usec == arg.tv_usec)
- return true;
+ if (tv.tv_sec == arg.tv_sec && tv.tv_usec == arg.tv_usec) return true;
*result_listener << "expected: {" << tv.tv_sec << ", " << tv.tv_usec << "} ";
*result_listener << "actual: {" << arg.tv_sec << ", " << arg.tv_usec << "}";
return false;
@@ -103,7 +101,7 @@ TEST(Time, ValueSemantics) {
EXPECT_EQ(a, b);
EXPECT_EQ(a, c);
EXPECT_EQ(b, c);
- b = c; // Assignment
+ b = c; // Assignment
EXPECT_EQ(a, b);
EXPECT_EQ(a, c);
EXPECT_EQ(b, c);
@@ -228,6 +226,9 @@ TEST(Time, Infinity) {
constexpr absl::Time t = absl::UnixEpoch(); // Any finite time.
static_assert(t < ifuture, "");
static_assert(t > ipast, "");
+
+ EXPECT_EQ(ifuture, t + absl::InfiniteDuration());
+ EXPECT_EQ(ipast, t - absl::InfiniteDuration());
}
TEST(Time, FloorConversion) {
@@ -358,19 +359,21 @@ TEST(Time, FloorConversion) {
const int64_t min_plus_1 = std::numeric_limits<int64_t>::min() + 1;
EXPECT_EQ(min_plus_1, absl::ToUnixSeconds(absl::FromUnixSeconds(min_plus_1)));
EXPECT_EQ(std::numeric_limits<int64_t>::min(),
- absl::ToUnixSeconds(
- absl::FromUnixSeconds(min_plus_1) - absl::Nanoseconds(1) / 2));
+ absl::ToUnixSeconds(absl::FromUnixSeconds(min_plus_1) -
+ absl::Nanoseconds(1) / 2));
// Tests flooring near positive infinity.
EXPECT_EQ(std::numeric_limits<int64_t>::max(),
- absl::ToUnixSeconds(absl::FromUnixSeconds(
- std::numeric_limits<int64_t>::max()) + absl::Nanoseconds(1) / 2));
+ absl::ToUnixSeconds(
+ absl::FromUnixSeconds(std::numeric_limits<int64_t>::max()) +
+ absl::Nanoseconds(1) / 2));
EXPECT_EQ(std::numeric_limits<int64_t>::max(),
absl::ToUnixSeconds(
absl::FromUnixSeconds(std::numeric_limits<int64_t>::max())));
EXPECT_EQ(std::numeric_limits<int64_t>::max() - 1,
- absl::ToUnixSeconds(absl::FromUnixSeconds(
- std::numeric_limits<int64_t>::max()) - absl::Nanoseconds(1) / 2));
+ absl::ToUnixSeconds(
+ absl::FromUnixSeconds(std::numeric_limits<int64_t>::max()) -
+ absl::Nanoseconds(1) / 2));
}
TEST(Time, RoundtripConversion) {
@@ -1045,15 +1048,15 @@ TEST(Time, ConversionSaturation) {
// Checks how TimeZone::At() saturates on infinities.
auto ci = utc.At(absl::InfiniteFuture());
- EXPECT_CIVIL_INFO(ci, std::numeric_limits<int64_t>::max(), 12, 31, 23,
- 59, 59, 0, false);
+ EXPECT_CIVIL_INFO(ci, std::numeric_limits<int64_t>::max(), 12, 31, 23, 59, 59,
+ 0, false);
EXPECT_EQ(absl::InfiniteDuration(), ci.subsecond);
EXPECT_EQ(absl::Weekday::thursday, absl::GetWeekday(ci.cs));
EXPECT_EQ(365, absl::GetYearDay(ci.cs));
EXPECT_STREQ("-00", ci.zone_abbr); // artifact of TimeZone::At()
ci = utc.At(absl::InfinitePast());
- EXPECT_CIVIL_INFO(ci, std::numeric_limits<int64_t>::min(), 1, 1, 0, 0,
- 0, 0, false);
+ EXPECT_CIVIL_INFO(ci, std::numeric_limits<int64_t>::min(), 1, 1, 0, 0, 0, 0,
+ false);
EXPECT_EQ(-absl::InfiniteDuration(), ci.subsecond);
EXPECT_EQ(absl::Weekday::sunday, absl::GetWeekday(ci.cs));
EXPECT_EQ(1, absl::GetYearDay(ci.cs));
@@ -1171,14 +1174,13 @@ TEST(Time, LegacyDateTime) {
const int kMin = std::numeric_limits<int>::min();
absl::Time t;
- t = absl::FromDateTime(std::numeric_limits<absl::civil_year_t>::max(),
- kMax, kMax, kMax, kMax, kMax, utc);
+ t = absl::FromDateTime(std::numeric_limits<absl::civil_year_t>::max(), kMax,
+ kMax, kMax, kMax, kMax, utc);
EXPECT_EQ("infinite-future",
absl::FormatTime(ymdhms, t, utc)); // no overflow
- t = absl::FromDateTime(std::numeric_limits<absl::civil_year_t>::min(),
- kMin, kMin, kMin, kMin, kMin, utc);
- EXPECT_EQ("infinite-past",
- absl::FormatTime(ymdhms, t, utc)); // no overflow
+ t = absl::FromDateTime(std::numeric_limits<absl::civil_year_t>::min(), kMin,
+ kMin, kMin, kMin, kMin, utc);
+ EXPECT_EQ("infinite-past", absl::FormatTime(ymdhms, t, utc)); // no overflow
// Check normalization.
EXPECT_TRUE(absl::ConvertDateTime(2013, 10, 32, 8, 30, 0, utc).normalized);