Fix issues with exact integer bounds and remove dead code

This commit is contained in:
gingerBill
2018-05-13 17:38:35 +01:00
parent de9a4b5164
commit e597a8d72e
10 changed files with 85 additions and 43 deletions
+9 -14
View File
@@ -346,9 +346,9 @@ bool find_or_generate_polymorphic_procedure(Checker *c, Entity *base_entity, Typ
{ {
Scope *s = entity->scope; Scope *s = entity->scope;
while (s != nullptr && s->file == nullptr) { while (s != nullptr && s->file == nullptr) {
file = s->file;
s = s->parent; s = s->parent;
} }
file = s->file;
} }
ProcedureInfo proc_info = {}; 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) { bool check_representable_as_constant(Checker *c, ExactValue in_value, Type *type, ExactValue *out_value) {
if (in_value.kind == ExactValue_Invalid) { if (in_value.kind == ExactValue_Invalid) {
// NOTE(bill): There's already been an error // 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; i64 i = v.value_integer;
u64 u = bit_cast<u64>(i); u64 u = bit_cast<u64>(i);
i64 s = 8*type_size_of(type); i64 bit_size = type_size_of(type);
u64 umax = ~cast(u64)0ull; u64 umax = unsigned_integer_maxs[bit_size];
if (s < 64) { i64 imin = signed_integer_mins[bit_size];
umax = (1ull << cast(u64)s) - 1ull; i64 imax = signed_integer_maxs[bit_size];
} 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;
switch (type->Basic.kind) { switch (type->Basic.kind) {
case Basic_rune: case Basic_rune:
@@ -1283,7 +1278,7 @@ bool check_representable_as_constant(Checker *c, ExactValue in_value, Type *type
case Basic_u32: case Basic_u32:
case Basic_uint: case Basic_uint:
case Basic_uintptr: case Basic_uintptr:
return !(u < 0ull || u > umax); return 0ull <= u && u <= umax;
case Basic_u64: case Basic_u64:
return 0ull <= i; 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) { if (x->mode == Addressing_Type && y->mode == Addressing_Type) {
bool comp = are_types_identical(x->type, y->type); bool comp = are_types_identical(x->type, y->type);
switch (op) { switch (op) {
case Token_CmpEq: comp = comp; break; case Token_CmpEq: /* comp = comp; */ break;
case Token_NotEq: comp = !comp; break; case Token_NotEq: comp = !comp; break;
} }
x->mode = Addressing_Constant; x->mode = Addressing_Constant;
@@ -3722,7 +3717,7 @@ break;
#endif #endif
case BuiltinProc_expand_to_tuple: { case BuiltinProc_expand_to_tuple: {
Type *type = base_type(operand->type); Type *type = base_type(operand->type);
if (!is_type_struct(type) & if (!is_type_struct(type) &&
!is_type_union(type)) { !is_type_union(type)) {
gbString type_str = type_to_string(operand->type); gbString type_str = type_to_string(operand->type);
error(call, "Expected a struct or union type, got '%s'", type_str); error(call, "Expected a struct or union type, got '%s'", type_str);
+1 -3
View File
@@ -190,7 +190,6 @@ Type *check_assignment_variable(Checker *c, Operand *lhs, Operand *rhs) {
// NOTE(bill): Ignore assignments to '_' // NOTE(bill): Ignore assignments to '_'
if (is_blank_ident(node)) { if (is_blank_ident(node)) {
add_entity_definition(&c->info, node, nullptr);
check_assignment(c, rhs, nullptr, str_lit("assignment to '_' identifier")); check_assignment(c, rhs, nullptr, str_lit("assignment to '_' identifier"));
if (rhs->mode == Addressing_Invalid) { if (rhs->mode == Addressing_Invalid) {
return nullptr; return nullptr;
@@ -269,8 +268,7 @@ Type *check_assignment_variable(Checker *c, Operand *lhs, Operand *rhs) {
} }
i64 imax = 1ll << (cast(i64)lhs_bits-1ll); i64 imax = 1ll << (cast(i64)lhs_bits-1ll);
bool ok = false; bool ok = !(u < 0 || u > umax);
ok = !(u < 0 || u > umax);
if (ok) { if (ok) {
return rhs->type; return rhs->type;
+1 -2
View File
@@ -178,8 +178,7 @@ void check_struct_fields(Checker *c, AstNode *node, Array<Entity *> *fields, Arr
Token name_token = name->Ident.token; Token name_token = name->Ident.token;
Entity *field = nullptr; Entity *field = alloc_entity_field(c->context.scope, name_token, type, is_using, field_src_index);
field = alloc_entity_field(c->context.scope, name_token, type, is_using, field_src_index);
field->Variable.default_value = value; field->Variable.default_value = value;
field->Variable.default_is_nil = default_is_nil; field->Variable.default_is_nil = default_is_nil;
+1
View File
@@ -859,6 +859,7 @@ void add_entity_definition(CheckerInfo *i, AstNode *identifier, Entity *entity)
// NOTE(bill): Identifier has already been handled // NOTE(bill): Identifier has already been handled
return; return;
} }
GB_ASSERT(entity != nullptr);
identifier->Ident.entity = entity; identifier->Ident.entity = entity;
entity->identifier = identifier; entity->identifier = identifier;
+33
View File
@@ -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,
};
+20 -9
View File
@@ -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 // NOTE(bill): unsigned integers will be negative and will need to be
// limited to the types precision // limited to the types precision
// IMPORTANT NOTE(bill): Max precision is 64 bits as that's how integers are stored // IMPORTANT NOTE(bill): Max precision is 64 bits as that's how integers are stored
if (0 < precision && precision < 64) { i = i & unsigned_integer_maxs[precision/8];
i = i & ~(-1ll << precision); // if (0 < precision && precision < 64) {
} // i = i & ~(-1ll << precision);
// }
return exact_value_i64(i); return exact_value_i64(i);
} }
@@ -438,7 +439,7 @@ failure:
} }
// NOTE(bill): Make sure things are evaluated in correct order // 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) { switch (v.kind) {
case ExactValue_Invalid: case ExactValue_Invalid:
return 0; return 0;
@@ -612,11 +613,21 @@ error:; // NOTE(bill): MSVC accepts this??? apparently you cannot declare variab
return empty_exact_value; 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_add(ExactValue const &x, ExactValue const &y) {
gb_inline ExactValue exact_value_sub(ExactValue x, ExactValue y) { return exact_binary_operator_value(Token_Sub, x, y); } return exact_binary_operator_value(Token_Add, 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_sub(ExactValue const &x, ExactValue const &y) {
gb_inline ExactValue exact_value_shift(TokenKind op, ExactValue x, ExactValue y) { return exact_binary_operator_value(op, x, 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) { i32 cmp_f64(f64 a, f64 b) {
+13 -12
View File
@@ -684,6 +684,7 @@ Type *ir_type(irValue *value) {
bool ir_type_has_default_values(Type *t) { bool ir_type_has_default_values(Type *t) {
#if 1
switch (t->kind) { switch (t->kind) {
case Type_Named: case Type_Named:
return ir_type_has_default_values(t->Named.base); return ir_type_has_default_values(t->Named.base);
@@ -709,7 +710,7 @@ bool ir_type_has_default_values(Type *t) {
} }
break; break;
} }
#endif
return false; 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) { if (addr.addr == nullptr) {
return 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) { if (addr.addr == nullptr) {
return 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); 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) { if (addr.addr == nullptr) {
GB_PANIC("Illegal addr load"); GB_PANIC("Illegal addr load");
return nullptr; return nullptr;
@@ -2139,7 +2140,7 @@ irValue *ir_addr_load(irProcedure *proc, irAddr addr) {
return ir_emit_load(proc, addr.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) { if (addr.addr == nullptr) {
GB_PANIC("Illegal addr -> nullptr"); GB_PANIC("Illegal addr -> nullptr");
return 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) { 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); 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: { case BuiltinProc_clear: {
ir_emit_comment(proc, str_lit("clear")); ir_emit_comment(proc, str_lit("clear"));
Type *original_type = type_of_expr(proc->module->info, ce->args[0]); 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; irValue *ptr = addr.addr;
if (is_double_pointer(ir_type(ptr))) { if (is_double_pointer(ir_type(ptr))) {
ptr = ir_addr_load(proc, addr); ptr = ir_addr_load(proc, addr);
@@ -4710,7 +4711,7 @@ irValue *ir_build_builtin_proc(irProcedure *proc, AstNode *expr, TypeAndValue tv
case BuiltinProc_swizzle: { case BuiltinProc_swizzle: {
ir_emit_comment(proc, str_lit("swizzle.begin")); 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; isize index_count = ce->args.count-1;
if (index_count == 0) { if (index_count == 0) {
return ir_addr_load(proc, addr); 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) { 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)); Type *bft = type_deref(ir_addr_type(addr));
if (sel.index.count == 1) { if (sel.index.count == 1) {
GB_ASSERT(is_type_bit_field(bft)); GB_ASSERT(is_type_bit_field(bft));
@@ -6118,7 +6119,7 @@ irAddr ir_build_addr(irProcedure *proc, AstNode *expr) {
return ir_addr(nullptr); 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); irValue *old_value = ir_addr_load(proc, lhs);
Type *type = ir_type(old_value); 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) { if (s->op.kind == Token_Dec) {
op = Token_Sub; 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); ir_build_assign_op(proc, addr, v_one, op);
case_end; case_end;
#endif #endif
@@ -7018,7 +7019,7 @@ void ir_build_stmt_internal(irProcedure *proc, AstNode *node) {
case Type_Map: { case Type_Map: {
is_map = true; is_map = true;
gbAllocator a = proc->module->allocator; 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); irValue *map = ir_addr_get_ptr(proc, addr);
if (is_type_pointer(type_deref(ir_addr_type(addr)))) { if (is_type_pointer(type_deref(ir_addr_type(addr)))) {
map = ir_addr_load(proc, addr); map = ir_addr_load(proc, addr);
-1
View File
@@ -1,4 +1,3 @@
#define USE_THREADED_PARSER 1
// #define NO_ARRAY_BOUNDS_CHECK // #define NO_ARRAY_BOUNDS_CHECK
#define NO_POINTER_ARITHMETIC #define NO_POINTER_ARITHMETIC
+6 -1
View File
@@ -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"); 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 (type != nullptr && type->kind == AstNode_Ellipsis) {
if (seen_ellipsis) syntax_error(type, "Extra variadic parameter after ellipsis"); if (seen_ellipsis) syntax_error(type, "Extra variadic parameter after ellipsis");
seen_ellipsis = true; seen_ellipsis = true;
@@ -4275,7 +4280,7 @@ ParseFileError parse_files(Parser *p, String init_filename) {
p->init_fullpath = init_fullpath; p->init_fullpath = init_fullpath;
// IMPORTANT TODO(bill): Figure out why this doesn't work on *nix sometimes // 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); isize thread_count = gb_max(build_context.thread_count, 1);
if (thread_count > 1) { if (thread_count > 1) {
isize volatile curr_import_index = 0; isize volatile curr_import_index = 0;
+1 -1
View File
@@ -1085,7 +1085,7 @@ bool is_type_polymorphic(Type *t) {
bool type_has_undef(Type *t) { bool type_has_undef(Type *t) {
t = base_type(t); // t = base_type(t);
return true; return true;
} }