From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 48) id 1F3773851C1B; Tue, 16 Jun 2020 03:27:14 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 1F3773851C1B DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1592278034; bh=Ums46Uq6ik8ZUYB2aOherWSAwvozwTvWNtFDxNz54No=; h=From:To:Subject:Date:In-Reply-To:References:From; b=RARN4ymOIs1/7zpf2uYpKIpTMshkS33WbQrcbk+kY/fgl9jv6fizPgRItM8hu11l4 ysH1oE3gTMtEGSvbdxBW9uBK2FB1VUTIX2AuM5sDyH4apZeTfqD0GOXVLGJgUCiaJb GSXnVuPACY/0WHLPOkZo+abaAHSfWtXgIsltARtE= From: "andrew2085 at gmail dot com" To: gcc-bugs@gcc.gnu.org Subject: [Bug c++/95349] Using std::launder(p) produces unexpected behavior where (p) produces expected behavior Date: Tue, 16 Jun 2020 03:27:13 +0000 X-Bugzilla-Reason: CC X-Bugzilla-Type: changed X-Bugzilla-Watch-Reason: None X-Bugzilla-Product: gcc X-Bugzilla-Component: c++ X-Bugzilla-Version: 10.1.0 X-Bugzilla-Keywords: alias, wrong-code X-Bugzilla-Severity: normal X-Bugzilla-Who: andrew2085 at gmail dot com X-Bugzilla-Status: UNCONFIRMED X-Bugzilla-Resolution: 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: Message-ID: In-Reply-To: References: Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable X-Bugzilla-URL: http://gcc.gnu.org/bugzilla/ Auto-Submitted: auto-generated MIME-Version: 1.0 X-BeenThere: gcc-bugs@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-bugs mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 16 Jun 2020 03:27:14 -0000 https://gcc.gnu.org/bugzilla/show_bug.cgi?id=3D95349 --- Comment #38 from Andrew Downing --- > int *p; > int x; > if () > p =3D &x; > else > p =3D malloc (4); > memcpy (p, q, 4); >=20 > 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). I would say just that, that it both does and doesn't transfer the effective type. Meaning that you need to be conservative during optimization and cons= ider p to alias both int and whatever type q is. > Note the C++ standard makes the placement new optional. Do you say that > your example is incorrect with the placement new elided? I'm not sure what you mean about the first part about it being optional. It depends what you mean by elided. I wouldn't expect any code to be generated= for it either way, but I would expect the compiler to now consider the object at that address as having a different type regardless. If we pretend for a second that GCC is using pre C++20 rules for memcpy and= not messing with the effective/dynamic type for the destination, then isn't this example still not going to work if GCC is treating placement new in this ca= se as doing nothing? In f1 after s1 is called, d is still a double, and u is a pointer to uint64_t, so pointing u at d and accessing *u is still going to = be UB right? I would expect d =3D 3.14159 to still be optimized out, because w= hy would a store to a double affect a load from a uint64_t? I can't see how this could work in every situation unless the compiler keeps track of the type of d changing from double -> uint64_t, so it knows that stores to it when it was a double could affect loads from a uint64_t after = it's type changed to uint64_t. In a more complex scenario where placement new was used conditionally with many different types, the compiler would have to consider pointers to any of those types as aliasing d afterwards. I can thi= nk of some situations where the compiler would have a very hard time proving t= hat the address of some object didn't make it's way to a placement new somewhere else in the program. This does seem very difficult to do correctly without being very conservative and disabling a lot of optimizations, or having pre= tty advanced static analysis.=