فهرست منبع

Fix #4508 for abs, min, max (#4516)

* Fix #4508 for abs, min, max and the rest of the builtins.

None of these segfault now:
```odin
package bug

main :: proc() {
	p :: proc() {}

	// _ = len(p())
	// _ = cap(p())

	// _ = size_of(p())
	// _ = align_of(p())

	// T :: struct {}
	// _ = offset_of(p())
	// _ = offset_of(T, p())
	// _ = offset_of(p(), foo)
	// _ = offset_of(p(), "")

	// _ = type_of(p())
	// _ = type_info_of(p())
	// _ = typeid_of(p())

	// A: [4]int
	// _ = swizzle(p())    //  :: proc(x: [N]T, indices: ..int) -> [len(indices)]T ---
	// _ = swizzle(A, p()) //  :: proc(x: [N]T, indices: ..int) -> [len(indices)]T ---

	// _ = complex(p(), p())
	// _ = quaternion(p(), p(), p(), p())
	// _ = quaternion(w=p(), x=p(), y=p(), z=p())

	// _ = real(p())
	// _ = imag(p())
	// _ = jmag(p())
	// _ = kmag(p())
	// _ = conj(p())

	// _ = expand_values(p())

	// _ = min(p())
	// _ = max(p())
	// _ = abs(p())
	// _ = clamp(p(), p(), p())

	// _ = soa_zip(p())
	// _ = soa_unzip(p())
}
```
Jeroen van Rijn 9 ماه پیش
والد
کامیت
0e3572947a
1فایلهای تغییر یافته به همراه38 افزوده شده و 1 حذف شده
  1. 38 1
      src/check_builtin.cpp

+ 38 - 1
src/check_builtin.cpp

@@ -2551,6 +2551,10 @@ gb_internal bool check_builtin_procedure(CheckerContext *c, Operand *operand, As
 
 	case BuiltinProc_swizzle: {
 		// swizzle :: proc(v: [N]T, ..int) -> [M]T
+		if (!operand->type) {
+			return false;
+		}
+
 		Type *original_type = operand->type;
 		Type *type = base_type(original_type);
 		i64 max_count = 0;
@@ -2908,6 +2912,10 @@ gb_internal bool check_builtin_procedure(CheckerContext *c, Operand *operand, As
 		// imag :: proc(x: type) -> float_type
 
 		Operand *x = operand;
+		if (!x->type) {
+			return false;
+		}
+
 		if (is_type_untyped(x->type)) {
 			if (x->mode == Addressing_Constant) {
 				if (is_type_numeric(x->type)) {
@@ -2968,6 +2976,10 @@ gb_internal bool check_builtin_procedure(CheckerContext *c, Operand *operand, As
 		// kmag :: proc(x: type) -> float_type
 
 		Operand *x = operand;
+		if (!x->type) {
+			return false;
+		}
+
 		if (is_type_untyped(x->type)) {
 			if (x->mode == Addressing_Constant) {
 				if (is_type_numeric(x->type)) {
@@ -3017,6 +3029,10 @@ gb_internal bool check_builtin_procedure(CheckerContext *c, Operand *operand, As
 	case BuiltinProc_conj: {
 		// conj :: proc(x: type) -> type
 		Operand *x = operand;
+		if (!x->type) {
+			return false;
+		}
+
 		Type *t = x->type;
 		Type *elem = core_array_type(t);
 		
@@ -3057,10 +3073,14 @@ gb_internal bool check_builtin_procedure(CheckerContext *c, Operand *operand, As
 	}
 
 	case BuiltinProc_expand_values: {
+		if (!operand->type) {
+			return false;
+		}
+
 		Type *type = base_type(operand->type);
 		if (!is_type_struct(type) && !is_type_array(type)) {
 			gbString type_str = type_to_string(operand->type);
-			error(call, "Expected a struct or array type, got '%s'", type_str);
+			error(call, "Expected a struct or array type to 'expand_values', got '%s'", type_str);
 			gb_string_free(type_str);
 			return false;
 		}
@@ -3096,8 +3116,13 @@ gb_internal bool check_builtin_procedure(CheckerContext *c, Operand *operand, As
 
 		check_multi_expr_or_type(c, operand, ce->args[0]);
 
+		if (!operand->type) {
+			return false;
+		}
+
 		Type *original_type = operand->type;
 		Type *type = base_type(operand->type);
+
 		if (operand->mode == Addressing_Type && is_type_enumerated_array(type)) {
 			// Okay
 		} else if (!is_type_ordered(type) || !(is_type_numeric(type) || is_type_string(type))) {
@@ -3268,6 +3293,10 @@ gb_internal bool check_builtin_procedure(CheckerContext *c, Operand *operand, As
 
 		check_multi_expr_or_type(c, operand, ce->args[0]);
 
+		if (!operand->type) {
+			return false;
+		}
+
 		Type *original_type = operand->type;
 		Type *type = base_type(operand->type);
 
@@ -3443,6 +3472,10 @@ gb_internal bool check_builtin_procedure(CheckerContext *c, Operand *operand, As
 
 	case BuiltinProc_abs: {
 		// abs :: proc(n: numeric) -> numeric
+		if (!operand->type) {
+			return false;
+		}
+
 		if (!(is_type_numeric(operand->type) && !is_type_array(operand->type))) {
 			gbString type_str = type_to_string(operand->type);
 			error(call, "Expected a numeric type to 'abs', got '%s'", type_str);
@@ -3498,6 +3531,10 @@ gb_internal bool check_builtin_procedure(CheckerContext *c, Operand *operand, As
 
 	case BuiltinProc_clamp: {
 		// clamp :: proc(a, min, max: ordered) -> ordered
+		if (!operand->type) {
+			return false;
+		}
+
 		Type *type = operand->type;
 		if (!is_type_ordered(type) || !(is_type_numeric(type) || is_type_string(type))) {
 			gbString type_str = type_to_string(operand->type);