aboutsummaryrefslogtreecommitdiffstats
path: root/src/eval.c
diff options
context:
space:
mode:
authorEli Zaretskii2016-12-09 16:03:08 +0200
committerEli Zaretskii2016-12-09 16:03:08 +0200
commit3ef50c1ff691b0a6c2f56da76f7c1c9b572d8be8 (patch)
tree4134d5dfa77b76e8d5312be1d84991a0e09e803b /src/eval.c
parent54f52a1390c394f42203f39d0b4d73318203e092 (diff)
downloademacs-3ef50c1ff691b0a6c2f56da76f7c1c9b572d8be8.tar.gz
emacs-3ef50c1ff691b0a6c2f56da76f7c1c9b572d8be8.zip
Fix subtle errors with let-binding of localized variables
* src/eval.c (do_specbind): Don't require a "symbol" that is actually a cons cell, in order to call set-default, as there are no longer such bindings. This makes do_specbind work like the pre-concurrency implementation in specbind for bindings of forwarded symbols. Use specpdl_kind to access the type of the binding. (specpdl_kind): New function.
Diffstat (limited to 'src/eval.c')
-rw-r--r--src/eval.c30
1 files changed, 14 insertions, 16 deletions
diff --git a/src/eval.c b/src/eval.c
index 9657f51aadc..5383d7c3b1b 100644
--- a/src/eval.c
+++ b/src/eval.c
@@ -102,6 +102,13 @@ specpdl_symbol (union specbinding *pdl)
102 return pdl->let.symbol; 102 return pdl->let.symbol;
103} 103}
104 104
105static enum specbind_tag
106specpdl_kind (union specbinding *pdl)
107{
108 eassert (pdl->kind >= SPECPDL_LET);
109 return pdl->let.kind;
110}
111
105static Lisp_Object 112static Lisp_Object
106specpdl_old_value (union specbinding *pdl) 113specpdl_old_value (union specbinding *pdl)
107{ 114{
@@ -3170,23 +3177,15 @@ do_specbind (struct Lisp_Symbol *sym, union specbinding *bind,
3170 set_internal (specpdl_symbol (bind), value, Qnil, SET_INTERNAL_BIND); 3177 set_internal (specpdl_symbol (bind), value, Qnil, SET_INTERNAL_BIND);
3171 break; 3178 break;
3172 3179
3173 case SYMBOL_LOCALIZED:
3174 case SYMBOL_FORWARDED: 3180 case SYMBOL_FORWARDED:
3175 if ((sym->redirect == SYMBOL_LOCALIZED 3181 if (BUFFER_OBJFWDP (SYMBOL_FWD (sym))
3176 || BUFFER_OBJFWDP (SYMBOL_FWD (sym))) 3182 && specpdl_kind (bind) == SPECPDL_LET_DEFAULT)
3177 && CONSP (specpdl_symbol (bind)))
3178 { 3183 {
3179 Lisp_Object where; 3184 Fset_default (specpdl_symbol (bind), value);
3180 3185 return;
3181 where = XCAR (XCDR (specpdl_symbol (bind)));
3182 if (NILP (where)
3183 && sym->redirect == SYMBOL_FORWARDED)
3184 {
3185 Fset_default (XCAR (specpdl_symbol (bind)), value);
3186 return;
3187 }
3188 } 3186 }
3189 3187 /* FALLTHROUGH */
3188 case SYMBOL_LOCALIZED:
3190 set_internal (specpdl_symbol (bind), value, Qnil, SET_INTERNAL_BIND); 3189 set_internal (specpdl_symbol (bind), value, Qnil, SET_INTERNAL_BIND);
3191 break; 3190 break;
3192 3191
@@ -3361,8 +3360,7 @@ do_one_unbind (union specbinding *this_binding, bool unwinding)
3361 break; 3360 break;
3362 case SPECPDL_LET: 3361 case SPECPDL_LET:
3363 { /* If variable has a trivial value (no forwarding), and isn't 3362 { /* If variable has a trivial value (no forwarding), and isn't
3364 trapped we can just set it. No need to check for constant 3363 trapped, we can just set it. */
3365 symbols here, since that was already done by specbind. */
3366 Lisp_Object sym = specpdl_symbol (this_binding); 3364 Lisp_Object sym = specpdl_symbol (this_binding);
3367 if (SYMBOLP (sym) && XSYMBOL (sym)->redirect == SYMBOL_PLAINVAL) 3365 if (SYMBOLP (sym) && XSYMBOL (sym)->redirect == SYMBOL_PLAINVAL)
3368 { 3366 {