diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog
index 4de7cc8517496cfd9a69c519167448d492e01925..fd61db5c9ee6cc4bd29ce6ec6f37eb692d88d218 100644
--- a/libstdc++-v3/ChangeLog
+++ b/libstdc++-v3/ChangeLog
@@ -1,3 +1,28 @@
+2018-11-27  Jonathan Wakely  <jwakely@redhat.com>
+
+	PR libstdc++/67843
+	* acinclude.m4 (GLIBCXX_ENABLE_LOCK_POLICY): Add new macro
+	that defines _GLIBCXX_HAVE_ATOMIC_LOCK_POLICY.
+	* config.h.in: Regenerate.
+	* configure: Regenerate.
+	* configure.ac: Use GLIBCXX_ENABLE_LOCK_POLICY.
+	* doc/xml/manual/configure.xml: Document new configure option.
+	* include/bits/fs_dir.h (directory_iterator): Use __shared_ptr
+	instead of shared_ptr.
+	(recursive_directory_iterator): Likewise.
+	(__shared_ptr<_Dir>): Add explicit instantiation declaration.
+	(__shared_ptr<recursive_directory_iterator::_Dir_stack>): Likewise.
+	* include/bits/shared_ptr_base.h (__allocate_shared, __make_shared):
+	Add default template argument for _Lock_policy template parameter.
+	* include/ext/concurrence.h (__default_lock_policy): Check macro
+	_GLIBCXX_HAVE_ATOMIC_LOCK_POLICY instead of checking if the current
+	target supports the builtins for compare-and-swap.
+	* src/filesystem/std-dir.cc (__shared_ptr<_Dir>): Add explicit
+	instantiation definition.
+	(__shared_ptr<recursive_directory_iterator::_Dir_stack>): Likewise.
+	(directory_iterator, recursive_directory_iterator): Use __make_shared
+	instead of make_shared.
+
 2018-11-27  François Dumont  <fdumont@gcc.gnu.org>
 
 	PR libstdc++/88199
diff --git a/libstdc++-v3/acinclude.m4 b/libstdc++-v3/acinclude.m4
index 82a25e5f2f113f36cfc12e666ae5a7d6136e3c05..6bcd29dc8c3f71b2df9da7e166c85bb571d0f9a5 100644
--- a/libstdc++-v3/acinclude.m4
+++ b/libstdc++-v3/acinclude.m4
@@ -3562,6 +3562,72 @@ EOF
 
 ])
 
