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

View File

@@ -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);

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;

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,
};

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
// 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) {

View File

@@ -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);

View File

@@ -1,4 +1,3 @@
#define USE_THREADED_PARSER 1
// #define NO_ARRAY_BOUNDS_CHECK
#define NO_POINTER_ARITHMETIC

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");
}
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;

View File

@@ -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;
}