This is the mail archive of the libc-alpha@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PATCH] malloc/obstack: Merge obstack code back from gnulib


On 03/28/2014 03:53 AM, Will Newton wrote:
The only change made was to replace _Noreturn with __attribute__ ((__noreturn__)).

It's better to keep the sources identical when possible. Gnulib uses _Noreturn with the C11 meaning, and libc should move in that direction too. Attached is a revised patch to get the ball rolling on that.

>From b7409f1c1788a00eee9c7878b76769ca78569f80 Mon Sep 17 00:00:00 2001
From: Paul Eggert <eggert@cs.ucla.edu>
Date: Fri, 28 Mar 2014 11:59:41 -0700
Subject: [PATCH 1/2] * misc/sys/cdefs.h (_Noreturn): New macro, for pre-C11
 compilers.

---
 ChangeLog        | 4 ++++
 misc/sys/cdefs.h | 8 ++++++++
 2 files changed, 12 insertions(+)

diff --git a/ChangeLog b/ChangeLog
index ac55c65..01e607b 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+2014-03-28  Paul Eggert  <eggert@cs.ucla.edu>
+
+	* misc/sys/cdefs.h (_Noreturn): New macro, for pre-C11 compilers.
+
 2014-03-27  Paul Pluzhnikov  <ppluzhnikov@google.com>
 
 	* elf/dl-load.c: Finish conversion of __builtin_expect into
diff --git a/misc/sys/cdefs.h b/misc/sys/cdefs.h
index 4d958ea..3a0f0b3 100644
--- a/misc/sys/cdefs.h
+++ b/misc/sys/cdefs.h
@@ -382,6 +382,14 @@
 # define __glibc_likely(cond)	(cond)
 #endif
 
+#if !defined _Noreturn && __STDC_VERSION__ < 201112
+# if __GNUC_PREREQ (2,8)
+#  define _Noreturn __attribute__ ((__noreturn__))
+# else
+#  define _Noreturn
+# endif
+#endif
+
 #include <bits/wordsize.h>
 
 #if defined __LONG_DOUBLE_MATH_OPTIONAL && defined __NO_LONG_DOUBLE_MATH
-- 
1.9.0

>From 261fcf4aa71b3298326077cc1474aabf3081346b Mon Sep 17 00:00:00 2001
From: Paul Eggert <eggert@cs.ucla.edu>
Date: Fri, 28 Mar 2014 12:00:51 -0700
Subject: [PATCH 2/2] * malloc/obstack.c, malloc/obstack.h: Merge from gnulib.

---
 ChangeLog        |  1 +
 malloc/obstack.c | 71 ++++++++++++++++++++++----------------------------------
 malloc/obstack.h | 62 ++++++++++++++++++++++++++++---------------------
 3 files changed, 65 insertions(+), 69 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 01e607b..0a3e16c 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,6 @@
 2014-03-28  Paul Eggert  <eggert@cs.ucla.edu>
 
+	* malloc/obstack.c, malloc/obstack.h: Merge from gnulib.
 	* misc/sys/cdefs.h (_Noreturn): New macro, for pre-C11 compilers.
 
 2014-03-27  Paul Pluzhnikov  <ppluzhnikov@google.com>
diff --git a/malloc/obstack.c b/malloc/obstack.c
index 4064f61..598f6aa 100644
--- a/malloc/obstack.c
+++ b/malloc/obstack.c
@@ -17,14 +17,11 @@
    <http://www.gnu.org/licenses/>.  */
 
 
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif
-
 #ifdef _LIBC
 # include <obstack.h>
 # include <shlib-compat.h>
 #else
+# include <config.h>
 # include "obstack.h"
 #endif
 
@@ -39,7 +36,7 @@
    C Library, but also included in many other GNU distributions.  Compiling
    and linking in this code is a waste when using the GNU C library
    (especially if it is a shared library).  Rather than having every GNU
