------- Comment #1 from rguenth at gcc dot gnu dot org 2007-07-24 10:11 ------- The problem seems to be a backend one(?). What happens is that for
signed char return_sc (signed char sc) { return sc; } the return value is now zero-extended instead of sign-extended (the sign extension was done in the C frontend code). The C standard in 6.8.6.4 specifies that for the return statement _only_ if the expression has a different type from the return type of the function then 'the value is converted as if by assignment to an object having the return type of the function'. Which reading either way doesn't specify whether the return value is implicitly sign-extended or not (AFAIK whether in this case the value is sign or zero extended should be / is specified by the target ABI). On x86_64 we get return_sc: .LFB12: movl %edi, %eax ret ... movl $-127, %edi call return_sc which is why we may be lucky here(?). On i686 we pass on the stack like return_sc: pushl %ebp movl %esp, %ebp movzbl 8(%ebp), %eax popl %ebp ret ... movl $-127, (%esp) call return_sc explicitly doing zero-extension. Now the libffi testcase explicitly checks for sign-extension(!) of the return value: for (sc = (signed char) -127; sc < (signed char) 127; sc++) { ffi_call(&cif, FFI_FN(return_sc), &rint, values); CHECK(rint == (ffi_arg) sc); } as rint is of type ffi_arg (unsigned long) and sc is signed char. I wonder whether this is desired or not. Andreas? Micha, how is promotion of the return value specified in the x86 ABI? -- rguenth at gcc dot gnu dot org changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |matz at suse dot de, | |andreast at gcc dot gnu dot | |org http://gcc.gnu.org/bugzilla/show_bug.cgi?id=32843