eugenis created this revision. eugenis added reviewers: EricWF, mclow.lists. eugenis added subscribers: cfe-commits, pcc. eugenis set the repository for this revision to rL LLVM.
static_cast of a pointer to object before the start of the object's lifetime has undefined behavior (c++14 p3.8) This code triggers CFI warnings. This also could be fixed in a different way by replacing C-style casts with reinterpret_cast<>, which, from my reading of the standard, is allowed in this context. That would not help with CFI though, which still flags such casts as invalid (yes, it is stricter that the standard). Repository: rL LLVM http://reviews.llvm.org/D16738 Files: include/functional
Index: include/functional =================================================================== --- include/functional +++ include/functional @@ -1440,7 +1440,7 @@ _LIBCPP_INLINE_VISIBILITY __base() {} _LIBCPP_INLINE_VISIBILITY virtual ~__base() {} virtual __base* __clone() const = 0; - virtual void __clone(__base*) const = 0; + virtual void __clone(void*) const = 0; virtual void destroy() _NOEXCEPT = 0; virtual void destroy_deallocate() _NOEXCEPT = 0; virtual _Rp operator()(_ArgTypes&& ...) = 0; @@ -1477,7 +1477,7 @@ : __f_(piecewise_construct, _VSTD::forward_as_tuple(_VSTD::move(__f)), _VSTD::forward_as_tuple(_VSTD::move(__a))) {} virtual __base<_Rp(_ArgTypes...)>* __clone() const; - virtual void __clone(__base<_Rp(_ArgTypes...)>*) const; + virtual void __clone(void*) const; virtual void destroy() _NOEXCEPT; virtual void destroy_deallocate() _NOEXCEPT; virtual _Rp operator()(_ArgTypes&& ... __arg); @@ -1502,7 +1502,7 @@ template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes> void -__func<_Fp, _Alloc, _Rp(_ArgTypes...)>::__clone(__base<_Rp(_ArgTypes...)>* __p) const +__func<_Fp, _Alloc, _Rp(_ArgTypes...)>::__clone(void* __p) const { ::new (__p) __func(__f_.first(), __f_.second()); } @@ -1660,10 +1660,10 @@ { if (__f.__f_ == 0) __f_ = 0; - else if (__f.__f_ == (const __base*)&__f.__buf_) + else if ((void *)__f.__f_ == &__f.__buf_) { + __f.__f_->__clone(&__buf_); __f_ = (__base*)&__buf_; - __f.__f_->__clone(__f_); } else __f_ = __f.__f_->__clone(); @@ -1676,10 +1676,10 @@ { if (__f.__f_ == 0) __f_ = 0; - else if (__f.__f_ == (const __base*)&__f.__buf_) + else if ((void *)__f.__f_ == &__f.__buf_) { + __f.__f_->__clone(&__buf_); __f_ = (__base*)&__buf_; - __f.__f_->__clone(__f_); } else __f_ = __f.__f_->__clone(); @@ -1690,10 +1690,10 @@ { if (__f.__f_ == 0) __f_ = 0; - else if (__f.__f_ == (__base*)&__f.__buf_) + else if ((void *)__f.__f_ == &__f.__buf_) { + __f.__f_->__clone(&__buf_); __f_ = (__base*)&__buf_; - __f.__f_->__clone(__f_); } else { @@ -1709,10 +1709,10 @@ { if (__f.__f_ == 0) __f_ = 0; - else if (__f.__f_ == (__base*)&__f.__buf_) + else if ((void *)__f.__f_ == &__f.__buf_) { + __f.__f_->__clone(&__buf_); __f_ = (__base*)&__buf_; - __f.__f_->__clone(__f_); } else { @@ -1736,8 +1736,8 @@ typedef __function::__func<_Fp, allocator<_Fp>, _Rp(_ArgTypes...)> _FF; if (sizeof(_FF) <= sizeof(__buf_) && is_nothrow_copy_constructible<_Fp>::value) { + ::new (&__buf_) _FF(_VSTD::move(__f)); __f_ = (__base*)&__buf_; - ::new (__f_) _FF(_VSTD::move(__f)); } else { @@ -1791,17 +1791,17 @@ function<_Rp(_ArgTypes...)>& function<_Rp(_ArgTypes...)>::operator=(function&& __f) _NOEXCEPT { - if (__f_ == (__base*)&__buf_) + if ((void *)__f_ == &__buf_) __f_->destroy(); else if (__f_) __f_->destroy_deallocate(); __f_ = 0; if (__f.__f_ == 0) __f_ = 0; - else if (__f.__f_ == (__base*)&__f.__buf_) + else if ((void *)__f.__f_ == &__f.__buf_) { + __f.__f_->__clone(&__buf_); __f_ = (__base*)&__buf_; - __f.__f_->__clone(__f_); } else { @@ -1815,7 +1815,7 @@ function<_Rp(_ArgTypes...)>& function<_Rp(_ArgTypes...)>::operator=(nullptr_t) _NOEXCEPT { - if (__f_ == (__base*)&__buf_) + if ((void *)__f_ == &__buf_) __f_->destroy(); else if (__f_) __f_->destroy_deallocate(); @@ -1840,7 +1840,7 @@ template<class _Rp, class ..._ArgTypes> function<_Rp(_ArgTypes...)>::~function() { - if (__f_ == (__base*)&__buf_) + if ((void *)__f_ == &__buf_) __f_->destroy(); else if (__f_) __f_->destroy_deallocate(); @@ -1850,31 +1850,31 @@ void function<_Rp(_ArgTypes...)>::swap(function& __f) _NOEXCEPT { - if (__f_ == (__base*)&__buf_ && __f.__f_ == (__base*)&__f.__buf_) + if ((void *)__f_ == &__buf_ && (void *)__f.__f_ == &__f.__buf_) { typename aligned_storage<sizeof(__buf_)>::type __tempbuf; + __f_->__clone(&__tempbuf); __base* __t = (__base*)&__tempbuf; - __f_->__clone(__t); __f_->destroy(); __f_ = 0; - __f.__f_->__clone((__base*)&__buf_); + __f.__f_->__clone(&__buf_); __f.__f_->destroy(); __f.__f_ = 0; __f_ = (__base*)&__buf_; - __t->__clone((__base*)&__f.__buf_); + __t->__clone(&__f.__buf_); __t->destroy(); __f.__f_ = (__base*)&__f.__buf_; } - else if (__f_ == (__base*)&__buf_) + else if ((void *)__f_ == &__buf_) { - __f_->__clone((__base*)&__f.__buf_); + __f_->__clone(&__f.__buf_); __f_->destroy(); __f_ = __f.__f_; __f.__f_ = (__base*)&__f.__buf_; } - else if (__f.__f_ == (__base*)&__f.__buf_) + else if ((void *)__f.__f_ == &__f.__buf_) { - __f.__f_->__clone((__base*)&__buf_); + __f.__f_->__clone(&__buf_); __f.__f_->destroy(); __f.__f_ = __f_; __f_ = (__base*)&__buf_;
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits