mirror of
https://github.com/abseil/abseil-cpp.git
synced 2026-06-04 12:07:05 +08:00
Export of internal Abseil changes
-- 587e6db882749fa7faa12815e614afab04d218b9 by Derek Mauro <dmauro@google.com>: Use attribute detection for other sanitizer related attributes PiperOrigin-RevId: 324077073 -- 3ee55e4935b4235516b1fcac3c55945e510f7afc by Evan Brown <ezb@google.com>: Simplify CordRepExternal allocation/deallocation. I think this can save some memory when `Releaser` is empty and when on platforms where alignof(CordRepExternal) < (default `::operator new` alignment). We no longer need the API requirement that alignof(Releaser) <= (default `::operator new` alignment). Also remove another static_assert from a TODO in cord_internal.h and fix some warnings about calling std::move on a forwarding reference. PiperOrigin-RevId: 324053720 -- 9fc78436565eb3b204d4aa425ee3773354392f45 by Derek Mauro <dmauro@google.com>: Use auto-detected sanitizer attributes for ASAN, MSAN, and TSAN builds PiperOrigin-RevId: 323831461 GitOrigin-RevId: 587e6db882749fa7faa12815e614afab04d218b9 Change-Id: Ie0e4a2846d7f66988a2d81a5e50721b62fdb3d6d
This commit is contained in:
committed by
Mark Barolak
parent
82302f1e05
commit
184cf25241
@@ -415,6 +415,7 @@ cc_library(
|
||||
deps = [
|
||||
":base",
|
||||
":base_internal",
|
||||
":config",
|
||||
":core_headers",
|
||||
"//absl/synchronization",
|
||||
"@com_google_googletest//:gtest",
|
||||
@@ -431,6 +432,7 @@ cc_test(
|
||||
deps = [
|
||||
":base",
|
||||
":base_internal",
|
||||
":config",
|
||||
":core_headers",
|
||||
"//absl/synchronization",
|
||||
"@com_google_googletest//:gtest_main",
|
||||
|
||||
@@ -384,6 +384,7 @@ absl_cc_library(
|
||||
${ABSL_TEST_COPTS}
|
||||
DEPS
|
||||
absl::base
|
||||
absl::config
|
||||
absl::base_internal
|
||||
absl::core_headers
|
||||
absl::synchronization
|
||||
@@ -402,6 +403,7 @@ absl_cc_test(
|
||||
DEPS
|
||||
absl::base
|
||||
absl::base_internal
|
||||
absl::config
|
||||
absl::core_headers
|
||||
absl::synchronization
|
||||
gtest_main
|
||||
|
||||
@@ -32,34 +32,12 @@
|
||||
// of them are not supported in older version of Clang. Thus, we check
|
||||
// `__has_attribute()` first. If the check fails, we check if we are on GCC and
|
||||
// assume the attribute exists on GCC (which is verified on GCC 4.7).
|
||||
//
|
||||
// -----------------------------------------------------------------------------
|
||||
// Sanitizer Attributes
|
||||
// -----------------------------------------------------------------------------
|
||||
//
|
||||
// Sanitizer-related attributes are not "defined" in this file (and indeed
|
||||
// are not defined as such in any file). To utilize the following
|
||||
// sanitizer-related attributes within your builds, define the following macros
|
||||
// within your build using a `-D` flag, along with the given value for
|
||||
// `-fsanitize`:
|
||||
//
|
||||
// * `ADDRESS_SANITIZER` + `-fsanitize=address` (Clang, GCC 4.8)
|
||||
// * `MEMORY_SANITIZER` + `-fsanitize=memory` (Clang-only)
|
||||
// * `THREAD_SANITIZER` + `-fsanitize=thread` (Clang, GCC 4.8+)
|
||||
// * `UNDEFINED_BEHAVIOR_SANITIZER` + `-fsanitize=undefined` (Clang, GCC 4.9+)
|
||||
// * `CONTROL_FLOW_INTEGRITY` + `-fsanitize=cfi` (Clang-only)
|
||||
//
|
||||
// Example:
|
||||
//
|
||||
// // Enable branches in the Abseil code that are tagged for ASan:
|
||||
// $ bazel build --copt=-DADDRESS_SANITIZER --copt=-fsanitize=address
|
||||
// --linkopt=-fsanitize=address *target*
|
||||
//
|
||||
// Since these macro names are only supported by GCC and Clang, we only check
|
||||
// for `__GNUC__` (GCC or Clang) and the above macros.
|
||||
|
||||
#ifndef ABSL_BASE_ATTRIBUTES_H_
|
||||
#define ABSL_BASE_ATTRIBUTES_H_
|
||||
|
||||
#include "absl/base/config.h"
|
||||
|
||||
// ABSL_HAVE_ATTRIBUTE
|
||||
//
|
||||
// A function-like feature checking macro that is a wrapper around
|
||||
@@ -234,7 +212,7 @@
|
||||
// out of bounds or does other scary things with memory.
|
||||
// NOTE: GCC supports AddressSanitizer(asan) since 4.8.
|
||||
// https://gcc.gnu.org/gcc-4.8/changes.html
|
||||
#if defined(__GNUC__)
|
||||
#if ABSL_HAVE_ATTRIBUTE(no_sanitize_address)
|
||||
#define ABSL_ATTRIBUTE_NO_SANITIZE_ADDRESS __attribute__((no_sanitize_address))
|
||||
#else
|
||||
#define ABSL_ATTRIBUTE_NO_SANITIZE_ADDRESS
|
||||
@@ -242,13 +220,13 @@
|
||||
|
||||
// ABSL_ATTRIBUTE_NO_SANITIZE_MEMORY
|
||||
//
|
||||
// Tells the MemorySanitizer to relax the handling of a given function. All
|
||||
// "Use of uninitialized value" warnings from such functions will be suppressed,
|
||||
// and all values loaded from memory will be considered fully initialized.
|
||||
// This attribute is similar to the ADDRESS_SANITIZER attribute above, but deals
|
||||
// with initialized-ness rather than addressability issues.
|
||||
// Tells the MemorySanitizer to relax the handling of a given function. All "Use
|
||||
// of uninitialized value" warnings from such functions will be suppressed, and
|
||||
// all values loaded from memory will be considered fully initialized. This
|
||||
// attribute is similar to the ABSL_ATTRIBUTE_NO_SANITIZE_ADDRESS attribute
|
||||
// above, but deals with initialized-ness rather than addressability issues.
|
||||
// NOTE: MemorySanitizer(msan) is supported by Clang but not GCC.
|
||||
#if defined(__clang__)
|
||||
#if ABSL_HAVE_ATTRIBUTE(no_sanitize_memory)
|
||||
#define ABSL_ATTRIBUTE_NO_SANITIZE_MEMORY __attribute__((no_sanitize_memory))
|
||||
#else
|
||||
#define ABSL_ATTRIBUTE_NO_SANITIZE_MEMORY
|
||||
@@ -259,7 +237,7 @@
|
||||
// Tells the ThreadSanitizer to not instrument a given function.
|
||||
// NOTE: GCC supports ThreadSanitizer(tsan) since 4.8.
|
||||
// https://gcc.gnu.org/gcc-4.8/changes.html
|
||||
#if defined(__GNUC__)
|
||||
#if ABSL_HAVE_ATTRIBUTE(no_sanitize_thread)
|
||||
#define ABSL_ATTRIBUTE_NO_SANITIZE_THREAD __attribute__((no_sanitize_thread))
|
||||
#else
|
||||
#define ABSL_ATTRIBUTE_NO_SANITIZE_THREAD
|
||||
@@ -271,8 +249,10 @@
|
||||
// where certain behavior (eg. division by zero) is being used intentionally.
|
||||
// NOTE: GCC supports UndefinedBehaviorSanitizer(ubsan) since 4.9.
|
||||
// https://gcc.gnu.org/gcc-4.9/changes.html
|
||||
#if defined(__GNUC__) && \
|
||||
(defined(UNDEFINED_BEHAVIOR_SANITIZER) || defined(ADDRESS_SANITIZER))
|
||||
#if ABSL_HAVE_ATTRIBUTE(no_sanitize_undefined)
|
||||
#define ABSL_ATTRIBUTE_NO_SANITIZE_UNDEFINED \
|
||||
__attribute__((no_sanitize_undefined))
|
||||
#elif ABSL_HAVE_ATTRIBUTE(no_sanitize)
|
||||
#define ABSL_ATTRIBUTE_NO_SANITIZE_UNDEFINED \
|
||||
__attribute__((no_sanitize("undefined")))
|
||||
#else
|
||||
@@ -283,7 +263,7 @@
|
||||
//
|
||||
// Tells the ControlFlowIntegrity sanitizer to not instrument a given function.
|
||||
// See https://clang.llvm.org/docs/ControlFlowIntegrity.html for details.
|
||||
#if defined(__GNUC__) && defined(CONTROL_FLOW_INTEGRITY)
|
||||
#if ABSL_HAVE_ATTRIBUTE(no_sanitize)
|
||||
#define ABSL_ATTRIBUTE_NO_SANITIZE_CFI __attribute__((no_sanitize("cfi")))
|
||||
#else
|
||||
#define ABSL_ATTRIBUTE_NO_SANITIZE_CFI
|
||||
@@ -293,7 +273,7 @@
|
||||
//
|
||||
// Tells the SafeStack to not instrument a given function.
|
||||
// See https://clang.llvm.org/docs/SafeStack.html for details.
|
||||
#if defined(__GNUC__) && defined(SAFESTACK_SANITIZER)
|
||||
#if ABSL_HAVE_ATTRIBUTE(no_sanitize)
|
||||
#define ABSL_ATTRIBUTE_NO_SANITIZE_SAFESTACK \
|
||||
__attribute__((no_sanitize("safe-stack")))
|
||||
#else
|
||||
|
||||
@@ -91,12 +91,9 @@
|
||||
#endif
|
||||
|
||||
// Memory annotations are also made available to LLVM's Memory Sanitizer
|
||||
#if defined(MEMORY_SANITIZER) && defined(__has_feature) && \
|
||||
!defined(__native_client__)
|
||||
#if __has_feature(memory_sanitizer)
|
||||
#if defined(ABSL_HAVE_MEMORY_SANITIZER) && !defined(__native_client__)
|
||||
#define ABSL_INTERNAL_MEMORY_ANNOTATIONS_ENABLED 1
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef ABSL_INTERNAL_MEMORY_ANNOTATIONS_ENABLED
|
||||
#define ABSL_INTERNAL_MEMORY_ANNOTATIONS_ENABLED 0
|
||||
@@ -162,7 +159,7 @@
|
||||
ABSL_INTERNAL_GLOBAL_SCOPED(AnnotateRWLockCreate)(__FILE__, __LINE__, lock)
|
||||
|
||||
// Report that a linker initialized lock has been created at address `lock`.
|
||||
#ifdef THREAD_SANITIZER
|
||||
#ifdef ABSL_HAVE_THREAD_SANITIZER
|
||||
#define ANNOTATE_RWLOCK_CREATE_STATIC(lock) \
|
||||
ABSL_INTERNAL_GLOBAL_SCOPED(AnnotateRWLockCreateStatic) \
|
||||
(__FILE__, __LINE__, lock)
|
||||
@@ -367,7 +364,7 @@
|
||||
// -------------------------------------------------------------------------
|
||||
// Address sanitizer annotations
|
||||
|
||||
#ifdef ADDRESS_SANITIZER
|
||||
#ifdef ABSL_HAVE_ADDRESS_SANITIZER
|
||||
// Describe the current state of a contiguous container such as e.g.
|
||||
// std::vector or std::string. For more details see
|
||||
// sanitizer/common_interface_defs.h, which is provided by the compiler.
|
||||
@@ -385,7 +382,7 @@
|
||||
#define ANNOTATE_CONTIGUOUS_CONTAINER(beg, end, old_mid, new_mid)
|
||||
#define ADDRESS_SANITIZER_REDZONE(name) static_assert(true, "")
|
||||
|
||||
#endif // ADDRESS_SANITIZER
|
||||
#endif // ABSL_HAVE_ADDRESS_SANITIZER
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Undefine the macros intended only for this file.
|
||||
|
||||
@@ -19,6 +19,8 @@
|
||||
#ifndef ABSL_BASE_INTERNAL_TSAN_MUTEX_INTERFACE_H_
|
||||
#define ABSL_BASE_INTERNAL_TSAN_MUTEX_INTERFACE_H_
|
||||
|
||||
#include "absl/base/config.h"
|
||||
|
||||
// ABSL_INTERNAL_HAVE_TSAN_INTERFACE
|
||||
// Macro intended only for internal use.
|
||||
//
|
||||
@@ -28,7 +30,7 @@
|
||||
#error "ABSL_INTERNAL_HAVE_TSAN_INTERFACE cannot be directly set."
|
||||
#endif
|
||||
|
||||
#if defined(THREAD_SANITIZER) && defined(__has_include)
|
||||
#if defined(ABSL_HAVE_THREAD_SANITIZER) && defined(__has_include)
|
||||
#if __has_include(<sanitizer/tsan_interface.h>)
|
||||
#define ABSL_INTERNAL_HAVE_TSAN_INTERFACE 1
|
||||
#endif
|
||||
|
||||
@@ -32,8 +32,8 @@
|
||||
// (namespaces, inline) which are absent or incompatible in C.
|
||||
#if defined(__cplusplus)
|
||||
|
||||
#if defined(ADDRESS_SANITIZER) || defined(THREAD_SANITIZER) ||\
|
||||
defined(MEMORY_SANITIZER)
|
||||
#if defined(ABSL_HAVE_ADDRESS_SANITIZER) || \
|
||||
defined(ABSL_HAVE_THREAD_SANITIZER) || defined(ABSL_HAVE_MEMORY_SANITIZER)
|
||||
// Consider we have an unaligned load/store of 4 bytes from address 0x...05.
|
||||
// AddressSanitizer will treat it as a 3-byte access to the range 05:07 and
|
||||
// will miss a bug if 08 is the first unaddressable byte.
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
#include "absl/base/attributes.h"
|
||||
#include "absl/base/config.h"
|
||||
#include "absl/base/internal/low_level_scheduling.h"
|
||||
#include "absl/base/internal/scheduling_mode.h"
|
||||
#include "absl/base/internal/spinlock.h"
|
||||
@@ -104,7 +105,7 @@ static void ThreadedTest(SpinLock* spinlock) {
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef THREAD_SANITIZER
|
||||
#ifndef ABSL_HAVE_THREAD_SANITIZER
|
||||
static_assert(std::is_trivially_destructible<SpinLock>(), "");
|
||||
#endif
|
||||
|
||||
|
||||
@@ -60,6 +60,7 @@ cc_library(
|
||||
deps = [
|
||||
":compressed_tuple",
|
||||
"//absl/algorithm",
|
||||
"//absl/base:config",
|
||||
"//absl/base:core_headers",
|
||||
"//absl/base:dynamic_annotations",
|
||||
"//absl/base:throw_delegate",
|
||||
@@ -368,6 +369,7 @@ cc_library(
|
||||
copts = ABSL_DEFAULT_COPTS,
|
||||
linkopts = ABSL_DEFAULT_LINKOPTS,
|
||||
deps = [
|
||||
"//absl/base:config",
|
||||
"//absl/memory",
|
||||
"//absl/meta:type_traits",
|
||||
"//absl/utility",
|
||||
@@ -620,6 +622,7 @@ cc_test(
|
||||
":hashtable_debug",
|
||||
":raw_hash_set",
|
||||
"//absl/base",
|
||||
"//absl/base:config",
|
||||
"//absl/base:core_headers",
|
||||
"//absl/base:raw_logging_internal",
|
||||
"//absl/strings",
|
||||
@@ -647,6 +650,7 @@ cc_library(
|
||||
copts = ABSL_DEFAULT_COPTS,
|
||||
linkopts = ABSL_DEFAULT_LINKOPTS,
|
||||
deps = [
|
||||
"//absl/base:config",
|
||||
"//absl/base:core_headers",
|
||||
"//absl/meta:type_traits",
|
||||
"//absl/strings",
|
||||
@@ -665,6 +669,7 @@ cc_test(
|
||||
visibility = ["//visibility:private"],
|
||||
deps = [
|
||||
":layout",
|
||||
"//absl/base:config",
|
||||
"//absl/base:core_headers",
|
||||
"//absl/base:raw_logging_internal",
|
||||
"//absl/types:span",
|
||||
|
||||
@@ -131,6 +131,7 @@ absl_cc_library(
|
||||
DEPS
|
||||
absl::compressed_tuple
|
||||
absl::algorithm
|
||||
absl::config
|
||||
absl::core_headers
|
||||
absl::dynamic_annotations
|
||||
absl::throw_delegate
|
||||
@@ -423,6 +424,7 @@ absl_cc_library(
|
||||
COPTS
|
||||
${ABSL_DEFAULT_COPTS}
|
||||
DEPS
|
||||
absl::config
|
||||
absl::memory
|
||||
absl::type_traits
|
||||
absl::utility
|
||||
@@ -696,6 +698,7 @@ absl_cc_test(
|
||||
absl::hashtable_debug
|
||||
absl::raw_hash_set
|
||||
absl::base
|
||||
absl::config
|
||||
absl::core_headers
|
||||
absl::raw_logging_internal
|
||||
absl::strings
|
||||
@@ -724,6 +727,7 @@ absl_cc_library(
|
||||
COPTS
|
||||
${ABSL_DEFAULT_COPTS}
|
||||
DEPS
|
||||
absl::config
|
||||
absl::core_headers
|
||||
absl::meta
|
||||
absl::strings
|
||||
@@ -741,6 +745,7 @@ absl_cc_test(
|
||||
${ABSL_TEST_COPTS}
|
||||
DEPS
|
||||
absl::layout
|
||||
absl::config
|
||||
absl::core_headers
|
||||
absl::raw_logging_internal
|
||||
absl::span
|
||||
|
||||
@@ -41,6 +41,7 @@
|
||||
#include <type_traits>
|
||||
|
||||
#include "absl/algorithm/algorithm.h"
|
||||
#include "absl/base/config.h"
|
||||
#include "absl/base/dynamic_annotations.h"
|
||||
#include "absl/base/internal/throw_delegate.h"
|
||||
#include "absl/base/macros.h"
|
||||
@@ -422,10 +423,10 @@ class FixedArray {
|
||||
void AnnotateConstruct(size_type n);
|
||||
void AnnotateDestruct(size_type n);
|
||||
|
||||
#ifdef ADDRESS_SANITIZER
|
||||
#ifdef ABSL_HAVE_ADDRESS_SANITIZER
|
||||
void* RedzoneBegin() { return &redzone_begin_; }
|
||||
void* RedzoneEnd() { return &redzone_end_ + 1; }
|
||||
#endif // ADDRESS_SANITIZER
|
||||
#endif // ABSL_HAVE_ADDRESS_SANITIZER
|
||||
|
||||
private:
|
||||
ABSL_ADDRESS_SANITIZER_REDZONE(redzone_begin_);
|
||||
@@ -503,26 +504,26 @@ constexpr typename FixedArray<T, N, A>::size_type
|
||||
template <typename T, size_t N, typename A>
|
||||
void FixedArray<T, N, A>::NonEmptyInlinedStorage::AnnotateConstruct(
|
||||
typename FixedArray<T, N, A>::size_type n) {
|
||||
#ifdef ADDRESS_SANITIZER
|
||||
#ifdef ABSL_HAVE_ADDRESS_SANITIZER
|
||||
if (!n) return;
|
||||
ABSL_ANNOTATE_CONTIGUOUS_CONTAINER(data(), RedzoneEnd(), RedzoneEnd(),
|
||||
data() + n);
|
||||
ABSL_ANNOTATE_CONTIGUOUS_CONTAINER(RedzoneBegin(), data(), data(),
|
||||
RedzoneBegin());
|
||||
#endif // ADDRESS_SANITIZER
|
||||
#endif // ABSL_HAVE_ADDRESS_SANITIZER
|
||||
static_cast<void>(n); // Mark used when not in asan mode
|
||||
}
|
||||
|
||||
template <typename T, size_t N, typename A>
|
||||
void FixedArray<T, N, A>::NonEmptyInlinedStorage::AnnotateDestruct(
|
||||
typename FixedArray<T, N, A>::size_type n) {
|
||||
#ifdef ADDRESS_SANITIZER
|
||||
#ifdef ABSL_HAVE_ADDRESS_SANITIZER
|
||||
if (!n) return;
|
||||
ABSL_ANNOTATE_CONTIGUOUS_CONTAINER(data(), RedzoneEnd(), data() + n,
|
||||
RedzoneEnd());
|
||||
ABSL_ANNOTATE_CONTIGUOUS_CONTAINER(RedzoneBegin(), data(), RedzoneBegin(),
|
||||
data());
|
||||
#endif // ADDRESS_SANITIZER
|
||||
#endif // ABSL_HAVE_ADDRESS_SANITIZER
|
||||
static_cast<void>(n); // Mark used when not in asan mode
|
||||
}
|
||||
ABSL_NAMESPACE_END
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
|
||||
#include "gmock/gmock.h"
|
||||
#include "gtest/gtest.h"
|
||||
#include "absl/base/config.h"
|
||||
#include "absl/base/internal/exception_testing.h"
|
||||
#include "absl/base/options.h"
|
||||
#include "absl/container/internal/counting_allocator.h"
|
||||
@@ -767,7 +768,7 @@ TEST(AllocatorSupportTest, SizeValAllocConstructor) {
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef ADDRESS_SANITIZER
|
||||
#ifdef ABSL_HAVE_ADDRESS_SANITIZER
|
||||
TEST(FixedArrayTest, AddressSanitizerAnnotations1) {
|
||||
absl::FixedArray<int, 32> a(10);
|
||||
int* raw = a.data();
|
||||
@@ -814,7 +815,7 @@ TEST(FixedArrayTest, AddressSanitizerAnnotations4) {
|
||||
// so reading raw[21] should still trigger the correct warning.
|
||||
EXPECT_DEATH_IF_SUPPORTED(raw[21] = ThreeInts(), "container-overflow");
|
||||
}
|
||||
#endif // ADDRESS_SANITIZER
|
||||
#endif // ABSL_HAVE_ADDRESS_SANITIZER
|
||||
|
||||
TEST(FixedArrayTest, AbslHashValueWorks) {
|
||||
using V = absl::FixedArray<int>;
|
||||
|
||||
@@ -15,14 +15,6 @@
|
||||
#ifndef ABSL_CONTAINER_INTERNAL_CONTAINER_MEMORY_H_
|
||||
#define ABSL_CONTAINER_INTERNAL_CONTAINER_MEMORY_H_
|
||||
|
||||
#ifdef ADDRESS_SANITIZER
|
||||
#include <sanitizer/asan_interface.h>
|
||||
#endif
|
||||
|
||||
#ifdef MEMORY_SANITIZER
|
||||
#include <sanitizer/msan_interface.h>
|
||||
#endif
|
||||
|
||||
#include <cassert>
|
||||
#include <cstddef>
|
||||
#include <memory>
|
||||
@@ -30,10 +22,19 @@
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
|
||||
#include "absl/base/config.h"
|
||||
#include "absl/memory/memory.h"
|
||||
#include "absl/meta/type_traits.h"
|
||||
#include "absl/utility/utility.h"
|
||||
|
||||
#ifdef ABSL_HAVE_ADDRESS_SANITIZER
|
||||
#include <sanitizer/asan_interface.h>
|
||||
#endif
|
||||
|
||||
#ifdef ABSL_HAVE_MEMORY_SANITIZER
|
||||
#include <sanitizer/msan_interface.h>
|
||||
#endif
|
||||
|
||||
namespace absl {
|
||||
ABSL_NAMESPACE_BEGIN
|
||||
namespace container_internal {
|
||||
@@ -209,10 +210,10 @@ DecomposeValue(F&& f, Arg&& arg) {
|
||||
|
||||
// Helper functions for asan and msan.
|
||||
inline void SanitizerPoisonMemoryRegion(const void* m, size_t s) {
|
||||
#ifdef ADDRESS_SANITIZER
|
||||
#ifdef ABSL_HAVE_ADDRESS_SANITIZER
|
||||
ASAN_POISON_MEMORY_REGION(m, s);
|
||||
#endif
|
||||
#ifdef MEMORY_SANITIZER
|
||||
#ifdef ABSL_HAVE_MEMORY_SANITIZER
|
||||
__msan_poison(m, s);
|
||||
#endif
|
||||
(void)m;
|
||||
@@ -220,10 +221,10 @@ inline void SanitizerPoisonMemoryRegion(const void* m, size_t s) {
|
||||
}
|
||||
|
||||
inline void SanitizerUnpoisonMemoryRegion(const void* m, size_t s) {
|
||||
#ifdef ADDRESS_SANITIZER
|
||||
#ifdef ABSL_HAVE_ADDRESS_SANITIZER
|
||||
ASAN_UNPOISON_MEMORY_REGION(m, s);
|
||||
#endif
|
||||
#ifdef MEMORY_SANITIZER
|
||||
#ifdef ABSL_HAVE_MEMORY_SANITIZER
|
||||
__msan_unpoison(m, s);
|
||||
#endif
|
||||
(void)m;
|
||||
|
||||
@@ -163,6 +163,7 @@
|
||||
#include <assert.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include <ostream>
|
||||
#include <string>
|
||||
#include <tuple>
|
||||
@@ -170,15 +171,16 @@
|
||||
#include <typeinfo>
|
||||
#include <utility>
|
||||
|
||||
#ifdef ADDRESS_SANITIZER
|
||||
#include <sanitizer/asan_interface.h>
|
||||
#endif
|
||||
|
||||
#include "absl/base/config.h"
|
||||
#include "absl/meta/type_traits.h"
|
||||
#include "absl/strings/str_cat.h"
|
||||
#include "absl/types/span.h"
|
||||
#include "absl/utility/utility.h"
|
||||
|
||||
#ifdef ABSL_HAVE_ADDRESS_SANITIZER
|
||||
#include <sanitizer/asan_interface.h>
|
||||
#endif
|
||||
|
||||
#if defined(__GXX_RTTI)
|
||||
#define ABSL_INTERNAL_HAS_CXA_DEMANGLE
|
||||
#endif
|
||||
@@ -614,7 +616,7 @@ class LayoutImpl<std::tuple<Elements...>, absl::index_sequence<SizeSeq...>,
|
||||
void PoisonPadding(const Char* p) const {
|
||||
static_assert(N < NumOffsets, "Index out of bounds");
|
||||
(void)p;
|
||||
#ifdef ADDRESS_SANITIZER
|
||||
#ifdef ABSL_HAVE_ADDRESS_SANITIZER
|
||||
PoisonPadding<Char, N - 1>(p);
|
||||
// The `if` is an optimization. It doesn't affect the observable behaviour.
|
||||
if (ElementAlignment<N - 1>::value % ElementAlignment<N>::value) {
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
// We need ::max_align_t because some libstdc++ versions don't provide
|
||||
// std::max_align_t
|
||||
#include <stddef.h>
|
||||
|
||||
#include <cstdint>
|
||||
#include <memory>
|
||||
#include <sstream>
|
||||
@@ -24,6 +25,7 @@
|
||||
|
||||
#include "gmock/gmock.h"
|
||||
#include "gtest/gtest.h"
|
||||
#include "absl/base/config.h"
|
||||
#include "absl/base/internal/raw_logging.h"
|
||||
#include "absl/types/span.h"
|
||||
|
||||
@@ -1314,7 +1316,7 @@ struct Region {
|
||||
};
|
||||
|
||||
void ExpectRegionPoisoned(const unsigned char* p, size_t n, bool poisoned) {
|
||||
#ifdef ADDRESS_SANITIZER
|
||||
#ifdef ABSL_HAVE_ADDRESS_SANITIZER
|
||||
for (size_t i = 0; i != n; ++i) {
|
||||
EXPECT_EQ(poisoned, __asan_address_is_poisoned(p + i));
|
||||
}
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
#include "gmock/gmock.h"
|
||||
#include "gtest/gtest.h"
|
||||
#include "absl/base/attributes.h"
|
||||
#include "absl/base/config.h"
|
||||
#include "absl/base/internal/cycleclock.h"
|
||||
#include "absl/base/internal/raw_logging.h"
|
||||
#include "absl/container/internal/container_memory.h"
|
||||
@@ -1839,7 +1840,7 @@ TEST(RawHashSamplerTest, DoNotSampleCustomAllocators) {
|
||||
0.00, 0.001);
|
||||
}
|
||||
|
||||
#ifdef ADDRESS_SANITIZER
|
||||
#ifdef ABSL_HAVE_ADDRESS_SANITIZER
|
||||
TEST(Sanitizer, PoisoningUnused) {
|
||||
IntTable t;
|
||||
t.reserve(5);
|
||||
@@ -1863,7 +1864,7 @@ TEST(Sanitizer, PoisoningOnErase) {
|
||||
t.erase(0);
|
||||
EXPECT_TRUE(__asan_address_is_poisoned(&v));
|
||||
}
|
||||
#endif // ADDRESS_SANITIZER
|
||||
#endif // ABSL_HAVE_ADDRESS_SANITIZER
|
||||
|
||||
} // namespace
|
||||
} // namespace container_internal
|
||||
|
||||
@@ -97,6 +97,7 @@ cc_test(
|
||||
":stack_consumption",
|
||||
":symbolize",
|
||||
"//absl/base",
|
||||
"//absl/base:config",
|
||||
"//absl/base:core_headers",
|
||||
"//absl/base:raw_logging_internal",
|
||||
"//absl/memory",
|
||||
@@ -204,6 +205,7 @@ cc_test(
|
||||
deps = [
|
||||
":demangle_internal",
|
||||
":stack_consumption",
|
||||
"//absl/base:config",
|
||||
"//absl/base:core_headers",
|
||||
"//absl/base:raw_logging_internal",
|
||||
"//absl/memory",
|
||||
|
||||
@@ -82,6 +82,7 @@ absl_cc_test(
|
||||
absl::stack_consumption
|
||||
absl::symbolize
|
||||
absl::base
|
||||
absl::config
|
||||
absl::core_headers
|
||||
absl::memory
|
||||
absl::raw_logging_internal
|
||||
@@ -189,6 +190,7 @@ absl_cc_test(
|
||||
DEPS
|
||||
absl::demangle_internal
|
||||
absl::stack_consumption
|
||||
absl::config
|
||||
absl::core_headers
|
||||
absl::memory
|
||||
absl::raw_logging_internal
|
||||
|
||||
@@ -136,8 +136,8 @@ static bool SetupAlternateStackOnce() {
|
||||
const size_t page_mask = sysconf(_SC_PAGESIZE) - 1;
|
||||
#endif
|
||||
size_t stack_size = (std::max(SIGSTKSZ, 65536) + page_mask) & ~page_mask;
|
||||
#if defined(ADDRESS_SANITIZER) || defined(MEMORY_SANITIZER) || \
|
||||
defined(THREAD_SANITIZER)
|
||||
#if defined(ABSL_HAVE_ADDRESS_SANITIZER) || \
|
||||
defined(ABSL_HAVE_MEMORY_SANITIZER) || defined(ABSL_HAVE_THREAD_SANITIZER)
|
||||
// Account for sanitizer instrumentation requiring additional stack space.
|
||||
stack_size *= 5;
|
||||
#endif
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
#include <string>
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
#include "absl/base/config.h"
|
||||
#include "absl/base/internal/raw_logging.h"
|
||||
#include "absl/debugging/internal/stack_consumption.h"
|
||||
#include "absl/memory/memory.h"
|
||||
@@ -82,9 +83,10 @@ TEST(Demangle, Clones) {
|
||||
// Tests that verify that Demangle footprint is within some limit.
|
||||
// They are not to be run under sanitizers as the sanitizers increase
|
||||
// stack consumption by about 4x.
|
||||
#if defined(ABSL_INTERNAL_HAVE_DEBUGGING_STACK_CONSUMPTION) && \
|
||||
!defined(ADDRESS_SANITIZER) && !defined(MEMORY_SANITIZER) && \
|
||||
!defined(THREAD_SANITIZER)
|
||||
#if defined(ABSL_INTERNAL_HAVE_DEBUGGING_STACK_CONSUMPTION) && \
|
||||
!defined(ABSL_HAVE_ADDRESS_SANITIZER) && \
|
||||
!defined(ABSL_HAVE_MEMORY_SANITIZER) && \
|
||||
!defined(ABSL_HAVE_THREAD_SANITIZER)
|
||||
|
||||
static const char *g_mangled;
|
||||
static char g_demangle_buffer[4096];
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
#include "gtest/gtest.h"
|
||||
#include "absl/base/attributes.h"
|
||||
#include "absl/base/casts.h"
|
||||
#include "absl/base/config.h"
|
||||
#include "absl/base/internal/per_thread_tls.h"
|
||||
#include "absl/base/internal/raw_logging.h"
|
||||
#include "absl/base/optimization.h"
|
||||
@@ -220,8 +221,8 @@ static const char *SymbolizeStackConsumption(void *pc, int *stack_consumed) {
|
||||
static int GetStackConsumptionUpperLimit() {
|
||||
// Symbolize stack consumption should be within 2kB.
|
||||
int stack_consumption_upper_limit = 2048;
|
||||
#if defined(ADDRESS_SANITIZER) || defined(MEMORY_SANITIZER) || \
|
||||
defined(THREAD_SANITIZER)
|
||||
#if defined(ABSL_HAVE_ADDRESS_SANITIZER) || \
|
||||
defined(ABSL_HAVE_MEMORY_SANITIZER) || defined(ABSL_HAVE_THREAD_SANITIZER)
|
||||
// Account for sanitizer instrumentation requiring additional stack space.
|
||||
stack_consumption_upper_limit *= 5;
|
||||
#endif
|
||||
|
||||
@@ -258,6 +258,8 @@ cc_library(
|
||||
visibility = ["//visibility:private"],
|
||||
deps = [
|
||||
":strings",
|
||||
"//absl/base:base_internal",
|
||||
"//absl/container:compressed_tuple",
|
||||
"//absl/meta:type_traits",
|
||||
],
|
||||
)
|
||||
@@ -277,7 +279,6 @@ cc_library(
|
||||
":str_format",
|
||||
":strings",
|
||||
"//absl/base",
|
||||
"//absl/base:base_internal",
|
||||
"//absl/base:core_headers",
|
||||
"//absl/base:endian",
|
||||
"//absl/base:raw_logging_internal",
|
||||
|
||||
@@ -548,6 +548,7 @@ absl_cc_library(
|
||||
DEPS
|
||||
absl::base
|
||||
absl::base_internal
|
||||
absl::compressed_tuple
|
||||
absl::core_headers
|
||||
absl::endian
|
||||
absl::fixed_array
|
||||
|
||||
@@ -61,48 +61,6 @@ enum CordRepKind {
|
||||
FLAT = 3,
|
||||
};
|
||||
|
||||
namespace {
|
||||
|
||||
// Type used with std::allocator for allocating and deallocating
|
||||
// `CordRepExternal`. std::allocator is used because it opaquely handles the
|
||||
// different new / delete overloads available on a given platform.
|
||||
struct alignas(absl::cord_internal::ExternalRepAlignment()) ExternalAllocType {
|
||||
unsigned char value[absl::cord_internal::ExternalRepAlignment()];
|
||||
};
|
||||
|
||||
// Returns the number of objects to pass in to std::allocator<ExternalAllocType>
|
||||
// allocate() and deallocate() to create enough room for `CordRepExternal` with
|
||||
// `releaser_size` bytes on the end.
|
||||
constexpr size_t GetExternalAllocNumObjects(size_t releaser_size) {
|
||||
// Be sure to round up since `releaser_size` could be smaller than
|
||||
// `sizeof(ExternalAllocType)`.
|
||||
return (sizeof(CordRepExternal) + releaser_size + sizeof(ExternalAllocType) -
|
||||
1) /
|
||||
sizeof(ExternalAllocType);
|
||||
}
|
||||
|
||||
// Allocates enough memory for `CordRepExternal` and a releaser with size
|
||||
// `releaser_size` bytes.
|
||||
void* AllocateExternal(size_t releaser_size) {
|
||||
return std::allocator<ExternalAllocType>().allocate(
|
||||
GetExternalAllocNumObjects(releaser_size));
|
||||
}
|
||||
|
||||
// Deallocates the memory for a `CordRepExternal` assuming it was allocated with
|
||||
// a releaser of given size and alignment.
|
||||
void DeallocateExternal(CordRepExternal* p, size_t releaser_size) {
|
||||
std::allocator<ExternalAllocType>().deallocate(
|
||||
reinterpret_cast<ExternalAllocType*>(p),
|
||||
GetExternalAllocNumObjects(releaser_size));
|
||||
}
|
||||
|
||||
// Returns a pointer to the type erased releaser for the given CordRepExternal.
|
||||
void* GetExternalReleaser(CordRepExternal* rep) {
|
||||
return rep + 1;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
namespace cord_internal {
|
||||
|
||||
inline CordRepConcat* CordRep::concat() {
|
||||
@@ -304,11 +262,7 @@ static void UnrefInternal(CordRep* rep) {
|
||||
}
|
||||
} else if (rep->tag == EXTERNAL) {
|
||||
CordRepExternal* rep_external = rep->external();
|
||||
absl::string_view data(rep_external->base, rep->length);
|
||||
void* releaser = GetExternalReleaser(rep_external);
|
||||
size_t releaser_size = rep_external->releaser_invoker(releaser, data);
|
||||
rep_external->~CordRepExternal();
|
||||
DeallocateExternal(rep_external, releaser_size);
|
||||
rep_external->releaser_invoker(rep_external);
|
||||
rep = nullptr;
|
||||
} else if (rep->tag == SUBSTRING) {
|
||||
CordRepSubstring* rep_substring = rep->substring();
|
||||
@@ -458,18 +412,12 @@ static CordRep* NewTree(const char* data,
|
||||
|
||||
namespace cord_internal {
|
||||
|
||||
ExternalRepReleaserPair NewExternalWithUninitializedReleaser(
|
||||
absl::string_view data, ExternalReleaserInvoker invoker,
|
||||
size_t releaser_size) {
|
||||
void InitializeCordRepExternal(absl::string_view data, CordRepExternal* rep) {
|
||||
assert(!data.empty());
|
||||
|
||||
void* raw_rep = AllocateExternal(releaser_size);
|
||||
auto* rep = new (raw_rep) CordRepExternal();
|
||||
rep->length = data.size();
|
||||
rep->tag = EXTERNAL;
|
||||
rep->base = data.data();
|
||||
rep->releaser_invoker = invoker;
|
||||
return {VerifyTree(rep), GetExternalReleaser(rep)};
|
||||
VerifyTree(rep);
|
||||
}
|
||||
|
||||
} // namespace cord_internal
|
||||
@@ -721,12 +669,12 @@ Cord::Cord(T&& src) {
|
||||
std::string data;
|
||||
};
|
||||
const absl::string_view original_data = src;
|
||||
CordRepExternal* rep =
|
||||
static_cast<CordRepExternal*>(absl::cord_internal::NewExternalRep(
|
||||
original_data, StringReleaser{std::move(src)}));
|
||||
auto* rep = static_cast<
|
||||
::absl::cord_internal::CordRepExternalImpl<StringReleaser>*>(
|
||||
absl::cord_internal::NewExternalRep(
|
||||
original_data, StringReleaser{std::forward<T>(src)}));
|
||||
// Moving src may have invalidated its data pointer, so adjust it.
|
||||
rep->base =
|
||||
static_cast<StringReleaser*>(GetExternalReleaser(rep))->data.data();
|
||||
rep->base = rep->template get<0>().data.data();
|
||||
contents_.set_tree(rep);
|
||||
}
|
||||
}
|
||||
@@ -775,7 +723,7 @@ Cord& Cord::operator=(T&& src) {
|
||||
if (src.size() <= kMaxBytesToCopy) {
|
||||
*this = absl::string_view(src);
|
||||
} else {
|
||||
*this = Cord(std::move(src));
|
||||
*this = Cord(std::forward<T>(src));
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
@@ -898,7 +846,7 @@ void Cord::Append(T&& src) {
|
||||
if (src.size() <= kMaxBytesToCopy) {
|
||||
Append(absl::string_view(src));
|
||||
} else {
|
||||
Append(Cord(std::move(src)));
|
||||
Append(Cord(std::forward<T>(src)));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -938,7 +886,7 @@ inline void Cord::Prepend(T&& src) {
|
||||
if (src.size() <= kMaxBytesToCopy) {
|
||||
Prepend(absl::string_view(src));
|
||||
} else {
|
||||
Prepend(Cord(std::move(src)));
|
||||
Prepend(Cord(std::forward<T>(src)));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -71,7 +71,6 @@
|
||||
#include <type_traits>
|
||||
|
||||
#include "absl/base/internal/endian.h"
|
||||
#include "absl/base/internal/invoke.h"
|
||||
#include "absl/base/internal/per_thread_tls.h"
|
||||
#include "absl/base/macros.h"
|
||||
#include "absl/base/port.h"
|
||||
@@ -173,10 +172,6 @@ class Cord {
|
||||
//
|
||||
// * be move constructible
|
||||
// * support `void operator()(absl::string_view) const` or `void operator()`
|
||||
// * not have alignment requirement greater than what is guaranteed by
|
||||
// `::operator new`. This alignment is dictated by
|
||||
// `alignof(std::max_align_t)` (pre-C++17 code) or
|
||||
// `__STDCPP_DEFAULT_NEW_ALIGNMENT__` (C++17 code).
|
||||
//
|
||||
// Example:
|
||||
//
|
||||
@@ -842,47 +837,15 @@ inline void SmallMemmove(char* dst, const char* src, size_t n,
|
||||
}
|
||||
}
|
||||
|
||||
struct ExternalRepReleaserPair {
|
||||
CordRep* rep;
|
||||
void* releaser_address;
|
||||
};
|
||||
|
||||
// Allocates a new external `CordRep` and returns a pointer to it and a pointer
|
||||
// to `releaser_size` bytes where the desired releaser can be constructed.
|
||||
// Does non-template-specific `CordRepExternal` initialization.
|
||||
// Expects `data` to be non-empty.
|
||||
ExternalRepReleaserPair NewExternalWithUninitializedReleaser(
|
||||
absl::string_view data, ExternalReleaserInvoker invoker,
|
||||
size_t releaser_size);
|
||||
|
||||
struct Rank1 {};
|
||||
struct Rank0 : Rank1 {};
|
||||
|
||||
template <typename Releaser, typename = ::absl::base_internal::invoke_result_t<
|
||||
Releaser, absl::string_view>>
|
||||
void InvokeReleaser(Rank0, Releaser&& releaser, absl::string_view data) {
|
||||
::absl::base_internal::invoke(std::forward<Releaser>(releaser), data);
|
||||
}
|
||||
|
||||
template <typename Releaser,
|
||||
typename = ::absl::base_internal::invoke_result_t<Releaser>>
|
||||
void InvokeReleaser(Rank1, Releaser&& releaser, absl::string_view) {
|
||||
::absl::base_internal::invoke(std::forward<Releaser>(releaser));
|
||||
}
|
||||
void InitializeCordRepExternal(absl::string_view data, CordRepExternal* rep);
|
||||
|
||||
// Creates a new `CordRep` that owns `data` and `releaser` and returns a pointer
|
||||
// to it, or `nullptr` if `data` was empty.
|
||||
template <typename Releaser>
|
||||
// NOLINTNEXTLINE - suppress clang-tidy raw pointer return.
|
||||
CordRep* NewExternalRep(absl::string_view data, Releaser&& releaser) {
|
||||
static_assert(
|
||||
#if defined(__STDCPP_DEFAULT_NEW_ALIGNMENT__)
|
||||
alignof(Releaser) <= __STDCPP_DEFAULT_NEW_ALIGNMENT__,
|
||||
#else
|
||||
alignof(Releaser) <= alignof(max_align_t),
|
||||
#endif
|
||||
"Releasers with alignment requirement greater than what is returned by "
|
||||
"default `::operator new()` are not supported.");
|
||||
|
||||
using ReleaserType = absl::decay_t<Releaser>;
|
||||
if (data.empty()) {
|
||||
// Never create empty external nodes.
|
||||
@@ -891,18 +854,10 @@ CordRep* NewExternalRep(absl::string_view data, Releaser&& releaser) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto releaser_invoker = [](void* type_erased_releaser, absl::string_view d) {
|
||||
auto* my_releaser = static_cast<ReleaserType*>(type_erased_releaser);
|
||||
InvokeReleaser(Rank0{}, std::move(*my_releaser), d);
|
||||
my_releaser->~ReleaserType();
|
||||
return sizeof(Releaser);
|
||||
};
|
||||
|
||||
ExternalRepReleaserPair external = NewExternalWithUninitializedReleaser(
|
||||
data, releaser_invoker, sizeof(releaser));
|
||||
::new (external.releaser_address)
|
||||
ReleaserType(std::forward<Releaser>(releaser));
|
||||
return external.rep;
|
||||
CordRepExternal* rep = new CordRepExternalImpl<ReleaserType>(
|
||||
std::forward<Releaser>(releaser), 0);
|
||||
InitializeCordRepExternal(data, rep);
|
||||
return rep;
|
||||
}
|
||||
|
||||
// Overload for function reference types that dispatches using a function
|
||||
|
||||
@@ -21,6 +21,8 @@
|
||||
#include <cstdint>
|
||||
#include <type_traits>
|
||||
|
||||
#include "absl/base/internal/invoke.h"
|
||||
#include "absl/container/internal/compressed_tuple.h"
|
||||
#include "absl/meta/type_traits.h"
|
||||
#include "absl/strings/string_view.h"
|
||||
|
||||
@@ -114,35 +116,56 @@ struct CordRepSubstring : public CordRep {
|
||||
CordRep* child;
|
||||
};
|
||||
|
||||
// TODO(strel): replace the following logic (and related functions in cord.cc)
|
||||
// with container_internal::Layout.
|
||||
|
||||
// Alignment requirement for CordRepExternal so that the type erased releaser
|
||||
// will be stored at a suitably aligned address.
|
||||
constexpr size_t ExternalRepAlignment() {
|
||||
#if defined(__STDCPP_DEFAULT_NEW_ALIGNMENT__)
|
||||
return __STDCPP_DEFAULT_NEW_ALIGNMENT__;
|
||||
#else
|
||||
return alignof(max_align_t);
|
||||
#endif
|
||||
}
|
||||
|
||||
// Type for function pointer that will invoke and destroy the type-erased
|
||||
// releaser function object. Accepts a pointer to the releaser and the
|
||||
// `string_view` that were passed in to `NewExternalRep` below. The return value
|
||||
// is the size of the `Releaser` type.
|
||||
using ExternalReleaserInvoker = size_t (*)(void*, absl::string_view);
|
||||
// Type for function pointer that will invoke the releaser function and also
|
||||
// delete the `CordRepExternalImpl` corresponding to the passed in
|
||||
// `CordRepExternal`.
|
||||
using ExternalReleaserInvoker = void (*)(CordRepExternal*);
|
||||
|
||||
// External CordReps are allocated together with a type erased releaser. The
|
||||
// releaser is stored in the memory directly following the CordRepExternal.
|
||||
struct alignas(ExternalRepAlignment()) CordRepExternal : public CordRep {
|
||||
struct CordRepExternal : public CordRep {
|
||||
const char* base;
|
||||
// Pointer to function that knows how to call and destroy the releaser.
|
||||
ExternalReleaserInvoker releaser_invoker;
|
||||
};
|
||||
|
||||
// TODO(strel): look into removing, it doesn't seem like anything relies on this
|
||||
static_assert(sizeof(CordRepConcat) == sizeof(CordRepSubstring), "");
|
||||
struct Rank1 {};
|
||||
struct Rank0 : Rank1 {};
|
||||
|
||||
template <typename Releaser, typename = ::absl::base_internal::invoke_result_t<
|
||||
Releaser, absl::string_view>>
|
||||
void InvokeReleaser(Rank0, Releaser&& releaser, absl::string_view data) {
|
||||
::absl::base_internal::invoke(std::forward<Releaser>(releaser), data);
|
||||
}
|
||||
|
||||
template <typename Releaser,
|
||||
typename = ::absl::base_internal::invoke_result_t<Releaser>>
|
||||
void InvokeReleaser(Rank1, Releaser&& releaser, absl::string_view) {
|
||||
::absl::base_internal::invoke(std::forward<Releaser>(releaser));
|
||||
}
|
||||
|
||||
// We use CompressedTuple so that we can benefit from EBCO.
|
||||
template <typename Releaser>
|
||||
struct CordRepExternalImpl
|
||||
: public CordRepExternal,
|
||||
public ::absl::container_internal::CompressedTuple<Releaser> {
|
||||
// The extra int arg is so that we can avoid interfering with copy/move
|
||||
// constructors while still benefitting from perfect forwarding.
|
||||
template <typename T>
|
||||
CordRepExternalImpl(T&& releaser, int)
|
||||
: CordRepExternalImpl::CompressedTuple(std::forward<T>(releaser)) {
|
||||
this->releaser_invoker = &Release;
|
||||
}
|
||||
|
||||
~CordRepExternalImpl() {
|
||||
InvokeReleaser(Rank0{}, std::move(this->template get<0>()),
|
||||
absl::string_view(base, length));
|
||||
}
|
||||
|
||||
static void Release(CordRepExternal* rep) {
|
||||
delete static_cast<CordRepExternalImpl*>(rep);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace cord_internal
|
||||
ABSL_NAMESPACE_END
|
||||
|
||||
@@ -1177,7 +1177,7 @@ TEST(FindOneCharTest, EdgeCases) {
|
||||
EXPECT_EQ(absl::string_view::npos, a.rfind('x'));
|
||||
}
|
||||
|
||||
#ifndef THREAD_SANITIZER // Allocates too much memory for tsan.
|
||||
#ifndef ABSL_HAVE_THREAD_SANITIZER // Allocates too much memory for tsan.
|
||||
TEST(HugeStringView, TwoPointTwoGB) {
|
||||
if (sizeof(size_t) <= 4)
|
||||
return;
|
||||
@@ -1191,7 +1191,7 @@ TEST(HugeStringView, TwoPointTwoGB) {
|
||||
sp.remove_suffix(2);
|
||||
EXPECT_EQ(size - 1 - 2, sp.length());
|
||||
}
|
||||
#endif // THREAD_SANITIZER
|
||||
#endif // ABSL_HAVE_THREAD_SANITIZER
|
||||
|
||||
#if !defined(NDEBUG) && !defined(ABSL_USES_STD_STRING_VIEW)
|
||||
TEST(NonNegativeLenTest, NonNegativeLen) {
|
||||
|
||||
@@ -190,6 +190,7 @@ cc_test(
|
||||
":synchronization",
|
||||
":thread_pool",
|
||||
"//absl/base",
|
||||
"//absl/base:config",
|
||||
"//absl/base:core_headers",
|
||||
"//absl/base:raw_logging_internal",
|
||||
"//absl/memory",
|
||||
@@ -211,6 +212,7 @@ cc_library(
|
||||
":synchronization",
|
||||
":thread_pool",
|
||||
"//absl/base",
|
||||
"//absl/base:config",
|
||||
"@com_github_google_benchmark//:benchmark_main",
|
||||
],
|
||||
alwayslink = 1,
|
||||
@@ -249,6 +251,7 @@ cc_library(
|
||||
deps = [
|
||||
":synchronization",
|
||||
"//absl/base",
|
||||
"//absl/base:config",
|
||||
"//absl/strings",
|
||||
"//absl/time",
|
||||
"@com_google_googletest//:gtest",
|
||||
|
||||
@@ -149,6 +149,7 @@ absl_cc_test(
|
||||
absl::synchronization
|
||||
absl::thread_pool
|
||||
absl::base
|
||||
absl::config
|
||||
absl::core_headers
|
||||
absl::memory
|
||||
absl::raw_logging_internal
|
||||
@@ -179,6 +180,7 @@ absl_cc_library(
|
||||
DEPS
|
||||
absl::synchronization
|
||||
absl::base
|
||||
absl::config
|
||||
absl::strings
|
||||
absl::time
|
||||
gmock
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include "absl/base/config.h"
|
||||
#include "absl/base/internal/raw_logging.h"
|
||||
#include "absl/time/time.h"
|
||||
|
||||
@@ -278,7 +279,7 @@ bool CondVar::WaitWithTimeout(Mutex* mu, absl::Duration timeout) {
|
||||
|
||||
void CondVar::EnableDebugLog(const char*) {}
|
||||
|
||||
#ifdef THREAD_SANITIZER
|
||||
#ifdef ABSL_HAVE_THREAD_SANITIZER
|
||||
extern "C" void __tsan_read1(void *addr);
|
||||
#else
|
||||
#define __tsan_read1(addr) // do nothing if TSan not enabled
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
#include <thread> // NOLINT(build/c++11)
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
#include "absl/base/config.h"
|
||||
#include "absl/base/internal/cycleclock.h"
|
||||
#include "absl/base/internal/thread_identity.h"
|
||||
#include "absl/strings/str_cat.h"
|
||||
|
||||
@@ -100,7 +100,7 @@ class Waiter {
|
||||
}
|
||||
|
||||
// How many periods to remain idle before releasing resources
|
||||
#ifndef THREAD_SANITIZER
|
||||
#ifndef ABSL_HAVE_THREAD_SANITIZER
|
||||
static constexpr int kIdlePeriods = 60;
|
||||
#else
|
||||
// Memory consumption under ThreadSanitizer is a serious concern,
|
||||
|
||||
@@ -77,7 +77,7 @@ ABSL_NAMESPACE_BEGIN
|
||||
|
||||
namespace {
|
||||
|
||||
#if defined(THREAD_SANITIZER)
|
||||
#if defined(ABSL_HAVE_THREAD_SANITIZER)
|
||||
constexpr OnDeadlockCycle kDeadlockDetectionDefault = OnDeadlockCycle::kIgnore;
|
||||
#else
|
||||
constexpr OnDeadlockCycle kDeadlockDetectionDefault = OnDeadlockCycle::kAbort;
|
||||
@@ -705,7 +705,7 @@ static constexpr bool kDebugMode = false;
|
||||
static constexpr bool kDebugMode = true;
|
||||
#endif
|
||||
|
||||
#ifdef THREAD_SANITIZER
|
||||
#ifdef ABSL_HAVE_THREAD_SANITIZER
|
||||
static unsigned TsanFlags(Mutex::MuHow how) {
|
||||
return how == kShared ? __tsan_mutex_read_lock : 0;
|
||||
}
|
||||
@@ -1767,7 +1767,7 @@ static inline bool EvalConditionAnnotated(const Condition *cond, Mutex *mu,
|
||||
// All memory accesses are ignored inside of mutex operations + for unlock
|
||||
// operation tsan considers that we've already released the mutex.
|
||||
bool res = false;
|
||||
#ifdef THREAD_SANITIZER
|
||||
#ifdef ABSL_HAVE_THREAD_SANITIZER
|
||||
const int flags = read_lock ? __tsan_mutex_read_lock : 0;
|
||||
const int tryflags = flags | (trylock ? __tsan_mutex_try_lock : 0);
|
||||
#endif
|
||||
@@ -2683,7 +2683,7 @@ void ReleasableMutexLock::Release() {
|
||||
this->mu_ = nullptr;
|
||||
}
|
||||
|
||||
#ifdef THREAD_SANITIZER
|
||||
#ifdef ABSL_HAVE_THREAD_SANITIZER
|
||||
extern "C" void __tsan_read1(void *addr);
|
||||
#else
|
||||
#define __tsan_read1(addr) // do nothing if TSan not enabled
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
#include <mutex> // NOLINT(build/c++11)
|
||||
#include <vector>
|
||||
|
||||
#include "absl/base/config.h"
|
||||
#include "absl/base/internal/cycleclock.h"
|
||||
#include "absl/base/internal/spinlock.h"
|
||||
#include "absl/synchronization/blocking_counter.h"
|
||||
@@ -213,7 +214,7 @@ void BM_ConditionWaiters(benchmark::State& state) {
|
||||
}
|
||||
|
||||
// Some configurations have higher thread limits than others.
|
||||
#if defined(__linux__) && !defined(THREAD_SANITIZER)
|
||||
#if defined(__linux__) && !defined(ABSL_HAVE_THREAD_SANITIZER)
|
||||
constexpr int kMaxConditionWaiters = 8192;
|
||||
#else
|
||||
constexpr int kMaxConditionWaiters = 1024;
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
#include "absl/base/attributes.h"
|
||||
#include "absl/base/config.h"
|
||||
#include "absl/base/internal/raw_logging.h"
|
||||
#include "absl/base/internal/sysinfo.h"
|
||||
#include "absl/memory/memory.h"
|
||||
@@ -815,7 +816,7 @@ TEST(Mutex, MutexReaderDecrementBug) ABSL_NO_THREAD_SAFETY_ANALYSIS {
|
||||
|
||||
// Test that we correctly handle the situation when a lock is
|
||||
// held and then destroyed (w/o unlocking).
|
||||
#ifdef THREAD_SANITIZER
|
||||
#ifdef ABSL_HAVE_THREAD_SANITIZER
|
||||
// TSAN reports errors when locked Mutexes are destroyed.
|
||||
TEST(Mutex, DISABLED_LockedMutexDestructionBug) NO_THREAD_SAFETY_ANALYSIS {
|
||||
#else
|
||||
@@ -1067,7 +1068,7 @@ class ScopedDisableBazelTestWarnings {
|
||||
const char ScopedDisableBazelTestWarnings::kVarName[] =
|
||||
"TEST_WARNINGS_OUTPUT_FILE";
|
||||
|
||||
#ifdef THREAD_SANITIZER
|
||||
#ifdef ABSL_HAVE_THREAD_SANITIZER
|
||||
// This test intentionally creates deadlocks to test the deadlock detector.
|
||||
TEST(Mutex, DISABLED_DeadlockDetectorBazelWarning) {
|
||||
#else
|
||||
@@ -1119,7 +1120,7 @@ TEST(Mutex, DeadlockDetectorStessTest) ABSL_NO_THREAD_SAFETY_ANALYSIS {
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef THREAD_SANITIZER
|
||||
#ifdef ABSL_HAVE_THREAD_SANITIZER
|
||||
// TSAN reports errors when locked Mutexes are destroyed.
|
||||
TEST(Mutex, DISABLED_DeadlockIdBug) NO_THREAD_SAFETY_ANALYSIS {
|
||||
#else
|
||||
|
||||
@@ -70,6 +70,7 @@ cc_library(
|
||||
],
|
||||
deps = [
|
||||
":time",
|
||||
"//absl/base:config",
|
||||
"//absl/base:raw_logging_internal",
|
||||
"//absl/time/internal/cctz:time_zone",
|
||||
"@com_google_googletest//:gtest",
|
||||
|
||||
@@ -99,6 +99,7 @@ absl_cc_library(
|
||||
${ABSL_DEFAULT_COPTS}
|
||||
DEPS
|
||||
absl::time
|
||||
absl::config
|
||||
absl::raw_logging_internal
|
||||
absl::time_zone
|
||||
gmock
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
#include <cstddef>
|
||||
#include <cstring>
|
||||
|
||||
#include "absl/base/config.h"
|
||||
#include "absl/base/internal/raw_logging.h"
|
||||
#include "absl/time/internal/cctz/include/cctz/zone_info_source.h"
|
||||
|
||||
|
||||
@@ -78,8 +78,6 @@ for std in ${STD}; do
|
||||
/usr/local/bin/bazel test ... \
|
||||
--compilation_mode="${compilation_mode}" \
|
||||
--copt="${exceptions_mode}" \
|
||||
--copt="-DADDRESS_SANITIZER" \
|
||||
--copt="-DUNDEFINED_BEHAVIOR_SANITIZER" \
|
||||
--copt="-fsanitize=address" \
|
||||
--copt="-fsanitize=float-divide-by-zero" \
|
||||
--copt="-fsanitize=nullability" \
|
||||
|
||||
@@ -79,8 +79,6 @@ for std in ${STD}; do
|
||||
--build_tag_filters="-notsan" \
|
||||
--compilation_mode="${compilation_mode}" \
|
||||
--copt="${exceptions_mode}" \
|
||||
--copt="-DDYNAMIC_ANNOTATIONS_ENABLED=1" \
|
||||
--copt="-DTHREAD_SANITIZER" \
|
||||
--copt="-fsanitize=thread" \
|
||||
--copt="-fno-sanitize-blacklist" \
|
||||
--copt=-Werror \
|
||||
|
||||
Reference in New Issue
Block a user