aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGinger Bill <bill@gingerbill.org>2017-02-14 17:24:56 +0000
committerGinger Bill <bill@gingerbill.org>2017-02-14 17:24:56 +0000
commit2722de65b7e2397c0b968abc4c652711095ec7ca (patch)
tree49a6d32999893197566cde6b65263d37e03618e8 /src
parent8b5e3428a1e569abf763e63e859754e767e107e7 (diff)
Prevent `cast` on pointer to union types
Diffstat (limited to 'src')
-rw-r--r--src/check_expr.c17
-rw-r--r--src/parser.c6
-rw-r--r--src/tokenizer.c2
3 files changed, 19 insertions, 6 deletions
diff --git a/src/check_expr.c b/src/check_expr.c
index a93165574..9ea57bd21 100644
--- a/src/check_expr.c
+++ b/src/check_expr.c
@@ -1071,7 +1071,7 @@ i64 check_array_or_map_count(Checker *c, AstNode *e, bool is_map) {
}
Operand o = {0};
if (e->kind == AstNode_UnaryExpr &&
- e->UnaryExpr.op.kind == Token_Question) {
+ e->UnaryExpr.op.kind == Token_Ellipsis) {
return -1;
}
@@ -1966,10 +1966,21 @@ bool check_is_castable_to(Checker *c, Operand *operand, Type *y) {
// Cast between pointers
if (is_type_pointer(src) && is_type_pointer(dst)) {
+ Type *s = base_type(type_deref(src));
+ if (is_type_union(s)) {
+ // NOTE(bill): Should the error be here?!
+ // NOTE(bill): This error should suppress the next casting error as it's at the same position
+ gbString xs = type_to_string(x);
+ gbString ys = type_to_string(y);
+ error_node(operand->expr, "Cannot cast from a union pointer `%s` to `%s`, try using `union_cast` or cast to a `rawptr`", xs, ys);
+ gb_string_free(ys);
+ gb_string_free(xs);
+ return false;
+ }
return true;
}
- // (u)int <-> pointer
+ // (u)int <-> rawptr
if (is_type_int_or_uint(src) && is_type_rawptr(dst)) {
return true;
}
@@ -4494,7 +4505,7 @@ ExprKind check__expr_base(Checker *c, Operand *o, AstNode *node, Type *type_hint
if (cl->type->kind == AstNode_ArrayType && cl->type->ArrayType.count != NULL) {
AstNode *count = cl->type->ArrayType.count;
if (count->kind == AstNode_UnaryExpr &&
- count->UnaryExpr.op.kind == Token_Question) {
+ count->UnaryExpr.op.kind == Token_Ellipsis) {
type = make_type_array(c->allocator, check_type(c, cl->type->ArrayType.elem), -1);
is_to_be_determined_array_count = true;
}
diff --git a/src/parser.c b/src/parser.c
index fedde531e..987022068 100644
--- a/src/parser.c
+++ b/src/parser.c
@@ -2574,8 +2574,8 @@ AstNode *parse_type_or_ident(AstFile *f) {
AstNode *count_expr = NULL;
bool is_vector = false;
- if (f->curr_token.kind == Token_Question) {
- count_expr = ast_unary_expr(f, expect_token(f, Token_Question), NULL);
+ if (f->curr_token.kind == Token_Ellipsis) {
+ count_expr = ast_unary_expr(f, expect_token(f, Token_Ellipsis), NULL);
} else if (f->curr_token.kind == Token_vector) {
next_token(f);
if (f->curr_token.kind != Token_CloseBracket) {
@@ -2586,7 +2586,7 @@ AstNode *parse_type_or_ident(AstFile *f) {
syntax_error(f->curr_token, "Vector type missing count");
}
is_vector = true;
- } else if (f->curr_token.kind == Token_Ellipsis) {
+ } else if (f->curr_token.kind == Token_dynamic) {
next_token(f);
expect_token(f, Token_CloseBracket);
return ast_dynamic_array_type(f, token, parse_type(f));
diff --git a/src/tokenizer.c b/src/tokenizer.c
index fc85fd927..68ab270be 100644
--- a/src/tokenizer.c
+++ b/src/tokenizer.c
@@ -99,6 +99,8 @@ TOKEN_KIND(Token__KeywordBegin, "_KeywordBegin"), \
TOKEN_KIND(Token_raw_union, "raw_union"), \
TOKEN_KIND(Token_enum, "enum"), \
TOKEN_KIND(Token_vector, "vector"), \
+ TOKEN_KIND(Token_static, "static"), \
+ TOKEN_KIND(Token_dynamic, "dynamic"), \
TOKEN_KIND(Token_map, "map"), \
TOKEN_KIND(Token_using, "using"), \
TOKEN_KIND(Token_no_alias, "no_alias"), \