aboutsummaryrefslogtreecommitdiff
path: root/util/romcc
diff options
context:
space:
mode:
Diffstat (limited to 'util/romcc')
-rw-r--r--util/romcc/Makefile7
-rw-r--r--util/romcc/romcc.c33
-rw-r--r--util/romcc/tests/fail_test6.c11
-rw-r--r--util/romcc/tests/fail_test7.c10
-rw-r--r--util/romcc/tests/fail_test8.c10
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;
+}