authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-07-09 17:14:42-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-07-09 17:14:42-04:00
log3f4d0ecd7e5a57b425b1cd99139145e7e509c3c6
tree76d1d16a397e44c04167456116d6d3cc91f0b994
parent9462852433a815496e0edf5d5b2e00726f5ea072
parent0ac1b83885c7f2a97a8ac25657afcb5c9b80afb4

Merge remote-tracking branch 'origin/master' into m-n-threading


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,7 +689,10 @@ fn termColor(allocator: *mem.Allocator, input: []const u8) ![]u8 {
689fn genHtml(allocator: *mem.Allocator, tokenizer: *Tokenizer, toc: *Toc, out: var, zig_exe: []const u8) !void {689fn genHtml(allocator: *mem.Allocator, tokenizer: *Tokenizer, toc: *Toc, out: var, zig_exe: []const u8) !void {
690 var code_progress_index: usize = 0;690 var code_progress_index: usize = 0;
691691
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));
693696
694 for (toc.nodes) |node| {697 for (toc.nodes) |node| {
695 switch (node) {698 switch (node) {
...@@ -778,12 +781,12 @@ fn genHtml(allocator: *mem.Allocator, tokenizer: *Tokenizer, toc: *Toc, out: var...@@ -778,12 +781,12 @@ fn genHtml(allocator: *mem.Allocator, tokenizer: *Tokenizer, toc: *Toc, out: var
778 try build_args.append("c");781 try build_args.append("c");
779 try out.print(" --library c");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");
782785
783 const run_args = [][]const u8{tmp_bin_file_name};786 const run_args = [][]const u8{tmp_bin_file_name};
784787
785 const result = if (expected_outcome == ExpectedOutcome.Fail) blk: {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 switch (result.term) {790 switch (result.term) {
788 os.ChildProcess.Term.Exited => |exit_code| {791 os.ChildProcess.Term.Exited => |exit_code| {
789 if (exit_code == 0) {792 if (exit_code == 0) {
...@@ -799,7 +802,7 @@ fn genHtml(allocator: *mem.Allocator, tokenizer: *Tokenizer, toc: *Toc, out: var...@@ -799,7 +802,7 @@ fn genHtml(allocator: *mem.Allocator, tokenizer: *Tokenizer, toc: *Toc, out: var
799 }802 }
800 break :blk result;803 break :blk result;
801 } else blk: {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 };
804807
805 const escaped_stderr = try escapeHtml(allocator, result.stderr);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,7 +848,7 @@ fn genHtml(allocator: *mem.Allocator, tokenizer: *Tokenizer, toc: *Toc, out: var
845 "msvc",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 const escaped_stderr = try escapeHtml(allocator, result.stderr);852 const escaped_stderr = try escapeHtml(allocator, result.stderr);
850 const escaped_stdout = try escapeHtml(allocator, result.stdout);853 const escaped_stdout = try escapeHtml(allocator, result.stdout);
851 try out.print("\n{}{}</code></pre>\n", escaped_stderr, escaped_stdout);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,7 +880,7 @@ fn genHtml(allocator: *mem.Allocator, tokenizer: *Tokenizer, toc: *Toc, out: var
877 try out.print(" --release-small");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 switch (result.term) {884 switch (result.term) {
882 os.ChildProcess.Term.Exited => |exit_code| {885 os.ChildProcess.Term.Exited => |exit_code| {
883 if (exit_code == 0) {886 if (exit_code == 0) {
...@@ -923,7 +926,7 @@ fn genHtml(allocator: *mem.Allocator, tokenizer: *Tokenizer, toc: *Toc, out: var...@@ -923,7 +926,7 @@ fn genHtml(allocator: *mem.Allocator, tokenizer: *Tokenizer, toc: *Toc, out: var
923 builtin.Mode.ReleaseSmall => try test_args.append("--release-small"),926 builtin.Mode.ReleaseSmall => try test_args.append("--release-small"),
924 }927 }
925928
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 switch (result.term) {930 switch (result.term) {
928 os.ChildProcess.Term.Exited => |exit_code| {931 os.ChildProcess.Term.Exited => |exit_code| {
929 if (exit_code == 0) {932 if (exit_code == 0) {
...@@ -1000,7 +1003,7 @@ fn genHtml(allocator: *mem.Allocator, tokenizer: *Tokenizer, toc: *Toc, out: var...@@ -1000,7 +1003,7 @@ fn genHtml(allocator: *mem.Allocator, tokenizer: *Tokenizer, toc: *Toc, out: var
1000 }1003 }
10011004
1002 if (maybe_error_match) |error_match| {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 switch (result.term) {1007 switch (result.term) {
1005 os.ChildProcess.Term.Exited => |exit_code| {1008 os.ChildProcess.Term.Exited => |exit_code| {
1006 if (exit_code == 0) {1009 if (exit_code == 0) {
...@@ -1032,7 +1035,7 @@ fn genHtml(allocator: *mem.Allocator, tokenizer: *Tokenizer, toc: *Toc, out: var...@@ -1032,7 +1035,7 @@ fn genHtml(allocator: *mem.Allocator, tokenizer: *Tokenizer, toc: *Toc, out: var
1032 try out.print("</code></pre>\n");1035 try out.print("</code></pre>\n");
1033 }1036 }
1034 } else {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 if (!code.is_inline) {1040 if (!code.is_inline) {
1038 try out.print("</code></pre>\n");1041 try out.print("</code></pre>\n");
...@@ -1045,8 +1048,8 @@ fn genHtml(allocator: *mem.Allocator, tokenizer: *Tokenizer, toc: *Toc, out: var...@@ -1045,8 +1048,8 @@ fn genHtml(allocator: *mem.Allocator, tokenizer: *Tokenizer, toc: *Toc, out: var
1045 }1048 }
1046}1049}
10471050
1048fn exec(allocator: *mem.Allocator, args: []const []const u8) !os.ChildProcess.ExecResult {1051fn exec(allocator: *mem.Allocator, env_map: *std.BufMap, args: []const []const u8) !os.ChildProcess.ExecResult {
1049 const result = try os.ChildProcess.exec(allocator, args, null, null, max_doc_file_size);1052 const result = try os.ChildProcess.exec(allocator, args, null, env_map, max_doc_file_size);
1050 switch (result.term) {1053 switch (result.term) {
1051 os.ChildProcess.Term.Exited => |exit_code| {1054 os.ChildProcess.Term.Exited => |exit_code| {
1052 if (exit_code != 0) {1055 if (exit_code != 0) {
...@@ -1070,8 +1073,8 @@ fn exec(allocator: *mem.Allocator, args: []const []const u8) !os.ChildProcess.Ex...@@ -1070,8 +1073,8 @@ fn exec(allocator: *mem.Allocator, args: []const []const u8) !os.ChildProcess.Ex
1070 return result;1073 return result;
1071}1074}
10721075
1073fn getBuiltinCode(allocator: *mem.Allocator, zig_exe: []const u8) ![]const u8 {1076fn getBuiltinCode(allocator: *mem.Allocator, env_map: *std.BufMap, zig_exe: []const u8) ![]const u8 {
1074 const result = try exec(allocator, []const []const u8{1077 const result = try exec(allocator, env_map, []const []const u8{
1075 zig_exe,1078 zig_exe,
1076 "builtin",1079 "builtin",
1077 });1080 });
doc/langref.html.in+51-3
...@@ -6649,12 +6649,60 @@ pub fn main() void {...@@ -6649,12 +6649,60 @@ pub fn main() void {
6649 {#header_close#}6649 {#header_close#}
66506650
6651 {#header_open|Invalid Error Set Cast#}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'#}
6654const Set1 = error{
6655 A,
6656 B,
6657};
6658const Set2 = error{
6659 A,
6660 C,
6661};
6662comptime {
6663 _ = @errSetCast(Set2, Set1.B);
6664}
6665 {#code_end#}
6666 <p>At runtime:</p>
6667 {#code_begin|exe_err#}
6668const Set1 = error{
6669 A,
6670 B,
6671};
6672const Set2 = error{
6673 A,
6674 C,
6675};
6676pub fn main() void {
6677 _ = foo(Set1.B);
6678}
6679fn foo(set1: Set1) Set2 {
6680 return @errSetCast(Set2, set1);
6681}
6682 {#code_end#}
6653 {#header_close#}6683 {#header_close#}
66546684
6655 {#header_open|Incorrect Pointer Alignment#}6685 {#header_open|Incorrect Pointer Alignment#}
6656 <p>TODO</p>6686 <p>At compile-time:</p>
66576687 {#code_begin|test_err|pointer address 0x1 is not aligned to 4 bytes#}
6688comptime {
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#}
6695pub 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}
6700fn 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 {#header_close#}6706 {#header_close#}
6659 {#header_open|Wrong Union Field Access#}6707 {#header_open|Wrong Union Field Access#}
6660 <p>TODO</p>6708 <p>TODO</p>
src/ir.cpp+15
...@@ -19370,6 +19370,15 @@ static IrInstruction *ir_align_cast(IrAnalyze *ira, IrInstruction *target, uint3...@@ -19370,6 +19370,15 @@ static IrInstruction *ir_align_cast(IrAnalyze *ira, IrInstruction *target, uint3
19370 if (!val)19370 if (!val)
19371 return ira->codegen->invalid_instruction;19371 return ira->codegen->invalid_instruction;
1937219372
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 IrInstruction *result = ir_create_const(&ira->new_irb, target->scope, target->source_node, result_type);19382 IrInstruction *result = ir_create_const(&ira->new_irb, target->scope, target->source_node, result_type);
19374 copy_const_val(&result->value, val, false);19383 copy_const_val(&result->value, val, false);
19375 result->value.type = result_type;19384 result->value.type = result_type;
...@@ -19796,6 +19805,12 @@ static TypeTableEntry *ir_analyze_instruction_ptr_to_int(IrAnalyze *ira, IrInstr...@@ -19796,6 +19805,12 @@ static TypeTableEntry *ir_analyze_instruction_ptr_to_int(IrAnalyze *ira, IrInstr
19796 return ira->codegen->builtin_types.entry_invalid;19805 return ira->codegen->builtin_types.entry_invalid;
19797 }19806 }
1979819807
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 if (instr_is_comptime(target)) {19814 if (instr_is_comptime(target)) {
19800 ConstExprValue *val = ir_resolve_const(ira, target, UndefBad);19815 ConstExprValue *val = ir_resolve_const(ira, target, UndefBad);
19801 if (!val)19816 if (!val)
std/build.zig+18
...@@ -814,6 +814,7 @@ pub const LibExeObjStep = struct {...@@ -814,6 +814,7 @@ pub const LibExeObjStep = struct {
814 out_h_filename: []const u8,814 out_h_filename: []const u8,
815 assembly_files: ArrayList([]const u8),815 assembly_files: ArrayList([]const u8),
816 packages: ArrayList(Pkg),816 packages: ArrayList(Pkg),
817 build_options_contents: std.Buffer,
817818
818 // C only stuff819 // C only stuff
819 source_files: ArrayList([]const u8),820 source_files: ArrayList([]const u8),
...@@ -905,6 +906,7 @@ pub const LibExeObjStep = struct {...@@ -905,6 +906,7 @@ pub const LibExeObjStep = struct {
905 .lib_paths = ArrayList([]const u8).init(builder.allocator),906 .lib_paths = ArrayList([]const u8).init(builder.allocator),
906 .object_src = undefined,907 .object_src = undefined,
907 .disable_libc = true,908 .disable_libc = true,
909 .build_options_contents = std.Buffer.initSize(builder.allocator, 0) catch unreachable,
908 };910 };
909 self.computeOutFileNames();911 self.computeOutFileNames();
910 return self;912 return self;
...@@ -945,6 +947,7 @@ pub const LibExeObjStep = struct {...@@ -945,6 +947,7 @@ pub const LibExeObjStep = struct {
945 .out_h_filename = undefined,947 .out_h_filename = undefined,
946 .assembly_files = undefined,948 .assembly_files = undefined,
947 .packages = undefined,949 .packages = undefined,
950 .build_options_contents = undefined,
948 };951 };
949 self.computeOutFileNames();952 self.computeOutFileNames();
950 return self;953 return self;
...@@ -1096,6 +1099,12 @@ pub const LibExeObjStep = struct {...@@ -1096,6 +1099,12 @@ pub const LibExeObjStep = struct {
1096 self.include_dirs.append(self.builder.cache_root) catch unreachable;1099 self.include_dirs.append(self.builder.cache_root) catch unreachable;
1097 }1100 }
10981101
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 pub fn addIncludeDir(self: *LibExeObjStep, path: []const u8) void {1108 pub fn addIncludeDir(self: *LibExeObjStep, path: []const u8) void {
1100 self.include_dirs.append(path) catch unreachable;1109 self.include_dirs.append(path) catch unreachable;
1101 }1110 }
...@@ -1155,6 +1164,15 @@ pub const LibExeObjStep = struct {...@@ -1155,6 +1164,15 @@ pub const LibExeObjStep = struct {
1155 zig_args.append(builder.pathFromRoot(root_src)) catch unreachable;1164 zig_args.append(builder.pathFromRoot(root_src)) catch unreachable;
1156 }1165 }
11571166
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 for (self.object_files.toSliceConst()) |object_file| {1176 for (self.object_files.toSliceConst()) |object_file| {
1159 zig_args.append("--object") catch unreachable;1177 zig_args.append("--object") catch unreachable;
1160 zig_args.append(builder.pathFromRoot(object_file)) catch unreachable;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,6 +10,7 @@ const ArrayList = std.ArrayList;
10const builtin = @import("builtin");10const builtin = @import("builtin");
1111
12pub const FailingAllocator = @import("failing_allocator.zig").FailingAllocator;12pub const FailingAllocator = @import("failing_allocator.zig").FailingAllocator;
13pub const failing_allocator = FailingAllocator.init(global_allocator, 0);
1314
14pub const runtime_safety = switch (builtin.mode) {15pub const runtime_safety = switch (builtin.mode) {
15 builtin.Mode.Debug, builtin.Mode.ReleaseSafe => true,16 builtin.Mode.Debug, builtin.Mode.ReleaseSafe => true,
...@@ -49,6 +50,12 @@ pub fn getSelfDebugInfo() !*ElfStackTrace {...@@ -49,6 +50,12 @@ pub fn getSelfDebugInfo() !*ElfStackTrace {
49 }50 }
50}51}
5152
53fn 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/// Tries to print the current stack trace to stderr, unbuffered, and ignores any error returned.59/// Tries to print the current stack trace to stderr, unbuffered, and ignores any error returned.
53pub fn dumpCurrentStackTrace(start_addr: ?usize) void {60pub fn dumpCurrentStackTrace(start_addr: ?usize) void {
54 const stderr = getStderrStream() catch return;61 const stderr = getStderrStream() catch return;
...@@ -56,7 +63,7 @@ pub fn dumpCurrentStackTrace(start_addr: ?usize) void {...@@ -56,7 +63,7 @@ pub fn dumpCurrentStackTrace(start_addr: ?usize) void {
56 stderr.print("Unable to dump stack trace: Unable to open debug info: {}\n", @errorName(err)) catch return;63 stderr.print("Unable to dump stack trace: Unable to open debug info: {}\n", @errorName(err)) catch return;
57 return;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 stderr.print("Unable to dump stack trace: {}\n", @errorName(err)) catch return;67 stderr.print("Unable to dump stack trace: {}\n", @errorName(err)) catch return;
61 return;68 return;
62 };69 };
...@@ -69,7 +76,7 @@ pub fn dumpStackTrace(stack_trace: *const builtin.StackTrace) void {...@@ -69,7 +76,7 @@ pub fn dumpStackTrace(stack_trace: *const builtin.StackTrace) void {
69 stderr.print("Unable to dump stack trace: Unable to open debug info: {}\n", @errorName(err)) catch return;76 stderr.print("Unable to dump stack trace: Unable to open debug info: {}\n", @errorName(err)) catch return;
70 return;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 stderr.print("Unable to dump stack trace: {}\n", @errorName(err)) catch return;80 stderr.print("Unable to dump stack trace: {}\n", @errorName(err)) catch return;
74 return;81 return;
75 };82 };
...@@ -161,7 +168,7 @@ pub fn writeStackTrace(stack_trace: *const builtin.StackTrace, out_stream: var,...@@ -161,7 +168,7 @@ pub fn writeStackTrace(stack_trace: *const builtin.StackTrace, out_stream: var,
161 frame_index = (frame_index + 1) % stack_trace.instruction_addresses.len;168 frame_index = (frame_index + 1) % stack_trace.instruction_addresses.len;
162 }) {169 }) {
163 const return_address = stack_trace.instruction_addresses[frame_index];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}
167174
...@@ -194,13 +201,11 @@ pub fn writeCurrentStackTrace(out_stream: var, allocator: *mem.Allocator, debug_...@@ -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}
200207
201fn printSourceAtAddress(debug_info: *ElfStackTrace, out_stream: var, address: usize) !void {208fn printSourceAtAddress(debug_info: *ElfStackTrace, out_stream: var, address: usize, tty_color: bool) !void {
202 const ptr_hex = "0x{x}";
203
204 switch (builtin.os) {209 switch (builtin.os) {
205 builtin.Os.windows => return error.UnsupportedDebugInfo,210 builtin.Os.windows => return error.UnsupportedDebugInfo,
206 builtin.Os.macosx => {211 builtin.Os.macosx => {
...@@ -214,36 +219,58 @@ fn printSourceAtAddress(debug_info: *ElfStackTrace, out_stream: var, address: us...@@ -214,36 +219,58 @@ fn printSourceAtAddress(debug_info: *ElfStackTrace, out_stream: var, address: us
214 .address = address,219 .address = address,
215 };220 };
216 const symbol = debug_info.symbol_table.search(address) orelse &unknown;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 else => {224 else => {
220 const compile_unit = findCompileUnit(debug_info, address) catch {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 return;231 return;
223 };232 };
224 const compile_unit_name = try compile_unit.die.getAttrString(debug_info, DW.AT_name);233 const compile_unit_name = try compile_unit.die.getAttrString(debug_info, DW.AT_name);
225 if (getLineNumberInfo(debug_info, compile_unit, address - 1)) |line_info| {234 if (getLineNumberInfo(debug_info, compile_unit, address - 1)) |line_info| {
226 defer line_info.deinit();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);236 if (tty_color) {
228 if (printLineFromFile(debug_info.allocator(), out_stream, line_info)) {237 try out_stream.print(
229 if (line_info.column == 0) {238 WHITE ++ "{}:{}:{}" ++ RESET ++ ": " ++ DIM ++ "0x{x} in ??? ({})" ++ RESET ++ "\n",
230 try out_stream.write("\n");239 line_info.file_name,
231 } else {240 line_info.line,
232 {241 line_info.column,
233 var col_i: usize = 1;242 address,
234 while (col_i < line_info.column) : (col_i += 1) {243 compile_unit_name,
235 try out_stream.writeByte(' ');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) {261 } else {
241 error.EndOfFile => {},262 try out_stream.print(
242 else => return err,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 } else |err| switch (err) {271 } else |err| switch (err) {
245 error.MissingDebugInfo, error.InvalidDebugInfo => {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 else => return err,275 else => return err,
249 }276 }
std/hash_map.zig+10-10
...@@ -259,14 +259,14 @@ test "basic hash map usage" {...@@ -259,14 +259,14 @@ test "basic hash map usage" {
259 var map = HashMap(i32, i32, hash_i32, eql_i32).init(&direct_allocator.allocator);259 var map = HashMap(i32, i32, hash_i32, eql_i32).init(&direct_allocator.allocator);
260 defer map.deinit();260 defer map.deinit();
261261
262 assert((map.put(1, 11) catch unreachable) == null);262 assert((try map.put(1, 11)) == null);
263 assert((map.put(2, 22) catch unreachable) == null);263 assert((try map.put(2, 22)) == null);
264 assert((map.put(3, 33) catch unreachable) == null);264 assert((try map.put(3, 33)) == null);
265 assert((map.put(4, 44) catch unreachable) == null);265 assert((try map.put(4, 44)) == null);
266 assert((map.put(5, 55) catch unreachable) == null);266 assert((try map.put(5, 55)) == null);
267267
268 assert((map.put(5, 66) catch unreachable).? == 55);268 assert((try map.put(5, 66)).? == 55);
269 assert((map.put(5, 55) catch unreachable).? == 66);269 assert((try map.put(5, 55)).? == 66);
270270
271 assert(map.contains(2));271 assert(map.contains(2));
272 assert(map.get(2).?.value == 22);272 assert(map.get(2).?.value == 22);
...@@ -282,9 +282,9 @@ test "iterator hash map" {...@@ -282,9 +282,9 @@ test "iterator hash map" {
282 var reset_map = HashMap(i32, i32, hash_i32, eql_i32).init(&direct_allocator.allocator);282 var reset_map = HashMap(i32, i32, hash_i32, eql_i32).init(&direct_allocator.allocator);
283 defer reset_map.deinit();283 defer reset_map.deinit();
284284
285 assert((reset_map.put(1, 11) catch unreachable) == null);285 assert((try reset_map.put(1, 11)) == null);
286 assert((reset_map.put(2, 22) catch unreachable) == null);286 assert((try reset_map.put(2, 22)) == null);
287 assert((reset_map.put(3, 33) catch unreachable) == null);287 assert((try reset_map.put(3, 33)) == null);
288288
289 var keys = []i32{289 var keys = []i32{
290 1,290 1,
std/os/index.zig+11-3
...@@ -553,8 +553,13 @@ pub fn getEnvPosix(key: []const u8) ?[]const u8 {...@@ -553,8 +553,13 @@ pub fn getEnvPosix(key: []const u8) ?[]const u8 {
553 return null;553 return null;
554}554}
555555
556pub const GetEnvVarOwnedError = error{
557 OutOfMemory,
558 EnvironmentVariableNotFound,
559};
560
556/// Caller must free returned memory.561/// Caller must free returned memory.
557pub fn getEnvVarOwned(allocator: *mem.Allocator, key: []const u8) ![]u8 {562pub fn getEnvVarOwned(allocator: *mem.Allocator, key: []const u8) GetEnvVarOwnedError![]u8 {
558 if (is_windows) {563 if (is_windows) {
559 const key_with_null = try cstr.addNullByte(allocator, key);564 const key_with_null = try cstr.addNullByte(allocator, key);
560 defer allocator.free(key_with_null);565 defer allocator.free(key_with_null);
...@@ -563,14 +568,17 @@ pub fn getEnvVarOwned(allocator: *mem.Allocator, key: []const u8) ![]u8 {...@@ -563,14 +568,17 @@ pub fn getEnvVarOwned(allocator: *mem.Allocator, key: []const u8) ![]u8 {
563 errdefer allocator.free(buf);568 errdefer allocator.free(buf);
564569
565 while (true) {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 const result = windows.GetEnvironmentVariableA(key_with_null.ptr, buf.ptr, windows_buf_len);572 const result = windows.GetEnvironmentVariableA(key_with_null.ptr, buf.ptr, windows_buf_len);
568573
569 if (result == 0) {574 if (result == 0) {
570 const err = windows.GetLastError();575 const err = windows.GetLastError();
571 return switch (err) {576 return switch (err) {
572 windows.ERROR.ENVVAR_NOT_FOUND => error.EnvironmentVariableNotFound,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 }
576584
std/special/build_runner.zig+6-3
...@@ -122,10 +122,13 @@ pub fn main() !void {...@@ -122,10 +122,13 @@ pub fn main() !void {
122 return usageAndErr(&builder, true, try stderr_stream);122 return usageAndErr(&builder, true, try stderr_stream);
123123
124 builder.make(targets.toSliceConst()) catch |err| {124 builder.make(targets.toSliceConst()) catch |err| {
125 if (err == error.InvalidStepName) {125 switch (err) {
126 return usageAndErr(&builder, true, try stderr_stream);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}
131134
std/zig/bench.zig+6-8
...@@ -19,20 +19,18 @@ pub fn main() !void {...@@ -19,20 +19,18 @@ pub fn main() !void {
19 }19 }
20 const end = timer.read();20 const end = timer.read();
21 memory_used /= iterations;21 memory_used /= iterations;
22 const elapsed_s = f64(end - start) / std.os.time.ns_per_s;22 const elapsed_s = @intToFloat(f64, end - start) / std.os.time.ns_per_s;
23 const bytes_per_sec = f64(source.len * iterations) / elapsed_s;23 const bytes_per_sec = @intToFloat(f64, source.len * iterations) / elapsed_s;
24 const mb_per_sec = bytes_per_sec / (1024 * 1024);24 const mb_per_sec = bytes_per_sec / (1024 * 1024);
2525
26 var stdout_file = try std.io.getStdOut();26 var stdout_file = try std.io.getStdOut();
27 const stdout = *std.io.FileOutStream.init(*stdout_file).stream;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);28 try stdout.print("{.3} MiB/s, {} KiB used \n", mb_per_sec, memory_used / 1024);
29}29}
3030
31fn testOnce() usize {31fn testOnce() usize {
32 var fixed_buf_alloc = std.heap.FixedBufferAllocator.init(fixed_buffer_mem[0..]);32 var fixed_buf_alloc = std.heap.FixedBufferAllocator.init(fixed_buffer_mem[0..]);
33 var allocator = *fixed_buf_alloc.allocator;33 var allocator = &fixed_buf_alloc.allocator;
34 var tokenizer = Tokenizer.init(source);34 _ = std.zig.parse(allocator, source) catch @panic("parse failure");
35 var parser = Parser.init(*tokenizer, allocator, "(memory buffer)");
36 _ = parser.parse() catch @panic("parse failure");
37 return fixed_buf_alloc.end_index;35 return fixed_buf_alloc.end_index;
38}36}
test/compile_errors.zig+19
...@@ -1,6 +1,25 @@...@@ -1,6 +1,25 @@
1const tests = @import("tests.zig");1const tests = @import("tests.zig");
22
3pub fn addCases(cases: *tests.CompileErrorContext) void {3pub 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 cases.add(23 cases.add(
5 "@popCount - non-integer",24 "@popCount - non-integer",
6 \\export fn entry(x: f32) u32 {25 \\export fn entry(x: f32) u32 {