changeset 39973:579177964efa

Avoid (most) uses of XCAR/XCDR as lvalues, for flexibility in experimenting with lisp system changes.
author Ken Raeburn <raeburn@raeburn.org>
date Tue, 16 Oct 2001 09:09:51 +0000
parents b2479b43184b
children a72c97b251de
files src/ChangeLog src/alloc.c src/buffer.c src/callint.c src/ccl.c src/coding.c src/composite.c src/data.c src/doc.c src/fileio.c src/fns.c src/fontset.c src/frame.c src/indent.c src/keyboard.c src/keyboard.h src/keymap.c src/lisp.h src/lread.c src/minibuf.c src/process.c src/search.c src/textprop.c src/undo.c src/w32fns.c src/w32term.c src/xfaces.c src/xselect.c src/xterm.c
diffstat 29 files changed, 350 insertions(+), 193 deletions(-) [+]
line wrap: on
line diff
--- a/src/ChangeLog	Mon Oct 15 20:52:59 2001 +0000
+++ b/src/ChangeLog	Tue Oct 16 09:09:51 2001 +0000
@@ -1,3 +1,81 @@
+2001-10-16  Ken Raeburn  <raeburn@gnu.org>
+
+	Avoid the assumption that car and cdr slots of cons cells are
+	addressable lvalues; this allows for easier experimentation with
+	other lisp implementations that may not permit such accesses for
+	various reasons.  Not quite complete -- buffer.c still needs some
+	work, and w32/mac files need rechecking -- so compile-time
+	enforcement is left disabled for now.
+
+	* lisp.h (LISP_MAKE_RVALUE): New macro, or function in the case of
+	gcc with a union-based Lisp object rep.  Redefine as no-op for
+	now.
+	(XCAR_AS_LVALUE, XCDR_AS_LVALUE): Rename from old XCAR, XCDR.
+	(XCAR, XCDR): Apply LISP_MAKE_RVALUE to the _AS_LVALUE versions.
+	(XSETCAR, XSETCDR): New macros.
+	(XSETCARFASTINT, XSETCDRFASTINT): New macros.
+	(CHECK_NUMBER_CAR, CHECK_NUMBER_CDR): New macros.
+	* keyboard.h (POSN_BUFFER_SET_POSN): New macro.
+	* alloc.c (Fcons, pure_cons, Fgarbage_collect): Use XSETCAR and
+	XSETCDR.
+	(mark_buffer): Use XCAR_AS_LVALUE, XCDR_AS_LVALUE.
+	* buffer.c (record_buffer, Fbury_buffer,
+	swap_out_buffer_local_variables, recenter_overlay_lists,
+	Foverlay_put): Use XSETCAR and XSETCDR to set the car and cdr
+	fields of a cons cell respectively.
+	* callint.c (quotify_args, Fcall_interactively): Likewise.
+	* ccl.c (Fregister_code_conversion_map): Likewise.
+	* coding.c (detect_coding_system): Likewise.
+	* composite.c (get_composition_id, make_composition_value_copy):
+	Likewise.
+	* data.c (Fsetcar, Fsetcdr, swap_in_global_binding,
+	swap_in_symval_forwarding, set_internal, Fset_default,
+	Fmake_variable_buffer_local, Fmake_local_variable,
+	Fmake_variable_frame_local): Likewise.
+	* fns.c (concat, Fcopy_alist, Fwidget_put): Likewise.
+	* keymap.c (Fset_keymap_parent, store_in_keymap,
+	accessible_keymaps_1, where_is_internal_2, Fcopy_keymap):
+	Likewise.
+	* minibuf.c (get_minibuffer): Likewise.
+	* search.c (Fmatch_data): Likewise.
+	* textprop.c (extend_property_ranges): Likewise.
+	* undo.c (record_insert, Fundo_boundary, truncate_undo_list):
+	Likewise.
+	* w32fns.c (w32_msg_pump, Fw32_register_hot_key, w32_list_fonts):
+	Likewise.
+	* w32term.c (x_delete_display): Likewise.
+	* xfaces.c (remove_duplicates, Finternal_set_lisp_face_attribute):
+	Likewise.
+	* xterm.c (x_list_fonts, x_load_font, x_delete_display):
+	Likewise.
+	* doc.c (store_function_docstring): Use XSETCARFASTINT.
+	* fileio.c (Fdo_auto_save): Use XSETCARFASTINT and
+	XSETCDRFASTINT.
+	(Fread_file_name): Use XSETCAR.
+	* fontset.c (Fset_fontset_font): Use CHECK_NUMBER_CAR and
+	CHECK_NUMBER_CDR.
+	(accumulate_font_info, Ffontset_info): Use XSETCAR and XSETCDR.
+	* frame.c (Fmake_terminal_frame): Use XSETCDR.
+	* indent.c (Fcompute_motion): Use CHECK_NUMBER_CAR and
+	CHECK_NUMBER_CDR.
+	* keyboard.c (read_char): Alter list traversal to avoid taking the
+	address of cons cell slots.  Use POSN_BUFFER_SET_POSN.
+	(parse_menu_item): Use XSETCAR and XSETCDR.
+	(reach_char_x_menu_prompt): Use XSETCAR.
+	(read_key_sequence): Use POSN_BUFFER_SET_POSN.
+	(Fcommand_execute): Use XSETCDR.
+	* lread.c (Fload): Use XSETCARFASTINT and XSETCDRFASTINT.
+	(openp): Change list traversal to avoid using XCAR as lvalue.
+	(read_list): Use XSETCDR.
+	* process.c (wait_reading_process_input): Change wait_for_cell
+	handling to avoid taking addresses of cons cell slots.
+	* xselect.c (x_own_selection, x_handle_selection_clear,
+	x_clear_frame_selections): Use XSETCDR.
+	(wait_for_property_change): Use XSETCARFASTINT and
+	XSETCDRFASTINT.
+	(x_handle_property_notify, x_get_foreign_selection,
+	x_handle_selection_notify): Use XSETCAR.
+
 2001-10-15  Pavel Jan,Bm(Bk  <Pavel@Janik.cz>
 
 	* buffer.c: Put doc strings in comments.
--- a/src/alloc.c	Mon Oct 15 20:52:59 2001 +0000
+++ b/src/alloc.c	Tue Oct 16 09:09:51 2001 +0000
@@ -2087,8 +2087,8 @@
       XSETCONS (val, &cons_block->conses[cons_block_index++]);
     }
   
-  XCAR (val) = car;
-  XCDR (val) = cdr;
+  XSETCAR (val, car);
+  XSETCDR (val, cdr);
   consing_since_gc += sizeof (struct Lisp_Cons);
   cons_cells_consed++;
   return val;
@@ -3878,8 +3878,8 @@
 
   p = (struct Lisp_Cons *) pure_alloc (sizeof *p, Lisp_Cons);
   XSETCONS (new, p);
-  XCAR (new) = Fpurecopy (car);
-  XCDR (new) = Fpurecopy (cdr);
+  XSETCAR (new, Fpurecopy (car));
+  XSETCDR (new, Fpurecopy (cdr));
   return new;
 }
 
@@ -4189,7 +4189,10 @@
 		    if (NILP (prev))
 		      nextb->undo_list = tail = XCDR (tail);
 		    else
-		      tail = XCDR (prev) = XCDR (tail);
+		      {
+			tail = XCDR (tail);
+			XSETCDR (prev, tail);
+		      }
 		  }
 		else
 		  {
@@ -4800,8 +4803,8 @@
 	      && ! XMARKBIT (XCAR (ptr->car))
 	      && GC_MARKERP (XCAR (ptr->car)))
 	    {
-	      XMARK (XCAR (ptr->car));
-	      mark_object (&XCDR (ptr->car));
+	      XMARK (XCAR_AS_LVALUE (ptr->car));
+	      mark_object (&XCDR_AS_LVALUE (ptr->car));
 	    }
 	  else
 	    mark_object (&ptr->car);
@@ -4812,7 +4815,7 @@
 	    break;
 	}
 
-      mark_object (&XCDR (tail));
+      mark_object (&XCDR_AS_LVALUE (tail));
     }
   else
     mark_object (&buffer->undo_list);
