diff options
Diffstat (limited to 'util/romcc')
-rw-r--r-- | util/romcc/Makefile | 7 | ||||
-rw-r--r-- | util/romcc/romcc.c | 33 | ||||
-rw-r--r-- | util/romcc/tests/fail_test6.c | 11 | ||||
-rw-r--r-- | util/romcc/tests/fail_test7.c | 10 | ||||
-rw-r--r-- | util/romcc/tests/fail_test8.c | 10 |
5 files changed, 58 insertions, 13 deletions
diff --git a/util/romcc/Makefile b/util/romcc/Makefile index e8dd0a9679..75fb56c01f 100644 --- a/util/romcc/Makefile +++ b/util/romcc/Makefile @@ -1,5 +1,5 @@ -VERSION:=0.37 -RELEASE_DATE:=21 October 2003 +VERSION:=0.38 +RELEASE_DATE:=18 December 2003 PACKAGE:=romcc @@ -108,6 +108,9 @@ FAIL_TESTS = \ fail_test3.c \ fail_test4.c \ fail_test5.c \ + fail_test6.c \ + fail_test7.c \ + fail_test8.c \ TEST_SRCS:=$(patsubst %, tests/%, $(TESTS)) TEST_ASM:=$(patsubst %.c, tests/%.S, $(TESTS)) diff --git a/util/romcc/romcc.c b/util/romcc/romcc.c index d460cfb548..ff7aee669b 100644 --- a/util/romcc/romcc.c +++ b/util/romcc/romcc.c @@ -1579,7 +1579,7 @@ static unsigned short triple_sizes(struct compile_state *state, rhs = rhs_wanted; lhs = 0; if ((type->type & TYPE_MASK) == TYPE_STRUCT) { - lhs = type->left->elements; + lhs = type->elements; } } else if (op == OP_VAL_VEC) { @@ -4822,7 +4822,8 @@ static int is_stable(struct compile_state *state, struct triple *def) if ((def->op == OP_ADECL) || (def->op == OP_SDECL) || (def->op == OP_DEREF) || - (def->op == OP_BLOBCONST)) { + (def->op == OP_BLOBCONST) || + (def->op == OP_LIST)) { ret = 1; } else if (def->op == OP_DOT) { @@ -4930,6 +4931,9 @@ static struct triple *do_mk_addr_expr(struct compile_state *state, RHS(expr, 0), int_const(state, &ulong_type, offset)); } + else if (expr->op == OP_LIST) { + error(state, 0, "Function addresses not supported"); + } if (!result) { internal_error(state, expr, "cannot take address of expression"); } @@ -4951,8 +4955,9 @@ static struct triple *mk_deref_expr( return triple(state, OP_DEREF, base_type, expr, 0); } -static struct triple *array_to_pointer(struct compile_state *state, struct triple *def) +static struct triple *lvalue_conversion(struct compile_state *state, struct triple *def) { + /* Tranform an array to a pointer to the first element */ if ((def->type->type & TYPE_MASK) == TYPE_ARRAY) { struct type *type; type = new_type( @@ -4971,6 +4976,10 @@ static struct triple *array_to_pointer(struct compile_state *state, struct tripl def = triple(state, OP_COPY, type, def, 0); } } + /* Transform a function to a pointer to it */ + else if ((def->type->type & TYPE_MASK) == TYPE_FUNCTION) { + def = mk_addr_expr(state, def, 0); + } return def; } @@ -5010,15 +5019,12 @@ static struct triple *read_expr(struct compile_state *state, struct triple *def) if (!def) { return 0; } +#warning "CHECK_ME is this the only place I need to do lvalue conversions?" + /* Transform lvalues into something we can read */ + def = lvalue_conversion(state, def); if (!is_stable(state, def)) { return def; } - /* Tranform an array to a pointer to the first element */ - -#warning "CHECK_ME is this the right place to transform arrays to pointers?" - if ((def->type->type & TYPE_MASK) == TYPE_ARRAY) { - return array_to_pointer(state, def); - } if (is_in_reg(state, def)) { op = OP_READ; } else { @@ -8268,7 +8274,11 @@ static struct triple *expr(struct compile_state *state) static void expr_statement(struct compile_state *state, struct triple *first) { if (peek(state) != TOK_SEMI) { - flatten(state, first, expr(state)); + /* lvalue conversions always apply except when certaion operators + * are applied so the values so apply them here as I know no more + * operators will be applied. + */ + flatten(state, first, lvalue_conversion(state, expr(state))); } eat(state, TOK_SEMI); } @@ -9650,7 +9660,7 @@ static struct triple *initializer( ((result->type->type & TYPE_MASK) == TYPE_ARRAY) && (type->type & TYPE_MASK) != TYPE_ARRAY) { - result = array_to_pointer(state, result); + result = lvalue_conversion(state, result); } if (!is_init_compatible(state, type, result->type)) { error(state, 0, "Incompatible types in initializer"); @@ -18548,6 +18558,7 @@ static void print_const(struct compile_state *state, case TYPE_UINT: case TYPE_LONG: case TYPE_ULONG: + case TYPE_POINTER: fprintf(fp, ".int %lu\n", (unsigned long)(ins->u.cval)); break; diff --git a/util/romcc/tests/fail_test6.c b/util/romcc/tests/fail_test6.c new file mode 100644 index 0000000000..cc7bcf52c6 --- /dev/null +++ b/util/romcc/tests/fail_test6.c @@ -0,0 +1,11 @@ + + +static void hlt(void) +{ +} + +static void main(void) +{ + void *foo; + foo = hlt; +} diff --git a/util/romcc/tests/fail_test7.c b/util/romcc/tests/fail_test7.c new file mode 100644 index 0000000000..e7a0db93d3 --- /dev/null +++ b/util/romcc/tests/fail_test7.c @@ -0,0 +1,10 @@ + + +static void hlt(void) +{ +} + +static void main(void) +{ + &hlt; +} diff --git a/util/romcc/tests/fail_test8.c b/util/romcc/tests/fail_test8.c new file mode 100644 index 0000000000..10ade55f75 --- /dev/null +++ b/util/romcc/tests/fail_test8.c @@ -0,0 +1,10 @@ + + +static void hlt(void) +{ +} + +static void main(void) +{ + hlt; +} |