aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Matz <matz@suse.de>2016-07-31 06:18:45 +0200
committerMichael Matz <matz@suse.de>2016-12-15 17:47:09 +0100
commit7bf323843ee2f59bcbdaa8e5dd7b060a2df4ea4d (patch)
tree9be1e61872b69e254171f92c358a6bc7fbe33cc0
parented7d54651d2ef33dd6f644f23ba2fa64706e84db (diff)
downloadtinycc-7bf323843ee2f59bcbdaa8e5dd7b060a2df4ea4d.tar.gz
tinycc-7bf323843ee2f59bcbdaa8e5dd7b060a2df4ea4d.tar.bz2
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.
-rw-r--r--tccgen.c114
-rw-r--r--tests/tests2/86-struct-init.c11
-rw-r--r--tests/tests2/86-struct-init.expect1
-rw-r--r--tests/tests2/Makefile2
4 files changed, 25 insertions, 103 deletions
diff --git a/tccgen.c b/tccgen.c
index 064a9fe..fe0f2c5 100644
--- a/tccgen.c
+++ b/tccgen.c
@@ -3209,6 +3209,7 @@ static void struct_decl(CType *type, AttributeDef *ad, int u)
} else {
v = anon_sym++;
}
+ /* Record the original enum/struct/union token. */
type1.t = a;
type1.ref = NULL;
/* we put an undefined size for struct/union */
@@ -5650,7 +5651,6 @@ static void block(int *bsym, int *csym, int is_expr)
}
}
-#define EXPR_VAL 0
#define EXPR_CONST 1
#define EXPR_ANY 2
@@ -5795,8 +5795,7 @@ static void decl_designator(CType *type, Section *sec, unsigned long c,
}
/* store a value or an expression directly in global data or in local array */
-static void init_putv(CType *type, Section *sec, unsigned long c,
- int v, int expr_type)
+static void init_putv(CType *type, Section *sec, unsigned long c)
{
int bt, bit_pos, bit_size;
void *ptr;
@@ -6039,8 +6038,7 @@ static void decl_initializer(CType *type, Section *sec, unsigned long c,
else
ch = ((nwchar_t *)tokc.str.data)[i];
vpushi(ch);
- init_putv(t1, sec, c + (array_length + i) * size1,
- ch, EXPR_VAL);
+ init_putv(t1, sec, c + (array_length + i) * size1);
}
}
}
@@ -6052,7 +6050,7 @@ static void decl_initializer(CType *type, Section *sec, unsigned long c,
if (n < 0 || array_length < n) {
if (!size_only) {
vpushi(0);
- init_putv(t1, sec, c + (array_length * size1), 0, EXPR_VAL);
+ init_putv(t1, sec, c + (array_length * size1));
}
array_length++;
}
@@ -6092,57 +6090,9 @@ static void decl_initializer(CType *type, Section *sec, unsigned long c,
/* patch type size if needed */
if (n < 0)
s->c = array_length;
- } else if (1 && have_elem && is_compatible_types(type, &vtop->type)) {
- /* currently, we always use constant expression for globals
- (may change for scripting case) */
- expr_type = !sec ? EXPR_ANY : EXPR_CONST;
- init_putv(type, sec, c, 0, expr_type);
- } else if ((type->t & VT_BTYPE) == VT_STRUCT &&
- (!first || tok == '{')) {
-
- /* NOTE: the previous test is a specific case for automatic
- struct/union init */
- /* XXX: union needs only one init */
-
- int par_count = 0;
- if (0 && tok == '(') {
- AttributeDef ad1;
- CType type1;
- next();
- if (tcc_state->old_struct_init_code) {
- /* an old version of struct initialization.
- It have a problems. But with a new version
- linux 2.4.26 can't load ramdisk.
- */
- while (tok == '(') {
- par_count++;
- next();
- }
- if (!parse_btype(&type1, &ad1))
- expect("cast");
- type_decl(&type1, &ad1, &n, TYPE_ABSTRACT);
- #if 0
- if (!is_assignable_types(type, &type1))
- tcc_error("invalid type for cast");
- #endif
- skip(')');
- }
- else
- {
- if (tok != '(') {
- if (!parse_btype(&type1, &ad1))
- expect("cast");
- type_decl(&type1, &ad1, &n, TYPE_ABSTRACT);
- #if 0
- if (!is_assignable_types(type, &type1))
- tcc_error("invalid type for cast");
- #endif
- skip(')');
- } else
- unget_tok(tok);
- }
- }
-
+ } else if (have_elem && is_compatible_types(type, &vtop->type)) {
+ init_putv(type, sec, c);
+ } else if ((type->t & VT_BTYPE) == VT_STRUCT) {
no_oblock = 1;
if (first || tok == '{') {
skip('{');
@@ -6165,44 +6115,10 @@ static void decl_initializer(CType *type, Section *sec, unsigned long c,
if (index > array_length)
array_length = index;
- /* gr: skip fields from same union - ugly. */
- while (f->next) {
- int align = 0;
- int f_size = type_size(&f->type, &align);
- int f_type = (f->type.t & VT_BTYPE);
-
- ///printf("index: %2d %08x -- %2d %08x\n", f->c, f->type.t, f->next->c, f->next->type.t);
- /* test for same offset */
- if (f->next->c != f->c)
- break;
- if ((f_type == VT_STRUCT) && (f_size == 0)) {
- /*
- Lets assume a structure of size 0 can't be a member of the union.
- This allow to compile the following code from a linux kernel v2.4.26
- typedef struct { } rwlock_t;
- struct fs_struct {
- int count;
- rwlock_t lock;
- int umask;
- };
- struct fs_struct init_fs = { { (1) }, (rwlock_t) {}, 0022, };
- tcc-0.9.23 can succesfully compile this version of the kernel.
- gcc don't have problems with this code too.
- */
- break;
- }
- /* if yes, test for bitfield shift */
- if ((f->type.t & VT_BITFIELD) && (f->next->type.t & VT_BITFIELD)) {
- int bit_pos_1 = (f->type.t >> VT_STRUCT_SHIFT) & 0x3f;
- int bit_pos_2 = (f->next->type.t >> VT_STRUCT_SHIFT) & 0x3f;
- //printf("bitfield %d %d\n", bit_pos_1, bit_pos_2);
- if (bit_pos_1 != bit_pos_2)
- break;
- }
- f = f->next;
- }
-
- f = f->next;
+ if (s->type.t == TOK_UNION)
+ f = NULL;
+ else
+ f = f->next;
if (no_oblock && f == NULL)
break;
if (tok == '}')
@@ -6216,10 +6132,6 @@ static void decl_initializer(CType *type, Section *sec, unsigned long c,
}
if (!no_oblock)
skip('}');
- while (par_count) {
- skip(')');
- par_count--;
- }
} else if (tok == '{') {
next();
if (have_elem)
@@ -6256,9 +6168,7 @@ static void decl_initializer(CType *type, Section *sec, unsigned long c,
expect("string constant");
parse_init_elem(!sec ? EXPR_ANY : EXPR_CONST);
}
- /* currently, we always use constant expression for globals
- (may change for scripting case) */
- init_putv(type, sec, c, 0, expr_type);
+ init_putv(type, sec, c);
}
}
diff --git a/tests/tests2/86-struct-init.c b/tests/tests2/86-struct-init.c
index 71a2810..fa0d967 100644
--- a/tests/tests2/86-struct-init.c
+++ b/tests/tests2/86-struct-init.c
@@ -67,6 +67,16 @@ struct V gv3 = {((struct S){7,8,{9,10}}), {"hoho", 49}, 50};
/* Initialization of a flex array member (warns in GCC) */
struct W gw = {{1,2,3,4}, {1,2,3,4,5}};
+union UU {
+ u8 a;
+ u8 b;
+};
+struct SU {
+ union UU u;
+ u8 c;
+};
+struct SU gsu = {5,6};
+
#include <stdio.h>
void print_ (const char *name, const u8 *p, long size)
{
@@ -133,6 +143,7 @@ int main()
print(gv3);
print(sinit16);
print(gw);
+ print(gsu);
foo(&gw);
//printf("q: %s\n", q);
return 0;
diff --git a/tests/tests2/86-struct-init.expect b/tests/tests2/86-struct-init.expect
index 221048f..6ae60e0 100644
--- a/tests/tests2/86-struct-init.expect
+++ b/tests/tests2/86-struct-init.expect
@@ -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
gv3: 7 8 9 a 68 6f 68 6f 0 0 0 0 0 0 0 0 0 0 0 0 31 32
sinit16: 1 0 0 0 2 0 0 0
gw: 1 2 3 4 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+gsu: 5 6
ls: 1 2 3 4
ls2: 1 2 3 4
lt: 68 65 6c 6c 6f 0 0 0 0 0 0 0 0 0 0 0 2a
diff --git a/tests/tests2/Makefile b/tests/tests2/Makefile
index 50cff85..2434215 100644
--- a/tests/tests2/Makefile
+++ b/tests/tests2/Makefile
@@ -53,7 +53,7 @@ all test: $(filter-out $(SKIP),$(TESTS))
@diff -Nbu $(SRC)/$*.expect $*.output && rm -f $*.output
# automatically generate .expect files with gcc:
-%.expect :
+%.expect : %.c
(gcc -w $*.c -o a.exe && ./a.exe $(ARGS)) >$*.expect 2>&1; rm -f a.exe
# tell make not to delete