diff options
| author | Paul Eggert | 2019-04-01 11:54:23 -0700 |
|---|---|---|
| committer | Paul Eggert | 2019-04-01 12:02:37 -0700 |
| commit | 9287813da1ae9076f29be111674d1795bee66447 (patch) | |
| tree | d48781deb3ccc24f40de2944efdccc6a84280fd5 /src | |
| parent | 197fbfc71f49b307baa3831a30732c3a0c4c7420 (diff) | |
| download | emacs-9287813da1ae9076f29be111674d1795bee66447.tar.gz emacs-9287813da1ae9076f29be111674d1795bee66447.zip | |
Fix union Lisp_Fwd * alignment bug
It's not portable to cast (e.g.) struct Lisp_Objfwd * to union
Lisp_Fwd * and then back again, because the compiler can then assume
that the pointer is aligned for union Lisp_Fwd * when accessing
the struct Lisp_Objfwd * components, and this assumption might
be incorrect becase we don't force that alignment.
* src/lisp.h (lispfwd): New type, replacing ...
(union Lisp_Fwd): ... this type, which was removed.
All uses changed.
(SET_SYMBOL_FWD): 2nd arg is now void *, not lispfwd.
All uses changed (casts no longer needed; they were
not portable anyway).
Diffstat (limited to 'src')
| -rw-r--r-- | src/buffer.c | 8 | ||||
| -rw-r--r-- | src/data.c | 74 | ||||
| -rw-r--r-- | src/lisp.h | 41 | ||||
| -rw-r--r-- | src/lread.c | 8 | ||||
| -rw-r--r-- | src/pdumper.c | 26 |
5 files changed, 80 insertions, 77 deletions
diff --git a/src/buffer.c b/src/buffer.c index 7c4691e52c0..c0f7521c9e1 100644 --- a/src/buffer.c +++ b/src/buffer.c | |||
| @@ -1207,7 +1207,7 @@ buffer_local_value (Lisp_Object variable, Lisp_Object buffer) | |||
| 1207 | result = Fassoc (variable, BVAR (buf, local_var_alist), Qnil); | 1207 | result = Fassoc (variable, BVAR (buf, local_var_alist), Qnil); |
| 1208 | if (!NILP (result)) | 1208 | if (!NILP (result)) |
| 1209 | { | 1209 | { |
| 1210 | if (blv->fwd) | 1210 | if (blv->fwd.fwdptr) |
| 1211 | { /* What binding is loaded right now? */ | 1211 | { /* What binding is loaded right now? */ |
| 1212 | Lisp_Object current_alist_element = blv->valcell; | 1212 | Lisp_Object current_alist_element = blv->valcell; |
| 1213 | 1213 | ||
| @@ -1228,7 +1228,7 @@ buffer_local_value (Lisp_Object variable, Lisp_Object buffer) | |||
| 1228 | } | 1228 | } |
| 1229 | case SYMBOL_FORWARDED: | 1229 | case SYMBOL_FORWARDED: |
| 1230 | { | 1230 | { |
| 1231 | union Lisp_Fwd *fwd = SYMBOL_FWD (sym); | 1231 | lispfwd fwd = SYMBOL_FWD (sym); |
| 1232 | if (BUFFER_OBJFWDP (fwd)) | 1232 | if (BUFFER_OBJFWDP (fwd)) |
| 1233 | result = per_buffer_value (buf, XBUFFER_OBJFWD (fwd)->offset); | 1233 | result = per_buffer_value (buf, XBUFFER_OBJFWD (fwd)->offset); |
| 1234 | else | 1234 | else |
| @@ -2140,7 +2140,7 @@ void set_buffer_internal_2 (register struct buffer *b) | |||
| 2140 | Lisp_Object var = XCAR (XCAR (tail)); | 2140 | Lisp_Object var = XCAR (XCAR (tail)); |
| 2141 | struct Lisp_Symbol *sym = XSYMBOL (var); | 2141 | struct Lisp_Symbol *sym = XSYMBOL (var); |
| 2142 | if (sym->u.s.redirect == SYMBOL_LOCALIZED /* Just to be sure. */ | 2142 | if (sym->u.s.redirect == SYMBOL_LOCALIZED /* Just to be sure. */ |
| 2143 | && SYMBOL_BLV (sym)->fwd) | 2143 | && SYMBOL_BLV (sym)->fwd.fwdptr) |
| 2144 | /* Just reference the variable | 2144 | /* Just reference the variable |
| 2145 | to cause it to become set for this buffer. */ | 2145 | to cause it to become set for this buffer. */ |
| 2146 | Fsymbol_value (var); | 2146 | Fsymbol_value (var); |
| @@ -5444,7 +5444,7 @@ defvar_per_buffer (struct Lisp_Buffer_Objfwd *bo_fwd, const char *namestring, | |||
| 5444 | bo_fwd->predicate = predicate; | 5444 | bo_fwd->predicate = predicate; |
| 5445 | sym->u.s.declared_special = true; | 5445 | sym->u.s.declared_special = true; |
| 5446 | sym->u.s.redirect = SYMBOL_FORWARDED; | 5446 | sym->u.s.redirect = SYMBOL_FORWARDED; |
| 5447 | SET_SYMBOL_FWD (sym, (union Lisp_Fwd *) bo_fwd); | 5447 | SET_SYMBOL_FWD (sym, bo_fwd); |
| 5448 | XSETSYMBOL (PER_BUFFER_SYMBOL (offset), sym); | 5448 | XSETSYMBOL (PER_BUFFER_SYMBOL (offset), sym); |
| 5449 | 5449 | ||
| 5450 | if (PER_BUFFER_IDX (offset) == 0) | 5450 | if (PER_BUFFER_IDX (offset) == 0) |
diff --git a/src/data.c b/src/data.c index 30c578dee94..936bb74f69a 100644 --- a/src/data.c +++ b/src/data.c | |||
| @@ -42,49 +42,49 @@ static void swap_in_symval_forwarding (struct Lisp_Symbol *, | |||
| 42 | struct Lisp_Buffer_Local_Value *); | 42 | struct Lisp_Buffer_Local_Value *); |
| 43 | 43 | ||
| 44 | static bool | 44 | static bool |
| 45 | BOOLFWDP (union Lisp_Fwd *a) | 45 | BOOLFWDP (lispfwd a) |
| 46 | { | 46 | { |
| 47 | return XFWDTYPE (a) == Lisp_Fwd_Bool; | 47 | return XFWDTYPE (a) == Lisp_Fwd_Bool; |
| 48 | } | 48 | } |
| 49 | static bool | 49 | static bool |
| 50 | INTFWDP (union Lisp_Fwd *a) | 50 | INTFWDP (lispfwd a) |
| 51 | { | 51 | { |
| 52 | return XFWDTYPE (a) == Lisp_Fwd_Int; | 52 | return XFWDTYPE (a) == Lisp_Fwd_Int; |
| 53 | } | 53 | } |
| 54 | static bool | 54 | static bool |
| 55 | KBOARD_OBJFWDP (union Lisp_Fwd *a) | 55 | KBOARD_OBJFWDP (lispfwd a) |
| 56 | { | 56 | { |
| 57 | return XFWDTYPE (a) == Lisp_Fwd_Kboard_Obj; | 57 | return XFWDTYPE (a) == Lisp_Fwd_Kboard_Obj; |
| 58 | } | 58 | } |
| 59 | static bool | 59 | static bool |
| 60 | OBJFWDP (union Lisp_Fwd *a) | 60 | OBJFWDP (lispfwd a) |
| 61 | { | 61 | { |
| 62 | return XFWDTYPE (a) == Lisp_Fwd_Obj; | 62 | return XFWDTYPE (a) == Lisp_Fwd_Obj; |
| 63 | } | 63 | } |
| 64 | 64 | ||
| 65 | static struct Lisp_Boolfwd * | 65 | static struct Lisp_Boolfwd * |
| 66 | XBOOLFWD (union Lisp_Fwd *a) | 66 | XBOOLFWD (lispfwd a) |
| 67 | { | 67 | { |
| 68 | eassert (BOOLFWDP (a)); | 68 | eassert (BOOLFWDP (a)); |
| 69 | return &a->u_boolfwd; | 69 | return a.fwdptr; |
| 70 | } | 70 | } |
| 71 | static struct Lisp_Kboard_Objfwd * | 71 | static struct Lisp_Kboard_Objfwd * |
| 72 | XKBOARD_OBJFWD (union Lisp_Fwd *a) | 72 | XKBOARD_OBJFWD (lispfwd a) |
| 73 | { | 73 | { |
| 74 | eassert (KBOARD_OBJFWDP (a)); | 74 | eassert (KBOARD_OBJFWDP (a)); |
| 75 | return &a->u_kboard_objfwd; | 75 | return a.fwdptr; |
| 76 | } | 76 | } |
| 77 | static struct Lisp_Intfwd * | 77 | static struct Lisp_Intfwd * |
| 78 | XFIXNUMFWD (union Lisp_Fwd *a) | 78 | XFIXNUMFWD (lispfwd a) |
| 79 | { | 79 | { |
| 80 | eassert (INTFWDP (a)); | 80 | eassert (INTFWDP (a)); |
| 81 | return &a->u_intfwd; | 81 | return a.fwdptr; |
| 82 | } | 82 | } |
| 83 | static struct Lisp_Objfwd * | 83 | static struct Lisp_Objfwd * |
| 84 | XOBJFWD (union Lisp_Fwd *a) | 84 | XOBJFWD (lispfwd a) |
| 85 | { | 85 | { |
| 86 | eassert (OBJFWDP (a)); | 86 | eassert (OBJFWDP (a)); |
| 87 | return &a->u_objfwd; | 87 | return a.fwdptr; |
| 88 | } | 88 | } |
| 89 | 89 | ||
| 90 | static void | 90 | static void |
| @@ -669,7 +669,7 @@ global value outside of any lexical scope. */) | |||
| 669 | case SYMBOL_LOCALIZED: | 669 | case SYMBOL_LOCALIZED: |
| 670 | { | 670 | { |
| 671 | struct Lisp_Buffer_Local_Value *blv = SYMBOL_BLV (sym); | 671 | struct Lisp_Buffer_Local_Value *blv = SYMBOL_BLV (sym); |
| 672 | if (blv->fwd) | 672 | if (blv->fwd.fwdptr) |
| 673 | /* In set_internal, we un-forward vars when their value is | 673 | /* In set_internal, we un-forward vars when their value is |
| 674 | set to Qunbound. */ | 674 | set to Qunbound. */ |
| 675 | return Qt; | 675 | return Qt; |
| @@ -980,7 +980,7 @@ chain of aliases, signal a `cyclic-variable-indirection' error. */) | |||
| 980 | swap_in_symval_forwarding for that. */ | 980 | swap_in_symval_forwarding for that. */ |
| 981 | 981 | ||
| 982 | Lisp_Object | 982 | Lisp_Object |
| 983 | do_symval_forwarding (union Lisp_Fwd *valcontents) | 983 | do_symval_forwarding (lispfwd valcontents) |
| 984 | { | 984 | { |
| 985 | switch (XFWDTYPE (valcontents)) | 985 | switch (XFWDTYPE (valcontents)) |
| 986 | { | 986 | { |
| @@ -1071,7 +1071,8 @@ wrong_range (Lisp_Object min, Lisp_Object max, Lisp_Object wrong) | |||
| 1071 | current buffer. This only plays a role for per-buffer variables. */ | 1071 | current buffer. This only plays a role for per-buffer variables. */ |
| 1072 | 1072 | ||
| 1073 | static void | 1073 | static void |
| 1074 | store_symval_forwarding (union Lisp_Fwd *valcontents, register Lisp_Object newval, struct buffer *buf) | 1074 | store_symval_forwarding (lispfwd valcontents, Lisp_Object newval, |
| 1075 | struct buffer *buf) | ||
| 1075 | { | 1076 | { |
| 1076 | switch (XFWDTYPE (valcontents)) | 1077 | switch (XFWDTYPE (valcontents)) |
| 1077 | { | 1078 | { |
| @@ -1178,12 +1179,12 @@ swap_in_global_binding (struct Lisp_Symbol *symbol) | |||
| 1178 | struct Lisp_Buffer_Local_Value *blv = SYMBOL_BLV (symbol); | 1179 | struct Lisp_Buffer_Local_Value *blv = SYMBOL_BLV (symbol); |
| 1179 | 1180 | ||
| 1180 | /* Unload the previously loaded binding. */ | 1181 | /* Unload the previously loaded binding. */ |
| 1181 | if (blv->fwd) | 1182 | if (blv->fwd.fwdptr) |
| 1182 | set_blv_value (blv, do_symval_forwarding (blv->fwd)); | 1183 | set_blv_value (blv, do_symval_forwarding (blv->fwd)); |
| 1183 | 1184 | ||
| 1184 | /* Select the global binding in the symbol. */ | 1185 | /* Select the global binding in the symbol. */ |
| 1185 | set_blv_valcell (blv, blv->defcell); | 1186 | set_blv_valcell (blv, blv->defcell); |
| 1186 | if (blv->fwd) | 1187 | if (blv->fwd.fwdptr) |
| 1187 | store_symval_forwarding (blv->fwd, XCDR (blv->defcell), NULL); | 1188 | store_symval_forwarding (blv->fwd, XCDR (blv->defcell), NULL); |
| 1188 | 1189 | ||
| 1189 | /* Indicate that the global binding is set up now. */ | 1190 | /* Indicate that the global binding is set up now. */ |
| @@ -1213,7 +1214,7 @@ swap_in_symval_forwarding (struct Lisp_Symbol *symbol, struct Lisp_Buffer_Local_ | |||
| 1213 | 1214 | ||
| 1214 | /* Unload the previously loaded binding. */ | 1215 | /* Unload the previously loaded binding. */ |
| 1215 | tem1 = blv->valcell; | 1216 | tem1 = blv->valcell; |
| 1216 | if (blv->fwd) | 1217 | if (blv->fwd.fwdptr) |
| 1217 | set_blv_value (blv, do_symval_forwarding (blv->fwd)); | 1218 | set_blv_value (blv, do_symval_forwarding (blv->fwd)); |
| 1218 | /* Choose the new binding. */ | 1219 | /* Choose the new binding. */ |
| 1219 | { | 1220 | { |
| @@ -1227,7 +1228,7 @@ swap_in_symval_forwarding (struct Lisp_Symbol *symbol, struct Lisp_Buffer_Local_ | |||
| 1227 | 1228 | ||
| 1228 | /* Load the new binding. */ | 1229 | /* Load the new binding. */ |
| 1229 | set_blv_valcell (blv, tem1); | 1230 | set_blv_valcell (blv, tem1); |
| 1230 | if (blv->fwd) | 1231 | if (blv->fwd.fwdptr) |
| 1231 | store_symval_forwarding (blv->fwd, blv_value (blv), NULL); | 1232 | store_symval_forwarding (blv->fwd, blv_value (blv), NULL); |
| 1232 | } | 1233 | } |
| 1233 | } | 1234 | } |
| @@ -1255,7 +1256,9 @@ find_symbol_value (Lisp_Object symbol) | |||
| 1255 | { | 1256 | { |
| 1256 | struct Lisp_Buffer_Local_Value *blv = SYMBOL_BLV (sym); | 1257 | struct Lisp_Buffer_Local_Value *blv = SYMBOL_BLV (sym); |
| 1257 | swap_in_symval_forwarding (sym, blv); | 1258 | swap_in_symval_forwarding (sym, blv); |
| 1258 | return blv->fwd ? do_symval_forwarding (blv->fwd) : blv_value (blv); | 1259 | return (blv->fwd.fwdptr |
| 1260 | ? do_symval_forwarding (blv->fwd) | ||
| 1261 | : blv_value (blv)); | ||
| 1259 | } | 1262 | } |
| 1260 | case SYMBOL_FORWARDED: | 1263 | case SYMBOL_FORWARDED: |
| 1261 | return do_symval_forwarding (SYMBOL_FWD (sym)); | 1264 | return do_symval_forwarding (SYMBOL_FWD (sym)); |
| @@ -1357,7 +1360,7 @@ set_internal (Lisp_Object symbol, Lisp_Object newval, Lisp_Object where, | |||
| 1357 | We need to unload it, and choose a new binding. */ | 1360 | We need to unload it, and choose a new binding. */ |
| 1358 | 1361 | ||
| 1359 | /* Write out `realvalue' to the old loaded binding. */ | 1362 | /* Write out `realvalue' to the old loaded binding. */ |
| 1360 | if (blv->fwd) | 1363 | if (blv->fwd.fwdptr) |
| 1361 | set_blv_value (blv, do_symval_forwarding (blv->fwd)); | 1364 | set_blv_value (blv, do_symval_forwarding (blv->fwd)); |
| 1362 | 1365 | ||
| 1363 | /* Find the new binding. */ | 1366 | /* Find the new binding. */ |
| @@ -1404,12 +1407,12 @@ set_internal (Lisp_Object symbol, Lisp_Object newval, Lisp_Object where, | |||
| 1404 | /* Store the new value in the cons cell. */ | 1407 | /* Store the new value in the cons cell. */ |
| 1405 | set_blv_value (blv, newval); | 1408 | set_blv_value (blv, newval); |
| 1406 | 1409 | ||
| 1407 | if (blv->fwd) | 1410 | if (blv->fwd.fwdptr) |
| 1408 | { | 1411 | { |
| 1409 | if (voide) | 1412 | if (voide) |
| 1410 | /* If storing void (making the symbol void), forward only through | 1413 | /* If storing void (making the symbol void), forward only through |
| 1411 | buffer-local indicator, not through Lisp_Objfwd, etc. */ | 1414 | buffer-local indicator, not through Lisp_Objfwd, etc. */ |
| 1412 | blv->fwd = NULL; | 1415 | blv->fwd.fwdptr = NULL; |
| 1413 | else | 1416 | else |
| 1414 | store_symval_forwarding (blv->fwd, newval, | 1417 | store_symval_forwarding (blv->fwd, newval, |
| 1415 | BUFFERP (where) | 1418 | BUFFERP (where) |
| @@ -1421,7 +1424,7 @@ set_internal (Lisp_Object symbol, Lisp_Object newval, Lisp_Object where, | |||
| 1421 | { | 1424 | { |
| 1422 | struct buffer *buf | 1425 | struct buffer *buf |
| 1423 | = BUFFERP (where) ? XBUFFER (where) : current_buffer; | 1426 | = BUFFERP (where) ? XBUFFER (where) : current_buffer; |
| 1424 | union Lisp_Fwd *innercontents = SYMBOL_FWD (sym); | 1427 | lispfwd innercontents = SYMBOL_FWD (sym); |
| 1425 | if (BUFFER_OBJFWDP (innercontents)) | 1428 | if (BUFFER_OBJFWDP (innercontents)) |
| 1426 | { | 1429 | { |
| 1427 | int offset = XBUFFER_OBJFWD (innercontents)->offset; | 1430 | int offset = XBUFFER_OBJFWD (innercontents)->offset; |
| @@ -1593,14 +1596,14 @@ default_value (Lisp_Object symbol) | |||
| 1593 | But the `realvalue' slot may be more up to date, since | 1596 | But the `realvalue' slot may be more up to date, since |
| 1594 | ordinary setq stores just that slot. So use that. */ | 1597 | ordinary setq stores just that slot. So use that. */ |
| 1595 | struct Lisp_Buffer_Local_Value *blv = SYMBOL_BLV (sym); | 1598 | struct Lisp_Buffer_Local_Value *blv = SYMBOL_BLV (sym); |
| 1596 | if (blv->fwd && EQ (blv->valcell, blv->defcell)) | 1599 | if (blv->fwd.fwdptr && EQ (blv->valcell, blv->defcell)) |
| 1597 | return do_symval_forwarding (blv->fwd); | 1600 | return do_symval_forwarding (blv->fwd); |
| 1598 | else | 1601 | else |
| 1599 | return XCDR (blv->defcell); | 1602 | return XCDR (blv->defcell); |
| 1600 | } | 1603 | } |
| 1601 | case SYMBOL_FORWARDED: | 1604 | case SYMBOL_FORWARDED: |
| 1602 | { | 1605 | { |
| 1603 | union Lisp_Fwd *valcontents = SYMBOL_FWD (sym); | 1606 | lispfwd valcontents = SYMBOL_FWD (sym); |
| 1604 | 1607 | ||
| 1605 | /* For a built-in buffer-local variable, get the default value | 1608 | /* For a built-in buffer-local variable, get the default value |
| 1606 | rather than letting do_symval_forwarding get the current value. */ | 1609 | rather than letting do_symval_forwarding get the current value. */ |
| @@ -1688,13 +1691,13 @@ set_default_internal (Lisp_Object symbol, Lisp_Object value, | |||
| 1688 | XSETCDR (blv->defcell, value); | 1691 | XSETCDR (blv->defcell, value); |
| 1689 | 1692 | ||
| 1690 | /* If the default binding is now loaded, set the REALVALUE slot too. */ | 1693 | /* If the default binding is now loaded, set the REALVALUE slot too. */ |
| 1691 | if (blv->fwd && EQ (blv->defcell, blv->valcell)) | 1694 | if (blv->fwd.fwdptr && EQ (blv->defcell, blv->valcell)) |
| 1692 | store_symval_forwarding (blv->fwd, value, NULL); | 1695 | store_symval_forwarding (blv->fwd, value, NULL); |
| 1693 | return; | 1696 | return; |
| 1694 | } | 1697 | } |
| 1695 | case SYMBOL_FORWARDED: | 1698 | case SYMBOL_FORWARDED: |
| 1696 | { | 1699 | { |
| 1697 | union Lisp_Fwd *valcontents = SYMBOL_FWD (sym); | 1700 | lispfwd valcontents = SYMBOL_FWD (sym); |
| 1698 | 1701 | ||
| 1699 | /* Handle variables like case-fold-search that have special slots | 1702 | /* Handle variables like case-fold-search that have special slots |
| 1700 | in the buffer. | 1703 | in the buffer. |
| @@ -1750,7 +1753,7 @@ for this variable. */) | |||
| 1750 | union Lisp_Val_Fwd | 1753 | union Lisp_Val_Fwd |
| 1751 | { | 1754 | { |
| 1752 | Lisp_Object value; | 1755 | Lisp_Object value; |
| 1753 | union Lisp_Fwd *fwd; | 1756 | lispfwd fwd; |
| 1754 | }; | 1757 | }; |
| 1755 | 1758 | ||
| 1756 | static struct Lisp_Buffer_Local_Value * | 1759 | static struct Lisp_Buffer_Local_Value * |
| @@ -1770,7 +1773,10 @@ make_blv (struct Lisp_Symbol *sym, bool forwarded, | |||
| 1770 | or keyboard-local forwarding. */ | 1773 | or keyboard-local forwarding. */ |
| 1771 | eassert (!(forwarded && BUFFER_OBJFWDP (valcontents.fwd))); | 1774 | eassert (!(forwarded && BUFFER_OBJFWDP (valcontents.fwd))); |
| 1772 | eassert (!(forwarded && KBOARD_OBJFWDP (valcontents.fwd))); | 1775 | eassert (!(forwarded && KBOARD_OBJFWDP (valcontents.fwd))); |
| 1773 | blv->fwd = forwarded ? valcontents.fwd : NULL; | 1776 | if (forwarded) |
| 1777 | blv->fwd = valcontents.fwd; | ||
| 1778 | else | ||
| 1779 | blv->fwd.fwdptr = NULL; | ||
| 1774 | set_blv_where (blv, Qnil); | 1780 | set_blv_where (blv, Qnil); |
| 1775 | blv->local_if_set = 0; | 1781 | blv->local_if_set = 0; |
| 1776 | set_blv_defcell (blv, tem); | 1782 | set_blv_defcell (blv, tem); |
| @@ -1941,7 +1947,7 @@ Instead, use `add-hook' and specify t for the LOCAL argument. */) | |||
| 1941 | Otherwise, if C code modifies the variable before we load the | 1947 | Otherwise, if C code modifies the variable before we load the |
| 1942 | binding in, then that new value would clobber the default binding | 1948 | binding in, then that new value would clobber the default binding |
| 1943 | the next time we unload it. See bug#34318. */ | 1949 | the next time we unload it. See bug#34318. */ |
| 1944 | if (blv->fwd) | 1950 | if (blv->fwd.fwdptr) |
| 1945 | swap_in_symval_forwarding (sym, blv); | 1951 | swap_in_symval_forwarding (sym, blv); |
| 1946 | } | 1952 | } |
| 1947 | 1953 | ||
| @@ -1968,7 +1974,7 @@ From now on the default value will apply in this buffer. Return VARIABLE. */) | |||
| 1968 | case SYMBOL_PLAINVAL: return variable; | 1974 | case SYMBOL_PLAINVAL: return variable; |
| 1969 | case SYMBOL_FORWARDED: | 1975 | case SYMBOL_FORWARDED: |
| 1970 | { | 1976 | { |
| 1971 | union Lisp_Fwd *valcontents = SYMBOL_FWD (sym); | 1977 | lispfwd valcontents = SYMBOL_FWD (sym); |
| 1972 | if (BUFFER_OBJFWDP (valcontents)) | 1978 | if (BUFFER_OBJFWDP (valcontents)) |
| 1973 | { | 1979 | { |
| 1974 | int offset = XBUFFER_OBJFWD (valcontents)->offset; | 1980 | int offset = XBUFFER_OBJFWD (valcontents)->offset; |
| @@ -2051,7 +2057,7 @@ BUFFER defaults to the current buffer. */) | |||
| 2051 | } | 2057 | } |
| 2052 | case SYMBOL_FORWARDED: | 2058 | case SYMBOL_FORWARDED: |
| 2053 | { | 2059 | { |
| 2054 | union Lisp_Fwd *valcontents = SYMBOL_FWD (sym); | 2060 | lispfwd valcontents = SYMBOL_FWD (sym); |
| 2055 | if (BUFFER_OBJFWDP (valcontents)) | 2061 | if (BUFFER_OBJFWDP (valcontents)) |
| 2056 | { | 2062 | { |
| 2057 | int offset = XBUFFER_OBJFWD (valcontents)->offset; | 2063 | int offset = XBUFFER_OBJFWD (valcontents)->offset; |
| @@ -2122,7 +2128,7 @@ If the current binding is global (the default), the value is nil. */) | |||
| 2122 | case SYMBOL_PLAINVAL: return Qnil; | 2128 | case SYMBOL_PLAINVAL: return Qnil; |
| 2123 | case SYMBOL_FORWARDED: | 2129 | case SYMBOL_FORWARDED: |
| 2124 | { | 2130 | { |
| 2125 | union Lisp_Fwd *valcontents = SYMBOL_FWD (sym); | 2131 | lispfwd valcontents = SYMBOL_FWD (sym); |
| 2126 | if (KBOARD_OBJFWDP (valcontents)) | 2132 | if (KBOARD_OBJFWDP (valcontents)) |
| 2127 | return Fframe_terminal (selected_frame); | 2133 | return Fframe_terminal (selected_frame); |
| 2128 | else if (!BUFFER_OBJFWDP (valcontents)) | 2134 | else if (!BUFFER_OBJFWDP (valcontents)) |
diff --git a/src/lisp.h b/src/lisp.h index 178eebed2a5..62c3230a148 100644 --- a/src/lisp.h +++ b/src/lisp.h | |||
| @@ -797,6 +797,13 @@ INLINE void | |||
| 797 | 797 | ||
| 798 | #define XUNTAG(a, type, ctype) ((ctype *) \ | 798 | #define XUNTAG(a, type, ctype) ((ctype *) \ |
| 799 | ((char *) XLP (a) - LISP_WORD_TAG (type))) | 799 | ((char *) XLP (a) - LISP_WORD_TAG (type))) |
| 800 | |||
| 801 | /* A forwarding pointer to a value. It uses a generic pointer to | ||
| 802 | avoid alignment bugs that could occur if it used a pointer to a | ||
| 803 | union of the possible values (struct Lisp_Objfwd, struct | ||
| 804 | Lisp_Intfwd, etc.). The pointer is packaged inside a struct to | ||
| 805 | help static checking. */ | ||
| 806 | typedef struct { void *fwdptr; } lispfwd; | ||
| 800 | 807 | ||
| 801 | /* Interned state of a symbol. */ | 808 | /* Interned state of a symbol. */ |
| 802 | 809 | ||
| @@ -862,7 +869,7 @@ struct Lisp_Symbol | |||
| 862 | Lisp_Object value; | 869 | Lisp_Object value; |
| 863 | struct Lisp_Symbol *alias; | 870 | struct Lisp_Symbol *alias; |
| 864 | struct Lisp_Buffer_Local_Value *blv; | 871 | struct Lisp_Buffer_Local_Value *blv; |
| 865 | union Lisp_Fwd *fwd; | 872 | lispfwd fwd; |
| 866 | } val; | 873 | } val; |
| 867 | 874 | ||
| 868 | /* Function value of the symbol or Qnil if not fboundp. */ | 875 | /* Function value of the symbol or Qnil if not fboundp. */ |
| @@ -2171,10 +2178,10 @@ SYMBOL_BLV (struct Lisp_Symbol *sym) | |||
| 2171 | eassume (sym->u.s.redirect == SYMBOL_LOCALIZED && sym->u.s.val.blv); | 2178 | eassume (sym->u.s.redirect == SYMBOL_LOCALIZED && sym->u.s.val.blv); |
| 2172 | return sym->u.s.val.blv; | 2179 | return sym->u.s.val.blv; |
| 2173 | } | 2180 | } |
| 2174 | INLINE union Lisp_Fwd * | 2181 | INLINE lispfwd |
| 2175 | SYMBOL_FWD (struct Lisp_Symbol *sym) | 2182 | SYMBOL_FWD (struct Lisp_Symbol *sym) |
| 2176 | { | 2183 | { |
| 2177 | eassume (sym->u.s.redirect == SYMBOL_FORWARDED && sym->u.s.val.fwd); | 2184 | eassume (sym->u.s.redirect == SYMBOL_FORWARDED && sym->u.s.val.fwd.fwdptr); |
| 2178 | return sym->u.s.val.fwd; | 2185 | return sym->u.s.val.fwd; |
| 2179 | } | 2186 | } |
| 2180 | 2187 | ||
| @@ -2197,10 +2204,10 @@ SET_SYMBOL_BLV (struct Lisp_Symbol *sym, struct Lisp_Buffer_Local_Value *v) | |||
| 2197 | sym->u.s.val.blv = v; | 2204 | sym->u.s.val.blv = v; |
| 2198 | } | 2205 | } |
| 2199 | INLINE void | 2206 | INLINE void |
| 2200 | SET_SYMBOL_FWD (struct Lisp_Symbol *sym, union Lisp_Fwd *v) | 2207 | SET_SYMBOL_FWD (struct Lisp_Symbol *sym, void *v) |
| 2201 | { | 2208 | { |
| 2202 | eassume (sym->u.s.redirect == SYMBOL_FORWARDED && v); | 2209 | eassume (sym->u.s.redirect == SYMBOL_FORWARDED && v); |
| 2203 | sym->u.s.val.fwd = v; | 2210 | sym->u.s.val.fwd.fwdptr = v; |
| 2204 | } | 2211 | } |
| 2205 | 2212 | ||
| 2206 | INLINE Lisp_Object | 2213 | INLINE Lisp_Object |
| @@ -2727,7 +2734,7 @@ struct Lisp_Buffer_Local_Value | |||
| 2727 | Presumably equivalent to (defcell!=valcell). */ | 2734 | Presumably equivalent to (defcell!=valcell). */ |
| 2728 | bool_bf found : 1; | 2735 | bool_bf found : 1; |
| 2729 | /* If non-NULL, a forwarding to the C var where it should also be set. */ | 2736 | /* If non-NULL, a forwarding to the C var where it should also be set. */ |
| 2730 | union Lisp_Fwd *fwd; /* Should never be (Buffer|Kboard)_Objfwd. */ | 2737 | lispfwd fwd; /* Should never be (Buffer|Kboard)_Objfwd. */ |
| 2731 | /* The buffer for which the loaded binding was found. */ | 2738 | /* The buffer for which the loaded binding was found. */ |
| 2732 | Lisp_Object where; | 2739 | Lisp_Object where; |
| 2733 | /* A cons cell that holds the default value. It has the form | 2740 | /* A cons cell that holds the default value. It has the form |
| @@ -2749,32 +2756,24 @@ struct Lisp_Kboard_Objfwd | |||
| 2749 | int offset; | 2756 | int offset; |
| 2750 | }; | 2757 | }; |
| 2751 | 2758 | ||
| 2752 | union Lisp_Fwd | ||
| 2753 | { | ||
| 2754 | struct Lisp_Intfwd u_intfwd; | ||
| 2755 | struct Lisp_Boolfwd u_boolfwd; | ||
| 2756 | struct Lisp_Objfwd u_objfwd; | ||
| 2757 | struct Lisp_Buffer_Objfwd u_buffer_objfwd; | ||
| 2758 | struct Lisp_Kboard_Objfwd u_kboard_objfwd; | ||
| 2759 | }; | ||
| 2760 | |||
| 2761 | INLINE enum Lisp_Fwd_Type | 2759 | INLINE enum Lisp_Fwd_Type |
| 2762 | XFWDTYPE (union Lisp_Fwd *a) | 2760 | XFWDTYPE (lispfwd a) |
| 2763 | { | 2761 | { |
| 2764 | return a->u_intfwd.type; | 2762 | enum Lisp_Fwd_Type *p = a.fwdptr; |
| 2763 | return *p; | ||
| 2765 | } | 2764 | } |
| 2766 | 2765 | ||
| 2767 | INLINE bool | 2766 | INLINE bool |
| 2768 | BUFFER_OBJFWDP (union Lisp_Fwd *a) | 2767 | BUFFER_OBJFWDP (lispfwd a) |
| 2769 | { | 2768 | { |
| 2770 | return XFWDTYPE (a) == Lisp_Fwd_Buffer_Obj; | 2769 | return XFWDTYPE (a) == Lisp_Fwd_Buffer_Obj; |
| 2771 | } | 2770 | } |
| 2772 | 2771 | ||
| 2773 | INLINE struct Lisp_Buffer_Objfwd * | 2772 | INLINE struct Lisp_Buffer_Objfwd * |
| 2774 | XBUFFER_OBJFWD (union Lisp_Fwd *a) | 2773 | XBUFFER_OBJFWD (lispfwd a) |
| 2775 | { | 2774 | { |
| 2776 | eassert (BUFFER_OBJFWDP (a)); | 2775 | eassert (BUFFER_OBJFWDP (a)); |
| 2777 | return &a->u_buffer_objfwd; | 2776 | return a.fwdptr; |
| 2778 | } | 2777 | } |
| 2779 | 2778 | ||
| 2780 | /* Lisp floating point type. */ | 2779 | /* Lisp floating point type. */ |
| @@ -3552,7 +3551,7 @@ extern _Noreturn void args_out_of_range (Lisp_Object, Lisp_Object); | |||
| 3552 | extern _Noreturn void args_out_of_range_3 (Lisp_Object, Lisp_Object, | 3551 | extern _Noreturn void args_out_of_range_3 (Lisp_Object, Lisp_Object, |
| 3553 | Lisp_Object); | 3552 | Lisp_Object); |
| 3554 | extern _Noreturn void circular_list (Lisp_Object); | 3553 | extern _Noreturn void circular_list (Lisp_Object); |
| 3555 | extern Lisp_Object do_symval_forwarding (union Lisp_Fwd *); | 3554 | extern Lisp_Object do_symval_forwarding (lispfwd); |
| 3556 | enum Set_Internal_Bind { | 3555 | enum Set_Internal_Bind { |
| 3557 | SET_INTERNAL_SET, | 3556 | SET_INTERNAL_SET, |
| 3558 | SET_INTERNAL_BIND, | 3557 | SET_INTERNAL_BIND, |
diff --git a/src/lread.c b/src/lread.c index 2d64b638ff5..dd35cf9063e 100644 --- a/src/lread.c +++ b/src/lread.c | |||
| @@ -4434,7 +4434,7 @@ defvar_int (struct Lisp_Intfwd *i_fwd, | |||
| 4434 | i_fwd->intvar = address; | 4434 | i_fwd->intvar = address; |
| 4435 | XSYMBOL (sym)->u.s.declared_special = true; | 4435 | XSYMBOL (sym)->u.s.declared_special = true; |
| 4436 | XSYMBOL (sym)->u.s.redirect = SYMBOL_FORWARDED; | 4436 | XSYMBOL (sym)->u.s.redirect = SYMBOL_FORWARDED; |
| 4437 | SET_SYMBOL_FWD (XSYMBOL (sym), (union Lisp_Fwd *)i_fwd); | 4437 | SET_SYMBOL_FWD (XSYMBOL (sym), i_fwd); |
| 4438 | } | 4438 | } |
| 4439 | 4439 | ||
| 4440 | /* Similar but define a variable whose value is t if address contains 1, | 4440 | /* Similar but define a variable whose value is t if address contains 1, |
| @@ -4449,7 +4449,7 @@ defvar_bool (struct Lisp_Boolfwd *b_fwd, | |||
| 4449 | b_fwd->boolvar = address; | 4449 | b_fwd->boolvar = address; |
| 4450 | XSYMBOL (sym)->u.s.declared_special = true; | 4450 | XSYMBOL (sym)->u.s.declared_special = true; |
| 4451 | XSYMBOL (sym)->u.s.redirect = SYMBOL_FORWARDED; | 4451 | XSYMBOL (sym)->u.s.redirect = SYMBOL_FORWARDED; |
| 4452 | SET_SYMBOL_FWD (XSYMBOL (sym), (union Lisp_Fwd *)b_fwd); | 4452 | SET_SYMBOL_FWD (XSYMBOL (sym), b_fwd); |
| 4453 | Vbyte_boolean_vars = Fcons (sym, Vbyte_boolean_vars); | 4453 | Vbyte_boolean_vars = Fcons (sym, Vbyte_boolean_vars); |
| 4454 | } | 4454 | } |
| 4455 | 4455 | ||
| @@ -4468,7 +4468,7 @@ defvar_lisp_nopro (struct Lisp_Objfwd *o_fwd, | |||
| 4468 | o_fwd->objvar = address; | 4468 | o_fwd->objvar = address; |
| 4469 | XSYMBOL (sym)->u.s.declared_special = true; | 4469 | XSYMBOL (sym)->u.s.declared_special = true; |
| 4470 | XSYMBOL (sym)->u.s.redirect = SYMBOL_FORWARDED; | 4470 | XSYMBOL (sym)->u.s.redirect = SYMBOL_FORWARDED; |
| 4471 | SET_SYMBOL_FWD (XSYMBOL (sym), (union Lisp_Fwd *)o_fwd); | 4471 | SET_SYMBOL_FWD (XSYMBOL (sym), o_fwd); |
| 4472 | } | 4472 | } |
| 4473 | 4473 | ||
| 4474 | void | 4474 | void |
| @@ -4492,7 +4492,7 @@ defvar_kboard (struct Lisp_Kboard_Objfwd *ko_fwd, | |||
| 4492 | ko_fwd->offset = offset; | 4492 | ko_fwd->offset = offset; |
| 4493 | XSYMBOL (sym)->u.s.declared_special = true; | 4493 | XSYMBOL (sym)->u.s.declared_special = true; |
| 4494 | XSYMBOL (sym)->u.s.redirect = SYMBOL_FORWARDED; | 4494 | XSYMBOL (sym)->u.s.redirect = SYMBOL_FORWARDED; |
| 4495 | SET_SYMBOL_FWD (XSYMBOL (sym), (union Lisp_Fwd *)ko_fwd); | 4495 | SET_SYMBOL_FWD (XSYMBOL (sym), ko_fwd); |
| 4496 | } | 4496 | } |
| 4497 | 4497 | ||
| 4498 | /* Check that the elements of lpath exist. */ | 4498 | /* Check that the elements of lpath exist. */ |
diff --git a/src/pdumper.c b/src/pdumper.c index a9b3732a2d4..53a10b62b3f 100644 --- a/src/pdumper.c +++ b/src/pdumper.c | |||
| @@ -2334,32 +2334,30 @@ dump_fwd_kboard_obj (struct dump_context *ctx, | |||
| 2334 | } | 2334 | } |
| 2335 | 2335 | ||
| 2336 | static dump_off | 2336 | static dump_off |
| 2337 | dump_fwd (struct dump_context *ctx, union Lisp_Fwd *fwd) | 2337 | dump_fwd (struct dump_context *ctx, lispfwd fwd) |
| 2338 | { | 2338 | { |
| 2339 | #if CHECK_STRUCTS && !defined (HASH_Lisp_Fwd_5227B18E87) | ||
| 2340 | # error "Lisp_Fwd changed. See CHECK_STRUCTS comment." | ||
| 2341 | #endif | ||
| 2342 | #if CHECK_STRUCTS && !defined (HASH_Lisp_Fwd_Type_9CBA6EE55E) | 2339 | #if CHECK_STRUCTS && !defined (HASH_Lisp_Fwd_Type_9CBA6EE55E) |
| 2343 | # error "Lisp_Fwd_Type changed. See CHECK_STRUCTS comment." | 2340 | # error "Lisp_Fwd_Type changed. See CHECK_STRUCTS comment." |
| 2344 | #endif | 2341 | #endif |
| 2342 | void const *p = fwd.fwdptr; | ||
| 2345 | dump_off offset; | 2343 | dump_off offset; |
| 2346 | 2344 | ||
| 2347 | switch (XFWDTYPE (fwd)) | 2345 | switch (XFWDTYPE (fwd)) |
| 2348 | { | 2346 | { |
| 2349 | case Lisp_Fwd_Int: | 2347 | case Lisp_Fwd_Int: |
| 2350 | offset = dump_fwd_int (ctx, &fwd->u_intfwd); | 2348 | offset = dump_fwd_int (ctx, p); |
| 2351 | break; | 2349 | break; |
| 2352 | case Lisp_Fwd_Bool: | 2350 | case Lisp_Fwd_Bool: |
| 2353 | offset = dump_fwd_bool (ctx, &fwd->u_boolfwd); | 2351 | offset = dump_fwd_bool (ctx, p); |
| 2354 | break; | 2352 | break; |
| 2355 | case Lisp_Fwd_Obj: | 2353 | case Lisp_Fwd_Obj: |
| 2356 | offset = dump_fwd_obj (ctx, &fwd->u_objfwd); | 2354 | offset = dump_fwd_obj (ctx, p); |
| 2357 | break; | 2355 | break; |
| 2358 | case Lisp_Fwd_Buffer_Obj: | 2356 | case Lisp_Fwd_Buffer_Obj: |
| 2359 | offset = dump_fwd_buffer_obj (ctx, &fwd->u_buffer_objfwd); | 2357 | offset = dump_fwd_buffer_obj (ctx, p); |
| 2360 | break; | 2358 | break; |
| 2361 | case Lisp_Fwd_Kboard_Obj: | 2359 | case Lisp_Fwd_Kboard_Obj: |
| 2362 | offset = dump_fwd_kboard_obj (ctx, &fwd->u_kboard_objfwd); | 2360 | offset = dump_fwd_kboard_obj (ctx, p); |
| 2363 | break; | 2361 | break; |
| 2364 | default: | 2362 | default: |
| 2365 | emacs_abort (); | 2363 | emacs_abort (); |
| @@ -2372,20 +2370,20 @@ static dump_off | |||
| 2372 | dump_blv (struct dump_context *ctx, | 2370 | dump_blv (struct dump_context *ctx, |
| 2373 | const struct Lisp_Buffer_Local_Value *blv) | 2371 | const struct Lisp_Buffer_Local_Value *blv) |
| 2374 | { | 2372 | { |
| 2375 | #if CHECK_STRUCTS && !defined (HASH_Lisp_Buffer_Local_Value_066F33A92E) | 2373 | #if CHECK_STRUCTS && !defined HASH_Lisp_Buffer_Local_Value_3C363FAC3C |
| 2376 | # error "Lisp_Buffer_Local_Value changed. See CHECK_STRUCTS comment." | 2374 | # error "Lisp_Buffer_Local_Value changed. See CHECK_STRUCTS comment." |
| 2377 | #endif | 2375 | #endif |
| 2378 | struct Lisp_Buffer_Local_Value out; | 2376 | struct Lisp_Buffer_Local_Value out; |
| 2379 | dump_object_start (ctx, &out, sizeof (out)); | 2377 | dump_object_start (ctx, &out, sizeof (out)); |
| 2380 | DUMP_FIELD_COPY (&out, blv, local_if_set); | 2378 | DUMP_FIELD_COPY (&out, blv, local_if_set); |
| 2381 | DUMP_FIELD_COPY (&out, blv, found); | 2379 | DUMP_FIELD_COPY (&out, blv, found); |
| 2382 | if (blv->fwd) | 2380 | if (blv->fwd.fwdptr) |
| 2383 | dump_field_fixup_later (ctx, &out, blv, &blv->fwd); | 2381 | dump_field_fixup_later (ctx, &out, blv, &blv->fwd.fwdptr); |
| 2384 | dump_field_lv (ctx, &out, blv, &blv->where, WEIGHT_NORMAL); | 2382 | dump_field_lv (ctx, &out, blv, &blv->where, WEIGHT_NORMAL); |
| 2385 | dump_field_lv (ctx, &out, blv, &blv->defcell, WEIGHT_STRONG); | 2383 | dump_field_lv (ctx, &out, blv, &blv->defcell, WEIGHT_STRONG); |
| 2386 | dump_field_lv (ctx, &out, blv, &blv->valcell, WEIGHT_STRONG); | 2384 | dump_field_lv (ctx, &out, blv, &blv->valcell, WEIGHT_STRONG); |
| 2387 | dump_off offset = dump_object_finish (ctx, &out, sizeof (out)); | 2385 | dump_off offset = dump_object_finish (ctx, &out, sizeof (out)); |
| 2388 | if (blv->fwd) | 2386 | if (blv->fwd.fwdptr) |
| 2389 | dump_remember_fixup_ptr_raw | 2387 | dump_remember_fixup_ptr_raw |
| 2390 | (ctx, | 2388 | (ctx, |
| 2391 | offset + dump_offsetof (struct Lisp_Buffer_Local_Value, fwd), | 2389 | offset + dump_offsetof (struct Lisp_Buffer_Local_Value, fwd), |
| @@ -2437,7 +2435,7 @@ dump_symbol (struct dump_context *ctx, | |||
| 2437 | Lisp_Object object, | 2435 | Lisp_Object object, |
| 2438 | dump_off offset) | 2436 | dump_off offset) |
| 2439 | { | 2437 | { |
| 2440 | #if CHECK_STRUCTS && !defined (HASH_Lisp_Symbol_60EA1E748E) | 2438 | #if CHECK_STRUCTS && !defined HASH_Lisp_Symbol_999DC26DEC |
| 2441 | # error "Lisp_Symbol changed. See CHECK_STRUCTS comment." | 2439 | # error "Lisp_Symbol changed. See CHECK_STRUCTS comment." |
| 2442 | #endif | 2440 | #endif |
| 2443 | #if CHECK_STRUCTS && !defined (HASH_symbol_redirect_ADB4F5B113) | 2441 | #if CHECK_STRUCTS && !defined (HASH_symbol_redirect_ADB4F5B113) |