--- a/src/buffer.c	Mon Oct 15 20:52:59 2001 +0000
+++ b/src/buffer.c	Tue Oct 16 09:09:51 2001 +0000
@@ -1415,9 +1415,9 @@
   if (NILP (prev))
     Vbuffer_alist = XCDR (Vbuffer_alist);
   else
-    XCDR (prev) = XCDR (XCDR (prev));
+    XSETCDR (prev, XCDR (XCDR (prev)));
 	
-  XCDR (link) = Vbuffer_alist;
+  XSETCDR (link, Vbuffer_alist);
   Vbuffer_alist = link;
 
   /* Now move this buffer to the front of frame_buffer_list also.  */
@@ -1439,9 +1439,9 @@
 	set_frame_buffer_list (frame,
 			       XCDR (frame_buffer_list (frame)));
       else
-	XCDR (prev) = XCDR (XCDR (prev));
+	XSETCDR (prev, XCDR (XCDR (prev)));
 	
-      XCDR (link) = frame_buffer_list (frame);
+      XSETCDR (link, frame_buffer_list (frame));
       set_frame_buffer_list (frame, link);
     }
   else
@@ -1863,7 +1863,7 @@
       aelt = Frassq (buffer, Vbuffer_alist);
       link = Fmemq (aelt, Vbuffer_alist);
       Vbuffer_alist = Fdelq (aelt, Vbuffer_alist);
-      XCDR (link) = Qnil;
+      XSETCDR (link, Qnil);
       Vbuffer_alist = nconc2 (Vbuffer_alist, link);
 
       frames_bury_buffer (buffer);
@@ -2286,10 +2286,10 @@
 	     it is currently set up for.  This is so that, if the
 	     local is marked permanent, and we make it local again
 	     later in Fkill_all_local_variables, we don't lose the value.  */
-	  XCDR (XCAR (tem))
-	    = do_symval_forwarding (XBUFFER_LOCAL_VALUE (SYMBOL_VALUE (sym))->realvalue);
+	  XSETCDR (XCAR (tem),
+		   do_symval_forwarding (XBUFFER_LOCAL_VALUE (SYMBOL_VALUE (sym))->realvalue));
 	  /* Switch to the symbol's default-value alist entry.  */
-	  XCAR (tem) = tem;
+	  XSETCAR (tem, tem);
 	  /* Mark it as current for buffer B.  */
 	  XBUFFER_LOCAL_VALUE (SYMBOL_VALUE (sym))->buffer = buffer;
 	  /* Store the current value into any forwarding in the symbol.  */
@@ -3008,7 +3008,7 @@
 
 	  /* Splice the cons cell TAIL out of overlays_before.  */
 	  if (!NILP (prev))
-	    XCDR (prev) = next;
+	    XSETCDR (prev, next);
 	  else
 	    buf->overlays_before = next;
 
@@ -3030,9 +3030,9 @@
 	    }
 
 	  /* Add TAIL to overlays_after before OTHER.  */
-	  XCDR (tail) = other;
+	  XSETCDR (tail, other);
 	  if (!NILP (other_prev))
-	    XCDR (other_prev) = tail;
+	    XSETCDR (other_prev, tail);
 	  else
 	    buf->overlays_after = tail;
 	  tail = prev;
@@ -3085,7 +3085,7 @@
 
 	  /* Splice the cons cell TAIL out of overlays_after.  */
 	  if (!NILP (prev))
-	    XCDR (prev) = next;
+	    XSETCDR (prev, next);
 	  else
 	    buf->overlays_after = next;
 
@@ -3107,9 +3107,9 @@
 	    }
 
 	  /* Add TAIL to overlays_before before OTHER.  */
-	  XCDR (tail) = other;
+	  XSETCDR (tail, other);
 	  if (!NILP (other_prev))
-	    XCDR (other_prev) = tail;
+	    XSETCDR (other_prev, tail);
 	  else
 	    buf->overlays_before = tail;
 	  tail = prev;
@@ -3841,7 +3841,7 @@
     if (EQ (XCAR (tail), prop))
       {
 	changed = !EQ (XCAR (XCDR (tail)), value);
-	XCAR (XCDR (tail)) = value;
+	XSETCAR (XCDR (tail), value);
 	goto found;
       }
   /* It wasn't in the list, so add it to the front.  */
--- a/src/callint.c	Mon Oct 15 20:52:59 2001 +0000
+++ b/src/callint.c	Tue Oct 16 09:09:51 2001 +0000
@@ -156,7 +156,7 @@
   for (tail = exp; CONSP (tail); tail = next)
     {
       next = XCDR (tail);
-      XCAR (tail) = quotify_arg (XCAR (tail));
+      XSETCAR (tail, quotify_arg (XCAR (tail)));
     }
   return exp;
 }
@@ -358,7 +358,7 @@
 	    {
 	      teml = Fnthcdr (Vhistory_length, Vcommand_history);
 	      if (CONSP (teml))
-		XCDR (teml) = Qnil;
+		XSETCDR (teml, Qnil);
 	    }
 	}
       single_kboard_state ();
@@ -776,7 +776,7 @@
 	{
 	  teml = Fnthcdr (Vhistory_length, Vcommand_history);
 	  if (CONSP (teml))
-	    XCDR (teml) = Qnil;
+	    XSETCDR (teml, Qnil);
 	}
     }
 
--- a/src/ccl.c	Mon Oct 15 20:52:59 2001 +0000
+++ b/src/ccl.c	Tue Oct 16 09:09:51 2001 +0000
@@ -2274,7 +2274,7 @@
       if (EQ (symbol, XCAR (slot)))
 	{
 	  index = make_number (i);
-	  XCDR (slot) = map;
+	  XSETCDR (slot, map);
 	  Fput (symbol, Qcode_conversion_map, map);
 	  Fput (symbol, Qcode_conversion_map_id, index);
 	  return index;
--- a/src/coding.c	Mon Oct 15 20:52:59 2001 +0000
+++ b/src/coding.c	Tue Oct 16 09:09:51 2001 +0000
@@ -6212,7 +6212,7 @@
 	  Lisp_Object eol;
 	  eol = Fget (XCAR (tmp), Qeol_type);
 	  if (VECTORP (eol))
-	    XCAR (tmp) = XVECTOR (eol)->contents[eol_type];
+	    XSETCAR (tmp, XVECTOR (eol)->contents[eol_type]);
 	}
     }
   return (highest ? XCAR (val) : val);
--- a/src/composite.c	Mon Oct 15 20:52:59 2001 +0000
+++ b/src/composite.c	Tue Oct 16 09:09:51 2001 +0000
@@ -249,8 +249,8 @@
 	 modify the cons cell of PROP because it is not shared.  */
       key = HASH_KEY (hash_table, hash_index);
       id = HASH_VALUE (hash_table, hash_index);
-      XCAR (prop) = id;
-      XCDR (prop) = Fcons (make_number (nchars), Fcons (key, XCDR (prop)));
+      XSETCAR (prop, id);
+      XSETCDR (prop, Fcons (make_number (nchars), Fcons (key, XCDR (prop))));
       return XINT (id);
     }
 
@@ -297,8 +297,8 @@
   /* Change PROP from Form-A above to Form-B.  We can directly modify
      the cons cell of PROP because it is not shared.  */
   XSETFASTINT (id, n_compositions);
-  XCAR (prop) = id;
-  XCDR (prop) = Fcons (make_number (nchars), Fcons (key, XCDR (prop)));
+  XSETCAR (prop, id);
+  XSETCDR (prop, Fcons (make_number (nchars), Fcons (key, XCDR (prop))));
 
   /* Register the composition in composition_hash_table.  */
   hash_index = hash_put (hash_table, key, id, hash_code);
@@ -569,7 +569,7 @@
 	{
 	  if (EQ (XCAR (plist), Qcomposition)
 	      && (val = XCAR (XCDR (plist)), CONSP (val)))
-	    XCAR (XCDR (plist)) = Fcons (XCAR (val), XCDR (val));
+	    XSETCAR (XCDR (plist), Fcons (XCAR (val), XCDR (val)));
 	  plist = XCDR (XCDR (plist));
 	}
     }
