From: khizmax <khizmax@gmail.com>
Date: Mon, 6 Mar 2017 12:18:42 +0000 (+0300)
Subject: Fixed UBsan warning "call to function through pointer to incorrect function type"
X-Git-Tag: v2.3.0~135
X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=b8a659b57968416be7d2ec28991a579e6759bb8d;p=libcds.git

Fixed UBsan warning "call to function through pointer to incorrect function type"
---

diff --git a/cds/details/static_functor.h b/cds/details/static_functor.h
index 2df6419a..52986bcc 100644
--- a/cds/details/static_functor.h
+++ b/cds/details/static_functor.h
@@ -37,9 +37,9 @@ namespace cds { namespace details {
     template <class Functor, typename T>
     struct static_functor
     {
-        static void call( T * p )
+        static void call( void* p )
         {
-            Functor()( p );
+            Functor()( reinterpret_cast<T*>( p ));
         }
     };
 
diff --git a/cds/gc/details/retired_ptr.h b/cds/gc/details/retired_ptr.h
index 85cfce6f..8f5ee4bf 100644
--- a/cds/gc/details/retired_ptr.h
+++ b/cds/gc/details/retired_ptr.h
@@ -75,11 +75,18 @@ namespace cds { namespace gc {
             {}
 
             /// Typecasting ctor
+            template <typename T>
+            retired_ptr( T* p, free_retired_ptr_func func) CDS_NOEXCEPT
+                : m_p( reinterpret_cast<pointer>(p))
+                , m_funcFree( func )
+            {}
+/*
             template <typename T>
             retired_ptr( T * p, void (* pFreeFunc)(T *)) CDS_NOEXCEPT
                 : m_p( reinterpret_cast<pointer>(p))
                 , m_funcFree( reinterpret_cast< free_retired_ptr_func >( pFreeFunc ))
             {}
+*/
 
             /// Assignment operator
             retired_ptr& operator =( retired_ptr const& s) CDS_NOEXCEPT
@@ -90,7 +97,7 @@ namespace cds { namespace gc {
             }
 
             /// Invokes destructor function for the pointer
-            void free() CDS_SUPPRESS_SANITIZE( "function" )
+            void free()
             {
                 assert( m_funcFree );
                 assert( m_p );
diff --git a/cds/gc/dhp.h b/cds/gc/dhp.h
index 755e051e..23d876b0 100644
--- a/cds/gc/dhp.h
+++ b/cds/gc/dhp.h
@@ -1381,7 +1381,7 @@ namespace cds { namespace gc {
             \p func is a disposer: when \p p can be safely removed, \p func is called.
         */
         template <typename T>
-        static void retire( T * p, void (* func)(T *))
+        static void retire( T * p, void (* func)(void *))
         {
             dhp::thread_data* rec = dhp::smr::tls();
             if ( !rec->retired_.push( dhp::retired_ptr( p, func ) ) )
@@ -1438,7 +1438,7 @@ namespace cds { namespace gc {
             \endcode
         */
         template <class Disposer, typename T>
-        static void retire( T * p )
+        static void retire( T* p )
         {
             if ( !dhp::smr::tls()->retired_.push( dhp::retired_ptr( p, cds::details::static_functor<Disposer, T>::call )))
                 scan();
diff --git a/cds/gc/hp.h b/cds/gc/hp.h
index 33a2d05c..09ba8059 100644
--- a/cds/gc/hp.h
+++ b/cds/gc/hp.h
@@ -1374,7 +1374,7 @@ namespace cds { namespace gc {
             \p func is a disposer: when \p p can be safely removed, \p func is called.
         */
         template <typename T>
-        static void retire( T * p, void( *func )( T * ))
+        static void retire( T * p, void( *func )( void * ))
         {
             hp::thread_data* rec = hp::smr::tls();
             if ( !rec->retired_.push( hp::retired_ptr( p, func )))
diff --git a/cds/intrusive/impl/ellen_bintree.h b/cds/intrusive/impl/ellen_bintree.h
index c17b090e..06ed7fd0 100644
--- a/cds/intrusive/impl/ellen_bintree.h
+++ b/cds/intrusive/impl/ellen_bintree.h
@@ -243,9 +243,9 @@ namespace cds { namespace intrusive {
 
     protected:
         //@cond
-        static void free_leaf_node( value_type * p )
+        static void free_leaf_node( void* p )
         {
-            disposer()( p );
+            disposer()( reinterpret_cast<value_type*>( p ));
         }
 
         internal_node * alloc_internal_node() const
@@ -255,9 +255,9 @@ namespace cds { namespace intrusive {
             return pNode;
         }
 
-        static void free_internal_node( internal_node * pNode )
+        static void free_internal_node( void* pNode )
         {
-            cxx_node_allocator().Delete( pNode );
+            cxx_node_allocator().Delete( reinterpret_cast<internal_node*>( pNode ));
         }
 
         struct internal_node_deleter {
@@ -275,9 +275,9 @@ namespace cds { namespace intrusive {
             return cxx_update_desc_allocator().New();
         }
 
-        static void free_update_desc( update_desc * pDesc )
+        static void free_update_desc( void* pDesc )
         {
-            cxx_update_desc_allocator().Delete( pDesc );
+            cxx_update_desc_allocator().Delete( reinterpret_cast<update_desc*>( pDesc ));
         }
 
         void retire_node( tree_node * pNode ) const
diff --git a/cds/intrusive/impl/skip_list.h b/cds/intrusive/impl/skip_list.h
index 61772430..89f80bfc 100644
--- a/cds/intrusive/impl/skip_list.h
+++ b/cds/intrusive/impl/skip_list.h
@@ -1141,9 +1141,10 @@ namespace cds { namespace intrusive {
             return node_traits::to_value_ptr( p.ptr());
         }
 
-        static void dispose_node( value_type * pVal )
+        static void dispose_node( void* p )
         {
-            assert( pVal != nullptr );
+            assert( p != nullptr );
+            value_type* pVal = reinterpret_cast<value_type*>( p );
             typename node_builder::node_disposer()( node_traits::to_node_ptr( pVal ));
             disposer()( pVal );
         }
diff --git a/cds/urcu/general_buffered.h b/cds/urcu/general_buffered.h
index b297813c..63d4db1c 100644
--- a/cds/urcu/general_buffered.h
+++ b/cds/urcu/general_buffered.h
@@ -97,9 +97,9 @@ namespace cds { namespace urcu {
             If the buffer is full, \ref synchronize function is invoked.
         */
         template <typename T>
-        static void retire_ptr( T * p, void (* pFunc)(T *))
+        static void retire_ptr( T * p, free_retired_ptr_func pFunc )
         {
-            retired_ptr rp( reinterpret_cast<void *>( p ), reinterpret_cast<free_retired_ptr_func>( pFunc ));
+            retired_ptr rp( p, pFunc );
             retire_ptr( rp );
         }
 
diff --git a/cds/urcu/general_instant.h b/cds/urcu/general_instant.h
index 91896a3e..2623024e 100644
--- a/cds/urcu/general_instant.h
+++ b/cds/urcu/general_instant.h
@@ -90,9 +90,9 @@ namespace cds { namespace urcu {
             and then evaluates disposing expression <tt>pFunc( p )</tt>
         */
         template <typename T>
-        static void retire_ptr( T * p, void (* pFunc)(T *))
+        static void retire_ptr( T* p, free_retired_ptr_func pFunc )
         {
-            retired_ptr rp( reinterpret_cast<void *>( p ), reinterpret_cast<free_retired_ptr_func>( pFunc ));
+            retired_ptr rp( p, pFunc );
             retire_ptr( rp );
         }
 
@@ -102,7 +102,7 @@ namespace cds { namespace urcu {
             and then evaluates disposing expression <tt>Disposer()( p )</tt>
         */
         template <typename Disposer, typename T>
-        static void retire_ptr( T * p )
+        static void retire_ptr( T* p )
         {
             retire_ptr( p, cds::details::static_functor<Disposer, T>::call );
         }
diff --git a/cds/urcu/general_threaded.h b/cds/urcu/general_threaded.h
index 16129d28..96f355f0 100644
--- a/cds/urcu/general_threaded.h
+++ b/cds/urcu/general_threaded.h
@@ -103,9 +103,9 @@ namespace cds { namespace urcu {
             If the buffer is full, \ref synchronize function is invoked.
         */
         template <typename T>
-        static void retire_ptr( T * p, void (* pFunc)(T *))
+        static void retire_ptr( T* p, free_retired_ptr_func pFunc )
         {
-            retired_ptr rp( reinterpret_cast<void *>( p ), reinterpret_cast<free_retired_ptr_func>( pFunc ));
+            retired_ptr rp( p, pFunc );
             retire_ptr( rp );
         }
 
@@ -114,7 +114,7 @@ namespace cds { namespace urcu {
             If the buffer is full, \ref synchronize function is invoked.
         */
         template <typename Disposer, typename T>
-        static void retire_ptr( T * p )
+        static void retire_ptr( T* p )
         {
             retire_ptr( p, cds::details::static_functor<Disposer, T>::call );
         }
diff --git a/cds/urcu/signal_buffered.h b/cds/urcu/signal_buffered.h
index df5d36ba..1ba5bab6 100644
--- a/cds/urcu/signal_buffered.h
+++ b/cds/urcu/signal_buffered.h
@@ -103,9 +103,9 @@ namespace cds { namespace urcu {
             If the buffer is full, \ref synchronize function is invoked.
         */
         template <typename T>
-        static void retire_ptr( T * p, void (* pFunc)(T *))
+        static void retire_ptr( T* p, free_retired_ptr_func pFunc )
         {
-            retired_ptr rp( reinterpret_cast<void *>( p ), reinterpret_cast<free_retired_ptr_func>( pFunc ));
+            retired_ptr rp( p, pFunc );
             retire_ptr( rp );
         }
 
@@ -114,7 +114,7 @@ namespace cds { namespace urcu {
             If the buffer is full, \ref synchronize function is invoked.
         */
         template <typename Disposer, typename T>
-        static void retire_ptr( T * p )
+        static void retire_ptr( T* p )
         {
             retire_ptr( p, cds::details::static_functor<Disposer, T>::call );
         }
diff --git a/cds/urcu/signal_threaded.h b/cds/urcu/signal_threaded.h
index e5e0517e..b001576e 100644
--- a/cds/urcu/signal_threaded.h
+++ b/cds/urcu/signal_threaded.h
@@ -110,9 +110,9 @@ namespace cds { namespace urcu {
             If the buffer is full, \ref synchronize function is invoked.
         */
         template <typename T>
-        static void retire_ptr( T * p, void (* pFunc)(T *))
+        static void retire_ptr( T* p, free_retired_ptr_func pFunc )
         {
-            retired_ptr rp( reinterpret_cast<void *>( p ), reinterpret_cast<free_retired_ptr_func>( pFunc ));
+            retired_ptr rp( p, pFunc );
             retire_ptr( rp );
         }