What are the steps to reproduce the problem? I build that source file with
-O0, 1, 2 and 3, and in all of them I get "42" as the output.

- Alon


On Sat, Apr 4, 2015 at 7:12 AM, <[email protected]> wrote:

> OK the following self contained code (*not* calling any boost headers) is
> fine with O0 or O1, but not with O2 or O3. The function which I am
> exporting is :
>
> extern "C" {
>   double test(void) {
>     boost::shared_ptr<int> y = boost::shared_ptr<int>(new int(42));
>     return *y;
>   }
> }
>
> The invocation of "dispose()" and "weak_release()"  in
> "sp_counted_base::release" is what is causing the problems :
>
> #include <atomic>
> #include <iostream>
> #include <vector>
> using namespace std;
>
> namespace boost
> {
>
> namespace core
> {
>
>
> class typeinfo
> {
> private:
>
>     typeinfo( typeinfo const& );
>     typeinfo& operator=( typeinfo const& );
>
>     char const * name_;
>
> public:
>
>     explicit typeinfo( char const * name ): name_( name )
>     {
>     }
>
>     bool operator==( typeinfo const& rhs ) const
>     {
>         return this == &rhs;
>     }
>
>     bool operator!=( typeinfo const& rhs ) const
>     {
>         return this != &rhs;
>     }
>
>     bool before( typeinfo const& rhs ) const
>     {
>         return std::less< typeinfo const* >()( this, &rhs );
>     }
>
>     char const* name() const
>     {
>         return name_;
>     }
> };
>
>
> }//namespace core
>
> template<class T> class shared_ptr;
> template<class T> class enable_shared_from_this;
>
> template<class T> inline void checked_delete(T * x)
> {
>     // intentionally complex - simplification causes regressions
>     typedef char type_must_be_complete[ sizeof(T)? 1: -1 ];
>     (void) sizeof(type_must_be_complete);
>     delete x;
> }
>
> namespace detail
> {
>
> typedef boost::core::typeinfo sp_typeinfo;
>
> inline void atomic_increment( std::atomic_int_least32_t * pw )
> {
>     pw->fetch_add( 1, std::memory_order_relaxed );
> }
>
> inline std::int_least32_t atomic_decrement( std::atomic_int_least32_t * pw
> )
> {
>     return pw->fetch_sub( 1, std::memory_order_acq_rel );
> }
>
> inline std::int_least32_t atomic_conditional_increment(
> std::atomic_int_least32_t * pw )
> {
>     // long r = *pw;
>     // if( r != 0 ) ++*pw;
>     // return r;
>
>     std::int_least32_t r = pw->load( std::memory_order_relaxed );
>
>     for( ;; )
>     {
>         if( r == 0 )
>         {
>             return r;
>         }
>
>         if( pw->compare_exchange_weak( r, r + 1,
> std::memory_order_relaxed, std::memory_order_relaxed ) )
>         {
>             return r;
>         }
>     }
> }
>
> class sp_counted_base
> {
> private:
>
>     sp_counted_base( sp_counted_base const & );
>     sp_counted_base & operator= ( sp_counted_base const & );
>
>     std::atomic_int_least32_t use_count_; // #shared
>     std::atomic_int_least32_t weak_count_; // #weak + (#shared != 0)
>
> public:
>
>     sp_counted_base(): use_count_( 1 ), weak_count_( 1 )
>     {
>     }
>
>     virtual ~sp_counted_base() // nothrow
>     {
>     }
>
>     // dispose() is called when use_count_ drops to zero, to release
>     // the resources managed by *this.
>
>     virtual void dispose() = 0; // nothrow
>
>     // destroy() is called when weak_count_ drops to zero.
>
>     virtual void destroy() // nothrow
>     {
>         delete this;
>     }
>
>     virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
>     virtual void * get_untyped_deleter() = 0;
>
>     void add_ref_copy()
>     {
>         atomic_increment( &use_count_ );
>     }
>
>     bool add_ref_lock() // true on success
>     {
>         return atomic_conditional_increment( &use_count_ ) != 0;
>     }
>
>     void release() // nothrow
>     {
>         if( atomic_decrement( &use_count_ ) == 1 )
>         {
>           dispose();
>           weak_release();
>         }
>     }
>
>     void weak_add_ref() // nothrow
>     {
>         atomic_increment( &weak_count_ );
>     }
>
>     void weak_release() // nothrow
>     {
>         if( atomic_decrement( &weak_count_ ) == 1 )
>         {
>             destroy();
>         }
>     }
>
>     long use_count() const // nothrow
>     {
>         return use_count_.load( std::memory_order_acquire );
>     }
> };
>
>
> template<class X> class sp_counted_impl_p: public sp_counted_base
> {
> private:
>
>     X * px_;
>
>     sp_counted_impl_p( sp_counted_impl_p const & );
>     sp_counted_impl_p & operator= ( sp_counted_impl_p const & );
>
>     typedef sp_counted_impl_p<X> this_type;
>
> public:
>
>     explicit sp_counted_impl_p( X * px ): px_( px )
>     {
> #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
>         boost::sp_scalar_constructor_hook( px, sizeof(X), this );
> #endif
>     }
>
>     virtual void dispose() // nothrow
>     {
> #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
>         boost::sp_scalar_destructor_hook( px_, sizeof(X), this );
> #endif
>         boost::checked_delete( px_ );
>     }
>
>     virtual void * get_deleter( detail::sp_typeinfo const & )
>     {
>         return 0;
>     }
>
>     virtual void * get_untyped_deleter()
>     {
>         return 0;
>     }
>
> #if defined(BOOST_SP_USE_STD_ALLOCATOR)
>
>     void * operator new( std::size_t )
>     {
>         return std::allocator<this_type>().allocate( 1,
> static_cast<this_type *>(0) );
>     }
>
>     void operator delete( void * p )
>     {
>         std::allocator<this_type>().deallocate( static_cast<this_type
> *>(p), 1 );
>     }
>
> #endif
>
> #if defined(BOOST_SP_USE_QUICK_ALLOCATOR)
>
>     void * operator new( std::size_t )
>     {
>         return quick_allocator<this_type>::alloc();
>     }
>
>     void operator delete( void * p )
>     {
>         quick_allocator<this_type>::dealloc( p );
>     }
>
> #endif
> };
>
> class shared_count
> {
> private:
>
>     sp_counted_base * pi_;
>
> public:
>
>     void swap(shared_count & r) // nothrow
>     {
>         sp_counted_base * tmp = r.pi_;
>         r.pi_ = pi_;
>         pi_ = tmp;
>     }
>
>     shared_count(): pi_(0) // nothrow
> #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
>         , id_(shared_count_id)
> #endif
>     {
>     }
>
>     template<class Y> explicit shared_count( Y * p ): pi_( 0 )
> #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
>         , id_(shared_count_id)
> #endif
>     {
> #ifndef BOOST_NO_EXCEPTIONS
>
>         try
>         {
>             pi_ = new sp_counted_impl_p<Y>( p );
>         }
>         catch(...)
>         {
>             boost::checked_delete( p );
>             throw;
>         }
>
> #else
>
>         pi_ = new sp_counted_impl_p<Y>( p );
>
>         if( pi_ == 0 )
>         {
>             boost::checked_delete( p );
>             boost::throw_exception( std::bad_alloc() );
>         }
>
> #endif
>     }
>
>
>     shared_count(shared_count && r): pi_(r.pi_) // nothrow
> #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
>         , id_(shared_count_id)
> #endif
>     {
>         r.pi_ = 0;
>     }
>
>     ~shared_count() // nothrow
>     {
>       if( pi_ != 0 ) pi_->release();
> #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
>         id_ = 0;
> #endif
>     }
>
> };
>
> template< class T > struct sp_element
> {
>     typedef T type;
> };
>
> template< class X, class Y, class T > inline void
> sp_enable_shared_from_this( boost::shared_ptr<X> const * ppx, Y const * py,
> boost::enable_shared_from_this< T > const * pe )
> {
>     if( pe != 0 )
>     {
>         pe->_internal_accept_owner( ppx, const_cast< Y* >( py ) );
>     }
> }
>
> struct sp_any_pointer
> {
>     template<class T> sp_any_pointer( T* ) {}
> };
>
> inline void sp_enable_shared_from_this( sp_any_pointer, sp_any_pointer,
> sp_any_pointer )
> {
> }
>
> template< class T, class Y > inline void sp_pointer_construct(
> boost::shared_ptr< T > * ppx, Y * p, boost::detail::shared_count & pn )
> {
>     boost::detail::shared_count( p ).swap( pn );
>     boost::detail::sp_enable_shared_from_this( ppx, p, p );
> }
>
> template< class T > struct sp_dereference
> {
>     typedef T & type;
> };
>
> }//namespace detail
>
> template<class T> class shared_ptr
> {
> private:
>
>     // Borland 5.5.1 specific workaround
>     typedef shared_ptr<T> this_type;
>
> public:
>
>     typedef typename boost::detail::sp_element< T >::type element_type;
>
>     template<class Y>
>     explicit shared_ptr( Y * p ): px( p ), pn() // Y must be complete
>     {
>         boost::detail::sp_pointer_construct( this, p, pn );
>     }
>
>     element_type * px;                 // contained pointer
>     boost::detail::shared_count pn;    // reference counter
>
> typename boost::detail::sp_dereference< T >::type operator* () const
> {
>   return *px;
> }
>
> };
>
> } // namespace boost
>
> extern "C" {
>   double test(void) {
>     boost::shared_ptr<int> y = boost::shared_ptr<int>(new int(42));
>     return *y;
>   }
> }
>
> int main(void){
>   double result = test();
>   cout<<result<<endl;
>   return 0;
> }
>
>  --
> You received this message because you are subscribed to the Google Groups
> "emscripten-discuss" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to [email protected].
> For more options, visit https://groups.google.com/d/optout.
>

-- 
You received this message because you are subscribed to the Google Groups 
"emscripten-discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.

Reply via email to