From fa46bcb36864e6616ce4449965063f3b8720f8e1 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Fri, 6 Mar 2020 18:30:30 -0500 Subject: [PATCH] stage1: make get_optional_type more robust Now it will emit a compile error rather than crashing when the child type has not been resolved properly. Introduces `get_optional_type2` which should be used generally inside ir.cpp. Fix some std lib compile errors noticed by the provided test case. Thanks @LemonBoy for the test case. Closes #4377. Fixes #4374. --- lib/std/builtin.zig | 8 ++++---- src/analyze.cpp | 13 ++++++++++++- src/analyze.hpp | 1 + src/ir.cpp | 3 ++- test/stage1/behavior/type_info.zig | 5 +++++ 5 files changed, 24 insertions(+), 6 deletions(-) diff --git a/lib/std/builtin.zig b/lib/std/builtin.zig index a4f0ef269f..fa5b49db37 100644 --- a/lib/std/builtin.zig +++ b/lib/std/builtin.zig @@ -27,7 +27,7 @@ pub const Cpu = std.Target.Cpu; /// On non-Windows targets, this is `null`. pub const subsystem: ?SubSystem = blk: { if (@hasDecl(@This(), "explicit_subsystem")) break :blk explicit_subsystem; - switch (os) { + switch (os.tag) { .windows => { if (is_test) { break :blk SubSystem.Console; @@ -406,9 +406,9 @@ pub const Version = struct { min: Version, max: Version, - pub fn includesVersion(self: LinuxVersionRange, ver: Version) bool { - if (self.min.compare(ver) == .gt) return false; - if (self.max.compare(ver) == .lt) return false; + pub fn includesVersion(self: Range, ver: Version) bool { + if (self.min.order(ver) == .gt) return false; + if (self.max.order(ver) == .lt) return false; return true; } }; diff --git a/src/analyze.cpp b/src/analyze.cpp index 1e667be5af..7712f0f707 100644 --- a/src/analyze.cpp +++ b/src/analyze.cpp @@ -649,11 +649,22 @@ ZigType *get_pointer_to_type(CodeGen *g, ZigType *child_type, bool is_const) { } ZigType *get_optional_type(CodeGen *g, ZigType *child_type) { + ZigType *result = get_optional_type2(g, child_type); + if (result == nullptr) { + codegen_report_errors_and_exit(g); + } + return result; +} + +ZigType *get_optional_type2(CodeGen *g, ZigType *child_type) { if (child_type->optional_parent != nullptr) { return child_type->optional_parent; } - assert(type_is_resolved(child_type, ResolveStatusSizeKnown)); + Error err; + if ((err = type_resolve(g, child_type, ResolveStatusSizeKnown))) { + return nullptr; + } ZigType *entry = new_type_table_entry(ZigTypeIdOptional); diff --git a/src/analyze.hpp b/src/analyze.hpp index 8e441ef769..fded1e4052 100644 --- a/src/analyze.hpp +++ b/src/analyze.hpp @@ -34,6 +34,7 @@ ZigType **get_c_int_type_ptr(CodeGen *g, CIntType c_int_type); ZigType *get_c_int_type(CodeGen *g, CIntType c_int_type); ZigType *get_fn_type(CodeGen *g, FnTypeId *fn_type_id); ZigType *get_optional_type(CodeGen *g, ZigType *child_type); +ZigType *get_optional_type2(CodeGen *g, ZigType *child_type); ZigType *get_array_type(CodeGen *g, ZigType *child_type, uint64_t array_size, ZigValue *sentinel); ZigType *get_slice_type(CodeGen *g, ZigType *ptr_type); ZigType *get_partial_container_type(CodeGen *g, Scope *scope, ContainerKind kind, diff --git a/src/ir.cpp b/src/ir.cpp index ef20c663b7..86d85303c0 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -24339,7 +24339,8 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInst* source_instr, ZigTy // default_value: var inner_fields[3]->special = ConstValSpecialStatic; - inner_fields[3]->type = get_optional_type(ira->codegen, struct_field->type_entry); + inner_fields[3]->type = get_optional_type2(ira->codegen, struct_field->type_entry); + if (inner_fields[3]->type == nullptr) return ErrorSemanticAnalyzeFail; memoize_field_init_val(ira->codegen, type_entry, struct_field); set_optional_payload(inner_fields[3], struct_field->init_val); diff --git a/test/stage1/behavior/type_info.zig b/test/stage1/behavior/type_info.zig index a3988cba6d..3ce44a89c4 100644 --- a/test/stage1/behavior/type_info.zig +++ b/test/stage1/behavior/type_info.zig @@ -386,3 +386,8 @@ test "@typeInfo does not force declarations into existence" { }; comptime expect(@typeInfo(S).Struct.fields.len == 1); } + +test "defaut value for a var-typed field" { + const S = struct { x: var }; + expect(@typeInfo(S).Struct.fields[0].default_value == null); +}