+dnl
+dnl Set default lock policy for synchronizing shared_ptr reference counting.
+dnl
+dnl --with-libstdcxx-lock-policy=auto
+dnl	Use atomic operations for shared_ptr reference counting only if
+dnl	the default target supports atomic compare-and-swap.
+dnl --with-libstdcxx-lock-policy=atomic
+dnl	Use atomic operations for shared_ptr reference counting.
+dnl --with-libstdcxx-lock-policy=mutex
+dnl	Use a mutex to synchronize shared_ptr reference counting.
+dnl
+dnl This controls the value of __gnu_cxx::__default_lock_policy, which
+dnl determines how shared_ptr reference counts are synchronized.
+dnl The option "atomic" means that atomic operations should be used,
+dnl "mutex" means that a mutex will be used. The default option, "auto",
+dnl will check if the target supports the compiler-generated builtins
+dnl for atomic compare-and-swap operations for 2-byte and 4-byte integers,
+dnl and will use "atomic" if supported, "mutex" otherwise.
+dnl This option is ignored if the thread model used by GCC is "single",
+dnl as no synchronization is used at all in that case.
+dnl This option affects the library ABI (except in the "single" thread model).
+dnl
+dnl Defines _GLIBCXX_HAVE_ATOMIC_LOCK_POLICY to 1 if atomics should be used.
+dnl
+AC_DEFUN([GLIBCXX_ENABLE_LOCK_POLICY], [
+
+  AC_ARG_WITH([libstdcxx-lock-policy],
+    AC_HELP_STRING([--with-libstdcxx-lock-policy={atomic,mutex,auto}],
+      [synchronization policy for shared_ptr reference counting [default=auto]]),
+              [libstdcxx_atomic_lock_policy=$withval],
+              [libstdcxx_atomic_lock_policy=auto])
+
+  case "$libstdcxx_atomic_lock_policy" in
+    atomic|mutex|auto) ;;
+    *) AC_MSG_ERROR([Invalid argument for --with-libstdcxx-lock-policy]) ;;
+  esac
+  AC_MSG_CHECKING([for lock policy for shared_ptr reference counts])
+
+  if test x"$libstdcxx_atomic_lock_policy" = x"auto"; then
+    AC_LANG_SAVE
+    AC_LANG_CPLUSPLUS
+    ac_save_CXXFLAGS="$CXXFLAGS"
+
+    dnl Why do we care about 2-byte CAS on targets with 4-byte _Atomic_word?!
+    AC_TRY_COMPILE([
+    #if ! defined __GCC_HAVE_SYNC_COMPARE_AND_SWAP_2
+    # error "No 2-byte compare-and-swap"
+    #elif ! defined __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4
+    # error "No 4-byte compare-and-swap"
+    #endif
+    ],,
+    [libstdcxx_atomic_lock_policy=atomic],
+    [libstdcxx_atomic_lock_policy=mutex])
+    AC_LANG_RESTORE
+    CXXFLAGS="$ac_save_CXXFLAGS"
+  fi
+
+  if test x"$libstdcxx_atomic_lock_policy" = x"atomic"; then
+    AC_MSG_RESULT(atomic)
+    AC_DEFINE(HAVE_ATOMIC_LOCK_POLICY,1,
+      [Defined if shared_ptr reference counting should use atomic operations.])
+  else
+    AC_MSG_RESULT(mutex)
+  fi
+
+])
 
 dnl
 dnl Allow visibility attributes to be used on namespaces, objects, etc.
diff --git a/libstdc++-v3/config.h.in b/libstdc++-v3/config.h.in
index fa69b7a08955b55651106ab97ae3add9f63a58c9..9c45c8c66284235ca92230498331aeb9375af3dc 100644
--- a/libstdc++-v3/config.h.in
+++ b/libstdc++-v3/config.h.in
@@ -33,6 +33,9 @@
 /* Define to 1 if you have the `atanl' function. */
 #undef HAVE_ATANL
 
+/* Defined if shared_ptr reference counting should use atomic operations. */
+#undef HAVE_ATOMIC_LOCK_POLICY
+
 /* Define to 1 if you have the `at_quick_exit' function. */
 #undef HAVE_AT_QUICK_EXIT
 
diff --git a/libstdc++-v3/configure b/libstdc++-v3/configure
index 39f83e239d7d39cbf74eff9d95b2d23f8ae6916a..77805e8680fe97417d91f4e89f6908a37b6db4b2 100755
--- a/libstdc++-v3/configure
+++ b/libstdc++-v3/configure
@@ -907,6 +907,7 @@ enable_libtool_lock
 enable_hosted_libstdcxx
 enable_libstdcxx_verbose
 enable_libstdcxx_pch
+with_libstdcxx_lock_policy
 enable_cstdio
 enable_clocale
 enable_nls
@@ -1652,6 +1653,9 @@ Optional Packages:
   --with-pic              try to use only PIC/non-PIC objects [default=use
                           both]
   --with-gnu-ld           assume the C compiler uses GNU ld [default=no]
+  --with-libstdcxx-lock-policy={atomic,mutex,auto}
+                          synchronization policy for shared_ptr reference
+                          counting [default=auto]
   --with-python-dir       the location to install Python modules. This path is
                           relative starting from the prefix.
   --with-gnu-ld           assume the C compiler uses GNU ld default=no
@@ -11840,7 +11844,7 @@ else
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<_LT_EOF
-#line 11843 "configure"
+#line 11847 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -11946,7 +11950,7 @@ else
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<_LT_EOF
-#line 11949 "configure"
+#line 11953 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -15632,7 +15636,7 @@ $as_echo "$glibcxx_cv_atomic_long_long" >&6; }
   # Fake what AC_TRY_COMPILE does.
 
     cat > conftest.$ac_ext << EOF
