aboutsummaryrefslogtreecommitdiff
path: root/absl/base
diff options
context:
space:
mode:
Diffstat (limited to 'absl/base')
-rw-r--r--absl/base/BUILD.bazel71
-rw-r--r--absl/base/CMakeLists.txt32
-rw-r--r--absl/base/attributes.h84
-rw-r--r--absl/base/c_header_test.c30
-rw-r--r--absl/base/config.h85
-rw-r--r--absl/base/dynamic_annotations.h16
-rw-r--r--absl/base/internal/nullability_impl.h4
-rw-r--r--absl/base/internal/poison.cc84
-rw-r--r--absl/base/internal/poison.h59
-rw-r--r--absl/base/internal/poison_test.cc41
-rw-r--r--absl/base/internal/spinlock.h16
-rw-r--r--absl/base/internal/unscaledcycleclock.cc12
-rw-r--r--absl/base/internal/unscaledcycleclock_config.h8
-rw-r--r--absl/base/macros.h48
-rw-r--r--absl/base/no_destructor.h75
-rw-r--r--absl/base/nullability.h40
-rw-r--r--absl/base/optimization.h11
-rw-r--r--absl/base/options.h2
-rw-r--r--absl/base/prefetch.h2
19 files changed, 573 insertions, 147 deletions
diff --git a/absl/base/BUILD.bazel b/absl/base/BUILD.bazel
index 0eb735da..96503c90 100644
--- a/absl/base/BUILD.bazel
+++ b/absl/base/BUILD.bazel
@@ -74,7 +74,10 @@ cc_library(
hdrs = ["no_destructor.h"],
copts = ABSL_DEFAULT_COPTS,
linkopts = ABSL_DEFAULT_LINKOPTS,
- deps = [":config"],
+ deps = [
+ ":config",
+ ":nullability",
+ ],
)
cc_library(
@@ -84,6 +87,7 @@ cc_library(
copts = ABSL_DEFAULT_COPTS,
linkopts = ABSL_DEFAULT_LINKOPTS,
deps = [
+ ":config",
":core_headers",
"//absl/meta:type_traits",
],
@@ -294,7 +298,7 @@ cc_library(
cc_library(
name = "atomic_hook_test_helper",
- testonly = 1,
+ testonly = True,
srcs = ["internal/atomic_hook_test_helper.cc"],
hdrs = ["internal/atomic_hook_test_helper.h"],
copts = ABSL_DEFAULT_COPTS,
@@ -336,6 +340,18 @@ cc_test(
],
)
+cc_test(
+ name = "c_header_test",
+ srcs = ["c_header_test.c"],
+ tags = [
+ "no_test_wasm",
+ ],
+ deps = [
+ ":config",
+ ":core_headers",
+ ],
+)
+
cc_library(
name = "throw_delegate",
srcs = ["internal/throw_delegate.cc"],
@@ -380,7 +396,7 @@ cc_test(
cc_library(
name = "exception_testing",
- testonly = 1,
+ testonly = True,
hdrs = ["internal/exception_testing.h"],
copts = ABSL_TEST_COPTS,
linkopts = ABSL_DEFAULT_LINKOPTS,
@@ -404,7 +420,7 @@ cc_library(
cc_library(
name = "exception_safety_testing",
- testonly = 1,
+ testonly = True,
srcs = ["internal/exception_safety_testing.cc"],
hdrs = ["internal/exception_safety_testing.h"],
copts = ABSL_TEST_COPTS,
@@ -470,7 +486,7 @@ cc_test(
# AbslInternalSpinLockDelay and AbslInternalSpinLockWake.
cc_library(
name = "spinlock_test_common",
- testonly = 1,
+ testonly = True,
srcs = ["spinlock_test_common.cc"],
copts = ABSL_TEST_COPTS,
linkopts = ABSL_DEFAULT_LINKOPTS,
@@ -507,7 +523,7 @@ cc_test(
cc_library(
name = "spinlock_benchmark_common",
- testonly = 1,
+ testonly = True,
srcs = ["internal/spinlock_benchmark.cc"],
copts = ABSL_TEST_COPTS,
linkopts = ABSL_DEFAULT_LINKOPTS,
@@ -527,7 +543,7 @@ cc_library(
cc_binary(
name = "spinlock_benchmark",
- testonly = 1,
+ testonly = True,
copts = ABSL_DEFAULT_COPTS,
linkopts = ABSL_DEFAULT_LINKOPTS,
tags = ["benchmark"],
@@ -608,7 +624,7 @@ cc_test(
cc_binary(
name = "no_destructor_benchmark",
- testonly = 1,
+ testonly = True,
srcs = ["no_destructor_benchmark.cc"],
copts = ABSL_TEST_COPTS,
linkopts = ABSL_DEFAULT_LINKOPTS,
@@ -710,7 +726,7 @@ cc_test(
cc_library(
name = "scoped_set_env",
- testonly = 1,
+ testonly = True,
srcs = ["internal/scoped_set_env.cc"],
hdrs = ["internal/scoped_set_env.h"],
linkopts = ABSL_DEFAULT_LINKOPTS,
@@ -784,7 +800,7 @@ cc_test(
cc_binary(
name = "strerror_benchmark",
- testonly = 1,
+ testonly = True,
srcs = ["internal/strerror_benchmark.cc"],
copts = ABSL_TEST_COPTS,
linkopts = ABSL_DEFAULT_LINKOPTS,
@@ -850,6 +866,41 @@ cc_test(
],
)
+cc_library(
+ name = "poison",
+ srcs = [
+ "internal/poison.cc",
+ ],
+ hdrs = ["internal/poison.h"],
+ copts = ABSL_DEFAULT_COPTS,
+ linkopts = ABSL_DEFAULT_LINKOPTS,
+ visibility = [
+ "//absl:__subpackages__",
+ ],
+ deps = [
+ ":config",
+ ":core_headers",
+ ":malloc_internal",
+ ],
+)
+
+cc_test(
+ name = "poison_test",
+ size = "small",
+ timeout = "short",
+ srcs = [
+ "internal/poison_test.cc",
+ ],
+ copts = ABSL_TEST_COPTS,
+ linkopts = ABSL_DEFAULT_LINKOPTS,
+ deps = [
+ ":config",
+ ":poison",
+ "@com_google_googletest//:gtest",
+ "@com_google_googletest//:gtest_main",
+ ],
+)
+
cc_test(
name = "unique_small_name_test",
size = "small",
diff --git a/absl/base/CMakeLists.txt b/absl/base/CMakeLists.txt
index 4cfc2285..97994fc6 100644
--- a/absl/base/CMakeLists.txt
+++ b/absl/base/CMakeLists.txt
@@ -62,6 +62,7 @@ absl_cc_library(
"no_destructor.h"
DEPS
absl::config
+ absl::nullability
COPTS
${ABSL_DEFAULT_COPTS}
)
@@ -74,6 +75,7 @@ absl_cc_library(
SRCS
"internal/nullability_impl.h"
DEPS
+ absl::config
absl::core_headers
absl::type_traits
COPTS
@@ -737,3 +739,33 @@ absl_cc_test(
absl::optional
GTest::gtest_main
)
+
+absl_cc_library(
+ NAME
+ poison
+ SRCS
+ "internal/poison.cc"
+ HDRS
+ "internal/poison.h"
+ COPTS
+ ${ABSL_DEFAULT_COPTS}
+ LINKOPTS
+ ${ABSL_DEFAULT_LINKOPTS}
+ DEPS
+ absl::config
+ absl::core_headers
+ absl::malloc_internal
+)
+
+absl_cc_test(
+ NAME
+ poison_test
+ SRCS
+ "internal/poison_test.cc"
+ COPTS
+ ${ABSL_TEST_COPTS}
+ DEPS
+ absl::config
+ absl::poison
+ GTest::gtest_main
+)
diff --git a/absl/base/attributes.h b/absl/base/attributes.h
index d4f67a12..5ea5ee3e 100644
--- a/absl/base/attributes.h
+++ b/absl/base/attributes.h
@@ -195,6 +195,9 @@
// ABSL_ATTRIBUTE_NORETURN
//
// Tells the compiler that a given function never returns.
+//
+// Deprecated: Prefer the `[[noreturn]]` attribute standardized by C++11 over
+// this macro.
#if ABSL_HAVE_ATTRIBUTE(noreturn) || (defined(__GNUC__) && !defined(__clang__))
#define ABSL_ATTRIBUTE_NORETURN __attribute__((noreturn))
#elif defined(_MSC_VER)
@@ -702,6 +705,11 @@
_Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"")
#define ABSL_INTERNAL_RESTORE_DEPRECATED_DECLARATION_WARNING \
_Pragma("GCC diagnostic pop")
+#elif defined(_MSC_VER)
+#define ABSL_INTERNAL_DISABLE_DEPRECATED_DECLARATION_WARNING \
+ _Pragma("warning(push)") _Pragma("warning(disable: 4996)")
+#define ABSL_INTERNAL_RESTORE_DEPRECATED_DECLARATION_WARNING \
+ _Pragma("warning(pop)")
#else
#define ABSL_INTERNAL_DISABLE_DEPRECATED_DECLARATION_WARNING
#define ABSL_INTERNAL_RESTORE_DEPRECATED_DECLARATION_WARNING
@@ -808,14 +816,43 @@
//
// See also the upstream documentation:
// https://clang.llvm.org/docs/AttributeReference.html#lifetimebound
+// https://learn.microsoft.com/en-us/cpp/code-quality/c26816?view=msvc-170
#if ABSL_HAVE_CPP_ATTRIBUTE(clang::lifetimebound)
#define ABSL_ATTRIBUTE_LIFETIME_BOUND [[clang::lifetimebound]]
+#elif ABSL_HAVE_CPP_ATTRIBUTE(msvc::lifetimebound)
+#define ABSL_ATTRIBUTE_LIFETIME_BOUND [[msvc::lifetimebound]]
#elif ABSL_HAVE_ATTRIBUTE(lifetimebound)
#define ABSL_ATTRIBUTE_LIFETIME_BOUND __attribute__((lifetimebound))
#else
#define ABSL_ATTRIBUTE_LIFETIME_BOUND
#endif
+// ABSL_INTERNAL_ATTRIBUTE_VIEW indicates that a type acts like a view i.e. a
+// raw (non-owning) pointer. This enables diagnoses similar to those enabled by
+// ABSL_ATTRIBUTE_LIFETIME_BOUND.
+//
+// See the following links for details:
+// https://reviews.llvm.org/D64448
+// https://lists.llvm.org/pipermail/cfe-dev/2018-November/060355.html
+#if ABSL_HAVE_CPP_ATTRIBUTE(gsl::Pointer)
+#define ABSL_INTERNAL_ATTRIBUTE_VIEW [[gsl::Pointer]]
+#else
+#define ABSL_INTERNAL_ATTRIBUTE_VIEW
+#endif
+
+// ABSL_INTERNAL_ATTRIBUTE_OWNER indicates that a type acts like a smart
+// (owning) pointer. This enables diagnoses similar to those enabled by
+// ABSL_ATTRIBUTE_LIFETIME_BOUND.
+//
+// See the following links for details:
+// https://reviews.llvm.org/D64448
+// https://lists.llvm.org/pipermail/cfe-dev/2018-November/060355.html
+#if ABSL_HAVE_CPP_ATTRIBUTE(gsl::Owner)
+#define ABSL_INTERNAL_ATTRIBUTE_OWNER [[gsl::Owner]]
+#else
+#define ABSL_INTERNAL_ATTRIBUTE_OWNER
+#endif
+
// ABSL_ATTRIBUTE_TRIVIAL_ABI
// Indicates that a type is "trivially relocatable" -- meaning it can be
// relocated without invoking the constructor/destructor, using a form of move
@@ -871,4 +908,51 @@
#define ABSL_ATTRIBUTE_NO_UNIQUE_ADDRESS
#endif
+// ABSL_ATTRIBUTE_UNINITIALIZED
+//
+// GCC and Clang support a flag `-ftrivial-auto-var-init=<option>` (<option>
+// can be "zero" or "pattern") that can be used to initialize automatic stack
+// variables. Variables with this attribute will be left uninitialized,
+// overriding the compiler flag.
+//
+// See https://clang.llvm.org/docs/AttributeReference.html#uninitialized
+// and https://gcc.gnu.org/onlinedocs/gcc/Common-Variable-Attributes.html#index-uninitialized-variable-attribute
+#if ABSL_HAVE_CPP_ATTRIBUTE(clang::uninitialized)
+#define ABSL_ATTRIBUTE_UNINITIALIZED [[clang::uninitialized]]
+#elif ABSL_HAVE_CPP_ATTRIBUTE(gnu::uninitialized)
+#define ABSL_ATTRIBUTE_UNINITIALIZED [[gnu::uninitialized]]
+#elif ABSL_HAVE_ATTRIBUTE(uninitialized)
+#define ABSL_ATTRIBUTE_UNINITIALIZED __attribute__((uninitialized))
+#else
+#define ABSL_ATTRIBUTE_UNINITIALIZED
+#endif
+
+// ABSL_ATTRIBUTE_WARN_UNUSED
+//
+// Compilers routinely warn about trivial variables that are unused. For
+// non-trivial types, this warning is suppressed since the
+// constructor/destructor may be intentional and load-bearing, for example, with
+// a RAII scoped lock.
+//
+// For example:
+//
+// class ABSL_ATTRIBUTE_WARN_UNUSED MyType {
+// public:
+// MyType();
+// ~MyType();
+// };
+//
+// void foo() {
+// // Warns with ABSL_ATTRIBUTE_WARN_UNUSED attribute present.
+// MyType unused;
+// }
+//
+// See https://clang.llvm.org/docs/AttributeReference.html#warn-unused and
+// https://gcc.gnu.org/onlinedocs/gcc/C_002b_002b-Attributes.html#index-warn_005funused-type-attribute
+#if ABSL_HAVE_CPP_ATTRIBUTE(gnu::warn_unused)
+#define ABSL_ATTRIBUTE_WARN_UNUSED [[gnu::warn_unused]]
+#else
+#define ABSL_ATTRIBUTE_WARN_UNUSED
+#endif
+
#endif // ABSL_BASE_ATTRIBUTES_H_
diff --git a/absl/base/c_header_test.c b/absl/base/c_header_test.c
new file mode 100644
index 00000000..3cd01778
--- /dev/null
+++ b/absl/base/c_header_test.c
@@ -0,0 +1,30 @@
+// Copyright 2024 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.
+
+#ifdef __cplusplus
+#error This is a C compile test
+#endif
+
+// This test ensures that headers that are included in legacy C code are
+// compatible with C. Abseil is a C++ library. We do not desire to expand C
+// compatibility or keep C compatibility forever. This test only exists to
+// ensure C compatibility until it is no longer required. Do not add new code
+// that requires C compatibility.
+#include "absl/base/attributes.h" // IWYU pragma: keep
+#include "absl/base/config.h" // IWYU pragma: keep
+#include "absl/base/optimization.h" // IWYU pragma: keep
+#include "absl/base/policy_checks.h" // IWYU pragma: keep
+#include "absl/base/port.h" // IWYU pragma: keep
+
+int main() { return 0; }
diff --git a/absl/base/config.h b/absl/base/config.h
index 3933a3db..0b22167e 100644
--- a/absl/base/config.h
+++ b/absl/base/config.h
@@ -117,8 +117,8 @@
//
// LTS releases can be obtained from
// https://github.com/abseil/abseil-cpp/releases.
-#define ABSL_LTS_RELEASE_VERSION 20240116
-#define ABSL_LTS_RELEASE_PATCH_LEVEL 2
+#define ABSL_LTS_RELEASE_VERSION 20240722
+#define ABSL_LTS_RELEASE_PATCH_LEVEL 0
// Helper macro to convert a CPP variable to a string literal.
#define ABSL_INTERNAL_DO_TOKEN_STR(x) #x
@@ -231,12 +231,11 @@ static_assert(ABSL_INTERNAL_INLINE_NAMESPACE_STR[0] != 'h' ||
#endif
// ABSL_HAVE_TLS is defined to 1 when __thread should be supported.
-// We assume __thread is supported on Linux or Asylo when compiled with Clang or
+// We assume __thread is supported on Linux when compiled with Clang or
// compiled against libstdc++ with _GLIBCXX_HAVE_TLS defined.
#ifdef ABSL_HAVE_TLS
#error ABSL_HAVE_TLS cannot be directly set
-#elif (defined(__linux__) || defined(__ASYLO__)) && \
- (defined(__clang__) || defined(_GLIBCXX_HAVE_TLS))
+#elif (defined(__linux__)) && (defined(__clang__) || defined(_GLIBCXX_HAVE_TLS))
#define ABSL_HAVE_TLS 1
#endif
@@ -275,53 +274,18 @@ static_assert(ABSL_INTERNAL_INLINE_NAMESPACE_STR[0] != 'h' ||
#define ABSL_HAVE_STD_IS_TRIVIALLY_COPYABLE 1
#endif
+
// ABSL_HAVE_THREAD_LOCAL
//
+// DEPRECATED - `thread_local` is available on all supported platforms.
// Checks whether C++11's `thread_local` storage duration specifier is
// supported.
#ifdef ABSL_HAVE_THREAD_LOCAL
#error ABSL_HAVE_THREAD_LOCAL cannot be directly set
-#elif defined(__APPLE__)
-// Notes:
-// * Xcode's clang did not support `thread_local` until version 8, and
-// even then not for all iOS < 9.0.
-// * Xcode 9.3 started disallowing `thread_local` for 32-bit iOS simulator
-// targeting iOS 9.x.
-// * Xcode 10 moves the deployment target check for iOS < 9.0 to link time
-// making ABSL_HAVE_FEATURE unreliable there.
-//
-#if ABSL_HAVE_FEATURE(cxx_thread_local) && \
- !(TARGET_OS_IPHONE && __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_9_0)
-#define ABSL_HAVE_THREAD_LOCAL 1
-#endif
-#else // !defined(__APPLE__)
+#else
#define ABSL_HAVE_THREAD_LOCAL 1
#endif
-// There are platforms for which TLS should not be used even though the compiler
-// makes it seem like it's supported (Android NDK < r12b for example).
-// This is primarily because of linker problems and toolchain misconfiguration:
-// Abseil does not intend to support this indefinitely. Currently, the newest
-// toolchain that we intend to support that requires this behavior is the
-// r11 NDK - allowing for a 5 year support window on that means this option
-// is likely to be removed around June of 2021.
-// TLS isn't supported until NDK r12b per
-// https://developer.android.com/ndk/downloads/revision_history.html
-// Since NDK r16, `__NDK_MAJOR__` and `__NDK_MINOR__` are defined in
-// <android/ndk-version.h>. For NDK < r16, users should define these macros,
-// e.g. `-D__NDK_MAJOR__=11 -D__NKD_MINOR__=0` for NDK r11.
-#if defined(__ANDROID__) && defined(__clang__)
-#if __has_include(<android/ndk-version.h>)
-#include <android/ndk-version.h>
-#endif // __has_include(<android/ndk-version.h>)
-#if defined(__ANDROID__) && defined(__clang__) && defined(__NDK_MAJOR__) && \
- defined(__NDK_MINOR__) && \
- ((__NDK_MAJOR__ < 12) || ((__NDK_MAJOR__ == 12) && (__NDK_MINOR__ < 1)))
-#undef ABSL_HAVE_TLS
-#undef ABSL_HAVE_THREAD_LOCAL
-#endif
-#endif // defined(__ANDROID__) && defined(__clang__)
-
// ABSL_HAVE_INTRINSIC_INT128
//
// Checks whether the __int128 compiler extension for a 128-bit integral type is
@@ -379,9 +343,7 @@ static_assert(ABSL_INTERNAL_INLINE_NAMESPACE_STR[0] != 'h' ||
#define ABSL_HAVE_EXCEPTIONS 1
#endif // defined(__EXCEPTIONS) && ABSL_HAVE_FEATURE(cxx_exceptions)
// Handle remaining special cases and default to exceptions being supported.
-#elif !(defined(__GNUC__) && (__GNUC__ < 5) && !defined(__EXCEPTIONS)) && \
- !(ABSL_INTERNAL_HAVE_MIN_GNUC_VERSION(5, 0) && \
- !defined(__cpp_exceptions)) && \
+#elif !(defined(__GNUC__) && !defined(__cpp_exceptions)) && \
!(defined(_MSC_VER) && !defined(_CPPUNWIND))
#define ABSL_HAVE_EXCEPTIONS 1
#endif
@@ -416,9 +378,9 @@ static_assert(ABSL_INTERNAL_INLINE_NAMESPACE_STR[0] != 'h' ||
#elif defined(__linux__) || defined(__APPLE__) || defined(__FreeBSD__) || \
defined(_AIX) || defined(__ros__) || defined(__native_client__) || \
defined(__asmjs__) || defined(__EMSCRIPTEN__) || defined(__Fuchsia__) || \
- defined(__sun) || defined(__ASYLO__) || defined(__myriad2__) || \
- defined(__HAIKU__) || defined(__OpenBSD__) || defined(__NetBSD__) || \
- defined(__QNX__) || defined(__VXWORKS__) || defined(__hexagon__)
+ defined(__sun) || defined(__myriad2__) || defined(__HAIKU__) || \
+ defined(__OpenBSD__) || defined(__NetBSD__) || defined(__QNX__) || \
+ defined(__VXWORKS__) || defined(__hexagon__)
#define ABSL_HAVE_MMAP 1
#endif
@@ -902,9 +864,7 @@ static_assert(ABSL_INTERNAL_INLINE_NAMESPACE_STR[0] != 'h' ||
#error ABSL_INTERNAL_HAS_CXA_DEMANGLE cannot be directly set
#elif defined(OS_ANDROID) && (defined(__i386__) || defined(__x86_64__))
#define ABSL_INTERNAL_HAS_CXA_DEMANGLE 0
-#elif defined(__GNUC__) && defined(__GNUC_MINOR__) && \
- (__GNUC__ >= 4 || (__GNUC__ >= 3 && __GNUC_MINOR__ >= 4)) && \
- !defined(__mips__)
+#elif defined(__GNUC__)
#define ABSL_INTERNAL_HAS_CXA_DEMANGLE 1
#elif defined(__clang__) && !defined(_MSC_VER)
#define ABSL_INTERNAL_HAS_CXA_DEMANGLE 1
@@ -981,6 +941,27 @@ static_assert(ABSL_INTERNAL_INLINE_NAMESPACE_STR[0] != 'h' ||
#define ABSL_HAVE_CONSTANT_EVALUATED 1
#endif
+// ABSL_INTERNAL_CONSTEXPR_SINCE_CXXYY is used to conditionally define constexpr
+// for different C++ versions.
+//
+// These macros are an implementation detail and will be unconditionally removed
+// once the minimum supported C++ version catches up to a given version.
+//
+// For this reason, this symbol is considered INTERNAL and code outside of
+// Abseil must not use it.
+#if defined(ABSL_INTERNAL_CPLUSPLUS_LANG) && \
+ ABSL_INTERNAL_CPLUSPLUS_LANG >= 201703L
+#define ABSL_INTERNAL_CONSTEXPR_SINCE_CXX17 constexpr
+#else
+#define ABSL_INTERNAL_CONSTEXPR_SINCE_CXX17
+#endif
+#if defined(ABSL_INTERNAL_CPLUSPLUS_LANG) && \
+ ABSL_INTERNAL_CPLUSPLUS_LANG >= 202002L
+#define ABSL_INTERNAL_CONSTEXPR_SINCE_CXX20 constexpr
+#else
+#define ABSL_INTERNAL_CONSTEXPR_SINCE_CXX20
+#endif
+
// ABSL_INTERNAL_EMSCRIPTEN_VERSION combines Emscripten's three version macros
// into an integer that can be compared against.
#ifdef ABSL_INTERNAL_EMSCRIPTEN_VERSION
diff --git a/absl/base/dynamic_annotations.h b/absl/base/dynamic_annotations.h
index 7ba8912e..f18b5e0a 100644
--- a/absl/base/dynamic_annotations.h
+++ b/absl/base/dynamic_annotations.h
@@ -252,25 +252,9 @@ ABSL_INTERNAL_END_EXTERN_C
#else // !defined(ABSL_HAVE_MEMORY_SANITIZER)
-// TODO(rogeeff): remove this branch
-#ifdef ABSL_HAVE_THREAD_SANITIZER
-#define ABSL_ANNOTATE_MEMORY_IS_INITIALIZED(address, size) \
- do { \
- (void)(address); \
- (void)(size); \
- } while (0)
-#define ABSL_ANNOTATE_MEMORY_IS_UNINITIALIZED(address, size) \
- do { \
- (void)(address); \
- (void)(size); \
- } while (0)
-#else
-
#define ABSL_ANNOTATE_MEMORY_IS_INITIALIZED(address, size) // empty
#define ABSL_ANNOTATE_MEMORY_IS_UNINITIALIZED(address, size) // empty
-#endif
-
#endif // ABSL_HAVE_MEMORY_SANITIZER
// -------------------------------------------------------------------------
diff --git a/absl/base/internal/nullability_impl.h b/absl/base/internal/nullability_impl.h
index 36e1b33d..03fa2434 100644
--- a/absl/base/internal/nullability_impl.h
+++ b/absl/base/internal/nullability_impl.h
@@ -19,10 +19,11 @@
#include <type_traits>
#include "absl/base/attributes.h"
+#include "absl/base/config.h"
#include "absl/meta/type_traits.h"
namespace absl {
-
+ABSL_NAMESPACE_BEGIN
namespace nullability_internal {
// `IsNullabilityCompatible` checks whether its first argument is a class
@@ -101,6 +102,7 @@ using NullabilityUnknownImpl
= T;
} // namespace nullability_internal
+ABSL_NAMESPACE_END
} // namespace absl
#endif // ABSL_BASE_INTERNAL_NULLABILITY_IMPL_H_
diff --git a/absl/base/internal/poison.cc b/absl/base/internal/poison.cc
new file mode 100644
index 00000000..b33d4c2d
--- /dev/null
+++ b/absl/base/internal/poison.cc
@@ -0,0 +1,84 @@
+// Copyright 2024 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.
+
+#include "absl/base/internal/poison.h"
+
+#include <cstdlib>
+
+#include "absl/base/config.h"
+#include "absl/base/internal/direct_mmap.h"
+
+#ifndef _WIN32
+#include <unistd.h>
+#endif
+
+#if defined(ABSL_HAVE_ADDRESS_SANITIZER)
+#include <sanitizer/asan_interface.h>
+#elif defined(ABSL_HAVE_MEMORY_SANITIZER)
+#include <sanitizer/msan_interface.h>
+#elif defined(ABSL_HAVE_MMAP)
+#include <sys/mman.h>
+#endif
+
+#if defined(_WIN32)
+#include <windows.h>
+#endif
+
+namespace absl {
+ABSL_NAMESPACE_BEGIN
+namespace base_internal {
+
+namespace {
+
+size_t GetPageSize() {
+#ifdef _WIN32
+ SYSTEM_INFO system_info;
+ GetSystemInfo(&system_info);
+ return system_info.dwPageSize;
+#elif defined(__wasm__) || defined(__asmjs__) || defined(__hexagon__)
+ return getpagesize();
+#else
+ return static_cast<size_t>(sysconf(_SC_PAGESIZE));
+#endif
+}
+
+} // namespace
+
+void* InitializePoisonedPointerInternal() {
+ const size_t block_size = GetPageSize();
+#if defined(ABSL_HAVE_ADDRESS_SANITIZER)
+ void* data = malloc(block_size);
+ ASAN_POISON_MEMORY_REGION(data, block_size);
+#elif defined(ABSL_HAVE_MEMORY_SANITIZER)
+ void* data = malloc(block_size);
+ __msan_poison(data, block_size);
+#elif defined(ABSL_HAVE_MMAP)
+ void* data = DirectMmap(nullptr, block_size, PROT_NONE,
+ MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+ if (data == MAP_FAILED) return GetBadPointerInternal();
+#elif defined(_WIN32)
+ void* data = VirtualAlloc(nullptr, block_size, MEM_RESERVE | MEM_COMMIT,
+ PAGE_NOACCESS);
+ if (data == nullptr) return GetBadPointerInternal();
+#else
+ return GetBadPointerInternal();
+#endif
+ // Return the middle of the block so that dereferences before and after the
+ // pointer will both crash.
+ return static_cast<char*>(data) + block_size / 2;
+}
+
+} // namespace base_internal
+ABSL_NAMESPACE_END
+} // namespace absl
diff --git a/absl/base/internal/poison.h b/absl/base/internal/poison.h
new file mode 100644
index 00000000..28113bdd
--- /dev/null
+++ b/absl/base/internal/poison.h
@@ -0,0 +1,59 @@
+// Copyright 2024 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_BASE_INTERNAL_POISON_H_
+#define ABSL_BASE_INTERNAL_POISON_H_
+
+#include <cstdint>
+
+#include "absl/base/config.h"
+
+namespace absl {
+ABSL_NAMESPACE_BEGIN
+namespace base_internal {
+
+inline void* GetBadPointerInternal() {
+ // A likely bad pointer. Pointers are required to have high bits that are all
+ // zero or all one for certain 64-bit CPUs. This pointer value will hopefully
+ // cause a crash on dereference and also be clearly recognizable as invalid.
+ constexpr uint64_t kBadPtr = 0xBAD0BAD0BAD0BAD0;
+ auto ret = reinterpret_cast<void*>(static_cast<uintptr_t>(kBadPtr));
+#ifndef _MSC_VER // MSVC doesn't support inline asm with `volatile`.
+ // Try to prevent the compiler from optimizing out the undefined behavior.
+ asm volatile("" : : "r"(ret) :); // NOLINT
+#endif
+ return ret;
+}
+
+void* InitializePoisonedPointerInternal();
+
+inline void* get_poisoned_pointer() {
+#if defined(NDEBUG) && !defined(ABSL_HAVE_ADDRESS_SANITIZER) && \
+ !defined(ABSL_HAVE_MEMORY_SANITIZER)
+ // In optimized non-sanitized builds, avoid the function-local static because
+ // of the codegen and runtime cost.
+ return GetBadPointerInternal();
+#else
+ // Non-optimized builds may use more robust implementation. Note that we can't
+ // use a static global because Chromium doesn't allow non-constinit globals.
+ static void* ptr = InitializePoisonedPointerInternal();
+ return ptr;
+#endif
+}
+
+} // namespace base_internal
+ABSL_NAMESPACE_END
+} // namespace absl
+
+#endif // ABSL_BASE_INTERNAL_POISON_H_
diff --git a/absl/base/internal/poison_test.cc b/absl/base/internal/poison_test.cc
new file mode 100644
index 00000000..6596b454
--- /dev/null
+++ b/absl/base/internal/poison_test.cc
@@ -0,0 +1,41 @@
+// Copyright 2024 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.
+
+#include "absl/base/internal/poison.h"
+
+#include <iostream>
+
+#include "gtest/gtest.h"
+#include "absl/base/config.h"
+
+namespace absl {
+ABSL_NAMESPACE_BEGIN
+namespace base_internal {
+namespace {
+
+TEST(PoisonTest, CrashesOnDereference) {
+#ifdef __ANDROID__
+ GTEST_SKIP() << "On Android, poisoned pointer dereference times out instead "
+ "of crashing.";
+#endif
+ int* poisoned_ptr = static_cast<int*>(get_poisoned_pointer());
+ EXPECT_DEATH_IF_SUPPORTED(std::cout << *poisoned_ptr, "");
+ EXPECT_DEATH_IF_SUPPORTED(std::cout << *(poisoned_ptr - 10), "");
+ EXPECT_DEATH_IF_SUPPORTED(std::cout << *(poisoned_ptr + 10), "");
+}
+
+} // namespace
+} // namespace base_internal
+ABSL_NAMESPACE_END
+} // namespace absl
diff --git a/absl/base/internal/spinlock.h b/absl/base/internal/spinlock.h
index 2929cd6f..1bb260f4 100644
--- a/absl/base/internal/spinlock.h
+++ b/absl/base/internal/spinlock.h
@@ -53,7 +53,7 @@ namespace absl {
ABSL_NAMESPACE_BEGIN
namespace base_internal {
-class ABSL_LOCKABLE SpinLock {
+class ABSL_LOCKABLE ABSL_ATTRIBUTE_WARN_UNUSED SpinLock {
public:
SpinLock() : lockword_(kSpinLockCooperative) {
ABSL_TSAN_MUTEX_CREATE(this, __tsan_mutex_not_static);
@@ -89,7 +89,8 @@ class ABSL_LOCKABLE SpinLock {
// acquisition was successful. If the lock was not acquired, false is
// returned. If this SpinLock is free at the time of the call, TryLock
// will return true with high probability.
- inline bool TryLock() ABSL_EXCLUSIVE_TRYLOCK_FUNCTION(true) {
+ ABSL_MUST_USE_RESULT inline bool TryLock()
+ ABSL_EXCLUSIVE_TRYLOCK_FUNCTION(true) {
ABSL_TSAN_MUTEX_PRE_LOCK(this, __tsan_mutex_try_lock);
bool res = TryLockImpl();
ABSL_TSAN_MUTEX_POST_LOCK(
@@ -120,7 +121,7 @@ class ABSL_LOCKABLE SpinLock {
// Determine if the lock is held. When the lock is held by the invoking
// thread, true will always be returned. Intended to be used as
// CHECK(lock.IsHeld()).
- inline bool IsHeld() const {
+ ABSL_MUST_USE_RESULT inline bool IsHeld() const {
return (lockword_.load(std::memory_order_relaxed) & kSpinLockHeld) != 0;
}
@@ -202,6 +203,15 @@ class ABSL_LOCKABLE SpinLock {
// Corresponding locker object that arranges to acquire a spinlock for
// the duration of a C++ scope.
+//
+// TODO(b/176172494): Use only [[nodiscard]] when baseline is raised.
+// TODO(b/6695610): Remove forward declaration when #ifdef is no longer needed.
+#if ABSL_HAVE_CPP_ATTRIBUTE(nodiscard)
+class [[nodiscard]] SpinLockHolder;
+#else
+class ABSL_MUST_USE_RESULT ABSL_ATTRIBUTE_TRIVIAL_ABI SpinLockHolder;
+#endif
+
class ABSL_SCOPED_LOCKABLE SpinLockHolder {
public:
inline explicit SpinLockHolder(SpinLock* l) ABSL_EXCLUSIVE_LOCK_FUNCTION(l)
diff --git a/absl/base/internal/unscaledcycleclock.cc b/absl/base/internal/unscaledcycleclock.cc
index 05e0e7ba..a0bf3a65 100644
--- a/absl/base/internal/unscaledcycleclock.cc
+++ b/absl/base/internal/unscaledcycleclock.cc
@@ -121,18 +121,6 @@ double UnscaledCycleClock::Frequency() {
return aarch64_timer_frequency;
}
-#elif defined(__riscv)
-
-int64_t UnscaledCycleClock::Now() {
- int64_t virtual_timer_value;
- asm volatile("rdcycle %0" : "=r"(virtual_timer_value));
- return virtual_timer_value;
-}
-
-double UnscaledCycleClock::Frequency() {
- return base_internal::NominalCPUFrequency();
-}
-
#elif defined(_M_IX86) || defined(_M_X64)
#pragma intrinsic(__rdtsc)
diff --git a/absl/base/internal/unscaledcycleclock_config.h b/absl/base/internal/unscaledcycleclock_config.h
index 24b324ac..43a3dabe 100644
--- a/absl/base/internal/unscaledcycleclock_config.h
+++ b/absl/base/internal/unscaledcycleclock_config.h
@@ -21,8 +21,8 @@
// The following platforms have an implementation of a hardware counter.
#if defined(__i386__) || defined(__x86_64__) || defined(__aarch64__) || \
- defined(__powerpc__) || defined(__ppc__) || defined(__riscv) || \
- defined(_M_IX86) || (defined(_M_X64) && !defined(_M_ARM64EC))
+ defined(__powerpc__) || defined(__ppc__) || defined(_M_IX86) || \
+ (defined(_M_X64) && !defined(_M_ARM64EC))
#define ABSL_HAVE_UNSCALED_CYCLECLOCK_IMPLEMENTATION 1
#else
#define ABSL_HAVE_UNSCALED_CYCLECLOCK_IMPLEMENTATION 0
@@ -53,8 +53,8 @@
#if ABSL_USE_UNSCALED_CYCLECLOCK
// This macro can be used to test if UnscaledCycleClock::Frequency()
// is NominalCPUFrequency() on a particular platform.
-#if (defined(__i386__) || defined(__x86_64__) || defined(__riscv) || \
- defined(_M_IX86) || defined(_M_X64))
+#if (defined(__i386__) || defined(__x86_64__) || defined(_M_IX86) || \
+ defined(_M_X64))
#define ABSL_INTERNAL_UNSCALED_CYCLECLOCK_FREQUENCY_IS_CPU_FREQUENCY
#endif
#endif
diff --git a/absl/base/macros.h b/absl/base/macros.h
index f33cd192..b318f116 100644
--- a/absl/base/macros.h
+++ b/absl/base/macros.h
@@ -138,4 +138,52 @@ ABSL_NAMESPACE_END
#define ABSL_INTERNAL_RETHROW do {} while (false)
#endif // ABSL_HAVE_EXCEPTIONS
+// ABSL_DEPRECATE_AND_INLINE()
+//
+// Marks a function or type alias as deprecated and tags it to be picked up for
+// automated refactoring by go/cpp-inliner. It can added to inline function
+// definitions or type aliases. It should only be used within a header file. It
+// differs from `ABSL_DEPRECATED` in the following ways:
+//
+// 1. New uses of the function or type will be discouraged via Tricorder
+// warnings.
+// 2. If enabled via `METADATA`, automated changes will be sent out inlining the
+// functions's body or replacing the type where it is used.
+//
+// For example:
+//
+// ABSL_DEPRECATE_AND_INLINE() inline int OldFunc(int x) {
+// return NewFunc(x, 0);
+// }
+//
+// will mark `OldFunc` as deprecated, and the go/cpp-inliner service will
+// replace calls to `OldFunc(x)` with calls to `NewFunc(x, 0)`. Once all calls
+// to `OldFunc` have been replaced, `OldFunc` can be deleted.
+//
+// See go/cpp-inliner for more information.
+//
+// Note: go/cpp-inliner is Google-internal service for automated refactoring.
+// While open-source users do not have access to this service, the macro is
+// provided for compatibility, and so that users receive deprecation warnings.
+#if ABSL_HAVE_CPP_ATTRIBUTE(deprecated) && \
+ ABSL_HAVE_CPP_ATTRIBUTE(clang::annotate)
+#define ABSL_DEPRECATE_AND_INLINE() [[deprecated, clang::annotate("inline-me")]]
+#elif ABSL_HAVE_CPP_ATTRIBUTE(deprecated)
+#define ABSL_DEPRECATE_AND_INLINE() [[deprecated]]
+#else
+#define ABSL_DEPRECATE_AND_INLINE()
+#endif
+
+// Requires the compiler to prove that the size of the given object is at least
+// the expected amount.
+#if ABSL_HAVE_ATTRIBUTE(diagnose_if) && ABSL_HAVE_BUILTIN(__builtin_object_size)
+#define ABSL_INTERNAL_NEED_MIN_SIZE(Obj, N) \
+ __attribute__((diagnose_if(__builtin_object_size(Obj, 0) < N, \
+ "object size provably too small " \
+ "(this would corrupt memory)", \
+ "error")))
+#else
+#define ABSL_INTERNAL_NEED_MIN_SIZE(Obj, N)
+#endif
+
#endif // ABSL_BASE_MACROS_H_
diff --git a/absl/base/no_destructor.h b/absl/base/no_destructor.h
index d4b16a6e..43b3540a 100644
--- a/absl/base/no_destructor.h
+++ b/absl/base/no_destructor.h
@@ -21,14 +21,13 @@
// such an object survives during program exit (and can be safely accessed at
// any time).
//
-// Objects of such type, if constructed safely and under the right conditions,
-// provide two main benefits over other alternatives:
-//
-// * Global objects not normally allowed due to concerns of destruction order
-// (i.e. no "complex globals") can be safely allowed, provided that such
-// objects can be constant initialized.
-// * Function scope static objects can be optimized to avoid heap allocation,
-// pointer chasing, and allow lazy construction.
+// absl::NoDestructor<T> is useful when when a variable has static storage
+// duration but its type has a non-trivial destructor. Global constructors are
+// not recommended because of the C++'s static initialization order fiasco (See
+// https://en.cppreference.com/w/cpp/language/siof). Global destructors are not
+// allowed due to similar concerns about destruction ordering. Using
+// absl::NoDestructor<T> as a function-local static prevents both of these
+// issues.
//
// See below for complete details.
@@ -41,6 +40,7 @@
#include <utility>
#include "absl/base/config.h"
+#include "absl/base/nullability.h"
namespace absl {
ABSL_NAMESPACE_BEGIN
@@ -49,8 +49,8 @@ ABSL_NAMESPACE_BEGIN
//
// NoDestructor<T> is a wrapper around an object of type T that behaves as an
// object of type T but never calls T's destructor. NoDestructor<T> makes it
-// safer and/or more efficient to use such objects in static storage contexts:
-// as global or function scope static variables.
+// safer and/or more efficient to use such objects in static storage contexts,
+// ideally as function scope static variables.
//
// An instance of absl::NoDestructor<T> has similar type semantics to an
// instance of T:
@@ -61,9 +61,6 @@ ABSL_NAMESPACE_BEGIN
// `->`, `*`, and `get()`.
// (Note that `const NoDestructor<T>` works like a pointer to const `T`.)
//
-// An object of type NoDestructor<T> should be defined in static storage:
-// as either a global static object, or as a function scope static variable.
-//
// Additionally, NoDestructor<T> provides the following benefits:
//
// * Never calls T's destructor for the object
@@ -71,24 +68,7 @@ ABSL_NAMESPACE_BEGIN
// lazily constructed.
//
// An object of type NoDestructor<T> is "trivially destructible" in the notion
-// that its destructor is never run. Provided that an object of this type can be
-// safely initialized and does not need to be cleaned up on program shutdown,
-// NoDestructor<T> allows you to define global static variables, since Google's
-// C++ style guide ban on such objects doesn't apply to objects that are
-// trivially destructible.
-//
-// Usage as Global Static Variables
-//
-// NoDestructor<T> allows declaration of a global object with a non-trivial
-// constructor in static storage without needing to add a destructor.
-// However, such objects still need to worry about initialization order, so
-// such objects should be const initialized:
-//
-// // Global or namespace scope.
-// ABSL_CONST_INIT absl::NoDestructor<MyRegistry> reg{"foo", "bar", 8008};
-//
-// Note that if your object already has a trivial destructor, you don't need to
-// use NoDestructor<T>.
+// that its destructor is never run.
//
// Usage as Function Scope Static Variables
//
@@ -114,6 +94,21 @@ ABSL_NAMESPACE_BEGIN
// return *x;
// }
//
+// Usage as Global Static Variables
+//
+// NoDestructor<T> allows declaration of a global object of type T that has a
+// non-trivial destructor since its destructor is never run. However, such
+// objects still need to worry about initialization order, so such use is not
+// recommended, strongly discouraged by the Google C++ Style Guide, and outright
+// banned in Chromium.
+// See https://google.github.io/styleguide/cppguide.html#Static_and_Global_Variables
+//
+// // Global or namespace scope.
+// absl::NoDestructor<MyRegistry> reg{"foo", "bar", 8008};
+//
+// Note that if your object already has a trivial destructor, you don't need to
+// use NoDestructor<T>.
+//
template <typename T>
class NoDestructor {
public:
@@ -140,11 +135,11 @@ class NoDestructor {
// Pretend to be a smart pointer to T with deep constness.
// Never returns a null pointer.
T& operator*() { return *get(); }
- T* operator->() { return get(); }
- T* get() { return impl_.get(); }
+ absl::Nonnull<T*> operator->() { return get(); }
+ absl::Nonnull<T*> get() { return impl_.get(); }
const T& operator*() const { return *get(); }
- const T* operator->() const { return get(); }
- const T* get() const { return impl_.get(); }
+ absl::Nonnull<const T*> operator->() const { return get(); }
+ absl::Nonnull<const T*> get() const { return impl_.get(); }
private:
class DirectImpl {
@@ -152,8 +147,8 @@ class NoDestructor {
template <typename... Args>
explicit constexpr DirectImpl(Args&&... args)
: value_(std::forward<Args>(args)...) {}
- const T* get() const { return &value_; }
- T* get() { return &value_; }
+ absl::Nonnull<const T*> get() const { return &value_; }
+ absl::Nonnull<T*> get() { return &value_; }
private:
T value_;
@@ -165,14 +160,14 @@ class NoDestructor {
explicit PlacementImpl(Args&&... args) {
new (&space_) T(std::forward<Args>(args)...);
}
- const T* get() const {
+ absl::Nonnull<const T*> get() const {
return Launder(reinterpret_cast<const T*>(&space_));
}
- T* get() { return Launder(reinterpret_cast<T*>(&space_)); }
+ absl::Nonnull<T*> get() { return Launder(reinterpret_cast<T*>(&space_)); }
private:
template <typename P>
- static P* Launder(P* p) {
+ static absl::Nonnull<P*> Launder(absl::Nonnull<P*> p) {
#if defined(__cpp_lib_launder) && __cpp_lib_launder >= 201606L
return std::launder(p);
#elif ABSL_HAVE_BUILTIN(__builtin_launder)
diff --git a/absl/base/nullability.h b/absl/base/nullability.h
index 6f49b6f5..34dc083a 100644
--- a/absl/base/nullability.h
+++ b/absl/base/nullability.h
@@ -128,9 +128,17 @@
//
// By default, nullability annotations are applicable to raw and smart
// pointers. User-defined types can indicate compatibility with nullability
-// annotations by providing an `absl_nullability_compatible` nested type. The
-// actual definition of this inner type is not relevant as it is used merely as
-// a marker. It is common to use a using declaration of
+// annotations by adding the ABSL_NULLABILITY_COMPATIBLE attribute.
+//
+// // Example:
+// struct ABSL_NULLABILITY_COMPATIBLE MyPtr {
+// ...
+// };
+//
+// Note: For the time being, nullability-compatible classes should additionally
+// be marked with an `absl_nullability_compatible` nested type (this will soon
+// be deprecated). The actual definition of this inner type is not relevant as
+// it is used merely as a marker. It is common to use a using declaration of
// `absl_nullability_compatible` set to void.
//
// // Example:
@@ -150,14 +158,16 @@
#ifndef ABSL_BASE_NULLABILITY_H_
#define ABSL_BASE_NULLABILITY_H_
+#include "absl/base/config.h"
#include "absl/base/internal/nullability_impl.h"
namespace absl {
+ABSL_NAMESPACE_BEGIN
// absl::Nonnull
//
// The indicated pointer is never null. It is the responsibility of the provider
-// of this pointer across an API boundary to ensure that the pointer is never be
+// of this pointer across an API boundary to ensure that the pointer is never
// set to null. Consumers of this pointer across an API boundary may safely
// dereference the pointer.
//
@@ -198,9 +208,9 @@ using Nullable = nullability_internal::NullableImpl<T>;
// migrated into one of the above two nullability states: `Nonnull<T>` or
// `Nullable<T>`.
//
-// NOTE: Because this annotation is the global default state, pointers without
-// any annotation are assumed to have "unknown" semantics. This assumption is
-// designed to minimize churn and reduce clutter within the codebase.
+// NOTE: Because this annotation is the global default state, unannotated
+// pointers are assumed to have "unknown" semantics. This assumption is designed
+// to minimize churn and reduce clutter within the codebase.
//
// Example:
//
@@ -219,6 +229,22 @@ using Nullable = nullability_internal::NullableImpl<T>;
template <typename T>
using NullabilityUnknown = nullability_internal::NullabilityUnknownImpl<T>;
+ABSL_NAMESPACE_END
} // namespace absl
+// ABSL_NULLABILITY_COMPATIBLE
+//
+// Indicates that a class is compatible with nullability annotations.
+//
+// For example:
+//
+// struct ABSL_NULLABILITY_COMPATIBLE MyPtr {
+// ...
+// };
+#if ABSL_HAVE_FEATURE(nullability_on_classes)
+#define ABSL_NULLABILITY_COMPATIBLE _Nullable
+#else
+#define ABSL_NULLABILITY_COMPATIBLE
+#endif
+
#endif // ABSL_BASE_NULLABILITY_H_
diff --git a/absl/base/optimization.h b/absl/base/optimization.h
index f9859958..3aa66e1c 100644
--- a/absl/base/optimization.h
+++ b/absl/base/optimization.h
@@ -18,12 +18,23 @@
// -----------------------------------------------------------------------------
//
// This header file defines portable macros for performance optimization.
+//
+// This header is included in both C++ code and legacy C code and thus must
+// remain compatible with both C and C++. C compatibility will be removed if
+// the legacy code is removed or converted to C++. Do not include this header in
+// new code that requires C compatibility or assume C compatibility will remain
+// indefinitely.
#ifndef ABSL_BASE_OPTIMIZATION_H_
#define ABSL_BASE_OPTIMIZATION_H_
#include <assert.h>
+#ifdef __cplusplus
+// Included for std::unreachable()
+#include <utility>
+#endif // __cplusplus
+
#include "absl/base/config.h"
#include "absl/base/options.h"
diff --git a/absl/base/options.h b/absl/base/options.h
index d7bf8cff..61a996b6 100644
--- a/absl/base/options.h
+++ b/absl/base/options.h
@@ -226,7 +226,7 @@
// allowed.
#define ABSL_OPTION_USE_INLINE_NAMESPACE 1
-#define ABSL_OPTION_INLINE_NAMESPACE_NAME lts_20240116
+#define ABSL_OPTION_INLINE_NAMESPACE_NAME lts_20240722
// ABSL_OPTION_HARDENED
//
diff --git a/absl/base/prefetch.h b/absl/base/prefetch.h
index eb40a445..482cde3a 100644
--- a/absl/base/prefetch.h
+++ b/absl/base/prefetch.h
@@ -129,7 +129,7 @@ void PrefetchToLocalCacheNta(const void* addr);
//
// void* Arena::Allocate(size_t size) {
// void* ptr = AllocateBlock(size);
-// absl::PrefetchToLocalCacheForWrite(p);
+// absl::PrefetchToLocalCacheForWrite(ptr);
// return ptr;
// }
//