From c7c5258c587b38508cd855ff2488a842503233eb Mon Sep 17 00:00:00 2001 From: Airtz <72342006+Airtz@users.noreply.github.com> Date: Fri, 20 Jun 2025 01:23:40 +0200 Subject: [PATCH 1/6] Update check_expr.cpp --- src/check_expr.cpp | 167 ++++++++++++++++++++------------------------- 1 file changed, 74 insertions(+), 93 deletions(-) diff --git a/src/check_expr.cpp b/src/check_expr.cpp index 335b82f1a..6ee6de146 100644 --- a/src/check_expr.cpp +++ b/src/check_expr.cpp @@ -3086,126 +3086,107 @@ gb_internal void check_shift(CheckerContext *c, Operand *x, Operand *y, Ast *nod GB_ASSERT(node->kind == Ast_BinaryExpr); ast_node(be, BinaryExpr, node); - ExactValue x_val = {}; - if (x->mode == Addressing_Constant) { - x_val = exact_value_to_integer(x->value); - } - - bool x_is_untyped = is_type_untyped(x->type); - if (!(is_type_integer(x->type) || (x_is_untyped && x_val.kind == ExactValue_Integer))) { - gbString err_str = expr_to_string(x->expr); - error(node, "Shifted operand '%s' must be an integer", err_str); - gb_string_free(err_str); - x->mode = Addressing_Invalid; - return; - } - - if (is_type_unsigned(y->type)) { - - } else if (is_type_untyped(y->type)) { + bool y_is_untyped = is_type_untyped(y->type); + if (y_is_untyped) { convert_to_typed(c, y, t_untyped_integer); if (y->mode == Addressing_Invalid) { x->mode = Addressing_Invalid; return; } - } else { - gbString err_str = expr_to_string(y->expr); - error(node, "Shift amount '%s' must be an unsigned integer", err_str); - gb_string_free(err_str); + } else if (!is_type_unsigned(y->type)) { + gbString y_str = expr_to_string(y->expr); + error(y->expr, "Shift amount '%s' must be an unsigned integer", y_str); + gb_string_free(y_str); x->mode = Addressing_Invalid; return; } + bool x_is_untyped = is_type_untyped(x->type); + if (!(x_is_untyped || is_type_integer(x->type))) { + gbString x_str = expr_to_string(x->expr); + error(x->expr, "Shifted operand '%s' must be an integer", x_str); + gb_string_free(x_str); + x->mode = Addressing_Invalid; + return; + } + + if (y->mode == Addressing_Constant) { + if (big_int_is_neg(&y->value.value_integer)) { + gbString y_str = expr_to_string(y->expr); + error(y->expr, "Shift amount '%s' must be positive", y_str); + gb_string_free(y_str); + x->mode = Addressing_Invalid; + return; + } + + BigInt max_shift = {}; + big_int_from_u64(&max_shift, MAX_BIG_INT_SHIFT); + + if (big_int_cmp(&y->value.value_integer, &max_shift) > 0) { + gbString y_str = expr_to_string(y->expr); + error(y->expr, "Shift amount '%s' must be <= %u", y_str, MAX_BIG_INT_SHIFT); + gb_string_free(y_str); + x->mode = Addressing_Invalid; + return; + } + + if (x->mode == Addressing_Constant) { + if (x_is_untyped) { + convert_to_typed(c, x, t_untyped_integer); + if (x->mode == Addressing_Invalid) { + return; + } + + x->expr = node; + x->value = exact_value_shift(be->op.kind, exact_value_to_integer(x->value), exact_value_to_integer(y->value)); - if (x->mode == Addressing_Constant) { - if (y->mode == Addressing_Constant) { - ExactValue y_val = exact_value_to_integer(y->value); - if (y_val.kind != ExactValue_Integer) { - gbString err_str = expr_to_string(y->expr); - error(node, "Shift amount '%s' must be an unsigned integer", err_str); - gb_string_free(err_str); - x->mode = Addressing_Invalid; return; } - BigInt max_shift = {}; - big_int_from_u64(&max_shift, MAX_BIG_INT_SHIFT); - - if (big_int_cmp(&y_val.value_integer, &max_shift) > 0) { - gbString err_str = expr_to_string(y->expr); - error(node, "Shift amount too large: '%s'", err_str); - gb_string_free(err_str); - x->mode = Addressing_Invalid; - return; - } - - if (!is_type_integer(x->type)) { - // NOTE(bill): It could be an untyped float but still representable - // as an integer - x->type = t_untyped_integer; - } - x->expr = node; - x->value = exact_value_shift(be->op.kind, x_val, y_val); + x->value = exact_value_shift(be->op.kind, x->value, y->value); + check_is_expressible(c, x, x->type); - if (is_type_typed(x->type)) { - check_is_expressible(c, x, x->type); - } return; } - TokenPos pos = ast_token(x->expr).pos; - if (x_is_untyped) { - if (x->expr != nullptr) { - x->expr->tav.is_lhs = true; - } - x->mode = Addressing_Value; - if (type_hint) { - if (is_type_integer(type_hint)) { - convert_to_typed(c, x, type_hint); - } else { - gbString x_str = expr_to_string(x->expr); - gbString to_type = type_to_string(type_hint); - error(node, "Conversion of shifted operand '%s' to '%s' is not allowed", x_str, to_type); - gb_string_free(x_str); - gb_string_free(to_type); - x->mode = Addressing_Invalid; - } - } else if (!is_type_integer(x->type)) { - gbString x_str = expr_to_string(x->expr); - error(node, "Non-integer shifted operand '%s' is not allowed", x_str); - gb_string_free(x_str); - x->mode = Addressing_Invalid; - } - // x->value = x_val; - return; + if (y_is_untyped) { + convert_to_typed(c, y, t_uint); } - } - if (y->mode == Addressing_Constant && big_int_is_neg(&y->value.value_integer)) { - gbString err_str = expr_to_string(y->expr); - error(node, "Shift amount cannot be negative: '%s'", err_str); - gb_string_free(err_str); - } - - if (!is_type_integer(x->type)) { - gbString err_str = expr_to_string(x->expr); - error(node, "Shift operand '%s' must be an integer", err_str); - gb_string_free(err_str); - x->mode = Addressing_Invalid; return; } - if (is_type_untyped(y->type)) { - convert_to_typed(c, y, t_uint); + if (x->mode == Addressing_Constant) { + if (x_is_untyped) { + Type *def_type = default_type(t_untyped_integer); + if (type_hint) { + if (is_type_integer(type_hint)) { + convert_to_typed(c, x, type_hint); + } else if (is_type_any(type_hint)) { + convert_to_typed(c, x, def_type); + } else { + gbString x_str = expr_to_string(x->expr); + gbString type_str = type_to_string(type_hint); + error(x->expr, "Shifted operand '%s' cannot convert to non-integer type '%s'", x_str, type_str); + gb_string_free(x_str); + gb_string_free(type_str); + x->mode = Addressing_Invalid; + return; + } + } else { + convert_to_typed(c, x, def_type); + } + if (x->mode == Addressing_Invalid) { + return; + } + } + + x->mode = Addressing_Value; } - - x->mode = Addressing_Value; } - - gb_internal bool check_is_castable_to(CheckerContext *c, Operand *operand, Type *y) { if (check_is_assignable_to(c, operand, y)) { return true; From 7c5b5618e8fb27589d6ae14b217dd0288a6621e2 Mon Sep 17 00:00:00 2001 From: Airtz <72342006+Airtz@users.noreply.github.com> Date: Fri, 20 Jun 2025 04:49:39 +0200 Subject: [PATCH 2/6] `check_is_expressible` instead of `convert_to_typed` when there is no `type_hint` --- src/check_expr.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/check_expr.cpp b/src/check_expr.cpp index 6ee6de146..7cf4ef83a 100644 --- a/src/check_expr.cpp +++ b/src/check_expr.cpp @@ -3160,12 +3160,11 @@ gb_internal void check_shift(CheckerContext *c, Operand *x, Operand *y, Ast *nod if (x->mode == Addressing_Constant) { if (x_is_untyped) { - Type *def_type = default_type(t_untyped_integer); if (type_hint) { if (is_type_integer(type_hint)) { convert_to_typed(c, x, type_hint); } else if (is_type_any(type_hint)) { - convert_to_typed(c, x, def_type); + convert_to_typed(c, x, default_type(t_untyped_integer)); } else { gbString x_str = expr_to_string(x->expr); gbString type_str = type_to_string(type_hint); @@ -3176,7 +3175,7 @@ gb_internal void check_shift(CheckerContext *c, Operand *x, Operand *y, Ast *nod return; } } else { - convert_to_typed(c, x, def_type); + check_is_expressible(c, x, default_type(t_untyped_integer)); } if (x->mode == Addressing_Invalid) { return; From e374ace10db3874cc50e4b1c72d75a7f76b18119 Mon Sep 17 00:00:00 2001 From: RaphGL Date: Sat, 21 Jun 2025 12:12:13 -0100 Subject: [PATCH 3/6] added IS_SUPPORTED to core:sys/posix --- core/sys/posix/posix.odin | 2 ++ core/sys/posix/posix_other.odin | 10 ++++++++++ core/sys/posix/posix_unix.odin | 5 +++++ 3 files changed, 17 insertions(+) create mode 100644 core/sys/posix/posix_other.odin create mode 100644 core/sys/posix/posix_unix.odin diff --git a/core/sys/posix/posix.odin b/core/sys/posix/posix.odin index 1e6a0aa9b..3dcf36a5e 100644 --- a/core/sys/posix/posix.odin +++ b/core/sys/posix/posix.odin @@ -53,6 +53,8 @@ import "base:intrinsics" import "core:c" +IS_SUPPORTED :: _IS_SUPPORTED + result :: enum c.int { // Use `errno` and `strerror` for more information. FAIL = -1, diff --git a/core/sys/posix/posix_other.odin b/core/sys/posix/posix_other.odin new file mode 100644 index 000000000..88542c56b --- /dev/null +++ b/core/sys/posix/posix_other.odin @@ -0,0 +1,10 @@ +#+build !linux +#+build !darwin +#+build !netbsd +#+build !openbsd +#+build !freebsd +#+build !haiku +package posix + +_IS_SUPPORTED :: false + diff --git a/core/sys/posix/posix_unix.odin b/core/sys/posix/posix_unix.odin new file mode 100644 index 000000000..51580a655 --- /dev/null +++ b/core/sys/posix/posix_unix.odin @@ -0,0 +1,5 @@ +#+build linux, darwin, netbsd, openbsd, freebsd, haiku +package posix + +_IS_SUPPORTED :: true + From 109edbcec7db78400d15aefc7dc02b1ac0cd82b0 Mon Sep 17 00:00:00 2001 From: Michael Freundorfer Date: Sun, 22 Jun 2025 14:09:50 +0200 Subject: [PATCH 4/6] Fix invalid selector for acceleration structure --- vendor/darwin/Metal/MetalClasses.odin | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/vendor/darwin/Metal/MetalClasses.odin b/vendor/darwin/Metal/MetalClasses.odin index 2d681b0ee..2792cb119 100644 --- a/vendor/darwin/Metal/MetalClasses.odin +++ b/vendor/darwin/Metal/MetalClasses.odin @@ -4105,9 +4105,9 @@ AccelerationStructure_size :: #force_inline proc "c" (self: ^AccelerationStructu return msgSend(NS.UInteger, self, "size") } -@(objc_type=AccelerationStructure, objc_name="getResourceID") -AccelerationStructure_getResourceID :: #force_inline proc "c" (self: ^AccelerationStructure) -> ResourceID { - return msgSend(ResourceID, self, "getResourceID") +@(objc_type=AccelerationStructure, objc_name="gpuResourceID") +AccelerationStructure_gpuResourceID :: #force_inline proc "c" (self: ^AccelerationStructure) -> ResourceID { + return msgSend(ResourceID, self, "gpuResourceID") } //////////////////////////////////////////////////////////////////////////////// From fc58158fb76ea76c59454b3d201dfac182a61e73 Mon Sep 17 00:00:00 2001 From: Brad Lewis <22850972+BradLewis@users.noreply.github.com> Date: Wed, 18 Jun 2025 21:45:15 -0400 Subject: [PATCH 5/6] Fix issue parsing `vendor/stb/image` with the `core:odin/parser` parser --- core/odin/parser/parser.odin | 6 ++---- tests/core/odin/test_parser.odin | 28 ++++++++++++++++++++++++++++ 2 files changed, 30 insertions(+), 4 deletions(-) diff --git a/core/odin/parser/parser.odin b/core/odin/parser/parser.odin index 7f1f4ca87..762410415 100644 --- a/core/odin/parser/parser.odin +++ b/core/odin/parser/parser.odin @@ -2307,6 +2307,7 @@ parse_operand :: proc(p: ^Parser, lhs: bool) -> ^ast.Expr { open := expect_token(p, .Open_Paren) p.expr_level += 1 expr := parse_expr(p, false) + skip_possible_newline(p) p.expr_level -= 1 close := expect_token(p, .Close_Paren) @@ -3526,6 +3527,7 @@ parse_binary_expr :: proc(p: ^Parser, lhs: bool, prec_in: int) -> ^ast.Expr { case .When: x := expr cond := parse_expr(p, lhs) + skip_possible_newline(p) else_tok := expect_token(p, .Else) y := parse_expr(p, lhs) te := ast.new(ast.Ternary_When_Expr, expr.pos, end_pos(p.prev_tok)) @@ -3780,10 +3782,6 @@ parse_import_decl :: proc(p: ^Parser, kind := Import_Decl_Kind.Standard) -> ^ast import_name.pos = p.curr_tok.pos } - if !is_using && is_blank_ident(import_name) { - error(p, import_name.pos, "illegal import name: '_'") - } - path := expect_token_after(p, .String, "import") decl := ast.new(ast.Import_Decl, tok.pos, end_pos(path)) diff --git a/tests/core/odin/test_parser.odin b/tests/core/odin/test_parser.odin index b4310104f..cc180f9af 100644 --- a/tests/core/odin/test_parser.odin +++ b/tests/core/odin/test_parser.odin @@ -66,3 +66,31 @@ Foo :: bit_field uint { ok := parser.parse_file(&p, &file) testing.expect(t, ok, "bad parse") } + +@test +test_parse_parser :: proc(t: ^testing.T) { + context.allocator = context.temp_allocator + runtime.DEFAULT_TEMP_ALLOCATOR_TEMP_GUARD() + + pkg, ok := parser.parse_package_from_path(ODIN_ROOT + "core/odin/parser") + + testing.expect(t, ok, "parser.parse_package_from_path failed") + + for key, value in pkg.files { + testing.expectf(t, value.syntax_error_count == 0, "%v should contain zero errors", key) + } +} + +@test +test_parse_stb_image :: proc(t: ^testing.T) { + context.allocator = context.temp_allocator + runtime.DEFAULT_TEMP_ALLOCATOR_TEMP_GUARD() + + pkg, ok := parser.parse_package_from_path(ODIN_ROOT + "vendor/stb/image") + + testing.expect(t, ok, "parser.parse_package_from_path failed") + + for key, value in pkg.files { + testing.expectf(t, value.syntax_error_count == 0, "%v should contain zero errors", key) + } +} From 277130111e941d30d73a3566e178c7f893d03113 Mon Sep 17 00:00:00 2001 From: Airtz Date: Sun, 22 Jun 2025 16:51:44 +0200 Subject: [PATCH 6/6] sign check error message update --- src/check_expr.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/check_expr.cpp b/src/check_expr.cpp index 7cf4ef83a..3c981d462 100644 --- a/src/check_expr.cpp +++ b/src/check_expr.cpp @@ -3113,7 +3113,7 @@ gb_internal void check_shift(CheckerContext *c, Operand *x, Operand *y, Ast *nod if (y->mode == Addressing_Constant) { if (big_int_is_neg(&y->value.value_integer)) { gbString y_str = expr_to_string(y->expr); - error(y->expr, "Shift amount '%s' must be positive", y_str); + error(y->expr, "Shift amount '%s' cannot be negative", y_str); gb_string_free(y_str); x->mode = Addressing_Invalid; return;