diff --git a/absl/base/config.h b/absl/base/config.h index 8a44c068..6aeceb9b 100644 --- a/absl/base/config.h +++ b/absl/base/config.h @@ -243,7 +243,7 @@ // Windows _WIN32 // NaCL __native_client__ // AsmJS __asmjs__ -// Fuschia __Fuchsia__ +// Fuchsia __Fuchsia__ // // Note that since Android defines both __ANDROID__ and __linux__, one // may probe for either Linux or Android by simply testing for __linux__. diff --git a/absl/copts.bzl b/absl/copts.bzl index f687f58f..22f3e54f 100644 --- a/absl/copts.bzl +++ b/absl/copts.bzl @@ -29,12 +29,18 @@ GCC_TEST_FLAGS = [ "-Wno-unused-private-field", ] + +# Docs on single flags is preceded by a comment. +# Docs on groups of flags is preceded by ###. + LLVM_FLAGS = [ "-Wall", "-Wextra", "-Weverything", + # Abseil does not support C++98 "-Wno-c++98-compat-pedantic", "-Wno-comma", + # Turns off all implicit conversion warnings. Most are re-enabled below. "-Wno-conversion", "-Wno-covered-switch-default", "-Wno-deprecated", @@ -47,6 +53,7 @@ LLVM_FLAGS = [ "-Wno-float-conversion", "-Wno-float-equal", "-Wno-format-nonliteral", + # Too aggressive: warns on Clang extensions enclosed in Clang-only code paths. "-Wno-gcc-compat", "-Wno-global-constructors", "-Wno-nested-anon-types", @@ -54,6 +61,7 @@ LLVM_FLAGS = [ "-Wno-old-style-cast", "-Wno-packed", "-Wno-padded", + # Warns on preferred usage of non-POD types such as string_view "-Wno-range-loop-analysis", "-Wno-reserved-id-macro", "-Wno-shorten-64-to-32", @@ -63,9 +71,12 @@ LLVM_FLAGS = [ "-Wno-undef", "-Wno-unknown-warning-option", "-Wno-unreachable-code", + # Causes warnings on include guards "-Wno-unused-macros", "-Wno-weak-vtables", - # flags below are also controlled by -Wconversion which is disabled + ### + # Implicit conversion warnings turned off by -Wno-conversion + # which are re-enabled below. "-Wbitfield-enum-conversion", "-Wbool-conversion", "-Wconstant-conversion", @@ -76,6 +87,7 @@ LLVM_FLAGS = [ "-Wnull-conversion", "-Wobjc-literal-conversion", "-Wstring-conversion", + ### ] LLVM_TEST_FLAGS = [ diff --git a/absl/strings/internal/numbers_test_common.inc b/absl/strings/internal/numbers_test_common.inc index e165b3be..81d2a1b7 100644 --- a/absl/strings/internal/numbers_test_common.inc +++ b/absl/strings/internal/numbers_test_common.inc @@ -17,16 +17,6 @@ namespace { -// Previously documented minimum buffer sizes for Fast*ToBuffer functions. -// NOTE(edk): These should be deleted and uses replaced with kFastToBufferSize -// once existing code has been fixed to use kFastToBufferSize. -enum { - kFastInt32ToBufferSize = 12, - kFastInt64ToBufferSize = 22, - kFastUInt32ToBufferSize = 12, - kFastUInt64ToBufferSize = 22 -}; - template bool Itoa(IntType value, int base, std::string* destination) { destination->clear(); diff --git a/absl/strings/numbers_test.cc b/absl/strings/numbers_test.cc index 817604d7..ff3120f5 100644 --- a/absl/strings/numbers_test.cc +++ b/absl/strings/numbers_test.cc @@ -28,11 +28,6 @@ namespace { -using absl::numbers_internal::FastInt32ToBuffer; -using absl::numbers_internal::FastInt64ToBuffer; -using absl::numbers_internal::FastUInt32ToBuffer; -using absl::numbers_internal::FastUInt64ToBuffer; -using absl::numbers_internal::kFastToBufferSize; using absl::numbers_internal::kSixDigitsToBufferSize; using absl::numbers_internal::safe_strto32_base; using absl::numbers_internal::safe_strto64_base; @@ -116,22 +111,22 @@ TEST(ToString, PerfectDtoa) { } void CheckInt32(int32_t x) { - char buffer[kFastInt32ToBufferSize]; - char* actual = FastInt32ToBuffer(x, buffer); + char buffer[absl::numbers_internal::kFastToBufferSize]; + char* actual = absl::numbers_internal::FastInt32ToBuffer(x, buffer); std::string expected = std::to_string(x); - ASSERT_TRUE(expected == actual) + ASSERT_TRUE(expected == std::string(buffer, actual)) << "Expected \"" << expected << "\", Actual \"" << actual << "\", Input " << x; } void CheckInt64(int64_t x) { - char buffer[kFastInt64ToBufferSize + 3]; + char buffer[absl::numbers_internal::kFastToBufferSize + 3]; buffer[0] = '*'; buffer[23] = '*'; buffer[24] = '*'; - char* actual = FastInt64ToBuffer(x, &buffer[1]); + char* actual = absl::numbers_internal::FastInt64ToBuffer(x, &buffer[1]); std::string expected = std::to_string(x); - ASSERT_TRUE(expected == actual) + ASSERT_TRUE(expected == std::string(&buffer[1], actual)) << "Expected \"" << expected << "\", Actual \"" << actual << "\", Input " << x; ASSERT_EQ(buffer[0], '*'); @@ -140,32 +135,32 @@ void CheckInt64(int64_t x) { } void CheckUInt32(uint32_t x) { - char buffer[kFastUInt64ToBufferSize]; - char* actual = FastUInt32ToBuffer(x, buffer); + char buffer[absl::numbers_internal::kFastToBufferSize]; + char* actual = absl::numbers_internal::FastUInt32ToBuffer(x, buffer); std::string expected = std::to_string(x); - ASSERT_TRUE(expected == actual) + ASSERT_TRUE(expected == std::string(buffer, actual)) << "Expected \"" << expected << "\", Actual \"" << actual << "\", Input " << x; } void CheckUInt64(uint64_t x) { - char buffer[kFastUInt64ToBufferSize + 1]; - char* actual = FastUInt64ToBuffer(x, &buffer[1]); + char buffer[absl::numbers_internal::kFastToBufferSize + 1]; + char* actual = absl::numbers_internal::FastUInt64ToBuffer(x, &buffer[1]); std::string expected = std::to_string(x); - ASSERT_TRUE(expected == actual) + ASSERT_TRUE(expected == std::string(&buffer[1], actual)) << "Expected \"" << expected << "\", Actual \"" << actual << "\", Input " << x; } void CheckHex64(uint64_t v) { - char expected[kFastUInt64ToBufferSize]; + char expected[16 + 1]; std::string actual = absl::StrCat(absl::Hex(v, absl::kZeroPad16)); snprintf(expected, sizeof(expected), "%016" PRIx64, static_cast(v)); ASSERT_TRUE(expected == actual) << "Expected \"" << expected << "\", Actual \"" << actual << "\""; } -void TestFastPrints() { +TEST(Numbers, TestFastPrints) { for (int i = -100; i <= 100; i++) { CheckInt32(i); CheckInt64(i); @@ -700,7 +695,7 @@ class SimpleDtoaTest : public testing::Test { } std::string ToNineDigits(double value) { - char buffer[kFastToBufferSize]; // more than enough for %.9g + char buffer[16]; // more than enough for %.9g snprintf(buffer, sizeof(buffer), "%.9g", value); return buffer; } diff --git a/absl/synchronization/internal/mutex_nonprod.cc b/absl/synchronization/internal/mutex_nonprod.cc index 94be54b8..62d19816 100644 --- a/absl/synchronization/internal/mutex_nonprod.cc +++ b/absl/synchronization/internal/mutex_nonprod.cc @@ -231,6 +231,11 @@ bool Mutex::LockWhenWithTimeout(const Condition& cond, absl::Duration timeout) { cond, synchronization_internal::DeadlineFromTimeout(timeout)); } +void Mutex::ReaderLockWhen(const Condition& cond) { + ReaderLock(); + Await(cond); +} + bool Mutex::ReaderLockWhenWithTimeout(const Condition& cond, absl::Duration timeout) { return LockWhenWithTimeout(cond, timeout); diff --git a/absl/synchronization/internal/mutex_nonprod.inc b/absl/synchronization/internal/mutex_nonprod.inc index 51441b25..0aab3d13 100644 --- a/absl/synchronization/internal/mutex_nonprod.inc +++ b/absl/synchronization/internal/mutex_nonprod.inc @@ -105,16 +105,16 @@ class MutexImpl { }; // Do not use this implementation detail of CondVar and Mutex. A storage -// space for T that supports a base::LinkerInitialized constructor. T must +// space for T that supports a LinkerInitialized constructor. T must // have a default constructor, which is called by the first call to -// get(). T's destructor is never called if the base::LinkerInitialized +// get(). T's destructor is never called if the LinkerInitialized // constructor is called. // // Objects constructed with the default constructor are constructed and // destructed like any other object, and should never be allocated in // static storage. // -// Objects constructed with the base::LinkerInitialized constructor should +// Objects constructed with the LinkerInitialized constructor should // always be in static storage. For such objects, calls to get() are always // valid, except from signal handlers. // @@ -126,7 +126,7 @@ class MutexImpl { // // [basic.life] says an object has non-trivial initialization if it is of // class type and it is initialized by a constructor other than a trivial -// default constructor. (the base::LinkerInitialized constructor is +// default constructor. (the LinkerInitialized constructor is // non-trivial) // // [basic.life] says the lifetime of an object with a non-trivial @@ -139,34 +139,34 @@ class MutexImpl { // members of an instance outside its // lifetime. (SynchronizationStorage::get() access non-static members) // -// So, base::LinkerInitialized object of SynchronizationStorage uses a +// So, LinkerInitialized object of SynchronizationStorage uses a // non-trivial constructor, which is called at some point during dynamic // initialization, and is therefore subject to order of dynamic // initialization bugs, where get() is called before the object's // constructor is, resulting in undefined behavior. // -// Similarly, a base::LinkerInitialized SynchronizationStorage object has a +// Similarly, a LinkerInitialized SynchronizationStorage object has a // non-trivial destructor, and so its lifetime ends at some point during // destruction of objects with static storage duration [basic.start.term] // p4. There is a window where other exit code could call get() after this // occurs, resulting in undefined behavior. // -// Combined, these statements imply that base::LinkerInitialized instances +// Combined, these statements imply that LinkerInitialized instances // of SynchronizationStorage rely on undefined behavior. // // However, in practice, the implementation works on all supported // compilers. Specifically, we rely on: // // a) zero-initialization being sufficient to initialize -// base::LinkerInitialized instances for the purposes of calling +// LinkerInitialized instances for the purposes of calling // get(), regardless of when the constructor is called. This is // because the is_dynamic_ boolean is correctly zero-initialized to // false. // -// b) the base::LinkerInitialized constructor is a NOP, and immaterial to +// b) the LinkerInitialized constructor is a NOP, and immaterial to // even to concurrent calls to get(). // -// c) the destructor being a NOP for base::LinkerInitialized objects +// c) the destructor being a NOP for LinkerInitialized objects // (guaranteed by a check for !is_dynamic_), and so any concurrent and // subsequent calls to get() functioning as if the destructor were not // called, by virtue of the instances' storage remaining valid after the @@ -212,7 +212,7 @@ class SynchronizationStorage { // Instances allocated in static storage (not on the heap, not on the // stack) should use this constructor. - explicit SynchronizationStorage(base::LinkerInitialized) {} + explicit SynchronizationStorage(base_internal::LinkerInitialized) {} SynchronizationStorage(SynchronizationStorage&) = delete; SynchronizationStorage& operator=(SynchronizationStorage&) = delete; @@ -227,7 +227,7 @@ class SynchronizationStorage { // incur the cost of absl::call_once(). // // For instances in static storage constructed with the - // base::LinkerInitialized constructor, may be called at any time without + // LinkerInitialized constructor, may be called at any time without // regard for order of dynamic initialization or destruction of objects // in static storage. See the class comment for caveats. T* get() { @@ -242,7 +242,7 @@ class SynchronizationStorage { // When true, T's destructor is run when this is destructed. // - // The base::LinkerInitialized constructor assumes this value will be set + // The LinkerInitialized constructor assumes this value will be set // false by static initialization. bool is_dynamic_;