--- a/src/data.c	Mon Oct 15 20:52:59 2001 +0000
+++ b/src/data.c	Tue Oct 16 09:09:51 2001 +0000
@@ -582,7 +582,7 @@
     cell = wrong_type_argument (Qconsp, cell);
 
   CHECK_IMPURE (cell);
-  XCAR (cell) = newcar;
+  XSETCAR (cell, newcar);
   return newcar;
 }
 
@@ -595,7 +595,7 @@
     cell = wrong_type_argument (Qconsp, cell);
 
   CHECK_IMPURE (cell);
-  XCDR (cell) = newcdr;
+  XSETCDR (cell, newcdr);
   return newcdr;
 }
 
@@ -937,7 +937,7 @@
 	   do_symval_forwarding (XBUFFER_LOCAL_VALUE (valcontents)->realvalue));
   
   /* Select the global binding in the symbol.  */
-  XCAR (cdr) = cdr;
+  XSETCAR (cdr, cdr);
   store_symval_forwarding (symbol, valcontents, XCDR (cdr), NULL);
 
   /* Indicate that the global binding is set up now.  */
@@ -991,7 +991,7 @@
 	XBUFFER_LOCAL_VALUE (valcontents)->found_for_buffer = 1;
 
       /* Load the new binding.  */
-      XCAR (XBUFFER_LOCAL_VALUE (valcontents)->cdr) = tem1;
+      XSETCAR (XBUFFER_LOCAL_VALUE (valcontents)->cdr, tem1);
       XSETBUFFER (XBUFFER_LOCAL_VALUE (valcontents)->buffer, current_buffer);
       XBUFFER_LOCAL_VALUE (valcontents)->frame = selected_frame;
       store_symval_forwarding (symbol,
@@ -1210,8 +1210,8 @@
 	    }
 
 	  /* Record which binding is now loaded.  */
-	  XCAR (XBUFFER_LOCAL_VALUE (valcontents)->cdr)
-	    = tem1;
+	  XSETCAR (XBUFFER_LOCAL_VALUE (valcontents)->cdr,
+		   tem1);
 
 	  /* Set `buffer' and `frame' slots for thebinding now loaded.  */
 	  XSETBUFFER (XBUFFER_LOCAL_VALUE (valcontents)->buffer, buf);
@@ -1243,7 +1243,7 @@
 	 the default binding is loaded, the loaded binding may be the
 	 wrong one.  */
       if (XBUFFER_LOCAL_VALUE (valcontents)->found_for_frame)
-	XCDR (current_alist_element) = newval;
+	XSETCDR (current_alist_element, newval);
     }
 
   return newval;
@@ -1362,7 +1362,7 @@
     return Fset (symbol, value);
 
   /* Store new value into the DEFAULT-VALUE slot.  */
-  XCDR (XBUFFER_LOCAL_VALUE (valcontents)->cdr) = value;
+  XSETCDR (XBUFFER_LOCAL_VALUE (valcontents)->cdr, value);
 
   /* If the default binding is now loaded, set the REALVALUE slot too.  */
   current_alist_element
@@ -1448,7 +1448,7 @@
   if (EQ (valcontents, Qunbound))
     SET_SYMBOL_VALUE (variable, Qnil);
   tem = Fcons (Qnil, Fsymbol_value (variable));
-  XCAR (tem) = tem;
+  XSETCAR (tem, tem);
   newval = allocate_misc ();
   XMISCTYPE (newval) = Lisp_Misc_Buffer_Local_Value;
   XBUFFER_LOCAL_VALUE (newval)->realvalue = SYMBOL_VALUE (variable);
@@ -1505,7 +1505,7 @@
     {
       Lisp_Object newval;
       tem = Fcons (Qnil, do_symval_forwarding (valcontents));
-      XCAR (tem) = tem;
+      XSETCAR (tem, tem);
       newval = allocate_misc ();
       XMISCTYPE (newval) = Lisp_Misc_Some_Buffer_Local_Value;
       XBUFFER_LOCAL_VALUE (newval)->realvalue = SYMBOL_VALUE (variable);
@@ -1644,7 +1644,7 @@
   if (EQ (valcontents, Qunbound))
     SET_SYMBOL_VALUE (variable, Qnil);
   tem = Fcons (Qnil, Fsymbol_value (variable));
-  XCAR (tem) = tem;
+  XSETCAR (tem, tem);
   newval = allocate_misc ();
   XMISCTYPE (newval) = Lisp_Misc_Some_Buffer_Local_Value;
   XBUFFER_LOCAL_VALUE (newval)->realvalue = SYMBOL_VALUE (variable);
--- a/src/doc.c	Mon Oct 15 20:52:59 2001 +0000
+++ b/src/doc.c	Tue Oct 16 09:09:51 2001 +0000
@@ -445,7 +445,7 @@
 	{
 	  tem = Fcdr (Fcdr (fun));
 	  if (CONSP (tem) && INTEGERP (XCAR (tem)))
-	    XSETFASTINT (XCAR (tem), offset);
+	    XSETCARFASTINT (tem, offset);
 	}
       else if (EQ (tem, Qmacro))
 	store_function_docstring (XCDR (fun), offset);
--- a/src/fileio.c	Mon Oct 15 20:52:59 2001 +0000
+++ b/src/fileio.c	Tue Oct 16 09:09:51 2001 +0000
@@ -5499,8 +5499,8 @@
 	  /* Arrange to close that file whether or not we get an error.
 	     Also reset auto_saving to 0.  */
 	  lispstream = Fcons (Qnil, Qnil);
-	  XSETFASTINT (XCAR (lispstream), (EMACS_UINT)stream >> 16);
-	  XSETFASTINT (XCDR (lispstream), (EMACS_UINT)stream & 0xffff);
+	  XSETCARFASTINT (lispstream, (EMACS_UINT)stream >> 16);
+	  XSETCDRFASTINT (lispstream, (EMACS_UINT)stream & 0xffff);
 	}
       else
 	lispstream = Qnil;
@@ -5939,7 +5939,7 @@
   if (replace_in_history)
     /* Replace what Fcompleting_read added to the history
        with what we will actually return.  */
-    XCAR (Fsymbol_value (Qfile_name_history)) = double_dollars (val);
+    XSETCAR (Fsymbol_value (Qfile_name_history), double_dollars (val));
   else if (add_to_history)
     {
       /* Add the value to the history--but not if it matches
--- a/src/fns.c	Mon Oct 15 20:52:59 2001 +0000
+++ b/src/fns.c	Tue Oct 16 09:09:51 2001 +0000
@@ -782,7 +782,7 @@
 	    /* Store this element into the result.  */
 	    if (toindex < 0)
 	      {
-		XCAR (tail) = elt;
+		XSETCAR (tail, elt);
 		prev = tail;
 		tail = XCDR (tail);
 	      }
@@ -823,7 +823,7 @@
 	  }
     }
   if (!NILP (prev))
-    XCDR (prev) = last_tail;
+    XSETCDR (prev, last_tail);
 
   if (num_textprops > 0)
     {
@@ -1159,7 +1159,7 @@
       car = XCAR (tem);
 
       if (CONSP (car))
-	XCAR (tem) = Fcons (XCAR (car), XCDR (car));
+	XSETCAR (tem, Fcons (XCAR (car), XCDR (car)));
     }
   return alist;
 }
@@ -3153,7 +3153,7 @@
      Lisp_Object widget, property, value;
 {
   CHECK_CONS (widget, 1);
-  XCDR (widget) = Fplist_put (XCDR (widget), property, value);
+  XSETCDR (widget, Fplist_put (XCDR (widget), property, value));
   return value;
 }
 
