Re: [PATCH 0/5] obstacks again

2014-10-29 Thread Paul Eggert
Thanks for doing all this.  The gnulib patches are good as far as they go, but 
they need one more change: alignments should also change from int to size_t. 
The first attached gnulib patch does that, plus it fixes a longstanding integer 
overflow bug that can occur with large alignments (plus large sizes).  While 
we're in the neighborhood we should be using C11's alignof rather than 
reinventing that particular wheel; the second attached gnulib patch does that. 
I've installed your five gnulib patches plus the two attached patches into gnulib.


Two things for the glibc patch.  First, the updated gnulib patches need to be 
merged into the glibc patch.  Second, the manual needs to be updated to match 
the revised API induced by all these patches.


And thanks again.
From 421a53ad006c9ad9a1cad0b1e42246c01ffa3154 Mon Sep 17 00:00:00 2001
From: Paul Eggert 
Date: Tue, 28 Oct 2014 23:58:42 -0700
Subject: [PATCH 1/2] obstack: use size_t alignments and check for overflow

* lib/obstack.c, lib/obstack.h (_obstack_begin, _obstack_begin_1):
* lib/obstack.c (_obstack_begin_worker, _obstack_newchunk):
* lib/obstack.h (struct obstack.alignment_mask):
Use _OBSTACK_SIZE_T, not int, for alignments.
* lib/obstack.c (_obstack_newchunk): Fail if the size calculation
overflows, e.g., when adding the alignment.
---
 ChangeLog | 10 ++
 lib/obstack.c | 18 +++---
 lib/obstack.h |  8 +---
 3 files changed, 26 insertions(+), 10 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 7aac7eb..8bf2baa 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,13 @@
+2014-10-28  Paul Eggert  
+
+   obstack: use size_t alignments and check for overflow
+   * lib/obstack.c, lib/obstack.h (_obstack_begin, _obstack_begin_1):
+   * lib/obstack.c (_obstack_begin_worker, _obstack_newchunk):
+   * lib/obstack.h (struct obstack.alignment_mask):
+   Use _OBSTACK_SIZE_T, not int, for alignments.
+   * lib/obstack.c (_obstack_newchunk): Fail if the size calculation
+   overflows, e.g., when adding the alignment.
+
 2014-10-24  Paul Eggert  
 
