Issue Details (XML | Word | Printable)

Key: PCC-296
Type: Bug Bug
Status: Resolved Resolved
Resolution: Fixed
Priority: Major Major
Assignee: Anders Magnusson
Reporter: Iain Hibbert
Votes: 0
Watchers: 0
Operations

If you were logged in you would be able to see more operations.
pcc

sign extension fails for function result

Created: 05/Apr/11 08:42 PM   Updated: 10/Apr/11 12:52 PM
Component/s: Common code
Affects Version/s: None
Fix Version/s: None

Environment: NetBSD/i386


 Description  « Hide
The following small example program

#include <stdio.h>

unsigned short uint16_min(void)
{
return 0x8000;
}

int
main(int ac, char *av[])
{
short s;
int i;
long l;
long long ll;

s = (short)uint16_min();
i = (short)uint16_min();
l = (short)uint16_min();
ll = (short)uint16_min();

printf("s = %d\n", s);
printf("i = %d\n", i);
printf("l = %ld\n", l);
printf("ll = %lld\n", ll);

return 0;
}

when compiled and run with pcc shows the following output

s = -32768
i = 32768
l = 32768
ll = 32768

that is, the latter three values have not been sign extended correctly as should
be caused by casting the unsigned short result to short before the assignment

 All   Comments   Change History      Sort Order: Ascending order - Click to sort in descending order
Iain Hibbert added a comment - 05/Apr/11 11:25 PM
I think unrelated but a similar issue so I'll tack it here, the following program

#include <stdio.h>

int main(int ac, char *av[])
{
        long long v = -3483738234;

        printf("v = %lld\n", a);

        return 0;
}

when compiled and run with pcc shows the following output
v = 811229062

and looking at the assembler output it seems that sign extension has not
happened during the initial assignment, as the following is produced

        movl $811229062,-8(%ebp)
        movl $0,-4(%ebp)

but the second one should be $-1 or something similar

Anders Magnusson added a comment - 09/Apr/11 02:51 PM
Short cast error fixed. The second bug is in fact a bug, even if gcc has this behavior on gcc3 also (but not gcc4).

Iain Hibbert added a comment - 09/Apr/11 06:36 PM
Ok thanks I found a comment somewhere that actually in C90 you had to use LL for that otherwise the behaviour was undefined but looking at C99 draft spec I think the LL is not needed? in point of fact the code I found using this was using

  typedef long long intmax_t;

  intmax_t v = -3483738234;

I note also here that explicitly specifying the number as LL does cause pcc to generate the correct code.. but for portability I guess that you shouldn't need to specify the LL, as it could be detrimental if intmax_t was in fact represented as long..

Anders Magnusson added a comment - 10/Apr/11 12:52 PM
Now fixed. Type assignment of constants have too many different handlings, see table in 6.4.4.1.