Currently, we warn if the given place is not enough to hold an extra
data for the array allocation overhead (cookie). I.e. if the size of the
place is equal to the size of the target. Also, we warn even if the size
of the place is greater than the size of the target. The current logic
does not know the size of the overhead(cookie), thus we just simply
warn. We warn even if the place is big enough to hold the overhead
and this is clearly wrong as it leads to false reports. This patch
eliminates the false reports and handles C++20 with special care.
Fixes #56264
C++17 and earlier standards state that:
new(2, f) T[5] results in a call of operator new[](sizeof(T) * 5 + y, 2, f). Here, ... and y are non-negative unspecified values representing array allocation overhead; the result of the new-expression will be offset by this amount from the value returned by operator new[]. This overhead may be applied in all array new-expressions, including those referencing the library function operator new[](std::size_t, void*) and other placement allocation functions. The amount of overhead may vary from one invocation of new to another.
Since the array overhead is an *unspecified* value, it makes sense to
warn only if the size of the Place is equal to the size of the Target.
Otherwise, e.g if we assumed that the overhead is sizeof(size_t),
then we might report a false positive.
Checking for array cookie does not makes sense if the standard is
C++20 or later. C++20 states that array overhead(cookie) is not
created if the new expression calls the non-allocating (placement)
form of the allocation function.
C++20, section 7.6.2.7 [expr.new], paragraph 15:
That argument shall be no less than the size of the object being created; it may be greater than the size of the object being created only if the object is an array and the allocation function is not a non-allocating form (17.6.2.3).
C++20, section 7.6.2.7 [expr.new], paragraph 19:
This overhead may be applied in all array new-expressions, including those referencing a placement allocation function, except when referencing the library function operator new[](std::size_t, void*).
Related Defect Report:
- Array allocation overhead for non-allocating placement new
https://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2382
"might" is not very convincing, it may cause a reaction like "I've no idea what it's talking about and the compiler itself isn't sure, must be false positive". Can we do anything to point the user in the right direction? Say, if this is implementation-defined, are we looking at a portability issue?