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

            Bug ID: 68571
           Summary: provide __builtin_cookie_size
           Product: gcc
           Version: 6.0
            Status: UNCONFIRMED
          Severity: enhancement
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: msebor at gcc dot gnu.org
  Target Milestone: ---

The array forms of the C++ new expression are specified to invoke the
corresponding operator new with a size_t argument set to the product of the
number elements, nelems, and the size of the type, sizeof(T), plus some
(possibly zero) overhead, X.  The C++ standard doesn't specify the amount of
overhead that is added, except that it may be different from one invocation of
the new expression to another.  This makes it difficult to write portable
programs that use the array placement new expression to construct an array of
objects into a fixed size buffer: how much bigger than nelems * sizeof(T)
should the buffer be?

On all targets but one, GCC uses the greater of sizeof(size_t) and alignof(T)
as the amount of overhead.  On ARM, however, the EABI specifies the minimum
overhead to be 8 bytes, regardless of the data model (i.e., ILP32 or LP64). 
See Section 3.2.2 of the ARM EABI:
http://infocenter.arm.com/help/topic/com.arm.doc.ihi0041d/IHI0041D_cppabi.pdf.

To make it less error-prone to write programs that are portable to all targets
supported by GCC, the compiler should provide an API to query the size of the
cookie for a given new expression.  The API should take as operands the type of
the new expression (in a form such as a pointer to the type), and the number of
elements to be allocated.

Below is a proposed outline of the the API in a style suitable for the GCC
manual:

-- Built-in Function: size_t __builtin_cookie_size (type *ptr, size_t nelems)

Returns the amount of overhead, in bytes, that an array form of a new
expression adds to the number of bytes it requests the corresponding operator
new to allocate for an array of nelems elements of the specified type.  The
pointer ptr is not evaluated.  The result is a constant expression when nelems
is a constant expression.  The overhead should be queried when determining the
amount of storage to allocate before invoking the array form of a placement new
expression to construct an array of objects in place.  For example:

  const size_t Overhead = __builtin_cookie_size((T*)0, NELEMS);
  unsigned char buf [NELEMS * sizeof(MyType) + Overhead];
  new (buf) MyType [NELEMS]

For additional background on some of the problems that providing such an API
can prevent, see the Noncompliant Code Example (Failure to Account For Array
Overhead) in the CERT C++ Secure Coding Standard rule MEM54-CPP. Provide
placement new with properly aligned pointers to sufficient storage capacity:
https://www.securecoding.cert.org/confluence/x/KQBEAw

Reply via email to