--- a/src/fontset.c	Mon Oct 15 20:52:59 2001 +0000
+++ b/src/fontset.c	Tue Oct 16 09:09:51 2001 +0000
@@ -994,8 +994,8 @@
     {
       /* CH should be (FROM . TO) where FROM and TO are non-generic
 	 characters.  */
-      CHECK_NUMBER (XCAR (character), 1);
-      CHECK_NUMBER (XCDR (character), 1);
+      CHECK_NUMBER_CAR (character, 1);
+      CHECK_NUMBER_CDR (character, 1);
       from = XINT (XCAR (character));
       to = XINT (XCDR (character));
       if (!char_valid_p (from, 0) || !char_valid_p (to, 0))
@@ -1214,7 +1214,7 @@
 	{
 	  if (this_charset == CHAR_CHARSET (XINT (XCAR (last_char))))
 	    {
-	      XCDR (last_char) = character;
+	      XSETCDR (last_char, character);
 	      return;
 	    }
 	}
@@ -1222,12 +1222,12 @@
 	return;
       else if (this_charset == CHAR_CHARSET (XINT (last_char)))
 	{
-	  XCAR (XCAR (last)) = Fcons (last_char, character);
+	  XSETCAR (XCAR (last), Fcons (last_char, character));
 	  return;
 	}
     }
-  XCDR (last) = Fcons (Fcons (character, Fcons (elt, Qnil)), Qnil);
-  XCAR (arg) = XCDR (last);
+  XSETCDR (last, Fcons (Fcons (character, Fcons (elt, Qnil)), Qnil));
+  XSETCAR (arg, XCDR (last));
 }
 
 
@@ -1306,7 +1306,7 @@
 	  c = XINT (XCAR (elt));
 	  SPLIT_CHAR (c, charset, c1, c2);
 	  if (c1 == 0)
-	    XCAR (elt) = CHARSET_SYMBOL (charset);
+	    XSETCAR (elt, CHARSET_SYMBOL (charset));
 	}
       else
 	c = XINT (XCAR (XCAR (elt)));
@@ -1323,7 +1323,7 @@
 		{
 		  font = build_string (face->font_name);
 		  if (NILP (Fmember (font, XCDR (XCDR (elt)))))
-		    XCDR (XCDR (elt)) = Fcons (font, XCDR (XCDR (elt)));
+		    XSETCDR (XCDR (elt), Fcons (font, XCDR (XCDR (elt))));
 		}
 	    }
 	}
--- a/src/frame.c	Mon Oct 15 20:52:59 2001 +0000
+++ b/src/frame.c	Tue Oct 16 09:09:51 2001 +0000
@@ -543,7 +543,7 @@
      the vectors which are the CDRs of associations in face_alist to
      be copied as well.  */
   for (tem = f->face_alist; CONSP (tem); tem = XCDR (tem))
-    XCDR (XCAR (tem)) = Fcopy_sequence (XCDR (XCAR (tem)));
+    XSETCDR (XCAR (tem), Fcopy_sequence (XCDR (XCAR (tem))));
   return frame;
 }
 
--- a/src/indent.c	Mon Oct 15 20:52:59 2001 +0000
+++ b/src/indent.c	Tue Oct 16 09:09:51 2001 +0000
@@ -1755,18 +1755,18 @@
 
   CHECK_NUMBER_COERCE_MARKER (from, 0);
   CHECK_CONS (frompos, 0);
-  CHECK_NUMBER (XCAR (frompos), 0);
-  CHECK_NUMBER (XCDR (frompos), 0);
+  CHECK_NUMBER_CAR (frompos, 0);
+  CHECK_NUMBER_CDR (frompos, 0);
   CHECK_NUMBER_COERCE_MARKER (to, 0);
   CHECK_CONS (topos, 0);
-  CHECK_NUMBER (XCAR (topos), 0);
-  CHECK_NUMBER (XCDR (topos), 0);
+  CHECK_NUMBER_CAR (topos, 0);
+  CHECK_NUMBER_CDR (topos, 0);
   CHECK_NUMBER (width, 0);
   if (!NILP (offsets))
     {
       CHECK_CONS (offsets, 0);
-      CHECK_NUMBER (XCAR (offsets), 0);
-      CHECK_NUMBER (XCDR (offsets), 0);
+      CHECK_NUMBER_CAR (offsets, 0);
+      CHECK_NUMBER_CDR (offsets, 0);
       hscroll = XINT (XCAR (offsets));
       tab_offset = XINT (XCDR (offsets));
     }
--- a/src/keyboard.c	Mon Oct 15 20:52:59 2001 +0000
+++ b/src/keyboard.c	Tue Oct 16 09:09:51 2001 +0000
@@ -2358,15 +2358,21 @@
 	KBOARD *kb = FRAME_KBOARD (XFRAME (selected_frame));
 	if (kb != current_kboard)
 	  {
-	    Lisp_Object *tailp = &kb->kbd_queue;
+	    Lisp_Object link = kb->kbd_queue;
 	    /* We shouldn't get here if we were in single-kboard mode!  */
 	    if (single_kboard)
 	      abort ();
-	    while (CONSP (*tailp))
-	      tailp = &XCDR (*tailp);
-	    if (!NILP (*tailp))
-	      abort ();
-	    *tailp = Fcons (c, Qnil);
+	    if (CONSP (link))
+	      {
+		while (CONSP (XCDR (link)))
+		  link = XCDR (link);
+		if (!NILP (XCDR (link)))
+		  abort ();
+	      }
+	    if (!CONSP (link))
+	      kb->kbd_queue = Fcons (c, Qnil);
+	    else
+	      XSETCDR (link, Fcons (c, Qnil));
 	    kb->kbd_queue_has_data = 1;
 	    current_kboard = kb;
 	    /* This is going to exit from read_char
@@ -2581,12 +2587,18 @@
 #ifdef MULTI_KBOARD
       if (! NILP (c) && (kb != current_kboard))
 	{
-	  Lisp_Object *tailp = &kb->kbd_queue;
-	  while (CONSP (*tailp))
-	    tailp = &XCDR (*tailp);
-	  if (!NILP (*tailp))
-	    abort ();
-	  *tailp = Fcons (c, Qnil);
+	  Lisp_Object link = kb->kbd_queue;
+	  if (CONSP (link))
+	    {
+	      while (CONSP (XCDR (link)))
+		link = XCDR (link);
+	      if (!NILP (XCDR (link)))
+		abort ();
+	    }
+	  if (!CONSP (link))
+	    kb->kbd_queue = Fcons (c, Qnil);
+	  else
+	    XSETCDR (link, Fcons (c, Qnil));
 	  kb->kbd_queue_has_data = 1;
 	  c = Qnil;
 	  if (single_kboard)
@@ -2702,7 +2714,7 @@
       if (EQ (posn, Qmenu_bar) || EQ (posn, Qtool_bar))
 	{
 	  /* Change menu-bar to (menu-bar) as the event "position".  */
-	  POSN_BUFFER_POSN (EVENT_START (c)) = Fcons (posn, Qnil);
+	  POSN_BUFFER_SET_POSN (EVENT_START (c), Fcons (posn, Qnil));
 
 	  also_record = c;
 	  Vunread_command_events = Fcons (c, Vunread_command_events);
@@ -6854,19 +6866,19 @@
     {
       /* We have to create a cachelist.  */
       CHECK_IMPURE (start);
-      XCDR (start) = Fcons (Fcons (Qnil, Qnil), XCDR (start));
+      XSETCDR (start, Fcons (Fcons (Qnil, Qnil), XCDR (start)));
       cachelist = XCAR (XCDR (start));
       newcache = 1;
       tem = AREF (item_properties, ITEM_PROPERTY_KEYEQ);
       if (!NILP (keyhint))
 	{
-	  XCAR (cachelist) = XCAR (keyhint);
+	  XSETCAR (cachelist, XCAR (keyhint));
 	  newcache = 0;
 	}
       else if (STRINGP (tem))
 	{
-	  XCDR (cachelist) = Fsubstitute_command_keys (tem);
-	  XCAR (cachelist) = Qt;
+	  XSETCDR (cachelist, Fsubstitute_command_keys (tem));
+	  XSETCAR (cachelist, Qt);
 	}
     }
   
@@ -6924,10 +6936,10 @@
 	      && ! NILP (Fget (def, Qmenu_alias)))
 	    def = XSYMBOL (def)->function;
 	  tem = Fwhere_is_internal (def, Qnil, Qt, Qnil);
-	  XCAR (cachelist) = tem;
+	  XSETCAR (cachelist, tem);
 	  if (NILP (tem))
 	    {
-	      XCDR (cachelist) = Qnil;
+	      XSETCDR (cachelist, Qnil);
 	      chkcache = 0;
 	    }
 	}
