1
Fork 0
mirror of git://git.sv.gnu.org/emacs.git synced 2026-01-11 05:51:21 -08:00

Align config.h better to src/lisp.h

This is mostly a cleanup patch to fix growing discrepancies
between src/lisp.h and configure.ac in terms of how they deduce
how EMACS_INT aligns.  The patch includes a static check that the
two methods now agree.  It also speeds up ‘configure’ a bit.
* configure.ac (ALIGNOF_INT, ALIGNOF_LONG, ALIGNOF_LONG_LONG):
Remove; no longer used.
(ALIGNOF_EMACS_INT): New macro.
(system_malloc): Set to 'no' more consistently with what’s
in src/lisp.h.
* src/lisp.h (ALIGNOF_EMACS_INT): Do not define here, as config.h
defines it now.  Check that config.h’s definition equals the
actual alignof (EMACS_INT).
(USE_USB_TAG): Set more consistently with what’s in configure.ac.
(alignas): Don’t second-guess Gnulib.
This commit is contained in:
Paul Eggert 2025-12-07 15:21:46 -08:00
parent f766e8a36b
commit 0d43f2a562
2 changed files with 51 additions and 58 deletions

View file

@ -3227,8 +3227,13 @@ to configure.])
fi
# Configure gnulib.
# Although this does not affect CFLAGS or LIBS permanently.
# it temporarily reverts them to their pre-pkg-config values,
#
# Do this after any CC or CFLAGS changes that affect Gnulib,
# and before any tests that depend on gnulib tests,
# e.g., the system_malloc=no test below.
#
# Do not affect CFLAGS or LIBS permanently.
# Instead, temporarily revert them to their pre-pkg-config values,
# because gnulib needs to work with both src (which uses the
# pkg-config stuff) and lib-src (which does not). For example, gnulib
# may need to determine whether CLOCK_TIME_LIB should contain -lrt,
@ -3266,9 +3271,19 @@ AC_CACHE_CHECK(
fi])
doug_lea_malloc=$emacs_cv_var_doug_lea_malloc
AC_CHECK_ALIGNOF([int])
AC_CHECK_ALIGNOF([long])
AC_CHECK_ALIGNOF([long long])
AC_CHECK_ALIGNOF([EMACS_INT],
[[#include <limits.h>
#include <stddef.h>
#include <stdint.h>
#if INTPTR_MAX <= INT_MAX && !defined WIDE_EMACS_INT
typedef int EMACS_INT;
#elif INTPTR_MAX <= LONG_MAX && !defined WIDE_EMACS_INT
typedef long int EMACS_INT;
#elif INTPTR_MAX <= LLONG_MAX
typedef long long int EMACS_INT;
#endif
]])
AC_CHECK_SIZEOF([long])
AC_CACHE_CHECK([for struct alignment],
@ -3293,40 +3308,27 @@ system_malloc=yes
# adequately positioned memory, enable the GNU malloc, which more
# consistently provides allocations at low addresses, as is required for
# the pdumper to load dump files at a representable location.
AS_IF([test "$with_pdumper" = "yes" && test "$with_wide_int" != "yes"],
AC_CHECK_HEADERS([stdalign.h])
[AC_CACHE_CHECK([whether alignas is required yet unavailable],
[emacs_cv_alignas_unavailable],
[AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
#ifdef HAVE_STDALIGN_H
#include <stdalign.h>
#endif
#include <limits.h>
]], [[
#define IDEAL_GCALIGNMENT 8
#if INTPTR_MAX <= INT_MAX && !defined WIDE_EMACS_INT
# define ALIGNOF_EMACS_INT ALIGNOF_INT
# elif INTPTR_MAX <= LONG_MAX && !defined WIDE_EMACS_INT
# define ALIGNOF_EMACS_INT ALIGNOF_LONG
# elif INTPTR_MAX <= LLONG_MAX
# define ALIGNOF_EMACS_INT ALIGNOF_LONG_LONG
# else
# error "INTPTR_MAX too large"
#endif
AS_CASE([$emacs_cv_struct_alignment%$gl_cv_header_working_stdalign_h%$with_wide_int%$ac_cv_alignof_EMACS_INT%$with_pdumper],
[*%*%*%*%*%*],
[AC_MSG_ERROR([configuration values cannot contain '%'])],
#if (ALIGNOF_EMACS_INT < IDEAL_GCALIGNMENT && !defined alignas \
&& !defined HAVE_STRUCT_ATTRIBUTE_ALIGNED \
&& !defined __alignas_is_defined \
&& __STDC_VERSION__ < 202311 && __cplusplus < 201103)
#error "!USE_LSB_TAG required"
#endif
]])], [emacs_cv_alignas_unavailable=no],
[emacs_cv_alignas_unavailable=yes])])
AS_IF([test "$emacs_cv_alignas_unavailable" = "yes"],
[system_malloc=no
AC_MSG_WARN([The GNU memory manager will be enabled as your system
does not guarantee that the portable dumper can allocate memory at a suitably
low address.])])])
dnl There is no problem in most situations, i.e.:
[dnl if emacs_cv_struct_alignment
yes%* \
dnl or if gl_cv_header_working_stdalign_h
| *%yes*%*%*%* \
dnl or if with_wide_int (as in practice tag bits are high-order)
| *%*%yes%*%* \
dnl or if EMACS_INT's alignment is at least 8.
| *%*%*%8%* | *%*%*%[1-9]?*%*],
[],
dnl Otherwise, if using the portable dumper, enable GNU malloc.
[*%yes],
[system_malloc=no
AC_MSG_WARN([The GNU memory manager will be enabled as your system
does not guarantee that the portable dumper can allocate memory
at a suitably low address.])])
dnl This must be before the test of $ac_cv_func_sbrk below.
AC_CHECK_FUNCS_ONCE([sbrk])

