aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTeddy <ted.sybil@gmail.com>2014-04-13 18:27:30 +0800
committerTeddy <ted.sybil@gmail.com>2014-04-13 18:27:30 +0800
commit63d47979eff3736da8c479cf3eea6399c0179736 (patch)
tree79897af2697cb53e4c5df93dfd309edbb0a20f69
parentf881fd3eba1cafa1bea1f098ce8f383b4d6813ea (diff)
...
-rw-r--r--semantics.c16
-rw-r--r--semantics.h1
-rw-r--r--testcases/array_decl.c6
-rw-r--r--testcases/array_decl2.c7
4 files changed, 25 insertions, 5 deletions
diff --git a/semantics.c b/semantics.c
index 9013aac..27d5db7 100644
--- a/semantics.c
+++ b/semantics.c
@@ -21,7 +21,8 @@
} while (0)
/* pointer to function conversion (std 6.3.2/4) */
-#define FUNC_POINTER_CONV(t) \
+/* also convert array to pointer */
+#define POINTER_CONV(t, p) \
do { \
if ((t)->type == CFUNC) \
{ \
@@ -29,6 +30,13 @@
f->rec.ref = t; \
t = f; \
} \
+ else if ((t)->type == CARR) \
+ { \
+ CType_t a = ctype_create("", CPTR, p); \
+ a->rec.ref = t->rec.arr.elem; \
+ free(t); \
+ t = a; \
+ } \
} while (0)
#define CHECK_CVOID(name, ast) \
@@ -596,12 +604,12 @@ CVar_t semantics_params(CNode *p, CScope_t scope) {
#else
CTable_t tparams = ctable_create(bkdr_hash);
#endif
- FUNC_POINTER_CONV(params->type);
+ POINTER_CONV(params->type, p);
ctable_insert(tparams, params->name, params, 0);
for (p = p->next; p; p = p->next)
{
CVar_t var = semantics_p_decl(p, scope);
- FUNC_POINTER_CONV(var->type);
+ POINTER_CONV(var->type, p);
if (scope) /* params inside a function definition */
if (!ctable_insert(tparams, var->name, var, 0))
ERROR((var->ast, "redefinition of parameter '%s'", var->name));
@@ -1227,7 +1235,7 @@ ExpType semantics_exp(CNode *p, CScope_t scope) {
p->ext.type = lu->rec.type;
res.type = p->ext.type;
res.lval = res.type->type == CFUNC;
- FUNC_POINTER_CONV(res.type);
+ POINTER_CONV(res.type, p);
}
p->ext.is_const = 0;
}
diff --git a/semantics.h b/semantics.h
index 87cd345..b3cadaa 100644
--- a/semantics.h
+++ b/semantics.h
@@ -18,7 +18,6 @@ struct CVar {
CVar_t next; /* next in the linked list */
CType_t type;
int offset;
- int is_const;
CNode *ast;
};
diff --git a/testcases/array_decl.c b/testcases/array_decl.c
new file mode 100644
index 0000000..33973e5
--- /dev/null
+++ b/testcases/array_decl.c
@@ -0,0 +1,6 @@
+int f(int a[1][3][2]) {
+}
+int main() {
+ int a[3][3][2];
+ f(a);
+}
diff --git a/testcases/array_decl2.c b/testcases/array_decl2.c
new file mode 100644
index 0000000..d7f8a04
--- /dev/null
+++ b/testcases/array_decl2.c
@@ -0,0 +1,7 @@
+int f(int a[20][2][2]);
+int f(int a[1][3][2]) {
+}
+int main() {
+ int a[3][3][2];
+ f(a);
+}