From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 19553 invoked by alias); 17 Mar 2009 10:55:43 -0000 Received: (qmail 19529 invoked by uid 48); 17 Mar 2009 10:55:30 -0000 Date: Tue, 17 Mar 2009 10:55:00 -0000 Subject: [Bug libstdc++/39480] New: generated memcpy causes trouble in assignment X-Bugzilla-Reason: CC Message-ID: Reply-To: gcc-bugzilla@gcc.gnu.org To: gcc-bugs@gcc.gnu.org From: "fpbeekhof at gmail dot com" Mailing-List: contact gcc-bugs-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-bugs-owner@gcc.gnu.org X-SW-Source: 2009-03/txt/msg01164.txt.bz2 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&, HarrisPoint&) (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 // #include /** * @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 inline void swap_from_glibcxx(_Tp& __a, _Tp& __b) { // concept requirements // __glibcxx_function_requires(_SGIAssignableConcept<_Tp>) _Tp __tmp = __a; __a = __b; __b = __tmp; } template struct Point2D : public std::tr1::array { template Point2D(const U x, const V y) { (*this)[0] = x; (*this)[1] = y; } }; template class FeaturePoint : public Point2D { public: typedef T data_type; FeaturePoint(const U h, const U w) : Point2D(h,w) {} }; template class HarrisPoint : public FeaturePoint { public: typedef T data_type; HarrisPoint(const U h, const U w, const T value) : FeaturePoint(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 a(1, 2, 3.0f); // std::tr1::array 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