@@ -6948,7 +6960,7 @@
 	      if (STRINGP (XCDR (prefix)))
 		tem = concat2 (tem, XCDR (prefix));
 	    }
-	  XCDR (cachelist) = tem;
+	  XSETCDR (cachelist, tem);
 	}
     }
 
@@ -6956,7 +6968,7 @@
   if (newcache && !NILP (tem))
     {
       tem = concat3 (build_string ("  ("), tem, build_string (")"));
-      XCDR (cachelist) = tem;
+      XSETCDR (cachelist, tem);
     }
 
   /* If we only want to precompute equivalent key bindings, stop here. */
@@ -7474,7 +7486,7 @@
 	      record_menu_key (XCAR (tem));
 	      if (SYMBOLP (XCAR (tem))
 		  || INTEGERP (XCAR (tem)))
-		XCAR (tem) = Fcons (XCAR (tem), Qdisabled);
+		XSETCAR (tem, Fcons (XCAR (tem), Qdisabled));
 	    }
 
 	  /* If we got more than one event, put all but the first
@@ -8466,8 +8478,8 @@
 
 		  /* Zap the position in key, so we know that we've
 		     expanded it, and don't try to do so again.  */
-		  POSN_BUFFER_POSN (EVENT_START (key))
-		    = Fcons (posn, Qnil);
+		  POSN_BUFFER_SET_POSN (EVENT_START (key),
+					Fcons (posn, Qnil));
 
 		  mock_input = t + 2;
 		  goto replay_sequence;
@@ -9203,7 +9215,7 @@
 	    {
 	      tem = Fnthcdr (Vhistory_length, Vcommand_history);
 	      if (CONSP (tem))
-		XCDR (tem) = Qnil;
+		XSETCDR (tem, Qnil);
 	    }
 	}
 
--- a/src/keyboard.h	Mon Oct 15 20:52:59 2001 +0000
+++ b/src/keyboard.h	Tue Oct 16 09:09:51 2001 +0000
@@ -260,6 +260,7 @@
 /* Extract the fields of a position.  */
 #define POSN_WINDOW(posn) (XCAR (posn))
 #define POSN_BUFFER_POSN(posn) (XCAR (XCDR (posn)))
+#define POSN_BUFFER_SET_POSN(posn,x) (XSETCAR (XCDR (posn), (x)))
 #define POSN_WINDOW_POSN(posn) (XCAR (XCDR (XCDR (posn))))
 #define POSN_TIMESTAMP(posn) \
   (XCAR (XCDR (XCDR (XCDR (posn)))))
--- a/src/keymap.c	Mon Oct 15 20:52:59 2001 +0000
+++ b/src/keymap.c	Tue Oct 16 09:09:51 2001 +0000
@@ -363,7 +363,7 @@
 	  if (EQ (XCDR (prev), parent))
 	    RETURN_UNGCPRO (parent);
 
-	  XCDR (prev) = parent;
+	  XSETCDR (prev, parent);
 	  break;
 	}
       prev = list;
@@ -769,7 +769,7 @@
 	  {
 	    if (EQ (idx, XCAR (elt)))
 	      {
-		XCDR (elt) = def;
+		XSETCDR (elt, def);
 		return def;
 	      }
 	  }
@@ -786,8 +786,8 @@
   keymap_end:
     /* We have scanned the entire keymap, and not found a binding for
        IDX.  Let's add one.  */
-    XCDR (insertion_point)
-      = Fcons (Fcons (idx, def), XCDR (insertion_point));
+    XSETCDR (insertion_point,
+	     Fcons (Fcons (idx, def), XCDR (insertion_point)));
   }
   
   return def;
@@ -830,7 +830,7 @@
 	  Lisp_Object indices[3];
 
 	  elt = Fcopy_sequence (elt);
-	  XCAR (tail) = elt;
+	  XSETCAR (tail, elt);
 
 	  map_char_table (copy_keymap_1, Qnil, elt, elt, 0, indices);
 	}
@@ -839,7 +839,7 @@
 	  int i;
 
 	  elt = Fcopy_sequence (elt);
-	  XCAR (tail) = elt;
+	  XSETCAR (tail, elt);
 
 	  for (i = 0; i < ASIZE (elt); i++)
 	    if (CONSP (AREF (elt, i)) && EQ (XCAR (AREF (elt, i)), Qkeymap))
@@ -854,15 +854,15 @@
 	  if (EQ (XCAR (tem),Qmenu_item))
 	    {
 	      /* Copy cell with menu-item marker.  */
-	      XCDR (elt)
-		= Fcons (XCAR (tem), XCDR (tem));
+	      XSETCDR (elt,
+		       Fcons (XCAR (tem), XCDR (tem)));
 	      elt = XCDR (elt);
 	      tem = XCDR (elt);
 	      if (CONSP (tem))
 		{
 		  /* Copy cell with menu-item name.  */
-		  XCDR (elt)
-		    = Fcons (XCAR (tem), XCDR (tem));
+		  XSETCDR (elt,
+			   Fcons (XCAR (tem), XCDR (tem)));
 		  elt = XCDR (elt);
 		  tem = XCDR (elt);
 		};
@@ -870,16 +870,16 @@
 		{
 		  /* Copy cell with binding and if the binding is a keymap,
 		     copy that.  */
-		  XCDR (elt)
-		    = Fcons (XCAR (tem), XCDR (tem));
+		  XSETCDR (elt,
+			   Fcons (XCAR (tem), XCDR (tem)));
 		  elt = XCDR (elt);
 		  tem = XCAR (elt);
 		  if (CONSP (tem) && EQ (XCAR (tem), Qkeymap))
-		    XCAR (elt) = Fcopy_keymap (tem);
+		    XSETCAR (elt, Fcopy_keymap (tem));
 		  tem = XCDR (elt);
 		  if (CONSP (tem) && CONSP (XCAR (tem)))
 		    /* Delete cache for key equivalences.  */
-		    XCDR (elt) = XCDR (tem);
+		    XSETCDR (elt, XCDR (tem));
 		}
 	    }
 	  else
@@ -890,15 +890,15 @@
 	      if (STRINGP (XCAR (tem)))
 		{
 		  /* Copy the cell, since copy-alist didn't go this deep.  */
-		  XCDR (elt)
-		    = Fcons (XCAR (tem), XCDR (tem));
+		  XSETCDR (elt,
+			   Fcons (XCAR (tem), XCDR (tem)));
 		  elt = XCDR (elt);
 		  tem = XCDR (elt);
 		  /* Also skip the optional menu help string.  */
 		  if (CONSP (tem) && STRINGP (XCAR (tem)))
 		    {
-		      XCDR (elt)
-			= Fcons (XCAR (tem), XCDR (tem));
+		      XSETCDR (elt,
+			       Fcons (XCAR (tem), XCDR (tem)));
 		      elt = XCDR (elt);
 		      tem = XCDR (elt);
 		    }
@@ -908,12 +908,12 @@
 		      && CONSP (XCAR (tem))
 		      && (NILP (XCAR (XCAR (tem)))
 			  || VECTORP (XCAR (XCAR (tem)))))
-		    XCDR (elt) = XCDR (tem);
+		    XSETCDR (elt, XCDR (tem));
 		}
 	      if (CONSP (elt)
 		  && CONSP (XCDR (elt))
 		  && EQ (XCAR (XCDR (elt)), Qkeymap))
-		XCDR (elt) = Fcopy_keymap (XCDR (elt));
+		XSETCDR (elt, Fcopy_keymap (XCDR (elt)));
 	    }
 
 	}
@@ -1548,8 +1548,8 @@
 	      /* This new sequence is the same length as
 		 thisseq, so stick it in the list right
 		 after this one.  */
-	      XCDR (tail)
-		= Fcons (Fcons (tem, cmd), XCDR (tail));
+	      XSETCDR (tail,
+		       Fcons (Fcons (tem, cmd), XCDR (tail)));
 	    }
 	  else
 	    {
@@ -2396,7 +2396,7 @@
 				  this, last, nomenus, last_is_meta);
 
   if (!NILP (sequence))
-    XCDR (XCAR (args)) = Fcons (sequence, result);
+    XSETCDR (XCAR (args), Fcons (sequence, result));
 
   UNGCPRO;
 }
