I had Claude (AI) help me bisect and prepare the code reproduction for this bug when I encountered it.
Since [r17035] ([bugs:#4149]), sdcc compiles a store to a member of an automatic union as a store to a bit-field member at the same address when the function stores to that bit-field earlier. In the sample, the code for the assignment to v.raw writes only bits 4 to 7, which hold the bit-field b, and leaves bits 0 to 3 as the initializer set them. r17034 and SDCC 4.6.0 compile the sample correctly.
1: Sample code that reproduces the problem
union u
{
struct
{
unsigned char a : 4;
unsigned char b : 4;
} s;
unsigned char raw;
};
__xdata __at(0x7000) volatile unsigned char res[1];
void main (void)
{
union u v = {{1, 2}};
v.raw = 0x55;
res[0] = v.raw; /* expected 0x55 */
for (;;);
}
2: Exact command used to run SDCC on this sample code
sdcc -mmcs51 main.c
printf 'step 100000\ndump xram 0x7000 0x7001\nquit\n' | s51 -t C52 main.ihx
The result is the same with --model-large.
3: SDCC version tested
SDCC : mcs51 TD- 4.6.4 #0 (Linux)
The compiler is trunk r17202, built on Debian 13 (amd64) from a git-svn mirror with only the mcs51 port, so the revision number is 0. I built r17034 and r17035 in the same way.
4: Observed and expected behavior
res[0] is 0x51. sdcc compiles v.raw = 0x55 to the code of a store of 5 to the bit-field b.
anl _main_v_10000_2,#0x0f
orl _main_v_10000_2,#0x50
res[0] should be 0x55. r17034 compiles the assignment to mov _main_v_10000_2,#0x55.