From ea204efb8a3e81a4d9b04d2a36cb8c2a1c74662c Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Sun, 12 Jun 2011 16:25:12 -0700 Subject: [PATCH] * lisp.h (UNSIGNED_CMP): New macro. This fixes comparison bugs on 64-bit hosts. (ASCII_CHAR_P): Use it. * casefiddle.c (casify_object): * character.h (ASCII_BYTE_P, CHAR_VALID_P): (SINGLE_BYTE_CHAR_P, CHAR_STRING): * composite.h (COMPOSITION_ENCODE_RULE_VALID): * dispextern.h (FACE_FROM_ID): * keyboard.c (read_char): Use UNSIGNED_CMP. --- src/ChangeLog | 12 ++++++++++++ src/casefiddle.c | 2 +- src/character.h | 12 ++++++------ src/composite.h | 2 +- src/dispextern.h | 2 +- src/keyboard.c | 8 ++++++-- src/lisp.h | 12 +++++++++++- 7 files changed, 38 insertions(+), 12 deletions(-) diff --git a/src/ChangeLog b/src/ChangeLog index 82fd3526785..cb3ed502c96 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,15 @@ +2011-06-12 Paul Eggert + + * lisp.h (UNSIGNED_CMP): New macro. + This fixes comparison bugs on 64-bit hosts. + (ASCII_CHAR_P): Use it. + * casefiddle.c (casify_object): + * character.h (ASCII_BYTE_P, CHAR_VALID_P): + (SINGLE_BYTE_CHAR_P, CHAR_STRING): + * composite.h (COMPOSITION_ENCODE_RULE_VALID): + * dispextern.h (FACE_FROM_ID): + * keyboard.c (read_char): Use UNSIGNED_CMP. + 2011-06-11 Paul Eggert * xmenu.c (dialog_selection_callback) [!USE_GTK]: Cast to intptr_t, diff --git a/src/casefiddle.c b/src/casefiddle.c index 9f286d73a5e..1a0a62f273c 100644 --- a/src/casefiddle.c +++ b/src/casefiddle.c @@ -52,7 +52,7 @@ casify_object (enum case_action flag, Lisp_Object obj) /* If the character has higher bits set above the flags, return it unchanged. It is not a real character. */ - if ((unsigned) XFASTINT (obj) > (unsigned) flagbits) + if (UNSIGNED_CMP (XFASTINT (obj), >, flagbits)) return obj; c1 = XFASTINT (obj) & ~flagbits; diff --git a/src/character.h b/src/character.h index 884833775de..695a55be3fa 100644 --- a/src/character.h +++ b/src/character.h @@ -102,13 +102,13 @@ along with GNU Emacs. If not, see . */ #define make_char(c) make_number (c) /* Nonzero iff C is an ASCII byte. */ -#define ASCII_BYTE_P(c) ((unsigned) (c) < 0x80) +#define ASCII_BYTE_P(c) UNSIGNED_CMP (c, <, 0x80) /* Nonzero iff X is a character. */ #define CHARACTERP(x) (NATNUMP (x) && XFASTINT (x) <= MAX_CHAR) /* Nonzero iff C is valid as a character code. GENERICP is not used. */ -#define CHAR_VALID_P(c, genericp) ((unsigned) (c) <= MAX_CHAR) +#define CHAR_VALID_P(c, genericp) UNSIGNED_CMP (c, <=, MAX_CHAR) /* Check if Lisp object X is a character or not. */ #define CHECK_CHARACTER(x) \ @@ -129,7 +129,7 @@ along with GNU Emacs. If not, see . */ } while (0) /* Nonzero iff C is a character of code less than 0x100. */ -#define SINGLE_BYTE_CHAR_P(c) ((unsigned) (c) < 0x100) +#define SINGLE_BYTE_CHAR_P(c) UNSIGNED_CMP (c, <, 0x100) /* Nonzero if character C has a printable glyph. */ #define CHAR_PRINTABLE_P(c) \ @@ -161,14 +161,14 @@ along with GNU Emacs. If not, see . */ Returns the length of the multibyte form. */ #define CHAR_STRING(c, p) \ - ((unsigned) (c) <= MAX_1_BYTE_CHAR \ + (UNSIGNED_CMP (c, <=, MAX_1_BYTE_CHAR) \ ? ((p)[0] = (c), \ 1) \ - : (unsigned) (c) <= MAX_2_BYTE_CHAR \ + : UNSIGNED_CMP (c, <=, MAX_2_BYTE_CHAR) \ ? ((p)[0] = (0xC0 | ((c) >> 6)), \ (p)[1] = (0x80 | ((c) & 0x3F)), \ 2) \ - : (unsigned) (c) <= MAX_3_BYTE_CHAR \ + : UNSIGNED_CMP (c, <=, MAX_3_BYTE_CHAR) \ ? ((p)[0] = (0xE0 | ((c) >> 12)), \ (p)[1] = (0x80 | (((c) >> 6) & 0x3F)), \ (p)[2] = (0x80 | ((c) & 0x3F)), \ diff --git a/src/composite.h b/src/composite.h index 0f81911f0b0..8cedfdbe352 100644 --- a/src/composite.h +++ b/src/composite.h @@ -151,7 +151,7 @@ extern Lisp_Object composition_temp; /* Nonzero if the global reference point GREF and new reference point NREF are valid. */ #define COMPOSITION_ENCODE_RULE_VALID(gref, nref) \ - ((unsigned) (gref) < 12 && (unsigned) (nref) < 12) + (UNSIGNED_CMP (gref, <, 12) && UNSIGNED_CMP (nref, <, 12)) /* Return encoded composition rule for the pair of global reference point GREF and new reference point NREF. Arguments must be valid. */ diff --git a/src/dispextern.h b/src/dispextern.h index 211a1b06659..75ebc462ce4 100644 --- a/src/dispextern.h +++ b/src/dispextern.h @@ -1729,7 +1729,7 @@ struct face_cache face doesn't exist. */ #define FACE_FROM_ID(F, ID) \ - (((unsigned) (ID) < FRAME_FACE_CACHE (F)->used) \ + (UNSIGNED_CMP (ID, <, FRAME_FACE_CACHE (F)->used) \ ? FRAME_FACE_CACHE (F)->faces_by_id[ID] \ : NULL) diff --git a/src/keyboard.c b/src/keyboard.c index 89483972a65..0bacc2fa28f 100644 --- a/src/keyboard.c +++ b/src/keyboard.c @@ -2906,9 +2906,13 @@ read_char (int commandflag, int nmaps, Lisp_Object *maps, Lisp_Object prev_event goto exit; if ((STRINGP (KVAR (current_kboard, Vkeyboard_translate_table)) - && SCHARS (KVAR (current_kboard, Vkeyboard_translate_table)) > (unsigned) XFASTINT (c)) + && UNSIGNED_CMP (XFASTINT (c), <, + SCHARS (KVAR (current_kboard, + Vkeyboard_translate_table)))) || (VECTORP (KVAR (current_kboard, Vkeyboard_translate_table)) - && ASIZE (KVAR (current_kboard, Vkeyboard_translate_table)) > (unsigned) XFASTINT (c)) + && UNSIGNED_CMP (XFASTINT (c), <, + ASIZE (KVAR (current_kboard, + Vkeyboard_translate_table)))) || (CHAR_TABLE_P (KVAR (current_kboard, Vkeyboard_translate_table)) && CHARACTERP (c))) { diff --git a/src/lisp.h b/src/lisp.h index 6003daee8fa..4dfed319490 100644 --- a/src/lisp.h +++ b/src/lisp.h @@ -911,8 +911,18 @@ struct Lisp_Vector #endif /* not __GNUC__ */ +/* Compute A OP B, using the unsigned comparison operator OP. A and B + should be integer expressions. This is not the same as + mathemeatical comparison; for example, UNSIGNED_CMP (0, <, -1) + returns 1. For efficiency, prefer plain unsigned comparison if A + and B's sizes both fit (after integer promotion). */ +#define UNSIGNED_CMP(a, op, b) \ + (max (sizeof ((a) + 0), sizeof ((b) + 0)) <= sizeof (unsigned) \ + ? ((a) + (unsigned) 0) op ((b) + (unsigned) 0) \ + : ((a) + (uintmax_t) 0) op ((b) + (uintmax_t) 0)) + /* Nonzero iff C is an ASCII character. */ -#define ASCII_CHAR_P(c) ((unsigned) (c) < 0x80) +#define ASCII_CHAR_P(c) UNSIGNED_CMP (c, <, 0x80) /* Almost equivalent to Faref (CT, IDX) with optimization for ASCII characters. Do not check validity of CT. */ -- 2.39.2