Opened 8 years ago

Closed 8 years ago

Last modified 8 years ago

#11044 closed Bugs (fixed)

boost::rv inherits off union, when such passed as template argument

Reported by: Petr Machata <pmachata@…> Owned by: Ion Gaztañaga
Milestone: To Be Determined Component: move
Version: Boost 1.57.0 Severity: Problem
Keywords: Cc:

Description

Consider the following minimal reproducer:

template<typename T> struct wrap { typedef T type; };
template <class T> class rv: public wrap <T>::type {};
 
template <class value_type>
struct circular_buffer
{
    typedef const value_type& param_value_type;
    typedef rv< value_type >& rvalue_type;
 
    void push_back(param_value_type item) {}
    void push_back(rvalue_type item) {}
};
 
union U { int i; char c; };
 
void f(circular_buffer<U> b, const U& u) { b.push_back(u); }

Certain GCC 5.0's had a bug where rv would be instantiated, even though it doesn't have to be (so I am told), which uncovered the latent bug in Boost that rv inherits off union when given one.

Proposed patch:

diff -up ./move/core.hpp~ ./move/core.hpp
--- boost/move/core.hpp~	2015-02-09 17:33:35.000000000 +0100
+++ boost/move/core.hpp	2015-02-13 13:54:52.012130813 +0100
@@ -43,6 +43,7 @@
 #if defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && !defined(BOOST_MOVE_DOXYGEN_INVOKED)
 
    #include <boost/move/detail/meta_utils.hpp>
+   #include <boost/type_traits/is_class.hpp>
 
    //Move emulation rv breaks standard aliasing rules so add workarounds for some compilers
    #if defined(__GNUC__) && (__GNUC__ >= 4) && \
@@ -65,7 +66,7 @@
    template <class T>
    class rv
       : public ::boost::move_detail::if_c
-         < ::boost::move_detail::is_class_or_union<T>::value
+         < ::boost::is_class<T>::value
          , T
          , ::boost::move_detail::nat
          >::type

I regtested this on x86_64 using GCC 5.0.0, and noted no regressions. However I'm not sure if pulling in type traits like this is admissible--I mean, why else reimplement is_class_or_union in Boost.Move? Historical reasons?

Change History (2)

comment:1 by Ion Gaztañaga, 8 years ago

Resolution: fixed
Status: newclosed

Hi,

In current master and develop branches it inherits from boost::move::is_class. Custom traits are used to avoid many dependencies brought by Boost.TypeTraits (MPL, Preprocessor...). This should change when the new version of dependency-free is released (see http://comments.gmane.org/gmane.comp.lib.boost.devel/256808).

in reply to:  1 comment:2 by Petr Machata <pmachata@…>, 8 years ago

Replying to igaztanaga:

In current master and develop branches it inherits from boost::move::is_class.

Oh, cool. I must have forgotten to sync the git tree before checking.

Custom traits are used to avoid many dependencies brought by Boost.TypeTraits.

That's what I suspected. Thanks for taking care of this!

Note: See TracTickets for help on using tickets.