diff options
author | Teddy <[email protected]> | 2014-04-11 16:04:48 +0800 |
---|---|---|
committer | Teddy <[email protected]> | 2014-04-11 16:04:48 +0800 |
commit | e2a62314728202e71a4daa2b7ff418994334fb83 (patch) | |
tree | fc08f679900bed17070c520bddc74546c396bbf9 | |
parent | a19c85b2b0c70db4e87efe129da38ea870f8971c (diff) |
array length checking
-rw-r--r-- | semantics.c | 24 | ||||
-rw-r--r-- | testcases/array_complete.c | 4 | ||||
-rw-r--r-- | testcases/function_returns_function.c | 1 | ||||
-rw-r--r-- | testcases/incomp_param.c | 5 | ||||
-rw-r--r-- | testcases/pass.c | 4 | ||||
-rw-r--r-- | testcases/ref.c | 4 |
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); +} |