C++ Logo

sg12

Advanced search

Re: [ub] memcpy blessing a new object of statically unknown type

From: Gabriel Dos Reis <gdr_at_[hidden]>
Date: Sat, 9 Jan 2016 21:38:19 +0000
I suspect the situation is analogous to reinterpret_cast vs. C-style cast: not so long ago, people would freak out when they see reinterpret_cast directly expressing the same intent an ambiguous C-style cast was previously used for. Of course, people would abuse; but I rather see them use std::launder and police them, than they doing other crazy hacks that are much harder to audit for correctness.

From: ub-bounces_at_[hidden] [mailto:ub-bounces_at_open-std.org] On Behalf Of Patrice Roy
Sent: Friday, January 8, 2016 7:51 PM
To: WG21 UB study group <ub_at_open-std.org>
Subject: Re: [ub] memcpy blessing a new object of statically unknown type

std::launder() is one of the scariest things I've seen, but it's part of the pleasure of working on WG21 :)

2016-01-08 22:35 GMT-05:00 Hubert Tong <hubert.reinterpretcast_at_[hidden]<mailto:hubert.reinterpretcast_at_[hidden]>>:
On Fri, Jan 8, 2016 at 9:41 PM, David Krauss <david_work_at_[hidden]<mailto:david_work_at_[hidden]>> wrote:

On 2016–01–09, at 1:54 AM, Hubert Tong <hubert.reinterpretcast_at_[hidden]<mailto:hubert.reinterpretcast_at_[hidden]>> wrote:

My two cents: even when memcpy becomes capable of initiating the lifetime of (and initializing) an object in an "aligned_storage blob", the kosher way of accessing that object would require std::launder.

Then the question becomes, does std::launder require a static type? I was under the impression that it does. In type erasure, memcpy needs to support polymorphism.
Yes, std::launder requires a static type; however, it does not limit the ability of memcpy to operate without knowing the type of the object being copied. The std::launder call is involved after the completion of memcpy to access the object that the memcpy initialized.


Now, I am not sure if it is a copy/paste error, my misunderstanding of the code, or what, but it seems that (2) crashes because "&erasure()" and "&storage" overlap (and if the memcpy UB was not enough, it probably does not do what you intended).

Oops, copy-paste error. It should say &o.storage. (I just double-checked, the post does differ from the defective test.)

It’s a good thing you mentioned it, because I ran some more tests and now it looks like an inlining issue, not cleverness in alias analysis. Apparently it works whenever both memcpy arguments are function calls; it doesn’t matter what type they cast to.

So, my bugfix didn’t clarify types at all; it merely obfuscated the object identities. The port works, but it’s still as UB as ever.


_______________________________________________
ub mailing list
ub_at_[hidden]<mailto:ub_at_[hidden]>
http://www.open-std.org/mailman/listinfo/ub<https://na01.safelinks.protection.outlook.com/?url=http%3a%2f%2fwww.open-std.org%2fmailman%2flistinfo%2fub&data=01%7c01%7cgdr%40microsoft.com%7cf061719c225842af4c3a08d318a80f50%7c72f988bf86f141af91ab2d7cd011db47%7c1&sdata=XeiYc1%2fXuTGiLnvXg8W41qgi0Jdv4AvAoie7ur0%2bcfc%3d>


_______________________________________________
ub mailing list
ub_at_[hidden]<mailto:ub_at_isocpp.open-std.org>
http://www.open-std.org/mailman/listinfo/ub<https://na01.safelinks.protection.outlook.com/?url=http%3a%2f%2fwww.open-std.org%2fmailman%2flistinfo%2fub&data=01%7c01%7cgdr%40microsoft.com%7cf061719c225842af4c3a08d318a80f50%7c72f988bf86f141af91ab2d7cd011db47%7c1&sdata=XeiYc1%2fXuTGiLnvXg8W41qgi0Jdv4AvAoie7ur0%2bcfc%3d>

Received on 2016-01-10 00:13:23