diff options
| author | Paul Eggert | 2013-07-18 18:24:35 -0700 |
|---|---|---|
| committer | Paul Eggert | 2013-07-18 18:24:35 -0700 |
| commit | 1396ac86dea5fccab800e4b25fdb5319381891eb (patch) | |
| tree | 7f89955a2ab13f3ef4a40f14a48bbcc293c3b179 /src/alloc.c | |
| parent | c7064f05d3d660fbdd9e7a2feb0860b04f46ae0d (diff) | |
| download | emacs-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/alloc.c')
| -rw-r--r-- | src/alloc.c | 97 |
1 files changed, 58 insertions, 39 deletions
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 | ||
| 3348 | Lisp_Object | 3348 | Lisp_Object |
| 3349 | make_save_value (enum Lisp_Save_Type save_type, ...) | 3349 | make_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 | 3360 | Lisp_Object |
| 3357 | && (save_type < 1 << (SAVE_TYPE_BITS - 1) | 3361 | make_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); | 3375 | Lisp_Object |
| 3380 | break; | 3376 | make_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: | 3386 | Lisp_Object |
| 3383 | emacs_abort (); | 3387 | make_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); | 3397 | Lisp_Object |
| 3398 | make_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 | ||
| 3394 | Lisp_Object | 3412 | Lisp_Object |
| 3395 | make_save_pointer (void *pointer) | 3413 | make_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 | ||