-   program understand `configure --with-gnu-libc' and omit the object
+   program understand 'configure --with-gnu-libc' and omit the object
    files, it is simpler to just do this in the source for each such file.  */
 
 #include <stdio.h>              /* Random thing to get __GNU_LIBRARY__.  */
@@ -55,12 +52,7 @@
 #ifndef ELIDE_CODE
 
 
-# if HAVE_INTTYPES_H
-#  include <inttypes.h>
-# endif
-# if HAVE_STDINT_H || defined _LIBC
-#  include <stdint.h>
-# endif
+# include <stdint.h>
 
 /* Determine default alignment.  */
 union fooround
@@ -85,23 +77,23 @@ enum
 
 /* When we copy a long block of data, this is the unit to do it with.
    On some machines, copying successive ints does not work;
-   in such a case, redefine COPYING_UNIT to `long' (if that works)
-   or `char' as a last resort.  */
+   in such a case, redefine COPYING_UNIT to 'long' (if that works)
+   or 'char' as a last resort.  */
 # ifndef COPYING_UNIT
 #  define COPYING_UNIT int
 # endif
 
 
-/* The functions allocating more room by calling `obstack_chunk_alloc'
-   jump to the handler pointed to by `obstack_alloc_failed_handler'.
+/* The functions allocating more room by calling 'obstack_chunk_alloc'
+   jump to the handler pointed to by 'obstack_alloc_failed_handler'.
    This can be set to a user defined function which should either
    abort gracefully or use longjump - but shouldn't return.  This
    variable by default points to the internal function
-   `print_and_abort'.  */
-static void print_and_abort (void);
+   'print_and_abort'.  */
+static _Noreturn void print_and_abort (void);
 void (*obstack_alloc_failed_handler) (void) = print_and_abort;
 
-/* Exit value used when `print_and_abort' is used.  */
+/* Exit value used when 'print_and_abort' is used.  */
 # include <stdlib.h>
 # ifdef _LIBC
 int obstack_exit_failure = EXIT_FAILURE;