--- a/src/lisp.h	Mon Oct 15 20:52:59 2001 +0000
+++ b/src/lisp.h	Tue Oct 16 09:09:51 2001 +0000
@@ -248,6 +248,16 @@
 
 #endif /* WORDS_BIG_ENDIAN */
 
+#ifdef __GNUC__
+static __inline__ Lisp_Object
+LISP_MAKE_RVALUE (Lisp_Object o)
+{
+    return o;
+}
+#else
+#define LISP_MAKE_RVALUE(o) (o) /* XXX - keeps arg as rvalue.  */
+#endif
+
 #endif /* NO_UNION_TYPE */
 
 
@@ -255,6 +265,7 @@
 
 #ifdef NO_UNION_TYPE
 #define Lisp_Object EMACS_INT
+#define LISP_MAKE_RVALUE(o) (0+(o))
 #endif /* NO_UNION_TYPE */
 
 #ifndef VALMASK
@@ -616,14 +627,43 @@
   };
 
 /* Take the car or cdr of something known to be a cons cell.  */
+/* The _AS_LVALUE macros shouldn't be used outside of the minimal set
+   of code that has to know what a cons cell looks like.  Other code not
+   part of the basic lisp implementation should assume that the car and cdr
+   fields are not accessible as lvalues.  (What if we want to switch to
+   a copying collector someday?  Cached cons cell field addresses may be
+   invalidated at arbitrary points.)  */
 #ifdef HIDE_LISP_IMPLEMENTATION
-#define XCAR(c) (XCONS ((c))->car_)
-#define XCDR(c) (XCONS ((c))->cdr_)
+#define XCAR_AS_LVALUE(c) (XCONS ((c))->car_)
+#define XCDR_AS_LVALUE(c) (XCONS ((c))->cdr_)
 #else
-#define XCAR(c) (XCONS ((c))->car)
-#define XCDR(c) (XCONS ((c))->cdr)
+#define XCAR_AS_LVALUE(c) (XCONS ((c))->car)
+#define XCDR_AS_LVALUE(c) (XCONS ((c))->cdr)
 #endif
 
+/* Okay, we're not quite ready to turn this on yet.  A few files still
+   need to be updated and tested.  */
+#undef LISP_MAKE_RVALUE
+#define LISP_MAKE_RVALUE(x) (x)
+
+/* Use these from normal code.  */
+#define XCAR(c)	LISP_MAKE_RVALUE(XCAR_AS_LVALUE(c))
+#define XCDR(c) LISP_MAKE_RVALUE(XCDR_AS_LVALUE(c))
+
+/* Use these to set the fields of a cons cell.
+
+   Note that both arguments may refer to the same object, so 'n'
+   should not be read after 'c' is first modified.  Also, neither
+   argument should be evaluated more than once; side effects are
+   especially common in the second argument.  */
+#define XSETCAR(c,n) (XCAR_AS_LVALUE(c) = (n))
+#define XSETCDR(c,n) (XCDR_AS_LVALUE(c) = (n))
+
+/* For performance: Fast storage of positive integers into the
+   fields of a cons cell.  See above caveats.  */
+#define XSETCARFASTINT(c,n)  XSETFASTINT(XCAR_AS_LVALUE(c),(n))
+#define XSETCDRFASTINT(c,n)  XSETFASTINT(XCDR_AS_LVALUE(c),(n))
+
 /* Take the car or cdr of something whose type is not known.  */
 #define CAR(c)					\
  (CONSP ((c)) ? XCAR ((c))			\
@@ -1474,6 +1514,22 @@
 #define CHECK_OVERLAY(x, i) \
   do { if (!OVERLAYP ((x))) x = wrong_type_argument (Qoverlayp, (x));} while (0)
 
+/* Since we can't assign directly to the CAR or CDR fields of a cons
+   cell, use these when checking that those fields contain numbers.  */
+#define CHECK_NUMBER_CAR(x, i) \
+  do {					\
+    Lisp_Object tmp = XCAR (x);		\
+    CHECK_NUMBER (tmp, (i));		\
+    XSETCAR ((x), tmp);			\
+  } while (0)
+
+#define CHECK_NUMBER_CDR(x, i) \
+  do {					\
+    Lisp_Object tmp = XCDR (x);		\
+    CHECK_NUMBER (tmp, (i));		\
+    XSETCDR ((x), tmp);			\
+  } while (0)
+
 /* Cast pointers to this type to compare them.  Some machines want int.  */
 #ifndef PNTR_COMPARISON_TYPE
 #define PNTR_COMPARISON_TYPE EMACS_UINT
--- a/src/lread.c	Mon Oct 15 20:52:59 2001 +0000
+++ b/src/lread.c	Tue Oct 16 09:09:51 2001 +0000
@@ -832,8 +832,8 @@
 
   GCPRO1 (file);
   lispstream = Fcons (Qnil, Qnil);
-  XSETFASTINT (XCAR (lispstream), (EMACS_UINT)stream >> 16);
-  XSETFASTINT (XCDR (lispstream), (EMACS_UINT)stream & 0xffff);
+  XSETCARFASTINT (lispstream, (EMACS_UINT)stream >> 16);
+  XSETCDRFASTINT (lispstream, (EMACS_UINT)stream & 0xffff);
   record_unwind_protect (load_unwind, lispstream);
   record_unwind_protect (load_descriptor_unwind, load_descriptor_list);
   specbind (Qload_file_name, found);
@@ -963,16 +963,19 @@
   Lisp_Object string, tail;
   int max_suffix_len = 0;
 
-  for (tail = suffixes; CONSP (tail); tail = XCDR (tail))
-    {
-      CHECK_STRING (XCAR (tail), 0);
-      max_suffix_len = max (max_suffix_len,
-			    STRING_BYTES (XSTRING (XCAR (tail))));
-    }
-
   string = filename = Qnil;
   GCPRO5 (str, string, filename, path, suffixes);
   
+  for (tail = suffixes; CONSP (tail); tail = XCDR (tail))
+    {
+      string = XCAR (tail);
+      CHECK_STRING (string, 0);
+      if (! EQ (string, XCAR (tail)))
+	XSETCAR (tail, string);
+      max_suffix_len = max (max_suffix_len,
+			    STRING_BYTES (XSTRING (string)));
+    }
+
   if (storeptr)
     *storeptr = Qnil;
 
@@ -2724,7 +2727,7 @@
 	    {
 	      GCPRO2 (val, tail);
 	      if (!NILP (tail))
-		XCDR (tail) = read0 (readcharfun);
+		XSETCDR (tail, read0 (readcharfun));
 	      else
 		val = read0 (readcharfun);
 	      read1 (readcharfun, &ch, 0);
@@ -2817,7 +2820,7 @@
 	     ? pure_cons (elt, Qnil)
 	     : Fcons (elt, Qnil));
       if (!NILP (tail))
-	XCDR (tail) = tem;
+	XSETCDR (tail, tem);
       else
 	val = tem;
       tail = tem;
--- a/src/minibuf.c	Mon Oct 15 20:52:59 2001 +0000
+++ b/src/minibuf.c	Tue Oct 16 09:09:51 2001 +0000
@@ -723,7 +723,7 @@
 	 enabled in it.  */
       Fbuffer_enable_undo (buf);
 
-      XCAR (tail) = buf;
+      XSETCAR (tail, buf);
     }
   else
     {
--- a/src/process.c	Mon Oct 15 20:52:59 2001 +0000
+++ b/src/process.c	Tue Oct 16 09:09:51 2001 +0000
@@ -2367,7 +2367,9 @@
   int wait_channel = -1;
   struct Lisp_Process *wait_proc = 0;
   int got_some_input = 0;
-  Lisp_Object *wait_for_cell = 0;
+  /* Either nil or a cons cell, the car of which is of interest and
+     may be changed outside of this routine.  */
+  Lisp_Object wait_for_cell = Qnil;
 
   FD_ZERO (&Available);
 
@@ -2383,7 +2385,7 @@
   /* If waiting for non-nil in a cell, record where.  */
   if (CONSP (read_kbd))
     {
-      wait_for_cell = &XCAR (read_kbd);
+      wait_for_cell = read_kbd;
       XSETFASTINT (read_kbd, 0);
     }
 
@@ -2417,7 +2419,7 @@
 	QUIT;
 
       /* Exit now if the cell we're waiting for became non-nil.  */
-      if (wait_for_cell && ! NILP (*wait_for_cell))
+      if (! NILP (wait_for_cell) && ! NILP (XCAR (wait_for_cell)))
 	break;
 
       /* Compute time from now till when time limit is up */
@@ -2446,7 +2448,7 @@
 	 But not if wait_for_cell; in those cases,
 	 the wait is supposed to be short,
 	 and those callers cannot handle running arbitrary Lisp code here.  */
-      if (! wait_for_cell)
+      if (NILP (wait_for_cell))
 	{
 	  EMACS_TIME timer_delay;
 
@@ -2567,7 +2569,7 @@
 
       /* Wait till there is something to do */
 
-      if (wait_for_cell)
+      if (!NILP (wait_for_cell))
 	Available = non_process_wait_mask;
       else if (! XINT (read_kbd))
 	Available = non_keyboard_wait_mask;
@@ -2723,7 +2725,7 @@
 	}
 
       /* Exit now if the cell we're waiting for became non-nil.  */
-      if (wait_for_cell && ! NILP (*wait_for_cell))
+      if (! NILP (wait_for_cell) && ! NILP (XCAR (wait_for_cell)))
 	break;
 
 #ifdef SIGIO
@@ -2742,7 +2744,7 @@
 
       /* If checking input just got us a size-change event from X,
 	 obey it now if we should.  */
-      if (XINT (read_kbd) || wait_for_cell)
+      if (XINT (read_kbd) || ! NILP (wait_for_cell))
 	do_pending_window_change (0);
 
       /* Check for data from a process.  */
@@ -4768,12 +4770,14 @@
   EMACS_TIME end_time, timeout;
   SELECT_TYPE waitchannels;
   int xerrno;
-  Lisp_Object *wait_for_cell = 0;
+  /* Either nil or a cons cell, the car of which is of interest and
+     may be changed outside of this routine.  */
+  Lisp_Object wait_for_cell = Qnil;
 
   /* If waiting for non-nil in a cell, record where.  */
   if (CONSP (read_kbd))
     {
-      wait_for_cell = &XCAR (read_kbd);
+      wait_for_cell = read_kbd;
       XSETFASTINT (read_kbd, 0);
     }
 
@@ -4800,7 +4804,7 @@
 	QUIT;
 
       /* Exit now if the cell we're waiting for became non-nil.  */
-      if (wait_for_cell && ! NILP (*wait_for_cell))
+      if (! NILP (wait_for_cell) && ! NILP (XCAR (wait_for_cell)))
 	break;
 
       /* Compute time from now till when time limit is up */
@@ -4829,7 +4833,7 @@
 	 run timer events directly.
 	 (Callers that will immediately read keyboard events
 	 call timer_delay on their own.)  */
-      if (! wait_for_cell)
+      if (NILP (wait_for_cell))
 	{
 	  EMACS_TIME timer_delay;
 
@@ -4870,7 +4874,7 @@
 
       /* Wait till there is something to do.  */
 
-      if (! XINT (read_kbd) && wait_for_cell == 0)
+      if (! XINT (read_kbd) && NILP (wait_for_cell))
 	FD_ZERO (&waitchannels);
       else
 	FD_SET (0, &waitchannels);
@@ -4946,7 +4950,7 @@
 	 input at all when wait_for_cell, but the code
 	 has been this way since July 1994.
 	 Try changing this after version 19.31.)  */
-      if (wait_for_cell
+      if (! NILP (wait_for_cell)
 	  && detect_input_pending ())
 	{
 	  swallow_events (do_display);
@@ -4955,7 +4959,7 @@
 	}
 
       /* Exit now if the cell we're waiting for became non-nil.  */
-      if (wait_for_cell && ! NILP (*wait_for_cell))
+      if (! NILP (wait_for_cell) && ! NILP (XCAR (wait_for_cell)))
 	break;
     }
 
--- a/src/search.c	Mon Oct 15 20:52:59 2001 +0000
+++ b/src/search.c	Tue Oct 16 09:09:51 2001 +0000
@@ -2691,16 +2691,16 @@
        i++, tail = XCDR (tail))
     {
       if (i < 2 * len + 2)
-	XCAR (tail) = data[i];
+	XSETCAR (tail, data[i]);
       else
-	XCAR (tail) = Qnil;
+	XSETCAR (tail, Qnil);
       prev = tail;
     }
 
   /* If we couldn't fit all value elements into REUSE,
      cons up the rest of them and add them to the end of REUSE.  */
   if (i < 2 * len + 2)
