diff options
| -rw-r--r-- | .github/workflows/ci.yml | 13 | ||||
| -rw-r--r-- | core/os/os_darwin.odin | 3 | ||||
| -rw-r--r-- | src/build_settings.cpp | 14 | ||||
| -rw-r--r-- | src/checker.cpp | 13 | ||||
| -rw-r--r-- | src/llvm_backend_expr.cpp | 47 | ||||
| -rw-r--r-- | src/llvm_backend_general.cpp | 27 | ||||
| -rw-r--r-- | src/main.cpp | 32 | ||||
| -rw-r--r-- | src/types.cpp | 38 |
8 files changed, 121 insertions, 66 deletions
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 5da70931f..882c21e75 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -38,10 +38,6 @@ jobs: cd tests/vendor make timeout-minutes: 10 - - name: Odin issues tests - run: | - cd tests/issues - ./run.sh - name: Odin check examples/all for Linux i386 run: ./odin check examples/all -vet -strict-style -target:linux_i386 timeout-minutes: 10 @@ -91,11 +87,6 @@ jobs: cd tests/vendor make timeout-minutes: 10 - - name: Odin issues tests - run: | - cd tests/issues - ./run.sh - timeout-minutes: 10 - name: Odin check examples/all for Darwin arm64 run: ./odin check examples/all -vet -strict-style -target:darwin_arm64 timeout-minutes: 10 @@ -155,10 +146,6 @@ jobs: cd tests\vendor call build.bat timeout-minutes: 10 - - name: Odin issues tests - run: | - cd tests/issues - ./run.bat - name: core:math/big tests shell: cmd run: | diff --git a/core/os/os_darwin.odin b/core/os/os_darwin.odin index ac7376752..0a7d7e1fb 100644 --- a/core/os/os_darwin.odin +++ b/core/os/os_darwin.odin @@ -404,6 +404,9 @@ read :: proc(fd: Handle, data: []u8) -> (int, Errno) { if bytes_read == -1 { return bytes_read_total, 1 } + if bytes_read == 0 { + break + } bytes_read_total += bytes_read } diff --git a/src/build_settings.cpp b/src/build_settings.cpp index 02de22ec4..97ee9f2a3 100644 --- a/src/build_settings.cpp +++ b/src/build_settings.cpp @@ -298,17 +298,17 @@ struct BuildContext { bool ignore_microsoft_magic; bool linker_map_file; - bool use_separate_modules; - bool threaded_checker; + bool use_separate_modules; + bool threaded_checker; - bool show_debug_messages; + bool show_debug_messages; - bool copy_file_contents; + bool copy_file_contents; - bool disallow_rtti; + bool disallow_rtti; RelocMode reloc_mode; - bool disable_red_zone; + bool disable_red_zone; u32 cmd_doc_flags; @@ -326,7 +326,7 @@ struct BuildContext { BlockingMutex target_features_mutex; StringSet target_features_set; String target_features_string; - + String minimum_os_version_string; }; gb_global BuildContext build_context = {0}; diff --git a/src/checker.cpp b/src/checker.cpp index 5bdc5b010..dd81e2a48 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -1673,7 +1673,18 @@ bool could_entity_be_lazy(Entity *e, DeclInfo *d) { } void add_entity_and_decl_info(CheckerContext *c, Ast *identifier, Entity *e, DeclInfo *d, bool is_exported) { - GB_ASSERT(identifier->kind == Ast_Ident); + if (identifier == nullptr) { + // NOTE(bill): Should only happen on errors + error(e->token, "Invalid variable declaration"); + return; + } + if (identifier->kind != Ast_Ident) { + // NOTE(bill): This is a safety check + gbString s = expr_to_string(identifier); + error(identifier, "A variable declaration must be an identifer, got %s", s); + gb_string_free(s); + return; + } GB_ASSERT(e != nullptr && d != nullptr); GB_ASSERT(identifier->Ident.token.string == e->token.string); diff --git a/src/llvm_backend_expr.cpp b/src/llvm_backend_expr.cpp index f26b990ff..05a9fdfbf 100644 --- a/src/llvm_backend_expr.cpp +++ b/src/llvm_backend_expr.cpp @@ -1952,34 +1952,33 @@ lbValue lb_emit_conv(lbProcedure *p, lbValue value, Type *t) { Type *dt = t; GB_ASSERT(is_type_struct(st) || is_type_raw_union(st)); - String field_name = lookup_subtype_polymorphic_field(t, src_type); - if (field_name.len > 0) { - // NOTE(bill): It can be casted - Selection sel = lookup_field(st, field_name, false, true); - if (sel.entity != nullptr) { - if (st_is_ptr) { - lbValue res = lb_emit_deep_field_gep(p, value, sel); - Type *rt = res.type; + Selection sel = {}; + sel.index.allocator = heap_allocator(); + defer (array_free(&sel.index)); + if (lookup_subtype_polymorphic_selection(t, src_type, &sel)) { + if (sel.entity == nullptr) { + GB_PANIC("invalid subtype cast %s -> ", type_to_string(src_type), type_to_string(t)); + } + if (st_is_ptr) { + lbValue res = lb_emit_deep_field_gep(p, value, sel); + Type *rt = res.type; + if (!are_types_identical(rt, dt) && are_types_identical(type_deref(rt), dt)) { + res = lb_emit_load(p, res); + } + return res; + } else { + if (is_type_pointer(value.type)) { + Type *rt = value.type; if (!are_types_identical(rt, dt) && are_types_identical(type_deref(rt), dt)) { - res = lb_emit_load(p, res); - } - return res; - } else { - if (is_type_pointer(value.type)) { - Type *rt = value.type; - if (!are_types_identical(rt, dt) && are_types_identical(type_deref(rt), dt)) { - value = lb_emit_load(p, value); - } else { - value = lb_emit_deep_field_gep(p, value, sel); - return lb_emit_load(p, value); - } + value = lb_emit_load(p, value); + } else { + value = lb_emit_deep_field_gep(p, value, sel); + return lb_emit_load(p, value); } + } - return lb_emit_deep_field_ev(p, value, sel); + return lb_emit_deep_field_ev(p, value, sel); - } - } else { - GB_PANIC("invalid subtype cast %s.%.*s", type_to_string(src_type), LIT(field_name)); } } } diff --git a/src/llvm_backend_general.cpp b/src/llvm_backend_general.cpp index 18cdd196d..87f8afa05 100644 --- a/src/llvm_backend_general.cpp +++ b/src/llvm_backend_general.cpp @@ -383,16 +383,27 @@ Type *lb_addr_type(lbAddr const &addr) { if (addr.addr.value == nullptr) { return nullptr; } - if (addr.kind == lbAddr_Map) { - Type *t = base_type(addr.map.type); - GB_ASSERT(is_type_map(t)); - return t->Map.value; - } - if (addr.kind == lbAddr_Swizzle) { + switch (addr.kind) { + case lbAddr_Map: + { + Type *t = base_type(addr.map.type); + GB_ASSERT(is_type_map(t)); + return t->Map.value; + } + case lbAddr_Swizzle: return addr.swizzle.type; - } - if (addr.kind == lbAddr_SwizzleLarge) { + case lbAddr_SwizzleLarge: return addr.swizzle_large.type; + case lbAddr_Context: + if (addr.ctx.sel.index.count > 0) { + Type *t = t_context; + for_array(i, addr.ctx.sel.index) { + GB_ASSERT(is_type_struct(t)); + t = base_type(t)->Struct.fields[addr.ctx.sel.index[i]]->type; + } + return t; + } + break; } return type_deref(addr.addr.type); } diff --git a/src/main.cpp b/src/main.cpp index 9ceedbb7a..b75137613 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -481,9 +481,9 @@ i32 linker_stage(lbGenerator *gen) { if (build_context.metrics.os == TargetOs_darwin) { // This sets a requirement of Mountain Lion and up, but the compiler doesn't work without this limit. - // NOTE: If you change this (although this minimum is as low as you can go with Odin working) - // make sure to also change the 'mtriple' param passed to 'opt' - if (build_context.metrics.arch == TargetArch_arm64) { + if (build_context.minimum_os_version_string.len) { + link_settings = gb_string_append_fmt(link_settings, " -mmacosx-version-min=%.*s ", LIT(build_context.minimum_os_version_string)); + } else if (build_context.metrics.arch == TargetArch_arm64) { link_settings = gb_string_appendc(link_settings, " -mmacosx-version-min=12.0.0 "); } else { link_settings = gb_string_appendc(link_settings, " -mmacosx-version-min=10.12.0 "); @@ -624,6 +624,7 @@ enum BuildFlagKind { BuildFlag_ExtraAssemblerFlags, BuildFlag_Microarch, BuildFlag_TargetFeatures, + BuildFlag_MinimumOSVersion, BuildFlag_RelocMode, BuildFlag_DisableRedZone, @@ -752,7 +753,7 @@ void did_you_mean_flag(String flag) { string_to_lower(&name); if (name == "opt") { - gb_printf_err("`-opt` is an unrecognized option. Did you mean `-o`?"); + gb_printf_err("`-opt` is an unrecognized option. Did you mean `-o`?\n"); return; } gb_printf_err("Unknown flag: '%.*s'\n", LIT(flag)); @@ -797,6 +798,7 @@ bool parse_build_flags(Array<String> args) { add_flag(&build_flags, BuildFlag_ExtraAssemblerFlags, str_lit("extra-assembler-flags"), BuildFlagParam_String, Command__does_build); add_flag(&build_flags, BuildFlag_Microarch, str_lit("microarch"), BuildFlagParam_String, Command__does_build); add_flag(&build_flags, BuildFlag_TargetFeatures, str_lit("target-features"), BuildFlagParam_String, Command__does_build); + add_flag(&build_flags, BuildFlag_MinimumOSVersion, str_lit("minimum-os-version"), BuildFlagParam_String, Command__does_build); add_flag(&build_flags, BuildFlag_RelocMode, str_lit("reloc-mode"), BuildFlagParam_String, Command__does_build); add_flag(&build_flags, BuildFlag_DisableRedZone, str_lit("disable-red-zone"), BuildFlagParam_None, Command__does_build); @@ -1361,6 +1363,11 @@ bool parse_build_flags(Array<String> args) { string_to_lower(&build_context.target_features_string); break; } + case BuildFlag_MinimumOSVersion: { + GB_ASSERT(value.kind == ExactValue_String); + build_context.minimum_os_version_string = value.value_string; + break; + } case BuildFlag_RelocMode: { GB_ASSERT(value.kind == ExactValue_String); String v = value.value_string; @@ -1972,12 +1979,6 @@ void print_show_help(String const arg0, String const &command) { print_usage_line(2, "Example: -out:foo.exe"); print_usage_line(0, ""); - print_usage_line(1, "-opt:<integer>"); - print_usage_line(2, "Set the optimization level for compilation"); - print_usage_line(2, "Accepted values: 0, 1, 2, 3"); - print_usage_line(2, "Example: -opt:2"); - print_usage_line(0, ""); - print_usage_line(1, "-o:<string>"); print_usage_line(2, "Set the optimization mode for compilation"); print_usage_line(2, "Accepted values: minimal, size, speed"); @@ -2039,8 +2040,8 @@ void print_show_help(String const arg0, String const &command) { print_usage_line(3, "import \"shared:foo\""); print_usage_line(0, ""); - print_usage_line(1, "-define:<name>=<expression>"); - print_usage_line(2, "Defines a global constant with a value"); + print_usage_line(1, "-define:<name>=<value>"); + print_usage_line(2, "Defines a scalar boolean, integer or string as global constant"); print_usage_line(2, "Example: -define:SPAM=123"); print_usage_line(2, "To use: #config(SPAM, default_value)"); print_usage_line(0, ""); @@ -2141,6 +2142,12 @@ void print_show_help(String const arg0, String const &command) { } if (run_or_build) { + print_usage_line(1, "-minimum-os-version:<string>"); + print_usage_line(2, "Sets the minimum OS version targeted by the application"); + print_usage_line(2, "e.g. -minimum-os-version:12.0.0"); + print_usage_line(2, "(Only used when target is Darwin)"); + print_usage_line(0, ""); + print_usage_line(1, "-extra-linker-flags:<string>"); print_usage_line(2, "Adds extra linker specific flags in a string"); print_usage_line(0, ""); @@ -2149,7 +2156,6 @@ void print_show_help(String const arg0, String const &command) { print_usage_line(2, "Adds extra assembler specific flags in a string"); print_usage_line(0, ""); - print_usage_line(1, "-microarch:<string>"); print_usage_line(2, "Specifies the specific micro-architecture for the build in a string"); print_usage_line(2, "Examples:"); diff --git a/src/types.cpp b/src/types.cpp index fec324bf4..b9f2b375f 100644 --- a/src/types.cpp +++ b/src/types.cpp @@ -2526,6 +2526,44 @@ String lookup_subtype_polymorphic_field(Type *dst, Type *src) { return str_lit(""); } +bool lookup_subtype_polymorphic_selection(Type *dst, Type *src, Selection *sel) { + Type *prev_src = src; + // Type *prev_dst = dst; + src = base_type(type_deref(src)); + // dst = base_type(type_deref(dst)); + bool src_is_ptr = src != prev_src; + // bool dst_is_ptr = dst != prev_dst; + + GB_ASSERT(is_type_struct(src) || is_type_union(src)); + for_array(i, src->Struct.fields) { + Entity *f = src->Struct.fields[i]; + if (f->kind == Entity_Variable && f->flags & EntityFlags_IsSubtype) { + if (are_types_identical(dst, f->type)) { + array_add(&sel->index, cast(i32)i); + sel->entity = f; + return true; + } + if (src_is_ptr && is_type_pointer(dst)) { + if (are_types_identical(type_deref(dst), f->type)) { + array_add(&sel->index, cast(i32)i); + sel->indirect = true; + sel->entity = f; + return true; + } + } + if ((f->flags & EntityFlag_Using) != 0 && is_type_struct(f->type)) { + String name = lookup_subtype_polymorphic_field(dst, f->type); + if (name.len > 0) { + array_add(&sel->index, cast(i32)i); + return lookup_subtype_polymorphic_selection(dst, f->type, sel); + } + } + } + } + return false; +} + + Type *strip_type_aliasing(Type *x) { |