[2/5] malloc: Sync dynarray with gnulib

Message ID 20210113165826.1014708-2-adhemerval.zanella@linaro.org
State Committed
Delegated to: Adhemerval Zanella Netto
Headers
Series [1/5] misc: Sync cdefs.h with gnulib |

Commit Message

Adhemerval Zanella Netto Jan. 13, 2021, 4:58 p.m. UTC
  It syncs with gnulib version a8bac4d49.  The main changes are:

  - Remove the usage of anonymous union within DYNARRAY_STRUCT.
  - Use DYNARRAY_FREE instead of DYNARRAY_NAME (free) so that
    Gnulib does not change 'free' to 'rpl_free'.
  - Use __nonnull instead of __attribute__ ((nonnull ())).
  - Use __attribute_maybe_unused__ instead of
    __attribute__ ((unused, nonnull (1))).
  - Use of _Noreturn instead of _attribute__ ((noreturn)).

The only difference with gnulib is:
  

Comments

Adhemerval Zanella Netto Feb. 9, 2021, 7:12 p.m. UTC | #1
I will commit this shortly if no one opposes it.

On 13/01/2021 13:58, Adhemerval Zanella wrote:
> It syncs with gnulib version a8bac4d49.  The main changes are:
> 
>   - Remove the usage of anonymous union within DYNARRAY_STRUCT.
>   - Use DYNARRAY_FREE instead of DYNARRAY_NAME (free) so that
>     Gnulib does not change 'free' to 'rpl_free'.
>   - Use __nonnull instead of __attribute__ ((nonnull ())).
>   - Use __attribute_maybe_unused__ instead of
>     __attribute__ ((unused, nonnull (1))).
>   - Use of _Noreturn instead of _attribute__ ((noreturn)).
> 
> The only difference with gnulib is:
> 
> --- ../../gnulib/gnulib-lib/lib/malloc/dynarray_at_failure.c
> +++ malloc/dynarray_at_failure.c
> @@ -18,7 +18,6 @@
> 
>  #include <dynarray.h>
>  #include <stdio.h>
> -#include <stdlib.h>
> 
>  void
>  __libc_dynarray_at_failure (size_t size, size_t index)
> @@ -28,6 +27,7 @@
>    __snprintf (buf, sizeof (buf), "Fatal glibc error: "
>                "array index %zu not less than array length %zu\n",
>                index, size);
> + __libc_fatal (buf);
>  #else
>   abort ();
>  #endif
> 
> It seems a wrong sync from gnulib.
> 
> Checked on x86_64-linux-gnu.
> ---
>  malloc/dynarray-skeleton.c        | 128 +++++++++++++++---------------
>  malloc/dynarray.h                 |   3 +-
>  malloc/dynarray_at_failure.c      |   4 +
>  malloc/dynarray_emplace_enlarge.c |   3 +-
>  malloc/dynarray_resize.c          |   3 +-
>  malloc/dynarray_resize_clear.c    |   4 +-
>  malloc/tst-dynarray-fail.c        |   8 +-
>  malloc/tst-dynarray-shared.h      |   4 +-
>  malloc/tst-dynarray.c             |  22 ++---
>  9 files changed, 95 insertions(+), 84 deletions(-)
> 
> diff --git a/malloc/dynarray-skeleton.c b/malloc/dynarray-skeleton.c
> index e552664bc5..5b9f37bdd6 100644
> --- a/malloc/dynarray-skeleton.c
> +++ b/malloc/dynarray-skeleton.c
> @@ -135,7 +135,7 @@ struct DYNARRAY_STRUCT
>        size_t allocated;
>        DYNARRAY_ELEMENT *array;
>      } dynarray_header;
> -  };
> +  } u;
>  
>  #if DYNARRAY_HAVE_SCRATCH
>    /* Initial inline allocation.  */
> @@ -150,6 +150,10 @@ struct DYNARRAY_STRUCT
>  #define DYNARRAY_CONCAT1(prefix, name) DYNARRAY_CONCAT0(prefix, name)
>  #define DYNARRAY_NAME(name) DYNARRAY_CONCAT1(DYNARRAY_PREFIX, name)
>  
> +/* Use DYNARRAY_FREE instead of DYNARRAY_NAME (free),
> +   so that Gnulib does not change 'free' to 'rpl_free'.  */
> +#define DYNARRAY_FREE DYNARRAY_CONCAT1 (DYNARRAY_NAME (f), ree)
> +
>  /* Address of the scratch buffer if any.  */
>  #if DYNARRAY_HAVE_SCRATCH
>  # define DYNARRAY_SCRATCH(list) (list)->scratch
> @@ -177,10 +181,10 @@ static inline void
>  DYNARRAY_NAME (free__array__) (struct DYNARRAY_STRUCT *list)
>  {
>  #if DYNARRAY_HAVE_SCRATCH
> -  if (list->dynarray_header.array != list->scratch)
> -    free (list->dynarray_header.array);
> +  if (list->u.dynarray_header.array != list->scratch)
> +    free (list->u.dynarray_header.array);
>  #else
> -  free (list->dynarray_header.array);
> +  free (list->u.dynarray_header.array);
>  #endif
>  }
>  
> @@ -188,86 +192,86 @@ DYNARRAY_NAME (free__array__) (struct DYNARRAY_STRUCT *list)
>  
>  /* Initialize a dynamic array object.  This must be called before any
>     use of the object.  */
> -__attribute__ ((nonnull (1)))
> +__nonnull ((1))
>  static void
>  DYNARRAY_NAME (init) (struct DYNARRAY_STRUCT *list)
>  {
> -  list->dynarray_header.used = 0;
> -  list->dynarray_header.allocated = DYNARRAY_INITIAL_SIZE;
> -  list->dynarray_header.array = DYNARRAY_SCRATCH (list);
> +  list->u.dynarray_header.used = 0;
> +  list->u.dynarray_header.allocated = DYNARRAY_INITIAL_SIZE;
> +  list->u.dynarray_header.array = DYNARRAY_SCRATCH (list);
>  }
>  
>  /* Deallocate the dynamic array and its elements.  */
> -__attribute__ ((unused, nonnull (1)))
> +__attribute_maybe_unused__ __nonnull ((1))
>  static void
> -DYNARRAY_NAME (free) (struct DYNARRAY_STRUCT *list)
> +DYNARRAY_FREE (struct DYNARRAY_STRUCT *list)
>  {
>    DYNARRAY_NAME (free__elements__)
> -    (list->dynarray_header.array, list->dynarray_header.used);
> +    (list->u.dynarray_header.array, list->u.dynarray_header.used);
>    DYNARRAY_NAME (free__array__) (list);
>    DYNARRAY_NAME (init) (list);
>  }
>  
>  /* Return true if the dynamic array is in an error state.  */
> -__attribute__ ((nonnull (1)))
> +__nonnull ((1))
>  static inline bool
>  DYNARRAY_NAME (has_failed) (const struct DYNARRAY_STRUCT *list)
>  {
> -  return list->dynarray_header.allocated == __dynarray_error_marker ();
> +  return list->u.dynarray_header.allocated == __dynarray_error_marker ();
>  }
>  
>  /* Mark the dynamic array as failed.  All elements are deallocated as
>     a side effect.  */
> -__attribute__ ((nonnull (1)))
> +__nonnull ((1))
>  static void
>  DYNARRAY_NAME (mark_failed) (struct DYNARRAY_STRUCT *list)
>  {
>    DYNARRAY_NAME (free__elements__)
> -    (list->dynarray_header.array, list->dynarray_header.used);
> +    (list->u.dynarray_header.array, list->u.dynarray_header.used);
>    DYNARRAY_NAME (free__array__) (list);
> -  list->dynarray_header.array = DYNARRAY_SCRATCH (list);
> -  list->dynarray_header.used = 0;
> -  list->dynarray_header.allocated = __dynarray_error_marker ();
> +  list->u.dynarray_header.array = DYNARRAY_SCRATCH (list);
> +  list->u.dynarray_header.used = 0;
> +  list->u.dynarray_header.allocated = __dynarray_error_marker ();
>  }
>  
>  /* Return the number of elements which have been added to the dynamic
>     array.  */
> -__attribute__ ((nonnull (1)))
> +__nonnull ((1))
>  static inline size_t
>  DYNARRAY_NAME (size) (const struct DYNARRAY_STRUCT *list)
>  {
> -  return list->dynarray_header.used;
> +  return list->u.dynarray_header.used;
>  }
>  
>  /* Return a pointer to the array element at INDEX.  Terminate the
>     process if INDEX is out of bounds.  */
> -__attribute__ ((nonnull (1)))
> +__nonnull ((1))
>  static inline DYNARRAY_ELEMENT *
>  DYNARRAY_NAME (at) (struct DYNARRAY_STRUCT *list, size_t index)
>  {
>    if (__glibc_unlikely (index >= DYNARRAY_NAME (size) (list)))
>      __libc_dynarray_at_failure (DYNARRAY_NAME (size) (list), index);
> -  return list->dynarray_header.array + index;
> +  return list->u.dynarray_header.array + index;
>  }
>  
>  /* Return a pointer to the first array element, if any.  For a
>     zero-length array, the pointer can be NULL even though the dynamic
>     array has not entered the failure state.  */
> -__attribute__ ((nonnull (1)))
> +__nonnull ((1))
>  static inline DYNARRAY_ELEMENT *
>  DYNARRAY_NAME (begin) (struct DYNARRAY_STRUCT *list)
>  {
> -  return list->dynarray_header.array;
> +  return list->u.dynarray_header.array;
>  }
>  
>  /* Return a pointer one element past the last array element.  For a
>     zero-length array, the pointer can be NULL even though the dynamic
>     array has not entered the failure state.  */
> -__attribute__ ((nonnull (1)))
> +__nonnull ((1))
>  static inline DYNARRAY_ELEMENT *
>  DYNARRAY_NAME (end) (struct DYNARRAY_STRUCT *list)
>  {
> -  return list->dynarray_header.array + list->dynarray_header.used;
> +  return list->u.dynarray_header.array + list->u.dynarray_header.used;
>  }
>  
>  /* Internal function.  Slow path for the add function below.  */
> @@ -275,7 +279,7 @@ static void
>  DYNARRAY_NAME (add__) (struct DYNARRAY_STRUCT *list, DYNARRAY_ELEMENT item)
>  {
>    if (__glibc_unlikely
> -      (!__libc_dynarray_emplace_enlarge (&list->dynarray_abstract,
> +      (!__libc_dynarray_emplace_enlarge (&list->u.dynarray_abstract,
>                                           DYNARRAY_SCRATCH (list),
>                                           sizeof (DYNARRAY_ELEMENT))))
>      {
> @@ -284,13 +288,13 @@ DYNARRAY_NAME (add__) (struct DYNARRAY_STRUCT *list, DYNARRAY_ELEMENT item)
>      }
>  
>    /* Copy the new element and increase the array length.  */
> -  list->dynarray_header.array[list->dynarray_header.used++] = item;
> +  list->u.dynarray_header.array[list->u.dynarray_header.used++] = item;
>  }
>  
>  /* Add ITEM at the end of the array, enlarging it by one element.
>     Mark *LIST as failed if the dynamic array allocation size cannot be
>     increased.  */
> -__attribute__ ((unused, nonnull (1)))
> +__nonnull ((1))
>  static inline void
>  DYNARRAY_NAME (add) (struct DYNARRAY_STRUCT *list, DYNARRAY_ELEMENT item)
>  {
> @@ -299,15 +303,15 @@ DYNARRAY_NAME (add) (struct DYNARRAY_STRUCT *list, DYNARRAY_ELEMENT item)
>      return;
>  
>    /* Enlarge the array if necessary.  */
> -  if (__glibc_unlikely (list->dynarray_header.used
> -                        == list->dynarray_header.allocated))
> +  if (__glibc_unlikely (list->u.dynarray_header.used
> +                        == list->u.dynarray_header.allocated))
>      {
>        DYNARRAY_NAME (add__) (list, item);
>        return;
>      }
>  
>    /* Copy the new element and increase the array length.  */
> -  list->dynarray_header.array[list->dynarray_header.used++] = item;
> +  list->u.dynarray_header.array[list->u.dynarray_header.used++] = item;
>  }
>  
>  /* Internal function.  Building block for the emplace functions below.
> @@ -316,8 +320,8 @@ static inline DYNARRAY_ELEMENT *
>  DYNARRAY_NAME (emplace__tail__) (struct DYNARRAY_STRUCT *list)
>  {
>    DYNARRAY_ELEMENT *result
> -    = &list->dynarray_header.array[list->dynarray_header.used];
> -  ++list->dynarray_header.used;
> +    = &list->u.dynarray_header.array[list->u.dynarray_header.used];
> +  ++list->u.dynarray_header.used;
>  #if defined (DYNARRAY_ELEMENT_INIT)
>    DYNARRAY_ELEMENT_INIT (result);
>  #elif defined (DYNARRAY_ELEMENT_FREE)
> @@ -331,7 +335,7 @@ static DYNARRAY_ELEMENT *
>  DYNARRAY_NAME (emplace__) (struct DYNARRAY_STRUCT *list)
>  {
>    if (__glibc_unlikely
> -      (!__libc_dynarray_emplace_enlarge (&list->dynarray_abstract,
> +      (!__libc_dynarray_emplace_enlarge (&list->u.dynarray_abstract,
>                                           DYNARRAY_SCRATCH (list),
>                                           sizeof (DYNARRAY_ELEMENT))))
>      {
> @@ -344,7 +348,7 @@ DYNARRAY_NAME (emplace__) (struct DYNARRAY_STRUCT *list)
>  /* Allocate a place for a new element in *LIST and return a pointer to
>     it.  The pointer can be NULL if the dynamic array cannot be
>     enlarged due to a memory allocation failure.  */
> -__attribute__ ((unused, warn_unused_result, nonnull (1)))
> +__attribute_maybe_unused__ __attribute_warn_unused_result__ __nonnull ((1))
>  static
>  /* Avoid inlining with the larger initialization code.  */
>  #if !(defined (DYNARRAY_ELEMENT_INIT) || defined (DYNARRAY_ELEMENT_FREE))
> @@ -358,8 +362,8 @@ DYNARRAY_NAME (emplace) (struct DYNARRAY_STRUCT *list)
>      return NULL;
>  
>    /* Enlarge the array if necessary.  */
> -  if (__glibc_unlikely (list->dynarray_header.used
> -                        == list->dynarray_header.allocated))
> +  if (__glibc_unlikely (list->u.dynarray_header.used
> +                        == list->u.dynarray_header.allocated))
>      return (DYNARRAY_NAME (emplace__) (list));
>    return DYNARRAY_NAME (emplace__tail__) (list);
>  }
> @@ -368,32 +372,32 @@ DYNARRAY_NAME (emplace) (struct DYNARRAY_STRUCT *list)
>     existing size, new elements are added (which can be initialized).
>     Otherwise, the list is truncated, and elements are freed.  Return
>     false on memory allocation failure (and mark *LIST as failed).  */
> -__attribute__ ((unused, nonnull (1)))
> +__attribute_maybe_unused__ __nonnull ((1))
>  static bool
>  DYNARRAY_NAME (resize) (struct DYNARRAY_STRUCT *list, size_t size)
>  {
> -  if (size > list->dynarray_header.used)
> +  if (size > list->u.dynarray_header.used)
>      {
>        bool ok;
>  #if defined (DYNARRAY_ELEMENT_INIT)
>        /* The new elements have to be initialized.  */
> -      size_t old_size = list->dynarray_header.used;
> -      ok = __libc_dynarray_resize (&list->dynarray_abstract,
> +      size_t old_size = list->u.dynarray_header.used;
> +      ok = __libc_dynarray_resize (&list->u.dynarray_abstract,
>                                     size, DYNARRAY_SCRATCH (list),
>                                     sizeof (DYNARRAY_ELEMENT));
>        if (ok)
>          for (size_t i = old_size; i < size; ++i)
>            {
> -            DYNARRAY_ELEMENT_INIT (&list->dynarray_header.array[i]);
> +            DYNARRAY_ELEMENT_INIT (&list->u.dynarray_header.array[i]);
>            }
>  #elif defined (DYNARRAY_ELEMENT_FREE)
>        /* Zero initialization is needed so that the elements can be
>           safely freed.  */
>        ok = __libc_dynarray_resize_clear
> -        (&list->dynarray_abstract, size,
> +        (&list->u.dynarray_abstract, size,
>           DYNARRAY_SCRATCH (list), sizeof (DYNARRAY_ELEMENT));
>  #else
> -      ok =  __libc_dynarray_resize (&list->dynarray_abstract,
> +      ok =  __libc_dynarray_resize (&list->u.dynarray_abstract,
>                                      size, DYNARRAY_SCRATCH (list),
>                                      sizeof (DYNARRAY_ELEMENT));
>  #endif
> @@ -405,40 +409,40 @@ DYNARRAY_NAME (resize) (struct DYNARRAY_STRUCT *list, size_t size)
>      {
>        /* The list has shrunk in size.  Free the removed elements.  */
>        DYNARRAY_NAME (free__elements__)
> -        (list->dynarray_header.array + size,
> -         list->dynarray_header.used - size);
> -      list->dynarray_header.used = size;
> +        (list->u.dynarray_header.array + size,
> +         list->u.dynarray_header.used - size);
> +      list->u.dynarray_header.used = size;
>        return true;
>      }
>  }
>  
>  /* Remove the last element of LIST if it is present.  */
> -__attribute__ ((unused, nonnull (1)))
> +__attribute_maybe_unused__ __nonnull ((1))
>  static void
>  DYNARRAY_NAME (remove_last) (struct DYNARRAY_STRUCT *list)
>  {
>    /* used > 0 implies that the array is the non-failed state.  */
> -  if (list->dynarray_header.used > 0)
> +  if (list->u.dynarray_header.used > 0)
>      {
> -      size_t new_length = list->dynarray_header.used - 1;
> +      size_t new_length = list->u.dynarray_header.used - 1;
>  #ifdef DYNARRAY_ELEMENT_FREE
> -      DYNARRAY_ELEMENT_FREE (&list->dynarray_header.array[new_length]);
> +      DYNARRAY_ELEMENT_FREE (&list->u.dynarray_header.array[new_length]);
>  #endif
> -      list->dynarray_header.used = new_length;
> +      list->u.dynarray_header.used = new_length;
>      }
>  }
>  
>  /* Remove all elements from the list.  The elements are freed, but the
>     list itself is not.  */
> -__attribute__ ((unused, nonnull (1)))
> +__attribute_maybe_unused__ __nonnull ((1))
>  static void
>  DYNARRAY_NAME (clear) (struct DYNARRAY_STRUCT *list)
>  {
>    /* free__elements__ does nothing if the list is in the failed
>       state.  */
>    DYNARRAY_NAME (free__elements__)
> -    (list->dynarray_header.array, list->dynarray_header.used);
> -  list->dynarray_header.used = 0;
> +    (list->u.dynarray_header.array, list->u.dynarray_header.used);
> +  list->u.dynarray_header.used = 0;
>  }
>  
>  #ifdef DYNARRAY_FINAL_TYPE
> @@ -448,13 +452,13 @@ DYNARRAY_NAME (clear) (struct DYNARRAY_STRUCT *list)
>     stored in *RESULT if LIST refers to an empty list.  On success, the
>     pointer in *RESULT is heap-allocated and must be deallocated using
>     free.  */
> -__attribute__ ((unused, warn_unused_result, nonnull (1, 2)))
> +__attribute_maybe_unused__ __attribute_warn_unused_result__ __nonnull ((1, 2))
>  static bool
>  DYNARRAY_NAME (finalize) (struct DYNARRAY_STRUCT *list,
>                            DYNARRAY_FINAL_TYPE *result)
>  {
>    struct dynarray_finalize_result res;
> -  if (__libc_dynarray_finalize (&list->dynarray_abstract,
> +  if (__libc_dynarray_finalize (&list->u.dynarray_abstract,
>                                  DYNARRAY_SCRATCH (list),
>                                  sizeof (DYNARRAY_ELEMENT), &res))
>      {
> @@ -466,7 +470,7 @@ DYNARRAY_NAME (finalize) (struct DYNARRAY_STRUCT *list,
>    else
>      {
>        /* On error, we need to free all data.  */
> -      DYNARRAY_NAME (free) (list);
> +      DYNARRAY_FREE (list);
>        errno = ENOMEM;
>        return false;
>      }
> @@ -479,12 +483,12 @@ DYNARRAY_NAME (finalize) (struct DYNARRAY_STRUCT *list,
>     have a sentinel at the end).  If LENGTHP is not NULL, the array
>     length is written to *LENGTHP.  *LIST is re-initialized and can be
>     reused.  */
> -__attribute__ ((unused, warn_unused_result, nonnull (1)))
> +__attribute_maybe_unused__ __attribute_warn_unused_result__ __nonnull ((1))
>  static DYNARRAY_ELEMENT *
>  DYNARRAY_NAME (finalize) (struct DYNARRAY_STRUCT *list, size_t *lengthp)
>  {
>    struct dynarray_finalize_result res;
> -  if (__libc_dynarray_finalize (&list->dynarray_abstract,
> +  if (__libc_dynarray_finalize (&list->u.dynarray_abstract,
>                                  DYNARRAY_SCRATCH (list),
>                                  sizeof (DYNARRAY_ELEMENT), &res))
>      {
> @@ -497,7 +501,7 @@ DYNARRAY_NAME (finalize) (struct DYNARRAY_STRUCT *list, size_t *lengthp)
>    else
>      {
>        /* On error, we need to free all data.  */
> -      DYNARRAY_NAME (free) (list);
> +      DYNARRAY_FREE (list);
>        errno = ENOMEM;
>        return NULL;
>      }
> diff --git a/malloc/dynarray.h b/malloc/dynarray.h
> index 24ca1620d2..638c33f986 100644
> --- a/malloc/dynarray.h
> +++ b/malloc/dynarray.h
> @@ -165,8 +165,7 @@ bool __libc_dynarray_finalize (struct dynarray_header *list, void *scratch,
>  /* Internal function.  Terminate the process after an index error.
>     SIZE is the number of elements of the dynamic array.  INDEX is the
>     lookup index which triggered the failure.  */
> -void __libc_dynarray_at_failure (size_t size, size_t index)
> -  __attribute__ ((noreturn));
> +_Noreturn void __libc_dynarray_at_failure (size_t size, size_t index);
>  
>  #ifndef _ISOMAC
>  libc_hidden_proto (__libc_dynarray_emplace_enlarge)
> diff --git a/malloc/dynarray_at_failure.c b/malloc/dynarray_at_failure.c
> index d27c0aebbc..88d9ee7f50 100644
> --- a/malloc/dynarray_at_failure.c
> +++ b/malloc/dynarray_at_failure.c
> @@ -22,10 +22,14 @@
>  void
>  __libc_dynarray_at_failure (size_t size, size_t index)
>  {
> +#ifdef _LIBC
>    char buf[200];
>    __snprintf (buf, sizeof (buf), "Fatal glibc error: "
>                "array index %zu not less than array length %zu\n",
>                index, size);
>   __libc_fatal (buf);
> +#else
> + abort ();
> +#endif
>  }
>  libc_hidden_def (__libc_dynarray_at_failure)
> diff --git a/malloc/dynarray_emplace_enlarge.c b/malloc/dynarray_emplace_enlarge.c
> index f98b0328df..ddfe306fcd 100644
> --- a/malloc/dynarray_emplace_enlarge.c
> +++ b/malloc/dynarray_emplace_enlarge.c
> @@ -18,6 +18,7 @@
>  
>  #include <dynarray.h>
>  #include <errno.h>
> +#include <intprops.h>
>  #include <stdlib.h>
>  #include <string.h>
>  
> @@ -51,7 +52,7 @@ __libc_dynarray_emplace_enlarge (struct dynarray_header *list,
>      }
>  
>    size_t new_size;
> -  if (__builtin_mul_overflow (new_allocated, element_size, &new_size))
> +  if (INT_MULTIPLY_WRAPV (new_allocated, element_size, &new_size))
>      return false;
>    void *new_array;
>    if (list->array == scratch)
> diff --git a/malloc/dynarray_resize.c b/malloc/dynarray_resize.c
> index bb50e32f9a..5c60927f37 100644
> --- a/malloc/dynarray_resize.c
> +++ b/malloc/dynarray_resize.c
> @@ -18,6 +18,7 @@
>  
>  #include <dynarray.h>
>  #include <errno.h>
> +#include <intprops.h>
>  #include <stdlib.h>
>  #include <string.h>
>  
> @@ -37,7 +38,7 @@ __libc_dynarray_resize (struct dynarray_header *list, size_t size,
>       over-allocation here.  */
>  
>    size_t new_size_bytes;
> -  if (__builtin_mul_overflow (size, element_size, &new_size_bytes))
> +  if (INT_MULTIPLY_WRAPV (size, element_size, &new_size_bytes))
>      {
>        /* Overflow.  */
>        __set_errno (ENOMEM);
> diff --git a/malloc/dynarray_resize_clear.c b/malloc/dynarray_resize_clear.c
> index 51d64fea5c..e893d1d58e 100644
> --- a/malloc/dynarray_resize_clear.c
> +++ b/malloc/dynarray_resize_clear.c
> @@ -17,7 +17,6 @@
>     <https://www.gnu.org/licenses/>.  */
>  
>  #include <dynarray.h>
> -#include <stdlib.h>
>  #include <string.h>
>  
>  bool
> @@ -28,7 +27,8 @@ __libc_dynarray_resize_clear (struct dynarray_header *list, size_t size,
>    if (!__libc_dynarray_resize (list, size, scratch, element_size))
>      return false;
>    /* __libc_dynarray_resize already checked for overflow.  */
> -  memset (list->array + (old_size * element_size), 0,
> +  char *array = list->array;
> +  memset (array + (old_size * element_size), 0,
>            (size - old_size) * element_size);
>    return true;
>  }
> diff --git a/malloc/tst-dynarray-fail.c b/malloc/tst-dynarray-fail.c
> index 1db3a00b34..9252586e79 100644
> --- a/malloc/tst-dynarray-fail.c
> +++ b/malloc/tst-dynarray-fail.c
> @@ -249,9 +249,9 @@ test_str_fail (void)
>          else
>            dynarray_str_free (&dyn);
>          TEST_VERIFY_EXIT (!dynarray_str_has_failed (&dyn));
> -        TEST_VERIFY_EXIT (dyn.dynarray_header.array == dyn.scratch);
> +        TEST_VERIFY_EXIT (dyn.u.dynarray_header.array == dyn.scratch);
>          TEST_VERIFY_EXIT (dynarray_str_size (&dyn) == 0);
> -        TEST_VERIFY_EXIT (dyn.dynarray_header.allocated > 0);
> +        TEST_VERIFY_EXIT (dyn.u.dynarray_header.allocated > 0);
>        }
>  
>    /* Exercise failure in finalize.  */
> @@ -278,9 +278,9 @@ test_str_fail (void)
>        TEST_VERIFY_EXIT (result.array == (char **) (uintptr_t) -1);
>        TEST_VERIFY_EXIT (result.length == (size_t) -1);
>        TEST_VERIFY_EXIT (!dynarray_str_has_failed (&dyn));
> -      TEST_VERIFY_EXIT (dyn.dynarray_header.array == dyn.scratch);
> +      TEST_VERIFY_EXIT (dyn.u.dynarray_header.array == dyn.scratch);
>        TEST_VERIFY_EXIT (dynarray_str_size (&dyn) == 0);
> -      TEST_VERIFY_EXIT (dyn.dynarray_header.allocated > 0);
> +      TEST_VERIFY_EXIT (dyn.u.dynarray_header.allocated > 0);
>        free_fill_heap (heap_filler);
>      }
>  
> diff --git a/malloc/tst-dynarray-shared.h b/malloc/tst-dynarray-shared.h
> index fbbbef2eab..c3d63c87c6 100644
> --- a/malloc/tst-dynarray-shared.h
> +++ b/malloc/tst-dynarray-shared.h
> @@ -48,9 +48,9 @@ struct str_array
>    ({                                                            \
>      TEST_VERIFY_EXIT (!dynarray_##type##_has_failed (dyn));     \
>      TEST_VERIFY_EXIT (dynarray_##type##_size (dyn) == 0);       \
> -    TEST_VERIFY_EXIT ((dyn)->dynarray_header.array              \
> +    TEST_VERIFY_EXIT ((dyn)->u.dynarray_header.array            \
>                        == (dyn)->scratch);                       \
> -    TEST_VERIFY_EXIT ((dyn)->dynarray_header.allocated > 0);    \
> +    TEST_VERIFY_EXIT ((dyn)->u.dynarray_header.allocated > 0);  \
>      (void) 0;                                                   \
>    })
>  
> diff --git a/malloc/tst-dynarray.c b/malloc/tst-dynarray.c
> index 6c6437b12a..c33505711f 100644
> --- a/malloc/tst-dynarray.c
> +++ b/malloc/tst-dynarray.c
> @@ -110,10 +110,10 @@ test_int (void)
>                    TEST_VERIFY_EXIT (!dynarray_int_has_failed (&dyn));
>                    TEST_VERIFY_EXIT (dynarray_int_size (&dyn) == i + 1);
>                    TEST_VERIFY_EXIT (dynarray_int_size (&dyn)
> -                                    <= dyn.dynarray_header.allocated);
> +                                    <= dyn.u.dynarray_header.allocated);
>                  }
>                TEST_VERIFY_EXIT (dynarray_int_size (&dyn) == count);
> -              TEST_VERIFY_EXIT (count <= dyn.dynarray_header.allocated);
> +              TEST_VERIFY_EXIT (count <= dyn.u.dynarray_header.allocated);
>                if (count > 0)
>                  {
>                    TEST_VERIFY (dynarray_int_begin (&dyn)
> @@ -122,7 +122,7 @@ test_int (void)
>                                 == dynarray_int_at (&dyn, count - 1) + 1);
>                  }
>                unsigned final_count;
> -              bool heap_array = dyn.dynarray_header.array != dyn.scratch;
> +              bool heap_array = dyn.u.dynarray_header.array != dyn.scratch;
>                if (do_remove_last)
>                  {
>                    dynarray_int_remove_last (&dyn);
> @@ -146,10 +146,11 @@ test_int (void)
>                    final_count = 0;
>                  }
>                TEST_VERIFY_EXIT (!dynarray_int_has_failed (&dyn));
> -              TEST_VERIFY_EXIT ((dyn.dynarray_header.array != dyn.scratch)
> +              TEST_VERIFY_EXIT ((dyn.u.dynarray_header.array != dyn.scratch)
>                                  == heap_array);
>                TEST_VERIFY_EXIT (dynarray_int_size (&dyn) == final_count);
> -              TEST_VERIFY_EXIT (dyn.dynarray_header.allocated >= final_count);
> +              TEST_VERIFY_EXIT (dyn.u.dynarray_header.allocated
> +				>= final_count);
>                if (!do_clear)
>                  for (unsigned int i = 0; i < final_count; ++i)
>                    TEST_VERIFY_EXIT (*dynarray_int_at (&dyn, i) == base + i);
> @@ -238,10 +239,10 @@ test_str (void)
>                    TEST_VERIFY_EXIT (!dynarray_str_has_failed (&dyn));
>                    TEST_VERIFY_EXIT (dynarray_str_size (&dyn) == i + 1);
>                    TEST_VERIFY_EXIT (dynarray_str_size (&dyn)
> -                                    <= dyn.dynarray_header.allocated);
> +                                    <= dyn.u.dynarray_header.allocated);
>                  }
>                TEST_VERIFY_EXIT (dynarray_str_size (&dyn) == count);
> -              TEST_VERIFY_EXIT (count <= dyn.dynarray_header.allocated);
> +              TEST_VERIFY_EXIT (count <= dyn.u.dynarray_header.allocated);
>                if (count > 0)
>                  {
>                    TEST_VERIFY (dynarray_str_begin (&dyn)
> @@ -250,7 +251,7 @@ test_str (void)
>                                 == dynarray_str_at (&dyn, count - 1) + 1);
>                  }
>                unsigned final_count;
> -              bool heap_array = dyn.dynarray_header.array != dyn.scratch;
> +              bool heap_array = dyn.u.dynarray_header.array != dyn.scratch;
>                if (do_remove_last)
>                  {
>                    dynarray_str_remove_last (&dyn);
> @@ -274,10 +275,11 @@ test_str (void)
>                    final_count = 0;
>                  }
>                TEST_VERIFY_EXIT (!dynarray_str_has_failed (&dyn));
> -              TEST_VERIFY_EXIT ((dyn.dynarray_header.array != dyn.scratch)
> +              TEST_VERIFY_EXIT ((dyn.u.dynarray_header.array != dyn.scratch)
>                                  == heap_array);
>                TEST_VERIFY_EXIT (dynarray_str_size (&dyn) == final_count);
> -              TEST_VERIFY_EXIT (dyn.dynarray_header.allocated >= final_count);
> +              TEST_VERIFY_EXIT (dyn.u.dynarray_header.allocated
> +				>= final_count);
>                if (!do_clear)
>                  for (unsigned int i = 0; i < count - do_remove_last; ++i)
>                    {
>
  

Patch

--- ../../gnulib/gnulib-lib/lib/malloc/dynarray_at_failure.c
+++ malloc/dynarray_at_failure.c
@@ -18,7 +18,6 @@ 

 #include <dynarray.h>
 #include <stdio.h>
-#include <stdlib.h>

 void
 __libc_dynarray_at_failure (size_t size, size_t index)
@@ -28,6 +27,7 @@ 
   __snprintf (buf, sizeof (buf), "Fatal glibc error: "
               "array index %zu not less than array length %zu\n",
               index, size);
+ __libc_fatal (buf);
 #else
  abort ();
 #endif

It seems a wrong sync from gnulib.

Checked on x86_64-linux-gnu.
---
 malloc/dynarray-skeleton.c        | 128 +++++++++++++++---------------
 malloc/dynarray.h                 |   3 +-
 malloc/dynarray_at_failure.c      |   4 +
 malloc/dynarray_emplace_enlarge.c |   3 +-
 malloc/dynarray_resize.c          |   3 +-
 malloc/dynarray_resize_clear.c    |   4 +-
 malloc/tst-dynarray-fail.c        |   8 +-
 malloc/tst-dynarray-shared.h      |   4 +-
 malloc/tst-dynarray.c             |  22 ++---
 9 files changed, 95 insertions(+), 84 deletions(-)

diff --git a/malloc/dynarray-skeleton.c b/malloc/dynarray-skeleton.c
index e552664bc5..5b9f37bdd6 100644
--- a/malloc/dynarray-skeleton.c
+++ b/malloc/dynarray-skeleton.c
@@ -135,7 +135,7 @@  struct DYNARRAY_STRUCT
       size_t allocated;
       DYNARRAY_ELEMENT *array;
     } dynarray_header;
-  };
+  } u;
 
 #if DYNARRAY_HAVE_SCRATCH
   /* Initial inline allocation.  */
@@ -150,6 +150,10 @@  struct DYNARRAY_STRUCT
 #define DYNARRAY_CONCAT1(prefix, name) DYNARRAY_CONCAT0(prefix, name)
 #define DYNARRAY_NAME(name) DYNARRAY_CONCAT1(DYNARRAY_PREFIX, name)
 
+/* Use DYNARRAY_FREE instead of DYNARRAY_NAME (free),
+   so that Gnulib does not change 'free' to 'rpl_free'.  */
+#define DYNARRAY_FREE DYNARRAY_CONCAT1 (DYNARRAY_NAME (f), ree)
+
 /* Address of the scratch buffer if any.  */
 #if DYNARRAY_HAVE_SCRATCH
 # define DYNARRAY_SCRATCH(list) (list)->scratch
@@ -177,10 +181,10 @@  static inline void
 DYNARRAY_NAME (free__array__) (struct DYNARRAY_STRUCT *list)
 {
 #if DYNARRAY_HAVE_SCRATCH
-  if (list->dynarray_header.array != list->scratch)
-    free (list->dynarray_header.array);
+  if (list->u.dynarray_header.array != list->scratch)
+    free (list->u.dynarray_header.array);
 #else
-  free (list->dynarray_header.array);
+  free (list->u.dynarray_header.array);
 #endif
 }
 
@@ -188,86 +192,86 @@  DYNARRAY_NAME (free__array__) (struct DYNARRAY_STRUCT *list)
 
 /* Initialize a dynamic array object.  This must be called before any
    use of the object.  */
-__attribute__ ((nonnull (1)))
+__nonnull ((1))
 static void
 DYNARRAY_NAME (init) (struct DYNARRAY_STRUCT *list)
 {
-  list->dynarray_header.used = 0;
-  list->dynarray_header.allocated = DYNARRAY_INITIAL_SIZE;
-  list->dynarray_header.array = DYNARRAY_SCRATCH (list);
+  list->u.dynarray_header.used = 0;
+  list->u.dynarray_header.allocated = DYNARRAY_INITIAL_SIZE;
+  list->u.dynarray_header.array = DYNARRAY_SCRATCH (list);
 }
 
 /* Deallocate the dynamic array and its elements.  */
-__attribute__ ((unused, nonnull (1)))
+__attribute_maybe_unused__ __nonnull ((1))
 static void
-DYNARRAY_NAME (free) (struct DYNARRAY_STRUCT *list)
+DYNARRAY_FREE (struct DYNARRAY_STRUCT *list)
 {
   DYNARRAY_NAME (free__elements__)
-    (list->dynarray_header.array, list->dynarray_header.used);
+    (list->u.dynarray_header.array, list->u.dynarray_header.used);
   DYNARRAY_NAME (free__array__) (list);
   DYNARRAY_NAME (init) (list);
 }
 
 /* Return true if the dynamic array is in an error state.  */
-__attribute__ ((nonnull (1)))
+__nonnull ((1))
 static inline bool
 DYNARRAY_NAME (has_failed) (const struct DYNARRAY_STRUCT *list)
 {
-  return list->dynarray_header.allocated == __dynarray_error_marker ();
+  return list->u.dynarray_header.allocated == __dynarray_error_marker ();
 }
 
 /* Mark the dynamic array as failed.  All elements are deallocated as
    a side effect.  */
-__attribute__ ((nonnull (1)))
+__nonnull ((1))
 static void
 DYNARRAY_NAME (mark_failed) (struct DYNARRAY_STRUCT *list)
 {
   DYNARRAY_NAME (free__elements__)
-    (list->dynarray_header.array, list->dynarray_header.used);
+    (list->u.dynarray_header.array, list->u.dynarray_header.used);
   DYNARRAY_NAME (free__array__) (list);
-  list->dynarray_header.array = DYNARRAY_SCRATCH (list);
-  list->dynarray_header.used = 0;
-  list->dynarray_header.allocated = __dynarray_error_marker ();
+  list->u.dynarray_header.array = DYNARRAY_SCRATCH (list);
+  list->u.dynarray_header.used = 0;
+  list->u.dynarray_header.allocated = __dynarray_error_marker ();
 }
 
 /* Return the number of elements which have been added to the dynamic
    array.  */
-__attribute__ ((nonnull (1)))
+__nonnull ((1))
 static inline size_t
 DYNARRAY_NAME (size) (const struct DYNARRAY_STRUCT *list)
 {
-  return list->dynarray_header.used;
+  return list->u.dynarray_header.used;
 }
 
 /* Return a pointer to the array element at INDEX.  Terminate the
    process if INDEX is out of bounds.  */
-__attribute__ ((nonnull (1)))
+__nonnull ((1))
 static inline DYNARRAY_ELEMENT *
 DYNARRAY_NAME (at) (struct DYNARRAY_STRUCT *list, size_t index)
 {
   if (__glibc_unlikely (index >= DYNARRAY_NAME (size) (list)))
     __libc_dynarray_at_failure (DYNARRAY_NAME (size) (list), index);
-  return list->dynarray_header.array + index;
+  return list->u.dynarray_header.array + index;
 }
 
 /* Return a pointer to the first array element, if any.  For a
    zero-length array, the pointer can be NULL even though the dynamic
    array has not entered the failure state.  */
-__attribute__ ((nonnull (1)))
+__nonnull ((1))
 static inline DYNARRAY_ELEMENT *
 DYNARRAY_NAME (begin) (struct DYNARRAY_STRUCT *list)
 {
-  return list->dynarray_header.array;
+  return list->u.dynarray_header.array;
 }
 
 /* Return a pointer one element past the last array element.  For a
    zero-length array, the pointer can be NULL even though the dynamic
    array has not entered the failure state.  */
-__attribute__ ((nonnull (1)))
+__nonnull ((1))
 static inline DYNARRAY_ELEMENT *
 DYNARRAY_NAME (end) (struct DYNARRAY_STRUCT *list)
 {
-  return list->dynarray_header.array + list->dynarray_header.used;
+  return list->u.dynarray_header.array + list->u.dynarray_header.used;
 }
 
 /* Internal function.  Slow path for the add function below.  */
@@ -275,7 +279,7 @@  static void
 DYNARRAY_NAME (add__) (struct DYNARRAY_STRUCT *list, DYNARRAY_ELEMENT item)
 {
   if (__glibc_unlikely
-      (!__libc_dynarray_emplace_enlarge (&list->dynarray_abstract,
+      (!__libc_dynarray_emplace_enlarge (&list->u.dynarray_abstract,
                                          DYNARRAY_SCRATCH (list),
                                          sizeof (DYNARRAY_ELEMENT))))
     {
@@ -284,13 +288,13 @@  DYNARRAY_NAME (add__) (struct DYNARRAY_STRUCT *list, DYNARRAY_ELEMENT item)
     }
 
   /* Copy the new element and increase the array length.  */
-  list->dynarray_header.array[list->dynarray_header.used++] = item;
+  list->u.dynarray_header.array[list->u.dynarray_header.used++] = item;
 }
 
 /* Add ITEM at the end of the array, enlarging it by one element.
    Mark *LIST as failed if the dynamic array allocation size cannot be
    increased.  */
-__attribute__ ((unused, nonnull (1)))
+__nonnull ((1))
 static inline void
 DYNARRAY_NAME (add) (struct DYNARRAY_STRUCT *list, DYNARRAY_ELEMENT item)
 {
@@ -299,15 +303,15 @@  DYNARRAY_NAME (add) (struct DYNARRAY_STRUCT *list, DYNARRAY_ELEMENT item)
     return;
 
   /* Enlarge the array if necessary.  */
-  if (__glibc_unlikely (list->dynarray_header.used
-                        == list->dynarray_header.allocated))
+  if (__glibc_unlikely (list->u.dynarray_header.used
+                        == list->u.dynarray_header.allocated))
     {
       DYNARRAY_NAME (add__) (list, item);
       return;
     }
 
   /* Copy the new element and increase the array length.  */
-  list->dynarray_header.array[list->dynarray_header.used++] = item;
+  list->u.dynarray_header.array[list->u.dynarray_header.used++] = item;
 }
 
 /* Internal function.  Building block for the emplace functions below.
@@ -316,8 +320,8 @@  static inline DYNARRAY_ELEMENT *
 DYNARRAY_NAME (emplace__tail__) (struct DYNARRAY_STRUCT *list)
 {
   DYNARRAY_ELEMENT *result
-    = &list->dynarray_header.array[list->dynarray_header.used];
-  ++list->dynarray_header.used;
+    = &list->u.dynarray_header.array[list->u.dynarray_header.used];
+  ++list->u.dynarray_header.used;
 #if defined (DYNARRAY_ELEMENT_INIT)
   DYNARRAY_ELEMENT_INIT (result);
 #elif defined (DYNARRAY_ELEMENT_FREE)
@@ -331,7 +335,7 @@  static DYNARRAY_ELEMENT *
 DYNARRAY_NAME (emplace__) (struct DYNARRAY_STRUCT *list)
 {
   if (__glibc_unlikely
-      (!__libc_dynarray_emplace_enlarge (&list->dynarray_abstract,
+      (!__libc_dynarray_emplace_enlarge (&list->u.dynarray_abstract,
                                          DYNARRAY_SCRATCH (list),
                                          sizeof (DYNARRAY_ELEMENT))))
     {
@@ -344,7 +348,7 @@  DYNARRAY_NAME (emplace__) (struct DYNARRAY_STRUCT *list)
 /* Allocate a place for a new element in *LIST and return a pointer to
    it.  The pointer can be NULL if the dynamic array cannot be
    enlarged due to a memory allocation failure.  */
-__attribute__ ((unused, warn_unused_result, nonnull (1)))
+__attribute_maybe_unused__ __attribute_warn_unused_result__ __nonnull ((1))
 static
 /* Avoid inlining with the larger initialization code.  */
 #if !(defined (DYNARRAY_ELEMENT_INIT) || defined (DYNARRAY_ELEMENT_FREE))
@@ -358,8 +362,8 @@  DYNARRAY_NAME (emplace) (struct DYNARRAY_STRUCT *list)
     return NULL;
 
   /* Enlarge the array if necessary.  */
-  if (__glibc_unlikely (list->dynarray_header.used
-                        == list->dynarray_header.allocated))
+  if (__glibc_unlikely (list->u.dynarray_header.used
+                        == list->u.dynarray_header.allocated))
     return (DYNARRAY_NAME (emplace__) (list));
   return DYNARRAY_NAME (emplace__tail__) (list);
 }
@@ -368,32 +372,32 @@  DYNARRAY_NAME (emplace) (struct DYNARRAY_STRUCT *list)
    existing size, new elements are added (which can be initialized).
    Otherwise, the list is truncated, and elements are freed.  Return
    false on memory allocation failure (and mark *LIST as failed).  */
-__attribute__ ((unused, nonnull (1)))
+__attribute_maybe_unused__ __nonnull ((1))
 static bool
 DYNARRAY_NAME (resize) (struct DYNARRAY_STRUCT *list, size_t size)
 {
-  if (size > list->dynarray_header.used)
+  if (size > list->u.dynarray_header.used)
     {
       bool ok;
 #if defined (DYNARRAY_ELEMENT_INIT)
       /* The new elements have to be initialized.  */
-      size_t old_size = list->dynarray_header.used;
-      ok = __libc_dynarray_resize (&list->dynarray_abstract,
+      size_t old_size = list->u.dynarray_header.used;
+      ok = __libc_dynarray_resize (&list->u.dynarray_abstract,
                                    size, DYNARRAY_SCRATCH (list),
                                    sizeof (DYNARRAY_ELEMENT));
       if (ok)
         for (size_t i = old_size; i < size; ++i)
           {
-            DYNARRAY_ELEMENT_INIT (&list->dynarray_header.array[i]);
+            DYNARRAY_ELEMENT_INIT (&list->u.dynarray_header.array[i]);
           }
 #elif defined (DYNARRAY_ELEMENT_FREE)
       /* Zero initialization is needed so that the elements can be
          safely freed.  */
       ok = __libc_dynarray_resize_clear
-        (&list->dynarray_abstract, size,
+        (&list->u.dynarray_abstract, size,
          DYNARRAY_SCRATCH (list), sizeof (DYNARRAY_ELEMENT));
 #else
-      ok =  __libc_dynarray_resize (&list->dynarray_abstract,
+      ok =  __libc_dynarray_resize (&list->u.dynarray_abstract,
                                     size, DYNARRAY_SCRATCH (list),
                                     sizeof (DYNARRAY_ELEMENT));
 #endif
@@ -405,40 +409,40 @@  DYNARRAY_NAME (resize) (struct DYNARRAY_STRUCT *list, size_t size)
     {
       /* The list has shrunk in size.  Free the removed elements.  */
       DYNARRAY_NAME (free__elements__)
-        (list->dynarray_header.array + size,
-         list->dynarray_header.used - size);
-      list->dynarray_header.used = size;
+        (list->u.dynarray_header.array + size,
+         list->u.dynarray_header.used - size);
+      list->u.dynarray_header.used = size;
       return true;
     }
 }
 
 /* Remove the last element of LIST if it is present.  */
-__attribute__ ((unused, nonnull (1)))
+__attribute_maybe_unused__ __nonnull ((1))
 static void
 DYNARRAY_NAME (remove_last) (struct DYNARRAY_STRUCT *list)
 {
   /* used > 0 implies that the array is the non-failed state.  */
-  if (list->dynarray_header.used > 0)
+  if (list->u.dynarray_header.used > 0)
     {
-      size_t new_length = list->dynarray_header.used - 1;
+      size_t new_length = list->u.dynarray_header.used - 1;
 #ifdef DYNARRAY_ELEMENT_FREE
-      DYNARRAY_ELEMENT_FREE (&list->dynarray_header.array[new_length]);
+      DYNARRAY_ELEMENT_FREE (&list->u.dynarray_header.array[new_length]);
 #endif
-      list->dynarray_header.used = new_length;
+      list->u.dynarray_header.used = new_length;
     }
 }
 
 /* Remove all elements from the list.  The elements are freed, but the
    list itself is not.  */
-__attribute__ ((unused, nonnull (1)))
+__attribute_maybe_unused__ __nonnull ((1))
 static void
 DYNARRAY_NAME (clear) (struct DYNARRAY_STRUCT *list)
 {
   /* free__elements__ does nothing if the list is in the failed
      state.  */
   DYNARRAY_NAME (free__elements__)
-    (list->dynarray_header.array, list->dynarray_header.used);
-  list->dynarray_header.used = 0;
+    (list->u.dynarray_header.array, list->u.dynarray_header.used);
+  list->u.dynarray_header.used = 0;
 }
 
 #ifdef DYNARRAY_FINAL_TYPE
@@ -448,13 +452,13 @@  DYNARRAY_NAME (clear) (struct DYNARRAY_STRUCT *list)
    stored in *RESULT if LIST refers to an empty list.  On success, the
    pointer in *RESULT is heap-allocated and must be deallocated using
    free.  */
-__attribute__ ((unused, warn_unused_result, nonnull (1, 2)))
+__attribute_maybe_unused__ __attribute_warn_unused_result__ __nonnull ((1, 2))
 static bool
 DYNARRAY_NAME (finalize) (struct DYNARRAY_STRUCT *list,
                           DYNARRAY_FINAL_TYPE *result)
 {
   struct dynarray_finalize_result res;
-  if (__libc_dynarray_finalize (&list->dynarray_abstract,
+  if (__libc_dynarray_finalize (&list->u.dynarray_abstract,
                                 DYNARRAY_SCRATCH (list),
                                 sizeof (DYNARRAY_ELEMENT), &res))
     {
@@ -466,7 +470,7 @@  DYNARRAY_NAME (finalize) (struct DYNARRAY_STRUCT *list,
   else
     {
       /* On error, we need to free all data.  */
-      DYNARRAY_NAME (free) (list);
+      DYNARRAY_FREE (list);
       errno = ENOMEM;
       return false;
     }
@@ -479,12 +483,12 @@  DYNARRAY_NAME (finalize) (struct DYNARRAY_STRUCT *list,
    have a sentinel at the end).  If LENGTHP is not NULL, the array
    length is written to *LENGTHP.  *LIST is re-initialized and can be
    reused.  */
-__attribute__ ((unused, warn_unused_result, nonnull (1)))
+__attribute_maybe_unused__ __attribute_warn_unused_result__ __nonnull ((1))
 static DYNARRAY_ELEMENT *
 DYNARRAY_NAME (finalize) (struct DYNARRAY_STRUCT *list, size_t *lengthp)
 {
   struct dynarray_finalize_result res;
-  if (__libc_dynarray_finalize (&list->dynarray_abstract,
+  if (__libc_dynarray_finalize (&list->u.dynarray_abstract,
                                 DYNARRAY_SCRATCH (list),
                                 sizeof (DYNARRAY_ELEMENT), &res))
     {
@@ -497,7 +501,7 @@  DYNARRAY_NAME (finalize) (struct DYNARRAY_STRUCT *list, size_t *lengthp)
   else
     {
       /* On error, we need to free all data.  */
-      DYNARRAY_NAME (free) (list);
+      DYNARRAY_FREE (list);
       errno = ENOMEM;
       return NULL;
     }
diff --git a/malloc/dynarray.h b/malloc/dynarray.h
index 24ca1620d2..638c33f986 100644
--- a/malloc/dynarray.h
+++ b/malloc/dynarray.h
@@ -165,8 +165,7 @@  bool __libc_dynarray_finalize (struct dynarray_header *list, void *scratch,
 /* Internal function.  Terminate the process after an index error.
    SIZE is the number of elements of the dynamic array.  INDEX is the
    lookup index which triggered the failure.  */
-void __libc_dynarray_at_failure (size_t size, size_t index)
-  __attribute__ ((noreturn));
+_Noreturn void __libc_dynarray_at_failure (size_t size, size_t index);
 
 #ifndef _ISOMAC
 libc_hidden_proto (__libc_dynarray_emplace_enlarge)
diff --git a/malloc/dynarray_at_failure.c b/malloc/dynarray_at_failure.c
index d27c0aebbc..88d9ee7f50 100644
--- a/malloc/dynarray_at_failure.c
+++ b/malloc/dynarray_at_failure.c
@@ -22,10 +22,14 @@ 
 void
 __libc_dynarray_at_failure (size_t size, size_t index)
 {
+#ifdef _LIBC
   char buf[200];
   __snprintf (buf, sizeof (buf), "Fatal glibc error: "
               "array index %zu not less than array length %zu\n",
               index, size);
  __libc_fatal (buf);
+#else
+ abort ();
+#endif
 }
 libc_hidden_def (__libc_dynarray_at_failure)
diff --git a/malloc/dynarray_emplace_enlarge.c b/malloc/dynarray_emplace_enlarge.c
index f98b0328df..ddfe306fcd 100644
--- a/malloc/dynarray_emplace_enlarge.c
+++ b/malloc/dynarray_emplace_enlarge.c
@@ -18,6 +18,7 @@ 
 
 #include <dynarray.h>
 #include <errno.h>
+#include <intprops.h>
 #include <stdlib.h>
 #include <string.h>
 
@@ -51,7 +52,7 @@  __libc_dynarray_emplace_enlarge (struct dynarray_header *list,
     }
 
   size_t new_size;
-  if (__builtin_mul_overflow (new_allocated, element_size, &new_size))
+  if (INT_MULTIPLY_WRAPV (new_allocated, element_size, &new_size))
     return false;
   void *new_array;
   if (list->array == scratch)
diff --git a/malloc/dynarray_resize.c b/malloc/dynarray_resize.c
index bb50e32f9a..5c60927f37 100644
--- a/malloc/dynarray_resize.c
+++ b/malloc/dynarray_resize.c
@@ -18,6 +18,7 @@ 
 
 #include <dynarray.h>
 #include <errno.h>
+#include <intprops.h>
 #include <stdlib.h>
 #include <string.h>
 
@@ -37,7 +38,7 @@  __libc_dynarray_resize (struct dynarray_header *list, size_t size,
      over-allocation here.  */
 
   size_t new_size_bytes;
-  if (__builtin_mul_overflow (size, element_size, &new_size_bytes))
+  if (INT_MULTIPLY_WRAPV (size, element_size, &new_size_bytes))
     {
       /* Overflow.  */
       __set_errno (ENOMEM);
diff --git a/malloc/dynarray_resize_clear.c b/malloc/dynarray_resize_clear.c
index 51d64fea5c..e893d1d58e 100644
--- a/malloc/dynarray_resize_clear.c
+++ b/malloc/dynarray_resize_clear.c
@@ -17,7 +17,6 @@ 
    <https://www.gnu.org/licenses/>.  */
 
 #include <dynarray.h>
-#include <stdlib.h>
 #include <string.h>
 
 bool
@@ -28,7 +27,8 @@  __libc_dynarray_resize_clear (struct dynarray_header *list, size_t size,
   if (!__libc_dynarray_resize (list, size, scratch, element_size))
     return false;
   /* __libc_dynarray_resize already checked for overflow.  */
-  memset (list->array + (old_size * element_size), 0,
+  char *array = list->array;
+  memset (array + (old_size * element_size), 0,
           (size - old_size) * element_size);
   return true;
 }
diff --git a/malloc/tst-dynarray-fail.c b/malloc/tst-dynarray-fail.c
index 1db3a00b34..9252586e79 100644
--- a/malloc/tst-dynarray-fail.c
+++ b/malloc/tst-dynarray-fail.c
@@ -249,9 +249,9 @@  test_str_fail (void)
         else
           dynarray_str_free (&dyn);
         TEST_VERIFY_EXIT (!dynarray_str_has_failed (&dyn));
-        TEST_VERIFY_EXIT (dyn.dynarray_header.array == dyn.scratch);
+        TEST_VERIFY_EXIT (dyn.u.dynarray_header.array == dyn.scratch);
         TEST_VERIFY_EXIT (dynarray_str_size (&dyn) == 0);
-        TEST_VERIFY_EXIT (dyn.dynarray_header.allocated > 0);
+        TEST_VERIFY_EXIT (dyn.u.dynarray_header.allocated > 0);
       }
 
   /* Exercise failure in finalize.  */
@@ -278,9 +278,9 @@  test_str_fail (void)
       TEST_VERIFY_EXIT (result.array == (char **) (uintptr_t) -1);
       TEST_VERIFY_EXIT (result.length == (size_t) -1);
       TEST_VERIFY_EXIT (!dynarray_str_has_failed (&dyn));
-      TEST_VERIFY_EXIT (dyn.dynarray_header.array == dyn.scratch);
+      TEST_VERIFY_EXIT (dyn.u.dynarray_header.array == dyn.scratch);
       TEST_VERIFY_EXIT (dynarray_str_size (&dyn) == 0);
-      TEST_VERIFY_EXIT (dyn.dynarray_header.allocated > 0);
+      TEST_VERIFY_EXIT (dyn.u.dynarray_header.allocated > 0);
       free_fill_heap (heap_filler);
     }
 
diff --git a/malloc/tst-dynarray-shared.h b/malloc/tst-dynarray-shared.h
index fbbbef2eab..c3d63c87c6 100644
--- a/malloc/tst-dynarray-shared.h
+++ b/malloc/tst-dynarray-shared.h
@@ -48,9 +48,9 @@  struct str_array
   ({                                                            \
     TEST_VERIFY_EXIT (!dynarray_##type##_has_failed (dyn));     \
     TEST_VERIFY_EXIT (dynarray_##type##_size (dyn) == 0);       \
-    TEST_VERIFY_EXIT ((dyn)->dynarray_header.array              \
+    TEST_VERIFY_EXIT ((dyn)->u.dynarray_header.array            \
                       == (dyn)->scratch);                       \
-    TEST_VERIFY_EXIT ((dyn)->dynarray_header.allocated > 0);    \
+    TEST_VERIFY_EXIT ((dyn)->u.dynarray_header.allocated > 0);  \
     (void) 0;                                                   \
   })
 
diff --git a/malloc/tst-dynarray.c b/malloc/tst-dynarray.c
index 6c6437b12a..c33505711f 100644
--- a/malloc/tst-dynarray.c
+++ b/malloc/tst-dynarray.c
@@ -110,10 +110,10 @@  test_int (void)
                   TEST_VERIFY_EXIT (!dynarray_int_has_failed (&dyn));
                   TEST_VERIFY_EXIT (dynarray_int_size (&dyn) == i + 1);
                   TEST_VERIFY_EXIT (dynarray_int_size (&dyn)
-                                    <= dyn.dynarray_header.allocated);
+                                    <= dyn.u.dynarray_header.allocated);
                 }
               TEST_VERIFY_EXIT (dynarray_int_size (&dyn) == count);
-              TEST_VERIFY_EXIT (count <= dyn.dynarray_header.allocated);
+              TEST_VERIFY_EXIT (count <= dyn.u.dynarray_header.allocated);
               if (count > 0)
                 {
                   TEST_VERIFY (dynarray_int_begin (&dyn)
@@ -122,7 +122,7 @@  test_int (void)
                                == dynarray_int_at (&dyn, count - 1) + 1);
                 }
               unsigned final_count;
-              bool heap_array = dyn.dynarray_header.array != dyn.scratch;
+              bool heap_array = dyn.u.dynarray_header.array != dyn.scratch;
               if (do_remove_last)
                 {
                   dynarray_int_remove_last (&dyn);
@@ -146,10 +146,11 @@  test_int (void)
                   final_count = 0;
                 }
               TEST_VERIFY_EXIT (!dynarray_int_has_failed (&dyn));
-              TEST_VERIFY_EXIT ((dyn.dynarray_header.array != dyn.scratch)
+              TEST_VERIFY_EXIT ((dyn.u.dynarray_header.array != dyn.scratch)
                                 == heap_array);
               TEST_VERIFY_EXIT (dynarray_int_size (&dyn) == final_count);
-              TEST_VERIFY_EXIT (dyn.dynarray_header.allocated >= final_count);
+              TEST_VERIFY_EXIT (dyn.u.dynarray_header.allocated
+				>= final_count);
               if (!do_clear)
                 for (unsigned int i = 0; i < final_count; ++i)
                   TEST_VERIFY_EXIT (*dynarray_int_at (&dyn, i) == base + i);
@@ -238,10 +239,10 @@  test_str (void)
                   TEST_VERIFY_EXIT (!dynarray_str_has_failed (&dyn));
                   TEST_VERIFY_EXIT (dynarray_str_size (&dyn) == i + 1);
                   TEST_VERIFY_EXIT (dynarray_str_size (&dyn)
-                                    <= dyn.dynarray_header.allocated);
+                                    <= dyn.u.dynarray_header.allocated);
                 }
               TEST_VERIFY_EXIT (dynarray_str_size (&dyn) == count);
-              TEST_VERIFY_EXIT (count <= dyn.dynarray_header.allocated);
+              TEST_VERIFY_EXIT (count <= dyn.u.dynarray_header.allocated);
               if (count > 0)
                 {
                   TEST_VERIFY (dynarray_str_begin (&dyn)
@@ -250,7 +251,7 @@  test_str (void)
                                == dynarray_str_at (&dyn, count - 1) + 1);
                 }
               unsigned final_count;
-              bool heap_array = dyn.dynarray_header.array != dyn.scratch;
+              bool heap_array = dyn.u.dynarray_header.array != dyn.scratch;
               if (do_remove_last)
                 {
                   dynarray_str_remove_last (&dyn);
@@ -274,10 +275,11 @@  test_str (void)
                   final_count = 0;
                 }
               TEST_VERIFY_EXIT (!dynarray_str_has_failed (&dyn));
-              TEST_VERIFY_EXIT ((dyn.dynarray_header.array != dyn.scratch)
+              TEST_VERIFY_EXIT ((dyn.u.dynarray_header.array != dyn.scratch)
                                 == heap_array);
               TEST_VERIFY_EXIT (dynarray_str_size (&dyn) == final_count);
-              TEST_VERIFY_EXIT (dyn.dynarray_header.allocated >= final_count);
+              TEST_VERIFY_EXIT (dyn.u.dynarray_header.allocated
+				>= final_count);
               if (!do_clear)
                 for (unsigned int i = 0; i < count - do_remove_last; ++i)
                   {