View file

@ -90,21 +90,18 @@ DEFINE_GDB_SYMBOL_END (GCTYPEBITS)
typedef int EMACS_INT;
typedef unsigned int EMACS_UINT;
enum { EMACS_INT_WIDTH = INT_WIDTH, EMACS_UINT_WIDTH = UINT_WIDTH };
# define ALIGNOF_EMACS_INT ALIGNOF_INT
# define EMACS_INT_MAX INT_MAX
# define pI ""
# elif INTPTR_MAX <= LONG_MAX && !defined WIDE_EMACS_INT
typedef long int EMACS_INT;
typedef unsigned long EMACS_UINT;
enum { EMACS_INT_WIDTH = LONG_WIDTH, EMACS_UINT_WIDTH = ULONG_WIDTH };
# define ALIGNOF_EMACS_INT ALIGNOF_LONG
# define EMACS_INT_MAX LONG_MAX
# define pI "l"
# elif INTPTR_MAX <= LLONG_MAX
typedef long long int EMACS_INT;
typedef unsigned long long int EMACS_UINT;
enum { EMACS_INT_WIDTH = LLONG_WIDTH, EMACS_UINT_WIDTH = ULLONG_WIDTH };
# define ALIGNOF_EMACS_INT ALIGNOF_LONG_LONG
# define EMACS_INT_MAX LLONG_MAX
/* MinGW supports %lld only if __USE_MINGW_ANSI_STDIO is non-zero,
which is arranged by config.h, and (for mingw.org) if GCC is 6.0 or
@ -123,6 +120,7 @@ enum { EMACS_INT_WIDTH = LLONG_WIDTH, EMACS_UINT_WIDTH = ULLONG_WIDTH };
# error "INTPTR_MAX too large"
# endif
#endif
static_assert (alignof (EMACS_INT) == ALIGNOF_EMACS_INT);
/* Number of bits to put in each character in the internal representation
of bool vectors. This should not vary across implementations. */
@ -252,15 +250,13 @@ DEFINE_GDB_SYMBOL_END (INTTYPEBITS)
b. slower, because it typically requires extra masking.
So, USE_LSB_TAG is true only on hosts where it might be useful. */
DEFINE_GDB_SYMBOL_BEGIN (bool, USE_LSB_TAG)
#if (ALIGNOF_EMACS_INT < IDEAL_GCALIGNMENT && !defined alignas \
&& ! (__GNUC__ || 4 <= __clang_major__) \
&& __STDC_VERSION__ < 202311 && __cplusplus < 201103) \
&& !defined WIDE_EMACS_INT \
&& !defined HAVE_STRUCT_ATTRIBUTE_ALIGNED
#define USE_LSB_TAG 0
#else /* ALIGNOF_EMACS_INT >= IDEAL_GCALIGNMENT || defined alignas ... */
#define USE_LSB_TAG (VAL_MAX / 2 < INTPTR_MAX)
#endif /* ALIGNOF_EMACS_INT >= IDEAL_GCALIGNMENT || defined alignas ... */
#if (ALIGNOF_EMACS_INT < IDEAL_GCALIGNMENT \
&& !HAVE_C_ALIGNASOF && !defined alignas \
&& !defined HAVE_STRUCT_ATTRIBUTE_ALIGNED)
# define USE_LSB_TAG false
#else
# define USE_LSB_TAG (VAL_MAX / 2 < INTPTR_MAX)
#endif
DEFINE_GDB_SYMBOL_END (USE_LSB_TAG)
/* Mask for the value (as opposed to the type bits) of a Lisp object. */
@ -268,14 +264,9 @@ DEFINE_GDB_SYMBOL_BEGIN (EMACS_INT, VALMASK)
# define VALMASK (USE_LSB_TAG ? - (1 << GCTYPEBITS) : VAL_MAX)
DEFINE_GDB_SYMBOL_END (VALMASK)
/* Support 'alignas (A)' if possible, where A is an integer constant. */
#ifndef alignas
# if __GNUC__ || 4 <= __clang_major__
/* This is more reliable than the alignas operator, in GCC 14. */
# define alignas(a) __attribute__ ((__aligned__ (a)))
# elif __STDC_VERSION__ < 202311 && __cplusplus < 201103
# define alignas(a) /* not supported */
# endif
/* Ignore 'alignas' on compilers lacking it. */
#if !HAVE_C_ALIGNASOF && !defined alignas
# define alignas(a) /* not supported */
#endif
/* The minimum alignment requirement for Lisp objects that is imposed by the