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
3209 } else {3209 } else {
3210 v = anon_sym++;3210 v = anon_sym++;
3211 }3211 }
3212 /* Record the original enum/struct/union token. */
3212 type1.t = a;3213 type1.t = a;
3213 type1.ref = NULL;3214 type1.ref = NULL;
3214 /* we put an undefined size for struct/union */3215 /* 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
5650 }5651 }
5651}5652}
5652 5653
5653#define EXPR_VAL 0
5654#define EXPR_CONST 15654#define EXPR_CONST 1
5655#define EXPR_ANY 25655#define EXPR_ANY 2
5656 5656
@@ -5795,8 +5795,7 @@ static void decl_designator(CType *type, Section *sec, unsigned long c, · 138 unmodified lines
5795}5795}
5796 5796
5797/* store a value or an expression directly in global data or in local array */5797/* store a value or an expression directly in global data or in local array */
5798static void init_putv(CType *type, Section *sec, unsigned long c,5798static void init_putv(CType *type, Section *sec, unsigned long c)
5799 int v, int expr_type)
5800{5799{
5801 int bt, bit_pos, bit_size;5800 int bt, bit_pos, bit_size;
5802 void *ptr;5801 void *ptr;
@@ -6039,8 +6038,7 @@ static void decl_initializer(CType *type, Section *sec, unsigned long c, · 236 unmodified lines
6039 else6038 else
6040 ch = ((nwchar_t *)tokc.str.data)[i];6039 ch = ((nwchar_t *)tokc.str.data)[i];
6041 vpushi(ch);6040 vpushi(ch);
6042 init_putv(t1, sec, c + (array_length + i) * size1,6041 init_putv(t1, sec, c + (array_length + i) * size1);
6043 ch, EXPR_VAL);
6044 }6042 }
6045 }6043 }
6046 }6044 }
@@ -6052,7 +6050,7 @@ static void decl_initializer(CType *type, Section *sec, unsigned long c, · 5 unmodified lines
6052 if (n < 0 || array_length < n) {6050 if (n < 0 || array_length < n) {
6053 if (!size_only) {6051 if (!size_only) {
6054 vpushi(0);6052 vpushi(0);
6055 init_putv(t1, sec, c + (array_length * size1), 0, EXPR_VAL);6053 init_putv(t1, sec, c + (array_length * size1));
6056 }6054 }
6057 array_length++;6055 array_length++;
6058 }6056 }
@@ -6092,57 +6090,9 @@ static void decl_initializer(CType *type, Section *sec, unsigned long c, · 33 unmodified lines
6092 /* patch type size if needed */6090 /* patch type size if needed */
6093 if (n < 0)6091 if (n < 0)
6094 s->c = array_length;6092 s->c = array_length;
6095 } else if (1 && have_elem && is_compatible_types(type, &vtop->type)) {6093 } else if (have_elem && is_compatible_types(type, &vtop->type)) {
6096 /* currently, we always use constant expression for globals6094 init_putv(type, sec, c);
6097 (may change for scripting case) */6095 } else if ((type->t & VT_BTYPE) == VT_STRUCT) {
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
6146 no_oblock = 1;6096 no_oblock = 1;
6147 if (first || tok == '{') {6097 if (first || tok == '{') {
6148 skip('{');6098 skip('{');
@@ -6165,44 +6115,10 @@ static void decl_initializer(CType *type, Section *sec, unsigned long c, · 16 unmodified lines
6165 if (index > array_length)6115 if (index > array_length)
6166 array_length = index;6116 array_length = index;
6167 6117
6168 /* gr: skip fields from same union - ugly. */6118 if (s->type.t == TOK_UNION)
6169 while (f->next) {6119 f = NULL;
6170 int align = 0;6120 else
6171 int f_size = type_size(&f->type, &align);6121 f = f->next;
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;
6206 if (no_oblock && f == NULL)6122 if (no_oblock && f == NULL)
6207 break;6123 break;
6208 if (tok == '}')6124 if (tok == '}')
@@ -6216,10 +6132,6 @@ static void decl_initializer(CType *type, Section *sec, unsigned long c, · 7 unmodified lines
6216 }6132 }
6217 if (!no_oblock)6133 if (!no_oblock)
6218 skip('}');6134 skip('}');
6219 while (par_count) {
6220 skip(')');
6221 par_count--;
6222 }
6223 } else if (tok == '{') {6135 } else if (tok == '{') {
6224 next();6136 next();
6225 if (have_elem)6137 if (have_elem)
@@ -6256,9 +6168,7 @@ static void decl_initializer(CType *type, Section *sec, unsigned long c, · 30 unmodified lines
6256 expect("string constant");6168 expect("string constant");
6257 parse_init_elem(!sec ? EXPR_ANY : EXPR_CONST);6169 parse_init_elem(!sec ? EXPR_ANY : EXPR_CONST);
6258 }6170 }
6259 /* currently, we always use constant expression for globals6171 init_putv(type, sec, c);
6260 (may change for scripting case) */
6261 init_putv(type, sec, c, 0, expr_type);
6262 }6172 }
6263}6173}
6264 6174
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
67/* Initialization of a flex array member (warns in GCC) */67/* Initialization of a flex array member (warns in GCC) */
68struct W gw = {{1,2,3,4}, {1,2,3,4,5}};68struct W gw = {{1,2,3,4}, {1,2,3,4,5}};
69 69
70union UU {
71 u8 a;
72 u8 b;
73};
74struct SU {
75 union UU u;
76 u8 c;
77};
78struct SU gsu = {5,6};
79
70#include <stdio.h>80#include <stdio.h>
71void print_ (const char *name, const u8 *p, long size)81void print_ (const char *name, const u8 *p, long size)
72{82{
@@ -133,6 +143,7 @@ int main() · 60 unmodified lines
133 print(gv3);143 print(gv3);
134 print(sinit16);144 print(sinit16);
135 print(gw);145 print(gw);
146 print(gsu);
136 foo(&gw);147 foo(&gw);
137 //printf("q: %s\n", q);148 //printf("q: %s\n", q);
138 return 0;149 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
12gv3: 7 8 9 a 68 6f 68 6f 0 0 0 0 0 0 0 0 0 0 0 0 31 3212gv3: 7 8 9 a 68 6f 68 6f 0 0 0 0 0 0 0 0 0 0 0 0 31 32
13sinit16: 1 0 0 0 2 0 0 013sinit16: 1 0 0 0 2 0 0 0
14gw: 1 2 3 4 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 014gw: 1 2 3 4 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
15gsu: 5 6
15ls: 1 2 3 416ls: 1 2 3 4
16ls2: 1 2 3 417ls2: 1 2 3 4
17lt: 68 65 6c 6c 6f 0 0 0 0 0 0 0 0 0 0 0 2a18lt: 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
53 @diff -Nbu $(SRC)/$*.expect $*.output && rm -f $*.output53 @diff -Nbu $(SRC)/$*.expect $*.output && rm -f $*.output
54 54
55# automatically generate .expect files with gcc:55# automatically generate .expect files with gcc:
56%.expect :56%.expect : %.c
57 (gcc -w $*.c -o a.exe && ./a.exe $(ARGS)) >$*.expect 2>&1; rm -f a.exe57 (gcc -w $*.c -o a.exe && ./a.exe $(ARGS)) >$*.expect 2>&1; rm -f a.exe
58 58
59# tell make not to delete59# tell make not to delete