aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTeddy <ted.sybil@gmail.com>2014-04-11 16:04:48 +0800
committerTeddy <ted.sybil@gmail.com>2014-04-11 16:04:48 +0800
commite2a62314728202e71a4daa2b7ff418994334fb83 (patch)
treefc08f679900bed17070c520bddc74546c396bbf9
parenta19c85b2b0c70db4e87efe129da38ea870f8971c (diff)
array length checking
-rw-r--r--semantics.c24
-rw-r--r--testcases/array_complete.c4
-rw-r--r--testcases/function_returns_function.c1
-rw-r--r--testcases/incomp_param.c5
-rw-r--r--testcases/pass.c4
-rw-r--r--testcases/ref.c4
6 files changed, 36 insertions, 6 deletions
diff --git a/semantics.c b/semantics.c
index b948031..3aba1c5 100644
--- a/semantics.c
+++ b/semantics.c
@@ -507,6 +507,11 @@ do { \
ERROR(ast); \
} while (0)
+#define IS_INT(tt) ((tt) == CINT || (tt) == CCHAR)
+#define IS_ARITH(tt) IS_INT(tt)
+#define IS_SCALAR(tt) (!((tt) == CUNION || (tt) == CSTRUCT))
+
+ExpType semantics_exp(CNode *, CScope_t);
CVar_t semantics_declr(CNode *p, CType_t type_spec, CScope_t scope, int func_chk) {
CVar_t type;
if (p->type == ID)
@@ -546,13 +551,25 @@ CVar_t semantics_declr(CNode *p, CType_t type_spec, CScope_t scope, int func_chk
case DECLR_ARR:
{
CType_t arr = ctype_create("", CARR, p); /* array declr */
+ CNode *rch = p->chd->next;
+ ExpType tl = semantics_exp(rch, scope);
if (!type_is_complete(type_spec))
{
sprintf(err_buff, "array type has incomplete element type");
ERROR(p);
}
+ if (!rch->ext.is_const)
+ {
+ sprintf(err_buff, "size of array must be a constant");
+ ERROR(p);
+ }
+ if (!IS_INT(tl.type->type))
+ {
+ sprintf(err_buff, "size of array has non-integer type");
+ ERROR(p);
+ }
arr->rec.arr.elem = type_spec;
- arr->rec.arr.len = p->chd->next->rec.intval;
+ arr->rec.arr.len = rch->ext.const_val;
type = semantics_declr(p->chd, arr, scope, 0);
}
break;
@@ -706,11 +723,6 @@ ExpType exp_check_aseq(ExpType lhs, ExpType rhs, CNode *ast) {
return lhs;
}
-#define IS_INT(tt) ((tt) == CINT || (tt) == CCHAR)
-#define IS_ARITH(tt) IS_INT(tt)
-#define IS_SCALAR(tt) (!((tt) == CUNION || (tt) == CSTRUCT))
-
-ExpType semantics_exp(CNode *, CScope_t);
ExpType semantics_cast(CNode *p, CScope_t scope) {
CNode *chd = p->chd->next;
diff --git a/testcases/array_complete.c b/testcases/array_complete.c
new file mode 100644
index 0000000..79c5c8a
--- /dev/null
+++ b/testcases/array_complete.c
@@ -0,0 +1,4 @@
+struct A arr[1];
+struct A {int x;};
+int main() {
+}
diff --git a/testcases/function_returns_function.c b/testcases/function_returns_function.c
new file mode 100644
index 0000000..e590ddb
--- /dev/null
+++ b/testcases/function_returns_function.c
@@ -0,0 +1 @@
+int main()() {}
diff --git a/testcases/incomp_param.c b/testcases/incomp_param.c
new file mode 100644
index 0000000..c1ece5f
--- /dev/null
+++ b/testcases/incomp_param.c
@@ -0,0 +1,5 @@
+int f(struct A a, int b) {
+
+}
+int main() {
+}
diff --git a/testcases/pass.c b/testcases/pass.c
index e762a5b..d70d9d8 100644
--- a/testcases/pass.c
+++ b/testcases/pass.c
@@ -90,6 +90,10 @@ int incomp(struct I a);
void (*bsd_signal(int sig, void (*func)(int a)))(int b);
+void array() {
+ int a[(1 + 1 == 2) * 2];
+}
+
struct Node n;
struct Node {int x, y;} n;
/* global forward declaration is ok */
diff --git a/testcases/ref.c b/testcases/ref.c
new file mode 100644
index 0000000..4644127
--- /dev/null
+++ b/testcases/ref.c
@@ -0,0 +1,4 @@
+int main() {
+ int a, b;
+ &(a + b);
+}