commit 498bcc6f4a07514d28d7867e27c94a1f642fe2bc Author: jiang Date: Sun Jun 22 15:24:18 2014 +0800 bug: struct { unsigned a:9, b:7, c:5; } s; s.a = s.b = s.c = 3; printf("%d / %d / %d\n", s.a, s.b, s.c); out: 0 / 0 / 3 and: struct { unsigned a:9, b:5, c:7; } _s, *s = &_s; int n = 250; s->a = s->b = s->c = n + 4; printf("--> %d / %d / %d\n", s->a, s->b, s->c); out: -> 0 / 0 / 126 diff --git a/tccgen.c b/tccgen.c index f134586..83a7752 100644 --- a/tccgen.c +++ b/tccgen.c @@ -2549,6 +2549,15 @@ ST_FUNC void vstore(void) /* bitfield store handling */ bit_pos = (ft >> VT_STRUCT_SHIFT) & 0x3f; bit_size = (ft >> (VT_STRUCT_SHIFT + 6)) & 0x3f; + + vpushv(&vtop[0]); + if(((vtop->r & (VT_VALMASK | VT_LVAL)) < VT_CONST) && (vtop > (vstack + 2))){ + int r = get_reg(RC_INT); + load(r, vtop); + vtop->r = r; + } + vrott(3); + /* remove bit field info to avoid loops */ vtop[-1].type.t = ft & ~(VT_BITFIELD | (-1 << VT_STRUCT_SHIFT)); @@ -2583,6 +2592,7 @@ ST_FUNC void vstore(void) gen_op('|'); /* store result */ vstore(); + vtop--; } else { #ifdef CONFIG_TCC_BCHECK /* bound check case */ @@ -4066,7 +4076,7 @@ ST_FUNC void unary(void) } else if (tok == '[') { next(); gexpr(); - if(tcc_state->warn_char_subscripts && (vtop->type.t & (VT_BTYPE|VT_UNSIGNED)) == VT_BYTE) + if(tcc_state->warn_char_subscripts && (vtop->type.t & (VT_BTYPE|VT_DEFSIGN|VT_UNSIGNED)) == VT_BYTE) tcc_warning("array subscript has type 'char'"); gen_op('+'); indir(); diff --git a/tests/tests2/03_struct.c b/tests/tests2/03_struct.c index c5d48c5..070c8d2 100644 --- a/tests/tests2/03_struct.c +++ b/tests/tests2/03_struct.c @@ -27,5 +27,35 @@ int main() printf("%d\n", jones[1].boris); printf("%d\n", jones[1].natasha); + struct sbf1 { + int f1 : 3; + int : 2; + int f2 : 1; + int : 0; + int f3 : 5; + int f4 : 7; + unsigned int f5 : 7; + } st1; + st1.f1 = st1.f2 = st1.f3 = st1.f4 = st1.f5 = 3; + printf("%d %d %d %d %d\n", + st1.f1, st1.f2, st1.f3, st1.f4, st1.f5); + + struct { unsigned a:9, b:7, c:5; } s1; + s1.a = s1.b = s1.c = 3; + printf("%d / %d / %d\n", s1.a, s1.b, s1.c); + + struct { + unsigned a:9, b:5, c:7; + } s2, *ps = &s2; + int n = 250; + + ps->a = ps->b = ps->c = n + 4; + printf("%d / %d / %d\n", ps->a, ps->b, ps->c); + + ps->a = n + 4; + ps->b = n + 4; + ps->c = n + 4; + printf("%d / %d / %d\n", ps->a, ps->b, ps->c); + return 0; } diff --git a/tests/tests2/03_struct.expect b/tests/tests2/03_struct.expect index ecbf589..ac7d10d 100644 --- a/tests/tests2/03_struct.expect +++ b/tests/tests2/03_struct.expect @@ -4,3 +4,7 @@ 34 56 78 +3 -1 3 3 3 +3 / 3 / 3 +254 / 30 / 126 +254 / 30 / 126