| author | |
| committer | |
| log | 3f4d0ecd7e5a57b425b1cd99139145e7e509c3c6 |
| tree | 76d1d16a397e44c04167456116d6d3cc91f0b994 |
| parent | 9462852433a815496e0edf5d5b2e00726f5ea072 |
| parent | 0ac1b83885c7f2a97a8ac25657afcb5c9b80afb4 |
10 files changed, 202 insertions(+), 63 deletions(-)
doc/docgen.zig+16-13| ... | ... | @@ -689,7 +689,10 @@ fn termColor(allocator: *mem.Allocator, input: []const u8) ![]u8 { |
| 689 | 689 | fn genHtml(allocator: *mem.Allocator, tokenizer: *Tokenizer, toc: *Toc, out: var, zig_exe: []const u8) !void { |
| 690 | 690 | var code_progress_index: usize = 0; |
| 691 | 691 | |
| 692 | const builtin_code = try escapeHtml(allocator, try getBuiltinCode(allocator, zig_exe)); | |
| 692 | var env_map = try os.getEnvMap(allocator); | |
| 693 | try env_map.set("ZIG_DEBUG_COLOR", "1"); | |
| 694 | ||
| 695 | const builtin_code = try escapeHtml(allocator, try getBuiltinCode(allocator, &env_map, zig_exe)); | |
| 693 | 696 | |
| 694 | 697 | for (toc.nodes) |node| { |
| 695 | 698 | switch (node) { |
| ... | ... | @@ -778,12 +781,12 @@ fn genHtml(allocator: *mem.Allocator, tokenizer: *Tokenizer, toc: *Toc, out: var |
| 778 | 781 | try build_args.append("c"); |
| 779 | 782 | try out.print(" --library c"); |
| 780 | 783 | } |
| 781 | _ = exec(allocator, build_args.toSliceConst()) catch return parseError(tokenizer, code.source_token, "example failed to compile"); | |
| 784 | _ = exec(allocator, &env_map, build_args.toSliceConst()) catch return parseError(tokenizer, code.source_token, "example failed to compile"); | |
| 782 | 785 | |
| 783 | 786 | const run_args = [][]const u8{tmp_bin_file_name}; |
| 784 | 787 | |
| 785 | 788 | const result = if (expected_outcome == ExpectedOutcome.Fail) blk: { |
| 786 | const result = try os.ChildProcess.exec(allocator, run_args, null, null, max_doc_file_size); | |
| 789 | const result = try os.ChildProcess.exec(allocator, run_args, null, &env_map, max_doc_file_size); | |
| 787 | 790 | switch (result.term) { |
| 788 | 791 | os.ChildProcess.Term.Exited => |exit_code| { |
| 789 | 792 | if (exit_code == 0) { |
| ... | ... | @@ -799,7 +802,7 @@ fn genHtml(allocator: *mem.Allocator, tokenizer: *Tokenizer, toc: *Toc, out: var |
| 799 | 802 | } |
| 800 | 803 | break :blk result; |
| 801 | 804 | } else blk: { |
| 802 | break :blk exec(allocator, run_args) catch return parseError(tokenizer, code.source_token, "example crashed"); | |
| 805 | break :blk exec(allocator, &env_map, run_args) catch return parseError(tokenizer, code.source_token, "example crashed"); | |
| 803 | 806 | }; |
| 804 | 807 | |
| 805 | 808 | const escaped_stderr = try escapeHtml(allocator, result.stderr); |
| ... | ... | @@ -845,7 +848,7 @@ fn genHtml(allocator: *mem.Allocator, tokenizer: *Tokenizer, toc: *Toc, out: var |
| 845 | 848 | "msvc", |
| 846 | 849 | }); |
| 847 | 850 | } |
| 848 | const result = exec(allocator, test_args.toSliceConst()) catch return parseError(tokenizer, code.source_token, "test failed"); | |
| 851 | const result = exec(allocator, &env_map, test_args.toSliceConst()) catch return parseError(tokenizer, code.source_token, "test failed"); | |
| 849 | 852 | const escaped_stderr = try escapeHtml(allocator, result.stderr); |
| 850 | 853 | const escaped_stdout = try escapeHtml(allocator, result.stdout); |
| 851 | 854 | try out.print("\n{}{}</code></pre>\n", escaped_stderr, escaped_stdout); |
| ... | ... | @@ -877,7 +880,7 @@ fn genHtml(allocator: *mem.Allocator, tokenizer: *Tokenizer, toc: *Toc, out: var |
| 877 | 880 | try out.print(" --release-small"); |
| 878 | 881 | }, |
| 879 | 882 | } |
| 880 | const result = try os.ChildProcess.exec(allocator, test_args.toSliceConst(), null, null, max_doc_file_size); | |
| 883 | const result = try os.ChildProcess.exec(allocator, test_args.toSliceConst(), null, &env_map, max_doc_file_size); | |
| 881 | 884 | switch (result.term) { |
| 882 | 885 | os.ChildProcess.Term.Exited => |exit_code| { |
| 883 | 886 | if (exit_code == 0) { |
| ... | ... | @@ -923,7 +926,7 @@ fn genHtml(allocator: *mem.Allocator, tokenizer: *Tokenizer, toc: *Toc, out: var |
| 923 | 926 | builtin.Mode.ReleaseSmall => try test_args.append("--release-small"), |
| 924 | 927 | } |
| 925 | 928 | |
| 926 | const result = try os.ChildProcess.exec(allocator, test_args.toSliceConst(), null, null, max_doc_file_size); | |
| 929 | const result = try os.ChildProcess.exec(allocator, test_args.toSliceConst(), null, &env_map, max_doc_file_size); | |
| 927 | 930 | switch (result.term) { |
| 928 | 931 | os.ChildProcess.Term.Exited => |exit_code| { |
| 929 | 932 | if (exit_code == 0) { |
| ... | ... | @@ -1000,7 +1003,7 @@ fn genHtml(allocator: *mem.Allocator, tokenizer: *Tokenizer, toc: *Toc, out: var |
| 1000 | 1003 | } |
| 1001 | 1004 | |
| 1002 | 1005 | if (maybe_error_match) |error_match| { |
| 1003 | const result = try os.ChildProcess.exec(allocator, build_args.toSliceConst(), null, null, max_doc_file_size); | |
| 1006 | const result = try os.ChildProcess.exec(allocator, build_args.toSliceConst(), null, &env_map, max_doc_file_size); | |
| 1004 | 1007 | switch (result.term) { |
| 1005 | 1008 | os.ChildProcess.Term.Exited => |exit_code| { |
| 1006 | 1009 | if (exit_code == 0) { |
| ... | ... | @@ -1032,7 +1035,7 @@ fn genHtml(allocator: *mem.Allocator, tokenizer: *Tokenizer, toc: *Toc, out: var |
| 1032 | 1035 | try out.print("</code></pre>\n"); |
| 1033 | 1036 | } |
| 1034 | 1037 | } else { |
| 1035 | _ = exec(allocator, build_args.toSliceConst()) catch return parseError(tokenizer, code.source_token, "example failed to compile"); | |
| 1038 | _ = exec(allocator, &env_map, build_args.toSliceConst()) catch return parseError(tokenizer, code.source_token, "example failed to compile"); | |
| 1036 | 1039 | } |
| 1037 | 1040 | if (!code.is_inline) { |
| 1038 | 1041 | try out.print("</code></pre>\n"); |
| ... | ... | @@ -1045,8 +1048,8 @@ fn genHtml(allocator: *mem.Allocator, tokenizer: *Tokenizer, toc: *Toc, out: var |
| 1045 | 1048 | } |
| 1046 | 1049 | } |
| 1047 | 1050 | |
| 1048 | fn exec(allocator: *mem.Allocator, args: []const []const u8) !os.ChildProcess.ExecResult { | |
| 1049 | const result = try os.ChildProcess.exec(allocator, args, null, null, max_doc_file_size); | |
| 1051 | fn exec(allocator: *mem.Allocator, env_map: *std.BufMap, args: []const []const u8) !os.ChildProcess.ExecResult { | |
| 1052 | const result = try os.ChildProcess.exec(allocator, args, null, env_map, max_doc_file_size); | |
| 1050 | 1053 | switch (result.term) { |
| 1051 | 1054 | os.ChildProcess.Term.Exited => |exit_code| { |
| 1052 | 1055 | if (exit_code != 0) { |
| ... | ... | @@ -1070,8 +1073,8 @@ fn exec(allocator: *mem.Allocator, args: []const []const u8) !os.ChildProcess.Ex |
| 1070 | 1073 | return result; |
| 1071 | 1074 | } |
| 1072 | 1075 | |
| 1073 | fn getBuiltinCode(allocator: *mem.Allocator, zig_exe: []const u8) ![]const u8 { | |
| 1074 | const result = try exec(allocator, []const []const u8{ | |
| 1076 | fn getBuiltinCode(allocator: *mem.Allocator, env_map: *std.BufMap, zig_exe: []const u8) ![]const u8 { | |
| 1077 | const result = try exec(allocator, env_map, []const []const u8{ | |
| 1075 | 1078 | zig_exe, |
| 1076 | 1079 | "builtin", |
| 1077 | 1080 | }); |
doc/langref.html.in+51-3| ... | ... | @@ -6649,12 +6649,60 @@ pub fn main() void { |
| 6649 | 6649 | {#header_close#} |
| 6650 | 6650 | |
| 6651 | 6651 | {#header_open|Invalid Error Set Cast#} |
| 6652 | <p>TODO</p> | |
| 6652 | <p>At compile-time:</p> | |
| 6653 | {#code_begin|test_err|error.B not a member of error set 'Set2'#} | |
| 6654 | const Set1 = error{ | |
| 6655 | A, | |
| 6656 | B, | |
| 6657 | }; | |
| 6658 | const Set2 = error{ | |
| 6659 | A, | |
| 6660 | C, | |
| 6661 | }; | |
| 6662 | comptime { | |
| 6663 | _ = @errSetCast(Set2, Set1.B); | |
| 6664 | } | |
| 6665 | {#code_end#} | |
| 6666 | <p>At runtime:</p> | |
| 6667 | {#code_begin|exe_err#} | |
| 6668 | const Set1 = error{ | |
| 6669 | A, | |
| 6670 | B, | |
| 6671 | }; | |
| 6672 | const Set2 = error{ | |
| 6673 | A, | |
| 6674 | C, | |
| 6675 | }; | |
| 6676 | pub fn main() void { | |
| 6677 | _ = foo(Set1.B); | |
| 6678 | } | |
| 6679 | fn foo(set1: Set1) Set2 { | |
| 6680 | return @errSetCast(Set2, set1); | |
| 6681 | } | |
| 6682 | {#code_end#} | |
| 6653 | 6683 | {#header_close#} |
| 6654 | 6684 | |
| 6655 | 6685 | {#header_open|Incorrect Pointer Alignment#} |
| 6656 | <p>TODO</p> | |
| 6657 | ||
| 6686 | <p>At compile-time:</p> | |
| 6687 | {#code_begin|test_err|pointer address 0x1 is not aligned to 4 bytes#} | |
| 6688 | comptime { | |
| 6689 | const ptr = @intToPtr(*i32, 0x1); | |
| 6690 | const aligned = @alignCast(4, ptr); | |
| 6691 | } | |
| 6692 | {#code_end#} | |
| 6693 | <p>At runtime:</p> | |
| 6694 | {#code_begin|exe_err#} | |
| 6695 | pub fn main() !void { | |
| 6696 | var array align(4) = []u32{ 0x11111111, 0x11111111 }; | |
| 6697 | const bytes = @sliceToBytes(array[0..]); | |
| 6698 | if (foo(bytes) != 0x11111111) return error.Wrong; | |
| 6699 | } | |
| 6700 | fn foo(bytes: []u8) u32 { | |
| 6701 | const slice4 = bytes[1..5]; | |
| 6702 | const int_slice = @bytesToSlice(u32, @alignCast(4, slice4)); | |
| 6703 | return int_slice[0]; | |
| 6704 | } | |
| 6705 | {#code_end#} | |
| 6658 | 6706 | {#header_close#} |
| 6659 | 6707 | {#header_open|Wrong Union Field Access#} |
| 6660 | 6708 | <p>TODO</p> |
src/ir.cpp+15| ... | ... | @@ -19370,6 +19370,15 @@ static IrInstruction *ir_align_cast(IrAnalyze *ira, IrInstruction *target, uint3 |
| 19370 | 19370 | if (!val) |
| 19371 | 19371 | return ira->codegen->invalid_instruction; |
| 19372 | 19372 | |
| 19373 | if (val->data.x_ptr.special == ConstPtrSpecialHardCodedAddr && | |
| 19374 | val->data.x_ptr.data.hard_coded_addr.addr % align_bytes != 0) | |
| 19375 | { | |
| 19376 | ir_add_error(ira, target, | |
| 19377 | buf_sprintf("pointer address 0x%" ZIG_PRI_x64 " is not aligned to %" PRIu32 " bytes", | |
| 19378 | val->data.x_ptr.data.hard_coded_addr.addr, align_bytes)); | |
| 19379 | return ira->codegen->invalid_instruction; | |
| 19380 | } | |
| 19381 | ||
| 19373 | 19382 | IrInstruction *result = ir_create_const(&ira->new_irb, target->scope, target->source_node, result_type); |
| 19374 | 19383 | copy_const_val(&result->value, val, false); |
| 19375 | 19384 | result->value.type = result_type; |
| ... | ... | @@ -19796,6 +19805,12 @@ static TypeTableEntry *ir_analyze_instruction_ptr_to_int(IrAnalyze *ira, IrInstr |
| 19796 | 19805 | return ira->codegen->builtin_types.entry_invalid; |
| 19797 | 19806 | } |
| 19798 | 19807 | |
| 19808 | if (!type_has_bits(target->value.type)) { | |
| 19809 | ir_add_error(ira, target, | |
| 19810 | buf_sprintf("pointer to size 0 type has no address")); | |
| 19811 | return ira->codegen->builtin_types.entry_invalid; | |
| 19812 | } | |
| 19813 | ||
| 19799 | 19814 | if (instr_is_comptime(target)) { |
| 19800 | 19815 | ConstExprValue *val = ir_resolve_const(ira, target, UndefBad); |
| 19801 | 19816 | if (!val) |
std/build.zig+18| ... | ... | @@ -814,6 +814,7 @@ pub const LibExeObjStep = struct { |
| 814 | 814 | out_h_filename: []const u8, |
| 815 | 815 | assembly_files: ArrayList([]const u8), |
| 816 | 816 | packages: ArrayList(Pkg), |
| 817 | build_options_contents: std.Buffer, | |
| 817 | 818 | |
| 818 | 819 | // C only stuff |
| 819 | 820 | source_files: ArrayList([]const u8), |
| ... | ... | @@ -905,6 +906,7 @@ pub const LibExeObjStep = struct { |
| 905 | 906 | .lib_paths = ArrayList([]const u8).init(builder.allocator), |
| 906 | 907 | .object_src = undefined, |
| 907 | 908 | .disable_libc = true, |
| 909 | .build_options_contents = std.Buffer.initSize(builder.allocator, 0) catch unreachable, | |
| 908 | 910 | }; |
| 909 | 911 | self.computeOutFileNames(); |
| 910 | 912 | return self; |
| ... | ... | @@ -945,6 +947,7 @@ pub const LibExeObjStep = struct { |
| 945 | 947 | .out_h_filename = undefined, |
| 946 | 948 | .assembly_files = undefined, |
| 947 | 949 | .packages = undefined, |
| 950 | .build_options_contents = undefined, | |
| 948 | 951 | }; |
| 949 | 952 | self.computeOutFileNames(); |
| 950 | 953 | return self; |
| ... | ... | @@ -1096,6 +1099,12 @@ pub const LibExeObjStep = struct { |
| 1096 | 1099 | self.include_dirs.append(self.builder.cache_root) catch unreachable; |
| 1097 | 1100 | } |
| 1098 | 1101 | |
| 1102 | pub fn addBuildOption(self: *LibExeObjStep, comptime T: type, name: []const u8, value: T) void { | |
| 1103 | assert(self.is_zig); | |
| 1104 | const out = &std.io.BufferOutStream.init(&self.build_options_contents).stream; | |
| 1105 | out.print("pub const {} = {};\n", name, value) catch unreachable; | |
| 1106 | } | |
| 1107 | ||
| 1099 | 1108 | pub fn addIncludeDir(self: *LibExeObjStep, path: []const u8) void { |
| 1100 | 1109 | self.include_dirs.append(path) catch unreachable; |
| 1101 | 1110 | } |
| ... | ... | @@ -1155,6 +1164,15 @@ pub const LibExeObjStep = struct { |
| 1155 | 1164 | zig_args.append(builder.pathFromRoot(root_src)) catch unreachable; |
| 1156 | 1165 | } |
| 1157 | 1166 | |
| 1167 | if (self.build_options_contents.len() > 0) { | |
| 1168 | const build_options_file = try os.path.join(builder.allocator, builder.cache_root, builder.fmt("{}_build_options.zig", self.name)); | |
| 1169 | try std.io.writeFile(builder.allocator, build_options_file, self.build_options_contents.toSliceConst()); | |
| 1170 | try zig_args.append("--pkg-begin"); | |
| 1171 | try zig_args.append("build_options"); | |
| 1172 | try zig_args.append(builder.pathFromRoot(build_options_file)); | |
| 1173 | try zig_args.append("--pkg-end"); | |
| 1174 | } | |
| 1175 | ||
| 1158 | 1176 | for (self.object_files.toSliceConst()) |object_file| { |
| 1159 | 1177 | zig_args.append("--object") catch unreachable; |
| 1160 | 1178 | zig_args.append(builder.pathFromRoot(object_file)) catch unreachable; |
std/debug/index.zig+50-23| ... | ... | @@ -10,6 +10,7 @@ const ArrayList = std.ArrayList; |
| 10 | 10 | const builtin = @import("builtin"); |
| 11 | 11 | |
| 12 | 12 | pub const FailingAllocator = @import("failing_allocator.zig").FailingAllocator; |
| 13 | pub const failing_allocator = FailingAllocator.init(global_allocator, 0); | |
| 13 | 14 | |
| 14 | 15 | pub const runtime_safety = switch (builtin.mode) { |
| 15 | 16 | builtin.Mode.Debug, builtin.Mode.ReleaseSafe => true, |
| ... | ... | @@ -49,6 +50,12 @@ pub fn getSelfDebugInfo() !*ElfStackTrace { |
| 49 | 50 | } |
| 50 | 51 | } |
| 51 | 52 | |
| 53 | fn wantTtyColor() bool { | |
| 54 | var bytes: [128]u8 = undefined; | |
| 55 | const allocator = &std.heap.FixedBufferAllocator.init(bytes[0..]).allocator; | |
| 56 | return if (std.os.getEnvVarOwned(allocator, "ZIG_DEBUG_COLOR")) |_| true else |_| stderr_file.isTty(); | |
| 57 | } | |
| 58 | ||
| 52 | 59 | /// Tries to print the current stack trace to stderr, unbuffered, and ignores any error returned. |
| 53 | 60 | pub fn dumpCurrentStackTrace(start_addr: ?usize) void { |
| 54 | 61 | const stderr = getStderrStream() catch return; |
| ... | ... | @@ -56,7 +63,7 @@ pub fn dumpCurrentStackTrace(start_addr: ?usize) void { |
| 56 | 63 | stderr.print("Unable to dump stack trace: Unable to open debug info: {}\n", @errorName(err)) catch return; |
| 57 | 64 | return; |
| 58 | 65 | }; |
| 59 | writeCurrentStackTrace(stderr, getDebugInfoAllocator(), debug_info, stderr_file.isTty(), start_addr) catch |err| { | |
| 66 | writeCurrentStackTrace(stderr, getDebugInfoAllocator(), debug_info, wantTtyColor(), start_addr) catch |err| { | |
| 60 | 67 | stderr.print("Unable to dump stack trace: {}\n", @errorName(err)) catch return; |
| 61 | 68 | return; |
| 62 | 69 | }; |
| ... | ... | @@ -69,7 +76,7 @@ pub fn dumpStackTrace(stack_trace: *const builtin.StackTrace) void { |
| 69 | 76 | stderr.print("Unable to dump stack trace: Unable to open debug info: {}\n", @errorName(err)) catch return; |
| 70 | 77 | return; |
| 71 | 78 | }; |
| 72 | writeStackTrace(stack_trace, stderr, getDebugInfoAllocator(), debug_info, stderr_file.isTty()) catch |err| { | |
| 79 | writeStackTrace(stack_trace, stderr, getDebugInfoAllocator(), debug_info, wantTtyColor()) catch |err| { | |
| 73 | 80 | stderr.print("Unable to dump stack trace: {}\n", @errorName(err)) catch return; |
| 74 | 81 | return; |
| 75 | 82 | }; |
| ... | ... | @@ -161,7 +168,7 @@ pub fn writeStackTrace(stack_trace: *const builtin.StackTrace, out_stream: var, |
| 161 | 168 | frame_index = (frame_index + 1) % stack_trace.instruction_addresses.len; |
| 162 | 169 | }) { |
| 163 | 170 | const return_address = stack_trace.instruction_addresses[frame_index]; |
| 164 | try printSourceAtAddress(debug_info, out_stream, return_address); | |
| 171 | try printSourceAtAddress(debug_info, out_stream, return_address, tty_color); | |
| 165 | 172 | } |
| 166 | 173 | } |
| 167 | 174 | |
| ... | ... | @@ -194,13 +201,11 @@ pub fn writeCurrentStackTrace(out_stream: var, allocator: *mem.Allocator, debug_ |
| 194 | 201 | } |
| 195 | 202 | }, |
| 196 | 203 | } |
| 197 | try printSourceAtAddress(debug_info, out_stream, return_address); | |
| 204 | try printSourceAtAddress(debug_info, out_stream, return_address, tty_color); | |
| 198 | 205 | } |
| 199 | 206 | } |
| 200 | 207 | |
| 201 | fn printSourceAtAddress(debug_info: *ElfStackTrace, out_stream: var, address: usize) !void { | |
| 202 | const ptr_hex = "0x{x}"; | |
| 203 | ||
| 208 | fn printSourceAtAddress(debug_info: *ElfStackTrace, out_stream: var, address: usize, tty_color: bool) !void { | |
| 204 | 209 | switch (builtin.os) { |
| 205 | 210 | builtin.Os.windows => return error.UnsupportedDebugInfo, |
| 206 | 211 | builtin.Os.macosx => { |
| ... | ... | @@ -214,36 +219,58 @@ fn printSourceAtAddress(debug_info: *ElfStackTrace, out_stream: var, address: us |
| 214 | 219 | .address = address, |
| 215 | 220 | }; |
| 216 | 221 | const symbol = debug_info.symbol_table.search(address) orelse &unknown; |
| 217 | try out_stream.print(WHITE ++ "{}" ++ RESET ++ ": " ++ DIM ++ ptr_hex ++ " in ??? (???)" ++ RESET ++ "\n", symbol.name, address); | |
| 222 | try out_stream.print(WHITE ++ "{}" ++ RESET ++ ": " ++ DIM ++ "0x{x}" ++ " in ??? (???)" ++ RESET ++ "\n", symbol.name, address); | |
| 218 | 223 | }, |
| 219 | 224 | else => { |
| 220 | 225 | const compile_unit = findCompileUnit(debug_info, address) catch { |
| 221 | try out_stream.print("???:?:?: " ++ DIM ++ ptr_hex ++ " in ??? (???)" ++ RESET ++ "\n ???\n\n", address); | |
| 226 | if (tty_color) { | |
| 227 | try out_stream.print("???:?:?: " ++ DIM ++ "0x{x} in ??? (???)" ++ RESET ++ "\n ???\n\n", address); | |
| 228 | } else { | |
| 229 | try out_stream.print("???:?:?: 0x{x} in ??? (???)\n ???\n\n", address); | |
| 230 | } | |
| 222 | 231 | return; |
| 223 | 232 | }; |
| 224 | 233 | const compile_unit_name = try compile_unit.die.getAttrString(debug_info, DW.AT_name); |
| 225 | 234 | if (getLineNumberInfo(debug_info, compile_unit, address - 1)) |line_info| { |
| 226 | 235 | defer line_info.deinit(); |
| 227 | try out_stream.print(WHITE ++ "{}:{}:{}" ++ RESET ++ ": " ++ DIM ++ ptr_hex ++ " in ??? ({})" ++ RESET ++ "\n", line_info.file_name, line_info.line, line_info.column, address, compile_unit_name); | |
| 228 | if (printLineFromFile(debug_info.allocator(), out_stream, line_info)) { | |
| 229 | if (line_info.column == 0) { | |
| 230 | try out_stream.write("\n"); | |
| 231 | } else { | |
| 232 | { | |
| 233 | var col_i: usize = 1; | |
| 234 | while (col_i < line_info.column) : (col_i += 1) { | |
| 235 | try out_stream.writeByte(' '); | |
| 236 | if (tty_color) { | |
| 237 | try out_stream.print( | |
| 238 | WHITE ++ "{}:{}:{}" ++ RESET ++ ": " ++ DIM ++ "0x{x} in ??? ({})" ++ RESET ++ "\n", | |
| 239 | line_info.file_name, | |
| 240 | line_info.line, | |
| 241 | line_info.column, | |
| 242 | address, | |
| 243 | compile_unit_name, | |
| 244 | ); | |
| 245 | if (printLineFromFile(debug_info.allocator(), out_stream, line_info)) { | |
| 246 | if (line_info.column == 0) { | |
| 247 | try out_stream.write("\n"); | |
| 248 | } else { | |
| 249 | { | |
| 250 | var col_i: usize = 1; | |
| 251 | while (col_i < line_info.column) : (col_i += 1) { | |
| 252 | try out_stream.writeByte(' '); | |
| 253 | } | |
| 236 | 254 | } |
| 255 | try out_stream.write(GREEN ++ "^" ++ RESET ++ "\n"); | |
| 237 | 256 | } |
| 238 | try out_stream.write(GREEN ++ "^" ++ RESET ++ "\n"); | |
| 257 | } else |err| switch (err) { | |
| 258 | error.EndOfFile => {}, | |
| 259 | else => return err, | |
| 239 | 260 | } |
| 240 | } else |err| switch (err) { | |
| 241 | error.EndOfFile => {}, | |
| 242 | else => return err, | |
| 261 | } else { | |
| 262 | try out_stream.print( | |
| 263 | "{}:{}:{}: 0x{x} in ??? ({})\n", | |
| 264 | line_info.file_name, | |
| 265 | line_info.line, | |
| 266 | line_info.column, | |
| 267 | address, | |
| 268 | compile_unit_name, | |
| 269 | ); | |
| 243 | 270 | } |
| 244 | 271 | } else |err| switch (err) { |
| 245 | 272 | error.MissingDebugInfo, error.InvalidDebugInfo => { |
| 246 | try out_stream.print(ptr_hex ++ " in ??? ({})\n", address, compile_unit_name); | |
| 273 | try out_stream.print("0x{x} in ??? ({})\n", address, compile_unit_name); | |
| 247 | 274 | }, |
| 248 | 275 | else => return err, |
| 249 | 276 | } |
std/hash_map.zig+10-10| ... | ... | @@ -259,14 +259,14 @@ test "basic hash map usage" { |
| 259 | 259 | var map = HashMap(i32, i32, hash_i32, eql_i32).init(&direct_allocator.allocator); |
| 260 | 260 | defer map.deinit(); |
| 261 | 261 | |
| 262 | assert((map.put(1, 11) catch unreachable) == null); | |
| 263 | assert((map.put(2, 22) catch unreachable) == null); | |
| 264 | assert((map.put(3, 33) catch unreachable) == null); | |
| 265 | assert((map.put(4, 44) catch unreachable) == null); | |
| 266 | assert((map.put(5, 55) catch unreachable) == null); | |
| 262 | assert((try map.put(1, 11)) == null); | |
| 263 | assert((try map.put(2, 22)) == null); | |
| 264 | assert((try map.put(3, 33)) == null); | |
| 265 | assert((try map.put(4, 44)) == null); | |
| 266 | assert((try map.put(5, 55)) == null); | |
| 267 | 267 | |
| 268 | assert((map.put(5, 66) catch unreachable).? == 55); | |
| 269 | assert((map.put(5, 55) catch unreachable).? == 66); | |
| 268 | assert((try map.put(5, 66)).? == 55); | |
| 269 | assert((try map.put(5, 55)).? == 66); | |
| 270 | 270 | |
| 271 | 271 | assert(map.contains(2)); |
| 272 | 272 | assert(map.get(2).?.value == 22); |
| ... | ... | @@ -282,9 +282,9 @@ test "iterator hash map" { |
| 282 | 282 | var reset_map = HashMap(i32, i32, hash_i32, eql_i32).init(&direct_allocator.allocator); |
| 283 | 283 | defer reset_map.deinit(); |
| 284 | 284 | |
| 285 | assert((reset_map.put(1, 11) catch unreachable) == null); | |
| 286 | assert((reset_map.put(2, 22) catch unreachable) == null); | |
| 287 | assert((reset_map.put(3, 33) catch unreachable) == null); | |
| 285 | assert((try reset_map.put(1, 11)) == null); | |
| 286 | assert((try reset_map.put(2, 22)) == null); | |
| 287 | assert((try reset_map.put(3, 33)) == null); | |
| 288 | 288 | |
| 289 | 289 | var keys = []i32{ |
| 290 | 290 | 1, |
std/os/index.zig+11-3| ... | ... | @@ -553,8 +553,13 @@ pub fn getEnvPosix(key: []const u8) ?[]const u8 { |
| 553 | 553 | return null; |
| 554 | 554 | } |
| 555 | 555 | |
| 556 | pub const GetEnvVarOwnedError = error{ | |
| 557 | OutOfMemory, | |
| 558 | EnvironmentVariableNotFound, | |
| 559 | }; | |
| 560 | ||
| 556 | 561 | /// Caller must free returned memory. |
| 557 | pub fn getEnvVarOwned(allocator: *mem.Allocator, key: []const u8) ![]u8 { | |
| 562 | pub fn getEnvVarOwned(allocator: *mem.Allocator, key: []const u8) GetEnvVarOwnedError![]u8 { | |
| 558 | 563 | if (is_windows) { |
| 559 | 564 | const key_with_null = try cstr.addNullByte(allocator, key); |
| 560 | 565 | defer allocator.free(key_with_null); |
| ... | ... | @@ -563,14 +568,17 @@ pub fn getEnvVarOwned(allocator: *mem.Allocator, key: []const u8) ![]u8 { |
| 563 | 568 | errdefer allocator.free(buf); |
| 564 | 569 | |
| 565 | 570 | while (true) { |
| 566 | const windows_buf_len = try math.cast(windows.DWORD, buf.len); | |
| 571 | const windows_buf_len = math.cast(windows.DWORD, buf.len) catch return error.OutOfMemory; | |
| 567 | 572 | const result = windows.GetEnvironmentVariableA(key_with_null.ptr, buf.ptr, windows_buf_len); |
| 568 | 573 | |
| 569 | 574 | if (result == 0) { |
| 570 | 575 | const err = windows.GetLastError(); |
| 571 | 576 | return switch (err) { |
| 572 | 577 | windows.ERROR.ENVVAR_NOT_FOUND => error.EnvironmentVariableNotFound, |
| 573 | else => unexpectedErrorWindows(err), | |
| 578 | else => { | |
| 579 | _ = unexpectedErrorWindows(err); | |
| 580 | return error.EnvironmentVariableNotFound; | |
| 581 | }, | |
| 574 | 582 | }; |
| 575 | 583 | } |
| 576 | 584 |
std/special/build_runner.zig+6-3| ... | ... | @@ -122,10 +122,13 @@ pub fn main() !void { |
| 122 | 122 | return usageAndErr(&builder, true, try stderr_stream); |
| 123 | 123 | |
| 124 | 124 | builder.make(targets.toSliceConst()) catch |err| { |
| 125 | if (err == error.InvalidStepName) { | |
| 126 | return usageAndErr(&builder, true, try stderr_stream); | |
| 125 | switch (err) { | |
| 126 | error.InvalidStepName => { | |
| 127 | return usageAndErr(&builder, true, try stderr_stream); | |
| 128 | }, | |
| 129 | error.UncleanExit => os.exit(1), | |
| 130 | else => return err, | |
| 127 | 131 | } |
| 128 | return err; | |
| 129 | 132 | }; |
| 130 | 133 | } |
| 131 | 134 |
std/zig/bench.zig+6-8| ... | ... | @@ -19,20 +19,18 @@ pub fn main() !void { |
| 19 | 19 | } |
| 20 | 20 | const end = timer.read(); |
| 21 | 21 | memory_used /= iterations; |
| 22 | const elapsed_s = f64(end - start) / std.os.time.ns_per_s; | |
| 23 | const bytes_per_sec = f64(source.len * iterations) / elapsed_s; | |
| 22 | const elapsed_s = @intToFloat(f64, end - start) / std.os.time.ns_per_s; | |
| 23 | const bytes_per_sec = @intToFloat(f64, source.len * iterations) / elapsed_s; | |
| 24 | 24 | const mb_per_sec = bytes_per_sec / (1024 * 1024); |
| 25 | 25 | |
| 26 | 26 | var stdout_file = try std.io.getStdOut(); |
| 27 | const stdout = *std.io.FileOutStream.init(*stdout_file).stream; | |
| 28 | try stdout.print("{.3} MB/s, {} KB used \n", mb_per_sec, memory_used / 1024); | |
| 27 | const stdout = &std.io.FileOutStream.init(&stdout_file).stream; | |
| 28 | try stdout.print("{.3} MiB/s, {} KiB used \n", mb_per_sec, memory_used / 1024); | |
| 29 | 29 | } |
| 30 | 30 | |
| 31 | 31 | fn testOnce() usize { |
| 32 | 32 | var fixed_buf_alloc = std.heap.FixedBufferAllocator.init(fixed_buffer_mem[0..]); |
| 33 | var allocator = *fixed_buf_alloc.allocator; | |
| 34 | var tokenizer = Tokenizer.init(source); | |
| 35 | var parser = Parser.init(*tokenizer, allocator, "(memory buffer)"); | |
| 36 | _ = parser.parse() catch @panic("parse failure"); | |
| 33 | var allocator = &fixed_buf_alloc.allocator; | |
| 34 | _ = std.zig.parse(allocator, source) catch @panic("parse failure"); | |
| 37 | 35 | return fixed_buf_alloc.end_index; |
| 38 | 36 | } |
test/compile_errors.zig+19| ... | ... | @@ -1,6 +1,25 @@ |
| 1 | 1 | const tests = @import("tests.zig"); |
| 2 | 2 | |
| 3 | 3 | pub fn addCases(cases: *tests.CompileErrorContext) void { |
| 4 | cases.add( | |
| 5 | "bad @alignCast at comptime", | |
| 6 | \\comptime { | |
| 7 | \\ const ptr = @intToPtr(*i32, 0x1); | |
| 8 | \\ const aligned = @alignCast(4, ptr); | |
| 9 | \\} | |
| 10 | , | |
| 11 | ".tmp_source.zig:3:35: error: pointer address 0x1 is not aligned to 4 bytes", | |
| 12 | ); | |
| 13 | ||
| 14 | cases.add( | |
| 15 | "@ptrToInt on *void", | |
| 16 | \\export fn entry() bool { | |
| 17 | \\ return @ptrToInt(&{}) == @ptrToInt(&{}); | |
| 18 | \\} | |
| 19 | , | |
| 20 | ".tmp_source.zig:2:23: error: pointer to size 0 type has no address", | |
| 21 | ); | |
| 22 | ||
| 4 | 23 | cases.add( |
| 5 | 24 | "@popCount - non-integer", |
| 6 | 25 | \\export fn entry(x: f32) u32 { |