Hi I am compiling via : EMCC_DEBUG=1 em++ -std=c++11 -O3 example.cpp -s 
EXPORTED_FUNCTIONS="['_test']" and am using version : emcc (Emscripten 
GCC-like replacement) 1.30.0 (commit 
ba813471568f05c97c59099a963bc35341d4dfb5)


On Monday, April 6, 2015 at 7:53:28 PM UTC+1, Alon Zakai wrote:
>
> 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] <javascript:>> 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] <javascript:>.
>> 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