This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Bug libstdc++/39480] New: generated memcpy causes trouble in assignment


The following code is unsafe, and I think it's not my fault.

$ g++ -Wall -g testIterSwap.cc ; valgrind -q ./a.out 
==1674== Source and destination overlap in memcpy(0x7FF000500, 0x7FF000500, 20)
==1674==    at 0x4C2508B: memcpy (mc_replace_strmem.c:402)
==1674==    by 0x4008D2: void swap_from_glibcxx<HarrisPoint<float, int>
>(HarrisPoint<float, int>&, HarrisPoint<float, int>&) (testIterSwap.cc:22)
==1674==    by 0x400793: main (testIterSwap.cc:68)

It would appear that the auto-generated operator=() uses a memcpy() which is
not safe. The operator=() that is provided below solves the problem.

-------- cut here ------------

#include <tr1/array>
// #include <algorithm>


 /**
   *  @brief Swaps two values.
   *  @param  a  A thing of arbitrary type.
   *  @param  b  Another thing of arbitrary type.
   *  @return   Nothing.
   *
   *  This is the simple classic generic implementation.  It will work on
   *  any type which has a copy constructor and an assignment operator.
  */
  template<typename _Tp>
    inline void
    swap_from_glibcxx(_Tp& __a, _Tp& __b)
    {
      // concept requirements
//      __glibcxx_function_requires(_SGIAssignableConcept<_Tp>)

      _Tp __tmp = __a;
      __a = __b;
      __b = __tmp;
    }



template <typename T>
struct Point2D :  public std::tr1::array<T, 2>
{
        template <typename U, typename V>
        Point2D(const U x, const V y)
        {
                (*this)[0] = x;
                (*this)[1] = y;
        }
};

template <typename T, typename U>
class FeaturePoint : public Point2D<U>
{
        public:
                typedef T data_type;

                FeaturePoint(const U h, const U w) : Point2D<U>(h,w) {}
};

template <typename T, typename U>
class HarrisPoint : public FeaturePoint<T, U>
{
        public:
                typedef T data_type;

                HarrisPoint(const U h, const U w, const T value) :
                        FeaturePoint<T, U>(h, w), value_(value) { }
/*
                // THIS FIXES IT.
                HarrisPoint &operator=(const HarrisPoint &rhs)
                {
                        std::memmove(this, &rhs, sizeof(HarrisPoint));
                        return *this;
                }
*/
        private:
                T value_;
};

int main()
{
        HarrisPoint<float, int> a(1, 2, 3.0f);
//      std::tr1::array<int, 2> a; a[0] = 3; a[1] = 5; // fine

        a = a; // fine
//      std::swap(a, a);
        swap_from_glibcxx(a, a);

        return 0;
}


-- 
           Summary: generated memcpy causes trouble in assignment
           Product: gcc
           Version: 4.2.4
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: libstdc++
        AssignedTo: unassigned at gcc dot gnu dot org
        ReportedBy: fpbeekhof at gmail dot com


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=39480


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]