-#line 15635 "configure"
+#line 15639 "configure"
 int main()
 {
   typedef bool atomic_type;
@@ -15667,7 +15671,7 @@ $as_echo "$glibcxx_cv_atomic_bool" >&6; }
     rm -f conftest*
 
     cat > conftest.$ac_ext << EOF
-#line 15670 "configure"
+#line 15674 "configure"
 int main()
 {
   typedef short atomic_type;
@@ -15702,7 +15706,7 @@ $as_echo "$glibcxx_cv_atomic_short" >&6; }
     rm -f conftest*
 
     cat > conftest.$ac_ext << EOF
-#line 15705 "configure"
+#line 15709 "configure"
 int main()
 {
   // NB: _Atomic_word not necessarily int.
@@ -15738,7 +15742,7 @@ $as_echo "$glibcxx_cv_atomic_int" >&6; }
     rm -f conftest*
 
     cat > conftest.$ac_ext << EOF
-#line 15741 "configure"
+#line 15745 "configure"
 int main()
 {
   typedef long long atomic_type;
@@ -15815,11 +15819,83 @@ $as_echo "$as_me: WARNING: Performance of certain classes will degrade as a resu
 
 
 
+
+# Check whether --with-libstdcxx-lock-policy was given.
+if test "${with_libstdcxx_lock_policy+set}" = set; then :
+  withval=$with_libstdcxx_lock_policy; libstdcxx_atomic_lock_policy=$withval
+else
+  libstdcxx_atomic_lock_policy=auto
+fi
+
+
+  case "$libstdcxx_atomic_lock_policy" in
+    atomic|mutex|auto) ;;
+    *) as_fn_error $? "Invalid argument for --with-libstdcxx-lock-policy" "$LINENO" 5 ;;
+  esac
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for lock policy for shared_ptr reference counts" >&5
+$as_echo_n "checking for lock policy for shared_ptr reference counts... " >&6; }
+
+  if test x"$libstdcxx_atomic_lock_policy" = x"auto"; then
+
+    ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+    ac_save_CXXFLAGS="$CXXFLAGS"
+
+        cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+    #if ! defined __GCC_HAVE_SYNC_COMPARE_AND_SWAP_2
+    # error "No 2-byte compare-and-swap"
+    #elif ! defined __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4
+    # error "No 4-byte compare-and-swap"
+    #endif
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+  libstdcxx_atomic_lock_policy=atomic
+else
+  libstdcxx_atomic_lock_policy=mutex
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+    ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+    CXXFLAGS="$ac_save_CXXFLAGS"
+  fi
+
+  if test x"$libstdcxx_atomic_lock_policy" = x"atomic"; then
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: atomic" >&5
+$as_echo "atomic" >&6; }
+
+$as_echo "#define HAVE_ATOMIC_LOCK_POLICY 1" >>confdefs.h
+
+  else
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: mutex" >&5
+$as_echo "mutex" >&6; }
+  fi
+
+
+
+
   # Fake what AC_TRY_COMPILE does, without linking as this is
   # unnecessary for this test.
 
     cat > conftest.$ac_ext << EOF
-#line 15822 "configure"
+#line 15898 "configure"
 int main()
 {
   _Decimal32 d1;
@@ -15861,7 +15937,7 @@ ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
   # unnecessary for this test.
 
     cat > conftest.$ac_ext << EOF
-#line 15864 "configure"
+#line 15940 "configure"
 template<typename T1, typename T2>
   struct same
   { typedef T2 type; };
@@ -15895,7 +15971,7 @@ $as_echo "$enable_int128" >&6; }
     rm -f conftest*
 
     cat > conftest.$ac_ext << EOF
-#line 15898 "configure"
+#line 15974 "configure"
 template<typename T1, typename T2>
   struct same
   { typedef T2 type; };
