History

struct-init: Cleanup

Remove dead code and variables. Properly check for unions when skipping fields in initializers. Make tests2/*.expect depend on the .c files so they are automatically rebuilt when the latter change.

Michael Matz committed 10 years ago

Commit 7bf32381 parent ed7d5464 files · +25 −103Browse files

Unified · Split

4 files
  1. tccgen.c +12 −102
  2. tests/tests2/86-struct-init.c +11 −0
  3. tests/tests2/86-struct-init.expect +1 −0
  4. tests/tests2/Makefile +1 −1
tccgen.c+12−102
@@ -3209,6 +3209,7 @@ static void struct_decl(CType *type, AttributeDef *ad, int u) · 3208 unmodified lines
32093209 } else {
32103210 v = anon_sym++;
32113211 }
3212+ /* Record the original enum/struct/union token. */
32123213 type1.t = a;
32133214 type1.ref = NULL;
32143215 /* we put an undefined size for struct/union */
@@ -5650,7 +5651,6 @@ static void block(int *bsym, int *csym, int is_expr) · 2435 unmodified lines
56505651 }
56515652 }
56525653
5653−#define EXPR_VAL 0
56545654 #define EXPR_CONST 1
56555655 #define EXPR_ANY 2
56565656
@@ -5795,8 +5795,7 @@ static void decl_designator(CType *type, Section *sec, unsigned long c, · 138 unmodified lines
57955795 }
57965796
57975797 /* store a value or an expression directly in global data or in local array */
5798−static void init_putv(CType *type, Section *sec, unsigned long c,
5799− int v, int expr_type)
5798+static void init_putv(CType *type, Section *sec, unsigned long c)
58005799 {
58015800 int bt, bit_pos, bit_size;
58025801 void *ptr;
@@ -6039,8 +6038,7 @@ static void decl_initializer(CType *type, Section *sec, unsigned long c, · 236 unmodified lines
60396038 else
60406039 ch = ((nwchar_t *)tokc.str.data)[i];
60416040 vpushi(ch);
6042− init_putv(t1, sec, c + (array_length + i) * size1,
6043− ch, EXPR_VAL);
6041+ init_putv(t1, sec, c + (array_length + i) * size1);
60446042 }
60456043 }
60466044 }
@@ -6052,7 +6050,7 @@ static void decl_initializer(CType *type, Section *sec, unsigned long c, · 5 unmodified lines
60526050 if (n < 0 || array_length < n) {
60536051 if (!size_only) {
60546052 vpushi(0);
6055− init_putv(t1, sec, c + (array_length * size1), 0, EXPR_VAL);
6053+ init_putv(t1, sec, c + (array_length * size1));
60566054 }
60576055 array_length++;
60586056 }
@@ -6092,57 +6090,9 @@ static void decl_initializer(CType *type, Section *sec, unsigned long c, · 33 unmodified lines
60926090 /* patch type size if needed */
60936091 if (n < 0)
60946092 s->c = array_length;
6095− } else if (1 && have_elem && is_compatible_types(type, &vtop->type)) {
6096− /* currently, we always use constant expression for globals
6097− (may change for scripting case) */
6098− expr_type = !sec ? EXPR_ANY : EXPR_CONST;
6099− init_putv(type, sec, c, 0, expr_type);
6100− } else if ((type->t & VT_BTYPE) == VT_STRUCT &&
6101− (!first || tok == '{')) {
6102−
6103− /* NOTE: the previous test is a specific case for automatic
6104− struct/union init */
6105− /* XXX: union needs only one init */
6106−
6107− int par_count = 0;
6108− if (0 && tok == '(') {
6109− AttributeDef ad1;
6110− CType type1;
6111− next();
6112− if (tcc_state->old_struct_init_code) {
6113− /* an old version of struct initialization.
6114− It have a problems. But with a new version
6115− linux 2.4.26 can't load ramdisk.
6116− */
6117− while (tok == '(') {
6118− par_count++;
6119− next();
6120− }
6121− if (!parse_btype(&type1, &ad1))
6122− expect("cast");
6123− type_decl(&type1, &ad1, &n, TYPE_ABSTRACT);
6124− #if 0
6125− if (!is_assignable_types(type, &type1))
6126− tcc_error("invalid type for cast");
6127− #endif
6128− skip(')');
6129− }
6130− else
6131− {
6132− if (tok != '(') {
6133− if (!parse_btype(&type1, &ad1))
6134− expect("cast");
6135− type_decl(&type1, &ad1, &n, TYPE_ABSTRACT);
6136− #if 0
6137− if (!is_assignable_types(type, &type1))
6138− tcc_error("invalid type for cast");
6139− #endif
6140− skip(')');
6141− } else
6142− unget_tok(tok);
6143− }
6144− }
6145−
6093+ } else if (have_elem && is_compatible_types(type, &vtop->type)) {
6094+ init_putv(type, sec, c);
6095+ } else if ((type->t & VT_BTYPE) == VT_STRUCT) {
61466096 no_oblock = 1;
61476097 if (first || tok == '{') {
61486098 skip('{');
@@ -6165,44 +6115,10 @@ static void decl_initializer(CType *type, Section *sec, unsigned long c, · 16 unmodified lines
61656115 if (index > array_length)
61666116 array_length = index;
61676117
6168− /* gr: skip fields from same union - ugly. */
6169− while (f->next) {
6170− int align = 0;
6171− int f_size = type_size(&f->type, &align);
6172− int f_type = (f->type.t & VT_BTYPE);
6173−
6174− ///printf("index: %2d %08x -- %2d %08x\n", f->c, f->type.t, f->next->c, f->next->type.t);
6175− /* test for same offset */
6176− if (f->next->c != f->c)
6177− break;
6178− if ((f_type == VT_STRUCT) && (f_size == 0)) {
6179− /*
6180− Lets assume a structure of size 0 can't be a member of the union.
6181− This allow to compile the following code from a linux kernel v2.4.26
6182− typedef struct { } rwlock_t;
6183− struct fs_struct {
6184− int count;
6185− rwlock_t lock;
6186− int umask;
6187− };
6188− struct fs_struct init_fs = { { (1) }, (rwlock_t) {}, 0022, };
6189− tcc-0.9.23 can succesfully compile this version of the kernel.
6190− gcc don't have problems with this code too.
6191− */
6192− break;
6193− }
6194− /* if yes, test for bitfield shift */
6195− if ((f->type.t & VT_BITFIELD) && (f->next->type.t & VT_BITFIELD)) {
6196− int bit_pos_1 = (f->type.t >> VT_STRUCT_SHIFT) & 0x3f;
6197− int bit_pos_2 = (f->next->type.t >> VT_STRUCT_SHIFT) & 0x3f;
6198− //printf("bitfield %d %d\n", bit_pos_1, bit_pos_2);
6199− if (bit_pos_1 != bit_pos_2)
6200− break;
6201− }
6202− f = f->next;
6203− }
6204−
6205− f = f->next;
6118+ if (s->type.t == TOK_UNION)
6119+ f = NULL;
6120+ else
6121+ f = f->next;
62066122 if (no_oblock && f == NULL)
62076123 break;
62086124 if (tok == '}')
@@ -6216,10 +6132,6 @@ static void decl_initializer(CType *type, Section *sec, unsigned long c, · 7 unmodified lines
62166132 }
62176133 if (!no_oblock)
62186134 skip('}');
6219− while (par_count) {
6220− skip(')');
6221− par_count--;
6222− }
62236135 } else if (tok == '{') {
62246136 next();
62256137 if (have_elem)
@@ -6256,9 +6168,7 @@ static void decl_initializer(CType *type, Section *sec, unsigned long c, · 30 unmodified lines
62566168 expect("string constant");
62576169 parse_init_elem(!sec ? EXPR_ANY : EXPR_CONST);
62586170 }
6259− /* currently, we always use constant expression for globals
6260− (may change for scripting case) */
6261− init_putv(type, sec, c, 0, expr_type);
6171+ init_putv(type, sec, c);
62626172 }
62636173 }
62646174
tests/tests2/86-struct-init.c+11−0
@@ -67,6 +67,16 @@ struct V gv3 = {((struct S){7,8,{9,10}}), {"hoho", 49}, 50}; · 66 unmodified lines
6767 /* Initialization of a flex array member (warns in GCC) */
6868 struct W gw = {{1,2,3,4}, {1,2,3,4,5}};
6969
70+union UU {
71+ u8 a;
72+ u8 b;
73+};
74+struct SU {
75+ union UU u;
76+ u8 c;
77+};
78+struct SU gsu = {5,6};
79+
7080 #include <stdio.h>
7181 void print_ (const char *name, const u8 *p, long size)
7282 {
@@ -133,6 +143,7 @@ int main() · 60 unmodified lines
133143 print(gv3);
134144 print(sinit16);
135145 print(gw);
146+ print(gsu);
136147 foo(&gw);
137148 //printf("q: %s\n", q);
138149 return 0;
tests/tests2/86-struct-init.expect+1−0
@@ -12,6 +12,7 @@ gv2: 7 8 9 a 68 69 68 69 0 0 0 0 0 0 0 0 0 0 0 0 2f 30 · 11 unmodified lines
1212 gv3: 7 8 9 a 68 6f 68 6f 0 0 0 0 0 0 0 0 0 0 0 0 31 32
1313 sinit16: 1 0 0 0 2 0 0 0
1414 gw: 1 2 3 4 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
15+gsu: 5 6
1516 ls: 1 2 3 4
1617 ls2: 1 2 3 4
1718 lt: 68 65 6c 6c 6f 0 0 0 0 0 0 0 0 0 0 0 2a
tests/tests2/Makefile+1−1
@@ -53,7 +53,7 @@ all test: $(filter-out $(SKIP),$(TESTS)) · 52 unmodified lines
5353 @diff -Nbu $(SRC)/$*.expect $*.output && rm -f $*.output
5454
5555 # automatically generate .expect files with gcc:
56−%.expect :
56+%.expect : %.c
5757 (gcc -w $*.c -o a.exe && ./a.exe $(ARGS)) >$*.expect 2>&1; rm -f a.exe
5858
5959 # tell make not to delete