diff options
| author | Paul Eggert | 2018-06-13 13:30:29 -0700 |
|---|---|---|
| committer | Paul Eggert | 2018-06-13 13:31:34 -0700 |
| commit | 967d2c55ef3908fd378e05b2a0070663ae45f6de (patch) | |
| tree | b49c5abdec3a63b16cf339268afdc8db729d6fe7 | |
| parent | b8478b2ab7ad19c629da9c6b0dfd9a6544a6acee (diff) | |
| download | emacs-967d2c55ef3908fd378e05b2a0070663ae45f6de.tar.gz emacs-967d2c55ef3908fd378e05b2a0070663ae45f6de.zip | |
Remove some wrong 8-byte alignment assumptions
Do not assume that 8-byte alignment suffices for all C objects,
as some platforms require 16-byte alignment for some objects,
and this will start to bite us as time goes on (e.g., if an
Emacs module ever uses an object containing a long
double, which requires 16-byte alignment on x86-64).
Conversely, on !USE_LSB_TAG platforms, do not insist on
aligning Lisp objects to a multiple of 8, as this is not
needed for high-order tag bits.
* src/alloc.c (LISP_ALIGNMENT, MALLOC_IS_LISP_ALIGNED):
New constants.
(XMALLOC_BASE_ALIGNMENT, XMALLOC_HEADER_ALIGNMENT):
Removed. All uses replaced by LISP_ALIGNMENT.
(aligned_alloc, laligned, lmalloc, lrealloc, union aligned_Lisp_Misc)
(maybe_lisp_pointer, pure_alloc):
Use LISP_ALIGNMENT rather than GCALIGNMENT.
(aligned_alloc): Do not worry about an alignment of
LISP_ALIGNMENT when MALLOC_IS_LISP_ALIGNED, as the code never
uses aligned_alloc with alignment == LISP_ALIGNMENT in that case.
(__alignof__): Remove. All uses removed.
(MALLOC_IS_GC_ALIGNED): Remove.
All uses replaced with MALLOC_IS_LISP_ALIGNED.
(vector_alignment): Remove.
All uses replaced with LISP_ALIGNMENT.
* src/alloc.c (mark_maybe_pointer):
* src/emacs-module.c (value_to_lisp_bits):
Do not assume GCALIGNMENT == 1 << GCTYPEBITS, as GCALIGNMENT
is 1 on !USE_LSB_TAG platforms now.
* src/lisp.h (GCALIGNMENT) [!USE_LSB_TAG]: Now 1.
(struct Lisp_Symbol, union vectorlike_header, struct Lisp_Cons)
(struct Lisp_String): Simplify test for verifying alignment.
| -rw-r--r-- | src/alloc.c | 98 | ||||
| -rw-r--r-- | src/emacs-module.c | 2 | ||||
| -rw-r--r-- | src/lisp.h | 29 |
3 files changed, 63 insertions, 66 deletions
diff --git a/src/alloc.c b/src/alloc.c index cde2e4b3407..e5fc6ebeb1a 100644 --- a/src/alloc.c +++ b/src/alloc.c | |||
| @@ -633,6 +633,27 @@ buffer_memory_full (ptrdiff_t nbytes) | |||
| 633 | #define COMMON_MULTIPLE(a, b) \ | 633 | #define COMMON_MULTIPLE(a, b) \ |
| 634 | ((a) % (b) == 0 ? (a) : (b) % (a) == 0 ? (b) : (a) * (b)) | 634 | ((a) % (b) == 0 ? (a) : (b) % (a) == 0 ? (b) : (a) * (b)) |
| 635 | 635 | ||
| 636 | /* LISP_ALIGNMENT is the alignment of Lisp objects. It must be at | ||
| 637 | least GCALIGNMENT so that pointers can be tagged. It also must be | ||
| 638 | at least as strict as the alignment of all the C types used to | ||
| 639 | implement Lisp objects; since pseudovectors can contain any C type, | ||
| 640 | this is max_align_t. On recent GNU/Linux x86 and x86-64 this can | ||
| 641 | often waste up to 8 bytes, since alignof (max_align_t) is 16 but | ||
| 642 | typical vectors need only an alignment of 8. However, it is not | ||
| 643 | worth the hassle to avoid this waste. */ | ||
| 644 | enum { LISP_ALIGNMENT = alignof (union { max_align_t x; GCALIGNED_UNION }) }; | ||
| 645 | verify (LISP_ALIGNMENT % GCALIGNMENT == 0); | ||
| 646 | |||
| 647 | /* True if malloc (N) is known to return storage suitably aligned for | ||
| 648 | Lisp objects whenever N is a multiple of LISP_ALIGNMENT. In | ||
| 649 | practice this is true whenever alignof (max_align_t) is also a | ||
| 650 | multiple of LISP_ALIGNMENT. This works even for x86, where some | ||
| 651 | platform combinations (e.g., GCC 7 and later, glibc 2.25 and | ||
| 652 | earlier) have bugs where alignof (max_align_t) is 16 even though | ||
| 653 | the malloc alignment is only 8, and where Emacs still works because | ||
| 654 | it never does anything that requires an alignment of 16. */ | ||
| 655 | enum { MALLOC_IS_LISP_ALIGNED = alignof (max_align_t) % LISP_ALIGNMENT == 0 }; | ||
| 656 | |||
| 636 | #ifndef XMALLOC_OVERRUN_CHECK | 657 | #ifndef XMALLOC_OVERRUN_CHECK |
| 637 | #define XMALLOC_OVERRUN_CHECK_OVERHEAD 0 | 658 | #define XMALLOC_OVERRUN_CHECK_OVERHEAD 0 |
| 638 | #else | 659 | #else |
| @@ -653,18 +674,13 @@ buffer_memory_full (ptrdiff_t nbytes) | |||
| 653 | #define XMALLOC_OVERRUN_CHECK_OVERHEAD \ | 674 | #define XMALLOC_OVERRUN_CHECK_OVERHEAD \ |
| 654 | (2 * XMALLOC_OVERRUN_CHECK_SIZE + XMALLOC_OVERRUN_SIZE_SIZE) | 675 | (2 * XMALLOC_OVERRUN_CHECK_SIZE + XMALLOC_OVERRUN_SIZE_SIZE) |
| 655 | 676 | ||
| 656 | #define XMALLOC_BASE_ALIGNMENT alignof (max_align_t) | ||
| 657 | |||
| 658 | #define XMALLOC_HEADER_ALIGNMENT \ | ||
| 659 | COMMON_MULTIPLE (GCALIGNMENT, XMALLOC_BASE_ALIGNMENT) | ||
| 660 | |||
| 661 | /* Define XMALLOC_OVERRUN_SIZE_SIZE so that (1) it's large enough to | 677 | /* Define XMALLOC_OVERRUN_SIZE_SIZE so that (1) it's large enough to |
| 662 | hold a size_t value and (2) the header size is a multiple of the | 678 | hold a size_t value and (2) the header size is a multiple of the |
| 663 | alignment that Emacs needs for C types and for USE_LSB_TAG. */ | 679 | alignment that Emacs needs for C types and for USE_LSB_TAG. */ |
| 664 | #define XMALLOC_OVERRUN_SIZE_SIZE \ | 680 | #define XMALLOC_OVERRUN_SIZE_SIZE \ |
| 665 | (((XMALLOC_OVERRUN_CHECK_SIZE + sizeof (size_t) \ | 681 | (((XMALLOC_OVERRUN_CHECK_SIZE + sizeof (size_t) \ |
| 666 | + XMALLOC_HEADER_ALIGNMENT - 1) \ | 682 | + LISP_ALIGNMENT - 1) \ |
| 667 | / XMALLOC_HEADER_ALIGNMENT * XMALLOC_HEADER_ALIGNMENT) \ | 683 | / LISP_ALIGNMENT * LISP_ALIGNMENT) \ |
| 668 | - XMALLOC_OVERRUN_CHECK_SIZE) | 684 | - XMALLOC_OVERRUN_CHECK_SIZE) |
| 669 | 685 | ||
| 670 | static char const xmalloc_overrun_check_header[XMALLOC_OVERRUN_CHECK_SIZE] = | 686 | static char const xmalloc_overrun_check_header[XMALLOC_OVERRUN_CHECK_SIZE] = |
| @@ -1165,9 +1181,11 @@ aligned_alloc (size_t alignment, size_t size) | |||
| 1165 | Verify this for all arguments this function is given. */ | 1181 | Verify this for all arguments this function is given. */ |
| 1166 | verify (BLOCK_ALIGN % sizeof (void *) == 0 | 1182 | verify (BLOCK_ALIGN % sizeof (void *) == 0 |
| 1167 | && POWER_OF_2 (BLOCK_ALIGN / sizeof (void *))); | 1183 | && POWER_OF_2 (BLOCK_ALIGN / sizeof (void *))); |
| 1168 | verify (GCALIGNMENT % sizeof (void *) == 0 | 1184 | verify (MALLOC_IS_LISP_ALIGNED |
| 1169 | && POWER_OF_2 (GCALIGNMENT / sizeof (void *))); | 1185 | || (LISP_ALIGNMENT % sizeof (void *) == 0 |
| 1170 | eassert (alignment == BLOCK_ALIGN || alignment == GCALIGNMENT); | 1186 | && POWER_OF_2 (LISP_ALIGNMENT / sizeof (void *)))); |
| 1187 | eassert (alignment == BLOCK_ALIGN | ||
| 1188 | || (!MALLOC_IS_LISP_ALIGNED && alignment == LISP_ALIGNMENT)); | ||
| 1171 | 1189 | ||
| 1172 | void *p; | 1190 | void *p; |
| 1173 | return posix_memalign (&p, alignment, size) == 0 ? p : 0; | 1191 | return posix_memalign (&p, alignment, size) == 0 ? p : 0; |
| @@ -1399,31 +1417,15 @@ lisp_align_free (void *block) | |||
| 1399 | MALLOC_UNBLOCK_INPUT; | 1417 | MALLOC_UNBLOCK_INPUT; |
| 1400 | } | 1418 | } |
| 1401 | 1419 | ||
| 1402 | #if !defined __GNUC__ && !defined __alignof__ | ||
| 1403 | # define __alignof__(type) alignof (type) | ||
| 1404 | #endif | ||
| 1405 | |||
| 1406 | /* True if malloc (N) is known to return a multiple of GCALIGNMENT | ||
| 1407 | whenever N is also a multiple. In practice this is true if | ||
| 1408 | __alignof__ (max_align_t) is a multiple as well, assuming | ||
| 1409 | GCALIGNMENT is 8; other values of GCALIGNMENT have not been looked | ||
| 1410 | into. Use __alignof__ if available, as otherwise | ||
| 1411 | MALLOC_IS_GC_ALIGNED would be false on GCC x86 even though the | ||
| 1412 | alignment is OK there. | ||
| 1413 | |||
| 1414 | This is a macro, not an enum constant, for portability to HP-UX | ||
| 1415 | 10.20 cc and AIX 3.2.5 xlc. */ | ||
| 1416 | #define MALLOC_IS_GC_ALIGNED \ | ||
| 1417 | (GCALIGNMENT == 8 && __alignof__ (max_align_t) % GCALIGNMENT == 0) | ||
| 1418 | |||
| 1419 | /* True if a malloc-returned pointer P is suitably aligned for SIZE, | 1420 | /* True if a malloc-returned pointer P is suitably aligned for SIZE, |
| 1420 | where Lisp alignment may be needed if SIZE is Lisp-aligned. */ | 1421 | where Lisp object alignment may be needed if SIZE is a multiple of |
| 1422 | LISP_ALIGNMENT. */ | ||
| 1421 | 1423 | ||
| 1422 | static bool | 1424 | static bool |
| 1423 | laligned (void *p, size_t size) | 1425 | laligned (void *p, size_t size) |
| 1424 | { | 1426 | { |
| 1425 | return (MALLOC_IS_GC_ALIGNED || (intptr_t) p % GCALIGNMENT == 0 | 1427 | return (MALLOC_IS_LISP_ALIGNED || (intptr_t) p % LISP_ALIGNMENT == 0 |
| 1426 | || size % GCALIGNMENT != 0); | 1428 | || size % LISP_ALIGNMENT != 0); |
| 1427 | } | 1429 | } |
| 1428 | 1430 | ||
| 1429 | /* Like malloc and realloc except that if SIZE is Lisp-aligned, make | 1431 | /* Like malloc and realloc except that if SIZE is Lisp-aligned, make |
| @@ -1446,8 +1448,8 @@ static void * | |||
| 1446 | lmalloc (size_t size) | 1448 | lmalloc (size_t size) |
| 1447 | { | 1449 | { |
| 1448 | #ifdef USE_ALIGNED_ALLOC | 1450 | #ifdef USE_ALIGNED_ALLOC |
| 1449 | if (! MALLOC_IS_GC_ALIGNED && size % GCALIGNMENT == 0) | 1451 | if (! MALLOC_IS_LISP_ALIGNED && size % LISP_ALIGNMENT == 0) |
| 1450 | return aligned_alloc (GCALIGNMENT, size); | 1452 | return aligned_alloc (LISP_ALIGNMENT, size); |
| 1451 | #endif | 1453 | #endif |
| 1452 | 1454 | ||
| 1453 | while (true) | 1455 | while (true) |
| @@ -1456,7 +1458,7 @@ lmalloc (size_t size) | |||
| 1456 | if (laligned (p, size)) | 1458 | if (laligned (p, size)) |
| 1457 | return p; | 1459 | return p; |
| 1458 | free (p); | 1460 | free (p); |
| 1459 | size_t bigger = size + GCALIGNMENT; | 1461 | size_t bigger = size + LISP_ALIGNMENT; |
| 1460 | if (size < bigger) | 1462 | if (size < bigger) |
| 1461 | size = bigger; | 1463 | size = bigger; |
| 1462 | } | 1464 | } |
| @@ -1470,7 +1472,7 @@ lrealloc (void *p, size_t size) | |||
| 1470 | p = realloc (p, size); | 1472 | p = realloc (p, size); |
| 1471 | if (laligned (p, size)) | 1473 | if (laligned (p, size)) |
| 1472 | return p; | 1474 | return p; |
| 1473 | size_t bigger = size + GCALIGNMENT; | 1475 | size_t bigger = size + LISP_ALIGNMENT; |
| 1474 | if (size < bigger) | 1476 | if (size < bigger) |
| 1475 | size = bigger; | 1477 | size = bigger; |
| 1476 | } | 1478 | } |
| @@ -2931,16 +2933,8 @@ set_next_vector (struct Lisp_Vector *v, struct Lisp_Vector *p) | |||
| 2931 | 2933 | ||
| 2932 | #define VECTOR_BLOCK_SIZE 4096 | 2934 | #define VECTOR_BLOCK_SIZE 4096 |
| 2933 | 2935 | ||
| 2934 | /* Alignment of struct Lisp_Vector objects. Because pseudovectors | ||
| 2935 | can contain any C type, align at least as strictly as | ||
| 2936 | max_align_t. On x86 and x86-64 this can waste up to 8 bytes | ||
| 2937 | for typical vectors, since alignof (max_align_t) is 16 but | ||
| 2938 | typical vectors need only an alignment of 8. However, it is | ||
| 2939 | not worth the hassle to avoid wasting those bytes. */ | ||
| 2940 | enum {vector_alignment = COMMON_MULTIPLE (alignof (max_align_t), GCALIGNMENT)}; | ||
| 2941 | |||
| 2942 | /* Vector size requests are a multiple of this. */ | 2936 | /* Vector size requests are a multiple of this. */ |
| 2943 | enum { roundup_size = COMMON_MULTIPLE (vector_alignment, word_size) }; | 2937 | enum { roundup_size = COMMON_MULTIPLE (LISP_ALIGNMENT, word_size) }; |
| 2944 | 2938 | ||
| 2945 | /* Verify assumptions described above. */ | 2939 | /* Verify assumptions described above. */ |
| 2946 | verify (VECTOR_BLOCK_SIZE % roundup_size == 0); | 2940 | verify (VECTOR_BLOCK_SIZE % roundup_size == 0); |
| @@ -3007,7 +3001,7 @@ struct large_vector | |||
| 3007 | 3001 | ||
| 3008 | enum | 3002 | enum |
| 3009 | { | 3003 | { |
| 3010 | large_vector_offset = ROUNDUP (sizeof (struct large_vector), vector_alignment) | 3004 | large_vector_offset = ROUNDUP (sizeof (struct large_vector), LISP_ALIGNMENT) |
| 3011 | }; | 3005 | }; |
| 3012 | 3006 | ||
| 3013 | static struct Lisp_Vector * | 3007 | static struct Lisp_Vector * |
| @@ -3656,8 +3650,8 @@ Its value is void, and its function definition and property list are nil. */) | |||
| 3656 | union aligned_Lisp_Misc | 3650 | union aligned_Lisp_Misc |
| 3657 | { | 3651 | { |
| 3658 | union Lisp_Misc m; | 3652 | union Lisp_Misc m; |
| 3659 | unsigned char c[(sizeof (union Lisp_Misc) + GCALIGNMENT - 1) | 3653 | unsigned char c[(sizeof (union Lisp_Misc) + LISP_ALIGNMENT - 1) |
| 3660 | & -GCALIGNMENT]; | 3654 | & -LISP_ALIGNMENT]; |
| 3661 | }; | 3655 | }; |
| 3662 | 3656 | ||
| 3663 | /* Allocation of markers and other objects that share that structure. | 3657 | /* Allocation of markers and other objects that share that structure. |
| @@ -4851,14 +4845,16 @@ mark_maybe_object (Lisp_Object obj) | |||
| 4851 | } | 4845 | } |
| 4852 | } | 4846 | } |
| 4853 | 4847 | ||
| 4854 | /* Return true if P can point to Lisp data, and false otherwise. | 4848 | /* Return true if P might point to Lisp data that can be garbage |
| 4849 | collected, and false otherwise (i.e., false if it is easy to see | ||
| 4850 | that P cannot point to Lisp data that can be garbage collected). | ||
| 4855 | Symbols are implemented via offsets not pointers, but the offsets | 4851 | Symbols are implemented via offsets not pointers, but the offsets |
| 4856 | are also multiples of GCALIGNMENT. */ | 4852 | are also multiples of LISP_ALIGNMENT. */ |
| 4857 | 4853 | ||
| 4858 | static bool | 4854 | static bool |
| 4859 | maybe_lisp_pointer (void *p) | 4855 | maybe_lisp_pointer (void *p) |
| 4860 | { | 4856 | { |
| 4861 | return (uintptr_t) p % GCALIGNMENT == 0; | 4857 | return (uintptr_t) p % LISP_ALIGNMENT == 0; |
| 4862 | } | 4858 | } |
| 4863 | 4859 | ||
| 4864 | #ifndef HAVE_MODULES | 4860 | #ifndef HAVE_MODULES |
| @@ -4887,7 +4883,7 @@ mark_maybe_pointer (void *p) | |||
| 4887 | { | 4883 | { |
| 4888 | /* For the wide-int case, also mark emacs_value tagged pointers, | 4884 | /* For the wide-int case, also mark emacs_value tagged pointers, |
| 4889 | which can be generated by emacs-module.c's value_to_lisp. */ | 4885 | which can be generated by emacs-module.c's value_to_lisp. */ |
| 4890 | p = (void *) ((uintptr_t) p & ~(GCALIGNMENT - 1)); | 4886 | p = (void *) ((uintptr_t) p & ~((1 << GCTYPEBITS) - 1)); |
| 4891 | } | 4887 | } |
| 4892 | 4888 | ||
| 4893 | m = mem_find (p); | 4889 | m = mem_find (p); |
| @@ -5358,7 +5354,7 @@ pure_alloc (size_t size, int type) | |||
| 5358 | { | 5354 | { |
| 5359 | /* Allocate space for a Lisp object from the beginning of the free | 5355 | /* Allocate space for a Lisp object from the beginning of the free |
| 5360 | space with taking account of alignment. */ | 5356 | space with taking account of alignment. */ |
| 5361 | result = pointer_align (purebeg + pure_bytes_used_lisp, GCALIGNMENT); | 5357 | result = pointer_align (purebeg + pure_bytes_used_lisp, LISP_ALIGNMENT); |
| 5362 | pure_bytes_used_lisp = ((char *)result - (char *)purebeg) + size; | 5358 | pure_bytes_used_lisp = ((char *)result - (char *)purebeg) + size; |
| 5363 | } | 5359 | } |
| 5364 | else | 5360 | else |
diff --git a/src/emacs-module.c b/src/emacs-module.c index 956706cf9f5..c18c7ab308b 100644 --- a/src/emacs-module.c +++ b/src/emacs-module.c | |||
| @@ -924,7 +924,7 @@ value_to_lisp_bits (emacs_value v) | |||
| 924 | makes TAG_PTR faster. */ | 924 | makes TAG_PTR faster. */ |
| 925 | 925 | ||
| 926 | intptr_t i = (intptr_t) v; | 926 | intptr_t i = (intptr_t) v; |
| 927 | EMACS_UINT tag = i & (GCALIGNMENT - 1); | 927 | EMACS_UINT tag = i & ((1 << GCTYPEBITS) - 1); |
| 928 | EMACS_UINT untagged = i - tag; | 928 | EMACS_UINT untagged = i - tag; |
| 929 | switch (tag) | 929 | switch (tag) |
| 930 | { | 930 | { |
diff --git a/src/lisp.h b/src/lisp.h index d4499846053..aaad90b2dad 100644 --- a/src/lisp.h +++ b/src/lisp.h | |||
| @@ -233,10 +233,6 @@ extern bool suppress_checking EXTERNALLY_VISIBLE; | |||
| 233 | 233 | ||
| 234 | enum Lisp_Bits | 234 | enum Lisp_Bits |
| 235 | { | 235 | { |
| 236 | /* 2**GCTYPEBITS. This must be a macro that expands to a literal | ||
| 237 | integer constant, for older versions of GCC (through at least 4.9). */ | ||
| 238 | #define GCALIGNMENT 8 | ||
| 239 | |||
| 240 | /* Number of bits in a Lisp_Object value, not counting the tag. */ | 236 | /* Number of bits in a Lisp_Object value, not counting the tag. */ |
| 241 | VALBITS = EMACS_INT_WIDTH - GCTYPEBITS, | 237 | VALBITS = EMACS_INT_WIDTH - GCTYPEBITS, |
| 242 | 238 | ||
| @@ -247,10 +243,6 @@ enum Lisp_Bits | |||
| 247 | FIXNUM_BITS = VALBITS + 1 | 243 | FIXNUM_BITS = VALBITS + 1 |
| 248 | }; | 244 | }; |
| 249 | 245 | ||
| 250 | #if GCALIGNMENT != 1 << GCTYPEBITS | ||
| 251 | # error "GCALIGNMENT and GCTYPEBITS are inconsistent" | ||
| 252 | #endif | ||
| 253 | |||
| 254 | /* The maximum value that can be stored in a EMACS_INT, assuming all | 246 | /* The maximum value that can be stored in a EMACS_INT, assuming all |
| 255 | bits other than the type bits contribute to a nonnegative signed value. | 247 | bits other than the type bits contribute to a nonnegative signed value. |
| 256 | This can be used in #if, e.g., '#if USE_LSB_TAG' below expands to an | 248 | This can be used in #if, e.g., '#if USE_LSB_TAG' below expands to an |
| @@ -277,12 +269,21 @@ DEFINE_GDB_SYMBOL_END (VALMASK) | |||
| 277 | error !; | 269 | error !; |
| 278 | #endif | 270 | #endif |
| 279 | 271 | ||
| 272 | /* Minimum alignment requirement for Lisp objects, imposed by the | ||
| 273 | internal representation of tagged pointers. It is 2**GCTYPEBITS if | ||
| 274 | USE_LSB_TAG, 1 otherwise. It must be a literal integer constant, | ||
| 275 | for older versions of GCC (through at least 4.9). */ | ||
| 280 | #if USE_LSB_TAG | 276 | #if USE_LSB_TAG |
| 281 | # define GCALIGNED_UNION char alignas (GCALIGNMENT) gcaligned; | 277 | # define GCALIGNMENT 8 |
| 278 | # if GCALIGNMENT != 1 << GCTYPEBITS | ||
| 279 | # error "GCALIGNMENT and GCTYPEBITS are inconsistent" | ||
| 280 | # endif | ||
| 282 | #else | 281 | #else |
| 283 | # define GCALIGNED_UNION | 282 | # define GCALIGNMENT 1 |
| 284 | #endif | 283 | #endif |
| 285 | 284 | ||
| 285 | #define GCALIGNED_UNION char alignas (GCALIGNMENT) gcaligned; | ||
| 286 | |||
| 286 | /* Lisp_Word is a scalar word suitable for holding a tagged pointer or | 287 | /* Lisp_Word is a scalar word suitable for holding a tagged pointer or |
| 287 | integer. Usually it is a pointer to a deliberately-incomplete type | 288 | integer. Usually it is a pointer to a deliberately-incomplete type |
| 288 | 'union Lisp_X'. However, it is EMACS_INT when Lisp_Objects and | 289 | 'union Lisp_X'. However, it is EMACS_INT when Lisp_Objects and |
| @@ -774,7 +775,7 @@ struct Lisp_Symbol | |||
| 774 | GCALIGNED_UNION | 775 | GCALIGNED_UNION |
| 775 | } u; | 776 | } u; |
| 776 | }; | 777 | }; |
| 777 | verify (!USE_LSB_TAG || alignof (struct Lisp_Symbol) % GCALIGNMENT == 0); | 778 | verify (alignof (struct Lisp_Symbol) % GCALIGNMENT == 0); |
| 778 | 779 | ||
| 779 | /* Declare a Lisp-callable function. The MAXARGS parameter has the same | 780 | /* Declare a Lisp-callable function. The MAXARGS parameter has the same |
| 780 | meaning as in the DEFUN macro, and is used to construct a prototype. */ | 781 | meaning as in the DEFUN macro, and is used to construct a prototype. */ |
| @@ -888,7 +889,7 @@ union vectorlike_header | |||
| 888 | ptrdiff_t size; | 889 | ptrdiff_t size; |
| 889 | GCALIGNED_UNION | 890 | GCALIGNED_UNION |
| 890 | }; | 891 | }; |
| 891 | verify (!USE_LSB_TAG || alignof (union vectorlike_header) % GCALIGNMENT == 0); | 892 | verify (alignof (union vectorlike_header) % GCALIGNMENT == 0); |
| 892 | 893 | ||
| 893 | INLINE bool | 894 | INLINE bool |
| 894 | (SYMBOLP) (Lisp_Object x) | 895 | (SYMBOLP) (Lisp_Object x) |
| @@ -1249,7 +1250,7 @@ struct Lisp_Cons | |||
| 1249 | GCALIGNED_UNION | 1250 | GCALIGNED_UNION |
| 1250 | } u; | 1251 | } u; |
| 1251 | }; | 1252 | }; |
| 1252 | verify (!USE_LSB_TAG || alignof (struct Lisp_Cons) % GCALIGNMENT == 0); | 1253 | verify (alignof (struct Lisp_Cons) % GCALIGNMENT == 0); |
| 1253 | 1254 | ||
| 1254 | INLINE bool | 1255 | INLINE bool |
| 1255 | (NILP) (Lisp_Object x) | 1256 | (NILP) (Lisp_Object x) |
| @@ -1371,7 +1372,7 @@ struct Lisp_String | |||
| 1371 | GCALIGNED_UNION | 1372 | GCALIGNED_UNION |
| 1372 | } u; | 1373 | } u; |
| 1373 | }; | 1374 | }; |
| 1374 | verify (!USE_LSB_TAG || alignof (struct Lisp_String) % GCALIGNMENT == 0); | 1375 | verify (alignof (struct Lisp_String) % GCALIGNMENT == 0); |
| 1375 | 1376 | ||
| 1376 | INLINE bool | 1377 | INLINE bool |
| 1377 | STRINGP (Lisp_Object x) | 1378 | STRINGP (Lisp_Object x) |