From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 25428 invoked by alias); 19 Feb 2015 04:03:05 -0000 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 Received: (qmail 25359 invoked by uid 48); 19 Feb 2015 04:03:01 -0000 From: "msebor at gmail dot com" To: gcc-bugs@gcc.gnu.org Subject: [Bug libstdc++/65114] New: char_traits::copy violates memcpy constraints, own postcondition Date: Thu, 19 Feb 2015 04:03:00 -0000 X-Bugzilla-Reason: CC X-Bugzilla-Type: new X-Bugzilla-Watch-Reason: None X-Bugzilla-Product: gcc X-Bugzilla-Component: libstdc++ X-Bugzilla-Version: 4.9.2 X-Bugzilla-Keywords: X-Bugzilla-Severity: normal X-Bugzilla-Who: msebor at gmail dot com X-Bugzilla-Status: UNCONFIRMED X-Bugzilla-Priority: P3 X-Bugzilla-Assigned-To: unassigned at gcc dot gnu.org X-Bugzilla-Target-Milestone: --- X-Bugzilla-Flags: X-Bugzilla-Changed-Fields: bug_id short_desc product version bug_status bug_severity priority component assigned_to reporter Message-ID: Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: 7bit X-Bugzilla-URL: http://gcc.gnu.org/bugzilla/ Auto-Submitted: auto-generated MIME-Version: 1.0 X-SW-Source: 2015-02/txt/msg02085.txt.bz2 https://gcc.gnu.org/bugzilla/show_bug.cgi?id=65114 Bug ID: 65114 Summary: char_traits::copy violates memcpy constraints, own postcondition Product: gcc Version: 4.9.2 Status: UNCONFIRMED Severity: normal Priority: P3 Component: libstdc++ Assignee: unassigned at gcc dot gnu.org Reporter: msebor at gmail dot com The precondition on char_traits::copy(s, p, n), namely that p not be in the range [s, s + n), is weaker than the precondition on a call to memcpy(s, p, n). The latter requires that none of the characters accessed via s is also accessed via p. The program below shows an example of a call to char_traits::copy that satisfies the C++ precondition but violates the C precondition (as indicated by the Valgrind error). The element a[1] is accessed by both s and p. As a result, the program also fails the C++ postcondition. $ cat t.cpp && g++ -Wall t.cpp && valgrind ./a.out #include #include #include struct Traits: std::char_traits { static char* copy (char *s, const char *p, size_t n) { assert (p < s || s + n < p); return std::char_traits::copy (s, p, n); } }; int main () { char a[] = "abc"; const size_t n = 2; const char *p = a; char *s = a + 1; for (size_t i = 0; i != n; ++i) Traits::assign (s[i], p[i]); char b[] = "abc"; p = b; s = b + 1; Traits::copy (s, p, n); printf ("%s == %s\n", a, b); assert (0 == Traits::compare (a, b, sizeof a)); } ==15497== Memcheck, a memory error detector ==15497== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al. ==15497== Using Valgrind-3.10.1 and LibVEX; rerun with -h for copyright info ==15497== Command: ./a.out ==15497== ==15497== Source and destination overlap in memcpy(0xffefffe41, 0xffefffe40, 2) ==15497== at 0x4C2E13D: memcpy@@GLIBC_2.14 (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so) ==15497== by 0x400859: std::char_traits::copy(char*, char const*, unsigned long) (in /home/msebor/tmp/a.out) ==15497== by 0x4008BA: Traits::copy(char*, char const*, unsigned long) (in /home/msebor/tmp/a.out) ==15497== by 0x40078A: main (in /home/msebor/tmp/a.out) ==15497== aaa == aab a.out: t.cpp:30: int main(): Assertion `0 == Traits::compare (a, b, sizeof a)' failed. ==15497== ==15497== HEAP SUMMARY: ==15497== in use at exit: 0 bytes in 0 blocks ==15497== total heap usage: 2 allocs, 2 frees, 188 bytes allocated ==15497== ==15497== All heap blocks were freed -- no leaks are possible ==15497== ==15497== For counts of detected and suppressed errors, rerun with: -v ==15497== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0) Aborted (core dumped)