C++ Logo


Advanced search

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

From: David Krauss <david_work_at_[hidden]>
Date: Fri, 08 Jan 2016 23:15:30 +0800
Porting my std::function library <https://github.com/potswa/cxx_function/> to MSVC, some UB reared its head. The function wrapper class uses an aligned_storage blob for its call target under the small-object optimization. When the target is small and trivially-copyable, the copy/move constructors use memcpy on the blob to avoid determining the dynamic type of the target.

MSVC seems to do stricter alias analysis than GCC or Clang. The effect of the memcpy is not subsequently observed unless its both its source and destination operands are of the appropriate type (before they’re implicitly cast to void*).

// Given:
erasure_base & erasure()
    { return reinterpret_cast< erasure_base & >( this->storage ); }

// Inside copy/move constructor:
// (1) well-behaved:
std::memcpy( & erasure(), & o.erasure(), sizeof (storage) );
// (2) crashes after erasure().foo observes stale bytes:
std::memcpy( & erasure(), & storage, sizeof (storage) );

In retrospect, (1) is certainly more kosher, but shouldn’t (2) work as well?

This doesn’t seem to rise to the level of a bug report, but it might be relevant to the new memcpy lifetime-initiation rules. Will they ascribe some static type to the source and destination bytes?

More worryingly, erasure_base is a base class. When the memcpy replaces one derived object with another of the same type, what’s the guarantee that the overwritten value won’t be observed? This problem doesn’t manifest so far, but it seems only a matter of time. No easy solution comes to mind, nor any practical workaround for type-erasure libraries. The tough solution is for alias analysis to somehow work without considering the static types passed to memcpy.

I’m no expert on alias analysis, so I don’t know whether GCC and Clang are more clever, or less aggressive. Is it luck that the same bug hasn’t appeared on other platforms? Any insights about the upcoming rules?

 - thanks,

Received on 2016-01-08 17:16:05