From 7c3ce334d6914f73165eb66e253a2176c77d69d6 Mon Sep 17 00:00:00 2001 From: Jeroen van Rijn Date: Mon, 25 Nov 2024 15:27:35 +0100 Subject: 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()) } ``` --- src/check_builtin.cpp | 39 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 38 insertions(+), 1 deletion(-) (limited to 'src/check_builtin.cpp') diff --git a/src/check_builtin.cpp b/src/check_builtin.cpp index c86503093..ea902387b 100644 --- a/src/check_builtin.cpp +++ b/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); -- cgit v1.2.3