aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPaul Eggert2013-07-18 18:24:35 -0700
committerPaul Eggert2013-07-18 18:24:35 -0700
commit1396ac86dea5fccab800e4b25fdb5319381891eb (patch)
tree7f89955a2ab13f3ef4a40f14a48bbcc293c3b179 /src
parentc7064f05d3d660fbdd9e7a2feb0860b04f46ae0d (diff)
downloademacs-1396ac86dea5fccab800e4b25fdb5319381891eb.tar.gz
emacs-1396ac86dea5fccab800e4b25fdb5319381891eb.zip
Fix obscure porting bug with varargs functions.
The code assumed that int is treated like ptrdiff_t in a vararg function, which is not a portable assumption. There was a similar -- though these days less likely -- porting problem with various assumptions that pointers of different types all smell the same as far as vararg functions is conserved. To make this problem less likely in the future, redo the API to use varargs functions. * alloc.c (make_save_value): Remove this vararg function. All uses changed to ... (make_save_int_int_int, make_save_obj_obj_obj_obj) (make_save_ptr_int, make_save_funcptr_ptr_obj, make_save_memory): New functions. (make_save_ptr): Rename from make_save_pointer, for consistency with the above. Define only on platforms that need it. All uses changed.
Diffstat (limited to 'src')
-rw-r--r--src/ChangeLog17
-rw-r--r--src/alloc.c97
-rw-r--r--src/editfns.c5
-rw-r--r--src/fileio.c3
-rw-r--r--src/font.c2
-rw-r--r--src/ftfont.c2
-rw-r--r--src/keymap.c4
-rw-r--r--src/lisp.h43
-rw-r--r--src/nsterm.m2
-rw-r--r--src/w32fns.c2
-rw-r--r--src/xmenu.c3
11 files changed, 108 insertions, 72 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index 81b23bccc8b..73fc64f37c5 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,20 @@
12013-07-19 Paul Eggert <eggert@cs.ucla.edu>
2
3 Fix obscure porting bug with varargs functions.
4 The code assumed that int is treated like ptrdiff_t in a vararg
5 function, which is not a portable assumption. There was a similar
6 -- though these days less likely -- porting problem with various
7 assumptions that pointers of different types all smell the same as
8 far as vararg functions is conserved. To make this problem less
9 likely in the future, redo the API to use varargs functions.
10 * alloc.c (make_save_value): Remove this vararg function.
11 All uses changed to ...
12 (make_save_int_int_int, make_save_obj_obj_obj_obj)
13 (make_save_ptr_int, make_save_funcptr_ptr_obj, make_save_memory):
14 New functions.
15 (make_save_ptr): Rename from make_save_pointer, for consistency with
16 the above. Define only on platforms that need it. All uses changed.
17
12013-07-18 Paul Eggert <eggert@cs.ucla.edu> 182013-07-18 Paul Eggert <eggert@cs.ucla.edu>
2 19
3 * keyboard.c: Try to fix typos in previous change. 20 * keyboard.c: Try to fix typos in previous change.
diff --git a/src/alloc.c b/src/alloc.c
index 39f6a82b138..11245741bd5 100644
--- a/src/alloc.c
+++ b/src/alloc.c
@@ -3342,62 +3342,81 @@ verify (((SAVE_INTEGER | SAVE_POINTER | SAVE_FUNCPOINTER | SAVE_OBJECT)
3342 >> SAVE_SLOT_BITS) 3342 >> SAVE_SLOT_BITS)
3343 == 0); 3343 == 0);
3344 3344
3345/* Return a Lisp_Save_Value object with the data saved according to 3345/* Return Lisp_Save_Value objects for the various combinations
3346 DATA_TYPE. DATA_TYPE should be one of SAVE_TYPE_INT_INT, etc. */ 3346 that callers need. */
3347 3347
3348Lisp_Object 3348Lisp_Object
3349make_save_value (enum Lisp_Save_Type save_type, ...) 3349make_save_int_int_int (ptrdiff_t a, ptrdiff_t b, ptrdiff_t c)
3350{ 3350{
3351 va_list ap;
3352 int i;
3353 Lisp_Object val = allocate_misc (Lisp_Misc_Save_Value); 3351 Lisp_Object val = allocate_misc (Lisp_Misc_Save_Value);
3354 struct Lisp_Save_Value *p = XSAVE_VALUE (val); 3352 struct Lisp_Save_Value *p = XSAVE_VALUE (val);
3353 p->save_type = SAVE_TYPE_INT_INT_INT;
3354 p->data[0].integer = a;
3355 p->data[1].integer = b;
3356 p->data[2].integer = c;
3357 return val;
3358}
3355 3359
3356 eassert (0 < save_type 3360Lisp_Object
3357 && (save_type < 1 << (SAVE_TYPE_BITS - 1) 3361make_save_obj_obj_obj_obj (Lisp_Object a, Lisp_Object b, Lisp_Object c,
3358 || save_type == SAVE_TYPE_MEMORY)); 3362 Lisp_Object d)
3359 p->save_type = save_type; 3363{
3360 va_start (ap, save_type); 3364 Lisp_Object val = allocate_misc (Lisp_Misc_Save_Value);
3361 save_type &= ~ (1 << (SAVE_TYPE_BITS - 1)); 3365 struct Lisp_Save_Value *p = XSAVE_VALUE (val);
3362 3366 p->save_type = SAVE_TYPE_OBJ_OBJ_OBJ_OBJ;
3363 for (i = 0; save_type; i++, save_type >>= SAVE_SLOT_BITS) 3367 p->data[0].object = a;
3364 switch (save_type & ((1 << SAVE_SLOT_BITS) - 1)) 3368 p->data[1].object = b;
3365 { 3369 p->data[2].object = c;
3366 case SAVE_POINTER: 3370 p->data[3].object = d;
3367 p->data[i].pointer = va_arg (ap, void *); 3371 return val;
3368 break; 3372}
3369
3370 case SAVE_FUNCPOINTER:
3371 p->data[i].funcpointer = va_arg (ap, voidfuncptr);
3372 break;
3373
3374 case SAVE_INTEGER:
3375 p->data[i].integer = va_arg (ap, ptrdiff_t);
3376 break;
3377 3373
3378 case SAVE_OBJECT: 3374#if defined HAVE_NS || defined DOS_NT
3379 p->data[i].object = va_arg (ap, Lisp_Object); 3375Lisp_Object
3380 break; 3376make_save_ptr (void *a)
3377{
3378 Lisp_Object val = allocate_misc (Lisp_Misc_Save_Value);
3379 struct Lisp_Save_Value *p = XSAVE_VALUE (val);
3380 p->save_type = SAVE_POINTER;
3381 p->data[0].pointer = a;
3382 return val;
3383}
3384#endif
3381 3385
3382 default: 3386Lisp_Object
3383 emacs_abort (); 3387make_save_ptr_int (void *a, ptrdiff_t b)
3384 } 3388{
3389 Lisp_Object val = allocate_misc (Lisp_Misc_Save_Value);
3390 struct Lisp_Save_Value *p = XSAVE_VALUE (val);
3391 p->save_type = SAVE_TYPE_PTR_INT;
3392 p->data[0].pointer = a;
3393 p->data[1].integer = b;
3394 return val;
3395}
3385 3396
3386 va_end (ap); 3397Lisp_Object
3398make_save_funcptr_ptr_obj (void (*a) (void), void *b, Lisp_Object c)
3399{
3400 Lisp_Object val = allocate_misc (Lisp_Misc_Save_Value);
3401 struct Lisp_Save_Value *p = XSAVE_VALUE (val);
3402 p->save_type = SAVE_TYPE_FUNCPTR_PTR_OBJ;
3403 p->data[0].funcpointer = a;
3404 p->data[1].pointer = b;
3405 p->data[2].object = c;
3387 return val; 3406 return val;
3388} 3407}
3389 3408
3390/* Save just one C pointer. record_unwind_protect_ptr is simpler and 3409/* Return a Lisp_Save_Value object that represents an array A
3391 faster than combining this with record_unwind_protect, but 3410 of N Lisp objects. */
3392 occasionally this function is useful for other reasons. */
3393 3411
3394Lisp_Object 3412Lisp_Object
3395make_save_pointer (void *pointer) 3413make_save_memory (Lisp_Object *a, ptrdiff_t n)
3396{ 3414{
3397 Lisp_Object val = allocate_misc (Lisp_Misc_Save_Value); 3415 Lisp_Object val = allocate_misc (Lisp_Misc_Save_Value);
3398 struct Lisp_Save_Value *p = XSAVE_VALUE (val); 3416 struct Lisp_Save_Value *p = XSAVE_VALUE (val);
3399 p->save_type = SAVE_POINTER; 3417 p->save_type = SAVE_TYPE_MEMORY;
3400 p->data[0].pointer = pointer; 3418 p->data[0].pointer = a;
3419 p->data[1].integer = n;
3401 return val; 3420 return val;
3402} 3421}
3403 3422
diff --git a/src/editfns.c b/src/editfns.c
index a4dea203a22..50bde90788d 100644
--- a/src/editfns.c
+++ b/src/editfns.c
@@ -838,9 +838,8 @@ This function does not move point. */)
838Lisp_Object 838Lisp_Object
839save_excursion_save (void) 839save_excursion_save (void)
840{ 840{
841 return make_save_value 841 return make_save_obj_obj_obj_obj
842 (SAVE_TYPE_OBJ_OBJ_OBJ_OBJ, 842 (Fpoint_marker (),
843 Fpoint_marker (),
844 /* Do not copy the mark if it points to nowhere. */ 843 /* Do not copy the mark if it points to nowhere. */
845 (XMARKER (BVAR (current_buffer, mark))->buffer 844 (XMARKER (BVAR (current_buffer, mark))->buffer
846 ? Fcopy_marker (BVAR (current_buffer, mark), Qnil) 845 ? Fcopy_marker (BVAR (current_buffer, mark), Qnil)
diff --git a/src/fileio.c b/src/fileio.c
index 5fe359d58bb..a19fcd9f663 100644
--- a/src/fileio.c
+++ b/src/fileio.c
@@ -4215,8 +4215,7 @@ by calling `format-decode', which see. */)
4215 to be signaled after decoding the text we read. */ 4215 to be signaled after decoding the text we read. */
4216 nbytes = internal_condition_case_1 4216 nbytes = internal_condition_case_1
4217 (read_non_regular, 4217 (read_non_regular,
4218 make_save_value (SAVE_TYPE_INT_INT_INT, (ptrdiff_t) fd, 4218 make_save_int_int_int (fd, inserted, trytry),
4219 inserted, trytry),
4220 Qerror, read_non_regular_quit); 4219 Qerror, read_non_regular_quit);
4221 4220
4222 if (NILP (nbytes)) 4221 if (NILP (nbytes))
diff --git a/src/font.c b/src/font.c
index 80b4b76c4e4..124d5f9bd9e 100644
--- a/src/font.c
+++ b/src/font.c
@@ -1861,7 +1861,7 @@ otf_open (Lisp_Object file)
1861 else 1861 else
1862 { 1862 {
1863 otf = STRINGP (file) ? OTF_open (SSDATA (file)) : NULL; 1863 otf = STRINGP (file) ? OTF_open (SSDATA (file)) : NULL;
1864 val = make_save_pointer (otf); 1864 val = make_save_ptr (otf);
1865 otf_list = Fcons (Fcons (file, val), otf_list); 1865 otf_list = Fcons (Fcons (file, val), otf_list);
1866 } 1866 }
1867 return otf; 1867 return otf;
diff --git a/src/ftfont.c b/src/ftfont.c
index 7c9534d5ae7..10090cb3bda 100644
--- a/src/ftfont.c
+++ b/src/ftfont.c
@@ -393,7 +393,7 @@ ftfont_lookup_cache (Lisp_Object key, enum ftfont_cache_for cache_for)
393 cache_data = xmalloc (sizeof *cache_data); 393 cache_data = xmalloc (sizeof *cache_data);
394 cache_data->ft_face = NULL; 394 cache_data->ft_face = NULL;
395 cache_data->fc_charset = NULL; 395 cache_data->fc_charset = NULL;
396 val = make_save_value (SAVE_TYPE_PTR_INT, cache_data, 0); 396 val = make_save_ptr_int (cache_data, 0);
397 cache = Fcons (Qnil, val); 397 cache = Fcons (Qnil, val);
398 Fputhash (key, cache, ft_face_cache); 398 Fputhash (key, cache, ft_face_cache);
399 } 399 }
diff --git a/src/keymap.c b/src/keymap.c
index e1268c8a06c..d13a6274347 100644
--- a/src/keymap.c
+++ b/src/keymap.c
@@ -617,8 +617,8 @@ map_keymap_internal (Lisp_Object map,
617 } 617 }
618 else if (CHAR_TABLE_P (binding)) 618 else if (CHAR_TABLE_P (binding))
619 map_char_table (map_keymap_char_table_item, Qnil, binding, 619 map_char_table (map_keymap_char_table_item, Qnil, binding,
620 make_save_value (SAVE_TYPE_FUNCPTR_PTR_OBJ, 620 make_save_funcptr_ptr_obj ((voidfuncptr) fun, data,
621 (voidfuncptr) fun, data, args)); 621 args));
622 } 622 }
623 UNGCPRO; 623 UNGCPRO;
624 return tail; 624 return tail;
diff --git a/src/lisp.h b/src/lisp.h
index 518de9db0ff..254ead231b9 100644
--- a/src/lisp.h
+++ b/src/lisp.h
@@ -441,8 +441,7 @@ enum Lisp_Fwd_Type
441 displayed to users. These are Lisp_Save_Value, a Lisp_Misc 441 displayed to users. These are Lisp_Save_Value, a Lisp_Misc
442 subtype; and PVEC_OTHER, a kind of vectorlike object. The former 442 subtype; and PVEC_OTHER, a kind of vectorlike object. The former
443 is suitable for temporarily stashing away pointers and integers in 443 is suitable for temporarily stashing away pointers and integers in
444 a Lisp object (see the existing uses of make_save_value and 444 a Lisp object. The latter is useful for vector-like Lisp objects
445 XSAVE_VALUE). The latter is useful for vector-like Lisp objects
446 that need to be used as part of other objects, but which are never 445 that need to be used as part of other objects, but which are never
447 shown to users or Lisp code (search for PVEC_OTHER in xterm.c for 446 shown to users or Lisp code (search for PVEC_OTHER in xterm.c for
448 an example). 447 an example).
@@ -1815,30 +1814,26 @@ enum Lisp_Save_Type
1815 1814
1816 This is mostly used to package C integers and pointers to call 1815 This is mostly used to package C integers and pointers to call
1817 record_unwind_protect when two or more values need to be saved. 1816 record_unwind_protect when two or more values need to be saved.
1818 make_save_value lets you pack up to SAVE_VALUE_SLOTS integers, pointers, 1817 For example:
1819 function pointers or Lisp_Objects and conveniently get them back
1820 with XSAVE_INTEGER, XSAVE_POINTER, XSAVE_FUNCPOINTER, and
1821 XSAVE_OBJECT macros:
1822 1818
1823 ... 1819 ...
1824 struct my_data *md = get_my_data (); 1820 struct my_data *md = get_my_data ();
1825 Lisp_Object my_object = get_my_object (); 1821 ptrdiff_t mi = get_my_integer ();
1826 record_unwind_protect 1822 record_unwind_protect (my_unwind, make_save_ptr_int (md, mi));
1827 (my_unwind, make_save_value (SAVE_TYPE_PTR_OBJ, md, my_object));
1828 ... 1823 ...
1829 1824
1830 Lisp_Object my_unwind (Lisp_Object arg) 1825 Lisp_Object my_unwind (Lisp_Object arg)
1831 { 1826 {
1832 struct my_data *md = XSAVE_POINTER (arg, 0); 1827 struct my_data *md = XSAVE_POINTER (arg, 0);
1833 Lisp_Object my_object = XSAVE_OBJECT (arg, 1); 1828 ptrdiff_t mi = XSAVE_INTEGER (arg, 1);
1834 ... 1829 ...
1835 } 1830 }
1836 1831
1837 If ENABLE_CHECKING is in effect, XSAVE_xxx macros do type checking of the 1832 If ENABLE_CHECKING is in effect, XSAVE_xxx macros do type checking of the
1838 saved objects and raise eassert if type of the saved object doesn't match 1833 saved objects and raise eassert if type of the saved object doesn't match
1839 the type which is extracted. In the example above, XSAVE_INTEGER (arg, 2) 1834 the type which is extracted. In the example above, XSAVE_INTEGER (arg, 2)
1840 or XSAVE_OBJECT (arg, 0) are wrong because nothing was saved in slot 2 and 1835 and XSAVE_OBJECT (arg, 0) are wrong because nothing was saved in slot 2 and
1841 Lisp_Object was saved in slot 1 of ARG. */ 1836 slot 0 is a pointer. */
1842 1837
1843typedef void (*voidfuncptr) (void); 1838typedef void (*voidfuncptr) (void);
1844 1839
@@ -1848,12 +1843,13 @@ struct Lisp_Save_Value
1848 unsigned gcmarkbit : 1; 1843 unsigned gcmarkbit : 1;
1849 int spacer : 32 - (16 + 1 + SAVE_TYPE_BITS); 1844 int spacer : 32 - (16 + 1 + SAVE_TYPE_BITS);
1850 1845
1851 /* DATA[N] may hold up to SAVE_VALUE_SLOTS entries. The type of 1846 /* V->data may hold up to SAVE_VALUE_SLOTS entries. The type of
1852 V's Ith entry is given by save_type (V, I). E.g., if save_type 1847 V's data entries are determined by V->save_type. E.g., if
1853 (V, 3) == SAVE_INTEGER, V->data[3].integer is in use. 1848 V->save_type == SAVE_TYPE_PTR_OBJ, V->data[0] is a pointer,
1849 V->data[1] is an integer, and V's other data entries are unused.
1854 1850
1855 If SAVE_TYPE == SAVE_TYPE_MEMORY, DATA[0].pointer is the address of 1851 If V->save_type == SAVE_TYPE_MEMORY, V->data[0].pointer is the address of
1856 a memory area containing DATA[1].integer potential Lisp_Objects. */ 1852 a memory area containing V->data[1].integer potential Lisp_Objects. */
1857 ENUM_BF (Lisp_Save_Type) save_type : SAVE_TYPE_BITS; 1853 ENUM_BF (Lisp_Save_Type) save_type : SAVE_TYPE_BITS;
1858 union { 1854 union {
1859 void *pointer; 1855 void *pointer;
@@ -3580,8 +3576,15 @@ extern bool abort_on_gc;
3580extern Lisp_Object make_float (double); 3576extern Lisp_Object make_float (double);
3581extern void display_malloc_warning (void); 3577extern void display_malloc_warning (void);
3582extern ptrdiff_t inhibit_garbage_collection (void); 3578extern ptrdiff_t inhibit_garbage_collection (void);
3583extern Lisp_Object make_save_value (enum Lisp_Save_Type, ...); 3579extern Lisp_Object make_save_int_int_int (ptrdiff_t, ptrdiff_t, ptrdiff_t);
3584extern Lisp_Object make_save_pointer (void *); 3580extern Lisp_Object make_save_obj_obj_obj_obj (Lisp_Object, Lisp_Object,
3581 Lisp_Object, Lisp_Object);
3582extern Lisp_Object make_save_ptr (void *);
3583extern Lisp_Object make_save_ptr_int (void *, ptrdiff_t);
3584extern Lisp_Object make_save_ptr_ptr (void *, void *);
3585extern Lisp_Object make_save_funcptr_ptr_obj (void (*) (void), void *,
3586 Lisp_Object);
3587extern Lisp_Object make_save_memory (Lisp_Object *, ptrdiff_t);
3585extern void free_save_value (Lisp_Object); 3588extern void free_save_value (Lisp_Object);
3586extern Lisp_Object build_overlay (Lisp_Object, Lisp_Object, Lisp_Object); 3589extern Lisp_Object build_overlay (Lisp_Object, Lisp_Object, Lisp_Object);
3587extern void free_marker (Lisp_Object); 3590extern void free_marker (Lisp_Object);
@@ -4314,7 +4317,7 @@ extern void *record_xmalloc (size_t);
4314 { \ 4317 { \
4315 Lisp_Object arg_; \ 4318 Lisp_Object arg_; \
4316 buf = xmalloc ((nelt) * word_size); \ 4319 buf = xmalloc ((nelt) * word_size); \
4317 arg_ = make_save_value (SAVE_TYPE_MEMORY, buf, nelt); \ 4320 arg_ = make_save_memory (buf, nelt); \
4318 sa_must_free = 1; \ 4321 sa_must_free = 1; \
4319 record_unwind_protect (free_save_value, arg_); \ 4322 record_unwind_protect (free_save_value, arg_); \
4320 } \ 4323 } \
diff --git a/src/nsterm.m b/src/nsterm.m
index c91e68f37a9..f3c35e95bfe 100644
--- a/src/nsterm.m
+++ b/src/nsterm.m
@@ -3777,7 +3777,7 @@ ns_set_vertical_scroll_bar (struct window *window,
3777 } 3777 }
3778 3778
3779 bar = [[EmacsScroller alloc] initFrame: r window: win]; 3779 bar = [[EmacsScroller alloc] initFrame: r window: win];
3780 wset_vertical_scroll_bar (window, make_save_pointer (bar)); 3780 wset_vertical_scroll_bar (window, make_save_ptr (bar));
3781 } 3781 }
3782 else 3782 else
3783 { 3783 {
diff --git a/src/w32fns.c b/src/w32fns.c
index 5d9200bdd7b..675b716f3b0 100644
--- a/src/w32fns.c
+++ b/src/w32fns.c
@@ -4916,7 +4916,7 @@ w32_monitor_enum (HMONITOR monitor, HDC hdc, RECT *rcMonitor, LPARAM dwData)
4916{ 4916{
4917 Lisp_Object *monitor_list = (Lisp_Object *) dwData; 4917 Lisp_Object *monitor_list = (Lisp_Object *) dwData;
4918 4918
4919 *monitor_list = Fcons (make_save_pointer (monitor), *monitor_list); 4919 *monitor_list = Fcons (make_save_ptr (monitor), *monitor_list);
4920 4920
4921 return TRUE; 4921 return TRUE;
4922} 4922}
diff --git a/src/xmenu.c b/src/xmenu.c
index 1151dea440e..6c0e3dd78a6 100644
--- a/src/xmenu.c
+++ b/src/xmenu.c
@@ -2465,8 +2465,7 @@ xmenu_show (FRAME_PTR f, int x, int y, bool for_click, bool keymaps,
2465 XMenuActivateSetWaitFunction (x_menu_wait_for_event, FRAME_X_DISPLAY (f)); 2465 XMenuActivateSetWaitFunction (x_menu_wait_for_event, FRAME_X_DISPLAY (f));
2466#endif 2466#endif
2467 2467
2468 record_unwind_protect (pop_down_menu, 2468 record_unwind_protect (pop_down_menu, make_save_ptr_ptr (f, menu));
2469 make_save_value (SAVE_TYPE_PTR_PTR, f, menu));
2470 2469
2471 /* Help display under X won't work because XMenuActivate contains 2470 /* Help display under X won't work because XMenuActivate contains
2472 a loop that doesn't give Emacs a chance to process it. */ 2471 a loop that doesn't give Emacs a chance to process it. */