aboutsummaryrefslogtreecommitdiffstats
path: root/src/alloc.c
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/alloc.c
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/alloc.c')
-rw-r--r--src/alloc.c97
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
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