diff options
| author | Laytan <laytanlaats@hotmail.com> | 2024-07-16 22:30:06 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-07-16 22:30:06 +0200 |
| commit | cb16d2ddaf5d70c39684c6ef2daa66f40619c1c6 (patch) | |
| tree | f6b29f25fd09d648e9772a2e5dfa0ea40c6f2ae7 /src/check_builtin.cpp | |
| parent | 0d881e1561d62065a6c702c3eabadc253a8f2bc6 (diff) | |
| parent | a6d1a2e46cb38df2583ba1d14be2516f16bba655 (diff) | |
Merge pull request #3934 from laytan/fix-saturating-intrinsics
fix `add_sat` and `sub_sat` intrinsics
Diffstat (limited to 'src/check_builtin.cpp')
| -rw-r--r-- | src/check_builtin.cpp | 43 |
1 files changed, 42 insertions, 1 deletions
diff --git a/src/check_builtin.cpp b/src/check_builtin.cpp index 26de3a112..b6b1f9874 100644 --- a/src/check_builtin.cpp +++ b/src/check_builtin.cpp @@ -4261,6 +4261,47 @@ gb_internal bool check_builtin_procedure(CheckerContext *c, Operand *operand, As case BuiltinProc_overflow_add: case BuiltinProc_overflow_sub: case BuiltinProc_overflow_mul: + { + Operand x = {}; + Operand y = {}; + check_expr(c, &x, ce->args[0]); + check_expr(c, &y, ce->args[1]); + if (x.mode == Addressing_Invalid) { + return false; + } + if (y.mode == Addressing_Invalid) { + return false; + } + convert_to_typed(c, &y, x.type); if (y.mode == Addressing_Invalid) return false; + convert_to_typed(c, &x, y.type); + if (is_type_untyped(x.type)) { + gbString xts = type_to_string(x.type); + error(x.expr, "Expected a typed integer for '%.*s', got %s", LIT(builtin_name), xts); + gb_string_free(xts); + return false; + } + if (!is_type_integer(x.type)) { + gbString xts = type_to_string(x.type); + error(x.expr, "Expected an integer for '%.*s', got %s", LIT(builtin_name), xts); + gb_string_free(xts); + return false; + } + Type *ct = core_type(x.type); + if (is_type_different_to_arch_endianness(ct)) { + GB_ASSERT(ct->kind == Type_Basic); + if (ct->Basic.flags & (BasicFlag_EndianLittle|BasicFlag_EndianBig)) { + gbString xts = type_to_string(x.type); + error(x.expr, "Expected an integer which does not specify the explicit endianness for '%.*s', got %s", LIT(builtin_name), xts); + gb_string_free(xts); + return false; + } + } + + operand->mode = Addressing_Value; + operand->type = make_optional_ok_type(default_type(x.type)); + } + break; + case BuiltinProc_add_sat: case BuiltinProc_sub_sat: { @@ -4300,7 +4341,7 @@ gb_internal bool check_builtin_procedure(CheckerContext *c, Operand *operand, As } operand->mode = Addressing_Value; - operand->type = make_optional_ok_type(default_type(x.type)); + operand->type = default_type(x.type); } break; |