diff --git a/src/check_builtin.cpp b/src/check_builtin.cpp index 79afef7cd..2770ac430 100644 --- a/src/check_builtin.cpp +++ b/src/check_builtin.cpp @@ -3867,10 +3867,6 @@ gb_internal bool check_builtin_procedure(CheckerContext *c, Operand *operand, As default: GB_PANIC("Invalid type"); break; } - if (type_hint != nullptr && check_is_castable_to(c, operand, type_hint)) { - operand->type = type_hint; - } - break; } @@ -3887,7 +3883,7 @@ gb_internal bool check_builtin_procedure(CheckerContext *c, Operand *operand, As if (is_type_untyped(x->type)) { if (x->mode == Addressing_Constant) { if (is_type_numeric(x->type)) { - x->type = t_untyped_complex; + x->type = t_untyped_quaternion; } } else{ convert_to_typed(c, x, t_quaternion256); @@ -3923,10 +3919,6 @@ gb_internal bool check_builtin_procedure(CheckerContext *c, Operand *operand, As default: GB_PANIC("Invalid type"); break; } - if (type_hint != nullptr && check_is_castable_to(c, operand, type_hint)) { - operand->type = type_hint; - } - break; } diff --git a/src/exact_value.cpp b/src/exact_value.cpp index 2f82a52cf..5c436fee6 100644 --- a/src/exact_value.cpp +++ b/src/exact_value.cpp @@ -1019,6 +1019,10 @@ gb_internal bool compare_exact_values(TokenKind op, ExactValue x, ExactValue y) f64 b = x.value_complex->imag; f64 c = y.value_complex->real; f64 d = y.value_complex->imag; + if (isnan(a) || isnan(b) || isnan(c) || isnan(d)) { + return op == Token_NotEq; + } + switch (op) { case Token_CmpEq: return cmp_f64(a, c) == 0 && cmp_f64(b, d) == 0; case Token_NotEq: return cmp_f64(a, c) != 0 || cmp_f64(b, d) != 0; @@ -1026,6 +1030,29 @@ gb_internal bool compare_exact_values(TokenKind op, ExactValue x, ExactValue y) break; } + case ExactValue_Quaternion: { + Quaternion256 a = *x.value_quaternion; + Quaternion256 b = *y.value_quaternion; + if (isnan(a.real) || isnan(a.imag) || isnan(a.jmag) || isnan(a.kmag) || + isnan(b.real) || isnan(b.imag) || isnan(b.jmag) || isnan(b.kmag)) { + return op == Token_NotEq; + } + + switch (op) { + case Token_CmpEq: + return cmp_f64(a.real, b.real) == 0 && + cmp_f64(a.imag, b.imag) == 0 && + cmp_f64(a.jmag, b.jmag) == 0 && + cmp_f64(a.kmag, b.kmag) == 0; + case Token_NotEq: + return cmp_f64(a.real, b.real) != 0 || + cmp_f64(a.imag, b.imag) != 0 || + cmp_f64(a.jmag, b.jmag) != 0 || + cmp_f64(a.kmag, b.kmag) != 0; + } + break; + } + case ExactValue_String: { String a = x.value_string; String b = y.value_string; diff --git a/tests/internal/test_nan_comparison.odin b/tests/internal/test_nan_comparison.odin index 5740be477..b47cc9dfc 100644 --- a/tests/internal/test_nan_comparison.odin +++ b/tests/internal/test_nan_comparison.odin @@ -89,3 +89,100 @@ compare_variable_nans_f64 :: proc(t: ^testing.T) { testing.expect_value(t, NaN > NaN, false) testing.expect_value(t, NaN >= NaN, false) } + +// A complex or quaternion compares componentwise, so a NaN in any one lane makes the whole +// comparison fail. The folded form used to disagree: `cmp_f64` is `(a>b)-(a