From: Bruno Haible Date: Wed, 27 Mar 2024 20:34:40 +0000 (+0100) Subject: obstack: Work around ICE with Oracle cc 12.6 (regr. 2023-12-01). X-Git-Url: https://gitweb.git.savannah.gnu.org/gitweb/?a=commitdiff_plain;h=e0d489e624d7c34537cdd948cb53b2125f006801;p=gnulib.git obstack: Work around ICE with Oracle cc 12.6 (regr. 2023-12-01). * lib/obstack.in.h (__PTR_ALIGN): Use SMALL_PTRDIFF_T, instead of testing sizeof (ptrdiff_t) < sizeof (void *) at compile time. * m4/obstack.m4 (gl_FUNC_OBSTACK): Set SMALL_PTRDIFF_T. * modules/obstack (Makefile.am): Substitute SMALL_PTRDIFF_T. --- diff --git a/ChangeLog b/ChangeLog index 1b7f0599a3..1a8e39226e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2024-03-27 Bruno Haible + + obstack: Work around ICE with Oracle cc 12.6 (regr. 2023-12-01). + * lib/obstack.in.h (__PTR_ALIGN): Use SMALL_PTRDIFF_T, instead of + testing sizeof (ptrdiff_t) < sizeof (void *) at compile time. + * m4/obstack.m4 (gl_FUNC_OBSTACK): Set SMALL_PTRDIFF_T. + * modules/obstack (Makefile.am): Substitute SMALL_PTRDIFF_T. + 2024-03-26 Bruno Haible gettime-res: Fix test failure on Solaris 11.4/SPARC. diff --git a/lib/obstack.in.h b/lib/obstack.in.h index cf149947be..28fb4d8916 100644 --- a/lib/obstack.in.h +++ b/lib/obstack.in.h @@ -133,17 +133,19 @@ # define _OBSTACK_CAST(type, expr) (expr) #endif -/* If B is the base of an object addressed by P, return the result of - 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. +/* __PTR_ALIGN(B, P, A) returns the result of aligning P to the next multiple + of A + 1. B must be the base of an object addressed by P. B and P must be + of type char *. A + 1 must be a power of 2. If ptrdiff_t is narrower than a pointer (e.g., the AS/400), play it safe and compute the alignment relative to B. Otherwise, use the faster strategy of computing the alignment through uintptr_t. */ - -#define __PTR_ALIGN(B, P, A) \ - (sizeof (ptrdiff_t) < sizeof (void *) \ - ? (B) + (((P) - (B) + (A)) & ~(A)) \ - : (P) + ((- (uintptr_t) (P)) & (A))) +#if @SMALL_PTRDIFF_T@ +# define __PTR_ALIGN(B, P, A) \ + ((B) + (((P) - (B) + (A)) & ~(A))) +#else +# define __PTR_ALIGN(B, P, A) \ + ((P) + ((- (uintptr_t) (P)) & (A))) +#endif #ifndef __attribute_pure__ # define __attribute_pure__ _GL_ATTRIBUTE_PURE diff --git a/m4/obstack.m4 b/m4/obstack.m4 index 196609d7fb..be553cfb78 100644 --- a/m4/obstack.m4 +++ b/m4/obstack.m4 @@ -45,4 +45,25 @@ AC_DEFUN([gl_FUNC_OBSTACK], GL_GENERATE_OBSTACK_H=false fi AC_SUBST([REPLACE_OBSTACK]) + + dnl Test whether a 'ptrdiff_t' has at least as many bits as a pointer. + AC_CACHE_CHECK([whether ptrdiff_t is at least as large as a pointer], + [gl_cv_ptrdiff_t_wide_enough], + [AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM( + [[#include + typedef int check[2 * (sizeof (ptrdiff_t) >= sizeof (void *)) - 1]; + ]], + [[]])], + [gl_cv_ptrdiff_t_wide_enough=yes], + [gl_cv_ptrdiff_t_wide_enough=no]) + ]) + if test $gl_cv_ptrdiff_t_wide_enough = yes; then + SMALL_PTRDIFF_T=0 + else + SMALL_PTRDIFF_T=1 + fi + dnl SMALL_PTRDIFF_T is expected to be 1 only on old / exotic platforms + dnl such as Windows 3.1 and AS/400. + AC_SUBST([SMALL_PTRDIFF_T]) ]) diff --git a/modules/obstack b/modules/obstack index e4db4cdc97..5c94894e8c 100644 --- a/modules/obstack +++ b/modules/obstack @@ -31,6 +31,7 @@ obstack.h: obstack.in.h $(top_builddir)/config.status @NMD@ $(AM_V_GEN)$(MKDIR_P) '%reldir%' $(gl_V_at)$(SED_HEADER_STDOUT) \ -e 's|@''REPLACE_OBSTACK''@|$(REPLACE_OBSTACK)|g' \ + -e 's|@''SMALL_PTRDIFF_T''@|$(SMALL_PTRDIFF_T)|g' \ $(srcdir)/obstack.in.h > $@-t $(AM_V_at)mv $@-t $@ else