diff --git a/libstdc++-v3/configure.ac b/libstdc++-v3/configure.ac
index a657a726778d9b2ae29ed222d78f21b698d66da9..ad5b4117cfda8a989cce4503f34d9fcf6c570037 100644
--- a/libstdc++-v3/configure.ac
+++ b/libstdc++-v3/configure.ac
@@ -149,6 +149,7 @@ GLIBCXX_ENABLE_VERBOSE
 GLIBCXX_ENABLE_PCH($is_hosted)
 GLIBCXX_ENABLE_THREADS
 GLIBCXX_ENABLE_ATOMIC_BUILTINS
+GLIBCXX_ENABLE_LOCK_POLICY
 GLIBCXX_ENABLE_DECIMAL_FLOAT
 GLIBCXX_ENABLE_INT128_FLOAT128
 if test "$enable_float128" = yes; then
diff --git a/libstdc++-v3/doc/xml/manual/configure.xml b/libstdc++-v3/doc/xml/manual/configure.xml
index ac383cf7fa76b549a7d3ded0c62c3d4e5756c9ed..d296c8d8a49e8efd5ea17fedb6e3ed9368110740 100644
--- a/libstdc++-v3/doc/xml/manual/configure.xml
+++ b/libstdc++-v3/doc/xml/manual/configure.xml
@@ -399,6 +399,28 @@
    </para>
  </listitem></varlistentry>
 
+ <varlistentry><term><code>--with-libstdcxx-lock-policy=OPTION</code></term>
+ <listitem><para>Sets the lock policy that controls how
+        <classname>shared_ptr</classname> reference counting is
+        synchronized.
+        The choice OPTION=atomic enables use of atomics for updates to
+        <classname>shared_ptr</classname> reference counts.
+        The choice OPTION=mutex enables use of a mutex to synchronize updates
+        to <classname>shared_ptr</classname> reference counts.
+        If the compiler's thread model is "single" then this option has no
+        effect, as no synchronization is used for the reference counts.
+	The default is OPTION=auto, which checks for the availability of
+        compiler built-ins for 2-byte and 4-byte atomic compare-and-swap,
+        and uses OPTION=atomic if they're available, OPTION=mutex otherwise.
+        This option can change the library ABI.
+        If the library is configured to use atomics and user programs are
+        compiled using a target that doesn't natively support the atomic
+        operations (e.g. the library is configured for armv7 and then code
+        is compiled with <option>-march=armv5t</option>) then the program
+        might rely on support in libgcc to provide the atomics.
+    </para>
+ </listitem></varlistentry>
+
  <varlistentry><term><code>--enable-vtable-verify</code>[default]</term>
  <listitem>
     <para>Use <code>-fvtable-verify=std</code> to compile the C++
diff --git a/libstdc++-v3/include/bits/fs_dir.h b/libstdc++-v3/include/bits/fs_dir.h
index 9ee1cb66b611c91ed63159baba79d5abd4345817..2f81a1709e445b3534e46c34984e519f2ccdc8d1 100644
--- a/libstdc++-v3/include/bits/fs_dir.h
+++ b/libstdc++-v3/include/bits/fs_dir.h
@@ -403,7 +403,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
 
     friend class recursive_directory_iterator;
 
-    std::shared_ptr<_Dir> _M_dir;
+    std::__shared_ptr<_Dir> _M_dir;
   };
 
   inline directory_iterator
@@ -494,7 +494,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
                const recursive_directory_iterator& __rhs);
 
     struct _Dir_stack;
-    std::shared_ptr<_Dir_stack> _M_dirs;
+    std::__shared_ptr<_Dir_stack> _M_dirs;
     directory_options _M_options = {};
     bool _M_pending = false;
   };
@@ -525,6 +525,14 @@ _GLIBCXX_END_NAMESPACE_CXX11
   // @} group filesystem
 } // namespace filesystem
 
+  // Use explicit instantiations of these types. Any inconsistency in the
+  // value of __default_lock_policy between code including this header and
+  // the library will cause a linker error.
+  extern template class
+    __shared_ptr<filesystem::_Dir>;
+  extern template class
+    __shared_ptr<filesystem::recursive_directory_iterator::_Dir_stack>;
+
 _GLIBCXX_END_NAMESPACE_VERSION
 } // namespace std
 
