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

Reply via email to