diff --git a/.gitignore b/.gitignore
index 31f3374..d54fa5a 100644
--- a/.gitignore
+++ b/.gitignore
@@ -11,5 +11,5 @@
 # Ignore VS Code files
 .vscode/*
 # Ignore generated python artifacts
-copts/copts.pyc
+*.pyc
 copts/__pycache__/
diff --git a/CMake/AbseilHelpers.cmake b/CMake/AbseilHelpers.cmake
index 7c81bea..6d26169 100644
--- a/CMake/AbseilHelpers.cmake
+++ b/CMake/AbseilHelpers.cmake
@@ -16,6 +16,7 @@
 
 include(CMakeParseArguments)
 include(AbseilConfigureCopts)
+include(GNUInstallDirs)
 
 # The IDE folder for Abseil that will be used if Abseil is included in a CMake
 # project that sets
@@ -35,13 +36,13 @@
 # COPTS: List of private compile options
 # DEFINES: List of public defines
 # LINKOPTS: List of link options
-# PUBLIC: Add this so that this library will be exported under absl:: (see Note).
+# PUBLIC: Add this so that this library will be exported under absl::
 # Also in IDE, target will appear in Abseil folder while non PUBLIC will be in Abseil/internal.
 # TESTONLY: When added, this target will only be built if user passes -DABSL_RUN_TESTS=ON to CMake.
 #
 # Note:
-# By default, absl_cc_library will always create a library named absl_internal_${NAME},
-# and alias target absl::${NAME}.
+# By default, absl_cc_library will always create a library named absl_${NAME},
+# and alias target absl::${NAME}.  The absl:: form should always be used.
 # This is to reduce namespace pollution.
 #
 # absl_cc_library(
@@ -59,20 +60,17 @@
 #     "b.cc"
 #   DEPS
 #     absl_internal_awesome # not "awesome"!
+#   PUBLIC
 # )
 #
-# If PUBLIC is set, absl_cc_library will instead create a target named
-# absl_${NAME} and still an alias absl::${NAME}.
-#
 # absl_cc_library(
 #   NAME
 #     main_lib
 #   ...
-#   PUBLIC
+#   DEPS
+#     absl::fantastic_lib # since fantastic_lib is public
 # )
 #
-# User can then use the library as absl::main_lib (although absl_main_lib is defined too).
-#
 # TODO: Implement "ALWAYSLINK"
 function(absl_cc_library)
   cmake_parse_arguments(ABSL_CC_LIB
@@ -83,11 +81,7 @@
   )
 
   if (NOT ABSL_CC_LIB_TESTONLY OR ABSL_RUN_TESTS)
-    if (ABSL_CC_LIB_PUBLIC)
-      set(_NAME "absl_${ABSL_CC_LIB_NAME}")
-    else()
-      set(_NAME "absl_internal_${ABSL_CC_LIB_NAME}")
-    endif()
+    set(_NAME "${ABSL_CC_LIB_NAME}")
 
     # Check if this is a header-only library
     # Note that as of February 2019, many popular OS's (for example, Ubuntu
@@ -109,7 +103,10 @@
       add_library(${_NAME} STATIC "")
       target_sources(${_NAME} PRIVATE ${ABSL_CC_LIB_SRCS} ${ABSL_CC_LIB_HDRS})
       target_include_directories(${_NAME}
-        PUBLIC ${ABSL_COMMON_INCLUDE_DIRS})
+        PUBLIC
+          $<BUILD_INTERFACE:${ABSL_COMMON_INCLUDE_DIRS}>
+          $<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
+      )
       target_compile_options(${_NAME}
         PRIVATE ${ABSL_CC_LIB_COPTS})
       target_link_libraries(${_NAME}
@@ -130,17 +127,37 @@
       # INTERFACE libraries can't have the CXX_STANDARD property set
       set_property(TARGET ${_NAME} PROPERTY CXX_STANDARD ${ABSL_CXX_STANDARD})
       set_property(TARGET ${_NAME} PROPERTY CXX_STANDARD_REQUIRED ON)
+
+      # When being installed, we lose the absl_ prefix.  We want to put it back
+      # to have properly named lib files.  This is a no-op when we are not being
+      # installed.
+      set_target_properties(${_NAME} PROPERTIES
+        OUTPUT_NAME "absl_${_NAME}"
+      )
     else()
       # Generating header-only library
       add_library(${_NAME} INTERFACE)
       target_include_directories(${_NAME}
-        INTERFACE ${ABSL_COMMON_INCLUDE_DIRS})
+        INTERFACE
+          $<BUILD_INTERFACE:${ABSL_COMMON_INCLUDE_DIRS}>
+          $<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
+        )
       target_link_libraries(${_NAME}
         INTERFACE ${ABSL_CC_LIB_DEPS} ${ABSL_CC_LIB_LINKOPTS}
       )
       target_compile_definitions(${_NAME} INTERFACE ${ABSL_CC_LIB_DEFINES})
     endif()
 
+    # TODO currently we don't install googletest alongside abseil sources, so
+    # installed abseil can't be tested.
+    if (NOT ABSL_CC_LIB_TESTONLY)
+      install(TARGETS ${_NAME} EXPORT ${PROJECT_NAME}Targets
+            RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
+            LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
+            ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
+      )
+    endif()
+
     add_library(absl::${ABSL_CC_LIB_NAME} ALIAS ${_NAME})
   endif()
 endfunction()
diff --git a/CMake/abslConfig.cmake.in b/CMake/abslConfig.cmake.in
new file mode 100644
index 0000000..bf8c4f6
--- /dev/null
+++ b/CMake/abslConfig.cmake.in
@@ -0,0 +1,6 @@
+## absl CMake configuration file.  Note that there is no corresponding
+# abslConfigVersion.cmake since non-LTS Abseil isn't versioned.
+
+@PACKAGE_INIT@
+
+include ("${CMAKE_CURRENT_LIST_DIR}/@PROJECT_NAME@Targets.cmake")
\ No newline at end of file
diff --git a/CMake/install_test_project/CMakeLists.txt b/CMake/install_test_project/CMakeLists.txt
new file mode 100644
index 0000000..b8e27dd
--- /dev/null
+++ b/CMake/install_test_project/CMakeLists.txt
@@ -0,0 +1,27 @@
+#
+# Copyright 2019 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.
+
+# A simple CMakeLists.txt for testing cmake installation
+
+cmake_minimum_required(VERSION 3.5)
+project(absl_cmake_testing)
+
+set(CMAKE_CXX_STANDARD 11)
+
+add_executable(simple simple.cc)
+
+find_package(absl REQUIRED)
+
+target_link_libraries(simple absl::strings)
diff --git a/CMake/install_test_project/simple.cc b/CMake/install_test_project/simple.cc
new file mode 100644
index 0000000..e9e3529
--- /dev/null
+++ b/CMake/install_test_project/simple.cc
@@ -0,0 +1,23 @@
+//
+// Copyright 2019 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 <iostream>
+#include "absl/strings/substitute.h"
+
+int main(int argc, char** argv) {
+  for (int i = 0; i < argc; ++i) {
+    std::cout << absl::Substitute("Arg $0: $1\n", i, argv[i]);
+  }
+}
diff --git a/CMake/install_test_project/test.sh b/CMake/install_test_project/test.sh
new file mode 100755
index 0000000..3e77e79
--- /dev/null
+++ b/CMake/install_test_project/test.sh
@@ -0,0 +1,110 @@
+#!/bin/bash
+#
+# Copyright 2019 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.
+
+# "Unit" and integration tests for Absl CMake installation
+
+# TODO(absl-team): This script isn't fully hermetic because
+# -DABSL_USE_GOOGLETEST_HEAD=ON means that this script isn't pinned to a fixed
+# version of GoogleTest. This means that an upstream change to GoogleTest could
+# break this test. Fix this by allowing this script to pin to a known-good
+# version of GoogleTest.
+
+# Fail on any error. Treat unset variables an error. Print commands as executed.
+set -euox pipefail
+absl_dir=/abseil-cpp
+absl_build_dir=/buildfs/absl-build
+project_dir="${absl_dir}"/CMake/install_test_project
+project_build_dir=/buildfs/project-build
+install_dir="${project_build_dir}"/install
+
+mkdir -p "${absl_build_dir}"
+mkdir -p "${project_build_dir}"
+mkdir -p "${install_dir}"
+
+install_absl() {
+  pushd "${absl_build_dir}"
+  if [[ "${#}" -eq 1 ]]; then
+    cmake -DCMAKE_INSTALL_PREFIX="${1}" "${absl_dir}"
+  else
+    cmake "${absl_dir}"
+  fi
+  cmake --build . --target install -- -j
+  popd
+}
+
+uninstall_absl() {
+  xargs rm < "${absl_build_dir}"/install_manifest.txt
+  rm -rf "${absl_build_dir}"
+  mkdir -p "${absl_build_dir}"
+}
+
+# Test build, install, and link against installed abseil
+install_absl "${install_dir}"
+pushd "${project_build_dir}"
+cmake "${project_dir}" -DCMAKE_PREFIX_PATH="${install_dir}"
+cmake --build . --target simple
+
+output="$(${project_build_dir}/simple "printme" 2>&1)"
+if [[ "${output}" != *"Arg 1: printme"* ]]; then
+  echo "Faulty output on simple project:"
+  echo "${output}"
+  exit 1
+fi
+
+# Test that we haven't accidentally made absl::abslblah
+pushd "${install_dir}"
+
+# Starting in CMake 3.12 the default install dir is lib$bit_width
+if [[ -d lib ]]; then
+  libdir="lib"
+elif [[ -d lib64 ]]; then
+  libdir="lib64"
+else
+  echo "ls *, */*, */*/*:"
+  ls *
+  ls */*
+  ls */*/*
+  echo "unknown lib dir"
+fi
+
+if ! grep absl::strings "${libdir}"/cmake/absl/abslTargets.cmake;  then
+  cat "${libdir}"/cmake/absl/abslTargets.cmake
+  echo "CMake targets named incorrectly"
+  exit 1
+fi
+
+uninstall_absl
+popd
+
+# Test that we warn if installed without a prefix or a system prefix
+output="$(install_absl 2>&1)"
+if [[ "${output}" != *"Please set CMAKE_INSTALL_PREFIX"* ]]; then
+  echo "Install without prefix didn't warn as expected. Output:"
+  echo "${output}"
+  exit 1
+fi
+uninstall_absl
+
+output="$(install_absl /usr 2>&1)"
+if [[ "${output}" != *"Please set CMAKE_INSTALL_PREFIX"* ]]; then
+  echo "Install with /usr didn't warn as expected. Output:"
+  echo "${output}"
+  exit 1
+fi
+uninstall_absl
+
+echo "Install test complete!"
+exit 0
diff --git a/CMakeLists.txt b/CMakeLists.txt
index a56d238..3f4fbdc 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -14,23 +14,38 @@
 # limitations under the License.
 #
 
-# We require 3.0 for modern, target-based CMake.  We require 3.1 for the use of
-# CXX_STANDARD in our targets.
-cmake_minimum_required(VERSION 3.1)
+# Most widely used distributions have cmake 3.5 or greater available as of March
+# 2019.  A notable exception is RHEL-7 (CentOS7).  You can install a current
+# version of CMake by first installing Extra Packages for Enterprise Linux
+# (https://fedoraproject.org/wiki/EPEL#Extra_Packages_for_Enterprise_Linux_.28EPEL.29)
+# and then issuing `yum install cmake3` on the command line.
+cmake_minimum_required(VERSION 3.5)
 
 # Compiler id for Apple Clang is now AppleClang.
 if (POLICY CMP0025)
   cmake_policy(SET CMP0025 NEW)
 endif()
 
+# if command can use IN_LIST
+cmake_policy(SET CMP0057 NEW)
+
 project(absl)
 
+# when absl is included as subproject (i.e. using add_subdirectory(abseil-cpp))
+# in the source tree of a project that uses it, install rules are disabled.
+if(NOT "^${CMAKE_SOURCE_DIR}$" STREQUAL "^${PROJECT_SOURCE_DIR}$")
+  set(ABSL_ENABLE_INSTALL FALSE)
+else()
+  set(ABSL_ENABLE_INSTALL TRUE)
+endif()
+
 list(APPEND CMAKE_MODULE_PATH
   ${CMAKE_CURRENT_LIST_DIR}/CMake
   ${CMAKE_CURRENT_LIST_DIR}/absl/copts
 )
 
 include(GNUInstallDirs)
+include(CMakePackageConfigHelpers)
 include(AbseilHelpers)
 
 
@@ -70,11 +85,23 @@
   enable_testing()
 endif()
 
+# We don't support system-wide installation
+list(APPEND SYSTEM_INSTALL_DIRS "/usr/local" "/usr" "/opt/" "/opt/local" "c:/Program Files/${PROJECT_NAME}")
+if(NOT DEFINED CMAKE_INSTALL_PREFIX OR CMAKE_INSTALL_PREFIX IN_LIST SYSTEM_INSTALL_DIRS)
+  message(WARNING "\
+The default and system-level install directories are unsupported except in LTS \
+releases of Abseil.  Please set CMAKE_INSTALL_PREFIX to install Abseil in your \
+source or build tree directly.\
+  ")
+endif()
+
 ## check targets
 if(BUILD_TESTING)
 
   if(${ABSL_USE_GOOGLETEST_HEAD})
     include(CMake/DownloadGTest.cmake)
+    set(absl_gtest_src_dir ${CMAKE_BINARY_DIR}/googletest-src)
+    set(absl_gtest_build_dir ${CMAKE_BINARY_DIR}/googletest-build)
   endif()
 
   check_target(gtest)
@@ -90,3 +117,26 @@
 endif()
 
 add_subdirectory(absl)
+
+# install as a subdirectory only
+install(EXPORT ${PROJECT_NAME}Targets
+  NAMESPACE absl::
+  DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}"
+)
+
+configure_package_config_file(
+  CMake/abslConfig.cmake.in
+  "${PROJECT_BINARY_DIR}/${PROJECT_NAME}Config.cmake"
+  INSTALL_DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}"
+)
+
+install(FILES "${PROJECT_BINARY_DIR}/${PROJECT_NAME}Config.cmake"
+  DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}"
+)
+
+install(DIRECTORY absl
+  DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
+  FILES_MATCHING
+    PATTERN "*.inc"
+    PATTERN "*.h"
+)
diff --git a/absl/algorithm/container.h b/absl/algorithm/container.h
index 7348d63..752e47b 100644
--- a/absl/algorithm/container.h
+++ b/absl/algorithm/container.h
@@ -36,7 +36,6 @@
 // For template parameter and variable naming, `C` indicates the container type
 // to which the function is applied, `Pred` indicates the predicate object type
 // to be used by the function and `T` indicates the applicable element type.
-//
 
 #ifndef ABSL_ALGORITHM_CONTAINER_H_
 #define ABSL_ALGORITHM_CONTAINER_H_
@@ -648,7 +647,6 @@
 // and `unique()` are omitted, because it's not clear whether or not such
 // functions should call erase on their supplied sequences afterwards. Either
 // behavior would be surprising for a different set of users.
-//
 
 // c_remove_copy()
 //
diff --git a/absl/base/BUILD.bazel b/absl/base/BUILD.bazel
index 19c5045..804f62a 100644
--- a/absl/base/BUILD.bazel
+++ b/absl/base/BUILD.bazel
@@ -326,7 +326,7 @@
     name = "spinlock_benchmark_common",
     testonly = 1,
     srcs = ["internal/spinlock_benchmark.cc"],
-    copts = ABSL_DEFAULT_COPTS,
+    copts = ABSL_TEST_COPTS,
     visibility = [
         "//absl/base:__pkg__",
     ],
diff --git a/absl/base/CMakeLists.txt b/absl/base/CMakeLists.txt
index f2bacb2..d8a311c 100644
--- a/absl/base/CMakeLists.txt
+++ b/absl/base/CMakeLists.txt
@@ -241,7 +241,7 @@
     "throw_delegate_test.cc"
   DEPS
     absl::base
-    absl_internal_throw_delegate
+    absl::throw_delegate
     gtest_main
 )
 
diff --git a/absl/base/const_init.h b/absl/base/const_init.h
index 1b2b8c2..17858a7 100644
--- a/absl/base/const_init.h
+++ b/absl/base/const_init.h
@@ -60,7 +60,6 @@
 //
 // The absl::kConstInit tag should only be used to define objects with static
 // or thread_local storage duration.
-//
 
 namespace absl {
 
diff --git a/absl/base/dynamic_annotations.h b/absl/base/dynamic_annotations.h
index cdeb18c..ac33df9 100644
--- a/absl/base/dynamic_annotations.h
+++ b/absl/base/dynamic_annotations.h
@@ -139,6 +139,7 @@
   #define ANNOTATE_MEMORY_IS_INITIALIZED(address, size) /* empty */
   #define ANNOTATE_MEMORY_IS_UNINITIALIZED(address, size) /* empty */
 #endif  /* DYNAMIC_ANNOTATIONS_ENABLED || MEMORY_SANITIZER */
+
 /* TODO(delesley) -- Replace __CLANG_SUPPORT_DYN_ANNOTATION__ with the
    appropriate feature ID. */
 #if defined(__clang__) && (!defined(SWIG)) \
diff --git a/absl/base/internal/cycleclock.h b/absl/base/internal/cycleclock.h
index 7874db7..794564e 100644
--- a/absl/base/internal/cycleclock.h
+++ b/absl/base/internal/cycleclock.h
@@ -28,7 +28,6 @@
 // not necessarily "CPU cycles" and code should not rely on that behavior, even
 // if experimentally observed.
 //
-//
 // An arbitrary offset may have been added to the counter at power on.
 //
 // On some platforms, the rate and offset of the counter may differ
diff --git a/absl/base/internal/low_level_alloc.h b/absl/base/internal/low_level_alloc.h
index f83c7bc..b35673d 100644
--- a/absl/base/internal/low_level_alloc.h
+++ b/absl/base/internal/low_level_alloc.h
@@ -119,4 +119,5 @@
 
 }  // namespace base_internal
 }  // namespace absl
+
 #endif  // ABSL_BASE_INTERNAL_LOW_LEVEL_ALLOC_H_
diff --git a/absl/base/internal/low_level_alloc_test.cc b/absl/base/internal/low_level_alloc_test.cc
index d2d3182..34a080c 100644
--- a/absl/base/internal/low_level_alloc_test.cc
+++ b/absl/base/internal/low_level_alloc_test.cc
@@ -137,6 +137,7 @@
     TEST_ASSERT(LowLevelAlloc::DeleteArena(arena));
   }
 }
+
 // LowLevelAlloc is designed to be safe to call before main().
 static struct BeforeMain {
   BeforeMain() {
diff --git a/absl/base/internal/low_level_scheduling.h b/absl/base/internal/low_level_scheduling.h
index 2a5a384..0fcc8d3 100644
--- a/absl/base/internal/low_level_scheduling.h
+++ b/absl/base/internal/low_level_scheduling.h
@@ -86,6 +86,7 @@
 //------------------------------------------------------------------------------
 // End of public interfaces.
 //------------------------------------------------------------------------------
+
 inline bool SchedulingGuard::ReschedulingIsAllowed() {
   return false;
 }
@@ -98,7 +99,7 @@
   return;
 }
 
-
 }  // namespace base_internal
 }  // namespace absl
+
 #endif  // ABSL_BASE_INTERNAL_LOW_LEVEL_SCHEDULING_H_
diff --git a/absl/base/internal/raw_logging.h b/absl/base/internal/raw_logging.h
index 4cbbbe5..6a4c093 100644
--- a/absl/base/internal/raw_logging.h
+++ b/absl/base/internal/raw_logging.h
@@ -38,6 +38,7 @@
 //   ABSL_RAW_LOG(ERROR, "Failed foo with %i: %s", status, error);
 // This will print an almost standard log line like this to stderr only:
 //   E0821 211317 file.cc:123] RAW: Failed foo with 22: bad_file
