zig

fork of https://codeberg.org/ziglang/zig
Log | Files | Refs | README | LICENSE

commit fa46bcb36864e6616ce4449965063f3b8720f8e1 (tree)
parent 83d27f71ef92d555cc15645bf9d948203ba8af1e
Author: Andrew Kelley <andrew@ziglang.org>
Date:   Fri,  6 Mar 2020 18:30:30 -0500

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.

Diffstat:
Mlib/std/builtin.zig | 8++++----
Msrc/analyze.cpp | 13++++++++++++-
Msrc/analyze.hpp | 1+
Msrc/ir.cpp | 3++-
Mtest/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 @@ -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 @@ -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 @@ -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 @@ -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 @@ -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); +}