about summary refs log tree commit diff
path: root/absl/base
diff options
context:
space:
mode:
Diffstat (limited to 'absl/base')
-rw-r--r--absl/base/BUILD.bazel7
-rw-r--r--absl/base/CMakeLists.txt2
-rw-r--r--absl/base/casts.h51
-rw-r--r--absl/base/internal/direct_mmap.h12
-rw-r--r--absl/base/internal/endian_test.cc20
-rw-r--r--absl/base/internal/identity.h4
-rw-r--r--absl/base/internal/raw_logging.cc18
-rw-r--r--absl/base/internal/raw_logging.h43
-rw-r--r--absl/base/internal/spinlock_wait.h2
-rw-r--r--absl/base/macros.h5
-rw-r--r--absl/base/raw_logging_test.cc29
-rw-r--r--absl/base/thread_annotations.h1
12 files changed, 157 insertions, 37 deletions
diff --git a/absl/base/BUILD.bazel b/absl/base/BUILD.bazel
index 1e93d97ebd40..06d092ebdfa8 100644
--- a/absl/base/BUILD.bazel
+++ b/absl/base/BUILD.bazel
@@ -362,6 +362,7 @@ cc_test(
     copts = ABSL_TEST_COPTS,
     deps = [
         ":base",
+        "//absl/strings",
         "@com_google_googletest//:gtest_main",
     ],
 )
@@ -371,11 +372,6 @@ cc_test(
     size = "small",
     srcs = ["internal/sysinfo_test.cc"],
     copts = ABSL_TEST_COPTS,
-    tags = [
-        "no_test_android_arm",
-        "no_test_android_arm64",
-        "no_test_android_x86",
-    ],
     deps = [
         ":base",
         "//absl/synchronization",
@@ -392,6 +388,7 @@ cc_test(
         "//absl:windows": [],
         "//conditions:default": ["-pthread"],
     }),
+    tags = ["no_test_ios_x86_64"],
     deps = [":malloc_internal"],
 )
 
