From db53731c5f7e11240244161623b82b55cf303043 Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Mon, 25 Mar 2019 14:31:31 -0700 Subject: [PATCH] Fix alignment bug with pure bignums Problem found on 32-bit sparc, which has stricter alignment checking than x86-64. * src/alloc.c (pure_alloc): When TYPE is negative it now specifies the negation of the required alignment of the result. (make_pure_bignum): Specify bignum limb alignment. --- src/alloc.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/alloc.c b/src/alloc.c index f929a37271b..3a8bd30c34b 100644 --- a/src/alloc.c +++ b/src/alloc.c @@ -5342,7 +5342,8 @@ valid_lisp_object_p (Lisp_Object obj) /* Allocate room for SIZE bytes from pure Lisp storage and return a pointer to it. TYPE is the Lisp type for which the memory is - allocated. TYPE < 0 means it's not used for a Lisp object. */ + allocated. TYPE < 0 means it's not used for a Lisp object, + and that the result should have an alignment of -TYPE. */ static void * pure_alloc (size_t size, int type) @@ -5361,8 +5362,11 @@ pure_alloc (size_t size, int type) { /* Allocate space for a non-Lisp object from the end of the free space. */ - pure_bytes_used_non_lisp += size; - result = purebeg + pure_size - pure_bytes_used_non_lisp; + ptrdiff_t unaligned_non_lisp = pure_bytes_used_non_lisp + size; + char *unaligned = purebeg + pure_size - unaligned_non_lisp; + int decr = (intptr_t) unaligned & (-1 - type); + pure_bytes_used_non_lisp = unaligned_non_lisp + decr; + result = unaligned - decr; } pure_bytes_used = pure_bytes_used_lisp + pure_bytes_used_non_lisp; @@ -5549,7 +5553,8 @@ make_pure_bignum (struct Lisp_Bignum *value) struct Lisp_Bignum *b = pure_alloc (sizeof *b, Lisp_Vectorlike); XSETPVECTYPESIZE (b, PVEC_BIGNUM, 0, VECSIZE (struct Lisp_Bignum)); - pure_limbs = pure_alloc (nbytes, -1); + int limb_alignment = alignof (mp_limb_t); + pure_limbs = pure_alloc (nbytes, - limb_alignment); for (i = 0; i < nlimbs; ++i) pure_limbs[i] = mpz_getlimbn (value->value, i); -- 2.39.5