aboutsummaryrefslogtreecommitdiffstats
path: root/src/alloc.c
diff options
context:
space:
mode:
authorPaul Eggert2012-02-25 11:39:42 -0800
committerPaul Eggert2012-02-25 11:39:42 -0800
commit27f3c6378b0e09d6e3c1b4b55b7e2fc5c22c8e65 (patch)
tree2e47f4531248214cbb4bd6ceb3bb152741e96aff /src/alloc.c
parent23453255524411eaae5c79d7e4ae6c22f6f05f3f (diff)
downloademacs-27f3c6378b0e09d6e3c1b4b55b7e2fc5c22c8e65.tar.gz
emacs-27f3c6378b0e09d6e3c1b4b55b7e2fc5c22c8e65.zip
Generalize fix for crash due to non-contiguous EMACS_INT (Bug#10780).
Suggested by Stefan Monnier in <http://lists.gnu.org/archive/html/emacs-devel/2012-02/msg00692.html>. * alloc.c (widen_to_Lisp_Object): New static function. (mark_memory): Also mark Lisp_Objects by fetching pointer words and widening them to Lisp_Objects. This would work even if USE_LSB_TAG is defined and wide integers are used, which might happen in a future version of Emacs.
Diffstat (limited to 'src/alloc.c')
-rw-r--r--src/alloc.c27
1 files changed, 26 insertions, 1 deletions
diff --git a/src/alloc.c b/src/alloc.c
index 044e750413b..21c4db4ddca 100644
--- a/src/alloc.c
+++ b/src/alloc.c
@@ -1582,6 +1582,21 @@ make_number (EMACS_INT n)
1582} 1582}
1583#endif 1583#endif
1584 1584
1585/* Convert the pointer-sized word P to EMACS_INT while preserving its
1586 type and ptr fields. */
1587static Lisp_Object
1588widen_to_Lisp_Object (void *p)
1589{
1590 intptr_t i = (intptr_t) p;
1591#ifdef USE_LISP_UNION_TYPE
1592 Lisp_Object obj;
1593 obj.i = i;
1594 return obj;
1595#else
1596 return i;
1597#endif
1598}
1599
1585/*********************************************************************** 1600/***********************************************************************
1586 String Allocation 1601 String Allocation
1587 ***********************************************************************/ 1602 ***********************************************************************/
@@ -4293,7 +4308,17 @@ mark_memory (void *start, void *end)
4293 4308
4294 for (pp = start; (void *) pp < end; pp++) 4309 for (pp = start; (void *) pp < end; pp++)
4295 for (i = 0; i < sizeof *pp; i += GC_POINTER_ALIGNMENT) 4310 for (i = 0; i < sizeof *pp; i += GC_POINTER_ALIGNMENT)
4296 mark_maybe_pointer (*(void **) ((char *) pp + i)); 4311 {
4312 void *w = *(void **) ((char *) pp + i);
4313 mark_maybe_pointer (w);
4314
4315 /* A host where a Lisp_Object is wider than a pointer might
4316 allocate a Lisp_Object in non-adjacent halves. If
4317 USE_LSB_TAG, the bottom half is not a valid pointer, so
4318 widen it to to a Lisp_Object and check it that way. */
4319 if (sizeof w < sizeof (Lisp_Object))
4320 mark_maybe_object (widen_to_Lisp_Object (w));
4321 }
4297} 4322}
4298 4323
4299/* setjmp will work with GCC unless NON_SAVING_SETJMP is defined in 4324/* setjmp will work with GCC unless NON_SAVING_SETJMP is defined in