Browse Source

Fix issues with exact integer bounds and remove dead code

gingerBill 7 years ago
parent
commit
e597a8d72e
10 changed files with 85 additions and 43 deletions
  1. 9 14
      src/check_expr.cpp
  2. 1 3
      src/check_stmt.cpp
  3. 1 2
      src/check_type.cpp
  4. 1 0
      src/checker.cpp
  5. 33 0
      src/common.cpp
  6. 20 9
      src/exact_value.cpp
  7. 13 12
      src/ir.cpp
  8. 0 1
      src/main.cpp
  9. 6 1
      src/parser.cpp
  10. 1 1
      src/types.cpp

+ 9 - 14
src/check_expr.cpp

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

+ 1 - 3
src/check_stmt.cpp

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

+ 1 - 2
src/check_type.cpp

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

+ 1 - 0
src/checker.cpp

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

+ 33 - 0
src/common.cpp

@@ -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
src/exact_value.cpp

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

+ 13 - 12
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);

+ 0 - 1
src/main.cpp

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

+ 6 - 1
src/parser.cpp

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

+ 1 - 1
src/types.cpp

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