| author | |
| committer | |
| log | 773bf8013391d2b309cfcb50bf9e1c7db25cc3f2 |
| tree | f9afac31b7211b157ca47c8bef022e405b13bed7 |
| parent | c26f543970771acba5484553e2c10ec90b3c39eb |
| parent | 280187031a68c577e84c72add037271153d27c62 |
19 files changed, 233 insertions(+), 53 deletions(-)
.builds/freebsd.yml created+22| ... | ... | @@ -0,0 +1,22 @@ |
| 1 | arch: x86_64 | |
| 2 | image: freebsd | |
| 3 | packages: | |
| 4 | - cmake | |
| 5 | - ninja | |
| 6 | - llvm70 | |
| 7 | sources: | |
| 8 | - https://github.com/ziglang/zig.git | |
| 9 | tasks: | |
| 10 | - build: | | |
| 11 | cd zig && mkdir build && cd build | |
| 12 | cmake .. -GNinja -DCMAKE_BUILD_TYPE=Release | |
| 13 | ninja install | |
| 14 | - test: | | |
| 15 | cd zig/build | |
| 16 | bin/zig test ../test/behavior.zig | |
| 17 | # TODO enable all tests | |
| 18 | #bin/zig build --build-file ../build.zig test | |
| 19 | # TODO integrate with the download page updater and make a | |
| 20 | # static build available to download for FreeBSD. | |
| 21 | # This will require setting up a cache of LLVM/Clang built | |
| 22 | # statically. |
doc/langref.html.in+1-1| ... | ... | @@ -165,7 +165,7 @@ const std = @import("std"); |
| 165 | 165 | |
| 166 | 166 | pub fn main() !void { |
| 167 | 167 | // If this program is run without stdout attached, exit with an error. |
| 168 | var stdout_file = try std.io.getStdOut(); | |
| 168 | const stdout_file = try std.io.getStdOut(); | |
| 169 | 169 | // If this program encounters pipe failure when printing to stdout, exit |
| 170 | 170 | // with an error. |
| 171 | 171 | try stdout_file.write("Hello, world!\n"); |
example/hello_world/hello.zig+1-1| ... | ... | @@ -2,7 +2,7 @@ const std = @import("std"); |
| 2 | 2 | |
| 3 | 3 | pub fn main() !void { |
| 4 | 4 | // If this program is run without stdout attached, exit with an error. |
| 5 | var stdout_file = try std.io.getStdOut(); | |
| 5 | const stdout_file = try std.io.getStdOut(); | |
| 6 | 6 | // If this program encounters pipe failure when printing to stdout, exit |
| 7 | 7 | // with an error. |
| 8 | 8 | try stdout_file.write("Hello, world!\n"); |
src-self-hosted/compilation.zig+1| ... | ... | @@ -300,6 +300,7 @@ pub const Compilation = struct { |
| 300 | 300 | UserResourceLimitReached, |
| 301 | 301 | InvalidUtf8, |
| 302 | 302 | BadPathName, |
| 303 | DeviceBusy, | |
| 303 | 304 | }; |
| 304 | 305 | |
| 305 | 306 | pub const Event = union(enum) { |
src/analyze.cpp+33-22| ... | ... | @@ -2681,39 +2681,50 @@ static Error resolve_struct_alignment(CodeGen *g, ZigType *struct_type) { |
| 2681 | 2681 | assert(decl_node->type == NodeTypeContainerDecl); |
| 2682 | 2682 | assert(struct_type->di_type); |
| 2683 | 2683 | |
| 2684 | size_t field_count = struct_type->data.structure.src_field_count; | |
| 2684 | 2685 | if (struct_type->data.structure.layout == ContainerLayoutPacked) { |
| 2685 | 2686 | struct_type->data.structure.abi_alignment = 1; |
| 2686 | } | |
| 2687 | ||
| 2688 | size_t field_count = struct_type->data.structure.src_field_count; | |
| 2689 | for (size_t i = 0; i < field_count; i += 1) { | |
| 2690 | TypeStructField *field = &struct_type->data.structure.fields[i]; | |
| 2691 | ||
| 2692 | // If this assertion trips, look up the call stack. Probably something is | |
| 2693 | // calling type_resolve with ResolveStatusAlignmentKnown when it should only | |
| 2694 | // be resolving ResolveStatusZeroBitsKnown | |
| 2695 | assert(field->type_entry != nullptr); | |
| 2696 | ||
| 2697 | if (type_is_invalid(field->type_entry)) { | |
| 2698 | struct_type->data.structure.resolve_status = ResolveStatusInvalid; | |
| 2699 | break; | |
| 2687 | for (size_t i = 0; i < field_count; i += 1) { | |
| 2688 | TypeStructField *field = &struct_type->data.structure.fields[i]; | |
| 2689 | if (field->type_entry != nullptr && type_is_invalid(field->type_entry)) { | |
| 2690 | struct_type->data.structure.resolve_status = ResolveStatusInvalid; | |
| 2691 | break; | |
| 2692 | } | |
| 2700 | 2693 | } |
| 2694 | } else for (size_t i = 0; i < field_count; i += 1) { | |
| 2695 | TypeStructField *field = &struct_type->data.structure.fields[i]; | |
| 2696 | uint32_t this_field_align; | |
| 2697 | ||
| 2698 | // TODO If we have no type_entry for the field, we've already failed to | |
| 2699 | // compile the program correctly. This stage1 compiler needs a deeper | |
| 2700 | // reworking to make this correct, or we can ignore the problem | |
| 2701 | // and make sure it is fixed in stage2. This workaround is for when | |
| 2702 | // there is a false positive of a dependency loop, of alignment depending | |
| 2703 | // on itself. When this false positive happens we assume a pointer-aligned | |
| 2704 | // field, which is usually fine but could be incorrectly over-aligned or | |
| 2705 | // even under-aligned. See https://github.com/ziglang/zig/issues/1512 | |
| 2706 | if (field->type_entry == nullptr) { | |
| 2707 | this_field_align = LLVMABIAlignmentOfType(g->target_data_ref, LLVMPointerType(LLVMInt8Type(), 0)); | |
| 2708 | } else { | |
| 2709 | if (type_is_invalid(field->type_entry)) { | |
| 2710 | struct_type->data.structure.resolve_status = ResolveStatusInvalid; | |
| 2711 | break; | |
| 2712 | } | |
| 2701 | 2713 | |
| 2702 | if (!type_has_bits(field->type_entry)) | |
| 2703 | continue; | |
| 2714 | if (!type_has_bits(field->type_entry)) | |
| 2715 | continue; | |
| 2704 | 2716 | |
| 2705 | // alignment of structs is the alignment of the most-aligned field | |
| 2706 | if (struct_type->data.structure.layout != ContainerLayoutPacked) { | |
| 2707 | 2717 | if ((err = type_resolve(g, field->type_entry, ResolveStatusAlignmentKnown))) { |
| 2708 | 2718 | struct_type->data.structure.resolve_status = ResolveStatusInvalid; |
| 2709 | 2719 | break; |
| 2710 | 2720 | } |
| 2711 | 2721 | |
| 2712 | uint32_t this_field_align = get_abi_alignment(g, field->type_entry); | |
| 2722 | this_field_align = get_abi_alignment(g, field->type_entry); | |
| 2713 | 2723 | assert(this_field_align != 0); |
| 2714 | if (this_field_align > struct_type->data.structure.abi_alignment) { | |
| 2715 | struct_type->data.structure.abi_alignment = this_field_align; | |
| 2716 | } | |
| 2724 | } | |
| 2725 | // alignment of structs is the alignment of the most-aligned field | |
| 2726 | if (this_field_align > struct_type->data.structure.abi_alignment) { | |
| 2727 | struct_type->data.structure.abi_alignment = this_field_align; | |
| 2717 | 2728 | } |
| 2718 | 2729 | } |
| 2719 | 2730 |
src/ir.cpp+50-15| ... | ... | @@ -159,7 +159,7 @@ static ZigType *ir_resolve_atomic_operand_type(IrAnalyze *ira, IrInstruction *op |
| 159 | 159 | static IrInstruction *ir_lval_wrap(IrBuilder *irb, Scope *scope, IrInstruction *value, LVal lval); |
| 160 | 160 | static ZigType *adjust_ptr_align(CodeGen *g, ZigType *ptr_type, uint32_t new_align); |
| 161 | 161 | static ZigType *adjust_slice_align(CodeGen *g, ZigType *slice_type, uint32_t new_align); |
| 162 | static void buf_read_value_bytes(CodeGen *codegen, uint8_t *buf, ConstExprValue *val); | |
| 162 | static Error buf_read_value_bytes(IrAnalyze *ira, AstNode *source_node, uint8_t *buf, ConstExprValue *val); | |
| 163 | 163 | static void buf_write_value_bytes(CodeGen *codegen, uint8_t *buf, ConstExprValue *val); |
| 164 | 164 | static Error ir_read_const_ptr(IrAnalyze *ira, AstNode *source_node, |
| 165 | 165 | ConstExprValue *out_val, ConstExprValue *ptr_val); |
| ... | ... | @@ -12495,6 +12495,7 @@ static IrInstruction *ir_analyze_instruction_decl_var(IrAnalyze *ira, IrInstruct |
| 12495 | 12495 | case ReqCompTimeNo: |
| 12496 | 12496 | if (casted_init_value->value.special == ConstValSpecialStatic && |
| 12497 | 12497 | casted_init_value->value.type->id == ZigTypeIdFn && |
| 12498 | casted_init_value->value.data.x_ptr.special != ConstPtrSpecialHardCodedAddr && | |
| 12498 | 12499 | casted_init_value->value.data.x_ptr.data.fn.fn_entry->fn_inline == FnInlineAlways) |
| 12499 | 12500 | { |
| 12500 | 12501 | var_class_requires_const = true; |
| ... | ... | @@ -13724,7 +13725,8 @@ static Error ir_read_const_ptr(IrAnalyze *ira, AstNode *source_node, |
| 13724 | 13725 | Buf buf = BUF_INIT; |
| 13725 | 13726 | buf_resize(&buf, src_size); |
| 13726 | 13727 | buf_write_value_bytes(ira->codegen, (uint8_t*)buf_ptr(&buf), pointee); |
| 13727 | buf_read_value_bytes(ira->codegen, (uint8_t*)buf_ptr(&buf), out_val); | |
| 13728 | if ((err = buf_read_value_bytes(ira, source_node, (uint8_t*)buf_ptr(&buf), out_val))) | |
| 13729 | return err; | |
| 13728 | 13730 | return ErrorNone; |
| 13729 | 13731 | } |
| 13730 | 13732 | |
| ... | ... | @@ -13758,7 +13760,8 @@ static Error ir_read_const_ptr(IrAnalyze *ira, AstNode *source_node, |
| 13758 | 13760 | ConstExprValue *elem_val = &array_val->data.x_array.data.s_none.elements[elem_index + i]; |
| 13759 | 13761 | buf_write_value_bytes(ira->codegen, (uint8_t*)buf_ptr(&buf) + (i * elem_size), elem_val); |
| 13760 | 13762 | } |
| 13761 | buf_read_value_bytes(ira->codegen, (uint8_t*)buf_ptr(&buf), out_val); | |
| 13763 | if ((err = buf_read_value_bytes(ira, source_node, (uint8_t*)buf_ptr(&buf), out_val))) | |
| 13764 | return err; | |
| 13762 | 13765 | return ErrorNone; |
| 13763 | 13766 | } |
| 13764 | 13767 | case ConstPtrSpecialBaseStruct: |
| ... | ... | @@ -20076,7 +20079,8 @@ static void buf_write_value_bytes(CodeGen *codegen, uint8_t *buf, ConstExprValue |
| 20076 | 20079 | zig_unreachable(); |
| 20077 | 20080 | } |
| 20078 | 20081 | |
| 20079 | static void buf_read_value_bytes(CodeGen *codegen, uint8_t *buf, ConstExprValue *val) { | |
| 20082 | static Error buf_read_value_bytes(IrAnalyze *ira, AstNode *source_node, uint8_t *buf, ConstExprValue *val) { | |
| 20083 | Error err; | |
| 20080 | 20084 | assert(val->special == ConstValSpecialStatic); |
| 20081 | 20085 | switch (val->type->id) { |
| 20082 | 20086 | case ZigTypeIdInvalid: |
| ... | ... | @@ -20093,30 +20097,60 @@ static void buf_read_value_bytes(CodeGen *codegen, uint8_t *buf, ConstExprValue |
| 20093 | 20097 | case ZigTypeIdPromise: |
| 20094 | 20098 | zig_unreachable(); |
| 20095 | 20099 | case ZigTypeIdVoid: |
| 20096 | return; | |
| 20100 | return ErrorNone; | |
| 20097 | 20101 | case ZigTypeIdBool: |
| 20098 | 20102 | val->data.x_bool = (buf[0] != 0); |
| 20099 | return; | |
| 20103 | return ErrorNone; | |
| 20100 | 20104 | case ZigTypeIdInt: |
| 20101 | 20105 | bigint_read_twos_complement(&val->data.x_bigint, buf, val->type->data.integral.bit_count, |
| 20102 | codegen->is_big_endian, val->type->data.integral.is_signed); | |
| 20103 | return; | |
| 20106 | ira->codegen->is_big_endian, val->type->data.integral.is_signed); | |
| 20107 | return ErrorNone; | |
| 20104 | 20108 | case ZigTypeIdFloat: |
| 20105 | float_read_ieee597(val, buf, codegen->is_big_endian); | |
| 20106 | return; | |
| 20109 | float_read_ieee597(val, buf, ira->codegen->is_big_endian); | |
| 20110 | return ErrorNone; | |
| 20107 | 20111 | case ZigTypeIdPointer: |
| 20108 | 20112 | { |
| 20109 | 20113 | val->data.x_ptr.special = ConstPtrSpecialHardCodedAddr; |
| 20110 | 20114 | BigInt bn; |
| 20111 | bigint_read_twos_complement(&bn, buf, codegen->builtin_types.entry_usize->data.integral.bit_count, | |
| 20112 | codegen->is_big_endian, false); | |
| 20115 | bigint_read_twos_complement(&bn, buf, ira->codegen->builtin_types.entry_usize->data.integral.bit_count, | |
| 20116 | ira->codegen->is_big_endian, false); | |
| 20113 | 20117 | val->data.x_ptr.data.hard_coded_addr.addr = bigint_as_unsigned(&bn); |
| 20114 | return; | |
| 20118 | return ErrorNone; | |
| 20115 | 20119 | } |
| 20116 | 20120 | case ZigTypeIdArray: |
| 20117 | 20121 | zig_panic("TODO buf_read_value_bytes array type"); |
| 20118 | 20122 | case ZigTypeIdStruct: |
| 20119 | zig_panic("TODO buf_read_value_bytes struct type"); | |
| 20123 | switch (val->type->data.structure.layout) { | |
| 20124 | case ContainerLayoutAuto: { | |
| 20125 | ErrorMsg *msg = ir_add_error_node(ira, source_node, | |
| 20126 | buf_sprintf("non-extern, non-packed struct '%s' cannot have its bytes reinterpreted", | |
| 20127 | buf_ptr(&val->type->name))); | |
| 20128 | add_error_note(ira->codegen, msg, val->type->data.structure.decl_node, | |
| 20129 | buf_sprintf("declared here")); | |
| 20130 | return ErrorSemanticAnalyzeFail; | |
| 20131 | } | |
| 20132 | case ContainerLayoutExtern: { | |
| 20133 | size_t src_field_count = val->type->data.structure.src_field_count; | |
| 20134 | val->data.x_struct.fields = create_const_vals(src_field_count); | |
| 20135 | for (size_t field_i = 0; field_i < src_field_count; field_i += 1) { | |
| 20136 | ConstExprValue *field_val = &val->data.x_struct.fields[field_i]; | |
| 20137 | field_val->special = ConstValSpecialStatic; | |
| 20138 | TypeStructField *type_field = &val->type->data.structure.fields[field_i]; | |
| 20139 | field_val->type = type_field->type_entry; | |
| 20140 | if (type_field->gen_index == SIZE_MAX) | |
| 20141 | continue; | |
| 20142 | size_t offset = LLVMOffsetOfElement(ira->codegen->target_data_ref, val->type->type_ref, | |
| 20143 | type_field->gen_index); | |
| 20144 | uint8_t *new_buf = buf + offset; | |
| 20145 | if ((err = buf_read_value_bytes(ira, source_node, new_buf, field_val))) | |
| 20146 | return err; | |
| 20147 | } | |
| 20148 | return ErrorNone; | |
| 20149 | } | |
| 20150 | case ContainerLayoutPacked: | |
| 20151 | zig_panic("TODO buf_read_value_bytes packed struct"); | |
| 20152 | } | |
| 20153 | zig_unreachable(); | |
| 20120 | 20154 | case ZigTypeIdOptional: |
| 20121 | 20155 | zig_panic("TODO buf_read_value_bytes maybe type"); |
| 20122 | 20156 | case ZigTypeIdErrorUnion: |
| ... | ... | @@ -20219,7 +20253,8 @@ static IrInstruction *ir_analyze_instruction_bit_cast(IrAnalyze *ira, IrInstruct |
| 20219 | 20253 | IrInstruction *result = ir_const(ira, &instruction->base, dest_type); |
| 20220 | 20254 | uint8_t *buf = allocate_nonzero<uint8_t>(src_size_bytes); |
| 20221 | 20255 | buf_write_value_bytes(ira->codegen, buf, val); |
| 20222 | buf_read_value_bytes(ira->codegen, buf, &result->value); | |
| 20256 | if ((err = buf_read_value_bytes(ira, instruction->base.source_node, buf, &result->value))) | |
| 20257 | return ira->codegen->invalid_instruction; | |
| 20223 | 20258 | return result; |
| 20224 | 20259 | } |
| 20225 | 20260 |
src/translate_c.cpp+8| ... | ... | @@ -4776,6 +4776,14 @@ Error parse_h_file(ImportTableEntry *import, ZigList<ErrorMsg *> *errors, const |
| 4776 | 4776 | |
| 4777 | 4777 | clang_argv.append(target_file); |
| 4778 | 4778 | |
| 4779 | if (codegen->verbose_cimport) { | |
| 4780 | fprintf(stderr, "clang"); | |
| 4781 | for (size_t i = 0; i < clang_argv.length; i += 1) { | |
| 4782 | fprintf(stderr, " %s", clang_argv.at(i)); | |
| 4783 | } | |
| 4784 | fprintf(stderr, "\n"); | |
| 4785 | } | |
| 4786 | ||
| 4779 | 4787 | // to make the [start...end] argument work |
| 4780 | 4788 | clang_argv.append(nullptr); |
| 4781 | 4789 |
std/array_list.zig+11| ... | ... | @@ -398,3 +398,14 @@ test "std.ArrayList.insertSlice" { |
| 398 | 398 | assert(list.len == 6); |
| 399 | 399 | assert(list.items[0] == 1); |
| 400 | 400 | } |
| 401 | ||
| 402 | const Item = struct { | |
| 403 | integer: i32, | |
| 404 | sub_items: ArrayList(Item), | |
| 405 | }; | |
| 406 | ||
| 407 | test "std.ArrayList: ArrayList(T) of struct T" { | |
| 408 | var root = Item{ .integer = 1, .sub_items = ArrayList(Item).init(debug.global_allocator) }; | |
| 409 | try root.sub_items.append( Item{ .integer = 42, .sub_items = ArrayList(Item).init(debug.global_allocator) } ); | |
| 410 | assert(root.sub_items.items[0].integer == 42); | |
| 411 | } |
std/dynamic_library.zig+1-3| ... | ... | @@ -19,7 +19,6 @@ pub const DynLib = switch (builtin.os) { |
| 19 | 19 | }; |
| 20 | 20 | |
| 21 | 21 | pub const LinuxDynLib = struct { |
| 22 | allocator: *mem.Allocator, | |
| 23 | 22 | elf_lib: ElfLib, |
| 24 | 23 | fd: i32, |
| 25 | 24 | map_addr: usize, |
| ... | ... | @@ -27,7 +26,7 @@ pub const LinuxDynLib = struct { |
| 27 | 26 | |
| 28 | 27 | /// Trusts the file |
| 29 | 28 | pub fn open(allocator: *mem.Allocator, path: []const u8) !DynLib { |
| 30 | const fd = try std.os.posixOpen(allocator, path, 0, linux.O_RDONLY | linux.O_CLOEXEC); | |
| 29 | const fd = try std.os.posixOpen(path, 0, linux.O_RDONLY | linux.O_CLOEXEC); | |
| 31 | 30 | errdefer std.os.close(fd); |
| 32 | 31 | |
| 33 | 32 | const size = @intCast(usize, (try std.os.posixFStat(fd)).size); |
| ... | ... | @@ -45,7 +44,6 @@ pub const LinuxDynLib = struct { |
| 45 | 44 | const bytes = @intToPtr([*]align(std.os.page_size) u8, addr)[0..size]; |
| 46 | 45 | |
| 47 | 46 | return DynLib{ |
| 48 | .allocator = allocator, | |
| 49 | 47 | .elf_lib = try ElfLib.init(bytes), |
| 50 | 48 | .fd = fd, |
| 51 | 49 | .map_addr = addr, |
std/fmt/index.zig+7| ... | ... | @@ -243,6 +243,9 @@ pub fn formatType( |
| 243 | 243 | } |
| 244 | 244 | return format(context, Errors, output, "{}@{x}", @typeName(T.Child), @ptrToInt(&value)); |
| 245 | 245 | }, |
| 246 | builtin.TypeId.Fn => { | |
| 247 | return format(context, Errors, output, "{}@{x}", @typeName(T), @ptrToInt(value)); | |
| 248 | }, | |
| 246 | 249 | else => @compileError("Unable to format type '" ++ @typeName(T) ++ "'"), |
| 247 | 250 | } |
| 248 | 251 | } |
| ... | ... | @@ -1013,6 +1016,10 @@ test "fmt.format" { |
| 1013 | 1016 | const value = @intToPtr(fn () void, 0xdeadbeef); |
| 1014 | 1017 | try testFmt("pointer: fn() void@deadbeef\n", "pointer: {}\n", value); |
| 1015 | 1018 | } |
| 1019 | { | |
| 1020 | const value = @intToPtr(fn () void, 0xdeadbeef); | |
| 1021 | try testFmt("pointer: fn() void@deadbeef\n", "pointer: {}\n", value); | |
| 1022 | } | |
| 1016 | 1023 | try testFmt("buf: Test \n", "buf: {s5}\n", "Test"); |
| 1017 | 1024 | try testFmt("buf: Test\n Other text", "buf: {s}\n Other text", "Test"); |
| 1018 | 1025 | try testFmt("cstr: Test C\n", "cstr: {s}\n", c"Test C"); |
std/index.zig+2-1| ... | ... | @@ -57,7 +57,8 @@ test "std" { |
| 57 | 57 | _ = @import("mutex.zig"); |
| 58 | 58 | _ = @import("segmented_list.zig"); |
| 59 | 59 | _ = @import("spinlock.zig"); |
| 60 | ||
| 60 | ||
| 61 | _ = @import("dynamic_library.zig"); | |
| 61 | 62 | _ = @import("base64.zig"); |
| 62 | 63 | _ = @import("build.zig"); |
| 63 | 64 | _ = @import("c/index.zig"); |
std/io.zig+5-5| ... | ... | @@ -155,32 +155,32 @@ pub fn InStream(comptime ReadError: type) type { |
| 155 | 155 | pub fn readIntNative(self: *Self, comptime T: type) !T { |
| 156 | 156 | var bytes: [@sizeOf(T)]u8 = undefined; |
| 157 | 157 | try self.readNoEof(bytes[0..]); |
| 158 | return mem.readIntSliceNative(T, bytes); | |
| 158 | return mem.readIntNative(T, &bytes); | |
| 159 | 159 | } |
| 160 | 160 | |
| 161 | 161 | /// Reads a foreign-endian integer |
| 162 | 162 | pub fn readIntForeign(self: *Self, comptime T: type) !T { |
| 163 | 163 | var bytes: [@sizeOf(T)]u8 = undefined; |
| 164 | 164 | try self.readNoEof(bytes[0..]); |
| 165 | return mem.readIntSliceForeign(T, bytes); | |
| 165 | return mem.readIntForeign(T, &bytes); | |
| 166 | 166 | } |
| 167 | 167 | |
| 168 | 168 | pub fn readIntLittle(self: *Self, comptime T: type) !T { |
| 169 | 169 | var bytes: [@sizeOf(T)]u8 = undefined; |
| 170 | 170 | try self.readNoEof(bytes[0..]); |
| 171 | return mem.readIntSliceLittle(T, bytes); | |
| 171 | return mem.readIntLittle(T, &bytes); | |
| 172 | 172 | } |
| 173 | 173 | |
| 174 | 174 | pub fn readIntBig(self: *Self, comptime T: type) !T { |
| 175 | 175 | var bytes: [@sizeOf(T)]u8 = undefined; |
| 176 | 176 | try self.readNoEof(bytes[0..]); |
| 177 | return mem.readIntSliceBig(T, bytes); | |
| 177 | return mem.readIntBig(T, &bytes); | |
| 178 | 178 | } |
| 179 | 179 | |
| 180 | 180 | pub fn readInt(self: *Self, comptime T: type, endian: builtin.Endian) !T { |
| 181 | 181 | var bytes: [@sizeOf(T)]u8 = undefined; |
| 182 | 182 | try self.readNoEof(bytes[0..]); |
| 183 | return mem.readIntSlice(T, bytes, endian); | |
| 183 | return mem.readInt(T, &bytes, endian); | |
| 184 | 184 | } |
| 185 | 185 | |
| 186 | 186 | pub fn readVarInt(self: *Self, comptime ReturnType: type, endian: builtin.Endian, size: usize) !ReturnType { |
std/os/index.zig+5| ... | ... | @@ -459,6 +459,7 @@ pub const PosixOpenError = error{ |
| 459 | 459 | NoSpaceLeft, |
| 460 | 460 | NotDir, |
| 461 | 461 | PathAlreadyExists, |
| 462 | DeviceBusy, | |
| 462 | 463 | |
| 463 | 464 | /// See https://github.com/ziglang/zig/issues/1396 |
| 464 | 465 | Unexpected, |
| ... | ... | @@ -497,6 +498,7 @@ pub fn posixOpenC(file_path: [*]const u8, flags: u32, perm: usize) !i32 { |
| 497 | 498 | posix.ENOTDIR => return PosixOpenError.NotDir, |
| 498 | 499 | posix.EPERM => return PosixOpenError.AccessDenied, |
| 499 | 500 | posix.EEXIST => return PosixOpenError.PathAlreadyExists, |
| 501 | posix.EBUSY => return PosixOpenError.DeviceBusy, | |
| 500 | 502 | else => return unexpectedErrorPosix(err), |
| 501 | 503 | } |
| 502 | 504 | } |
| ... | ... | @@ -1402,6 +1404,7 @@ const DeleteTreeError = error{ |
| 1402 | 1404 | FileSystem, |
| 1403 | 1405 | FileBusy, |
| 1404 | 1406 | DirNotEmpty, |
| 1407 | DeviceBusy, | |
| 1405 | 1408 | |
| 1406 | 1409 | /// On Windows, file paths must be valid Unicode. |
| 1407 | 1410 | InvalidUtf8, |
| ... | ... | @@ -1463,6 +1466,7 @@ pub fn deleteTree(allocator: *Allocator, full_path: []const u8) DeleteTreeError! |
| 1463 | 1466 | error.Unexpected, |
| 1464 | 1467 | error.InvalidUtf8, |
| 1465 | 1468 | error.BadPathName, |
| 1469 | error.DeviceBusy, | |
| 1466 | 1470 | => return err, |
| 1467 | 1471 | }; |
| 1468 | 1472 | defer dir.close(); |
| ... | ... | @@ -1545,6 +1549,7 @@ pub const Dir = struct { |
| 1545 | 1549 | OutOfMemory, |
| 1546 | 1550 | InvalidUtf8, |
| 1547 | 1551 | BadPathName, |
| 1552 | DeviceBusy, | |
| 1548 | 1553 | |
| 1549 | 1554 | /// See https://github.com/ziglang/zig/issues/1396 |
| 1550 | 1555 | Unexpected, |
std/os/path.zig+1| ... | ... | @@ -1093,6 +1093,7 @@ pub const RealError = error{ |
| 1093 | 1093 | NoSpaceLeft, |
| 1094 | 1094 | FileSystem, |
| 1095 | 1095 | BadPathName, |
| 1096 | DeviceBusy, | |
| 1096 | 1097 | |
| 1097 | 1098 | /// On Windows, file paths must be valid Unicode. |
| 1098 | 1099 | InvalidUtf8, |
test/behavior.zig+1| ... | ... | @@ -42,6 +42,7 @@ comptime { |
| 42 | 42 | _ = @import("cases/if.zig"); |
| 43 | 43 | _ = @import("cases/import.zig"); |
| 44 | 44 | _ = @import("cases/incomplete_struct_param_tld.zig"); |
| 45 | _ = @import("cases/inttoptr.zig"); | |
| 45 | 46 | _ = @import("cases/ir_block_deps.zig"); |
| 46 | 47 | _ = @import("cases/math.zig"); |
| 47 | 48 | _ = @import("cases/merge_error_sets.zig"); |
test/cases/inttoptr.zig created+13| ... | ... | @@ -0,0 +1,13 @@ |
| 1 | const builtin = @import("builtin"); | |
| 2 | const std = @import("std"); | |
| 3 | const assertOrPanic = std.debug.assertOrPanic; | |
| 4 | ||
| 5 | test "casting random address to function pointer" { | |
| 6 | randomAddressToFunction(); | |
| 7 | comptime randomAddressToFunction(); | |
| 8 | } | |
| 9 | ||
| 10 | fn randomAddressToFunction() void { | |
| 11 | var addr: usize = 0xdeadbeef; | |
| 12 | var ptr = @intToPtr(fn () void, addr); | |
| 13 | } |
test/cases/ptrcast.zig+19| ... | ... | @@ -15,3 +15,22 @@ fn testReinterpretBytesAsInteger() void { |
| 15 | 15 | }; |
| 16 | 16 | assertOrPanic(@ptrCast(*align(1) const u32, bytes[1..5].ptr).* == expected); |
| 17 | 17 | } |
| 18 | ||
| 19 | test "reinterpret bytes of an array into an extern struct" { | |
| 20 | testReinterpretBytesAsExternStruct(); | |
| 21 | comptime testReinterpretBytesAsExternStruct(); | |
| 22 | } | |
| 23 | ||
| 24 | fn testReinterpretBytesAsExternStruct() void { | |
| 25 | var bytes align(2) = []u8{ 1, 2, 3, 4, 5, 6 }; | |
| 26 | ||
| 27 | const S = extern struct { | |
| 28 | a: u8, | |
| 29 | b: u16, | |
| 30 | c: u8, | |
| 31 | }; | |
| 32 | ||
| 33 | var ptr = @ptrCast(*const S, &bytes); | |
| 34 | var val = ptr.c; | |
| 35 | assertOrPanic(val == 5); | |
| 36 | } |
test/cases/struct_contains_slice_of_itself.zig+42| ... | ... | @@ -5,6 +5,11 @@ const Node = struct { |
| 5 | 5 | children: []Node, |
| 6 | 6 | }; |
| 7 | 7 | |
| 8 | const NodeAligned = struct { | |
| 9 | payload: i32, | |
| 10 | children: []align(@alignOf(NodeAligned)) NodeAligned, | |
| 11 | }; | |
| 12 | ||
| 8 | 13 | test "struct contains slice of itself" { |
| 9 | 14 | var other_nodes = []Node{ |
| 10 | 15 | Node{ |
| ... | ... | @@ -41,3 +46,40 @@ test "struct contains slice of itself" { |
| 41 | 46 | assert(root.children[2].children[0].payload == 31); |
| 42 | 47 | assert(root.children[2].children[1].payload == 32); |
| 43 | 48 | } |
| 49 | ||
| 50 | test "struct contains aligned slice of itself" { | |
| 51 | var other_nodes = []NodeAligned{ | |
| 52 | NodeAligned{ | |
| 53 | .payload = 31, | |
| 54 | .children = []NodeAligned{}, | |
| 55 | }, | |
| 56 | NodeAligned{ | |
| 57 | .payload = 32, | |
| 58 | .children = []NodeAligned{}, | |
| 59 | }, | |
| 60 | }; | |
| 61 | var nodes = []NodeAligned{ | |
| 62 | NodeAligned{ | |
| 63 | .payload = 1, | |
| 64 | .children = []NodeAligned{}, | |
| 65 | }, | |
| 66 | NodeAligned{ | |
| 67 | .payload = 2, | |
| 68 | .children = []NodeAligned{}, | |
| 69 | }, | |
| 70 | NodeAligned{ | |
| 71 | .payload = 3, | |
| 72 | .children = other_nodes[0..], | |
| 73 | }, | |
| 74 | }; | |
| 75 | const root = NodeAligned{ | |
| 76 | .payload = 1234, | |
| 77 | .children = nodes[0..], | |
| 78 | }; | |
| 79 | assert(root.payload == 1234); | |
| 80 | assert(root.children[0].payload == 1); | |
| 81 | assert(root.children[1].payload == 2); | |
| 82 | assert(root.children[2].payload == 3); | |
| 83 | assert(root.children[2].children[0].payload == 31); | |
| 84 | assert(root.children[2].children[1].payload == 32); | |
| 85 | } |
test/cases/type_info.zig+10-5| ... | ... | @@ -144,15 +144,20 @@ test "type info: enum info" { |
| 144 | 144 | } |
| 145 | 145 | |
| 146 | 146 | fn testEnum() void { |
| 147 | const Os = @import("builtin").Os; | |
| 147 | const Os = enum { | |
| 148 | Windows, | |
| 149 | Macos, | |
| 150 | Linux, | |
| 151 | FreeBSD, | |
| 152 | }; | |
| 148 | 153 | |
| 149 | 154 | const os_info = @typeInfo(Os); |
| 150 | 155 | assert(TypeId(os_info) == TypeId.Enum); |
| 151 | 156 | assert(os_info.Enum.layout == TypeInfo.ContainerLayout.Auto); |
| 152 | assert(os_info.Enum.fields.len == 32); | |
| 153 | assert(mem.eql(u8, os_info.Enum.fields[1].name, "ananas")); | |
| 154 | assert(os_info.Enum.fields[10].value == 10); | |
| 155 | assert(os_info.Enum.tag_type == u5); | |
| 157 | assert(os_info.Enum.fields.len == 4); | |
| 158 | assert(mem.eql(u8, os_info.Enum.fields[1].name, "Macos")); | |
| 159 | assert(os_info.Enum.fields[3].value == 3); | |
| 160 | assert(os_info.Enum.tag_type == u2); | |
| 156 | 161 | assert(os_info.Enum.defs.len == 0); |
| 157 | 162 | } |
| 158 | 163 |