diff options
Diffstat (limited to 'src/eval.c')
| -rw-r--r-- | src/eval.c | 30 |
1 files changed, 21 insertions, 9 deletions
diff --git a/src/eval.c b/src/eval.c index eb40c953f96..3f4e77cd3b1 100644 --- a/src/eval.c +++ b/src/eval.c | |||
| @@ -254,7 +254,7 @@ init_eval (void) | |||
| 254 | static void | 254 | static void |
| 255 | max_ensure_room (intmax_t *m, intmax_t a, intmax_t b) | 255 | max_ensure_room (intmax_t *m, intmax_t a, intmax_t b) |
| 256 | { | 256 | { |
| 257 | intmax_t sum = INT_ADD_WRAPV (a, b, &sum) ? INTMAX_MAX : sum; | 257 | intmax_t sum = ckd_add (&sum, a, b) ? INTMAX_MAX : sum; |
| 258 | *m = max (*m, sum); | 258 | *m = max (*m, sum); |
| 259 | } | 259 | } |
| 260 | 260 | ||
| @@ -571,11 +571,12 @@ omitted or nil, NEW-ALIAS gets the documentation string of BASE-VARIABLE, | |||
| 571 | or of the variable at the end of the chain of aliases, if BASE-VARIABLE is | 571 | or of the variable at the end of the chain of aliases, if BASE-VARIABLE is |
| 572 | itself an alias. If NEW-ALIAS is bound, and BASE-VARIABLE is not, | 572 | itself an alias. If NEW-ALIAS is bound, and BASE-VARIABLE is not, |
| 573 | then the value of BASE-VARIABLE is set to that of NEW-ALIAS. | 573 | then the value of BASE-VARIABLE is set to that of NEW-ALIAS. |
| 574 | The return value is BASE-VARIABLE. */) | 574 | The return value is BASE-VARIABLE. |
| 575 | |||
| 576 | If the resulting chain of variable definitions would contain a loop, | ||
| 577 | signal a `cyclic-variable-indirection' error. */) | ||
| 575 | (Lisp_Object new_alias, Lisp_Object base_variable, Lisp_Object docstring) | 578 | (Lisp_Object new_alias, Lisp_Object base_variable, Lisp_Object docstring) |
| 576 | { | 579 | { |
| 577 | struct Lisp_Symbol *sym; | ||
| 578 | |||
| 579 | CHECK_SYMBOL (new_alias); | 580 | CHECK_SYMBOL (new_alias); |
| 580 | CHECK_SYMBOL (base_variable); | 581 | CHECK_SYMBOL (base_variable); |
| 581 | 582 | ||
| @@ -584,7 +585,18 @@ The return value is BASE-VARIABLE. */) | |||
| 584 | error ("Cannot make a constant an alias: %s", | 585 | error ("Cannot make a constant an alias: %s", |
| 585 | SDATA (SYMBOL_NAME (new_alias))); | 586 | SDATA (SYMBOL_NAME (new_alias))); |
| 586 | 587 | ||
| 587 | sym = XSYMBOL (new_alias); | 588 | struct Lisp_Symbol *sym = XSYMBOL (new_alias); |
| 589 | |||
| 590 | /* Ensure non-circularity. */ | ||
| 591 | struct Lisp_Symbol *s = XSYMBOL (base_variable); | ||
| 592 | for (;;) | ||
| 593 | { | ||
| 594 | if (s == sym) | ||
| 595 | xsignal1 (Qcyclic_variable_indirection, base_variable); | ||
| 596 | if (s->u.s.redirect != SYMBOL_VARALIAS) | ||
| 597 | break; | ||
| 598 | s = SYMBOL_ALIAS (s); | ||
| 599 | } | ||
| 588 | 600 | ||
| 589 | switch (sym->u.s.redirect) | 601 | switch (sym->u.s.redirect) |
| 590 | { | 602 | { |
| @@ -2373,8 +2385,7 @@ grow_specpdl_allocation (void) | |||
| 2373 | union specbinding *pdlvec = specpdl - 1; | 2385 | union specbinding *pdlvec = specpdl - 1; |
| 2374 | ptrdiff_t size = specpdl_end - specpdl; | 2386 | ptrdiff_t size = specpdl_end - specpdl; |
| 2375 | ptrdiff_t pdlvecsize = size + 1; | 2387 | ptrdiff_t pdlvecsize = size + 1; |
| 2376 | if (max_size <= size) | 2388 | eassert (max_size > size); |
| 2377 | xsignal0 (Qexcessive_variable_binding); /* Can't happen, essentially. */ | ||
| 2378 | pdlvec = xpalloc (pdlvec, &pdlvecsize, 1, max_size + 1, sizeof *specpdl); | 2389 | pdlvec = xpalloc (pdlvec, &pdlvecsize, 1, max_size + 1, sizeof *specpdl); |
| 2379 | specpdl = pdlvec + 1; | 2390 | specpdl = pdlvec + 1; |
| 2380 | specpdl_end = specpdl + pdlvecsize - 1; | 2391 | specpdl_end = specpdl + pdlvecsize - 1; |
| @@ -3400,7 +3411,7 @@ DEFUN ("fetch-bytecode", Ffetch_bytecode, Sfetch_bytecode, | |||
| 3400 | return object; | 3411 | return object; |
| 3401 | } | 3412 | } |
| 3402 | 3413 | ||
| 3403 | /* Return true if SYMBOL currently has a let-binding | 3414 | /* Return true if SYMBOL's default currently has a let-binding |
| 3404 | which was made in the buffer that is now current. */ | 3415 | which was made in the buffer that is now current. */ |
| 3405 | 3416 | ||
| 3406 | bool | 3417 | bool |
| @@ -3415,6 +3426,7 @@ let_shadows_buffer_binding_p (struct Lisp_Symbol *symbol) | |||
| 3415 | struct Lisp_Symbol *let_bound_symbol = XSYMBOL (specpdl_symbol (p)); | 3426 | struct Lisp_Symbol *let_bound_symbol = XSYMBOL (specpdl_symbol (p)); |
| 3416 | eassert (let_bound_symbol->u.s.redirect != SYMBOL_VARALIAS); | 3427 | eassert (let_bound_symbol->u.s.redirect != SYMBOL_VARALIAS); |
| 3417 | if (symbol == let_bound_symbol | 3428 | if (symbol == let_bound_symbol |
| 3429 | && p->kind != SPECPDL_LET_LOCAL /* bug#62419 */ | ||
| 3418 | && EQ (specpdl_where (p), buf)) | 3430 | && EQ (specpdl_where (p), buf)) |
| 3419 | return 1; | 3431 | return 1; |
| 3420 | } | 3432 | } |
| @@ -3476,7 +3488,7 @@ specbind (Lisp_Object symbol, Lisp_Object value) | |||
| 3476 | switch (sym->u.s.redirect) | 3488 | switch (sym->u.s.redirect) |
| 3477 | { | 3489 | { |
| 3478 | case SYMBOL_VARALIAS: | 3490 | case SYMBOL_VARALIAS: |
| 3479 | sym = indirect_variable (sym); XSETSYMBOL (symbol, sym); goto start; | 3491 | sym = SYMBOL_ALIAS (sym); XSETSYMBOL (symbol, sym); goto start; |
| 3480 | case SYMBOL_PLAINVAL: | 3492 | case SYMBOL_PLAINVAL: |
| 3481 | /* The most common case is that of a non-constant symbol with a | 3493 | /* The most common case is that of a non-constant symbol with a |
| 3482 | trivial value. Make that as fast as we can. */ | 3494 | trivial value. Make that as fast as we can. */ |