APPROVE COMMIT
NOTE: This patch has been committed
# HG changeset patch
# User Aidan Kehoe <kehoea(a)parhasard.net>
# Date 1524318697 -3600
# Sat Apr 21 14:51:37 2018 +0100
# Node ID 368318a5c386b0bce05209874e3241e3880e6ee2
# Parent 1df45726e0d6d45a816063328bd8e85c7ba701cc
Reduce narrowing warnings, catch non-idempotent arguments to make_integer()
src/ChangeLog addition:
2018-04-21 Aidan Kehoe <kehoea(a)parhasard.net>
* lisp.h (NUMBER_FITS_IN_A_FIXNUM, NUMBER_FITS_IN_A_FIXNUM):
* number.h (make_integer, make_unsigned_integer):
If the GCC extended expression syntax is available, use it and
__typeof__ to catch non-idempotent arguments to these arguments,
and to silence type-narrowing warnings for non-EMACS_INT
arguments.
diff -r 1df45726e0d6 -r 368318a5c386 src/ChangeLog
--- a/src/ChangeLog Sat Apr 21 14:14:56 2018 +0100
+++ b/src/ChangeLog Sat Apr 21 14:51:37 2018 +0100
@@ -1,3 +1,12 @@
+2018-04-21 Aidan Kehoe <kehoea(a)parhasard.net>
+
+ * lisp.h (NUMBER_FITS_IN_A_FIXNUM, NUMBER_FITS_IN_A_FIXNUM):
+ * number.h (make_integer, make_unsigned_integer):
+ If the GCC extended expression syntax is available, use it and
+ __typeof__ to catch non-idempotent arguments to these arguments,
+ and to silence type-narrowing warnings for non-EMACS_INT
+ arguments.
+
2018-04-21 Aidan Kehoe <kehoea(a)parhasard.net>
* gccache-x.c (gc_cache_hash):
diff -r 1df45726e0d6 -r 368318a5c386 src/lisp.h
--- a/src/lisp.h Sat Apr 21 14:14:56 2018 +0100
+++ b/src/lisp.h Sat Apr 21 14:51:37 2018 +0100
@@ -1810,11 +1810,26 @@
#define MOST_POSITIVE_FIXNUM ((EMACS_INT) MOST_POSITIVE_FIXNUM_UNSIGNED)
#define MOST_NEGATIVE_FIXNUM (-(MOST_POSITIVE_FIXNUM) - 1)
/* WARNING: evaluates its arg twice. */
+#ifdef USE_GCC_EXTENDED_EXPRESSION_SYNTAX
+#define NUMBER_FITS_IN_A_FIXNUM(num) \
+ ({ __typeof__ (num) _num = (num); \
+ assert (_num == num); /* Catch any non-idempotent argument. */ \
+ (((__typeof__ (num))-1 < 0) ? /* Signed? */ \
+ ((sizeof (_num) * BITS_PER_CHAR) <= FIXNUM_VALBITS || \
+ (((__typeof__ (num)) MOST_NEGATIVE_FIXNUM <= _num) && \
+ _num <= ((__typeof__ (num)) MOST_POSITIVE_FIXNUM))) \
+ : ((sizeof (_num) * BITS_PER_CHAR) < FIXNUM_VALBITS || \
+ (((__typeof__ (num)) 0 <= _num) && \
+ _num <= ((__typeof__ (num)) MOST_POSITIVE_FIXNUM)))); })
+#define UNSIGNED_NUMBER_FITS_IN_A_FIXNUM(num) \
+ ((num) <= (__typeof__ (num)) MOST_POSITIVE_FIXNUM_UNSIGNED)
+#else
#define NUMBER_FITS_IN_A_FIXNUM(num) \
((num) <= MOST_POSITIVE_FIXNUM && (num) >= MOST_NEGATIVE_FIXNUM)
#define UNSIGNED_NUMBER_FITS_IN_A_FIXNUM(num) \
((num) <= MOST_POSITIVE_FIXNUM_UNSIGNED)
+#endif
#ifdef USE_UNION_TYPE
# include "lisp-union.h"
#else /* !USE_UNION_TYPE */
diff -r 1df45726e0d6 -r 368318a5c386 src/number.h
--- a/src/number.h Sat Apr 21 14:14:56 2018 +0100
+++ b/src/number.h Sat Apr 21 14:51:37 2018 +0100
@@ -172,7 +172,18 @@
} while (0)
#ifdef HAVE_BIGNUM
-#define make_integer(x) \
+#ifdef USE_GCC_EXTENDED_EXPRESSION_SYNTAX
+#define make_integer(x) \
+ ({ __typeof__ (x) _x = (x); \
+ assert (x == _x); /* Catch non-idempotent arguments. */ \
+ (NUMBER_FITS_IN_A_FIXNUM (_x) ? make_fixnum (_x) : \
+ (((__typeof__ (x))-1 < 0) ? \
+ (sizeof (_x) > SIZEOF_LONG ? make_bignum_ll (_x) : make_bignum (_x)) \
+ : (sizeof (_x) > SIZEOF_LONG ? make_bignum_ull (_x) \
+ : make_bignum_un (_x)))); })
+#define make_unsigned_integer make_integer
+#else
+#define make_integer(x) \
(NUMBER_FITS_IN_A_FIXNUM (x) ? make_fixnum (x) \
: (sizeof (x) > SIZEOF_LONG ? make_bignum_ll (x) : \
make_bignum ((long) x)))
@@ -180,6 +191,7 @@
(UNSIGNED_NUMBER_FITS_IN_A_FIXNUM (x) ? make_fixnum (x) \
: (sizeof (x) > SIZEOF_LONG ? make_bignum_ull (x) : \
make_bignum_un ((unsigned long) x)))
+#endif /* USE_GCC_EXTENDED_EXPRESSION_SYNTAX */
#else
#define make_integer(x) make_fixnum (x)
#define make_unsigned_integer(x) make_fixnum ((EMACS_INT) x)
--
‘As I sat looking up at the Guinness ad, I could never figure out /
How your man stayed up on the surfboard after forty pints of stout’
(C. Moore)