socketlib, sockets, sys_socket: Use AC_REQUIRE to pacify autoconf.
diff --git a/lib/obstack.c b/lib/obstack.c
index 8e247fb..342f9f8 100644
--- a/lib/obstack.c
+++ b/lib/obstack.c
@@ -106,7 +106,7 @@ typedef void (*freefun_type) (void *, struct _obstack_chunk 
*);
 
 static int
 _obstack_begin_worker (struct obstack *h,
-   _OBSTACK_SIZE_T size, int alignment,
+   _OBSTACK_SIZE_T size, _OBSTACK_SIZE_T alignment,
chunkfun_type chunkfun, freefun_type freefun)
 {
   struct _obstack_chunk *chunk; /* points to new chunk */
@@ -150,7 +150,7 @@ _obstack_begin_worker (struct obstack *h,
 
 int
 _obstack_begin (struct obstack *h,
-_OBSTACK_SIZE_T size, int alignment,
+_OBSTACK_SIZE_T size, _OBSTACK_SIZE_T alignment,
 void *(*chunkfun) (size_t),
 void (*freefun) (void *))
 {
@@ -162,7 +162,7 @@ _obstack_begin (struct obstack *h,
 
 int
 _obstack_begin_1 (struct obstack *h,
-  _OBSTACK_SIZE_T size, int alignment,
+  _OBSTACK_SIZE_T size, _OBSTACK_SIZE_T alignment,
   void *(*chunkfun) (void *, size_t),
   void (*freefun) (void *, void *),
   void *arg)
@@ -184,18 +184,22 @@ void
 _obstack_newchunk (struct obstack *h, _OBSTACK_SIZE_T length)
 {
   struct _obstack_chunk *old_chunk = h->chunk;
-  struct _obstack_chunk *new_chunk;
-  size_t new_size;
+  struct _obstack_chunk *new_chunk = 0;
   size_t obj_size = h->next_free - h->object_base;
   char *object_base;
 
   /* Compute size for new chunk.  */
-  new_size = (obj_size + length) + (obj_size >> 3) + h->alignment_mask + 100;
+  size_t sum1 = obj_size + length;
+  size_t sum2 = sum1 + h->alignment_mask;
+  size_t new_size = sum2 + (obj_size >> 3) + 100;
+  if (new_size < sum2)
+new_size = sum2;
   if (new_size < h->chunk_size)
 new_size = h->chunk_size;
 
   /* Allocate and initialize the new chunk.  */
-  new_chunk = CALL_CHUNKFUN (h, new_size);
+  if (obj_size <= sum1 && sum1 <= sum2)
+new_chunk = CALL_CHUNKFUN (h, new_size);
   if (!new_chunk)
 (*obstack_alloc_failed_handler)();
   h->chunk = new_chunk;
diff --git a/lib/obstack.h b/lib/obstack.h
index 909d0d3..ba4de1d 100644
--- a/lib/obstack.h
+++ b/lib/obstack.h
@@ -166,7 +166,7 @@ struct obstack  /* control current object in 
current chunk */
 _OBSTACK_SIZE_T i;
 void *p;
   } temp;   /* Temporary for some macros.  */
-  int alignment_mask;   /* Mask of alignment for each object. */
+  _OBSTACK_SIZE_T alignment_mask;  /* Mask of alignment for each object. */
   /* 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.  */
@@ -187,9 +187,11 @@ struct obstack 

Re: [PATCH 0/5] obstacks again

2014-10-29 Thread Joseph S. Myers
On Wed, 29 Oct 2014, Paul Eggert wrote:

> While we're in the neighborhood we should be using C11's alignof rather than
> reinventing that particular wheel; the second attached gnulib patch does that.

Note that we can't use  in glibc sources unless we move to 
requiring GCC >= 4.7 (and it's not clear whether we'd get consensus for 
such a requirement if proposed).

-- 
Joseph S. Myers
jos...@codesourcery.com



Re: [PATCH] 64-bit obstack support

2014-10-29 Thread Joseph S. Myers
On Wed, 29 Oct 2014, Alan Modra wrote:

> And >2G on 32-bit.
> 

[BZ #14483]

in the ChangeLog entry.

-- 
Joseph S. Myers
jos...@codesourcery.com



Re: [PATCH 0/5] obstacks again

2014-10-29 Thread Alan Modra
On Wed, Oct 29, 2014 at 12:33:19AM -0700, Paul Eggert wrote:
> Thanks for doing all this.  The gnulib patches are good as far as they go,
> but they need one more change: alignments should also change from int to
> size_t. The first attached gnulib patch does that, plus it fixes a
> longstanding integer overflow bug that can occur with large alignments (plus
> large sizes).  While we're in the neighborhood we should be using C11's
> alignof rather than reinventing that particular wheel; the second attached
> gnulib patch does that. I've installed your five gnulib patches plus the two
> attached patches into gnulib.

One thing though, I didn't put the ChangeLog diffs in the patch as I
usually add them when committing.

> Two things for the glibc patch.  First, the updated gnulib patches need to
> be merged into the glibc patch.  Second, the manual needs to be updated to
> match the revised API induced by all these patches.

Ow!  The manual reflects obstacks as they were 20 years ago.

Hmm, looking over it I see a misfeature that I've removed.

@cindex shrinking objects
You can use @code{obstack_blank} with a negative size argument to make
the current object smaller.  Just don't try to shrink it beyond zero
length---there's no telling what will happen if you do that.

It is no longer possible to shrink an obstack with obstack_blank (but
you can still do that with obstack_blank_fast).

-- 
Alan Modra
Australia Development Lab, IBM



Re: [PATCH 0/5] obstacks again

2014-10-29 Thread Paul Eggert

Joseph S. Myers wrote:

Note that we can't use  in glibc sources unless we move to
requiring GCC >= 4.7


Ah, thanks for mentioning that; the attached patch should fix that.  I pushed 
this into gnulib.
From d91a04a3dfc05b42031e8fd00af2cd29b6fa585d Mon Sep 17 00:00:00 2001
From: Paul Eggert 
Date: Wed, 29 Oct 2014 16:15:41 -0700
Subject: [PATCH] obstack: prefer __alignof__ to alignof

This is for portability to pre-4.7 GCC when compiling glibc.
See Joseph S. Myers in:
http://sourceware.org/ml/libc-alpha/2014-10/msg00703.html
* lib/obstack.c (__alignof__) [!_LIBC && !__GNUC__]:
New macro, defined by including and using .
(MAX): New macro.
(DEFAULT_ALIGNMENT, DEFAULT_ROUNDING): Redefine in terms of these.
Do not use enums as they are not portable to some broken compilers.
* modules/obstack (Depends-on): Depend on alignof, not stdalign.
---
 ChangeLog   | 11 +++
 lib/obstack.c   | 32 ++--
 modules/obstack |  2 +-
 3 files changed, 30 insertions(+), 15 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index ffe7285..cea54fc 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,16 @@
 2014-10-29  Paul Eggert  
 
+   obstack: prefer __alignof__ to alignof
+   This is for portability to pre-4.7 GCC when compiling glibc.
+   See Joseph S. Myers in:
+   http://sourceware.org/ml/libc-alpha/2014-10/msg00703.html
+   * lib/obstack.c (__alignof__) [!_LIBC && !__GNUC__]:
+   New macro, defined by including and using .
+   (MAX): New macro.
+   (DEFAULT_ALIGNMENT, DEFAULT_ROUNDING): Redefine in terms of these.
+   Do not use enums as they are not portable to some broken compilers.
+   * modules/obstack (Depends-on): Depend on alignof, not stdalign.
+
obstack: prefer alignof to calculating alignments by hand
* lib/obstack.c: Include .
(struct fooalign): Remove.
diff --git a/lib/obstack.c b/lib/obstack.c
index 03281ae..ba7dff3 100644
--- a/lib/obstack.c
+++ b/lib/obstack.c
@@ -48,26 +48,30 @@
 #endif
 
 #ifndef _OBSTACK_ELIDE_CODE
-# include 
+# if !defined _LIBC && !defined __GNUC__
+#  include 
+#  define __alignof__(type) alignof_type (type)
+# endif
 # include 
 # include 
 
+# ifndef MAX
+#  define MAX(a,b) ((a) > (b) ? (a) : (b))
+# endif
+
 /* Determine default alignment.  */
-union fooround
-{
-  uintmax_t i;
-  long double d;
-  void *p;
-};
+
 /* If malloc were really smart, it would round addresses to DEFAULT_ALIGNMENT.
But in fact it might be less smart and round addresses to as much as
-   DEFAULT_ROUNDING.  So we prepare for it to do that.  */
-enum
-{
-  DEFAULT_ALIGNMENT = alignof (union fooround),
-  DEFAULT_ROUNDING = sizeof (union fooround)
-};
-
+   DEFAULT_ROUNDING.  So we prepare for it to do that.
+
+   DEFAULT_ALIGNMENT cannot be an enum constant; see gnulib's alignof.h.  */
+#define DEFAULT_ALIGNMENT MAX (__alignof__ (long double),\
+   MAX (__alignof__ (uintmax_t), \
+__alignof__ (void *)))
+#define DEFAULT_ROUNDING MAX (sizeof (long double),  \
+   MAX (sizeof (uintmax_t),
  \
+sizeof (void *)))
 
 /* Define a macro that either calls functions with the traditional malloc/free
calling interface, or calls functions with the mmalloc/mfree interface
diff --git a/modules/obstack b/modules/obstack
index c2c6390..36dc444 100644
--- a/modules/obstack
+++ b/modules/obstack
@@ -6,9 +6,9 @@ lib/obstack.h
 lib/obstack.c
 
 Depends-on:
+alignof
 gettext-h
 exitfail
-stdalign
 stdint
 stdlib
 
-- 
1.9.3



Re: [PATCH] 64-bit obstack support

2014-10-29 Thread Alan Modra
On Wed, Oct 29, 2014 at 06:34:02PM +, Joseph S. Myers wrote:
> On Wed, 29 Oct 2014, Alan Modra wrote:
> 
> > And >2G on 32-bit.
> > 
> 
>   [BZ #14483]
> 
> in the ChangeLog entry.

Thanks, added.  Since the stdalign.h change won't do for glibc, I've
split the glibc patch into two.  The first being

Import new obstack support from gnulib

* malloc/obstack.h: Import from gnulib.
* malloc/obstack.c: Likewise.

The second

64-bit obstack support

And >2G on 32-bit.

[BZ #14483]
* include/gnu-versions.h (_GNU_OBSTACK_INTERFACE_VERSION): Bump.
* include/obstack.h: Include shlib-compat.h and gnu-versions.h.
(_OBSTACK_ELIDE_CODE, _OBSTACK_NO_ERROR_HANDLER, _OBSTACK_COMPAT,
_OBSTACK_ALIAS): Define.
(_obstack_allocated_p, _obstack_newchunk, _obstack_free,
_obstack_begin, _obstack_begin_1, _obstack_memory_used): Define.
(_obstack_newchunk): Only use libc_hidden_proto on the version
we will use inside glibc.
* malloc/obstack.c: Revert gnulib commit e8f86ce9, ie. don't
use stdalign.h and alignof.
* malloc/obstackv1.c: New file.
* malloc/obstackv2.c: New file.
* malloc/Makefile (routines): Remove obstack.  Add obstackv1 and
obstackv2.
(CFLAGS-obstack.c): Don't define.
(CFLAGS-obstackv1.c, CFLAGS-obstackv2.c): Define.
(malloc/Versions): Add GLIBC_2.21 _obstack functions.
* config.h.in (SIZEOF_INT, SIZEOF_SIZE_T): Add.
* configure.in: AC_CHECK_SIZEOF int and size_t.
* configure: Regenerate.
* manual/memory.texi: Update obstack documentation.

Added manual patch follows.  It's missing @safety markup for the
previously undocumented obstack_begin, obstack_specify_allocation, and
obstack_specify_allocation_with_arg macros.  I'm hoping someone else
can do that as I'd just be guessing.  (Are they even appropriate for
macros?)

diff --git a/manual/memory.texi b/manual/memory.texi
index 0729e70..5ab16b7 100644
--- a/manual/memory.texi
+++ b/manual/memory.texi
@@ -1922,8 +1922,7 @@ the padding needed to start each object on a suitable 
boundary.
 use obstacks.
 * Allocation in an Obstack::Allocating objects in an obstack.
 * Freeing Obstack Objects:: Freeing objects in an obstack.
-* Obstack Functions::  The obstack functions are both
-functions and macros.
+* Obstack Functions::  The obstack functions are really macros.
 * Growing Objects:: Making an object bigger by stages.
 * Extra Fast Growing:: Extra-high-efficiency (though more
 complicated) growing objects.
@@ -1948,7 +1947,7 @@ An obstack is represented by a data structure of type 
@code{struct
 obstack}.  This structure has a small fixed size; it records the status
 of the obstack and how to find the space in which objects are allocated.
 It does not contain any of the objects themselves.  You should not try
-to access the contents of the structure directly; use only the functions
+to access the contents of the structure directly; use only the macros
 described in this chapter.
 @end deftp
 
@@ -1958,7 +1957,7 @@ of object.  Dynamic allocation of obstacks allows your 
program to have a
 variable number of different stacks.  (You can even allocate an
 obstack structure in another obstack, but this is rarely useful.)
 
-All the functions that work with obstacks require you to specify which
+All the macros that work with obstacks require you to specify which
 obstack to use.  You do this with a pointer of type @code{struct obstack
 *}.  In the following, we often say ``an obstack'' when strictly
 speaking the object at hand is such a pointer.
@@ -1978,7 +1977,7 @@ These matters are described in the following section.
 @node Preparing for Obstacks
 @subsubsection Preparing for Using Obstacks
 
-Each source file in which you plan to use the obstack functions
+Each source file in which you plan to use obstacks
 must include the header file @file{obstack.h}, like this:
 
 @smallexample
@@ -2011,7 +2010,9 @@ larger blocks of memory.  @xref{Obstack Chunks}, for full 
details.
 
 At run time, before the program can use a @code{struct obstack} object
 as an obstack, it must initialize the obstack by calling
-@code{obstack_init}.
+@code{obstack_init} or one of its variants, @code{obstack_begin},
+@code{obstack_specify_allocation}, or
+@code{obstack_specify_allocation_with_arg}.
 
 @comment obstack.h
 @comment GNU
@@ -2031,10 +2032,10 @@ as an obstack, it must initialize the obstack by calling
 @c  fxprintf dup @asucorrupt @aculock @acucorrupt
 @c  exit @acucorrupt?
 Initialize obstack @var{obstack-ptr} for allocation of objects.  This
-function calls the obstack's @code{obstack_chunk_alloc} function.  If
+macro calls the obstack's @code{obstack_chunk_alloc} function.  If
 allocation of memory fails, the function pointed to by

Re: [PATCH 0/5] obstacks again

2014-10-29 Thread Paul Eggert

Alan Modra wrote:


One thing though, I didn't put the ChangeLog diffs in the patch as I
usually add them when committing.


Oh, I missed that.  I added them now.  For Gnulib it's better to put them into 
the patch.



It is no longer possible to shrink an obstack with obstack_blank (but
you can still do that with obstack_blank_fast).


Ouch, I hadn't noticed that.  That's an incompatible change and I expect it will 
break real-world usage for no particularly good reason, so we really need to fix 
this.  How about making the 2nd argument to obstack_blank and obstack_blank_fast 
be of type ptrdiff_t rather than size_t?




Re: [PATCH 0/5] obstacks again

2014-10-29 Thread Alan Modra
On Wed, Oct 29, 2014 at 08:35:18PM -0700, Paul Eggert wrote:
> Alan Modra wrote:
> >It is no longer possible to shrink an obstack with obstack_blank (but
> >you can still do that with obstack_blank_fast).
> 
> Ouch, I hadn't noticed that.  That's an incompatible change and I expect it
> will break real-world usage for no particularly good reason, so we really
> need to fix this.  How about making the 2nd argument to obstack_blank and
> obstack_blank_fast be of type ptrdiff_t rather than size_t?

We could, but..  I expect there is going to be other downstream code
breakage anyway.  Witness the patches needed to make gcc work with a
more modern obstack.h, where a seemingly innocuous change like casting
the obstack_base value to void* broke code doing pointer arithmetic,
and gcc's use of the internal _obstack_begin function meant that gcc
was exposed to the changed chunkfun type.

Now if the 2nd arg of obstack_blank changes to type ptrdiff_t, then it
becomes an odd case, all the other obstack "functions" taking a size_t.
Also, I'd say obstack_blank is the wrong macro to use for shrinking,
the most natural one being obstack_blank_fast due to it bypassing the
obstack_room check.

So there are my reasons for leaving obstack_blank as is.  However, if
you and others prefer to go with ptrdiff_t I'm happy enough to submit
a patch.

Oh, and while I'm advocating breakage, the doc for obstack_next_free
says it returns a void* but actually returns a char*.  Since it was
deemed a good idea to similarly correct obstack_base, should we do the
same for obstack_next_free?

-- 
Alan Modra
Australia Development Lab, IBM