From 92394119721e6a581c344fa5c0e47faa9283ddef Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Wed, 27 Apr 2011 17:43:18 -0700 Subject: [PATCH 01/38] * fns.c (Frandom): Let EMACS_UINT be wider than unsigned long. --- src/ChangeLog | 4 ++++ src/fns.c | 4 ++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/ChangeLog b/src/ChangeLog index 567c1251480..a43e61f8278 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,7 @@ +2011-04-28 Paul Eggert + + * fns.c (Frandom): Let EMACS_UINT be wider than unsigned long. + 2011-04-27 Paul Eggert * doprnt.c (doprnt): Support "ll" length modifier, for long long. diff --git a/src/fns.c b/src/fns.c index a128b9292c6..47ded456c6e 100644 --- a/src/fns.c +++ b/src/fns.c @@ -75,7 +75,7 @@ Other values of LIMIT are ignored. */) { EMACS_INT val; Lisp_Object lispy_val; - unsigned long denominator; + EMACS_UINT denominator; if (EQ (limit, Qt)) seed_random (getpid () + time (NULL)); @@ -88,7 +88,7 @@ Other values of LIMIT are ignored. */) it's possible to get a quotient larger than n; discarding these values eliminates the bias that would otherwise appear when using a large n. */ - denominator = ((unsigned long)1 << VALBITS) / XFASTINT (limit); + denominator = ((EMACS_UINT) 1 << VALBITS) / XFASTINT (limit); do val = get_random () / denominator; while (val >= XFASTINT (limit)); From 51639eace139fdbed3522d4f752d771e6c66b067 Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Wed, 27 Apr 2011 17:45:40 -0700 Subject: [PATCH 02/38] * eval.c (Fautoload): Don't double-shift a pointer. --- src/ChangeLog | 2 ++ src/eval.c | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/ChangeLog b/src/ChangeLog index a43e61f8278..442e8e3b1f6 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,5 +1,7 @@ 2011-04-28 Paul Eggert + * eval.c (Fautoload): Don't double-shift a pointer. + * fns.c (Frandom): Let EMACS_UINT be wider than unsigned long. 2011-04-27 Paul Eggert diff --git a/src/eval.c b/src/eval.c index bcbbf740153..88b8572a33e 100644 --- a/src/eval.c +++ b/src/eval.c @@ -2144,7 +2144,7 @@ this does nothing and returns nil. */) We used to use 0 here, but that leads to accidental sharing in purecopy's hash-consing, so we use a (hopefully) unique integer instead. */ - docstring = make_number (XHASH (function)); + docstring = make_number (XPNTR (function)); return Ffset (function, Fpurecopy (list5 (Qautoload, file, docstring, interactive, type))); From 2a866e7b9881176980c0a4acb998e1625aabf87f Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Wed, 27 Apr 2011 17:48:19 -0700 Subject: [PATCH 03/38] * dbusbind.c: Don't possibly lose pointer info when converting. (xd_remove_watch, Fdbus_init_bus, xd_read_queued_messages): Use XPNTR rather than XHASH, so that the high-order bits of the pointer aren't lost when converting through void *. --- src/ChangeLog | 5 +++++ src/dbusbind.c | 6 +++--- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/src/ChangeLog b/src/ChangeLog index 442e8e3b1f6..52b7f323cd3 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,5 +1,10 @@ 2011-04-28 Paul Eggert + * dbusbind.c: Don't possibly lose pointer info when converting. + (xd_remove_watch, Fdbus_init_bus, xd_read_queued_messages): + Use XPNTR rather than XHASH, so that the high-order bits of + the pointer aren't lost when converting through void *. + * eval.c (Fautoload): Don't double-shift a pointer. * fns.c (Frandom): Let EMACS_UINT be wider than unsigned long. diff --git a/src/dbusbind.c b/src/dbusbind.c index 4c0b9bd017a..06feec3e792 100644 --- a/src/dbusbind.c +++ b/src/dbusbind.c @@ -892,7 +892,7 @@ xd_remove_watch (DBusWatch *watch, void *data) return; /* Unset session environment. */ - if (data != NULL && data == (void*) XHASH (QCdbus_session_bus)) + if (data != NULL && data == (void *) XPNTR (QCdbus_session_bus)) { XD_DEBUG_MESSAGE ("unsetenv DBUS_SESSION_BUS_ADDRESS"); unsetenv ("DBUS_SESSION_BUS_ADDRESS"); @@ -929,7 +929,7 @@ DEFUN ("dbus-init-bus", Fdbus_init_bus, Sdbus_init_bus, 1, 1, 0, xd_add_watch, xd_remove_watch, xd_toggle_watch, - (void*) XHASH (bus), NULL)) + (void *) XPNTR (bus), NULL)) XD_SIGNAL1 (build_string ("Cannot add watch functions")); /* Add bus to list of registered buses. */ @@ -1824,7 +1824,7 @@ xd_read_queued_messages (int fd, void *data, int for_read) if (data != NULL) while (!NILP (busp)) { - if (data == (void*) XHASH (CAR_SAFE (busp))) + if (data == (void *) XPNTR (CAR_SAFE (busp))) bus = CAR_SAFE (busp); busp = CDR_SAFE (busp); } From 2f30ecd05f7e5b9f78f256f75677530c501e5a6d Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Wed, 27 Apr 2011 22:15:35 -0700 Subject: [PATCH 04/38] * lread.c (hash_string): Use size_t, not int, for hash computation. Normally we prefer signed values; but hashing is special, because it's better to use unsigned division on hash table sizes so that the remainder is nonnegative. Also, size_t is the natural width for hashing into memory. The previous code used 'int', which doesn't retain enough info to hash well into very large tables. (oblookup, oblookup_last_bucket_number, Funintern): Likewise. --- src/ChangeLog | 8 ++++++++ src/lread.c | 20 ++++++++++---------- 2 files changed, 18 insertions(+), 10 deletions(-) diff --git a/src/ChangeLog b/src/ChangeLog index 52b7f323cd3..2bda5ffa46f 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,5 +1,13 @@ 2011-04-28 Paul Eggert + * lread.c (hash_string): Use size_t, not int, for hash computation. + Normally we prefer signed values; but hashing is special, because + it's better to use unsigned division on hash table sizes so that + the remainder is nonnegative. Also, size_t is the natural width + for hashing into memory. The previous code used 'int', which doesn't + retain enough info to hash well into very large tables. + (oblookup, oblookup_last_bucket_number, Funintern): Likewise. + * dbusbind.c: Don't possibly lose pointer info when converting. (xd_remove_watch, Fdbus_init_bus, xd_read_queued_messages): Use XPNTR rather than XHASH, so that the high-order bits of diff --git a/src/lread.c b/src/lread.c index 7ffc98b254f..2c8c3acd56a 100644 --- a/src/lread.c +++ b/src/lread.c @@ -3611,9 +3611,9 @@ static Lisp_Object initial_obarray; /* oblookup stores the bucket number here, for the sake of Funintern. */ -static int oblookup_last_bucket_number; +static size_t oblookup_last_bucket_number; -static int hash_string (const char *ptr, int len); +static size_t hash_string (const char *ptr, size_t len); /* Get an error if OBARRAY is not an obarray. If it is one, return it. */ @@ -3755,7 +3755,7 @@ OBARRAY defaults to the value of the variable `obarray'. */) (Lisp_Object name, Lisp_Object obarray) { register Lisp_Object string, tem; - int hash; + size_t hash; if (NILP (obarray)) obarray = Vobarray; obarray = check_obarray (obarray); @@ -3824,8 +3824,8 @@ OBARRAY defaults to the value of the variable `obarray'. */) Lisp_Object oblookup (Lisp_Object obarray, register const char *ptr, EMACS_INT size, EMACS_INT size_byte) { - int hash; - int obsize; + size_t hash; + size_t obsize; register Lisp_Object tail; Lisp_Object bucket, tem; @@ -3858,21 +3858,21 @@ oblookup (Lisp_Object obarray, register const char *ptr, EMACS_INT size, EMACS_I return tem; } -static int -hash_string (const char *ptr, int len) +static size_t +hash_string (const char *ptr, size_t len) { register const char *p = ptr; register const char *end = p + len; register unsigned char c; - register int hash = 0; + register size_t hash = 0; while (p != end) { c = *p++; if (c >= 0140) c -= 40; - hash = ((hash<<3) + (hash>>28) + c); + hash = (hash << 3) + (hash >> (CHAR_BIT * sizeof hash - 4)) + c; } - return hash & 07777777777; + return hash; } void From ede49d7153ed628078bcbc2473f898904b5250ea Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Thu, 28 Apr 2011 01:18:53 -0700 Subject: [PATCH 05/38] * sysdep.c (get_random): Don't assume EMACS_INT is no wider than long. Also, don't assume VALBITS / RAND_BITS is less than 5, and don't rely on undefined behavior when shifting a 1 left into the sign bit. * lisp.h (get_random): Change signature to match. --- src/ChangeLog | 6 ++++++ src/lisp.h | 2 +- src/sysdep.c | 21 ++++++--------------- 3 files changed, 13 insertions(+), 16 deletions(-) diff --git a/src/ChangeLog b/src/ChangeLog index 2bda5ffa46f..40fb601e061 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,5 +1,11 @@ 2011-04-28 Paul Eggert + * sysdep.c (get_random): Don't assume EMACS_INT is no wider than long. + Also, don't assume VALBITS / RAND_BITS is less than 5, + and don't rely on undefined behavior when shifting a 1 left into + the sign bit. + * lisp.h (get_random): Change signature to match. + * lread.c (hash_string): Use size_t, not int, for hash computation. Normally we prefer signed values; but hashing is special, because it's better to use unsigned division on hash table sizes so that diff --git a/src/lisp.h b/src/lisp.h index 625027769cf..dca3b4d9a32 100644 --- a/src/lisp.h +++ b/src/lisp.h @@ -3353,7 +3353,7 @@ extern void flush_pending_output (int); extern void child_setup_tty (int); extern void setup_pty (int); extern int set_window_size (int, int, int); -extern long get_random (void); +extern EMACS_INT get_random (void); extern void seed_random (long); extern int emacs_open (const char *, int, int); extern int emacs_close (int); diff --git a/src/sysdep.c b/src/sysdep.c index ca7de4f54bb..43f50cdb0a9 100644 --- a/src/sysdep.c +++ b/src/sysdep.c @@ -1760,23 +1760,14 @@ seed_random (long int arg) * Build a full Emacs-sized word out of whatever we've got. * This suffices even for a 64-bit architecture with a 15-bit rand. */ -long +EMACS_INT get_random (void) { - long val = random (); -#if VALBITS > RAND_BITS - val = (val << RAND_BITS) ^ random (); -#if VALBITS > 2*RAND_BITS - val = (val << RAND_BITS) ^ random (); -#if VALBITS > 3*RAND_BITS - val = (val << RAND_BITS) ^ random (); -#if VALBITS > 4*RAND_BITS - val = (val << RAND_BITS) ^ random (); -#endif /* need at least 5 */ -#endif /* need at least 4 */ -#endif /* need at least 3 */ -#endif /* need at least 2 */ - return val & ((1L << VALBITS) - 1); + EMACS_UINT val = 0; + int i; + for (i = 0; i < (VALBITS + RAND_BITS - 1) / RAND_BITS; i++) + val = (val << RAND_BITS) ^ random (); + return val & (((EMACS_INT) 1 << VALBITS) - 1); } #ifndef HAVE_STRERROR From 8ac068ac0c00afa85bc4df54032b7a855c639312 Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Fri, 29 Apr 2011 00:54:43 -0700 Subject: [PATCH 06/38] Prefer intptr_t/uintptr_t for integers the same widths as pointers. This removes an assumption that EMACS_INT and long are the same width as pointers. The assumption is true for Emacs porting targets now, but we want to make other targets possible. * lisp.h: Include , for INTPTR_MAX, UINTPTR_MAX. (EMACS_INTPTR, EMACS_UINTPTR): New macros. In the rest of the code, change types of integers that hold casted pointers to EMACS_INTPTR and EMACS_UINTPTR, systematically replacing EMACS_INT, long, EMACS_UINT, and unsigned long. (XTYPE): Don't cast arg to EMACS_UINT; normally is not needed. (XSET): Cast type of XTYPE arg to EMACS_INTPTR; it is needed here. No need to cast type when ORing. (XPNTR): Return a value of type EMACS_INTPTR or EMACS_UINTPTR. * alloc.c (lisp_align_malloc): Remove a no-longer-needed cast. * doc.c (store_function_docstring): Use EMACS_INTPTR, so as not to assume EMACS_INT is the same width as char *. * gtkutil.c (xg_gtk_scroll_destroy, xg_tool_bar_button_cb): (xg_tool_bar_callback, xg_tool_bar_help_callback, xg_make_tool_item): Remove no-longer-needed casts. (xg_create_scroll_bar, xg_tool_bar_button_cb, xg_tool_bar_callback): (xg_tool_bar_help_callback, xg_make_tool_item): Use EMACS_INTPTR to hold an integer that will be cast to void *; this can avoid a GCC warning if EMACS_INT is not the same width as void *. * menu.c (find_and_call_menu_selection): Remove no-longer-needed cast. * xdisp.c (display_echo_area_1, resize_mini_window_1): (current_message_1, set_message_1): Use a local to convert to proper width without a cast. * xmenu.c (dialog_selection_callback): Likewise. --- src/ChangeLog | 32 ++++++++++++++++++++++++++++++++ src/alloc.c | 42 ++++++++++++++++++++++-------------------- src/doc.c | 11 +++++++---- src/gtkutil.c | 31 +++++++++++++++---------------- src/lisp.h | 39 ++++++++++++++++++++++++++------------- src/menu.c | 8 ++++---- src/xdisp.c | 21 +++++++++++++-------- src/xmenu.c | 8 ++++---- 8 files changed, 123 insertions(+), 69 deletions(-) diff --git a/src/ChangeLog b/src/ChangeLog index 45d7e7a9044..05f332b8142 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,35 @@ +2011-04-29 Paul Eggert + + Prefer intptr_t/uintptr_t for integers the same widths as pointers. + This removes an assumption that EMACS_INT and long are the same + width as pointers. The assumption is true for Emacs porting targets + now, but we want to make other targets possible. + * lisp.h: Include , for INTPTR_MAX, UINTPTR_MAX. + (EMACS_INTPTR, EMACS_UINTPTR): New macros. + In the rest of the code, change types of integers that hold casted + pointers to EMACS_INTPTR and EMACS_UINTPTR, systematically + replacing EMACS_INT, long, EMACS_UINT, and unsigned long. + (XTYPE): Don't cast arg to EMACS_UINT; normally is not needed. + (XSET): Cast type of XTYPE arg to EMACS_INTPTR; it is needed here. + No need to cast type when ORing. + (XPNTR): Return a value of type EMACS_INTPTR or EMACS_UINTPTR. + * alloc.c (lisp_align_malloc): Remove a no-longer-needed cast. + * doc.c (store_function_docstring): Use EMACS_INTPTR, so as not to + assume EMACS_INT is the same width as char *. + * gtkutil.c (xg_gtk_scroll_destroy, xg_tool_bar_button_cb): + (xg_tool_bar_callback, xg_tool_bar_help_callback, xg_make_tool_item): + Remove no-longer-needed casts. + (xg_create_scroll_bar, xg_tool_bar_button_cb, xg_tool_bar_callback): + (xg_tool_bar_help_callback, xg_make_tool_item): + Use EMACS_INTPTR to hold an integer + that will be cast to void *; this can avoid a GCC warning + if EMACS_INT is not the same width as void *. + * menu.c (find_and_call_menu_selection): Remove no-longer-needed cast. + * xdisp.c (display_echo_area_1, resize_mini_window_1): + (current_message_1, set_message_1): + Use a local to convert to proper width without a cast. + * xmenu.c (dialog_selection_callback): Likewise. + 2011-04-28 Paul Eggert * sysdep.c (get_random): Don't assume EMACS_INT is no wider than long. diff --git a/src/alloc.c b/src/alloc.c index 842088f4e92..591d8264295 100644 --- a/src/alloc.c +++ b/src/alloc.c @@ -438,7 +438,7 @@ static POINTER_TYPE *pure_alloc (size_t, int); ALIGNMENT must be a power of 2. */ #define ALIGN(ptr, ALIGNMENT) \ - ((POINTER_TYPE *) ((((EMACS_UINT)(ptr)) + (ALIGNMENT) - 1) \ + ((POINTER_TYPE *) ((((EMACS_UINTPTR) (ptr)) + (ALIGNMENT) - 1) \ & ~((ALIGNMENT) - 1))) @@ -876,7 +876,7 @@ struct ablocks #define ABLOCKS_BYTES (sizeof (struct ablocks) - BLOCK_PADDING) #define ABLOCK_ABASE(block) \ - (((unsigned long) (block)->abase) <= (1 + 2 * ABLOCKS_SIZE) \ + (((EMACS_UINTPTR) (block)->abase) <= (1 + 2 * ABLOCKS_SIZE) \ ? (struct ablocks *)(block) \ : (block)->abase) @@ -888,7 +888,7 @@ struct ablocks #define ABLOCKS_BASE(abase) (abase) #else #define ABLOCKS_BASE(abase) \ - (1 & (long) ABLOCKS_BUSY (abase) ? abase : ((void**)abase)[-1]) + (1 & (EMACS_INTPTR) ABLOCKS_BUSY (abase) ? abase : ((void**)abase)[-1]) #endif /* The list of free ablock. */ @@ -914,7 +914,7 @@ lisp_align_malloc (size_t nbytes, enum mem_type type) if (!free_ablock) { int i; - EMACS_INT aligned; /* int gets warning casting to 64-bit pointer. */ + EMACS_INTPTR aligned; /* int gets warning casting to 64-bit pointer. */ #ifdef DOUG_LEA_MALLOC /* Prevent mmap'ing the chunk. Lisp data may not be mmap'ed @@ -977,17 +977,18 @@ lisp_align_malloc (size_t nbytes, enum mem_type type) abase->blocks[i].x.next_free = free_ablock; free_ablock = &abase->blocks[i]; } - ABLOCKS_BUSY (abase) = (struct ablocks *) (long) aligned; + ABLOCKS_BUSY (abase) = (struct ablocks *) aligned; - eassert (0 == ((EMACS_UINT)abase) % BLOCK_ALIGN); + eassert (0 == ((EMACS_UINTPTR) abase) % BLOCK_ALIGN); eassert (ABLOCK_ABASE (&abase->blocks[3]) == abase); /* 3 is arbitrary */ eassert (ABLOCK_ABASE (&abase->blocks[0]) == abase); eassert (ABLOCKS_BASE (abase) == base); - eassert (aligned == (long) ABLOCKS_BUSY (abase)); + eassert (aligned == (EMACS_INTPTR) ABLOCKS_BUSY (abase)); } abase = ABLOCK_ABASE (free_ablock); - ABLOCKS_BUSY (abase) = (struct ablocks *) (2 + (long) ABLOCKS_BUSY (abase)); + ABLOCKS_BUSY (abase) = + (struct ablocks *) (2 + (EMACS_INTPTR) ABLOCKS_BUSY (abase)); val = free_ablock; free_ablock = free_ablock->x.next_free; @@ -1000,7 +1001,7 @@ lisp_align_malloc (size_t nbytes, enum mem_type type) if (!val && nbytes) memory_full (); - eassert (0 == ((EMACS_UINT)val) % BLOCK_ALIGN); + eassert (0 == ((EMACS_UINTPTR) val) % BLOCK_ALIGN); return val; } @@ -1018,11 +1019,12 @@ lisp_align_free (POINTER_TYPE *block) ablock->x.next_free = free_ablock; free_ablock = ablock; /* Update busy count. */ - ABLOCKS_BUSY (abase) = (struct ablocks *) (-2 + (long) ABLOCKS_BUSY (abase)); + ABLOCKS_BUSY (abase) = + (struct ablocks *) (-2 + (EMACS_INTPTR) ABLOCKS_BUSY (abase)); - if (2 > (long) ABLOCKS_BUSY (abase)) + if (2 > (EMACS_INTPTR) ABLOCKS_BUSY (abase)) { /* All the blocks are free. */ - int i = 0, aligned = (long) ABLOCKS_BUSY (abase); + int i = 0, aligned = (EMACS_INTPTR) ABLOCKS_BUSY (abase); struct ablock **tem = &free_ablock; struct ablock *atop = &abase->blocks[aligned ? ABLOCKS_SIZE : ABLOCKS_SIZE - 1]; @@ -1039,7 +1041,7 @@ lisp_align_free (POINTER_TYPE *block) eassert ((aligned & 1) == aligned); eassert (i == (aligned ? ABLOCKS_SIZE : ABLOCKS_SIZE - 1)); #ifdef USE_POSIX_MEMALIGN - eassert ((unsigned long)ABLOCKS_BASE (abase) % BLOCK_ALIGN == 0); + eassert ((EMACS_UINTPTR) ABLOCKS_BASE (abase) % BLOCK_ALIGN == 0); #endif free (ABLOCKS_BASE (abase)); } @@ -1772,7 +1774,7 @@ check_string_free_list (void) s = string_free_list; while (s != NULL) { - if ((unsigned long)s < 1024) + if ((EMACS_UINTPTR) s < 1024) abort(); s = NEXT_FREE_LISP_STRING (s); } @@ -2432,10 +2434,10 @@ make_uninit_multibyte_string (EMACS_INT nchars, EMACS_INT nbytes) &= ~(1 << ((n) % (sizeof(int) * CHAR_BIT))) #define FLOAT_BLOCK(fptr) \ - ((struct float_block *)(((EMACS_UINT)(fptr)) & ~(BLOCK_ALIGN - 1))) + ((struct float_block *) (((EMACS_UINTPTR) (fptr)) & ~(BLOCK_ALIGN - 1))) #define FLOAT_INDEX(fptr) \ - ((((EMACS_UINT)(fptr)) & (BLOCK_ALIGN - 1)) / sizeof (struct Lisp_Float)) + ((((EMACS_UINTPTR) (fptr)) & (BLOCK_ALIGN - 1)) / sizeof (struct Lisp_Float)) struct float_block { @@ -2544,10 +2546,10 @@ make_float (double float_value) / (sizeof (struct Lisp_Cons) * CHAR_BIT + 1)) #define CONS_BLOCK(fptr) \ - ((struct cons_block *)(((EMACS_UINT)(fptr)) & ~(BLOCK_ALIGN - 1))) + ((struct cons_block *) ((EMACS_UINTPTR) (fptr) & ~(BLOCK_ALIGN - 1))) #define CONS_INDEX(fptr) \ - ((((EMACS_UINT)(fptr)) & (BLOCK_ALIGN - 1)) / sizeof (struct Lisp_Cons)) + (((EMACS_UINTPTR) (fptr) & (BLOCK_ALIGN - 1)) / sizeof (struct Lisp_Cons)) struct cons_block { @@ -4021,7 +4023,7 @@ mark_maybe_pointer (void *p) struct mem_node *m; /* Quickly rule out some values which can't point to Lisp data. */ - if ((EMACS_INT) p % + if ((EMACS_INTPTR) p % #ifdef USE_LSB_TAG 8 /* USE_LSB_TAG needs Lisp data to be aligned on multiples of 8. */ #else @@ -6072,7 +6074,7 @@ We divide the value by 1024 to make sure it fits in a Lisp integer. */) { Lisp_Object end; - XSETINT (end, (EMACS_INT) (char *) sbrk (0) / 1024); + XSETINT (end, (EMACS_INTPTR) (char *) sbrk (0) / 1024); return end; } diff --git a/src/doc.c b/src/doc.c index 3832eb3708d..740bb26ff08 100644 --- a/src/doc.c +++ b/src/doc.c @@ -349,10 +349,10 @@ string is passed through `substitute-command-keys'. */) return Qnil; /* FIXME: This is not portable, as it assumes that string pointers have the top bit clear. */ - else if ((EMACS_INT) XSUBR (fun)->doc >= 0) + else if ((EMACS_INTPTR) XSUBR (fun)->doc >= 0) doc = build_string (XSUBR (fun)->doc); else - doc = make_number ((EMACS_INT) XSUBR (fun)->doc); + doc = make_number ((EMACS_INTPTR) XSUBR (fun)->doc); } else if (COMPILEDP (fun)) { @@ -506,8 +506,11 @@ store_function_docstring (Lisp_Object fun, EMACS_INT offset) /* The type determines where the docstring is stored. */ /* Lisp_Subrs have a slot for it. */ - if (SUBRP (fun)) - XSUBR (fun)->doc = (char *) - offset; + if (SUBRP (fun)) + { + EMACS_INTPTR negative_offset = - offset; + XSUBR (fun)->doc = (char *) negative_offset; + } /* If it's a lisp form, stick it in the form. */ else if (CONSP (fun)) diff --git a/src/gtkutil.c b/src/gtkutil.c index 9d3bfe6a89c..ff33a3f3c04 100644 --- a/src/gtkutil.c +++ b/src/gtkutil.c @@ -3354,7 +3354,7 @@ xg_get_scroll_id_for_window (Display *dpy, Window wid) static void xg_gtk_scroll_destroy (GtkWidget *widget, gpointer data) { - int id = (int) (EMACS_INT) data; /* The EMACS_INT cast avoids a warning. */ + int id = (EMACS_INTPTR) data; xg_remove_widget_from_map (id); } @@ -3375,7 +3375,7 @@ xg_create_scroll_bar (FRAME_PTR f, { GtkWidget *wscroll; GtkWidget *webox; - int scroll_id; + EMACS_INTPTR scroll_id; #ifdef HAVE_GTK3 GtkAdjustment *vadj; #else @@ -3397,11 +3397,10 @@ xg_create_scroll_bar (FRAME_PTR f, scroll_id = xg_store_widget_in_map (wscroll); - /* The EMACS_INT cast avoids a warning. */ g_signal_connect (G_OBJECT (wscroll), "destroy", G_CALLBACK (xg_gtk_scroll_destroy), - (gpointer) (EMACS_INT) scroll_id); + (gpointer) scroll_id); g_signal_connect (G_OBJECT (wscroll), "change-value", scroll_callback, @@ -3663,8 +3662,8 @@ xg_tool_bar_button_cb (GtkWidget *widget, GdkEventButton *event, gpointer user_data) { - /* Casts to avoid warnings when gpointer is 64 bits and int is 32 bits */ - gpointer ptr = (gpointer) (EMACS_INT) event->state; + EMACS_INTPTR state = event->state; + gpointer ptr = (gpointer) state; g_object_set_data (G_OBJECT (widget), XG_TOOL_BAR_LAST_MODIFIER, ptr); return FALSE; } @@ -3678,10 +3677,9 @@ xg_tool_bar_button_cb (GtkWidget *widget, static void xg_tool_bar_callback (GtkWidget *w, gpointer client_data) { - /* The EMACS_INT cast avoids a warning. */ - int idx = (int) (EMACS_INT) client_data; + EMACS_INTPTR idx = (EMACS_INTPTR) client_data; gpointer gmod = g_object_get_data (G_OBJECT (w), XG_TOOL_BAR_LAST_MODIFIER); - int mod = (int) (EMACS_INT) gmod; + EMACS_INTPTR mod = (EMACS_INTPTR) gmod; FRAME_PTR f = (FRAME_PTR) g_object_get_data (G_OBJECT (w), XG_FRAME_DATA); Lisp_Object key, frame; @@ -3960,8 +3958,7 @@ xg_tool_bar_help_callback (GtkWidget *w, GdkEventCrossing *event, gpointer client_data) { - /* The EMACS_INT cast avoids a warning. */ - int idx = (int) (EMACS_INT) client_data; + EMACS_INTPTR idx = (EMACS_INTPTR) client_data; FRAME_PTR f = (FRAME_PTR) g_object_get_data (G_OBJECT (w), XG_FRAME_DATA); Lisp_Object help, frame; @@ -4155,14 +4152,16 @@ xg_make_tool_item (FRAME_PTR f, if (wimage) { - /* The EMACS_INT cast avoids a warning. */ + EMACS_INTPTR ii = i; + gpointer gi = (gpointer) ii; + g_signal_connect (G_OBJECT (ti), "create-menu-proxy", G_CALLBACK (xg_tool_bar_menu_proxy), - (gpointer) (EMACS_INT) i); + gi); g_signal_connect (G_OBJECT (wb), "clicked", G_CALLBACK (xg_tool_bar_callback), - (gpointer) (EMACS_INT) i); + gi); g_object_set_data (G_OBJECT (weventbox), XG_FRAME_DATA, (gpointer)f); @@ -4193,11 +4192,11 @@ xg_make_tool_item (FRAME_PTR f, g_signal_connect (G_OBJECT (weventbox), "enter-notify-event", G_CALLBACK (xg_tool_bar_help_callback), - (gpointer) (EMACS_INT) i); + gi); g_signal_connect (G_OBJECT (weventbox), "leave-notify-event", G_CALLBACK (xg_tool_bar_help_callback), - (gpointer) (EMACS_INT) i); + gi); } if (wbutton) *wbutton = wb; diff --git a/src/lisp.h b/src/lisp.h index dca3b4d9a32..a8cf38f6669 100644 --- a/src/lisp.h +++ b/src/lisp.h @@ -22,6 +22,7 @@ along with GNU Emacs. If not, see . */ #include #include +#include /* Use the configure flag --enable-checking[=LIST] to enable various types of run time checks for Lisp objects. */ @@ -54,6 +55,18 @@ extern void check_cons_list (void); #endif #endif +/* Integers large enough to hold casted pointers without losing info. */ +#ifdef INTPTR_MAX +# define EMACS_INTPTR intptr_t +#else +# define EMACS_INTPTR EMACS_INT +#endif +#ifdef UINTPTR_MAX +# define EMACS_UINTPTR uintptr_t +#else +# define EMACS_UINTPTR EMACS_UINT +#endif + /* Extra internal type checking? */ #ifdef ENABLE_CHECKING @@ -398,7 +411,7 @@ enum pvec_type #ifdef USE_LSB_TAG #define TYPEMASK ((((EMACS_INT) 1) << GCTYPEBITS) - 1) -#define XTYPE(a) ((enum Lisp_Type) (((EMACS_UINT) (a)) & TYPEMASK)) +#define XTYPE(a) ((enum Lisp_Type) ((a) & TYPEMASK)) #ifdef USE_2_TAGS_FOR_INTS # define XINT(a) (((EMACS_INT) (a)) >> (GCTYPEBITS - 1)) # define XUINT(a) (((EMACS_UINT) (a)) >> (GCTYPEBITS - 1)) @@ -408,11 +421,11 @@ enum pvec_type # define XUINT(a) (((EMACS_UINT) (a)) >> GCTYPEBITS) # define make_number(N) (((EMACS_INT) (N)) << GCTYPEBITS) #endif -#define XSET(var, type, ptr) \ - (eassert (XTYPE (ptr) == 0), /* Check alignment. */ \ - (var) = ((EMACS_INT) (type)) | ((EMACS_INT) (ptr))) +#define XSET(var, type, ptr) \ + (eassert (XTYPE ((EMACS_INTPTR) (ptr)) == 0), /* Check alignment. */ \ + (var) = (type) | (EMACS_INTPTR) (ptr)) -#define XPNTR(a) ((EMACS_INT) ((a) & ~TYPEMASK)) +#define XPNTR(a) ((EMACS_INTPTR) ((a) & ~TYPEMASK)) #else /* not USE_LSB_TAG */ @@ -446,14 +459,14 @@ enum pvec_type #define XSET(var, type, ptr) \ ((var) = ((EMACS_INT) ((EMACS_UINT) (type) << VALBITS) \ - + ((EMACS_INT) (ptr) & VALMASK))) + + ((EMACS_INTPTR) (ptr) & VALMASK))) #ifdef DATA_SEG_BITS /* DATA_SEG_BITS forces extra bits to be or'd in with any pointers which were stored in a Lisp_Object */ -#define XPNTR(a) ((EMACS_UINT) (((a) & VALMASK) | DATA_SEG_BITS)) +#define XPNTR(a) ((EMACS_UINTPTR) (((a) & VALMASK)) | DATA_SEG_BITS)) #else -#define XPNTR(a) ((EMACS_UINT) ((a) & VALMASK)) +#define XPNTR(a) ((EMACS_UINTPTR) ((a) & VALMASK)) #endif #endif /* not USE_LSB_TAG */ @@ -479,7 +492,7 @@ enum pvec_type /* Some versions of gcc seem to consider the bitfield width when issuing the "cast to pointer from integer of different size" warning, so the cast is here to widen the value back to its natural size. */ -# define XPNTR(v) ((EMACS_INT)((v).s.val) << GCTYPEBITS) +# define XPNTR(v) ((EMACS_INTPTR) (v).s.val << GCTYPEBITS) #else /* !USE_LSB_TAG */ @@ -495,9 +508,9 @@ enum pvec_type #ifdef DATA_SEG_BITS /* DATA_SEG_BITS forces extra bits to be or'd in with any pointers which were stored in a Lisp_Object */ -#define XPNTR(a) (XUINT (a) | DATA_SEG_BITS) +#define XPNTR(a) ((EMACS_INTPTR) (XUINT (a) | DATA_SEG_BITS)) #else -#define XPNTR(a) ((EMACS_INT) XUINT (a)) +#define XPNTR(a) ((EMACS_INTPTR) XUINT (a)) #endif #endif /* !USE_LSB_TAG */ @@ -1814,8 +1827,8 @@ typedef struct { XSETCDR ((x), tmp); \ } while (0) -/* Cast pointers to this type to compare them. Some machines want int. */ -#define PNTR_COMPARISON_TYPE EMACS_UINT +/* Cast pointers to this type to compare them. */ +#define PNTR_COMPARISON_TYPE EMACS_UINTPTR /* Define a built-in function for calling from Lisp. `lname' should be the name to give the function in Lisp, diff --git a/src/menu.c b/src/menu.c index f637b92679a..5162ee083bf 100644 --- a/src/menu.c +++ b/src/menu.c @@ -800,9 +800,9 @@ digest_single_submenu (int start, int end, int top_level_items) if (!NILP (descrip)) wv->lkey = descrip; wv->value = 0; - /* The EMACS_INT cast avoids a warning. There's no problem + /* The EMACS_INTPTR cast avoids a warning. There's no problem as long as pointers have enough bits to hold small integers. */ - wv->call_data = (!NILP (def) ? (void *) (EMACS_INT) i : 0); + wv->call_data = (!NILP (def) ? (void *) (EMACS_INTPTR) i : 0); wv->enabled = !NILP (enable); if (NILP (type)) @@ -911,9 +911,9 @@ find_and_call_menu_selection (FRAME_PTR f, int menu_bar_items_used, Lisp_Object else { entry = XVECTOR (vector)->contents[i + MENU_ITEMS_ITEM_VALUE]; - /* The EMACS_INT cast avoids a warning. There's no problem + /* Treat the pointer as an integer. There's no problem as long as pointers have enough bits to hold small integers. */ - if ((int) (EMACS_INT) client_data == i) + if ((EMACS_INTPTR) client_data == i) { int j; struct input_event buf; diff --git a/src/xdisp.c b/src/xdisp.c index 6d3c142f62a..af03a504e86 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -8737,7 +8737,7 @@ display_echo_area (struct window *w) window_height_changed_p = with_echo_area_buffer (w, display_last_displayed_message_p, display_echo_area_1, - (EMACS_INT) w, Qnil, 0, 0); + (EMACS_INTPTR) w, Qnil, 0, 0); if (no_message_p) echo_area_buffer[i] = Qnil; @@ -8756,7 +8756,8 @@ display_echo_area (struct window *w) static int display_echo_area_1 (EMACS_INT a1, Lisp_Object a2, EMACS_INT a3, EMACS_INT a4) { - struct window *w = (struct window *) a1; + EMACS_INTPTR i1 = a1; + struct window *w = (struct window *) i1; Lisp_Object window; struct text_pos start; int window_height_changed_p = 0; @@ -8798,7 +8799,8 @@ resize_echo_area_exactly (void) resize_exactly = Qnil; resized_p = with_echo_area_buffer (w, 0, resize_mini_window_1, - (EMACS_INT) w, resize_exactly, 0, 0); + (EMACS_INTPTR) w, resize_exactly, + 0, 0); if (resized_p) { ++windows_or_buffers_changed; @@ -8818,7 +8820,8 @@ resize_echo_area_exactly (void) static int resize_mini_window_1 (EMACS_INT a1, Lisp_Object exactly, EMACS_INT a3, EMACS_INT a4) { - return resize_mini_window ((struct window *) a1, !NILP (exactly)); + EMACS_INTPTR i1 = a1; + return resize_mini_window ((struct window *) i1, !NILP (exactly)); } @@ -8984,7 +8987,7 @@ current_message (void) else { with_echo_area_buffer (0, 0, current_message_1, - (EMACS_INT) &msg, Qnil, 0, 0); + (EMACS_INTPTR) &msg, Qnil, 0, 0); if (NILP (msg)) echo_area_buffer[0] = Qnil; } @@ -8996,7 +8999,8 @@ current_message (void) static int current_message_1 (EMACS_INT a1, Lisp_Object a2, EMACS_INT a3, EMACS_INT a4) { - Lisp_Object *msg = (Lisp_Object *) a1; + EMACS_INTPTR i1 = a1; + Lisp_Object *msg = (Lisp_Object *) i1; if (Z > BEG) *msg = make_buffer_string (BEG, Z, 1); @@ -9127,7 +9131,7 @@ set_message (const char *s, Lisp_Object string, || (STRINGP (string) && STRING_MULTIBYTE (string))); with_echo_area_buffer (0, -1, set_message_1, - (EMACS_INT) s, string, nbytes, multibyte_p); + (EMACS_INTPTR) s, string, nbytes, multibyte_p); message_buf_print = 0; help_echo_showing_p = 0; } @@ -9141,7 +9145,8 @@ set_message (const char *s, Lisp_Object string, static int set_message_1 (EMACS_INT a1, Lisp_Object a2, EMACS_INT nbytes, EMACS_INT multibyte_p) { - const char *s = (const char *) a1; + EMACS_INTPTR i1 = a1; + const char *s = (const char *) i1; const unsigned char *msg = (const unsigned char *) s; Lisp_Object string = a2; diff --git a/src/xmenu.c b/src/xmenu.c index 2d6185c16e5..54f1fc666ec 100644 --- a/src/xmenu.c +++ b/src/xmenu.c @@ -1139,9 +1139,9 @@ set_frame_menubar (FRAME_PTR f, int first_time, int deep_p) wv->help = Qnil; /* This prevents lwlib from assuming this menu item is really supposed to be empty. */ - /* The EMACS_INT cast avoids a warning. + /* The EMACS_INTPTR cast avoids a warning. This value just has to be different from small integers. */ - wv->call_data = (void *) (EMACS_INT) (-1); + wv->call_data = (void *) (EMACS_INTPTR) (-1); if (prev_wv) prev_wv->next = wv; @@ -1876,9 +1876,9 @@ xmenu_show (FRAME_PTR f, int x, int y, int for_click, int keymaps, static void dialog_selection_callback (GtkWidget *widget, gpointer client_data) { - /* The EMACS_INT cast avoids a warning. There's no problem + /* Treat the pointer as an integer. There's no problem as long as pointers have enough bits to hold small integers. */ - if ((int) (EMACS_INT) client_data != -1) + if ((EMACS_INTPTR) client_data != -1) menu_item_selection = (Lisp_Object *) client_data; popup_activated_flag = 0; From 8727937b9656243b361ba3d8d12ff1ac502a9080 Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Fri, 29 Apr 2011 00:55:25 -0700 Subject: [PATCH 07/38] * lread.c, process.c: Do not include ; lisp.h does it now. --- src/ChangeLog | 2 ++ src/lread.c | 1 - src/process.c | 5 +---- 3 files changed, 3 insertions(+), 5 deletions(-) diff --git a/src/ChangeLog b/src/ChangeLog index 05f332b8142..a1e048b1390 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,5 +1,7 @@ 2011-04-29 Paul Eggert + * lread.c, process.c: Do not include ; lisp.h does it now. + Prefer intptr_t/uintptr_t for integers the same widths as pointers. This removes an assumption that EMACS_INT and long are the same width as pointers. The assumption is true for Emacs porting targets diff --git a/src/lread.c b/src/lread.c index 2c8c3acd56a..c7c91f8c3e4 100644 --- a/src/lread.c +++ b/src/lread.c @@ -19,7 +19,6 @@ along with GNU Emacs. If not, see . */ #include -#include #include #include #include diff --git a/src/process.c b/src/process.c index 1544522ff55..59d1b9ea77f 100644 --- a/src/process.c +++ b/src/process.c @@ -28,9 +28,6 @@ along with GNU Emacs. If not, see . */ #include #include #include -#ifdef HAVE_INTTYPES_H -#include -#endif #include #include @@ -4539,7 +4536,7 @@ wait_reading_process_output (int time_limit, int microsecs, int read_kbd, some data in the TCP buffers so that select works, but with custom pull/push functions we need to check if some data is available in the buffers manually. */ - if (nfds == 0 && + if (nfds == 0 && wait_proc && wait_proc->gnutls_p /* Check for valid process. */ /* Do we have pending data? */ && gnutls_record_check_pending (wait_proc->gnutls_state) > 0) From d1a2ac5c058c374b2c8178d94ce401febe07e9d8 Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Fri, 29 Apr 2011 00:55:57 -0700 Subject: [PATCH 08/38] * configure.in (BITS_PER_LONG_LONG): New macro. --- ChangeLog | 4 ++++ configure.in | 10 ++++++---- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/ChangeLog b/ChangeLog index a561f8efeec..31e8c869e52 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2011-04-29 Paul Eggert + + * configure.in (BITS_PER_LONG_LONG): New macro. + 2011-04-27 Ben Key * configure.in: Fixed a bug that caused configure with diff --git a/configure.in b/configure.in index 68404bf0bcd..aadb6ebe84c 100644 --- a/configure.in +++ b/configure.in @@ -3518,7 +3518,8 @@ AH_BOTTOM([ #endif /* These default definitions are good for almost all machines. - The exceptions override them in m/MACHINE.h. */ + Any exceptions should override them in m/MACHINE.h. + They must be usable in preprocessor conditionals. */ #ifndef BITS_PER_CHAR #define BITS_PER_CHAR 8 @@ -3528,9 +3529,6 @@ AH_BOTTOM([ #define BITS_PER_SHORT 16 #endif -/* Note that lisp.h uses this in a preprocessor conditional, so it - would not work to use sizeof. That being so, we do all of them - without sizeof, for uniformity's sake. */ #ifndef BITS_PER_INT #define BITS_PER_INT 32 #endif @@ -3543,6 +3541,10 @@ AH_BOTTOM([ #endif #endif +#if !defined BITS_PER_LONG_LONG && HAVE_LONG_LONG_INT +#define BITS_PER_LONG_LONG 64 +#endif + /* Define if the compiler supports function prototypes. It may do so but not define __STDC__ (e.g. DEC C by default) or may define it as zero. */ #undef PROTOTYPES From 7fd47d5ce2020a22f8db9776e8d1f47891b966dc Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Fri, 29 Apr 2011 01:51:24 -0700 Subject: [PATCH 09/38] * lisp.h: Prefer 64-bit EMACS_INT if available. (EMACS_INT, EMACS_UINT, BITS_PER_EMACS_INT, pI): Define to 64-bit on 32-bit hosts that have 64-bit int, so that they can access large files. --- src/ChangeLog | 5 +++++ src/lisp.h | 11 ++++++++++- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/src/ChangeLog b/src/ChangeLog index a1e048b1390..a9fc541b481 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,5 +1,10 @@ 2011-04-29 Paul Eggert + * lisp.h: Prefer 64-bit EMACS_INT if available. + (EMACS_INT, EMACS_UINT, BITS_PER_EMACS_INT, pI): Define to 64-bit + on 32-bit hosts that have 64-bit int, so that they can access + large files. + * lread.c, process.c: Do not include ; lisp.h does it now. Prefer intptr_t/uintptr_t for integers the same widths as pointers. diff --git a/src/lisp.h b/src/lisp.h index a8cf38f6669..3b9778ddc64 100644 --- a/src/lisp.h +++ b/src/lisp.h @@ -44,7 +44,16 @@ extern void check_cons_list (void); #ifndef EMACS_UINT #define EMACS_UINT unsigned long #endif -#else /* not _LP64 */ +#elif /* !_LP64 && */ BITS_PER_LONG < BITS_PER_LONG_LONG +#ifndef EMACS_INT +#define EMACS_INT long long +#define BITS_PER_EMACS_INT BITS_PER_LONG_LONG +#define pI "ll" +#endif +#ifndef EMACS_UINT +#define EMACS_UINT unsigned long long +#endif +#else /* ! (_LP64 || BITS_PER_LONG < BITS_PER_LONG_LONG) */ #ifndef EMACS_INT #define EMACS_INT int #define BITS_PER_EMACS_INT BITS_PER_INT From d01a78266d12561b46777a2156914d12d8099c4f Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Fri, 29 Apr 2011 10:56:27 -0700 Subject: [PATCH 10/38] * lisp.h (EMACS_INTPTR): Remove. All uses changed to intptr_t. (EMACS_UINTPTR): Likewise, with uintptr_t. --- src/ChangeLog | 3 +++ src/alloc.c | 38 +++++++++++++++++++------------------- src/doc.c | 6 +++--- src/gtkutil.c | 14 +++++++------- src/lisp.h | 32 ++++++++++---------------------- src/menu.c | 6 +++--- src/xdisp.c | 16 ++++++++-------- src/xmenu.c | 6 +++--- 8 files changed, 56 insertions(+), 65 deletions(-) diff --git a/src/ChangeLog b/src/ChangeLog index a9fc541b481..a2bf1fe39cf 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,5 +1,8 @@ 2011-04-29 Paul Eggert + * lisp.h (EMACS_INTPTR): Remove. All uses changed to intptr_t. + (EMACS_UINTPTR): Likewise, with uintptr_t. + * lisp.h: Prefer 64-bit EMACS_INT if available. (EMACS_INT, EMACS_UINT, BITS_PER_EMACS_INT, pI): Define to 64-bit on 32-bit hosts that have 64-bit int, so that they can access diff --git a/src/alloc.c b/src/alloc.c index 591d8264295..0bce83bfae7 100644 --- a/src/alloc.c +++ b/src/alloc.c @@ -438,7 +438,7 @@ static POINTER_TYPE *pure_alloc (size_t, int); ALIGNMENT must be a power of 2. */ #define ALIGN(ptr, ALIGNMENT) \ - ((POINTER_TYPE *) ((((EMACS_UINTPTR) (ptr)) + (ALIGNMENT) - 1) \ + ((POINTER_TYPE *) ((((uintptr_t) (ptr)) + (ALIGNMENT) - 1) \ & ~((ALIGNMENT) - 1))) @@ -876,7 +876,7 @@ struct ablocks #define ABLOCKS_BYTES (sizeof (struct ablocks) - BLOCK_PADDING) #define ABLOCK_ABASE(block) \ - (((EMACS_UINTPTR) (block)->abase) <= (1 + 2 * ABLOCKS_SIZE) \ + (((uintptr_t) (block)->abase) <= (1 + 2 * ABLOCKS_SIZE) \ ? (struct ablocks *)(block) \ : (block)->abase) @@ -888,7 +888,7 @@ struct ablocks #define ABLOCKS_BASE(abase) (abase) #else #define ABLOCKS_BASE(abase) \ - (1 & (EMACS_INTPTR) ABLOCKS_BUSY (abase) ? abase : ((void**)abase)[-1]) + (1 & (intptr_t) ABLOCKS_BUSY (abase) ? abase : ((void**)abase)[-1]) #endif /* The list of free ablock. */ @@ -914,7 +914,7 @@ lisp_align_malloc (size_t nbytes, enum mem_type type) if (!free_ablock) { int i; - EMACS_INTPTR aligned; /* int gets warning casting to 64-bit pointer. */ + intptr_t aligned; /* int gets warning casting to 64-bit pointer. */ #ifdef DOUG_LEA_MALLOC /* Prevent mmap'ing the chunk. Lisp data may not be mmap'ed @@ -979,16 +979,16 @@ lisp_align_malloc (size_t nbytes, enum mem_type type) } ABLOCKS_BUSY (abase) = (struct ablocks *) aligned; - eassert (0 == ((EMACS_UINTPTR) abase) % BLOCK_ALIGN); + eassert (0 == ((uintptr_t) abase) % BLOCK_ALIGN); eassert (ABLOCK_ABASE (&abase->blocks[3]) == abase); /* 3 is arbitrary */ eassert (ABLOCK_ABASE (&abase->blocks[0]) == abase); eassert (ABLOCKS_BASE (abase) == base); - eassert (aligned == (EMACS_INTPTR) ABLOCKS_BUSY (abase)); + eassert (aligned == (intptr_t) ABLOCKS_BUSY (abase)); } abase = ABLOCK_ABASE (free_ablock); ABLOCKS_BUSY (abase) = - (struct ablocks *) (2 + (EMACS_INTPTR) ABLOCKS_BUSY (abase)); + (struct ablocks *) (2 + (intptr_t) ABLOCKS_BUSY (abase)); val = free_ablock; free_ablock = free_ablock->x.next_free; @@ -1001,7 +1001,7 @@ lisp_align_malloc (size_t nbytes, enum mem_type type) if (!val && nbytes) memory_full (); - eassert (0 == ((EMACS_UINTPTR) val) % BLOCK_ALIGN); + eassert (0 == ((uintptr_t) val) % BLOCK_ALIGN); return val; } @@ -1020,11 +1020,11 @@ lisp_align_free (POINTER_TYPE *block) free_ablock = ablock; /* Update busy count. */ ABLOCKS_BUSY (abase) = - (struct ablocks *) (-2 + (EMACS_INTPTR) ABLOCKS_BUSY (abase)); + (struct ablocks *) (-2 + (intptr_t) ABLOCKS_BUSY (abase)); - if (2 > (EMACS_INTPTR) ABLOCKS_BUSY (abase)) + if (2 > (intptr_t) ABLOCKS_BUSY (abase)) { /* All the blocks are free. */ - int i = 0, aligned = (EMACS_INTPTR) ABLOCKS_BUSY (abase); + int i = 0, aligned = (intptr_t) ABLOCKS_BUSY (abase); struct ablock **tem = &free_ablock; struct ablock *atop = &abase->blocks[aligned ? ABLOCKS_SIZE : ABLOCKS_SIZE - 1]; @@ -1041,7 +1041,7 @@ lisp_align_free (POINTER_TYPE *block) eassert ((aligned & 1) == aligned); eassert (i == (aligned ? ABLOCKS_SIZE : ABLOCKS_SIZE - 1)); #ifdef USE_POSIX_MEMALIGN - eassert ((EMACS_UINTPTR) ABLOCKS_BASE (abase) % BLOCK_ALIGN == 0); + eassert ((uintptr_t) ABLOCKS_BASE (abase) % BLOCK_ALIGN == 0); #endif free (ABLOCKS_BASE (abase)); } @@ -1774,7 +1774,7 @@ check_string_free_list (void) s = string_free_list; while (s != NULL) { - if ((EMACS_UINTPTR) s < 1024) + if ((uintptr_t) s < 1024) abort(); s = NEXT_FREE_LISP_STRING (s); } @@ -2434,10 +2434,10 @@ make_uninit_multibyte_string (EMACS_INT nchars, EMACS_INT nbytes) &= ~(1 << ((n) % (sizeof(int) * CHAR_BIT))) #define FLOAT_BLOCK(fptr) \ - ((struct float_block *) (((EMACS_UINTPTR) (fptr)) & ~(BLOCK_ALIGN - 1))) + ((struct float_block *) (((uintptr_t) (fptr)) & ~(BLOCK_ALIGN - 1))) #define FLOAT_INDEX(fptr) \ - ((((EMACS_UINTPTR) (fptr)) & (BLOCK_ALIGN - 1)) / sizeof (struct Lisp_Float)) + ((((uintptr_t) (fptr)) & (BLOCK_ALIGN - 1)) / sizeof (struct Lisp_Float)) struct float_block { @@ -2546,10 +2546,10 @@ make_float (double float_value) / (sizeof (struct Lisp_Cons) * CHAR_BIT + 1)) #define CONS_BLOCK(fptr) \ - ((struct cons_block *) ((EMACS_UINTPTR) (fptr) & ~(BLOCK_ALIGN - 1))) + ((struct cons_block *) ((uintptr_t) (fptr) & ~(BLOCK_ALIGN - 1))) #define CONS_INDEX(fptr) \ - (((EMACS_UINTPTR) (fptr) & (BLOCK_ALIGN - 1)) / sizeof (struct Lisp_Cons)) + (((uintptr_t) (fptr) & (BLOCK_ALIGN - 1)) / sizeof (struct Lisp_Cons)) struct cons_block { @@ -4023,7 +4023,7 @@ mark_maybe_pointer (void *p) struct mem_node *m; /* Quickly rule out some values which can't point to Lisp data. */ - if ((EMACS_INTPTR) p % + if ((intptr_t) p % #ifdef USE_LSB_TAG 8 /* USE_LSB_TAG needs Lisp data to be aligned on multiples of 8. */ #else @@ -6074,7 +6074,7 @@ We divide the value by 1024 to make sure it fits in a Lisp integer. */) { Lisp_Object end; - XSETINT (end, (EMACS_INTPTR) (char *) sbrk (0) / 1024); + XSETINT (end, (intptr_t) (char *) sbrk (0) / 1024); return end; } diff --git a/src/doc.c b/src/doc.c index 740bb26ff08..d764b66e75e 100644 --- a/src/doc.c +++ b/src/doc.c @@ -349,10 +349,10 @@ string is passed through `substitute-command-keys'. */) return Qnil; /* FIXME: This is not portable, as it assumes that string pointers have the top bit clear. */ - else if ((EMACS_INTPTR) XSUBR (fun)->doc >= 0) + else if ((intptr_t) XSUBR (fun)->doc >= 0) doc = build_string (XSUBR (fun)->doc); else - doc = make_number ((EMACS_INTPTR) XSUBR (fun)->doc); + doc = make_number ((intptr_t) XSUBR (fun)->doc); } else if (COMPILEDP (fun)) { @@ -508,7 +508,7 @@ store_function_docstring (Lisp_Object fun, EMACS_INT offset) /* Lisp_Subrs have a slot for it. */ if (SUBRP (fun)) { - EMACS_INTPTR negative_offset = - offset; + intptr_t negative_offset = - offset; XSUBR (fun)->doc = (char *) negative_offset; } diff --git a/src/gtkutil.c b/src/gtkutil.c index ff33a3f3c04..6e54006d913 100644 --- a/src/gtkutil.c +++ b/src/gtkutil.c @@ -3354,7 +3354,7 @@ xg_get_scroll_id_for_window (Display *dpy, Window wid) static void xg_gtk_scroll_destroy (GtkWidget *widget, gpointer data) { - int id = (EMACS_INTPTR) data; + int id = (intptr_t) data; xg_remove_widget_from_map (id); } @@ -3375,7 +3375,7 @@ xg_create_scroll_bar (FRAME_PTR f, { GtkWidget *wscroll; GtkWidget *webox; - EMACS_INTPTR scroll_id; + intptr_t scroll_id; #ifdef HAVE_GTK3 GtkAdjustment *vadj; #else @@ -3662,7 +3662,7 @@ xg_tool_bar_button_cb (GtkWidget *widget, GdkEventButton *event, gpointer user_data) { - EMACS_INTPTR state = event->state; + intptr_t state = event->state; gpointer ptr = (gpointer) state; g_object_set_data (G_OBJECT (widget), XG_TOOL_BAR_LAST_MODIFIER, ptr); return FALSE; @@ -3677,9 +3677,9 @@ xg_tool_bar_button_cb (GtkWidget *widget, static void xg_tool_bar_callback (GtkWidget *w, gpointer client_data) { - EMACS_INTPTR idx = (EMACS_INTPTR) client_data; + intptr_t idx = (intptr_t) client_data; gpointer gmod = g_object_get_data (G_OBJECT (w), XG_TOOL_BAR_LAST_MODIFIER); - EMACS_INTPTR mod = (EMACS_INTPTR) gmod; + intptr_t mod = (intptr_t) gmod; FRAME_PTR f = (FRAME_PTR) g_object_get_data (G_OBJECT (w), XG_FRAME_DATA); Lisp_Object key, frame; @@ -3958,7 +3958,7 @@ xg_tool_bar_help_callback (GtkWidget *w, GdkEventCrossing *event, gpointer client_data) { - EMACS_INTPTR idx = (EMACS_INTPTR) client_data; + intptr_t idx = (intptr_t) client_data; FRAME_PTR f = (FRAME_PTR) g_object_get_data (G_OBJECT (w), XG_FRAME_DATA); Lisp_Object help, frame; @@ -4152,7 +4152,7 @@ xg_make_tool_item (FRAME_PTR f, if (wimage) { - EMACS_INTPTR ii = i; + intptr_t ii = i; gpointer gi = (gpointer) ii; g_signal_connect (G_OBJECT (ti), "create-menu-proxy", diff --git a/src/lisp.h b/src/lisp.h index 3b9778ddc64..41848ebae8e 100644 --- a/src/lisp.h +++ b/src/lisp.h @@ -64,18 +64,6 @@ extern void check_cons_list (void); #endif #endif -/* Integers large enough to hold casted pointers without losing info. */ -#ifdef INTPTR_MAX -# define EMACS_INTPTR intptr_t -#else -# define EMACS_INTPTR EMACS_INT -#endif -#ifdef UINTPTR_MAX -# define EMACS_UINTPTR uintptr_t -#else -# define EMACS_UINTPTR EMACS_UINT -#endif - /* Extra internal type checking? */ #ifdef ENABLE_CHECKING @@ -431,10 +419,10 @@ enum pvec_type # define make_number(N) (((EMACS_INT) (N)) << GCTYPEBITS) #endif #define XSET(var, type, ptr) \ - (eassert (XTYPE ((EMACS_INTPTR) (ptr)) == 0), /* Check alignment. */ \ - (var) = (type) | (EMACS_INTPTR) (ptr)) + (eassert (XTYPE ((intptr_t) (ptr)) == 0), /* Check alignment. */ \ + (var) = (type) | (intptr_t) (ptr)) -#define XPNTR(a) ((EMACS_INTPTR) ((a) & ~TYPEMASK)) +#define XPNTR(a) ((intptr_t) ((a) & ~TYPEMASK)) #else /* not USE_LSB_TAG */ @@ -468,14 +456,14 @@ enum pvec_type #define XSET(var, type, ptr) \ ((var) = ((EMACS_INT) ((EMACS_UINT) (type) << VALBITS) \ - + ((EMACS_INTPTR) (ptr) & VALMASK))) + + ((intptr_t) (ptr) & VALMASK))) #ifdef DATA_SEG_BITS /* DATA_SEG_BITS forces extra bits to be or'd in with any pointers which were stored in a Lisp_Object */ -#define XPNTR(a) ((EMACS_UINTPTR) (((a) & VALMASK)) | DATA_SEG_BITS)) +#define XPNTR(a) ((uintptr_t) (((a) & VALMASK)) | DATA_SEG_BITS)) #else -#define XPNTR(a) ((EMACS_UINTPTR) ((a) & VALMASK)) +#define XPNTR(a) ((uintptr_t) ((a) & VALMASK)) #endif #endif /* not USE_LSB_TAG */ @@ -501,7 +489,7 @@ enum pvec_type /* Some versions of gcc seem to consider the bitfield width when issuing the "cast to pointer from integer of different size" warning, so the cast is here to widen the value back to its natural size. */ -# define XPNTR(v) ((EMACS_INTPTR) (v).s.val << GCTYPEBITS) +# define XPNTR(v) ((intptr_t) (v).s.val << GCTYPEBITS) #else /* !USE_LSB_TAG */ @@ -517,9 +505,9 @@ enum pvec_type #ifdef DATA_SEG_BITS /* DATA_SEG_BITS forces extra bits to be or'd in with any pointers which were stored in a Lisp_Object */ -#define XPNTR(a) ((EMACS_INTPTR) (XUINT (a) | DATA_SEG_BITS)) +#define XPNTR(a) ((intptr_t) (XUINT (a) | DATA_SEG_BITS)) #else -#define XPNTR(a) ((EMACS_INTPTR) XUINT (a)) +#define XPNTR(a) ((intptr_t) XUINT (a)) #endif #endif /* !USE_LSB_TAG */ @@ -1837,7 +1825,7 @@ typedef struct { } while (0) /* Cast pointers to this type to compare them. */ -#define PNTR_COMPARISON_TYPE EMACS_UINTPTR +#define PNTR_COMPARISON_TYPE uintptr_t /* Define a built-in function for calling from Lisp. `lname' should be the name to give the function in Lisp, diff --git a/src/menu.c b/src/menu.c index 5162ee083bf..7a3edcb6f4f 100644 --- a/src/menu.c +++ b/src/menu.c @@ -800,9 +800,9 @@ digest_single_submenu (int start, int end, int top_level_items) if (!NILP (descrip)) wv->lkey = descrip; wv->value = 0; - /* The EMACS_INTPTR cast avoids a warning. There's no problem + /* The intptr_t cast avoids a warning. There's no problem as long as pointers have enough bits to hold small integers. */ - wv->call_data = (!NILP (def) ? (void *) (EMACS_INTPTR) i : 0); + wv->call_data = (!NILP (def) ? (void *) (intptr_t) i : 0); wv->enabled = !NILP (enable); if (NILP (type)) @@ -913,7 +913,7 @@ find_and_call_menu_selection (FRAME_PTR f, int menu_bar_items_used, Lisp_Object entry = XVECTOR (vector)->contents[i + MENU_ITEMS_ITEM_VALUE]; /* Treat the pointer as an integer. There's no problem as long as pointers have enough bits to hold small integers. */ - if ((EMACS_INTPTR) client_data == i) + if ((intptr_t) client_data == i) { int j; struct input_event buf; diff --git a/src/xdisp.c b/src/xdisp.c index af03a504e86..88353e37925 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -8737,7 +8737,7 @@ display_echo_area (struct window *w) window_height_changed_p = with_echo_area_buffer (w, display_last_displayed_message_p, display_echo_area_1, - (EMACS_INTPTR) w, Qnil, 0, 0); + (intptr_t) w, Qnil, 0, 0); if (no_message_p) echo_area_buffer[i] = Qnil; @@ -8756,7 +8756,7 @@ display_echo_area (struct window *w) static int display_echo_area_1 (EMACS_INT a1, Lisp_Object a2, EMACS_INT a3, EMACS_INT a4) { - EMACS_INTPTR i1 = a1; + intptr_t i1 = a1; struct window *w = (struct window *) i1; Lisp_Object window; struct text_pos start; @@ -8799,7 +8799,7 @@ resize_echo_area_exactly (void) resize_exactly = Qnil; resized_p = with_echo_area_buffer (w, 0, resize_mini_window_1, - (EMACS_INTPTR) w, resize_exactly, + (intptr_t) w, resize_exactly, 0, 0); if (resized_p) { @@ -8820,7 +8820,7 @@ resize_echo_area_exactly (void) static int resize_mini_window_1 (EMACS_INT a1, Lisp_Object exactly, EMACS_INT a3, EMACS_INT a4) { - EMACS_INTPTR i1 = a1; + intptr_t i1 = a1; return resize_mini_window ((struct window *) i1, !NILP (exactly)); } @@ -8987,7 +8987,7 @@ current_message (void) else { with_echo_area_buffer (0, 0, current_message_1, - (EMACS_INTPTR) &msg, Qnil, 0, 0); + (intptr_t) &msg, Qnil, 0, 0); if (NILP (msg)) echo_area_buffer[0] = Qnil; } @@ -8999,7 +8999,7 @@ current_message (void) static int current_message_1 (EMACS_INT a1, Lisp_Object a2, EMACS_INT a3, EMACS_INT a4) { - EMACS_INTPTR i1 = a1; + intptr_t i1 = a1; Lisp_Object *msg = (Lisp_Object *) i1; if (Z > BEG) @@ -9131,7 +9131,7 @@ set_message (const char *s, Lisp_Object string, || (STRINGP (string) && STRING_MULTIBYTE (string))); with_echo_area_buffer (0, -1, set_message_1, - (EMACS_INTPTR) s, string, nbytes, multibyte_p); + (intptr_t) s, string, nbytes, multibyte_p); message_buf_print = 0; help_echo_showing_p = 0; } @@ -9145,7 +9145,7 @@ set_message (const char *s, Lisp_Object string, static int set_message_1 (EMACS_INT a1, Lisp_Object a2, EMACS_INT nbytes, EMACS_INT multibyte_p) { - EMACS_INTPTR i1 = a1; + intptr_t i1 = a1; const char *s = (const char *) i1; const unsigned char *msg = (const unsigned char *) s; Lisp_Object string = a2; diff --git a/src/xmenu.c b/src/xmenu.c index 54f1fc666ec..35ad42970cf 100644 --- a/src/xmenu.c +++ b/src/xmenu.c @@ -1139,9 +1139,9 @@ set_frame_menubar (FRAME_PTR f, int first_time, int deep_p) wv->help = Qnil; /* This prevents lwlib from assuming this menu item is really supposed to be empty. */ - /* The EMACS_INTPTR cast avoids a warning. + /* The intptr_t cast avoids a warning. This value just has to be different from small integers. */ - wv->call_data = (void *) (EMACS_INTPTR) (-1); + wv->call_data = (void *) (intptr_t) (-1); if (prev_wv) prev_wv->next = wv; @@ -1878,7 +1878,7 @@ dialog_selection_callback (GtkWidget *widget, gpointer client_data) { /* Treat the pointer as an integer. There's no problem as long as pointers have enough bits to hold small integers. */ - if ((EMACS_INTPTR) client_data != -1) + if ((intptr_t) client_data != -1) menu_item_selection = (Lisp_Object *) client_data; popup_activated_flag = 0; From 371cac43187cce3b5cc4c1779ae059b2bafa29a0 Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Fri, 29 Apr 2011 18:06:41 -0700 Subject: [PATCH 11/38] * dbusbind.c: Do not use XPNTR on a value that may be an integer. Reported by Stefan Monnier in . (xd_remove_watch, Fdbus_init_bus, xd_read_queued_messages): Use SYMBOLP-guarded XSYMBOL, not XPNTR. --- src/ChangeLog | 8 ++++++++ src/dbusbind.c | 8 +++++--- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/src/ChangeLog b/src/ChangeLog index a2bf1fe39cf..2b71a06ae4a 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,11 @@ +2011-04-30 Paul Eggert + + * dbusbind.c: Do not use XPNTR on a value that may be an integer. + Reported by Stefan Monnier in + . + (xd_remove_watch, Fdbus_init_bus, xd_read_queued_messages): Use + SYMBOLP-guarded XSYMBOL, not XPNTR. + 2011-04-29 Paul Eggert * lisp.h (EMACS_INTPTR): Remove. All uses changed to intptr_t. diff --git a/src/dbusbind.c b/src/dbusbind.c index 06feec3e792..76035341540 100644 --- a/src/dbusbind.c +++ b/src/dbusbind.c @@ -892,7 +892,7 @@ xd_remove_watch (DBusWatch *watch, void *data) return; /* Unset session environment. */ - if (data != NULL && data == (void *) XPNTR (QCdbus_session_bus)) + if (SYMBOLP (QCdbus_session_bus) && XSYMBOL (QCdbus_session_bus) == data) { XD_DEBUG_MESSAGE ("unsetenv DBUS_SESSION_BUS_ADDRESS"); unsetenv ("DBUS_SESSION_BUS_ADDRESS"); @@ -920,6 +920,8 @@ DEFUN ("dbus-init-bus", Fdbus_init_bus, Sdbus_init_bus, 1, 1, 0, { DBusConnection *connection; + CHECK_SYMBOL (bus); + /* Open a connection to the bus. */ connection = xd_initialize (bus, TRUE); @@ -929,7 +931,7 @@ DEFUN ("dbus-init-bus", Fdbus_init_bus, Sdbus_init_bus, 1, 1, 0, xd_add_watch, xd_remove_watch, xd_toggle_watch, - (void *) XPNTR (bus), NULL)) + XSYMBOL (bus), NULL)) XD_SIGNAL1 (build_string ("Cannot add watch functions")); /* Add bus to list of registered buses. */ @@ -1824,7 +1826,7 @@ xd_read_queued_messages (int fd, void *data, int for_read) if (data != NULL) while (!NILP (busp)) { - if (data == (void *) XPNTR (CAR_SAFE (busp))) + if (SYMBOLP (CAR_SAFE (busp)) && XSYMBOL (CAR_SAFE (busp)) == data) bus = CAR_SAFE (busp); busp = CDR_SAFE (busp); } From 47be4ab5001b31c7097749ec6d35d0c0a2f27b63 Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Fri, 29 Apr 2011 19:49:39 -0700 Subject: [PATCH 12/38] * lisp.h (EMACS_INT, EMACS_UINT, BITS_PER_EMACS_INT, pI): Simplify. --- src/ChangeLog | 2 ++ src/lisp.h | 38 ++++++++++++++------------------------ 2 files changed, 16 insertions(+), 24 deletions(-) diff --git a/src/ChangeLog b/src/ChangeLog index 2b71a06ae4a..d75ec22b9f9 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,5 +1,7 @@ 2011-04-30 Paul Eggert + * lisp.h (EMACS_INT, EMACS_UINT, BITS_PER_EMACS_INT, pI): Simplify. + * dbusbind.c: Do not use XPNTR on a value that may be an integer. Reported by Stefan Monnier in . diff --git a/src/lisp.h b/src/lisp.h index 41848ebae8e..76938a49ac4 100644 --- a/src/lisp.h +++ b/src/lisp.h @@ -35,33 +35,23 @@ extern void check_cons_list (void); #endif /* These are default choices for the types to use. */ -#ifdef _LP64 #ifndef EMACS_INT -#define EMACS_INT long -#define BITS_PER_EMACS_INT BITS_PER_LONG -#define pI "l" +# if BITS_PER_LONG < BITS_PER_LONG_LONG +# define EMACS_INT long long +# define BITS_PER_EMACS_INT BITS_PER_LONG_LONG +# define pI "ll" +# elif BITS_PER_INT < BITS_PER_LONG +# define EMACS_INT long +# define BITS_PER_EMACS_INT BITS_PER_LONG +# define pI "l" +# else +# define EMACS_INT int +# define BITS_PER_EMACS_INT BITS_PER_INT +# define pI "" +# endif #endif #ifndef EMACS_UINT -#define EMACS_UINT unsigned long -#endif -#elif /* !_LP64 && */ BITS_PER_LONG < BITS_PER_LONG_LONG -#ifndef EMACS_INT -#define EMACS_INT long long -#define BITS_PER_EMACS_INT BITS_PER_LONG_LONG -#define pI "ll" -#endif -#ifndef EMACS_UINT -#define EMACS_UINT unsigned long long -#endif -#else /* ! (_LP64 || BITS_PER_LONG < BITS_PER_LONG_LONG) */ -#ifndef EMACS_INT -#define EMACS_INT int -#define BITS_PER_EMACS_INT BITS_PER_INT -#define pI "" -#endif -#ifndef EMACS_UINT -#define EMACS_UINT unsigned int -#endif +# define EMACS_UINT unsigned EMACS_INT #endif /* Extra internal type checking? */ From b28b879992f7637094ed9af008588143e0e58002 Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Fri, 29 Apr 2011 23:51:50 -0700 Subject: [PATCH 13/38] * config.nt: Configure 64-bit integers. (BITS_PER_LONG_LONG): Define if C99-style long long and "%lld" work. (EMACS_INT, BITS_PER_EMACS_INT, pI): Otherwise, define these if __int64 and "%I64d" work. --- nt/ChangeLog | 8 +++++++- nt/config.nt | 12 +++++++++++- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/nt/ChangeLog b/nt/ChangeLog index ea4f7547962..4597478081b 100644 --- a/nt/ChangeLog +++ b/nt/ChangeLog @@ -1,3 +1,10 @@ +2011-04-30 Paul Eggert + + * config.nt: Configure 64-bit integers. + (BITS_PER_LONG_LONG): Define if C99-style long long and "%lld" work. + (EMACS_INT, BITS_PER_EMACS_INT, pI): Otherwise, define these if + __int64 and "%I64d" work. + 2011-04-28 Eli Zaretskii * gmake.defs (ARCH): Fix error message in case of unknown @@ -2062,4 +2069,3 @@ You should have received a copy of the GNU General Public License along with GNU Emacs. If not, see . - diff --git a/nt/config.nt b/nt/config.nt index a159234be7d..f46868cd6ea 100644 --- a/nt/config.nt +++ b/nt/config.nt @@ -470,6 +470,17 @@ extern char *getenv (); #define BITS_PER_LONG 32 #endif +#if (defined __MINGW32__ \ + || 1400 <= _MSC_VER || (1310 <= _MSC_VER && defined _MSC_EXTENSIONS)) +/* C99-style long long and "%lld" both work, so use them. */ +# define BITS_PER_LONG_LONG 64 +#elif 1200 <= _MSC_VER +/* Use pre-C99-style 64-bit integers. */ +# define EMACS_INT __int64 +# define BITS_PER_EMACS_INT 64 +# define pI "I64" +#endif + #ifndef POINTER_TYPE #define POINTER_TYPE void #endif @@ -508,4 +519,3 @@ void w32_abort (void) NO_RETURN; /* Make a leaner executable. */ #define WIN32_LEAN_AND_MEAN 1 - From 68652052aa84634e84652f46e9a795081cd40906 Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Sat, 30 Apr 2011 00:38:26 -0700 Subject: [PATCH 14/38] * config.nt: Simplify test to 1400 <= _MSC_VER. --- nt/config.nt | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/nt/config.nt b/nt/config.nt index f46868cd6ea..7765919638f 100644 --- a/nt/config.nt +++ b/nt/config.nt @@ -470,8 +470,7 @@ extern char *getenv (); #define BITS_PER_LONG 32 #endif -#if (defined __MINGW32__ \ - || 1400 <= _MSC_VER || (1310 <= _MSC_VER && defined _MSC_EXTENSIONS)) +#if defined __MINGW32__ || 1400 <= _MSC_VER /* C99-style long long and "%lld" both work, so use them. */ # define BITS_PER_LONG_LONG 64 #elif 1200 <= _MSC_VER From aec1708a5548072ba337a345fb72a184840eb0cb Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Sat, 30 Apr 2011 08:40:06 -0700 Subject: [PATCH 15/38] * dispnew.c (scrolling_window): Return 1 if we scrolled, to match comment at start of function. This also removes a GCC warning about overflow in a 32+64-bit port. --- src/ChangeLog | 4 ++++ src/dispnew.c | 4 ++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/ChangeLog b/src/ChangeLog index d75ec22b9f9..0a9c3d88ca5 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,5 +1,9 @@ 2011-04-30 Paul Eggert + * dispnew.c (scrolling_window): Return 1 if we scrolled, + to match comment at start of function. This also removes a + GCC warning about overflow in a 32+64-bit port. + * lisp.h (EMACS_INT, EMACS_UINT, BITS_PER_EMACS_INT, pI): Simplify. * dbusbind.c: Do not use XPNTR on a value that may be an integer. diff --git a/src/dispnew.c b/src/dispnew.c index 13e920166c5..0457d650b3a 100644 --- a/src/dispnew.c +++ b/src/dispnew.c @@ -4576,8 +4576,8 @@ scrolling_window (struct window *w, int header_line_p) for (i = 0; i < row_entry_idx; ++i) row_table[row_entry_pool[i].bucket] = NULL; - /* Value is > 0 to indicate that we scrolled the display. */ - return nruns; + /* Value is 1 to indicate that we scrolled the display. */ + return 0 < nruns; } From ad5f9eeaa2f0f872e063849f8f0d24d2c200acfa Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Sat, 30 Apr 2011 13:05:43 -0700 Subject: [PATCH 16/38] * doprnt.c (doprnt): Support arbitrary pI values, such as "I64". --- src/ChangeLog | 2 ++ src/doprnt.c | 58 +++++++++++++++++++++++---------------------------- 2 files changed, 28 insertions(+), 32 deletions(-) diff --git a/src/ChangeLog b/src/ChangeLog index 310d32a6432..d043bf7f691 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,5 +1,7 @@ 2011-04-30 Paul Eggert + * doprnt.c (doprnt): Support arbitrary pI values, such as "I64". + * dispnew.c (scrolling_window): Return 1 if we scrolled, to match comment at start of function. This also removes a GCC warning about overflow in a 32+64-bit port. diff --git a/src/doprnt.c b/src/doprnt.c index 7b4bd35d5b1..d2abc119912 100644 --- a/src/doprnt.c +++ b/src/doprnt.c @@ -70,9 +70,9 @@ along with GNU Emacs. If not, see . */ %character where flags is [+ -0], width is [0-9]+, precision is .[0-9]+, and length - is empty or l or ll. Also, %% in a format stands for a single % in the - output. A % that does not introduce a valid %-sequence causes - undefined behavior. + is empty or l or the value of the pI macro. Also, %% in a format + stands for a single % in the output. A % that does not introduce a + valid %-sequence causes undefined behavior. The + flag character inserts a + before any positive number, while a space inserts a space before any positive number; these flags only affect %d, %o, @@ -85,11 +85,8 @@ along with GNU Emacs. If not, see . */ modifier: it is supported for %d, %o, and %x conversions of integral arguments, must immediately precede the conversion specifier, and means that the respective argument is to be treated as `long int' or `unsigned long - int'. Similarly, ll (two letter ells) means to use `long long int' or - `unsigned long long int'; this can be used only on hosts that have - these two types. The empty length modifier means to use `int' or - `unsigned int'. EMACS_INT arguments should use the pI macro, which - expands to whatever length modifier is needed for the target host. + int'. Similarly, the value of the pI macro means to use EMACS_INT or + EMACS_UINT and the empty length modifier means `int' or `unsigned int'. The width specifier supplies a lower limit for the length of the printed representation. The padding, if any, normally goes on the left, but it goes @@ -186,6 +183,7 @@ doprnt (char *buffer, register size_t bufsize, const char *format, size_t size_bound = 0; EMACS_INT width; /* Columns occupied by STRING on display. */ int long_flag = 0; + int pIlen = sizeof pI - 1; fmt++; /* Copy this one %-spec into fmtcpy. */ @@ -201,7 +199,7 @@ doprnt (char *buffer, register size_t bufsize, const char *format, %1.1000f and %1000.1f both might need 1000+ bytes. Parse the width or precision, checking for overflow. */ size_t n = *fmt - '0'; - while (fmt < format_end + while (fmt + 1 < format_end && '0' <= fmt[1] && fmt[1] <= '9') { /* Avoid size_t overflow. Avoid int overflow too, as @@ -218,20 +216,25 @@ doprnt (char *buffer, register size_t bufsize, const char *format, if (size_bound < n) size_bound = n; } - else if (*fmt == '-' || *fmt == ' ' || *fmt == '.' || *fmt == '+') - ; - else if (*fmt == 'l') - { - long_flag = 1 + (fmt + 1 < format_end && fmt[1] == 'l'); - fmt += long_flag; - break; - } - else + else if (! (*fmt == '-' || *fmt == ' ' || *fmt == '.' + || *fmt == '+')) break; fmt++; } - if (fmt > format_end) - fmt = format_end; + + if (0 < pIlen && pIlen <= format_end - fmt + && memcmp (fmt, pI, pIlen) == 0) + { + long_flag = 2; + memcpy (string, fmt + 1, pIlen); + string += pIlen; + fmt += pIlen; + } + else if (fmt < format_end && *fmt == 'l') + { + long_flag = 1; + *string++ = *++fmt; + } *string = 0; /* Make the size bound large enough to handle floating point formats @@ -253,8 +256,7 @@ doprnt (char *buffer, register size_t bufsize, const char *format, switch (*fmt++) { default: - error ("Invalid format operation %%%s%c", - "ll" + 2 - long_flag, fmt[-1]); + error ("Invalid format operation %s", fmtcpy); /* case 'b': */ case 'l': @@ -265,12 +267,8 @@ doprnt (char *buffer, register size_t bufsize, const char *format, if (1 < long_flag) { -#ifdef HAVE_LONG_LONG_INT - long long ll = va_arg (ap, long long); + EMACS_INT ll = va_arg (ap, EMACS_INT); sprintf (sprintf_buffer, fmtcpy, ll); -#else - error ("Invalid format operation %%ll%c", fmt[-1]); -#endif } else if (long_flag) { @@ -295,12 +293,8 @@ doprnt (char *buffer, register size_t bufsize, const char *format, if (1 < long_flag) { -#ifdef HAVE_UNSIGNED_LONG_LONG_INT - unsigned long long ull = va_arg (ap, unsigned long long); + EMACS_UINT ull = va_arg (ap, EMACS_UINT); sprintf (sprintf_buffer, fmtcpy, ull); -#else - error ("Invalid format operation %%ll%c", fmt[-1]); -#endif } else if (long_flag) { From c032b5f8c03c4cd94239074dc9fd682bc3e2f3a1 Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Sun, 1 May 2011 09:27:34 -0700 Subject: [PATCH 17/38] * charset.h (struct charset.code_space): Now has 15 elements, not 16. * charset.c (Fdefine_charset_internal): Don't initialize charset.code_space[15]. The value was garbage, on hosts with 32-bit int. --- src/ChangeLog | 7 +++++++ src/charset.c | 8 +++++--- src/charset.h | 7 ++++--- 3 files changed, 16 insertions(+), 6 deletions(-) diff --git a/src/ChangeLog b/src/ChangeLog index 7b54b1e521c..93af816947c 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,10 @@ +2011-05-01 Paul Eggert + + * charset.h (struct charset.code_space): Now has 15 elements, not 16. + * charset.c (Fdefine_charset_internal): Don't initialize + charset.code_space[15]. The value was garbage, on hosts with + 32-bit int. + 2011-04-30 Eli Zaretskii * dosfns.c (Fint86, Fdos_memget, Fdos_memput): Use `ASIZE (FOO)' diff --git a/src/charset.c b/src/charset.c index 52c2ebdcc4e..55fd57031ac 100644 --- a/src/charset.c +++ b/src/charset.c @@ -869,7 +869,7 @@ usage: (define-charset-internal ...) */) ASET (attrs, charset_name, args[charset_arg_name]); val = args[charset_arg_code_space]; - for (i = 0, dimension = 0, nchars = 1; i < 4; i++) + for (i = 0, dimension = 0, nchars = 1; ; i++) { int min_byte, max_byte; @@ -880,10 +880,12 @@ usage: (define-charset-internal ...) */) charset.code_space[i * 4] = min_byte; charset.code_space[i * 4 + 1] = max_byte; charset.code_space[i * 4 + 2] = max_byte - min_byte + 1; - nchars *= charset.code_space[i * 4 + 2]; - charset.code_space[i * 4 + 3] = nchars; if (max_byte > 0) dimension = i + 1; + if (i == 3) + break; + nchars *= charset.code_space[i * 4 + 2]; + charset.code_space[i * 4 + 3] = nchars; } val = args[charset_arg_dimension]; diff --git a/src/charset.h b/src/charset.h index 74d55a31b43..53784bf8455 100644 --- a/src/charset.h +++ b/src/charset.h @@ -155,10 +155,11 @@ struct charset byte code of the (N+1)th dimension, [4N+1] is a maximum byte code of the (N+1)th dimension, [4N+2] is ([4N+1] - [4N] + 1), [4N+3] - is a number of characters containd in the first to (N+1)th - dismesions. We get `char-index' of a `code-point' from this + is the number of characters contained in the first through (N+1)th + dimensions, except that there is no [15]. + We get `char-index' of a `code-point' from this information. */ - int code_space[16]; + int code_space[15]; /* If B is a byte of Nth dimension of a code-point, the (N-1)th bit of code_space_mask[B] is set. This array is used to quickly From 2d38271b704d7a3dc9453a6cda4a2115e6b9a56f Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Sun, 1 May 2011 10:53:49 -0700 Subject: [PATCH 18/38] Add Bug#. --- src/ChangeLog | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ChangeLog b/src/ChangeLog index 93af816947c..230761a6f1e 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -3,7 +3,7 @@ * charset.h (struct charset.code_space): Now has 15 elements, not 16. * charset.c (Fdefine_charset_internal): Don't initialize charset.code_space[15]. The value was garbage, on hosts with - 32-bit int. + 32-bit int (Bug#8600). 2011-04-30 Eli Zaretskii From 2f9442b848594799dd155d455930215df2d2a222 Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Sun, 1 May 2011 16:37:08 -0700 Subject: [PATCH 19/38] * coding.c (detect_coding_charset): Fix typo: * 2 -> *4 (Bug#8601). --- src/ChangeLog | 2 ++ src/coding.c | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/ChangeLog b/src/ChangeLog index 230761a6f1e..52d7a6cc068 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,5 +1,7 @@ 2011-05-01 Paul Eggert + * coding.c (detect_coding_charset): Fix typo: * 2 -> *4 (Bug#8601). + * charset.h (struct charset.code_space): Now has 15 elements, not 16. * charset.c (Fdefine_charset_internal): Don't initialize charset.code_space[15]. The value was garbage, on hosts with diff --git a/src/coding.c b/src/coding.c index d17346efdcb..71253df6469 100644 --- a/src/coding.c +++ b/src/coding.c @@ -5368,8 +5368,8 @@ detect_coding_charset (struct coding_system *coding, if (src == src_end) goto too_short; ONE_MORE_BYTE (c); - if (c < charset->code_space[(dim - 1 - idx) * 2] - || c > charset->code_space[(dim - 1 - idx) * 2 + 1]) + if (c < charset->code_space[(dim - 1 - idx) * 4] + || c > charset->code_space[(dim - 1 - idx) * 4 + 1]) break; } if (idx < dim) From a108c10b7ae69e5f782c83be925c168e007874fb Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Sun, 1 May 2011 19:58:08 -0700 Subject: [PATCH 20/38] * lread.c (read_integer): Be more consistent with string-to-number. Use string_to_number to do the actual conversion; this avoids rounding errors and fixes some other screwups. Without this fix, for example, #x1fffffffffffffff was misread as -2305843009213693952. (digit_to_number): Move earlier, for benefit of read_integer. Return -1 if the digit is out of range for the base, -2 if it is not a digit in any supported base. --- src/ChangeLog | 10 +++++ src/lread.c | 102 +++++++++++++++++++++++++++----------------------- 2 files changed, 65 insertions(+), 47 deletions(-) diff --git a/src/ChangeLog b/src/ChangeLog index d043bf7f691..a93cc8d2a9d 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,13 @@ +2011-05-02 Paul Eggert + + * lread.c (read_integer): Be more consistent with string-to-number. + Use string_to_number to do the actual conversion; this avoids + rounding errors and fixes some other screwups. Without this fix, + for example, #x1fffffffffffffff was misread as -2305843009213693952. + (digit_to_number): Move earlier, for benefit of read_integer. + Return -1 if the digit is out of range for the base, -2 if it is + not a digit in any supported base. + 2011-04-30 Paul Eggert * doprnt.c (doprnt): Support arbitrary pI values, such as "I64". diff --git a/src/lread.c b/src/lread.c index c7c91f8c3e4..7686f966db2 100644 --- a/src/lread.c +++ b/src/lread.c @@ -2245,6 +2245,26 @@ read_escape (Lisp_Object readcharfun, int stringp) } } +/* Return the digit that CHARACTER stands for in the given BASE. + Return -1 if CHARACTER is out of range for BASE, + and -2 if CHARACTER is not valid for any supported BASE. */ +static inline int +digit_to_number (int character, int base) +{ + int digit; + + if ('0' <= character && character <= '9') + digit = character - '0'; + else if ('a' <= character && character <= 'z') + digit = character - 'a' + 10; + else if ('A' <= character && character <= 'Z') + digit = character - 'A' + 10; + else + return -2; + + return digit < base ? digit : -1; +} + /* Read an integer in radix RADIX using READCHARFUN to read characters. RADIX must be in the interval [2..36]; if it isn't, a read error is signaled . Value is the integer read. Signals an @@ -2254,59 +2274,64 @@ read_escape (Lisp_Object readcharfun, int stringp) static Lisp_Object read_integer (Lisp_Object readcharfun, int radix) { - int ndigits = 0, invalid_p, c, sign = 0; - /* We use a floating point number because */ - double number = 0; + /* Room for sign, leading 0, other digits, trailing null byte. */ + char buf[1 + 1 + sizeof (uintmax_t) * CHAR_BIT + 1]; + + int valid = -1; /* 1 if valid, 0 if not, -1 if incomplete. */ if (radix < 2 || radix > 36) - invalid_p = 1; + valid = 0; else { - number = ndigits = invalid_p = 0; - sign = 1; + char *p = buf; + int c, digit; c = READCHAR; - if (c == '-') + if (c == '-' || c == '+') { + *p++ = c; c = READCHAR; - sign = -1; } - else if (c == '+') - c = READCHAR; - while (c >= 0) + if (c == '0') { - int digit; + *p++ = c; + valid = 1; - if (c >= '0' && c <= '9') - digit = c - '0'; - else if (c >= 'a' && c <= 'z') - digit = c - 'a' + 10; - else if (c >= 'A' && c <= 'Z') - digit = c - 'A' + 10; + /* Ignore redundant leading zeros, so the buffer doesn't + fill up with them. */ + do + c = READCHAR; + while (c == '0'); + } + + while (-1 <= (digit = digit_to_number (c, radix))) + { + if (digit == -1) + valid = 0; + if (valid < 0) + valid = 1; + + if (p < buf + sizeof buf - 1) + *p++ = c; else - { - UNREAD (c); - break; - } + valid = 0; - if (digit < 0 || digit >= radix) - invalid_p = 1; - - number = radix * number + digit; - ++ndigits; c = READCHAR; } + + if (c >= 0) + UNREAD (c); + *p = '\0'; } - if (ndigits == 0 || invalid_p) + if (! valid) { - char buf[50]; sprintf (buf, "integer, radix %d", radix); invalid_syntax (buf, 0); } - return make_fixnum_or_float (sign * number); + return string_to_number (buf, radix, 0); } @@ -3165,23 +3190,6 @@ substitute_in_interval (INTERVAL interval, Lisp_Object arg) } -static inline int -digit_to_number (int character, int base) -{ - int digit; - - if ('0' <= character && character <= '9') - digit = character - '0'; - else if ('a' <= character && character <= 'z') - digit = character - 'a' + 10; - else if ('A' <= character && character <= 'Z') - digit = character - 'A' + 10; - else - return -1; - - return digit < base ? digit : -1; -} - #define LEAD_INT 1 #define DOT_CHAR 2 #define TRAIL_INT 4 From 48e400f07d5a37b8ab7a75f758b61fb6440cedd8 Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Sun, 1 May 2011 20:21:58 -0700 Subject: [PATCH 21/38] Add Bug#. --- src/ChangeLog | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ChangeLog b/src/ChangeLog index a93cc8d2a9d..3013418afec 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -6,7 +6,7 @@ for example, #x1fffffffffffffff was misread as -2305843009213693952. (digit_to_number): Move earlier, for benefit of read_integer. Return -1 if the digit is out of range for the base, -2 if it is - not a digit in any supported base. + not a digit in any supported base. (Bug#8602) 2011-04-30 Paul Eggert From 88c9450f387d1a89aabcbadef504f3688586410c Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Mon, 2 May 2011 23:12:50 -0700 Subject: [PATCH 22/38] * xmenu.c (set_frame_menubar): Fix typo: int * -> int (3 times). --- src/ChangeLog | 2 ++ src/xmenu.c | 6 +++--- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/ChangeLog b/src/ChangeLog index c237ba24b0f..6235e908cfd 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,5 +1,7 @@ 2011-05-03 Paul Eggert + * xmenu.c (set_frame_menubar): Fix typo: int * -> int (3 times). + * coding.c (detect_coding_charset): Fix typo: * 2 -> *4 (Bug#8601). * charset.h (struct charset.code_space): Now has 15 elements, not 16. diff --git a/src/xmenu.c b/src/xmenu.c index 35ad42970cf..2a4359fa84a 100644 --- a/src/xmenu.c +++ b/src/xmenu.c @@ -1012,10 +1012,10 @@ set_frame_menubar (FRAME_PTR f, int first_time, int deep_p) menu_items = f->menu_bar_vector; menu_items_allocated = VECTORP (menu_items) ? ASIZE (menu_items) : 0; subitems = ASIZE (items) / 4; - submenu_start = (int *) alloca (subitems * sizeof (int *)); - submenu_end = (int *) alloca (subitems * sizeof (int *)); + submenu_start = (int *) alloca (subitems * sizeof (int)); + submenu_end = (int *) alloca (subitems * sizeof (int)); submenu_n_panes = (int *) alloca (subitems * sizeof (int)); - submenu_top_level_items = (int *) alloca (subitems * sizeof (int *)); + submenu_top_level_items = (int *) alloca (subitems * sizeof (int)); init_menu_items (); for (i = 0; i < subitems; i++) { From dd5963ea216906d4047f9dcbd044326a3c019868 Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Mon, 2 May 2011 23:13:54 -0700 Subject: [PATCH 23/38] * process.c (Fformat_network_address): Fix typo: args2 -> *args2. --- src/ChangeLog | 2 ++ src/process.c | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/ChangeLog b/src/ChangeLog index 6235e908cfd..56e1ac9a503 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,5 +1,7 @@ 2011-05-03 Paul Eggert + * process.c (Fformat_network_address): Fix typo: args2 -> *args2. + * xmenu.c (set_frame_menubar): Fix typo: int * -> int (3 times). * coding.c (detect_coding_charset): Fix typo: * 2 -> *4 (Bug#8601). diff --git a/src/process.c b/src/process.c index 59d1b9ea77f..3dc096e7d60 100644 --- a/src/process.c +++ b/src/process.c @@ -1384,7 +1384,7 @@ usage: (start-process NAME BUFFER PROGRAM &rest PROGRAM-ARGS) */) { if (EQ (coding_systems, Qt)) { - args2 = (Lisp_Object *) alloca ((nargs + 1) * sizeof args2); + args2 = (Lisp_Object *) alloca ((nargs + 1) * sizeof *args2); args2[0] = Qstart_process; for (i = 0; i < nargs; i++) args2[i + 1] = args[i]; GCPRO2 (proc, current_dir); From db6c0e74f1e0483060623ed68c49107685902e65 Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Mon, 2 May 2011 23:26:40 -0700 Subject: [PATCH 24/38] * callproc.c (Fcall_process): Use 'volatile' to avoid vfork clobbering. --- src/ChangeLog | 2 ++ src/callproc.c | 17 +++++++++++++---- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/src/ChangeLog b/src/ChangeLog index 56e1ac9a503..ccf1fea9514 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,5 +1,7 @@ 2011-05-03 Paul Eggert + * callproc.c (Fcall_process): Use 'volatile' to avoid vfork clobbering. + * process.c (Fformat_network_address): Fix typo: args2 -> *args2. * xmenu.c (set_frame_menubar): Fix typo: int * -> int (3 times). diff --git a/src/callproc.c b/src/callproc.c index 4a29e95b356..c2c301eb4a5 100644 --- a/src/callproc.c +++ b/src/callproc.c @@ -192,7 +192,6 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS) */) int count = SPECPDL_INDEX (); volatile USE_SAFE_ALLOCA; - const unsigned char **volatile new_argv_volatile; register const unsigned char **new_argv; /* File to use for stderr in the child. t means use same as standard output. */ @@ -415,7 +414,6 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS) */) SAFE_ALLOCA (new_argv, const unsigned char **, (nargs > 4 ? nargs - 2 : 2) * sizeof *new_argv); - new_argv_volatile = new_argv; if (nargs > 4) { register size_t i; @@ -590,9 +588,20 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS) */) BLOCK_INPUT; - pid = vfork (); + /* vfork, and prevent local vars from being clobbered by the vfork. */ + { + int volatile fd_error_volatile = fd_error; + int volatile fd_output_volatile = fd_output; + int volatile output_to_buffer_volatile = output_to_buffer; + unsigned char const **volatile new_argv_volatile = new_argv; - new_argv = new_argv_volatile; + pid = vfork (); + + fd_error = fd_error_volatile; + fd_output = fd_output_volatile; + output_to_buffer = output_to_buffer_volatile; + new_argv = new_argv_volatile; + } if (pid == 0) { From fed14fd75201f3c313293432e58de8f860979a3e Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Tue, 3 May 2011 00:41:32 -0700 Subject: [PATCH 25/38] * numbers.texi (Integer Basics): Large integers are treated as floats. --- doc/lispref/ChangeLog | 4 ++++ doc/lispref/numbers.texi | 7 ++++--- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/doc/lispref/ChangeLog b/doc/lispref/ChangeLog index 4aa63c6abaa..163de31f220 100644 --- a/doc/lispref/ChangeLog +++ b/doc/lispref/ChangeLog @@ -1,3 +1,7 @@ +2011-05-03 Paul Eggert + + * numbers.texi (Integer Basics): Large integers are treated as floats. + 2011-04-30 Lars Magne Ingebrigtsen * processes.texi (Synchronous Processes): Document the (:file diff --git a/doc/lispref/numbers.texi b/doc/lispref/numbers.texi index 23150c2c937..2c73a03a26c 100644 --- a/doc/lispref/numbers.texi +++ b/doc/lispref/numbers.texi @@ -55,14 +55,15 @@ chapter assume an integer has 30 bits. @cindex overflow The Lisp reader reads an integer as a sequence of digits with optional -initial sign and optional final period. +initial sign and optional final period. An integer that is out of the +Emacs range is treated as a floating-point number. @example 1 ; @r{The integer 1.} 1. ; @r{The integer 1.} +1 ; @r{Also the integer 1.} -1 ; @r{The integer @minus{}1.} - 1073741825 ; @r{Also the integer 1, due to overflow.} + 1073741825 ; @r{The floating point number 1073741825.0.} 0 ; @r{The integer 0.} -0 ; @r{The integer 0.} @end example @@ -195,7 +196,7 @@ point values: @samp{1.0e+INF} @item negative infinity @samp{-1.0e+INF} -@item Not-a-number +@item Not-a-number @samp{0.0e+NaN} or @samp{-0.0e+NaN}. @end table From 7fc4768c45bce52d34f183eb4734d9f58745ea3d Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Tue, 3 May 2011 00:51:38 -0700 Subject: [PATCH 26/38] Arithmetic overflows now return float rather than wrapping around. * data.c: Include . (arith_driver): Use floating point if the accumulator would otherwise go out of EMACS_INT range. (arith_driver, Fadd1, Fsub1): Use floating point if the result is out of Emacs fixnum range. * bytecode.c (exec_byte_code): Likewise, for Bsub1, Badd1, Bnegate. --- src/ChangeLog | 8 ++++ src/bytecode.c | 6 +-- src/data.c | 126 +++++++++++++++++++++++++++++++------------------ 3 files changed, 91 insertions(+), 49 deletions(-) diff --git a/src/ChangeLog b/src/ChangeLog index ccf1fea9514..435f90abad9 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,5 +1,13 @@ 2011-05-03 Paul Eggert + Arithmetic overflows now return float rather than wrapping around. + * data.c: Include . + (arith_driver): Use floating point if the accumulator would otherwise + go out of EMACS_INT range. + (arith_driver, Fadd1, Fsub1): Use floating point if the result is + out of Emacs fixnum range. + * bytecode.c (exec_byte_code): Likewise, for Bsub1, Badd1, Bnegate. + * callproc.c (Fcall_process): Use 'volatile' to avoid vfork clobbering. * process.c (Fformat_network_address): Fix typo: args2 -> *args2. diff --git a/src/bytecode.c b/src/bytecode.c index c3cd3d43072..ce79b011bbb 100644 --- a/src/bytecode.c +++ b/src/bytecode.c @@ -1186,7 +1186,7 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth, { Lisp_Object v1; v1 = TOP; - if (INTEGERP (v1)) + if (INTEGERP (v1) && MOST_NEGATIVE_FIXNUM < XINT (v1)) { XSETINT (v1, XINT (v1) - 1); TOP = v1; @@ -1204,7 +1204,7 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth, { Lisp_Object v1; v1 = TOP; - if (INTEGERP (v1)) + if (INTEGERP (v1) && XINT (v1) < MOST_POSITIVE_FIXNUM) { XSETINT (v1, XINT (v1) + 1); TOP = v1; @@ -1290,7 +1290,7 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth, { Lisp_Object v1; v1 = TOP; - if (INTEGERP (v1)) + if (INTEGERP (v1) && - MOST_POSITIVE_FIXNUM <= XINT (v1)) { XSETINT (v1, - XINT (v1)); TOP = v1; diff --git a/src/data.c b/src/data.c index 577ae777d89..beff570d552 100644 --- a/src/data.c +++ b/src/data.c @@ -22,6 +22,9 @@ along with GNU Emacs. If not, see . */ #include #include #include + +#include + #include "lisp.h" #include "puresize.h" #include "character.h" @@ -2426,10 +2429,8 @@ static Lisp_Object float_arith_driver (double, size_t, enum arithop, static Lisp_Object arith_driver (enum arithop code, size_t nargs, register Lisp_Object *args) { - register Lisp_Object val; register size_t argnum; register EMACS_INT accum = 0; - register EMACS_INT next; switch (SWITCH_ENUM_CAST (code)) { @@ -2451,58 +2452,89 @@ arith_driver (enum arithop code, size_t nargs, register Lisp_Object *args) for (argnum = 0; argnum < nargs; argnum++) { + EMACS_INT a = accum; + int use_float = 0; + /* Using args[argnum] as argument to CHECK_NUMBER_... */ - val = args[argnum]; + Lisp_Object val = args[argnum]; CHECK_NUMBER_OR_FLOAT_COERCE_MARKER (val); + args[argnum] = val; if (FLOATP (val)) - return float_arith_driver ((double) accum, argnum, code, - nargs, args); - args[argnum] = val; - next = XINT (args[argnum]); - switch (SWITCH_ENUM_CAST (code)) + use_float = 1; + else { - case Aadd: - accum += next; - break; - case Asub: - accum = argnum ? accum - next : nargs == 1 ? - next : next; - break; - case Amult: - accum *= next; - break; - case Adiv: - if (!argnum) - accum = next; - else + EMACS_INT next = XINT (val); + switch (SWITCH_ENUM_CAST (code)) { - if (next == 0) - xsignal0 (Qarith_error); - accum /= next; + case Aadd: + if (next < 0 + ? a < TYPE_MINIMUM (EMACS_INT) - next + : TYPE_MAXIMUM (EMACS_INT) - next < a) + use_float = 1; + else + a += next; + break; + case Asub: + if (argnum == 0 && nargs != 1) + a = next; + else if (next < 0 + ? TYPE_MAXIMUM (EMACS_INT) + next < a + : a < TYPE_MINIMUM (EMACS_INT) + next) + use_float = 1; + else + a -= next; + break; + case Amult: + if (next < 0 + ? (a < 0 + ? a < TYPE_MAXIMUM (EMACS_INT) / next + : next != -1 && TYPE_MINIMUM (EMACS_INT) / next < a) + : (next != 0 + && (a < 0 + ? a < TYPE_MINIMUM (EMACS_INT) / next + : TYPE_MAXIMUM (EMACS_INT) / next < a))) + use_float = 1; + else + a *= next; + break; + case Adiv: + if (!argnum) + a = next; + else + { + if (next == 0) + xsignal0 (Qarith_error); + a /= next; + } + break; + case Alogand: + a &= next; + break; + case Alogior: + a |= next; + break; + case Alogxor: + a ^= next; + break; + case Amax: + if (!argnum || a < next) + a = next; + break; + case Amin: + if (!argnum || next < a) + a = next; + break; } - break; - case Alogand: - accum &= next; - break; - case Alogior: - accum |= next; - break; - case Alogxor: - accum ^= next; - break; - case Amax: - if (!argnum || next > accum) - accum = next; - break; - case Amin: - if (!argnum || next < accum) - accum = next; - break; } + + if (use_float) + return float_arith_driver (accum, argnum, code, nargs, args); + + accum = a; } - XSETINT (val, accum); - return val; + return make_fixnum_or_float (accum); } #undef isnan @@ -2777,7 +2809,8 @@ Markers are converted to integers. */) if (FLOATP (number)) return (make_float (1.0 + XFLOAT_DATA (number))); - + if (XINT (number) + 1 == MOST_POSITIVE_FIXNUM + 1) + return make_float (XINT (number) + 1); XSETINT (number, XINT (number) + 1); return number; } @@ -2791,7 +2824,8 @@ Markers are converted to integers. */) if (FLOATP (number)) return (make_float (-1.0 + XFLOAT_DATA (number))); - + if (XINT (number) - 1 == MOST_NEGATIVE_FIXNUM - 1) + return make_float (XINT (number) - 1); XSETINT (number, XINT (number) - 1); return number; } From 4ed0cebda869315a9e729daa55c50a16e2a5cde1 Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Tue, 3 May 2011 01:52:13 -0700 Subject: [PATCH 27/38] * floatfns.c (Fexpt): Likewise. --- src/ChangeLog | 1 + src/floatfns.c | 46 +++++++++++++++++++++++++++++----------------- 2 files changed, 30 insertions(+), 17 deletions(-) diff --git a/src/ChangeLog b/src/ChangeLog index 435f90abad9..26b3af3225c 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -7,6 +7,7 @@ (arith_driver, Fadd1, Fsub1): Use floating point if the result is out of Emacs fixnum range. * bytecode.c (exec_byte_code): Likewise, for Bsub1, Badd1, Bnegate. + * floatfns.c (Fexpt): Likewise. * callproc.c (Fcall_process): Use 'volatile' to avoid vfork clobbering. diff --git a/src/floatfns.c b/src/floatfns.c index 1232fc0afa1..5c286772864 100644 --- a/src/floatfns.c +++ b/src/floatfns.c @@ -491,27 +491,39 @@ DEFUN ("expt", Fexpt, Sexpt, 2, 2, 0, y = XINT (arg2); acc = 1; - if (y < 0) + if ((x == 0 && y != 0) || x == 1 || (x == -1 && (y & 1))) + return arg1; + if (x == -1) + y = 0; + + while (1) { - if (x == 1) - acc = 1; - else if (x == -1) - acc = (y & 1) ? -1 : 1; - else - acc = 0; - } - else - { - while (y > 0) + if (y & 1) { - if (y & 1) - acc *= x; - x *= x; - y = (unsigned)y >> 1; + if (x < 0 + ? (acc < 0 + ? acc < MOST_POSITIVE_FIXNUM / x + : MOST_NEGATIVE_FIXNUM / x < acc) + : (acc < 0 + ? acc < MOST_NEGATIVE_FIXNUM / x + : MOST_POSITIVE_FIXNUM / x < acc)) + break; + acc *= x; } + + y >>= 1; + if (y == 0) + { + XSETINT (val, acc); + return val; + } + + if (x < 0 + ? x < MOST_POSITIVE_FIXNUM / x + : MOST_POSITIVE_FIXNUM / x < x) + break; + x *= x; } - XSETINT (val, acc); - return val; } f1 = FLOATP (arg1) ? XFLOAT_DATA (arg1) : XINT (arg1); f2 = FLOATP (arg2) ? XFLOAT_DATA (arg2) : XINT (arg2); From 680186416d09efb9c3b4599ee848e3bb9fe184b6 Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Tue, 3 May 2011 09:33:36 -0700 Subject: [PATCH 28/38] [etc/ChangeLog] * NEWS: Integer overflow now yields floating-point instead of wrapping around. [doc/lispref/ChangeLog] * numbers.texi (Arithmetic Operations, Math Functions): Large integers go to floats instead of wrapping around. * objects.texi (Integer Type): Likewise. --- doc/lispref/ChangeLog | 3 +++ doc/lispref/numbers.texi | 12 ++++++------ doc/lispref/objects.texi | 11 ++++++----- etc/ChangeLog | 5 +++++ etc/NEWS | 6 ++++++ 5 files changed, 26 insertions(+), 11 deletions(-) diff --git a/doc/lispref/ChangeLog b/doc/lispref/ChangeLog index 163de31f220..a48fa634cb7 100644 --- a/doc/lispref/ChangeLog +++ b/doc/lispref/ChangeLog @@ -1,6 +1,9 @@ 2011-05-03 Paul Eggert * numbers.texi (Integer Basics): Large integers are treated as floats. + (Arithmetic Operations, Math Functions): Large integers go to + floats instead of wrapping around. + * objects.texi (Integer Type): Likewise. 2011-04-30 Lars Magne Ingebrigtsen diff --git a/doc/lispref/numbers.texi b/doc/lispref/numbers.texi index 2c73a03a26c..ebf5660febe 100644 --- a/doc/lispref/numbers.texi +++ b/doc/lispref/numbers.texi @@ -507,9 +507,9 @@ commonly used. All of these functions except @code{%} return a floating point value if any argument is floating. - It is important to note that in Emacs Lisp, arithmetic functions -do not check for overflow. Thus @code{(1+ 268435455)} may evaluate to -@minus{}268435456, depending on your hardware. + If integer arithmetic overflows, the resulting value is converted +to floating point. Thus @code{(1+ 536870911)} may evaluate to +536870912.0, depending on your hardware. @defun 1+ number-or-marker This function returns @var{number-or-marker} plus 1. @@ -826,7 +826,7 @@ On the other hand, shifting one place to the right looks like this: As the example illustrates, shifting one place to the right divides the value of a positive integer by two, rounding downward. -The function @code{lsh}, like all Emacs Lisp arithmetic functions, does +The function @code{lsh} does not check for overflow, so shifting left can discard significant bits and change the sign of the number. For example, left shifting 536,870,911 produces @minus{}2 on a 30-bit machine: @@ -1169,8 +1169,8 @@ approximately. @defun expt x y This function returns @var{x} raised to power @var{y}. If both -arguments are integers and @var{y} is positive, the result is an -integer; in this case, overflow causes truncation, so watch out. +arguments are integers and @var{y} is nonnegative, the result is an +integer if it is in Emacs integer range. @end defun @defun sqrt arg diff --git a/doc/lispref/objects.texi b/doc/lispref/objects.texi index c58d54f13fc..6dd7878e53b 100644 --- a/doc/lispref/objects.texi +++ b/doc/lispref/objects.texi @@ -179,10 +179,10 @@ to @tex @math{2^{29}-1}) @end tex -on most machines. (Some machines may provide a wider range.) It is -important to note that the Emacs Lisp arithmetic functions do not check -for overflow. Thus @code{(1+ 536870911)} is @minus{}536870912 on most -machines. +on most machines. (Some machines may provide a wider range.) +If integer arithmetic overflows, the resulting value is converted ++to floating point. Thus @code{(1+ 536870911)} may evaluate to ++536870912.0, depending on your hardware. The read syntax for integers is a sequence of (base ten) digits with an optional sign at the beginning and an optional period at the end. The @@ -195,7 +195,8 @@ leading @samp{+} or a final @samp{.}. 1 ; @r{The integer 1.} 1. ; @r{Also the integer 1.} +1 ; @r{Also the integer 1.} -1073741825 ; @r{Also the integer 1 on a 30-bit implementation.} +1073741825 ; @r{The floating point number 1073741825.0,} + ; @r{on a 30-bit implementation.} @end group @end example diff --git a/etc/ChangeLog b/etc/ChangeLog index 0eb21406105..bd91ccc1c39 100644 --- a/etc/ChangeLog +++ b/etc/ChangeLog @@ -1,3 +1,8 @@ +2011-05-03 Paul Eggert + + * NEWS: Integer overflow now yields floating-point instead of + wrapping around. + 2011-05-03 Leo Liu * NEWS: Mention the new command isearch-yank-pop. diff --git a/etc/NEWS b/etc/NEWS index 5094ecfc4fc..669c143ba7f 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -728,6 +728,12 @@ soap-inspect.el is an interactive inspector for SOAP WSDL structures. * Incompatible Lisp Changes in Emacs 24.1 ++++ +** Integer arithmetic overflow now yields the nearest floating-piont +value rather than wrapping around. For example, on a 32-bit machine, +(1+ 536870911) yields 536870912.0, instead of the -536870912 it +yielded in Emacs 23.3, or the 0 it yielded in Emacs 23.1. + --- ** `char-direction-table' and the associated function `char-direction' were deleted. They were buggy and inferior to the new support of From 59dba0f4d83541ca638492d137db7723d47faa1e Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Tue, 3 May 2011 11:57:49 -0700 Subject: [PATCH 29/38] Add Bug#. --- doc/lispref/ChangeLog | 2 +- etc/ChangeLog | 2 +- src/ChangeLog | 1 + 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/doc/lispref/ChangeLog b/doc/lispref/ChangeLog index a48fa634cb7..bca76b8a23c 100644 --- a/doc/lispref/ChangeLog +++ b/doc/lispref/ChangeLog @@ -3,7 +3,7 @@ * numbers.texi (Integer Basics): Large integers are treated as floats. (Arithmetic Operations, Math Functions): Large integers go to floats instead of wrapping around. - * objects.texi (Integer Type): Likewise. + * objects.texi (Integer Type): Likewise. (Bug#8611) 2011-04-30 Lars Magne Ingebrigtsen diff --git a/etc/ChangeLog b/etc/ChangeLog index bd91ccc1c39..bba73855d6e 100644 --- a/etc/ChangeLog +++ b/etc/ChangeLog @@ -1,7 +1,7 @@ 2011-05-03 Paul Eggert * NEWS: Integer overflow now yields floating-point instead of - wrapping around. + wrapping around. (Bug#8611) 2011-05-03 Leo Liu diff --git a/src/ChangeLog b/src/ChangeLog index 26b3af3225c..0bcad1118b6 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,6 +1,7 @@ 2011-05-03 Paul Eggert Arithmetic overflows now return float rather than wrapping around. + (Bug#8611). * data.c: Include . (arith_driver): Use floating point if the accumulator would otherwise go out of EMACS_INT range. From 19548d0861ced228dd0598240a410bf6a720b59e Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Tue, 3 May 2011 23:11:49 -0700 Subject: [PATCH 30/38] * Makefile.in (GNULIB_TOOL_FLAG): Add --conditional-dependencies. This new gnulib-tool option saves 'configure' the trouble of checking for strtoull when strtoumax exists. --- ChangeLog | 6 ++ Makefile.in | 3 +- lib/gnulib.mk | 10 +++ lib/stdlib.in.h | 3 +- m4/gl-comp.m4 | 186 +++++++++++++++++++++++++++--------------------- m4/stdio_h.m4 | 4 +- 6 files changed, 126 insertions(+), 86 deletions(-) diff --git a/ChangeLog b/ChangeLog index 31e8c869e52..a9446476bc6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2011-05-04 Paul Eggert + + * Makefile.in (GNULIB_TOOL_FLAG): Add --conditional-dependencies. + This new gnulib-tool option saves 'configure' the trouble of + checking for strtoull when strtoumax exists. + 2011-04-29 Paul Eggert * configure.in (BITS_PER_LONG_LONG): New macro. diff --git a/Makefile.in b/Makefile.in index e5828b35199..180f7e5be16 100644 --- a/Makefile.in +++ b/Makefile.in @@ -335,7 +335,8 @@ GNULIB_MODULES = \ ignore-value intprops lstat mktime readlink \ socklen stdio strftime strtoumax symlink sys_stat GNULIB_TOOL_FLAGS = \ - --import --no-changelog --no-vc-files --makefile-name=gnulib.mk + --conditional-dependencies --import --no-changelog --no-vc-files \ + --makefile-name=gnulib.mk sync-from-gnulib: $(gnulib_srcdir) -cd $(srcdir)/m4 && cp $(DOS_gnulib_comp.m4) gnulib-comp.m4 cd $(srcdir) && \ diff --git a/lib/gnulib.mk b/lib/gnulib.mk index f686137d38d..faf89aaa0e6 100644 --- a/lib/gnulib.mk +++ b/lib/gnulib.mk @@ -96,7 +96,9 @@ EXTRA_libgnu_a_SOURCES += md5.c ## begin gnulib module dosname +if gl_GNULIB_ENABLED_dosname +endif EXTRA_DIST += dosname.h ## end gnulib module dosname @@ -157,8 +159,10 @@ EXTRA_libgnu_a_SOURCES += getopt.c getopt1.c ## begin gnulib module gettext-h +if gl_GNULIB_ENABLED_be453cec5eecf5731a274f2de7f2db36 libgnu_a_SOURCES += gettext.h +endif ## end gnulib module gettext-h ## begin gnulib module ignore-value @@ -245,7 +249,9 @@ EXTRA_libgnu_a_SOURCES += readlink.c ## begin gnulib module stat +if gl_GNULIB_ENABLED_stat +endif EXTRA_DIST += stat.c EXTRA_libgnu_a_SOURCES += stat.c @@ -576,7 +582,9 @@ EXTRA_libgnu_a_SOURCES += strftime.c ## begin gnulib module strtoull +if gl_GNULIB_ENABLED_strtoull +endif EXTRA_DIST += strtol.c strtoul.c strtoull.c EXTRA_libgnu_a_SOURCES += strtol.c strtoul.c strtoull.c @@ -847,8 +855,10 @@ EXTRA_DIST += unistd.in.h ## begin gnulib module verify +if gl_GNULIB_ENABLED_verify libgnu_a_SOURCES += verify.h +endif ## end gnulib module verify ## begin gnulib module warn-on-use diff --git a/lib/stdlib.in.h b/lib/stdlib.in.h index b9ada2cd1a8..7513553b672 100644 --- a/lib/stdlib.in.h +++ b/lib/stdlib.in.h @@ -81,8 +81,9 @@ struct random_data # endif #endif -#if (@GNULIB_MKSTEMP@ || @GNULIB_GETSUBOPT@ || defined GNULIB_POSIXCHECK) && ! defined __GLIBC__ && !((defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__) +#if (@GNULIB_MKSTEMP@ || @GNULIB_MKSTEMPS@ || @GNULIB_GETSUBOPT@ || defined GNULIB_POSIXCHECK) && ! defined __GLIBC__ && !((defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__) /* On MacOS X 10.3, only declares mkstemp. */ +/* On MacOS X 10.5, only declares mkstemps. */ /* On Cygwin 1.7.1, only declares getsubopt. */ /* But avoid namespace pollution on glibc systems and native Windows. */ # include diff --git a/m4/gl-comp.m4 b/m4/gl-comp.m4 index 3b7bdfc5673..4338f2036b1 100644 --- a/m4/gl-comp.m4 +++ b/m4/gl-comp.m4 @@ -84,87 +84,110 @@ AC_DEFUN([gl_INIT], m4_pushdef([gl_LIBSOURCES_DIR], []) gl_COMMON gl_source_base='lib' - # Code from module allocator: - # Code from module arg-nonnull: - # Code from module c++defs: - # Code from module careadlinkat: - AC_CHECK_FUNCS_ONCE([readlinkat]) - # Code from module crypto/md5: - gl_MD5 - # Code from module dosname: - # Code from module dtoastr: - AC_REQUIRE([gl_C99_STRTOLD]) - # Code from module extensions: - # Code from module filemode: - gl_FILEMODE - # Code from module getloadavg: - gl_GETLOADAVG([$gl_source_base]) - gl_STDLIB_MODULE_INDICATOR([getloadavg]) - # Code from module getopt-gnu: - gl_FUNC_GETOPT_GNU - gl_MODULE_INDICATOR_FOR_TESTS([getopt-gnu]) - # Code from module getopt-posix: - gl_FUNC_GETOPT_POSIX - # Code from module gettext-h: - AC_SUBST([LIBINTL]) - AC_SUBST([LTLIBINTL]) - # Code from module ignore-value: - AC_REQUIRE([AC_C_INLINE]) - # Code from module include_next: - # Code from module intprops: - # Code from module inttypes-incomplete: - gl_INTTYPES_INCOMPLETE - # Code from module lstat: - gl_FUNC_LSTAT - gl_SYS_STAT_MODULE_INDICATOR([lstat]) - # Code from module mktime: - gl_FUNC_MKTIME - gl_TIME_MODULE_INDICATOR([mktime]) - # Code from module multiarch: - gl_MULTIARCH - # Code from module readlink: - gl_FUNC_READLINK - gl_UNISTD_MODULE_INDICATOR([readlink]) - # Code from module socklen: - gl_TYPE_SOCKLEN_T - # Code from module ssize_t: - gt_TYPE_SSIZE_T - # Code from module stat: - gl_FUNC_STAT - gl_SYS_STAT_MODULE_INDICATOR([stat]) - # Code from module stdbool: - AM_STDBOOL_H - # Code from module stddef: - gl_STDDEF_H - # Code from module stdint: - gl_STDINT_H - # Code from module stdio: - gl_STDIO_H - # Code from module stdlib: - gl_STDLIB_H - # Code from module strftime: - gl_FUNC_GNU_STRFTIME - # Code from module strtoull: - gl_FUNC_STRTOULL - gl_STDLIB_MODULE_INDICATOR([strtoull]) - # Code from module strtoumax: - gl_FUNC_STRTOUMAX - gl_INTTYPES_MODULE_INDICATOR([strtoumax]) - # Code from module symlink: - gl_FUNC_SYMLINK - gl_UNISTD_MODULE_INDICATOR([symlink]) - # Code from module sys_stat: - gl_HEADER_SYS_STAT_H - AC_PROG_MKDIR_P - # Code from module time: - gl_HEADER_TIME_H - # Code from module time_r: - gl_TIME_R - gl_TIME_MODULE_INDICATOR([time_r]) - # Code from module unistd: - gl_UNISTD_H - # Code from module verify: - # Code from module warn-on-use: +AC_CHECK_FUNCS_ONCE([readlinkat]) +gl_MD5 +AC_REQUIRE([gl_C99_STRTOLD]) +gl_FILEMODE +gl_GETLOADAVG([$gl_source_base]) +gl_STDLIB_MODULE_INDICATOR([getloadavg]) +gl_FUNC_GETOPT_GNU +gl_MODULE_INDICATOR_FOR_TESTS([getopt-gnu]) +gl_FUNC_GETOPT_POSIX +AC_REQUIRE([AC_C_INLINE]) +gl_INTTYPES_INCOMPLETE +gl_FUNC_LSTAT +gl_SYS_STAT_MODULE_INDICATOR([lstat]) +gl_FUNC_MKTIME +gl_TIME_MODULE_INDICATOR([mktime]) +gl_MULTIARCH +gl_FUNC_READLINK +gl_UNISTD_MODULE_INDICATOR([readlink]) +gl_TYPE_SOCKLEN_T +gt_TYPE_SSIZE_T +AM_STDBOOL_H +gl_STDDEF_H +gl_STDINT_H +gl_STDIO_H +gl_STDLIB_H +gl_FUNC_GNU_STRFTIME +gl_FUNC_STRTOUMAX +gl_INTTYPES_MODULE_INDICATOR([strtoumax]) +gl_FUNC_SYMLINK +gl_UNISTD_MODULE_INDICATOR([symlink]) +gl_HEADER_SYS_STAT_H +AC_PROG_MKDIR_P +gl_HEADER_TIME_H +gl_TIME_R +gl_TIME_MODULE_INDICATOR([time_r]) +gl_UNISTD_H + gl_gnulib_enabled_dosname=false + gl_gnulib_enabled_be453cec5eecf5731a274f2de7f2db36=false + gl_gnulib_enabled_stat=false + gl_gnulib_enabled_strtoull=false + gl_gnulib_enabled_verify=false + func_gl_gnulib_m4code_dosname () + { + if ! $gl_gnulib_enabled_dosname; then + gl_gnulib_enabled_dosname=true + fi + } + func_gl_gnulib_m4code_be453cec5eecf5731a274f2de7f2db36 () + { + if ! $gl_gnulib_enabled_be453cec5eecf5731a274f2de7f2db36; then +AC_SUBST([LIBINTL]) +AC_SUBST([LTLIBINTL]) + gl_gnulib_enabled_be453cec5eecf5731a274f2de7f2db36=true + fi + } + func_gl_gnulib_m4code_stat () + { + if ! $gl_gnulib_enabled_stat; then +gl_FUNC_STAT +gl_SYS_STAT_MODULE_INDICATOR([stat]) + gl_gnulib_enabled_stat=true + if $condition; then + func_gl_gnulib_m4code_dosname + fi + fi + } + func_gl_gnulib_m4code_strtoull () + { + if ! $gl_gnulib_enabled_strtoull; then +gl_FUNC_STRTOULL +gl_STDLIB_MODULE_INDICATOR([strtoull]) + gl_gnulib_enabled_strtoull=true + fi + } + func_gl_gnulib_m4code_verify () + { + if ! $gl_gnulib_enabled_verify; then + gl_gnulib_enabled_verify=true + fi + } + if test $GNULIB_UNISTD_H_GETOPT = 1; then + func_gl_gnulib_m4code_be453cec5eecf5731a274f2de7f2db36 + fi + if test $REPLACE_LSTAT = 1; then + func_gl_gnulib_m4code_dosname + fi + if test $REPLACE_LSTAT = 1; then + func_gl_gnulib_m4code_stat + fi + if test $HAVE_READLINK = 0 || test $REPLACE_READLINK = 1; then + func_gl_gnulib_m4code_stat + fi + if test "$ac_cv_have_decl_strtoumax" != yes && test $ac_cv_func_strtoumax = no; then + func_gl_gnulib_m4code_verify + fi + if test "$ac_cv_have_decl_strtoumax" != yes && test $ac_cv_func_strtoumax = no && test $ac_cv_type_unsigned_long_long_int = yes; then + func_gl_gnulib_m4code_strtoull + fi + m4_pattern_allow([^gl_GNULIB_ENABLED_]) + AM_CONDITIONAL([gl_GNULIB_ENABLED_dosname], [$gl_gnulib_enabled_dosname]) + AM_CONDITIONAL([gl_GNULIB_ENABLED_be453cec5eecf5731a274f2de7f2db36], [$gl_gnulib_enabled_be453cec5eecf5731a274f2de7f2db36]) + AM_CONDITIONAL([gl_GNULIB_ENABLED_stat], [$gl_gnulib_enabled_stat]) + AM_CONDITIONAL([gl_GNULIB_ENABLED_strtoull], [$gl_gnulib_enabled_strtoull]) + AM_CONDITIONAL([gl_GNULIB_ENABLED_verify], [$gl_gnulib_enabled_verify]) # End of code from modules m4_ifval(gl_LIBSOURCES_LIST, [ m4_syscmd([test ! -d ]m4_defn([gl_LIBSOURCES_DIR])[ || @@ -211,6 +234,7 @@ changequote([, ])dnl AC_SUBST([gltests_WITNESS]) gl_module_indicator_condition=$gltests_WITNESS m4_pushdef([gl_MODULE_INDICATOR_CONDITION], [$gl_module_indicator_condition]) + m4_pattern_allow([^gl_GNULIB_ENABLED_]) m4_popdef([gl_MODULE_INDICATOR_CONDITION]) m4_ifval(gltests_LIBSOURCES_LIST, [ m4_syscmd([test ! -d ]m4_defn([gltests_LIBSOURCES_DIR])[ || diff --git a/m4/stdio_h.m4 b/m4/stdio_h.m4 index 8b013c2f352..a8326f3c349 100644 --- a/m4/stdio_h.m4 +++ b/m4/stdio_h.m4 @@ -1,4 +1,4 @@ -# stdio_h.m4 serial 36 +# stdio_h.m4 serial 37 dnl Copyright (C) 2007-2011 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, @@ -14,8 +14,6 @@ AC_DEFUN([gl_STDIO_H], dnl likely needs them. GNULIB_FSCANF=1 GNULIB_SCANF=1 - GNULIB_VFSCANF=1 - GNULIB_VSCANF=1 GNULIB_FGETC=1 GNULIB_GETC=1 GNULIB_GETCHAR=1 From e3601888f128801233a35cbff7031d9a58931d20 Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Tue, 3 May 2011 23:21:26 -0700 Subject: [PATCH 31/38] * term.c: Don't include , as does that. --- src/ChangeLog | 2 ++ src/term.c | 1 - 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/ChangeLog b/src/ChangeLog index f8135ee2ab0..87876ac9b8b 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,5 +1,7 @@ 2011-05-04 Paul Eggert + * term.c: Don't include , as does that. + Arithmetic overflows now return float rather than wrapping around. (Bug#8611). * data.c: Include . diff --git a/src/term.c b/src/term.c index 28709138a17..9d19b256308 100644 --- a/src/term.c +++ b/src/term.c @@ -26,7 +26,6 @@ along with GNU Emacs. If not, see . */ #include #include #include -#include #include #include "lisp.h" From 288b08c747644d42c1636c2b469f8c34836ccd35 Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Tue, 3 May 2011 23:24:29 -0700 Subject: [PATCH 32/38] * eval.c (verror): OK to create a string of up to MOST_POSITIVE_FIXNUM bytes. --- src/ChangeLog | 3 +++ src/eval.c | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/ChangeLog b/src/ChangeLog index 87876ac9b8b..9fac265ae48 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,5 +1,8 @@ 2011-05-04 Paul Eggert + * eval.c (verror): OK to create a string of up to MOST_POSITIVE_FIXNUM + bytes. + * term.c: Don't include , as does that. Arithmetic overflows now return float rather than wrapping around. diff --git a/src/eval.c b/src/eval.c index 0187cf96705..90ef02ef37b 100644 --- a/src/eval.c +++ b/src/eval.c @@ -1994,7 +1994,7 @@ verror (const char *m, va_list ap) { char buf[4000]; size_t size = sizeof buf; - size_t size_max = min (MOST_POSITIVE_FIXNUM, SIZE_MAX); + size_t size_max = min (MOST_POSITIVE_FIXNUM + 1, SIZE_MAX); size_t mlen = strlen (m); char *buffer = buf; size_t used; From c378da0b47eb8c26fc8da4d89e128ee3c73537de Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Wed, 4 May 2011 00:19:21 -0700 Subject: [PATCH 33/38] Use C99's va_copy to avoid undefined behavior on x86-64 GNU/Linux. --- ChangeLog | 4 +++ Makefile.in | 2 +- lib/gnulib.mk | 29 +++++++++++++++++- lib/stdarg.in.h | 36 +++++++++++++++++++++++ m4/gl-comp.m4 | 9 ++++++ m4/stdarg.m4 | 78 +++++++++++++++++++++++++++++++++++++++++++++++++ src/ChangeLog | 3 ++ src/eval.c | 5 +++- 8 files changed, 163 insertions(+), 3 deletions(-) create mode 100644 lib/stdarg.in.h create mode 100644 m4/stdarg.m4 diff --git a/ChangeLog b/ChangeLog index a9446476bc6..c1e774c2924 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,9 @@ 2011-05-04 Paul Eggert + Use C99's va_copy to avoid undefined behavior on x86-64 GNU/Linux. + * Makefile.in (GNULIB_MODULES): Add stdarg, for va_copy. + * lib/stdarg.in.h, m4/stdarg.m4: New files, from gnulib. + * Makefile.in (GNULIB_TOOL_FLAG): Add --conditional-dependencies. This new gnulib-tool option saves 'configure' the trouble of checking for strtoull when strtoumax exists. diff --git a/Makefile.in b/Makefile.in index 180f7e5be16..ba2926d2853 100644 --- a/Makefile.in +++ b/Makefile.in @@ -333,7 +333,7 @@ DOS_gnulib_comp.m4 = gl-comp.m4 GNULIB_MODULES = \ careadlinkat crypto/md5 dtoastr filemode getloadavg getopt-gnu \ ignore-value intprops lstat mktime readlink \ - socklen stdio strftime strtoumax symlink sys_stat + socklen stdarg stdio strftime strtoumax symlink sys_stat GNULIB_TOOL_FLAGS = \ --conditional-dependencies --import --no-changelog --no-vc-files \ --makefile-name=gnulib.mk diff --git a/lib/gnulib.mk b/lib/gnulib.mk index faf89aaa0e6..1466e430a4c 100644 --- a/lib/gnulib.mk +++ b/lib/gnulib.mk @@ -9,7 +9,7 @@ # the same distribution terms as the rest of that program. # # Generated by gnulib-tool. -# Reproduce by: gnulib-tool --import --dir=. --lib=libgnu --source-base=lib --m4-base=m4 --doc-base=doc --tests-base=tests --aux-dir=. --makefile-name=gnulib.mk --no-libtool --macro-prefix=gl --no-vc-files careadlinkat crypto/md5 dtoastr filemode getloadavg getopt-gnu ignore-value intprops lstat mktime readlink socklen stdio strftime strtoumax symlink sys_stat +# Reproduce by: gnulib-tool --import --dir=. --lib=libgnu --source-base=lib --m4-base=m4 --doc-base=doc --tests-base=tests --aux-dir=. --makefile-name=gnulib.mk --no-libtool --macro-prefix=gl --no-vc-files careadlinkat crypto/md5 dtoastr filemode getloadavg getopt-gnu ignore-value intprops lstat mktime readlink socklen stdarg stdio strftime strtoumax symlink sys_stat MOSTLYCLEANFILES += core *.stackdump @@ -258,6 +258,33 @@ EXTRA_libgnu_a_SOURCES += stat.c ## end gnulib module stat +## begin gnulib module stdarg + +BUILT_SOURCES += $(STDARG_H) + +# We need the following in order to create when the system +# doesn't have one that works with the given compiler. +if GL_GENERATE_STDARG_H +stdarg.h: stdarg.in.h $(top_builddir)/config.status + $(AM_V_GEN)rm -f $@-t $@ && \ + { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */' && \ + sed -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \ + -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \ + -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \ + -e 's|@''NEXT_STDARG_H''@|$(NEXT_STDARG_H)|g' \ + < $(srcdir)/stdarg.in.h; \ + } > $@-t && \ + mv $@-t $@ +else +stdarg.h: $(top_builddir)/config.status + rm -f $@ +endif +MOSTLYCLEANFILES += stdarg.h stdarg.h-t + +EXTRA_DIST += stdarg.in.h + +## end gnulib module stdarg + ## begin gnulib module stdbool BUILT_SOURCES += $(STDBOOL_H) diff --git a/lib/stdarg.in.h b/lib/stdarg.in.h new file mode 100644 index 00000000000..4469d54e4f4 --- /dev/null +++ b/lib/stdarg.in.h @@ -0,0 +1,36 @@ +/* Substitute for and wrapper around . + Copyright (C) 2008-2011 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#ifndef _GL_STDARG_H + +#if __GNUC__ >= 3 +@PRAGMA_SYSTEM_HEADER@ +#endif +@PRAGMA_COLUMNS@ + +/* The include_next requires a split double-inclusion guard. */ +#@INCLUDE_NEXT@ @NEXT_STDARG_H@ + +#ifndef _GL_STDARG_H +#define _GL_STDARG_H + +#ifndef va_copy +# define va_copy(a,b) ((a) = (b)) +#endif + +#endif /* _GL_STDARG_H */ +#endif /* _GL_STDARG_H */ diff --git a/m4/gl-comp.m4 b/m4/gl-comp.m4 index 4338f2036b1..87d7616f8bb 100644 --- a/m4/gl-comp.m4 +++ b/m4/gl-comp.m4 @@ -51,6 +51,12 @@ AC_DEFUN([gl_EARLY], # Code from module socklen: # Code from module ssize_t: # Code from module stat: + # Code from module stdarg: + dnl Some compilers (e.g., AIX 5.3 cc) need to be in c99 mode + dnl for the builtin va_copy to work. With Autoconf 2.60 or later, + dnl AC_PROG_CC_STDC arranges for this. With older Autoconf AC_PROG_CC_STDC + dnl shouldn't hurt, though installers are on their own to set c99 mode. + AC_REQUIRE([AC_PROG_CC_STDC]) # Code from module stdbool: # Code from module stddef: # Code from module stdint: @@ -104,6 +110,7 @@ gl_FUNC_READLINK gl_UNISTD_MODULE_INDICATOR([readlink]) gl_TYPE_SOCKLEN_T gt_TYPE_SSIZE_T +gl_STDARG_H AM_STDBOOL_H gl_STDDEF_H gl_STDINT_H @@ -358,6 +365,7 @@ AC_DEFUN([gl_FILE_LIST], [ lib/mktime.c lib/readlink.c lib/stat.c + lib/stdarg.in.h lib/stdbool.in.h lib/stddef.in.h lib/stdint.in.h @@ -395,6 +403,7 @@ AC_DEFUN([gl_FILE_LIST], [ m4/ssize_t.m4 m4/st_dm_mode.m4 m4/stat.m4 + m4/stdarg.m4 m4/stdbool.m4 m4/stddef_h.m4 m4/stdint.m4 diff --git a/m4/stdarg.m4 b/m4/stdarg.m4 new file mode 100644 index 00000000000..5705de9ecaa --- /dev/null +++ b/m4/stdarg.m4 @@ -0,0 +1,78 @@ +# stdarg.m4 serial 6 +dnl Copyright (C) 2006, 2008-2011 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +dnl From Bruno Haible. +dnl Provide a working va_copy in combination with . + +AC_DEFUN([gl_STDARG_H], +[ + STDARG_H='' + NEXT_STDARG_H='' + AC_MSG_CHECKING([for va_copy]) + AC_CACHE_VAL([gl_cv_func_va_copy], [ + AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM( + [[#include ]], + [[ +#ifndef va_copy +void (*func) (va_list, va_list) = va_copy; +#endif + ]])], + [gl_cv_func_va_copy=yes], + [gl_cv_func_va_copy=no])]) + AC_MSG_RESULT([$gl_cv_func_va_copy]) + if test $gl_cv_func_va_copy = no; then + dnl Provide a substitute. + dnl Usually a simple definition in is enough. Not so on AIX 5 + dnl with some versions of the /usr/vac/bin/cc compiler. It has an + dnl which does '#undef va_copy', leading to a missing va_copy symbol. For + dnl this platform, we use an substitute. But we cannot use this + dnl approach on other platforms, because often defines only + dnl preprocessor macros and gl_ABSOLUTE_HEADER, gl_CHECK_NEXT_HEADERS do + dnl not work in this situation. + AC_EGREP_CPP([vaccine], + [#if defined _AIX && !defined __GNUC__ + AIX vaccine + #endif + ], [gl_aixcc=yes], [gl_aixcc=no]) + if test $gl_aixcc = yes; then + dnl Provide a substitute file. + STDARG_H=stdarg.h + gl_NEXT_HEADERS([stdarg.h]) + dnl Fallback for the case when contains only macro definitions. + if test "$gl_cv_next_stdarg_h" = '""'; then + gl_cv_next_stdarg_h='"///usr/include/stdarg.h"' + NEXT_STDARG_H="$gl_cv_next_stdarg_h" + fi + else + dnl Provide a substitute in , either __va_copy or as a simple + dnl assignment. + gl_CACHE_VAL_SILENT([gl_cv_func___va_copy], [ + AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM( + [[#include ]], + [[ +#ifndef __va_copy +error, bail out +#endif + ]])], + [gl_cv_func___va_copy=yes], + [gl_cv_func___va_copy=no])]) + if test $gl_cv_func___va_copy = yes; then + AC_DEFINE([va_copy], [__va_copy], + [Define as a macro for copying va_list variables.]) + else + AH_VERBATIM([gl_VA_COPY], [/* A replacement for va_copy, if needed. */ +#define gl_va_copy(a,b) ((a) = (b))]) + AC_DEFINE([va_copy], [gl_va_copy], + [Define as a macro for copying va_list variables.]) + fi + fi + fi + AC_SUBST([STDARG_H]) + AM_CONDITIONAL([GL_GENERATE_STDARG_H], [test -n "$STDARG_H"]) + AC_SUBST([NEXT_STDARG_H]) +]) diff --git a/src/ChangeLog b/src/ChangeLog index 9fac265ae48..a1aa19e6f2e 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,5 +1,8 @@ 2011-05-04 Paul Eggert + Use C99's va_copy to avoid undefined behavior on x86-64 GNU/Linux. + * eval.c (verror): doprnt a copy of ap, not the original. (Bug#8545) + * eval.c (verror): OK to create a string of up to MOST_POSITIVE_FIXNUM bytes. diff --git a/src/eval.c b/src/eval.c index 90ef02ef37b..6b4182cb319 100644 --- a/src/eval.c +++ b/src/eval.c @@ -2002,7 +2002,10 @@ verror (const char *m, va_list ap) while (1) { - used = doprnt (buffer, size, m, m + mlen, ap); + va_list ap_copy; + va_copy (ap_copy, ap); + used = doprnt (buffer, size, m, m + mlen, ap_copy); + va_end (ap_copy); /* Note: the -1 below is because `doprnt' returns the number of bytes excluding the terminating null byte, and it always terminates with a From aab2b9b5abaa4862b2814929c31035e7920f5e21 Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Wed, 4 May 2011 00:20:46 -0700 Subject: [PATCH 34/38] * term.c (vfatal): Remove stray call to va_end. It's not needed and the C Standard doesn't allow it here anyway. --- src/ChangeLog | 3 +++ src/term.c | 1 - 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/ChangeLog b/src/ChangeLog index a1aa19e6f2e..c0d81fc1248 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,5 +1,8 @@ 2011-05-04 Paul Eggert + * term.c (vfatal): Remove stray call to va_end. + It's not needed and the C Standard doesn't allow it here anyway. + Use C99's va_copy to avoid undefined behavior on x86-64 GNU/Linux. * eval.c (verror): doprnt a copy of ap, not the original. (Bug#8545) diff --git a/src/term.c b/src/term.c index 9d19b256308..c68228cc51a 100644 --- a/src/term.c +++ b/src/term.c @@ -3618,7 +3618,6 @@ vfatal (const char *str, va_list ap) vfprintf (stderr, str, ap); if (!(strlen (str) > 0 && str[strlen (str) - 1] == '\n')) fprintf (stderr, "\n"); - va_end (ap); fflush (stderr); exit (1); } From c717b32678affe3864f0d5024a9de514c950214d Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Wed, 4 May 2011 23:31:14 -0700 Subject: [PATCH 35/38] Revert to wraparound integer arithmetic, instead of going to float. --- doc/lispref/ChangeLog | 3 - doc/lispref/numbers.texi | 12 ++-- doc/lispref/objects.texi | 11 ++-- etc/ChangeLog | 5 -- etc/NEWS | 6 -- src/ChangeLog | 10 ---- src/bytecode.c | 6 +- src/data.c | 126 ++++++++++++++------------------------- src/floatfns.c | 50 ++++++---------- 9 files changed, 79 insertions(+), 150 deletions(-) diff --git a/doc/lispref/ChangeLog b/doc/lispref/ChangeLog index bca76b8a23c..163de31f220 100644 --- a/doc/lispref/ChangeLog +++ b/doc/lispref/ChangeLog @@ -1,9 +1,6 @@ 2011-05-03 Paul Eggert * numbers.texi (Integer Basics): Large integers are treated as floats. - (Arithmetic Operations, Math Functions): Large integers go to - floats instead of wrapping around. - * objects.texi (Integer Type): Likewise. (Bug#8611) 2011-04-30 Lars Magne Ingebrigtsen diff --git a/doc/lispref/numbers.texi b/doc/lispref/numbers.texi index ebf5660febe..2c73a03a26c 100644 --- a/doc/lispref/numbers.texi +++ b/doc/lispref/numbers.texi @@ -507,9 +507,9 @@ commonly used. All of these functions except @code{%} return a floating point value if any argument is floating. - If integer arithmetic overflows, the resulting value is converted -to floating point. Thus @code{(1+ 536870911)} may evaluate to -536870912.0, depending on your hardware. + It is important to note that in Emacs Lisp, arithmetic functions +do not check for overflow. Thus @code{(1+ 268435455)} may evaluate to +@minus{}268435456, depending on your hardware. @defun 1+ number-or-marker This function returns @var{number-or-marker} plus 1. @@ -826,7 +826,7 @@ On the other hand, shifting one place to the right looks like this: As the example illustrates, shifting one place to the right divides the value of a positive integer by two, rounding downward. -The function @code{lsh} does +The function @code{lsh}, like all Emacs Lisp arithmetic functions, does not check for overflow, so shifting left can discard significant bits and change the sign of the number. For example, left shifting 536,870,911 produces @minus{}2 on a 30-bit machine: @@ -1169,8 +1169,8 @@ approximately. @defun expt x y This function returns @var{x} raised to power @var{y}. If both -arguments are integers and @var{y} is nonnegative, the result is an -integer if it is in Emacs integer range. +arguments are integers and @var{y} is positive, the result is an +integer; in this case, overflow causes truncation, so watch out. @end defun @defun sqrt arg diff --git a/doc/lispref/objects.texi b/doc/lispref/objects.texi index 6dd7878e53b..c58d54f13fc 100644 --- a/doc/lispref/objects.texi +++ b/doc/lispref/objects.texi @@ -179,10 +179,10 @@ to @tex @math{2^{29}-1}) @end tex -on most machines. (Some machines may provide a wider range.) -If integer arithmetic overflows, the resulting value is converted -+to floating point. Thus @code{(1+ 536870911)} may evaluate to -+536870912.0, depending on your hardware. +on most machines. (Some machines may provide a wider range.) It is +important to note that the Emacs Lisp arithmetic functions do not check +for overflow. Thus @code{(1+ 536870911)} is @minus{}536870912 on most +machines. The read syntax for integers is a sequence of (base ten) digits with an optional sign at the beginning and an optional period at the end. The @@ -195,8 +195,7 @@ leading @samp{+} or a final @samp{.}. 1 ; @r{The integer 1.} 1. ; @r{Also the integer 1.} +1 ; @r{Also the integer 1.} -1073741825 ; @r{The floating point number 1073741825.0,} - ; @r{on a 30-bit implementation.} +1073741825 ; @r{Also the integer 1 on a 30-bit implementation.} @end group @end example diff --git a/etc/ChangeLog b/etc/ChangeLog index bba73855d6e..0eb21406105 100644 --- a/etc/ChangeLog +++ b/etc/ChangeLog @@ -1,8 +1,3 @@ -2011-05-03 Paul Eggert - - * NEWS: Integer overflow now yields floating-point instead of - wrapping around. (Bug#8611) - 2011-05-03 Leo Liu * NEWS: Mention the new command isearch-yank-pop. diff --git a/etc/NEWS b/etc/NEWS index 669c143ba7f..5094ecfc4fc 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -728,12 +728,6 @@ soap-inspect.el is an interactive inspector for SOAP WSDL structures. * Incompatible Lisp Changes in Emacs 24.1 -+++ -** Integer arithmetic overflow now yields the nearest floating-piont -value rather than wrapping around. For example, on a 32-bit machine, -(1+ 536870911) yields 536870912.0, instead of the -536870912 it -yielded in Emacs 23.3, or the 0 it yielded in Emacs 23.1. - --- ** `char-direction-table' and the associated function `char-direction' were deleted. They were buggy and inferior to the new support of diff --git a/src/ChangeLog b/src/ChangeLog index ee2db310562..2b4f498a0b9 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -11,16 +11,6 @@ * term.c: Don't include , as does that. - Arithmetic overflows now return float rather than wrapping around. - (Bug#8611). - * data.c: Include . - (arith_driver): Use floating point if the accumulator would otherwise - go out of EMACS_INT range. - (arith_driver, Fadd1, Fsub1): Use floating point if the result is - out of Emacs fixnum range. - * bytecode.c (exec_byte_code): Likewise, for Bsub1, Badd1, Bnegate. - * floatfns.c (Fexpt): Likewise. - * callproc.c (Fcall_process): Use 'volatile' to avoid vfork clobbering. * process.c (Fformat_network_address): Fix typo: args2 -> *args2. diff --git a/src/bytecode.c b/src/bytecode.c index ce79b011bbb..c3cd3d43072 100644 --- a/src/bytecode.c +++ b/src/bytecode.c @@ -1186,7 +1186,7 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth, { Lisp_Object v1; v1 = TOP; - if (INTEGERP (v1) && MOST_NEGATIVE_FIXNUM < XINT (v1)) + if (INTEGERP (v1)) { XSETINT (v1, XINT (v1) - 1); TOP = v1; @@ -1204,7 +1204,7 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth, { Lisp_Object v1; v1 = TOP; - if (INTEGERP (v1) && XINT (v1) < MOST_POSITIVE_FIXNUM) + if (INTEGERP (v1)) { XSETINT (v1, XINT (v1) + 1); TOP = v1; @@ -1290,7 +1290,7 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth, { Lisp_Object v1; v1 = TOP; - if (INTEGERP (v1) && - MOST_POSITIVE_FIXNUM <= XINT (v1)) + if (INTEGERP (v1)) { XSETINT (v1, - XINT (v1)); TOP = v1; diff --git a/src/data.c b/src/data.c index beff570d552..577ae777d89 100644 --- a/src/data.c +++ b/src/data.c @@ -22,9 +22,6 @@ along with GNU Emacs. If not, see . */ #include #include #include - -#include - #include "lisp.h" #include "puresize.h" #include "character.h" @@ -2429,8 +2426,10 @@ static Lisp_Object float_arith_driver (double, size_t, enum arithop, static Lisp_Object arith_driver (enum arithop code, size_t nargs, register Lisp_Object *args) { + register Lisp_Object val; register size_t argnum; register EMACS_INT accum = 0; + register EMACS_INT next; switch (SWITCH_ENUM_CAST (code)) { @@ -2452,89 +2451,58 @@ arith_driver (enum arithop code, size_t nargs, register Lisp_Object *args) for (argnum = 0; argnum < nargs; argnum++) { - EMACS_INT a = accum; - int use_float = 0; - /* Using args[argnum] as argument to CHECK_NUMBER_... */ - Lisp_Object val = args[argnum]; + val = args[argnum]; CHECK_NUMBER_OR_FLOAT_COERCE_MARKER (val); - args[argnum] = val; if (FLOATP (val)) - use_float = 1; - else + return float_arith_driver ((double) accum, argnum, code, + nargs, args); + args[argnum] = val; + next = XINT (args[argnum]); + switch (SWITCH_ENUM_CAST (code)) { - EMACS_INT next = XINT (val); - switch (SWITCH_ENUM_CAST (code)) + case Aadd: + accum += next; + break; + case Asub: + accum = argnum ? accum - next : nargs == 1 ? - next : next; + break; + case Amult: + accum *= next; + break; + case Adiv: + if (!argnum) + accum = next; + else { - case Aadd: - if (next < 0 - ? a < TYPE_MINIMUM (EMACS_INT) - next - : TYPE_MAXIMUM (EMACS_INT) - next < a) - use_float = 1; - else - a += next; - break; - case Asub: - if (argnum == 0 && nargs != 1) - a = next; - else if (next < 0 - ? TYPE_MAXIMUM (EMACS_INT) + next < a - : a < TYPE_MINIMUM (EMACS_INT) + next) - use_float = 1; - else - a -= next; - break; - case Amult: - if (next < 0 - ? (a < 0 - ? a < TYPE_MAXIMUM (EMACS_INT) / next - : next != -1 && TYPE_MINIMUM (EMACS_INT) / next < a) - : (next != 0 - && (a < 0 - ? a < TYPE_MINIMUM (EMACS_INT) / next - : TYPE_MAXIMUM (EMACS_INT) / next < a))) - use_float = 1; - else - a *= next; - break; - case Adiv: - if (!argnum) - a = next; - else - { - if (next == 0) - xsignal0 (Qarith_error); - a /= next; - } - break; - case Alogand: - a &= next; - break; - case Alogior: - a |= next; - break; - case Alogxor: - a ^= next; - break; - case Amax: - if (!argnum || a < next) - a = next; - break; - case Amin: - if (!argnum || next < a) - a = next; - break; + if (next == 0) + xsignal0 (Qarith_error); + accum /= next; } + break; + case Alogand: + accum &= next; + break; + case Alogior: + accum |= next; + break; + case Alogxor: + accum ^= next; + break; + case Amax: + if (!argnum || next > accum) + accum = next; + break; + case Amin: + if (!argnum || next < accum) + accum = next; + break; } - - if (use_float) - return float_arith_driver (accum, argnum, code, nargs, args); - - accum = a; } - return make_fixnum_or_float (accum); + XSETINT (val, accum); + return val; } #undef isnan @@ -2809,8 +2777,7 @@ Markers are converted to integers. */) if (FLOATP (number)) return (make_float (1.0 + XFLOAT_DATA (number))); - if (XINT (number) + 1 == MOST_POSITIVE_FIXNUM + 1) - return make_float (XINT (number) + 1); + XSETINT (number, XINT (number) + 1); return number; } @@ -2824,8 +2791,7 @@ Markers are converted to integers. */) if (FLOATP (number)) return (make_float (-1.0 + XFLOAT_DATA (number))); - if (XINT (number) - 1 == MOST_NEGATIVE_FIXNUM - 1) - return make_float (XINT (number) - 1); + XSETINT (number, XINT (number) - 1); return number; } diff --git a/src/floatfns.c b/src/floatfns.c index 5c286772864..1232fc0afa1 100644 --- a/src/floatfns.c +++ b/src/floatfns.c @@ -491,39 +491,27 @@ DEFUN ("expt", Fexpt, Sexpt, 2, 2, 0, y = XINT (arg2); acc = 1; - if ((x == 0 && y != 0) || x == 1 || (x == -1 && (y & 1))) - return arg1; - if (x == -1) - y = 0; - - while (1) + if (y < 0) { - if (y & 1) - { - if (x < 0 - ? (acc < 0 - ? acc < MOST_POSITIVE_FIXNUM / x - : MOST_NEGATIVE_FIXNUM / x < acc) - : (acc < 0 - ? acc < MOST_NEGATIVE_FIXNUM / x - : MOST_POSITIVE_FIXNUM / x < acc)) - break; - acc *= x; - } - - y >>= 1; - if (y == 0) - { - XSETINT (val, acc); - return val; - } - - if (x < 0 - ? x < MOST_POSITIVE_FIXNUM / x - : MOST_POSITIVE_FIXNUM / x < x) - break; - x *= x; + if (x == 1) + acc = 1; + else if (x == -1) + acc = (y & 1) ? -1 : 1; + else + acc = 0; } + else + { + while (y > 0) + { + if (y & 1) + acc *= x; + x *= x; + y = (unsigned)y >> 1; + } + } + XSETINT (val, acc); + return val; } f1 = FLOATP (arg1) ? XFLOAT_DATA (arg1) : XINT (arg1); f2 = FLOATP (arg2) ? XFLOAT_DATA (arg2) : XINT (arg2); From 4c4b566b11106e0dd4767340e6e7e0fc89cfd589 Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Thu, 5 May 2011 00:23:07 -0700 Subject: [PATCH 36/38] * image.c (Finit_image_library) [!HAVE_NTGUI]: Omit unused local. --- src/ChangeLog | 2 ++ src/image.c | 4 +--- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/ChangeLog b/src/ChangeLog index 2b4f498a0b9..755b02631f6 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,5 +1,7 @@ 2011-05-05 Paul Eggert + * image.c (Finit_image_library) [!HAVE_NTGUI]: Omit unused local. + * term.c (vfatal): Remove stray call to va_end. It's not needed and the C Standard doesn't allow it here anyway. diff --git a/src/image.c b/src/image.c index d78b556d8c9..4e0503ac1dc 100644 --- a/src/image.c +++ b/src/image.c @@ -8602,11 +8602,9 @@ Libraries to load are specified in alist LIBRARIES (usually, the value of `dynamic-library-alist', which see). */) (Lisp_Object type, Lisp_Object libraries) { - Lisp_Object tested; - #ifdef HAVE_NTGUI /* Don't try to reload the library. */ - tested = Fassq (type, Vlibrary_cache); + Lisp_Object tested = Fassq (type, Vlibrary_cache); if (CONSP (tested)) return XCDR (tested); #endif From 122b0c864338fa0c428b0ff2afbed2454dd2d1c7 Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Thu, 5 May 2011 22:55:01 -0700 Subject: [PATCH 37/38] Temporarily disable wider-than-pointer EMACS_INT. --- nt/ChangeLog | 6 ++++-- nt/config.nt | 8 ++++++++ src/ChangeLog | 2 ++ src/lisp.h | 6 +++++- 4 files changed, 19 insertions(+), 3 deletions(-) diff --git a/nt/ChangeLog b/nt/ChangeLog index f1f34bb88b5..83d13ce77c6 100644 --- a/nt/ChangeLog +++ b/nt/ChangeLog @@ -1,6 +1,8 @@ -2011-05-05 Paul Eggert +2011-05-06 Paul Eggert - * config.nt: Configure 64-bit integers for older compilers. + * config.nt: Prepare to configure 64-bit integers for older compilers. + However, temporarily disable this change unless the temporary + symbol WIDE_EMACS_INT is defined. (EMACS_INT, BITS_PER_EMACS_INT, pI): Define these if __int64 and "%I64d" work but long long and "%lld" do not. diff --git a/nt/config.nt b/nt/config.nt index b595e298996..55a8bccae19 100644 --- a/nt/config.nt +++ b/nt/config.nt @@ -480,11 +480,19 @@ extern char *getenv (); #elif _MSC_VER >= 1200 +/* Temporarily disable wider-than-pointer integers until they're tested more. + Build with CFLAGS='-DWIDE_EMACS_INT' to try them out. */ +/* #undef WIDE_EMACS_INT */ + +# ifdef WIDE_EMACS_INT + /* Use pre-C99-style 64-bit integers. */ # define EMACS_INT __int64 # define BITS_PER_EMACS_INT 64 # define pI "I64" +# endif + #endif #ifndef POINTER_TYPE diff --git a/src/ChangeLog b/src/ChangeLog index 755b02631f6..80baa5d131a 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -55,6 +55,8 @@ (EMACS_INT, EMACS_UINT, BITS_PER_EMACS_INT, pI): Define to 64-bit on 32-bit hosts that have 64-bit int, so that they can access large files. + However, temporarily disable this change unless the temporary + symbol WIDE_EMACS_INT is defined. * lread.c, process.c: Do not include ; lisp.h does it now. diff --git a/src/lisp.h b/src/lisp.h index bb3a8cc393c..66f5c962be8 100644 --- a/src/lisp.h +++ b/src/lisp.h @@ -34,9 +34,13 @@ extern void check_cons_list (void); #define CHECK_CONS_LIST() ((void) 0) #endif +/* Temporarily disable wider-than-pointer integers until they're tested more. + Build with CFLAGS='-DWIDE_EMACS_INT' to try them out. */ +/* #undef WIDE_EMACS_INT */ + /* These are default choices for the types to use. */ #ifndef EMACS_INT -# if BITS_PER_LONG < BITS_PER_LONG_LONG +# if BITS_PER_LONG < BITS_PER_LONG_LONG && defined WIDE_EMACS_INT # define EMACS_INT long long # define BITS_PER_EMACS_INT BITS_PER_LONG_LONG # define pI "ll" From 9991d78e8cd74e986a9b7625c12a43fbf7a283b3 Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Thu, 5 May 2011 23:03:30 -0700 Subject: [PATCH 38/38] Merge from gnulib. --- lib/verify.h | 130 +++++++++++++++++++++++++++++++-------------------- 1 file changed, 79 insertions(+), 51 deletions(-) diff --git a/lib/verify.h b/lib/verify.h index 6bca43f6a9b..e5065ffa00b 100644 --- a/lib/verify.h +++ b/lib/verify.h @@ -17,42 +17,37 @@ /* Written by Paul Eggert, Bruno Haible, and Jim Meyering. */ -#ifndef VERIFY_H -# define VERIFY_H 1 +#ifndef _GL_VERIFY_H +# define _GL_VERIFY_H -/* Define HAVE__STATIC_ASSERT to 1 if _Static_assert works as per the + +/* Define _GL_HAVE__STATIC_ASSERT to 1 if _Static_assert works as per the C1X draft N1548 section 6.7.10. This is supported by GCC 4.6.0 and later, in C mode, and its use here generates easier-to-read diagnostics when verify (R) fails. - Define HAVE_STATIC_ASSERT to 1 if static_assert works as per the - C1X draft N1548 section 7.2 or the C++0X draft N3242 section 7.(4). + Define _GL_HAVE_STATIC_ASSERT to 1 if static_assert works as per the + C++0X draft N3242 section 7.(4). This will likely be supported by future GCC versions, in C++ mode. - For now, use this only with GCC. Eventually whether _Static_assert - and static_assert works should be determined by 'configure'. */ + Use this only with GCC. If we were willing to slow 'configure' + down we could also use it with other compilers, but since this + affects only the quality of diagnostics, why bother? */ # if (4 < __GNUC__ || (__GNUC__ == 4 && 6 <= __GNUC_MINOR__)) && !defined __cplusplus -# define HAVE__STATIC_ASSERT 1 +# define _GL_HAVE__STATIC_ASSERT 1 # endif /* The condition (99 < __GNUC__) is temporary, until we know about the first G++ release that supports static_assert. */ # if (99 < __GNUC__) && defined __cplusplus -# define HAVE_STATIC_ASSERT 1 +# define _GL_HAVE_STATIC_ASSERT 1 # endif /* Each of these macros verifies that its argument R is nonzero. To be portable, R should be an integer constant expression. Unlike assert (R), there is no run-time overhead. - There are two macros, since no single macro can be used in all - contexts in C. verify_true (R) is for scalar contexts, including - integer constant expression contexts. verify (R) is for declaration - contexts, e.g., the top level. - - Symbols ending in "__" are private to this header. - If _Static_assert works, verify (R) uses it directly. Similarly, - verify_true (R) works by packaging a _Static_assert inside a struct + _GL_VERIFY_TRUE works by packaging a _Static_assert inside a struct that is an operand of sizeof. The code below uses several ideas for C++ compilers, and for C @@ -64,7 +59,9 @@ constant and nonnegative. * Next this expression W is wrapped in a type - struct verify_type__ { unsigned int verify_error_if_negative_size__: W; }. + struct _gl_verify_type { + unsigned int _gl_verify_error_if_negative: W; + }. If W is negative, this yields a compile-time error. No compiler can deal with a bit-field of negative size. @@ -78,7 +75,7 @@ void function (int n) { verify (n < 0); } - * For the verify macro, the struct verify_type__ will need to + * For the verify macro, the struct _gl_verify_type will need to somehow be embedded into a declaration. To be portable, this declaration must declare an object, a constant, a function, or a typedef name. If the declared entity uses the type directly, @@ -116,11 +113,11 @@ Which of the following alternatives can be used? extern int dummy [sizeof (struct {...})]; - extern int dummy [sizeof (struct verify_type__ {...})]; + extern int dummy [sizeof (struct _gl_verify_type {...})]; extern void dummy (int [sizeof (struct {...})]); - extern void dummy (int [sizeof (struct verify_type__ {...})]); + extern void dummy (int [sizeof (struct _gl_verify_type {...})]); extern int (*dummy (void)) [sizeof (struct {...})]; - extern int (*dummy (void)) [sizeof (struct verify_type__ {...})]; + extern int (*dummy (void)) [sizeof (struct _gl_verify_type {...})]; In the second and sixth case, the struct type is exported to the outer scope; two such declarations therefore collide. GCC warns @@ -159,44 +156,75 @@ possible. */ # define _GL_GENSYM(prefix) _GL_CONCAT (prefix, _GL_COUNTER) -/* Verify requirement R at compile-time, as an integer constant expression. - Return 1. */ +/* Verify requirement R at compile-time, as an integer constant expression + that returns 1. If R is false, fail at compile-time, preferably + with a diagnostic that includes the string-literal DIAGNOSTIC. */ + +# define _GL_VERIFY_TRUE(R, DIAGNOSTIC) \ + (!!sizeof (_GL_VERIFY_TYPE (R, DIAGNOSTIC))) # ifdef __cplusplus template - struct verify_type__ { unsigned int verify_error_if_negative_size__: w; }; -# define verify_true(R) \ - (!!sizeof (verify_type__<(R) ? 1 : -1>)) -# elif HAVE__STATIC_ASSERT -# define verify_true(R) \ - (!!sizeof \ - (struct { \ - _Static_assert (R, "verify_true (" #R ")"); \ - int verify_dummy__; \ - })) -# elif HAVE_STATIC_ASSERT -# define verify_true(R) \ - (!!sizeof \ - (struct { \ - static_assert (R, "verify_true (" #R ")"); \ - int verify_dummy__; \ - })) + struct _gl_verify_type { + unsigned int _gl_verify_error_if_negative: w; + }; +# define _GL_VERIFY_TYPE(R, DIAGNOSTIC) \ + _gl_verify_type<(R) ? 1 : -1> +# elif defined _GL_HAVE__STATIC_ASSERT +# define _GL_VERIFY_TYPE(R, DIAGNOSTIC) \ + struct { \ + _Static_assert (R, DIAGNOSTIC); \ + int _gl_dummy; \ + } # else -# define verify_true(R) \ - (!!sizeof \ - (struct { unsigned int verify_error_if_negative_size__: (R) ? 1 : -1; })) +# define _GL_VERIFY_TYPE(R, DIAGNOSTIC) \ + struct { unsigned int _gl_verify_error_if_negative: (R) ? 1 : -1; } # endif +/* Verify requirement R at compile-time, as a declaration without a + trailing ';'. If R is false, fail at compile-time, preferably + with a diagnostic that includes the string-literal DIAGNOSTIC. + + Unfortunately, unlike C1X, this implementation must appear as an + ordinary declaration, and cannot appear inside struct { ... }. */ + +# ifdef _GL_HAVE__STATIC_ASSERT +# define _GL_VERIFY _Static_assert +# else +# define _GL_VERIFY(R, DIAGNOSTIC) \ + extern int (*_GL_GENSYM (_gl_verify_function) (void)) \ + [_GL_VERIFY_TRUE (R, DIAGNOSTIC)] +# endif + +/* _GL_STATIC_ASSERT_H is defined if this code is copied into assert.h. */ +# ifdef _GL_STATIC_ASSERT_H +# if !defined _GL_HAVE__STATIC_ASSERT && !defined _Static_assert +# define _Static_assert(R, DIAGNOSTIC) _GL_VERIFY (R, DIAGNOSTIC) +# endif +# if !defined _GL_HAVE_STATIC_ASSERT && !defined static_assert +# define static_assert _Static_assert /* Draft C1X requires this #define. */ +# endif +# else + +/* Each of these macros verifies that its argument R is nonzero. To + be portable, R should be an integer constant expression. Unlike + assert (R), there is no run-time overhead. + + There are two macros, since no single macro can be used in all + contexts in C. verify_true (R) is for scalar contexts, including + integer constant expression contexts. verify (R) is for declaration + contexts, e.g., the top level. */ + +/* Verify requirement R at compile-time, as an integer constant expression. + Return 1. */ + +# define verify_true(R) _GL_VERIFY_TRUE (R, "verify_true (" #R ")") + /* Verify requirement R at compile-time, as a declaration without a trailing ';'. */ -# if HAVE__STATIC_ASSERT -# define verify(R) _Static_assert (R, "verify (" #R ")") -# elif HAVE_STATIC_ASSERT -# define verify(R) static_assert (R, "verify (" #R ")") -# else -# define verify(R) \ - extern int (* _GL_GENSYM (verify_function) (void)) [verify_true (R)] +# define verify(R) _GL_VERIFY (R, "verify (" #R ")") + # endif #endif