mirror of
https://github.com/odin-lang/Odin.git
synced 2026-02-15 07:43:13 +00:00
Prevent cast on pointer to union types
This commit is contained in:
@@ -1,4 +1,11 @@
|
||||
#import "fmt.odin";
|
||||
#import "atomic.odin";
|
||||
#import "hash.odin";
|
||||
#import "math.odin";
|
||||
#import "mem.odin";
|
||||
#import "opengl.odin";
|
||||
#import "os.odin";
|
||||
#import "utf8.odin";
|
||||
|
||||
|
||||
main :: proc() {
|
||||
|
||||
@@ -381,7 +381,7 @@ Raw_Dynamic_Array :: struct #ordered {
|
||||
};
|
||||
|
||||
Raw_Dynamic_Map :: struct #ordered {
|
||||
hashes: [...]int,
|
||||
hashes: [dynamic]int,
|
||||
entries: Raw_Dynamic_Array,
|
||||
};
|
||||
|
||||
|
||||
@@ -140,7 +140,7 @@ buffer_write_type :: proc(buf: ^Buffer, ti: ^Type_Info) {
|
||||
if info.params == nil {
|
||||
buffer_write_string(buf, "()");
|
||||
} else {
|
||||
t := cast(^Tuple)info.params;
|
||||
t := union_cast(^Tuple)info.params;
|
||||
buffer_write_string(buf, "(");
|
||||
for type, i in t.types {
|
||||
if i > 0 { buffer_write_string(buf, ", "); }
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
is_signed :: proc(info: ^Type_Info) -> bool {
|
||||
if is_integer(info) {
|
||||
i := cast(^Type_Info.Integer)info;
|
||||
i := union_cast(^Type_Info.Integer)info;
|
||||
return i.signed;
|
||||
}
|
||||
if is_float(info) {
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -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"), \
|
||||
|
||||
Reference in New Issue
Block a user