[Boost-bugs] [Boost C++ Libraries] #12264: queue<Apple*> can pop to Orange* even when Apples don't relate to Oranges

Subject: [Boost-bugs] [Boost C++ Libraries] #12264: queue<Apple*> can pop to Orange* even when Apples don't relate to Oranges
From: Boost C++ Libraries (noreply_at_[hidden])
Date: 2016-06-10 20:04:29


#12264: queue<Apple*> can pop to Orange* even when Apples don't relate to Oranges
----------------------------------------------+--------------------------
 Reporter: Jacob Burckhardt <JBurckhardt@…> | Owner: timblechmann
     Type: Bugs | Status: new
Milestone: To Be Determined | Component: lockfree
  Version: Boost 1.61.0 | Severity: Problem
 Keywords: |
----------------------------------------------+--------------------------
 The following program successfully compiles, but I think it should
 give a compiler error since it is casting an Apple pointer to an
 Orange pointer. Apple and Orange have no inheritance relationship so
 I think the cast should be invalid.


 {{{
 #include <boost/lockfree/queue.hpp>

 class Apple {};
 class Orange {};

 int main() {
    boost::lockfree::queue<Apple*> m_queue(1);
    Orange *orange;
    m_queue.pop(orange);
 }

 }}}

 For the following program, g++ says "error: cannot convert ‘Orange*’ to
 â€˜Apple*’". If someone forgets what type of object that are storing in
 boost::lockfree::queue then they could make the above mistake of
 trying to extract the wrong type and it would be helpful if the
 compiler and boost caught the error.


 {{{
 class Apple {};
 class Orange {};

 int main() {
    Orange *orange = new Orange;
    Apple *apple = orange;
 }
 }}}


 When I make the following change, g++ says "error: cannot convert
 â€˜Apple*’ to ‘Orange*’" for the first program:


 {{{
 diff --git a/include/boost/lockfree/detail/copy_payload.hpp
 b/include/boost/lockfree/detail/copy_payload.hpp
 index 75b1b52..7679d50 100644
 --- a/include/boost/lockfree/detail/copy_payload.hpp
 +++ b/include/boost/lockfree/detail/copy_payload.hpp
 @@ -35,7 +35,7 @@ struct copy_constructible_and_copyable
      template <typename T, typename U>
      static void copy(T & t, U & u)
      {
 - u = U(t);
 + u = t;
      }
  };

 }}}

 Even though that change helps my case by warning me of my error, I
 think it probably breaks other cases, but at least this might help in
 understanding the reason why the original version of lockfree does not
 give an error message. In my case, U is a pointer type. It looks
 like it is calling the U constructor but I'm not sure what it means to
 call a constructor of a pointer type. Apparently what it means is to
 perform some kind of dangerous cast like an old style C cast instead of
 one of the more safer types of casts like a newer C++ cast. Perhaps you
 can make lockfree use my change only when U is a pointer type, but use
 the old version of the code for non-pointer types?

 I tested with g++ (GCC) 4.8.3 20140911 (Red Hat 4.8.3-9)

 I used this version of lockfree:

 commit c112c29bee1d35089d4a603027dbbc4e1744d59b
 Apr 2 12:02:35 2016 +0200

-- 
Ticket URL: <https://svn.boost.org/trac/boost/ticket/12264>
Boost C++ Libraries <http://www.boost.org/>
Boost provides free peer-reviewed portable C++ source libraries.

This archive was generated by hypermail 2.1.7 : 2017-02-16 18:50:20 UTC