GHC FFI Return Type Bug

Carl R. Witty
07 Aug 2001 11:13:43 -0700

"Sigbjorn Finne" <> writes:

> "Julian Seward (Intl Vendor)" <> writes:
> > 
> > Hmm, we're looking at this.  However, I don't really know what
> > C is or is not supposed to do here.  Given
> > 
> > char fooble ( ... )
> > {
> >    return 'z';
> > }
> > 
> > on an x86, 'z' will be returned at the lowest 8 bits in %eax.
> > What I don't know is, is the C compiler obliged to clear the
> > upper 24 bits of %eax, or does that onus fall on the callee?
> Yes, the callee is required to narrow <expr> in 'return <expr>;' to
> fit that of the specified return type -- see 9.8 of Harbison and
> Steele. So, a C compiler that cause f() to return 0x7fffffff for
> the following,
> unsigned char g()
> {
>     return 0x7fffffff;
> }
> unsigned int f()
> {
>     return g();
> }
> is in the wrong. [Notice that narrowing for signed integral types
> is undefined in ISO C, but most current-day compilers implement
> such narrowing ops the same way, i.e., by masking off excess bits.]

It's certainly true that an ISO C compiler on a typical machine must
return 255 from f() (on an atypical machine, it's possible to have
unsigned char be a 32-bit type).  However, this is essentially
unrelated to the question of whether the x86 ABI allows g() to return
a value in %eax that has the upper 3 bytes non-zero.

When I compile the following file:
-------------------- abitest.c --------------------
unsigned int g_val;

unsigned char g()
    return g_val;

unsigned int f()
    return g();

with the command
	gcc -Wall -O2 -fomit-frame-pointer -S abitest.c

I get the output:
-------------------- abitest.S --------------------
	.file	"abitest.c"
	.version	"01.01"
	.align 16
.globl g
	.type	 g,@function
	movzbl g_val,%eax
	.size	 g,.Lfe1-g
	.align 16
.globl f
	.type	 f,@function
	call g
	andl $255,%eax
	.size	 f,.Lfe2-f
	.comm	g_val,4,4
	.ident	"GCC: (GNU)"

You can see that the code for f is:
	call g
	andl $255,%eax
So gcc believes that a function which returns a value of type unsigned
char is not responsible for clearing the high 3 bytes of %eax.

Carl Witty