diff mbox

69759 - document __builtin_alloca and __builtin_alloca_with_align

Message ID 56BF8976.3080907@gmail.com
State New
Headers show

Commit Message

Martin Sebor Feb. 13, 2016, 7:52 p.m. UTC
The __builtin_alloca intrinsic is mentioned in the GCC manual but
its GCC-specific properties are not documented.  The Linux man
page for the alloca() function briefly mentions __builtin_alloca
in the NOTES section but cautions that the function is "machine-
and compiler-dependent" without providing any details.

   http://man7.org/linux/man-pages/man3/alloca.3.html

The __builtin_alloca_with_align function isn't mentioned in the
GCC manual at all.

Both built-ins are being relied on by user programs and both seem
to be poorly understood and occasionally causing problems.  See
for example:
   https://bugzilla.mozilla.org/show_bug.cgi?id=1111355

__builtin_alloca_with_align() is also tricky to use and subject
to bugs (see PR/69780).

I spent some time experimenting with and debugging the two builtins
to get a better understanding of their constraints and guarantees.
The attached documentation-only patch adds a description of each
to the GCC manual as a starting point.  If there are additional
details that could or should be mentioned (or cautionary statements)
I'd be grateful to hear them and happy to add them.

Martin

PS The __builtin_alloca_with_align optimization to release small
allocations at the end of the block as opposed to the end of the
function is safe and useful for VLAs but seems error-prone for
a general purpose utility.  It might perhaps be worth changing
the builtin so as to avoid the optimization when it's used
directly (as opposed to internally by GCC).

In addition, both functions can be called at other scopes than
block scope (especially in C++).  I didn't uncover any bugs in
this feature but I'm not sure it's safe (especially since there
are no test for the builtin in the test suite).  If someone
feels that the functions should be callable at other scopes
it would be good to know so tests exercising it can be put in
place.  Otherwise, GCC should either reject such calls or at
least issue a warning for them.

Comments

Joseph Myers Feb. 15, 2016, 11:18 p.m. UTC | #1
The description here is self-contradictory; __BIGGEST_ALIGNMENT__ bytes is 
often different from the greatest fundamental alignment (fundamental 
alignments and max_align_t only consider standard C types, 
__BIGGEST_ALIGNMENT__ can allow for e.g. vector type extensions).
diff mbox

Patch

PR c/69759 - __builtin_alloca and __builtin_alloca_with_align undocumented

gcc/ChangeLog:
2016-02-13  Martin Sebor  <msebor@redhat.com>

	PR c/69759
	* doc/extend.texi (Other Builtins): Document __builtin_alloca and
	__builtin_alloca_with_align.

Index: gcc/doc/extend.texi
===================================================================
--- gcc/doc/extend.texi	(revision 233367)
+++ gcc/doc/extend.texi	(working copy)
@@ -10144,6 +10144,8 @@  in the Cilk Plus language manual which c
 @node Other Builtins
 @section Other Built-in Functions Provided by GCC
 @cindex built-in functions
+@findex __builtin_alloca
+@findex __builtin_alloca_with_align
 @findex __builtin_call_with_static_chain
 @findex __builtin_fpclassify
 @findex __builtin_isfinite
@@ -10690,6 +10692,92 @@  In the same fashion, GCC provides @code{
 @code{__builtin_} prefixed.  The @code{isinf} and @code{isnan}
 built-in functions appear both with and without the @code{__builtin_} prefix.
 
+@deftypefn {Built-in Function} void* __builtin_alloca (size_t size)
+The @code{__builtin_alloca} function must be called at block scope.
+The function allocates an object @var{size} bytes large on the stack of
+the calling function.  The object is aligned at the  greatest fundametal
+alignment boundary for the target.  The greatest fundametal alignment is
+the result of the @code{__BIGGEST_ALIGNMENT__ * __CHAR_BIT__} expression.
+In portable C99 and C11 (or later) programs, the value should be obtained
+by evaluating the @code{_Alignof (max_align_t)} and
+@code{alignof (std::max_align_t)} expressions, respectively.  The function
+returns a pointer to the first byte of the allocated object.  The lifetime
+of the allocated object ends just before the calling function returns to
+its caller.   This is so even when @code{__builtin_alloca_with_align} is
+called within a nested block.
+
+For example, the following function allocates eight objects of @code{n}
+bytes each on the stack, storing a pointer to each in consecutive elements
+of the array @code{a}.  It then passes the array to function @code{g()}
+which can safely use the storage pointed to by each of the array elements.
+
+@smallexample
+void f (unsigned n)
+@{
+  void *a [8];
+  for (int i = 0; i != 8; ++i)
+    a [i] = __builtin_alloca (n);
+
+  g (a, n);   // safe
+@}
+@end smallexample
+
+Since the @code{__builtin_alloca} function doesn't validate its arguments
+it is the responsibility of its caller to make sure the argument doesn't
+cause it doesn't exceed the stack size limit.
+The @code{__builtin_alloca} function is provided to make it possible to
+allocate arrays with a runtime bound on the stack.  Since C99 variable
+length arrays offer similar functionality under a portable, more convenient,
+and safer interface they are recommended instead, in both C99 and C++
+programs where GCC provides them as an extension.
+
+@end deftypefn
+
+@deftypefn {Built-in Function} void* __builtin_alloca_with_align (size_t size, size_t align)
+The @code{__builtin_alloca_with_align} function must be called at block
+scope.  The function allocates an object @var{align} bytes large on
+the stack of the calling function.  The allocated object is aligned on
+the boundary specified by the argument @var{align} whose unit is given
+in bits (not bytes).  @var{size} must be positive and not exceed the stack
+size limit.  @var{align} must be a constant integer expression that
+evaluates to a power of 2 greater than or equal to @code{__CHAR_BIT__},
+otherwise the behavior is undefined.  The function returns a pointer to
+the first byte of the allocated object.  The lifetime of the allocated
+object ends at the end of the block in which the function was called.
+The allocated storage is released no later than just before the calling
+function returns to its called, but may be released at the end of
+the block in which the function was called.
+
+For example, in the following function the call to @code{g()} is unsafe
+because when @code{a} is non-zero, the space allocated by
+@code{__builtin_alloca_with_align} may have been released at the end
+of the @code{if} statement in which it was called.
+
+@smallexample
+void f (unsigned n, unsigned a)
+@{
+  void *p;
+  if (a)
+    p = __builtin_alloca_with_align (n, a * __CHAR_BIT__);
+  else
+    p = __builtin_alloc (n);
+
+  g (p, n);   // unsafe
+@}
+@end smallexample
+
+Since the @code{__builtin_alloca_with_align} function doesn't validate its
+arguments it is the responsibility of its caller to make sure the argument
+doesn't cause it doesn't exceed the stack size limit.
+The @code{__builtin_alloca_with_align} function is provided to make
+it possible to allocate overaligned arrays with a runtime bound on
+the stack.  Since C99 variable length arrays offer the same functionality
+under a portable, more convenient, and safer interface they are recommended
+instead, in both C99 and C++ programs where GCC provides them as
+an extension.
+
+@end deftypefn
+
 @deftypefn {Built-in Function} int __builtin_types_compatible_p (@var{type1}, @var{type2})
 
 You can use the built-in function @code{__builtin_types_compatible_p} to