structure to an N-byte boundary.])
fi
+AC_C_TYPEOF
+
+AC_CACHE_CHECK([for statement expressions],
+ [emacs_cv_statement_expressions],
+ [AC_COMPILE_IFELSE(
+ [AC_LANG_PROGRAM([], [[return ({ int x = 5; x-x; });]])],
+ [emacs_cv_statement_expressions=yes],
+ [emacs_cv_statement_expressions=no])])
+if test "$emacs_cv_statement_expressions" = yes; then
+ AC_DEFINE([HAVE_STATEMENT_EXPRESSIONS], 1,
+ [Define to 1 if statement expressions work.])
+fi
+
if test "${GNU_MALLOC}" = "yes" ; then
AC_DEFINE(GNU_MALLOC, 1,
[Define to 1 if you want to use the GNU memory allocator.])
return make_fixnum (remainder);
val = get_random ();
}
- return make_fixnum (val);
+ return make_ufixnum (val);
}
\f
/* Random data-structure functions. */
static Lisp_Object
hashfn_eq (Lisp_Object key, struct Lisp_Hash_Table *h)
{
- return make_fixnum (XHASH (key) ^ XTYPE (key));
+ return make_ufixnum (XHASH (key) ^ XTYPE (key));
}
/* Ignore HT and return a hash code for KEY which uses 'equal' to compare keys.
Lisp_Object
hashfn_equal (Lisp_Object key, struct Lisp_Hash_Table *h)
{
- return make_fixnum (sxhash (key, 0));
+ return make_ufixnum (sxhash (key, 0));
}
/* Ignore HT and return a hash code for KEY which uses 'eql' to compare keys.
{
Lisp_Object args[] = { h->test.user_hash_function, key };
Lisp_Object hash = hash_table_user_defined_call (ARRAYELTS (args), args, h);
- return FIXNUMP (hash) ? hash : make_fixnum (sxhash (hash, 0));
+ return FIXNUMP (hash) ? hash : make_ufixnum (sxhash (hash, 0));
}
struct hash_table_test const
(eassert (CONSP (a)), XUNTAG (a, Lisp_Cons, struct Lisp_Cons))
#define lisp_h_XHASH(a) XUFIXNUM_RAW (a)
#if USE_LSB_TAG
-# define lisp_h_make_fixnum(n) \
+# define lisp_h_make_fixnum_wrap(n) \
XIL ((EMACS_INT) (((EMACS_UINT) (n) << INTTYPEBITS) + Lisp_Int0))
+# if defined HAVE_STATEMENT_EXPRESSIONS && defined HAVE_TYPEOF
+# define lisp_h_make_fixnum(n) \
+ ({ typeof (n) lisp_h_make_fixnum_n = n; \
+ eassert (!FIXNUM_OVERFLOW_P (lisp_h_make_fixnum_n)); \
+ lisp_h_make_fixnum_wrap (lisp_h_make_fixnum_n); })
+# else
+# define lisp_h_make_fixnum(n) lisp_h_make_fixnum_wrap (n)
+# endif
# define lisp_h_XFIXNUM_RAW(a) (XLI (a) >> INTTYPEBITS)
# define lisp_h_XTYPE(a) ((enum Lisp_Type) (XLI (a) & ~VALMASK))
#endif
#define MOST_POSITIVE_FIXNUM (EMACS_INT_MAX >> INTTYPEBITS)
#define MOST_NEGATIVE_FIXNUM (-1 - MOST_POSITIVE_FIXNUM)
+/* True if the possibly-unsigned integer I doesn't fit in a fixnum. */
+
+#define FIXNUM_OVERFLOW_P(i) \
+ (! ((0 <= (i) || MOST_NEGATIVE_FIXNUM <= (i)) && (i) <= MOST_POSITIVE_FIXNUM))
+
#if USE_LSB_TAG
INLINE Lisp_Object
(make_fixnum) (EMACS_INT n)
{
- return lisp_h_make_fixnum (n);
+ eassert (!FIXNUM_OVERFLOW_P (n));
+ return lisp_h_make_fixnum_wrap (n);
}
INLINE EMACS_INT
return lisp_h_XFIXNUM_RAW (a);
}
+INLINE Lisp_Object
+make_ufixnum (EMACS_INT n)
+{
+ eassert (0 <= n && n <= INTMASK);
+ return lisp_h_make_fixnum_wrap (n);
+}
+
#else /* ! USE_LSB_TAG */
/* Although compiled only if ! USE_LSB_TAG, the following functions
INLINE Lisp_Object
make_fixnum (EMACS_INT n)
{
+ eassert (! FIXNUM_OVERFLOW_P (n));
EMACS_INT int0 = Lisp_Int0;
if (USE_LSB_TAG)
{
return i >> INTTYPEBITS;
}
+INLINE Lisp_Object
+make_ufixnum (EMACS_INT n)
+{
+ eassert (0 <= n && n <= INTMASK);
+ EMACS_INT int0 = Lisp_Int0;
+ if (USE_LSB_TAG)
+ {
+ EMACS_UINT u = n;
+ n = u << INTTYPEBITS;
+ n += int0;
+ }
+ else
+ n += int0 << VALBITS;
+ return XIL (n);
+}
+
#endif /* ! USE_LSB_TAG */
INLINE bool
return lisp_h_EQ (x, y);
}
-/* True if the possibly-unsigned integer I doesn't fit in a fixnum. */
-
-#define FIXNUM_OVERFLOW_P(i) \
- (! ((0 <= (i) || MOST_NEGATIVE_FIXNUM <= (i)) && (i) <= MOST_POSITIVE_FIXNUM))
-
INLINE intmax_t
clip_to_bounds (intmax_t lower, intmax_t num, intmax_t upper)
{