unsigned char ttt[] = {0xff, 1};
unsigned char test(void)
{
unsigned char a, i;
// a = 0; /* uncomment this line to generate correct
code */
for (i = 0; i < sizeof(ttt); i++) {
a |= ttt[i];
}
return a;
}
The return value is 1, but is should be 0xff.
If the variable a is initialized, the result is correct.
This is a minimized code from the regression test
bug-971834.c.
$sdcc --version
SDCC :
mcs51/gbz80/z80/avr/ds390/pic16/pic14/TININative/xa51/ds400/hc08
2.5.6 #4244 (Jun 24 2006) (MINGW32)
sdcc -mpic16 -pp18f452 t.c
Borut
Not really helpful for fixing this, but maybe interesting to the readers:
unsigned char is the only type for which such a bug can exist. If the variable a was of any type other than unsigned char, the |= on the uninitialized value would be undefined behaviour. For unsigned char though, it's unspecified behaviour instead.
Philipp
I tested the original PIC16 reproducer with current SDCC 4.6.4 (around r16998) for PIC18F452.
The old result reported in this ticket is no longer reproducible.
Current SDCC emits:
warning 84: 'auto' variable 'a' may be used before initialization
For the original uninitialized case, the generated PIC16 code currently clears the temporary used for a before the loop, and the old result of returning 1 instead of 0xff is not observed.
I also tested equivalent defined cases with:
unsigned char a = 0;
and:
unsigned char a = 0x55;
Both generate the expected OR loop over { 0xff, 1 } and therefore produce 0xff.
I repeated the original test with both --opt-code-size and --opt-code-speed; both generate the same relevant sequence and the old miscompilation is not reproduced.
So this appears to be fixed in the current PIC16 backend.
The original testcase still reads an automatic variable before explicit initialization, and current SDCC appropriately diagnoses that with warning 84.
Thanks for checking.