libcxx: Mark __temp_value::__temp_value as _LIBCPP_NO_CFI.
authorPeter Collingbourne <peter@pcc.me.uk>
Wed, 15 Aug 2018 17:49:30 +0000 (17:49 +0000)
committerPeter Collingbourne <peter@pcc.me.uk>
Wed, 15 Aug 2018 17:49:30 +0000 (17:49 +0000)
This constructor needs to cast a pointer to uninitialized
memory to a pointer to object type in order to call
allocator_traits::construct(). This cast is not allowed when CFI cast
checks are enabled.

I did this instead of marking __addr() as _LIBCPP_NO_CFI so that we
don't lose CFI checks on get() or the dtor.

Differential Revision: https://reviews.llvm.org/D50743

llvm-svn: 339797

libcxx/include/memory

index a4bf89b..4b7a26c 100644 (file)
@@ -5631,8 +5631,11 @@ struct __temp_value {
     _Tp &   get() { return *__addr(); }
 
     template<class... _Args>
-    __temp_value(_Alloc &__alloc, _Args&& ... __args) : __a(__alloc)
-    { _Traits::construct(__a, __addr(), _VSTD::forward<_Args>(__args)...); }
+    _LIBCPP_NO_CFI
+    __temp_value(_Alloc &__alloc, _Args&& ... __args) : __a(__alloc) {
+      _Traits::construct(__a, reinterpret_cast<_Tp*>(addressof(__v)),
+                         _VSTD::forward<_Args>(__args)...);
+    }
 
     ~__temp_value() { _Traits::destroy(__a, __addr()); }
     };