about summary refs log tree commit diff
path: root/absl
diff options
context:
space:
mode:
Diffstat (limited to 'absl')
-rw-r--r--absl/FAQ.md144
-rwxr-xr-xabsl/abseil.podspec.gen.py18
-rw-r--r--absl/base/config.h14
-rw-r--r--absl/container/node_hash_set.h4
-rw-r--r--absl/debugging/failure_signal_handler.cc13
-rw-r--r--absl/flags/BUILD.bazel1
-rw-r--r--absl/flags/CMakeLists.txt1
-rw-r--r--absl/flags/internal/flag.cc29
-rw-r--r--absl/flags/internal/flag.h19
9 files changed, 43 insertions, 200 deletions
diff --git a/absl/FAQ.md b/absl/FAQ.md
deleted file mode 100644
index af721307c2..0000000000
--- a/absl/FAQ.md
+++ /dev/null
@@ -1,144 +0,0 @@
-# Abseil FAQ
-
-## Is Abseil the right home for my utility library?
-
-Most often the answer to the question is "no." As both the [About
-Abseil](https://abseil.io/about/) page and our [contributing
-guidelines](https://github.com/abseil/abseil-cpp/blob/master/CONTRIBUTING.md#contribution-guidelines)
-explain, Abseil contains a variety of core C++ library code that is widely used
-at [Google](https://www.google.com/). As such, Abseil's primary purpose is to be
-used as a dependency by Google's open source C++ projects. While we do hope that
-Abseil is also useful to the C++ community at large, this added constraint also
-means that we are unlikely to accept a contribution of utility code that isn't
-already widely used by Google.
-
-## How to I set the C++ dialect used to build Abseil?
-
-The short answer is that whatever mechanism you choose, you need to make sure
-that you set this option consistently at the global level for your entire
-project. If, for example, you want to set the C++ dialect to C++17, with
-[Bazel](https://bazel/build/) as the build system and `gcc` or `clang` as the
-compiler, there several ways to do this:
-* Pass `--cxxopt=-std=c++17` on the command line (for example, `bazel build
-  --cxxopt=-std=c++17 ...`)
-* Set the environment variable `BAZEL_CXXOPTS` (for example,
-  `BAZEL_CXXOPTS=-std=c++17`)
-* Add `build --cxxopt=-std=c++17` to your [`.bazelrc`
-  file](https://docs.bazel.build/versions/master/guide.html#bazelrc)
-
-If you are using CMake as the build system, you'll need to add a line like
-`set(CMAKE_CXX_STANDARD 17)` to your top level `CMakeLists.txt` file. See the
-[CMake build
-instructions](https://github.com/abseil/abseil-cpp/blob/master/CMake/README.md)
-for more information.
-
-For a longer answer to this question and to understand why some other approaches
-don't work, see the answer to "What is ABI and why don't you recommend using a
-pre-compiled version of Abseil?"
-
-## What is ABI and why don't you recommend using a pre-compiled version of Abseil?
-
-For the purposes of this discussion, you can think of
-[ABI](https://en.wikipedia.org/wiki/Application_binary_interface) as the
-compiled representation of the interfaces in code. This is in contrast to
-[API](https://en.wikipedia.org/wiki/Application_programming_interface), which
-you can think of as the interfaces as defined by the code itself. [Abseil has a
-strong promise of API compatibility, but does not make any promise of ABI
-compatibility](https://abseil.io/about/compatibility). Let's take a look at what
-this means in practice.
-
-You might be tempted to do something like this in a
-[Bazel](https://bazel.build/) `BUILD` file:
-
-```
-# DON'T DO THIS!!!
-cc_library(
-    name = "my_library",
-    srcs = ["my_library.cc"],
-    copts = ["-std=c++17"],  # May create a mixed-mode compile!
-    deps = ["@com_google_absl//absl/strings"],
-)
-```
-
-Applying `-std=c++17` to an individual target in your `BUILD` file is going to
-compile that specific target in C++17 mode, but it isn't going to ensure the
-Abseil library is built in C++17 mode, since the Abseil library itself is a
-different build target. If your code includes an Abseil header, then your
-program may contain conflicting definitions of the same
-class/function/variable/enum, etc. As a rule, all compile options that affect
-the ABI of a program need to be applied to the entire build on a global basis.
-
-C++ has something called the [One Definition
-Rule](https://en.wikipedia.org/wiki/One_Definition_Rule) (ODR). C++ doesn't
-allow multiple definitions of the same class/function/variable/enum, etc. ODR
-violations sometimes result in linker errors, but linkers do not always catch
-violations. Uncaught ODR violations can result in strange runtime behaviors or
-crashes that can be hard to debug.
-
-If you build the Abseil library and your code using different compile options
-that affect ABI, there is a good chance you will run afoul of the One Definition
-Rule. Examples of GCC compile options that affect ABI include (but aren't
-limited to) language dialect (e.g. `-std=`), optimization level (e.g. `-O2`),
-code generation flags (e.g. `-fexceptions`), and preprocessor defines
-(e.g. `-DNDEBUG`).
-
-If you use a pre-compiled version of Abseil, (for example, from your Linux
-distribution package manager or from something like
-[vcpkg](https://github.com/microsoft/vcpkg)) you have to be very careful to
-ensure ABI compatibility across the components of your program. The only way you
-can be sure your program is going to be correct regarding ABI is to ensure
-you've used the exact same compile options as were used to build the
-pre-compiled library. This does not mean that Abseil cannot work as part of a
-Linux distribution since a knowledgeable binary packager will have ensured that
-all packages have been built with consistent compile options. This is one of the
-reasons we warn against - though do not outright reject - using Abseil as a
-pre-compiled library.
-
-Another possible way that you might afoul of ABI issues is if you accidentally
-include two versions of Abseil in your program. Multiple versions of Abseil can
-end up within the same binary if your program uses the Abseil library and
-another library also transitively depends on Abseil (resulting in what is
-sometimes called the diamond dependency problem). In cases such as this you must
-structure your build so that all libraries use the same version of Abseil.
-[Abseil's strong promise of API compatibility between
-releases](https://abseil.io/about/compatibility) means the latest "HEAD" release
-of Abseil is almost certainly the right choice if you are doing as we recommend
-and building all of your code from source.
-
-For these reasons we recommend you avoid pre-compiled code and build the Abseil
-library yourself in a consistent manner with the rest of your code.
-
-## What is "live at head" and how do I do it?
-
-From Abseil's point-of-view, "live at head" means that every Abseil source
-release (which happens on an almost daily basis) is either API compatible with
-the previous release, or comes with an automated tool that you can run over code
-to make it compatible. In practice, the need to use an automated tool is
-extremely rare. This means that upgrading from one source release to another
-should be a routine practice that can and should be performed often.
-
-We recommend you update to the latest release of Abseil as often as
-possible. Not only will you pick up bug fixes more quickly, but if you have good
-automated testing, you will catch and be able to fix any [Hyrum's
-Law](https://www.hyrumslaw.com/) dependency problems on an incremental basis
-instead of being overwhelmed by them and having difficulty isolating them if you
-wait longer between updates.
-
-If you are using the [Bazel](https://bazel.build/) build system and its
-[external dependencies](https://docs.bazel.build/versions/master/external.html)
-feature, updating the
-[`http_archive`](https://docs.bazel.build/versions/master/repo/http.html#http_archive)
-rule in your
-[`WORKSPACE`](https://docs.bazel.build/versions/master/be/workspace.html) for
-`com_google_abseil` to point to the latest release is all you need to do. You
-can commit the updated `WORKSPACE` file to your source control every time you
-update, and if you have good automated testing, you might even consider
-automating this.
-
-One thing we don't recommend is using GitHub's `master.zip` files (for example
-[https://github.com/abseil/abseil-cpp/archive/master.zip](https://github.com/abseil/abseil-cpp/archive/master.zip)),
-which are always the latest commit in the `master` branch, to implement live at
-head. Since these `master.zip` URLs are not versioned, you will lose build
-reproducibility. In addition, some build systems, including Bazel, will simply
-cache this file, which means you won't actually be updating to the latest
-release until your cache is cleared or invalidated.
diff --git a/absl/abseil.podspec.gen.py b/absl/abseil.podspec.gen.py
index 2bf153c002..6aefb794df 100755
--- a/absl/abseil.podspec.gen.py
+++ b/absl/abseil.podspec.gen.py
@@ -46,18 +46,6 @@ Pod::Spec.new do |s|
   s.watchos.deployment_target = '2.0'
 """
 
-# Limited platforms that abseil supports.
-# This is mainly because of sigaltstack unavailable on watchOS.
-LIMITED_SUPPORT_PLATFORMS = [
-    "ios.deployment_target = '7.0'",
-    "osx.deployment_target = '10.9'",
-]
-
-# Custom specification per rule.
-CUSTOM_SPEC_MAP = {
-    "//absl/debugging:failure_signal_handler": LIMITED_SUPPORT_PLATFORMS,
-}
-
 # Rule object representing the rule of Bazel BUILD.
 Rule = collections.namedtuple(
     "Rule", "type name package srcs hdrs textual_hdrs deps visibility testonly")
@@ -200,12 +188,6 @@ def write_podspec_rule(f, rule, depth):
     name = get_spec_name(dep.replace(":", "/"))
     f.write("{indent}{var}.dependency '{dep}'\n".format(
         indent=indent, var=spec_var, dep=name))
-  # Writes custom specification.
-  custom_spec = CUSTOM_SPEC_MAP.get(rule.package + ":" + rule.name)
-  if custom_spec:
-    for spec in custom_spec:
-      f.write("{indent}{var}.{spec}\n".format(
-          indent=indent, var=spec_var, spec=spec))
 
 
 def write_indented_list(f, leading, values):
diff --git a/absl/base/config.h b/absl/base/config.h
index eac5d268e1..ee99f94629 100644
--- a/absl/base/config.h
+++ b/absl/base/config.h
@@ -316,13 +316,19 @@ static_assert(ABSL_INTERNAL_INLINE_NAMESPACE_STR[0] != 'h' ||
 #error ABSL_HAVE_EXCEPTIONS cannot be directly set.
 
 #elif defined(__clang__)
-// TODO(calabrese)
-// Switch to using __cpp_exceptions when we no longer support versions < 3.6.
-// For details on this check, see:
-//   http://releases.llvm.org/3.6.0/tools/clang/docs/ReleaseNotes.html#the-exceptions-macro
+
+#if __clang_major__ > 3 || (__clang_major__ == 3 && __clang_minor__ >= 6)
+// Clang >= 3.6
+#if __has_feature(cxx_exceptions)
+#define ABSL_HAVE_EXCEPTIONS 1
+#endif  // __has_feature(cxx_exceptions)
+#else
+// Clang < 3.6
+// http://releases.llvm.org/3.6.0/tools/clang/docs/ReleaseNotes.html#the-exceptions-macro
 #if defined(__EXCEPTIONS) && __has_feature(cxx_exceptions)
 #define ABSL_HAVE_EXCEPTIONS 1
 #endif  // defined(__EXCEPTIONS) && __has_feature(cxx_exceptions)
+#endif  // __clang_major__ > 3 || (__clang_major__ == 3 && __clang_minor__ >= 6)
 
 // Handle remaining special cases and default to exceptions being supported.
 #elif !(defined(__GNUC__) && (__GNUC__ < 5) && !defined(__EXCEPTIONS)) &&    \
diff --git a/absl/container/node_hash_set.h b/absl/container/node_hash_set.h
index 0e2dee54aa..ad54b6dccb 100644
--- a/absl/container/node_hash_set.h
+++ b/absl/container/node_hash_set.h
@@ -77,7 +77,7 @@ struct NodeHashSetPolicy;
 //
 //   // Create a node hash set of three strings
 //   absl::node_hash_map<std::string, std::string> ducks =
-//     {"huey", "dewey"}, "louie"};
+//     {"huey", "dewey", "louie"};
 //
 //  // Insert a new element into the node hash map
 //  ducks.insert("donald"};
@@ -111,7 +111,7 @@ class node_hash_set
   // * Initializer List constructor
   //
   //   absl::node_hash_set<std::string> set2 =
-  //       {{"huey"}, {"dewey"}, {"louie"},};
+  //       {{"huey"}, {"dewey"}, {"louie"}};
   //
   // * Copy constructor
   //
diff --git a/absl/debugging/failure_signal_handler.cc b/absl/debugging/failure_signal_handler.cc
index 470d676812..cd141ecf5d 100644
--- a/absl/debugging/failure_signal_handler.cc
+++ b/absl/debugging/failure_signal_handler.cc
@@ -24,6 +24,10 @@
 #include <unistd.h>
 #endif
 
+#ifdef __APPLE__
+#include <TargetConditionals.h>
+#endif
+
 #ifdef ABSL_HAVE_MMAP
 #include <sys/mman.h>
 #endif
@@ -44,6 +48,11 @@
 
 #ifndef _WIN32
 #define ABSL_HAVE_SIGACTION
+// Apple WatchOS and TVOS don't allow sigaltstack
+#if !(defined(TARGET_OS_WATCH) && TARGET_OS_WATCH) && \
+    !(defined(TARGET_OS_TV) && TARGET_OS_TV)
+#define ABSL_HAVE_SIGALTSTACK
+#endif
 #endif
 
 namespace absl {
@@ -117,7 +126,7 @@ const char* FailureSignalToString(int signo) {
 
 }  // namespace debugging_internal
 
-#ifndef _WIN32
+#ifdef ABSL_HAVE_SIGALTSTACK
 
 static bool SetupAlternateStackOnce() {
 #if defined(__wasm__) || defined (__asjms__)
@@ -169,7 +178,7 @@ static bool SetupAlternateStackOnce() {
 // Returns the appropriate flag for sig_action.sa_flags
 // if the system supports using an alternate stack.
 static int MaybeSetupAlternateStack() {
-#ifndef _WIN32
+#ifdef ABSL_HAVE_SIGALTSTACK
   ABSL_ATTRIBUTE_UNUSED static const bool kOnce = SetupAlternateStackOnce();
   return SA_ONSTACK;
 #else
diff --git a/absl/flags/BUILD.bazel b/absl/flags/BUILD.bazel
index d2ca5c6f83..cdb4e7e8fe 100644
--- a/absl/flags/BUILD.bazel
+++ b/absl/flags/BUILD.bazel
@@ -41,6 +41,7 @@ cc_library(
         ":config",
         ":handle",
         ":registry",
+        "//absl/base",
         "//absl/base:config",
         "//absl/base:core_headers",
         "//absl/memory",
diff --git a/absl/flags/CMakeLists.txt b/absl/flags/CMakeLists.txt
index 20e66825a0..1d25f0ded8 100644
--- a/absl/flags/CMakeLists.txt
+++ b/absl/flags/CMakeLists.txt
@@ -27,6 +27,7 @@ absl_cc_library(
   LINKOPTS
     ${ABSL_DEFAULT_LINKOPTS}
   DEPS
+    absl::base
     absl::config
     absl::flags_config
     absl::flags_handle
diff --git a/absl/flags/internal/flag.cc b/absl/flags/internal/flag.cc
index ba70da91af..721e411e08 100644
--- a/absl/flags/internal/flag.cc
+++ b/absl/flags/internal/flag.cc
@@ -80,41 +80,22 @@ class MutexRelock {
   absl::Mutex* mu_;
 };
 
-// This global lock guards the initialization and destruction of data_guard_,
-// which is used to guard the other Flag data.
-ABSL_CONST_INIT static absl::Mutex flag_mutex_lifetime_guard(absl::kConstInit);
-
 }  // namespace
 
 void FlagImpl::Init() {
-  {
-    absl::MutexLock lock(&flag_mutex_lifetime_guard);
-
-    // Must initialize data guard for this flag.
-    if (!is_data_guard_inited_) {
-      new (&data_guard_) absl::Mutex;
-      is_data_guard_inited_ = true;
-    }
-  }
+  new (&data_guard_) absl::Mutex;
 
   absl::MutexLock lock(reinterpret_cast<absl::Mutex*>(&data_guard_));
 
-  if (value_.dynamic != nullptr) {
-    inited_.store(true, std::memory_order_release);
-  } else {
-    // Need to initialize cur field.
-    value_.dynamic = MakeInitValue().release();
-    StoreAtomic();
-    inited_.store(true, std::memory_order_release);
-  }
+  value_.dynamic = MakeInitValue().release();
+  StoreAtomic();
 }
 
 // Ensures that the lazily initialized data is initialized,
 // and returns pointer to the mutex guarding flags data.
 absl::Mutex* FlagImpl::DataGuard() const {
-  if (ABSL_PREDICT_FALSE(!inited_.load(std::memory_order_acquire))) {
-    const_cast<FlagImpl*>(this)->Init();
-  }
+  absl::call_once(const_cast<FlagImpl*>(this)->init_control_, &FlagImpl::Init,
+                  const_cast<FlagImpl*>(this));
 
   // data_guard_ is initialized.
   return reinterpret_cast<absl::Mutex*>(&data_guard_);
diff --git a/absl/flags/internal/flag.h b/absl/flags/internal/flag.h
index ef30a22f53..b426ccb571 100644
--- a/absl/flags/internal/flag.h
+++ b/absl/flags/internal/flag.h
@@ -24,6 +24,7 @@
 #include <string>
 #include <type_traits>
 
+#include "absl/base/call_once.h"
 #include "absl/base/config.h"
 #include "absl/base/thread_annotations.h"
 #include "absl/flags/config.h"
@@ -281,10 +282,8 @@ class FlagImpl {
         help_(help.source),
         help_source_kind_(static_cast<uint8_t>(help.kind)),
         def_kind_(static_cast<uint8_t>(FlagDefaultKind::kGenFunc)),
-        is_data_guard_inited_(false),
         modified_(false),
         on_command_line_(false),
-        inited_(false),
         counter_(0),
         callback_(nullptr),
         default_src_(default_value_gen),
@@ -406,20 +405,28 @@ class FlagImpl {
   // Indicates if help message was supplied as literal or generator func.
   const uint8_t help_source_kind_ : 1;
 
+  // ------------------------------------------------------------------------
+  // The bytes containing the const bitfields must not be shared with bytes
+  // containing the mutable bitfields.
+  // ------------------------------------------------------------------------
+
+  // Unique tag for absl::call_once call to initialize this flag.
+  //
+  // The placement of this variable between the immutable and mutable bitfields
+  // is important as prevents them from occupying the same byte. If you remove
+  // this variable, make sure to maintain this property.
+  absl::once_flag init_control_;
+
   // Mutable flag's state (guarded by `data_guard_`).
 
   // If def_kind_ == kDynamicValue, default_src_ holds a dynamically allocated
   // value.
   uint8_t def_kind_ : 1 ABSL_GUARDED_BY(*DataGuard());
-  // Protects against multiple concurrent constructions of `data_guard_`.
-  bool is_data_guard_inited_ : 1;
   // Has this flag's value been modified?
   bool modified_ : 1 ABSL_GUARDED_BY(*DataGuard());
   // Has this flag been specified on command line.
   bool on_command_line_ : 1 ABSL_GUARDED_BY(*DataGuard());
 
-  // Indicates that the flag state is initialized.
-  std::atomic<bool> inited_;
   // Mutation counter
   int64_t counter_ ABSL_GUARDED_BY(*DataGuard());
   // Optional flag's callback and absl::Mutex to guard the invocations.