aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul Eggert2017-11-13 10:54:20 -0800
committerPaul Eggert2017-11-13 10:54:20 -0800
commit99ceefa8ec4f9993663492cfcce6bb82a94569c1 (patch)
tree507f76715b3086f34672b7c984dc09befaa57fc6
parenta7b7b85567f766ff510a5eaaaf32dbbbec15efd0 (diff)
parent79108894dbcd642121466bb6af6c98c6a56e9233 (diff)
downloademacs-99ceefa8ec4f9993663492cfcce6bb82a94569c1.tar.gz
emacs-99ceefa8ec4f9993663492cfcce6bb82a94569c1.zip
Merge from origin/emacs-26
79108894db Port to IBM xlc 12.01 d14956099d Simplify by removing HAVE_STRUCT_ATTRIBUTE_ALIGNED b1573a97e1 Use alignas to fix GCALIGN-related bugs 5d68dc9a2f Change vectorlike from struct to union 6aa0a26b46 Don't enable cursor-sensor-mode in mhtml-mode 2b8ef8dddf * lisp/files.el (abbreviate-file-name): Doc fix. (Bug#29267) fe85ce1e16 Unbreak interactive run of a flymake test (bug#29267) 48ad00390d Fix Bug#29225 42daf83f08 CC Mode: Fix defun-open being recognized as brace-list-ope... 7775c47298 Merge from Gnulib e470d16448 Pacify GCC when configured --with-x-toolkit=no 49450d0951 * lisp/find-dired.el (find-grep-dired): Doc fix. (Bug#29262) e286b3381f Fix more flymake-diag-region eob corner cases and add test... # Conflicts: # src/lisp.h
-rw-r--r--admin/CPP-DEFINES1
-rwxr-xr-xbuild-aux/config.guess9
-rwxr-xr-xbuild-aux/config.sub5
-rw-r--r--configure.ac16
-rw-r--r--doc/lispref/internals.texi4
-rw-r--r--doc/misc/texinfo.tex4
-rw-r--r--lib-src/make-docfile.c4
-rw-r--r--lib/faccessat.c60
-rw-r--r--lib/fstatat.c2
-rw-r--r--lib/gnulib.mk.in2
-rw-r--r--lib/unistd.in.h16
-rw-r--r--lisp/files.el8
-rw-r--r--lisp/find-dired.el6
-rw-r--r--lisp/progmodes/cc-engine.el14
-rw-r--r--lisp/progmodes/flymake.el16
-rw-r--r--lisp/textmodes/mhtml-mode.el5
-rw-r--r--m4/faccessat.m46
-rw-r--r--m4/gnulib-comp.m410
-rw-r--r--m4/unistd_h.m43
-rw-r--r--oldXMenu/Activate.c1
-rw-r--r--src/alloc.c234
-rw-r--r--src/buffer.c19
-rw-r--r--src/buffer.h2
-rw-r--r--src/bytecode.c4
-rw-r--r--src/casefiddle.c4
-rw-r--r--src/cmds.c6
-rw-r--r--src/data.c76
-rw-r--r--src/doc.c2
-rw-r--r--src/emacs-module.c17
-rw-r--r--src/eval.c59
-rw-r--r--src/fileio.c3
-rw-r--r--src/fns.c4
-rw-r--r--src/font.h6
-rw-r--r--src/frame.h2
-rw-r--r--src/keyboard.c10
-rw-r--r--src/lisp.h303
-rw-r--r--src/lread.c52
-rw-r--r--src/minibuf.c12
-rw-r--r--src/process.h2
-rw-r--r--src/termhooks.h2
-rw-r--r--src/thread.c2
-rw-r--r--src/thread.h6
-rw-r--r--src/w32term.h2
-rw-r--r--src/window.c8
-rw-r--r--src/window.h2
-rw-r--r--src/xterm.c7
-rw-r--r--src/xterm.h2
-rw-r--r--src/xwidget.h4
-rw-r--r--test/lisp/net/tramp-tests.el251
-rw-r--r--test/lisp/progmodes/flymake-tests.el37
50 files changed, 790 insertions, 542 deletions
diff --git a/admin/CPP-DEFINES b/admin/CPP-DEFINES
index eb3eadf2da8..04d1ff76f36 100644
--- a/admin/CPP-DEFINES
+++ b/admin/CPP-DEFINES
@@ -102,7 +102,6 @@ HAVE_ALARM
102HAVE_ALLOCA 102HAVE_ALLOCA
103HAVE_ALLOCA_H 103HAVE_ALLOCA_H
104HAVE_ALSA 104HAVE_ALSA
105HAVE_ATTRIBUTE_ALIGNED
106HAVE_BDFFONT 105HAVE_BDFFONT
107HAVE_BOXES 106HAVE_BOXES
108HAVE_C99_STRTOLD 107HAVE_C99_STRTOLD
diff --git a/build-aux/config.guess b/build-aux/config.guess
index 2773ac4f5ed..31e01efec3e 100755
--- a/build-aux/config.guess
+++ b/build-aux/config.guess
@@ -2,7 +2,7 @@
2# Attempt to guess a canonical system name. 2# Attempt to guess a canonical system name.
3# Copyright 1992-2017 Free Software Foundation, Inc. 3# Copyright 1992-2017 Free Software Foundation, Inc.
4 4
5timestamp='2017-11-01' 5timestamp='2017-11-07'
6 6
7# This file is free software; you can redistribute it and/or modify it 7# This file is free software; you can redistribute it and/or modify it
8# under the terms of the GNU General Public License as published by 8# under the terms of the GNU General Public License as published by
@@ -39,7 +39,7 @@ Usage: $0 [OPTION]
39 39
40Output the configuration name of the system \`$me' is run on. 40Output the configuration name of the system \`$me' is run on.
41 41
42Operation modes: 42Options:
43 -h, --help print this help, then exit 43 -h, --help print this help, then exit
44 -t, --time-stamp print date of last modification, then exit 44 -t, --time-stamp print date of last modification, then exit
45 -v, --version print version number, then exit 45 -v, --version print version number, then exit
@@ -244,6 +244,9 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
244 UNAME_MACHINE_ARCH=`arch | sed 's/^.*BSD\.//'` 244 UNAME_MACHINE_ARCH=`arch | sed 's/^.*BSD\.//'`
245 echo ${UNAME_MACHINE_ARCH}-unknown-libertybsd${UNAME_RELEASE} 245 echo ${UNAME_MACHINE_ARCH}-unknown-libertybsd${UNAME_RELEASE}
246 exit ;; 246 exit ;;
247 *:MidnightBSD:*:*)
248 echo ${UNAME_MACHINE}-unknown-midnightbsd${UNAME_RELEASE}
249 exit ;;
247 *:ekkoBSD:*:*) 250 *:ekkoBSD:*:*)
248 echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE} 251 echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE}
249 exit ;; 252 exit ;;
@@ -479,7 +482,7 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
479#endif 482#endif
480 #if defined (host_mips) && defined (MIPSEB) 483 #if defined (host_mips) && defined (MIPSEB)
481 #if defined (SYSTYPE_SYSV) 484 #if defined (SYSTYPE_SYSV)
482 printf ("mips-mips-risco0s%ssysv\\n", argv[1]); exit (0); 485 printf ("mips-mips-riscos%ssysv\\n", argv[1]); exit (0);
483 #endif 486 #endif
484 #if defined (SYSTYPE_SVR4) 487 #if defined (SYSTYPE_SVR4)
485 printf ("mips-mips-riscos%ssvr4\\n", argv[1]); exit (0); 488 printf ("mips-mips-riscos%ssvr4\\n", argv[1]); exit (0);
diff --git a/build-aux/config.sub b/build-aux/config.sub
index bbad4c45e5d..fb579478695 100755
--- a/build-aux/config.sub
+++ b/build-aux/config.sub
@@ -2,7 +2,7 @@
2# Configuration validation subroutine script. 2# Configuration validation subroutine script.
3# Copyright 1992-2017 Free Software Foundation, Inc. 3# Copyright 1992-2017 Free Software Foundation, Inc.
4 4
5timestamp='2017-11-01' 5timestamp='2017-11-04'
6 6
7# This file is free software; you can redistribute it and/or modify it 7# This file is free software; you can redistribute it and/or modify it
8# under the terms of the GNU General Public License as published by 8# under the terms of the GNU General Public License as published by
@@ -57,7 +57,7 @@ Usage: $0 [OPTION] CPU-MFR-OPSYS or ALIAS
57 57
58Canonicalize a configuration name. 58Canonicalize a configuration name.
59 59
60Operation modes: 60Options:
61 -h, --help print this help, then exit 61 -h, --help print this help, then exit
62 -t, --time-stamp print date of last modification, then exit 62 -t, --time-stamp print date of last modification, then exit
63 -v, --version print version number, then exit 63 -v, --version print version number, then exit
@@ -313,7 +313,6 @@ case $basic_machine in
313 | v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \ 313 | v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \
314 | visium \ 314 | visium \
315 | wasm32 \ 315 | wasm32 \
316 | we32k \
317 | x86 | xc16x | xstormy16 | xtensa \ 316 | x86 | xc16x | xstormy16 | xtensa \
318 | z8k | z80) 317 | z8k | z80)
319 basic_machine=$basic_machine-unknown 318 basic_machine=$basic_machine-unknown
diff --git a/configure.ac b/configure.ac
index 2dd21b77dac..29016d89ae2 100644
--- a/configure.ac
+++ b/configure.ac
@@ -5113,22 +5113,6 @@ else
5113fi 5113fi
5114AC_SUBST(LIBXMENU) 5114AC_SUBST(LIBXMENU)
5115 5115
5116AC_CACHE_CHECK([for struct alignment],
5117 [emacs_cv_struct_alignment],
5118 [AC_COMPILE_IFELSE(
5119 [AC_LANG_PROGRAM([[#include <stddef.h>
5120 struct __attribute__ ((aligned (8))) s { char c; };
5121 struct t { char c; struct s s; };
5122 char verify[offsetof (struct t, s) == 8 ? 1 : -1];
5123 ]])],
5124 [emacs_cv_struct_alignment=yes],
5125 [emacs_cv_struct_alignment=no])])
5126if test "$emacs_cv_struct_alignment" = yes; then
5127 AC_DEFINE([HAVE_STRUCT_ATTRIBUTE_ALIGNED], 1,
5128 [Define to 1 if 'struct __attribute__ ((aligned (N)))' aligns the
5129 structure to an N-byte boundary.])
5130fi
5131
5132if test "${GNU_MALLOC}" = "yes" ; then 5116if test "${GNU_MALLOC}" = "yes" ; then
5133 AC_DEFINE(GNU_MALLOC, 1, 5117 AC_DEFINE(GNU_MALLOC, 1,
5134 [Define to 1 if you want to use the GNU memory allocator.]) 5118 [Define to 1 if you want to use the GNU memory allocator.])
diff --git a/doc/lispref/internals.texi b/doc/lispref/internals.texi
index 663d0fd92b9..b0348e74d47 100644
--- a/doc/lispref/internals.texi
+++ b/doc/lispref/internals.texi
@@ -248,7 +248,7 @@ of 8k bytes, and small vectors are packed into blocks of 4k bytes).
248@cindex storage of vector-like Lisp objects 248@cindex storage of vector-like Lisp objects
249 Beyond the basic vector, a lot of objects like window, buffer, and 249 Beyond the basic vector, a lot of objects like window, buffer, and
250frame are managed as if they were vectors. The corresponding C data 250frame are managed as if they were vectors. The corresponding C data
251structures include the @code{struct vectorlike_header} field whose 251structures include the @code{union vectorlike_header} field whose
252@code{size} member contains the subtype enumerated by @code{enum pvec_type} 252@code{size} member contains the subtype enumerated by @code{enum pvec_type}
253and an information about how many @code{Lisp_Object} fields this structure 253and an information about how many @code{Lisp_Object} fields this structure
254contains and what the size of the rest data is. This information is 254contains and what the size of the rest data is. This information is
@@ -1085,7 +1085,7 @@ Some of the fields of @code{struct buffer} are:
1085 1085
1086@table @code 1086@table @code
1087@item header 1087@item header
1088A header of type @code{struct vectorlike_header} is common to all 1088A header of type @code{union vectorlike_header} is common to all
1089vectorlike objects. 1089vectorlike objects.
1090 1090
1091@item own_text 1091@item own_text
diff --git a/doc/misc/texinfo.tex b/doc/misc/texinfo.tex
index 9bd75b91e46..022c3f5b370 100644
--- a/doc/misc/texinfo.tex
+++ b/doc/misc/texinfo.tex
@@ -3,7 +3,7 @@
3% Load plain if necessary, i.e., if running under initex. 3% Load plain if necessary, i.e., if running under initex.
4\expandafter\ifx\csname fmtname\endcsname\relax\input plain\fi 4\expandafter\ifx\csname fmtname\endcsname\relax\input plain\fi
5% 5%
6\def\texinfoversion{2017-09-16.10} 6\def\texinfoversion{2017-09-11.18}
7% 7%
8% Copyright 1985, 1986, 1988, 1990, 1991, 1992, 1993, 1994, 1995, 8% Copyright 1985, 1986, 1988, 1990, 1991, 1992, 1993, 1994, 1995,
9% 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 9% 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
@@ -11425,9 +11425,11 @@ directory should work if nowhere else does.}
11425 % 11425 %
11426 \dimen0 = #1\relax 11426 \dimen0 = #1\relax
11427 \advance\dimen0 by \voffset 11427 \advance\dimen0 by \voffset
11428 \advance\dimen0 by 1in % reference point for DVI is 1 inch from top of page
11428 % 11429 %
11429 \dimen2 = \hsize 11430 \dimen2 = \hsize
11430 \advance\dimen2 by \normaloffset 11431 \advance\dimen2 by \normaloffset
11432 \advance\dimen2 by 1in % reference point is 1 inch from left edge of page
11431 % 11433 %
11432 \internalpagesizes{#1}{\hsize}% 11434 \internalpagesizes{#1}{\hsize}%
11433 {\voffset}{\normaloffset}% 11435 {\voffset}{\normaloffset}%
diff --git a/lib-src/make-docfile.c b/lib-src/make-docfile.c
index ff84df94a69..9e4755b63ac 100644
--- a/lib-src/make-docfile.c
+++ b/lib-src/make-docfile.c
@@ -667,9 +667,7 @@ close_emacs_globals (ptrdiff_t num_symbols)
667 "#ifndef DEFINE_SYMBOLS\n" 667 "#ifndef DEFINE_SYMBOLS\n"
668 "extern\n" 668 "extern\n"
669 "#endif\n" 669 "#endif\n"
670 "struct {\n" 670 "struct Lisp_Symbol lispsym[%td];\n"),
671 " struct GCALIGNED Lisp_Symbol s;\n"
672 "} lispsym[%td];\n"),
673 num_symbols); 671 num_symbols);
674} 672}
675 673
diff --git a/lib/faccessat.c b/lib/faccessat.c
index 6cf9c99df20..fa9235820dc 100644
--- a/lib/faccessat.c
+++ b/lib/faccessat.c
@@ -16,10 +16,31 @@
16 16
17/* written by Eric Blake */ 17/* written by Eric Blake */
18 18
19/* If the user's config.h happens to include <unistd.h>, let it include only
20 the system's <unistd.h> here, so that orig_faccessat doesn't recurse to
21 rpl_faccessat. */
22#define _GL_INCLUDING_UNISTD_H
19#include <config.h> 23#include <config.h>
20 24
21#include <unistd.h> 25#include <unistd.h>
26#include <errno.h>
22#include <fcntl.h> 27#include <fcntl.h>
28#include <string.h>
29#include <sys/stat.h>
30#undef _GL_INCLUDING_UNISTD_H
31
32#if HAVE_FACCESSAT
33static int
34orig_faccessat (int fd, char const *name, int mode, int flag)
35{
36 return faccessat (fd, name, mode, flag);
37}
38#endif
39
40/* Write "unistd.h" here, not <unistd.h>, otherwise OSF/1 5.1 DTK cc
41 eliminates this include because of the preliminary #include <unistd.h>
42 above. */
43#include "unistd.h"
23 44
24#ifndef HAVE_ACCESS 45#ifndef HAVE_ACCESS
25/* Mingw lacks access, but it also lacks real vs. effective ids, so 46/* Mingw lacks access, but it also lacks real vs. effective ids, so
@@ -28,6 +49,29 @@
28# define access euidaccess 49# define access euidaccess
29#endif 50#endif
30 51
52#if HAVE_FACCESSAT
53
54int
55rpl_faccessat (int fd, char const *file, int mode, int flag)
56{
57 int result = orig_faccessat (fd, file, mode, flag);
58
59 if (result == 0 && file[strlen (file) - 1] == '/')
60 {
61 struct stat st;
62 result = fstatat (fd, file, &st, 0);
63 if (result == 0 && !S_ISDIR (st.st_mode))
64 {
65 errno = ENOTDIR;
66 return -1;
67 }
68 }
69
70 return result;
71}
72
73#else /* !HAVE_FACCESSAT */
74
31/* Invoke access or euidaccess on file, FILE, using mode MODE, in the directory 75/* Invoke access or euidaccess on file, FILE, using mode MODE, in the directory
32 open on descriptor FD. If possible, do it without changing the 76 open on descriptor FD. If possible, do it without changing the
33 working directory. Otherwise, resort to using save_cwd/fchdir, then 77 working directory. Otherwise, resort to using save_cwd/fchdir, then
@@ -36,10 +80,12 @@
36 Note that this implementation only supports AT_EACCESS, although some 80 Note that this implementation only supports AT_EACCESS, although some
37 native versions also support AT_SYMLINK_NOFOLLOW. */ 81 native versions also support AT_SYMLINK_NOFOLLOW. */
38 82
39#define AT_FUNC_NAME faccessat 83# define AT_FUNC_NAME faccessat
40#define AT_FUNC_F1 euidaccess 84# define AT_FUNC_F1 euidaccess
41#define AT_FUNC_F2 access 85# define AT_FUNC_F2 access
42#define AT_FUNC_USE_F1_COND AT_EACCESS 86# define AT_FUNC_USE_F1_COND AT_EACCESS
43#define AT_FUNC_POST_FILE_PARAM_DECLS , int mode, int flag 87# define AT_FUNC_POST_FILE_PARAM_DECLS , int mode, int flag
44#define AT_FUNC_POST_FILE_ARGS , mode 88# define AT_FUNC_POST_FILE_ARGS , mode
45#include "at-func.c" 89# include "at-func.c"
90
91#endif
diff --git a/lib/fstatat.c b/lib/fstatat.c
index 67e48d95d71..294861f51b1 100644
--- a/lib/fstatat.c
+++ b/lib/fstatat.c
@@ -28,7 +28,7 @@
28#include <sys/stat.h> 28#include <sys/stat.h>
29#undef __need_system_sys_stat_h 29#undef __need_system_sys_stat_h
30 30
31#if HAVE_FSTATAT 31#if HAVE_FSTATAT && HAVE_WORKING_FSTATAT_ZERO_FLAG
32static int 32static int
33orig_fstatat (int fd, char const *filename, struct stat *buf, int flags) 33orig_fstatat (int fd, char const *filename, struct stat *buf, int flags)
34{ 34{
diff --git a/lib/gnulib.mk.in b/lib/gnulib.mk.in
index e9358a6855d..a7b33ba34e8 100644
--- a/lib/gnulib.mk.in
+++ b/lib/gnulib.mk.in
@@ -689,6 +689,7 @@ REPLACE_DIRFD = @REPLACE_DIRFD@
689REPLACE_DPRINTF = @REPLACE_DPRINTF@ 689REPLACE_DPRINTF = @REPLACE_DPRINTF@
690REPLACE_DUP = @REPLACE_DUP@ 690REPLACE_DUP = @REPLACE_DUP@
691REPLACE_DUP2 = @REPLACE_DUP2@ 691REPLACE_DUP2 = @REPLACE_DUP2@
692REPLACE_FACCESSAT = @REPLACE_FACCESSAT@
692REPLACE_FCHOWNAT = @REPLACE_FCHOWNAT@ 693REPLACE_FCHOWNAT = @REPLACE_FCHOWNAT@
693REPLACE_FCLOSE = @REPLACE_FCLOSE@ 694REPLACE_FCLOSE = @REPLACE_FCLOSE@
694REPLACE_FCNTL = @REPLACE_FCNTL@ 695REPLACE_FCNTL = @REPLACE_FCNTL@
@@ -2997,6 +2998,7 @@ unistd.h: unistd.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H
2997 -e 's|@''REPLACE_CLOSE''@|$(REPLACE_CLOSE)|g' \ 2998 -e 's|@''REPLACE_CLOSE''@|$(REPLACE_CLOSE)|g' \
2998 -e 's|@''REPLACE_DUP''@|$(REPLACE_DUP)|g' \ 2999 -e 's|@''REPLACE_DUP''@|$(REPLACE_DUP)|g' \
2999 -e 's|@''REPLACE_DUP2''@|$(REPLACE_DUP2)|g' \ 3000 -e 's|@''REPLACE_DUP2''@|$(REPLACE_DUP2)|g' \
3001 -e 's|@''REPLACE_FACCESSAT''@|$(REPLACE_FACCESSAT)|g' \
3000 -e 's|@''REPLACE_FCHOWNAT''@|$(REPLACE_FCHOWNAT)|g' \ 3002 -e 's|@''REPLACE_FCHOWNAT''@|$(REPLACE_FCHOWNAT)|g' \
3001 -e 's|@''REPLACE_FTRUNCATE''@|$(REPLACE_FTRUNCATE)|g' \ 3003 -e 's|@''REPLACE_FTRUNCATE''@|$(REPLACE_FTRUNCATE)|g' \
3002 -e 's|@''REPLACE_GETCWD''@|$(REPLACE_GETCWD)|g' \ 3004 -e 's|@''REPLACE_GETCWD''@|$(REPLACE_GETCWD)|g' \
diff --git a/lib/unistd.in.h b/lib/unistd.in.h
index ca8090a3526..91447835811 100644
--- a/lib/unistd.in.h
+++ b/lib/unistd.in.h
@@ -461,13 +461,25 @@ _GL_WARN_ON_USE (euidaccess, "euidaccess is unportable - "
461 461
462 462
463#if @GNULIB_FACCESSAT@ 463#if @GNULIB_FACCESSAT@
464# if !@HAVE_FACCESSAT@ 464# if @REPLACE_FACCESSAT@
465# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
466# undef faccessat
467# define faccessat rpl_faccessat
468# endif
469_GL_FUNCDECL_RPL (faccessat, int,
470 (int fd, char const *name, int mode, int flag)
471 _GL_ARG_NONNULL ((2)));
472_GL_CXXALIAS_RPL (faccessat, int,
473 (int fd, char const *name, int mode, int flag));
474# else
475# if !@HAVE_FACCESSAT@
465_GL_FUNCDECL_SYS (faccessat, int, 476_GL_FUNCDECL_SYS (faccessat, int,
466 (int fd, char const *file, int mode, int flag) 477 (int fd, char const *file, int mode, int flag)
467 _GL_ARG_NONNULL ((2))); 478 _GL_ARG_NONNULL ((2)));
468# endif 479# endif
469_GL_CXXALIAS_SYS (faccessat, int, 480_GL_CXXALIAS_SYS (faccessat, int,
470 (int fd, char const *file, int mode, int flag)); 481 (int fd, char const *file, int mode, int flag));
482# endif
471_GL_CXXALIASWARN (faccessat); 483_GL_CXXALIASWARN (faccessat);
472#elif defined GNULIB_POSIXCHECK 484#elif defined GNULIB_POSIXCHECK
473# undef faccessat 485# undef faccessat
diff --git a/lisp/files.el b/lisp/files.el
index e3a34af2dc3..ae90d19f2f2 100644
--- a/lisp/files.el
+++ b/lisp/files.el
@@ -1855,7 +1855,13 @@ The value includes abbreviation according to `directory-abbrev-alist'.")
1855 "Return a version of FILENAME shortened using `directory-abbrev-alist'. 1855 "Return a version of FILENAME shortened using `directory-abbrev-alist'.
1856This also substitutes \"~\" for the user's home directory (unless the 1856This also substitutes \"~\" for the user's home directory (unless the
1857home directory is a root directory) and removes automounter prefixes 1857home directory is a root directory) and removes automounter prefixes
1858\(see the variable `automount-dir-prefix')." 1858\(see the variable `automount-dir-prefix').
1859
1860When this function is first called, it caches the user's home
1861directory as a regexp in `abbreviated-home-dir', and reuses it
1862afterwards. Lisp programs that temporarily set the home directory
1863to a different value should let-bind `abbreviated-home-dir' for
1864the modified home directory to take effect."
1859 ;; Get rid of the prefixes added by the automounter. 1865 ;; Get rid of the prefixes added by the automounter.
1860 (save-match-data 1866 (save-match-data
1861 (if (and automount-dir-prefix 1867 (if (and automount-dir-prefix
diff --git a/lisp/find-dired.el b/lisp/find-dired.el
index 2d2540b1330..3b0613b2806 100644
--- a/lisp/find-dired.el
+++ b/lisp/find-dired.el
@@ -255,14 +255,14 @@ See `find-name-arg' to customize the arguments."
255(defalias 'lookfor-dired 'find-grep-dired) 255(defalias 'lookfor-dired 'find-grep-dired)
256;;;###autoload 256;;;###autoload
257(defun find-grep-dired (dir regexp) 257(defun find-grep-dired (dir regexp)
258 "Find files in DIR matching a regexp REGEXP and start Dired on output. 258 "Find files in DIR that contain matches for REGEXP and start Dired on output.
259The command run (after changing into DIR) is 259The command run (after changing into DIR) is
260 260
261 find . \\( -type f -exec `grep-program' `find-grep-options' \\ 261 find . \\( -type f -exec `grep-program' `find-grep-options' \\
262 -e REGEXP {} \\; \\) -ls 262 -e REGEXP {} \\; \\) -ls
263 263
264where the car of the variable `find-ls-option' specifies what to 264where the first string in the value of the variable `find-ls-option'
265use in place of \"-ls\" as the final argument." 265specifies what to use in place of \"-ls\" as the final argument."
266 ;; Doc used to say "Thus ARG can also contain additional grep options." 266 ;; Doc used to say "Thus ARG can also contain additional grep options."
267 ;; i) Presumably ARG == REGEXP? 267 ;; i) Presumably ARG == REGEXP?
268 ;; ii) No it can't have options, since it gets shell-quoted. 268 ;; ii) No it can't have options, since it gets shell-quoted.
diff --git a/lisp/progmodes/cc-engine.el b/lisp/progmodes/cc-engine.el
index 8ec01e1810b..ab0204cb961 100644
--- a/lisp/progmodes/cc-engine.el
+++ b/lisp/progmodes/cc-engine.el
@@ -10740,10 +10740,8 @@ comment at the start of cc-engine.el for more info."
10740 (t ; We're at (1+ here). 10740 (t ; We're at (1+ here).
10741 (cond 10741 (cond
10742 ((progn (c-forward-syntactic-ws) 10742 ((progn (c-forward-syntactic-ws)
10743 (eq (point) (1- there))) 10743 (eq (point) (1- there))))
10744 t) 10744 ((c-syntactic-re-search-forward c-keywords-regexp there t))
10745 ((c-syntactic-re-search-forward c-keywords-regexp there t)
10746 t)
10747 ((c-syntactic-re-search-forward "{" there t t) 10745 ((c-syntactic-re-search-forward "{" there t t)
10748 (backward-char) 10746 (backward-char)
10749 (c-looking-at-statement-block)) 10747 (c-looking-at-statement-block))
@@ -10752,8 +10750,12 @@ comment at the start of cc-engine.el for more info."
10752 (cond 10750 (cond
10753 ((c-syntactic-re-search-forward "[;,]" nil t t) 10751 ((c-syntactic-re-search-forward "[;,]" nil t t)
10754 (eq (char-before) ?\;)) 10752 (eq (char-before) ?\;))
10755 ((c-syntactic-re-search-forward c-keywords-regexp nil t t) 10753 ((progn (c-forward-syntactic-ws)
10756 t) 10754 (eobp)))
10755 ((c-syntactic-re-search-forward c-keywords-regexp nil t t))
10756 ((c-syntactic-re-search-forward "{" nil t t)
10757 (backward-char)
10758 (c-looking-at-statement-block))
10757 (t nil))) 10759 (t nil)))
10758 (goto-char here)))) 10760 (goto-char here))))
10759 10761
diff --git a/lisp/progmodes/flymake.el b/lisp/progmodes/flymake.el
index 1930f4fc832..aac167357ec 100644
--- a/lisp/progmodes/flymake.el
+++ b/lisp/progmodes/flymake.el
@@ -318,7 +318,11 @@ region is invalid."
318 (goto-char (point-min)) 318 (goto-char (point-min))
319 (forward-line (1- line)) 319 (forward-line (1- line))
320 (cl-flet ((fallback-bol 320 (cl-flet ((fallback-bol
321 () (progn (back-to-indentation) (point))) 321 ()
322 (back-to-indentation)
323 (if (eobp)
324 (line-beginning-position 0)
325 (point)))
322 (fallback-eol 326 (fallback-eol
323 (beg) 327 (beg)
324 (progn 328 (progn
@@ -335,11 +339,11 @@ region is invalid."
335 (not (= sexp-end beg)) 339 (not (= sexp-end beg))
336 sexp-end) 340 sexp-end)
337 (and (< (goto-char (1+ beg)) (point-max)) 341 (and (< (goto-char (1+ beg)) (point-max))
338 (point)))) 342 (point)))))
339 (safe-end (or end 343 (if end
340 (fallback-eol beg)))) 344 (cons beg end)
341 (cons (if end beg (fallback-bol)) 345 (cons (setq beg (fallback-bol))
342 safe-end)) 346 (fallback-eol beg))))
343 (let* ((beg (fallback-bol)) 347 (let* ((beg (fallback-bol))
344 (end (fallback-eol beg))) 348 (end (fallback-eol beg)))
345 (cons beg end))))))) 349 (cons beg end)))))))
diff --git a/lisp/textmodes/mhtml-mode.el b/lisp/textmodes/mhtml-mode.el
index 58541677509..8df251276b5 100644
--- a/lisp/textmodes/mhtml-mode.el
+++ b/lisp/textmodes/mhtml-mode.el
@@ -237,8 +237,8 @@ smallest."
237 (cons 'jit-lock-bounds (cons new-beg new-end))))) 237 (cons 'jit-lock-bounds (cons new-beg new-end)))))
238 238
239(defvar-local mhtml--last-submode nil 239(defvar-local mhtml--last-submode nil
240 "Record the last visited submode, so the cursor-sensor function 240 "Record the last visited submode.
241can function properly.") 241This is used by `mhtml--pre-command'.")
242 242
243(defvar-local mhtml--stashed-crucial-variables nil 243(defvar-local mhtml--stashed-crucial-variables nil
244 "Alist of stashed values of the crucial variables.") 244 "Alist of stashed values of the crucial variables.")
@@ -359,7 +359,6 @@ can function properly.")
359Code inside a <script> element is indented using the rules from 359Code inside a <script> element is indented using the rules from
360`js-mode'; and code inside a <style> element is indented using 360`js-mode'; and code inside a <style> element is indented using
361the rules from `css-mode'." 361the rules from `css-mode'."
362 (cursor-sensor-mode)
363 (setq-local indent-line-function #'mhtml-indent-line) 362 (setq-local indent-line-function #'mhtml-indent-line)
364 (setq-local parse-sexp-lookup-properties t) 363 (setq-local parse-sexp-lookup-properties t)
365 (setq-local syntax-propertize-function #'mhtml-syntax-propertize) 364 (setq-local syntax-propertize-function #'mhtml-syntax-propertize)
diff --git a/m4/faccessat.m4 b/m4/faccessat.m4
index 837ae5407c9..f4cb49d166c 100644
--- a/m4/faccessat.m4
+++ b/m4/faccessat.m4
@@ -1,4 +1,4 @@
1# serial 6 1# serial 7
2# See if we need to provide faccessat replacement. 2# See if we need to provide faccessat replacement.
3 3
4dnl Copyright (C) 2009-2017 Free Software Foundation, Inc. 4dnl Copyright (C) 2009-2017 Free Software Foundation, Inc.
@@ -18,10 +18,12 @@ AC_DEFUN([gl_FUNC_FACCESSAT],
18 AC_CHECK_FUNCS_ONCE([faccessat]) 18 AC_CHECK_FUNCS_ONCE([faccessat])
19 if test $ac_cv_func_faccessat = no; then 19 if test $ac_cv_func_faccessat = no; then
20 HAVE_FACCESSAT=0 20 HAVE_FACCESSAT=0
21 elif test "$gl_cv_func_lstat_dereferences_slashed_symlink" != yes; then
22 REPLACE_FACCESSAT=1
21 fi 23 fi
22]) 24])
23 25
24# Prerequisites of lib/faccessat.m4. 26# Prerequisites of lib/faccessat.c.
25AC_DEFUN([gl_PREREQ_FACCESSAT], 27AC_DEFUN([gl_PREREQ_FACCESSAT],
26[ 28[
27 AC_CHECK_FUNCS([access]) 29 AC_CHECK_FUNCS([access])
diff --git a/m4/gnulib-comp.m4 b/m4/gnulib-comp.m4
index cb255fcf6d9..61d39ebda2b 100644
--- a/m4/gnulib-comp.m4
+++ b/m4/gnulib-comp.m4
@@ -223,7 +223,7 @@ AC_DEFUN([gl_INIT],
223 gl_STRING_MODULE_INDICATOR([explicit_bzero]) 223 gl_STRING_MODULE_INDICATOR([explicit_bzero])
224 AC_REQUIRE([gl_EXTERN_INLINE]) 224 AC_REQUIRE([gl_EXTERN_INLINE])
225 gl_FUNC_FACCESSAT 225 gl_FUNC_FACCESSAT
226 if test $HAVE_FACCESSAT = 0; then 226 if test $HAVE_FACCESSAT = 0 || test $REPLACE_FACCESSAT = 1; then
227 AC_LIBOBJ([faccessat]) 227 AC_LIBOBJ([faccessat])
228 gl_PREREQ_FACCESSAT 228 gl_PREREQ_FACCESSAT
229 fi 229 fi
@@ -599,16 +599,16 @@ AC_DEFUN([gl_INIT],
599 gl_gnulib_enabled_682e609604ccaac6be382e4ee3a4eaec=true 599 gl_gnulib_enabled_682e609604ccaac6be382e4ee3a4eaec=true
600 fi 600 fi
601 } 601 }
602 if test $HAVE_FACCESSAT = 0; then 602 if test $HAVE_FACCESSAT = 0 || test $REPLACE_FACCESSAT = 1; then
603 func_gl_gnulib_m4code_260941c0e5dc67ec9e87d1fb321c300b 603 func_gl_gnulib_m4code_260941c0e5dc67ec9e87d1fb321c300b
604 fi 604 fi
605 if test $HAVE_FACCESSAT = 0; then 605 if test $HAVE_FACCESSAT = 0 || test $REPLACE_FACCESSAT = 1; then
606 func_gl_gnulib_m4code_dosname 606 func_gl_gnulib_m4code_dosname
607 fi 607 fi
608 if test $HAVE_FACCESSAT = 0; then 608 if test $HAVE_FACCESSAT = 0 || test $REPLACE_FACCESSAT = 1; then
609 func_gl_gnulib_m4code_euidaccess 609 func_gl_gnulib_m4code_euidaccess
610 fi 610 fi
611 if test $HAVE_FACCESSAT = 0; then 611 if test $HAVE_FACCESSAT = 0 || test $REPLACE_FACCESSAT = 1; then
612 func_gl_gnulib_m4code_03e0aaad4cb89ca757653bd367a6ccb7 612 func_gl_gnulib_m4code_03e0aaad4cb89ca757653bd367a6ccb7
613 fi 613 fi
614 if test $HAVE_FCNTL = 0 || test $REPLACE_FCNTL = 1; then 614 if test $HAVE_FCNTL = 0 || test $REPLACE_FCNTL = 1; then
diff --git a/m4/unistd_h.m4 b/m4/unistd_h.m4
index cc44677d9eb..60e7ea4d049 100644
--- a/m4/unistd_h.m4
+++ b/m4/unistd_h.m4
@@ -1,4 +1,4 @@
1# unistd_h.m4 serial 70 1# unistd_h.m4 serial 71
2dnl Copyright (C) 2006-2017 Free Software Foundation, Inc. 2dnl Copyright (C) 2006-2017 Free Software Foundation, Inc.
3dnl This file is free software; the Free Software Foundation 3dnl This file is free software; the Free Software Foundation
4dnl gives unlimited permission to copy and/or distribute it, 4dnl gives unlimited permission to copy and/or distribute it,
@@ -159,6 +159,7 @@ AC_DEFUN([gl_UNISTD_H_DEFAULTS],
159 REPLACE_CLOSE=0; AC_SUBST([REPLACE_CLOSE]) 159 REPLACE_CLOSE=0; AC_SUBST([REPLACE_CLOSE])
160 REPLACE_DUP=0; AC_SUBST([REPLACE_DUP]) 160 REPLACE_DUP=0; AC_SUBST([REPLACE_DUP])
161 REPLACE_DUP2=0; AC_SUBST([REPLACE_DUP2]) 161 REPLACE_DUP2=0; AC_SUBST([REPLACE_DUP2])
162 REPLACE_FACCESSAT=0; AC_SUBST([REPLACE_FACCESSAT])
162 REPLACE_FCHOWNAT=0; AC_SUBST([REPLACE_FCHOWNAT]) 163 REPLACE_FCHOWNAT=0; AC_SUBST([REPLACE_FCHOWNAT])
163 REPLACE_FTRUNCATE=0; AC_SUBST([REPLACE_FTRUNCATE]) 164 REPLACE_FTRUNCATE=0; AC_SUBST([REPLACE_FTRUNCATE])
164 REPLACE_GETCWD=0; AC_SUBST([REPLACE_GETCWD]) 165 REPLACE_GETCWD=0; AC_SUBST([REPLACE_GETCWD])
diff --git a/oldXMenu/Activate.c b/oldXMenu/Activate.c
index c27005fd9e3..638a20875ae 100644
--- a/oldXMenu/Activate.c
+++ b/oldXMenu/Activate.c
@@ -571,6 +571,7 @@ XMenuActivate(
571 event.xbutton.window 571 event.xbutton.window
572 ); 572 );
573 if (event_xmp != NULL) continue; 573 if (event_xmp != NULL) continue;
574 FALLTHROUGH;
574 default: 575 default:
575 /* 576 /*
576 * This is a foreign event. 577 * This is a foreign event.
diff --git a/src/alloc.c b/src/alloc.c
index ae892e49d7d..15a3d34d40f 100644
--- a/src/alloc.c
+++ b/src/alloc.c
@@ -211,9 +211,9 @@ alloc_unexec_post (void)
211/* Mark, unmark, query mark bit of a Lisp string. S must be a pointer 211/* Mark, unmark, query mark bit of a Lisp string. S must be a pointer
212 to a struct Lisp_String. */ 212 to a struct Lisp_String. */
213 213
214#define MARK_STRING(S) ((S)->size |= ARRAY_MARK_FLAG) 214#define MARK_STRING(S) ((S)->u.s.size |= ARRAY_MARK_FLAG)
215#define UNMARK_STRING(S) ((S)->size &= ~ARRAY_MARK_FLAG) 215#define UNMARK_STRING(S) ((S)->u.s.size &= ~ARRAY_MARK_FLAG)
216#define STRING_MARKED_P(S) (((S)->size & ARRAY_MARK_FLAG) != 0) 216#define STRING_MARKED_P(S) (((S)->u.s.size & ARRAY_MARK_FLAG) != 0)
217 217
218#define VECTOR_MARK(V) ((V)->header.size |= ARRAY_MARK_FLAG) 218#define VECTOR_MARK(V) ((V)->header.size |= ARRAY_MARK_FLAG)
219#define VECTOR_UNMARK(V) ((V)->header.size &= ~ARRAY_MARK_FLAG) 219#define VECTOR_UNMARK(V) ((V)->header.size &= ~ARRAY_MARK_FLAG)
@@ -1730,14 +1730,14 @@ static EMACS_INT total_string_bytes;
1730 string_free_list, return a pointer to its successor in the 1730 string_free_list, return a pointer to its successor in the
1731 free-list. */ 1731 free-list. */
1732 1732
1733#define NEXT_FREE_LISP_STRING(S) (*(struct Lisp_String **) (S)) 1733#define NEXT_FREE_LISP_STRING(S) ((S)->u.next)
1734 1734
1735/* Return a pointer to the sdata structure belonging to Lisp string S. 1735/* Return a pointer to the sdata structure belonging to Lisp string S.
1736 S must be live, i.e. S->data must not be null. S->data is actually 1736 S must be live, i.e. S->data must not be null. S->data is actually
1737 a pointer to the `u.data' member of its sdata structure; the 1737 a pointer to the `u.data' member of its sdata structure; the
1738 structure starts at a constant offset in front of that. */ 1738 structure starts at a constant offset in front of that. */
1739 1739
1740#define SDATA_OF_STRING(S) ((sdata *) ((S)->data - SDATA_DATA_OFFSET)) 1740#define SDATA_OF_STRING(S) ((sdata *) ((S)->u.s.data - SDATA_DATA_OFFSET))
1741 1741
1742 1742
1743#ifdef GC_CHECK_STRING_OVERRUN 1743#ifdef GC_CHECK_STRING_OVERRUN
@@ -1818,9 +1818,10 @@ ptrdiff_t
1818string_bytes (struct Lisp_String *s) 1818string_bytes (struct Lisp_String *s)
1819{ 1819{
1820 ptrdiff_t nbytes = 1820 ptrdiff_t nbytes =
1821 (s->size_byte < 0 ? s->size & ~ARRAY_MARK_FLAG : s->size_byte); 1821 (s->u.s.size_byte < 0 ? s->u.s.size & ~ARRAY_MARK_FLAG : s->u.s.size_byte);
1822 1822
1823 if (!PURE_P (s) && s->data && nbytes != SDATA_NBYTES (SDATA_OF_STRING (s))) 1823 if (!PURE_P (s) && s->u.s.data
1824 && nbytes != SDATA_NBYTES (SDATA_OF_STRING (s)))
1824 emacs_abort (); 1825 emacs_abort ();
1825 return nbytes; 1826 return nbytes;
1826} 1827}
@@ -1926,7 +1927,7 @@ allocate_string (void)
1926 { 1927 {
1927 s = b->strings + i; 1928 s = b->strings + i;
1928 /* Every string on a free list should have NULL data pointer. */ 1929 /* Every string on a free list should have NULL data pointer. */
1929 s->data = NULL; 1930 s->u.s.data = NULL;
1930 NEXT_FREE_LISP_STRING (s) = string_free_list; 1931 NEXT_FREE_LISP_STRING (s) = string_free_list;
1931 string_free_list = s; 1932 string_free_list = s;
1932 } 1933 }
@@ -1965,10 +1966,10 @@ allocate_string (void)
1965 1966
1966 1967
1967/* Set up Lisp_String S for holding NCHARS characters, NBYTES bytes, 1968/* Set up Lisp_String S for holding NCHARS characters, NBYTES bytes,
1968 plus a NUL byte at the end. Allocate an sdata structure for S, and 1969 plus a NUL byte at the end. Allocate an sdata structure DATA for
1969 set S->data to its `u.data' member. Store a NUL byte at the end of 1970 S, and set S->u.s.data to SDATA->u.data. Store a NUL byte at the
1970 S->data. Set S->size to NCHARS and S->size_byte to NBYTES. Free 1971 end of S->u.s.data. Set S->u.s.size to NCHARS and S->u.s.size_byte
1971 S->data if it was initially non-null. */ 1972 to NBYTES. Free S->u.s.data if it was initially non-null. */
1972 1973
1973void 1974void
1974allocate_string_data (struct Lisp_String *s, 1975allocate_string_data (struct Lisp_String *s,
@@ -1984,7 +1985,7 @@ allocate_string_data (struct Lisp_String *s,
1984 /* Determine the number of bytes needed to store NBYTES bytes 1985 /* Determine the number of bytes needed to store NBYTES bytes
1985 of string data. */ 1986 of string data. */
1986 needed = SDATA_SIZE (nbytes); 1987 needed = SDATA_SIZE (nbytes);
1987 if (s->data) 1988 if (s->u.s.data)
1988 { 1989 {
1989 old_data = SDATA_OF_STRING (s); 1990 old_data = SDATA_OF_STRING (s);
1990 old_nbytes = STRING_BYTES (s); 1991 old_nbytes = STRING_BYTES (s);
@@ -2043,13 +2044,13 @@ allocate_string_data (struct Lisp_String *s,
2043 2044
2044 MALLOC_UNBLOCK_INPUT; 2045 MALLOC_UNBLOCK_INPUT;
2045 2046
2046 s->data = SDATA_DATA (data); 2047 s->u.s.data = SDATA_DATA (data);
2047#ifdef GC_CHECK_STRING_BYTES 2048#ifdef GC_CHECK_STRING_BYTES
2048 SDATA_NBYTES (data) = nbytes; 2049 SDATA_NBYTES (data) = nbytes;
2049#endif 2050#endif
2050 s->size = nchars; 2051 s->u.s.size = nchars;
2051 s->size_byte = nbytes; 2052 s->u.s.size_byte = nbytes;
2052 s->data[nbytes] = '\0'; 2053 s->u.s.data[nbytes] = '\0';
2053#ifdef GC_CHECK_STRING_OVERRUN 2054#ifdef GC_CHECK_STRING_OVERRUN
2054 memcpy ((char *) data + needed, string_overrun_cookie, 2055 memcpy ((char *) data + needed, string_overrun_cookie,
2055 GC_STRING_OVERRUN_COOKIE_SIZE); 2056 GC_STRING_OVERRUN_COOKIE_SIZE);
@@ -2093,7 +2094,7 @@ sweep_strings (void)
2093 { 2094 {
2094 struct Lisp_String *s = b->strings + i; 2095 struct Lisp_String *s = b->strings + i;
2095 2096
2096 if (s->data) 2097 if (s->u.s.data)
2097 { 2098 {
2098 /* String was not on free-list before. */ 2099 /* String was not on free-list before. */
2099 if (STRING_MARKED_P (s)) 2100 if (STRING_MARKED_P (s))
@@ -2102,7 +2103,7 @@ sweep_strings (void)
2102 UNMARK_STRING (s); 2103 UNMARK_STRING (s);
2103 2104
2104 /* Do not use string_(set|get)_intervals here. */ 2105 /* Do not use string_(set|get)_intervals here. */
2105 s->intervals = balance_intervals (s->intervals); 2106 s->u.s.intervals = balance_intervals (s->u.s.intervals);
2106 2107
2107 ++total_strings; 2108 ++total_strings;
2108 total_string_bytes += STRING_BYTES (s); 2109 total_string_bytes += STRING_BYTES (s);
@@ -2125,7 +2126,7 @@ sweep_strings (void)
2125 2126
2126 /* Reset the strings's `data' member so that we 2127 /* Reset the strings's `data' member so that we
2127 know it's free. */ 2128 know it's free. */
2128 s->data = NULL; 2129 s->u.s.data = NULL;
2129 2130
2130 /* Put the string on the free-list. */ 2131 /* Put the string on the free-list. */
2131 NEXT_FREE_LISP_STRING (s) = string_free_list; 2132 NEXT_FREE_LISP_STRING (s) = string_free_list;
@@ -2264,7 +2265,7 @@ compact_small_strings (void)
2264 { 2265 {
2265 eassert (tb != b || to < from); 2266 eassert (tb != b || to < from);
2266 memmove (to, from, nbytes + GC_STRING_EXTRA); 2267 memmove (to, from, nbytes + GC_STRING_EXTRA);
2267 to->string->data = SDATA_DATA (to); 2268 to->string->u.s.data = SDATA_DATA (to);
2268 } 2269 }
2269 2270
2270 /* Advance past the sdata we copied to. */ 2271 /* Advance past the sdata we copied to. */
@@ -2546,7 +2547,7 @@ make_uninit_multibyte_string (EMACS_INT nchars, EMACS_INT nbytes)
2546 return empty_multibyte_string; 2547 return empty_multibyte_string;
2547 2548
2548 s = allocate_string (); 2549 s = allocate_string ();
2549 s->intervals = NULL; 2550 s->u.s.intervals = NULL;
2550 allocate_string_data (s, nchars, nbytes); 2551 allocate_string_data (s, nchars, nbytes);
2551 XSETSTRING (string, s); 2552 XSETSTRING (string, s);
2552 string_chars_consed += nbytes; 2553 string_chars_consed += nbytes;
@@ -2731,8 +2732,8 @@ static struct Lisp_Cons *cons_free_list;
2731void 2732void
2732free_cons (struct Lisp_Cons *ptr) 2733free_cons (struct Lisp_Cons *ptr)
2733{ 2734{
2734 ptr->u.chain = cons_free_list; 2735 ptr->u.s.u.chain = cons_free_list;
2735 ptr->car = Vdead; 2736 ptr->u.s.car = Vdead;
2736 cons_free_list = ptr; 2737 cons_free_list = ptr;
2737 consing_since_gc -= sizeof *ptr; 2738 consing_since_gc -= sizeof *ptr;
2738 total_free_conses++; 2739 total_free_conses++;
@@ -2751,7 +2752,7 @@ DEFUN ("cons", Fcons, Scons, 2, 2, 0,
2751 /* We use the cdr for chaining the free list 2752 /* We use the cdr for chaining the free list
2752 so that we won't use the same field that has the mark bit. */ 2753 so that we won't use the same field that has the mark bit. */
2753 XSETCONS (val, cons_free_list); 2754 XSETCONS (val, cons_free_list);
2754 cons_free_list = cons_free_list->u.chain; 2755 cons_free_list = cons_free_list->u.s.u.chain;
2755 } 2756 }
2756 else 2757 else
2757 { 2758 {
@@ -2788,7 +2789,7 @@ check_cons_list (void)
2788 struct Lisp_Cons *tail = cons_free_list; 2789 struct Lisp_Cons *tail = cons_free_list;
2789 2790
2790 while (tail) 2791 while (tail)
2791 tail = tail->u.chain; 2792 tail = tail->u.s.u.chain;
2792} 2793}
2793#endif 2794#endif
2794 2795
@@ -2923,19 +2924,16 @@ set_next_vector (struct Lisp_Vector *v, struct Lisp_Vector *p)
2923 2924
2924#define VECTOR_BLOCK_SIZE 4096 2925#define VECTOR_BLOCK_SIZE 4096
2925 2926
2926enum 2927/* Alignment of struct Lisp_Vector objects. Because pseudovectors
2927 { 2928 can contain any C type, align at least as strictly as
2928 /* Alignment of struct Lisp_Vector objects. Because pseudovectors 2929 max_align_t. On x86 and x86-64 this can waste up to 8 bytes
2929 can contain any C type, align at least as strictly as 2930 for typical vectors, since alignof (max_align_t) is 16 but
2930 max_align_t. On x86 and x86-64 this can waste up to 8 bytes 2931 typical vectors need only an alignment of 8. However, it is
2931 for typical vectors, since alignof (max_align_t) is 16 but 2932 not worth the hassle to avoid wasting those bytes. */
2932 typical vectors need only an alignment of 8. However, it is 2933enum {vector_alignment = COMMON_MULTIPLE (alignof (max_align_t), GCALIGNMENT)};
2933 not worth the hassle to avoid wasting those bytes. */ 2934
2934 vector_alignment = COMMON_MULTIPLE (alignof (max_align_t), GCALIGNMENT), 2935/* Vector size requests are a multiple of this. */
2935 2936enum { roundup_size = COMMON_MULTIPLE (vector_alignment, word_size) };
2936 /* Vector size requests are a multiple of this. */
2937 roundup_size = COMMON_MULTIPLE (vector_alignment, word_size)
2938 };
2939 2937
2940/* Verify assumptions described above. */ 2938/* Verify assumptions described above. */
2941verify (VECTOR_BLOCK_SIZE % roundup_size == 0); 2939verify (VECTOR_BLOCK_SIZE % roundup_size == 0);
@@ -3545,27 +3543,17 @@ usage: (make-byte-code ARGLIST BYTE-CODE CONSTANTS DEPTH &optional DOCSTRING INT
3545 Symbol Allocation 3543 Symbol Allocation
3546 ***********************************************************************/ 3544 ***********************************************************************/
3547 3545
3548/* Like struct Lisp_Symbol, but padded so that the size is a multiple
3549 of the required alignment. */
3550
3551union aligned_Lisp_Symbol
3552{
3553 struct Lisp_Symbol s;
3554 unsigned char c[(sizeof (struct Lisp_Symbol) + GCALIGNMENT - 1)
3555 & -GCALIGNMENT];
3556};
3557
3558/* Each symbol_block is just under 1020 bytes long, since malloc 3546/* Each symbol_block is just under 1020 bytes long, since malloc
3559 really allocates in units of powers of two and uses 4 bytes for its 3547 really allocates in units of powers of two and uses 4 bytes for its
3560 own overhead. */ 3548 own overhead. */
3561 3549
3562#define SYMBOL_BLOCK_SIZE \ 3550#define SYMBOL_BLOCK_SIZE \
3563 ((1020 - sizeof (struct symbol_block *)) / sizeof (union aligned_Lisp_Symbol)) 3551 ((1020 - sizeof (struct symbol_block *)) / sizeof (struct Lisp_Symbol))
3564 3552
3565struct symbol_block 3553struct symbol_block
3566{ 3554{
3567 /* Place `symbols' first, to preserve alignment. */ 3555 /* Place `symbols' first, to preserve alignment. */
3568 union aligned_Lisp_Symbol symbols[SYMBOL_BLOCK_SIZE]; 3556 struct Lisp_Symbol symbols[SYMBOL_BLOCK_SIZE];
3569 struct symbol_block *next; 3557 struct symbol_block *next;
3570}; 3558};
3571 3559
@@ -3589,7 +3577,7 @@ static struct Lisp_Symbol *symbol_free_list;
3589static void 3577static void
3590set_symbol_name (Lisp_Object sym, Lisp_Object name) 3578set_symbol_name (Lisp_Object sym, Lisp_Object name)
3591{ 3579{
3592 XSYMBOL (sym)->name = name; 3580 XSYMBOL (sym)->u.s.name = name;
3593} 3581}
3594 3582
3595void 3583void
@@ -3598,15 +3586,15 @@ init_symbol (Lisp_Object val, Lisp_Object name)
3598 struct Lisp_Symbol *p = XSYMBOL (val); 3586 struct Lisp_Symbol *p = XSYMBOL (val);
3599 set_symbol_name (val, name); 3587 set_symbol_name (val, name);
3600 set_symbol_plist (val, Qnil); 3588 set_symbol_plist (val, Qnil);
3601 p->redirect = SYMBOL_PLAINVAL; 3589 p->u.s.redirect = SYMBOL_PLAINVAL;
3602 SET_SYMBOL_VAL (p, Qunbound); 3590 SET_SYMBOL_VAL (p, Qunbound);
3603 set_symbol_function (val, Qnil); 3591 set_symbol_function (val, Qnil);
3604 set_symbol_next (val, NULL); 3592 set_symbol_next (val, NULL);
3605 p->gcmarkbit = false; 3593 p->u.s.gcmarkbit = false;
3606 p->interned = SYMBOL_UNINTERNED; 3594 p->u.s.interned = SYMBOL_UNINTERNED;
3607 p->trapped_write = SYMBOL_UNTRAPPED_WRITE; 3595 p->u.s.trapped_write = SYMBOL_UNTRAPPED_WRITE;
3608 p->declared_special = false; 3596 p->u.s.declared_special = false;
3609 p->pinned = false; 3597 p->u.s.pinned = false;
3610} 3598}
3611 3599
3612DEFUN ("make-symbol", Fmake_symbol, Smake_symbol, 1, 1, 0, 3600DEFUN ("make-symbol", Fmake_symbol, Smake_symbol, 1, 1, 0,
@@ -3623,7 +3611,7 @@ Its value is void, and its function definition and property list are nil. */)
3623 if (symbol_free_list) 3611 if (symbol_free_list)
3624 { 3612 {
3625 XSETSYMBOL (val, symbol_free_list); 3613 XSETSYMBOL (val, symbol_free_list);
3626 symbol_free_list = symbol_free_list->next; 3614 symbol_free_list = symbol_free_list->u.s.next;
3627 } 3615 }
3628 else 3616 else
3629 { 3617 {
@@ -3636,7 +3624,7 @@ Its value is void, and its function definition and property list are nil. */)
3636 symbol_block_index = 0; 3624 symbol_block_index = 0;
3637 total_free_symbols += SYMBOL_BLOCK_SIZE; 3625 total_free_symbols += SYMBOL_BLOCK_SIZE;
3638 } 3626 }
3639 XSETSYMBOL (val, &symbol_block->symbols[symbol_block_index].s); 3627 XSETSYMBOL (val, &symbol_block->symbols[symbol_block_index]);
3640 symbol_block_index++; 3628 symbol_block_index++;
3641 } 3629 }
3642 3630
@@ -4589,7 +4577,7 @@ live_string_holding (struct mem_node *m, void *p)
4589 if (0 <= offset && offset < STRING_BLOCK_SIZE * sizeof b->strings[0]) 4577 if (0 <= offset && offset < STRING_BLOCK_SIZE * sizeof b->strings[0])
4590 { 4578 {
4591 struct Lisp_String *s = p = cp -= offset % sizeof b->strings[0]; 4579 struct Lisp_String *s = p = cp -= offset % sizeof b->strings[0];
4592 if (s->data) 4580 if (s->u.s.data)
4593 return make_lisp_ptr (s, Lisp_String); 4581 return make_lisp_ptr (s, Lisp_String);
4594 } 4582 }
4595 } 4583 }
@@ -4623,7 +4611,7 @@ live_cons_holding (struct mem_node *m, void *p)
4623 || offset / sizeof b->conses[0] < cons_block_index)) 4611 || offset / sizeof b->conses[0] < cons_block_index))
4624 { 4612 {
4625 struct Lisp_Cons *s = p = cp -= offset % sizeof b->conses[0]; 4613 struct Lisp_Cons *s = p = cp -= offset % sizeof b->conses[0];
4626 if (!EQ (s->car, Vdead)) 4614 if (!EQ (s->u.s.car, Vdead))
4627 return make_lisp_ptr (s, Lisp_Cons); 4615 return make_lisp_ptr (s, Lisp_Cons);
4628 } 4616 }
4629 } 4617 }
@@ -4658,7 +4646,7 @@ live_symbol_holding (struct mem_node *m, void *p)
4658 || offset / sizeof b->symbols[0] < symbol_block_index)) 4646 || offset / sizeof b->symbols[0] < symbol_block_index))
4659 { 4647 {
4660 struct Lisp_Symbol *s = p = cp -= offset % sizeof b->symbols[0]; 4648 struct Lisp_Symbol *s = p = cp -= offset % sizeof b->symbols[0];
4661 if (!EQ (s->function, Vdead)) 4649 if (!EQ (s->u.s.function, Vdead))
4662 return make_lisp_symbol (s); 4650 return make_lisp_symbol (s);
4663 } 4651 }
4664 } 4652 }
@@ -4986,7 +4974,7 @@ mark_memory (void *start, void *end)
4986 Lisp_Object obj = build_string ("test"); 4974 Lisp_Object obj = build_string ("test");
4987 struct Lisp_String *s = XSTRING (obj); 4975 struct Lisp_String *s = XSTRING (obj);
4988 Fgarbage_collect (); 4976 Fgarbage_collect ();
4989 fprintf (stderr, "test '%s'\n", s->data); 4977 fprintf (stderr, "test '%s'\n", s->u.s.data);
4990 return Qnil; 4978 return Qnil;
4991 } 4979 }
4992 4980
@@ -5486,16 +5474,16 @@ make_pure_string (const char *data,
5486{ 5474{
5487 Lisp_Object string; 5475 Lisp_Object string;
5488 struct Lisp_String *s = pure_alloc (sizeof *s, Lisp_String); 5476 struct Lisp_String *s = pure_alloc (sizeof *s, Lisp_String);
5489 s->data = (unsigned char *) find_string_data_in_pure (data, nbytes); 5477 s->u.s.data = (unsigned char *) find_string_data_in_pure (data, nbytes);
5490 if (s->data == NULL) 5478 if (s->u.s.data == NULL)
5491 { 5479 {
5492 s->data = pure_alloc (nbytes + 1, -1); 5480 s->u.s.data = pure_alloc (nbytes + 1, -1);
5493 memcpy (s->data, data, nbytes); 5481 memcpy (s->u.s.data, data, nbytes);
5494 s->data[nbytes] = '\0'; 5482 s->u.s.data[nbytes] = '\0';
5495 } 5483 }
5496 s->size = nchars; 5484 s->u.s.size = nchars;
5497 s->size_byte = multibyte ? nbytes : -1; 5485 s->u.s.size_byte = multibyte ? nbytes : -1;
5498 s->intervals = NULL; 5486 s->u.s.intervals = NULL;
5499 XSETSTRING (string, s); 5487 XSETSTRING (string, s);
5500 return string; 5488 return string;
5501} 5489}
@@ -5508,10 +5496,10 @@ make_pure_c_string (const char *data, ptrdiff_t nchars)
5508{ 5496{
5509 Lisp_Object string; 5497 Lisp_Object string;
5510 struct Lisp_String *s = pure_alloc (sizeof *s, Lisp_String); 5498 struct Lisp_String *s = pure_alloc (sizeof *s, Lisp_String);
5511 s->size = nchars; 5499 s->u.s.size = nchars;
5512 s->size_byte = -1; 5500 s->u.s.size_byte = -1;
5513 s->data = (unsigned char *) data; 5501 s->u.s.data = (unsigned char *) data;
5514 s->intervals = NULL; 5502 s->u.s.intervals = NULL;
5515 XSETSTRING (string, s); 5503 XSETSTRING (string, s);
5516 return string; 5504 return string;
5517} 5505}
@@ -5622,7 +5610,7 @@ purecopy (Lisp_Object obj)
5622 || SUBRP (obj)) 5610 || SUBRP (obj))
5623 return obj; /* Already pure. */ 5611 return obj; /* Already pure. */
5624 5612
5625 if (STRINGP (obj) && XSTRING (obj)->intervals) 5613 if (STRINGP (obj) && XSTRING (obj)->u.s.intervals)
5626 message_with_string ("Dropping text-properties while making string `%s' pure", 5614 message_with_string ("Dropping text-properties while making string `%s' pure",
5627 obj, true); 5615 obj, true);
5628 5616
@@ -5677,10 +5665,10 @@ purecopy (Lisp_Object obj)
5677 } 5665 }
5678 else if (SYMBOLP (obj)) 5666 else if (SYMBOLP (obj))
5679 { 5667 {
5680 if (!XSYMBOL (obj)->pinned && !c_symbol_p (XSYMBOL (obj))) 5668 if (!XSYMBOL (obj)->u.s.pinned && !c_symbol_p (XSYMBOL (obj)))
5681 { /* We can't purify them, but they appear in many pure objects. 5669 { /* We can't purify them, but they appear in many pure objects.
5682 Mark them as `pinned' so we know to mark them at every GC cycle. */ 5670 Mark them as `pinned' so we know to mark them at every GC cycle. */
5683 XSYMBOL (obj)->pinned = true; 5671 XSYMBOL (obj)->u.s.pinned = true;
5684 symbol_block_pinned = symbol_block; 5672 symbol_block_pinned = symbol_block;
5685 } 5673 }
5686 /* Don't hash-cons it. */ 5674 /* Don't hash-cons it. */
@@ -5893,10 +5881,10 @@ mark_pinned_symbols (void)
5893 5881
5894 for (sblk = symbol_block_pinned; sblk; sblk = sblk->next) 5882 for (sblk = symbol_block_pinned; sblk; sblk = sblk->next)
5895 { 5883 {
5896 union aligned_Lisp_Symbol *sym = sblk->symbols, *end = sym + lim; 5884 struct Lisp_Symbol *sym = sblk->symbols, *end = sym + lim;
5897 for (; sym < end; ++sym) 5885 for (; sym < end; ++sym)
5898 if (sym->s.pinned) 5886 if (sym->u.s.pinned)
5899 mark_object (make_lisp_symbol (&sym->s)); 5887 mark_object (make_lisp_symbol (sym));
5900 5888
5901 lim = SYMBOL_BLOCK_SIZE; 5889 lim = SYMBOL_BLOCK_SIZE;
5902 } 5890 }
@@ -6258,7 +6246,7 @@ mark_char_table (struct Lisp_Vector *ptr, enum pvec_type pvectype)
6258 { 6246 {
6259 Lisp_Object val = ptr->contents[i]; 6247 Lisp_Object val = ptr->contents[i];
6260 6248
6261 if (INTEGERP (val) || (SYMBOLP (val) && XSYMBOL (val)->gcmarkbit)) 6249 if (INTEGERP (val) || (SYMBOLP (val) && XSYMBOL (val)->u.s.gcmarkbit))
6262 continue; 6250 continue;
6263 if (SUB_CHAR_TABLE_P (val)) 6251 if (SUB_CHAR_TABLE_P (val))
6264 { 6252 {
@@ -6501,7 +6489,7 @@ mark_object (Lisp_Object arg)
6501 break; 6489 break;
6502 CHECK_ALLOCATED_AND_LIVE (live_string_p); 6490 CHECK_ALLOCATED_AND_LIVE (live_string_p);
6503 MARK_STRING (ptr); 6491 MARK_STRING (ptr);
6504 MARK_INTERVAL_TREE (ptr->intervals); 6492 MARK_INTERVAL_TREE (ptr->u.s.intervals);
6505#ifdef GC_CHECK_STRING_BYTES 6493#ifdef GC_CHECK_STRING_BYTES
6506 /* Check that the string size recorded in the string is the 6494 /* Check that the string size recorded in the string is the
6507 same as the one recorded in the sdata structure. */ 6495 same as the one recorded in the sdata structure. */
@@ -6642,17 +6630,17 @@ mark_object (Lisp_Object arg)
6642 6630
6643 case Lisp_Symbol: 6631 case Lisp_Symbol:
6644 { 6632 {
6645 register struct Lisp_Symbol *ptr = XSYMBOL (obj); 6633 struct Lisp_Symbol *ptr = XSYMBOL (obj);
6646 nextsym: 6634 nextsym:
6647 if (ptr->gcmarkbit) 6635 if (ptr->u.s.gcmarkbit)
6648 break; 6636 break;
6649 CHECK_ALLOCATED_AND_LIVE_SYMBOL (); 6637 CHECK_ALLOCATED_AND_LIVE_SYMBOL ();
6650 ptr->gcmarkbit = 1; 6638 ptr->u.s.gcmarkbit = 1;
6651 /* Attempt to catch bogus objects. */ 6639 /* Attempt to catch bogus objects. */
6652 eassert (valid_lisp_object_p (ptr->function)); 6640 eassert (valid_lisp_object_p (ptr->u.s.function));
6653 mark_object (ptr->function); 6641 mark_object (ptr->u.s.function);
6654 mark_object (ptr->plist); 6642 mark_object (ptr->u.s.plist);
6655 switch (ptr->redirect) 6643 switch (ptr->u.s.redirect)
6656 { 6644 {
6657 case SYMBOL_PLAINVAL: mark_object (SYMBOL_VAL (ptr)); break; 6645 case SYMBOL_PLAINVAL: mark_object (SYMBOL_VAL (ptr)); break;
6658 case SYMBOL_VARALIAS: 6646 case SYMBOL_VARALIAS:
@@ -6673,11 +6661,11 @@ mark_object (Lisp_Object arg)
6673 break; 6661 break;
6674 default: emacs_abort (); 6662 default: emacs_abort ();
6675 } 6663 }
6676 if (!PURE_P (XSTRING (ptr->name))) 6664 if (!PURE_P (XSTRING (ptr->u.s.name)))
6677 MARK_STRING (XSTRING (ptr->name)); 6665 MARK_STRING (XSTRING (ptr->u.s.name));
6678 MARK_INTERVAL_TREE (string_intervals (ptr->name)); 6666 MARK_INTERVAL_TREE (string_intervals (ptr->u.s.name));
6679 /* Inner loop to mark next symbol in this bucket, if any. */ 6667 /* Inner loop to mark next symbol in this bucket, if any. */
6680 po = ptr = ptr->next; 6668 po = ptr = ptr->u.s.next;
6681 if (ptr) 6669 if (ptr)
6682 goto nextsym; 6670 goto nextsym;
6683 } 6671 }
@@ -6731,14 +6719,14 @@ mark_object (Lisp_Object arg)
6731 CHECK_ALLOCATED_AND_LIVE (live_cons_p); 6719 CHECK_ALLOCATED_AND_LIVE (live_cons_p);
6732 CONS_MARK (ptr); 6720 CONS_MARK (ptr);
6733 /* If the cdr is nil, avoid recursion for the car. */ 6721 /* If the cdr is nil, avoid recursion for the car. */
6734 if (EQ (ptr->u.cdr, Qnil)) 6722 if (EQ (ptr->u.s.u.cdr, Qnil))
6735 { 6723 {
6736 obj = ptr->car; 6724 obj = ptr->u.s.car;
6737 cdr_count = 0; 6725 cdr_count = 0;
6738 goto loop; 6726 goto loop;
6739 } 6727 }
6740 mark_object (ptr->car); 6728 mark_object (ptr->u.s.car);
6741 obj = ptr->u.cdr; 6729 obj = ptr->u.s.u.cdr;
6742 cdr_count++; 6730 cdr_count++;
6743 if (cdr_count == mark_object_loop_halt) 6731 if (cdr_count == mark_object_loop_halt)
6744 emacs_abort (); 6732 emacs_abort ();
@@ -6799,7 +6787,7 @@ survives_gc_p (Lisp_Object obj)
6799 break; 6787 break;
6800 6788
6801 case Lisp_Symbol: 6789 case Lisp_Symbol:
6802 survives_p = XSYMBOL (obj)->gcmarkbit; 6790 survives_p = XSYMBOL (obj)->u.s.gcmarkbit;
6803 break; 6791 break;
6804 6792
6805 case Lisp_Misc: 6793 case Lisp_Misc:
@@ -6875,9 +6863,9 @@ sweep_conses (void)
6875 if (!CONS_MARKED_P (&cblk->conses[pos])) 6863 if (!CONS_MARKED_P (&cblk->conses[pos]))
6876 { 6864 {
6877 this_free++; 6865 this_free++;
6878 cblk->conses[pos].u.chain = cons_free_list; 6866 cblk->conses[pos].u.s.u.chain = cons_free_list;
6879 cons_free_list = &cblk->conses[pos]; 6867 cons_free_list = &cblk->conses[pos];
6880 cons_free_list->car = Vdead; 6868 cons_free_list->u.s.car = Vdead;
6881 } 6869 }
6882 else 6870 else
6883 { 6871 {
@@ -6896,7 +6884,7 @@ sweep_conses (void)
6896 { 6884 {
6897 *cprev = cblk->next; 6885 *cprev = cblk->next;
6898 /* Unhook from the free list. */ 6886 /* Unhook from the free list. */
6899 cons_free_list = cblk->conses[0].u.chain; 6887 cons_free_list = cblk->conses[0].u.s.u.chain;
6900 lisp_align_free (cblk); 6888 lisp_align_free (cblk);
6901 } 6889 }
6902 else 6890 else
@@ -7020,39 +7008,39 @@ sweep_symbols (void)
7020 symbol_free_list = NULL; 7008 symbol_free_list = NULL;
7021 7009
7022 for (int i = 0; i < ARRAYELTS (lispsym); i++) 7010 for (int i = 0; i < ARRAYELTS (lispsym); i++)
7023 lispsym[i].s.gcmarkbit = 0; 7011 lispsym[i].u.s.gcmarkbit = 0;
7024 7012
7025 for (sblk = symbol_block; sblk; sblk = *sprev) 7013 for (sblk = symbol_block; sblk; sblk = *sprev)
7026 { 7014 {
7027 int this_free = 0; 7015 int this_free = 0;
7028 union aligned_Lisp_Symbol *sym = sblk->symbols; 7016 struct Lisp_Symbol *sym = sblk->symbols;
7029 union aligned_Lisp_Symbol *end = sym + lim; 7017 struct Lisp_Symbol *end = sym + lim;
7030 7018
7031 for (; sym < end; ++sym) 7019 for (; sym < end; ++sym)
7032 { 7020 {
7033 if (!sym->s.gcmarkbit) 7021 if (!sym->u.s.gcmarkbit)
7034 { 7022 {
7035 if (sym->s.redirect == SYMBOL_LOCALIZED) 7023 if (sym->u.s.redirect == SYMBOL_LOCALIZED)
7036 { 7024 {
7037 xfree (SYMBOL_BLV (&sym->s)); 7025 xfree (SYMBOL_BLV (sym));
7038 /* At every GC we sweep all symbol_blocks and rebuild the 7026 /* At every GC we sweep all symbol_blocks and rebuild the
7039 symbol_free_list, so those symbols which stayed unused 7027 symbol_free_list, so those symbols which stayed unused
7040 between the two will be re-swept. 7028 between the two will be re-swept.
7041 So we have to make sure we don't re-free this blv next 7029 So we have to make sure we don't re-free this blv next
7042 time we sweep this symbol_block (bug#29066). */ 7030 time we sweep this symbol_block (bug#29066). */
7043 sym->s.redirect = SYMBOL_PLAINVAL; 7031 sym->u.s.redirect = SYMBOL_PLAINVAL;
7044 } 7032 }
7045 sym->s.next = symbol_free_list; 7033 sym->u.s.next = symbol_free_list;
7046 symbol_free_list = &sym->s; 7034 symbol_free_list = sym;
7047 symbol_free_list->function = Vdead; 7035 symbol_free_list->u.s.function = Vdead;
7048 ++this_free; 7036 ++this_free;
7049 } 7037 }
7050 else 7038 else
7051 { 7039 {
7052 ++num_used; 7040 ++num_used;
7053 sym->s.gcmarkbit = 0; 7041 sym->u.s.gcmarkbit = 0;
7054 /* Attempt to catch bogus objects. */ 7042 /* Attempt to catch bogus objects. */
7055 eassert (valid_lisp_object_p (sym->s.function)); 7043 eassert (valid_lisp_object_p (sym->u.s.function));
7056 } 7044 }
7057 } 7045 }
7058 7046
@@ -7064,7 +7052,7 @@ sweep_symbols (void)
7064 { 7052 {
7065 *sprev = sblk->next; 7053 *sprev = sblk->next;
7066 /* Unhook from the free list. */ 7054 /* Unhook from the free list. */
7067 symbol_free_list = sblk->symbols[0].s.next; 7055 symbol_free_list = sblk->symbols[0].u.s.next;
7068 lisp_free (sblk); 7056 lisp_free (sblk);
7069 } 7057 }
7070 else 7058 else
@@ -7291,10 +7279,10 @@ symbol_uses_obj (Lisp_Object symbol, Lisp_Object obj)
7291 struct Lisp_Symbol *sym = XSYMBOL (symbol); 7279 struct Lisp_Symbol *sym = XSYMBOL (symbol);
7292 Lisp_Object val = find_symbol_value (symbol); 7280 Lisp_Object val = find_symbol_value (symbol);
7293 return (EQ (val, obj) 7281 return (EQ (val, obj)
7294 || EQ (sym->function, obj) 7282 || EQ (sym->u.s.function, obj)
7295 || (!NILP (sym->function) 7283 || (!NILP (sym->u.s.function)
7296 && COMPILEDP (sym->function) 7284 && COMPILEDP (sym->u.s.function)
7297 && EQ (AREF (sym->function, COMPILED_BYTECODE), obj)) 7285 && EQ (AREF (sym->u.s.function, COMPILED_BYTECODE), obj))
7298 || (!NILP (val) 7286 || (!NILP (val)
7299 && COMPILEDP (val) 7287 && COMPILEDP (val)
7300 && EQ (AREF (val, COMPILED_BYTECODE), obj))); 7288 && EQ (AREF (val, COMPILED_BYTECODE), obj)));
@@ -7325,15 +7313,15 @@ which_symbols (Lisp_Object obj, EMACS_INT find_max)
7325 7313
7326 for (sblk = symbol_block; sblk; sblk = sblk->next) 7314 for (sblk = symbol_block; sblk; sblk = sblk->next)
7327 { 7315 {
7328 union aligned_Lisp_Symbol *aligned_sym = sblk->symbols; 7316 struct Lisp_Symbol *asym = sblk->symbols;
7329 int bn; 7317 int bn;
7330 7318
7331 for (bn = 0; bn < SYMBOL_BLOCK_SIZE; bn++, aligned_sym++) 7319 for (bn = 0; bn < SYMBOL_BLOCK_SIZE; bn++, asym++)
7332 { 7320 {
7333 if (sblk == symbol_block && bn >= symbol_block_index) 7321 if (sblk == symbol_block && bn >= symbol_block_index)
7334 break; 7322 break;
7335 7323
7336 Lisp_Object sym = make_lisp_symbol (&aligned_sym->s); 7324 Lisp_Object sym = make_lisp_symbol (asym);
7337 if (symbol_uses_obj (sym, obj)) 7325 if (symbol_uses_obj (sym, obj))
7338 { 7326 {
7339 found = Fcons (sym, found); 7327 found = Fcons (sym, found);
diff --git a/src/buffer.c b/src/buffer.c
index edeed55e8be..4ae5e811b07 100644
--- a/src/buffer.c
+++ b/src/buffer.c
@@ -61,7 +61,7 @@ struct buffer *all_buffers;
61 Setting the default value also goes through the alist of buffers 61 Setting the default value also goes through the alist of buffers
62 and stores into each buffer that does not say it has a local value. */ 62 and stores into each buffer that does not say it has a local value. */
63 63
64struct GCALIGNED buffer buffer_defaults; 64struct buffer buffer_defaults;
65 65
66/* This structure marks which slots in a buffer have corresponding 66/* This structure marks which slots in a buffer have corresponding
67 default values in buffer_defaults. 67 default values in buffer_defaults.
@@ -84,7 +84,7 @@ struct buffer buffer_local_flags;
84/* This structure holds the names of symbols whose values may be 84/* This structure holds the names of symbols whose values may be
85 buffer-local. It is indexed and accessed in the same way as the above. */ 85 buffer-local. It is indexed and accessed in the same way as the above. */
86 86
87struct GCALIGNED buffer buffer_local_symbols; 87struct buffer buffer_local_symbols;
88 88
89/* Return the symbol of the per-buffer variable at offset OFFSET in 89/* Return the symbol of the per-buffer variable at offset OFFSET in
90 the buffer structure. */ 90 the buffer structure. */
@@ -1021,7 +1021,8 @@ reset_buffer_local_variables (struct buffer *b, bool permanent_too)
1021 newlist = Fcons (elt, newlist); 1021 newlist = Fcons (elt, newlist);
1022 } 1022 }
1023 newlist = Fnreverse (newlist); 1023 newlist = Fnreverse (newlist);
1024 if (XSYMBOL (local_var)->trapped_write == SYMBOL_TRAPPED_WRITE) 1024 if (XSYMBOL (local_var)->u.s.trapped_write
1025 == SYMBOL_TRAPPED_WRITE)
1025 notify_variable_watchers (local_var, newlist, 1026 notify_variable_watchers (local_var, newlist,
1026 Qmakunbound, Fcurrent_buffer ()); 1027 Qmakunbound, Fcurrent_buffer ());
1027 XSETCDR (XCAR (tmp), newlist); 1028 XSETCDR (XCAR (tmp), newlist);
@@ -1034,7 +1035,7 @@ reset_buffer_local_variables (struct buffer *b, bool permanent_too)
1034 else 1035 else
1035 XSETCDR (last, XCDR (tmp)); 1036 XSETCDR (last, XCDR (tmp));
1036 1037
1037 if (XSYMBOL (local_var)->trapped_write == SYMBOL_TRAPPED_WRITE) 1038 if (XSYMBOL (local_var)->u.s.trapped_write == SYMBOL_TRAPPED_WRITE)
1038 notify_variable_watchers (local_var, Qnil, 1039 notify_variable_watchers (local_var, Qnil,
1039 Qmakunbound, Fcurrent_buffer ()); 1040 Qmakunbound, Fcurrent_buffer ());
1040 } 1041 }
@@ -1166,7 +1167,7 @@ buffer_local_value (Lisp_Object variable, Lisp_Object buffer)
1166 sym = XSYMBOL (variable); 1167 sym = XSYMBOL (variable);
1167 1168
1168 start: 1169 start:
1169 switch (sym->redirect) 1170 switch (sym->u.s.redirect)
1170 { 1171 {
1171 case SYMBOL_VARALIAS: sym = indirect_variable (sym); goto start; 1172 case SYMBOL_VARALIAS: sym = indirect_variable (sym); goto start;
1172 case SYMBOL_PLAINVAL: result = SYMBOL_VAL (sym); break; 1173 case SYMBOL_PLAINVAL: result = SYMBOL_VAL (sym); break;
@@ -2096,7 +2097,7 @@ void set_buffer_internal_2 (register struct buffer *b)
2096 { 2097 {
2097 Lisp_Object var = XCAR (XCAR (tail)); 2098 Lisp_Object var = XCAR (XCAR (tail));
2098 struct Lisp_Symbol *sym = XSYMBOL (var); 2099 struct Lisp_Symbol *sym = XSYMBOL (var);
2099 if (sym->redirect == SYMBOL_LOCALIZED /* Just to be sure. */ 2100 if (sym->u.s.redirect == SYMBOL_LOCALIZED /* Just to be sure. */
2100 && SYMBOL_BLV (sym)->fwd) 2101 && SYMBOL_BLV (sym)->fwd)
2101 /* Just reference the variable 2102 /* Just reference the variable
2102 to cause it to become set for this buffer. */ 2103 to cause it to become set for this buffer. */
@@ -2752,7 +2753,7 @@ swap_out_buffer_local_variables (struct buffer *b)
2752 for (alist = oalist; CONSP (alist); alist = XCDR (alist)) 2753 for (alist = oalist; CONSP (alist); alist = XCDR (alist))
2753 { 2754 {
2754 Lisp_Object sym = XCAR (XCAR (alist)); 2755 Lisp_Object sym = XCAR (XCAR (alist));
2755 eassert (XSYMBOL (sym)->redirect == SYMBOL_LOCALIZED); 2756 eassert (XSYMBOL (sym)->u.s.redirect == SYMBOL_LOCALIZED);
2756 /* Need not do anything if some other buffer's binding is 2757 /* Need not do anything if some other buffer's binding is
2757 now cached. */ 2758 now cached. */
2758 if (EQ (SYMBOL_BLV (XSYMBOL (sym))->where, buffer)) 2759 if (EQ (SYMBOL_BLV (XSYMBOL (sym))->where, buffer))
@@ -5423,8 +5424,8 @@ defvar_per_buffer (struct Lisp_Buffer_Objfwd *bo_fwd, const char *namestring,
5423 bo_fwd->type = Lisp_Fwd_Buffer_Obj; 5424 bo_fwd->type = Lisp_Fwd_Buffer_Obj;
5424 bo_fwd->offset = offset; 5425 bo_fwd->offset = offset;
5425 bo_fwd->predicate = predicate; 5426 bo_fwd->predicate = predicate;
5426 sym->declared_special = 1; 5427 sym->u.s.declared_special = true;
5427 sym->redirect = SYMBOL_FORWARDED; 5428 sym->u.s.redirect = SYMBOL_FORWARDED;
5428 SET_SYMBOL_FWD (sym, (union Lisp_Fwd *) bo_fwd); 5429 SET_SYMBOL_FWD (sym, (union Lisp_Fwd *) bo_fwd);
5429 XSETSYMBOL (PER_BUFFER_SYMBOL (offset), sym); 5430 XSETSYMBOL (PER_BUFFER_SYMBOL (offset), sym);
5430 5431
diff --git a/src/buffer.h b/src/buffer.h
index ac7c5a54679..46c7c6e5ad6 100644
--- a/src/buffer.h
+++ b/src/buffer.h
@@ -504,7 +504,7 @@ struct buffer_text
504 504
505struct buffer 505struct buffer
506{ 506{
507 struct vectorlike_header header; 507 union vectorlike_header header;
508 508
509 /* The name of this buffer. */ 509 /* The name of this buffer. */
510 Lisp_Object name_; 510 Lisp_Object name_;
diff --git a/src/bytecode.c b/src/bytecode.c
index 50c7abe2891..ebaf3c3a7fc 100644
--- a/src/bytecode.c
+++ b/src/bytecode.c
@@ -489,7 +489,7 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth,
489 { 489 {
490 Lisp_Object v1 = vectorp[op], v2; 490 Lisp_Object v1 = vectorp[op], v2;
491 if (!SYMBOLP (v1) 491 if (!SYMBOLP (v1)
492 || XSYMBOL (v1)->redirect != SYMBOL_PLAINVAL 492 || XSYMBOL (v1)->u.s.redirect != SYMBOL_PLAINVAL
493 || (v2 = SYMBOL_VAL (XSYMBOL (v1)), EQ (v2, Qunbound))) 493 || (v2 = SYMBOL_VAL (XSYMBOL (v1)), EQ (v2, Qunbound)))
494 v2 = Fsymbol_value (v1); 494 v2 = Fsymbol_value (v1);
495 PUSH (v2); 495 PUSH (v2);
@@ -558,7 +558,7 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth,
558 /* Inline the most common case. */ 558 /* Inline the most common case. */
559 if (SYMBOLP (sym) 559 if (SYMBOLP (sym)
560 && !EQ (val, Qunbound) 560 && !EQ (val, Qunbound)
561 && !XSYMBOL (sym)->redirect 561 && !XSYMBOL (sym)->u.s.redirect
562 && !SYMBOL_TRAPPED_WRITE_P (sym)) 562 && !SYMBOL_TRAPPED_WRITE_P (sym))
563 SET_SYMBOL_VAL (XSYMBOL (sym), val); 563 SET_SYMBOL_VAL (XSYMBOL (sym), val);
564 else 564 else
diff --git a/src/casefiddle.c b/src/casefiddle.c
index 8f564edeb95..7b34f78a5c9 100644
--- a/src/casefiddle.c
+++ b/src/casefiddle.c
@@ -133,9 +133,9 @@ case_character_impl (struct casing_str_buf *buf,
133 struct Lisp_String *str = XSTRING (prop); 133 struct Lisp_String *str = XSTRING (prop);
134 if (STRING_BYTES (str) <= sizeof buf->data) 134 if (STRING_BYTES (str) <= sizeof buf->data)
135 { 135 {
136 buf->len_chars = str->size; 136 buf->len_chars = str->u.s.size;
137 buf->len_bytes = STRING_BYTES (str); 137 buf->len_bytes = STRING_BYTES (str);
138 memcpy (buf->data, str->data, buf->len_bytes); 138 memcpy (buf->data, str->u.s.data, buf->len_bytes);
139 return 1; 139 return 1;
140 } 140 }
141 } 141 }
diff --git a/src/cmds.c b/src/cmds.c
index f76fe873720..6a7a0fa50a1 100644
--- a/src/cmds.c
+++ b/src/cmds.c
@@ -421,11 +421,11 @@ internal_self_insert (int c, EMACS_INT n)
421 and the hook has a non-nil `no-self-insert' property, 421 and the hook has a non-nil `no-self-insert' property,
422 return right away--don't really self-insert. */ 422 return right away--don't really self-insert. */
423 if (SYMBOLP (sym) && ! NILP (sym) 423 if (SYMBOLP (sym) && ! NILP (sym)
424 && ! NILP (XSYMBOL (sym)->function) 424 && ! NILP (XSYMBOL (sym)->u.s.function)
425 && SYMBOLP (XSYMBOL (sym)->function)) 425 && SYMBOLP (XSYMBOL (sym)->u.s.function))
426 { 426 {
427 Lisp_Object prop; 427 Lisp_Object prop;
428 prop = Fget (XSYMBOL (sym)->function, intern ("no-self-insert")); 428 prop = Fget (XSYMBOL (sym)->u.s.function, intern ("no-self-insert"));
429 if (! NILP (prop)) 429 if (! NILP (prop))
430 return 1; 430 return 1;
431 } 431 }
diff --git a/src/data.c b/src/data.c
index 00d1eb43033..4a3afed6f71 100644
--- a/src/data.c
+++ b/src/data.c
@@ -670,7 +670,7 @@ global value outside of any lexical scope. */)
670 sym = XSYMBOL (symbol); 670 sym = XSYMBOL (symbol);
671 671
672 start: 672 start:
673 switch (sym->redirect) 673 switch (sym->u.s.redirect)
674 { 674 {
675 case SYMBOL_PLAINVAL: valcontents = SYMBOL_VAL (sym); break; 675 case SYMBOL_PLAINVAL: valcontents = SYMBOL_VAL (sym); break;
676 case SYMBOL_VARALIAS: sym = indirect_variable (sym); goto start; 676 case SYMBOL_VARALIAS: sym = indirect_variable (sym); goto start;
@@ -704,10 +704,10 @@ global value outside of any lexical scope. */)
704 expect `t' in particular, rather than any true value. */ 704 expect `t' in particular, rather than any true value. */
705DEFUN ("fboundp", Ffboundp, Sfboundp, 1, 1, 0, 705DEFUN ("fboundp", Ffboundp, Sfboundp, 1, 1, 0,
706 doc: /* Return t if SYMBOL's function definition is not void. */) 706 doc: /* Return t if SYMBOL's function definition is not void. */)
707 (register Lisp_Object symbol) 707 (Lisp_Object symbol)
708{ 708{
709 CHECK_SYMBOL (symbol); 709 CHECK_SYMBOL (symbol);
710 return NILP (XSYMBOL (symbol)->function) ? Qnil : Qt; 710 return NILP (XSYMBOL (symbol)->u.s.function) ? Qnil : Qt;
711} 711}
712 712
713DEFUN ("makunbound", Fmakunbound, Smakunbound, 1, 1, 0, 713DEFUN ("makunbound", Fmakunbound, Smakunbound, 1, 1, 0,
@@ -736,18 +736,18 @@ Return SYMBOL. */)
736 736
737DEFUN ("symbol-function", Fsymbol_function, Ssymbol_function, 1, 1, 0, 737DEFUN ("symbol-function", Fsymbol_function, Ssymbol_function, 1, 1, 0,
738 doc: /* Return SYMBOL's function definition, or nil if that is void. */) 738 doc: /* Return SYMBOL's function definition, or nil if that is void. */)
739 (register Lisp_Object symbol) 739 (Lisp_Object symbol)
740{ 740{
741 CHECK_SYMBOL (symbol); 741 CHECK_SYMBOL (symbol);
742 return XSYMBOL (symbol)->function; 742 return XSYMBOL (symbol)->u.s.function;
743} 743}
744 744
745DEFUN ("symbol-plist", Fsymbol_plist, Ssymbol_plist, 1, 1, 0, 745DEFUN ("symbol-plist", Fsymbol_plist, Ssymbol_plist, 1, 1, 0,
746 doc: /* Return SYMBOL's property list. */) 746 doc: /* Return SYMBOL's property list. */)
747 (register Lisp_Object symbol) 747 (Lisp_Object symbol)
748{ 748{
749 CHECK_SYMBOL (symbol); 749 CHECK_SYMBOL (symbol);
750 return XSYMBOL (symbol)->plist; 750 return XSYMBOL (symbol)->u.s.plist;
751} 751}
752 752
753DEFUN ("symbol-name", Fsymbol_name, Ssymbol_name, 1, 1, 0, 753DEFUN ("symbol-name", Fsymbol_name, Ssymbol_name, 1, 1, 0,
@@ -771,7 +771,7 @@ DEFUN ("fset", Ffset, Sfset, 2, 2, 0,
771 if (NILP (symbol)) 771 if (NILP (symbol))
772 xsignal1 (Qsetting_constant, symbol); 772 xsignal1 (Qsetting_constant, symbol);
773 773
774 function = XSYMBOL (symbol)->function; 774 function = XSYMBOL (symbol)->u.s.function;
775 775
776 if (!NILP (Vautoload_queue) && !NILP (function)) 776 if (!NILP (Vautoload_queue) && !NILP (function))
777 Vautoload_queue = Fcons (Fcons (symbol, function), Vautoload_queue); 777 Vautoload_queue = Fcons (Fcons (symbol, function), Vautoload_queue);
@@ -814,7 +814,7 @@ The return value is undefined. */)
814 { /* Only add autoload entries after dumping, because the ones before are 814 { /* Only add autoload entries after dumping, because the ones before are
815 not useful and else we get loads of them from the loaddefs.el. */ 815 not useful and else we get loads of them from the loaddefs.el. */
816 816
817 if (AUTOLOADP (XSYMBOL (symbol)->function)) 817 if (AUTOLOADP (XSYMBOL (symbol)->u.s.function))
818 /* Remember that the function was already an autoload. */ 818 /* Remember that the function was already an autoload. */
819 LOADHIST_ATTACH (Fcons (Qt, symbol)); 819 LOADHIST_ATTACH (Fcons (Qt, symbol));
820 LOADHIST_ATTACH (Fcons (autoload ? Qautoload : Qdefun, symbol)); 820 LOADHIST_ATTACH (Fcons (autoload ? Qautoload : Qdefun, symbol));
@@ -940,10 +940,10 @@ indirect_variable (struct Lisp_Symbol *symbol)
940 940
941 hare = tortoise = symbol; 941 hare = tortoise = symbol;
942 942
943 while (hare->redirect == SYMBOL_VARALIAS) 943 while (hare->u.s.redirect == SYMBOL_VARALIAS)
944 { 944 {
945 hare = SYMBOL_ALIAS (hare); 945 hare = SYMBOL_ALIAS (hare);
946 if (hare->redirect != SYMBOL_VARALIAS) 946 if (hare->u.s.redirect != SYMBOL_VARALIAS)
947 break; 947 break;
948 948
949 hare = SYMBOL_ALIAS (hare); 949 hare = SYMBOL_ALIAS (hare);
@@ -1247,7 +1247,7 @@ find_symbol_value (Lisp_Object symbol)
1247 sym = XSYMBOL (symbol); 1247 sym = XSYMBOL (symbol);
1248 1248
1249 start: 1249 start:
1250 switch (sym->redirect) 1250 switch (sym->u.s.redirect)
1251 { 1251 {
1252 case SYMBOL_VARALIAS: sym = indirect_variable (sym); goto start; 1252 case SYMBOL_VARALIAS: sym = indirect_variable (sym); goto start;
1253 case SYMBOL_PLAINVAL: return SYMBOL_VAL (sym); 1253 case SYMBOL_PLAINVAL: return SYMBOL_VAL (sym);
@@ -1310,7 +1310,7 @@ set_internal (Lisp_Object symbol, Lisp_Object newval, Lisp_Object where,
1310 1310
1311 CHECK_SYMBOL (symbol); 1311 CHECK_SYMBOL (symbol);
1312 sym = XSYMBOL (symbol); 1312 sym = XSYMBOL (symbol);
1313 switch (sym->trapped_write) 1313 switch (sym->u.s.trapped_write)
1314 { 1314 {
1315 case SYMBOL_NOWRITE: 1315 case SYMBOL_NOWRITE:
1316 if (NILP (Fkeywordp (symbol)) 1316 if (NILP (Fkeywordp (symbol))
@@ -1336,7 +1336,7 @@ set_internal (Lisp_Object symbol, Lisp_Object newval, Lisp_Object where,
1336 } 1336 }
1337 1337
1338 start: 1338 start:
1339 switch (sym->redirect) 1339 switch (sym->u.s.redirect)
1340 { 1340 {
1341 case SYMBOL_VARALIAS: sym = indirect_variable (sym); goto start; 1341 case SYMBOL_VARALIAS: sym = indirect_variable (sym); goto start;
1342 case SYMBOL_PLAINVAL: SET_SYMBOL_VAL (sym , newval); return; 1342 case SYMBOL_PLAINVAL: SET_SYMBOL_VAL (sym , newval); return;
@@ -1436,7 +1436,7 @@ set_internal (Lisp_Object symbol, Lisp_Object newval, Lisp_Object where,
1436 if (voide) 1436 if (voide)
1437 { /* If storing void (making the symbol void), forward only through 1437 { /* If storing void (making the symbol void), forward only through
1438 buffer-local indicator, not through Lisp_Objfwd, etc. */ 1438 buffer-local indicator, not through Lisp_Objfwd, etc. */
1439 sym->redirect = SYMBOL_PLAINVAL; 1439 sym->u.s.redirect = SYMBOL_PLAINVAL;
1440 SET_SYMBOL_VAL (sym, newval); 1440 SET_SYMBOL_VAL (sym, newval);
1441 } 1441 }
1442 else 1442 else
@@ -1452,9 +1452,9 @@ static void
1452set_symbol_trapped_write (Lisp_Object symbol, enum symbol_trapped_write trap) 1452set_symbol_trapped_write (Lisp_Object symbol, enum symbol_trapped_write trap)
1453{ 1453{
1454 struct Lisp_Symbol *sym = XSYMBOL (symbol); 1454 struct Lisp_Symbol *sym = XSYMBOL (symbol);
1455 if (sym->trapped_write == SYMBOL_NOWRITE) 1455 if (sym->u.s.trapped_write == SYMBOL_NOWRITE)
1456 xsignal1 (Qtrapping_constant, symbol); 1456 xsignal1 (Qtrapping_constant, symbol);
1457 sym->trapped_write = trap; 1457 sym->u.s.trapped_write = trap;
1458} 1458}
1459 1459
1460static void 1460static void
@@ -1469,7 +1469,7 @@ harmonize_variable_watchers (Lisp_Object alias, Lisp_Object base_variable)
1469 if (!EQ (base_variable, alias) 1469 if (!EQ (base_variable, alias)
1470 && EQ (base_variable, Findirect_variable (alias))) 1470 && EQ (base_variable, Findirect_variable (alias)))
1471 set_symbol_trapped_write 1471 set_symbol_trapped_write
1472 (alias, XSYMBOL (base_variable)->trapped_write); 1472 (alias, XSYMBOL (base_variable)->u.s.trapped_write);
1473} 1473}
1474 1474
1475DEFUN ("add-variable-watcher", Fadd_variable_watcher, Sadd_variable_watcher, 1475DEFUN ("add-variable-watcher", Fadd_variable_watcher, Sadd_variable_watcher,
@@ -1583,7 +1583,7 @@ default_value (Lisp_Object symbol)
1583 sym = XSYMBOL (symbol); 1583 sym = XSYMBOL (symbol);
1584 1584
1585 start: 1585 start:
1586 switch (sym->redirect) 1586 switch (sym->u.s.redirect)
1587 { 1587 {
1588 case SYMBOL_VARALIAS: sym = indirect_variable (sym); goto start; 1588 case SYMBOL_VARALIAS: sym = indirect_variable (sym); goto start;
1589 case SYMBOL_PLAINVAL: return SYMBOL_VAL (sym); 1589 case SYMBOL_PLAINVAL: return SYMBOL_VAL (sym);
@@ -1653,7 +1653,7 @@ set_default_internal (Lisp_Object symbol, Lisp_Object value,
1653 1653
1654 CHECK_SYMBOL (symbol); 1654 CHECK_SYMBOL (symbol);
1655 sym = XSYMBOL (symbol); 1655 sym = XSYMBOL (symbol);
1656 switch (sym->trapped_write) 1656 switch (sym->u.s.trapped_write)
1657 { 1657 {
1658 case SYMBOL_NOWRITE: 1658 case SYMBOL_NOWRITE:
1659 if (NILP (Fkeywordp (symbol)) 1659 if (NILP (Fkeywordp (symbol))
@@ -1665,7 +1665,7 @@ set_default_internal (Lisp_Object symbol, Lisp_Object value,
1665 1665
1666 case SYMBOL_TRAPPED_WRITE: 1666 case SYMBOL_TRAPPED_WRITE:
1667 /* Don't notify here if we're going to call Fset anyway. */ 1667 /* Don't notify here if we're going to call Fset anyway. */
1668 if (sym->redirect != SYMBOL_PLAINVAL 1668 if (sym->u.s.redirect != SYMBOL_PLAINVAL
1669 /* Setting due to thread switching doesn't count. */ 1669 /* Setting due to thread switching doesn't count. */
1670 && bindflag != SET_INTERNAL_THREAD_SWITCH) 1670 && bindflag != SET_INTERNAL_THREAD_SWITCH)
1671 notify_variable_watchers (symbol, value, Qset_default, Qnil); 1671 notify_variable_watchers (symbol, value, Qset_default, Qnil);
@@ -1677,7 +1677,7 @@ set_default_internal (Lisp_Object symbol, Lisp_Object value,
1677 } 1677 }
1678 1678
1679 start: 1679 start:
1680 switch (sym->redirect) 1680 switch (sym->u.s.redirect)
1681 { 1681 {
1682 case SYMBOL_VARALIAS: sym = indirect_variable (sym); goto start; 1682 case SYMBOL_VARALIAS: sym = indirect_variable (sym); goto start;
1683 case SYMBOL_PLAINVAL: set_internal (symbol, value, Qnil, bindflag); return; 1683 case SYMBOL_PLAINVAL: set_internal (symbol, value, Qnil, bindflag); return;
@@ -1829,7 +1829,7 @@ The function `default-value' gets the default value and `set-default' sets it.
1829 sym = XSYMBOL (variable); 1829 sym = XSYMBOL (variable);
1830 1830
1831 start: 1831 start:
1832 switch (sym->redirect) 1832 switch (sym->u.s.redirect)
1833 { 1833 {
1834 case SYMBOL_VARALIAS: sym = indirect_variable (sym); goto start; 1834 case SYMBOL_VARALIAS: sym = indirect_variable (sym); goto start;
1835 case SYMBOL_PLAINVAL: 1835 case SYMBOL_PLAINVAL:
@@ -1857,7 +1857,7 @@ The function `default-value' gets the default value and `set-default' sets it.
1857 if (!blv) 1857 if (!blv)
1858 { 1858 {
1859 blv = make_blv (sym, forwarded, valcontents); 1859 blv = make_blv (sym, forwarded, valcontents);
1860 sym->redirect = SYMBOL_LOCALIZED; 1860 sym->u.s.redirect = SYMBOL_LOCALIZED;
1861 SET_SYMBOL_BLV (sym, blv); 1861 SET_SYMBOL_BLV (sym, blv);
1862 } 1862 }
1863 1863
@@ -1897,7 +1897,7 @@ Instead, use `add-hook' and specify t for the LOCAL argument. */)
1897 sym = XSYMBOL (variable); 1897 sym = XSYMBOL (variable);
1898 1898
1899 start: 1899 start:
1900 switch (sym->redirect) 1900 switch (sym->u.s.redirect)
1901 { 1901 {
1902 case SYMBOL_VARALIAS: sym = indirect_variable (sym); goto start; 1902 case SYMBOL_VARALIAS: sym = indirect_variable (sym); goto start;
1903 case SYMBOL_PLAINVAL: 1903 case SYMBOL_PLAINVAL:
@@ -1914,7 +1914,7 @@ Instead, use `add-hook' and specify t for the LOCAL argument. */)
1914 default: emacs_abort (); 1914 default: emacs_abort ();
1915 } 1915 }
1916 1916
1917 if (sym->trapped_write == SYMBOL_NOWRITE) 1917 if (sym->u.s.trapped_write == SYMBOL_NOWRITE)
1918 error ("Symbol %s may not be buffer-local", 1918 error ("Symbol %s may not be buffer-local",
1919 SDATA (SYMBOL_NAME (variable))); 1919 SDATA (SYMBOL_NAME (variable)));
1920 1920
@@ -1930,7 +1930,7 @@ Instead, use `add-hook' and specify t for the LOCAL argument. */)
1930 if (!blv) 1930 if (!blv)
1931 { 1931 {
1932 blv = make_blv (sym, forwarded, valcontents); 1932 blv = make_blv (sym, forwarded, valcontents);
1933 sym->redirect = SYMBOL_LOCALIZED; 1933 sym->u.s.redirect = SYMBOL_LOCALIZED;
1934 SET_SYMBOL_BLV (sym, blv); 1934 SET_SYMBOL_BLV (sym, blv);
1935 } 1935 }
1936 1936
@@ -1987,7 +1987,7 @@ From now on the default value will apply in this buffer. Return VARIABLE. */)
1987 sym = XSYMBOL (variable); 1987 sym = XSYMBOL (variable);
1988 1988
1989 start: 1989 start:
1990 switch (sym->redirect) 1990 switch (sym->u.s.redirect)
1991 { 1991 {
1992 case SYMBOL_VARALIAS: sym = indirect_variable (sym); goto start; 1992 case SYMBOL_VARALIAS: sym = indirect_variable (sym); goto start;
1993 case SYMBOL_PLAINVAL: return variable; 1993 case SYMBOL_PLAINVAL: return variable;
@@ -2014,7 +2014,7 @@ From now on the default value will apply in this buffer. Return VARIABLE. */)
2014 default: emacs_abort (); 2014 default: emacs_abort ();
2015 } 2015 }
2016 2016
2017 if (sym->trapped_write == SYMBOL_TRAPPED_WRITE) 2017 if (sym->u.s.trapped_write == SYMBOL_TRAPPED_WRITE)
2018 notify_variable_watchers (variable, Qnil, Qmakunbound, Fcurrent_buffer ()); 2018 notify_variable_watchers (variable, Qnil, Qmakunbound, Fcurrent_buffer ());
2019 2019
2020 /* Get rid of this buffer's alist element, if any. */ 2020 /* Get rid of this buffer's alist element, if any. */
@@ -2056,7 +2056,7 @@ BUFFER defaults to the current buffer. */)
2056 sym = XSYMBOL (variable); 2056 sym = XSYMBOL (variable);
2057 2057
2058 start: 2058 start:
2059 switch (sym->redirect) 2059 switch (sym->u.s.redirect)
2060 { 2060 {
2061 case SYMBOL_VARALIAS: sym = indirect_variable (sym); goto start; 2061 case SYMBOL_VARALIAS: sym = indirect_variable (sym); goto start;
2062 case SYMBOL_PLAINVAL: return Qnil; 2062 case SYMBOL_PLAINVAL: return Qnil;
@@ -2110,7 +2110,7 @@ value in BUFFER, or if VARIABLE is automatically buffer-local (see
2110 sym = XSYMBOL (variable); 2110 sym = XSYMBOL (variable);
2111 2111
2112 start: 2112 start:
2113 switch (sym->redirect) 2113 switch (sym->u.s.redirect)
2114 { 2114 {
2115 case SYMBOL_VARALIAS: sym = indirect_variable (sym); goto start; 2115 case SYMBOL_VARALIAS: sym = indirect_variable (sym); goto start;
2116 case SYMBOL_PLAINVAL: return Qnil; 2116 case SYMBOL_PLAINVAL: return Qnil;
@@ -2145,7 +2145,7 @@ If the current binding is global (the default), the value is nil. */)
2145 find_symbol_value (variable); 2145 find_symbol_value (variable);
2146 2146
2147 start: 2147 start:
2148 switch (sym->redirect) 2148 switch (sym->u.s.redirect)
2149 { 2149 {
2150 case SYMBOL_VARALIAS: sym = indirect_variable (sym); goto start; 2150 case SYMBOL_VARALIAS: sym = indirect_variable (sym); goto start;
2151 case SYMBOL_PLAINVAL: return Qnil; 2151 case SYMBOL_PLAINVAL: return Qnil;
@@ -2163,7 +2163,7 @@ If the current binding is global (the default), the value is nil. */)
2163 buffer's or frame's value we are saving. */ 2163 buffer's or frame's value we are saving. */
2164 if (!NILP (Flocal_variable_p (variable, Qnil))) 2164 if (!NILP (Flocal_variable_p (variable, Qnil)))
2165 return Fcurrent_buffer (); 2165 return Fcurrent_buffer ();
2166 else if (sym->redirect == SYMBOL_LOCALIZED 2166 else if (sym->u.s.redirect == SYMBOL_LOCALIZED
2167 && blv_found (SYMBOL_BLV (sym))) 2167 && blv_found (SYMBOL_BLV (sym)))
2168 return SYMBOL_BLV (sym)->where; 2168 return SYMBOL_BLV (sym)->where;
2169 else 2169 else
@@ -2234,12 +2234,12 @@ indirect_function (register Lisp_Object object)
2234 { 2234 {
2235 if (!SYMBOLP (hare) || NILP (hare)) 2235 if (!SYMBOLP (hare) || NILP (hare))
2236 break; 2236 break;
2237 hare = XSYMBOL (hare)->function; 2237 hare = XSYMBOL (hare)->u.s.function;
2238 if (!SYMBOLP (hare) || NILP (hare)) 2238 if (!SYMBOLP (hare) || NILP (hare))
2239 break; 2239 break;
2240 hare = XSYMBOL (hare)->function; 2240 hare = XSYMBOL (hare)->u.s.function;
2241 2241
2242 tortoise = XSYMBOL (tortoise)->function; 2242 tortoise = XSYMBOL (tortoise)->u.s.function;
2243 2243
2244 if (EQ (hare, tortoise)) 2244 if (EQ (hare, tortoise))
2245 xsignal1 (Qcyclic_function_indirection, object); 2245 xsignal1 (Qcyclic_function_indirection, object);
@@ -2261,7 +2261,7 @@ function chain of symbols. */)
2261 /* Optimize for no indirection. */ 2261 /* Optimize for no indirection. */
2262 result = object; 2262 result = object;
2263 if (SYMBOLP (result) && !NILP (result) 2263 if (SYMBOLP (result) && !NILP (result)
2264 && (result = XSYMBOL (result)->function, SYMBOLP (result))) 2264 && (result = XSYMBOL (result)->u.s.function, SYMBOLP (result)))
2265 result = indirect_function (result); 2265 result = indirect_function (result);
2266 if (!NILP (result)) 2266 if (!NILP (result))
2267 return result; 2267 return result;
@@ -3894,7 +3894,7 @@ syms_of_data (void)
3894 defsubr (&Sbool_vector_count_consecutive); 3894 defsubr (&Sbool_vector_count_consecutive);
3895 defsubr (&Sbool_vector_count_population); 3895 defsubr (&Sbool_vector_count_population);
3896 3896
3897 set_symbol_function (Qwholenump, XSYMBOL (Qnatnump)->function); 3897 set_symbol_function (Qwholenump, XSYMBOL (Qnatnump)->u.s.function);
3898 3898
3899 DEFVAR_LISP ("most-positive-fixnum", Vmost_positive_fixnum, 3899 DEFVAR_LISP ("most-positive-fixnum", Vmost_positive_fixnum,
3900 doc: /* The largest value that is representable in a Lisp integer. */); 3900 doc: /* The largest value that is representable in a Lisp integer. */);
diff --git a/src/doc.c b/src/doc.c
index e81740bfc1c..0cd62172c38 100644
--- a/src/doc.c
+++ b/src/doc.c
@@ -472,7 +472,7 @@ store_function_docstring (Lisp_Object obj, EMACS_INT offset)
472{ 472{
473 /* Don't use indirect_function here, or defaliases will apply their 473 /* Don't use indirect_function here, or defaliases will apply their
474 docstrings to the base functions (Bug#2603). */ 474 docstrings to the base functions (Bug#2603). */
475 Lisp_Object fun = SYMBOLP (obj) ? XSYMBOL (obj)->function : obj; 475 Lisp_Object fun = SYMBOLP (obj) ? XSYMBOL (obj)->u.s.function : obj;
476 476
477 /* The type determines where the docstring is stored. */ 477 /* The type determines where the docstring is stored. */
478 478
diff --git a/src/emacs-module.c b/src/emacs-module.c
index 6bc91a7e06a..b351515c3bd 100644
--- a/src/emacs-module.c
+++ b/src/emacs-module.c
@@ -998,10 +998,6 @@ lisp_to_value_bits (Lisp_Object o)
998 return (emacs_value) p; 998 return (emacs_value) p;
999} 999}
1000 1000
1001#ifndef HAVE_STRUCT_ATTRIBUTE_ALIGNED
1002enum { HAVE_STRUCT_ATTRIBUTE_ALIGNED = 0 };
1003#endif
1004
1005/* Convert O to an emacs_value. Allocate storage if needed; this can 1001/* Convert O to an emacs_value. Allocate storage if needed; this can
1006 signal if memory is exhausted. Must be an injective function. */ 1002 signal if memory is exhausted. Must be an injective function. */
1007static emacs_value 1003static emacs_value
@@ -1029,19 +1025,6 @@ lisp_to_value (emacs_env *env, Lisp_Object o)
1029 /* Package the incompressible object pointer inside a pair 1025 /* Package the incompressible object pointer inside a pair
1030 that is compressible. */ 1026 that is compressible. */
1031 Lisp_Object pair = Fcons (o, ltv_mark); 1027 Lisp_Object pair = Fcons (o, ltv_mark);
1032
1033 if (! HAVE_STRUCT_ATTRIBUTE_ALIGNED)
1034 {
1035 /* Keep calling Fcons until it returns a compressible pair.
1036 This shouldn't take long. */
1037 while ((intptr_t) XCONS (pair) & (GCALIGNMENT - 1))
1038 pair = Fcons (o, pair);
1039
1040 /* Plant the mark. The garbage collector will eventually
1041 reclaim any just-allocated incompressible pairs. */
1042 XSETCDR (pair, ltv_mark);
1043 }
1044
1045 v = (emacs_value) ((intptr_t) XCONS (pair) + Lisp_Cons); 1028 v = (emacs_value) ((intptr_t) XCONS (pair) + Lisp_Cons);
1046 } 1029 }
1047 1030
diff --git a/src/eval.c b/src/eval.c
index 063deb4ba03..ec507dd2042 100644
--- a/src/eval.c
+++ b/src/eval.c
@@ -603,7 +603,7 @@ The return value is BASE-VARIABLE. */)
603 603
604 sym = XSYMBOL (new_alias); 604 sym = XSYMBOL (new_alias);
605 605
606 switch (sym->redirect) 606 switch (sym->u.s.redirect)
607 { 607 {
608 case SYMBOL_FORWARDED: 608 case SYMBOL_FORWARDED:
609 error ("Cannot make an internal variable an alias"); 609 error ("Cannot make an internal variable an alias");
@@ -632,14 +632,14 @@ The return value is BASE-VARIABLE. */)
632 error ("Don't know how to make a let-bound variable an alias"); 632 error ("Don't know how to make a let-bound variable an alias");
633 } 633 }
634 634
635 if (sym->trapped_write == SYMBOL_TRAPPED_WRITE) 635 if (sym->u.s.trapped_write == SYMBOL_TRAPPED_WRITE)
636 notify_variable_watchers (new_alias, base_variable, Qdefvaralias, Qnil); 636 notify_variable_watchers (new_alias, base_variable, Qdefvaralias, Qnil);
637 637
638 sym->declared_special = 1; 638 sym->u.s.declared_special = true;
639 XSYMBOL (base_variable)->declared_special = 1; 639 XSYMBOL (base_variable)->u.s.declared_special = true;
640 sym->redirect = SYMBOL_VARALIAS; 640 sym->u.s.redirect = SYMBOL_VARALIAS;
641 SET_SYMBOL_ALIAS (sym, XSYMBOL (base_variable)); 641 SET_SYMBOL_ALIAS (sym, XSYMBOL (base_variable));
642 sym->trapped_write = XSYMBOL (base_variable)->trapped_write; 642 sym->u.s.trapped_write = XSYMBOL (base_variable)->u.s.trapped_write;
643 LOADHIST_ATTACH (new_alias); 643 LOADHIST_ATTACH (new_alias);
644 /* Even if docstring is nil: remove old docstring. */ 644 /* Even if docstring is nil: remove old docstring. */
645 Fput (new_alias, Qvariable_documentation, docstring); 645 Fput (new_alias, Qvariable_documentation, docstring);
@@ -745,7 +745,7 @@ usage: (defvar SYMBOL &optional INITVALUE DOCSTRING) */)
745 tem = Fdefault_boundp (sym); 745 tem = Fdefault_boundp (sym);
746 746
747 /* Do it before evaluating the initial value, for self-references. */ 747 /* Do it before evaluating the initial value, for self-references. */
748 XSYMBOL (sym)->declared_special = 1; 748 XSYMBOL (sym)->u.s.declared_special = true;
749 749
750 if (NILP (tem)) 750 if (NILP (tem))
751 Fset_default (sym, eval_sub (XCAR (tail))); 751 Fset_default (sym, eval_sub (XCAR (tail)));
@@ -769,7 +769,7 @@ usage: (defvar SYMBOL &optional INITVALUE DOCSTRING) */)
769 LOADHIST_ATTACH (sym); 769 LOADHIST_ATTACH (sym);
770 } 770 }
771 else if (!NILP (Vinternal_interpreter_environment) 771 else if (!NILP (Vinternal_interpreter_environment)
772 && !XSYMBOL (sym)->declared_special) 772 && !XSYMBOL (sym)->u.s.declared_special)
773 /* A simple (defvar foo) with lexical scoping does "nothing" except 773 /* A simple (defvar foo) with lexical scoping does "nothing" except
774 declare that var to be dynamically scoped *locally* (i.e. within 774 declare that var to be dynamically scoped *locally* (i.e. within
775 the current file or let-block). */ 775 the current file or let-block). */
@@ -818,7 +818,7 @@ usage: (defconst SYMBOL INITVALUE [DOCSTRING]) */)
818 if (!NILP (Vpurify_flag)) 818 if (!NILP (Vpurify_flag))
819 tem = Fpurecopy (tem); 819 tem = Fpurecopy (tem);
820 Fset_default (sym, tem); 820 Fset_default (sym, tem);
821 XSYMBOL (sym)->declared_special = 1; 821 XSYMBOL (sym)->u.s.declared_special = true;
822 if (!NILP (docstring)) 822 if (!NILP (docstring))
823 { 823 {
824 if (!NILP (Vpurify_flag)) 824 if (!NILP (Vpurify_flag))
@@ -837,7 +837,7 @@ DEFUN ("internal-make-var-non-special", Fmake_var_non_special,
837 (Lisp_Object symbol) 837 (Lisp_Object symbol)
838{ 838{
839 CHECK_SYMBOL (symbol); 839 CHECK_SYMBOL (symbol);
840 XSYMBOL (symbol)->declared_special = 0; 840 XSYMBOL (symbol)->u.s.declared_special = false;
841 return Qnil; 841 return Qnil;
842} 842}
843 843
@@ -877,7 +877,7 @@ usage: (let* VARLIST BODY...) */)
877 } 877 }
878 878
879 if (!NILP (lexenv) && SYMBOLP (var) 879 if (!NILP (lexenv) && SYMBOLP (var)
880 && !XSYMBOL (var)->declared_special 880 && !XSYMBOL (var)->u.s.declared_special
881 && NILP (Fmemq (var, Vinternal_interpreter_environment))) 881 && NILP (Fmemq (var, Vinternal_interpreter_environment)))
882 /* Lexically bind VAR by adding it to the interpreter's binding 882 /* Lexically bind VAR by adding it to the interpreter's binding
883 alist. */ 883 alist. */
@@ -953,7 +953,7 @@ usage: (let VARLIST BODY...) */)
953 tem = temps[argnum]; 953 tem = temps[argnum];
954 954
955 if (!NILP (lexenv) && SYMBOLP (var) 955 if (!NILP (lexenv) && SYMBOLP (var)
956 && !XSYMBOL (var)->declared_special 956 && !XSYMBOL (var)->u.s.declared_special
957 && NILP (Fmemq (var, Vinternal_interpreter_environment))) 957 && NILP (Fmemq (var, Vinternal_interpreter_environment)))
958 /* Lexically bind VAR by adding it to the lexenv alist. */ 958 /* Lexically bind VAR by adding it to the lexenv alist. */
959 lexenv = Fcons (Fcons (var, tem), lexenv); 959 lexenv = Fcons (Fcons (var, tem), lexenv);
@@ -1022,7 +1022,7 @@ definitions to shadow the loaded ones for use in file byte-compilation. */)
1022 tem = Fassq (sym, environment); 1022 tem = Fassq (sym, environment);
1023 if (NILP (tem)) 1023 if (NILP (tem))
1024 { 1024 {
1025 def = XSYMBOL (sym)->function; 1025 def = XSYMBOL (sym)->u.s.function;
1026 if (!NILP (def)) 1026 if (!NILP (def))
1027 continue; 1027 continue;
1028 } 1028 }
@@ -1932,8 +1932,8 @@ this does nothing and returns nil. */)
1932 CHECK_STRING (file); 1932 CHECK_STRING (file);
1933 1933
1934 /* If function is defined and not as an autoload, don't override. */ 1934 /* If function is defined and not as an autoload, don't override. */
1935 if (!NILP (XSYMBOL (function)->function) 1935 if (!NILP (XSYMBOL (function)->u.s.function)
1936 && !AUTOLOADP (XSYMBOL (function)->function)) 1936 && !AUTOLOADP (XSYMBOL (function)->u.s.function))
1937 return Qnil; 1937 return Qnil;
1938 1938
1939 if (!NILP (Vpurify_flag) && EQ (docstring, make_number (0))) 1939 if (!NILP (Vpurify_flag) && EQ (docstring, make_number (0)))
@@ -2165,7 +2165,7 @@ eval_sub (Lisp_Object form)
2165 fun = original_fun; 2165 fun = original_fun;
2166 if (!SYMBOLP (fun)) 2166 if (!SYMBOLP (fun))
2167 fun = Ffunction (Fcons (fun, Qnil)); 2167 fun = Ffunction (Fcons (fun, Qnil));
2168 else if (!NILP (fun) && (fun = XSYMBOL (fun)->function, SYMBOLP (fun))) 2168 else if (!NILP (fun) && (fun = XSYMBOL (fun)->u.s.function, SYMBOLP (fun)))
2169 fun = indirect_function (fun); 2169 fun = indirect_function (fun);
2170 2170
2171 if (SUBRP (fun)) 2171 if (SUBRP (fun))
@@ -2348,7 +2348,7 @@ usage: (apply FUNCTION &rest ARGUMENTS) */)
2348 2348
2349 /* Optimize for no indirection. */ 2349 /* Optimize for no indirection. */
2350 if (SYMBOLP (fun) && !NILP (fun) 2350 if (SYMBOLP (fun) && !NILP (fun)
2351 && (fun = XSYMBOL (fun)->function, SYMBOLP (fun))) 2351 && (fun = XSYMBOL (fun)->u.s.function, SYMBOLP (fun)))
2352 { 2352 {
2353 fun = indirect_function (fun); 2353 fun = indirect_function (fun);
2354 if (NILP (fun)) 2354 if (NILP (fun))
@@ -2760,7 +2760,7 @@ usage: (funcall FUNCTION &rest ARGUMENTS) */)
2760 /* Optimize for no indirection. */ 2760 /* Optimize for no indirection. */
2761 fun = original_fun; 2761 fun = original_fun;
2762 if (SYMBOLP (fun) && !NILP (fun) 2762 if (SYMBOLP (fun) && !NILP (fun)
2763 && (fun = XSYMBOL (fun)->function, SYMBOLP (fun))) 2763 && (fun = XSYMBOL (fun)->u.s.function, SYMBOLP (fun)))
2764 fun = indirect_function (fun); 2764 fun = indirect_function (fun);
2765 2765
2766 if (SUBRP (fun)) 2766 if (SUBRP (fun))
@@ -3076,7 +3076,7 @@ function with `&rest' args, or `unevalled' for a special form. */)
3076 function = original; 3076 function = original;
3077 if (SYMBOLP (function) && !NILP (function)) 3077 if (SYMBOLP (function) && !NILP (function))
3078 { 3078 {
3079 function = XSYMBOL (function)->function; 3079 function = XSYMBOL (function)->u.s.function;
3080 if (SYMBOLP (function)) 3080 if (SYMBOLP (function))
3081 function = indirect_function (function); 3081 function = indirect_function (function);
3082 } 3082 }
@@ -3215,7 +3215,7 @@ let_shadows_buffer_binding_p (struct Lisp_Symbol *symbol)
3215 if ((--p)->kind > SPECPDL_LET) 3215 if ((--p)->kind > SPECPDL_LET)
3216 { 3216 {
3217 struct Lisp_Symbol *let_bound_symbol = XSYMBOL (specpdl_symbol (p)); 3217 struct Lisp_Symbol *let_bound_symbol = XSYMBOL (specpdl_symbol (p));
3218 eassert (let_bound_symbol->redirect != SYMBOL_VARALIAS); 3218 eassert (let_bound_symbol->u.s.redirect != SYMBOL_VARALIAS);
3219 if (symbol == let_bound_symbol 3219 if (symbol == let_bound_symbol
3220 && EQ (specpdl_where (p), buf)) 3220 && EQ (specpdl_where (p), buf))
3221 return 1; 3221 return 1;
@@ -3228,10 +3228,10 @@ static void
3228do_specbind (struct Lisp_Symbol *sym, union specbinding *bind, 3228do_specbind (struct Lisp_Symbol *sym, union specbinding *bind,
3229 Lisp_Object value, enum Set_Internal_Bind bindflag) 3229 Lisp_Object value, enum Set_Internal_Bind bindflag)
3230{ 3230{
3231 switch (sym->redirect) 3231 switch (sym->u.s.redirect)
3232 { 3232 {
3233 case SYMBOL_PLAINVAL: 3233 case SYMBOL_PLAINVAL:
3234 if (!sym->trapped_write) 3234 if (!sym->u.s.trapped_write)
3235 SET_SYMBOL_VAL (sym, value); 3235 SET_SYMBOL_VAL (sym, value);
3236 else 3236 else
3237 set_internal (specpdl_symbol (bind), value, Qnil, bindflag); 3237 set_internal (specpdl_symbol (bind), value, Qnil, bindflag);
@@ -3275,7 +3275,7 @@ specbind (Lisp_Object symbol, Lisp_Object value)
3275 sym = XSYMBOL (symbol); 3275 sym = XSYMBOL (symbol);
3276 3276
3277 start: 3277 start:
3278 switch (sym->redirect) 3278 switch (sym->u.s.redirect)
3279 { 3279 {
3280 case SYMBOL_VARALIAS: 3280 case SYMBOL_VARALIAS:
3281 sym = indirect_variable (sym); XSETSYMBOL (symbol, sym); goto start; 3281 sym = indirect_variable (sym); XSETSYMBOL (symbol, sym); goto start;
@@ -3299,10 +3299,10 @@ specbind (Lisp_Object symbol, Lisp_Object value)
3299 specpdl_ptr->let.where = Fcurrent_buffer (); 3299 specpdl_ptr->let.where = Fcurrent_buffer ();
3300 specpdl_ptr->let.saved_value = Qnil; 3300 specpdl_ptr->let.saved_value = Qnil;
3301 3301
3302 eassert (sym->redirect != SYMBOL_LOCALIZED 3302 eassert (sym->u.s.redirect != SYMBOL_LOCALIZED
3303 || (EQ (SYMBOL_BLV (sym)->where, Fcurrent_buffer ()))); 3303 || (EQ (SYMBOL_BLV (sym)->where, Fcurrent_buffer ())));
3304 3304
3305 if (sym->redirect == SYMBOL_LOCALIZED) 3305 if (sym->u.s.redirect == SYMBOL_LOCALIZED)
3306 { 3306 {
3307 if (!blv_found (SYMBOL_BLV (sym))) 3307 if (!blv_found (SYMBOL_BLV (sym)))
3308 specpdl_ptr->let.kind = SPECPDL_LET_DEFAULT; 3308 specpdl_ptr->let.kind = SPECPDL_LET_DEFAULT;
@@ -3413,9 +3413,9 @@ do_one_unbind (union specbinding *this_binding, bool unwinding,
3413 { /* If variable has a trivial value (no forwarding), and isn't 3413 { /* If variable has a trivial value (no forwarding), and isn't
3414 trapped, we can just set it. */ 3414 trapped, we can just set it. */
3415 Lisp_Object sym = specpdl_symbol (this_binding); 3415 Lisp_Object sym = specpdl_symbol (this_binding);
3416 if (SYMBOLP (sym) && XSYMBOL (sym)->redirect == SYMBOL_PLAINVAL) 3416 if (SYMBOLP (sym) && XSYMBOL (sym)->u.s.redirect == SYMBOL_PLAINVAL)
3417 { 3417 {
3418 if (XSYMBOL (sym)->trapped_write == SYMBOL_UNTRAPPED_WRITE) 3418 if (XSYMBOL (sym)->u.s.trapped_write == SYMBOL_UNTRAPPED_WRITE)
3419 SET_SYMBOL_VAL (XSYMBOL (sym), specpdl_old_value (this_binding)); 3419 SET_SYMBOL_VAL (XSYMBOL (sym), specpdl_old_value (this_binding));
3420 else 3420 else
3421 set_internal (sym, specpdl_old_value (this_binding), 3421 set_internal (sym, specpdl_old_value (this_binding),
@@ -3547,7 +3547,7 @@ context where binding is lexical by default. */)
3547 (Lisp_Object symbol) 3547 (Lisp_Object symbol)
3548{ 3548{
3549 CHECK_SYMBOL (symbol); 3549 CHECK_SYMBOL (symbol);
3550 return XSYMBOL (symbol)->declared_special ? Qt : Qnil; 3550 return XSYMBOL (symbol)->u.s.declared_special ? Qt : Qnil;
3551} 3551}
3552 3552
3553 3553
@@ -3703,7 +3703,8 @@ backtrace_eval_unrewind (int distance)
3703 just set it. No need to check for constant symbols here, 3703 just set it. No need to check for constant symbols here,
3704 since that was already done by specbind. */ 3704 since that was already done by specbind. */
3705 Lisp_Object sym = specpdl_symbol (tmp); 3705 Lisp_Object sym = specpdl_symbol (tmp);
3706 if (SYMBOLP (sym) && XSYMBOL (sym)->redirect == SYMBOL_PLAINVAL) 3706 if (SYMBOLP (sym)
3707 && XSYMBOL (sym)->u.s.redirect == SYMBOL_PLAINVAL)
3707 { 3708 {
3708 Lisp_Object old_value = specpdl_old_value (tmp); 3709 Lisp_Object old_value = specpdl_old_value (tmp);
3709 set_specpdl_old_value (tmp, SYMBOL_VAL (XSYMBOL (sym))); 3710 set_specpdl_old_value (tmp, SYMBOL_VAL (XSYMBOL (sym)));
diff --git a/src/fileio.c b/src/fileio.c
index fb66118905f..8808ad1d7ad 100644
--- a/src/fileio.c
+++ b/src/fileio.c
@@ -3050,7 +3050,8 @@ support. */)
3050 acl = acl_from_text (SSDATA (acl_string)); 3050 acl = acl_from_text (SSDATA (acl_string));
3051 if (acl == NULL) 3051 if (acl == NULL)
3052 { 3052 {
3053 report_file_error ("Converting ACL", absname); 3053 if (acl_errno_valid (errno))
3054 report_file_error ("Converting ACL", absname);
3054 return Qnil; 3055 return Qnil;
3055 } 3056 }
3056 3057
diff --git a/src/fns.c b/src/fns.c
index 2311a6e041b..42859344bdc 100644
--- a/src/fns.c
+++ b/src/fns.c
@@ -1993,7 +1993,7 @@ This is the last value stored with `(put SYMBOL PROPNAME VALUE)'. */)
1993 propname); 1993 propname);
1994 if (!NILP (propval)) 1994 if (!NILP (propval))
1995 return propval; 1995 return propval;
1996 return Fplist_get (XSYMBOL (symbol)->plist, propname); 1996 return Fplist_get (XSYMBOL (symbol)->u.s.plist, propname);
1997} 1997}
1998 1998
1999DEFUN ("plist-put", Fplist_put, Splist_put, 3, 3, 0, 1999DEFUN ("plist-put", Fplist_put, Splist_put, 3, 3, 0,
@@ -2039,7 +2039,7 @@ It can be retrieved with `(get SYMBOL PROPNAME)'. */)
2039{ 2039{
2040 CHECK_SYMBOL (symbol); 2040 CHECK_SYMBOL (symbol);
2041 set_symbol_plist 2041 set_symbol_plist
2042 (symbol, Fplist_put (XSYMBOL (symbol)->plist, propname, value)); 2042 (symbol, Fplist_put (XSYMBOL (symbol)->u.s.plist, propname, value));
2043 return value; 2043 return value;
2044} 2044}
2045 2045
diff --git a/src/font.h b/src/font.h
index 8f2e27f0edd..43d6f67e3e9 100644
--- a/src/font.h
+++ b/src/font.h
@@ -244,7 +244,7 @@ enum font_property_index
244 244
245struct font_spec 245struct font_spec
246{ 246{
247 struct vectorlike_header header; 247 union vectorlike_header header;
248 Lisp_Object props[FONT_SPEC_MAX]; 248 Lisp_Object props[FONT_SPEC_MAX];
249}; 249};
250 250
@@ -252,7 +252,7 @@ struct font_spec
252 252
253struct font_entity 253struct font_entity
254{ 254{
255 struct vectorlike_header header; 255 union vectorlike_header header;
256 Lisp_Object props[FONT_ENTITY_MAX]; 256 Lisp_Object props[FONT_ENTITY_MAX];
257}; 257};
258 258
@@ -265,7 +265,7 @@ struct font_entity
265 265
266struct font 266struct font
267{ 267{
268 struct vectorlike_header header; 268 union vectorlike_header header;
269 269
270 /* All Lisp_Object components must come first. 270 /* All Lisp_Object components must come first.
271 That ensures they are all aligned normally. */ 271 That ensures they are all aligned normally. */
diff --git a/src/frame.h b/src/frame.h
index e610fc768d3..a3b77636435 100644
--- a/src/frame.h
+++ b/src/frame.h
@@ -79,7 +79,7 @@ enum ns_appearance_type
79 79
80struct frame 80struct frame
81{ 81{
82 struct vectorlike_header header; 82 union vectorlike_header header;
83 83
84 /* All Lisp_Object components must come first. 84 /* All Lisp_Object components must come first.
85 That ensures they are all aligned normally. */ 85 That ensures they are all aligned normally. */
diff --git a/src/keyboard.c b/src/keyboard.c
index 2c29a643011..399149ae978 100644
--- a/src/keyboard.c
+++ b/src/keyboard.c
@@ -7904,7 +7904,7 @@ parse_menu_item (Lisp_Object item, int inmenubar)
7904 (such as lmenu.el set it up), check if the 7904 (such as lmenu.el set it up), check if the
7905 original command matches the cached command. */ 7905 original command matches the cached command. */
7906 && !(SYMBOLP (def) 7906 && !(SYMBOLP (def)
7907 && EQ (tem, XSYMBOL (def)->function)))) 7907 && EQ (tem, XSYMBOL (def)->u.s.function))))
7908 keys = Qnil; 7908 keys = Qnil;
7909 } 7909 }
7910 7910
@@ -8764,9 +8764,9 @@ access_keymap_keyremap (Lisp_Object map, Lisp_Object key, Lisp_Object prompt,
8764 /* Handle a symbol whose function definition is a keymap 8764 /* Handle a symbol whose function definition is a keymap
8765 or an array. */ 8765 or an array. */
8766 if (SYMBOLP (next) && !NILP (Ffboundp (next)) 8766 if (SYMBOLP (next) && !NILP (Ffboundp (next))
8767 && (ARRAYP (XSYMBOL (next)->function) 8767 && (ARRAYP (XSYMBOL (next)->u.s.function)
8768 || KEYMAPP (XSYMBOL (next)->function))) 8768 || KEYMAPP (XSYMBOL (next)->u.s.function)))
8769 next = Fautoload_do_load (XSYMBOL (next)->function, next, Qnil); 8769 next = Fautoload_do_load (XSYMBOL (next)->u.s.function, next, Qnil);
8770 8770
8771 /* If the keymap gives a function, not an 8771 /* If the keymap gives a function, not an
8772 array, then call the function with one arg and use 8772 array, then call the function with one arg and use
@@ -11513,7 +11513,7 @@ for that character after that prefix key. */);
11513 doc: /* Form to evaluate when Emacs starts up. 11513 doc: /* Form to evaluate when Emacs starts up.
11514Useful to set before you dump a modified Emacs. */); 11514Useful to set before you dump a modified Emacs. */);
11515 Vtop_level = Qnil; 11515 Vtop_level = Qnil;
11516 XSYMBOL (Qtop_level)->declared_special = false; 11516 XSYMBOL (Qtop_level)->u.s.declared_special = false;
11517 11517
11518 DEFVAR_KBOARD ("keyboard-translate-table", Vkeyboard_translate_table, 11518 DEFVAR_KBOARD ("keyboard-translate-table", Vkeyboard_translate_table,
11519 doc: /* Translate table for local keyboard input, or nil. 11519 doc: /* Translate table for local keyboard input, or nil.
diff --git a/src/lisp.h b/src/lisp.h
index e3262ad40f3..a25a673a9aa 100644
--- a/src/lisp.h
+++ b/src/lisp.h
@@ -229,7 +229,7 @@ extern bool suppress_checking EXTERNALLY_VISIBLE;
229 USE_LSB_TAG not only requires the least 3 bits of pointers returned by 229 USE_LSB_TAG not only requires the least 3 bits of pointers returned by
230 malloc to be 0 but also needs to be able to impose a mult-of-8 alignment 230 malloc to be 0 but also needs to be able to impose a mult-of-8 alignment
231 on the few static Lisp_Objects used, all of which are aligned via 231 on the few static Lisp_Objects used, all of which are aligned via
232 the GCALIGN macro defined below. */ 232 'char alignas (GCALIGNMENT) gcaligned;' inside a union. */
233 233
234enum Lisp_Bits 234enum Lisp_Bits
235 { 235 {
@@ -277,20 +277,6 @@ DEFINE_GDB_SYMBOL_END (VALMASK)
277error !; 277error !;
278#endif 278#endif
279 279
280/* Use GCALIGNED immediately after the 'struct' keyword to require the
281 struct to have an address that is a multiple of GCALIGNMENT. This
282 is a no-op if the struct's natural alignment is already a multiple
283 of GCALIGNMENT. GCALIGNED's implementation uses the 'aligned'
284 attribute instead of 'alignas (GCALIGNMENT)', as the latter would
285 fail if an object's natural alignment exceeds GCALIGNMENT. The
286 implementation hopes that natural alignment suffices on platforms
287 lacking 'aligned'. */
288#ifdef HAVE_STRUCT_ATTRIBUTE_ALIGNED
289# define GCALIGNED __attribute__ ((aligned (GCALIGNMENT)))
290#else
291# define GCALIGNED /* empty */
292#endif
293
294/* Some operations are so commonly executed that they are implemented 280/* Some operations are so commonly executed that they are implemented
295 as macros, not functions, because otherwise runtime performance would 281 as macros, not functions, because otherwise runtime performance would
296 suffer too much when compiling with GCC without optimization. 282 suffer too much when compiling with GCC without optimization.
@@ -338,15 +324,17 @@ error !;
338#define lisp_h_MISCP(x) (XTYPE (x) == Lisp_Misc) 324#define lisp_h_MISCP(x) (XTYPE (x) == Lisp_Misc)
339#define lisp_h_NILP(x) EQ (x, Qnil) 325#define lisp_h_NILP(x) EQ (x, Qnil)
340#define lisp_h_SET_SYMBOL_VAL(sym, v) \ 326#define lisp_h_SET_SYMBOL_VAL(sym, v) \
341 (eassert ((sym)->redirect == SYMBOL_PLAINVAL), (sym)->val.value = (v)) 327 (eassert ((sym)->u.s.redirect == SYMBOL_PLAINVAL), \
342#define lisp_h_SYMBOL_CONSTANT_P(sym) (XSYMBOL (sym)->trapped_write == SYMBOL_NOWRITE) 328 (sym)->u.s.val.value = (v))
343#define lisp_h_SYMBOL_TRAPPED_WRITE_P(sym) (XSYMBOL (sym)->trapped_write) 329#define lisp_h_SYMBOL_CONSTANT_P(sym) \
330 (XSYMBOL (sym)->u.s.trapped_write == SYMBOL_NOWRITE)
331#define lisp_h_SYMBOL_TRAPPED_WRITE_P(sym) (XSYMBOL (sym)->u.s.trapped_write)
344#define lisp_h_SYMBOL_VAL(sym) \ 332#define lisp_h_SYMBOL_VAL(sym) \
345 (eassert ((sym)->redirect == SYMBOL_PLAINVAL), (sym)->val.value) 333 (eassert ((sym)->u.s.redirect == SYMBOL_PLAINVAL), (sym)->u.s.val.value)
346#define lisp_h_SYMBOLP(x) (XTYPE (x) == Lisp_Symbol) 334#define lisp_h_SYMBOLP(x) (XTYPE (x) == Lisp_Symbol)
347#define lisp_h_VECTORLIKEP(x) (XTYPE (x) == Lisp_Vectorlike) 335#define lisp_h_VECTORLIKEP(x) (XTYPE (x) == Lisp_Vectorlike)
348#define lisp_h_XCAR(c) XCONS (c)->car 336#define lisp_h_XCAR(c) XCONS (c)->u.s.car
349#define lisp_h_XCDR(c) XCONS (c)->u.cdr 337#define lisp_h_XCDR(c) XCONS (c)->u.s.u.cdr
350#define lisp_h_XCONS(a) \ 338#define lisp_h_XCONS(a) \
351 (eassert (CONSP (a)), (struct Lisp_Cons *) XUNTAG (a, Lisp_Cons)) 339 (eassert (CONSP (a)), (struct Lisp_Cons *) XUNTAG (a, Lisp_Cons))
352#define lisp_h_XHASH(a) XUINT (a) 340#define lisp_h_XHASH(a) XUINT (a)
@@ -676,52 +664,60 @@ enum symbol_trapped_write
676 664
677struct Lisp_Symbol 665struct Lisp_Symbol
678{ 666{
679 bool_bf gcmarkbit : 1; 667 union
680 668 {
681 /* Indicates where the value can be found: 669 struct
682 0 : it's a plain var, the value is in the `value' field. 670 {
683 1 : it's a varalias, the value is really in the `alias' symbol. 671 bool_bf gcmarkbit : 1;
684 2 : it's a localized var, the value is in the `blv' object. 672
685 3 : it's a forwarding variable, the value is in `forward'. */ 673 /* Indicates where the value can be found:
686 ENUM_BF (symbol_redirect) redirect : 3; 674 0 : it's a plain var, the value is in the `value' field.
687 675 1 : it's a varalias, the value is really in the `alias' symbol.
688 /* 0 : normal case, just set the value 676 2 : it's a localized var, the value is in the `blv' object.
689 1 : constant, cannot set, e.g. nil, t, :keywords. 677 3 : it's a forwarding variable, the value is in `forward'. */
690 2 : trap the write, call watcher functions. */ 678 ENUM_BF (symbol_redirect) redirect : 3;
691 ENUM_BF (symbol_trapped_write) trapped_write : 2; 679
692 680 /* 0 : normal case, just set the value
693 /* Interned state of the symbol. This is an enumerator from 681 1 : constant, cannot set, e.g. nil, t, :keywords.
694 enum symbol_interned. */ 682 2 : trap the write, call watcher functions. */
695 unsigned interned : 2; 683 ENUM_BF (symbol_trapped_write) trapped_write : 2;
696 684
697 /* True means that this variable has been explicitly declared 685 /* Interned state of the symbol. This is an enumerator from
698 special (with `defvar' etc), and shouldn't be lexically bound. */ 686 enum symbol_interned. */
699 bool_bf declared_special : 1; 687 unsigned interned : 2;
700 688
701 /* True if pointed to from purespace and hence can't be GC'd. */ 689 /* True means that this variable has been explicitly declared
702 bool_bf pinned : 1; 690 special (with `defvar' etc), and shouldn't be lexically bound. */
703 691 bool_bf declared_special : 1;
704 /* The symbol's name, as a Lisp string. */ 692
705 Lisp_Object name; 693 /* True if pointed to from purespace and hence can't be GC'd. */
706 694 bool_bf pinned : 1;
707 /* Value of the symbol or Qunbound if unbound. Which alternative of the 695
708 union is used depends on the `redirect' field above. */ 696 /* The symbol's name, as a Lisp string. */
709 union { 697 Lisp_Object name;
710 Lisp_Object value; 698
711 struct Lisp_Symbol *alias; 699 /* Value of the symbol or Qunbound if unbound. Which alternative of the
712 struct Lisp_Buffer_Local_Value *blv; 700 union is used depends on the `redirect' field above. */
713 union Lisp_Fwd *fwd; 701 union {
714 } val; 702 Lisp_Object value;
715 703 struct Lisp_Symbol *alias;
716 /* Function value of the symbol or Qnil if not fboundp. */ 704 struct Lisp_Buffer_Local_Value *blv;
717 Lisp_Object function; 705 union Lisp_Fwd *fwd;
706 } val;
707
708 /* Function value of the symbol or Qnil if not fboundp. */
709 Lisp_Object function;
718 710
719 /* The symbol's property list. */ 711 /* The symbol's property list. */
720 Lisp_Object plist; 712 Lisp_Object plist;
721 713
722 /* Next symbol in obarray bucket, if the symbol is interned. */ 714 /* Next symbol in obarray bucket, if the symbol is interned. */
723 struct Lisp_Symbol *next; 715 struct Lisp_Symbol *next;
716 } s;
717 char alignas (GCALIGNMENT) gcaligned;
718 } u;
724}; 719};
720verify (alignof (struct Lisp_Symbol) % GCALIGNMENT == 0);
725 721
726/* Declare a Lisp-callable function. The MAXARGS parameter has the same 722/* Declare a Lisp-callable function. The MAXARGS parameter has the same
727 meaning as in the DEFUN macro, and is used to construct a prototype. */ 723 meaning as in the DEFUN macro, and is used to construct a prototype. */
@@ -795,13 +791,13 @@ struct Lisp_Symbol
795/* Header of vector-like objects. This documents the layout constraints on 791/* Header of vector-like objects. This documents the layout constraints on
796 vectors and pseudovectors (objects of PVEC_xxx subtype). It also prevents 792 vectors and pseudovectors (objects of PVEC_xxx subtype). It also prevents
797 compilers from being fooled by Emacs's type punning: XSETPSEUDOVECTOR 793 compilers from being fooled by Emacs's type punning: XSETPSEUDOVECTOR
798 and PSEUDOVECTORP cast their pointers to struct vectorlike_header *, 794 and PSEUDOVECTORP cast their pointers to union vectorlike_header *,
799 because when two such pointers potentially alias, a compiler won't 795 because when two such pointers potentially alias, a compiler won't
800 incorrectly reorder loads and stores to their size fields. See 796 incorrectly reorder loads and stores to their size fields. See
801 Bug#8546. */ 797 Bug#8546. */
802struct vectorlike_header 798union vectorlike_header
803 { 799 {
804 /* The only field contains various pieces of information: 800 /* The main member contains various pieces of information:
805 - The MSB (ARRAY_MARK_FLAG) holds the gcmarkbit. 801 - The MSB (ARRAY_MARK_FLAG) holds the gcmarkbit.
806 - The next bit (PSEUDOVECTOR_FLAG) indicates whether this is a plain 802 - The next bit (PSEUDOVECTOR_FLAG) indicates whether this is a plain
807 vector (0) or a pseudovector (1). 803 vector (0) or a pseudovector (1).
@@ -821,7 +817,9 @@ struct vectorlike_header
821 Current layout limits the pseudovectors to 63 PVEC_xxx subtypes, 817 Current layout limits the pseudovectors to 63 PVEC_xxx subtypes,
822 4095 Lisp_Objects in GC-ed area and 4095 word-sized other slots. */ 818 4095 Lisp_Objects in GC-ed area and 4095 word-sized other slots. */
823 ptrdiff_t size; 819 ptrdiff_t size;
820 char alignas (GCALIGNMENT) gcaligned;
824 }; 821 };
822verify (alignof (union vectorlike_header) % GCALIGNMENT == 0);
825 823
826INLINE bool 824INLINE bool
827(SYMBOLP) (Lisp_Object x) 825(SYMBOLP) (Lisp_Object x)
@@ -853,7 +851,7 @@ make_lisp_symbol (struct Lisp_Symbol *sym)
853INLINE Lisp_Object 851INLINE Lisp_Object
854builtin_lisp_symbol (int index) 852builtin_lisp_symbol (int index)
855{ 853{
856 return make_lisp_symbol (&lispsym[index].s); 854 return make_lisp_symbol (&lispsym[index]);
857} 855}
858 856
859INLINE void 857INLINE void
@@ -1093,10 +1091,10 @@ INLINE bool
1093 | ((restsize) << PSEUDOVECTOR_SIZE_BITS) \ 1091 | ((restsize) << PSEUDOVECTOR_SIZE_BITS) \
1094 | (lispsize))) 1092 | (lispsize)))
1095 1093
1096/* The cast to struct vectorlike_header * avoids aliasing issues. */ 1094/* The cast to union vectorlike_header * avoids aliasing issues. */
1097#define XSETPSEUDOVECTOR(a, b, code) \ 1095#define XSETPSEUDOVECTOR(a, b, code) \
1098 XSETTYPED_PSEUDOVECTOR (a, b, \ 1096 XSETTYPED_PSEUDOVECTOR (a, b, \
1099 (((struct vectorlike_header *) \ 1097 (((union vectorlike_header *) \
1100 XUNTAG (a, Lisp_Vectorlike)) \ 1098 XUNTAG (a, Lisp_Vectorlike)) \
1101 ->size), \ 1099 ->size), \
1102 code) 1100 code)
@@ -1143,20 +1141,28 @@ make_pointer_integer (void *p)
1143 1141
1144typedef struct interval *INTERVAL; 1142typedef struct interval *INTERVAL;
1145 1143
1146struct GCALIGNED Lisp_Cons 1144struct Lisp_Cons
1145{
1146 union
1147 { 1147 {
1148 /* Car of this cons cell. */ 1148 struct
1149 Lisp_Object car;
1150
1151 union
1152 { 1149 {
1153 /* Cdr of this cons cell. */ 1150 /* Car of this cons cell. */
1154 Lisp_Object cdr; 1151 Lisp_Object car;
1155 1152
1156 /* Used to chain conses on a free list. */ 1153 union
1157 struct Lisp_Cons *chain; 1154 {
1158 } u; 1155 /* Cdr of this cons cell. */
1159 }; 1156 Lisp_Object cdr;
1157
1158 /* Used to chain conses on a free list. */
1159 struct Lisp_Cons *chain;
1160 } u;
1161 } s;
1162 char alignas (GCALIGNMENT) gcaligned;
1163 } u;
1164};
1165verify (alignof (struct Lisp_Cons) % GCALIGNMENT == 0);
1160 1166
1161INLINE bool 1167INLINE bool
1162(NILP) (Lisp_Object x) 1168(NILP) (Lisp_Object x)
@@ -1192,12 +1198,12 @@ INLINE struct Lisp_Cons *
1192INLINE Lisp_Object * 1198INLINE Lisp_Object *
1193xcar_addr (Lisp_Object c) 1199xcar_addr (Lisp_Object c)
1194{ 1200{
1195 return &XCONS (c)->car; 1201 return &XCONS (c)->u.s.car;
1196} 1202}
1197INLINE Lisp_Object * 1203INLINE Lisp_Object *
1198xcdr_addr (Lisp_Object c) 1204xcdr_addr (Lisp_Object c)
1199{ 1205{
1200 return &XCONS (c)->u.cdr; 1206 return &XCONS (c)->u.s.u.cdr;
1201} 1207}
1202 1208
1203/* Use these from normal code. */ 1209/* Use these from normal code. */
@@ -1261,15 +1267,24 @@ CDR_SAFE (Lisp_Object c)
1261 return CONSP (c) ? XCDR (c) : Qnil; 1267 return CONSP (c) ? XCDR (c) : Qnil;
1262} 1268}
1263 1269
1264/* In a string or vector, the sign bit of the `size' is the gc mark bit. */ 1270/* In a string or vector, the sign bit of u.s.size is the gc mark bit. */
1265 1271
1266struct GCALIGNED Lisp_String 1272struct Lisp_String
1273{
1274 union
1267 { 1275 {
1268 ptrdiff_t size; 1276 struct
1269 ptrdiff_t size_byte; 1277 {
1270 INTERVAL intervals; /* Text properties in this string. */ 1278 ptrdiff_t size;
1271 unsigned char *data; 1279 ptrdiff_t size_byte;
1272 }; 1280 INTERVAL intervals; /* Text properties in this string. */
1281 unsigned char *data;
1282 } s;
1283 struct Lisp_String *next;
1284 char alignas (GCALIGNMENT) gcaligned;
1285 } u;
1286};
1287verify (alignof (struct Lisp_String) % GCALIGNMENT == 0);
1273 1288
1274INLINE bool 1289INLINE bool
1275STRINGP (Lisp_Object x) 1290STRINGP (Lisp_Object x)
@@ -1294,7 +1309,7 @@ XSTRING (Lisp_Object a)
1294INLINE bool 1309INLINE bool
1295STRING_MULTIBYTE (Lisp_Object str) 1310STRING_MULTIBYTE (Lisp_Object str)
1296{ 1311{
1297 return 0 <= XSTRING (str)->size_byte; 1312 return 0 <= XSTRING (str)->u.s.size_byte;
1298} 1313}
1299 1314
1300/* An upper bound on the number of bytes in a Lisp string, not 1315/* An upper bound on the number of bytes in a Lisp string, not
@@ -1316,20 +1331,20 @@ STRING_MULTIBYTE (Lisp_Object str)
1316/* Mark STR as a unibyte string. */ 1331/* Mark STR as a unibyte string. */
1317#define STRING_SET_UNIBYTE(STR) \ 1332#define STRING_SET_UNIBYTE(STR) \
1318 do { \ 1333 do { \
1319 if (XSTRING (STR)->size == 0) \ 1334 if (XSTRING (STR)->u.s.size == 0) \
1320 (STR) = empty_unibyte_string; \ 1335 (STR) = empty_unibyte_string; \
1321 else \ 1336 else \
1322 XSTRING (STR)->size_byte = -1; \ 1337 XSTRING (STR)->u.s.size_byte = -1; \
1323 } while (false) 1338 } while (false)
1324 1339
1325/* Mark STR as a multibyte string. Assure that STR contains only 1340/* Mark STR as a multibyte string. Assure that STR contains only
1326 ASCII characters in advance. */ 1341 ASCII characters in advance. */
1327#define STRING_SET_MULTIBYTE(STR) \ 1342#define STRING_SET_MULTIBYTE(STR) \
1328 do { \ 1343 do { \
1329 if (XSTRING (STR)->size == 0) \ 1344 if (XSTRING (STR)->u.s.size == 0) \
1330 (STR) = empty_multibyte_string; \ 1345 (STR) = empty_multibyte_string; \
1331 else \ 1346 else \
1332 XSTRING (STR)->size_byte = XSTRING (STR)->size; \ 1347 XSTRING (STR)->u.s.size_byte = XSTRING (STR)->u.s.size; \
1333 } while (false) 1348 } while (false)
1334 1349
1335/* Convenience functions for dealing with Lisp strings. */ 1350/* Convenience functions for dealing with Lisp strings. */
@@ -1337,7 +1352,7 @@ STRING_MULTIBYTE (Lisp_Object str)
1337INLINE unsigned char * 1352INLINE unsigned char *
1338SDATA (Lisp_Object string) 1353SDATA (Lisp_Object string)
1339{ 1354{
1340 return XSTRING (string)->data; 1355 return XSTRING (string)->u.s.data;
1341} 1356}
1342INLINE char * 1357INLINE char *
1343SSDATA (Lisp_Object string) 1358SSDATA (Lisp_Object string)
@@ -1358,7 +1373,7 @@ SSET (Lisp_Object string, ptrdiff_t index, unsigned char new)
1358INLINE ptrdiff_t 1373INLINE ptrdiff_t
1359SCHARS (Lisp_Object string) 1374SCHARS (Lisp_Object string)
1360{ 1375{
1361 ptrdiff_t nchars = XSTRING (string)->size; 1376 ptrdiff_t nchars = XSTRING (string)->u.s.size;
1362 eassume (0 <= nchars); 1377 eassume (0 <= nchars);
1363 return nchars; 1378 return nchars;
1364} 1379}
@@ -1372,7 +1387,7 @@ STRING_BYTES (struct Lisp_String *s)
1372#ifdef GC_CHECK_STRING_BYTES 1387#ifdef GC_CHECK_STRING_BYTES
1373 ptrdiff_t nbytes = string_bytes (s); 1388 ptrdiff_t nbytes = string_bytes (s);
1374#else 1389#else
1375 ptrdiff_t nbytes = s->size_byte < 0 ? s->size : s->size_byte; 1390 ptrdiff_t nbytes = s->u.s.size_byte < 0 ? s->u.s.size : s->u.s.size_byte;
1376#endif 1391#endif
1377 eassume (0 <= nbytes); 1392 eassume (0 <= nbytes);
1378 return nbytes; 1393 return nbytes;
@@ -1391,14 +1406,14 @@ STRING_SET_CHARS (Lisp_Object string, ptrdiff_t newsize)
1391 eassert (STRING_MULTIBYTE (string) 1406 eassert (STRING_MULTIBYTE (string)
1392 ? 0 <= newsize && newsize <= SBYTES (string) 1407 ? 0 <= newsize && newsize <= SBYTES (string)
1393 : newsize == SCHARS (string)); 1408 : newsize == SCHARS (string));
1394 XSTRING (string)->size = newsize; 1409 XSTRING (string)->u.s.size = newsize;
1395} 1410}
1396 1411
1397/* A regular vector is just a header plus an array of Lisp_Objects. */ 1412/* A regular vector is just a header plus an array of Lisp_Objects. */
1398 1413
1399struct Lisp_Vector 1414struct Lisp_Vector
1400 { 1415 {
1401 struct vectorlike_header header; 1416 union vectorlike_header header;
1402 Lisp_Object contents[FLEXIBLE_ARRAY_MEMBER]; 1417 Lisp_Object contents[FLEXIBLE_ARRAY_MEMBER];
1403 }; 1418 };
1404 1419
@@ -1455,7 +1470,7 @@ PSEUDOVECTOR_TYPE (struct Lisp_Vector *v)
1455 1470
1456/* Can't be used with PVEC_NORMAL_VECTOR. */ 1471/* Can't be used with PVEC_NORMAL_VECTOR. */
1457INLINE bool 1472INLINE bool
1458PSEUDOVECTOR_TYPEP (struct vectorlike_header *a, enum pvec_type code) 1473PSEUDOVECTOR_TYPEP (union vectorlike_header *a, enum pvec_type code)
1459{ 1474{
1460 /* We don't use PSEUDOVECTOR_TYPE here so as to avoid a shift 1475 /* We don't use PSEUDOVECTOR_TYPE here so as to avoid a shift
1461 * operation when `code' is known. */ 1476 * operation when `code' is known. */
@@ -1471,8 +1486,8 @@ PSEUDOVECTORP (Lisp_Object a, int code)
1471 return false; 1486 return false;
1472 else 1487 else
1473 { 1488 {
1474 /* Converting to struct vectorlike_header * avoids aliasing issues. */ 1489 /* Converting to union vectorlike_header * avoids aliasing issues. */
1475 struct vectorlike_header *h = XUNTAG (a, Lisp_Vectorlike); 1490 union vectorlike_header *h = XUNTAG (a, Lisp_Vectorlike);
1476 return PSEUDOVECTOR_TYPEP (h, code); 1491 return PSEUDOVECTOR_TYPEP (h, code);
1477 } 1492 }
1478} 1493}
@@ -1483,7 +1498,7 @@ struct Lisp_Bool_Vector
1483 { 1498 {
1484 /* HEADER.SIZE is the vector's size field. It doesn't have the real size, 1499 /* HEADER.SIZE is the vector's size field. It doesn't have the real size,
1485 just the subtype information. */ 1500 just the subtype information. */
1486 struct vectorlike_header header; 1501 union vectorlike_header header;
1487 /* This is the size in bits. */ 1502 /* This is the size in bits. */
1488 EMACS_INT size; 1503 EMACS_INT size;
1489 /* The actual bits, packed into bytes. 1504 /* The actual bits, packed into bytes.
@@ -1696,7 +1711,7 @@ struct Lisp_Char_Table
1696 pseudovector type information. It holds the size, too. 1711 pseudovector type information. It holds the size, too.
1697 The size counts the defalt, parent, purpose, ascii, 1712 The size counts the defalt, parent, purpose, ascii,
1698 contents, and extras slots. */ 1713 contents, and extras slots. */
1699 struct vectorlike_header header; 1714 union vectorlike_header header;
1700 1715
1701 /* This holds a default value, 1716 /* This holds a default value,
1702 which is used whenever the value for a specific character is nil. */ 1717 which is used whenever the value for a specific character is nil. */
@@ -1738,7 +1753,7 @@ struct Lisp_Sub_Char_Table
1738 { 1753 {
1739 /* HEADER.SIZE is the vector's size field, which also holds the 1754 /* HEADER.SIZE is the vector's size field, which also holds the
1740 pseudovector type information. It holds the size, too. */ 1755 pseudovector type information. It holds the size, too. */
1741 struct vectorlike_header header; 1756 union vectorlike_header header;
1742 1757
1743 /* Depth of this sub char-table. It should be 1, 2, or 3. A sub 1758 /* Depth of this sub char-table. It should be 1, 2, or 3. A sub
1744 char-table of depth 1 contains 16 elements, and each element 1759 char-table of depth 1 contains 16 elements, and each element
@@ -1813,7 +1828,7 @@ CHAR_TABLE_SET (Lisp_Object ct, int idx, Lisp_Object val)
1813 1828
1814struct Lisp_Subr 1829struct Lisp_Subr
1815 { 1830 {
1816 struct vectorlike_header header; 1831 union vectorlike_header header;
1817 union { 1832 union {
1818 Lisp_Object (*a0) (void); 1833 Lisp_Object (*a0) (void);
1819 Lisp_Object (*a1) (Lisp_Object); 1834 Lisp_Object (*a1) (Lisp_Object);
@@ -1909,20 +1924,20 @@ INLINE Lisp_Object
1909INLINE struct Lisp_Symbol * 1924INLINE struct Lisp_Symbol *
1910SYMBOL_ALIAS (struct Lisp_Symbol *sym) 1925SYMBOL_ALIAS (struct Lisp_Symbol *sym)
1911{ 1926{
1912 eassume (sym->redirect == SYMBOL_VARALIAS && sym->val.alias); 1927 eassume (sym->u.s.redirect == SYMBOL_VARALIAS && sym->u.s.val.alias);
1913 return sym->val.alias; 1928 return sym->u.s.val.alias;
1914} 1929}
1915INLINE struct Lisp_Buffer_Local_Value * 1930INLINE struct Lisp_Buffer_Local_Value *
1916SYMBOL_BLV (struct Lisp_Symbol *sym) 1931SYMBOL_BLV (struct Lisp_Symbol *sym)
1917{ 1932{
1918 eassume (sym->redirect == SYMBOL_LOCALIZED && sym->val.blv); 1933 eassume (sym->u.s.redirect == SYMBOL_LOCALIZED && sym->u.s.val.blv);
1919 return sym->val.blv; 1934 return sym->u.s.val.blv;
1920} 1935}
1921INLINE union Lisp_Fwd * 1936INLINE union Lisp_Fwd *
1922SYMBOL_FWD (struct Lisp_Symbol *sym) 1937SYMBOL_FWD (struct Lisp_Symbol *sym)
1923{ 1938{
1924 eassume (sym->redirect == SYMBOL_FORWARDED && sym->val.fwd); 1939 eassume (sym->u.s.redirect == SYMBOL_FORWARDED && sym->u.s.val.fwd);
1925 return sym->val.fwd; 1940 return sym->u.s.val.fwd;
1926} 1941}
1927 1942
1928INLINE void 1943INLINE void
@@ -1934,26 +1949,26 @@ INLINE void
1934INLINE void 1949INLINE void
1935SET_SYMBOL_ALIAS (struct Lisp_Symbol *sym, struct Lisp_Symbol *v) 1950SET_SYMBOL_ALIAS (struct Lisp_Symbol *sym, struct Lisp_Symbol *v)
1936{ 1951{
1937 eassume (sym->redirect == SYMBOL_VARALIAS && v); 1952 eassume (sym->u.s.redirect == SYMBOL_VARALIAS && v);
1938 sym->val.alias = v; 1953 sym->u.s.val.alias = v;
1939} 1954}
1940INLINE void 1955INLINE void
1941SET_SYMBOL_BLV (struct Lisp_Symbol *sym, struct Lisp_Buffer_Local_Value *v) 1956SET_SYMBOL_BLV (struct Lisp_Symbol *sym, struct Lisp_Buffer_Local_Value *v)
1942{ 1957{
1943 eassume (sym->redirect == SYMBOL_LOCALIZED && v); 1958 eassume (sym->u.s.redirect == SYMBOL_LOCALIZED && v);
1944 sym->val.blv = v; 1959 sym->u.s.val.blv = v;
1945} 1960}
1946INLINE void 1961INLINE void
1947SET_SYMBOL_FWD (struct Lisp_Symbol *sym, union Lisp_Fwd *v) 1962SET_SYMBOL_FWD (struct Lisp_Symbol *sym, union Lisp_Fwd *v)
1948{ 1963{
1949 eassume (sym->redirect == SYMBOL_FORWARDED && v); 1964 eassume (sym->u.s.redirect == SYMBOL_FORWARDED && v);
1950 sym->val.fwd = v; 1965 sym->u.s.val.fwd = v;
1951} 1966}
1952 1967
1953INLINE Lisp_Object 1968INLINE Lisp_Object
1954SYMBOL_NAME (Lisp_Object sym) 1969SYMBOL_NAME (Lisp_Object sym)
1955{ 1970{
1956 return XSYMBOL (sym)->name; 1971 return XSYMBOL (sym)->u.s.name;
1957} 1972}
1958 1973
1959/* Value is true if SYM is an interned symbol. */ 1974/* Value is true if SYM is an interned symbol. */
@@ -1961,7 +1976,7 @@ SYMBOL_NAME (Lisp_Object sym)
1961INLINE bool 1976INLINE bool
1962SYMBOL_INTERNED_P (Lisp_Object sym) 1977SYMBOL_INTERNED_P (Lisp_Object sym)
1963{ 1978{
1964 return XSYMBOL (sym)->interned != SYMBOL_UNINTERNED; 1979 return XSYMBOL (sym)->u.s.interned != SYMBOL_UNINTERNED;
1965} 1980}
1966 1981
1967/* Value is true if SYM is interned in initial_obarray. */ 1982/* Value is true if SYM is interned in initial_obarray. */
@@ -1969,7 +1984,7 @@ SYMBOL_INTERNED_P (Lisp_Object sym)
1969INLINE bool 1984INLINE bool
1970SYMBOL_INTERNED_IN_INITIAL_OBARRAY_P (Lisp_Object sym) 1985SYMBOL_INTERNED_IN_INITIAL_OBARRAY_P (Lisp_Object sym)
1971{ 1986{
1972 return XSYMBOL (sym)->interned == SYMBOL_INTERNED_IN_INITIAL_OBARRAY; 1987 return XSYMBOL (sym)->u.s.interned == SYMBOL_INTERNED_IN_INITIAL_OBARRAY;
1973} 1988}
1974 1989
1975/* Value is non-zero if symbol cannot be changed through a simple set, 1990/* Value is non-zero if symbol cannot be changed through a simple set,
@@ -2025,7 +2040,7 @@ struct hash_table_test
2025struct Lisp_Hash_Table 2040struct Lisp_Hash_Table
2026{ 2041{
2027 /* This is for Lisp; the hash table code does not refer to it. */ 2042 /* This is for Lisp; the hash table code does not refer to it. */
2028 struct vectorlike_header header; 2043 union vectorlike_header header;
2029 2044
2030 /* Nil if table is non-weak. Otherwise a symbol describing the 2045 /* Nil if table is non-weak. Otherwise a symbol describing the
2031 weakness of the table. */ 2046 weakness of the table. */
@@ -2945,7 +2960,7 @@ CHECK_NUMBER_CDR (Lisp_Object x)
2945/* This version of DEFUN declares a function prototype with the right 2960/* This version of DEFUN declares a function prototype with the right
2946 arguments, so we can catch errors with maxargs at compile-time. */ 2961 arguments, so we can catch errors with maxargs at compile-time. */
2947#define DEFUN(lname, fnname, sname, minargs, maxargs, intspec, doc) \ 2962#define DEFUN(lname, fnname, sname, minargs, maxargs, intspec, doc) \
2948 static struct GCALIGNED Lisp_Subr sname = \ 2963 static struct Lisp_Subr sname = \
2949 { { PVEC_SUBR << PSEUDOVECTOR_AREA_BITS }, \ 2964 { { PVEC_SUBR << PSEUDOVECTOR_AREA_BITS }, \
2950 { .a ## maxargs = fnname }, \ 2965 { .a ## maxargs = fnname }, \
2951 minargs, maxargs, lname, intspec, 0}; \ 2966 minargs, maxargs, lname, intspec, 0}; \
@@ -3212,25 +3227,25 @@ set_hash_value_slot (struct Lisp_Hash_Table *h, ptrdiff_t idx, Lisp_Object val)
3212INLINE void 3227INLINE void
3213set_symbol_function (Lisp_Object sym, Lisp_Object function) 3228set_symbol_function (Lisp_Object sym, Lisp_Object function)
3214{ 3229{
3215 XSYMBOL (sym)->function = function; 3230 XSYMBOL (sym)->u.s.function = function;
3216} 3231}
3217 3232
3218INLINE void 3233INLINE void
3219set_symbol_plist (Lisp_Object sym, Lisp_Object plist) 3234set_symbol_plist (Lisp_Object sym, Lisp_Object plist)
3220{ 3235{
3221 XSYMBOL (sym)->plist = plist; 3236 XSYMBOL (sym)->u.s.plist = plist;
3222} 3237}
3223 3238
3224INLINE void 3239INLINE void
3225set_symbol_next (Lisp_Object sym, struct Lisp_Symbol *next) 3240set_symbol_next (Lisp_Object sym, struct Lisp_Symbol *next)
3226{ 3241{
3227 XSYMBOL (sym)->next = next; 3242 XSYMBOL (sym)->u.s.next = next;
3228} 3243}
3229 3244
3230INLINE void 3245INLINE void
3231make_symbol_constant (Lisp_Object sym) 3246make_symbol_constant (Lisp_Object sym)
3232{ 3247{
3233 XSYMBOL (sym)->trapped_write = SYMBOL_NOWRITE; 3248 XSYMBOL (sym)->u.s.trapped_write = SYMBOL_NOWRITE;
3234} 3249}
3235 3250
3236/* Buffer-local variable access functions. */ 3251/* Buffer-local variable access functions. */
@@ -3255,7 +3270,7 @@ set_overlay_plist (Lisp_Object overlay, Lisp_Object plist)
3255INLINE INTERVAL 3270INLINE INTERVAL
3256string_intervals (Lisp_Object s) 3271string_intervals (Lisp_Object s)
3257{ 3272{
3258 return XSTRING (s)->intervals; 3273 return XSTRING (s)->u.s.intervals;
3259} 3274}
3260 3275
3261/* Set text properties of S to I. */ 3276/* Set text properties of S to I. */
@@ -3263,7 +3278,7 @@ string_intervals (Lisp_Object s)
3263INLINE void 3278INLINE void
3264set_string_intervals (Lisp_Object s, INTERVAL i) 3279set_string_intervals (Lisp_Object s, INTERVAL i)
3265{ 3280{
3266 XSTRING (s)->intervals = i; 3281 XSTRING (s)->u.s.intervals = i;
3267} 3282}
3268 3283
3269/* Set a Lisp slot in TABLE to VAL. Most code should use this instead 3284/* Set a Lisp slot in TABLE to VAL. Most code should use this instead
@@ -3917,7 +3932,7 @@ typedef emacs_value (*emacs_subr) (emacs_env *, ptrdiff_t,
3917 3932
3918struct Lisp_Module_Function 3933struct Lisp_Module_Function
3919{ 3934{
3920 struct vectorlike_header header; 3935 union vectorlike_header header;
3921 3936
3922 /* Fields traced by GC; these must come first. */ 3937 /* Fields traced by GC; these must come first. */
3923 Lisp_Object documentation; 3938 Lisp_Object documentation;
@@ -4588,20 +4603,6 @@ enum { defined_GC_CHECK_STRING_BYTES = true };
4588enum { defined_GC_CHECK_STRING_BYTES = false }; 4603enum { defined_GC_CHECK_STRING_BYTES = false };
4589#endif 4604#endif
4590 4605
4591/* Struct inside unions that are typically no larger and aligned enough. */
4592
4593union Aligned_Cons
4594{
4595 struct Lisp_Cons s;
4596 double d; intmax_t i; void *p;
4597};
4598
4599union Aligned_String
4600{
4601 struct Lisp_String s;
4602 double d; intmax_t i; void *p;
4603};
4604
4605/* True for stack-based cons and string implementations, respectively. 4606/* True for stack-based cons and string implementations, respectively.
4606 Use stack-based strings only if stack-based cons also works. 4607 Use stack-based strings only if stack-based cons also works.
4607 Otherwise, STACK_CONS would create heap-based cons cells that 4608 Otherwise, STACK_CONS would create heap-based cons cells that
@@ -4609,18 +4610,16 @@ union Aligned_String
4609 4610
4610enum 4611enum
4611 { 4612 {
4612 USE_STACK_CONS = (USE_STACK_LISP_OBJECTS 4613 USE_STACK_CONS = USE_STACK_LISP_OBJECTS,
4613 && alignof (union Aligned_Cons) % GCALIGNMENT == 0),
4614 USE_STACK_STRING = (USE_STACK_CONS 4614 USE_STACK_STRING = (USE_STACK_CONS
4615 && !defined_GC_CHECK_STRING_BYTES 4615 && !defined_GC_CHECK_STRING_BYTES)
4616 && alignof (union Aligned_String) % GCALIGNMENT == 0)
4617 }; 4616 };
4618 4617
4619/* Auxiliary macros used for auto allocation of Lisp objects. Please 4618/* Auxiliary macros used for auto allocation of Lisp objects. Please
4620 use these only in macros like AUTO_CONS that declare a local 4619 use these only in macros like AUTO_CONS that declare a local
4621 variable whose lifetime will be clear to the programmer. */ 4620 variable whose lifetime will be clear to the programmer. */
4622#define STACK_CONS(a, b) \ 4621#define STACK_CONS(a, b) \
4623 make_lisp_ptr (&((union Aligned_Cons) { { a, { b } } }).s, Lisp_Cons) 4622 make_lisp_ptr (&((struct Lisp_Cons) {{{a, {b}}}}), Lisp_Cons)
4624#define AUTO_CONS_EXPR(a, b) \ 4623#define AUTO_CONS_EXPR(a, b) \
4625 (USE_STACK_CONS ? STACK_CONS (a, b) : Fcons (a, b)) 4624 (USE_STACK_CONS ? STACK_CONS (a, b) : Fcons (a, b))
4626 4625
@@ -4666,7 +4665,7 @@ enum
4666 Lisp_Object name = \ 4665 Lisp_Object name = \
4667 (USE_STACK_STRING \ 4666 (USE_STACK_STRING \
4668 ? (make_lisp_ptr \ 4667 ? (make_lisp_ptr \
4669 ((&((union Aligned_String) {{len, -1, 0, (unsigned char *) (str)}}).s), \ 4668 ((&(struct Lisp_String) {{{len, -1, 0, (unsigned char *) (str)}}}), \
4670 Lisp_String)) \ 4669 Lisp_String)) \
4671 : make_unibyte_string (str, len)) 4670 : make_unibyte_string (str, len))
4672 4671
diff --git a/src/lread.c b/src/lread.c
index 19ed07220cd..17463f4ef4e 100644
--- a/src/lread.c
+++ b/src/lread.c
@@ -4043,14 +4043,14 @@ intern_sym (Lisp_Object sym, Lisp_Object obarray, Lisp_Object index)
4043{ 4043{
4044 Lisp_Object *ptr; 4044 Lisp_Object *ptr;
4045 4045
4046 XSYMBOL (sym)->interned = (EQ (obarray, initial_obarray) 4046 XSYMBOL (sym)->u.s.interned = (EQ (obarray, initial_obarray)
4047 ? SYMBOL_INTERNED_IN_INITIAL_OBARRAY 4047 ? SYMBOL_INTERNED_IN_INITIAL_OBARRAY
4048 : SYMBOL_INTERNED); 4048 : SYMBOL_INTERNED);
4049 4049
4050 if (SREF (SYMBOL_NAME (sym), 0) == ':' && EQ (obarray, initial_obarray)) 4050 if (SREF (SYMBOL_NAME (sym), 0) == ':' && EQ (obarray, initial_obarray))
4051 { 4051 {
4052 make_symbol_constant (sym); 4052 make_symbol_constant (sym);
4053 XSYMBOL (sym)->redirect = SYMBOL_PLAINVAL; 4053 XSYMBOL (sym)->u.s.redirect = SYMBOL_PLAINVAL;
4054 SET_SYMBOL_VAL (XSYMBOL (sym), sym); 4054 SET_SYMBOL_VAL (XSYMBOL (sym), sym);
4055 } 4055 }
4056 4056
@@ -4203,16 +4203,16 @@ usage: (unintern NAME OBARRAY) */)
4203 /* if (EQ (tem, Qnil) || EQ (tem, Qt)) 4203 /* if (EQ (tem, Qnil) || EQ (tem, Qt))
4204 error ("Attempt to unintern t or nil"); */ 4204 error ("Attempt to unintern t or nil"); */
4205 4205
4206 XSYMBOL (tem)->interned = SYMBOL_UNINTERNED; 4206 XSYMBOL (tem)->u.s.interned = SYMBOL_UNINTERNED;
4207 4207
4208 hash = oblookup_last_bucket_number; 4208 hash = oblookup_last_bucket_number;
4209 4209
4210 if (EQ (AREF (obarray, hash), tem)) 4210 if (EQ (AREF (obarray, hash), tem))
4211 { 4211 {
4212 if (XSYMBOL (tem)->next) 4212 if (XSYMBOL (tem)->u.s.next)
4213 { 4213 {
4214 Lisp_Object sym; 4214 Lisp_Object sym;
4215 XSETSYMBOL (sym, XSYMBOL (tem)->next); 4215 XSETSYMBOL (sym, XSYMBOL (tem)->u.s.next);
4216 ASET (obarray, hash, sym); 4216 ASET (obarray, hash, sym);
4217 } 4217 }
4218 else 4218 else
@@ -4223,13 +4223,13 @@ usage: (unintern NAME OBARRAY) */)
4223 Lisp_Object tail, following; 4223 Lisp_Object tail, following;
4224 4224
4225 for (tail = AREF (obarray, hash); 4225 for (tail = AREF (obarray, hash);
4226 XSYMBOL (tail)->next; 4226 XSYMBOL (tail)->u.s.next;
4227 tail = following) 4227 tail = following)
4228 { 4228 {
4229 XSETSYMBOL (following, XSYMBOL (tail)->next); 4229 XSETSYMBOL (following, XSYMBOL (tail)->u.s.next);
4230 if (EQ (following, tem)) 4230 if (EQ (following, tem))
4231 { 4231 {
4232 set_symbol_next (tail, XSYMBOL (following)->next); 4232 set_symbol_next (tail, XSYMBOL (following)->u.s.next);
4233 break; 4233 break;
4234 } 4234 }
4235 } 4235 }
@@ -4264,13 +4264,13 @@ oblookup (Lisp_Object obarray, register const char *ptr, ptrdiff_t size, ptrdiff
4264 else if (!SYMBOLP (bucket)) 4264 else if (!SYMBOLP (bucket))
4265 error ("Bad data in guts of obarray"); /* Like CADR error message. */ 4265 error ("Bad data in guts of obarray"); /* Like CADR error message. */
4266 else 4266 else
4267 for (tail = bucket; ; XSETSYMBOL (tail, XSYMBOL (tail)->next)) 4267 for (tail = bucket; ; XSETSYMBOL (tail, XSYMBOL (tail)->u.s.next))
4268 { 4268 {
4269 if (SBYTES (SYMBOL_NAME (tail)) == size_byte 4269 if (SBYTES (SYMBOL_NAME (tail)) == size_byte
4270 && SCHARS (SYMBOL_NAME (tail)) == size 4270 && SCHARS (SYMBOL_NAME (tail)) == size
4271 && !memcmp (SDATA (SYMBOL_NAME (tail)), ptr, size_byte)) 4271 && !memcmp (SDATA (SYMBOL_NAME (tail)), ptr, size_byte))
4272 return tail; 4272 return tail;
4273 else if (XSYMBOL (tail)->next == 0) 4273 else if (XSYMBOL (tail)->u.s.next == 0)
4274 break; 4274 break;
4275 } 4275 }
4276 XSETINT (tem, hash); 4276 XSETINT (tem, hash);
@@ -4290,9 +4290,9 @@ map_obarray (Lisp_Object obarray, void (*fn) (Lisp_Object, Lisp_Object), Lisp_Ob
4290 while (1) 4290 while (1)
4291 { 4291 {
4292 (*fn) (tail, arg); 4292 (*fn) (tail, arg);
4293 if (XSYMBOL (tail)->next == 0) 4293 if (XSYMBOL (tail)->u.s.next == 0)
4294 break; 4294 break;
4295 XSETSYMBOL (tail, XSYMBOL (tail)->next); 4295 XSETSYMBOL (tail, XSYMBOL (tail)->u.s.next);
4296 } 4296 }
4297 } 4297 }
4298} 4298}
@@ -4332,12 +4332,12 @@ init_obarray (void)
4332 DEFSYM (Qnil, "nil"); 4332 DEFSYM (Qnil, "nil");
4333 SET_SYMBOL_VAL (XSYMBOL (Qnil), Qnil); 4333 SET_SYMBOL_VAL (XSYMBOL (Qnil), Qnil);
4334 make_symbol_constant (Qnil); 4334 make_symbol_constant (Qnil);
4335 XSYMBOL (Qnil)->declared_special = true; 4335 XSYMBOL (Qnil)->u.s.declared_special = true;
4336 4336
4337 DEFSYM (Qt, "t"); 4337 DEFSYM (Qt, "t");
4338 SET_SYMBOL_VAL (XSYMBOL (Qt), Qt); 4338 SET_SYMBOL_VAL (XSYMBOL (Qt), Qt);
4339 make_symbol_constant (Qt); 4339 make_symbol_constant (Qt);
4340 XSYMBOL (Qt)->declared_special = true; 4340 XSYMBOL (Qt)->u.s.declared_special = true;
4341 4341
4342 /* Qt is correct even if CANNOT_DUMP. loadup.el will set to nil at end. */ 4342 /* Qt is correct even if CANNOT_DUMP. loadup.el will set to nil at end. */
4343 Vpurify_flag = Qt; 4343 Vpurify_flag = Qt;
@@ -4361,7 +4361,7 @@ defalias (struct Lisp_Subr *sname, char *string)
4361{ 4361{
4362 Lisp_Object sym; 4362 Lisp_Object sym;
4363 sym = intern (string); 4363 sym = intern (string);
4364 XSETSUBR (XSYMBOL (sym)->function, sname); 4364 XSETSUBR (XSYMBOL (sym)->u.s.function, sname);
4365} 4365}
4366#endif /* NOTDEF */ 4366#endif /* NOTDEF */
4367 4367
@@ -4376,8 +4376,8 @@ defvar_int (struct Lisp_Intfwd *i_fwd,
4376 sym = intern_c_string (namestring); 4376 sym = intern_c_string (namestring);
4377 i_fwd->type = Lisp_Fwd_Int; 4377 i_fwd->type = Lisp_Fwd_Int;
4378 i_fwd->intvar = address; 4378 i_fwd->intvar = address;
4379 XSYMBOL (sym)->declared_special = 1; 4379 XSYMBOL (sym)->u.s.declared_special = true;
4380 XSYMBOL (sym)->redirect = SYMBOL_FORWARDED; 4380 XSYMBOL (sym)->u.s.redirect = SYMBOL_FORWARDED;
4381 SET_SYMBOL_FWD (XSYMBOL (sym), (union Lisp_Fwd *)i_fwd); 4381 SET_SYMBOL_FWD (XSYMBOL (sym), (union Lisp_Fwd *)i_fwd);
4382} 4382}
4383 4383
@@ -4391,8 +4391,8 @@ defvar_bool (struct Lisp_Boolfwd *b_fwd,
4391 sym = intern_c_string (namestring); 4391 sym = intern_c_string (namestring);
4392 b_fwd->type = Lisp_Fwd_Bool; 4392 b_fwd->type = Lisp_Fwd_Bool;
4393 b_fwd->boolvar = address; 4393 b_fwd->boolvar = address;
4394 XSYMBOL (sym)->declared_special = 1; 4394 XSYMBOL (sym)->u.s.declared_special = true;
4395 XSYMBOL (sym)->redirect = SYMBOL_FORWARDED; 4395 XSYMBOL (sym)->u.s.redirect = SYMBOL_FORWARDED;
4396 SET_SYMBOL_FWD (XSYMBOL (sym), (union Lisp_Fwd *)b_fwd); 4396 SET_SYMBOL_FWD (XSYMBOL (sym), (union Lisp_Fwd *)b_fwd);
4397 Vbyte_boolean_vars = Fcons (sym, Vbyte_boolean_vars); 4397 Vbyte_boolean_vars = Fcons (sym, Vbyte_boolean_vars);
4398} 4398}
@@ -4410,8 +4410,8 @@ defvar_lisp_nopro (struct Lisp_Objfwd *o_fwd,
4410 sym = intern_c_string (namestring); 4410 sym = intern_c_string (namestring);
4411 o_fwd->type = Lisp_Fwd_Obj; 4411 o_fwd->type = Lisp_Fwd_Obj;
4412 o_fwd->objvar = address; 4412 o_fwd->objvar = address;
4413 XSYMBOL (sym)->declared_special = 1; 4413 XSYMBOL (sym)->u.s.declared_special = true;
4414 XSYMBOL (sym)->redirect = SYMBOL_FORWARDED; 4414 XSYMBOL (sym)->u.s.redirect = SYMBOL_FORWARDED;
4415 SET_SYMBOL_FWD (XSYMBOL (sym), (union Lisp_Fwd *)o_fwd); 4415 SET_SYMBOL_FWD (XSYMBOL (sym), (union Lisp_Fwd *)o_fwd);
4416} 4416}
4417 4417
@@ -4434,8 +4434,8 @@ defvar_kboard (struct Lisp_Kboard_Objfwd *ko_fwd,
4434 sym = intern_c_string (namestring); 4434 sym = intern_c_string (namestring);
4435 ko_fwd->type = Lisp_Fwd_Kboard_Obj; 4435 ko_fwd->type = Lisp_Fwd_Kboard_Obj;
4436 ko_fwd->offset = offset; 4436 ko_fwd->offset = offset;
4437 XSYMBOL (sym)->declared_special = 1; 4437 XSYMBOL (sym)->u.s.declared_special = true;
4438 XSYMBOL (sym)->redirect = SYMBOL_FORWARDED; 4438 XSYMBOL (sym)->u.s.redirect = SYMBOL_FORWARDED;
4439 SET_SYMBOL_FWD (XSYMBOL (sym), (union Lisp_Fwd *)ko_fwd); 4439 SET_SYMBOL_FWD (XSYMBOL (sym), (union Lisp_Fwd *)ko_fwd);
4440} 4440}
4441 4441
@@ -4769,7 +4769,7 @@ to find all the symbols in an obarray, use `mapatoms'. */);
4769 DEFVAR_LISP ("values", Vvalues, 4769 DEFVAR_LISP ("values", Vvalues,
4770 doc: /* List of values of all expressions which were read, evaluated and printed. 4770 doc: /* List of values of all expressions which were read, evaluated and printed.
4771Order is reverse chronological. */); 4771Order is reverse chronological. */);
4772 XSYMBOL (intern ("values"))->declared_special = 0; 4772 XSYMBOL (intern ("values"))->u.s.declared_special = true;
4773 4773
4774 DEFVAR_LISP ("standard-input", Vstandard_input, 4774 DEFVAR_LISP ("standard-input", Vstandard_input,
4775 doc: /* Stream for read to get input from. 4775 doc: /* Stream for read to get input from.
diff --git a/src/minibuf.c b/src/minibuf.c
index a2f3324f99f..913c93001ef 100644
--- a/src/minibuf.c
+++ b/src/minibuf.c
@@ -1280,8 +1280,8 @@ is used to further constrain the set of candidates. */)
1280 error ("Bad data in guts of obarray"); 1280 error ("Bad data in guts of obarray");
1281 elt = bucket; 1281 elt = bucket;
1282 eltstring = elt; 1282 eltstring = elt;
1283 if (XSYMBOL (bucket)->next) 1283 if (XSYMBOL (bucket)->u.s.next)
1284 XSETSYMBOL (bucket, XSYMBOL (bucket)->next); 1284 XSETSYMBOL (bucket, XSYMBOL (bucket)->u.s.next);
1285 else 1285 else
1286 XSETFASTINT (bucket, 0); 1286 XSETFASTINT (bucket, 0);
1287 } 1287 }
@@ -1533,8 +1533,8 @@ with a space are ignored unless STRING itself starts with a space. */)
1533 error ("Bad data in guts of obarray"); 1533 error ("Bad data in guts of obarray");
1534 elt = bucket; 1534 elt = bucket;
1535 eltstring = elt; 1535 eltstring = elt;
1536 if (XSYMBOL (bucket)->next) 1536 if (XSYMBOL (bucket)->u.s.next)
1537 XSETSYMBOL (bucket, XSYMBOL (bucket)->next); 1537 XSETSYMBOL (bucket, XSYMBOL (bucket)->u.s.next);
1538 else 1538 else
1539 XSETFASTINT (bucket, 0); 1539 XSETFASTINT (bucket, 0);
1540 } 1540 }
@@ -1754,9 +1754,9 @@ the values STRING, PREDICATE and `lambda'. */)
1754 tem = tail; 1754 tem = tail;
1755 break; 1755 break;
1756 } 1756 }
1757 if (XSYMBOL (tail)->next == 0) 1757 if (XSYMBOL (tail)->u.s.next == 0)
1758 break; 1758 break;
1759 XSETSYMBOL (tail, XSYMBOL (tail)->next); 1759 XSETSYMBOL (tail, XSYMBOL (tail)->u.s.next);
1760 } 1760 }
1761 } 1761 }
1762 } 1762 }
diff --git a/src/process.h b/src/process.h
index 5a044f669f2..5670f447365 100644
--- a/src/process.h
+++ b/src/process.h
@@ -41,7 +41,7 @@ enum { PROCESS_OPEN_FDS = 6 };
41 41
42struct Lisp_Process 42struct Lisp_Process
43 { 43 {
44 struct vectorlike_header header; 44 union vectorlike_header header;
45 45
46 /* Name of subprocess terminal. */ 46 /* Name of subprocess terminal. */
47 Lisp_Object tty_name; 47 Lisp_Object tty_name;
diff --git a/src/termhooks.h b/src/termhooks.h
index dd6044aabd5..fe4e993c968 100644
--- a/src/termhooks.h
+++ b/src/termhooks.h
@@ -373,7 +373,7 @@ extern struct tty_display_info *gpm_tty;
373struct terminal 373struct terminal
374{ 374{
375 /* This is for Lisp; the terminal code does not refer to it. */ 375 /* This is for Lisp; the terminal code does not refer to it. */
376 struct vectorlike_header header; 376 union vectorlike_header header;
377 377
378 /* Parameter alist of this terminal. */ 378 /* Parameter alist of this terminal. */
379 Lisp_Object param_alist; 379 Lisp_Object param_alist;
diff --git a/src/thread.c b/src/thread.c
index 7335833cf94..c03cdda0fae 100644
--- a/src/thread.c
+++ b/src/thread.c
@@ -26,7 +26,7 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
26#include "coding.h" 26#include "coding.h"
27#include "syssignal.h" 27#include "syssignal.h"
28 28
29static struct GCALIGNED thread_state main_thread; 29static struct thread_state main_thread;
30 30
31struct thread_state *current_thread = &main_thread; 31struct thread_state *current_thread = &main_thread;
32 32
diff --git a/src/thread.h b/src/thread.h
index 19baafbf8a1..1845974bc28 100644
--- a/src/thread.h
+++ b/src/thread.h
@@ -35,7 +35,7 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
35 35
36struct thread_state 36struct thread_state
37{ 37{
38 struct vectorlike_header header; 38 union vectorlike_header header;
39 39
40 /* The buffer in which the last search was performed, or 40 /* The buffer in which the last search was performed, or
41 Qt if the last search was done in a string; 41 Qt if the last search was done in a string;
@@ -230,7 +230,7 @@ typedef struct
230/* A mutex as a lisp object. */ 230/* A mutex as a lisp object. */
231struct Lisp_Mutex 231struct Lisp_Mutex
232{ 232{
233 struct vectorlike_header header; 233 union vectorlike_header header;
234 234
235 /* The name of the mutex, or nil. */ 235 /* The name of the mutex, or nil. */
236 Lisp_Object name; 236 Lisp_Object name;
@@ -261,7 +261,7 @@ XMUTEX (Lisp_Object a)
261/* A condition variable as a lisp object. */ 261/* A condition variable as a lisp object. */
262struct Lisp_CondVar 262struct Lisp_CondVar
263{ 263{
264 struct vectorlike_header header; 264 union vectorlike_header header;
265 265
266 /* The associated mutex. */ 266 /* The associated mutex. */
267 Lisp_Object mutex; 267 Lisp_Object mutex;
diff --git a/src/w32term.h b/src/w32term.h
index 8d08ca0a2bf..de234cb57db 100644
--- a/src/w32term.h
+++ b/src/w32term.h
@@ -431,7 +431,7 @@ extern struct w32_output w32term_display;
431struct scroll_bar { 431struct scroll_bar {
432 432
433 /* This field is shared by all vectors. */ 433 /* This field is shared by all vectors. */
434 struct vectorlike_header header; 434 union vectorlike_header header;
435 435
436 /* The window we're a scroll bar for. */ 436 /* The window we're a scroll bar for. */
437 Lisp_Object window; 437 Lisp_Object window;
diff --git a/src/window.c b/src/window.c
index cc1d2a7b36e..7f472523b49 100644
--- a/src/window.c
+++ b/src/window.c
@@ -3733,8 +3733,8 @@ make_parent_window (Lisp_Object window, bool horflag)
3733 3733
3734 o = XWINDOW (window); 3734 o = XWINDOW (window);
3735 p = allocate_window (); 3735 p = allocate_window ();
3736 memcpy ((char *) p + sizeof (struct vectorlike_header), 3736 memcpy ((char *) p + sizeof (union vectorlike_header),
3737 (char *) o + sizeof (struct vectorlike_header), 3737 (char *) o + sizeof (union vectorlike_header),
3738 word_size * VECSIZE (struct window)); 3738 word_size * VECSIZE (struct window));
3739 /* P's buffer slot may change from nil to a buffer... */ 3739 /* P's buffer slot may change from nil to a buffer... */
3740 adjust_window_count (p, 1); 3740 adjust_window_count (p, 1);
@@ -6232,7 +6232,7 @@ from the top of the window. */)
6232 6232
6233struct save_window_data 6233struct save_window_data
6234 { 6234 {
6235 struct vectorlike_header header; 6235 union vectorlike_header header;
6236 Lisp_Object selected_frame; 6236 Lisp_Object selected_frame;
6237 Lisp_Object current_window; 6237 Lisp_Object current_window;
6238 Lisp_Object f_current_buffer; 6238 Lisp_Object f_current_buffer;
@@ -6260,7 +6260,7 @@ struct save_window_data
6260/* This is saved as a Lisp_Vector. */ 6260/* This is saved as a Lisp_Vector. */
6261struct saved_window 6261struct saved_window
6262{ 6262{
6263 struct vectorlike_header header; 6263 union vectorlike_header header;
6264 6264
6265 Lisp_Object window, buffer, start, pointm, old_pointm; 6265 Lisp_Object window, buffer, start, pointm, old_pointm;
6266 Lisp_Object pixel_left, pixel_top, pixel_height, pixel_width; 6266 Lisp_Object pixel_left, pixel_top, pixel_height, pixel_width;
diff --git a/src/window.h b/src/window.h
index df7c23f824b..25c9686a9f0 100644
--- a/src/window.h
+++ b/src/window.h
@@ -88,7 +88,7 @@ struct cursor_pos
88struct window 88struct window
89 { 89 {
90 /* This is for Lisp; the terminal code does not refer to it. */ 90 /* This is for Lisp; the terminal code does not refer to it. */
91 struct vectorlike_header header; 91 union vectorlike_header header;
92 92
93 /* The frame this window is on. */ 93 /* The frame this window is on. */
94 Lisp_Object frame; 94 Lisp_Object frame;
diff --git a/src/xterm.c b/src/xterm.c
index e11cde771ab..28abfaecde9 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -231,7 +231,7 @@ static void x_sync_with_move (struct frame *, int, int, bool);
231static int handle_one_xevent (struct x_display_info *, 231static int handle_one_xevent (struct x_display_info *,
232 const XEvent *, int *, 232 const XEvent *, int *,
233 struct input_event *); 233 struct input_event *);
234#if ! (defined USE_X_TOOLKIT || defined USE_MOTIF) 234#if ! (defined USE_X_TOOLKIT || defined USE_MOTIF) && defined USE_GTK
235static int x_dispatch_event (XEvent *, Display *); 235static int x_dispatch_event (XEvent *, Display *);
236#endif 236#endif
237static void x_wm_set_window_state (struct frame *, int); 237static void x_wm_set_window_state (struct frame *, int);
@@ -9047,6 +9047,8 @@ handle_one_xevent (struct x_display_info *dpyinfo,
9047 return count; 9047 return count;
9048} 9048}
9049 9049
9050#if defined USE_X_TOOLKIT || defined USE_MOTIF || defined USE_GTK
9051
9050/* Handles the XEvent EVENT on display DISPLAY. 9052/* Handles the XEvent EVENT on display DISPLAY.
9051 This is used for event loops outside the normal event handling, 9053 This is used for event loops outside the normal event handling,
9052 i.e. looping while a popup menu or a dialog is posted. 9054 i.e. looping while a popup menu or a dialog is posted.
@@ -9065,6 +9067,7 @@ x_dispatch_event (XEvent *event, Display *display)
9065 9067
9066 return finish; 9068 return finish;
9067} 9069}
9070#endif
9068 9071
9069/* Read events coming from the X server. 9072/* Read events coming from the X server.
9070 Return as soon as there are no more events to be read. 9073 Return as soon as there are no more events to be read.
@@ -12512,7 +12515,7 @@ x_term_init (Lisp_Object display_name, char *xrm_option, char *resource_name)
12512 { 12515 {
12513 terminal->kboard = allocate_kboard (Qx); 12516 terminal->kboard = allocate_kboard (Qx);
12514 12517
12515 if (!EQ (XSYMBOL (Qvendor_specific_keysyms)->function, Qunbound)) 12518 if (!EQ (XSYMBOL (Qvendor_specific_keysyms)->u.s.function, Qunbound))
12516 { 12519 {
12517 char *vendor = ServerVendor (dpy); 12520 char *vendor = ServerVendor (dpy);
12518 12521
diff --git a/src/xterm.h b/src/xterm.h
index 6274630706f..7ab20ba06c6 100644
--- a/src/xterm.h
+++ b/src/xterm.h
@@ -887,7 +887,7 @@ extern void x_mark_frame_dirty (struct frame *f);
887struct scroll_bar 887struct scroll_bar
888{ 888{
889 /* These fields are shared by all vectors. */ 889 /* These fields are shared by all vectors. */
890 struct vectorlike_header header; 890 union vectorlike_header header;
891 891
892 /* The window we're a scroll bar for. */ 892 /* The window we're a scroll bar for. */
893 Lisp_Object window; 893 Lisp_Object window;
diff --git a/src/xwidget.h b/src/xwidget.h
index 22a8eb3a557..02a0453dabb 100644
--- a/src/xwidget.h
+++ b/src/xwidget.h
@@ -33,7 +33,7 @@ struct window;
33 33
34struct xwidget 34struct xwidget
35{ 35{
36 struct vectorlike_header header; 36 union vectorlike_header header;
37 37
38 /* Auxiliary data. */ 38 /* Auxiliary data. */
39 Lisp_Object plist; 39 Lisp_Object plist;
@@ -62,7 +62,7 @@ struct xwidget
62 62
63struct xwidget_view 63struct xwidget_view
64{ 64{
65 struct vectorlike_header header; 65 union vectorlike_header header;
66 Lisp_Object model; 66 Lisp_Object model;
67 Lisp_Object w; 67 Lisp_Object w;
68 68
diff --git a/test/lisp/net/tramp-tests.el b/test/lisp/net/tramp-tests.el
index 5a7134f5f53..7a7cf933fa3 100644
--- a/test/lisp/net/tramp-tests.el
+++ b/test/lisp/net/tramp-tests.el
@@ -1878,7 +1878,7 @@ This checks also `file-name-as-directory', `file-name-directory',
1878 "Check `copy-file'." 1878 "Check `copy-file'."
1879 (skip-unless (tramp--test-enabled)) 1879 (skip-unless (tramp--test-enabled))
1880 1880
1881 ;; TODO: The quoted case does not work. 1881 ;; TODO: The quoted case does not work. Copy local file to remote.
1882 ;;(dolist (quoted (if tramp--test-expensive-test '(nil t) '(nil))) 1882 ;;(dolist (quoted (if tramp--test-expensive-test '(nil t) '(nil)))
1883 (let (quoted) 1883 (let (quoted)
1884 (let ((tmp-name1 (tramp--test-make-temp-name nil quoted)) 1884 (let ((tmp-name1 (tramp--test-make-temp-name nil quoted))
@@ -2921,7 +2921,188 @@ This tests also `make-symbolic-link', `file-truename' and `add-name-to-file'."
2921 ;; Cleanup. 2921 ;; Cleanup.
2922 (ignore-errors (delete-file tmp-name)))))) 2922 (ignore-errors (delete-file tmp-name))))))
2923 2923
2924(ert-deftest tramp-test24-file-name-completion () 2924(ert-deftest tramp-test24-file-acl ()
2925 "Check that `file-acl' and `set-file-acl' work proper."
2926 (skip-unless (tramp--test-enabled))
2927 (skip-unless (file-acl tramp-test-temporary-file-directory))
2928
2929 ;; TODO: The quoted case does not work. Copy local file to remote.
2930 ;;(dolist (quoted (if tramp--test-expensive-test '(nil t) '(nil)))
2931 (let (quoted)
2932 (let ((tmp-name1 (tramp--test-make-temp-name nil quoted))
2933 (tmp-name2 (tramp--test-make-temp-name nil quoted))
2934 (tmp-name3 (tramp--test-make-temp-name 'local quoted)))
2935 ;; Both files are remote.
2936 (unwind-protect
2937 (progn
2938 ;; Two files with same ACLs.
2939 (write-region "foo" nil tmp-name1)
2940 (should (file-exists-p tmp-name1))
2941 (should (file-acl tmp-name1))
2942 (copy-file tmp-name1 tmp-name2)
2943 (should (file-acl tmp-name2))
2944 (should (string-equal (file-acl tmp-name1) (file-acl tmp-name2)))
2945 ;; Different permissions mean different ACLs.
2946 (set-file-modes tmp-name1 #o777)
2947 (set-file-modes tmp-name2 #o444)
2948 (should-not
2949 (string-equal (file-acl tmp-name1) (file-acl tmp-name2)))
2950 ;; Copy ACL.
2951 (should (set-file-acl tmp-name2 (file-acl tmp-name1)))
2952 (should (string-equal (file-acl tmp-name1) (file-acl tmp-name2)))
2953 ;; An invalid ACL does not harm.
2954 (should-not (set-file-acl tmp-name2 "foo")))
2955
2956 ;; Cleanup.
2957 (ignore-errors (delete-file tmp-name1))
2958 (ignore-errors (delete-file tmp-name2)))
2959
2960 ;; Remote and local file.
2961 (unwind-protect
2962 (when (and (file-acl temporary-file-directory)
2963 (not (tramp--test-windows-nt-or-smb-p)))
2964 ;; Two files with same ACLs.
2965 (write-region "foo" nil tmp-name1)
2966 (should (file-exists-p tmp-name1))
2967 (should (file-acl tmp-name1))
2968 (copy-file tmp-name1 tmp-name3)
2969 (should (file-acl tmp-name3))
2970 (should (string-equal (file-acl tmp-name1) (file-acl tmp-name3)))
2971 ;; Different permissions mean different ACLs.
2972 (set-file-modes tmp-name1 #o777)
2973 (set-file-modes tmp-name3 #o444)
2974 (should-not
2975 (string-equal (file-acl tmp-name1) (file-acl tmp-name3)))
2976 ;; Copy ACL.
2977 (set-file-acl tmp-name3 (file-acl tmp-name1))
2978 (should (string-equal (file-acl tmp-name1) (file-acl tmp-name3)))
2979
2980 ;; Two files with same ACLs.
2981 (delete-file tmp-name1)
2982 (copy-file tmp-name3 tmp-name1)
2983 (should (file-acl tmp-name1))
2984 (should (string-equal (file-acl tmp-name1) (file-acl tmp-name3)))
2985 ;; Different permissions mean different ACLs.
2986 (set-file-modes tmp-name1 #o777)
2987 (set-file-modes tmp-name3 #o444)
2988 (should-not
2989 (string-equal (file-acl tmp-name1) (file-acl tmp-name3)))
2990 ;; Copy ACL.
2991 (set-file-acl tmp-name1 (file-acl tmp-name3))
2992 (should (string-equal (file-acl tmp-name1) (file-acl tmp-name3))))
2993
2994 ;; Cleanup.
2995 (ignore-errors (delete-file tmp-name1))
2996 (ignore-errors (delete-file tmp-name3))))))
2997
2998;; TODO: This test didn't run in reality yet. Pls report if it
2999;; doesn't work as expected.
3000(ert-deftest tramp-test25-file-selinux ()
3001 "Check `file-selinux-context' and `set-file-selinux-context'."
3002 (skip-unless (tramp--test-enabled))
3003 (skip-unless
3004 (not (equal (file-selinux-context tramp-test-temporary-file-directory)
3005 '(nil nil nil nil))))
3006
3007 ;; TODO: The quoted case does not work. Copy local file to remote.
3008 ;;(dolist (quoted (if tramp--test-expensive-test '(nil t) '(nil)))
3009 (let (quoted)
3010 (let ((tmp-name1 (tramp--test-make-temp-name nil quoted))
3011 (tmp-name2 (tramp--test-make-temp-name nil quoted))
3012 (tmp-name3 (tramp--test-make-temp-name 'local quoted)))
3013 ;; Both files are remote.
3014 (unwind-protect
3015 (progn
3016 ;; Two files with same SELINUX context.
3017 (write-region "foo" nil tmp-name1)
3018 (should (file-exists-p tmp-name1))
3019 (should (file-selinux-context tmp-name1))
3020 (copy-file tmp-name1 tmp-name2)
3021 (should (file-selinux-context tmp-name2))
3022 (should
3023 (equal
3024 (file-selinux-context tmp-name1)
3025 (file-selinux-context tmp-name2)))
3026 ;; Different permissions mean different SELINUX context.
3027 (set-file-modes tmp-name1 #o777)
3028 (set-file-modes tmp-name2 #o444)
3029 (should-not
3030 (equal
3031 (file-selinux-context tmp-name1)
3032 (file-selinux-context tmp-name2)))
3033 ;; Copy SELINUX context.
3034 (should
3035 (set-file-selinux-context
3036 tmp-name2 (file-selinux-context tmp-name1)))
3037 (should
3038 (equal
3039 (file-selinux-context tmp-name1)
3040 (file-selinux-context tmp-name2)))
3041 ;; An invalid SELINUX context does not harm.
3042 (should-not (set-file-selinux-context tmp-name2 "foo")))
3043
3044 ;; Cleanup.
3045 (ignore-errors (delete-file tmp-name1))
3046 (ignore-errors (delete-file tmp-name2)))
3047
3048 ;; Remote and local file.
3049 (unwind-protect
3050 (when (not (or (equal (file-selinux-context temporary-file-directory)
3051 '(nil nil nil nil))
3052 (tramp--test-windows-nt-or-smb-p)))
3053 ;; Two files with same SELINUX context.
3054 (write-region "foo" nil tmp-name1)
3055 (should (file-exists-p tmp-name1))
3056 (should (file-selinux-context tmp-name1))
3057 (copy-file tmp-name1 tmp-name3)
3058 (should (file-selinux-context tmp-name3))
3059 (should
3060 (equal
3061 (file-selinux-context tmp-name1)
3062 (file-selinux-context tmp-name3)))
3063 ;; Different permissions mean different SELINUX context.
3064 (set-file-modes tmp-name1 #o777)
3065 (set-file-modes tmp-name3 #o444)
3066 (should-not
3067 (equal
3068 (file-selinux-context tmp-name1)
3069 (file-selinux-context tmp-name3)))
3070 ;; Copy SELINUX context.
3071 (set-file-selinux-context
3072 tmp-name3 (file-selinux-context tmp-name1))
3073 (should
3074 (equal
3075 (file-selinux-context tmp-name1)
3076 (file-selinux-context tmp-name3)))
3077
3078 ;; Two files with same SELINUX context.
3079 (delete-file tmp-name1)
3080 (copy-file tmp-name3 tmp-name1)
3081 (should (file-selinux-context tmp-name1))
3082 (should
3083 (equal
3084 (file-selinux-context tmp-name1)
3085 (file-selinux-context tmp-name3)))
3086 ;; Different permissions mean different SELINUX context.
3087 (set-file-modes tmp-name1 #o777)
3088 (set-file-modes tmp-name3 #o444)
3089 (should-not
3090 (equal
3091 (file-selinux-context tmp-name1)
3092 (file-selinux-context tmp-name3)))
3093 ;; Copy SELINUX context.
3094 (set-file-selinux-context
3095 tmp-name1 (file-selinux-context tmp-name2))
3096 (should
3097 (equal
3098 (file-selinux-context tmp-name1)
3099 (file-selinux-context tmp-name3))))
3100
3101 ;; Cleanup.
3102 (ignore-errors (delete-file tmp-name1))
3103 (ignore-errors (delete-file tmp-name3))))))
3104
3105(ert-deftest tramp-test26-file-name-completion ()
2925 "Check `file-name-completion' and `file-name-all-completions'." 3106 "Check `file-name-completion' and `file-name-all-completions'."
2926 (skip-unless (tramp--test-enabled)) 3107 (skip-unless (tramp--test-enabled))
2927 3108
@@ -3046,7 +3227,7 @@ This tests also `make-symbolic-link', `file-truename' and `add-name-to-file'."
3046 ;; Cleanup. 3227 ;; Cleanup.
3047 (ignore-errors (delete-directory tmp-name 'recursive))))))) 3228 (ignore-errors (delete-directory tmp-name 'recursive)))))))
3048 3229
3049(ert-deftest tramp-test25-load () 3230(ert-deftest tramp-test27-load ()
3050 "Check `load'." 3231 "Check `load'."
3051 (skip-unless (tramp--test-enabled)) 3232 (skip-unless (tramp--test-enabled))
3052 3233
@@ -3069,7 +3250,7 @@ This tests also `make-symbolic-link', `file-truename' and `add-name-to-file'."
3069 (and (featurep 'tramp-test-load) (unload-feature 'tramp-test-load)) 3250 (and (featurep 'tramp-test-load) (unload-feature 'tramp-test-load))
3070 (delete-file tmp-name)))))) 3251 (delete-file tmp-name))))))
3071 3252
3072(ert-deftest tramp-test26-process-file () 3253(ert-deftest tramp-test28-process-file ()
3073 "Check `process-file'." 3254 "Check `process-file'."
3074 :tags '(:expensive-test) 3255 :tags '(:expensive-test)
3075 (skip-unless (tramp--test-enabled)) 3256 (skip-unless (tramp--test-enabled))
@@ -3115,7 +3296,7 @@ This tests also `make-symbolic-link', `file-truename' and `add-name-to-file'."
3115 ;; Cleanup. 3296 ;; Cleanup.
3116 (ignore-errors (delete-file tmp-name)))))) 3297 (ignore-errors (delete-file tmp-name))))))
3117 3298
3118(ert-deftest tramp-test27-start-file-process () 3299(ert-deftest tramp-test29-start-file-process ()
3119 "Check `start-file-process'." 3300 "Check `start-file-process'."
3120 :tags '(:expensive-test) 3301 :tags '(:expensive-test)
3121 (skip-unless (tramp--test-enabled)) 3302 (skip-unless (tramp--test-enabled))
@@ -3180,7 +3361,7 @@ This tests also `make-symbolic-link', `file-truename' and `add-name-to-file'."
3180 ;; Cleanup. 3361 ;; Cleanup.
3181 (ignore-errors (delete-process proc)))))) 3362 (ignore-errors (delete-process proc))))))
3182 3363
3183(ert-deftest tramp-test28-interrupt-process () 3364(ert-deftest tramp-test30-interrupt-process ()
3184 "Check `interrupt-process'." 3365 "Check `interrupt-process'."
3185 :tags '(:expensive-test) 3366 :tags '(:expensive-test)
3186 (skip-unless (tramp--test-enabled)) 3367 (skip-unless (tramp--test-enabled))
@@ -3207,7 +3388,7 @@ This tests also `make-symbolic-link', `file-truename' and `add-name-to-file'."
3207 ;; Cleanup. 3388 ;; Cleanup.
3208 (ignore-errors (delete-process proc))))) 3389 (ignore-errors (delete-process proc)))))
3209 3390
3210(ert-deftest tramp-test29-shell-command () 3391(ert-deftest tramp-test31-shell-command ()
3211 "Check `shell-command'." 3392 "Check `shell-command'."
3212 :tags '(:expensive-test) 3393 :tags '(:expensive-test)
3213 (skip-unless (tramp--test-enabled)) 3394 (skip-unless (tramp--test-enabled))
@@ -3311,7 +3492,7 @@ This tests also `make-symbolic-link', `file-truename' and `add-name-to-file'."
3311 (buffer-substring-no-properties (point-min) (point-max)))) 3492 (buffer-substring-no-properties (point-min) (point-max))))
3312 3493
3313;; This test is inspired by Bug#23952. 3494;; This test is inspired by Bug#23952.
3314(ert-deftest tramp-test30-environment-variables () 3495(ert-deftest tramp-test32-environment-variables ()
3315 "Check that remote processes set / unset environment variables properly." 3496 "Check that remote processes set / unset environment variables properly."
3316 :tags '(:expensive-test) 3497 :tags '(:expensive-test)
3317 (skip-unless (tramp--test-enabled)) 3498 (skip-unless (tramp--test-enabled))
@@ -3389,7 +3570,7 @@ This tests also `make-symbolic-link', `file-truename' and `add-name-to-file'."
3389 (funcall this-shell-command-to-string "set"))))))))) 3570 (funcall this-shell-command-to-string "set")))))))))
3390 3571
3391;; This test is inspired by Bug#27009. 3572;; This test is inspired by Bug#27009.
3392(ert-deftest tramp-test30-environment-variables-and-port-numbers () 3573(ert-deftest tramp-test32-environment-variables-and-port-numbers ()
3393 "Check that two connections with separate ports are different." 3574 "Check that two connections with separate ports are different."
3394 (skip-unless (tramp--test-enabled)) 3575 (skip-unless (tramp--test-enabled))
3395 ;; We test it only for the mock-up connection; otherwise there might 3576 ;; We test it only for the mock-up connection; otherwise there might
@@ -3428,7 +3609,7 @@ This tests also `make-symbolic-link', `file-truename' and `add-name-to-file'."
3428 (tramp-cleanup-connection (tramp-dissect-file-name dir))))) 3609 (tramp-cleanup-connection (tramp-dissect-file-name dir)))))
3429 3610
3430;; The functions were introduced in Emacs 26.1. 3611;; The functions were introduced in Emacs 26.1.
3431(ert-deftest tramp-test31-explicit-shell-file-name () 3612(ert-deftest tramp-test33-explicit-shell-file-name ()
3432 "Check that connection-local `explicit-shell-file-name' is set." 3613 "Check that connection-local `explicit-shell-file-name' is set."
3433 :tags '(:expensive-test) 3614 :tags '(:expensive-test)
3434 (skip-unless (tramp--test-enabled)) 3615 (skip-unless (tramp--test-enabled))
@@ -3472,7 +3653,7 @@ This tests also `make-symbolic-link', `file-truename' and `add-name-to-file'."
3472 (put 'explicit-shell-file-name 'permanent-local nil) 3653 (put 'explicit-shell-file-name 'permanent-local nil)
3473 (kill-buffer "*shell*")))) 3654 (kill-buffer "*shell*"))))
3474 3655
3475(ert-deftest tramp-test32-vc-registered () 3656(ert-deftest tramp-test34-vc-registered ()
3476 "Check `vc-registered'." 3657 "Check `vc-registered'."
3477 :tags '(:expensive-test) 3658 :tags '(:expensive-test)
3478 (skip-unless (tramp--test-enabled)) 3659 (skip-unless (tramp--test-enabled))
@@ -3544,7 +3725,7 @@ This tests also `make-symbolic-link', `file-truename' and `add-name-to-file'."
3544 ;; Cleanup. 3725 ;; Cleanup.
3545 (ignore-errors (delete-directory tmp-name1 'recursive)))))) 3726 (ignore-errors (delete-directory tmp-name1 'recursive))))))
3546 3727
3547(ert-deftest tramp-test33-make-auto-save-file-name () 3728(ert-deftest tramp-test35-make-auto-save-file-name ()
3548 "Check `make-auto-save-file-name'." 3729 "Check `make-auto-save-file-name'."
3549 (skip-unless (tramp--test-enabled)) 3730 (skip-unless (tramp--test-enabled))
3550 3731
@@ -3638,7 +3819,7 @@ This tests also `make-symbolic-link', `file-truename' and `add-name-to-file'."
3638 (ignore-errors (delete-file tmp-name1)) 3819 (ignore-errors (delete-file tmp-name1))
3639 (ignore-errors (delete-directory tmp-name2 'recursive)))))) 3820 (ignore-errors (delete-directory tmp-name2 'recursive))))))
3640 3821
3641(ert-deftest tramp-test34-find-backup-file-name () 3822(ert-deftest tramp-test36-find-backup-file-name ()
3642 "Check `find-backup-file-name'." 3823 "Check `find-backup-file-name'."
3643 (skip-unless (tramp--test-enabled)) 3824 (skip-unless (tramp--test-enabled))
3644 3825
@@ -3734,7 +3915,7 @@ This tests also `make-symbolic-link', `file-truename' and `add-name-to-file'."
3734 (ignore-errors (delete-directory tmp-name2 'recursive)))))) 3915 (ignore-errors (delete-directory tmp-name2 'recursive))))))
3735 3916
3736;; The functions were introduced in Emacs 26.1. 3917;; The functions were introduced in Emacs 26.1.
3737(ert-deftest tramp-test35-make-nearby-temp-file () 3918(ert-deftest tramp-test37-make-nearby-temp-file ()
3738 "Check `make-nearby-temp-file' and `temporary-file-directory'." 3919 "Check `make-nearby-temp-file' and `temporary-file-directory'."
3739 (skip-unless (tramp--test-enabled)) 3920 (skip-unless (tramp--test-enabled))
3740 ;; Since Emacs 26.1. 3921 ;; Since Emacs 26.1.
@@ -3999,7 +4180,7 @@ This requires restrictions of file name syntax."
3999 (ignore-errors (delete-directory tmp-name2 'recursive)))))) 4180 (ignore-errors (delete-directory tmp-name2 'recursive))))))
4000 4181
4001(defun tramp--test-special-characters () 4182(defun tramp--test-special-characters ()
4002 "Perform the test in `tramp-test36-special-characters*'." 4183 "Perform the test in `tramp-test38-special-characters*'."
4003 ;; Newlines, slashes and backslashes in file names are not 4184 ;; Newlines, slashes and backslashes in file names are not
4004 ;; supported. So we don't test. And we don't test the tab 4185 ;; supported. So we don't test. And we don't test the tab
4005 ;; character on Windows or Cygwin, because the backslash is 4186 ;; character on Windows or Cygwin, because the backslash is
@@ -4042,7 +4223,7 @@ This requires restrictions of file name syntax."
4042 "{foo}bar{baz}")) 4223 "{foo}bar{baz}"))
4043 4224
4044;; These tests are inspired by Bug#17238. 4225;; These tests are inspired by Bug#17238.
4045(ert-deftest tramp-test36-special-characters () 4226(ert-deftest tramp-test38-special-characters ()
4046 "Check special characters in file names." 4227 "Check special characters in file names."
4047 (skip-unless (tramp--test-enabled)) 4228 (skip-unless (tramp--test-enabled))
4048 (skip-unless (not (tramp--test-rsync-p))) 4229 (skip-unless (not (tramp--test-rsync-p)))
@@ -4050,7 +4231,7 @@ This requires restrictions of file name syntax."
4050 4231
4051 (tramp--test-special-characters)) 4232 (tramp--test-special-characters))
4052 4233
4053(ert-deftest tramp-test36-special-characters-with-stat () 4234(ert-deftest tramp-test38-special-characters-with-stat ()
4054 "Check special characters in file names. 4235 "Check special characters in file names.
4055Use the `stat' command." 4236Use the `stat' command."
4056 :tags '(:expensive-test) 4237 :tags '(:expensive-test)
@@ -4068,7 +4249,7 @@ Use the `stat' command."
4068 tramp-connection-properties))) 4249 tramp-connection-properties)))
4069 (tramp--test-special-characters))) 4250 (tramp--test-special-characters)))
4070 4251
4071(ert-deftest tramp-test36-special-characters-with-perl () 4252(ert-deftest tramp-test38-special-characters-with-perl ()
4072 "Check special characters in file names. 4253 "Check special characters in file names.
4073Use the `perl' command." 4254Use the `perl' command."
4074 :tags '(:expensive-test) 4255 :tags '(:expensive-test)
@@ -4089,7 +4270,7 @@ Use the `perl' command."
4089 tramp-connection-properties))) 4270 tramp-connection-properties)))
4090 (tramp--test-special-characters))) 4271 (tramp--test-special-characters)))
4091 4272
4092(ert-deftest tramp-test36-special-characters-with-ls () 4273(ert-deftest tramp-test38-special-characters-with-ls ()
4093 "Check special characters in file names. 4274 "Check special characters in file names.
4094Use the `ls' command." 4275Use the `ls' command."
4095 :tags '(:expensive-test) 4276 :tags '(:expensive-test)
@@ -4112,7 +4293,7 @@ Use the `ls' command."
4112 (tramp--test-special-characters))) 4293 (tramp--test-special-characters)))
4113 4294
4114(defun tramp--test-utf8 () 4295(defun tramp--test-utf8 ()
4115 "Perform the test in `tramp-test37-utf8*'." 4296 "Perform the test in `tramp-test39-utf8*'."
4116 (let* ((utf8 (if (and (eq system-type 'darwin) 4297 (let* ((utf8 (if (and (eq system-type 'darwin)
4117 (memq 'utf-8-hfs (coding-system-list))) 4298 (memq 'utf-8-hfs (coding-system-list)))
4118 'utf-8-hfs 'utf-8)) 4299 'utf-8-hfs 'utf-8))
@@ -4127,7 +4308,7 @@ Use the `ls' command."
4127 "银河系漫游指南系列" 4308 "银河系漫游指南系列"
4128 "Автостопом по гала́ктике"))) 4309 "Автостопом по гала́ктике")))
4129 4310
4130(ert-deftest tramp-test37-utf8 () 4311(ert-deftest tramp-test39-utf8 ()
4131 "Check UTF8 encoding in file names and file contents." 4312 "Check UTF8 encoding in file names and file contents."
4132 (skip-unless (tramp--test-enabled)) 4313 (skip-unless (tramp--test-enabled))
4133 (skip-unless (not (tramp--test-docker-p))) 4314 (skip-unless (not (tramp--test-docker-p)))
@@ -4137,7 +4318,7 @@ Use the `ls' command."
4137 4318
4138 (tramp--test-utf8)) 4319 (tramp--test-utf8))
4139 4320
4140(ert-deftest tramp-test37-utf8-with-stat () 4321(ert-deftest tramp-test39-utf8-with-stat ()
4141 "Check UTF8 encoding in file names and file contents. 4322 "Check UTF8 encoding in file names and file contents.
4142Use the `stat' command." 4323Use the `stat' command."
4143 :tags '(:expensive-test) 4324 :tags '(:expensive-test)
@@ -4157,7 +4338,7 @@ Use the `stat' command."
4157 tramp-connection-properties))) 4338 tramp-connection-properties)))
4158 (tramp--test-utf8))) 4339 (tramp--test-utf8)))
4159 4340
4160(ert-deftest tramp-test37-utf8-with-perl () 4341(ert-deftest tramp-test39-utf8-with-perl ()
4161 "Check UTF8 encoding in file names and file contents. 4342 "Check UTF8 encoding in file names and file contents.
4162Use the `perl' command." 4343Use the `perl' command."
4163 :tags '(:expensive-test) 4344 :tags '(:expensive-test)
@@ -4180,7 +4361,7 @@ Use the `perl' command."
4180 tramp-connection-properties))) 4361 tramp-connection-properties)))
4181 (tramp--test-utf8))) 4362 (tramp--test-utf8)))
4182 4363
4183(ert-deftest tramp-test37-utf8-with-ls () 4364(ert-deftest tramp-test39-utf8-with-ls ()
4184 "Check UTF8 encoding in file names and file contents. 4365 "Check UTF8 encoding in file names and file contents.
4185Use the `ls' command." 4366Use the `ls' command."
4186 :tags '(:expensive-test) 4367 :tags '(:expensive-test)
@@ -4203,7 +4384,7 @@ Use the `ls' command."
4203 tramp-connection-properties))) 4384 tramp-connection-properties)))
4204 (tramp--test-utf8))) 4385 (tramp--test-utf8)))
4205 4386
4206(ert-deftest tramp-test38-file-system-info () 4387(ert-deftest tramp-test40-file-system-info ()
4207 "Check that `file-system-info' returns proper values." 4388 "Check that `file-system-info' returns proper values."
4208 (skip-unless (tramp--test-enabled)) 4389 (skip-unless (tramp--test-enabled))
4209 ;; Since Emacs 27.1. 4390 ;; Since Emacs 27.1.
@@ -4225,7 +4406,7 @@ Use the `ls' command."
4225 (ert-fail (format "`%s' timed out" (ert-test-name (ert-running-test))))) 4406 (ert-fail (format "`%s' timed out" (ert-test-name (ert-running-test)))))
4226 4407
4227;; This test is inspired by Bug#16928. 4408;; This test is inspired by Bug#16928.
4228(ert-deftest tramp-test39-asynchronous-requests () 4409(ert-deftest tramp-test41-asynchronous-requests ()
4229 "Check parallel asynchronous requests. 4410 "Check parallel asynchronous requests.
4230Such requests could arrive from timers, process filters and 4411Such requests could arrive from timers, process filters and
4231process sentinels. They shall not disturb each other." 4412process sentinels. They shall not disturb each other."
@@ -4382,7 +4563,7 @@ process sentinels. They shall not disturb each other."
4382 (ignore-errors (cancel-timer timer)) 4563 (ignore-errors (cancel-timer timer))
4383 (ignore-errors (delete-directory tmp-name 'recursive))))))) 4564 (ignore-errors (delete-directory tmp-name 'recursive)))))))
4384 4565
4385(ert-deftest tramp-test40-recursive-load () 4566(ert-deftest tramp-test42-recursive-load ()
4386 "Check that Tramp does not fail due to recursive load." 4567 "Check that Tramp does not fail due to recursive load."
4387 (skip-unless (tramp--test-enabled)) 4568 (skip-unless (tramp--test-enabled))
4388 4569
@@ -4405,7 +4586,7 @@ process sentinels. They shall not disturb each other."
4405 (mapconcat 'shell-quote-argument load-path " -L ") 4586 (mapconcat 'shell-quote-argument load-path " -L ")
4406 (shell-quote-argument code)))))))) 4587 (shell-quote-argument code))))))))
4407 4588
4408(ert-deftest tramp-test41-remote-load-path () 4589(ert-deftest tramp-test43-remote-load-path ()
4409 "Check that Tramp autoloads its packages with remote `load-path'." 4590 "Check that Tramp autoloads its packages with remote `load-path'."
4410 ;; `tramp-cleanup-all-connections' is autoloaded from tramp-cmds.el. 4591 ;; `tramp-cleanup-all-connections' is autoloaded from tramp-cmds.el.
4411 ;; It shall still work, when a remote file name is in the 4592 ;; It shall still work, when a remote file name is in the
@@ -4428,7 +4609,7 @@ process sentinels. They shall not disturb each other."
4428 (mapconcat 'shell-quote-argument load-path " -L ") 4609 (mapconcat 'shell-quote-argument load-path " -L ")
4429 (shell-quote-argument code))))))) 4610 (shell-quote-argument code)))))))
4430 4611
4431(ert-deftest tramp-test42-delay-load () 4612(ert-deftest tramp-test44-delay-load ()
4432 "Check that Tramp is loaded lazily, only when needed." 4613 "Check that Tramp is loaded lazily, only when needed."
4433 ;; Tramp is neither loaded at Emacs startup, nor when completing a 4614 ;; Tramp is neither loaded at Emacs startup, nor when completing a
4434 ;; non-Tramp file name like "/foo". Completing a Tramp-alike file 4615 ;; non-Tramp file name like "/foo". Completing a Tramp-alike file
@@ -4454,7 +4635,7 @@ process sentinels. They shall not disturb each other."
4454 (mapconcat 'shell-quote-argument load-path " -L ") 4635 (mapconcat 'shell-quote-argument load-path " -L ")
4455 (shell-quote-argument (format code tm))))))))) 4636 (shell-quote-argument (format code tm)))))))))
4456 4637
4457(ert-deftest tramp-test43-unload () 4638(ert-deftest tramp-test45-unload ()
4458 "Check that Tramp and its subpackages unload completely. 4639 "Check that Tramp and its subpackages unload completely.
4459Since it unloads Tramp, it shall be the last test to run." 4640Since it unloads Tramp, it shall be the last test to run."
4460 :tags '(:expensive-test) 4641 :tags '(:expensive-test)
@@ -4504,18 +4685,14 @@ Since it unloads Tramp, it shall be the last test to run."
4504 4685
4505;; * dired-compress-file 4686;; * dired-compress-file
4506;; * dired-uncache 4687;; * dired-uncache
4507;; * file-acl
4508;; * file-name-case-insensitive-p 4688;; * file-name-case-insensitive-p
4509;; * file-selinux-context
4510;; * set-file-acl
4511;; * set-file-selinux-context
4512 4689
4513;; * Work on skipped tests. Make a comment, when it is impossible. 4690;; * Work on skipped tests. Make a comment, when it is impossible.
4514;; * Fix `tramp-test05-expand-file-name-relative' in `expand-file-name'. 4691;; * Fix `tramp-test05-expand-file-name-relative' in `expand-file-name'.
4515;; * Fix `tramp-test06-directory-file-name' for `ftp'. 4692;; * Fix `tramp-test06-directory-file-name' for `ftp'.
4516;; * Fix `tramp-test27-start-file-process' on MS Windows (`process-send-eof'?). 4693;; * Fix `tramp-test29-start-file-process' on MS Windows (`process-send-eof'?).
4517;; * Fix `tramp-test28-interrupt-process', timeout doesn't work reliably. 4694;; * Fix `tramp-test30-interrupt-process', timeout doesn't work reliably.
4518;; * Fix Bug#16928 in `tramp-test39-asynchronous-requests'. 4695;; * Fix Bug#16928 in `tramp-test41-asynchronous-requests'.
4519 4696
4520(defun tramp-test-all (&optional interactive) 4697(defun tramp-test-all (&optional interactive)
4521 "Run all tests for \\[tramp]." 4698 "Run all tests for \\[tramp]."
diff --git a/test/lisp/progmodes/flymake-tests.el b/test/lisp/progmodes/flymake-tests.el
index 05214e7a927..8eb180a5130 100644
--- a/test/lisp/progmodes/flymake-tests.el
+++ b/test/lisp/progmodes/flymake-tests.el
@@ -124,7 +124,10 @@ SEVERITY-PREDICATE is used to setup
124 ;; Some versions of ruby fail if HOME doesn't exist (bug#29187). 124 ;; Some versions of ruby fail if HOME doesn't exist (bug#29187).
125 (let* ((tempdir (make-temp-file "flymake-tests-ruby" t)) 125 (let* ((tempdir (make-temp-file "flymake-tests-ruby" t))
126 (process-environment (cons (format "HOME=%s" tempdir) 126 (process-environment (cons (format "HOME=%s" tempdir)
127 process-environment))) 127 process-environment))
128 ;; And see https://debbugs.gnu.org/cgi/bugreport.cgi?bug=19657#20
129 ;; for this particular yuckiness
130 (abbreviated-home-dir nil))
128 (unwind-protect 131 (unwind-protect
129 (flymake-tests--with-flymake ("test.rb") 132 (flymake-tests--with-flymake ("test.rb")
130 (flymake-goto-next-error) 133 (flymake-goto-next-error)
@@ -333,6 +336,38 @@ SEVERITY-PREDICATE is used to setup
333 (should-error (flymake-goto-prev-error nil nil t)) 336 (should-error (flymake-goto-prev-error nil nil t))
334 ))))) 337 )))))
335 338
339(ert-deftest eob-region-and-trailing-newline ()
340 "`flymake-diag-region' at eob with varying trailing newlines."
341 (cl-flet ((diag-region-substring
342 (line col)
343 (pcase-let
344 ((`(,a . ,b) (flymake-diag-region (current-buffer) line col)))
345 (buffer-substring a b))))
346 (with-temp-buffer
347 (insert "beg\nmmm\nend")
348 (should (equal
349 (diag-region-substring 3 3)
350 "d"))
351 (should (equal
352 (diag-region-substring 3 nil)
353 "end"))
354 (insert "\n")
355 (should (equal
356 (diag-region-substring 4 1)
357 "end"))
358 (should (equal
359 (diag-region-substring 4 nil)
360 "end"))
361 (insert "\n")
362 (should (equal
363 (diag-region-substring 5 1)
364 "\n"))
365 (should (equal
366 (diag-region-substring 5 nil)
367 "\n")))))
368
369
370
336(provide 'flymake-tests) 371(provide 'flymake-tests)
337 372
338;;; flymake.el ends here 373;;; flymake.el ends here