public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug c/108296] New: __builtin_memcpy generating wrong code in some cases
@ 2023-01-05  8:37 nyh at math dot technion.ac.il
  2023-01-05  8:53 ` [Bug c/108296] " pinskia at gcc dot gnu.org
                   ` (4 more replies)
  0 siblings, 5 replies; 6+ messages in thread
From: nyh at math dot technion.ac.il @ 2023-01-05  8:37 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108296

            Bug ID: 108296
           Summary: __builtin_memcpy generating wrong code in some cases
           Product: gcc
           Version: 12.2.1
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c
          Assignee: unassigned at gcc dot gnu.org
          Reporter: nyh at math dot technion.ac.il
  Target Milestone: ---

The following trivial code, copying a string over itself moved by one byte,
shows wrong results for __builtin_memcpy() on gcc 12.2.1:

#include <cstring>
int main(){
    char bufa[128] = "0123456789abcdefghijklmnopqrstuvwxyz";
    char bufb[128] = "0123456789abcdefghijklmnopqrstuvwxyz";
    memcpy(bufa, bufa+1, 27);
    printf("          memcpy: %s\n", bufa);
    __builtin_memcpy(bufb, bufb+1, 27);
    printf("__builtin_memcpy: %s\n", bufb);
}

As you can see running it, memcpy() returned the right result,
123456789abcdefghijklmnopqrrstuvwxyz (the first 27 characters shifted back, so
"r" is double in the response), but __builtin_memcpy() returned the *wrong*
result - 123456789abdefgghijklmnopqrrstuvwxyz (the "c" character disappeared
and the "g" is  also doubled).


This bug was discovered in the OSv project
https://github.com/cloudius-systems/osv/issues/1212 with code that doesn't
(obviously) call __builtin_memcpy() directly, but rather had a 27-character
type being copied and the compiler implemented this copy with a call to
__builtin_memcpy(). The original miscompiling code in OSv  was something like
the following:

#include <cstdio>
int main(){
    char buf[128] = "0123456789abcdefghijklmnopqrstuvwxyz";
    struct [[gnu::packed]] data {
        char x[27];
    };
    void *p0 = buf;
    void *p1 = &buf[1];
    *static_cast<data*>(p0) = *static_cast<const data*>(p1);
    printf("%s", buf);
}

This appears to be a regression - this code did not miscompile in earlier gcc
releases.

^ permalink raw reply	[flat|nested] 6+ messages in thread

* [Bug c/108296] __builtin_memcpy generating wrong code in some cases
  2023-01-05  8:37 [Bug c/108296] New: __builtin_memcpy generating wrong code in some cases nyh at math dot technion.ac.il
@ 2023-01-05  8:53 ` pinskia at gcc dot gnu.org
  2023-01-05  9:08 ` nyh at math dot technion.ac.il
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: pinskia at gcc dot gnu.org @ 2023-01-05  8:53 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108296

Andrew Pinski <pinskia at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
         Resolution|---                         |DUPLICATE
             Status|UNCONFIRMED                 |RESOLVED

--- Comment #1 from Andrew Pinski <pinskia at gcc dot gnu.org> ---
Dup of bug 32667.

The bug is not memcpy does not work for overlapping memory locations but rather
using memcpy instead of memmove for struct/block copies.

*** This bug has been marked as a duplicate of bug 32667 ***

^ permalink raw reply	[flat|nested] 6+ messages in thread

