aboutsummaryrefslogtreecommitdiffstats
path: root/src/data.c
diff options
context:
space:
mode:
authorPo Lu2024-07-22 09:56:08 +0800
committerPo Lu2024-07-22 09:56:08 +0800
commitda0165a01e01dcb4334feee03b462ac09ceb0f8c (patch)
treec707b09510f6c41d636e59c7fbbf4f9d81d37b86 /src/data.c
parent4868a17396b6796b77285a3608b383aac32aee4f (diff)
downloademacs-da0165a01e01dcb4334feee03b462ac09ceb0f8c.tar.gz
emacs-da0165a01e01dcb4334feee03b462ac09ceb0f8c.zip
Prohibit unbinding of built-in variables
* src/data.c (set_internal): Signal error if a BLV with a redirect or a forwarded symbol is being unbound. * test/src/data-tests.el (binding-test-makunbound-built-in): New test.
Diffstat (limited to 'src/data.c')
-rw-r--r--src/data.c45
1 files changed, 22 insertions, 23 deletions
diff --git a/src/data.c b/src/data.c
index 3490d4985c9..752856abf09 100644
--- a/src/data.c
+++ b/src/data.c
@@ -1642,7 +1642,7 @@ void
1642set_internal (Lisp_Object symbol, Lisp_Object newval, Lisp_Object where, 1642set_internal (Lisp_Object symbol, Lisp_Object newval, Lisp_Object where,
1643 enum Set_Internal_Bind bindflag) 1643 enum Set_Internal_Bind bindflag)
1644{ 1644{
1645 bool voide = BASE_EQ (newval, Qunbound); 1645 bool unbinding_p = BASE_EQ (newval, Qunbound);
1646 1646
1647 /* If restoring in a dead buffer, do nothing. */ 1647 /* If restoring in a dead buffer, do nothing. */
1648 1648
@@ -1661,10 +1661,13 @@ set_internal (Lisp_Object symbol, Lisp_Object newval, Lisp_Object where,
1661 case SYMBOL_TRAPPED_WRITE: 1661 case SYMBOL_TRAPPED_WRITE:
1662 /* Setting due to thread-switching doesn't count. */ 1662 /* Setting due to thread-switching doesn't count. */
1663 if (bindflag != SET_INTERNAL_THREAD_SWITCH) 1663 if (bindflag != SET_INTERNAL_THREAD_SWITCH)
1664 notify_variable_watchers (symbol, voide? Qnil : newval, 1664 notify_variable_watchers (symbol, (unbinding_p ? Qnil : newval),
1665 (bindflag == SET_INTERNAL_BIND? Qlet : 1665 (bindflag == SET_INTERNAL_BIND
1666 bindflag == SET_INTERNAL_UNBIND? Qunlet : 1666 ? Qlet
1667 voide? Qmakunbound : Qset), 1667 : (bindflag == SET_INTERNAL_UNBIND
1668 ? Qunlet
1669 : (unbinding_p
1670 ? Qmakunbound : Qset))),
1668 where); 1671 where);
1669 break; 1672 break;
1670 1673
@@ -1682,6 +1685,11 @@ set_internal (Lisp_Object symbol, Lisp_Object newval, Lisp_Object where,
1682 case SYMBOL_LOCALIZED: 1685 case SYMBOL_LOCALIZED:
1683 { 1686 {
1684 struct Lisp_Buffer_Local_Value *blv = SYMBOL_BLV (sym); 1687 struct Lisp_Buffer_Local_Value *blv = SYMBOL_BLV (sym);
1688
1689 if (unbinding_p && blv->fwd.fwdptr)
1690 /* Forbid unbinding built-in variables. */
1691 error ("Built-in variables may not be unbound");
1692
1685 if (NILP (where)) 1693 if (NILP (where))
1686 XSETBUFFER (where, current_buffer); 1694 XSETBUFFER (where, current_buffer);
1687 1695
@@ -1746,16 +1754,9 @@ set_internal (Lisp_Object symbol, Lisp_Object newval, Lisp_Object where,
1746 set_blv_value (blv, newval); 1754 set_blv_value (blv, newval);
1747 1755
1748 if (blv->fwd.fwdptr) 1756 if (blv->fwd.fwdptr)
1749 { 1757 store_symval_forwarding (blv->fwd, newval, (BUFFERP (where)
1750 if (voide) 1758 ? XBUFFER (where)
1751 /* If storing void (making the symbol void), forward only through 1759 : current_buffer));
1752 buffer-local indicator, not through Lisp_Objfwd, etc. */
1753 blv->fwd.fwdptr = NULL;
1754 else
1755 store_symval_forwarding (blv->fwd, newval,
1756 BUFFERP (where)
1757 ? XBUFFER (where) : current_buffer);
1758 }
1759 break; 1760 break;
1760 } 1761 }
1761 case SYMBOL_FORWARDED: 1762 case SYMBOL_FORWARDED:
@@ -1763,6 +1764,11 @@ set_internal (Lisp_Object symbol, Lisp_Object newval, Lisp_Object where,
1763 struct buffer *buf 1764 struct buffer *buf
1764 = BUFFERP (where) ? XBUFFER (where) : current_buffer; 1765 = BUFFERP (where) ? XBUFFER (where) : current_buffer;
1765 lispfwd innercontents = SYMBOL_FWD (sym); 1766 lispfwd innercontents = SYMBOL_FWD (sym);
1767
1768 if (unbinding_p)
1769 /* Forbid unbinding built-in variables. */
1770 error ("Built-in variables may not be unbound");
1771
1766 if (BUFFER_OBJFWDP (innercontents)) 1772 if (BUFFER_OBJFWDP (innercontents))
1767 { 1773 {
1768 int offset = XBUFFER_OBJFWD (innercontents)->offset; 1774 int offset = XBUFFER_OBJFWD (innercontents)->offset;
@@ -1778,14 +1784,7 @@ set_internal (Lisp_Object symbol, Lisp_Object newval, Lisp_Object where,
1778 } 1784 }
1779 } 1785 }
1780 1786
1781 if (voide) 1787 store_symval_forwarding (/* sym, */ innercontents, newval, buf);
1782 { /* If storing void (making the symbol void), forward only through
1783 buffer-local indicator, not through Lisp_Objfwd, etc. */
1784 sym->u.s.redirect = SYMBOL_PLAINVAL;
1785 SET_SYMBOL_VAL (sym, newval);
1786 }
1787 else
1788 store_symval_forwarding (/* sym, */ innercontents, newval, buf);
1789 break; 1788 break;
1790 } 1789 }
1791 default: emacs_abort (); 1790 default: emacs_abort ();