diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog
index 9285a6becf51e4a5a84607efad47520095a47aa4..575e52a70b6edbc547d8385c0575ae5d260c653f 100644
--- a/libstdc++-v3/ChangeLog
+++ b/libstdc++-v3/ChangeLog
@@ -1,3 +1,24 @@
+2018-10-25  Marc Glisse  <marc.glisse@inria.fr>
+
+	PR libstdc++/87106
+	* include/bits/alloc_traits.h (_S_construct, _S_destroy, construct,
+	destroy): Add noexcept specification.
+	* include/bits/allocator.h (construct, destroy): Likewise.
+	* include/ext/alloc_traits.h (construct, destroy): Likewise.
+	* include/ext/malloc_allocator.h (construct, destroy): Likewise.
+	* include/ext/new_allocator.h (construct, destroy): Likewise.
+	* include/bits/stl_uninitialized.h (__relocate_object_a, __relocate_a,
+	__relocate_a_1): New functions.
+	(__is_trivially_relocatable): New class.
+	* include/bits/stl_vector.h (__use_relocate): New static member.
+	* include/bits/vector.tcc (reserve, _M_realloc_insert,
+	_M_default_append): Use __relocate_a.
+	(reserve, _M_assign_aux, _M_realloc_insert, _M_fill_insert,
+	_M_default_append, _M_range_insert): Move _GLIBCXX_ASAN_ANNOTATE_REINIT
+	after _Destroy.
+	* testsuite/23_containers/vector/modifiers/push_back/49836.cc:
+	Replace CopyConsOnlyType with DelAnyAssign.
+
 2018-10-24  François Dumont  <fdumont@gcc.gnu.org>
 
 	* include/debug/safe_unordered_container.h
diff --git a/libstdc++-v3/include/bits/alloc_traits.h b/libstdc++-v3/include/bits/alloc_traits.h
index 742fdd0447d9201e26094be9685178e5be80d5c3..9321fdff352cc6e13ad53841ea87894a2e95dae1 100644
--- a/libstdc++-v3/include/bits/alloc_traits.h
+++ b/libstdc++-v3/include/bits/alloc_traits.h
@@ -240,6 +240,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       template<typename _Tp, typename... _Args>
 	static _Require<__has_construct<_Tp, _Args...>>
 	_S_construct(_Alloc& __a, _Tp* __p, _Args&&... __args)
+	noexcept(noexcept(__a.construct(__p, std::forward<_Args>(__args)...)))
 	{ __a.construct(__p, std::forward<_Args>(__args)...); }
 
       template<typename _Tp, typename... _Args>
@@ -247,17 +248,21 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 	_Require<__and_<__not_<__has_construct<_Tp, _Args...>>,
 			       is_constructible<_Tp, _Args...>>>
 	_S_construct(_Alloc&, _Tp* __p, _Args&&... __args)
+	noexcept(noexcept(::new((void*)__p)
+			  _Tp(std::forward<_Args>(__args)...)))
 	{ ::new((void*)__p) _Tp(std::forward<_Args>(__args)...); }
 
       template<typename _Alloc2, typename _Tp>
 	static auto
 	_S_destroy(_Alloc2& __a, _Tp* __p, int)
+	noexcept(noexcept(__a.destroy(__p)))
 	-> decltype(__a.destroy(__p))
 	{ __a.destroy(__p); }
 
       template<typename _Alloc2, typename _Tp>
 	static void
 	_S_destroy(_Alloc2&, _Tp* __p, ...)
+	noexcept(noexcept(__p->~_Tp()))
 	{ __p->~_Tp(); }
 
       template<typename _Alloc2>
@@ -340,6 +345,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       */
       template<typename _Tp, typename... _Args>
 	static auto construct(_Alloc& __a, _Tp* __p, _Args&&... __args)
+	noexcept(noexcept(_S_construct(__a, __p,
+				       std::forward<_Args>(__args)...)))
 	-> decltype(_S_construct(__a, __p, std::forward<_Args>(__args)...))
 	{ _S_construct(__a, __p, std::forward<_Args>(__args)...); }
 