* [Bug c/108296] __builtin_memcpy generating wrong code in some cases
  2023-01-05  8:37 [Bug c/108296] New: __builtin_memcpy generating wrong code in some cases nyh at math dot technion.ac.il
  2023-01-05  8:53 ` [Bug c/108296] " pinskia at gcc dot gnu.org
@ 2023-01-05  9:08 ` nyh at math dot technion.ac.il
  2023-01-05 11:10 ` jakub at gcc dot gnu.org
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: nyh at math dot technion.ac.il @ 2023-01-05  9:08 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108296

--- Comment #2 from Nadav Har'El <nyh at math dot technion.ac.il> ---
Thanks. Interesting. So __builtin_memcpy() is simply not supposed to work
correctly for overlapping areas? I now realize that according to memcpy(3)
documentation, memcpy() is also not guaranteed to work correctly in this case
(and you should use memmove() in this case), but in practice it does work
correctly when copying a higher address to a lower address.

^ permalink raw reply	[flat|nested] 6+ messages in thread

* [Bug c/108296] __builtin_memcpy generating wrong code in some cases
  2023-01-05  8:37 [Bug c/108296] New: __builtin_memcpy generating wrong code in some cases nyh at math dot technion.ac.il
  2023-01-05  8:53 ` [Bug c/108296] " pinskia at gcc dot gnu.org
  2023-01-05  9:08 ` nyh at math dot technion.ac.il
@ 2023-01-05 11:10 ` jakub at gcc dot gnu.org
  2023-01-05 11:14 ` jakub at gcc dot gnu.org
  2023-01-09 11:15 ` rguenth at gcc dot gnu.org
  4 siblings, 0 replies; 6+ messages in thread
From: jakub at gcc dot gnu.org @ 2023-01-05 11:10 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108296

Jakub Jelinek <jakub at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |jakub at gcc dot gnu.org

--- Comment #3 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
The restrictions on __builtin_memcpy are exactly the same as on memcpy, and ISO
C is very clear on: "If copying takes place between objects that overlap, the
behavior
is undefined."

^ permalink raw reply	[flat|nested] 6+ messages in thread

* [Bug c/108296] __builtin_memcpy generating wrong code in some cases
  2023-01-05  8:37 [Bug c/108296] New: __builtin_memcpy generating wrong code in some cases nyh at math dot technion.ac.il
                   ` (2 preceding siblings ...)
  2023-01-05 11:10 ` jakub at gcc dot gnu.org
@ 2023-01-05 11:14 ` jakub at gcc dot gnu.org
  2023-01-09 11:15 ` rguenth at gcc dot gnu.org
  4 siblings, 0 replies; 6+ messages in thread
From: jakub at gcc dot gnu.org @ 2023-01-05 11:14 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108296

--- Comment #4 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
I think all of the above snippets have UB, whether using memcpy,
__builtin_memcpy or
overlapping structure assignment.  It is all user error.
If you need overlapping copies, always use memmove/__builtin_memmove.

^ permalink raw reply	[flat|nested] 6+ messages in thread

* [Bug c/108296] __builtin_memcpy generating wrong code in some cases
  2023-01-05  8:37 [Bug c/108296] New: __builtin_memcpy generating wrong code in some cases nyh at math dot technion.ac.il
                   ` (3 preceding siblings ...)
  2023-01-05 11:14 ` jakub at gcc dot gnu.org
@ 2023-01-09 11:15 ` rguenth at gcc dot gnu.org
  4 siblings, 0 replies; 6+ messages in thread
From: rguenth at gcc dot gnu.org @ 2023-01-09 11:15 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108296

Richard Biener <rguenth at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
         Resolution|DUPLICATE                   |INVALID

--- Comment #5 from Richard Biener <rguenth at gcc dot gnu.org> ---
Not a duplicate but indeed invalid.  For the aggregate asignment
you cannot have an object of type data live at &x and &x + 1 at the same time.

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2023-01-09 11:15 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-01-05  8:37 [Bug c/108296] New: __builtin_memcpy generating wrong code in some cases nyh at math dot technion.ac.il
2023-01-05  8:53 ` [Bug c/108296] " pinskia at gcc dot gnu.org
2023-01-05  9:08 ` nyh at math dot technion.ac.il
2023-01-05 11:10 ` jakub at gcc dot gnu.org
2023-01-05 11:14 ` jakub at gcc dot gnu.org
2023-01-09 11:15 ` rguenth at gcc dot gnu.org

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).