diff --git a/absl/base/CMakeLists.txt b/absl/base/CMakeLists.txt
index 303533e26d1b..01d2af085f58 100644
--- a/absl/base/CMakeLists.txt
+++ b/absl/base/CMakeLists.txt
@@ -310,7 +310,7 @@ absl_test(
 
 # test raw_logging_test
 set(RAW_LOGGING_TEST_SRC "raw_logging_test.cc")
-set(RAW_LOGGING_TEST_PUBLIC_LIBRARIES absl::base)
+set(RAW_LOGGING_TEST_PUBLIC_LIBRARIES absl::base absl::strings)
 
 absl_test(
   TARGET
diff --git a/absl/base/casts.h b/absl/base/casts.h
index 8bd5264d9780..20fd34da7010 100644
--- a/absl/base/casts.h
+++ b/absl/base/casts.h
@@ -25,12 +25,36 @@
 #define ABSL_BASE_CASTS_H_
 
 #include <cstring>
+#include <memory>
 #include <type_traits>
 
 #include "absl/base/internal/identity.h"
+#include "absl/base/macros.h"
 
 namespace absl {
 
+namespace internal_casts {
+
+// NOTE: Not a fully compliant implementation of `std::is_trivially_copyable`.
+// TODO(calabrese) Branch on implementations that directly provide
+// `std::is_trivially_copyable`, create a more rigorous workaround, and publicly
+// expose in meta/type_traits.
+template <class T>
+struct is_trivially_copyable
+    : std::integral_constant<
+          bool, std::is_destructible<T>::value&& __has_trivial_destructor(T) &&
+                    __has_trivial_copy(T) && __has_trivial_assign(T)> {};
+
+template <class Dest, class Source>
+struct is_bitcastable
+    : std::integral_constant<bool,
+                             sizeof(Dest) == sizeof(Source) &&
+                                 is_trivially_copyable<Source>::value &&
+                                 is_trivially_copyable<Dest>::value &&
+                                 std::is_default_constructible<Dest>::value> {};
+
+}  // namespace internal_casts
+
 // implicit_cast()
 //
 // Performs an implicit conversion between types following the language
@@ -125,7 +149,32 @@ inline To implicit_cast(typename absl::internal::identity_t<To> to) {
 // and reading its bits back using a different type. A `bit_cast()` avoids this
 // issue by implementing its casts using `memcpy()`, which avoids introducing
 // this undefined behavior.
-template <typename Dest, typename Source>
+//
+// NOTE: The requirements here are more strict than the bit_cast of standard
+// proposal p0476 due to the need for workarounds and lack of intrinsics.
+// Specifically, this implementation also requires `Dest` to be
+// default-constructible.
+template <
+    typename Dest, typename Source,
+    typename std::enable_if<internal_casts::is_bitcastable<Dest, Source>::value,
+                            int>::type = 0>
+inline Dest bit_cast(const Source& source) {
+  Dest dest;
+  memcpy(static_cast<void*>(std::addressof(dest)),
+         static_cast<const void*>(std::addressof(source)), sizeof(dest));
+  return dest;
+}
+
+// NOTE: This overload is only picked if the requirements of bit_cast are not
+// met. It is therefore UB, but is provided temporarily as previous versions of
+// this function template were unchecked. Do not use this in new code.
+template <
+    typename Dest, typename Source,
+    typename std::enable_if<
+        !internal_casts::is_bitcastable<Dest, Source>::value, int>::type = 0>
+ABSL_DEPRECATED(
+    "absl::bit_cast type requirements were violated. Update the types being "
+    "used such that they are the same size and are both TriviallyCopyable.")
 inline Dest bit_cast(const Source& source) {
   static_assert(sizeof(Dest) == sizeof(Source),
                 "Source and destination types should have equal sizes.");
diff --git a/absl/base/internal/direct_mmap.h b/absl/base/internal/direct_mmap.h
index 2fe345fc85aa..0426e11890b6 100644
--- a/absl/base/internal/direct_mmap.h
+++ b/absl/base/internal/direct_mmap.h
@@ -92,11 +92,13 @@ inline void* DirectMmap(void* start, size_t length, int prot, int flags, int fd,
 #endif
 #elif defined(__s390x__)
   // On s390x, mmap() arguments are passed in memory.
-  uint32_t buf[6] = {
-      reinterpret_cast<uint32_t>(start), static_cast<uint32_t>(length),
-      static_cast<uint32_t>(prot),       static_cast<uint32_t>(flags),
-      static_cast<uint32_t>(fd),         static_cast<uint32_t>(offset)};
-  return reintrepret_cast<void*>(syscall(SYS_mmap, buf));
+  unsigned long buf[6] = {reinterpret_cast<unsigned long>(start),  // NOLINT
+                          static_cast<unsigned long>(length),      // NOLINT
+                          static_cast<unsigned long>(prot),        // NOLINT
+                          static_cast<unsigned long>(flags),       // NOLINT
+                          static_cast<unsigned long>(fd),          // NOLINT
+                          static_cast<unsigned long>(offset)};     // NOLINT
+  return reinterpret_cast<void*>(syscall(SYS_mmap, buf));
 #elif defined(__x86_64__)
 // The x32 ABI has 32 bit longs, but the syscall interface is 64 bit.
 // We need to explicitly cast to an unsigned 64 bit type to avoid implicit
diff --git a/absl/base/internal/endian_test.cc b/absl/base/internal/endian_test.cc
index f3ff4b39bb65..e27691553bc6 100644
--- a/absl/base/internal/endian_test.cc
+++ b/absl/base/internal/endian_test.cc
@@ -33,32 +33,16 @@ const uint16_t k16Value{0x0123};
 const int kNumValuesToTest = 1000000;
 const int kRandomSeed = 12345;
 
-#ifdef ABSL_IS_BIG_ENDIAN
+#if defined(ABSL_IS_BIG_ENDIAN)
 const uint64_t kInitialInNetworkOrder{kInitialNumber};
 const uint64_t k64ValueLE{0xefcdab8967452301};
 const uint32_t k32ValueLE{0x67452301};
 const uint16_t k16ValueLE{0x2301};
-const uint8_t k8ValueLE{k8Value};
-const uint64_t k64IValueLE{0xefcdab89674523a1};
-const uint32_t k32IValueLE{0x67452391};
-const uint16_t k16IValueLE{0x85ff};
-const uint8_t k8IValueLE{0xff};
-const uint64_t kDoubleValueLE{0x6e861bf0f9210940};
-const uint32_t kFloatValueLE{0xd00f4940};
-const uint8_t kBoolValueLE{0x1};
 
 const uint64_t k64ValueBE{kInitialNumber};
 const uint32_t k32ValueBE{k32Value};
 const uint16_t k16ValueBE{k16Value};
-const uint8_t k8ValueBE{k8Value};
-const uint64_t k64IValueBE{0xa123456789abcdef};
-const uint32_t k32IValueBE{0x91234567};
-const uint16_t k16IValueBE{0xff85};
-const uint8_t k8IValueBE{0xff};
-const uint64_t kDoubleValueBE{0x400921f9f01b866e};
-const uint32_t kFloatValueBE{0x40490fd0};
-const uint8_t kBoolValueBE{0x1};
-#elif defined ABSL_IS_LITTLE_ENDIAN
+#elif defined(ABSL_IS_LITTLE_ENDIAN)
 const uint64_t kInitialInNetworkOrder{0xefcdab8967452301};
 const uint64_t k64ValueLE{kInitialNumber};
 const uint32_t k32ValueLE{k32Value};
diff --git a/absl/base/internal/identity.h b/absl/base/internal/identity.h
index a6734b4d3537..a1a5d70a84dd 100644
--- a/absl/base/internal/identity.h
+++ b/absl/base/internal/identity.h
@@ -27,7 +27,7 @@ struct identity {
 template <typename T>
 using identity_t = typename identity<T>::type;
 
-}  //  namespace internal
-}  //  namespace absl
+}  // namespace internal
+}  // namespace absl
 
 #endif  // ABSL_BASE_INTERNAL_IDENTITY_H_
diff --git a/absl/base/internal/raw_logging.cc b/absl/base/internal/raw_logging.cc
index 1ce138887252..d9485a66cc64 100644
--- a/absl/base/internal/raw_logging.cc
+++ b/absl/base/internal/raw_logging.cc
@@ -139,7 +139,7 @@ void RawLogVA(absl::LogSeverity severity, const char* file, int line,
 #endif
 
 #ifdef ABSL_MIN_LOG_LEVEL
-  if (static_cast<int>(severity) < ABSL_MIN_LOG_LEVEL &&
+  if (severity < static_cast<absl::LogSeverity>(ABSL_MIN_LOG_LEVEL) &&
       severity < absl::LogSeverity::kFatal) {
     enabled = false;
   }
@@ -206,6 +206,15 @@ void RawLog(absl::LogSeverity severity, const char* file, int line,
   va_end(ap);
 }
 
+// Non-formatting version of RawLog().
+//
+// TODO(gfalcon): When string_view no longer depends on base, change this
+// interface to take its message as a string_view instead.
+static void DefaultInternalLog(absl::LogSeverity severity, const char* file,
+                               int line, const std::string& message) {
+  RawLog(severity, file, line, "%s", message.c_str());
+}
+
 bool RawLoggingFullySupported() {
 #ifdef ABSL_LOW_LEVEL_WRITE_SUPPORTED
   return true;
@@ -214,5 +223,12 @@ bool RawLoggingFullySupported() {
 #endif  // !ABSL_LOW_LEVEL_WRITE_SUPPORTED
 }
 
+ABSL_CONST_INIT absl::base_internal::AtomicHook<InternalLogFunction>
+    internal_log_function(DefaultInternalLog);
+
+void RegisterInternalLogFunction(InternalLogFunction func) {
+  internal_log_function.Store(func);
+}
+
 }  // namespace raw_logging_internal
 }  // namespace absl
diff --git a/absl/base/internal/raw_logging.h b/absl/base/internal/raw_logging.h
index a2b7207a032c..67abfd30798d 100644
--- a/absl/base/internal/raw_logging.h
+++ b/absl/base/internal/raw_logging.h
@@ -19,7 +19,10 @@
 #ifndef ABSL_BASE_INTERNAL_RAW_LOGGING_H_
 #define ABSL_BASE_INTERNAL_RAW_LOGGING_H_
 
+#include <string>
+
 #include "absl/base/attributes.h"
+#include "absl/base/internal/atomic_hook.h"
 #include "absl/base/log_severity.h"
 #include "absl/base/macros.h"
 #include "absl/base/port.h"
@@ -57,6 +60,34 @@
     }                                                                  \
   } while (0)
 
+// ABSL_INTERNAL_LOG and ABSL_INTERNAL_CHECK work like the RAW variants above,
+// except that if the richer log library is linked into the binary, we dispatch
+// to that instead.  This is potentially useful for internal logging and
+// assertions, where we are using RAW_LOG neither for its async-signal-safety
+// nor for its non-allocating nature, but rather because raw logging has very
+// few other dependencies.
+//
+// The API is a subset of the above: each macro only takes two arguments.  Use
+// StrCat if you need to build a richer message.
+#define ABSL_INTERNAL_LOG(severity, message)                          \
+  do {                                                                \
+    constexpr const char* absl_raw_logging_internal_basename =        \
+        ::absl::raw_logging_internal::Basename(__FILE__,              \
+                                               sizeof(__FILE__) - 1); \
+    ::absl::raw_logging_internal::internal_log_function(              \
+        ABSL_RAW_LOGGING_INTERNAL_##severity,                         \
+        absl_raw_logging_internal_basename, __LINE__, message);       \
+  } while (0)
+
+#define ABSL_INTERNAL_CHECK(condition, message)               \
+  do {                                                        \
+    if (ABSL_PREDICT_FALSE(!(condition))) {                   \
+      std::string death_message = "Check " #condition " failed: "; \
+      death_message += std::string(message);                       \
+      ABSL_INTERNAL_LOG(FATAL, death_message);                \
+    }                                                         \
+  } while (0)
+
 #define ABSL_RAW_LOGGING_INTERNAL_INFO ::absl::LogSeverity::kInfo
 #define ABSL_RAW_LOGGING_INTERNAL_WARNING ::absl::LogSeverity::kWarning
 #define ABSL_RAW_LOGGING_INTERNAL_ERROR ::absl::LogSeverity::kError
@@ -131,6 +162,18 @@ using LogPrefixHook = bool (*)(absl::LogSeverity severity, const char* file,
 using AbortHook = void (*)(const char* file, int line, const char* buf_start,
                            const char* prefix_end, const char* buf_end);
 
+// Internal logging function for ABSL_INTERNAL_LOG to dispatch to.
+//
+// TODO(gfalcon): When string_view no longer depends on base, change this
+// interface to take its message as a string_view instead.
+using InternalLogFunction = void (*)(absl::LogSeverity severity,
+                                     const char* file, int line,
+                                     const std::string& message);
+
+extern base_internal::AtomicHook<InternalLogFunction> internal_log_function;
+
+void RegisterInternalLogFunction(InternalLogFunction func);
+
 }  // namespace raw_logging_internal
 }  // namespace absl
 
diff --git a/absl/base/internal/spinlock_wait.h b/absl/base/internal/spinlock_wait.h
index 5f658211cc56..5c6cc7fdba4c 100644
--- a/absl/base/internal/spinlock_wait.h
+++ b/absl/base/internal/spinlock_wait.h
@@ -84,7 +84,7 @@ inline void absl::base_internal::SpinLockWake(std::atomic<uint32_t> *w,
 
 inline void absl::base_internal::SpinLockDelay(
     std::atomic<uint32_t> *w, uint32_t value, int loop,
-    base_internal::SchedulingMode scheduling_mode) {
+    absl::base_internal::SchedulingMode scheduling_mode) {
   AbslInternalSpinLockDelay(w, value, loop, scheduling_mode);
 }
 
diff --git a/absl/base/macros.h b/absl/base/macros.h
index afa30300bc3e..ca3d5edb6536 100644
--- a/absl/base/macros.h
+++ b/absl/base/macros.h
@@ -194,8 +194,9 @@ enum LinkerInitialized {
 #if defined(NDEBUG)
 #define ABSL_ASSERT(expr) (false ? (void)(expr) : (void)0)
 #else
-#define ABSL_ASSERT(expr) \
-  (ABSL_PREDICT_TRUE((expr)) ? (void)0 : [] { assert(false && #expr); }())
+#define ABSL_ASSERT(expr)              \
+  (ABSL_PREDICT_TRUE((expr)) ? (void)0 \
+                             : [] { assert(false && #expr); }())  // NOLINT
 #endif
 
 #endif  // ABSL_BASE_MACROS_H_
diff --git a/absl/base/raw_logging_test.cc b/absl/base/raw_logging_test.cc
index dae4b35138c5..ebbc5db90672 100644
--- a/absl/base/raw_logging_test.cc
+++ b/absl/base/raw_logging_test.cc
@@ -18,12 +18,20 @@
 
 #include "absl/base/internal/raw_logging.h"
 
+#include <tuple>
+
 #include "gtest/gtest.h"
+#include "absl/strings/str_cat.h"
 
 namespace {
 
 TEST(RawLoggingCompilationTest, Log) {
   ABSL_RAW_LOG(INFO, "RAW INFO: %d", 1);
+  ABSL_RAW_LOG(INFO, "RAW INFO: %d %d", 1, 2);
+  ABSL_RAW_LOG(INFO, "RAW INFO: %d %d %d", 1, 2, 3);
+  ABSL_RAW_LOG(INFO, "RAW INFO: %d %d %d %d", 1, 2, 3, 4);
+  ABSL_RAW_LOG(INFO, "RAW INFO: %d %d %d %d %d", 1, 2, 3, 4, 5);
+  ABSL_RAW_LOG(WARNING, "RAW WARNING: %d", 1);
   ABSL_RAW_LOG(ERROR, "RAW ERROR: %d", 1);
 }
 
@@ -47,4 +55,25 @@ TEST(RawLoggingDeathTest, LogFatal) {
                             kExpectedDeathOutput);
 }
 
+TEST(InternalLog, CompilationTest) {
+  ABSL_INTERNAL_LOG(INFO, "Internal Log");
+  std::string log_msg = "Internal Log";
+  ABSL_INTERNAL_LOG(INFO, log_msg);
+
+  ABSL_INTERNAL_LOG(INFO, log_msg + " 2");
+
+  float d = 1.1f;
+  ABSL_INTERNAL_LOG(INFO, absl::StrCat("Internal log ", 3, " + ", d));
+}
+
+TEST(InternalLogDeathTest, FailingCheck) {
+  EXPECT_DEATH_IF_SUPPORTED(ABSL_INTERNAL_CHECK(1 == 0, "explanation"),
+                            kExpectedDeathOutput);
+}
+
+TEST(InternalLogDeathTest, LogFatal) {
+  EXPECT_DEATH_IF_SUPPORTED(ABSL_INTERNAL_LOG(FATAL, "my dog has fleas"),
+                            kExpectedDeathOutput);
+}
+
 }  // namespace
diff --git a/absl/base/thread_annotations.h b/absl/base/thread_annotations.h
index 8d30b9324b52..fbb2797b825f 100644
--- a/absl/base/thread_annotations.h
+++ b/absl/base/thread_annotations.h
@@ -31,7 +31,6 @@
 // that evaluate to a concrete mutex object whenever possible. If the mutex
 // you want to refer to is not in scope, you may use a member pointer
 // (e.g. &MyClass::mutex_) to refer to a mutex in some (unknown) object.
-//
 
 #ifndef ABSL_BASE_THREAD_ANNOTATIONS_H_
 #define ABSL_BASE_THREAD_ANNOTATIONS_H_