-    XCDR (prev) = Flist (2 * len + 2 - i, data + i);
+    XSETCDR (prev, Flist (2 * len + 2 - i, data + i));
 
   return reuse;
 }
--- a/src/textprop.c	Mon Oct 15 20:52:59 2001 +0000
+++ b/src/textprop.c	Tue Oct 16 09:09:51 2001 +0000
@@ -1738,7 +1738,7 @@
       end = XCAR (XCDR (item));
 
       if (EQ (end, old_end))
-	XCAR (XCDR (item)) = new_end;
+	XSETCAR (XCDR (item), new_end);
     }
 }
 
--- a/src/undo.c	Mon Oct 15 20:52:59 2001 +0000
+++ b/src/undo.c	Tue Oct 16 09:09:51 2001 +0000
@@ -73,7 +73,7 @@
 	  && INTEGERP (XCDR (elt))
 	  && XINT (XCDR (elt)) == beg)
 	{
-	  XSETINT (XCDR (elt), beg + length);
+	  XSETCDR (elt, make_number (beg + length));
 	  return;
 	}
     }
@@ -273,7 +273,7 @@
 	{
 	  /* If we have preallocated the cons cell to use here,
 	     use that one.  */
-	  XCDR (pending_boundary) = current_buffer->undo_list;
+	  XSETCDR (pending_boundary, current_buffer->undo_list);
 	  current_buffer->undo_list = pending_boundary;
 	  pending_boundary = Qnil;
 	}
@@ -378,7 +378,7 @@
   /* Truncate at the boundary where we decided to truncate.  */
   if (!NILP (last_boundary))
     {
-      XCDR (last_boundary) = Qnil;
+      XSETCDR (last_boundary, Qnil);
       return list;
     }
   else
--- a/src/w32fns.c	Mon Oct 15 20:52:59 2001 +0000
+++ b/src/w32fns.c	Tue Oct 16 09:09:51 2001 +0000
@@ -3784,7 +3784,7 @@
                  thread-safe.  The next line is okay because the cons
                  cell is never made into garbage and is not relocated by
                  GC.  */
-	      XCAR ((Lisp_Object) msg.lParam) = Qnil;
+	      XSETCAR ((Lisp_Object) msg.lParam, Qnil);
 	      if (!PostThreadMessage (dwMainThreadId, WM_EMACS_DONE, 0, 0))
 		abort ();
 	      break;
@@ -6866,9 +6866,9 @@
 
       /* Make a list of the fonts we got back.
          Store that in the font cache for the display. */
-      XCDR (dpyinfo->name_list_element)
-        = Fcons (Fcons (tpat, list),
-                 XCDR (dpyinfo->name_list_element));
+      XSETCDR (dpyinfo->name_list_element,
+	       Fcons (Fcons (tpat, list),
+		      XCDR (dpyinfo->name_list_element)));
 
     label_cached:
       if (NILP (list)) continue; /* Try the remaining alternatives.  */
@@ -6915,9 +6915,9 @@
               hdc = GetDC (dpyinfo->root_window);
               oldobj = SelectObject (hdc, thisinfo.hfont);
               if (GetTextMetrics (hdc, &thisinfo.tm))
-                XCDR (tem) = make_number (FONT_WIDTH (&thisinfo));
+                XSETCDR (tem, make_number (FONT_WIDTH (&thisinfo)));
               else
-                XCDR (tem) = make_number (0);
+                XSETCDR (tem, make_number (0));
               SelectObject (hdc, oldobj);
               ReleaseDC (dpyinfo->root_window, hdc);
               DeleteObject(thisinfo.hfont);