+
 #define ABSL_RAW_LOG(severity, ...)                                            \
   do {                                                                         \
     constexpr const char* absl_raw_logging_internal_basename =                 \
diff --git a/absl/base/internal/scoped_set_env.cc b/absl/base/internal/scoped_set_env.cc
index 9b16412..3ac3f68 100644
--- a/absl/base/internal/scoped_set_env.cc
+++ b/absl/base/internal/scoped_set_env.cc
@@ -33,7 +33,7 @@
 
 void SetEnvVar(const char* name, const char* value) {
 #ifdef _WIN32
-  SetEnvironmentVariable(name, value);
+  SetEnvironmentVariableA(name, value);
 #else
   if (value == nullptr) {
     ::unsetenv(name);
@@ -49,7 +49,7 @@
     : var_name_(var_name), was_unset_(false) {
 #ifdef _WIN32
   char buf[kMaxEnvVarValueSize];
-  auto get_res = GetEnvironmentVariable(var_name_.c_str(), buf, sizeof(buf));
+  auto get_res = GetEnvironmentVariableA(var_name_.c_str(), buf, sizeof(buf));
   ABSL_INTERNAL_CHECK(get_res < sizeof(buf), "value exceeds buffer size");
 
   if (get_res == 0) {
@@ -58,7 +58,7 @@
     old_value_.assign(buf, get_res);
   }
 
-  SetEnvironmentVariable(var_name_.c_str(), new_value);
+  SetEnvironmentVariableA(var_name_.c_str(), new_value);
 #else
   const char* val = ::getenv(var_name_.c_str());
   if (val == nullptr) {
diff --git a/absl/base/internal/scoped_set_env_test.cc b/absl/base/internal/scoped_set_env_test.cc
index 4bd68c4..5cbad24 100644
--- a/absl/base/internal/scoped_set_env_test.cc
+++ b/absl/base/internal/scoped_set_env_test.cc
@@ -26,8 +26,8 @@
 std::string GetEnvVar(const char* name) {
 #ifdef _WIN32
   char buf[1024];
-  auto get_res = GetEnvironmentVariable(name, buf, sizeof(buf));
-  if (get_res == sizeof(buf)) {
+  auto get_res = GetEnvironmentVariableA(name, buf, sizeof(buf));
+  if (get_res >= sizeof(buf)) {
     return "TOO_BIG";
   }
 
diff --git a/absl/base/internal/thread_identity.h b/absl/base/internal/thread_identity.h
index dde3e01..b34674a 100644
--- a/absl/base/internal/thread_identity.h
+++ b/absl/base/internal/thread_identity.h
@@ -237,4 +237,5 @@
 
 }  // namespace base_internal
 }  // namespace absl
+
 #endif  // ABSL_BASE_INTERNAL_THREAD_IDENTITY_H_
diff --git a/absl/base/internal/unscaledcycleclock.h b/absl/base/internal/unscaledcycleclock.h
index d5e186a..58950cc 100644
--- a/absl/base/internal/unscaledcycleclock.h
+++ b/absl/base/internal/unscaledcycleclock.h
@@ -83,6 +83,7 @@
       defined(_M_IX86) || defined(_M_X64))
 #define ABSL_INTERNAL_UNSCALED_CYCLECLOCK_FREQUENCY_IS_CPU_FREQUENCY
 #endif
+
 namespace absl {
 namespace time_internal {
 class UnscaledCycleClockWrapperForGetCurrentTime;
@@ -114,6 +115,7 @@
 
 }  // namespace base_internal
 }  // namespace absl
+
 #endif  // ABSL_USE_UNSCALED_CYCLECLOCK
 
 #endif  // ABSL_BASE_INTERNAL_UNSCALEDCYCLECLOCK_H_
diff --git a/absl/base/log_severity.h b/absl/base/log_severity.h
index 4b9833e..b19a7ff 100644
--- a/absl/base/log_severity.h
+++ b/absl/base/log_severity.h
@@ -11,7 +11,6 @@
 // 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_LOG_SEVERITY_H_
 #define ABSL_BASE_INTERNAL_LOG_SEVERITY_H_
diff --git a/absl/base/spinlock_test_common.cc b/absl/base/spinlock_test_common.cc
index b32cea2..e62b2ea 100644
--- a/absl/base/spinlock_test_common.cc
+++ b/absl/base/spinlock_test_common.cc
@@ -54,6 +54,7 @@
 
 static constexpr int kArrayLength = 10;
 static uint32_t values[kArrayLength];
+
 static SpinLock static_spinlock(base_internal::kLinkerInitialized);
 static SpinLock static_cooperative_spinlock(
     base_internal::kLinkerInitialized,
@@ -189,6 +190,7 @@
     SpinLockTest::DecodeWaitCycles(before_max_value);
   EXPECT_GT(expected_max_value_decoded, before_max_value_decoded);
 }
+
 TEST(SpinLockWithThreads, StaticSpinLock) {
   ThreadedTest(&static_spinlock);
 }
diff --git a/absl/base/thread_annotations.h b/absl/base/thread_annotations.h
index a8162d4..0b2c306 100644
--- a/absl/base/thread_annotations.h
+++ b/absl/base/thread_annotations.h
@@ -21,7 +21,6 @@
 // code. The annotations can also help program analysis tools to identify
 // potential thread safety issues.
 //
-//
 // These annotations are implemented using compiler attributes. Using the macros
 // defined here instead of raw attributes allow for portability and future
 // compatibility.
@@ -34,6 +33,7 @@
 
 #ifndef ABSL_BASE_THREAD_ANNOTATIONS_H_
 #define ABSL_BASE_THREAD_ANNOTATIONS_H_
+
 #if defined(__clang__)
 #define THREAD_ANNOTATION_ATTRIBUTE__(x)   __attribute__((x))
 #else
diff --git a/absl/compiler_config_setting.bzl b/absl/compiler_config_setting.bzl
index e03f94e..6696229 100644
--- a/absl/compiler_config_setting.bzl
+++ b/absl/compiler_config_setting.bzl
@@ -12,7 +12,6 @@
 # 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.
-#
 
 """Creates config_setting that allows selecting based on 'compiler' value."""
 
diff --git a/absl/container/BUILD.bazel b/absl/container/BUILD.bazel
index b6592ca..cd914ba 100644
--- a/absl/container/BUILD.bazel
+++ b/absl/container/BUILD.bazel
@@ -112,10 +112,20 @@
 )
 
 cc_library(
+    name = "inlined_vector_internal",
+    hdrs = ["internal/inlined_vector.h"],
+    copts = ABSL_DEFAULT_COPTS,
+    deps = [
+        "//absl/meta:type_traits",
+    ],
+)
+
+cc_library(
     name = "inlined_vector",
     hdrs = ["inlined_vector.h"],
     copts = ABSL_DEFAULT_COPTS,
     deps = [
+        ":inlined_vector_internal",
         "//absl/algorithm",
         "//absl/base:core_headers",
         "//absl/base:throw_delegate",
diff --git a/absl/container/CMakeLists.txt b/absl/container/CMakeLists.txt
index 76542be..292fea2 100644
--- a/absl/container/CMakeLists.txt
+++ b/absl/container/CMakeLists.txt
@@ -109,6 +109,18 @@
 
 absl_cc_library(
   NAME
+    inlined_vector_internal
+  HDRS
+   "internal/inlined_vector.h"
+  COPTS
+    ${ABSL_DEFAULT_COPTS}
+  DEPS
+    absl::type_traits
+  PUBLIC
+)
+
+absl_cc_library(
+  NAME
     inlined_vector
   HDRS
    "inlined_vector.h"
diff --git a/absl/container/fixed_array.h b/absl/container/fixed_array.h
index 0161d0a..2a8240a 100644
--- a/absl/container/fixed_array.h
+++ b/absl/container/fixed_array.h
@@ -515,4 +515,5 @@
   static_cast<void>(n);  // Mark used when not in asan mode
 }
 }  // namespace absl
+
 #endif  // ABSL_CONTAINER_FIXED_ARRAY_H_
diff --git a/absl/container/flat_hash_map.h b/absl/container/flat_hash_map.h
index dfc497b..00cc4dc 100644
--- a/absl/container/flat_hash_map.h
+++ b/absl/container/flat_hash_map.h
@@ -219,8 +219,12 @@
   //   Erases the element at `position` of the `flat_hash_map`, returning
   //   `void`.
   //
-  //   NOTE: this return behavior is different than that of STL containers in
-  //   general and `std::unordered_map` in particular.
+  //   NOTE: returning `void` in this case is different than that of STL
+  //   containers in general and `std::unordered_map` in particular (which
+  //   return an iterator to the element following the erased element). If that
+  //   iterator is needed, simply post increment the iterator:
+  //
+  //     map.erase(it++);
   //
   // iterator erase(const_iterator first, const_iterator last):
   //
diff --git a/absl/container/flat_hash_map_test.cc b/absl/container/flat_hash_map_test.cc
index 562305e..ebcb560 100644
--- a/absl/container/flat_hash_map_test.cc
+++ b/absl/container/flat_hash_map_test.cc
@@ -141,6 +141,7 @@
   int conversions = 0;
   int hashes = 0;
   flat_hash_map<size_t, size_t, Hash, Eq> m(0, Hash{&hashes});
+  m.reserve(3);
 
   m[LazyInt(1, &conversions)] = 1;
   EXPECT_THAT(m, UnorderedElementsAre(Pair(1, 1)));
@@ -205,7 +206,9 @@
   m.insert(std::move(node));
   EXPECT_THAT(m, UnorderedElementsAre(Pair(1, 17), Pair(2, 9)));
 }
-#if !defined(__ANDROID__) && !defined(__APPLE__) && !defined(__EMSCRIPTEN__)
+
+#if (defined(ABSL_HAVE_STD_ANY) || !defined(_LIBCPP_VERSION)) && \
+    !defined(__EMSCRIPTEN__)
 TEST(FlatHashMap, Any) {
   absl::flat_hash_map<int, absl::any> m;
   m.emplace(1, 7);
@@ -236,7 +239,8 @@
   ASSERT_NE(it2, m2.end());
   EXPECT_EQ(7, it2->second);
 }
-#endif  // __ANDROID__
+#endif  // (defined(ABSL_HAVE_STD_ANY) || !defined(_LIBCPP_VERSION)) &&
+        // !defined(__EMSCRIPTEN__)
 
 }  // namespace
 }  // namespace container_internal
diff --git a/absl/container/flat_hash_set.h b/absl/container/flat_hash_set.h
index f27f174..6bf5183 100644
--- a/absl/container/flat_hash_set.h
+++ b/absl/container/flat_hash_set.h
@@ -212,8 +212,12 @@
   //   Erases the element at `position` of the `flat_hash_set`, returning
   //   `void`.
   //
-  //   NOTE: this return behavior is different than that of STL containers in
-  //   general and `std::unordered_map` in particular.
+  //   NOTE: returning `void` in this case is different than that of STL
+  //   containers in general and `std::unordered_set` in particular (which
+  //   return an iterator to the element following the erased element). If that
+  //   iterator is needed, simply post increment the iterator:
+  //
+  //     set.erase(it++);
   //
   // iterator erase(const_iterator first, const_iterator last):
   //
diff --git a/absl/container/inlined_vector.h b/absl/container/inlined_vector.h
index 80929e3..7798805 100644
--- a/absl/container/inlined_vector.h
+++ b/absl/container/inlined_vector.h
@@ -1,4 +1,4 @@
-// Copyright 2018 The Abseil Authors.
+// Copyright 2019 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.
@@ -50,6 +50,7 @@
 #include "absl/base/internal/throw_delegate.h"
 #include "absl/base/optimization.h"
 #include "absl/base/port.h"
+#include "absl/container/internal/inlined_vector.h"
 #include "absl/memory/memory.h"
 
 namespace absl {
@@ -65,10 +66,13 @@
 // designed to cover the same API footprint as covered by `std::vector`.
 template <typename T, size_t N, typename A = std::allocator<T>>
 class InlinedVector {
-  static_assert(N > 0, "InlinedVector requires inline capacity greater than 0");
-  constexpr static typename A::size_type GetInlinedCapacity() {
-    return static_cast<typename A::size_type>(N);
-  }
+  static_assert(
+      N > 0, "InlinedVector cannot be instantiated with `0` inlined elements.");
+
+  using Storage = inlined_vector_internal::Storage<InlinedVector>;
+  using Tag = typename Storage::Tag;
+  using AllocatorAndTag = typename Storage::AllocatorAndTag;
+  using Allocation = typename Storage::Allocation;
 
   template <typename Iterator>
   using IsAtLeastForwardIterator = std::is_convertible<
@@ -83,21 +87,21 @@
   using DisableIfAtLeastForwardIterator =
       absl::enable_if_t<!IsAtLeastForwardIterator<Iterator>::value>;
 
-  using rvalue_reference = typename A::value_type&&;
+  using rvalue_reference = typename Storage::rvalue_reference;
 
  public:
-  using allocator_type = A;
-  using value_type = typename allocator_type::value_type;
-  using pointer = typename allocator_type::pointer;
-  using const_pointer = typename allocator_type::const_pointer;
-  using reference = typename allocator_type::reference;
-  using const_reference = typename allocator_type::const_reference;
-  using size_type = typename allocator_type::size_type;
-  using difference_type = typename allocator_type::difference_type;
-  using iterator = pointer;
-  using const_iterator = const_pointer;
-  using reverse_iterator = std::reverse_iterator<iterator>;
-  using const_reverse_iterator = std::reverse_iterator<const_iterator>;
+  using allocator_type = typename Storage::allocator_type;
+  using value_type = typename Storage::value_type;
+  using pointer = typename Storage::pointer;
+  using const_pointer = typename Storage::const_pointer;
+  using reference = typename Storage::reference;
+  using const_reference = typename Storage::const_reference;
+  using size_type = typename Storage::size_type;
+  using difference_type = typename Storage::difference_type;
+  using iterator = typename Storage::iterator;
+  using const_iterator = typename Storage::const_iterator;
+  using reverse_iterator = typename Storage::reverse_iterator;
+  using const_reverse_iterator = typename Storage::const_reverse_iterator;
 
   // ---------------------------------------------------------------------------
   // InlinedVector Constructors and Destructor
@@ -105,30 +109,30 @@
 
   // Creates an empty inlined vector with a default initialized allocator.
   InlinedVector() noexcept(noexcept(allocator_type()))
-      : allocator_and_tag_(allocator_type()) {}
+      : storage_(allocator_type()) {}
 
   // Creates an empty inlined vector with a specified allocator.
   explicit InlinedVector(const allocator_type& alloc) noexcept
-      : allocator_and_tag_(alloc) {}
+      : storage_(alloc) {}
 
   // Creates an inlined vector with `n` copies of `value_type()`.
   explicit InlinedVector(size_type n,
                          const allocator_type& alloc = allocator_type())
-      : allocator_and_tag_(alloc) {
+      : storage_(alloc) {
     InitAssign(n);
   }
 
   // Creates an inlined vector with `n` copies of `v`.
   InlinedVector(size_type n, const_reference v,
                 const allocator_type& alloc = allocator_type())
-      : allocator_and_tag_(alloc) {
+      : storage_(alloc) {
     InitAssign(n, v);
   }
 
   // Creates an inlined vector of copies of the values in `list`.
   InlinedVector(std::initializer_list<value_type> list,
                 const allocator_type& alloc = allocator_type())
-      : allocator_and_tag_(alloc) {
+      : storage_(alloc) {
     AppendForwardRange(list.begin(), list.end());
   }
 
@@ -142,7 +146,7 @@
             EnableIfAtLeastForwardIterator<ForwardIterator>* = nullptr>
   InlinedVector(ForwardIterator first, ForwardIterator last,
                 const allocator_type& alloc = allocator_type())
-      : allocator_and_tag_(alloc) {
+      : storage_(alloc) {
     AppendForwardRange(first, last);
   }
 
@@ -152,7 +156,7 @@
             DisableIfAtLeastForwardIterator<InputIterator>* = nullptr>
   InlinedVector(InputIterator first, InputIterator last,
                 const allocator_type& alloc = allocator_type())
-      : allocator_and_tag_(alloc) {
+      : storage_(alloc) {
     std::copy(first, last, std::back_inserter(*this));
   }
 
@@ -162,7 +166,7 @@
 
   // Creates a copy of an `other` inlined vector using a specified allocator.
   InlinedVector(const InlinedVector& other, const allocator_type& alloc)
-      : allocator_and_tag_(alloc) {
+      : storage_(alloc) {
     reserve(other.size());
     if (allocated()) {
       UninitializedCopy(other.begin(), other.end(), allocated_space());
@@ -191,7 +195,7 @@
   InlinedVector(InlinedVector&& other) noexcept(
       absl::allocator_is_nothrow<allocator_type>::value ||
       std::is_nothrow_move_constructible<value_type>::value)
-      : allocator_and_tag_(other.allocator()) {
+      : storage_(other.allocator()) {
     if (other.allocated()) {
       // We can just steal the underlying buffer from the source.
       // That leaves the source empty, so we clear its size.
@@ -222,7 +226,7 @@
   // ownership of `other`'s allocated memory.
   InlinedVector(InlinedVector&& other, const allocator_type& alloc) noexcept(
       absl::allocator_is_nothrow<allocator_type>::value)
-      : allocator_and_tag_(alloc) {
+      : storage_(alloc) {
     if (other.allocated()) {
       if (alloc == other.allocator()) {
         // We can just steal the allocation from the source.
@@ -282,7 +286,7 @@
   // will no longer be inlined and `capacity()` will equal its capacity on the
   // allocated heap.
   size_type capacity() const noexcept {
-    return allocated() ? allocation().capacity() : GetInlinedCapacity();
+    return allocated() ? allocation().capacity() : static_cast<size_type>(N);
   }
 
   // `InlinedVector::data()`
@@ -800,19 +804,19 @@
   // `InlinedVector::shrink_to_fit()`
   //
   // Reduces memory usage by freeing unused memory. After this call, calls to
-  // `capacity()` will be equal to `(std::max)(GetInlinedCapacity(), size())`.
+  // `capacity()` will be equal to `max(N, size())`.
   //
-  // If `size() <= GetInlinedCapacity()` and the elements are currently stored
-  // on the heap, they will be moved to the inlined storage and the heap memory
-  // will be deallocated.
+  // If `size() <= N` and the elements are currently stored on the heap, they
+  // will be moved to the inlined storage and the heap memory will be
+  // deallocated.
   //
-  // If `size() > GetInlinedCapacity()` and `size() < capacity()` the elements
-  // will be moved to a smaller heap allocation.
+  // If `size() > N` and `size() < capacity()` the elements will be moved to a
+  // smaller heap allocation.
   void shrink_to_fit() {
     const auto s = size();
     if (ABSL_PREDICT_FALSE(!allocated() || s == capacity())) return;
 
-    if (s <= GetInlinedCapacity()) {
+    if (s <= N) {
       // Move the elements to the inlined storage.
       // We have to do this using a temporary, because `inlined_storage` and
       // `allocation_storage` are in a union field.
@@ -845,88 +849,33 @@
   template <typename H, typename TheT, size_t TheN, typename TheA>
   friend auto AbslHashValue(H h, const InlinedVector<TheT, TheN, TheA>& v) -> H;
 
-  // Holds whether the vector is allocated or not in the lowest bit and the size
-  // in the high bits:
-  //   `size_ = (size << 1) | is_allocated;`
-  class Tag {
-   public:
-    Tag() : size_(0) {}
-    size_type size() const { return size_ / 2; }
-    void add_size(size_type n) { size_ += n * 2; }
-    void set_inline_size(size_type n) { size_ = n * 2; }
-    void set_allocated_size(size_type n) { size_ = (n * 2) + 1; }
-    bool allocated() const { return size_ % 2; }
+  const Tag& tag() const { return storage_.allocator_and_tag_.tag(); }
 
-   private:
-    size_type size_;
-  };
-
-  // Derives from `allocator_type` to use the empty base class optimization.
-  // If the `allocator_type` is stateless, we can store our instance for free.
-  class AllocatorAndTag : private allocator_type {
-   public:
-    explicit AllocatorAndTag(const allocator_type& a) : allocator_type(a) {}
-
-    Tag& tag() { return tag_; }
-    const Tag& tag() const { return tag_; }
-
-    allocator_type& allocator() { return *this; }
-    const allocator_type& allocator() const { return *this; }
-
-   private:
-    Tag tag_;
-  };
-
-  class Allocation {
-   public:
-    Allocation(allocator_type& a, size_type capacity)
-        : capacity_(capacity), buffer_(Create(a, capacity)) {}
-
-    void Dealloc(allocator_type& a) {
-      std::allocator_traits<allocator_type>::deallocate(a, buffer_, capacity_);
-    }
-
-    size_type capacity() const { return capacity_; }
-
-    const_pointer buffer() const { return buffer_; }
-
-    pointer buffer() { return buffer_; }
-
-   private:
-    static pointer Create(allocator_type& a, size_type n) {
-      return std::allocator_traits<allocator_type>::allocate(a, n);
-    }
-
-    size_type capacity_;
-    pointer buffer_;
-  };
-
-  const Tag& tag() const { return allocator_and_tag_.tag(); }
-
-  Tag& tag() { return allocator_and_tag_.tag(); }
+  Tag& tag() { return storage_.allocator_and_tag_.tag(); }
 
   Allocation& allocation() {
-    return reinterpret_cast<Allocation&>(rep_.allocation_storage.allocation);
+    return reinterpret_cast<Allocation&>(
+        storage_.rep_.allocation_storage.allocation);
   }
 
   const Allocation& allocation() const {
     return reinterpret_cast<const Allocation&>(
-        rep_.allocation_storage.allocation);
+        storage_.rep_.allocation_storage.allocation);
   }
 
   void init_allocation(const Allocation& allocation) {
-    new (&rep_.allocation_storage.allocation) Allocation(allocation);
+    new (&storage_.rep_.allocation_storage.allocation) Allocation(allocation);
   }
 
   // TODO(absl-team): investigate whether the reinterpret_cast is appropriate.
   pointer inlined_space() {
     return reinterpret_cast<pointer>(
-        std::addressof(rep_.inlined_storage.inlined[0]));
+        std::addressof(storage_.rep_.inlined_storage.inlined[0]));
   }
 
   const_pointer inlined_space() const {
     return reinterpret_cast<const_pointer>(
-        std::addressof(rep_.inlined_storage.inlined[0]));
+        std::addressof(storage_.rep_.inlined_storage.inlined[0]));
   }
 
   pointer allocated_space() { return allocation().buffer(); }
@@ -934,10 +883,12 @@
   const_pointer allocated_space() const { return allocation().buffer(); }
 
   const allocator_type& allocator() const {
-    return allocator_and_tag_.allocator();
+    return storage_.allocator_and_tag_.allocator();
   }
 
-  allocator_type& allocator() { return allocator_and_tag_.allocator(); }
+  allocator_type& allocator() {
+    return storage_.allocator_and_tag_.allocator();
+  }
 
   bool allocated() const { return tag().allocated(); }
 
@@ -994,7 +945,7 @@
     const size_type s = size();
     assert(s <= capacity());
 
-    size_type target = (std::max)(GetInlinedCapacity(), s + delta);
+    size_type target = (std::max)(N, s + delta);
 
     // Compute new capacity by repeatedly doubling current capacity
     // TODO(psrc): Check and avoid overflow?
@@ -1097,7 +1048,7 @@
   }
 
   void InitAssign(size_type n) {
-    if (n > GetInlinedCapacity()) {
+    if (n > N) {
       Allocation new_allocation(allocator(), n);
       init_allocation(new_allocation);
       UninitializedFill(allocated_space(), allocated_space() + n);
@@ -1109,7 +1060,7 @@
   }
 
   void InitAssign(size_type n, const_reference v) {
-    if (n > GetInlinedCapacity()) {
+    if (n > N) {
       Allocation new_allocation(allocator(), n);
       init_allocation(new_allocation);
       UninitializedFill(allocated_space(), allocated_space() + n, v);
@@ -1267,28 +1218,7 @@
     assert(a->size() == b_size);
   }
 
-  // Stores either the inlined or allocated representation
-  union Rep {
-    using ValueTypeBuffer =
-        absl::aligned_storage_t<sizeof(value_type), alignof(value_type)>;
-    using AllocationBuffer =
-        absl::aligned_storage_t<sizeof(Allocation), alignof(Allocation)>;
-
-    // Structs wrap the buffers to perform indirection that solves a bizarre
-    // compilation error on Visual Studio (all known versions).
-    struct InlinedRep {
-      ValueTypeBuffer inlined[N];
-    };
-    struct AllocatedRep {
-      AllocationBuffer allocation;
-    };
-
-    InlinedRep inlined_storage;
-    AllocatedRep allocation_storage;
-  };
-
-  AllocatorAndTag allocator_and_tag_;
-  Rep rep_;
+  Storage storage_;
 };
 
 // -----------------------------------------------------------------------------
diff --git a/absl/container/inlined_vector_benchmark.cc b/absl/container/inlined_vector_benchmark.cc
index fc928af..867a29e 100644
--- a/absl/container/inlined_vector_benchmark.cc
+++ b/absl/container/inlined_vector_benchmark.cc
@@ -23,17 +23,13 @@
 
 namespace {
 
-using IntVec = absl::InlinedVector<int, 8>;
-
 void BM_InlinedVectorFill(benchmark::State& state) {
-  const int len = state.range(0);
+  absl::InlinedVector<int, 8> v;
+  int val = 10;
   for (auto _ : state) {
-    IntVec v;
-    for (int i = 0; i < len; i++) {
-      v.push_back(i);
-    }
+    benchmark::DoNotOptimize(v);
+    v.push_back(val);
   }
-  state.SetItemsProcessed(static_cast<int64_t>(state.iterations()) * len);
 }
 BENCHMARK(BM_InlinedVectorFill)->Range(0, 1024);
 
@@ -43,23 +39,25 @@
   for (int i = 0; i < len; i++) {
     ia[i] = i;
   }
+  auto* from = ia.get();
+  auto* to = from + len;
   for (auto _ : state) {
-    IntVec v(ia.get(), ia.get() + len);
+    benchmark::DoNotOptimize(from);
+    benchmark::DoNotOptimize(to);
+    absl::InlinedVector<int, 8> v(from, to);
     benchmark::DoNotOptimize(v);
   }
-  state.SetItemsProcessed(static_cast<int64_t>(state.iterations()) * len);
 }
 BENCHMARK(BM_InlinedVectorFillRange)->Range(0, 1024);
 
 void BM_StdVectorFill(benchmark::State& state) {
-  const int len = state.range(0);
+  std::vector<int> v;
+  int val = 10;
   for (auto _ : state) {
-    std::vector<int> v;
-    for (int i = 0; i < len; i++) {
-      v.push_back(i);
-    }
+    benchmark::DoNotOptimize(v);
+    benchmark::DoNotOptimize(val);
+    v.push_back(val);
   }
-  state.SetItemsProcessed(static_cast<int64_t>(state.iterations()) * len);
 }
 BENCHMARK(BM_StdVectorFill)->Range(0, 1024);
 
@@ -124,7 +122,7 @@
   void* user_data;
 };
 
-void BM_InlinedVectorTenAssignments(benchmark::State& state) {
+void BM_InlinedVectorAssignments(benchmark::State& state) {
   const int len = state.range(0);
   using BufferVec = absl::InlinedVector<Buffer, 2>;
 
@@ -133,18 +131,25 @@
 
   BufferVec dst;
   for (auto _ : state) {
-    for (int i = 0; i < 10; ++i) {
-      dst = src;
-    }
+    benchmark::DoNotOptimize(dst);
+    benchmark::DoNotOptimize(src);
+    dst = src;
   }
 }
-BENCHMARK(BM_InlinedVectorTenAssignments)
-    ->Arg(0)->Arg(1)->Arg(2)->Arg(3)->Arg(4)->Arg(20);
+BENCHMARK(BM_InlinedVectorAssignments)
+    ->Arg(0)
+    ->Arg(1)
+    ->Arg(2)
+    ->Arg(3)
+    ->Arg(4)
+    ->Arg(20);
 
 void BM_CreateFromContainer(benchmark::State& state) {
   for (auto _ : state) {
-    absl::InlinedVector<int, 4> x(absl::InlinedVector<int, 4>{1, 2, 3});
-    benchmark::DoNotOptimize(x);
+    absl::InlinedVector<int, 4> src{1, 2, 3};
+    benchmark::DoNotOptimize(src);
+    absl::InlinedVector<int, 4> dst(std::move(src));
+    benchmark::DoNotOptimize(dst);
   }
 }
 BENCHMARK(BM_CreateFromContainer);
@@ -214,6 +219,8 @@
   Vec b;
   for (auto _ : state) {
     using std::swap;
+    benchmark::DoNotOptimize(a);
+    benchmark::DoNotOptimize(b);
     swap(a, b);
   }
 }
@@ -259,60 +266,44 @@
 void BM_InlinedVectorIndexInlined(benchmark::State& state) {
   absl::InlinedVector<int, 8> v = {1, 2, 3, 4, 5, 6, 7};
   for (auto _ : state) {
-    for (int i = 0; i < 1000; ++i) {
-      benchmark::DoNotOptimize(v);
-      benchmark::DoNotOptimize(v[4]);
-    }
+    benchmark::DoNotOptimize(v);
+    benchmark::DoNotOptimize(v[4]);
   }
-  state.SetItemsProcessed(1000 * static_cast<int64_t>(state.iterations()));
 }
 BENCHMARK(BM_InlinedVectorIndexInlined);
 
 void BM_InlinedVectorIndexExternal(benchmark::State& state) {
   absl::InlinedVector<int, 8> v = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
   for (auto _ : state) {
-    for (int i = 0; i < 1000; ++i) {
-      benchmark::DoNotOptimize(v);
-      benchmark::DoNotOptimize(v[4]);
-    }
+    benchmark::DoNotOptimize(v);
+    benchmark::DoNotOptimize(v[4]);
   }
-  state.SetItemsProcessed(1000 * static_cast<int64_t>(state.iterations()));
 }
 BENCHMARK(BM_InlinedVectorIndexExternal);
 
 void BM_StdVectorIndex(benchmark::State& state) {
   std::vector<int> v = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
   for (auto _ : state) {
-    for (int i = 0; i < 1000; ++i) {
-      benchmark::DoNotOptimize(v);
-      benchmark::DoNotOptimize(v[4]);
-    }
+    benchmark::DoNotOptimize(v);
+    benchmark::DoNotOptimize(v[4]);
   }
-  state.SetItemsProcessed(1000 * static_cast<int64_t>(state.iterations()));
 }
 BENCHMARK(BM_StdVectorIndex);
 
-#define UNROLL_2(x)            \
-  benchmark::DoNotOptimize(x); \
-  benchmark::DoNotOptimize(x);
-
-#define UNROLL_4(x) UNROLL_2(x) UNROLL_2(x)
-#define UNROLL_8(x) UNROLL_4(x) UNROLL_4(x)
-#define UNROLL_16(x) UNROLL_8(x) UNROLL_8(x);
-
 void BM_InlinedVectorDataInlined(benchmark::State& state) {
   absl::InlinedVector<int, 8> v = {1, 2, 3, 4, 5, 6, 7};
   for (auto _ : state) {
-    UNROLL_16(v.data());
+    benchmark::DoNotOptimize(v);
+    benchmark::DoNotOptimize(v.data());
   }
-  state.SetItemsProcessed(16 * static_cast<int64_t>(state.iterations()));
 }
 BENCHMARK(BM_InlinedVectorDataInlined);
 
 void BM_InlinedVectorDataExternal(benchmark::State& state) {
   absl::InlinedVector<int, 8> v = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
   for (auto _ : state) {
-    UNROLL_16(v.data());
+    benchmark::DoNotOptimize(v);
+    benchmark::DoNotOptimize(v.data());
   }
   state.SetItemsProcessed(16 * static_cast<int64_t>(state.iterations()));
 }
@@ -321,7 +312,8 @@
 void BM_StdVectorData(benchmark::State& state) {
   std::vector<int> v = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
   for (auto _ : state) {
-    UNROLL_16(v.data());
+    benchmark::DoNotOptimize(v);
+    benchmark::DoNotOptimize(v.data());
   }
   state.SetItemsProcessed(16 * static_cast<int64_t>(state.iterations()));
 }
@@ -330,54 +322,54 @@
 void BM_InlinedVectorSizeInlined(benchmark::State& state) {
   absl::InlinedVector<int, 8> v = {1, 2, 3, 4, 5, 6, 7};
   for (auto _ : state) {
-    UNROLL_16(v.size());
+    benchmark::DoNotOptimize(v);
+    benchmark::DoNotOptimize(v.size());
   }
-  state.SetItemsProcessed(16 * static_cast<int64_t>(state.iterations()));
 }
 BENCHMARK(BM_InlinedVectorSizeInlined);
 
 void BM_InlinedVectorSizeExternal(benchmark::State& state) {
   absl::InlinedVector<int, 8> v = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
   for (auto _ : state) {
-    UNROLL_16(v.size());
+    benchmark::DoNotOptimize(v);
+    benchmark::DoNotOptimize(v.size());
   }
-  state.SetItemsProcessed(16 * static_cast<int64_t>(state.iterations()));
 }
 BENCHMARK(BM_InlinedVectorSizeExternal);
 
 void BM_StdVectorSize(benchmark::State& state) {
   std::vector<int> v = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
   for (auto _ : state) {
-    UNROLL_16(v.size());
+    benchmark::DoNotOptimize(v);
+    benchmark::DoNotOptimize(v.size());
   }
-  state.SetItemsProcessed(16 * static_cast<int64_t>(state.iterations()));
 }
 BENCHMARK(BM_StdVectorSize);
 
 void BM_InlinedVectorEmptyInlined(benchmark::State& state) {
   absl::InlinedVector<int, 8> v = {1, 2, 3, 4, 5, 6, 7};
   for (auto _ : state) {
-    UNROLL_16(v.empty());
+    benchmark::DoNotOptimize(v);
+    benchmark::DoNotOptimize(v.empty());
   }
-  state.SetItemsProcessed(16 * static_cast<int64_t>(state.iterations()));
 }
 BENCHMARK(BM_InlinedVectorEmptyInlined);
 
 void BM_InlinedVectorEmptyExternal(benchmark::State& state) {
   absl::InlinedVector<int, 8> v = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
   for (auto _ : state) {
-    UNROLL_16(v.empty());
+    benchmark::DoNotOptimize(v);
+    benchmark::DoNotOptimize(v.empty());
   }
-  state.SetItemsProcessed(16 * static_cast<int64_t>(state.iterations()));
 }
 BENCHMARK(BM_InlinedVectorEmptyExternal);
 
 void BM_StdVectorEmpty(benchmark::State& state) {
   std::vector<int> v = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
   for (auto _ : state) {
-    UNROLL_16(v.empty());
+    benchmark::DoNotOptimize(v);
+    benchmark::DoNotOptimize(v.empty());
   }
-  state.SetItemsProcessed(16 * static_cast<int64_t>(state.iterations()));
 }
 BENCHMARK(BM_StdVectorEmpty);
 
diff --git a/absl/container/internal/hashtablez_sampler.h b/absl/container/internal/hashtablez_sampler.h
index aff8d15..a308e78 100644
--- a/absl/container/internal/hashtablez_sampler.h
+++ b/absl/container/internal/hashtablez_sampler.h
@@ -34,7 +34,6 @@
 // are using a table in an unusual circumstance where allocation or calling a
 // linux syscall is unacceptable, this could interfere.
 //
-//
 // This utility is internal-only. Use at your own risk.
 
 #ifndef ABSL_CONTAINER_INTERNAL_HASHTABLEZ_SAMPLER_H_
diff --git a/absl/container/internal/inlined_vector.h b/absl/container/internal/inlined_vector.h
new file mode 100644
index 0000000..24059d9
--- /dev/null
+++ b/absl/container/internal/inlined_vector.h
@@ -0,0 +1,126 @@
+// Copyright 2019 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_CONTAINER_INTERNAL_INLINED_VECTOR_INTERNAL_H_
+#define ABSL_CONTAINER_INTERNAL_INLINED_VECTOR_INTERNAL_H_
+
+#include <cstddef>
+#include <iterator>
+#include <memory>
+
+#include "absl/meta/type_traits.h"
+
+namespace absl {
+namespace inlined_vector_internal {
+
+template <typename InlinedVector>
+class Storage;
+
+template <template <typename, size_t, typename> class InlinedVector, typename T,
+          size_t N, typename A>
+class Storage<InlinedVector<T, N, A>> {
+ public:
+  using allocator_type = A;
+  using value_type = typename allocator_type::value_type;
+  using pointer = typename allocator_type::pointer;
+  using const_pointer = typename allocator_type::const_pointer;
+  using reference = typename allocator_type::reference;
+  using const_reference = typename allocator_type::const_reference;
+  using rvalue_reference = typename allocator_type::value_type&&;
+  using size_type = typename allocator_type::size_type;
+  using difference_type = typename allocator_type::difference_type;
+  using iterator = pointer;
+  using const_iterator = const_pointer;
+  using reverse_iterator = std::reverse_iterator<iterator>;
+  using const_reverse_iterator = std::reverse_iterator<const_iterator>;
+
+  explicit Storage(const allocator_type& a) : allocator_and_tag_(a) {}
+
+  // TODO(johnsoncj): Make the below types and members private after migration
+
+  // Holds whether the vector is allocated or not in the lowest bit and the size
+  // in the high bits:
+  //   `size_ = (size << 1) | is_allocated;`
+  class Tag {
+    size_type size_;
+
+   public:
+    Tag() : size_(0) {}
+    size_type size() const { return size_ / 2; }
+    void add_size(size_type n) { size_ += n * 2; }
+    void set_inline_size(size_type n) { size_ = n * 2; }
+    void set_allocated_size(size_type n) { size_ = (n * 2) + 1; }
+    bool allocated() const { return size_ % 2; }
+  };
+
+  // Derives from `allocator_type` to use the empty base class optimization.
+  // If the `allocator_type` is stateless, we can store our instance for free.
+  class AllocatorAndTag : private allocator_type {
+    Tag tag_;
+
+   public:
+    explicit AllocatorAndTag(const allocator_type& a) : allocator_type(a) {}
+    Tag& tag() { return tag_; }
+    const Tag& tag() const { return tag_; }
+    allocator_type& allocator() { return *this; }
+    const allocator_type& allocator() const { return *this; }
+  };
+
+  class Allocation {
+    size_type capacity_;
+    pointer buffer_;
+
+   public:
+    Allocation(allocator_type& a, size_type capacity)
+        : capacity_(capacity), buffer_(Create(a, capacity)) {}
+    void Dealloc(allocator_type& a) {
+      std::allocator_traits<allocator_type>::deallocate(a, buffer_, capacity_);
+    }
+    size_type capacity() const { return capacity_; }
+    const_pointer buffer() const { return buffer_; }
+    pointer buffer() { return buffer_; }
+    static pointer Create(allocator_type& a, size_type n) {
+      return std::allocator_traits<allocator_type>::allocate(a, n);
+    }
+  };
+
+  // Stores either the inlined or allocated representation
+  union Rep {
+    using ValueTypeBuffer =
+        absl::aligned_storage_t<sizeof(value_type), alignof(value_type)>;
+    using AllocationBuffer =
+        absl::aligned_storage_t<sizeof(Allocation), alignof(Allocation)>;
+
+    // Structs wrap the buffers to perform indirection that solves a bizarre
+    // compilation error on Visual Studio (all known versions).
+    struct InlinedRep {
+      ValueTypeBuffer inlined[N];
+    };
+
+    struct AllocatedRep {
+      AllocationBuffer allocation;
+    };
+
+    InlinedRep inlined_storage;
+    AllocatedRep allocation_storage;
+  };
+
+  AllocatorAndTag allocator_and_tag_;
+  Rep rep_;
+};
+
+}  // namespace inlined_vector_internal
+}  // namespace absl
+
+#endif  // ABSL_CONTAINER_INTERNAL_INLINED_VECTOR_INTERNAL_H_
diff --git a/absl/container/internal/raw_hash_set.h b/absl/container/internal/raw_hash_set.h
index c4f198b..85e3334 100644
--- a/absl/container/internal/raw_hash_set.h
+++ b/absl/container/internal/raw_hash_set.h
@@ -446,9 +446,7 @@
 template <class Policy, class Hash, class Eq, class Alloc>
 class raw_hash_set;
 
-inline bool IsValidCapacity(size_t n) {
-  return ((n + 1) & n) == 0 && n >= Group::kWidth - 1;
-}
+inline bool IsValidCapacity(size_t n) { return ((n + 1) & n) == 0 && n > 0; }
 
 // PRECONDITION:
 //   IsValidCapacity(capacity)
@@ -470,13 +468,9 @@
   ctrl[capacity] = kSentinel;
 }
 
-// Rounds up the capacity to the next power of 2 minus 1 and ensures it is
-// greater or equal to Group::kWidth - 1.
+// Rounds up the capacity to the next power of 2 minus 1, with a minimum of 1.
 inline size_t NormalizeCapacity(size_t n) {
-  constexpr size_t kMinCapacity = Group::kWidth - 1;
-  return n <= kMinCapacity
-             ? kMinCapacity
-             : (std::numeric_limits<size_t>::max)() >> LeadingZeros(n);
+  return n ? ~size_t{} >> LeadingZeros(n) : 1;
 }
 
 // We use 7/8th as maximum load factor.
@@ -1507,6 +1501,7 @@
 
   void drop_deletes_without_resize() ABSL_ATTRIBUTE_NOINLINE {
     assert(IsValidCapacity(capacity_));
+    assert(!is_small());
     // Algorithm:
     // - mark all DELETED slots as EMPTY
     // - mark all FULL slots as DELETED
@@ -1572,7 +1567,7 @@
 
   void rehash_and_grow_if_necessary() {
     if (capacity_ == 0) {
-      resize(Group::kWidth - 1);
+      resize(1);
     } else if (size() <= CapacityToGrowth(capacity()) / 2) {
       // Squash DELETED without growing if there is enough capacity.
       drop_deletes_without_resize();
@@ -1619,17 +1614,15 @@
       auto mask = g.MatchEmptyOrDeleted();
       if (mask) {
 #if !defined(NDEBUG)
-        // We want to force small tables to have random entries too, so
-        // in debug build we will randomly insert in either the front or back of
+        // We want to add entropy even when ASLR is not enabled.
+        // In debug build we will randomly insert in either the front or back of
         // the group.
         // TODO(kfm,sbenza): revisit after we do unconditional mixing
-        if (ShouldInsertBackwards(hash, ctrl_))
+        if (!is_small() && ShouldInsertBackwards(hash, ctrl_)) {
           return {seq.offset(mask.HighestBitSet()), seq.index()};
-        else
-          return {seq.offset(mask.LowestBitSet()), seq.index()};
-#else
-        return {seq.offset(mask.LowestBitSet()), seq.index()};
+        }
 #endif
+        return {seq.offset(mask.LowestBitSet()), seq.index()};
       }
       assert(seq.index() < capacity_ && "full table!");
       seq.next();
@@ -1732,11 +1725,28 @@
     }
 
     ctrl_[i] = h;
-    ctrl_[((i - Group::kWidth) & capacity_) + Group::kWidth] = h;
+    ctrl_[((i - Group::kWidth) & capacity_) + 1 +
+          ((Group::kWidth - 1) & capacity_)] = h;
   }
 
   size_t& growth_left() { return settings_.template get<0>(); }
 
+  // The representation of the object has two modes:
+  //  - small: For capacities < kWidth-1
+  //  - large: For the rest.
+  //
+  // Differences:
+  //  - In small mode we are able to use the whole capacity. The extra control
+  //  bytes give us at least one "empty" control byte to stop the iteration.
+  //  This is important to make 1 a valid capacity.
+  //
+  //  - In small mode only the first `capacity()` control bytes after the
+  //  sentinel are valid. The rest contain dummy kEmpty values that do not
+  //  represent a real slot. This is important to take into account on
+  //  find_first_non_full(), where we never try ShouldInsertBackwards() for
+  //  small tables.
+  bool is_small() const { return capacity_ < Group::kWidth - 1; }
+
   hasher& hash_ref() { return settings_.template get<1>(); }
   const hasher& hash_ref() const { return settings_.template get<1>(); }
   key_equal& eq_ref() { return settings_.template get<2>(); }
diff --git a/absl/container/internal/raw_hash_set_test.cc b/absl/container/internal/raw_hash_set_test.cc
index b684571..02fd0bf 100644
--- a/absl/container/internal/raw_hash_set_test.cc
+++ b/absl/container/internal/raw_hash_set_test.cc
@@ -55,13 +55,16 @@
 using ::testing::UnorderedElementsAre;
 
 TEST(Util, NormalizeCapacity) {
-  constexpr size_t kMinCapacity = Group::kWidth - 1;
-  EXPECT_EQ(kMinCapacity, NormalizeCapacity(0));
-  EXPECT_EQ(kMinCapacity, NormalizeCapacity(1));
-  EXPECT_EQ(kMinCapacity, NormalizeCapacity(2));
-  EXPECT_EQ(kMinCapacity, NormalizeCapacity(kMinCapacity));
-  EXPECT_EQ(kMinCapacity * 2 + 1, NormalizeCapacity(kMinCapacity + 1));
-  EXPECT_EQ(kMinCapacity * 2 + 1, NormalizeCapacity(kMinCapacity + 2));
+  EXPECT_EQ(1, NormalizeCapacity(0));
+  EXPECT_EQ(1, NormalizeCapacity(1));
+  EXPECT_EQ(3, NormalizeCapacity(2));
+  EXPECT_EQ(3, NormalizeCapacity(3));
+  EXPECT_EQ(7, NormalizeCapacity(4));
+  EXPECT_EQ(7, NormalizeCapacity(7));
+  EXPECT_EQ(15, NormalizeCapacity(8));
+  EXPECT_EQ(15, NormalizeCapacity(15));
+  EXPECT_EQ(15 * 2 + 1, NormalizeCapacity(15 + 1));
+  EXPECT_EQ(15 * 2 + 1, NormalizeCapacity(15 + 2));
 }
 
 TEST(Util, GrowthAndCapacity) {
@@ -72,10 +75,7 @@
     size_t capacity = NormalizeCapacity(GrowthToLowerboundCapacity(growth));
     // The capacity is large enough for `growth`
     EXPECT_THAT(CapacityToGrowth(capacity), Ge(growth));
-    if (growth < Group::kWidth - 1) {
-      // Fits in one group, that is the minimum capacity.
-      EXPECT_EQ(capacity, Group::kWidth - 1);
-    } else {
+    if (growth != 0 && capacity > 1) {
       // There is no smaller capacity that works.
       EXPECT_THAT(CapacityToGrowth(capacity / 2), Lt(growth));
     }
@@ -135,14 +135,14 @@
 }
 
 TEST(BitMask, LeadingTrailing) {
-  EXPECT_EQ((BitMask<uint32_t, 16>(0b0001101001000000).LeadingZeros()), 3);
-  EXPECT_EQ((BitMask<uint32_t, 16>(0b0001101001000000).TrailingZeros()), 6);
+  EXPECT_EQ((BitMask<uint32_t, 16>(0x00001a40).LeadingZeros()), 3);
+  EXPECT_EQ((BitMask<uint32_t, 16>(0x00001a40).TrailingZeros()), 6);
 
-  EXPECT_EQ((BitMask<uint32_t, 16>(0b0000000000000001).LeadingZeros()), 15);
-  EXPECT_EQ((BitMask<uint32_t, 16>(0b0000000000000001).TrailingZeros()), 0);
+  EXPECT_EQ((BitMask<uint32_t, 16>(0x00000001).LeadingZeros()), 15);
+  EXPECT_EQ((BitMask<uint32_t, 16>(0x00000001).TrailingZeros()), 0);
 
-  EXPECT_EQ((BitMask<uint32_t, 16>(0b1000000000000000).LeadingZeros()), 0);
-  EXPECT_EQ((BitMask<uint32_t, 16>(0b1000000000000000).TrailingZeros()), 15);
+  EXPECT_EQ((BitMask<uint32_t, 16>(0x00008000).LeadingZeros()), 0);
+  EXPECT_EQ((BitMask<uint32_t, 16>(0x00008000).TrailingZeros()), 15);
 
   EXPECT_EQ((BitMask<uint64_t, 8, 3>(0x0000008080808000).LeadingZeros()), 3);
   EXPECT_EQ((BitMask<uint64_t, 8, 3>(0x0000008080808000).TrailingZeros()), 1);
@@ -814,7 +814,7 @@
 TEST(Table, ClearBug) {
   IntTable t;
   constexpr size_t capacity = container_internal::Group::kWidth - 1;
-  constexpr size_t max_size = capacity / 2;
+  constexpr size_t max_size = capacity / 2 + 1;
   for (size_t i = 0; i < max_size; ++i) {
     t.insert(i);
   }
@@ -845,6 +845,25 @@
   EXPECT_TRUE(t.find(0) == t.end());
 }
 
+TEST(Table, EraseMaintainsValidIterator) {
+  IntTable t;
+  const int kNumElements = 100;
+  for (int i = 0; i < kNumElements; i ++) {
+    EXPECT_TRUE(t.emplace(i).second);
+  }
+  EXPECT_EQ(t.size(), kNumElements);
+
+  int num_erase_calls = 0;
+  auto it = t.begin();
+  while (it != t.end()) {
+    t.erase(it++);
+    num_erase_calls++;
+  }
+
+  EXPECT_TRUE(t.empty());
+  EXPECT_EQ(num_erase_calls, kNumElements);
+}
+
 // Collect N bad keys by following algorithm:
 // 1. Create an empty table and reserve it to 2 * N.
 // 2. Insert N random elements.
@@ -1080,6 +1099,7 @@
   ABSL_RAW_LOG(FATAL, "%s", "Unknown Group width");
   return {};
 }
+
 TEST(Table, DISABLED_EnsureNonQuadraticTopNXorSeedByProbeSeqLength) {
   ProbeStatsPerSize stats;
   std::vector<size_t> sizes = {Group::kWidth << 5, Group::kWidth << 10};
@@ -1173,6 +1193,7 @@
   ABSL_RAW_LOG(FATAL, "%s", "Unknown Group width");
   return {};
 }
+
 TEST(Table, DISABLED_EnsureNonQuadraticTopNLinearTransformByProbeSeqLength) {
   ProbeStatsPerSize stats;
   std::vector<size_t> sizes = {Group::kWidth << 5, Group::kWidth << 10};
@@ -1741,73 +1762,49 @@
   EXPECT_FALSE(node);
 }
 
-StringTable MakeSimpleTable(size_t size) {
-  StringTable t;
-  for (size_t i = 0; i < size; ++i) t.emplace(std::string(1, 'A' + i), "");
+IntTable MakeSimpleTable(size_t size) {
+  IntTable t;
+  while (t.size() < size) t.insert(t.size());
   return t;
 }
 
-std::string OrderOfIteration(const StringTable& t) {
-  std::string order;
-  for (auto& p : t) order += p.first;
-  return order;
+std::vector<int> OrderOfIteration(const IntTable& t) {
+  return {t.begin(), t.end()};
 }
 
+// These IterationOrderChanges tests depend on non-deterministic behavior.
+// We are injecting non-determinism from the pointer of the table, but do so in
+// a way that only the page matters. We have to retry enough times to make sure
+// we are touching different memory pages to cause the ordering to change.
+// We also need to keep the old tables around to avoid getting the same memory
+// blocks over and over.
 TEST(Table, IterationOrderChangesByInstance) {
-  // Needs to be more than kWidth elements to be able to affect order.
-  const StringTable reference = MakeSimpleTable(20);
+  for (size_t size : {2, 6, 12, 20}) {
+    const auto reference_table = MakeSimpleTable(size);
+    const auto reference = OrderOfIteration(reference_table);
 
-  // Since order is non-deterministic we can't just try once and verify.
-  // We'll try until we find that order changed. It should not take many tries
-  // for that.
-  // Important: we have to keep the old tables around. Otherwise tcmalloc will
-  // just give us the same blocks and we would be doing the same order again.
-  std::vector<StringTable> garbage;
-  for (int i = 0; i < 10; ++i) {
-    auto trial = MakeSimpleTable(20);
-    if (OrderOfIteration(trial) != OrderOfIteration(reference)) {
-      // We are done.
-      return;
+    std::vector<IntTable> tables;
+    bool found_difference = false;
+    for (int i = 0; !found_difference && i < 500; ++i) {
+      tables.push_back(MakeSimpleTable(size));
+      found_difference = OrderOfIteration(tables.back()) != reference;
     }
-    garbage.push_back(std::move(trial));
+    if (!found_difference) {
+      FAIL()
+          << "Iteration order remained the same across many attempts with size "
+          << size;
+    }
   }
-  FAIL();
 }
 
 TEST(Table, IterationOrderChangesOnRehash) {
-  // Since order is non-deterministic we can't just try once and verify.
-  // We'll try until we find that order changed. It should not take many tries
-  // for that.
-  // Important: we have to keep the old tables around. Otherwise tcmalloc will
-  // just give us the same blocks and we would be doing the same order again.
-  std::vector<StringTable> garbage;
-  for (int i = 0; i < 10; ++i) {
-    // Needs to be more than kWidth elements to be able to affect order.
-    StringTable t = MakeSimpleTable(20);
-    const std::string reference = OrderOfIteration(t);
+  std::vector<IntTable> garbage;
+  for (int i = 0; i < 500; ++i) {
+    auto t = MakeSimpleTable(20);
+    const auto reference = OrderOfIteration(t);
     // Force rehash to the same size.
     t.rehash(0);
-    std::string trial = OrderOfIteration(t);
-    if (trial != reference) {
-      // We are done.
-      return;
-    }
-    garbage.push_back(std::move(t));
-  }
-  FAIL();
-}
-
-TEST(Table, IterationOrderChangesForSmallTables) {
-  // Since order is non-deterministic we can't just try once and verify.
-  // We'll try until we find that order changed.
-  // Important: we have to keep the old tables around. Otherwise tcmalloc will
-  // just give us the same blocks and we would be doing the same order again.
-  StringTable reference_table = MakeSimpleTable(5);
-  const std::string reference = OrderOfIteration(reference_table);
-  std::vector<StringTable> garbage;
-  for (int i = 0; i < 50; ++i) {
-    StringTable t = MakeSimpleTable(5);
-    std::string trial = OrderOfIteration(t);
+    auto trial = OrderOfIteration(t);
     if (trial != reference) {
       // We are done.
       return;
@@ -1817,6 +1814,24 @@
   FAIL() << "Iteration order remained the same across many attempts.";
 }
 
+// Verify that pointers are invalidated as soon as a second element is inserted.
+// This prevents dependency on pointer stability on small tables.
+TEST(Table, UnstablePointers) {
+  IntTable table;
+
+  const auto addr = [&](int i) {
+    return reinterpret_cast<uintptr_t>(&*table.find(i));
+  };
+
+  table.insert(0);
+  const uintptr_t old_ptr = addr(0);
+
+  // This causes a rehash.
+  table.insert(1);
+
+  EXPECT_NE(old_ptr, addr(0));
+}
+
 // Confirm that we assert if we try to erase() end().
 TEST(TableDeathTest, EraseOfEndAsserts) {
   // Use an assert with side-effects to figure out if they are actually enabled.
@@ -1857,6 +1872,7 @@
 #ifdef ADDRESS_SANITIZER
 TEST(Sanitizer, PoisoningUnused) {
   IntTable t;
+  t.reserve(5);
   // Insert something to force an allocation.
   int64_t& v1 = *t.insert(0).first;
 
diff --git a/absl/copts/AbseilConfigureCopts.cmake b/absl/copts/AbseilConfigureCopts.cmake
index f68895d..5084958 100644
--- a/absl/copts/AbseilConfigureCopts.cmake
+++ b/absl/copts/AbseilConfigureCopts.cmake
@@ -5,26 +5,33 @@
 set(ABSL_HAVE_LSAN OFF)
 
 if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
-  set(ABSL_DEFAULT_COPTS "${GCC_FLAGS}")
-  set(ABSL_TEST_COPTS "${GCC_FLAGS};${GCC_TEST_FLAGS}")
-  set(ABSL_EXCEPTIONS_FLAG "${GCC_EXCEPTIONS_FLAGS}")
+  set(ABSL_DEFAULT_COPTS "${ABSL_GCC_FLAGS}")
+  set(ABSL_TEST_COPTS "${ABSL_GCC_FLAGS};${ABSL_GCC_TEST_FLAGS}")
+  set(ABSL_EXCEPTIONS_FLAG "${ABSL_GCC_EXCEPTIONS_FLAGS}")
 elseif("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang")
   # MATCHES so we get both Clang and AppleClang
-  set(ABSL_DEFAULT_COPTS "${LLVM_FLAGS}")
-  set(ABSL_TEST_COPTS "${LLVM_FLAGS};${LLVM_TEST_FLAGS}")
-  set(ABSL_EXCEPTIONS_FLAG "${LLVM_EXCEPTIONS_FLAGS}")
-  if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
-    # AppleClang doesn't have lsan
-    # https://developer.apple.com/documentation/code_diagnostics
-    if(CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 3.5)
-      set(ABSL_LSAN_LINKOPTS "-fsanitize=leak")
-      set(ABSL_HAVE_LSAN ON)
+  if (MSVC)
+    # clang-cl is half MSVC, half LLVM
+    set(ABSL_DEFAULT_COPTS "${ABSL_CLANG_CL_FLAGS}")
+    set(ABSL_TEST_COPTS "${ABSL_CLANG_CL_FLAGS};${ABSL_CLANG_CL_TEST_FLAGS}")
+    set(ABSL_EXCEPTIONS_FLAG "${ABSL_CLANG_CL_EXCEPTIONS_FLAGS}")
+  else()
+    set(ABSL_DEFAULT_COPTS "${ABSL_LLVM_FLAGS}")
+    set(ABSL_TEST_COPTS "${ABSL_LLVM_FLAGS};${ABSL_LLVM_TEST_FLAGS}")
+    set(ABSL_EXCEPTIONS_FLAG "${ABSL_LLVM_EXCEPTIONS_FLAGS}")
+    if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
+      # AppleClang doesn't have lsan
+      # https://developer.apple.com/documentation/code_diagnostics
+      if(CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 3.5)
+        set(ABSL_LSAN_LINKOPTS "-fsanitize=leak")
+        set(ABSL_HAVE_LSAN ON)
+      endif()
     endif()
   endif()
 elseif("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
-  set(ABSL_DEFAULT_COPTS "${MSVC_FLAGS}")
-  set(ABSL_TEST_COPTS "${MSVC_FLAGS};${MSVC_TEST_FLAGS}")
-  set(ABSL_EXCEPTIONS_FLAG "${MSVC_EXCEPTIONS_FLAGS}")
+  set(ABSL_DEFAULT_COPTS "${ABSL_MSVC_FLAGS}")
+  set(ABSL_TEST_COPTS "${ABSL_MSVC_FLAGS};${ABSL_MSVC_TEST_FLAGS}")
+  set(ABSL_EXCEPTIONS_FLAG "${ABSL_MSVC_EXCEPTIONS_FLAGS}")
 else()
   message(WARNING "Unknown compiler: ${CMAKE_CXX_COMPILER}.  Building with no default flags")
   set(ABSL_DEFAULT_COPTS "")
@@ -42,4 +49,4 @@
   set(ABSL_CXX_STANDARD 11)
 else()
   set(ABSL_CXX_STANDARD "${CMAKE_CXX_STANDARD}")
-endif()
\ No newline at end of file
+endif()
diff --git a/absl/copts/GENERATED_AbseilCopts.cmake b/absl/copts/GENERATED_AbseilCopts.cmake
index 80c9819..9031bfa 100644
--- a/absl/copts/GENERATED_AbseilCopts.cmake
+++ b/absl/copts/GENERATED_AbseilCopts.cmake
@@ -3,11 +3,87 @@
 # (1) Edit absl/copts/copts.py.
 # (2) Run `python <path_to_absl>/copts/generate_copts.py`.
 
-list(APPEND GCC_EXCEPTIONS_FLAGS
+list(APPEND ABSL_CLANG_CL_EXCEPTIONS_FLAGS
+    "/U_HAS_EXCEPTIONS"
+    "/D_HAS_EXCEPTIONS=1"
+    "/EHsc"
+)
+
+list(APPEND ABSL_CLANG_CL_FLAGS
+    "/W3"
+    "-Wno-c++98-compat-pedantic"
+    "-Wno-conversion"
+    "-Wno-covered-switch-default"
+    "-Wno-deprecated"
+    "-Wno-disabled-macro-expansion"
+    "-Wno-double-promotion"
+    "-Wno-comma"
+    "-Wno-extra-semi"
+    "-Wno-extra-semi-stmt"
+    "-Wno-packed"
+    "-Wno-padded"
+    "-Wno-sign-compare"
+    "-Wno-float-conversion"
+    "-Wno-float-equal"
+    "-Wno-format-nonliteral"
+    "-Wno-gcc-compat"
+    "-Wno-global-constructors"
+    "-Wno-exit-time-destructors"
+    "-Wno-nested-anon-types"
+    "-Wno-non-modular-include-in-module"
+    "-Wno-old-style-cast"
+    "-Wno-range-loop-analysis"
+    "-Wno-reserved-id-macro"
+    "-Wno-shorten-64-to-32"
+    "-Wno-switch-enum"
+    "-Wno-thread-safety-negative"
+    "-Wno-undef"
+    "-Wno-unknown-warning-option"
+    "-Wno-unreachable-code"
+    "-Wno-unused-macros"
+    "-Wno-weak-vtables"
+    "-Wbitfield-enum-conversion"
+    "-Wbool-conversion"
+    "-Wconstant-conversion"
+    "-Wenum-conversion"
+    "-Wint-conversion"
+    "-Wliteral-conversion"
+    "-Wnon-literal-null-conversion"
+    "-Wnull-conversion"
+    "-Wobjc-literal-conversion"
+    "-Wno-sign-conversion"
+    "-Wstring-conversion"
+    "/DNOMINMAX"
+    "/DWIN32_LEAN_AND_MEAN"
+    "/D_CRT_SECURE_NO_WARNINGS"
+    "/D_SCL_SECURE_NO_WARNINGS"
+    "/D_ENABLE_EXTENDED_ALIGNED_STORAGE"
+)
+
+list(APPEND ABSL_CLANG_CL_TEST_FLAGS
+    "-Wno-c99-extensions"
+    "-Wno-missing-noreturn"
+    "-Wno-missing-prototypes"
+    "-Wno-missing-variable-declarations"
+    "-Wno-null-conversion"
+    "-Wno-shadow"
+    "-Wno-shift-sign-overflow"
+    "-Wno-sign-compare"
+    "-Wno-unused-function"
+    "-Wno-unused-member-function"
+    "-Wno-unused-parameter"
+    "-Wno-unused-private-field"
+    "-Wno-unused-template"
+    "-Wno-used-but-marked-unused"
+    "-Wno-zero-as-null-pointer-constant"
+    "-Wno-gnu-zero-variadic-macro-arguments"
+)
+
+list(APPEND ABSL_GCC_EXCEPTIONS_FLAGS
     "-fexceptions"
 )
 
-list(APPEND GCC_FLAGS
+list(APPEND ABSL_GCC_FLAGS
     "-Wall"
     "-Wextra"
     "-Wcast-qual"
@@ -20,10 +96,11 @@
     "-Wvarargs"
     "-Wvla"
     "-Wwrite-strings"
+    "-Wno-missing-field-initializers"
     "-Wno-sign-compare"
 )
 
-list(APPEND GCC_TEST_FLAGS
+list(APPEND ABSL_GCC_TEST_FLAGS
     "-Wno-conversion-null"
     "-Wno-missing-declarations"
     "-Wno-sign-compare"
@@ -32,11 +109,11 @@
     "-Wno-unused-private-field"
 )
 
-list(APPEND LLVM_EXCEPTIONS_FLAGS
+list(APPEND ABSL_LLVM_EXCEPTIONS_FLAGS
     "-fexceptions"
 )
 
-list(APPEND LLVM_FLAGS
+list(APPEND ABSL_LLVM_FLAGS
     "-Wall"
     "-Wextra"
     "-Weverything"
@@ -84,7 +161,7 @@
     "-Wstring-conversion"
 )
 
-list(APPEND LLVM_TEST_FLAGS
+list(APPEND ABSL_LLVM_TEST_FLAGS
     "-Wno-c99-extensions"
     "-Wno-missing-noreturn"
     "-Wno-missing-prototypes"
@@ -103,28 +180,28 @@
     "-Wno-gnu-zero-variadic-macro-arguments"
 )
 
-list(APPEND MSVC_EXCEPTIONS_FLAGS
+list(APPEND ABSL_MSVC_EXCEPTIONS_FLAGS
     "/U_HAS_EXCEPTIONS"
     "/D_HAS_EXCEPTIONS=1"
     "/EHsc"
 )
 
-list(APPEND MSVC_FLAGS
+list(APPEND ABSL_MSVC_FLAGS
     "/W3"
+    "/DNOMINMAX"
+    "/DWIN32_LEAN_AND_MEAN"
+    "/D_CRT_SECURE_NO_WARNINGS"
+    "/D_SCL_SECURE_NO_WARNINGS"
+    "/D_ENABLE_EXTENDED_ALIGNED_STORAGE"
     "/wd4005"
     "/wd4068"
     "/wd4180"
     "/wd4244"
     "/wd4267"
     "/wd4800"
-    "/DNOMINMAX"
-    "/DWIN32_LEAN_AND_MEAN"
-    "/D_CRT_SECURE_NO_WARNINGS"
-    "/D_SCL_SECURE_NO_WARNINGS"
-    "/D_ENABLE_EXTENDED_ALIGNED_STORAGE"
 )
 
-list(APPEND MSVC_TEST_FLAGS
+list(APPEND ABSL_MSVC_TEST_FLAGS
     "/wd4018"
     "/wd4101"
     "/wd4503"
diff --git a/absl/copts/GENERATED_copts.bzl b/absl/copts/GENERATED_copts.bzl
index a001347..e05a58e 100644
--- a/absl/copts/GENERATED_copts.bzl
+++ b/absl/copts/GENERATED_copts.bzl
@@ -4,11 +4,87 @@
 (2) Run `python <path_to_absl>/copts/generate_copts.py`.
 """
 
-GCC_EXCEPTIONS_FLAGS = [
+ABSL_CLANG_CL_EXCEPTIONS_FLAGS = [
+    "/U_HAS_EXCEPTIONS",
+    "/D_HAS_EXCEPTIONS=1",
+    "/EHsc",
+]
+
+ABSL_CLANG_CL_FLAGS = [
+    "/W3",
+    "-Wno-c++98-compat-pedantic",
+    "-Wno-conversion",
+    "-Wno-covered-switch-default",
+    "-Wno-deprecated",
+    "-Wno-disabled-macro-expansion",
+    "-Wno-double-promotion",
+    "-Wno-comma",
+    "-Wno-extra-semi",
+    "-Wno-extra-semi-stmt",
+    "-Wno-packed",
+    "-Wno-padded",
+    "-Wno-sign-compare",
+    "-Wno-float-conversion",
+    "-Wno-float-equal",
+    "-Wno-format-nonliteral",
+    "-Wno-gcc-compat",
+    "-Wno-global-constructors",
+    "-Wno-exit-time-destructors",
+    "-Wno-nested-anon-types",
+    "-Wno-non-modular-include-in-module",
+    "-Wno-old-style-cast",
+    "-Wno-range-loop-analysis",
+    "-Wno-reserved-id-macro",
+    "-Wno-shorten-64-to-32",
+    "-Wno-switch-enum",
+    "-Wno-thread-safety-negative",
+    "-Wno-undef",
+    "-Wno-unknown-warning-option",
+    "-Wno-unreachable-code",
+    "-Wno-unused-macros",
+    "-Wno-weak-vtables",
+    "-Wbitfield-enum-conversion",
+    "-Wbool-conversion",
+    "-Wconstant-conversion",
+    "-Wenum-conversion",
+    "-Wint-conversion",
+    "-Wliteral-conversion",
+    "-Wnon-literal-null-conversion",
+    "-Wnull-conversion",
+    "-Wobjc-literal-conversion",
+    "-Wno-sign-conversion",
+    "-Wstring-conversion",
+    "/DNOMINMAX",
+    "/DWIN32_LEAN_AND_MEAN",
+    "/D_CRT_SECURE_NO_WARNINGS",
+    "/D_SCL_SECURE_NO_WARNINGS",
+    "/D_ENABLE_EXTENDED_ALIGNED_STORAGE",
+]
+
+ABSL_CLANG_CL_TEST_FLAGS = [
+    "-Wno-c99-extensions",
+    "-Wno-missing-noreturn",
+    "-Wno-missing-prototypes",
+    "-Wno-missing-variable-declarations",
+    "-Wno-null-conversion",
+    "-Wno-shadow",
+    "-Wno-shift-sign-overflow",
+    "-Wno-sign-compare",
+    "-Wno-unused-function",
+    "-Wno-unused-member-function",
+    "-Wno-unused-parameter",
+    "-Wno-unused-private-field",
+    "-Wno-unused-template",
+    "-Wno-used-but-marked-unused",
+    "-Wno-zero-as-null-pointer-constant",
+    "-Wno-gnu-zero-variadic-macro-arguments",
+]
+
+ABSL_GCC_EXCEPTIONS_FLAGS = [
     "-fexceptions",
 ]
 
-GCC_FLAGS = [
+ABSL_GCC_FLAGS = [
     "-Wall",
     "-Wextra",
     "-Wcast-qual",
@@ -21,10 +97,11 @@
     "-Wvarargs",
     "-Wvla",
     "-Wwrite-strings",
+    "-Wno-missing-field-initializers",
     "-Wno-sign-compare",
 ]
 
-GCC_TEST_FLAGS = [
+ABSL_GCC_TEST_FLAGS = [
     "-Wno-conversion-null",
     "-Wno-missing-declarations",
     "-Wno-sign-compare",
@@ -33,11 +110,11 @@
     "-Wno-unused-private-field",
 ]
 
-LLVM_EXCEPTIONS_FLAGS = [
+ABSL_LLVM_EXCEPTIONS_FLAGS = [
     "-fexceptions",
 ]
 
-LLVM_FLAGS = [
+ABSL_LLVM_FLAGS = [
     "-Wall",
     "-Wextra",
     "-Weverything",
@@ -85,7 +162,7 @@
     "-Wstring-conversion",
 ]
 
-LLVM_TEST_FLAGS = [
+ABSL_LLVM_TEST_FLAGS = [
     "-Wno-c99-extensions",
     "-Wno-missing-noreturn",
     "-Wno-missing-prototypes",
@@ -104,28 +181,28 @@
     "-Wno-gnu-zero-variadic-macro-arguments",
 ]
 
-MSVC_EXCEPTIONS_FLAGS = [
+ABSL_MSVC_EXCEPTIONS_FLAGS = [
     "/U_HAS_EXCEPTIONS",
     "/D_HAS_EXCEPTIONS=1",
     "/EHsc",
 ]
 
-MSVC_FLAGS = [
+ABSL_MSVC_FLAGS = [
     "/W3",
+    "/DNOMINMAX",
+    "/DWIN32_LEAN_AND_MEAN",
+    "/D_CRT_SECURE_NO_WARNINGS",
+    "/D_SCL_SECURE_NO_WARNINGS",
+    "/D_ENABLE_EXTENDED_ALIGNED_STORAGE",
     "/wd4005",
     "/wd4068",
     "/wd4180",
     "/wd4244",
     "/wd4267",
     "/wd4800",
-    "/DNOMINMAX",
-    "/DWIN32_LEAN_AND_MEAN",
-    "/D_CRT_SECURE_NO_WARNINGS",
-    "/D_SCL_SECURE_NO_WARNINGS",
-    "/D_ENABLE_EXTENDED_ALIGNED_STORAGE",
 ]
 
-MSVC_TEST_FLAGS = [
+ABSL_MSVC_TEST_FLAGS = [
     "/wd4018",
     "/wd4101",
     "/wd4503",
diff --git a/absl/copts/configure_copts.bzl b/absl/copts/configure_copts.bzl
index 57cd3f6..1655add 100644
--- a/absl/copts/configure_copts.bzl
+++ b/absl/copts/configure_copts.bzl
@@ -6,35 +6,35 @@
 
 load(
     "//absl:copts/GENERATED_copts.bzl",
-    "GCC_EXCEPTIONS_FLAGS",
-    "GCC_FLAGS",
-    "GCC_TEST_FLAGS",
-    "LLVM_EXCEPTIONS_FLAGS",
-    "LLVM_FLAGS",
-    "LLVM_TEST_FLAGS",
-    "MSVC_EXCEPTIONS_FLAGS",
-    "MSVC_FLAGS",
-    "MSVC_TEST_FLAGS",
+    "ABSL_GCC_EXCEPTIONS_FLAGS",
+    "ABSL_GCC_FLAGS",
+    "ABSL_GCC_TEST_FLAGS",
+    "ABSL_LLVM_EXCEPTIONS_FLAGS",
+    "ABSL_LLVM_FLAGS",
+    "ABSL_LLVM_TEST_FLAGS",
+    "ABSL_MSVC_EXCEPTIONS_FLAGS",
+    "ABSL_MSVC_FLAGS",
+    "ABSL_MSVC_TEST_FLAGS",
 )
 
 ABSL_DEFAULT_COPTS = select({
-    "//absl:windows": MSVC_FLAGS,
-    "//absl:llvm_compiler": LLVM_FLAGS,
-    "//conditions:default": GCC_FLAGS,
+    "//absl:windows": ABSL_MSVC_FLAGS,
+    "//absl:llvm_compiler": ABSL_LLVM_FLAGS,
+    "//conditions:default": ABSL_GCC_FLAGS,
 })
 
 # in absence of modules (--compiler=gcc or -c opt), cc_tests leak their copts
 # to their (included header) dependencies and fail to build outside absl
 ABSL_TEST_COPTS = ABSL_DEFAULT_COPTS + select({
-    "//absl:windows": MSVC_TEST_FLAGS,
-    "//absl:llvm_compiler": LLVM_TEST_FLAGS,
-    "//conditions:default": GCC_TEST_FLAGS,
+    "//absl:windows": ABSL_MSVC_TEST_FLAGS,
+    "//absl:llvm_compiler": ABSL_LLVM_TEST_FLAGS,
+    "//conditions:default": ABSL_GCC_TEST_FLAGS,
 })
 
 ABSL_EXCEPTIONS_FLAG = select({
-    "//absl:windows": MSVC_EXCEPTIONS_FLAGS,
-    "//absl:llvm_compiler": LLVM_EXCEPTIONS_FLAGS,
-    "//conditions:default": GCC_EXCEPTIONS_FLAGS,
+    "//absl:windows": ABSL_MSVC_EXCEPTIONS_FLAGS,
+    "//absl:llvm_compiler": ABSL_LLVM_EXCEPTIONS_FLAGS,
+    "//conditions:default": ABSL_GCC_EXCEPTIONS_FLAGS,
 })
 
 ABSL_EXCEPTIONS_FLAG_LINKOPTS = select({
diff --git a/absl/copts/copts.py b/absl/copts/copts.py
index 4da8442..3c9d429 100644
--- a/absl/copts/copts.py
+++ b/absl/copts/copts.py
@@ -10,8 +10,120 @@
 The generated copts are consumed by configure_copts.bzl and
 AbseilConfigureCopts.cmake.
 """
+
+# /Wall with msvc includes unhelpful warnings such as C4711, C4710, ...
+MSVC_BIG_WARNING_FLAGS = [
+    "/W3",
+]
+
+LLVM_BIG_WARNING_FLAGS = [
+    "-Wall",
+    "-Wextra",
+    "-Weverything",
+]
+
+# Docs on single flags is preceded by a comment.
+# Docs on groups of flags is preceded by ###.
+LLVM_DISABLE_WARNINGS_FLAGS = [
+    # Abseil does not support C++98
+    "-Wno-c++98-compat-pedantic",
+    # Turns off all implicit conversion warnings. Most are re-enabled below.
+    "-Wno-conversion",
+    "-Wno-covered-switch-default",
+    "-Wno-deprecated",
+    "-Wno-disabled-macro-expansion",
+    "-Wno-double-promotion",
+    ###
+    # Turned off as they include valid C++ code.
+    "-Wno-comma",
+    "-Wno-extra-semi",
+    "-Wno-extra-semi-stmt",
+    "-Wno-packed",
+    "-Wno-padded",
+    ###
+    # Google style does not use unsigned integers, though STL containers
+    # have unsigned types.
+    "-Wno-sign-compare",
+    ###
+    "-Wno-float-conversion",
+    "-Wno-float-equal",
+    "-Wno-format-nonliteral",
+    # Too aggressive: warns on Clang extensions enclosed in Clang-only
+    # compilation paths.
+    "-Wno-gcc-compat",
+    ###
+    # Some internal globals are necessary. Don't do this at home.
+    "-Wno-global-constructors",
+    "-Wno-exit-time-destructors",
+    ###
+    "-Wno-nested-anon-types",
+    "-Wno-non-modular-include-in-module",
+    "-Wno-old-style-cast",
+    # Warns on preferred usage of non-POD types such as string_view
+    "-Wno-range-loop-analysis",
+    "-Wno-reserved-id-macro",
+    "-Wno-shorten-64-to-32",
+    "-Wno-switch-enum",
+    "-Wno-thread-safety-negative",
+    "-Wno-undef",
+    "-Wno-unknown-warning-option",
+    "-Wno-unreachable-code",
+    # Causes warnings on include guards
+    "-Wno-unused-macros",
+    "-Wno-weak-vtables",
+    ###
+    # Implicit conversion warnings turned off by -Wno-conversion
+    # which are re-enabled below.
+    "-Wbitfield-enum-conversion",
+    "-Wbool-conversion",
+    "-Wconstant-conversion",
+    "-Wenum-conversion",
+    "-Wint-conversion",
+    "-Wliteral-conversion",
+    "-Wnon-literal-null-conversion",
+    "-Wnull-conversion",
+    "-Wobjc-literal-conversion",
+    "-Wno-sign-conversion",
+    "-Wstring-conversion",
+]
+
+LLVM_TEST_DISABLE_WARNINGS_FLAGS = [
+    "-Wno-c99-extensions",
+    "-Wno-missing-noreturn",
+    "-Wno-missing-prototypes",
+    "-Wno-missing-variable-declarations",
+    "-Wno-null-conversion",
+    "-Wno-shadow",
+    "-Wno-shift-sign-overflow",
+    "-Wno-sign-compare",
+    "-Wno-unused-function",
+    "-Wno-unused-member-function",
+    "-Wno-unused-parameter",
+    "-Wno-unused-private-field",
+    "-Wno-unused-template",
+    "-Wno-used-but-marked-unused",
+    "-Wno-zero-as-null-pointer-constant",
+    # gtest depends on this GNU extension being offered.
+    "-Wno-gnu-zero-variadic-macro-arguments",
+]
+
+MSVC_STYLE_EXCEPTIONS_FLAGS = [
+    "/U_HAS_EXCEPTIONS", "/D_HAS_EXCEPTIONS=1", "/EHsc"
+]
+
+MSVC_DEFINES = [
+    "/DNOMINMAX",  # Don't define min and max macros (windows.h)
+    # Don't bloat namespace with incompatible winsock versions.
+    "/DWIN32_LEAN_AND_MEAN",
+    # Don't warn about usage of insecure C functions.
+    "/D_CRT_SECURE_NO_WARNINGS",
+    "/D_SCL_SECURE_NO_WARNINGS",
+    # Introduced in VS 2017 15.8, allow overaligned types in aligned_storage
+    "/D_ENABLE_EXTENDED_ALIGNED_STORAGE",
+]
+
 COPT_VARS = {
-    "GCC_FLAGS": [
+    "ABSL_GCC_FLAGS": [
         "-Wall",
         "-Wextra",
         "-Wcast-qual",
@@ -24,11 +136,15 @@
         "-Wvarargs",
         "-Wvla",  # variable-length array
         "-Wwrite-strings",
+        # gcc-4.x has spurious missing field initializer warnings.
+        # https://gcc.gnu.org/bugzilla/show_bug.cgi?id=36750
+        # Remove when gcc-4.x is no longer supported.
+        "-Wno-missing-field-initializers",
         # Google style does not use unsigned integers, though STL containers
         # have unsigned types.
         "-Wno-sign-compare",
     ],
-    "GCC_TEST_FLAGS": [
+    "ABSL_GCC_TEST_FLAGS": [
         "-Wno-conversion-null",
         "-Wno-missing-declarations",
         "-Wno-sign-compare",
@@ -36,98 +152,15 @@
         "-Wno-unused-parameter",
         "-Wno-unused-private-field",
     ],
-    "GCC_EXCEPTIONS_FLAGS": ["-fexceptions"],
-
-    # Docs on single flags is preceded by a comment.
-    # Docs on groups of flags is preceded by ###.
-    "LLVM_FLAGS": [
-        "-Wall",
-        "-Wextra",
-        "-Weverything",
-        # Abseil does not support C++98
-        "-Wno-c++98-compat-pedantic",
-        # Turns off all implicit conversion warnings. Most are re-enabled below.
-        "-Wno-conversion",
-        "-Wno-covered-switch-default",
-        "-Wno-deprecated",
-        "-Wno-disabled-macro-expansion",
-        "-Wno-double-promotion",
-        ###
-        # Turned off as they include valid C++ code.
-        "-Wno-comma",
-        "-Wno-extra-semi",
-        "-Wno-extra-semi-stmt",
-        "-Wno-packed",
-        "-Wno-padded",
-        ###
-        # Google style does not use unsigned integers, though STL containers
-        # have unsigned types.
-        "-Wno-sign-compare",
-        ###
-        "-Wno-float-conversion",
-        "-Wno-float-equal",
-        "-Wno-format-nonliteral",
-        # Too aggressive: warns on Clang extensions enclosed in Clang-only
-        # compilation paths.
-        "-Wno-gcc-compat",
-        ###
-        # Some internal globals are necessary. Don't do this at home.
-        "-Wno-global-constructors",
-        "-Wno-exit-time-destructors",
-        ###
-        "-Wno-nested-anon-types",
-        "-Wno-non-modular-include-in-module",
-        "-Wno-old-style-cast",
-        # Warns on preferred usage of non-POD types such as string_view
-        "-Wno-range-loop-analysis",
-        "-Wno-reserved-id-macro",
-        "-Wno-shorten-64-to-32",
-        "-Wno-switch-enum",
-        "-Wno-thread-safety-negative",
-        "-Wno-undef",
-        "-Wno-unknown-warning-option",
-        "-Wno-unreachable-code",
-        # Causes warnings on include guards
-        "-Wno-unused-macros",
-        "-Wno-weak-vtables",
-        ###
-        # Implicit conversion warnings turned off by -Wno-conversion
-        # which are re-enabled below.
-        "-Wbitfield-enum-conversion",
-        "-Wbool-conversion",
-        "-Wconstant-conversion",
-        "-Wenum-conversion",
-        "-Wint-conversion",
-        "-Wliteral-conversion",
-        "-Wnon-literal-null-conversion",
-        "-Wnull-conversion",
-        "-Wobjc-literal-conversion",
-        "-Wno-sign-conversion",
-        "-Wstring-conversion",
-    ],
-    "LLVM_TEST_FLAGS": [
-        "-Wno-c99-extensions",
-        "-Wno-missing-noreturn",
-        "-Wno-missing-prototypes",
-        "-Wno-missing-variable-declarations",
-        "-Wno-null-conversion",
-        "-Wno-shadow",
-        "-Wno-shift-sign-overflow",
-        "-Wno-sign-compare",
-        "-Wno-unused-function",
-        "-Wno-unused-member-function",
-        "-Wno-unused-parameter",
-        "-Wno-unused-private-field",
-        "-Wno-unused-template",
-        "-Wno-used-but-marked-unused",
-        "-Wno-zero-as-null-pointer-constant",
-        # gtest depends on this GNU extension being offered.
-        "-Wno-gnu-zero-variadic-macro-arguments",
-    ],
-    "LLVM_EXCEPTIONS_FLAGS": ["-fexceptions"],
-    # /Wall with msvc includes unhelpful warnings such as C4711, C4710, ...
-    "MSVC_FLAGS": [
-        "/W3",
+    "ABSL_GCC_EXCEPTIONS_FLAGS": ["-fexceptions"],
+    "ABSL_LLVM_FLAGS": LLVM_BIG_WARNING_FLAGS + LLVM_DISABLE_WARNINGS_FLAGS,
+    "ABSL_LLVM_TEST_FLAGS": LLVM_TEST_DISABLE_WARNINGS_FLAGS,
+    "ABSL_LLVM_EXCEPTIONS_FLAGS": ["-fexceptions"],
+    "ABSL_CLANG_CL_FLAGS": (MSVC_BIG_WARNING_FLAGS +
+                            LLVM_DISABLE_WARNINGS_FLAGS + MSVC_DEFINES),
+    "ABSL_CLANG_CL_TEST_FLAGS": LLVM_TEST_DISABLE_WARNINGS_FLAGS,
+    "ABSL_CLANG_CL_EXCEPTIONS_FLAGS": MSVC_STYLE_EXCEPTIONS_FLAGS,
+    "ABSL_MSVC_FLAGS": MSVC_BIG_WARNING_FLAGS + MSVC_DEFINES + [
         "/wd4005",  # macro-redefinition
         "/wd4068",  # unknown pragma
         "/wd4180",  # qualifier applied to function type has no meaning; ignored
@@ -135,21 +168,11 @@
         "/wd4267",  # conversion from 'size_t' to 'type', possible loss of data
         # forcing value to bool 'true' or 'false' (performance warning)
         "/wd4800",
-        "/DNOMINMAX",  # Don't define min and max macros (windows.h)
-        # Don't bloat namespace with incompatible winsock versions.
-        "/DWIN32_LEAN_AND_MEAN",
-        # Don't warn about usage of insecure C functions.
-        "/D_CRT_SECURE_NO_WARNINGS",
-        "/D_SCL_SECURE_NO_WARNINGS",
-        # Introduced in VS 2017 15.8, allow overaligned types in aligned_storage
-        "/D_ENABLE_EXTENDED_ALIGNED_STORAGE",
     ],
-    "MSVC_TEST_FLAGS": [
+    "ABSL_MSVC_TEST_FLAGS": [
         "/wd4018",  # signed/unsigned mismatch
         "/wd4101",  # unreferenced local variable
         "/wd4503",  # decorated name length exceeded, name was truncated
     ],
-    "MSVC_EXCEPTIONS_FLAGS": [
-        "/U_HAS_EXCEPTIONS", "/D_HAS_EXCEPTIONS=1", "/EHsc"
-    ]
+    "ABSL_MSVC_EXCEPTIONS_FLAGS": MSVC_STYLE_EXCEPTIONS_FLAGS,
 }
diff --git a/absl/debugging/internal/address_is_readable.h b/absl/debugging/internal/address_is_readable.h
index 64c3f1e..ca8003e 100644
--- a/absl/debugging/internal/address_is_readable.h
+++ b/absl/debugging/internal/address_is_readable.h
@@ -11,7 +11,6 @@
 // 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_DEBUGGING_INTERNAL_ADDRESS_IS_READABLE_H_
 #define ABSL_DEBUGGING_INTERNAL_ADDRESS_IS_READABLE_H_
diff --git a/absl/debugging/internal/demangle_test.cc b/absl/debugging/internal/demangle_test.cc
index d410a23..883b92d 100644
--- a/absl/debugging/internal/demangle_test.cc
+++ b/absl/debugging/internal/demangle_test.cc
@@ -176,6 +176,7 @@
 TEST(DemangleRegression, NegativeLength) {
   TestOnInput("_ZZn4");
 }
+
 TEST(DemangleRegression, DeeplyNestedArrayType) {
   const int depth = 100000;
   std::string data = "_ZStI";
diff --git a/absl/debugging/internal/stacktrace_x86-inl.inc b/absl/debugging/internal/stacktrace_x86-inl.inc
index 248966b..25aa8bd 100644
--- a/absl/debugging/internal/stacktrace_x86-inl.inc
+++ b/absl/debugging/internal/stacktrace_x86-inl.inc
@@ -33,6 +33,7 @@
 #include "absl/debugging/internal/address_is_readable.h"
 #include "absl/debugging/internal/vdso_support.h"  // a no-op on non-elf or non-glibc systems
 #include "absl/debugging/stacktrace.h"
+
 #include "absl/base/internal/raw_logging.h"
 
 #if defined(__linux__) && defined(__i386__)
diff --git a/absl/debugging/leak_check.cc b/absl/debugging/leak_check.cc
index a1cae96..ffe3d1b 100644
--- a/absl/debugging/leak_check.cc
+++ b/absl/debugging/leak_check.cc
@@ -11,6 +11,7 @@
 // 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.
+
 // Wrappers around lsan_interface functions.
 // When lsan is not linked in, these functions are not available,
 // therefore Abseil code which depends on these functions is conditioned on the
diff --git a/absl/debugging/stacktrace.cc b/absl/debugging/stacktrace.cc
index 9935adf..9de8782 100644
--- a/absl/debugging/stacktrace.cc
+++ b/absl/debugging/stacktrace.cc
@@ -46,6 +46,7 @@
 #include ABSL_STACKTRACE_INL_HEADER
 #else
 # error Cannot calculate stack trace: will need to write for your environment
+
 # include "absl/debugging/internal/stacktrace_aarch64-inl.inc"
 # include "absl/debugging/internal/stacktrace_arm-inl.inc"
 # include "absl/debugging/internal/stacktrace_generic-inl.inc"
diff --git a/absl/hash/hash.h b/absl/hash/hash.h
index 94cb674..c0ede35 100644
--- a/absl/hash/hash.h
+++ b/absl/hash/hash.h
@@ -309,4 +309,5 @@
 };
 
 }  // namespace absl
+
 #endif  // ABSL_HASH_HASH_H_
diff --git a/absl/hash/hash_test.cc b/absl/hash/hash_test.cc
index a2430e7..af95938 100644
--- a/absl/hash/hash_test.cc
+++ b/absl/hash/hash_test.cc
@@ -276,6 +276,7 @@
   const std::string dup = "foofoo";
   const std::string large = "large";
   const std::string huge = std::string(5000, 'a');
+
   EXPECT_TRUE(absl::VerifyTypeImplementsAbslHashCorrectly(std::make_tuple(
       std::string(), absl::string_view(),
       std::string(""), absl::string_view(""),
diff --git a/absl/hash/internal/city.h b/absl/hash/internal/city.h
index 1b3b4ef..b43d340 100644
--- a/absl/hash/internal/city.h
+++ b/absl/hash/internal/city.h
@@ -49,7 +49,6 @@
 #include <stdlib.h>  // for size_t.
 #include <utility>
 
-
 namespace absl {
 namespace hash_internal {
 
diff --git a/absl/memory/memory.h b/absl/memory/memory.h
index a0d0714..5a4a1a1 100644
--- a/absl/memory/memory.h
+++ b/absl/memory/memory.h
@@ -47,19 +47,14 @@
 //   X* NewX(int, int);
 //   auto x = WrapUnique(NewX(1, 2));  // 'x' is std::unique_ptr<X>.
 //
-// The purpose of WrapUnique is to automatically deduce the pointer type. If you
-// wish to make the type explicit, for readability reasons or because you prefer
-// to use a base-class pointer rather than a derived one, just use
+// Do not call WrapUnique with an explicit type, as in
+// `WrapUnique<X>(NewX(1, 2))`.  The purpose of WrapUnique is to automatically
+// deduce the pointer type. If you wish to make the type explicit, just use
 // `std::unique_ptr` directly.
 //
-// Example:
-//   X* Factory(int, int);
-//   auto x = std::unique_ptr<X>(Factory(1, 2));
+//   auto x = std::unique_ptr<X>(NewX(1, 2));
 //                  - or -
-//   std::unique_ptr<X> x(Factory(1, 2));
-//
-// This has the added advantage of working whether Factory returns a raw
-// pointer or a `std::unique_ptr`.
+//   std::unique_ptr<X> x(NewX(1, 2));
 //
 // While `absl::WrapUnique` is useful for capturing the output of a raw
 // pointer factory, prefer 'absl::make_unique<T>(args...)' over
diff --git a/absl/meta/type_traits.h b/absl/meta/type_traits.h
index 8a788de..fbdc921 100644
--- a/absl/meta/type_traits.h
+++ b/absl/meta/type_traits.h
@@ -483,6 +483,69 @@
 
 }  // namespace type_traits_internal
 
+// An internal namespace that is required to implement the C++17 swap traits.
+// It is not further nested in type_traits_internal to avoid long symbol names.
+namespace swap_internal {
+
+// Necessary for the traits.
+using std::swap;
+
+// This declaration prevents global `swap` and `absl::swap` overloads from being
+// considered unless ADL picks them up.
+void swap();
+
+template <class T>
+using IsSwappableImpl = decltype(swap(std::declval<T&>(), std::declval<T&>()));
+
+// NOTE: This dance with the default template parameter is for MSVC.
+template <class T,
+          class IsNoexcept = std::integral_constant<
+              bool, noexcept(swap(std::declval<T&>(), std::declval<T&>()))>>
+using IsNothrowSwappableImpl = typename std::enable_if<IsNoexcept::value>::type;
+
+// IsSwappable
+//
+// Determines whether the standard swap idiom is a valid expression for
+// arguments of type `T`.
+template <class T>
+struct IsSwappable
+    : absl::type_traits_internal::is_detected<IsSwappableImpl, T> {};
+
+// IsNothrowSwappable
+//
+// Determines whether the standard swap idiom is a valid expression for
+// arguments of type `T` and is noexcept.
+template <class T>
+struct IsNothrowSwappable
+    : absl::type_traits_internal::is_detected<IsNothrowSwappableImpl, T> {};
+
+// Swap()
+//
+// Performs the swap idiom from a namespace where valid candidates may only be
+// found in `std` or via ADL.
+template <class T, absl::enable_if_t<IsSwappable<T>::value, int> = 0>
+void Swap(T& lhs, T& rhs) noexcept(IsNothrowSwappable<T>::value) {
+  swap(lhs, rhs);
+}
+
+// StdSwapIsUnconstrained
+//
+// Some standard library implementations are broken in that they do not
+// constrain `std::swap`. This will effectively tell us if we are dealing with
+// one of those implementations.
+using StdSwapIsUnconstrained = IsSwappable<void()>;
+
+}  // namespace swap_internal
+
+namespace type_traits_internal {
+
+// Make the swap-related traits/function accessible from this namespace.
+using swap_internal::IsNothrowSwappable;
+using swap_internal::IsSwappable;
+using swap_internal::Swap;
+using swap_internal::StdSwapIsUnconstrained;
+
+}  // namespace type_traits_internal
 }  // namespace absl
 
 #endif  // ABSL_META_TYPE_TRAITS_H_
diff --git a/absl/meta/type_traits_test.cc b/absl/meta/type_traits_test.cc
index 29a6db6..912336e 100644
--- a/absl/meta/type_traits_test.cc
+++ b/absl/meta/type_traits_test.cc
@@ -953,4 +953,85 @@
 #endif  // _LIBCPP_VERSION
 }
 
+namespace adl_namespace {
+
+struct DeletedSwap {
+};
+
+void swap(DeletedSwap&, DeletedSwap&) = delete;
+
+struct SpecialNoexceptSwap {
+  SpecialNoexceptSwap(SpecialNoexceptSwap&&) {}
+  SpecialNoexceptSwap& operator=(SpecialNoexceptSwap&&) { return *this; }
+  ~SpecialNoexceptSwap() = default;
+};
+
+void swap(SpecialNoexceptSwap&, SpecialNoexceptSwap&) noexcept {}
+
+}  // namespace adl_namespace
+
+TEST(TypeTraitsTest, IsSwappable) {
+  using absl::type_traits_internal::IsSwappable;
+  using absl::type_traits_internal::StdSwapIsUnconstrained;
+
+  EXPECT_TRUE(IsSwappable<int>::value);
+
+  struct S {};
+  EXPECT_TRUE(IsSwappable<S>::value);
+
+  struct NoConstruct {
+    NoConstruct(NoConstruct&&) = delete;
+    NoConstruct& operator=(NoConstruct&&) { return *this; }
+    ~NoConstruct() = default;
+  };
+
+  EXPECT_EQ(IsSwappable<NoConstruct>::value, StdSwapIsUnconstrained::value);
+  struct NoAssign {
+    NoAssign(NoAssign&&) {}
+    NoAssign& operator=(NoAssign&&) = delete;
+    ~NoAssign() = default;
+  };
+
+  EXPECT_EQ(IsSwappable<NoAssign>::value, StdSwapIsUnconstrained::value);
+
+  EXPECT_FALSE(IsSwappable<adl_namespace::DeletedSwap>::value);
+
+  EXPECT_TRUE(IsSwappable<adl_namespace::SpecialNoexceptSwap>::value);
+}
+
+TEST(TypeTraitsTest, IsNothrowSwappable) {
+  using absl::type_traits_internal::IsNothrowSwappable;
+  using absl::type_traits_internal::StdSwapIsUnconstrained;
+
+  EXPECT_TRUE(IsNothrowSwappable<int>::value);
+
+  struct NonNoexceptMoves {
+    NonNoexceptMoves(NonNoexceptMoves&&) {}
+    NonNoexceptMoves& operator=(NonNoexceptMoves&&) { return *this; }
+    ~NonNoexceptMoves() = default;
+  };
+
+  EXPECT_FALSE(IsNothrowSwappable<NonNoexceptMoves>::value);
+
+  struct NoConstruct {
+    NoConstruct(NoConstruct&&) = delete;
+    NoConstruct& operator=(NoConstruct&&) { return *this; }
+    ~NoConstruct() = default;
+  };
+
+  EXPECT_FALSE(IsNothrowSwappable<NoConstruct>::value);
+
+  struct NoAssign {
+    NoAssign(NoAssign&&) {}
+    NoAssign& operator=(NoAssign&&) = delete;
+    ~NoAssign() = default;
+  };
+
+  EXPECT_FALSE(IsNothrowSwappable<NoAssign>::value);
+
+  EXPECT_FALSE(IsNothrowSwappable<adl_namespace::DeletedSwap>::value);
+
+  EXPECT_TRUE(IsNothrowSwappable<adl_namespace::SpecialNoexceptSwap>::value);
+}
+
 }  // namespace
diff --git a/absl/numeric/int128.cc b/absl/numeric/int128.cc
index 33f528c..93b62c5 100644
--- a/absl/numeric/int128.cc
+++ b/absl/numeric/int128.cc
@@ -123,6 +123,28 @@
 
   return MakeUint128(0, static_cast<uint64_t>(v));
 }
+
+#if defined(__clang__) && !defined(__SSE3__)
+// Workaround for clang bug: https://bugs.llvm.org/show_bug.cgi?id=38289
+// Casting from long double to uint64_t is miscompiled and drops bits.
+// It is more work, so only use when we need the workaround.
+uint128 MakeUint128FromFloat(long double v) {
+  // Go 50 bits at a time, that fits in a double
+  static_assert(std::numeric_limits<double>::digits >= 50, "");
+  static_assert(std::numeric_limits<long double>::digits <= 150, "");
+  // Undefined behavior if v is not finite or cannot fit into uint128.
+  assert(std::isfinite(v) && v > -1 && v < std::ldexp(1.0L, 128));
+
+  v = std::ldexp(v, -100);
+  uint64_t w0 = static_cast<uint64_t>(static_cast<double>(std::trunc(v)));
+  v = std::ldexp(v - static_cast<double>(w0), 50);
+  uint64_t w1 = static_cast<uint64_t>(static_cast<double>(std::trunc(v)));
+  v = std::ldexp(v - static_cast<double>(w1), 50);
+  uint64_t w2 = static_cast<uint64_t>(static_cast<double>(std::trunc(v)));
+  return (static_cast<uint128>(w0) << 100) | (static_cast<uint128>(w1) << 50) |
+         static_cast<uint128>(w2);
+}
+#endif  // __clang__ && !__SSE3__
 }  // namespace
 
 uint128::uint128(float v) : uint128(MakeUint128FromFloat(v)) {}
diff --git a/absl/numeric/int128.h b/absl/numeric/int128.h
index c0ec03d..2f5b8ad 100644
--- a/absl/numeric/int128.h
+++ b/absl/numeric/int128.h
@@ -53,7 +53,6 @@
 
 namespace absl {
 
-
 // uint128
 //
 // An unsigned 128-bit integer type. The API is meant to mimic an intrinsic type
diff --git a/absl/numeric/int128_test.cc b/absl/numeric/int128_test.cc
index 216ec50..5e1b5ec 100644
--- a/absl/numeric/int128_test.cc
+++ b/absl/numeric/int128_test.cc
@@ -271,6 +271,20 @@
   EXPECT_EQ(static_cast<absl::uint128>(round_to_zero), 0);
   EXPECT_EQ(static_cast<absl::uint128>(round_to_five), 5);
   EXPECT_EQ(static_cast<absl::uint128>(round_to_nine), 9);
+
+  absl::uint128 highest_precision_in_long_double =
+      ~absl::uint128{} >> (128 - std::numeric_limits<long double>::digits);
+  EXPECT_EQ(highest_precision_in_long_double,
+            static_cast<absl::uint128>(
+                static_cast<long double>(highest_precision_in_long_double)));
+  // Apply a mask just to make sure all the bits are the right place.
+  const absl::uint128 arbitrary_mask =
+      absl::MakeUint128(0xa29f622677ded751, 0xf8ca66add076f468);
+  EXPECT_EQ(highest_precision_in_long_double & arbitrary_mask,
+            static_cast<absl::uint128>(static_cast<long double>(
+                highest_precision_in_long_double & arbitrary_mask)));
+
+  EXPECT_EQ(static_cast<absl::uint128>(-0.1L), 0);
 }
 
 TEST(Uint128, OperatorAssignReturnRef) {
diff --git a/absl/strings/BUILD.bazel b/absl/strings/BUILD.bazel
index 8afe817..9640ff4 100644
--- a/absl/strings/BUILD.bazel
+++ b/absl/strings/BUILD.bazel
@@ -12,7 +12,6 @@
 # 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.
-#
 
 load(
     "//absl:copts/configure_copts.bzl",
diff --git a/absl/strings/escaping.h b/absl/strings/escaping.h
index 03ab0ae..fd9be78 100644
--- a/absl/strings/escaping.h
+++ b/absl/strings/escaping.h
@@ -19,7 +19,6 @@
 //
 // This header file contains string utilities involved in escaping and
 // unescaping strings in various ways.
-//
 
 #ifndef ABSL_STRINGS_ESCAPING_H_
 #define ABSL_STRINGS_ESCAPING_H_
@@ -56,7 +55,6 @@
 //     UTF-8. (E.g., `\u2019` unescapes to the three bytes 0xE2, 0x80, and
 //     0x99).
 //
-//
 // If any errors are encountered, this function returns `false`, leaving the
 // `dest` output parameter in an unspecified state, and stores the first
 // encountered error in `error`. To disable error reporting, set `error` to
diff --git a/absl/strings/internal/str_format/arg.h b/absl/strings/internal/str_format/arg.h
index c54cd1a..4d48af0 100644
--- a/absl/strings/internal/str_format/arg.h
+++ b/absl/strings/internal/str_format/arg.h
@@ -35,12 +35,14 @@
     T, void_t<decltype(AbslFormatConvert(
            std::declval<const T&>(), std::declval<ConversionSpec>(),
            std::declval<FormatSink*>()))>> : std::true_type {};
+
 template <typename T>
 class StreamedWrapper;
 
 // If 'v' can be converted (in the printf sense) according to 'conv',
 // then convert it, appending to `sink` and return `true`.
 // Otherwise fail and return `false`.
+
 // Raw pointers.
 struct VoidPtr {
   VoidPtr() = default;
diff --git a/absl/strings/internal/str_format/convert_test.cc b/absl/strings/internal/str_format/convert_test.cc
index 5d77856..99cc0af 100644
--- a/absl/strings/internal/str_format/convert_test.cc
+++ b/absl/strings/internal/str_format/convert_test.cc
@@ -363,6 +363,7 @@
     AllIntTypes;
 INSTANTIATE_TYPED_TEST_CASE_P(TypedFormatConvertTestWithAllIntTypes,
                               TypedFormatConvertTest, AllIntTypes);
+
 TEST_F(FormatConvertTest, Uint128) {
   absl::uint128 v = static_cast<absl::uint128>(0x1234567890abcdef) * 1979;
   absl::uint128 max = absl::Uint128Max();
diff --git a/absl/strings/internal/str_format/extension.h b/absl/strings/internal/str_format/extension.h
index 30235e0..eb81f8a 100644
--- a/absl/strings/internal/str_format/extension.h
+++ b/absl/strings/internal/str_format/extension.h
@@ -13,7 +13,6 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 //
-//
 #ifndef ABSL_STRINGS_INTERNAL_STR_FORMAT_EXTENSION_H_
 #define ABSL_STRINGS_INTERNAL_STR_FORMAT_EXTENSION_H_
 
diff --git a/absl/strings/internal/str_format/extension_test.cc b/absl/strings/internal/str_format/extension_test.cc
index 334a148..4e23fef 100644
--- a/absl/strings/internal/str_format/extension_test.cc
+++ b/absl/strings/internal/str_format/extension_test.cc
@@ -18,6 +18,7 @@
 
 #include <random>
 #include <string>
+
 #include "absl/strings/str_format.h"
 
 #include "gtest/gtest.h"
diff --git a/absl/strings/internal/str_format/output_test.cc b/absl/strings/internal/str_format/output_test.cc
index ca93d1e..6e04abe 100644
--- a/absl/strings/internal/str_format/output_test.cc
+++ b/absl/strings/internal/str_format/output_test.cc
@@ -17,7 +17,6 @@
 #include <sstream>
 #include <string>
 
-
 #include "gmock/gmock.h"
 #include "gtest/gtest.h"
 
diff --git a/absl/strings/internal/utf8.h b/absl/strings/internal/utf8.h
index 445d4c3..0423630 100644
--- a/absl/strings/internal/utf8.h
+++ b/absl/strings/internal/utf8.h
@@ -13,7 +13,6 @@
 // limitations under the License.
 //
 // UTF8 utilities, implemented to reduce dependencies.
-//
 
 #ifndef ABSL_STRINGS_INTERNAL_UTF8_H_
 #define ABSL_STRINGS_INTERNAL_UTF8_H_
diff --git a/absl/strings/numbers_test.cc b/absl/strings/numbers_test.cc
index b7b03ff..ca2ee48 100644
--- a/absl/strings/numbers_test.cc
+++ b/absl/strings/numbers_test.cc
@@ -785,7 +785,7 @@
   if (iters_per_float == 0) iters_per_float = 1;
   for (float f : floats) {
     if (f == last) continue;
-    float testf = nextafter(last, std::numeric_limits<float>::max());
+    float testf = std::nextafter(last, std::numeric_limits<float>::max());
     runnable(testf);
     runnable(-testf);
     last = testf;
@@ -799,7 +799,7 @@
         last = testf;
       }
     }
-    testf = nextafter(f, 0.0f);
+    testf = std::nextafter(f, 0.0f);
     if (testf > last) {
       runnable(testf);
       runnable(-testf);
diff --git a/absl/strings/str_cat.h b/absl/strings/str_cat.h
index 69d6eaa..cba8ceb 100644
--- a/absl/strings/str_cat.h
+++ b/absl/strings/str_cat.h
@@ -42,7 +42,6 @@
 // Floating point numbers are formatted with six-digit precision, which is
 // the default for "std::cout <<" or printf "%g" (the same as "%.6g").
 //
-//
 // You can convert to hexadecimal output rather than decimal output using the
 // `Hex` type contained here. To do so, pass `Hex(my_int)` as a parameter to
 // `StrCat()` or `StrAppend()`. You may specify a minimum hex field width using
diff --git a/absl/strings/str_format.h b/absl/strings/str_format.h
index 486fe0e..539d951 100644
--- a/absl/strings/str_format.h
+++ b/absl/strings/str_format.h
@@ -513,4 +513,5 @@
 }
 
 }  // namespace absl
+
 #endif  // ABSL_STRINGS_STR_FORMAT_H_
diff --git a/absl/strings/str_split.h b/absl/strings/str_split.h
index 8eb5508..7333078 100644
--- a/absl/strings/str_split.h
+++ b/absl/strings/str_split.h
@@ -71,7 +71,6 @@
 //   - `ByLength`
 //   - `MaxSplits`
 //
-//
 // A Delimiter's `Find()` member function will be passed an input `text` that is
 // to be split and a position (`pos`) to begin searching for the next delimiter
 // in `text`. The returned absl::string_view should refer to the next occurrence
diff --git a/absl/strings/string_view.h b/absl/strings/string_view.h
index 524dbeb..f8b2001 100644
--- a/absl/strings/string_view.h
+++ b/absl/strings/string_view.h
@@ -32,7 +32,7 @@
 
 #ifdef ABSL_HAVE_STD_STRING_VIEW
 
-#include <string_view>
+#include <string_view>  // IWYU pragma: export
 
 namespace absl {
 using std::string_view;
@@ -101,7 +101,6 @@
 // example, when splitting a string, `std::vector<absl::string_view>` is a
 // natural data type for the output.
 //
-//
 // When constructed from a source which is nul-terminated, the `string_view`
 // itself will not include the nul-terminator unless a specific size (including
 // the nul) is passed to the constructor. As a result, common idioms that work
@@ -508,6 +507,7 @@
   if (len != y.size()) {
     return false;
   }
+
   return x.data() == y.data() || len <= 0 ||
          memcmp(x.data(), y.data(), len) == 0;
 }
diff --git a/absl/strings/substitute.h b/absl/strings/substitute.h
index a45ff03..507bc4f 100644
--- a/absl/strings/substitute.h
+++ b/absl/strings/substitute.h
@@ -45,7 +45,6 @@
 //   SubstituteAndAppend(&s, "My name is $0 and I am $1 years old.", "Bob", 5);
 //   EXPECT_EQ("Hi. My name is Bob and I am 5 years old.", s);
 //
-//
 // Supported types:
 //   * absl::string_view, std::string, const char* (null is equivalent to "")
 //   * int32_t, int64_t, uint32_t, uint64
diff --git a/absl/synchronization/BUILD.bazel b/absl/synchronization/BUILD.bazel
index ac01904..5e69847 100644
--- a/absl/synchronization/BUILD.bazel
+++ b/absl/synchronization/BUILD.bazel
@@ -178,7 +178,7 @@
     name = "mutex_benchmark_common",
     testonly = 1,
     srcs = ["mutex_benchmark.cc"],
-    copts = ABSL_DEFAULT_COPTS,
+    copts = ABSL_TEST_COPTS,
     visibility = [
         "//absl/synchronization:__pkg__",
     ],
diff --git a/absl/synchronization/internal/create_thread_identity.h b/absl/synchronization/internal/create_thread_identity.h
index b2525b7..ebb16c5 100644
--- a/absl/synchronization/internal/create_thread_identity.h
+++ b/absl/synchronization/internal/create_thread_identity.h
@@ -50,4 +50,5 @@
 
 }  // namespace synchronization_internal
 }  // namespace absl
+
 #endif  // ABSL_SYNCHRONIZATION_INTERNAL_CREATE_THREAD_IDENTITY_H_
diff --git a/absl/synchronization/internal/kernel_timeout.h b/absl/synchronization/internal/kernel_timeout.h
index 543c4a0..61c72e7 100644
--- a/absl/synchronization/internal/kernel_timeout.h
+++ b/absl/synchronization/internal/kernel_timeout.h
@@ -53,6 +53,7 @@
 
   // We explicitly do not support other custom formats: timespec, int64_t nanos.
   // Unify on this and absl::Time, please.
+
   bool has_timeout() const { return ns_ != 0; }
 
  private:
@@ -148,4 +149,5 @@
 
 }  // namespace synchronization_internal
 }  // namespace absl
+
 #endif  // ABSL_SYNCHRONIZATION_INTERNAL_KERNEL_TIMEOUT_H_
diff --git a/absl/synchronization/internal/per_thread_sem.cc b/absl/synchronization/internal/per_thread_sem.cc
index d22539d..b7014fb 100644
--- a/absl/synchronization/internal/per_thread_sem.cc
+++ b/absl/synchronization/internal/per_thread_sem.cc
@@ -89,6 +89,7 @@
   if (identity->blocked_count_ptr != nullptr) {
     identity->blocked_count_ptr->fetch_sub(1, std::memory_order_relaxed);
   }
+
   identity->is_idle.store(false, std::memory_order_relaxed);
   identity->wait_start.store(0, std::memory_order_relaxed);
   return !timeout;
diff --git a/absl/synchronization/internal/per_thread_sem.h b/absl/synchronization/internal/per_thread_sem.h
index d373f63..e7da070 100644
--- a/absl/synchronization/internal/per_thread_sem.h
+++ b/absl/synchronization/internal/per_thread_sem.h
@@ -104,4 +104,5 @@
     absl::synchronization_internal::KernelTimeout t) {
   return AbslInternalPerThreadSemWait(t);
 }
+
 #endif  // ABSL_SYNCHRONIZATION_INTERNAL_PER_THREAD_SEM_H_
diff --git a/absl/synchronization/internal/waiter.cc b/absl/synchronization/internal/waiter.cc
index bab6d1a..74b0965 100644
--- a/absl/synchronization/internal/waiter.cc
+++ b/absl/synchronization/internal/waiter.cc
@@ -40,6 +40,7 @@
 #include <atomic>
 #include <cassert>
 #include <cstdint>
+
 #include "absl/base/internal/raw_logging.h"
 #include "absl/base/internal/thread_identity.h"
 #include "absl/base/optimization.h"
@@ -81,6 +82,7 @@
 #define FUTEX_BITSET_MATCH_ANY 0xFFFFFFFF
 #endif
 #endif
+
 class Futex {
  public:
   static int WaitUntil(std::atomic<int32_t> *v, int32_t val,
diff --git a/absl/synchronization/mutex.cc b/absl/synchronization/mutex.cc
index f4ed0d0..37ffff3 100644
--- a/absl/synchronization/mutex.cc
+++ b/absl/synchronization/mutex.cc
@@ -118,6 +118,10 @@
 
 }  // namespace
 
+static inline bool EvalConditionAnnotated(const Condition *cond, Mutex *mu,
+                                          bool locking, bool trylock,
+                                          bool read_lock);
+
 void RegisterMutexProfiler(void (*fn)(int64_t wait_timestamp)) {
   submit_profile_data.Store(fn);
 }
@@ -233,15 +237,14 @@
   SYNCH_EV_SIGNALALL,
 };
 
-enum {                 // Event flags
-  SYNCH_F_R = 0x01,    // reader event
-  SYNCH_F_LCK = 0x02,  // PostSynchEvent called with mutex held
-  SYNCH_F_ACQ = 0x04,  // event is an acquire
+enum {                    // Event flags
+  SYNCH_F_R = 0x01,       // reader event
+  SYNCH_F_LCK = 0x02,     // PostSynchEvent called with mutex held
+  SYNCH_F_TRY = 0x04,     // TryLock or ReaderTryLock
+  SYNCH_F_UNLOCK = 0x08,  // Unlock or ReaderUnlock
 
   SYNCH_F_LCK_W = SYNCH_F_LCK,
   SYNCH_F_LCK_R = SYNCH_F_LCK | SYNCH_F_R,
-  SYNCH_F_ACQ_W = SYNCH_F_ACQ,
-  SYNCH_F_ACQ_R = SYNCH_F_ACQ | SYNCH_F_R,
 };
 }  // anonymous namespace
 
@@ -250,21 +253,22 @@
   int flags;
   const char *msg;
 } event_properties[] = {
-  { SYNCH_F_LCK_W|SYNCH_F_ACQ_W, "TryLock succeeded " },
-  { 0,                           "TryLock failed " },
-  { SYNCH_F_LCK_R|SYNCH_F_ACQ_R, "ReaderTryLock succeeded " },
-  { 0,                           "ReaderTryLock failed " },
-  {               SYNCH_F_ACQ_W, "Lock blocking " },
-  { SYNCH_F_LCK_W,               "Lock returning " },
-  {               SYNCH_F_ACQ_R, "ReaderLock blocking " },
-  { SYNCH_F_LCK_R,               "ReaderLock returning " },
-  { SYNCH_F_LCK_W,               "Unlock " },
-  { SYNCH_F_LCK_R,               "ReaderUnlock " },
-  { 0,                           "Wait on " },
-  { 0,                           "Wait unblocked " },
-  { 0,                           "Signal on " },
-  { 0,                           "SignalAll on " },
+    {SYNCH_F_LCK_W | SYNCH_F_TRY, "TryLock succeeded "},
+    {0, "TryLock failed "},
+    {SYNCH_F_LCK_R | SYNCH_F_TRY, "ReaderTryLock succeeded "},
+    {0, "ReaderTryLock failed "},
+    {0, "Lock blocking "},
+    {SYNCH_F_LCK_W, "Lock returning "},
+    {0, "ReaderLock blocking "},
+    {SYNCH_F_LCK_R, "ReaderLock returning "},
+    {SYNCH_F_LCK_W | SYNCH_F_UNLOCK, "Unlock "},
+    {SYNCH_F_LCK_R | SYNCH_F_UNLOCK, "ReaderUnlock "},
+    {0, "Wait on "},
+    {0, "Wait unblocked "},
+    {0, "Signal on "},
+    {0, "SignalAll on "},
 };
+
 static absl::base_internal::SpinLock synch_event_mu(
     absl::base_internal::kLinkerInitialized);
 // protects synch_event
@@ -414,9 +418,26 @@
     ABSL_RAW_LOG(INFO, "%s%p %s %s", event_properties[ev].msg, obj,
                  (e == nullptr ? "" : e->name), buffer);
   }
-  if ((event_properties[ev].flags & SYNCH_F_LCK) != 0 && e != nullptr &&
-      e->invariant != nullptr) {
-    (*e->invariant)(e->arg);
+  const int flags = event_properties[ev].flags;
+  if ((flags & SYNCH_F_LCK) != 0 && e != nullptr && e->invariant != nullptr) {
+    // Calling the invariant as is causes problems under ThreadSanitizer.
+    // We are currently inside of Mutex Lock/Unlock and are ignoring all
+    // memory accesses and synchronization. If the invariant transitively
+    // synchronizes something else and we ignore the synchronization, we will
+    // get false positive race reports later.
+    // Reuse EvalConditionAnnotated to properly call into user code.
+    struct local {
+      static bool pred(SynchEvent *ev) {
+        (*ev->invariant)(ev->arg);
+        return false;
+      }
+    };
+    Condition cond(&local::pred, e);
+    Mutex *mu = static_cast<Mutex *>(obj);
+    const bool locking = (flags & SYNCH_F_UNLOCK) == 0;
+    const bool trylock = (flags & SYNCH_F_TRY) != 0;
+    const bool read_lock = (flags & SYNCH_F_R) != 0;
+    EvalConditionAnnotated(&cond, mu, locking, trylock, read_lock);
   }
   UnrefSynchEvent(e);
 }
@@ -1552,7 +1573,7 @@
   ABSL_TSAN_MUTEX_PRE_LOCK(this, TsanFlags(how));
   this->LockSlowLoop(&waitp, flags);
   bool res = waitp.cond != nullptr ||  // => cond known true from LockSlowLoop
-             cond.Eval();
+             EvalConditionAnnotated(&cond, this, true, false, how == kShared);
   ABSL_TSAN_MUTEX_POST_LOCK(this, TsanFlags(how), 0);
   return res;
 }
@@ -1730,12 +1751,17 @@
 
 // Compute cond->Eval() and tell race detectors that we do it under mutex mu.
 static inline bool EvalConditionAnnotated(const Condition *cond, Mutex *mu,
-                                          bool locking, Mutex::MuHow how) {
+                                          bool locking, bool trylock,
+                                          bool read_lock) {
   // Delicate annotation dance.
   // We are currently inside of read/write lock/unlock operation.
   // 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
+  const int flags = read_lock ? __tsan_mutex_read_lock : 0;
+  const int tryflags = flags | (trylock ? __tsan_mutex_try_lock : 0);
+#endif
   if (locking) {
     // For lock we pretend that we have finished the operation,
     // evaluate the predicate, then unlock the mutex and start locking it again
@@ -1743,24 +1769,26 @@
     // Note: we can't simply do POST_LOCK, Eval, PRE_LOCK, because then tsan
     // will think the lock acquisition is recursive which will trigger
     // deadlock detector.
-    ABSL_TSAN_MUTEX_POST_LOCK(mu, TsanFlags(how), 0);
+    ABSL_TSAN_MUTEX_POST_LOCK(mu, tryflags, 0);
     res = cond->Eval();
-    ABSL_TSAN_MUTEX_PRE_UNLOCK(mu, TsanFlags(how));
-    ABSL_TSAN_MUTEX_POST_UNLOCK(mu, TsanFlags(how));
-    ABSL_TSAN_MUTEX_PRE_LOCK(mu, TsanFlags(how));
+    // There is no "try" version of Unlock, so use flags instead of tryflags.
+    ABSL_TSAN_MUTEX_PRE_UNLOCK(mu, flags);
+    ABSL_TSAN_MUTEX_POST_UNLOCK(mu, flags);
+    ABSL_TSAN_MUTEX_PRE_LOCK(mu, tryflags);
   } else {
     // Similarly, for unlock we pretend that we have unlocked the mutex,
     // lock the mutex, evaluate the predicate, and start unlocking it again
     // to match the annotation at the end of outer unlock operation.
-    ABSL_TSAN_MUTEX_POST_UNLOCK(mu, TsanFlags(how));
-    ABSL_TSAN_MUTEX_PRE_LOCK(mu, TsanFlags(how));
-    ABSL_TSAN_MUTEX_POST_LOCK(mu, TsanFlags(how), 0);
+    ABSL_TSAN_MUTEX_POST_UNLOCK(mu, flags);
+    ABSL_TSAN_MUTEX_PRE_LOCK(mu, flags);
+    ABSL_TSAN_MUTEX_POST_LOCK(mu, flags, 0);
     res = cond->Eval();
-    ABSL_TSAN_MUTEX_PRE_UNLOCK(mu, TsanFlags(how));
+    ABSL_TSAN_MUTEX_PRE_UNLOCK(mu, flags);
   }
   // Prevent unused param warnings in non-TSAN builds.
   static_cast<void>(mu);
-  static_cast<void>(how);
+  static_cast<void>(trylock);
+  static_cast<void>(read_lock);
   return res;
 }
 
@@ -1806,7 +1834,8 @@
           v, (how->fast_or | (v & zap_desig_waker[flags & kMuHasBlocked])) +
                  how->fast_add,
           std::memory_order_acquire, std::memory_order_relaxed)) {
-    if (cond == nullptr || EvalConditionAnnotated(cond, this, true, how)) {
+    if (cond == nullptr ||
+        EvalConditionAnnotated(cond, this, true, false, how == kShared)) {
       return true;
     }
     unlock = true;
@@ -1824,7 +1853,8 @@
   }
   this->LockSlowLoop(&waitp, flags);
   return waitp.cond != nullptr ||  // => cond known true from LockSlowLoop
-         cond == nullptr || EvalConditionAnnotated(cond, this, true, how);
+         cond == nullptr ||
+         EvalConditionAnnotated(cond, this, true, false, how == kShared);
 }
 
 // RAW_CHECK_FMT() takes a condition, a printf-style format string, and
@@ -1880,7 +1910,8 @@
                      waitp->how->fast_add,
               std::memory_order_acquire, std::memory_order_relaxed)) {
         if (waitp->cond == nullptr ||
-            EvalConditionAnnotated(waitp->cond, this, true, waitp->how)) {
+            EvalConditionAnnotated(waitp->cond, this, true, false,
+                                   waitp->how == kShared)) {
           break;  // we timed out, or condition true, so return
         }
         this->UnlockSlow(waitp);  // got lock but condition false
@@ -1923,7 +1954,8 @@
                                               std::memory_order_release,
                                               std::memory_order_relaxed));
           if (waitp->cond == nullptr ||
-              EvalConditionAnnotated(waitp->cond, this, true, waitp->how)) {
+              EvalConditionAnnotated(waitp->cond, this, true, false,
+                                     waitp->how == kShared)) {
             break;  // we timed out, or condition true, so return
           }
           this->UnlockSlow(waitp);           // got lock but condition false
diff --git a/absl/synchronization/mutex.h b/absl/synchronization/mutex.h
index cf0f86d..c38e356 100644
--- a/absl/synchronization/mutex.h
+++ b/absl/synchronization/mutex.h
@@ -157,6 +157,7 @@
   //   ABSL_CONST_INIT Mutex mu(absl::kConstInit);
   //   }
   explicit constexpr Mutex(absl::ConstInitType);
+
   ~Mutex();
 
   // Mutex::Lock()
@@ -900,10 +901,12 @@
 
 #ifdef ABSL_INTERNAL_USE_NONPROD_MUTEX
 inline constexpr Mutex::Mutex(absl::ConstInitType) : impl_(absl::kConstInit) {}
+
 #else
 inline Mutex::Mutex() : mu_(0) {
   ABSL_TSAN_MUTEX_CREATE(this, __tsan_mutex_not_static);
 }
+
 inline constexpr Mutex::Mutex(absl::ConstInitType) : mu_(0) {}
 
 inline CondVar::CondVar() : cv_(0) {}
@@ -1047,4 +1050,5 @@
 extern "C" {
 void AbslInternalMutexYield();
 }  // extern "C"
+
 #endif  // ABSL_SYNCHRONIZATION_MUTEX_H_
diff --git a/absl/synchronization/mutex_test.cc b/absl/synchronization/mutex_test.cc
index 53c1f74..1021122 100644
--- a/absl/synchronization/mutex_test.cc
+++ b/absl/synchronization/mutex_test.cc
@@ -1032,9 +1032,9 @@
   ScopedDisableBazelTestWarnings() {
 #ifdef WIN32
     char file[MAX_PATH];
-    if (GetEnvironmentVariable(kVarName, file, sizeof(file)) < sizeof(file)) {
+    if (GetEnvironmentVariableA(kVarName, file, sizeof(file)) < sizeof(file)) {
       warnings_output_file_ = file;
-      SetEnvironmentVariable(kVarName, nullptr);
+      SetEnvironmentVariableA(kVarName, nullptr);
     }
 #else
     const char *file = getenv(kVarName);
@@ -1048,7 +1048,7 @@
   ~ScopedDisableBazelTestWarnings() {
     if (!warnings_output_file_.empty()) {
 #ifdef WIN32
-      SetEnvironmentVariable(kVarName, warnings_output_file_.c_str());
+      SetEnvironmentVariableA(kVarName, warnings_output_file_.c_str());
 #else
       setenv(kVarName, warnings_output_file_.c_str(), 0);
 #endif
diff --git a/absl/synchronization/notification.h b/absl/synchronization/notification.h
index 19f51de..82d111a 100644
--- a/absl/synchronization/notification.h
+++ b/absl/synchronization/notification.h
@@ -110,4 +110,5 @@
 };
 
 }  // namespace absl
+
 #endif  // ABSL_SYNCHRONIZATION_NOTIFICATION_H_
diff --git a/absl/time/CMakeLists.txt b/absl/time/CMakeLists.txt
index d67a486..5909832 100644
--- a/absl/time/CMakeLists.txt
+++ b/absl/time/CMakeLists.txt
@@ -53,6 +53,10 @@
     ${ABSL_DEFAULT_COPTS}
 )
 
+if(APPLE)
+  find_library(CoreFoundation CoreFoundation)
+endif()
+
 absl_cc_library(
   NAME
     time_zone
@@ -78,6 +82,8 @@
     "internal/cctz/src/zone_info_source.cc"
   COPTS
     ${ABSL_DEFAULT_COPTS}
+  DEPS
+    $<$<PLATFORM_ID:Darwin>:${CoreFoundation}>
 )
 
 absl_cc_library(
diff --git a/absl/time/civil_time.h b/absl/time/civil_time.h
index f231e4f..2dfcbd2 100644
--- a/absl/time/civil_time.h
+++ b/absl/time/civil_time.h
@@ -66,7 +66,6 @@
 //
 //   // Valid in C++14
 //   constexpr absl::CivilDay cd(1969, 07, 20);
-//
 
 #ifndef ABSL_TIME_CIVIL_TIME_H_
 #define ABSL_TIME_CIVIL_TIME_H_
diff --git a/absl/time/duration.cc b/absl/time/duration.cc
index 8ce4acb..67791fe 100644
--- a/absl/time/duration.cc
+++ b/absl/time/duration.cc
@@ -901,6 +901,7 @@
   *d = dur;
   return true;
 }
+
 bool ParseFlag(const std::string& text, Duration* dst, std::string* ) {
   return ParseDuration(text, dst);
 }
diff --git a/absl/time/internal/cctz/BUILD.bazel b/absl/time/internal/cctz/BUILD.bazel
index 1fb33c2..903499b 100644
--- a/absl/time/internal/cctz/BUILD.bazel
+++ b/absl/time/internal/cctz/BUILD.bazel
@@ -4,7 +4,7 @@
 # you may not use this file except in compliance with the License.
 # You may obtain a copy of the License at
 #
-#   http://www.apache.org/licenses/LICENSE-2.0
+#   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,
diff --git a/absl/time/internal/cctz/include/cctz/civil_time.h b/absl/time/internal/cctz/include/cctz/civil_time.h
index 0842fa4..f844182 100644
--- a/absl/time/internal/cctz/include/cctz/civil_time.h
+++ b/absl/time/internal/cctz/include/cctz/civil_time.h
@@ -4,7 +4,7 @@
 // you may not use this file except in compliance with the License.
 // You may obtain a copy of the License at
 //
-//   http://www.apache.org/licenses/LICENSE-2.0
+//   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,
diff --git a/absl/time/internal/cctz/include/cctz/civil_time_detail.h b/absl/time/internal/cctz/include/cctz/civil_time_detail.h
index 1c5d097..a5923f1 100644
--- a/absl/time/internal/cctz/include/cctz/civil_time_detail.h
+++ b/absl/time/internal/cctz/include/cctz/civil_time_detail.h
@@ -4,7 +4,7 @@
 // you may not use this file except in compliance with the License.
 // You may obtain a copy of the License at
 //
-//   http://www.apache.org/licenses/LICENSE-2.0
+//   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,
diff --git a/absl/time/internal/cctz/include/cctz/time_zone.h b/absl/time/internal/cctz/include/cctz/time_zone.h
index f28dad1..ef6c4ba 100644
--- a/absl/time/internal/cctz/include/cctz/time_zone.h
+++ b/absl/time/internal/cctz/include/cctz/time_zone.h
@@ -4,7 +4,7 @@
 // you may not use this file except in compliance with the License.
 // You may obtain a copy of the License at
 //
-//   http://www.apache.org/licenses/LICENSE-2.0
+//   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,
@@ -72,7 +72,7 @@
 //
 // See also:
 // - http://www.iana.org/time-zones
-// - http://en.wikipedia.org/wiki/Zoneinfo
+// - https://en.wikipedia.org/wiki/Zoneinfo
 class time_zone {
  public:
   time_zone() : time_zone(nullptr) {}  // Equivalent to UTC
diff --git a/absl/time/internal/cctz/include/cctz/zone_info_source.h b/absl/time/internal/cctz/include/cctz/zone_info_source.h
index 20a7697..2b898d1 100644
--- a/absl/time/internal/cctz/include/cctz/zone_info_source.h
+++ b/absl/time/internal/cctz/include/cctz/zone_info_source.h
@@ -4,7 +4,7 @@
 // you may not use this file except in compliance with the License.
 // You may obtain a copy of the License at
 //
-//   http://www.apache.org/licenses/LICENSE-2.0
+//   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,
diff --git a/absl/time/internal/cctz/src/cctz_benchmark.cc b/absl/time/internal/cctz/src/cctz_benchmark.cc
index a00f47b..445366e 100644
--- a/absl/time/internal/cctz/src/cctz_benchmark.cc
+++ b/absl/time/internal/cctz/src/cctz_benchmark.cc
@@ -4,7 +4,7 @@
 // you may not use this file except in compliance with the License.
 // You may obtain a copy of the License at
 //
-//   http://www.apache.org/licenses/LICENSE-2.0
+//   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,
diff --git a/absl/time/internal/cctz/src/civil_time_detail.cc b/absl/time/internal/cctz/src/civil_time_detail.cc
index 780d5c9..cb40b6b 100644
--- a/absl/time/internal/cctz/src/civil_time_detail.cc
+++ b/absl/time/internal/cctz/src/civil_time_detail.cc
@@ -4,7 +4,7 @@
 // you may not use this file except in compliance with the License.
 // You may obtain a copy of the License at
 //
-//   http://www.apache.org/licenses/LICENSE-2.0
+//   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,
diff --git a/absl/time/internal/cctz/src/civil_time_test.cc b/absl/time/internal/cctz/src/civil_time_test.cc
index faffde4..e590ee3 100644
--- a/absl/time/internal/cctz/src/civil_time_test.cc
+++ b/absl/time/internal/cctz/src/civil_time_test.cc
@@ -4,7 +4,7 @@
 // you may not use this file except in compliance with the License.
 // You may obtain a copy of the License at
 //
-//   http://www.apache.org/licenses/LICENSE-2.0
+//   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,
diff --git a/absl/time/internal/cctz/src/time_zone_fixed.cc b/absl/time/internal/cctz/src/time_zone_fixed.cc
index db9a475..81ece72 100644
--- a/absl/time/internal/cctz/src/time_zone_fixed.cc
+++ b/absl/time/internal/cctz/src/time_zone_fixed.cc
@@ -4,7 +4,7 @@
 // you may not use this file except in compliance with the License.
 // You may obtain a copy of the License at
 //
-//   http://www.apache.org/licenses/LICENSE-2.0
+//   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,
diff --git a/absl/time/internal/cctz/src/time_zone_fixed.h b/absl/time/internal/cctz/src/time_zone_fixed.h
index 489b857..9c1f5e7 100644
--- a/absl/time/internal/cctz/src/time_zone_fixed.h
+++ b/absl/time/internal/cctz/src/time_zone_fixed.h
@@ -4,7 +4,7 @@
 // you may not use this file except in compliance with the License.
 // You may obtain a copy of the License at
 //
-//   http://www.apache.org/licenses/LICENSE-2.0
+//   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,
diff --git a/absl/time/internal/cctz/src/time_zone_format.cc b/absl/time/internal/cctz/src/time_zone_format.cc
index a5c72df..2585098 100644
--- a/absl/time/internal/cctz/src/time_zone_format.cc
+++ b/absl/time/internal/cctz/src/time_zone_format.cc
@@ -4,7 +4,7 @@
 // you may not use this file except in compliance with the License.
 // You may obtain a copy of the License at
 //
-//   http://www.apache.org/licenses/LICENSE-2.0
+//   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,
diff --git a/absl/time/internal/cctz/src/time_zone_format_test.cc b/absl/time/internal/cctz/src/time_zone_format_test.cc
index b99e1c6..705ccdc 100644
--- a/absl/time/internal/cctz/src/time_zone_format_test.cc
+++ b/absl/time/internal/cctz/src/time_zone_format_test.cc
@@ -4,7 +4,7 @@
 // you may not use this file except in compliance with the License.
 // You may obtain a copy of the License at
 //
-//   http://www.apache.org/licenses/LICENSE-2.0
+//   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,
diff --git a/absl/time/internal/cctz/src/time_zone_if.cc b/absl/time/internal/cctz/src/time_zone_if.cc
index 380834a..09aaee5 100644
--- a/absl/time/internal/cctz/src/time_zone_if.cc
+++ b/absl/time/internal/cctz/src/time_zone_if.cc
@@ -4,7 +4,7 @@
 // you may not use this file except in compliance with the License.
 // You may obtain a copy of the License at
 //
-//   http://www.apache.org/licenses/LICENSE-2.0
+//   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,
diff --git a/absl/time/internal/cctz/src/time_zone_if.h b/absl/time/internal/cctz/src/time_zone_if.h
index e4bd386..d000b7a 100644
--- a/absl/time/internal/cctz/src/time_zone_if.h
+++ b/absl/time/internal/cctz/src/time_zone_if.h
@@ -4,7 +4,7 @@
 // you may not use this file except in compliance with the License.
 // You may obtain a copy of the License at
 //
-//   http://www.apache.org/licenses/LICENSE-2.0
+//   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,
diff --git a/absl/time/internal/cctz/src/time_zone_impl.cc b/absl/time/internal/cctz/src/time_zone_impl.cc
index 3062ccd..3cbc674 100644
--- a/absl/time/internal/cctz/src/time_zone_impl.cc
+++ b/absl/time/internal/cctz/src/time_zone_impl.cc
@@ -4,7 +4,7 @@
 // you may not use this file except in compliance with the License.
 // You may obtain a copy of the License at
 //
-//   http://www.apache.org/licenses/LICENSE-2.0
+//   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,
diff --git a/absl/time/internal/cctz/src/time_zone_impl.h b/absl/time/internal/cctz/src/time_zone_impl.h
index 14965ef..b73fad9 100644
--- a/absl/time/internal/cctz/src/time_zone_impl.h
+++ b/absl/time/internal/cctz/src/time_zone_impl.h
@@ -4,7 +4,7 @@
 // you may not use this file except in compliance with the License.
 // You may obtain a copy of the License at
 //
-//   http://www.apache.org/licenses/LICENSE-2.0
+//   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,
diff --git a/absl/time/internal/cctz/src/time_zone_info.cc b/absl/time/internal/cctz/src/time_zone_info.cc
index 6aa80ff..50f7de5 100644
--- a/absl/time/internal/cctz/src/time_zone_info.cc
+++ b/absl/time/internal/cctz/src/time_zone_info.cc
@@ -4,7 +4,7 @@
 // you may not use this file except in compliance with the License.
 // You may obtain a copy of the License at
 //
-//   http://www.apache.org/licenses/LICENSE-2.0
+//   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,
@@ -25,7 +25,7 @@
 // a grain of salt.
 //
 // For more information see tzfile(5), http://www.iana.org/time-zones, or
-// http://en.wikipedia.org/wiki/Zoneinfo.
+// https://en.wikipedia.org/wiki/Zoneinfo.
 //
 // Note that we assume the proleptic Gregorian calendar and 60-second
 // minutes throughout.
diff --git a/absl/time/internal/cctz/src/time_zone_info.h b/absl/time/internal/cctz/src/time_zone_info.h
index 958e9b6..bff639f 100644
--- a/absl/time/internal/cctz/src/time_zone_info.h
+++ b/absl/time/internal/cctz/src/time_zone_info.h
@@ -4,7 +4,7 @@
 // you may not use this file except in compliance with the License.
 // You may obtain a copy of the License at
 //
-//   http://www.apache.org/licenses/LICENSE-2.0
+//   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,
diff --git a/absl/time/internal/cctz/src/time_zone_libc.cc b/absl/time/internal/cctz/src/time_zone_libc.cc
index 2829170..3ab1623 100644
--- a/absl/time/internal/cctz/src/time_zone_libc.cc
+++ b/absl/time/internal/cctz/src/time_zone_libc.cc
@@ -4,7 +4,7 @@
 // you may not use this file except in compliance with the License.
 // You may obtain a copy of the License at
 //
-//   http://www.apache.org/licenses/LICENSE-2.0
+//   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,
diff --git a/absl/time/internal/cctz/src/time_zone_libc.h b/absl/time/internal/cctz/src/time_zone_libc.h
index 4e40c61..0d18e9a 100644
--- a/absl/time/internal/cctz/src/time_zone_libc.h
+++ b/absl/time/internal/cctz/src/time_zone_libc.h
@@ -4,7 +4,7 @@
 // you may not use this file except in compliance with the License.
 // You may obtain a copy of the License at
 //
-//   http://www.apache.org/licenses/LICENSE-2.0
+//   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,
diff --git a/absl/time/internal/cctz/src/time_zone_lookup.cc b/absl/time/internal/cctz/src/time_zone_lookup.cc
index f2d151e..fd04e2d 100644
--- a/absl/time/internal/cctz/src/time_zone_lookup.cc
+++ b/absl/time/internal/cctz/src/time_zone_lookup.cc
@@ -4,7 +4,7 @@
 // you may not use this file except in compliance with the License.
 // You may obtain a copy of the License at
 //
-//   http://www.apache.org/licenses/LICENSE-2.0
+//   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,
@@ -20,6 +20,11 @@
 #include <dlfcn.h>
 #endif
 #endif
+
+#if defined(__APPLE__)
+#include <CoreFoundation/CFTimeZone.h>
+#endif
+
 #include <cstdlib>
 #include <cstring>
 #include <string>
@@ -121,6 +126,11 @@
   char* tz_env = nullptr;
 #if defined(_MSC_VER)
   _dupenv_s(&tz_env, nullptr, "TZ");
+#elif defined(__APPLE__)
+  CFTimeZoneRef system_time_zone = CFTimeZoneCopyDefault();
+  CFStringRef tz_name = CFTimeZoneGetName(system_time_zone);
+  tz_env = strdup(CFStringGetCStringPtr(tz_name, CFStringGetSystemEncoding()));
+  CFRelease(system_time_zone);
 #else
   tz_env = std::getenv("TZ");
 #endif
@@ -153,6 +163,8 @@
 #if defined(_MSC_VER)
   free(localtime_env);
   free(tz_env);
+#elif defined(__APPLE__)
+  free(tz_env);
 #endif
 
   time_zone tz;
diff --git a/absl/time/internal/cctz/src/time_zone_lookup_test.cc b/absl/time/internal/cctz/src/time_zone_lookup_test.cc
index 2e49e48..8068e2f 100644
--- a/absl/time/internal/cctz/src/time_zone_lookup_test.cc
+++ b/absl/time/internal/cctz/src/time_zone_lookup_test.cc
@@ -4,7 +4,7 @@
 // you may not use this file except in compliance with the License.
 // You may obtain a copy of the License at
 //
-//   http://www.apache.org/licenses/LICENSE-2.0
+//   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,
diff --git a/absl/time/internal/cctz/src/time_zone_posix.cc b/absl/time/internal/cctz/src/time_zone_posix.cc
index 75ad8bc..993901a 100644
--- a/absl/time/internal/cctz/src/time_zone_posix.cc
+++ b/absl/time/internal/cctz/src/time_zone_posix.cc
@@ -4,7 +4,7 @@
 // you may not use this file except in compliance with the License.
 // You may obtain a copy of the License at
 //
-//   http://www.apache.org/licenses/LICENSE-2.0
+//   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,
diff --git a/absl/time/internal/cctz/src/time_zone_posix.h b/absl/time/internal/cctz/src/time_zone_posix.h
index ef2a8c1..6a60022 100644
--- a/absl/time/internal/cctz/src/time_zone_posix.h
+++ b/absl/time/internal/cctz/src/time_zone_posix.h
@@ -4,7 +4,7 @@
 // you may not use this file except in compliance with the License.
 // You may obtain a copy of the License at
 //
-//   http://www.apache.org/licenses/LICENSE-2.0
+//   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,
diff --git a/absl/time/internal/cctz/src/zone_info_source.cc b/absl/time/internal/cctz/src/zone_info_source.cc
index 1bc16ae..1324846 100644
--- a/absl/time/internal/cctz/src/zone_info_source.cc
+++ b/absl/time/internal/cctz/src/zone_info_source.cc
@@ -4,7 +4,7 @@
 // you may not use this file except in compliance with the License.
 // You may obtain a copy of the License at
 //
-//   http://www.apache.org/licenses/LICENSE-2.0
+//   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,
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/iso3166.tab b/absl/time/internal/cctz/testdata/zoneinfo/iso3166.tab
index c2e0f8e..4e4a5c3 100644
--- a/absl/time/internal/cctz/testdata/zoneinfo/iso3166.tab
+++ b/absl/time/internal/cctz/testdata/zoneinfo/iso3166.tab
@@ -10,7 +10,7 @@
 #
 # 1.  ISO 3166-1 alpha-2 country code, current as of
 #     ISO 3166-1 N905 (2016-11-15).  See: Updates on ISO 3166-1
-#     http://isotc.iso.org/livelink/livelink/Open/16944257
+#     https://isotc.iso.org/livelink/livelink/Open/16944257
 # 2.  The usual English name for the coded region,
 #     chosen so that alphabetic sorting of subsets produces helpful lists.
 #     This is not the same as the English name in the ISO 3166 tables.
diff --git a/absl/time/time.cc b/absl/time/time.cc
index 799bf85..977a951 100644
--- a/absl/time/time.cc
+++ b/absl/time/time.cc
@@ -41,6 +41,7 @@
 #include "absl/time/internal/cctz/include/cctz/time_zone.h"
 
 namespace cctz = absl::time_internal::cctz;
+
 namespace absl {
 
 namespace {
diff --git a/absl/time/time.h b/absl/time/time.h
index 59e1dc6..594396c 100644
--- a/absl/time/time.h
+++ b/absl/time/time.h
@@ -58,7 +58,6 @@
 //   std::string s = absl::FormatTime(
 //       "My flight will land in Sydney on %Y-%m-%d at %H:%M:%S",
 //       landing, syd);
-//
 
 #ifndef ABSL_TIME_TIME_H_
 #define ABSL_TIME_TIME_H_
@@ -569,7 +568,6 @@
 // The `absl::Time` class represents an instant in time as a count of clock
 // ticks of some granularity (resolution) from some starting point (epoch).
 //
-//
 // `absl::Time` uses a resolution that is high enough to avoid loss in
 // precision, and a range that is wide enough to avoid overflow, when
 // converting between tick counts in most Google time scales (i.e., resolution
@@ -1450,6 +1448,7 @@
 }
 
 }  // namespace time_internal
+
 constexpr Duration Nanoseconds(int64_t n) {
   return time_internal::FromInt64(n, std::nano{});
 }
diff --git a/absl/types/any.h b/absl/types/any.h
index e750f48..f3a3281 100644
--- a/absl/types/any.h
+++ b/absl/types/any.h
@@ -58,7 +58,7 @@
 
 #ifdef ABSL_HAVE_STD_ANY
 
-#include <any>
+#include <any>  // IWYU pragma: export
 
 namespace absl {
 using std::any;
diff --git a/absl/types/any_exception_safety_test.cc b/absl/types/any_exception_safety_test.cc
index 00d0fb7..5d7d8a5 100644
--- a/absl/types/any_exception_safety_test.cc
+++ b/absl/types/any_exception_safety_test.cc
@@ -135,6 +135,7 @@
   EXPECT_TRUE(strong_empty_any_tester.Test(assign_val));
   EXPECT_TRUE(strong_empty_any_tester.Test(move));
 }
+
 // libstdc++ std::any fails this test
 #if !defined(ABSL_HAVE_STD_ANY)
 TEST(AnyExceptionSafety, Emplace) {
diff --git a/absl/types/internal/variant.h b/absl/types/internal/variant.h
index 4926b32..5ca66e2 100644
--- a/absl/types/internal/variant.h
+++ b/absl/types/internal/variant.h
@@ -15,7 +15,6 @@
 // Implementation details of absl/types/variant.h, pulled into a
 // separate file to avoid cluttering the top of the API header with
 // implementation details.
-//
 
 #ifndef ABSL_TYPES_variant_internal_H_
 #define ABSL_TYPES_variant_internal_H_
@@ -1549,8 +1548,8 @@
   variant<Types...>* w;
   template <std::size_t I>
   void operator()(SizeT<I>) const {
-    using std::swap;
-    swap(VariantCoreAccess::Access<I>(*v), VariantCoreAccess::Access<I>(*w));
+    type_traits_internal::Swap(VariantCoreAccess::Access<I>(*v),
+                               VariantCoreAccess::Access<I>(*w));
   }
 
   void operator()(SizeT<variant_npos>) const {}
diff --git a/absl/types/optional.h b/absl/types/optional.h
index 0c1213f..f0ae9a1 100644
--- a/absl/types/optional.h
+++ b/absl/types/optional.h
@@ -36,11 +36,12 @@
 #define ABSL_TYPES_OPTIONAL_H_
 
 #include "absl/base/config.h"
+#include "absl/memory/memory.h"
 #include "absl/utility/utility.h"
 
 #ifdef ABSL_HAVE_STD_OPTIONAL
 
-#include <optional>
+#include <optional>  // IWYU pragma: export
 
 namespace absl {
 using std::bad_optional_access;
@@ -60,7 +61,6 @@
 #include <utility>
 
 #include "absl/base/attributes.h"
-#include "absl/memory/memory.h"
 #include "absl/meta/type_traits.h"
 #include "absl/types/bad_optional_access.h"
 
@@ -114,10 +114,6 @@
 //      need the inline variable support in C++17 for external linkage.
 //    * Throws `absl::bad_optional_access` instead of
 //      `std::bad_optional_access`.
-//    * `optional::swap()` and `absl::swap()` relies on
-//      `std::is_(nothrow_)swappable()`, which has been introduced in C++17.
-//      As a workaround, we assume `is_swappable()` is always `true`
-//      and `is_nothrow_swappable()` is the same as `std::is_trivial()`.
 //    * `make_optional()` cannot be declared `constexpr` due to the absence of
 //      guaranteed copy elision.
 //    * The move constructor's `noexcept` specification is stronger, i.e. if the
@@ -404,23 +400,24 @@
 };
 
 template <typename T>
-constexpr copy_traits get_ctor_copy_traits() {
-  return std::is_copy_constructible<T>::value
-             ? copy_traits::copyable
-             : std::is_move_constructible<T>::value ? copy_traits::movable
-                                                    : copy_traits::non_movable;
-}
+struct ctor_copy_traits {
+  static constexpr copy_traits traits =
+      std::is_copy_constructible<T>::value
+          ? copy_traits::copyable
+          : std::is_move_constructible<T>::value ? copy_traits::movable
+                                                 : copy_traits::non_movable;
+};
 
 template <typename T>
-constexpr copy_traits get_assign_copy_traits() {
-  return absl::is_copy_assignable<T>::value &&
-                 std::is_copy_constructible<T>::value
-             ? copy_traits::copyable
-             : absl::is_move_assignable<T>::value &&
-                       std::is_move_constructible<T>::value
-                   ? copy_traits::movable
-                   : copy_traits::non_movable;
-}
+struct assign_copy_traits {
+  static constexpr copy_traits traits =
+      absl::is_copy_assignable<T>::value && std::is_copy_constructible<T>::value
+          ? copy_traits::copyable
+          : absl::is_move_assignable<T>::value &&
+                    std::is_move_constructible<T>::value
+                ? copy_traits::movable
+                : copy_traits::non_movable;
+};
 
 // Whether T is constructible or convertible from optional<U>.
 template <typename T, typename U>
@@ -486,9 +483,9 @@
 template <typename T>
 class optional : private optional_internal::optional_data<T>,
                  private optional_internal::optional_ctor_base<
-                     optional_internal::get_ctor_copy_traits<T>()>,
+                     optional_internal::ctor_copy_traits<T>::traits>,
                  private optional_internal::optional_assign_base<
-                     optional_internal::get_assign_copy_traits<T>()> {
+                     optional_internal::assign_copy_traits<T>::traits> {
   using data_base = optional_internal::optional_data<T>;
 
  public:
@@ -513,10 +510,11 @@
   // the arguments `std::forward<Args>(args)...`  within the `optional`.
   // (The `in_place_t` is a tag used to indicate that the contained object
   // should be constructed in-place.)
-  //
-  // TODO(absl-team): Add std::is_constructible<T, Args&&...> SFINAE.
-  template <typename... Args>
-  constexpr explicit optional(in_place_t, Args&&... args)
+  template <typename InPlaceT, typename... Args,
+            absl::enable_if_t<absl::conjunction<
+                std::is_same<InPlaceT, in_place_t>,
+                std::is_constructible<T, Args&&...> >::value>* = nullptr>
+  constexpr explicit optional(InPlaceT, Args&&... args)
       : data_base(in_place_t(), absl::forward<Args>(args)...) {}
 
   // Constructs a non-empty `optional` direct-initialized value of type `T` from
@@ -752,11 +750,10 @@
   // Swap, standard semantics
   void swap(optional& rhs) noexcept(
       std::is_nothrow_move_constructible<T>::value&&
-          std::is_trivial<T>::value) {
+          type_traits_internal::IsNothrowSwappable<T>::value) {
     if (*this) {
       if (rhs) {
-        using std::swap;
-        swap(**this, *rhs);
+        type_traits_internal::Swap(**this, *rhs);
       } else {
         rhs.construct(std::move(**this));
         this->destruct();
@@ -908,12 +905,10 @@
 //
 // Performs a swap between two `absl::optional` objects, using standard
 // semantics.
-//
-// NOTE: we assume `is_swappable()` is always `true`. A compile error will
-// result if this is not the case.
-template <typename T,
-          typename std::enable_if<std::is_move_constructible<T>::value,
-                                  bool>::type = false>
+template <typename T, typename std::enable_if<
+                          std::is_move_constructible<T>::value &&
+                              type_traits_internal::IsSwappable<T>::value,
+                          bool>::type = false>
 void swap(optional<T>& a, optional<T>& b) noexcept(noexcept(a.swap(b))) {
   a.swap(b);
 }
diff --git a/absl/types/optional_test.cc b/absl/types/optional_test.cc
index b93aa98..0665488 100644
--- a/absl/types/optional_test.cc
+++ b/absl/types/optional_test.cc
@@ -157,6 +157,16 @@
   NonMovable& operator=(NonMovable&&) = delete;
 };
 
+struct NoDefault {
+  NoDefault() = delete;
+  NoDefault(const NoDefault&) {}
+  NoDefault& operator=(const NoDefault&) { return *this; }
+};
+
+struct ConvertsFromInPlaceT {
+  ConvertsFromInPlaceT(absl::in_place_t) {}  // NOLINT
+};
+
 TEST(optionalTest, DefaultConstructor) {
   absl::optional<int> empty;
   EXPECT_FALSE(empty);
@@ -337,16 +347,18 @@
   static_assert((*opt2).x == ConstexprType::kCtorInitializerList, "");
 #endif
 
-  // TODO(absl-team): uncomment these when std::is_constructible<T, Args&&...>
-  // SFINAE is added to optional::optional(absl::in_place_t, Args&&...).
-  // struct I {
-  //   I(absl::in_place_t);
-  // };
+  EXPECT_FALSE((std::is_constructible<absl::optional<ConvertsFromInPlaceT>,
+                                      absl::in_place_t>::value));
+  EXPECT_FALSE((std::is_constructible<absl::optional<ConvertsFromInPlaceT>,
+                                      const absl::in_place_t&>::value));
+  EXPECT_TRUE(
+      (std::is_constructible<absl::optional<ConvertsFromInPlaceT>,
+                             absl::in_place_t, absl::in_place_t>::value));
 
-  // EXPECT_FALSE((std::is_constructible<absl::optional<I>,
-  // absl::in_place_t>::value));
-  // EXPECT_FALSE((std::is_constructible<absl::optional<I>, const
-  // absl::in_place_t&>::value));
+  EXPECT_FALSE((std::is_constructible<absl::optional<NoDefault>,
+                                      absl::in_place_t>::value));
+  EXPECT_FALSE((std::is_constructible<absl::optional<NoDefault>,
+                                      absl::in_place_t&&>::value));
 }
 
 // template<U=T> optional(U&&);
@@ -1624,4 +1636,29 @@
   EXPECT_TRUE(absl::is_copy_assignable<absl::optional<AnyLike>>::value);
 }
 
+#if !defined(ABSL_HAVE_STD_OPTIONAL) && !defined(_LIBCPP_VERSION)
+struct NestedClassBug {
+  struct Inner {
+    bool dummy = false;
+  };
+  absl::optional<Inner> value;
+};
+
+TEST(optionalTest, InPlaceTSFINAEBug) {
+  NestedClassBug b;
+  ((void)b);
+  using Inner = NestedClassBug::Inner;
+
+  EXPECT_TRUE((std::is_default_constructible<Inner>::value));
+  EXPECT_TRUE((std::is_constructible<Inner>::value));
+  EXPECT_TRUE(
+      (std::is_constructible<absl::optional<Inner>, absl::in_place_t>::value));
+
+  absl::optional<Inner> o(absl::in_place);
+  EXPECT_TRUE(o.has_value());
+  o.emplace();
+  EXPECT_TRUE(o.has_value());
+}
+#endif  // !defined(ABSL_HAVE_STD_OPTIONAL) && !defined(_LIBCPP_VERSION)
+
 }  // namespace
diff --git a/absl/types/variant.h b/absl/types/variant.h
index 9652e3b..ebd52d2 100644
--- a/absl/types/variant.h
+++ b/absl/types/variant.h
@@ -47,7 +47,7 @@
 
 #ifdef ABSL_HAVE_STD_VARIANT
 
-#include <variant>
+#include <variant>  // IWYU pragma: export
 
 namespace absl {
 using std::bad_variant_access;
@@ -129,7 +129,12 @@
 // type (in which case, they will be swapped) or to two different types (in
 // which case the values will need to be moved).
 //
-template <typename... Ts>
+template <
+    typename... Ts,
+    absl::enable_if_t<
+        absl::conjunction<std::is_move_constructible<Ts>...,
+                          type_traits_internal::IsSwappable<Ts>...>::value,
+        int> = 0>
 void swap(variant<Ts...>& v, variant<Ts...>& w) noexcept(noexcept(v.swap(w))) {
   v.swap(w);
 }
@@ -688,12 +693,12 @@
   //
   // Swaps the values of two variant objects.
   //
-  // TODO(calabrese)
-  //   `variant::swap()` and `swap()` rely on `std::is_(nothrow)_swappable()`
-  //   which is introduced in C++17. So we assume `is_swappable()` is always
-  //   true and `is_nothrow_swappable()` is same as `std::is_trivial()`.
   void swap(variant& rhs) noexcept(
-      absl::conjunction<std::is_trivial<T0>, std::is_trivial<Tn>...>::value) {
+      absl::conjunction<
+          std::is_nothrow_move_constructible<T0>,
+          std::is_nothrow_move_constructible<Tn>...,
+          type_traits_internal::IsNothrowSwappable<T0>,
+          type_traits_internal::IsNothrowSwappable<Tn>...>::value) {
     return variant_internal::VisitIndices<sizeof...(Tn) + 1>::Run(
         variant_internal::Swap<T0, Tn...>{this, &rhs}, rhs.index());
   }
diff --git a/absl/types/variant_exception_safety_test.cc b/absl/types/variant_exception_safety_test.cc
index 086fcff..76beb59 100644
--- a/absl/types/variant_exception_safety_test.cc
+++ b/absl/types/variant_exception_safety_test.cc
@@ -24,6 +24,7 @@
 #include "absl/base/config.h"
 #include "absl/base/internal/exception_safety_testing.h"
 #include "absl/memory/memory.h"
+
 // See comment in absl/base/config.h
 #if !defined(ABSL_INTERNAL_MSVC_2017_DBG_MODE)
 
@@ -315,6 +316,12 @@
     EXPECT_FALSE(tester.WithContracts(strong_guarantee).Test());
   }
   {
+    // libstdc++ introduced a regression between 2018-09-25 and 2019-01-06.
+    // The fix is targeted for gcc-9.
+    // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=87431#c7
+    // https://gcc.gnu.org/viewcvs/gcc?view=revision&revision=267614
+#if !(defined(ABSL_HAVE_STD_VARIANT) && \
+      defined(_GLIBCXX_RELEASE) && _GLIBCXX_RELEASE == 8)
     // - otherwise (index() != j), equivalent to
     // emplace<j>(get<j>(std::move(rhs)))
     // - If an exception is thrown during the call to Tj's move construction
@@ -330,6 +337,8 @@
                       auto copy = rhs;
                       *lhs = std::move(copy);
                     }));
+#endif  // !(defined(ABSL_HAVE_STD_VARIANT) &&
+        //   defined(_GLIBCXX_RELEASE) && _GLIBCXX_RELEASE == 8)
   }
 }
 
diff --git a/absl/types/variant_test.cc b/absl/types/variant_test.cc
index 9df702d..ab40ed2 100644
--- a/absl/types/variant_test.cc
+++ b/absl/types/variant_test.cc
@@ -561,6 +561,7 @@
 }
 
 #ifdef ABSL_HAVE_EXCEPTIONS
+
 // See comment in absl/base/config.h
 #if defined(ABSL_INTERNAL_MSVC_2017_DBG_MODE)
 TEST(VariantTest, DISABLED_TestDtorValuelessByException)
diff --git a/absl/utility/utility.h b/absl/utility/utility.h
index 62ce6f3..853c1fb 100644
--- a/absl/utility/utility.h
+++ b/absl/utility/utility.h
@@ -35,7 +35,6 @@
 //  https://en.cppreference.com/w/cpp/utility/integer_sequence
 //  https://en.cppreference.com/w/cpp/utility/apply
 //  http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3658.html
-//
 
 #ifndef ABSL_UTILITY_UTILITY_H_
 #define ABSL_UTILITY_UTILITY_H_
diff --git a/ci/cmake_install_test.sh b/ci/cmake_install_test.sh
new file mode 100755
index 0000000..e54b783
--- /dev/null
+++ b/ci/cmake_install_test.sh
@@ -0,0 +1,33 @@
+#!/bin/bash
+#
+# Copyright 2019 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.
+
+set -euox pipefail
+
+if [ -z ${ABSEIL_ROOT:-} ]; then
+  ABSEIL_ROOT="$(realpath $(dirname ${0})/..)"
+fi
+
+time docker run \
+    --volume="${ABSEIL_ROOT}:/abseil-cpp:ro" \
+    --workdir=/abseil-cpp \
+    --tmpfs=/buildfs:exec \
+    --cap-add=SYS_PTRACE \
+    --rm \
+    -e CFLAGS="-Werror" \
+    -e CXXFLAGS="-Werror" \
+    gcr.io/google.com/absl-177019/linux_gcc-4.8:20190316 \
+    /bin/bash CMake/install_test_project/test.sh
+
diff --git a/ci/linux_clang-latest_libcxx_bazel.sh b/ci/linux_clang-latest_libcxx_bazel.sh
new file mode 100755
index 0000000..741e48c
--- /dev/null
+++ b/ci/linux_clang-latest_libcxx_bazel.sh
@@ -0,0 +1,62 @@
+#!/bin/bash
+#
+# Copyright 2019 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.
+
+# This script that can be invoked to test abseil-cpp in a hermetic environment
+# using a Docker image on Linux. You must have Docker installed to use this
+# script.
+
+set -euox pipefail
+
+if [ -z ${ABSEIL_ROOT:-} ]; then
+  ABSEIL_ROOT="$(realpath $(dirname ${0})/..)"
+fi
+
+if [ -z ${STD:-} ]; then
+  STD="c++11 c++14 c++17"
+fi
+
+if [ -z ${COMPILATION_MODE:-} ]; then
+  COMPILATION_MODE="fastbuild opt"
+fi
+
+for std in ${STD}; do
+  for compilation_mode in ${COMPILATION_MODE}; do
+    echo "--------------------------------------------------------------------"
+    echo "Testing with --compilation_mode=${compilation_mode} and --std=${std}"
+
+    time docker run \
+      --volume="${ABSEIL_ROOT}:/abseil-cpp:ro" \
+      --workdir=/abseil-cpp \
+      --cap-add=SYS_PTRACE \
+      --rm \
+      -e CC="/opt/llvm/clang/bin/clang" \
+      -e BAZEL_COMPILER="llvm" \
+      -e BAZEL_CXXOPTS="-std=${std}:-nostdinc++" \
+      -e BAZEL_LINKOPTS="-L/opt/llvm/libcxx/lib:-lc++:-lc++abi:-lm:-Wl,-rpath=/opt/llvm/libcxx/lib" \
+      -e CPLUS_INCLUDE_PATH="/opt/llvm/libcxx/include/c++/v1" \
+      gcr.io/google.com/absl-177019/linux_clang-latest:20190313 \
+      /usr/local/bin/bazel test ... \
+        --compilation_mode=${compilation_mode} \
+        --copt=-Werror \
+        --define="absl=1" \
+        --keep_going \
+        --show_timestamps \
+        --test_env="GTEST_INSTALL_FAILURE_SIGNAL_HANDLER=1" \
+        --test_env="TZDIR=/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo" \
+        --test_output=errors \
+        --test_tag_filters=-benchmark
+  done
+done
diff --git a/ci/linux_clang-latest_libstdcxx_bazel.sh b/ci/linux_clang-latest_libstdcxx_bazel.sh
new file mode 100755
index 0000000..d703a77
--- /dev/null
+++ b/ci/linux_clang-latest_libstdcxx_bazel.sh
@@ -0,0 +1,61 @@
+#!/bin/bash
+#
+# Copyright 2019 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.
+
+# This script that can be invoked to test abseil-cpp in a hermetic environment
+# using a Docker image on Linux. You must have Docker installed to use this
+# script.
+
+set -euox pipefail
+
+if [ -z ${ABSEIL_ROOT:-} ]; then
+  ABSEIL_ROOT="$(realpath $(dirname ${0})/..)"
+fi
+
+if [ -z ${STD:-} ]; then
+  STD="c++11 c++14 c++17"
+fi
+
+if [ -z ${COMPILATION_MODE:-} ]; then
+  COMPILATION_MODE="fastbuild opt"
+fi
+
+for std in ${STD}; do
+  for compilation_mode in ${COMPILATION_MODE}; do
+    echo "--------------------------------------------------------------------"
+    echo "Testing with --compilation_mode=${compilation_mode} and --std=${std}"
+
+    time docker run \
+      --volume="${ABSEIL_ROOT}:/abseil-cpp:ro" \
+      --workdir=/abseil-cpp \
+      --cap-add=SYS_PTRACE \
+      --rm \
+      -e CC="/opt/llvm/clang/bin/clang" \
+      -e BAZEL_COMPILER="llvm" \
+      -e BAZEL_CXXOPTS="-std=${std}" \
+      -e CPLUS_INCLUDE_PATH="/usr/include/c++/6" \
+      gcr.io/google.com/absl-177019/linux_clang-latest:20190313 \
+      /usr/local/bin/bazel test ... \
+        --compilation_mode=${compilation_mode} \
+        --copt=-Werror \
+        --define="absl=1" \
+        --keep_going \
+        --show_timestamps \
+        --test_env="GTEST_INSTALL_FAILURE_SIGNAL_HANDLER=1" \
+        --test_env="TZDIR=/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo" \
+        --test_output=errors \
+        --test_tag_filters=-benchmark
+  done
+done
diff --git a/ci/linux_gcc-4.8_libstdcxx_cmake.sh b/ci/linux_gcc-4.8_libstdcxx_cmake.sh
new file mode 100755
index 0000000..4f964e2
--- /dev/null
+++ b/ci/linux_gcc-4.8_libstdcxx_cmake.sh
@@ -0,0 +1,61 @@
+#!/bin/bash
+#
+# Copyright 2019 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.
+
+# TODO(absl-team): This script isn't fully hermetic because
+# -DABSL_USE_GOOGLETEST_HEAD=ON means that this script isn't pinned to a fixed
+# version of GoogleTest. This means that an upstream change to GoogleTest could
+# break this test. Fix this by allowing this script to pin to a known-good
+# version of GoogleTest.
+
+set -euox pipefail
+
+if [ -z ${ABSEIL_ROOT:-} ]; then
+  ABSEIL_ROOT="$(realpath $(dirname ${0})/..)"
+fi
+
+if [ -z ${ABSL_CMAKE_CXX_STANDARDS:-} ]; then
+  ABSL_CMAKE_CXX_STANDARDS="11 14"
+fi
+
+if [ -z ${ABSL_CMAKE_BUILD_TYPES:-} ]; then
+  ABSL_CMAKE_BUILD_TYPES="Debug Release"
+fi
+
+for std in ${ABSL_CMAKE_CXX_STANDARDS}; do
+  for compilation_mode in ${ABSL_CMAKE_BUILD_TYPES}; do
+    echo "--------------------------------------------------------------------"
+    echo "Testing with CMAKE_BUILD_TYPE=${compilation_mode} and -std=c++${std}"
+
+    time docker run \
+      --volume="${ABSEIL_ROOT}:/abseil-cpp:ro" \
+      --workdir=/abseil-cpp \
+      --tmpfs=/buildfs:exec \
+      --cap-add=SYS_PTRACE \
+      --rm \
+      -e CFLAGS="-Werror" \
+      -e CXXFLAGS="-Werror" \
+      gcr.io/google.com/absl-177019/linux_gcc-4.8:20190316 \
+      /bin/bash -c "
+        cd /buildfs && \
+        cmake /abseil-cpp \
+          -DABSL_USE_GOOGLETEST_HEAD=ON \
+          -DABSL_RUN_TESTS=ON \
+          -DCMAKE_BUILD_TYPE=${compilation_mode} \
+          -DCMAKE_CXX_STANDARD=${std} && \
+        make -j$(nproc) VERBOSE=1 && \
+        ctest -j$(nproc) --output-on-failure"
+  done
+done
diff --git a/ci/linux_gcc-latest_libstdcxx_bazel.sh b/ci/linux_gcc-latest_libstdcxx_bazel.sh
new file mode 100755
index 0000000..e14a019
--- /dev/null
+++ b/ci/linux_gcc-latest_libstdcxx_bazel.sh
@@ -0,0 +1,59 @@
+#!/bin/bash
+#
+# Copyright 2019 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.
+
+# This script that can be invoked to test abseil-cpp in a hermetic environment
+# using a Docker image on Linux. You must have Docker installed to use this
+# script.
+
+set -euox pipefail
+
+if [ -z ${ABSEIL_ROOT:-} ]; then
+  ABSEIL_ROOT="$(realpath $(dirname ${0})/..)"
+fi
+
+if [ -z ${STD:-} ]; then
+  STD="c++11 c++14 c++17"
+fi
+
+if [ -z ${COMPILATION_MODE:-} ]; then
+  COMPILATION_MODE="fastbuild opt"
+fi
+
+for std in ${STD}; do
+  for compilation_mode in ${COMPILATION_MODE}; do
+    echo "--------------------------------------------------------------------"
+    echo "Testing with --compilation_mode=${compilation_mode} and --std=${std}"
+
+    time docker run \
+      --volume="${ABSEIL_ROOT}:/abseil-cpp:ro" \
+      --workdir=/abseil-cpp \
+      --cap-add=SYS_PTRACE \
+      --rm \
+      -e CC="/usr/local/bin/gcc" \
+      -e BAZEL_CXXOPTS="-std=${std}" \
+      gcr.io/google.com/absl-177019/linux_gcc-latest:20190318 \
+      /usr/local/bin/bazel test ... \
+        --compilation_mode=${compilation_mode} \
+        --copt=-Werror \
+        --define="absl=1" \
+        --keep_going \
+        --show_timestamps \
+        --test_env="GTEST_INSTALL_FAILURE_SIGNAL_HANDLER=1" \
+        --test_env="TZDIR=/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo" \
+        --test_output=errors \
+        --test_tag_filters=-benchmark
+  done
+done