diff --git a/libstdc++-v3/include/bits/shared_ptr_base.h b/libstdc++-v3/include/bits/shared_ptr_base.h
index 46ff4a7cf291841b1e41696e3913395396dd26ae..21debf362aabf87069ec3ec54a9d844c9ec3a1a0 100644
--- a/libstdc++-v3/include/bits/shared_ptr_base.h
+++ b/libstdc++-v3/include/bits/shared_ptr_base.h
@@ -1803,7 +1803,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       mutable __weak_ptr<_Tp, _Lp>  _M_weak_this;
     };
 
-  template<typename _Tp, _Lock_policy _Lp, typename _Alloc, typename... _Args>
+  template<typename _Tp, _Lock_policy _Lp = __default_lock_policy,
+	   typename _Alloc, typename... _Args>
     inline __shared_ptr<_Tp, _Lp>
     __allocate_shared(const _Alloc& __a, _Args&&... __args)
     {
@@ -1811,7 +1812,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 				    std::forward<_Args>(__args)...);
     }
 
-  template<typename _Tp, _Lock_policy _Lp, typename... _Args>
+  template<typename _Tp, _Lock_policy _Lp = __default_lock_policy,
+	   typename... _Args>
     inline __shared_ptr<_Tp, _Lp>
     __make_shared(_Args&&... __args)
     {
diff --git a/libstdc++-v3/include/ext/concurrence.h b/libstdc++-v3/include/ext/concurrence.h
index 302cddfa473c36b47b418022afbaa38df0a9b22e..33ad9e06c9fc2b1605f08adbf156014e1d9e9d1a 100644
--- a/libstdc++-v3/include/ext/concurrence.h
+++ b/libstdc++-v3/include/ext/concurrence.h
@@ -51,16 +51,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   // Compile time constant that indicates prefered locking policy in
   // the current configuration.
   static const _Lock_policy __default_lock_policy = 
-#ifdef __GTHREADS
-#if (defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2) \
-     && defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4))
+#ifndef __GTHREADS
+  _S_single;
+#elif defined _GLIBCXX_HAVE_ATOMIC_LOCK_POLICY
   _S_atomic;
 #else
   _S_mutex;
 #endif
-#else
-  _S_single;
-#endif
 
   // NB: As this is used in libsupc++, need to only depend on
   // exception. No stdexception classes, no use of std::string.
diff --git a/libstdc++-v3/src/filesystem/std-dir.cc b/libstdc++-v3/src/filesystem/std-dir.cc
index 4c9a287ad806d5319b2f623378acc385748b071a..038f635a712adb9472b16112acba51ff64a049ff 100644
--- a/libstdc++-v3/src/filesystem/std-dir.cc
+++ b/libstdc++-v3/src/filesystem/std-dir.cc
@@ -39,6 +39,9 @@
 namespace fs = std::filesystem;
 namespace posix = std::filesystem::__gnu_posix;
 
+template class std::__shared_ptr<fs::_Dir>;
+template class std::__shared_ptr<fs::recursive_directory_iterator::_Dir_stack>;
+
 struct fs::_Dir : _Dir_base
 {
   _Dir(const fs::path& p, bool skip_permission_denied, error_code& ec)
@@ -125,7 +128,7 @@ directory_iterator(const path& p, directory_options options, error_code* ecptr)
 
   if (dir.dirp)
     {
-      auto sp = std::make_shared<fs::_Dir>(std::move(dir));
+      auto sp = std::__make_shared<fs::_Dir>(std::move(dir));
       if (sp->advance(skip_permission_denied, ec))
 	_M_dir.swap(sp);
     }
@@ -185,7 +188,7 @@ recursive_directory_iterator(const path& p, directory_options options,
     {
       if (ecptr)
 	ecptr->clear();
-      auto sp = std::make_shared<_Dir_stack>();
+      auto sp = std::__make_shared<_Dir_stack>();
       sp->push(_Dir{ dirp, p });
       if (ecptr ? sp->top().advance(*ecptr) : sp->top().advance())
 	_M_dirs.swap(sp);