#11044 closed Bugs (fixed)
boost::rv inherits off union, when such passed as template argument
Reported by: | 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)
follow-up: 2 comment:1 by , 8 years ago
Resolution: | → fixed |
---|---|
Status: | new → closed |
comment:2 by , 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!
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).