@@ -13240,7 +13240,7 @@
       if (NILP (item))
 	w32_grabbed_keys = Fcons (key, w32_grabbed_keys);
       else
-	XCAR (item) = key;
+	XSETCAR (item, key);
 
       /* Notify input thread about new hot-key definition, so that it
 	 takes effect without needing to switch focus.  */
--- a/src/w32term.c	Mon Oct 15 20:52:59 2001 +0000
+++ b/src/w32term.c	Tue Oct 16 09:09:51 2001 +0000
@@ -10286,7 +10286,7 @@
 	{
 	  if (EQ (XCAR (XCDR (tail)), dpyinfo->name_list_element))
 	    {
-	      XCDR (tail) = XCDR (XCDR (tail));
+	      XSETCDR (tail, XCDR (XCDR (tail)));
 	      break;
 	    }
 	  tail = XCDR (tail);
--- a/src/xfaces.c	Mon Oct 15 20:52:59 2001 +0000
+++ b/src/xfaces.c	Tue Oct 16 09:09:51 2001 +0000
@@ -2684,7 +2684,7 @@
     {
       Lisp_Object next = XCDR (tail);
       if (!NILP (Fequal (XCAR (next), XCAR (tail))))
-	XCDR (tail) = XCDR (next);
+	XSETCDR (tail, XCDR (next));
       else
 	tail = XCDR (tail);
     }
@@ -4199,8 +4199,8 @@
 	  {
 	    Lisp_Object cons;
 	    cons = XCAR (Vparam_value_alist);
-	    XCAR (cons) = param;
-	    XCDR (cons) = value;
+	    XSETCAR (cons, param);
+	    XSETCDR (cons, value);
 	    Fmodify_frame_parameters (frame, Vparam_value_alist);
 	  }
     }
--- a/src/xselect.c	Mon Oct 15 20:52:59 2001 +0000
+++ b/src/xselect.c	Tue Oct 16 09:09:51 2001 +0000
@@ -338,7 +338,7 @@
 	for (rest = Vselection_alist; !NILP (rest); rest = Fcdr (rest))
 	  if (EQ (prev_value, Fcar (XCDR (rest))))
 	    {
-	      XCDR (rest) = Fcdr (XCDR (rest));
+	      XSETCDR (rest, Fcdr (XCDR (rest)));
 	      break;
 	    }
       }
@@ -905,7 +905,7 @@
       for (rest = Vselection_alist; !NILP (rest); rest = Fcdr (rest))
 	if (EQ (local_selection_data, Fcar (XCDR (rest))))
 	  {
-	    XCDR (rest) = Fcdr (XCDR (rest));
+	    XSETCDR (rest, Fcdr (XCDR (rest)));
 	    break;
 	  }
     }
@@ -982,7 +982,7 @@
 	    redisplay_preserve_echo_area (22);
 #endif
 	  }
-	XCDR (rest) = Fcdr (XCDR (rest));
+	XSETCDR (rest, Fcdr (XCDR (rest)));
 	break;
       }
 }
@@ -1076,13 +1076,13 @@
   Lisp_Object tem;
 
   tem = Fcons (Qnil, Qnil);
-  XSETFASTINT (XCAR (tem), (EMACS_UINT)location >> 16);
-  XSETFASTINT (XCDR (tem), (EMACS_UINT)location & 0xffff);
+  XSETCARFASTINT (tem, (EMACS_UINT)location >> 16);
+  XSETCDRFASTINT (tem, (EMACS_UINT)location & 0xffff);
 
   /* Make sure to do unexpect_property_change if we quit or err.  */
   record_unwind_protect (wait_for_property_change_unwind, tem);
 
-  XCAR (property_change_reply) = Qnil;
+  XSETCAR (property_change_reply, Qnil);
 
   property_change_reply_object = location;
   /* If the event we are waiting for arrives beyond here, it will set
@@ -1128,7 +1128,7 @@
 	  /* If this is the one wait_for_property_change is waiting for,
 	     tell it to wake up.  */
 	  if (rest == property_change_reply_object)
-	    XCAR (property_change_reply) = Qt;
+	    XSETCAR (property_change_reply, Qt);
 
 	  if (prev)
 	    prev->next = rest->next;
@@ -1239,7 +1239,7 @@
   /* Prepare to block until the reply has been read.  */
   reading_selection_window = requestor_window;
   reading_which_selection = selection_atom;
-  XCAR (reading_selection_reply) = Qnil;
+  XSETCAR (reading_selection_reply, Qnil);
 
   frame = some_frame_on_display (dpyinfo);
 
@@ -1942,8 +1942,8 @@
     return;
 
   TRACE0 ("Received SelectionNotify");
-  XCAR (reading_selection_reply)
-    = (event->property != 0 ? Qt : Qlambda);
+  XSETCAR (reading_selection_reply,
+	   (event->property != 0 ? Qt : Qlambda));
 }
 
 
--- a/src/xterm.c	Mon Oct 15 20:52:59 2001 +0000
+++ b/src/xterm.c	Tue Oct 16 09:09:51 2001 +0000
@@ -13714,8 +13714,8 @@
 	}
 
       /* Now store the result in the cache.  */
-      XCDR (dpyinfo->name_list_element)
-        = Fcons (Fcons (key, list), XCDR (dpyinfo->name_list_element));
+      XSETCDR (dpyinfo->name_list_element,
+	       Fcons (Fcons (key, list), XCDR (dpyinfo->name_list_element)));
 
     label_cached:
       if (NILP (list)) continue; /* Try the remaining alternatives.  */
@@ -13758,10 +13758,10 @@
 
 	      if (thisinfo)
 		{
-		  XCDR (tem)
-		    = (thisinfo->min_bounds.width == 0
-		       ? make_number (0)
-		       : make_number (thisinfo->max_bounds.width));
+		  XSETCDR (tem,
+			   (thisinfo->min_bounds.width == 0
+			    ? make_number (0)
+			    : make_number (thisinfo->max_bounds.width)));
 		  BLOCK_INPUT;
 		  XFreeFont (dpy, thisinfo);
 		  UNBLOCK_INPUT;
@@ -13770,7 +13770,7 @@
 		/* For unknown reason, the previous call of XListFont had
 		  returned a font which can't be opened.  Record the size
 		  as 0 not to try to open it again.  */
-		XCDR (tem) = make_number (0);
+		XSETCDR (tem, make_number (0));
 	    }
 
 	  found_size = XINT (XCDR (tem));
@@ -14036,22 +14036,22 @@
 	Lisp_Object key = Fcons (Fcons (lispy_name, make_number (256)),
 				 Qnil);
 
-	XCDR (dpyinfo->name_list_element)
-	  = Fcons (Fcons (key,
-			  Fcons (Fcons (lispy_full_name,
-					make_number (fontp->size)),
-				 Qnil)),
-		   XCDR (dpyinfo->name_list_element));
+	XSETCDR (dpyinfo->name_list_element,
+		 Fcons (Fcons (key,
+			       Fcons (Fcons (lispy_full_name,
+					     make_number (fontp->size)),
+				      Qnil)),
+			XCDR (dpyinfo->name_list_element)));
 	if (full_name)
 	  {
 	    key = Fcons (Fcons (lispy_full_name, make_number (256)),
 			 Qnil);
-	    XCDR (dpyinfo->name_list_element)
-	      = Fcons (Fcons (key,
-			      Fcons (Fcons (lispy_full_name,
-					    make_number (fontp->size)),
-				     Qnil)),
-		       XCDR (dpyinfo->name_list_element));
+	    XSETCDR (dpyinfo->name_list_element,
+		     Fcons (Fcons (key,
+				   Fcons (Fcons (lispy_full_name,
+						 make_number (fontp->size)),
+					  Qnil)),
+			    XCDR (dpyinfo->name_list_element)));
 	  }
       }
 
@@ -14622,7 +14622,7 @@
 	{
 	  if (EQ (XCAR (XCDR (tail)), dpyinfo->name_list_element))
 	    {
-	      XCDR (tail) = XCDR (XCDR (tail));
+	      XSETCDR (tail, XCDR (XCDR (tail)));
 	      break;
 	    }
 	  tail = XCDR (tail);