mirror of
https://github.com/odin-lang/Odin.git
synced 2026-06-04 09:44:40 +00:00
Fix issues with exact integer bounds and remove dead code
This commit is contained in:
@@ -346,9 +346,9 @@ bool find_or_generate_polymorphic_procedure(Checker *c, Entity *base_entity, Typ
|
||||
{
|
||||
Scope *s = entity->scope;
|
||||
while (s != nullptr && s->file == nullptr) {
|
||||
file = s->file;
|
||||
s = s->parent;
|
||||
}
|
||||
file = s->file;
|
||||
}
|
||||
|
||||
ProcedureInfo proc_info = {};
|
||||
@@ -1232,6 +1232,7 @@ bool check_binary_op(Checker *c, Operand *o, Token op) {
|
||||
|
||||
}
|
||||
|
||||
|
||||
bool check_representable_as_constant(Checker *c, ExactValue in_value, Type *type, ExactValue *out_value) {
|
||||
if (in_value.kind == ExactValue_Invalid) {
|
||||
// NOTE(bill): There's already been an error
|
||||
@@ -1259,16 +1260,10 @@ bool check_representable_as_constant(Checker *c, ExactValue in_value, Type *type
|
||||
|
||||
i64 i = v.value_integer;
|
||||
u64 u = bit_cast<u64>(i);
|
||||
i64 s = 8*type_size_of(type);
|
||||
u64 umax = ~cast(u64)0ull;
|
||||
if (s < 64) {
|
||||
umax = (1ull << cast(u64)s) - 1ull;
|
||||
} else {
|
||||
// IMPORTANT TODO(bill): I NEED A PROPER BIG NUMBER LIBRARY THAT CAN SUPPORT 128 bit floats
|
||||
s = 64;
|
||||
}
|
||||
i64 imin = -1ll << (s-1ll);
|
||||
i64 imax = (1ll << (s-1ll))-1ll;
|
||||
i64 bit_size = type_size_of(type);
|
||||
u64 umax = unsigned_integer_maxs[bit_size];
|
||||
i64 imin = signed_integer_mins[bit_size];
|
||||
i64 imax = signed_integer_maxs[bit_size];
|
||||
|
||||
switch (type->Basic.kind) {
|
||||
case Basic_rune:
|
||||
@@ -1283,7 +1278,7 @@ bool check_representable_as_constant(Checker *c, ExactValue in_value, Type *type
|
||||
case Basic_u32:
|
||||
case Basic_uint:
|
||||
case Basic_uintptr:
|
||||
return !(u < 0ull || u > umax);
|
||||
return 0ull <= u && u <= umax;
|
||||
|
||||
case Basic_u64:
|
||||
return 0ull <= i;
|
||||
@@ -1488,7 +1483,7 @@ void check_comparison(Checker *c, Operand *x, Operand *y, TokenKind op) {
|
||||
if (x->mode == Addressing_Type && y->mode == Addressing_Type) {
|
||||
bool comp = are_types_identical(x->type, y->type);
|
||||
switch (op) {
|
||||
case Token_CmpEq: comp = comp; break;
|
||||
case Token_CmpEq: /* comp = comp; */ break;
|
||||
case Token_NotEq: comp = !comp; break;
|
||||
}
|
||||
x->mode = Addressing_Constant;
|
||||
@@ -3722,7 +3717,7 @@ break;
|
||||
#endif
|
||||
case BuiltinProc_expand_to_tuple: {
|
||||
Type *type = base_type(operand->type);
|
||||
if (!is_type_struct(type) &
|
||||
if (!is_type_struct(type) &&
|
||||
!is_type_union(type)) {
|
||||
gbString type_str = type_to_string(operand->type);
|
||||
error(call, "Expected a struct or union type, got '%s'", type_str);
|
||||
|
||||
@@ -190,7 +190,6 @@ Type *check_assignment_variable(Checker *c, Operand *lhs, Operand *rhs) {
|
||||
|
||||
// NOTE(bill): Ignore assignments to '_'
|
||||
if (is_blank_ident(node)) {
|
||||
add_entity_definition(&c->info, node, nullptr);
|
||||
check_assignment(c, rhs, nullptr, str_lit("assignment to '_' identifier"));
|
||||
if (rhs->mode == Addressing_Invalid) {
|
||||
return nullptr;
|
||||
@@ -269,8 +268,7 @@ Type *check_assignment_variable(Checker *c, Operand *lhs, Operand *rhs) {
|
||||
}
|
||||
i64 imax = 1ll << (cast(i64)lhs_bits-1ll);
|
||||
|
||||
bool ok = false;
|
||||
ok = !(u < 0 || u > umax);
|
||||
bool ok = !(u < 0 || u > umax);
|
||||
|
||||
if (ok) {
|
||||
return rhs->type;
|
||||
|
||||
@@ -178,8 +178,7 @@ void check_struct_fields(Checker *c, AstNode *node, Array<Entity *> *fields, Arr
|
||||
|
||||
Token name_token = name->Ident.token;
|
||||
|
||||
Entity *field = nullptr;
|
||||
field = alloc_entity_field(c->context.scope, name_token, type, is_using, field_src_index);
|
||||
Entity *field = alloc_entity_field(c->context.scope, name_token, type, is_using, field_src_index);
|
||||
field->Variable.default_value = value;
|
||||
field->Variable.default_is_nil = default_is_nil;
|
||||
|
||||
|
||||
@@ -859,6 +859,7 @@ void add_entity_definition(CheckerInfo *i, AstNode *identifier, Entity *entity)
|
||||
// NOTE(bill): Identifier has already been handled
|
||||
return;
|
||||
}
|
||||
GB_ASSERT(entity != nullptr);
|
||||
|
||||
identifier->Ident.entity = entity;
|
||||
entity->identifier = identifier;
|
||||
|
||||
@@ -241,6 +241,39 @@ String i64_to_string(i64 a, char *out_buf, isize out_buf_len) {
|
||||
}
|
||||
|
||||
|
||||
gb_global i64 const signed_integer_mins[] = {
|
||||
0,
|
||||
-128ll,
|
||||
-32768ll,
|
||||
0,
|
||||
-2147483648ll,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
-9223372036854775808ll,
|
||||
};
|
||||
gb_global i64 const signed_integer_maxs[] = {
|
||||
0,
|
||||
127ll,
|
||||
32767ll,
|
||||
0,
|
||||
2147483647ll,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
9223372036854775807ll,
|
||||
};
|
||||
gb_global u64 const unsigned_integer_maxs[] = {
|
||||
0,
|
||||
255ull,
|
||||
65535ull,
|
||||
0,
|
||||
4294967295ull,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
18446744073709551615ull,
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -413,9 +413,10 @@ ExactValue exact_unary_operator_value(TokenKind op, ExactValue v, i32 precision)
|
||||
// NOTE(bill): unsigned integers will be negative and will need to be
|
||||
// limited to the types precision
|
||||
// IMPORTANT NOTE(bill): Max precision is 64 bits as that's how integers are stored
|
||||
if (0 < precision && precision < 64) {
|
||||
i = i & ~(-1ll << precision);
|
||||
}
|
||||
i = i & unsigned_integer_maxs[precision/8];
|
||||
// if (0 < precision && precision < 64) {
|
||||
// i = i & ~(-1ll << precision);
|
||||
// }
|
||||
|
||||
return exact_value_i64(i);
|
||||
}
|
||||
@@ -438,7 +439,7 @@ failure:
|
||||
}
|
||||
|
||||
// NOTE(bill): Make sure things are evaluated in correct order
|
||||
i32 exact_value_order(ExactValue v) {
|
||||
i32 exact_value_order(ExactValue const &v) {
|
||||
switch (v.kind) {
|
||||
case ExactValue_Invalid:
|
||||
return 0;
|
||||
@@ -612,11 +613,21 @@ error:; // NOTE(bill): MSVC accepts this??? apparently you cannot declare variab
|
||||
return empty_exact_value;
|
||||
}
|
||||
|
||||
gb_inline ExactValue exact_value_add(ExactValue x, ExactValue y) { return exact_binary_operator_value(Token_Add, x, y); }
|
||||
gb_inline ExactValue exact_value_sub(ExactValue x, ExactValue y) { return exact_binary_operator_value(Token_Sub, x, y); }
|
||||
gb_inline ExactValue exact_value_mul(ExactValue x, ExactValue y) { return exact_binary_operator_value(Token_Mul, x, y); }
|
||||
gb_inline ExactValue exact_value_quo(ExactValue x, ExactValue y) { return exact_binary_operator_value(Token_Quo, x, y); }
|
||||
gb_inline ExactValue exact_value_shift(TokenKind op, ExactValue x, ExactValue y) { return exact_binary_operator_value(op, x, y); }
|
||||
gb_inline ExactValue exact_value_add(ExactValue const &x, ExactValue const &y) {
|
||||
return exact_binary_operator_value(Token_Add, x, y);
|
||||
}
|
||||
gb_inline ExactValue exact_value_sub(ExactValue const &x, ExactValue const &y) {
|
||||
return exact_binary_operator_value(Token_Sub, x, y);
|
||||
}
|
||||
gb_inline ExactValue exact_value_mul(ExactValue const &x, ExactValue const &y) {
|
||||
return exact_binary_operator_value(Token_Mul, x, y);
|
||||
}
|
||||
gb_inline ExactValue exact_value_quo(ExactValue const &x, ExactValue const &y) {
|
||||
return exact_binary_operator_value(Token_Quo, x, y);
|
||||
}
|
||||
gb_inline ExactValue exact_value_shift(TokenKind op, ExactValue const &x, ExactValue const &y) {
|
||||
return exact_binary_operator_value(op, x, y);
|
||||
}
|
||||
|
||||
|
||||
i32 cmp_f64(f64 a, f64 b) {
|
||||
|
||||
25
src/ir.cpp
25
src/ir.cpp
@@ -684,6 +684,7 @@ Type *ir_type(irValue *value) {
|
||||
|
||||
|
||||
bool ir_type_has_default_values(Type *t) {
|
||||
#if 1
|
||||
switch (t->kind) {
|
||||
case Type_Named:
|
||||
return ir_type_has_default_values(t->Named.base);
|
||||
@@ -709,7 +710,7 @@ bool ir_type_has_default_values(Type *t) {
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -1913,7 +1914,7 @@ irValue *ir_address_from_load_or_generate_local(irProcedure *proc, irValue *val)
|
||||
}
|
||||
|
||||
|
||||
Type *ir_addr_type(irAddr addr) {
|
||||
Type *ir_addr_type(irAddr const &addr) {
|
||||
if (addr.addr == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
@@ -1955,7 +1956,7 @@ irValue *ir_insert_dynamic_map_key_and_value(irProcedure *proc, irValue *addr, T
|
||||
|
||||
|
||||
|
||||
irValue *ir_addr_store(irProcedure *proc, irAddr addr, irValue *value) {
|
||||
irValue *ir_addr_store(irProcedure *proc, irAddr const &addr, irValue *value) {
|
||||
if (addr.addr == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
@@ -2033,7 +2034,7 @@ irValue *ir_addr_store(irProcedure *proc, irAddr addr, irValue *value) {
|
||||
return ir_emit_store(proc, addr.addr, v);
|
||||
}
|
||||
|
||||
irValue *ir_addr_load(irProcedure *proc, irAddr addr) {
|
||||
irValue *ir_addr_load(irProcedure *proc, irAddr const &addr) {
|
||||
if (addr.addr == nullptr) {
|
||||
GB_PANIC("Illegal addr load");
|
||||
return nullptr;
|
||||
@@ -2139,7 +2140,7 @@ irValue *ir_addr_load(irProcedure *proc, irAddr addr) {
|
||||
return ir_emit_load(proc, addr.addr);
|
||||
}
|
||||
|
||||
irValue *ir_addr_get_ptr(irProcedure *proc, irAddr addr) {
|
||||
irValue *ir_addr_get_ptr(irProcedure *proc, irAddr const &addr) {
|
||||
if (addr.addr == nullptr) {
|
||||
GB_PANIC("Illegal addr -> nullptr");
|
||||
return nullptr;
|
||||
@@ -2157,7 +2158,7 @@ irValue *ir_addr_get_ptr(irProcedure *proc, irAddr addr) {
|
||||
}
|
||||
|
||||
irValue *ir_build_addr_ptr(irProcedure *proc, AstNode *expr) {
|
||||
irAddr addr = ir_build_addr(proc, expr);
|
||||
irAddr const &addr = ir_build_addr(proc, expr);
|
||||
return ir_addr_get_ptr(proc, addr);
|
||||
}
|
||||
|
||||
@@ -4553,7 +4554,7 @@ irValue *ir_build_builtin_proc(irProcedure *proc, AstNode *expr, TypeAndValue tv
|
||||
case BuiltinProc_clear: {
|
||||
ir_emit_comment(proc, str_lit("clear"));
|
||||
Type *original_type = type_of_expr(proc->module->info, ce->args[0]);
|
||||
irAddr addr = ir_build_addr(proc, ce->args[0]);
|
||||
irAddr const &addr = ir_build_addr(proc, ce->args[0]);
|
||||
irValue *ptr = addr.addr;
|
||||
if (is_double_pointer(ir_type(ptr))) {
|
||||
ptr = ir_addr_load(proc, addr);
|
||||
@@ -4710,7 +4711,7 @@ irValue *ir_build_builtin_proc(irProcedure *proc, AstNode *expr, TypeAndValue tv
|
||||
|
||||
case BuiltinProc_swizzle: {
|
||||
ir_emit_comment(proc, str_lit("swizzle.begin"));
|
||||
irAddr addr = ir_build_addr(proc, ce->args[0]);
|
||||
irAddr const &addr = ir_build_addr(proc, ce->args[0]);
|
||||
isize index_count = ce->args.count-1;
|
||||
if (index_count == 0) {
|
||||
return ir_addr_load(proc, addr);
|
||||
@@ -5559,7 +5560,7 @@ irAddr ir_build_addr(irProcedure *proc, AstNode *expr) {
|
||||
|
||||
|
||||
if (sel.entity->type->kind == Type_BitFieldValue) {
|
||||
irAddr addr = ir_build_addr(proc, se->expr);
|
||||
irAddr const &addr = ir_build_addr(proc, se->expr);
|
||||
Type *bft = type_deref(ir_addr_type(addr));
|
||||
if (sel.index.count == 1) {
|
||||
GB_ASSERT(is_type_bit_field(bft));
|
||||
@@ -6118,7 +6119,7 @@ irAddr ir_build_addr(irProcedure *proc, AstNode *expr) {
|
||||
return ir_addr(nullptr);
|
||||
}
|
||||
|
||||
void ir_build_assign_op(irProcedure *proc, irAddr lhs, irValue *value, TokenKind op) {
|
||||
void ir_build_assign_op(irProcedure *proc, irAddr const &lhs, irValue *value, TokenKind op) {
|
||||
irValue *old_value = ir_addr_load(proc, lhs);
|
||||
Type *type = ir_type(old_value);
|
||||
|
||||
@@ -6629,7 +6630,7 @@ void ir_build_stmt_internal(irProcedure *proc, AstNode *node) {
|
||||
if (s->op.kind == Token_Dec) {
|
||||
op = Token_Sub;
|
||||
}
|
||||
irAddr addr = ir_build_addr(proc, s->expr);
|
||||
irAddr const &addr = ir_build_addr(proc, s->expr);
|
||||
ir_build_assign_op(proc, addr, v_one, op);
|
||||
case_end;
|
||||
#endif
|
||||
@@ -7018,7 +7019,7 @@ void ir_build_stmt_internal(irProcedure *proc, AstNode *node) {
|
||||
case Type_Map: {
|
||||
is_map = true;
|
||||
gbAllocator a = proc->module->allocator;
|
||||
irAddr addr = ir_build_addr(proc, rs->expr);
|
||||
irAddr const &addr = ir_build_addr(proc, rs->expr);
|
||||
irValue *map = ir_addr_get_ptr(proc, addr);
|
||||
if (is_type_pointer(type_deref(ir_addr_type(addr)))) {
|
||||
map = ir_addr_load(proc, addr);
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
#define USE_THREADED_PARSER 1
|
||||
// #define NO_ARRAY_BOUNDS_CHECK
|
||||
#define NO_POINTER_ARITHMETIC
|
||||
|
||||
|
||||
@@ -2959,6 +2959,11 @@ AstNode *parse_field_list(AstFile *f, isize *name_count_, u32 allowed_flags, Tok
|
||||
syntax_error(f->curr_token, "Default parameters can only be applied to single values");
|
||||
}
|
||||
|
||||
if (allowed_flags == FieldFlag_Struct && default_value != nullptr) {
|
||||
syntax_error(default_value, "Default parameters are not allowed for structs");
|
||||
default_value = nullptr;
|
||||
}
|
||||
|
||||
if (type != nullptr && type->kind == AstNode_Ellipsis) {
|
||||
if (seen_ellipsis) syntax_error(type, "Extra variadic parameter after ellipsis");
|
||||
seen_ellipsis = true;
|
||||
@@ -4275,7 +4280,7 @@ ParseFileError parse_files(Parser *p, String init_filename) {
|
||||
p->init_fullpath = init_fullpath;
|
||||
|
||||
// IMPORTANT TODO(bill): Figure out why this doesn't work on *nix sometimes
|
||||
#if USE_THREADED_PARSER && defined(GB_SYSTEM_WINDOWS)
|
||||
#if defined(GB_SYSTEM_WINDOWS)
|
||||
isize thread_count = gb_max(build_context.thread_count, 1);
|
||||
if (thread_count > 1) {
|
||||
isize volatile curr_import_index = 0;
|
||||
|
||||
@@ -1085,7 +1085,7 @@ bool is_type_polymorphic(Type *t) {
|
||||
|
||||
|
||||
bool type_has_undef(Type *t) {
|
||||
t = base_type(t);
|
||||
// t = base_type(t);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user