@@ -151,15 +143,15 @@ compat_symbol (libc, _obstack_compat, _obstack, GLIBC_2_0);
 int
 _obstack_begin (struct obstack *h,
                 int size, int alignment,
-                void *(*chunkfun)(long),
-                void (*freefun)(void *))
+                void *(*chunkfun) (long),
+                void (*freefun) (void *))
 {
   struct _obstack_chunk *chunk; /* points to new chunk */
 
   if (alignment == 0)
     alignment = DEFAULT_ALIGNMENT;
   if (size == 0)
-  /* Default size is what GNU malloc can fit in a 4096-byte block.  */
+    /* Default size is what GNU malloc can fit in a 4096-byte block.  */
     {
       /* 12 is sizeof (mhead) and 4 is EXTRA from GNU malloc.
          Use the values for range checking, because if range checking is off,
@@ -175,15 +167,15 @@ _obstack_begin (struct obstack *h,
       size = 4096 - extra;
     }
 
-  h->chunkfun = (struct _obstack_chunk * (*)(void *, long))chunkfun;
-  h->freefun = (void (*)(void *, struct _obstack_chunk *))freefun;
+  h->chunkfun = (struct _obstack_chunk * (*) (void *, long)) chunkfun;
+  h->freefun = (void (*) (void *, struct _obstack_chunk *)) freefun;
   h->chunk_size = size;
   h->alignment_mask = alignment - 1;
   h->use_extra_arg = 0;
 
   chunk = h->chunk = CALL_CHUNKFUN (h, h->chunk_size);
   if (!chunk)
-    (*obstack_alloc_failed_handler)();
+    (*obstack_alloc_failed_handler) ();
   h->next_free = h->object_base = __PTR_ALIGN ((char *) chunk, chunk->contents,
                                                alignment - 1);
   h->chunk_limit = chunk->limit
@@ -197,8 +189,8 @@ _obstack_begin (struct obstack *h,
 
 int
 _obstack_begin_1 (struct obstack *h, int size, int alignment,
-                  void *(*chunkfun)(void *, long),
-                  void (*freefun)(void *, void *),
+                  void *(*chunkfun) (void *, long),
+                  void (*freefun) (void *, void *),
                   void *arg)
 {
   struct _obstack_chunk *chunk; /* points to new chunk */
@@ -206,7 +198,7 @@ _obstack_begin_1 (struct obstack *h, int size, int alignment,
   if (alignment == 0)
     alignment = DEFAULT_ALIGNMENT;
   if (size == 0)
-  /* Default size is what GNU malloc can fit in a 4096-byte block.  */
+    /* Default size is what GNU malloc can fit in a 4096-byte block.  */
     {
       /* 12 is sizeof (mhead) and 4 is EXTRA from GNU malloc.
          Use the values for range checking, because if range checking is off,
@@ -222,8 +214,8 @@ _obstack_begin_1 (struct obstack *h, int size, int alignment,
       size = 4096 - extra;
     }
 
-  h->chunkfun = (struct _obstack_chunk * (*)(void *, long))chunkfun;
-  h->freefun = (void (*)(void *, struct _obstack_chunk *))freefun;
+  h->chunkfun = (struct _obstack_chunk * (*)(void *,long)) chunkfun;
+  h->freefun = (void (*) (void *, struct _obstack_chunk *)) freefun;
   h->chunk_size = size;
   h->alignment_mask = alignment - 1;
   h->extra_arg = arg;
@@ -231,7 +223,7 @@ _obstack_begin_1 (struct obstack *h, int size, int alignment,
 
   chunk = h->chunk = CALL_CHUNKFUN (h, h->chunk_size);
   if (!chunk)
-    (*obstack_alloc_failed_handler)();
+    (*obstack_alloc_failed_handler) ();
   h->next_free = h->object_base = __PTR_ALIGN ((char *) chunk, chunk->contents,
                                                alignment - 1);
   h->chunk_limit = chunk->limit
@@ -324,7 +316,7 @@ libc_hidden_def (_obstack_newchunk)
 
 /* Suppress -Wmissing-prototypes warning.  We don't want to declare this in
    obstack.h because it is just for debugging.  */
-int _obstack_allocated_p (struct obstack *h, void *obj);
+int _obstack_allocated_p (struct obstack *h, void *obj) __attribute_pure__;
 
 int
 _obstack_allocated_p (struct obstack *h, void *obj)
@@ -350,7 +342,7 @@ _obstack_allocated_p (struct obstack *h, void *obj)
 # undef obstack_free
 
 void
-obstack_free (struct obstack *h, void *obj)
+__obstack_free (struct obstack *h, void *obj)
 {
   struct _obstack_chunk *lp;    /* below addr of any objects in this chunk */
   struct _obstack_chunk *plp;   /* point to previous chunk if any */
@@ -412,15 +404,7 @@ _obstack_memory_used (struct obstack *h)
 #  include <libio/iolibio.h>
 # endif
 
-# ifndef __attribute__
-/* This feature is available in gcc versions 2.5 and later.  */
-#  if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 5)
-#   define __attribute__(Spec) /* empty */
-#  endif
-# endif
-
-static void
-__attribute__ ((noreturn))
+static _Noreturn void
 print_and_abort (void)
 {
   /* Don't change any of these strings.  Yes, it would be possible to add
@@ -429,10 +413,11 @@ print_and_abort (void)
      like this and the translation should be reused instead of creating
      a very similar string which requires a separate translation.  */
 # ifdef _LIBC
-  (void) __fxprintf (NULL, "%s\n", _ ("memory exhausted"));
+  (void) __fxprintf (NULL, "%s\n", _("memory exhausted"));
 # else
-  fprintf (stderr, "%s\n", _ ("memory exhausted"));
+  fprintf (stderr, "%s\n", _("memory exhausted"));
 # endif
   exit (obstack_exit_failure);
 }
+
 #endif  /* !ELIDE_CODE */
diff --git a/malloc/obstack.h b/malloc/obstack.h
index 85472f9..f92492f 100644
--- a/malloc/obstack.h
+++ b/malloc/obstack.h
@@ -32,11 +32,11 @@
    stack is of mature, fixed size and fixed address objects.
 
    These routines grab large chunks of memory, using a function you
-   supply, called `obstack_chunk_alloc'.  On occasion, they free chunks,
-   by calling `obstack_chunk_free'.  You must define them and declare
+   supply, called 'obstack_chunk_alloc'.  On occasion, they free chunks,
+   by calling 'obstack_chunk_free'.  You must define them and declare
    them before using any obstack macros.
 
-   Each independent stack is represented by a `struct obstack'.
+   Each independent stack is represented by a 'struct obstack'.
    Each of the obstack macros expects a pointer to such a structure
    as the first argument.
 
@@ -93,7 +93,7 @@
         Exactly one object is growing in an obstack at any one time.
         You can run one obstack per control block.
         You may have as many control blocks as you dare.
-        Because of the way we do it, you can `unwind' an obstack
+        Because of the way we do it, you can "unwind" an obstack
           back to a previous state. (You may remove objects much
           as you would with a stack.)
  */
@@ -104,10 +104,6 @@
 #ifndef _OBSTACK_H
 #define _OBSTACK_H 1
 
-#ifdef __cplusplus
-extern "C" {
-#endif
-
 /* We need the type of a pointer subtraction.  If __PTRDIFF_TYPE__ is
    defined, as with GNU C, use that; that way we don't pollute the
    namespace with <stddef.h>'s symbols.  Otherwise, include <stddef.h>
@@ -124,9 +120,9 @@ extern "C" {
    aligning P to the next multiple of A + 1.  B and P must be of type
    char *.  A + 1 must be a power of 2.  */
 
-#define __BPTR_ALIGN(B, P, A) ((B) + (((P) -(B) + (A)) & ~(A)))
+#define __BPTR_ALIGN(B, P, A) ((B) + (((P) - (B) + (A)) & ~(A)))
 
-/* Similiar to _BPTR_ALIGN (B, P, A), except optimize the common case
+/* Similar to _BPTR_ALIGN (B, P, A), except optimize the common case
    where pointers can be converted to integers, aligned as integers,
    and converted back again.  If PTR_INT_TYPE is narrower than a
    pointer (e.g., the AS/400), play it safe and compute the alignment
@@ -139,6 +135,14 @@ extern "C" {
 
 #include <string.h>
 
+#ifndef __attribute_pure__
+# define __attribute_pure__ _GL_ATTRIBUTE_PURE
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 struct _obstack_chunk           /* Lives at front of each chunk. */
 {
   char *limit;                  /* 1 past end of this chunk */
@@ -159,7 +163,7 @@ struct obstack          /* control current object in current chunk */
     void *tempptr;
   } temp;                       /* Temporary for some macros.  */
   int alignment_mask;           /* Mask of alignment for each object. */
-  /* These prototypes vary based on `use_extra_arg', and we use
+  /* These prototypes vary based on 'use_extra_arg', and we use
      casts to the prototypeless function type in all assignments,
      but having prototypes here quiets -Wstrict-prototypes.  */
   struct _obstack_chunk *(*chunkfun) (void *, long);
@@ -183,18 +187,23 @@ extern int _obstack_begin (struct obstack *, int, int,
 extern int _obstack_begin_1 (struct obstack *, int, int,
                              void *(*)(void *, long),
                              void (*)(void *, void *), void *);
-extern int _obstack_memory_used (struct obstack *);
+extern int _obstack_memory_used (struct obstack *) __attribute_pure__;
 
-void obstack_free (struct obstack *__obstack, void *__glibc_block);
+/* The default name of the function for freeing a chunk is 'obstack_free',
+   but gnulib users can override this by defining '__obstack_free'.  */
+#ifndef __obstack_free
+# define __obstack_free obstack_free
+#endif
+extern void __obstack_free (struct obstack *, void *);
 
 
-/* Error handler called when `obstack_chunk_alloc' failed to allocate
+/* Error handler called when 'obstack_chunk_alloc' failed to allocate
    more memory.  This can be set to a user defined function which
    should either abort gracefully or use longjump - but shouldn't
    return.  The default action is to print a message and abort.  */
 extern void (*obstack_alloc_failed_handler) (void);
 
-/* Exit value used when `print_and_abort' is used.  */
+/* Exit value used when 'print_and_abort' is used.  */
 extern int obstack_exit_failure;
 
 /* Pointer to beginning of object being allocated or to be allocated next.
@@ -249,17 +258,14 @@ extern int obstack_exit_failure;
 #define obstack_memory_used(h) _obstack_memory_used (h)
 
 #if defined __GNUC__
-/* NextStep 2.0 cc is really gcc 1.93 but it defines __GNUC__ = 2 and
-   does not implement __extension__.  But that compiler doesn't define
-   __GNUC_MINOR__.  */
-# if __GNUC__ < 2 || (__NeXT__ && !__GNUC_MINOR__)
+# if ! (2 < __GNUC__ + (8 <= __GNUC_MINOR__))
 #  define __extension__
 # endif
 
 /* For GNU C, if not -traditional,
    we can define these macros to compute all args only once
    without using a global variable.
-   Also, we can avoid using the `temp' slot, to make faster code.  */
+   Also, we can avoid using the 'temp' slot, to make faster code.  */
 
 # define obstack_object_size(OBSTACK)					      \
   __extension__								      \
@@ -337,14 +343,16 @@ extern int obstack_exit_failure;
 # define obstack_ptr_grow_fast(OBSTACK, aptr)				      \
   __extension__								      \
     ({ struct obstack *__o1 = (OBSTACK);				      \
-       *(const void **) __o1->next_free = (aptr);			      \
+       void *__p1 = __o1->next_free;					      \
+       *(const void **) __p1 = (aptr);					      \
        __o1->next_free += sizeof (const void *);			      \
        (void) 0; })
 
 # define obstack_int_grow_fast(OBSTACK, aint)				      \
   __extension__								      \
     ({ struct obstack *__o1 = (OBSTACK);				      \
-       *(int *) __o1->next_free = (aint);				      \
+       void *__p1 = __o1->next_free;					      \
+       *(int *) __p1 = (aint);						      \
        __o1->next_free += sizeof (int);					      \
        (void) 0; })
 
@@ -398,7 +406,7 @@ extern int obstack_exit_failure;
        void *__obj = (OBJ);						      \
        if (__obj > (void *) __o->chunk && __obj < (void *) __o->chunk_limit)  \
          __o->next_free = __o->object_base = (char *) __obj;		      \
-       else (obstack_free) (__o, __obj); })
+       else (__obstack_free) (__o, __obj); })
 
 #else /* not __GNUC__ */
 
@@ -494,12 +502,14 @@ extern int obstack_exit_failure;
   ((h)->temp.tempint = (char *) (obj) - (char *) (h)->chunk,		      \
    ((((h)->temp.tempint > 0						      \
       && (h)->temp.tempint < (h)->chunk_limit - (char *) (h)->chunk))	      \
-   ? (((h)->next_free = (h)->object_base				      \
-                          = (h)->temp.tempint + (char *) (h)->chunk), 0)      \
-   : ((obstack_free) ((h), (h)->temp.tempint + (char *) (h)->chunk), 0)))
+    ? (void) ((h)->next_free = (h)->object_base				      \
+                          = (h)->temp.tempint + (char *) (h)->chunk)	      \
+    : (__obstack_free) (h, (h)->temp.tempint + (char *) (h)->chunk)))
+
 #endif /* not __GNUC__ */
 
 #ifdef __cplusplus
 }       /* C++ */
 #endif
+
 #endif /* obstack.h */
-- 
1.9.0


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]