With GCC 4.1 and configuring --with-union-type, bignums are broken. The
build log shows that gcc complains in quite a few places about
comparisons always being true due to the limited range of some type.
Here is my analysis of the problem.
Consider XREALINT for an example. The other extraction macros are
similar. With lisp-disunion.h, a Lisp_Object is really an EMACS_INT
(which is "long" on my x86_64 Linux box). The definition of XREALINT is
#define XREALINT(x) ((x) >> INT_GCBITS)
so the type of the result is still EMACS_INT. With lisp-union.h,
though, a Lisp_Object is a union. The definition of XREALINT is
#define XREALINT(x) ((x).s.val)
where the "s" field of the union is defined like this:
struct
{
unsigned int bits : INT_GCBITS;
signed EMACS_INT val : INT_VALBITS;
} s;
so the type of the result is INT_VALBITS of a signed EMACS_INT, not a
full EMACS_INT as in the disunion case. That means that this code from
Fminus in data.c:
return make_integer (-XREALINT (accum));
runs into trouble, because XREALINT(accum) is only a 63-bit quantity,
and so when make_integer expands, the comparison to see if the result
needs to be a fixnum or a bignum ALWAYS decides on fixnum, because a
63-bit quantity always fits. What I really wanted to know was whether
the negation of the 64-bit expansion of accum.s.val would fit into a
fixnum.
I haven't tried this yet (I'm out of time for the day), but my initial
reaction would be to try making this modification to lisp-union.h. I
suspect it will not cause any trouble, because the types of the
corresponding definitions in lisp-disunion.h are already the full (i.e.,
not bit-restricted) types.
#define XCHARVAL(x) (EMACS_UINT)((x).gu.val)
#define XPNTRVAL(x) ((x).ui)
#define XREALINT(x) (EMACS_INT)((x).s.val)
#define XUINT(x) (EMACS_UINT)((x).u.val)
I'm not sure if we need an extra level of parentheses around that.
Thoughts?
--
Jerry James, Assistant Professor james(a)xemacs.org
Computer Science Department
http://www.cs.usu.edu/~jerry/
Utah State University