Menu ▾ ▴

#4255 Since r17035, a store to a union member after a store to a bit-field member is compiled as a bit-field store

open
nobody
None
redundancy elimination
5
1 day ago
1 day ago
Matt Mower
No

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.

Related

Bugs: #4149
Commit: [r17035]

Discussion


Log in to post a comment.