diff options
author | Leo Tenenbaum <pommicket@gmail.com> | 2020-03-11 15:57:42 -0400 |
---|---|---|
committer | Leo Tenenbaum <pommicket@gmail.com> | 2020-03-11 15:57:42 -0400 |
commit | 0b16c903741e2f6178c07531ab13026c3de6ce5b (patch) | |
tree | 40e8b20204618edc705638cc36620df88a859c7d | |
parent | 4cdee65cadb4f6e714fe30945ed9080e191618f6 (diff) |
prevent varargs[i] from being an lvalue
-rw-r--r-- | main.c | 4 | ||||
-rw-r--r-- | parse.c | 5 | ||||
-rw-r--r-- | test.toc | 14 | ||||
-rw-r--r-- | types.c | 4 |
4 files changed, 16 insertions, 11 deletions
@@ -8,10 +8,8 @@ /* TODO: -make sure varargs[i] isn't an lvalue -make sure you can't have a variadic function pointer -make sure varargs works with inference passing varargs variable to varargs function +make sure varargs works with inference #foreign variadic fns EXPR_VALs don't always need temp variables where @@ -2200,7 +2200,10 @@ static Status parse_expr(Parser *p, Expression *e, Token *end) { } success: e->where.end = t->token; - assert(t->token == end); + if (t->token != end) { + tokr_err(t, "Did not expect this stuff after expression. Did you forget a semicolon?"); + return false; + } if (e->kind == EXPR_FN) { e->fn->where = e->where; @@ -1,19 +1,19 @@ #include "std/io.toc"; -s ::= struct(x::..) { -}; - -f ::= fn(x : ..) int { +g ::= fn(x : ..) int { total := 0; - for _, i := x { - total += i * (x[0] as int); + for e, i := x { + total += i * (e as int); } total }; +f ::= fn(x : ..) int { + g(x) +}; main ::= fn() { - puti(f(5)); + puti(g(5)); puti(f(5,6)); @@ -303,6 +303,10 @@ static Status expr_must_lval(Expression *e) { case BINARY_AT_INDEX: if (!expr_must_lval(e->binary.lhs)) return false; + if (type_is_builtin(&e->binary.lhs->type, BUILTIN_VARARGS)) { + err_print(e->where, "Cannot set or take address of vararg."); + return false; + } return true; case BINARY_DOT: return true; default: break; |