public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
From: "rguenth at gcc dot gnu.org" <gcc-bugzilla@gcc.gnu.org>
To: gcc-bugs@gcc.gnu.org
Subject: [Bug c++/95349] Using std::launder(p) produces unexpected behavior where (p) produces expected behavior
Date: Mon, 15 Jun 2020 09:29:25 +0000	[thread overview]
Message-ID: <bug-95349-4-qLXx33BrJn@http.gcc.gnu.org/bugzilla/> (raw)
In-Reply-To: <bug-95349-4@http.gcc.gnu.org/bugzilla/>

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

--- Comment #36 from Richard Biener <rguenth at gcc dot gnu.org> ---
(In reply to Andrew Downing from comment #35)
> I agree that the new implicit object creation rules sound very difficult to
> implement correctly especially because the behavior in C is different. I'm
> curious to see how that will all play out.
> 
> In this situation though, if we use the C rules for what memcpy does C17
> 6.5/6
> https://web.archive.org/web/20181230041359if_/http://www.open-std.org/jtc1/
> sc22/wg14/www/abq/c17_updated_proposed_fdis.pdf#section.6.5, the effective
> type shouldn't be changed. The declared type of both objects is known to the
> compiler. In the first memcpy the declared type of the object is unsigned
> char[8], in the second memcpy the declared type of the object is double.

The issue I have with this special handling of objects with a declared type
is that the standard assumes universal knowledge and disregards that
compilers are imperfect.  It's also not clear what it means for

 int *p;
 int x;
 if (<condition>)
   p = &x;
 else
   p = malloc (4);
 memcpy (p, q, 4);

there is a single memcpy call and the standard says that both the dynamic
type transfers (from q) and that it does not (to x).

> Placement new changes the effective type to std::uint64_t, but that doesn't
> change the behavior of memcpy. Footnote 88 says "Allocated objects have no
> declared type.". I believe calling a function defined in another TU that
> returns a pointer also has to be considered to return a pointer to an object
> with no declared type, because the object's declaration isn't visible. In
> this situation though, the declared types are visible, and so a modifying
> access, or memcpy, or memmove shouldn't change the effective type.

Note the C++ standard makes the placement new optional.  Do you say that
your example is incorrect with the placement new elided?  Note you say
the declared types are visible - but at least 'd' is in another function
(compilers are imperfect) and is accessed via a pointer here.  IIRC C++
does not have this "special-casing" of objects with declared types
(it doesn't have this memcpy wording at all I think).  [there's more
"interesting" bits of all this dynamic type frobbing in PR79671 when
partial objects are re-used]

> If gcc is changing the effective type with every memcpy no matter what, that
> would be the wrong thing to do right? Especially since you're saying that
> it's the reason that this example isn't being compiled correctly.

As you say above the C rule that memcpy does not change the dynamic type
of an object with a declared type can only be fulfilled by being conservative.
This is why GCC interprets memcpy as TBAA barrier but it uses the
transfer of dynamic type as means to be able to elide a memcpy roundtrip
as seen in your testcase.  If the memcpy roundtrip has to be considered
a side-effect then I see no easy way to preserve that without preserving
the actual memcpy operation [without changing the intermediate representation
of GCC, that is].  I'd be interested in a C testcase that we get wrong,
even when relying on that special casing of objects with a declared type.
It should then be possible to construct a C++ variant that expects exactly
the opposite behavior.

The main issue I see is that this differing expectations of C and C++ are
impossible to get correct at the same time.

  parent reply	other threads:[~2020-06-15  9:29 UTC|newest]

Thread overview: 53+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-05-26 20:45 [Bug c++/95349] New: " andrew2085 at gmail dot com
2020-05-27  8:04 ` [Bug c++/95349] " rguenth at gcc dot gnu.org
2020-05-27  9:14 ` redi at gcc dot gnu.org
2020-05-27  9:40 ` rguenther at suse dot de
2020-05-27 11:05 ` redi at gcc dot gnu.org
2020-05-27 14:45 ` andrew2085 at gmail dot com
2020-05-27 15:07 ` redi at gcc dot gnu.org
2020-05-27 15:19 ` andrew2085 at gmail dot com
2020-05-27 16:01 ` andrew2085 at gmail dot com
2020-05-29 10:59 ` ed at catmur dot uk
2020-05-29 11:23 ` rguenth at gcc dot gnu.org
2020-05-29 11:32 ` rguenth at gcc dot gnu.org
2020-05-29 13:53 ` ed at catmur dot uk
2020-05-29 14:15 ` redi at gcc dot gnu.org
2020-05-29 14:24 ` rguenther at suse dot de
2020-05-29 15:05 ` andrew2085 at gmail dot com
2020-05-29 18:07 ` richard-gccbugzilla at metafoo dot co.uk
2020-05-29 21:00 ` andrew2085 at gmail dot com
2020-05-29 21:50 ` richard-gccbugzilla at metafoo dot co.uk
2020-05-29 23:13 ` andrew2085 at gmail dot com
2020-05-29 23:25 ` richard-gccbugzilla at metafoo dot co.uk
2020-06-02 12:09 ` rguenth at gcc dot gnu.org
2020-06-02 12:20 ` rguenth at gcc dot gnu.org
2020-06-02 16:00 ` andrew2085 at gmail dot com
2020-06-02 16:23 ` rguenther at suse dot de
2020-06-02 16:34 ` andrew2085 at gmail dot com
2020-06-02 16:37 ` andrew2085 at gmail dot com
2020-06-02 17:54 ` rguenther at suse dot de
2020-06-02 18:43 ` andrew2085 at gmail dot com
2020-06-02 20:53 ` andrew2085 at gmail dot com
2020-06-03  6:52 ` rguenth at gcc dot gnu.org
2020-06-04  0:27 ` andrew2085 at gmail dot com
2020-06-04  6:14 ` rguenther at suse dot de
2020-06-04 16:05 ` andrew2085 at gmail dot com
2020-06-05  6:52 ` rguenth at gcc dot gnu.org
2020-06-05 14:30 ` andrew2085 at gmail dot com
2020-06-15  9:29 ` rguenth at gcc dot gnu.org [this message]
2020-06-15 21:45 ` richard-gccbugzilla at metafoo dot co.uk
2020-06-16  3:27 ` andrew2085 at gmail dot com
2020-06-16  6:50 ` rguenther at suse dot de
2020-06-16  6:57 ` rguenther at suse dot de
2020-06-16 13:56 ` andrew2085 at gmail dot com
2022-01-11 12:43 ` rguenth at gcc dot gnu.org
2022-01-11 12:48 ` rguenth at gcc dot gnu.org
2022-11-14  4:53 ` andrew2085 at gmail dot com
2024-06-03  8:02 ` Christopher.Nerz at de dot bosch.com
2024-06-03  8:51 ` rguenth at gcc dot gnu.org
2024-06-03  9:13 ` Christopher.Nerz at de dot bosch.com
2024-06-03  9:23 ` rguenth at gcc dot gnu.org
2024-06-03 10:26 ` Christopher.Nerz at de dot bosch.com
2024-06-03 11:19 ` rguenther at suse dot de
2024-06-03 15:53 ` redi at gcc dot gnu.org
2024-06-03 16:00 ` redi at gcc dot gnu.org

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=bug-95349-4-qLXx33BrJn@http.gcc.gnu.org/bugzilla/ \
    --to=gcc-bugzilla@gcc.gnu.org \
    --cc=gcc-bugs@gcc.gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).