@@ -353,6 +360,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       */
       template<typename _Tp>
 	static void destroy(_Alloc& __a, _Tp* __p)
+	noexcept(noexcept(_S_destroy(__a, __p, 0)))
 	{ _S_destroy(__a, __p, 0); }
 
       /**
@@ -472,6 +480,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       template<typename _Up, typename... _Args>
 	static void
 	construct(allocator_type& __a, _Up* __p, _Args&&... __args)
+	noexcept(noexcept(__a.construct(__p, std::forward<_Args>(__args)...)))
 	{ __a.construct(__p, std::forward<_Args>(__args)...); }
 
       /**
@@ -484,6 +493,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       template<typename _Up>
 	static void
 	destroy(allocator_type& __a, _Up* __p)
+	noexcept(noexcept(__a.destroy(__p)))
 	{ __a.destroy(__p); }
 
       /**
diff --git a/libstdc++-v3/include/bits/allocator.h b/libstdc++-v3/include/bits/allocator.h
index d9d1d26e13aafd5f79a71078303b26747665063a..9f018ea239c6cb40282f75ade1eb807a8054946e 100644
--- a/libstdc++-v3/include/bits/allocator.h
+++ b/libstdc++-v3/include/bits/allocator.h
@@ -88,11 +88,15 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       template<typename _Up, typename... _Args>
 	void
 	construct(_Up* __p, _Args&&... __args)
+	noexcept(noexcept(::new((void *)__p)
+			    _Up(std::forward<_Args>(__args)...)))
 	{ ::new((void *)__p) _Up(std::forward<_Args>(__args)...); }
 
       template<typename _Up>
 	void
-	destroy(_Up* __p) { __p->~_Up(); }
+	destroy(_Up* __p)
+	noexcept(noexcept(__p->~_Up()))
+	{ __p->~_Up(); }
 #endif
     };
 
diff --git a/libstdc++-v3/include/bits/stl_uninitialized.h b/libstdc++-v3/include/bits/stl_uninitialized.h
index c740503052b52e2081700d6c2c89ba6ea52852b2..94c7e151e29abcbc3804c0e3333ff5ab4f480f04 100644
--- a/libstdc++-v3/include/bits/stl_uninitialized.h
+++ b/libstdc++-v3/include/bits/stl_uninitialized.h
@@ -879,6 +879,68 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     }
 #endif
 
+#if __cplusplus >= 201103L
+  template<typename _Tp, typename _Up, typename _Allocator>
+    inline void
+    __relocate_object_a(_Tp* __dest, _Up* __orig, _Allocator& __alloc)
+    noexcept(noexcept(std::allocator_traits<_Allocator>::construct(__alloc,
+			 __dest, std::move(*__orig)))
+	     && noexcept(std::allocator_traits<_Allocator>::destroy(
+			    __alloc, std::__addressof(*__orig))))
+    {
+      typedef std::allocator_traits<_Allocator> __traits;
+      __traits::construct(__alloc, __dest, std::move(*__orig));
+      __traits::destroy(__alloc, std::__addressof(*__orig));
+    }
+
+  // This class may be specialized for specific types.
+  template<typename _Tp>
+    struct __is_trivially_relocatable
+    : is_trivial<_Tp> { };
+
+  template <typename _Tp, typename _Up>
+    inline __enable_if_t<std::__is_trivially_relocatable<_Tp>::value, _Tp*>
+    __relocate_a_1(_Tp* __first, _Tp* __last,
+		   _Tp* __result, allocator<_Up>& __alloc)
+    {
+      ptrdiff_t __count = __last - __first;
+      __builtin_memmove(__result, __first, __count * sizeof(_Tp));
+      return __result + __count;
+    }
+
+  template <typename _InputIterator, typename _ForwardIterator,
+	    typename _Allocator>
+    inline _ForwardIterator
+    __relocate_a_1(_InputIterator __first, _InputIterator __last,
+		   _ForwardIterator __result, _Allocator& __alloc)
+    {
+      typedef typename iterator_traits<_InputIterator>::value_type
+	_ValueType;
+      typedef typename iterator_traits<_ForwardIterator>::value_type
+	_ValueType2;
+      static_assert(std::is_same<_ValueType, _ValueType2>::value);
+      static_assert(noexcept(std::__relocate_object_a(std::addressof(*__result),
+						      std::addressof(*__first),
+						      __alloc)));
+      _ForwardIterator __cur = __result;
+      for (; __first != __last; ++__first, (void)++__cur)
+	std::__relocate_object_a(std::__addressof(*__cur),
+				 std::__addressof(*__first), __alloc);
+      return __cur;
+    }
+
+  template <typename _InputIterator, typename _ForwardIterator,
+	    typename _Allocator>
+    inline _ForwardIterator
+    __relocate_a(_InputIterator __first, _InputIterator __last,
+		 _ForwardIterator __result, _Allocator& __alloc)
+    {
+      return __relocate_a_1(std::__niter_base(__first),
+			    std::__niter_base(__last),
+			    std::__niter_base(__result), __alloc);
+    }
+#endif
+
 _GLIBCXX_END_NAMESPACE_VERSION
 } // namespace
 
diff --git a/libstdc++-v3/include/bits/stl_vector.h b/libstdc++-v3/include/bits/stl_vector.h
index 37607417d087caae3b7a70db8d2d207bba245ada..40debd62396ed30402dd20963c5da43f3fb87a31 100644
--- a/libstdc++-v3/include/bits/stl_vector.h
+++ b/libstdc++-v3/include/bits/stl_vector.h
@@ -421,6 +421,15 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
       typedef ptrdiff_t					difference_type;
       typedef _Alloc					allocator_type;
 
+    private:
+#if __cplusplus >= 201103L
+      static constexpr bool __use_relocate =
+	noexcept(std::__relocate_object_a(
+			std::addressof(*std::declval<pointer>()),
+			std::addressof(*std::declval<pointer>()),
+			std::declval<_Tp_alloc_type&>()));
+#endif
+
     protected:
       using _Base::_M_allocate;
       using _Base::_M_deallocate;
diff --git a/libstdc++-v3/include/bits/vector.tcc b/libstdc++-v3/include/bits/vector.tcc
index a1d114a0a9a7f2620b9946e8a7404cf1501f04cc..8df0f4180d4c1d304b2248ed50e25b623af1d4e1 100644
--- a/libstdc++-v3/include/bits/vector.tcc
+++ b/libstdc++-v3/include/bits/vector.tcc
@@ -71,12 +71,25 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
       if (this->capacity() < __n)
 	{
 	  const size_type __old_size = size();
-	  pointer __tmp = _M_allocate_and_copy(__n,
-	    _GLIBCXX_MAKE_MOVE_IF_NOEXCEPT_ITERATOR(this->_M_impl._M_start),
-	    _GLIBCXX_MAKE_MOVE_IF_NOEXCEPT_ITERATOR(this->_M_impl._M_finish));
+	  pointer __tmp;
+#if __cplusplus >= 201103L
+	  if constexpr (__use_relocate)
+	    {
+	      __tmp = this->_M_allocate(__n);
+	      std::__relocate_a(this->_M_impl._M_start,
+				this->_M_impl._M_finish,
+				__tmp, _M_get_Tp_allocator());
+	    }
+	  else
+#endif
+	    {
+	      __tmp = _M_allocate_and_copy(__n,
+		_GLIBCXX_MAKE_MOVE_IF_NOEXCEPT_ITERATOR(this->_M_impl._M_start),
+		_GLIBCXX_MAKE_MOVE_IF_NOEXCEPT_ITERATOR(this->_M_impl._M_finish));
+	      std::_Destroy(this->_M_impl._M_start, this->_M_impl._M_finish,
+			    _M_get_Tp_allocator());
+	    }
 	  _GLIBCXX_ASAN_ANNOTATE_REINIT;
-	  std::_Destroy(this->_M_impl._M_start, this->_M_impl._M_finish,
-			_M_get_Tp_allocator());
 	  _M_deallocate(this->_M_impl._M_start,
 			this->_M_impl._M_end_of_storage
 			- this->_M_impl._M_start);
@@ -295,9 +308,9 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
 	  {
 	    _S_check_init_len(__len, _M_get_Tp_allocator());
 	    pointer __tmp(_M_allocate_and_copy(__len, __first, __last));
-	    _GLIBCXX_ASAN_ANNOTATE_REINIT;
 	    std::_Destroy(this->_M_impl._M_start, this->_M_impl._M_finish,
 			  _M_get_Tp_allocator());
+	    _GLIBCXX_ASAN_ANNOTATE_REINIT;
 	    _M_deallocate(this->_M_impl._M_start,
 			  this->_M_impl._M_end_of_storage
 			  - this->_M_impl._M_start);
@@ -443,17 +456,36 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
 #endif
 	  __new_finish = pointer();
 
-	  __new_finish
-	    = std::__uninitialized_move_if_noexcept_a
-	    (__old_start, __position.base(),
-	     __new_start, _M_get_Tp_allocator());
+#if __cplusplus >= 201103L
+	  if constexpr (__use_relocate)
+	    {
+	      __new_finish
+		= std::__relocate_a
+		(__old_start, __position.base(),
+		 __new_start, _M_get_Tp_allocator());
+
+	      ++__new_finish;
+
+	      __new_finish
+		= std::__relocate_a
+		(__position.base(), __old_finish,
+		 __new_finish, _M_get_Tp_allocator());
+	    }
+	  else
+#endif
+	    {
+	      __new_finish
+		= std::__uninitialized_move_if_noexcept_a
+		(__old_start, __position.base(),
+		 __new_start, _M_get_Tp_allocator());
 
-	  ++__new_finish;
+	      ++__new_finish;
 
-	  __new_finish
-	    = std::__uninitialized_move_if_noexcept_a
-	    (__position.base(), __old_finish,
-	     __new_finish, _M_get_Tp_allocator());
+	      __new_finish
+		= std::__uninitialized_move_if_noexcept_a
+		(__position.base(), __old_finish,
+		 __new_finish, _M_get_Tp_allocator());
+	    }
 	}
       __catch(...)
 	{
@@ -465,8 +497,11 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
 	  _M_deallocate(__new_start, __len);
 	  __throw_exception_again;
 	}
+#if __cplusplus >= 201103L
+      if constexpr (!__use_relocate)
+#endif
+	std::_Destroy(__old_start, __old_finish, _M_get_Tp_allocator());
       _GLIBCXX_ASAN_ANNOTATE_REINIT;
-      std::_Destroy(__old_start, __old_finish, _M_get_Tp_allocator());
       _M_deallocate(__old_start,
 		    this->_M_impl._M_end_of_storage - __old_start);
       this->_M_impl._M_start = __new_start;
@@ -562,9 +597,9 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
 		  _M_deallocate(__new_start, __len);
 		  __throw_exception_again;
 		}
-	      _GLIBCXX_ASAN_ANNOTATE_REINIT;
 	      std::_Destroy(this->_M_impl._M_start, this->_M_impl._M_finish,
 			    _M_get_Tp_allocator());
+	      _GLIBCXX_ASAN_ANNOTATE_REINIT;
 	      _M_deallocate(this->_M_impl._M_start,
 			    this->_M_impl._M_end_of_storage
 			    - this->_M_impl._M_start);
@@ -603,27 +638,48 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
 	      const size_type __len =
 		_M_check_len(__n, "vector::_M_default_append");
 	      pointer __new_start(this->_M_allocate(__len));
-	      pointer __destroy_from = pointer();
-	      __try
+#if __cplusplus >= 201103L
+	      if constexpr (__use_relocate)
 		{
-		  std::__uninitialized_default_n_a(__new_start + __size,
-						   __n, _M_get_Tp_allocator());
-		  __destroy_from = __new_start + __size;
-		  std::__uninitialized_move_if_noexcept_a(
-		      this->_M_impl._M_start, this->_M_impl._M_finish,
-		      __new_start, _M_get_Tp_allocator());
+		  __try
+		    {
+		      std::__uninitialized_default_n_a(__new_start + __size,
+			      __n, _M_get_Tp_allocator());
+		    }
+		  __catch(...)
+		    {
+		      _M_deallocate(__new_start, __len);
+		      __throw_exception_again;
+		    }
+		  std::__relocate_a(this->_M_impl._M_start,
+				    this->_M_impl._M_finish,
+				    __new_start, _M_get_Tp_allocator());
 		}
-	      __catch(...)
+	      else
+#endif
 		{
-		  if (__destroy_from)
-		    std::_Destroy(__destroy_from, __destroy_from + __n,
-				  _M_get_Tp_allocator());
-		  _M_deallocate(__new_start, __len);
-		  __throw_exception_again;
+		  pointer __destroy_from = pointer();
+		  __try
+		    {
+		      std::__uninitialized_default_n_a(__new_start + __size,
+			      __n, _M_get_Tp_allocator());
+		      __destroy_from = __new_start + __size;
+		      std::__uninitialized_move_if_noexcept_a(
+			      this->_M_impl._M_start, this->_M_impl._M_finish,
+			      __new_start, _M_get_Tp_allocator());
+		    }
+		  __catch(...)
+		    {
+		      if (__destroy_from)
+			std::_Destroy(__destroy_from, __destroy_from + __n,
+				      _M_get_Tp_allocator());
+		      _M_deallocate(__new_start, __len);
+		      __throw_exception_again;
+		    }
+		  std::_Destroy(this->_M_impl._M_start, this->_M_impl._M_finish,
+				_M_get_Tp_allocator());
 		}
 	      _GLIBCXX_ASAN_ANNOTATE_REINIT;
-	      std::_Destroy(this->_M_impl._M_start, this->_M_impl._M_finish,
-			    _M_get_Tp_allocator());
 	      _M_deallocate(this->_M_impl._M_start,
 			    this->_M_impl._M_end_of_storage
 			    - this->_M_impl._M_start);
@@ -742,9 +798,9 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
 		    _M_deallocate(__new_start, __len);
 		    __throw_exception_again;
 		  }
-		_GLIBCXX_ASAN_ANNOTATE_REINIT;
 		std::_Destroy(this->_M_impl._M_start, this->_M_impl._M_finish,
 			      _M_get_Tp_allocator());
+		_GLIBCXX_ASAN_ANNOTATE_REINIT;
 		_M_deallocate(this->_M_impl._M_start,
 			      this->_M_impl._M_end_of_storage
 			      - this->_M_impl._M_start);
diff --git a/libstdc++-v3/include/ext/alloc_traits.h b/libstdc++-v3/include/ext/alloc_traits.h
index 2570c59d81ffde641a4b3fb3176f9e3f1640cbf3..f16853743665fef2372ec8bc689e756480789afd 100644
--- a/libstdc++-v3/include/ext/alloc_traits.h
+++ b/libstdc++-v3/include/ext/alloc_traits.h
@@ -80,6 +80,8 @@ template<typename _Alloc, typename = typename _Alloc::value_type>
     template<typename _Ptr, typename... _Args>
       static typename std::enable_if<__is_custom_pointer<_Ptr>::value>::type
       construct(_Alloc& __a, _Ptr __p, _Args&&... __args)
+      noexcept(noexcept(_Base_type::construct(__a, std::__to_address(__p),
+					      std::forward<_Args>(__args)...)))
       {
 	_Base_type::construct(__a, std::__to_address(__p),
 			      std::forward<_Args>(__args)...);
@@ -89,6 +91,7 @@ template<typename _Alloc, typename = typename _Alloc::value_type>
     template<typename _Ptr>
       static typename std::enable_if<__is_custom_pointer<_Ptr>::value>::type
       destroy(_Alloc& __a, _Ptr __p)
+      noexcept(noexcept(_Base_type::destroy(__a, std::__to_address(__p))))
       { _Base_type::destroy(__a, std::__to_address(__p)); }
 
     static _Alloc _S_select_on_copy(const _Alloc& __a)
diff --git a/libstdc++-v3/include/ext/malloc_allocator.h b/libstdc++-v3/include/ext/malloc_allocator.h
index 1ae53b11ddb536898831a36ba58a3023beeb85ff..5f91fe08af467a9f45a7b6aecad3eda3aee39144 100644
--- a/libstdc++-v3/include/ext/malloc_allocator.h
+++ b/libstdc++-v3/include/ext/malloc_allocator.h
@@ -151,11 +151,15 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       template<typename _Up, typename... _Args>
         void
         construct(_Up* __p, _Args&&... __args)
+	noexcept(noexcept(::new((void *)__p)
+			  _Up(std::forward<_Args>(__args)...)))
 	{ ::new((void *)__p) _Up(std::forward<_Args>(__args)...); }
 
       template<typename _Up>
         void 
-        destroy(_Up* __p) { __p->~_Up(); }
+        destroy(_Up* __p)
+	noexcept(noexcept(__p->~_Up()))
+	{ __p->~_Up(); }
 #else
       // _GLIBCXX_RESOLVE_LIB_DEFECTS
       // 402. wrong new expression in [some_] allocator::construct
diff --git a/libstdc++-v3/include/ext/new_allocator.h b/libstdc++-v3/include/ext/new_allocator.h
index 83c894ce0a778d70c6e287378dfa6cab5724cf41..18a45cd75f1089b470e8580fbfcf0db67dca4658 100644
--- a/libstdc++-v3/include/ext/new_allocator.h
+++ b/libstdc++-v3/include/ext/new_allocator.h
@@ -142,11 +142,15 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       template<typename _Up, typename... _Args>
 	void
 	construct(_Up* __p, _Args&&... __args)
+	noexcept(noexcept(::new((void *)__p)
+			    _Up(std::forward<_Args>(__args)...)))
 	{ ::new((void *)__p) _Up(std::forward<_Args>(__args)...); }
 
       template<typename _Up>
 	void
-	destroy(_Up* __p) { __p->~_Up(); }
+	destroy(_Up* __p)
+	noexcept(noexcept( __p->~_Up()))
+	{ __p->~_Up(); }
 #else
       // _GLIBCXX_RESOLVE_LIB_DEFECTS
       // 402. wrong new expression in [some_] allocator::construct
diff --git a/libstdc++-v3/testsuite/23_containers/vector/modifiers/push_back/49836.cc b/libstdc++-v3/testsuite/23_containers/vector/modifiers/push_back/49836.cc
index eb39e41cfac8fc7f16dee88cc13d5abf846d7393..85925ab756e33b6b17837a7f49a8830566983591 100644
--- a/libstdc++-v3/testsuite/23_containers/vector/modifiers/push_back/49836.cc
+++ b/libstdc++-v3/testsuite/23_containers/vector/modifiers/push_back/49836.cc
@@ -24,11 +24,11 @@
 // libstdc++/49836
 void test01()
 {
-  using __gnu_test::CopyConsOnlyType;
+  using __gnu_test::assign::DelAnyAssign;
   using __gnu_test::MoveConsOnlyType;
 
-  std::vector<CopyConsOnlyType> v1;
-  CopyConsOnlyType t1(1);
+  std::vector<DelAnyAssign> v1;
+  DelAnyAssign t1;
   v1.push_back(t1);
   v1.push_back(t1);
   v1.push_back(t1);