From 47f06be36943f808aa9798c19172363afe6ae35c Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Tue, 19 Nov 2019 20:29:08 -0500 Subject: [PATCH] string literals are now null terminated this also deletes C string literals from the language, and then makes the std lib changes and compiler changes necessary to get the behavior tests and std lib tests passing again. --- lib/std/child_process.zig | 2 +- lib/std/crypto/x25519.zig | 12 +- lib/std/cstr.zig | 4 +- lib/std/fmt.zig | 112 +++--- lib/std/fs.zig | 6 +- lib/std/fs/file.zig | 2 +- lib/std/fs/path.zig | 2 +- lib/std/hash/siphash.zig | 256 ++++++------ lib/std/io/test.zig | 4 +- lib/std/mem.zig | 18 +- lib/std/meta.zig | 13 +- lib/std/meta/trait.zig | 2 - lib/std/net.zig | 16 +- lib/std/os.zig | 4 +- lib/std/os/linux.zig | 2 +- lib/std/os/linux/test.zig | 4 +- lib/std/process.zig | 14 +- lib/std/special/c.zig | 10 +- lib/std/thread.zig | 2 +- lib/std/valgrind/memcheck.zig | 2 +- src-self-hosted/codegen.zig | 6 +- src-self-hosted/compilation.zig | 4 +- src-self-hosted/ir.zig | 12 +- src-self-hosted/link.zig | 126 +++--- src-self-hosted/stage1.zig | 2 +- src-self-hosted/value.zig | 2 +- src/all_types.hpp | 9 +- src/analyze.cpp | 143 ++++--- src/analyze.hpp | 9 +- src/ast_render.cpp | 3 - src/codegen.cpp | 61 +-- src/ir.cpp | 448 +++++++++++++++------ src/parser.cpp | 1 - src/tokenizer.cpp | 53 +-- src/tokenizer.hpp | 1 - src/translate_c.cpp | 18 +- test/compare_output.zig | 72 ++-- test/compile_errors.zig | 10 +- test/stage1/behavior/array.zig | 39 +- test/stage1/behavior/bugs/1076.zig | 16 +- test/stage1/behavior/cast.zig | 110 +++-- test/stage1/behavior/const_slice_child.zig | 9 +- test/stage1/behavior/eval.zig | 2 +- test/stage1/behavior/misc.zig | 17 +- test/stage1/behavior/pointers.zig | 2 +- test/stage1/behavior/ptrcast.zig | 2 +- test/stage1/behavior/slice.zig | 2 +- test/stage1/behavior/struct.zig | 2 +- test/stage2/compare_output.zig | 4 +- test/standalone/hello_world/hello_libc.zig | 2 +- test/translate_c.zig | 28 +- 51 files changed, 986 insertions(+), 716 deletions(-) diff --git a/lib/std/child_process.zig b/lib/std/child_process.zig index d329855c03..50479016ac 100644 --- a/lib/std/child_process.zig +++ b/lib/std/child_process.zig @@ -328,7 +328,7 @@ pub const ChildProcess = struct { const any_ignore = (self.stdin_behavior == StdIo.Ignore or self.stdout_behavior == StdIo.Ignore or self.stderr_behavior == StdIo.Ignore); const dev_null_fd = if (any_ignore) - os.openC(c"/dev/null", os.O_RDWR, 0) catch |err| switch (err) { + os.openC("/dev/null", os.O_RDWR, 0) catch |err| switch (err) { error.PathAlreadyExists => unreachable, error.NoSpaceLeft => unreachable, error.FileTooBig => unreachable, diff --git a/lib/std/crypto/x25519.zig b/lib/std/crypto/x25519.zig index cd908b0868..73e0f033f2 100644 --- a/lib/std/crypto/x25519.zig +++ b/lib/std/crypto/x25519.zig @@ -610,8 +610,8 @@ test "x25519 rfc7748 vector2" { } test "x25519 rfc7748 one iteration" { - const initial_value = "\x09\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"; - const expected_output = "\x42\x2c\x8e\x7a\x62\x27\xd7\xbc\xa1\x35\x0b\x3e\x2b\xb7\x27\x9f\x78\x97\xb8\x7b\xb6\x85\x4b\x78\x3c\x60\xe8\x03\x11\xae\x30\x79"; + const initial_value = "\x09\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".*; + const expected_output = "\x42\x2c\x8e\x7a\x62\x27\xd7\xbc\xa1\x35\x0b\x3e\x2b\xb7\x27\x9f\x78\x97\xb8\x7b\xb6\x85\x4b\x78\x3c\x60\xe8\x03\x11\xae\x30\x79".*; var k: [32]u8 = initial_value; var u: [32]u8 = initial_value; @@ -634,8 +634,8 @@ test "x25519 rfc7748 1,000 iterations" { return error.SkipZigTest; } - const initial_value = "\x09\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"; - const expected_output = "\x68\x4c\xf5\x9b\xa8\x33\x09\x55\x28\x00\xef\x56\x6f\x2f\x4d\x3c\x1c\x38\x87\xc4\x93\x60\xe3\x87\x5f\x2e\xb9\x4d\x99\x53\x2c\x51"; + const initial_value = "\x09\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".*; + const expected_output = "\x68\x4c\xf5\x9b\xa8\x33\x09\x55\x28\x00\xef\x56\x6f\x2f\x4d\x3c\x1c\x38\x87\xc4\x93\x60\xe3\x87\x5f\x2e\xb9\x4d\x99\x53\x2c\x51".*; var k: [32]u8 = initial_value; var u: [32]u8 = initial_value; @@ -657,8 +657,8 @@ test "x25519 rfc7748 1,000,000 iterations" { return error.SkipZigTest; } - const initial_value = "\x09\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"; - const expected_output = "\x7c\x39\x11\xe0\xab\x25\x86\xfd\x86\x44\x97\x29\x7e\x57\x5e\x6f\x3b\xc6\x01\xc0\x88\x3c\x30\xdf\x5f\x4d\xd2\xd2\x4f\x66\x54\x24"; + const initial_value = "\x09\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".*; + const expected_output = "\x7c\x39\x11\xe0\xab\x25\x86\xfd\x86\x44\x97\x29\x7e\x57\x5e\x6f\x3b\xc6\x01\xc0\x88\x3c\x30\xdf\x5f\x4d\xd2\xd2\x4f\x66\x54\x24".*; var k: [32]u8 = initial_value; var u: [32]u8 = initial_value; diff --git a/lib/std/cstr.zig b/lib/std/cstr.zig index dd28e50449..4229ff3ed5 100644 --- a/lib/std/cstr.zig +++ b/lib/std/cstr.zig @@ -27,8 +27,8 @@ test "cstr fns" { } fn testCStrFnsImpl() void { - testing.expect(cmp(c"aoeu", c"aoez") == -1); - testing.expect(mem.len(u8, c"123456789") == 9); + testing.expect(cmp("aoeu", "aoez") == -1); + testing.expect(mem.len(u8, "123456789") == 9); } /// Returns a mutable slice with 1 more byte of length which is a null byte. diff --git a/lib/std/fmt.zig b/lib/std/fmt.zig index 743ca4d920..cbb11cba36 100644 --- a/lib/std/fmt.zig +++ b/lib/std/fmt.zig @@ -1,8 +1,6 @@ const std = @import("std.zig"); const math = std.math; -const debug = std.debug; -const assert = debug.assert; -const testing = std.testing; +const assert = std.debug.assert; const mem = std.mem; const builtin = @import("builtin"); const errol = @import("fmt/errol.zig"); @@ -36,7 +34,7 @@ fn nextArg(comptime used_pos_args: *u32, comptime maybe_pos_arg: ?comptime_int, fn peekIsAlign(comptime fmt: []const u8) bool { // Should only be called during a state transition to the format segment. - std.debug.assert(fmt[0] == ':'); + comptime assert(fmt[0] == ':'); inline for (([_]u8{ 1, 2 })[0..]) |i| { if (fmt.len > i and (fmt[i] == '<' or fmt[i] == '^' or fmt[i] == '>')) { @@ -1009,13 +1007,13 @@ pub fn parseInt(comptime T: type, buf: []const u8, radix: u8) !T { } test "parseInt" { - testing.expect((parseInt(i32, "-10", 10) catch unreachable) == -10); - testing.expect((parseInt(i32, "+10", 10) catch unreachable) == 10); - testing.expect(if (parseInt(i32, " 10", 10)) |_| false else |err| err == error.InvalidCharacter); - testing.expect(if (parseInt(i32, "10 ", 10)) |_| false else |err| err == error.InvalidCharacter); - testing.expect(if (parseInt(u32, "-10", 10)) |_| false else |err| err == error.InvalidCharacter); - testing.expect((parseInt(u8, "255", 10) catch unreachable) == 255); - testing.expect(if (parseInt(u8, "256", 10)) |_| false else |err| err == error.Overflow); + std.testing.expect((parseInt(i32, "-10", 10) catch unreachable) == -10); + std.testing.expect((parseInt(i32, "+10", 10) catch unreachable) == 10); + std.testing.expect(if (parseInt(i32, " 10", 10)) |_| false else |err| err == error.InvalidCharacter); + std.testing.expect(if (parseInt(i32, "10 ", 10)) |_| false else |err| err == error.InvalidCharacter); + std.testing.expect(if (parseInt(u32, "-10", 10)) |_| false else |err| err == error.InvalidCharacter); + std.testing.expect((parseInt(u8, "255", 10) catch unreachable) == 255); + std.testing.expect(if (parseInt(u8, "256", 10)) |_| false else |err| err == error.Overflow); } const ParseUnsignedError = error{ @@ -1040,30 +1038,30 @@ pub fn parseUnsigned(comptime T: type, buf: []const u8, radix: u8) ParseUnsigned } test "parseUnsigned" { - testing.expect((try parseUnsigned(u16, "050124", 10)) == 50124); - testing.expect((try parseUnsigned(u16, "65535", 10)) == 65535); - testing.expectError(error.Overflow, parseUnsigned(u16, "65536", 10)); + std.testing.expect((try parseUnsigned(u16, "050124", 10)) == 50124); + std.testing.expect((try parseUnsigned(u16, "65535", 10)) == 65535); + std.testing.expectError(error.Overflow, parseUnsigned(u16, "65536", 10)); - testing.expect((try parseUnsigned(u64, "0ffffffffffffffff", 16)) == 0xffffffffffffffff); - testing.expectError(error.Overflow, parseUnsigned(u64, "10000000000000000", 16)); + std.testing.expect((try parseUnsigned(u64, "0ffffffffffffffff", 16)) == 0xffffffffffffffff); + std.testing.expectError(error.Overflow, parseUnsigned(u64, "10000000000000000", 16)); - testing.expect((try parseUnsigned(u32, "DeadBeef", 16)) == 0xDEADBEEF); + std.testing.expect((try parseUnsigned(u32, "DeadBeef", 16)) == 0xDEADBEEF); - testing.expect((try parseUnsigned(u7, "1", 10)) == 1); - testing.expect((try parseUnsigned(u7, "1000", 2)) == 8); + std.testing.expect((try parseUnsigned(u7, "1", 10)) == 1); + std.testing.expect((try parseUnsigned(u7, "1000", 2)) == 8); - testing.expectError(error.InvalidCharacter, parseUnsigned(u32, "f", 10)); - testing.expectError(error.InvalidCharacter, parseUnsigned(u8, "109", 8)); + std.testing.expectError(error.InvalidCharacter, parseUnsigned(u32, "f", 10)); + std.testing.expectError(error.InvalidCharacter, parseUnsigned(u8, "109", 8)); - testing.expect((try parseUnsigned(u32, "NUMBER", 36)) == 1442151747); + std.testing.expect((try parseUnsigned(u32, "NUMBER", 36)) == 1442151747); // these numbers should fit even though the radix itself doesn't fit in the destination type - testing.expect((try parseUnsigned(u1, "0", 10)) == 0); - testing.expect((try parseUnsigned(u1, "1", 10)) == 1); - testing.expectError(error.Overflow, parseUnsigned(u1, "2", 10)); - testing.expect((try parseUnsigned(u1, "001", 16)) == 1); - testing.expect((try parseUnsigned(u2, "3", 16)) == 3); - testing.expectError(error.Overflow, parseUnsigned(u2, "4", 16)); + std.testing.expect((try parseUnsigned(u1, "0", 10)) == 0); + std.testing.expect((try parseUnsigned(u1, "1", 10)) == 1); + std.testing.expectError(error.Overflow, parseUnsigned(u1, "2", 10)); + std.testing.expect((try parseUnsigned(u1, "001", 16)) == 1); + std.testing.expect((try parseUnsigned(u2, "3", 16)) == 3); + std.testing.expectError(error.Overflow, parseUnsigned(u2, "4", 16)); } pub const parseFloat = @import("fmt/parse_float.zig").parseFloat; @@ -1134,19 +1132,19 @@ fn countSize(size: *usize, bytes: []const u8) (error{}!void) { test "bufPrintInt" { var buffer: [100]u8 = undefined; const buf = buffer[0..]; - testing.expect(mem.eql(u8, bufPrintIntToSlice(buf, @as(i32, -12345678), 2, false, FormatOptions{}), "-101111000110000101001110")); - testing.expect(mem.eql(u8, bufPrintIntToSlice(buf, @as(i32, -12345678), 10, false, FormatOptions{}), "-12345678")); - testing.expect(mem.eql(u8, bufPrintIntToSlice(buf, @as(i32, -12345678), 16, false, FormatOptions{}), "-bc614e")); - testing.expect(mem.eql(u8, bufPrintIntToSlice(buf, @as(i32, -12345678), 16, true, FormatOptions{}), "-BC614E")); + std.testing.expect(mem.eql(u8, bufPrintIntToSlice(buf, @as(i32, -12345678), 2, false, FormatOptions{}), "-101111000110000101001110")); + std.testing.expect(mem.eql(u8, bufPrintIntToSlice(buf, @as(i32, -12345678), 10, false, FormatOptions{}), "-12345678")); + std.testing.expect(mem.eql(u8, bufPrintIntToSlice(buf, @as(i32, -12345678), 16, false, FormatOptions{}), "-bc614e")); + std.testing.expect(mem.eql(u8, bufPrintIntToSlice(buf, @as(i32, -12345678), 16, true, FormatOptions{}), "-BC614E")); - testing.expect(mem.eql(u8, bufPrintIntToSlice(buf, @as(u32, 12345678), 10, true, FormatOptions{}), "12345678")); + std.testing.expect(mem.eql(u8, bufPrintIntToSlice(buf, @as(u32, 12345678), 10, true, FormatOptions{}), "12345678")); - testing.expect(mem.eql(u8, bufPrintIntToSlice(buf, @as(u32, 666), 10, false, FormatOptions{ .width = 6 }), " 666")); - testing.expect(mem.eql(u8, bufPrintIntToSlice(buf, @as(u32, 0x1234), 16, false, FormatOptions{ .width = 6 }), " 1234")); - testing.expect(mem.eql(u8, bufPrintIntToSlice(buf, @as(u32, 0x1234), 16, false, FormatOptions{ .width = 1 }), "1234")); + std.testing.expect(mem.eql(u8, bufPrintIntToSlice(buf, @as(u32, 666), 10, false, FormatOptions{ .width = 6 }), " 666")); + std.testing.expect(mem.eql(u8, bufPrintIntToSlice(buf, @as(u32, 0x1234), 16, false, FormatOptions{ .width = 6 }), " 1234")); + std.testing.expect(mem.eql(u8, bufPrintIntToSlice(buf, @as(u32, 0x1234), 16, false, FormatOptions{ .width = 1 }), "1234")); - testing.expect(mem.eql(u8, bufPrintIntToSlice(buf, @as(i32, 42), 10, false, FormatOptions{ .width = 3 }), "+42")); - testing.expect(mem.eql(u8, bufPrintIntToSlice(buf, @as(i32, -42), 10, false, FormatOptions{ .width = 3 }), "-42")); + std.testing.expect(mem.eql(u8, bufPrintIntToSlice(buf, @as(i32, 42), 10, false, FormatOptions{ .width = 3 }), "+42")); + std.testing.expect(mem.eql(u8, bufPrintIntToSlice(buf, @as(i32, -42), 10, false, FormatOptions{ .width = 3 }), "-42")); } fn bufPrintIntToSlice(buf: []u8, value: var, base: u8, uppercase: bool, options: FormatOptions) []u8 { @@ -1163,7 +1161,7 @@ test "parse u64 digit too big" { test "parse unsigned comptime" { comptime { - testing.expect((try parseUnsigned(usize, "2", 10)) == 2); + std.testing.expect((try parseUnsigned(usize, "2", 10)) == 2); } } @@ -1218,23 +1216,23 @@ test "buffer" { var context = BufPrintContext{ .remaining = buf1[0..] }; try formatType(1234, "", FormatOptions{}, &context, error{BufferTooSmall}, bufPrintWrite, default_max_depth); var res = buf1[0 .. buf1.len - context.remaining.len]; - testing.expect(mem.eql(u8, res, "1234")); + std.testing.expect(mem.eql(u8, res, "1234")); context = BufPrintContext{ .remaining = buf1[0..] }; try formatType('a', "c", FormatOptions{}, &context, error{BufferTooSmall}, bufPrintWrite, default_max_depth); res = buf1[0 .. buf1.len - context.remaining.len]; - testing.expect(mem.eql(u8, res, "a")); + std.testing.expect(mem.eql(u8, res, "a")); context = BufPrintContext{ .remaining = buf1[0..] }; try formatType(0b1100, "b", FormatOptions{}, &context, error{BufferTooSmall}, bufPrintWrite, default_max_depth); res = buf1[0 .. buf1.len - context.remaining.len]; - testing.expect(mem.eql(u8, res, "1100")); + std.testing.expect(mem.eql(u8, res, "1100")); } } test "array" { { - const value: [3]u8 = "abc"; + const value: [3]u8 = "abc".*; try testFmt("array: abc\n", "array: {}\n", value); try testFmt("array: abc\n", "array: {}\n", &value); @@ -1278,8 +1276,8 @@ test "pointer" { } test "cstr" { - try testFmt("cstr: Test C\n", "cstr: {s}\n", c"Test C"); - try testFmt("cstr: Test C \n", "cstr: {s:10}\n", c"Test C"); + try testFmt("cstr: Test C\n", "cstr: {s}\n", "Test C"); + try testFmt("cstr: Test C \n", "cstr: {s:10}\n", "Test C"); } test "filesize" { @@ -1479,10 +1477,10 @@ test "union" { var buf: [100]u8 = undefined; const uu_result = try bufPrint(buf[0..], "{}", uu_inst); - testing.expect(mem.eql(u8, uu_result[0..3], "UU@")); + std.testing.expect(mem.eql(u8, uu_result[0..3], "UU@")); const eu_result = try bufPrint(buf[0..], "{}", eu_inst); - testing.expect(mem.eql(u8, uu_result[0..3], "EU@")); + std.testing.expect(mem.eql(u8, uu_result[0..3], "EU@")); } test "enum" { @@ -1569,11 +1567,11 @@ pub fn trim(buf: []const u8) []const u8 { } test "trim" { - testing.expect(mem.eql(u8, "abc", trim("\n abc \t"))); - testing.expect(mem.eql(u8, "", trim(" "))); - testing.expect(mem.eql(u8, "", trim(""))); - testing.expect(mem.eql(u8, "abc", trim(" abc"))); - testing.expect(mem.eql(u8, "abc", trim("abc "))); + std.testing.expect(mem.eql(u8, "abc", trim("\n abc \t"))); + std.testing.expect(mem.eql(u8, "", trim(" "))); + std.testing.expect(mem.eql(u8, "", trim(""))); + std.testing.expect(mem.eql(u8, "abc", trim(" abc"))); + std.testing.expect(mem.eql(u8, "abc", trim("abc "))); } pub fn isWhiteSpace(byte: u8) bool { @@ -1607,7 +1605,7 @@ test "formatIntValue with comptime_int" { var buf = try std.Buffer.init(std.debug.global_allocator, ""); try formatIntValue(value, "", FormatOptions{}, &buf, @typeOf(std.Buffer.append).ReturnType.ErrorSet, std.Buffer.append); - assert(mem.eql(u8, buf.toSlice(), "123456789123456789")); + std.testing.expect(mem.eql(u8, buf.toSlice(), "123456789123456789")); } test "formatType max_depth" { @@ -1661,19 +1659,19 @@ test "formatType max_depth" { var buf0 = try std.Buffer.init(std.debug.global_allocator, ""); try formatType(inst, "", FormatOptions{}, &buf0, @typeOf(std.Buffer.append).ReturnType.ErrorSet, std.Buffer.append, 0); - assert(mem.eql(u8, buf0.toSlice(), "S{ ... }")); + std.testing.expect(mem.eql(u8, buf0.toSlice(), "S{ ... }")); var buf1 = try std.Buffer.init(std.debug.global_allocator, ""); try formatType(inst, "", FormatOptions{}, &buf1, @typeOf(std.Buffer.append).ReturnType.ErrorSet, std.Buffer.append, 1); - assert(mem.eql(u8, buf1.toSlice(), "S{ .a = S{ ... }, .tu = TU{ ... }, .e = E.Two, .vec = (10.200,2.220) }")); + std.testing.expect(mem.eql(u8, buf1.toSlice(), "S{ .a = S{ ... }, .tu = TU{ ... }, .e = E.Two, .vec = (10.200,2.220) }")); var buf2 = try std.Buffer.init(std.debug.global_allocator, ""); try formatType(inst, "", FormatOptions{}, &buf2, @typeOf(std.Buffer.append).ReturnType.ErrorSet, std.Buffer.append, 2); - assert(mem.eql(u8, buf2.toSlice(), "S{ .a = S{ .a = S{ ... }, .tu = TU{ ... }, .e = E.Two, .vec = (10.200,2.220) }, .tu = TU{ .ptr = TU{ ... } }, .e = E.Two, .vec = (10.200,2.220) }")); + std.testing.expect(mem.eql(u8, buf2.toSlice(), "S{ .a = S{ .a = S{ ... }, .tu = TU{ ... }, .e = E.Two, .vec = (10.200,2.220) }, .tu = TU{ .ptr = TU{ ... } }, .e = E.Two, .vec = (10.200,2.220) }")); var buf3 = try std.Buffer.init(std.debug.global_allocator, ""); try formatType(inst, "", FormatOptions{}, &buf3, @typeOf(std.Buffer.append).ReturnType.ErrorSet, std.Buffer.append, 3); - assert(mem.eql(u8, buf3.toSlice(), "S{ .a = S{ .a = S{ .a = S{ ... }, .tu = TU{ ... }, .e = E.Two, .vec = (10.200,2.220) }, .tu = TU{ .ptr = TU{ ... } }, .e = E.Two, .vec = (10.200,2.220) }, .tu = TU{ .ptr = TU{ .ptr = TU{ ... } } }, .e = E.Two, .vec = (10.200,2.220) }")); + std.testing.expect(mem.eql(u8, buf3.toSlice(), "S{ .a = S{ .a = S{ .a = S{ ... }, .tu = TU{ ... }, .e = E.Two, .vec = (10.200,2.220) }, .tu = TU{ .ptr = TU{ ... } }, .e = E.Two, .vec = (10.200,2.220) }, .tu = TU{ .ptr = TU{ .ptr = TU{ ... } } }, .e = E.Two, .vec = (10.200,2.220) }")); } test "positional" { diff --git a/lib/std/fs.zig b/lib/std/fs.zig index bc2c921d1e..0b9c6559d7 100644 --- a/lib/std/fs.zig +++ b/lib/std/fs.zig @@ -1240,7 +1240,7 @@ pub const OpenSelfExeError = os.OpenError || os.windows.CreateFileError || SelfE pub fn openSelfExe() OpenSelfExeError!File { if (builtin.os == .linux) { - return File.openReadC(c"/proc/self/exe"); + return File.openReadC("/proc/self/exe"); } if (builtin.os == .windows) { const wide_slice = selfExePathW(); @@ -1280,7 +1280,7 @@ pub fn selfExePath(out_buffer: *[MAX_PATH_BYTES]u8) SelfExePathError![]u8 { return mem.toSlice(u8, out_buffer); } switch (builtin.os) { - .linux => return os.readlinkC(c"/proc/self/exe", out_buffer), + .linux => return os.readlinkC("/proc/self/exe", out_buffer), .freebsd, .dragonfly => { var mib = [4]c_int{ os.CTL_KERN, os.KERN_PROC, os.KERN_PROC_PATHNAME, -1 }; var out_len: usize = out_buffer.len; @@ -1326,7 +1326,7 @@ pub fn selfExeDirPath(out_buffer: *[MAX_PATH_BYTES]u8) SelfExePathError![]const // the file path looks something like `/a/b/c/exe (deleted)` // This path cannot be opened, but it's valid for determining the directory // the executable was in when it was run. - const full_exe_path = try os.readlinkC(c"/proc/self/exe", out_buffer); + const full_exe_path = try os.readlinkC("/proc/self/exe", out_buffer); // Assume that /proc/self/exe has an absolute path, and therefore dirname // will not return null. return path.dirname(full_exe_path).?; diff --git a/lib/std/fs/file.zig b/lib/std/fs/file.zig index b25403fa02..cd50fcdece 100644 --- a/lib/std/fs/file.zig +++ b/lib/std/fs/file.zig @@ -172,7 +172,7 @@ pub const File = struct { if (self.isTty()) { if (self.handle == os.STDOUT_FILENO or self.handle == os.STDERR_FILENO) { // Use getenvC to workaround https://github.com/ziglang/zig/issues/3511 - if (os.getenvC(c"TERM")) |term| { + if (os.getenvC("TERM")) |term| { if (std.mem.eql(u8, term, "dumb")) return false; } diff --git a/lib/std/fs/path.zig b/lib/std/fs/path.zig index 6a24055667..e2f1b5ac65 100644 --- a/lib/std/fs/path.zig +++ b/lib/std/fs/path.zig @@ -394,7 +394,7 @@ pub fn resolveWindows(allocator: *Allocator, paths: []const []const u8) ![]u8 { } // determine which disk designator we will result with, if any - var result_drive_buf = "_:"; + var result_drive_buf = "_:".*; var result_disk_designator: []const u8 = ""; var have_drive_kind = WindowsPath.Kind.None; var have_abs_path = false; diff --git a/lib/std/hash/siphash.zig b/lib/std/hash/siphash.zig index c3a9184fa4..6b4cc2b16b 100644 --- a/lib/std/hash/siphash.zig +++ b/lib/std/hash/siphash.zig @@ -202,70 +202,70 @@ const test_key = "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x test "siphash64-2-4 sanity" { const vectors = [_][8]u8{ - "\x31\x0e\x0e\xdd\x47\xdb\x6f\x72", // "" - "\xfd\x67\xdc\x93\xc5\x39\xf8\x74", // "\x00" - "\x5a\x4f\xa9\xd9\x09\x80\x6c\x0d", // "\x00\x01" ... etc - "\x2d\x7e\xfb\xd7\x96\x66\x67\x85", - "\xb7\x87\x71\x27\xe0\x94\x27\xcf", - "\x8d\xa6\x99\xcd\x64\x55\x76\x18", - "\xce\xe3\xfe\x58\x6e\x46\xc9\xcb", - "\x37\xd1\x01\x8b\xf5\x00\x02\xab", - "\x62\x24\x93\x9a\x79\xf5\xf5\x93", - "\xb0\xe4\xa9\x0b\xdf\x82\x00\x9e", - "\xf3\xb9\xdd\x94\xc5\xbb\x5d\x7a", - "\xa7\xad\x6b\x22\x46\x2f\xb3\xf4", - "\xfb\xe5\x0e\x86\xbc\x8f\x1e\x75", - "\x90\x3d\x84\xc0\x27\x56\xea\x14", - "\xee\xf2\x7a\x8e\x90\xca\x23\xf7", - "\xe5\x45\xbe\x49\x61\xca\x29\xa1", - "\xdb\x9b\xc2\x57\x7f\xcc\x2a\x3f", - "\x94\x47\xbe\x2c\xf5\xe9\x9a\x69", - "\x9c\xd3\x8d\x96\xf0\xb3\xc1\x4b", - "\xbd\x61\x79\xa7\x1d\xc9\x6d\xbb", - "\x98\xee\xa2\x1a\xf2\x5c\xd6\xbe", - "\xc7\x67\x3b\x2e\xb0\xcb\xf2\xd0", - "\x88\x3e\xa3\xe3\x95\x67\x53\x93", - "\xc8\xce\x5c\xcd\x8c\x03\x0c\xa8", - "\x94\xaf\x49\xf6\xc6\x50\xad\xb8", - "\xea\xb8\x85\x8a\xde\x92\xe1\xbc", - "\xf3\x15\xbb\x5b\xb8\x35\xd8\x17", - "\xad\xcf\x6b\x07\x63\x61\x2e\x2f", - "\xa5\xc9\x1d\xa7\xac\xaa\x4d\xde", - "\x71\x65\x95\x87\x66\x50\xa2\xa6", - "\x28\xef\x49\x5c\x53\xa3\x87\xad", - "\x42\xc3\x41\xd8\xfa\x92\xd8\x32", - "\xce\x7c\xf2\x72\x2f\x51\x27\x71", - "\xe3\x78\x59\xf9\x46\x23\xf3\xa7", - "\x38\x12\x05\xbb\x1a\xb0\xe0\x12", - "\xae\x97\xa1\x0f\xd4\x34\xe0\x15", - "\xb4\xa3\x15\x08\xbe\xff\x4d\x31", - "\x81\x39\x62\x29\xf0\x90\x79\x02", - "\x4d\x0c\xf4\x9e\xe5\xd4\xdc\xca", - "\x5c\x73\x33\x6a\x76\xd8\xbf\x9a", - "\xd0\xa7\x04\x53\x6b\xa9\x3e\x0e", - "\x92\x59\x58\xfc\xd6\x42\x0c\xad", - "\xa9\x15\xc2\x9b\xc8\x06\x73\x18", - "\x95\x2b\x79\xf3\xbc\x0a\xa6\xd4", - "\xf2\x1d\xf2\xe4\x1d\x45\x35\xf9", - "\x87\x57\x75\x19\x04\x8f\x53\xa9", - "\x10\xa5\x6c\xf5\xdf\xcd\x9a\xdb", - "\xeb\x75\x09\x5c\xcd\x98\x6c\xd0", - "\x51\xa9\xcb\x9e\xcb\xa3\x12\xe6", - "\x96\xaf\xad\xfc\x2c\xe6\x66\xc7", - "\x72\xfe\x52\x97\x5a\x43\x64\xee", - "\x5a\x16\x45\xb2\x76\xd5\x92\xa1", - "\xb2\x74\xcb\x8e\xbf\x87\x87\x0a", - "\x6f\x9b\xb4\x20\x3d\xe7\xb3\x81", - "\xea\xec\xb2\xa3\x0b\x22\xa8\x7f", - "\x99\x24\xa4\x3c\xc1\x31\x57\x24", - "\xbd\x83\x8d\x3a\xaf\xbf\x8d\xb7", - "\x0b\x1a\x2a\x32\x65\xd5\x1a\xea", - "\x13\x50\x79\xa3\x23\x1c\xe6\x60", - "\x93\x2b\x28\x46\xe4\xd7\x06\x66", - "\xe1\x91\x5f\x5c\xb1\xec\xa4\x6c", - "\xf3\x25\x96\x5c\xa1\x6d\x62\x9f", - "\x57\x5f\xf2\x8e\x60\x38\x1b\xe5", - "\x72\x45\x06\xeb\x4c\x32\x8a\x95", + "\x31\x0e\x0e\xdd\x47\xdb\x6f\x72".*, // "" + "\xfd\x67\xdc\x93\xc5\x39\xf8\x74".*, // "\x00" + "\x5a\x4f\xa9\xd9\x09\x80\x6c\x0d".*, // "\x00\x01" ... etc + "\x2d\x7e\xfb\xd7\x96\x66\x67\x85".*, + "\xb7\x87\x71\x27\xe0\x94\x27\xcf".*, + "\x8d\xa6\x99\xcd\x64\x55\x76\x18".*, + "\xce\xe3\xfe\x58\x6e\x46\xc9\xcb".*, + "\x37\xd1\x01\x8b\xf5\x00\x02\xab".*, + "\x62\x24\x93\x9a\x79\xf5\xf5\x93".*, + "\xb0\xe4\xa9\x0b\xdf\x82\x00\x9e".*, + "\xf3\xb9\xdd\x94\xc5\xbb\x5d\x7a".*, + "\xa7\xad\x6b\x22\x46\x2f\xb3\xf4".*, + "\xfb\xe5\x0e\x86\xbc\x8f\x1e\x75".*, + "\x90\x3d\x84\xc0\x27\x56\xea\x14".*, + "\xee\xf2\x7a\x8e\x90\xca\x23\xf7".*, + "\xe5\x45\xbe\x49\x61\xca\x29\xa1".*, + "\xdb\x9b\xc2\x57\x7f\xcc\x2a\x3f".*, + "\x94\x47\xbe\x2c\xf5\xe9\x9a\x69".*, + "\x9c\xd3\x8d\x96\xf0\xb3\xc1\x4b".*, + "\xbd\x61\x79\xa7\x1d\xc9\x6d\xbb".*, + "\x98\xee\xa2\x1a\xf2\x5c\xd6\xbe".*, + "\xc7\x67\x3b\x2e\xb0\xcb\xf2\xd0".*, + "\x88\x3e\xa3\xe3\x95\x67\x53\x93".*, + "\xc8\xce\x5c\xcd\x8c\x03\x0c\xa8".*, + "\x94\xaf\x49\xf6\xc6\x50\xad\xb8".*, + "\xea\xb8\x85\x8a\xde\x92\xe1\xbc".*, + "\xf3\x15\xbb\x5b\xb8\x35\xd8\x17".*, + "\xad\xcf\x6b\x07\x63\x61\x2e\x2f".*, + "\xa5\xc9\x1d\xa7\xac\xaa\x4d\xde".*, + "\x71\x65\x95\x87\x66\x50\xa2\xa6".*, + "\x28\xef\x49\x5c\x53\xa3\x87\xad".*, + "\x42\xc3\x41\xd8\xfa\x92\xd8\x32".*, + "\xce\x7c\xf2\x72\x2f\x51\x27\x71".*, + "\xe3\x78\x59\xf9\x46\x23\xf3\xa7".*, + "\x38\x12\x05\xbb\x1a\xb0\xe0\x12".*, + "\xae\x97\xa1\x0f\xd4\x34\xe0\x15".*, + "\xb4\xa3\x15\x08\xbe\xff\x4d\x31".*, + "\x81\x39\x62\x29\xf0\x90\x79\x02".*, + "\x4d\x0c\xf4\x9e\xe5\xd4\xdc\xca".*, + "\x5c\x73\x33\x6a\x76\xd8\xbf\x9a".*, + "\xd0\xa7\x04\x53\x6b\xa9\x3e\x0e".*, + "\x92\x59\x58\xfc\xd6\x42\x0c\xad".*, + "\xa9\x15\xc2\x9b\xc8\x06\x73\x18".*, + "\x95\x2b\x79\xf3\xbc\x0a\xa6\xd4".*, + "\xf2\x1d\xf2\xe4\x1d\x45\x35\xf9".*, + "\x87\x57\x75\x19\x04\x8f\x53\xa9".*, + "\x10\xa5\x6c\xf5\xdf\xcd\x9a\xdb".*, + "\xeb\x75\x09\x5c\xcd\x98\x6c\xd0".*, + "\x51\xa9\xcb\x9e\xcb\xa3\x12\xe6".*, + "\x96\xaf\xad\xfc\x2c\xe6\x66\xc7".*, + "\x72\xfe\x52\x97\x5a\x43\x64\xee".*, + "\x5a\x16\x45\xb2\x76\xd5\x92\xa1".*, + "\xb2\x74\xcb\x8e\xbf\x87\x87\x0a".*, + "\x6f\x9b\xb4\x20\x3d\xe7\xb3\x81".*, + "\xea\xec\xb2\xa3\x0b\x22\xa8\x7f".*, + "\x99\x24\xa4\x3c\xc1\x31\x57\x24".*, + "\xbd\x83\x8d\x3a\xaf\xbf\x8d\xb7".*, + "\x0b\x1a\x2a\x32\x65\xd5\x1a\xea".*, + "\x13\x50\x79\xa3\x23\x1c\xe6\x60".*, + "\x93\x2b\x28\x46\xe4\xd7\x06\x66".*, + "\xe1\x91\x5f\x5c\xb1\xec\xa4\x6c".*, + "\xf3\x25\x96\x5c\xa1\x6d\x62\x9f".*, + "\x57\x5f\xf2\x8e\x60\x38\x1b\xe5".*, + "\x72\x45\x06\xeb\x4c\x32\x8a\x95".*, }; const siphash = SipHash64(2, 4); @@ -281,70 +281,70 @@ test "siphash64-2-4 sanity" { test "siphash128-2-4 sanity" { const vectors = [_][16]u8{ - "\xa3\x81\x7f\x04\xba\x25\xa8\xe6\x6d\xf6\x72\x14\xc7\x55\x02\x93", - "\xda\x87\xc1\xd8\x6b\x99\xaf\x44\x34\x76\x59\x11\x9b\x22\xfc\x45", - "\x81\x77\x22\x8d\xa4\xa4\x5d\xc7\xfc\xa3\x8b\xde\xf6\x0a\xff\xe4", - "\x9c\x70\xb6\x0c\x52\x67\xa9\x4e\x5f\x33\xb6\xb0\x29\x85\xed\x51", - "\xf8\x81\x64\xc1\x2d\x9c\x8f\xaf\x7d\x0f\x6e\x7c\x7b\xcd\x55\x79", - "\x13\x68\x87\x59\x80\x77\x6f\x88\x54\x52\x7a\x07\x69\x0e\x96\x27", - "\x14\xee\xca\x33\x8b\x20\x86\x13\x48\x5e\xa0\x30\x8f\xd7\xa1\x5e", - "\xa1\xf1\xeb\xbe\xd8\xdb\xc1\x53\xc0\xb8\x4a\xa6\x1f\xf0\x82\x39", - "\x3b\x62\xa9\xba\x62\x58\xf5\x61\x0f\x83\xe2\x64\xf3\x14\x97\xb4", - "\x26\x44\x99\x06\x0a\xd9\xba\xab\xc4\x7f\x8b\x02\xbb\x6d\x71\xed", - "\x00\x11\x0d\xc3\x78\x14\x69\x56\xc9\x54\x47\xd3\xf3\xd0\xfb\xba", - "\x01\x51\xc5\x68\x38\x6b\x66\x77\xa2\xb4\xdc\x6f\x81\xe5\xdc\x18", - "\xd6\x26\xb2\x66\x90\x5e\xf3\x58\x82\x63\x4d\xf6\x85\x32\xc1\x25", - "\x98\x69\xe2\x47\xe9\xc0\x8b\x10\xd0\x29\x93\x4f\xc4\xb9\x52\xf7", - "\x31\xfc\xef\xac\x66\xd7\xde\x9c\x7e\xc7\x48\x5f\xe4\x49\x49\x02", - "\x54\x93\xe9\x99\x33\xb0\xa8\x11\x7e\x08\xec\x0f\x97\xcf\xc3\xd9", - "\x6e\xe2\xa4\xca\x67\xb0\x54\xbb\xfd\x33\x15\xbf\x85\x23\x05\x77", - "\x47\x3d\x06\xe8\x73\x8d\xb8\x98\x54\xc0\x66\xc4\x7a\xe4\x77\x40", - "\xa4\x26\xe5\xe4\x23\xbf\x48\x85\x29\x4d\xa4\x81\xfe\xae\xf7\x23", - "\x78\x01\x77\x31\xcf\x65\xfa\xb0\x74\xd5\x20\x89\x52\x51\x2e\xb1", - "\x9e\x25\xfc\x83\x3f\x22\x90\x73\x3e\x93\x44\xa5\xe8\x38\x39\xeb", - "\x56\x8e\x49\x5a\xbe\x52\x5a\x21\x8a\x22\x14\xcd\x3e\x07\x1d\x12", - "\x4a\x29\xb5\x45\x52\xd1\x6b\x9a\x46\x9c\x10\x52\x8e\xff\x0a\xae", - "\xc9\xd1\x84\xdd\xd5\xa9\xf5\xe0\xcf\x8c\xe2\x9a\x9a\xbf\x69\x1c", - "\x2d\xb4\x79\xae\x78\xbd\x50\xd8\x88\x2a\x8a\x17\x8a\x61\x32\xad", - "\x8e\xce\x5f\x04\x2d\x5e\x44\x7b\x50\x51\xb9\xea\xcb\x8d\x8f\x6f", - "\x9c\x0b\x53\xb4\xb3\xc3\x07\xe8\x7e\xae\xe0\x86\x78\x14\x1f\x66", - "\xab\xf2\x48\xaf\x69\xa6\xea\xe4\xbf\xd3\xeb\x2f\x12\x9e\xeb\x94", - "\x06\x64\xda\x16\x68\x57\x4b\x88\xb9\x35\xf3\x02\x73\x58\xae\xf4", - "\xaa\x4b\x9d\xc4\xbf\x33\x7d\xe9\x0c\xd4\xfd\x3c\x46\x7c\x6a\xb7", - "\xea\x5c\x7f\x47\x1f\xaf\x6b\xde\x2b\x1a\xd7\xd4\x68\x6d\x22\x87", - "\x29\x39\xb0\x18\x32\x23\xfa\xfc\x17\x23\xde\x4f\x52\xc4\x3d\x35", - "\x7c\x39\x56\xca\x5e\xea\xfc\x3e\x36\x3e\x9d\x55\x65\x46\xeb\x68", - "\x77\xc6\x07\x71\x46\xf0\x1c\x32\xb6\xb6\x9d\x5f\x4e\xa9\xff\xcf", - "\x37\xa6\x98\x6c\xb8\x84\x7e\xdf\x09\x25\xf0\xf1\x30\x9b\x54\xde", - "\xa7\x05\xf0\xe6\x9d\xa9\xa8\xf9\x07\x24\x1a\x2e\x92\x3c\x8c\xc8", - "\x3d\xc4\x7d\x1f\x29\xc4\x48\x46\x1e\x9e\x76\xed\x90\x4f\x67\x11", - "\x0d\x62\xbf\x01\xe6\xfc\x0e\x1a\x0d\x3c\x47\x51\xc5\xd3\x69\x2b", - "\x8c\x03\x46\x8b\xca\x7c\x66\x9e\xe4\xfd\x5e\x08\x4b\xbe\xe7\xb5", - "\x52\x8a\x5b\xb9\x3b\xaf\x2c\x9c\x44\x73\xcc\xe5\xd0\xd2\x2b\xd9", - "\xdf\x6a\x30\x1e\x95\xc9\x5d\xad\x97\xae\x0c\xc8\xc6\x91\x3b\xd8", - "\x80\x11\x89\x90\x2c\x85\x7f\x39\xe7\x35\x91\x28\x5e\x70\xb6\xdb", - "\xe6\x17\x34\x6a\xc9\xc2\x31\xbb\x36\x50\xae\x34\xcc\xca\x0c\x5b", - "\x27\xd9\x34\x37\xef\xb7\x21\xaa\x40\x18\x21\xdc\xec\x5a\xdf\x89", - "\x89\x23\x7d\x9d\xed\x9c\x5e\x78\xd8\xb1\xc9\xb1\x66\xcc\x73\x42", - "\x4a\x6d\x80\x91\xbf\x5e\x7d\x65\x11\x89\xfa\x94\xa2\x50\xb1\x4c", - "\x0e\x33\xf9\x60\x55\xe7\xae\x89\x3f\xfc\x0e\x3d\xcf\x49\x29\x02", - "\xe6\x1c\x43\x2b\x72\x0b\x19\xd1\x8e\xc8\xd8\x4b\xdc\x63\x15\x1b", - "\xf7\xe5\xae\xf5\x49\xf7\x82\xcf\x37\x90\x55\xa6\x08\x26\x9b\x16", - "\x43\x8d\x03\x0f\xd0\xb7\xa5\x4f\xa8\x37\xf2\xad\x20\x1a\x64\x03", - "\xa5\x90\xd3\xee\x4f\xbf\x04\xe3\x24\x7e\x0d\x27\xf2\x86\x42\x3f", - "\x5f\xe2\xc1\xa1\x72\xfe\x93\xc4\xb1\x5c\xd3\x7c\xae\xf9\xf5\x38", - "\x2c\x97\x32\x5c\xbd\x06\xb3\x6e\xb2\x13\x3d\xd0\x8b\x3a\x01\x7c", - "\x92\xc8\x14\x22\x7a\x6b\xca\x94\x9f\xf0\x65\x9f\x00\x2a\xd3\x9e", - "\xdc\xe8\x50\x11\x0b\xd8\x32\x8c\xfb\xd5\x08\x41\xd6\x91\x1d\x87", - "\x67\xf1\x49\x84\xc7\xda\x79\x12\x48\xe3\x2b\xb5\x92\x25\x83\xda", - "\x19\x38\xf2\xcf\x72\xd5\x4e\xe9\x7e\x94\x16\x6f\xa9\x1d\x2a\x36", - "\x74\x48\x1e\x96\x46\xed\x49\xfe\x0f\x62\x24\x30\x16\x04\x69\x8e", - "\x57\xfc\xa5\xde\x98\xa9\xd6\xd8\x00\x64\x38\xd0\x58\x3d\x8a\x1d", - "\x9f\xec\xde\x1c\xef\xdc\x1c\xbe\xd4\x76\x36\x74\xd9\x57\x53\x59", - "\xe3\x04\x0c\x00\xeb\x28\xf1\x53\x66\xca\x73\xcb\xd8\x72\xe7\x40", - "\x76\x97\x00\x9a\x6a\x83\x1d\xfe\xcc\xa9\x1c\x59\x93\x67\x0f\x7a", - "\x58\x53\x54\x23\x21\xf5\x67\xa0\x05\xd5\x47\xa4\xf0\x47\x59\xbd", - "\x51\x50\xd1\x77\x2f\x50\x83\x4a\x50\x3e\x06\x9a\x97\x3f\xbd\x7c", + "\xa3\x81\x7f\x04\xba\x25\xa8\xe6\x6d\xf6\x72\x14\xc7\x55\x02\x93".*, + "\xda\x87\xc1\xd8\x6b\x99\xaf\x44\x34\x76\x59\x11\x9b\x22\xfc\x45".*, + "\x81\x77\x22\x8d\xa4\xa4\x5d\xc7\xfc\xa3\x8b\xde\xf6\x0a\xff\xe4".*, + "\x9c\x70\xb6\x0c\x52\x67\xa9\x4e\x5f\x33\xb6\xb0\x29\x85\xed\x51".*, + "\xf8\x81\x64\xc1\x2d\x9c\x8f\xaf\x7d\x0f\x6e\x7c\x7b\xcd\x55\x79".*, + "\x13\x68\x87\x59\x80\x77\x6f\x88\x54\x52\x7a\x07\x69\x0e\x96\x27".*, + "\x14\xee\xca\x33\x8b\x20\x86\x13\x48\x5e\xa0\x30\x8f\xd7\xa1\x5e".*, + "\xa1\xf1\xeb\xbe\xd8\xdb\xc1\x53\xc0\xb8\x4a\xa6\x1f\xf0\x82\x39".*, + "\x3b\x62\xa9\xba\x62\x58\xf5\x61\x0f\x83\xe2\x64\xf3\x14\x97\xb4".*, + "\x26\x44\x99\x06\x0a\xd9\xba\xab\xc4\x7f\x8b\x02\xbb\x6d\x71\xed".*, + "\x00\x11\x0d\xc3\x78\x14\x69\x56\xc9\x54\x47\xd3\xf3\xd0\xfb\xba".*, + "\x01\x51\xc5\x68\x38\x6b\x66\x77\xa2\xb4\xdc\x6f\x81\xe5\xdc\x18".*, + "\xd6\x26\xb2\x66\x90\x5e\xf3\x58\x82\x63\x4d\xf6\x85\x32\xc1\x25".*, + "\x98\x69\xe2\x47\xe9\xc0\x8b\x10\xd0\x29\x93\x4f\xc4\xb9\x52\xf7".*, + "\x31\xfc\xef\xac\x66\xd7\xde\x9c\x7e\xc7\x48\x5f\xe4\x49\x49\x02".*, + "\x54\x93\xe9\x99\x33\xb0\xa8\x11\x7e\x08\xec\x0f\x97\xcf\xc3\xd9".*, + "\x6e\xe2\xa4\xca\x67\xb0\x54\xbb\xfd\x33\x15\xbf\x85\x23\x05\x77".*, + "\x47\x3d\x06\xe8\x73\x8d\xb8\x98\x54\xc0\x66\xc4\x7a\xe4\x77\x40".*, + "\xa4\x26\xe5\xe4\x23\xbf\x48\x85\x29\x4d\xa4\x81\xfe\xae\xf7\x23".*, + "\x78\x01\x77\x31\xcf\x65\xfa\xb0\x74\xd5\x20\x89\x52\x51\x2e\xb1".*, + "\x9e\x25\xfc\x83\x3f\x22\x90\x73\x3e\x93\x44\xa5\xe8\x38\x39\xeb".*, + "\x56\x8e\x49\x5a\xbe\x52\x5a\x21\x8a\x22\x14\xcd\x3e\x07\x1d\x12".*, + "\x4a\x29\xb5\x45\x52\xd1\x6b\x9a\x46\x9c\x10\x52\x8e\xff\x0a\xae".*, + "\xc9\xd1\x84\xdd\xd5\xa9\xf5\xe0\xcf\x8c\xe2\x9a\x9a\xbf\x69\x1c".*, + "\x2d\xb4\x79\xae\x78\xbd\x50\xd8\x88\x2a\x8a\x17\x8a\x61\x32\xad".*, + "\x8e\xce\x5f\x04\x2d\x5e\x44\x7b\x50\x51\xb9\xea\xcb\x8d\x8f\x6f".*, + "\x9c\x0b\x53\xb4\xb3\xc3\x07\xe8\x7e\xae\xe0\x86\x78\x14\x1f\x66".*, + "\xab\xf2\x48\xaf\x69\xa6\xea\xe4\xbf\xd3\xeb\x2f\x12\x9e\xeb\x94".*, + "\x06\x64\xda\x16\x68\x57\x4b\x88\xb9\x35\xf3\x02\x73\x58\xae\xf4".*, + "\xaa\x4b\x9d\xc4\xbf\x33\x7d\xe9\x0c\xd4\xfd\x3c\x46\x7c\x6a\xb7".*, + "\xea\x5c\x7f\x47\x1f\xaf\x6b\xde\x2b\x1a\xd7\xd4\x68\x6d\x22\x87".*, + "\x29\x39\xb0\x18\x32\x23\xfa\xfc\x17\x23\xde\x4f\x52\xc4\x3d\x35".*, + "\x7c\x39\x56\xca\x5e\xea\xfc\x3e\x36\x3e\x9d\x55\x65\x46\xeb\x68".*, + "\x77\xc6\x07\x71\x46\xf0\x1c\x32\xb6\xb6\x9d\x5f\x4e\xa9\xff\xcf".*, + "\x37\xa6\x98\x6c\xb8\x84\x7e\xdf\x09\x25\xf0\xf1\x30\x9b\x54\xde".*, + "\xa7\x05\xf0\xe6\x9d\xa9\xa8\xf9\x07\x24\x1a\x2e\x92\x3c\x8c\xc8".*, + "\x3d\xc4\x7d\x1f\x29\xc4\x48\x46\x1e\x9e\x76\xed\x90\x4f\x67\x11".*, + "\x0d\x62\xbf\x01\xe6\xfc\x0e\x1a\x0d\x3c\x47\x51\xc5\xd3\x69\x2b".*, + "\x8c\x03\x46\x8b\xca\x7c\x66\x9e\xe4\xfd\x5e\x08\x4b\xbe\xe7\xb5".*, + "\x52\x8a\x5b\xb9\x3b\xaf\x2c\x9c\x44\x73\xcc\xe5\xd0\xd2\x2b\xd9".*, + "\xdf\x6a\x30\x1e\x95\xc9\x5d\xad\x97\xae\x0c\xc8\xc6\x91\x3b\xd8".*, + "\x80\x11\x89\x90\x2c\x85\x7f\x39\xe7\x35\x91\x28\x5e\x70\xb6\xdb".*, + "\xe6\x17\x34\x6a\xc9\xc2\x31\xbb\x36\x50\xae\x34\xcc\xca\x0c\x5b".*, + "\x27\xd9\x34\x37\xef\xb7\x21\xaa\x40\x18\x21\xdc\xec\x5a\xdf\x89".*, + "\x89\x23\x7d\x9d\xed\x9c\x5e\x78\xd8\xb1\xc9\xb1\x66\xcc\x73\x42".*, + "\x4a\x6d\x80\x91\xbf\x5e\x7d\x65\x11\x89\xfa\x94\xa2\x50\xb1\x4c".*, + "\x0e\x33\xf9\x60\x55\xe7\xae\x89\x3f\xfc\x0e\x3d\xcf\x49\x29\x02".*, + "\xe6\x1c\x43\x2b\x72\x0b\x19\xd1\x8e\xc8\xd8\x4b\xdc\x63\x15\x1b".*, + "\xf7\xe5\xae\xf5\x49\xf7\x82\xcf\x37\x90\x55\xa6\x08\x26\x9b\x16".*, + "\x43\x8d\x03\x0f\xd0\xb7\xa5\x4f\xa8\x37\xf2\xad\x20\x1a\x64\x03".*, + "\xa5\x90\xd3\xee\x4f\xbf\x04\xe3\x24\x7e\x0d\x27\xf2\x86\x42\x3f".*, + "\x5f\xe2\xc1\xa1\x72\xfe\x93\xc4\xb1\x5c\xd3\x7c\xae\xf9\xf5\x38".*, + "\x2c\x97\x32\x5c\xbd\x06\xb3\x6e\xb2\x13\x3d\xd0\x8b\x3a\x01\x7c".*, + "\x92\xc8\x14\x22\x7a\x6b\xca\x94\x9f\xf0\x65\x9f\x00\x2a\xd3\x9e".*, + "\xdc\xe8\x50\x11\x0b\xd8\x32\x8c\xfb\xd5\x08\x41\xd6\x91\x1d\x87".*, + "\x67\xf1\x49\x84\xc7\xda\x79\x12\x48\xe3\x2b\xb5\x92\x25\x83\xda".*, + "\x19\x38\xf2\xcf\x72\xd5\x4e\xe9\x7e\x94\x16\x6f\xa9\x1d\x2a\x36".*, + "\x74\x48\x1e\x96\x46\xed\x49\xfe\x0f\x62\x24\x30\x16\x04\x69\x8e".*, + "\x57\xfc\xa5\xde\x98\xa9\xd6\xd8\x00\x64\x38\xd0\x58\x3d\x8a\x1d".*, + "\x9f\xec\xde\x1c\xef\xdc\x1c\xbe\xd4\x76\x36\x74\xd9\x57\x53\x59".*, + "\xe3\x04\x0c\x00\xeb\x28\xf1\x53\x66\xca\x73\xcb\xd8\x72\xe7\x40".*, + "\x76\x97\x00\x9a\x6a\x83\x1d\xfe\xcc\xa9\x1c\x59\x93\x67\x0f\x7a".*, + "\x58\x53\x54\x23\x21\xf5\x67\xa0\x05\xd5\x47\xa4\xf0\x47\x59\xbd".*, + "\x51\x50\xd1\x77\x2f\x50\x83\x4a\x50\x3e\x06\x9a\x97\x3f\xbd\x7c".*, }; const siphash = SipHash128(2, 4); diff --git a/lib/std/io/test.zig b/lib/std/io/test.zig index 28b8371d9d..d2374f0a3f 100644 --- a/lib/std/io/test.zig +++ b/lib/std/io/test.zig @@ -595,8 +595,8 @@ test "Deserializer bad data" { test "c out stream" { if (!builtin.link_libc) return error.SkipZigTest; - const filename = c"tmp_io_test_file.txt"; - const out_file = std.c.fopen(filename, c"w") orelse return error.UnableToOpenTestFile; + const filename = "tmp_io_test_file.txt"; + const out_file = std.c.fopen(filename, "w") orelse return error.UnableToOpenTestFile; defer { _ = std.c.fclose(out_file); fs.deleteFileC(filename) catch {}; diff --git a/lib/std/mem.zig b/lib/std/mem.zig index 19e9634d5a..160b8e6e5e 100644 --- a/lib/std/mem.zig +++ b/lib/std/mem.zig @@ -1408,7 +1408,9 @@ test "toBytes" { fn BytesAsValueReturnType(comptime T: type, comptime B: type) type { const size = @as(usize, @sizeOf(T)); - if (comptime !trait.is(builtin.TypeId.Pointer)(B) or meta.Child(B) != [size]u8) { + if (comptime !trait.is(builtin.TypeId.Pointer)(B) or + (meta.Child(B) != [size]u8 and meta.Child(B) != [size]null u8)) + { @compileError("expected *[N]u8 " ++ ", passed " ++ @typeName(B)); } @@ -1430,12 +1432,12 @@ test "bytesAsValue" { builtin.Endian.Little => "\xEF\xBE\xAD\xDE", }; - testing.expect(deadbeef == bytesAsValue(u32, &deadbeef_bytes).*); + testing.expect(deadbeef == bytesAsValue(u32, deadbeef_bytes).*); - var codeface_bytes = switch (builtin.endian) { + var codeface_bytes: [4]u8 = switch (builtin.endian) { builtin.Endian.Big => "\xC0\xDE\xFA\xCE", builtin.Endian.Little => "\xCE\xFA\xDE\xC0", - }; + }.*; var codeface = bytesAsValue(u32, &codeface_bytes); testing.expect(codeface.* == 0xC0DEFACE); codeface.* = 0; @@ -1456,14 +1458,14 @@ test "bytesAsValue" { .d = 0xA1, }; const inst_bytes = "\xBE\xEF\xDE\xA1"; - const inst2 = bytesAsValue(S, &inst_bytes); + const inst2 = bytesAsValue(S, inst_bytes); testing.expect(meta.eql(inst, inst2.*)); } ///Given a pointer to an array of bytes, returns a value of the specified type backed by a /// copy of those bytes. pub fn bytesToValue(comptime T: type, bytes: var) T { - return bytesAsValue(T, &bytes).*; + return bytesAsValue(T, bytes).*; } test "bytesToValue" { const deadbeef_bytes = switch (builtin.endian) { @@ -1491,11 +1493,11 @@ pub fn subArrayPtr(ptr: var, comptime start: usize, comptime length: usize) SubA } test "subArrayPtr" { - const a1 = "abcdef"; + const a1: [6]u8 = "abcdef".*; const sub1 = subArrayPtr(&a1, 2, 3); testing.expect(eql(u8, sub1.*, "cde")); - var a2 = "abcdef"; + var a2: [6]u8 = "abcdef".*; var sub2 = subArrayPtr(&a2, 2, 3); testing.expect(eql(u8, sub2, "cde")); diff --git a/lib/std/meta.zig b/lib/std/meta.zig index 01d240f31f..b770b97a47 100644 --- a/lib/std/meta.zig +++ b/lib/std/meta.zig @@ -469,19 +469,19 @@ test "std.meta.eql" { const s_1 = S{ .a = 134, .b = 123.3, - .c = "12345", + .c = "12345".*, }; const s_2 = S{ .a = 1, .b = 123.3, - .c = "54321", + .c = "54321".*, }; const s_3 = S{ .a = 134, .b = 123.3, - .c = "12345", + .c = "12345".*, }; const u_1 = U{ .f = 24 }; @@ -494,9 +494,9 @@ test "std.meta.eql" { testing.expect(eql(u_1, u_3)); testing.expect(!eql(u_1, u_2)); - var a1 = "abcdef"; - var a2 = "abcdef"; - var a3 = "ghijkl"; + var a1 = "abcdef".*; + var a2 = "abcdef".*; + var a3 = "ghijkl".*; testing.expect(eql(a1, a2)); testing.expect(!eql(a1, a3)); @@ -558,4 +558,3 @@ pub fn refAllDecls(comptime T: type) void { if (!builtin.is_test) return; _ = declarations(T); } - diff --git a/lib/std/meta/trait.zig b/lib/std/meta/trait.zig index 8857b4aa9e..2388acbeb6 100644 --- a/lib/std/meta/trait.zig +++ b/lib/std/meta/trait.zig @@ -319,7 +319,6 @@ test "std.meta.trait.isNumber" { testing.expect(!isNumber(NotANumber)); } -/// pub fn isConstPtr(comptime T: type) bool { if (!comptime is(builtin.TypeId.Pointer)(T)) return false; const info = @typeInfo(T); @@ -335,7 +334,6 @@ test "std.meta.trait.isConstPtr" { testing.expect(!isConstPtr(@typeOf(6))); } -/// pub fn isContainer(comptime T: type) bool { const info = @typeInfo(T); return switch (info) { diff --git a/lib/std/net.zig b/lib/std/net.zig index f4cd09482b..5e194d73ca 100644 --- a/lib/std/net.zig +++ b/lib/std/net.zig @@ -666,35 +666,35 @@ const Policy = struct { const defined_policies = [_]Policy{ Policy{ - .addr = "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01", + .addr = "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01".*, .len = 15, .mask = 0xff, .prec = 50, .label = 0, }, Policy{ - .addr = "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff\x00\x00\x00\x00", + .addr = "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff\x00\x00\x00\x00".*, .len = 11, .mask = 0xff, .prec = 35, .label = 4, }, Policy{ - .addr = "\x20\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", + .addr = "\x20\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".*, .len = 1, .mask = 0xff, .prec = 30, .label = 2, }, Policy{ - .addr = "\x20\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", + .addr = "\x20\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".*, .len = 3, .mask = 0xff, .prec = 5, .label = 5, }, Policy{ - .addr = "\xfc\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", + .addr = "\xfc\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".*, .len = 0, .mask = 0xfe, .prec = 3, @@ -708,7 +708,7 @@ const defined_policies = [_]Policy{ // { "\x3f\xfe", 1, 0xff, 1, 12 }, // Last rule must match all addresses to stop loop. Policy{ - .addr = "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", + .addr = "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".*, .len = 0, .mask = 0, .prec = 40, @@ -812,7 +812,7 @@ fn linuxLookupNameFromHosts( family: os.sa_family_t, port: u16, ) !void { - const file = fs.File.openReadC(c"/etc/hosts") catch |err| switch (err) { + const file = fs.File.openReadC("/etc/hosts") catch |err| switch (err) { error.FileNotFound, error.NotDir, error.AccessDenied, @@ -1006,7 +1006,7 @@ fn getResolvConf(allocator: *mem.Allocator, rc: *ResolvConf) !void { }; errdefer rc.deinit(); - const file = fs.File.openReadC(c"/etc/resolv.conf") catch |err| switch (err) { + const file = fs.File.openReadC("/etc/resolv.conf") catch |err| switch (err) { error.FileNotFound, error.NotDir, error.AccessDenied, diff --git a/lib/std/os.zig b/lib/std/os.zig index 68a3a6e9f6..28a88beb04 100644 --- a/lib/std/os.zig +++ b/lib/std/os.zig @@ -157,7 +157,7 @@ pub fn getrandom(buffer: []u8) GetRandomError!void { } fn getRandomBytesDevURandom(buf: []u8) !void { - const fd = try openC(c"/dev/urandom", O_RDONLY | O_CLOEXEC, 0); + const fd = try openC("/dev/urandom", O_RDONLY | O_CLOEXEC, 0); defer close(fd); const st = try fstat(fd); @@ -2674,7 +2674,7 @@ pub fn dl_iterate_phdr( if (it.end()) { var info = dl_phdr_info{ .dlpi_addr = elf_base, - .dlpi_name = c"/proc/self/exe", + .dlpi_name = "/proc/self/exe", .dlpi_phdr = phdrs.ptr, .dlpi_phnum = ehdr.e_phnum, }; diff --git a/lib/std/os/linux.zig b/lib/std/os/linux.zig index 7e2f14021f..1de66b8d2e 100644 --- a/lib/std/os/linux.zig +++ b/lib/std/os/linux.zig @@ -1053,7 +1053,7 @@ pub fn dl_iterate_phdr(comptime T: type, callback: extern fn (info: *dl_phdr_inf if (it.end()) { var info = dl_phdr_info{ .dlpi_addr = elf_base, - .dlpi_name = c"/proc/self/exe", + .dlpi_name = "/proc/self/exe", .dlpi_phdr = @intToPtr([*]elf.Phdr, elf_base + __ehdr_start.e_phoff), .dlpi_phnum = __ehdr_start.e_phnum, }; diff --git a/lib/std/os/linux/test.zig b/lib/std/os/linux/test.zig index bccb7beb1e..8281851d6b 100644 --- a/lib/std/os/linux/test.zig +++ b/lib/std/os/linux/test.zig @@ -56,7 +56,7 @@ test "statx" { } var statx_buf: linux.Statx = undefined; - switch (linux.getErrno(linux.statx(file.handle, c"", linux.AT_EMPTY_PATH, linux.STATX_BASIC_STATS, &statx_buf))) { + switch (linux.getErrno(linux.statx(file.handle, "", linux.AT_EMPTY_PATH, linux.STATX_BASIC_STATS, &statx_buf))) { 0 => {}, // The statx syscall was only introduced in linux 4.11 linux.ENOSYS => return error.SkipZigTest, @@ -64,7 +64,7 @@ test "statx" { } var stat_buf: linux.Stat = undefined; - switch (linux.getErrno(linux.fstatat(file.handle, c"", &stat_buf, linux.AT_EMPTY_PATH))) { + switch (linux.getErrno(linux.fstatat(file.handle, "", &stat_buf, linux.AT_EMPTY_PATH))) { 0 => {}, else => unreachable, } diff --git a/lib/std/process.zig b/lib/std/process.zig index fca10a240d..3f065de8fc 100644 --- a/lib/std/process.zig +++ b/lib/std/process.zig @@ -473,14 +473,14 @@ pub fn argsFree(allocator: *mem.Allocator, args_alloc: []const []u8) void { } test "windows arg parsing" { - testWindowsCmdLine(c"a b\tc d", [_][]const u8{ "a", "b", "c", "d" }); - testWindowsCmdLine(c"\"abc\" d e", [_][]const u8{ "abc", "d", "e" }); - testWindowsCmdLine(c"a\\\\\\b d\"e f\"g h", [_][]const u8{ "a\\\\\\b", "de fg", "h" }); - testWindowsCmdLine(c"a\\\\\\\"b c d", [_][]const u8{ "a\\\"b", "c", "d" }); - testWindowsCmdLine(c"a\\\\\\\\\"b c\" d e", [_][]const u8{ "a\\\\b c", "d", "e" }); - testWindowsCmdLine(c"a b\tc \"d f", [_][]const u8{ "a", "b", "c", "\"d", "f" }); + testWindowsCmdLine("a b\tc d", [_][]const u8{ "a", "b", "c", "d" }); + testWindowsCmdLine("\"abc\" d e", [_][]const u8{ "abc", "d", "e" }); + testWindowsCmdLine("a\\\\\\b d\"e f\"g h", [_][]const u8{ "a\\\\\\b", "de fg", "h" }); + testWindowsCmdLine("a\\\\\\\"b c d", [_][]const u8{ "a\\\"b", "c", "d" }); + testWindowsCmdLine("a\\\\\\\\\"b c\" d e", [_][]const u8{ "a\\\\b c", "d", "e" }); + testWindowsCmdLine("a b\tc \"d f", [_][]const u8{ "a", "b", "c", "\"d", "f" }); - testWindowsCmdLine(c"\".\\..\\zig-cache\\build\" \"bin\\zig.exe\" \".\\..\" \".\\..\\zig-cache\" \"--help\"", [_][]const u8{ + testWindowsCmdLine("\".\\..\\zig-cache\\build\" \"bin\\zig.exe\" \".\\..\" \".\\..\\zig-cache\" \"--help\"", [_][]const u8{ ".\\..\\zig-cache\\build", "bin\\zig.exe", ".\\..", diff --git a/lib/std/special/c.zig b/lib/std/special/c.zig index 145c8897d5..8ac00c4e04 100644 --- a/lib/std/special/c.zig +++ b/lib/std/special/c.zig @@ -66,14 +66,14 @@ extern fn strncmp(_l: [*]const u8, _r: [*]const u8, _n: usize) c_int { } extern fn strerror(errnum: c_int) [*]const u8 { - return c"TODO strerror implementation"; + return "TODO strerror implementation"; } test "strncmp" { - std.testing.expect(strncmp(c"a", c"b", 1) == -1); - std.testing.expect(strncmp(c"a", c"c", 1) == -2); - std.testing.expect(strncmp(c"b", c"a", 1) == 1); - std.testing.expect(strncmp(c"\xff", c"\x02", 1) == 253); + std.testing.expect(strncmp("a", "b", 1) == -1); + std.testing.expect(strncmp("a", "c", 1) == -2); + std.testing.expect(strncmp("b", "a", 1) == 1); + std.testing.expect(strncmp("\xff", "\x02", 1) == 253); } // Avoid dragging in the runtime safety mechanisms into this .o file, diff --git a/lib/std/thread.zig b/lib/std/thread.zig index 4e15354055..fe976a6839 100644 --- a/lib/std/thread.zig +++ b/lib/std/thread.zig @@ -353,7 +353,7 @@ pub const Thread = struct { } var count: c_int = undefined; var count_len: usize = @sizeOf(c_int); - const name = if (comptime std.Target.current.isDarwin()) c"hw.logicalcpu" else c"hw.ncpu"; + const name = if (comptime std.Target.current.isDarwin()) "hw.logicalcpu" else "hw.ncpu"; os.sysctlbynameC(name, &count, &count_len, null, 0) catch |err| switch (err) { error.NameTooLong => unreachable, else => |e| return e, diff --git a/lib/std/valgrind/memcheck.zig b/lib/std/valgrind/memcheck.zig index a15a6cca0e..e0aefa7d5f 100644 --- a/lib/std/valgrind/memcheck.zig +++ b/lib/std/valgrind/memcheck.zig @@ -3,7 +3,7 @@ const testing = std.testing; const valgrind = std.valgrind; pub const MemCheckClientRequest = extern enum { - MakeMemNoAccess = valgrind.ToolBase("MC"), + MakeMemNoAccess = valgrind.ToolBase("MC".*), MakeMemUndefined, MakeMemDefined, Discard, diff --git a/src-self-hosted/codegen.zig b/src-self-hosted/codegen.zig index 90f5309faf..212a54b1aa 100644 --- a/src-self-hosted/codegen.zig +++ b/src-self-hosted/codegen.zig @@ -52,7 +52,7 @@ pub async fn renderToLlvm(comp: *Compilation, fn_val: *Value.Fn, code: *ir.Code) u32(c.ZIG_VERSION_MINOR), u32(c.ZIG_VERSION_PATCH), ); - const flags = c""; + const flags = ""; const runtime_version = 0; const compile_unit_file = llvm.CreateFile( dibuilder, @@ -68,7 +68,7 @@ pub async fn renderToLlvm(comp: *Compilation, fn_val: *Value.Fn, code: *ir.Code) is_optimized, flags, runtime_version, - c"", + "", 0, !comp.strip, ) orelse return error.OutOfMemory; @@ -402,7 +402,7 @@ pub fn getHandleValue(ofile: *ObjectFile, ptr: *llvm.Value, ptr_type: *Type.Poin if (child_type.handleIsPtr()) { return ptr; } - return try renderLoad(ofile, ptr, ptr_type, c""); + return try renderLoad(ofile, ptr, ptr_type, ""); } pub fn renderStoreUntyped( diff --git a/src-self-hosted/compilation.zig b/src-self-hosted/compilation.zig index 1e71a5e561..24c57f98ba 100644 --- a/src-self-hosted/compilation.zig +++ b/src-self-hosted/compilation.zig @@ -511,8 +511,8 @@ pub const Compilation = struct { comp.target_machine = llvm.CreateTargetMachine( comp.llvm_target, comp.llvm_triple.ptr(), - target_specific_cpu_args orelse c"", - target_specific_cpu_features orelse c"", + target_specific_cpu_args orelse "", + target_specific_cpu_features orelse "", opt_level, reloc_mode, llvm.CodeModelDefault, diff --git a/src-self-hosted/ir.zig b/src-self-hosted/ir.zig index df4d436b50..a650a3999d 100644 --- a/src-self-hosted/ir.zig +++ b/src-self-hosted/ir.zig @@ -331,7 +331,7 @@ pub const Inst = struct { @intCast(c_uint, args.len), llvm_cc, fn_inline, - c"", + "", ) orelse error.OutOfMemory; } }; @@ -1410,7 +1410,7 @@ pub const Builder = struct { if (block.label) |label| { block_scope.incoming_values = std.ArrayList(*Inst).init(irb.arena()); block_scope.incoming_blocks = std.ArrayList(*BasicBlock).init(irb.arena()); - block_scope.end_block = try irb.createBasicBlock(parent_scope, c"BlockEnd"); + block_scope.end_block = try irb.createBasicBlock(parent_scope, "BlockEnd"); block_scope.is_comptime = try irb.buildConstBool( parent_scope, Span.token(block.lbrace), @@ -1542,8 +1542,8 @@ pub const Builder = struct { const defer_counts = irb.countDefers(scope, outer_scope); const have_err_defers = defer_counts.error_exit != 0; if (have_err_defers or irb.comp.have_err_ret_tracing) { - const err_block = try irb.createBasicBlock(scope, c"ErrRetErr"); - const ok_block = try irb.createBasicBlock(scope, c"ErrRetOk"); + const err_block = try irb.createBasicBlock(scope, "ErrRetErr"); + const ok_block = try irb.createBasicBlock(scope, "ErrRetOk"); if (!have_err_defers) { _ = try await (async irb.genDefersForBlock(scope, outer_scope, Scope.Defer.Kind.ScopeExit) catch unreachable); } @@ -1564,7 +1564,7 @@ pub const Builder = struct { .is_comptime = err_is_comptime, }); - const ret_stmt_block = try irb.createBasicBlock(scope, c"RetStmt"); + const ret_stmt_block = try irb.createBasicBlock(scope, "RetStmt"); try irb.setCursorAtEndAndAppendBlock(err_block); if (have_err_defers) { @@ -2530,7 +2530,7 @@ pub async fn gen( var irb = try Builder.init(comp, tree_scope, scope); errdefer irb.abort(); - const entry_block = try irb.createBasicBlock(scope, c"Entry"); + const entry_block = try irb.createBasicBlock(scope, "Entry"); entry_block.ref(&irb); // Entry block gets a reference because we enter it to begin. try irb.setCursorAtEndAndAppendBlock(entry_block); diff --git a/src-self-hosted/link.zig b/src-self-hosted/link.zig index 1f5f07eff0..3af1842b9d 100644 --- a/src-self-hosted/link.zig +++ b/src-self-hosted/link.zig @@ -55,7 +55,7 @@ pub async fn link(comp: *Compilation) !void { // even though we're calling LLD as a library it thinks the first // argument is its own exe name - try ctx.args.append(c"lld"); + try ctx.args.append("lld"); if (comp.haveLibC()) { ctx.libc = ctx.comp.override_libc orelse blk: { @@ -145,7 +145,7 @@ fn constructLinkerArgsElf(ctx: *Context) !void { // lj->args.append("-T"); // lj->args.append(g->linker_script); //} - try ctx.args.append(c"--gc-sections"); + try ctx.args.append("--gc-sections"); //lj->args.append("-m"); //lj->args.append(getLDMOption(&g->zig_target)); @@ -155,9 +155,9 @@ fn constructLinkerArgsElf(ctx: *Context) !void { //Buf *soname = nullptr; if (ctx.comp.is_static) { if (ctx.comp.target.isArmOrThumb()) { - try ctx.args.append(c"-Bstatic"); + try ctx.args.append("-Bstatic"); } else { - try ctx.args.append(c"-static"); + try ctx.args.append("-static"); } } //} else if (shared) { @@ -170,7 +170,7 @@ fn constructLinkerArgsElf(ctx: *Context) !void { // soname = buf_sprintf("lib%s.so.%" ZIG_PRI_usize "", buf_ptr(g->root_out_name), g->version_major); //} - try ctx.args.append(c"-o"); + try ctx.args.append("-o"); try ctx.args.append(ctx.out_file_path.ptr()); if (ctx.link_in_crt) { @@ -213,10 +213,10 @@ fn constructLinkerArgsElf(ctx: *Context) !void { //} if (ctx.comp.haveLibC()) { - try ctx.args.append(c"-L"); + try ctx.args.append("-L"); try ctx.args.append((try std.cstr.addNullByte(&ctx.arena.allocator, ctx.libc.lib_dir.?)).ptr); - try ctx.args.append(c"-L"); + try ctx.args.append("-L"); try ctx.args.append((try std.cstr.addNullByte(&ctx.arena.allocator, ctx.libc.static_lib_dir.?)).ptr); if (!ctx.comp.is_static) { @@ -225,7 +225,7 @@ fn constructLinkerArgsElf(ctx: *Context) !void { if (ctx.comp.target.getDynamicLinkerPath()) |dl| break :blk dl; return error.LibCMissingDynamicLinker; }; - try ctx.args.append(c"-dynamic-linker"); + try ctx.args.append("-dynamic-linker"); try ctx.args.append((try std.cstr.addNullByte(&ctx.arena.allocator, dl)).ptr); } } @@ -272,23 +272,23 @@ fn constructLinkerArgsElf(ctx: *Context) !void { // libc dep if (ctx.comp.haveLibC()) { if (ctx.comp.is_static) { - try ctx.args.append(c"--start-group"); - try ctx.args.append(c"-lgcc"); - try ctx.args.append(c"-lgcc_eh"); - try ctx.args.append(c"-lc"); - try ctx.args.append(c"-lm"); - try ctx.args.append(c"--end-group"); + try ctx.args.append("--start-group"); + try ctx.args.append("-lgcc"); + try ctx.args.append("-lgcc_eh"); + try ctx.args.append("-lc"); + try ctx.args.append("-lm"); + try ctx.args.append("--end-group"); } else { - try ctx.args.append(c"-lgcc"); - try ctx.args.append(c"--as-needed"); - try ctx.args.append(c"-lgcc_s"); - try ctx.args.append(c"--no-as-needed"); - try ctx.args.append(c"-lc"); - try ctx.args.append(c"-lm"); - try ctx.args.append(c"-lgcc"); - try ctx.args.append(c"--as-needed"); - try ctx.args.append(c"-lgcc_s"); - try ctx.args.append(c"--no-as-needed"); + try ctx.args.append("-lgcc"); + try ctx.args.append("--as-needed"); + try ctx.args.append("-lgcc_s"); + try ctx.args.append("--no-as-needed"); + try ctx.args.append("-lc"); + try ctx.args.append("-lm"); + try ctx.args.append("-lgcc"); + try ctx.args.append("--as-needed"); + try ctx.args.append("-lgcc_s"); + try ctx.args.append("--no-as-needed"); } } @@ -299,14 +299,14 @@ fn constructLinkerArgsElf(ctx: *Context) !void { } if (ctx.comp.target != Target.Native) { - try ctx.args.append(c"--allow-shlib-undefined"); + try ctx.args.append("--allow-shlib-undefined"); } if (ctx.comp.target.getOs() == .zen) { - try ctx.args.append(c"-e"); - try ctx.args.append(c"_start"); + try ctx.args.append("-e"); + try ctx.args.append("_start"); - try ctx.args.append(c"--image-base=0x10000000"); + try ctx.args.append("--image-base=0x10000000"); } } @@ -317,23 +317,23 @@ fn addPathJoin(ctx: *Context, dirname: []const u8, basename: []const u8) !void { } fn constructLinkerArgsCoff(ctx: *Context) !void { - try ctx.args.append(c"-NOLOGO"); + try ctx.args.append("-NOLOGO"); if (!ctx.comp.strip) { - try ctx.args.append(c"-DEBUG"); + try ctx.args.append("-DEBUG"); } switch (ctx.comp.target.getArch()) { - builtin.Arch.i386 => try ctx.args.append(c"-MACHINE:X86"), - builtin.Arch.x86_64 => try ctx.args.append(c"-MACHINE:X64"), - builtin.Arch.aarch64 => try ctx.args.append(c"-MACHINE:ARM"), + builtin.Arch.i386 => try ctx.args.append("-MACHINE:X86"), + builtin.Arch.x86_64 => try ctx.args.append("-MACHINE:X64"), + builtin.Arch.aarch64 => try ctx.args.append("-MACHINE:ARM"), else => return error.UnsupportedLinkArchitecture, } if (ctx.comp.windows_subsystem_windows) { - try ctx.args.append(c"/SUBSYSTEM:windows"); + try ctx.args.append("/SUBSYSTEM:windows"); } else if (ctx.comp.windows_subsystem_console) { - try ctx.args.append(c"/SUBSYSTEM:console"); + try ctx.args.append("/SUBSYSTEM:console"); } const is_library = ctx.comp.kind == Compilation.Kind.Lib; @@ -367,14 +367,14 @@ fn constructLinkerArgsCoff(ctx: *Context) !void { // Visual C++ 2015 Conformance Changes // https://msdn.microsoft.com/en-us/library/bb531344.aspx - try ctx.args.append(c"legacy_stdio_definitions.lib"); + try ctx.args.append("legacy_stdio_definitions.lib"); // msvcrt depends on kernel32 - try ctx.args.append(c"kernel32.lib"); + try ctx.args.append("kernel32.lib"); } else { - try ctx.args.append(c"-NODEFAULTLIB"); + try ctx.args.append("-NODEFAULTLIB"); if (!is_library) { - try ctx.args.append(c"-ENTRY:WinMainCRTStartup"); + try ctx.args.append("-ENTRY:WinMainCRTStartup"); // TODO //if (g->have_winmain) { // lj->args.append("-ENTRY:WinMain"); @@ -385,7 +385,7 @@ fn constructLinkerArgsCoff(ctx: *Context) !void { } if (is_library and !ctx.comp.is_static) { - try ctx.args.append(c"-DLL"); + try ctx.args.append("-DLL"); } //for (size_t i = 0; i < g->lib_dirs.length; i += 1) { @@ -463,18 +463,18 @@ fn constructLinkerArgsCoff(ctx: *Context) !void { } fn constructLinkerArgsMachO(ctx: *Context) !void { - try ctx.args.append(c"-demangle"); + try ctx.args.append("-demangle"); if (ctx.comp.linker_rdynamic) { - try ctx.args.append(c"-export_dynamic"); + try ctx.args.append("-export_dynamic"); } const is_lib = ctx.comp.kind == Compilation.Kind.Lib; const shared = !ctx.comp.is_static and is_lib; if (ctx.comp.is_static) { - try ctx.args.append(c"-static"); + try ctx.args.append("-static"); } else { - try ctx.args.append(c"-dynamic"); + try ctx.args.append("-dynamic"); } //if (is_lib) { @@ -503,7 +503,7 @@ fn constructLinkerArgsMachO(ctx: *Context) !void { // } //} - try ctx.args.append(c"-arch"); + try ctx.args.append("-arch"); const darwin_arch_str = try std.cstr.addNullByte( &ctx.arena.allocator, ctx.comp.target.getDarwinArchString(), @@ -512,22 +512,22 @@ fn constructLinkerArgsMachO(ctx: *Context) !void { const platform = try DarwinPlatform.get(ctx.comp); switch (platform.kind) { - DarwinPlatform.Kind.MacOS => try ctx.args.append(c"-macosx_version_min"), - DarwinPlatform.Kind.IPhoneOS => try ctx.args.append(c"-iphoneos_version_min"), - DarwinPlatform.Kind.IPhoneOSSimulator => try ctx.args.append(c"-ios_simulator_version_min"), + DarwinPlatform.Kind.MacOS => try ctx.args.append("-macosx_version_min"), + DarwinPlatform.Kind.IPhoneOS => try ctx.args.append("-iphoneos_version_min"), + DarwinPlatform.Kind.IPhoneOSSimulator => try ctx.args.append("-ios_simulator_version_min"), } const ver_str = try std.fmt.allocPrint(&ctx.arena.allocator, "{}.{}.{}\x00", platform.major, platform.minor, platform.micro); try ctx.args.append(ver_str.ptr); if (ctx.comp.kind == Compilation.Kind.Exe) { if (ctx.comp.is_static) { - try ctx.args.append(c"-no_pie"); + try ctx.args.append("-no_pie"); } else { - try ctx.args.append(c"-pie"); + try ctx.args.append("-pie"); } } - try ctx.args.append(c"-o"); + try ctx.args.append("-o"); try ctx.args.append(ctx.out_file_path.ptr()); //for (size_t i = 0; i < g->rpath_list.length; i += 1) { @@ -537,27 +537,27 @@ fn constructLinkerArgsMachO(ctx: *Context) !void { //add_rpath(lj, &lj->out_file); if (shared) { - try ctx.args.append(c"-headerpad_max_install_names"); + try ctx.args.append("-headerpad_max_install_names"); } else if (ctx.comp.is_static) { - try ctx.args.append(c"-lcrt0.o"); + try ctx.args.append("-lcrt0.o"); } else { switch (platform.kind) { DarwinPlatform.Kind.MacOS => { if (platform.versionLessThan(10, 5)) { - try ctx.args.append(c"-lcrt1.o"); + try ctx.args.append("-lcrt1.o"); } else if (platform.versionLessThan(10, 6)) { - try ctx.args.append(c"-lcrt1.10.5.o"); + try ctx.args.append("-lcrt1.10.5.o"); } else if (platform.versionLessThan(10, 8)) { - try ctx.args.append(c"-lcrt1.10.6.o"); + try ctx.args.append("-lcrt1.10.6.o"); } }, DarwinPlatform.Kind.IPhoneOS => { if (ctx.comp.target.getArch() == builtin.Arch.aarch64) { // iOS does not need any crt1 files for arm64 } else if (platform.versionLessThan(3, 1)) { - try ctx.args.append(c"-lcrt1.o"); + try ctx.args.append("-lcrt1.o"); } else if (platform.versionLessThan(6, 0)) { - try ctx.args.append(c"-lcrt1.3.1.o"); + try ctx.args.append("-lcrt1.3.1.o"); } }, DarwinPlatform.Kind.IPhoneOSSimulator => {}, // no crt1.o needed @@ -589,7 +589,7 @@ fn constructLinkerArgsMachO(ctx: *Context) !void { // to make syscalls because the syscall numbers are not documented // and change between versions. // so we always link against libSystem - try ctx.args.append(c"-lSystem"); + try ctx.args.append("-lSystem"); } else { if (mem.indexOfScalar(u8, lib.name, '/') == null) { const arg = try std.fmt.allocPrint(&ctx.arena.allocator, "-l{}\x00", lib.name); @@ -601,15 +601,15 @@ fn constructLinkerArgsMachO(ctx: *Context) !void { } } } else { - try ctx.args.append(c"-undefined"); - try ctx.args.append(c"dynamic_lookup"); + try ctx.args.append("-undefined"); + try ctx.args.append("dynamic_lookup"); } if (platform.kind == DarwinPlatform.Kind.MacOS) { if (platform.versionLessThan(10, 5)) { - try ctx.args.append(c"-lgcc_s.10.4"); + try ctx.args.append("-lgcc_s.10.4"); } else if (platform.versionLessThan(10, 6)) { - try ctx.args.append(c"-lgcc_s.10.5"); + try ctx.args.append("-lgcc_s.10.5"); } } else { @panic("TODO"); diff --git a/src-self-hosted/stage1.zig b/src-self-hosted/stage1.zig index 37945bf029..49ad23a19d 100644 --- a/src-self-hosted/stage1.zig +++ b/src-self-hosted/stage1.zig @@ -28,7 +28,7 @@ comptime { // ABI warning export fn stage2_zen(ptr: *[*]const u8, len: *usize) void { const info_zen = @import("main.zig").info_zen; - ptr.* = &info_zen; + ptr.* = info_zen; len.* = info_zen.len; } diff --git a/src-self-hosted/value.zig b/src-self-hosted/value.zig index 6908307c56..63aefbe717 100644 --- a/src-self-hosted/value.zig +++ b/src-self-hosted/value.zig @@ -474,7 +474,7 @@ pub const Value = struct { dont_null_terminate, ) orelse return error.OutOfMemory; const str_init_type = llvm.TypeOf(llvm_str_init); - const global = llvm.AddGlobal(ofile.module, str_init_type, c"") orelse return error.OutOfMemory; + const global = llvm.AddGlobal(ofile.module, str_init_type, "") orelse return error.OutOfMemory; llvm.SetInitializer(global, llvm_str_init); llvm.SetLinkage(global, llvm.PrivateLinkage); llvm.SetGlobalConstant(global, 1); diff --git a/src/all_types.hpp b/src/all_types.hpp index 0fe43eaa3e..4047a7d4a5 100644 --- a/src/all_types.hpp +++ b/src/all_types.hpp @@ -102,6 +102,10 @@ struct IrExecutable { bool is_inline; bool is_generic_instantiation; bool need_err_code_spill; + + // This is a function for use in the debugger to print + // the source location. + void src(); }; enum OutType { @@ -237,9 +241,6 @@ struct ConstPtrValue { struct { ConstExprValue *array_val; size_t elem_index; - // This helps us preserve the null byte when performing compile-time - // concatenation on C strings. - bool is_cstr; } base_array; struct { ConstExprValue *struct_val; @@ -1001,7 +1002,6 @@ struct AstNodeStructField { struct AstNodeStringLiteral { Buf *buf; - bool c; }; struct AstNodeCharLiteral { @@ -1956,6 +1956,7 @@ struct CodeGen { HashMap external_prototypes; HashMap string_literals_table; HashMap type_info_cache; + HashMap one_possible_values; ZigList resolve_queue; size_t resolve_queue_index; diff --git a/src/analyze.cpp b/src/analyze.cpp index f67c4a035e..9c42177d11 100644 --- a/src/analyze.cpp +++ b/src/analyze.cpp @@ -767,10 +767,18 @@ ZigType *get_array_type(CodeGen *g, ZigType *child_type, uint64_t array_size, bo ZigType *entry = new_type_table_entry(ZigTypeIdArray); - buf_resize(&entry->name, 0); - buf_appendf(&entry->name, "[%" ZIG_PRI_u64 "]%s", array_size, buf_ptr(&child_type->name)); + const char *null_str = is_null_terminated ? "null " : ""; + + buf_resize(&entry->name, 0); + buf_appendf(&entry->name, "[%" ZIG_PRI_u64 "]%s%s", array_size, null_str, buf_ptr(&child_type->name)); + + size_t full_array_size; + if (array_size == 0) { + full_array_size = 0; + } else { + full_array_size = array_size + (is_null_terminated ? 1 : 0); + } - size_t full_array_size = array_size + (is_null_terminated ? 1 : 0); entry->size_in_bits = child_type->size_in_bits * full_array_size; entry->abi_align = child_type->abi_align; entry->abi_size = child_type->abi_size * full_array_size; @@ -5046,7 +5054,6 @@ static uint32_t hash_const_val_ptr(ConstExprValue *const_val) { hash_val += (uint32_t)1764906839; hash_val += hash_ptr(const_val->data.x_ptr.data.base_array.array_val); hash_val += hash_size(const_val->data.x_ptr.data.base_array.elem_index); - hash_val += const_val->data.x_ptr.data.base_array.is_cstr ? 1297263887 : 200363492; return hash_val; case ConstPtrSpecialBaseStruct: hash_val += (uint32_t)3518317043; @@ -5550,6 +5557,18 @@ OnePossibleValue type_has_one_possible_value(CodeGen *g, ZigType *type_entry) { zig_unreachable(); } +ConstExprValue *get_the_one_possible_value(CodeGen *g, ZigType *type_entry) { + auto entry = g->one_possible_values.maybe_get(type_entry); + if (entry != nullptr) { + return entry->value; + } + ConstExprValue *result = create_const_vals(1); + result->type = type_entry; + result->special = ConstValSpecialStatic; + g->one_possible_values.put(type_entry, result); + return result; +} + ReqCompTime type_requires_comptime(CodeGen *g, ZigType *ty) { Error err; switch (ty->id) { @@ -5617,10 +5636,19 @@ void init_const_str_lit(CodeGen *g, ConstExprValue *const_val, Buf *str) { return; } + // first we build the underlying array + ConstExprValue *array_val = create_const_vals(1); + array_val->special = ConstValSpecialStatic; + array_val->type = get_array_type(g, g->builtin_types.entry_u8, buf_len(str), true); + array_val->data.x_array.special = ConstArraySpecialBuf; + array_val->data.x_array.data.s_buf = str; + + // then make the pointer point to it const_val->special = ConstValSpecialStatic; - const_val->type = get_array_type(g, g->builtin_types.entry_u8, buf_len(str), false); - const_val->data.x_array.special = ConstArraySpecialBuf; - const_val->data.x_array.data.s_buf = str; + const_val->type = get_pointer_to_type_extra2(g, array_val->type, true, false, + PtrLenSingle, 0, 0, 0, false, VECTOR_INDEX_NONE, nullptr); + const_val->data.x_ptr.special = ConstPtrSpecialRef; + const_val->data.x_ptr.data.ref.pointee = array_val; g->string_literals_table.put(str, const_val); } @@ -5631,41 +5659,6 @@ ConstExprValue *create_const_str_lit(CodeGen *g, Buf *str) { return const_val; } -void init_const_c_str_lit(CodeGen *g, ConstExprValue *const_val, Buf *str) { - // first we build the underlying array - size_t len_with_null = buf_len(str) + 1; - ConstExprValue *array_val = create_const_vals(1); - array_val->special = ConstValSpecialStatic; - array_val->type = get_array_type(g, g->builtin_types.entry_u8, len_with_null, false); - // TODO buf optimization - array_val->data.x_array.data.s_none.elements = create_const_vals(len_with_null); - for (size_t i = 0; i < buf_len(str); i += 1) { - ConstExprValue *this_char = &array_val->data.x_array.data.s_none.elements[i]; - this_char->special = ConstValSpecialStatic; - this_char->type = g->builtin_types.entry_u8; - bigint_init_unsigned(&this_char->data.x_bigint, (uint8_t)buf_ptr(str)[i]); - } - ConstExprValue *null_char = &array_val->data.x_array.data.s_none.elements[len_with_null - 1]; - null_char->special = ConstValSpecialStatic; - null_char->type = g->builtin_types.entry_u8; - bigint_init_unsigned(&null_char->data.x_bigint, 0); - - // then make the pointer point to it - const_val->special = ConstValSpecialStatic; - // TODO make this `[*]null u8` instead of `[*]u8` - const_val->type = get_pointer_to_type_extra(g, g->builtin_types.entry_u8, true, false, - PtrLenUnknown, 0, 0, 0, false); - const_val->data.x_ptr.special = ConstPtrSpecialBaseArray; - const_val->data.x_ptr.data.base_array.array_val = array_val; - const_val->data.x_ptr.data.base_array.elem_index = 0; - const_val->data.x_ptr.data.base_array.is_cstr = true; -} -ConstExprValue *create_const_c_str_lit(CodeGen *g, Buf *str) { - ConstExprValue *const_val = create_const_vals(1); - init_const_c_str_lit(g, const_val, str); - return const_val; -} - void init_const_bigint(ConstExprValue *const_val, ZigType *type, const BigInt *bigint) { const_val->special = ConstValSpecialStatic; const_val->type = type; @@ -5712,6 +5705,18 @@ ConstExprValue *create_const_signed(ZigType *type, int64_t x) { return const_val; } +void init_const_null(ConstExprValue *const_val, ZigType *type) { + const_val->special = ConstValSpecialStatic; + const_val->type = type; + const_val->data.x_optional = nullptr; +} + +ConstExprValue *create_const_null(ZigType *type) { + ConstExprValue *const_val = create_const_vals(1); + init_const_null(const_val, type); + return const_val; +} + void init_const_float(ConstExprValue *const_val, ZigType *type, double value) { const_val->special = ConstValSpecialStatic; const_val->type = type; @@ -6446,8 +6451,6 @@ bool ir_get_var_is_comptime(ZigVar *var) { bool const_values_equal_ptr(ConstExprValue *a, ConstExprValue *b) { if (a->data.x_ptr.special != b->data.x_ptr.special) return false; - if (a->data.x_ptr.mut != b->data.x_ptr.mut) - return false; switch (a->data.x_ptr.special) { case ConstPtrSpecialInvalid: zig_unreachable(); @@ -6464,8 +6467,6 @@ bool const_values_equal_ptr(ConstExprValue *a, ConstExprValue *b) { } if (a->data.x_ptr.data.base_array.elem_index != b->data.x_ptr.data.base_array.elem_index) return false; - if (a->data.x_ptr.data.base_array.is_cstr != b->data.x_ptr.data.base_array.is_cstr) - return false; return true; case ConstPtrSpecialBaseStruct: if (a->data.x_ptr.data.base_struct.struct_val != b->data.x_ptr.data.base_struct.struct_val && @@ -6544,6 +6545,16 @@ bool const_values_equal(CodeGen *g, ConstExprValue *a, ConstExprValue *b) { assert(a->type->id == b->type->id); assert(a->special == ConstValSpecialStatic); assert(b->special == ConstValSpecialStatic); + if (a->type == b->type) { + switch (type_has_one_possible_value(g, a->type)) { + case OnePossibleValueInvalid: + zig_unreachable(); + case OnePossibleValueNo: + break; + case OnePossibleValueYes: + return true; + } + } switch (a->type->id) { case ZigTypeIdOpaque: zig_unreachable(); @@ -6709,15 +6720,10 @@ static void render_const_val_ptr(CodeGen *g, Buf *buf, ConstExprValue *const_val render_const_value(g, buf, const_ptr_pointee(nullptr, g, const_val, nullptr)); return; case ConstPtrSpecialBaseArray: - if (const_val->data.x_ptr.data.base_array.is_cstr) { - buf_appendf(buf, "*(c str lit)"); - return; - } else { - buf_appendf(buf, "*"); - // TODO we need a source node for const_ptr_pointee because it can generate compile errors - render_const_value(g, buf, const_ptr_pointee(nullptr, g, const_val, nullptr)); - return; - } + buf_appendf(buf, "*"); + // TODO we need a source node for const_ptr_pointee because it can generate compile errors + render_const_value(g, buf, const_ptr_pointee(nullptr, g, const_val, nullptr)); + return; case ConstPtrSpecialHardCodedAddr: buf_appendf(buf, "(%s)(%" ZIG_PRI_x64 ")", buf_ptr(&type_entry->name), const_val->data.x_ptr.data.hard_coded_addr.addr); @@ -8653,14 +8659,16 @@ static void resolve_llvm_types_array(CodeGen *g, ZigType *type) { ZigType *elem_type = type->data.array.child_type; + uint64_t extra_len_from_null = type->data.array.is_null_terminated ? 1 : 0; + uint64_t full_len = type->data.array.len + extra_len_from_null; // TODO https://github.com/ziglang/zig/issues/1424 - type->llvm_type = LLVMArrayType(get_llvm_type(g, elem_type), (unsigned)type->data.array.len); + type->llvm_type = LLVMArrayType(get_llvm_type(g, elem_type), (unsigned)full_len); uint64_t debug_size_in_bits = 8*LLVMStoreSizeOfType(g->target_data_ref, type->llvm_type); uint64_t debug_align_in_bits = 8*LLVMABISizeOfType(g->target_data_ref, type->llvm_type); type->llvm_di_type = ZigLLVMCreateDebugArrayType(g->dbuilder, debug_size_in_bits, - debug_align_in_bits, get_llvm_di_type(g, elem_type), (int)type->data.array.len); + debug_align_in_bits, get_llvm_di_type(g, elem_type), (int)full_len); } static void resolve_llvm_types_fn_type(CodeGen *g, ZigType *fn_type) { @@ -9150,3 +9158,24 @@ Error analyze_import(CodeGen *g, ZigType *source_import, Buf *import_target_str, *out_import = add_source_file(g, target_package, resolved_path, import_code, source_kind); return ErrorNone; } + + +void IrExecutable::src() { + IrExecutable *it; + for (it = this; it != nullptr && it->source_node != nullptr; it = it->parent_exec) { + it->source_node->src(); + } +} + +ConstExprValue *get_null_value(ZigType *ty) { + if (ty->id == ZigTypeIdInt || ty->id == ZigTypeIdComptimeInt) { + return create_const_unsigned_negative(ty, 0, false); + } else if (ty->id == ZigTypeIdFloat || ty->id == ZigTypeIdComptimeFloat) { + return create_const_float(ty, NAN); + } else if (ty->id == ZigTypeIdOptional) { + return create_const_null(ty); + } else { + zig_unreachable(); + } +} + diff --git a/src/analyze.hpp b/src/analyze.hpp index a1e38a43d7..a3d4621178 100644 --- a/src/analyze.hpp +++ b/src/analyze.hpp @@ -126,9 +126,6 @@ ScopeExpr *create_expr_scope(CodeGen *g, AstNode *node, Scope *parent); void init_const_str_lit(CodeGen *g, ConstExprValue *const_val, Buf *str); ConstExprValue *create_const_str_lit(CodeGen *g, Buf *str); -void init_const_c_str_lit(CodeGen *g, ConstExprValue *const_val, Buf *c_str); -ConstExprValue *create_const_c_str_lit(CodeGen *g, Buf *c_str); - void init_const_bigint(ConstExprValue *const_val, ZigType *type, const BigInt *bigint); ConstExprValue *create_const_bigint(ZigType *type, const BigInt *bigint); @@ -176,6 +173,9 @@ ConstExprValue *create_const_slice(CodeGen *g, ConstExprValue *array_val, size_t void init_const_arg_tuple(CodeGen *g, ConstExprValue *const_val, size_t arg_index_start, size_t arg_index_end); ConstExprValue *create_const_arg_tuple(CodeGen *g, size_t arg_index_start, size_t arg_index_end); +void init_const_null(ConstExprValue *const_val, ZigType *type); +ConstExprValue *create_const_null(ZigType *type); + ConstExprValue *create_const_vals(size_t count); ConstExprValue **alloc_const_vals_ptrs(size_t count); ConstExprValue **realloc_const_vals_ptrs(ConstExprValue **ptr, size_t old_count, size_t new_count); @@ -275,5 +275,6 @@ IrInstruction *ir_create_alloca(CodeGen *g, Scope *scope, AstNode *source_node, ZigType *var_type, const char *name_hint); Error analyze_import(CodeGen *codegen, ZigType *source_import, Buf *import_target_str, ZigType **out_import, Buf **out_import_target_path, Buf *out_full_path); - +ConstExprValue *get_the_one_possible_value(CodeGen *g, ZigType *type_entry); +ConstExprValue *get_null_value(ZigType *ty); #endif diff --git a/src/ast_render.cpp b/src/ast_render.cpp index 34cbed245a..53388fa033 100644 --- a/src/ast_render.cpp +++ b/src/ast_render.cpp @@ -619,9 +619,6 @@ static void render_node_extra(AstRender *ar, AstNode *node, bool grouped) { break; case NodeTypeStringLiteral: { - if (node->data.string_literal.c) { - fprintf(ar->f, "c"); - } Buf tmp_buf = BUF_INIT; string_literal_escape(node->data.string_literal.buf, &tmp_buf); fprintf(ar->f, "\"%s\"", buf_ptr(&tmp_buf)); diff --git a/src/codegen.cpp b/src/codegen.cpp index 5def04575e..4fc3b968c1 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -949,7 +949,7 @@ static LLVMValueRef get_panic_msg_ptr_val(CodeGen *g, PanicMsgId msg_id) { if (!val->global_refs->llvm_global) { Buf *buf_msg = panic_msg_buf(msg_id); - ConstExprValue *array_val = create_const_str_lit(g, buf_msg); + ConstExprValue *array_val = create_const_str_lit(g, buf_msg)->data.x_ptr.data.ref.pointee; init_const_slice(g, val, array_val, 0, buf_len(buf_msg), true); render_const_val(g, val, ""); @@ -2784,14 +2784,6 @@ static LLVMValueRef ir_render_bin_op(CodeGen *g, IrExecutable *executable, IrInstruction *op1 = bin_op_instruction->op1; IrInstruction *op2 = bin_op_instruction->op2; - assert(op1->value.type == op2->value.type || op_id == IrBinOpBitShiftLeftLossy || - op_id == IrBinOpBitShiftLeftExact || op_id == IrBinOpBitShiftRightLossy || - op_id == IrBinOpBitShiftRightExact || - (op1->value.type->id == ZigTypeIdErrorSet && op2->value.type->id == ZigTypeIdErrorSet) || - (op1->value.type->id == ZigTypeIdPointer && - (op_id == IrBinOpAdd || op_id == IrBinOpSub) && - op1->value.type->data.pointer.ptr_len != PtrLenSingle) - ); ZigType *operand_type = op1->value.type; ZigType *scalar_type = (operand_type->id == ZigTypeIdVector) ? operand_type->data.vector.elem_type : operand_type; @@ -2848,7 +2840,6 @@ static LLVMValueRef ir_render_bin_op(CodeGen *g, IrExecutable *executable, AddSubMulMul; if (scalar_type->id == ZigTypeIdPointer) { - assert(scalar_type->data.pointer.ptr_len != PtrLenSingle); LLVMValueRef subscript_value; if (operand_type->id == ZigTypeIdVector) zig_panic("TODO: Implement vector operations on pointers."); @@ -3077,7 +3068,14 @@ static LLVMValueRef ir_render_cast(CodeGen *g, IrExecutable *executable, case CastOpNumLitToConcrete: zig_unreachable(); case CastOpNoop: - return expr_val; + if (actual_type->id == ZigTypeIdPointer && wanted_type->id == ZigTypeIdPointer && + actual_type->data.pointer.child_type->id == ZigTypeIdArray && + wanted_type->data.pointer.child_type->id == ZigTypeIdArray) + { + return LLVMBuildBitCast(g->builder, expr_val, get_llvm_type(g, wanted_type), ""); + } else { + return expr_val; + } case CastOpIntToFloat: assert(actual_type->id == ZigTypeIdInt); if (actual_type->data.integral.is_signed) { @@ -3709,8 +3707,9 @@ static LLVMValueRef ir_render_elem_ptr(CodeGen *g, IrExecutable *executable, IrI array_type = array_type->data.pointer.child_type; } if (safety_check_on) { - LLVMValueRef end = LLVMConstInt(g->builtin_types.entry_usize->llvm_type, - array_type->data.array.len, false); + uint64_t extra_len_from_null = array_type->data.array.is_null_terminated ? 1 : 0; + uint64_t full_len = array_type->data.array.len + extra_len_from_null; + LLVMValueRef end = LLVMConstInt(g->builtin_types.entry_usize->llvm_type, full_len, false); add_bounds_check(g, subscript_value, LLVMIntEQ, nullptr, LLVMIntULT, end); } if (array_ptr_type->data.pointer.host_int_bytes != 0) { @@ -6637,11 +6636,20 @@ static LLVMValueRef gen_const_val_ptr(CodeGen *g, ConstExprValue *const_val, con ConstExprValue *array_const_val = const_val->data.x_ptr.data.base_array.array_val; assert(array_const_val->type->id == ZigTypeIdArray); if (!type_has_bits(array_const_val->type)) { - // make this a null pointer - ZigType *usize = g->builtin_types.entry_usize; - const_val->global_refs->llvm_value = LLVMConstIntToPtr(LLVMConstNull(usize->llvm_type), - get_llvm_type(g, const_val->type)); - return const_val->global_refs->llvm_value; + if (array_const_val->type->data.array.is_null_terminated) { + ConstExprValue *pointee = get_null_value(array_const_val->type->data.array.child_type); + render_const_val(g, pointee, ""); + render_const_val_global(g, pointee, ""); + const_val->global_refs->llvm_value = LLVMConstBitCast(pointee->global_refs->llvm_global, + get_llvm_type(g, const_val->type)); + return const_val->global_refs->llvm_value; + } else { + // make this a null pointer + ZigType *usize = g->builtin_types.entry_usize; + const_val->global_refs->llvm_value = LLVMConstIntToPtr(LLVMConstNull(usize->llvm_type), + get_llvm_type(g, const_val->type)); + return const_val->global_refs->llvm_value; + } } size_t elem_index = const_val->data.x_ptr.data.base_array.elem_index; LLVMValueRef uncasted_ptr_val = gen_const_ptr_array_recursive(g, array_const_val, elem_index); @@ -6955,7 +6963,9 @@ check: switch (const_val->special) { case ConstArraySpecialUndef: return LLVMGetUndef(get_llvm_type(g, type_entry)); case ConstArraySpecialNone: { - LLVMValueRef *values = allocate(len); + uint64_t extra_len_from_null = type_entry->data.array.is_null_terminated ? 1 : 0; + uint64_t full_len = len + extra_len_from_null; + LLVMValueRef *values = allocate(full_len); LLVMTypeRef element_type_ref = get_llvm_type(g, type_entry->data.array.child_type); bool make_unnamed_struct = false; for (uint64_t i = 0; i < len; i += 1) { @@ -6964,15 +6974,19 @@ check: switch (const_val->special) { values[i] = val; make_unnamed_struct = make_unnamed_struct || is_llvm_value_unnamed_type(g, elem_value->type, val); } + if (type_entry->data.array.is_null_terminated) { + values[len] = LLVMConstNull(element_type_ref); + } if (make_unnamed_struct) { - return LLVMConstStruct(values, len, true); + return LLVMConstStruct(values, full_len, true); } else { - return LLVMConstArray(element_type_ref, values, (unsigned)len); + return LLVMConstArray(element_type_ref, values, (unsigned)full_len); } } case ConstArraySpecialBuf: { Buf *buf = const_val->data.x_array.data.s_buf; - return LLVMConstString(buf_ptr(buf), (unsigned)buf_len(buf), true); + return LLVMConstString(buf_ptr(buf), (unsigned)buf_len(buf), + !type_entry->data.array.is_null_terminated); } } zig_unreachable(); @@ -9092,7 +9106,7 @@ static void create_test_compile_var_and_add_test_runner(CodeGen *g) { this_val->data.x_struct.fields = alloc_const_vals_ptrs(2); ConstExprValue *name_field = this_val->data.x_struct.fields[0]; - ConstExprValue *name_array_val = create_const_str_lit(g, &test_fn_entry->symbol_name); + ConstExprValue *name_array_val = create_const_str_lit(g, &test_fn_entry->symbol_name)->data.x_ptr.data.ref.pointee; init_const_slice(g, name_field, name_array_val, 0, buf_len(&test_fn_entry->symbol_name), true); ConstExprValue *fn_field = this_val->data.x_struct.fields[1]; @@ -10415,6 +10429,7 @@ CodeGen *codegen_create(Buf *main_pkg_path, Buf *root_src_path, const ZigTarget g->external_prototypes.init(8); g->string_literals_table.init(16); g->type_info_cache.init(32); + g->one_possible_values.init(32); g->is_test_build = is_test_build; g->is_single_threaded = false; buf_resize(&g->global_asm, 0); diff --git a/src/ir.cpp b/src/ir.cpp index c910d4800d..4a3d89c0c1 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -66,6 +66,8 @@ enum ConstCastResultId { ConstCastResultIdUnresolvedInferredErrSet, ConstCastResultIdAsyncAllocatorType, ConstCastResultIdBadAllowsZero, + ConstCastResultIdArrayChild, + ConstCastResultIdBadNullTermArrays, }; struct ConstCastOnly; @@ -87,7 +89,9 @@ struct ConstCastErrUnionErrSetMismatch; struct ConstCastErrUnionPayloadMismatch; struct ConstCastErrSetMismatch; struct ConstCastTypeMismatch; +struct ConstCastArrayMismatch; struct ConstCastBadAllowsZero; +struct ConstCastBadNullTermArrays; struct ConstCastOnly { ConstCastResultId id; @@ -99,11 +103,13 @@ struct ConstCastOnly { ConstCastErrUnionPayloadMismatch *error_union_payload; ConstCastErrUnionErrSetMismatch *error_union_error_set; ConstCastTypeMismatch *type_mismatch; + ConstCastArrayMismatch *array_mismatch; ConstCastOnly *return_type; ConstCastOnly *null_wrap_ptr_child; ConstCastArg fn_arg; ConstCastArgNoAlias arg_no_alias; ConstCastBadAllowsZero *bad_allows_zero; + ConstCastBadNullTermArrays *bad_null_term_arrays; } data; }; @@ -130,6 +136,12 @@ struct ConstCastSliceMismatch { ZigType *actual_child; }; +struct ConstCastArrayMismatch { + ConstCastOnly child; + ZigType *wanted_child; + ZigType *actual_child; +}; + struct ConstCastErrUnionErrSetMismatch { ConstCastOnly child; ZigType *wanted_err_set; @@ -151,6 +163,12 @@ struct ConstCastBadAllowsZero { ZigType *actual_type; }; +struct ConstCastBadNullTermArrays { + ConstCastOnly child; + ZigType *wanted_type; + ZigType *actual_type; +}; + static IrInstruction *ir_gen_node(IrBuilder *irb, AstNode *node, Scope *scope); static IrInstruction *ir_gen_node_extra(IrBuilder *irb, AstNode *node, Scope *scope, LVal lval, @@ -217,10 +235,7 @@ static ConstExprValue *const_ptr_pointee_unchecked(CodeGen *g, ConstExprValue *c case OnePossibleValueInvalid: zig_unreachable(); case OnePossibleValueYes: - result = create_const_vals(1); - result->type = const_val->type->data.pointer.child_type; - result->special = ConstValSpecialStatic; - return result; + return get_the_one_possible_value(g, const_val->type->data.pointer.child_type); case OnePossibleValueNo: break; } @@ -233,8 +248,13 @@ static ConstExprValue *const_ptr_pointee_unchecked(CodeGen *g, ConstExprValue *c break; case ConstPtrSpecialBaseArray: { ConstExprValue *array_val = const_val->data.x_ptr.data.base_array.array_val; - expand_undef_array(g, array_val); - result = &array_val->data.x_array.data.s_none.elements[const_val->data.x_ptr.data.base_array.elem_index]; + if (const_val->data.x_ptr.data.base_array.elem_index == array_val->type->data.array.len) { + assert(array_val->type->data.array.is_null_terminated); + result = get_null_value(array_val->type->data.array.child_type); + } else { + expand_undef_array(g, array_val); + result = &array_val->data.x_array.data.s_none.elements[const_val->data.x_ptr.data.base_array.elem_index]; + } break; } case ConstPtrSpecialBaseStruct: { @@ -282,20 +302,20 @@ static bool slice_is_const(ZigType *type) { // This function returns true when you can change the type of a ConstExprValue and the // value remains meaningful. -static bool types_have_same_zig_comptime_repr(ZigType *a, ZigType *b) { - if (a == b) +static bool types_have_same_zig_comptime_repr(ZigType *expected, ZigType *actual) { + if (expected == actual) return true; - if (get_codegen_ptr_type(a) != nullptr && get_codegen_ptr_type(b) != nullptr) + if (get_codegen_ptr_type(expected) != nullptr && get_codegen_ptr_type(actual) != nullptr) return true; - if (is_opt_err_set(a) && is_opt_err_set(b)) + if (is_opt_err_set(expected) && is_opt_err_set(actual)) return true; - if (a->id != b->id) + if (expected->id != actual->id) return false; - switch (a->id) { + switch (expected->id) { case ZigTypeIdInvalid: case ZigTypeIdUnreachable: zig_unreachable(); @@ -314,12 +334,11 @@ static bool types_have_same_zig_comptime_repr(ZigType *a, ZigType *b) { case ZigTypeIdAnyFrame: return true; case ZigTypeIdFloat: - return a->data.floating.bit_count == b->data.floating.bit_count; + return expected->data.floating.bit_count == actual->data.floating.bit_count; case ZigTypeIdInt: - return a->data.integral.is_signed == b->data.integral.is_signed; + return expected->data.integral.is_signed == actual->data.integral.is_signed; case ZigTypeIdStruct: - return is_slice(a) && is_slice(b); - case ZigTypeIdArray: + return is_slice(expected) && is_slice(actual); case ZigTypeIdOptional: case ZigTypeIdErrorUnion: case ZigTypeIdEnum: @@ -329,6 +348,10 @@ static bool types_have_same_zig_comptime_repr(ZigType *a, ZigType *b) { case ZigTypeIdVector: case ZigTypeIdFnFrame: return false; + case ZigTypeIdArray: + return expected->data.array.len == actual->data.array.len && + expected->data.array.child_type == actual->data.array.child_type && + (!expected->data.array.is_null_terminated || actual->data.array.is_null_terminated); } zig_unreachable(); } @@ -1299,12 +1322,6 @@ static IrInstruction *ir_build_const_str_lit(IrBuilder *irb, Scope *scope, AstNo return instruction; } -static IrInstruction *ir_build_const_c_str_lit(IrBuilder *irb, Scope *scope, AstNode *source_node, Buf *str) { - IrInstructionConst *const_instruction = ir_build_instruction(irb, scope, source_node); - init_const_c_str_lit(irb->codegen, &const_instruction->base.value, str); - return &const_instruction->base; -} - static IrInstruction *ir_build_bin_op(IrBuilder *irb, Scope *scope, AstNode *source_node, IrBinOp op_id, IrInstruction *op1, IrInstruction *op2, bool safety_check_on) { @@ -6932,11 +6949,7 @@ static IrInstruction *ir_gen_enum_literal(IrBuilder *irb, Scope *scope, AstNode static IrInstruction *ir_gen_string_literal(IrBuilder *irb, Scope *scope, AstNode *node) { assert(node->type == NodeTypeStringLiteral); - if (node->data.string_literal.c) { - return ir_build_const_c_str_lit(irb, scope, node, node->data.string_literal.buf); - } else { - return ir_build_const_str_lit(irb, scope, node, node->data.string_literal.buf); - } + return ir_build_const_str_lit(irb, scope, node, node->data.string_literal.buf); } static IrInstruction *ir_gen_array_type(IrBuilder *irb, Scope *scope, AstNode *node) { @@ -8662,7 +8675,15 @@ ConstExprValue *const_ptr_pointee(IrAnalyze *ira, CodeGen *codegen, ConstExprVal assert(val != nullptr); assert(const_val->type->id == ZigTypeIdPointer); ZigType *expected_type = const_val->type->data.pointer.child_type; - if (!types_have_same_zig_comptime_repr(val->type, expected_type)) { + switch (type_has_one_possible_value(codegen, expected_type)) { + case OnePossibleValueInvalid: + return nullptr; + case OnePossibleValueNo: + break; + case OnePossibleValueYes: + return get_the_one_possible_value(codegen, expected_type); + } + if (!types_have_same_zig_comptime_repr(expected_type, val->type)) { if ((err = eval_comptime_ptr_reinterpret(ira, codegen, source_node, const_val))) return nullptr; return const_ptr_pointee_unchecked(codegen, const_val); @@ -9876,6 +9897,35 @@ static ConstCastOnly types_match_const_cast_only(IrAnalyze *ira, ZigType *wanted } } + // arrays + if (wanted_type->id == ZigTypeIdArray && actual_type->id == ZigTypeIdArray && + wanted_type->data.array.len == actual_type->data.array.len) + { + ConstCastOnly child = types_match_const_cast_only(ira, wanted_type->data.array.child_type, + actual_type->data.array.child_type, source_node, wanted_is_mutable); + if (child.id == ConstCastResultIdInvalid) + return child; + if (child.id != ConstCastResultIdOk) { + result.id = ConstCastResultIdArrayChild; + result.data.array_mismatch = allocate_nonzero(1); + result.data.array_mismatch->child = child; + result.data.array_mismatch->wanted_child = wanted_type->data.array.child_type; + result.data.array_mismatch->actual_child = actual_type->data.array.child_type; + return result; + } + bool ok_null_terminated = !wanted_type->data.array.is_null_terminated || + actual_type->data.array.is_null_terminated; + if (!ok_null_terminated) { + result.id = ConstCastResultIdBadNullTermArrays; + result.data.bad_null_term_arrays = allocate_nonzero(1); + result.data.bad_null_term_arrays->child = child; + result.data.bad_null_term_arrays->wanted_type = wanted_type; + result.data.bad_null_term_arrays->actual_type = actual_type; + return result; + } + return result; + } + // slice const if (is_slice(wanted_type) && is_slice(actual_type)) { ZigType *actual_ptr_type = actual_type->data.structure.fields[slice_ptr_index]->type_entry; @@ -10692,6 +10742,42 @@ static ZigType *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_node, ZigT continue; } + + // *[N]T and *[M]T + if (cur_type->id == ZigTypeIdPointer && cur_type->data.pointer.ptr_len == PtrLenSingle && + cur_type->data.pointer.child_type->id == ZigTypeIdArray && + prev_type->id == ZigTypeIdPointer && prev_type->data.pointer.ptr_len == PtrLenSingle && + prev_type->data.pointer.child_type->id == ZigTypeIdArray && + (cur_type->data.pointer.is_const || !prev_type->data.pointer.is_const || + prev_type->data.pointer.child_type->data.array.len == 0) && + (cur_type->data.pointer.child_type->data.array.is_null_terminated || + !prev_type->data.pointer.child_type->data.array.is_null_terminated) && + types_match_const_cast_only(ira, + cur_type->data.pointer.child_type->data.array.child_type, + prev_type->data.pointer.child_type->data.array.child_type, + source_node, !cur_type->data.pointer.is_const).id == ConstCastResultIdOk) + { + prev_inst = cur_inst; + convert_to_const_slice = true; + continue; + } + if (prev_type->id == ZigTypeIdPointer && prev_type->data.pointer.ptr_len == PtrLenSingle && + prev_type->data.pointer.child_type->id == ZigTypeIdArray && + cur_type->id == ZigTypeIdPointer && cur_type->data.pointer.ptr_len == PtrLenSingle && + cur_type->data.pointer.child_type->id == ZigTypeIdArray && + (prev_type->data.pointer.is_const || !cur_type->data.pointer.is_const || + cur_type->data.pointer.child_type->data.array.len == 0) && + (prev_type->data.pointer.child_type->data.array.is_null_terminated || + !cur_type->data.pointer.child_type->data.array.is_null_terminated) && + types_match_const_cast_only(ira, + prev_type->data.pointer.child_type->data.array.child_type, + cur_type->data.pointer.child_type->data.array.child_type, + source_node, !prev_type->data.pointer.is_const).id == ConstCastResultIdOk) + { + convert_to_const_slice = true; + continue; + } + // [N]T to []T if (prev_type->id == ZigTypeIdArray && is_slice(cur_type) && (cur_type->data.structure.fields[slice_ptr_index]->type_entry->data.pointer.is_const || @@ -10740,16 +10826,33 @@ static ZigType *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_node, ZigT free(errors); if (convert_to_const_slice) { - assert(prev_inst->value.type->id == ZigTypeIdArray); - ZigType *ptr_type = get_pointer_to_type_extra( - ira->codegen, prev_inst->value.type->data.array.child_type, - true, false, PtrLenUnknown, - 0, 0, 0, false); - ZigType *slice_type = get_slice_type(ira->codegen, ptr_type); - if (err_set_type != nullptr) { - return get_error_union_type(ira->codegen, err_set_type, slice_type); + if (prev_inst->value.type->id == ZigTypeIdArray) { + ZigType *ptr_type = get_pointer_to_type_extra( + ira->codegen, prev_inst->value.type->data.array.child_type, + true, false, PtrLenUnknown, + 0, 0, 0, false); + ZigType *slice_type = get_slice_type(ira->codegen, ptr_type); + if (err_set_type != nullptr) { + return get_error_union_type(ira->codegen, err_set_type, slice_type); + } else { + return slice_type; + } + } else if (prev_inst->value.type->id == ZigTypeIdPointer) { + ZigType *array_type = prev_inst->value.type->data.pointer.child_type; + src_assert(array_type->id == ZigTypeIdArray, source_node); + ZigType *ptr_type = get_pointer_to_type_extra( + ira->codegen, array_type->data.array.child_type, + prev_inst->value.type->data.pointer.is_const, false, + array_type->data.array.is_null_terminated ? PtrLenNull : PtrLenUnknown, + 0, 0, 0, false); + ZigType *slice_type = get_slice_type(ira->codegen, ptr_type); + if (err_set_type != nullptr) { + return get_error_union_type(ira->codegen, err_set_type, slice_type); + } else { + return slice_type; + } } else { - return slice_type; + zig_unreachable(); } } else if (err_set_type != nullptr) { if (prev_inst->value.type->id == ZigTypeIdErrorSet) { @@ -10970,7 +11073,6 @@ static IrInstruction *ir_resolve_ptr_of_array_to_unknown_len_ptr(IrAnalyze *ira, result->value.data.x_ptr.mut = value->value.data.x_ptr.mut; result->value.data.x_ptr.data.base_array.array_val = pointee; result->value.data.x_ptr.data.base_array.elem_index = 0; - result->value.data.x_ptr.data.base_array.is_cstr = false; return result; } } @@ -10982,31 +11084,31 @@ static IrInstruction *ir_resolve_ptr_of_array_to_unknown_len_ptr(IrAnalyze *ira, } static IrInstruction *ir_resolve_ptr_of_array_to_slice(IrAnalyze *ira, IrInstruction *source_instr, - IrInstruction *value, ZigType *wanted_type, ResultLoc *result_loc) + IrInstruction *array_ptr, ZigType *wanted_type, ResultLoc *result_loc) { Error err; - if ((err = type_resolve(ira->codegen, value->value.type->data.pointer.child_type, + if ((err = type_resolve(ira->codegen, array_ptr->value.type->data.pointer.child_type, ResolveStatusAlignmentKnown))) { return ira->codegen->invalid_instruction; } - wanted_type = adjust_slice_align(ira->codegen, wanted_type, get_ptr_align(ira->codegen, value->value.type)); + wanted_type = adjust_slice_align(ira->codegen, wanted_type, get_ptr_align(ira->codegen, array_ptr->value.type)); - if (instr_is_comptime(value)) { - ConstExprValue *pointee = const_ptr_pointee(ira, ira->codegen, &value->value, source_instr->source_node); + if (instr_is_comptime(array_ptr)) { + ConstExprValue *pointee = const_ptr_pointee(ira, ira->codegen, &array_ptr->value, source_instr->source_node); if (pointee == nullptr) return ira->codegen->invalid_instruction; if (pointee->special != ConstValSpecialRuntime) { - assert(value->value.type->id == ZigTypeIdPointer); - ZigType *array_type = value->value.type->data.pointer.child_type; + assert(array_ptr->value.type->id == ZigTypeIdPointer); + ZigType *array_type = array_ptr->value.type->data.pointer.child_type; assert(is_slice(wanted_type)); bool is_const = wanted_type->data.structure.fields[slice_ptr_index]->type_entry->data.pointer.is_const; IrInstruction *result = ir_const(ira, source_instr, wanted_type); init_const_slice(ira->codegen, &result->value, pointee, 0, array_type->data.array.len, is_const); - result->value.data.x_struct.fields[slice_ptr_index]->data.x_ptr.mut = value->value.data.x_ptr.mut; + result->value.data.x_struct.fields[slice_ptr_index]->data.x_ptr.mut = array_ptr->value.data.x_ptr.mut; result->value.type = wanted_type; return result; } @@ -11018,7 +11120,7 @@ static IrInstruction *ir_resolve_ptr_of_array_to_slice(IrAnalyze *ira, IrInstruc if (type_is_invalid(result_loc_inst->value.type) || instr_is_unreachable(result_loc_inst)) { return result_loc_inst; } - return ir_build_ptr_of_array_to_slice(ira, source_instr, wanted_type, value, result_loc_inst); + return ir_build_ptr_of_array_to_slice(ira, source_instr, wanted_type, array_ptr, result_loc_inst); } static IrBasicBlock *ir_get_new_bb(IrAnalyze *ira, IrBasicBlock *old_bb, IrInstruction *ref_old_instruction) { @@ -12483,6 +12585,8 @@ static void report_recursive_error(IrAnalyze *ira, AstNode *source_node, ConstCa case ConstCastResultIdFnArgNoAlias: // TODO case ConstCastResultIdUnresolvedInferredErrSet: // TODO case ConstCastResultIdAsyncAllocatorType: // TODO + case ConstCastResultIdArrayChild: // TODO + case ConstCastResultIdBadNullTermArrays: // TODO break; } } @@ -12795,7 +12899,6 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst return ir_analyze_widen_or_shorten(ira, source_instr, value, wanted_type); } - // cast from [N]T to []const T // TODO: once https://github.com/ziglang/zig/issues/265 lands, remove this if (is_slice(wanted_type) && actual_type->id == ZigTypeIdArray) { @@ -12834,23 +12937,46 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst } } - // *[N]T to [*]T and [*c]T - if (wanted_type->id == ZigTypeIdPointer && - (wanted_type->data.pointer.ptr_len == PtrLenUnknown || wanted_type->data.pointer.ptr_len == PtrLenC) && + // *[N]T to ?[]const T + if (wanted_type->id == ZigTypeIdOptional && + is_slice(wanted_type->data.maybe.child_type) && actual_type->id == ZigTypeIdPointer && actual_type->data.pointer.ptr_len == PtrLenSingle && actual_type->data.pointer.child_type->id == ZigTypeIdArray) { - if ((err = type_resolve(ira->codegen, actual_type->data.pointer.child_type, ResolveStatusAlignmentKnown))) + IrInstruction *cast1 = ir_analyze_cast(ira, source_instr, wanted_type->data.maybe.child_type, value, nullptr); + if (type_is_invalid(cast1->value.type)) return ira->codegen->invalid_instruction; - if ((err = type_resolve(ira->codegen, wanted_type->data.pointer.child_type, ResolveStatusAlignmentKnown))) + + IrInstruction *cast2 = ir_analyze_cast(ira, source_instr, wanted_type, cast1, result_loc); + if (type_is_invalid(cast2->value.type)) return ira->codegen->invalid_instruction; - if (get_ptr_align(ira->codegen, actual_type) >= get_ptr_align(ira->codegen, wanted_type) && - types_match_const_cast_only(ira, wanted_type->data.pointer.child_type, - actual_type->data.pointer.child_type->data.array.child_type, source_node, - !wanted_type->data.pointer.is_const).id == ConstCastResultIdOk) + + return cast2; + } + + // *[N]T to [*]T and [*c]T + if (wanted_type->id == ZigTypeIdPointer && + (wanted_type->data.pointer.ptr_len == PtrLenUnknown || wanted_type->data.pointer.ptr_len == PtrLenC || + wanted_type->data.pointer.ptr_len == PtrLenNull) && + actual_type->id == ZigTypeIdPointer && + actual_type->data.pointer.ptr_len == PtrLenSingle && + actual_type->data.pointer.child_type->id == ZigTypeIdArray) + { + if (wanted_type->data.pointer.ptr_len != PtrLenNull || + actual_type->data.pointer.child_type->data.array.is_null_terminated) { - return ir_resolve_ptr_of_array_to_unknown_len_ptr(ira, source_instr, value, wanted_type); + if ((err = type_resolve(ira->codegen, actual_type->data.pointer.child_type, ResolveStatusAlignmentKnown))) + return ira->codegen->invalid_instruction; + if ((err = type_resolve(ira->codegen, wanted_type->data.pointer.child_type, ResolveStatusAlignmentKnown))) + return ira->codegen->invalid_instruction; + if (get_ptr_align(ira->codegen, actual_type) >= get_ptr_align(ira->codegen, wanted_type) && + types_match_const_cast_only(ira, wanted_type->data.pointer.child_type, + actual_type->data.pointer.child_type->data.array.child_type, source_node, + !wanted_type->data.pointer.is_const).id == ConstCastResultIdOk) + { + return ir_resolve_ptr_of_array_to_unknown_len_ptr(ira, source_instr, value, wanted_type); + } } } @@ -14544,8 +14670,6 @@ static bool ok_float_op(IrBinOp op) { } static bool is_pointer_arithmetic_allowed(ZigType *lhs_type, IrBinOp op) { - if (lhs_type->id != ZigTypeIdPointer) - return false; switch (op) { case IrBinOpAdd: case IrBinOpSub: @@ -14553,15 +14677,17 @@ static bool is_pointer_arithmetic_allowed(ZigType *lhs_type, IrBinOp op) { default: return false; } + if (lhs_type->id != ZigTypeIdPointer) + return false; switch (lhs_type->data.pointer.ptr_len) { case PtrLenSingle: - return false; + return lhs_type->data.pointer.child_type->id == ZigTypeIdArray; case PtrLenUnknown: case PtrLenNull: case PtrLenC: - break; + return true; } - return true; + zig_unreachable(); } static IrInstruction *ir_analyze_bin_op_math(IrAnalyze *ira, IrInstructionBinOp *instruction) { @@ -14823,6 +14949,7 @@ static IrInstruction *ir_analyze_array_cat(IrAnalyze *ira, IrInstructionBinOp *i if (!op2_val) return ira->codegen->invalid_instruction; + bool is_null_terminated = false; ConstExprValue *op1_array_val; size_t op1_array_index; size_t op1_array_end; @@ -14834,13 +14961,14 @@ static IrInstruction *ir_analyze_array_cat(IrAnalyze *ira, IrInstructionBinOp *i op1_array_end = op1_type->data.array.len; } else if (op1_type->id == ZigTypeIdPointer && op1_type->data.pointer.child_type == ira->codegen->builtin_types.entry_u8 && - op1_val->data.x_ptr.special == ConstPtrSpecialBaseArray && - op1_val->data.x_ptr.data.base_array.is_cstr) + op1_type->data.pointer.ptr_len == PtrLenNull && + op1_val->data.x_ptr.special == ConstPtrSpecialBaseArray) { child_type = op1_type->data.pointer.child_type; op1_array_val = op1_val->data.x_ptr.data.base_array.array_val; op1_array_index = op1_val->data.x_ptr.data.base_array.elem_index; - op1_array_end = op1_array_val->type->data.array.len - 1; + op1_array_end = op1_array_val->type->data.array.len; + is_null_terminated = true; } else if (is_slice(op1_type)) { ZigType *ptr_type = op1_type->data.structure.fields[slice_ptr_index]->type_entry; child_type = ptr_type->data.pointer.child_type; @@ -14850,9 +14978,20 @@ static IrInstruction *ir_analyze_array_cat(IrAnalyze *ira, IrInstructionBinOp *i op1_array_index = ptr_val->data.x_ptr.data.base_array.elem_index; ConstExprValue *len_val = op1_val->data.x_struct.fields[slice_len_index]; op1_array_end = op1_array_index + bigint_as_usize(&len_val->data.x_bigint); + } else if (op1_type->id == ZigTypeIdPointer && op1_type->data.pointer.ptr_len == PtrLenSingle && + op1_type->data.pointer.child_type->id == ZigTypeIdArray) + { + ZigType *array_type = op1_type->data.pointer.child_type; + child_type = array_type->data.array.child_type; + op1_array_val = const_ptr_pointee(ira, ira->codegen, op1_val, op1->source_node); + if (op1_array_val == nullptr) + return ira->codegen->invalid_instruction; + op1_array_index = 0; + op1_array_end = array_type->data.array.len; + is_null_terminated = is_null_terminated || array_type->data.array.is_null_terminated; } else { ir_add_error(ira, op1, - buf_sprintf("expected array or C string literal, found '%s'", buf_ptr(&op1->value.type->name))); + buf_sprintf("expected array, found '%s'", buf_ptr(&op1->value.type->name))); return ira->codegen->invalid_instruction; } @@ -14866,14 +15005,14 @@ static IrInstruction *ir_analyze_array_cat(IrAnalyze *ira, IrInstructionBinOp *i op2_array_index = 0; op2_array_end = op2_array_val->type->data.array.len; } else if (op2_type->id == ZigTypeIdPointer && - op2_type->data.pointer.child_type == ira->codegen->builtin_types.entry_u8 && - op2_val->data.x_ptr.special == ConstPtrSpecialBaseArray && - op2_val->data.x_ptr.data.base_array.is_cstr) + op2_type->data.pointer.ptr_len == PtrLenNull && + op2_val->data.x_ptr.special == ConstPtrSpecialBaseArray) { - op2_type_valid = child_type == ira->codegen->builtin_types.entry_u8; + op2_type_valid = op2_type->data.pointer.child_type == child_type; op2_array_val = op2_val->data.x_ptr.data.base_array.array_val; op2_array_index = op2_val->data.x_ptr.data.base_array.elem_index; - op2_array_end = op2_array_val->type->data.array.len - 1; + op2_array_end = op2_array_val->type->data.array.len; + is_null_terminated = true; } else if (is_slice(op2_type)) { ZigType *ptr_type = op2_type->data.structure.fields[slice_ptr_index]->type_entry; op2_type_valid = ptr_type->data.pointer.child_type == child_type; @@ -14883,6 +15022,17 @@ static IrInstruction *ir_analyze_array_cat(IrAnalyze *ira, IrInstructionBinOp *i op2_array_index = ptr_val->data.x_ptr.data.base_array.elem_index; ConstExprValue *len_val = op2_val->data.x_struct.fields[slice_len_index]; op2_array_end = op2_array_index + bigint_as_usize(&len_val->data.x_bigint); + } else if (op2_type->id == ZigTypeIdPointer && op2_type->data.pointer.ptr_len == PtrLenSingle && + op2_type->data.pointer.child_type->id == ZigTypeIdArray) + { + ZigType *array_type = op2_type->data.pointer.child_type; + op2_type_valid = array_type->data.array.child_type == child_type; + op2_array_val = const_ptr_pointee(ira, ira->codegen, op2_val, op2->source_node); + if (op2_array_val == nullptr) + return ira->codegen->invalid_instruction; + op2_array_index = 0; + op2_array_end = array_type->data.array.len; + is_null_terminated = is_null_terminated || array_type->data.array.is_null_terminated; } else { ir_add_error(ira, op2, buf_sprintf("expected array or C string literal, found '%s'", buf_ptr(&op2->value.type->name))); @@ -14905,6 +15055,14 @@ static IrInstruction *ir_analyze_array_cat(IrAnalyze *ira, IrInstructionBinOp *i result->value.type = get_array_type(ira->codegen, child_type, new_len, false); out_array_val = out_val; + } else if (op1_type->id == ZigTypeIdPointer || op2_type->id == ZigTypeIdPointer) { + out_array_val = create_const_vals(1); + out_array_val->special = ConstValSpecialStatic; + out_array_val->type = get_array_type(ira->codegen, child_type, new_len, is_null_terminated); + + out_val->data.x_ptr.special = ConstPtrSpecialRef; + out_val->data.x_ptr.data.ref.pointee = out_array_val; + out_val->type = get_pointer_to_type(ira->codegen, out_array_val->type, true); } else if (is_slice(op1_type) || is_slice(op2_type)) { ZigType *ptr_type = get_pointer_to_type_extra(ira->codegen, child_type, true, false, PtrLenUnknown, 0, 0, 0, false); @@ -14925,22 +15083,20 @@ static IrInstruction *ir_analyze_array_cat(IrAnalyze *ira, IrInstructionBinOp *i out_val->data.x_struct.fields[slice_len_index]->special = ConstValSpecialStatic; bigint_init_unsigned(&out_val->data.x_struct.fields[slice_len_index]->data.x_bigint, new_len); } else { - new_len += 1; // null byte - - // TODO make this `[*]null T` instead of `[*]T` - result->value.type = get_pointer_to_type_extra(ira->codegen, child_type, true, false, PtrLenUnknown, 0, 0, 0, false); + result->value.type = get_pointer_to_type_extra(ira->codegen, child_type, true, false, PtrLenNull, + 0, 0, 0, false); out_array_val = create_const_vals(1); out_array_val->special = ConstValSpecialStatic; out_array_val->type = get_array_type(ira->codegen, child_type, new_len, false); out_val->data.x_ptr.special = ConstPtrSpecialBaseArray; - out_val->data.x_ptr.data.base_array.is_cstr = true; out_val->data.x_ptr.data.base_array.array_val = out_array_val; out_val->data.x_ptr.data.base_array.elem_index = 0; } if (op1_array_val->data.x_array.special == ConstArraySpecialUndef && - op2_array_val->data.x_array.special == ConstArraySpecialUndef) { + op2_array_val->data.x_array.special == ConstArraySpecialUndef) + { out_array_val->data.x_array.special = ConstArraySpecialUndef; return result; } @@ -14978,20 +15134,34 @@ static IrInstruction *ir_analyze_array_mult(IrAnalyze *ira, IrInstructionBinOp * if (type_is_invalid(op2->value.type)) return ira->codegen->invalid_instruction; - ConstExprValue *array_val = ir_resolve_const(ira, op1, UndefBad); - if (!array_val) + bool want_ptr_to_array = false; + ZigType *array_type; + ConstExprValue *array_val; + if (op1->value.type->id == ZigTypeIdArray) { + array_type = op1->value.type; + array_val = ir_resolve_const(ira, op1, UndefOk); + if (array_val == nullptr) + return ira->codegen->invalid_instruction; + } else if (op1->value.type->id == ZigTypeIdPointer && op1->value.type->data.pointer.ptr_len == PtrLenSingle && + op1->value.type->data.pointer.child_type->id == ZigTypeIdArray) + { + array_type = op1->value.type->data.pointer.child_type; + IrInstruction *array_inst = ir_get_deref(ira, op1, op1, nullptr); + if (type_is_invalid(array_inst->value.type)) + return ira->codegen->invalid_instruction; + array_val = ir_resolve_const(ira, array_inst, UndefOk); + if (array_val == nullptr) + return ira->codegen->invalid_instruction; + want_ptr_to_array = true; + } else { + ir_add_error(ira, op1, buf_sprintf("expected array type, found '%s'", buf_ptr(&op1->value.type->name))); return ira->codegen->invalid_instruction; + } uint64_t mult_amt; if (!ir_resolve_usize(ira, op2, &mult_amt)) return ira->codegen->invalid_instruction; - ZigType *array_type = op1->value.type; - if (array_type->id != ZigTypeIdArray) { - ir_add_error(ira, op1, buf_sprintf("expected array type, found '%s'", buf_ptr(&op1->value.type->name))); - return ira->codegen->invalid_instruction; - } - uint64_t old_array_len = array_type->data.array.len; uint64_t new_array_len; @@ -15001,42 +15171,59 @@ static IrInstruction *ir_analyze_array_mult(IrAnalyze *ira, IrInstructionBinOp * } ZigType *child_type = array_type->data.array.child_type; + ZigType *result_array_type = get_array_type(ira->codegen, child_type, new_array_len, + array_type->data.array.is_null_terminated); - IrInstruction *result = ir_const(ira, &instruction->base, - get_array_type(ira->codegen, child_type, new_array_len, false)); - ConstExprValue *out_val = &result->value; - if (array_val->data.x_array.special == ConstArraySpecialUndef) { - out_val->data.x_array.special = ConstArraySpecialUndef; - return result; - } + IrInstruction *array_result; + if (array_val->special == ConstValSpecialUndef || array_val->data.x_array.special == ConstArraySpecialUndef) { + array_result = ir_const_undef(ira, &instruction->base, result_array_type); + } else { + array_result = ir_const(ira, &instruction->base, result_array_type); + ConstExprValue *out_val = &array_result->value; - switch (type_has_one_possible_value(ira->codegen, result->value.type)) { - case OnePossibleValueInvalid: - return ira->codegen->invalid_instruction; - case OnePossibleValueYes: - return result; - case OnePossibleValueNo: - break; - } + switch (type_has_one_possible_value(ira->codegen, result_array_type)) { + case OnePossibleValueInvalid: + return ira->codegen->invalid_instruction; + case OnePossibleValueYes: + goto skip_computation; + case OnePossibleValueNo: + break; + } - // TODO optimize the buf case - expand_undef_array(ira->codegen, array_val); - out_val->data.x_array.data.s_none.elements = create_const_vals(new_array_len); + // TODO optimize the buf case + expand_undef_array(ira->codegen, array_val); + size_t extra_null_term = array_type->data.array.is_null_terminated ? 1 : 0; + out_val->data.x_array.data.s_none.elements = create_const_vals(new_array_len + extra_null_term); - uint64_t i = 0; - for (uint64_t x = 0; x < mult_amt; x += 1) { - for (uint64_t y = 0; y < old_array_len; y += 1) { + uint64_t i = 0; + for (uint64_t x = 0; x < mult_amt; x += 1) { + for (uint64_t y = 0; y < old_array_len; y += 1) { + ConstExprValue *elem_dest_val = &out_val->data.x_array.data.s_none.elements[i]; + copy_const_val(elem_dest_val, &array_val->data.x_array.data.s_none.elements[y], false); + elem_dest_val->parent.id = ConstParentIdArray; + elem_dest_val->parent.data.p_array.array_val = out_val; + elem_dest_val->parent.data.p_array.elem_index = i; + i += 1; + } + } + assert(i == new_array_len); + + if (array_type->data.array.is_null_terminated) { + ConstExprValue *null_value = get_null_value(array_type->data.array.child_type); ConstExprValue *elem_dest_val = &out_val->data.x_array.data.s_none.elements[i]; - copy_const_val(elem_dest_val, &array_val->data.x_array.data.s_none.elements[y], false); + copy_const_val(elem_dest_val, null_value, false); elem_dest_val->parent.id = ConstParentIdArray; elem_dest_val->parent.data.p_array.array_val = out_val; elem_dest_val->parent.data.p_array.elem_index = i; i += 1; } } - assert(i == new_array_len); - - return result; +skip_computation: + if (want_ptr_to_array) { + return ir_get_ref(ira, &instruction->base, array_result, true, false); + } else { + return array_result; + } } static IrInstruction *ir_analyze_instruction_merge_err_sets(IrAnalyze *ira, @@ -17309,6 +17496,7 @@ static Error ir_read_const_ptr(IrAnalyze *ira, CodeGen *codegen, AstNode *source assert(out_val->type != nullptr); ConstExprValue *pointee = const_ptr_pointee_unchecked(codegen, ptr_val); + src_assert(pointee->type != nullptr, source_node); if ((err = type_resolve(codegen, pointee->type, ResolveStatusSizeKnown))) return ErrorSemanticAnalyzeFail; @@ -17319,7 +17507,7 @@ static Error ir_read_const_ptr(IrAnalyze *ira, CodeGen *codegen, AstNode *source size_t dst_size = type_size(codegen, out_val->type); if (dst_size <= src_size) { - if (src_size == dst_size && types_have_same_zig_comptime_repr(pointee->type, out_val->type)) { + if (src_size == dst_size && types_have_same_zig_comptime_repr(out_val->type, pointee->type)) { copy_const_val(out_val, pointee, ptr_val->data.x_ptr.mut != ConstPtrMutComptimeVar); return ErrorNone; } @@ -18070,6 +18258,12 @@ static IrInstruction *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruct uint64_t index = bigint_as_u64(&casted_elem_index->value.data.x_bigint); if (array_type->id == ZigTypeIdArray) { uint64_t array_len = array_type->data.array.len; + if (index == array_len && array_type->data.array.is_null_terminated) { + ZigType *elem_type = array_type->data.array.child_type; + IrInstruction *null_element = ir_const(ira, &elem_ptr_instruction->base, elem_type); + null_element->value = *get_null_value(elem_type); + return ir_get_ref(ira, &elem_ptr_instruction->base, null_element, true, false); + } if (index >= array_len) { ir_add_error_node(ira, elem_ptr_instruction->base.source_node, buf_sprintf("index %" ZIG_PRI_u64 " outside array of size %" ZIG_PRI_u64, @@ -18203,7 +18397,11 @@ static IrInstruction *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruct { size_t offset = array_ptr_val->data.x_ptr.data.base_array.elem_index; new_index = offset + index; - mem_size = array_ptr_val->data.x_ptr.data.base_array.array_val->type->data.array.len; + ZigType *array_type = array_ptr_val->data.x_ptr.data.base_array.array_val->type; + mem_size = array_type->data.array.len; + if (array_type->data.array.is_null_terminated) { + mem_size += 1; + } old_size = mem_size - offset; assert(array_ptr_val->data.x_ptr.data.base_array.array_val); @@ -18212,8 +18410,6 @@ static IrInstruction *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruct out_val->data.x_ptr.data.base_array.array_val = array_ptr_val->data.x_ptr.data.base_array.array_val; out_val->data.x_ptr.data.base_array.elem_index = new_index; - out_val->data.x_ptr.data.base_array.is_cstr = - array_ptr_val->data.x_ptr.data.base_array.is_cstr; break; } @@ -18277,8 +18473,6 @@ static IrInstruction *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruct out_val->data.x_ptr.data.base_array.array_val = ptr_field->data.x_ptr.data.base_array.array_val; out_val->data.x_ptr.data.base_array.elem_index = new_index; - out_val->data.x_ptr.data.base_array.is_cstr = - ptr_field->data.x_ptr.data.base_array.is_cstr; break; } case ConstPtrSpecialBaseStruct: @@ -19550,7 +19744,7 @@ static IrInstruction *ir_analyze_unwrap_optional_payload(IrAnalyze *ira, IrInstr ZigType *result_type = get_pointer_to_type_extra(ira->codegen, child_type, ptr_type->data.pointer.is_const, ptr_type->data.pointer.is_volatile, PtrLenSingle, 0, 0, 0, false); - bool same_comptime_repr = types_have_same_zig_comptime_repr(type_entry, child_type); + bool same_comptime_repr = types_have_same_zig_comptime_repr(child_type, type_entry); if (instr_is_comptime(base_ptr)) { ConstExprValue *ptr_val = ir_resolve_const(ira, base_ptr, UndefBad); @@ -20685,7 +20879,7 @@ static IrInstruction *ir_analyze_instruction_err_name(IrAnalyze *ira, IrInstruct return ira->codegen->invalid_instruction; ErrorTableEntry *err = casted_value->value.data.x_err_set; if (!err->cached_error_name_val) { - ConstExprValue *array_val = create_const_str_lit(ira->codegen, &err->name); + ConstExprValue *array_val = create_const_str_lit(ira->codegen, &err->name)->data.x_ptr.data.ref.pointee; err->cached_error_name_val = create_const_slice(ira->codegen, array_val, 0, buf_len(&err->name), true); } IrInstruction *result = ir_const(ira, &instruction->base, nullptr); @@ -20714,7 +20908,7 @@ static IrInstruction *ir_analyze_instruction_enum_tag_name(IrAnalyze *ira, IrIns if ((err = type_resolve(ira->codegen, target->value.type, ResolveStatusZeroBitsKnown))) return ira->codegen->invalid_instruction; TypeEnumField *field = find_enum_field_by_tag(target->value.type, &target->value.data.x_bigint); - ConstExprValue *array_val = create_const_str_lit(ira->codegen, field->name); + ConstExprValue *array_val = create_const_str_lit(ira->codegen, field->name)->data.x_ptr.data.ref.pointee; IrInstruction *result = ir_const(ira, &instruction->base, nullptr); init_const_slice(ira->codegen, &result->value, array_val, 0, buf_len(field->name), true); return result; @@ -21019,7 +21213,7 @@ static Error ir_make_type_info_decls(IrAnalyze *ira, IrInstruction *source_instr declaration_val->type = type_info_declaration_type; ConstExprValue **inner_fields = alloc_const_vals_ptrs(3); - ConstExprValue *name = create_const_str_lit(ira->codegen, curr_entry->key); + ConstExprValue *name = create_const_str_lit(ira->codegen, curr_entry->key)->data.x_ptr.data.ref.pointee; init_const_slice(ira->codegen, inner_fields[0], name, 0, buf_len(curr_entry->key), true); inner_fields[1]->special = ConstValSpecialStatic; inner_fields[1]->type = ira->codegen->builtin_types.entry_bool; @@ -21122,7 +21316,7 @@ static Error ir_make_type_info_decls(IrAnalyze *ira, IrInstruction *source_instr fn_decl_fields[6]->type = get_optional_type(ira->codegen, get_slice_type(ira->codegen, u8_ptr)); if (fn_node->is_extern && fn_node->lib_name != nullptr && buf_len(fn_node->lib_name) > 0) { fn_decl_fields[6]->data.x_optional = create_const_vals(1); - ConstExprValue *lib_name = create_const_str_lit(ira->codegen, fn_node->lib_name); + ConstExprValue *lib_name = create_const_str_lit(ira->codegen, fn_node->lib_name)->data.x_ptr.data.ref.pointee; init_const_slice(ira->codegen, fn_decl_fields[6]->data.x_optional, lib_name, 0, buf_len(fn_node->lib_name), true); } else { @@ -21149,7 +21343,7 @@ static Error ir_make_type_info_decls(IrAnalyze *ira, IrInstruction *source_instr ZigVar *arg_var = fn_entry->variable_list.at(fn_arg_index); ConstExprValue *fn_arg_name_val = &fn_arg_name_array->data.x_array.data.s_none.elements[fn_arg_index]; ConstExprValue *arg_name = create_const_str_lit(ira->codegen, - buf_create_from_str(arg_var->name)); + buf_create_from_str(arg_var->name))->data.x_ptr.data.ref.pointee; init_const_slice(ira->codegen, fn_arg_name_val, arg_name, 0, strlen(arg_var->name), true); fn_arg_name_val->parent.id = ConstParentIdArray; fn_arg_name_val->parent.data.p_array.array_val = fn_arg_name_array; @@ -21294,7 +21488,7 @@ static void make_enum_field_val(IrAnalyze *ira, ConstExprValue *enum_field_val, inner_fields[1]->special = ConstValSpecialStatic; inner_fields[1]->type = ira->codegen->builtin_types.entry_num_lit_int; - ConstExprValue *name = create_const_str_lit(ira->codegen, enum_field->name); + ConstExprValue *name = create_const_str_lit(ira->codegen, enum_field->name)->data.x_ptr.data.ref.pointee; init_const_slice(ira->codegen, inner_fields[0], name, 0, buf_len(enum_field->name), true); bigint_init_bigint(&inner_fields[1]->data.x_bigint, &enum_field->value); @@ -21560,7 +21754,7 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInstruction *source_instr if (error->cached_error_name_val != nullptr) name = error->cached_error_name_val; if (name == nullptr) - name = create_const_str_lit(ira->codegen, &error->name); + name = create_const_str_lit(ira->codegen, &error->name)->data.x_ptr.data.ref.pointee; init_const_slice(ira->codegen, inner_fields[0], name, 0, buf_len(&error->name), true); bigint_init_unsigned(&inner_fields[1]->data.x_bigint, error->value); @@ -21666,7 +21860,7 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInstruction *source_instr inner_fields[2]->type = ira->codegen->builtin_types.entry_type; inner_fields[2]->data.x_type = union_field->type_entry; - ConstExprValue *name = create_const_str_lit(ira->codegen, union_field->name); + ConstExprValue *name = create_const_str_lit(ira->codegen, union_field->name)->data.x_ptr.data.ref.pointee; init_const_slice(ira->codegen, inner_fields[0], name, 0, buf_len(union_field->name), true); union_field_val->data.x_struct.fields = inner_fields; @@ -21752,7 +21946,7 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInstruction *source_instr inner_fields[2]->type = ira->codegen->builtin_types.entry_type; inner_fields[2]->data.x_type = struct_field->type_entry; - ConstExprValue *name = create_const_str_lit(ira->codegen, struct_field->name); + ConstExprValue *name = create_const_str_lit(ira->codegen, struct_field->name)->data.x_ptr.data.ref.pointee; init_const_slice(ira->codegen, inner_fields[0], name, 0, buf_len(struct_field->name), true); struct_field_val->data.x_struct.fields = inner_fields; diff --git a/src/parser.cpp b/src/parser.cpp index 3da0d8a643..c3f719425b 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -1718,7 +1718,6 @@ static AstNode *ast_parse_primary_type_expr(ParseContext *pc) { if (string_lit != nullptr) { AstNode *res = ast_create_node(pc, NodeTypeStringLiteral, string_lit); res->data.string_literal.buf = token_buf(string_lit); - res->data.string_literal.c = string_lit->data.str_lit.is_c_str; return res; } diff --git a/src/tokenizer.cpp b/src/tokenizer.cpp index 7ece5ff3fe..5088fbdbf8 100644 --- a/src/tokenizer.cpp +++ b/src/tokenizer.cpp @@ -33,10 +33,10 @@ '0': \ case DIGIT_NON_ZERO -#define ALPHA_EXCEPT_C \ +#define ALPHA \ 'a': \ case 'b': \ - /*case 'c':*/ \ + case 'c': \ case 'd': \ case 'e': \ case 'f': \ @@ -87,10 +87,6 @@ case 'Y': \ case 'Z' -#define ALPHA \ - ALPHA_EXCEPT_C: \ - case 'c' - #define SYMBOL_CHAR \ ALPHA: \ case DIGIT: \ @@ -180,7 +176,6 @@ static bool is_symbol_char(uint8_t c) { enum TokenizeState { TokenizeStateStart, TokenizeStateSymbol, - TokenizeStateSymbolFirstC, TokenizeStateZero, // "0", which might lead to "0x" TokenizeStateNumber, // "123", "0x123" TokenizeStateNumberDot, @@ -279,7 +274,6 @@ static void set_token_id(Tokenize *t, Token *token, TokenId id) { } else if (id == TokenIdStringLiteral || id == TokenIdSymbol) { memset(&token->data.str_lit.str, 0, sizeof(Buf)); buf_resize(&token->data.str_lit.str, 0); - token->data.str_lit.is_c_str = false; } } @@ -429,12 +423,7 @@ void tokenize(Buf *buf, Tokenization *out) { switch (c) { case WHITESPACE: break; - case 'c': - t.state = TokenizeStateSymbolFirstC; - begin_token(&t, TokenIdSymbol); - buf_append_char(&t.cur_tok->data.str_lit.str, c); - break; - case ALPHA_EXCEPT_C: + case ALPHA: case '_': t.state = TokenizeStateSymbol; begin_token(&t, TokenIdSymbol); @@ -1007,19 +996,7 @@ void tokenize(Buf *buf, Tokenization *out) { switch (c) { case WHITESPACE: break; - case 'c': - if (!t.cur_tok->data.str_lit.is_c_str) { - t.pos -= 1; - end_token(&t); - t.state = TokenizeStateStart; - break; - } - t.state = TokenizeStateLineStringContinueC; - break; case '\\': - if (t.cur_tok->data.str_lit.is_c_str) { - invalid_char_error(&t, c); - } t.state = TokenizeStateLineStringContinue; break; default: @@ -1084,29 +1061,6 @@ void tokenize(Buf *buf, Tokenization *out) { break; } break; - case TokenizeStateSymbolFirstC: - switch (c) { - case '"': - set_token_id(&t, t.cur_tok, TokenIdStringLiteral); - t.cur_tok->data.str_lit.is_c_str = true; - t.state = TokenizeStateString; - break; - case '\\': - set_token_id(&t, t.cur_tok, TokenIdStringLiteral); - t.cur_tok->data.str_lit.is_c_str = true; - t.state = TokenizeStateSawBackslash; - break; - case SYMBOL_CHAR: - t.state = TokenizeStateSymbol; - buf_append_char(&t.cur_tok->data.str_lit.str, c); - break; - default: - t.pos -= 1; - end_token(&t); - t.state = TokenizeStateStart; - continue; - } - break; case TokenizeStateSawAtSign: switch (c) { case '"': @@ -1544,7 +1498,6 @@ void tokenize(Buf *buf, Tokenization *out) { tokenize_error(&t, "unterminated character literal"); break; case TokenizeStateSymbol: - case TokenizeStateSymbolFirstC: case TokenizeStateZero: case TokenizeStateNumber: case TokenizeStateFloatFraction: diff --git a/src/tokenizer.hpp b/src/tokenizer.hpp index 149e58b6a7..b152eb079c 100644 --- a/src/tokenizer.hpp +++ b/src/tokenizer.hpp @@ -149,7 +149,6 @@ struct TokenIntLit { struct TokenStrLit { Buf str; - bool is_c_str; }; struct TokenCharLit { diff --git a/src/translate_c.cpp b/src/translate_c.cpp index 6df61ab13c..5dd6064984 100644 --- a/src/translate_c.cpp +++ b/src/translate_c.cpp @@ -323,17 +323,9 @@ static AstNode *trans_create_node_bool(Context *c, bool value) { return bool_node; } -static AstNode *trans_create_node_str_lit_c(Context *c, Buf *buf) { +static AstNode *trans_create_node_str_lit(Context *c, Buf *buf) { AstNode *node = trans_create_node(c, NodeTypeStringLiteral); node->data.string_literal.buf = buf; - node->data.string_literal.c = true; - return node; -} - -static AstNode *trans_create_node_str_lit_non_c(Context *c, Buf *buf) { - AstNode *node = trans_create_node(c, NodeTypeStringLiteral); - node->data.string_literal.buf = buf; - node->data.string_literal.c = false; return node; } @@ -632,7 +624,7 @@ static AstNode *qual_type_to_log2_int_ref(Context *c, const ZigClangQualType qt, // zig_type_node AstNode *import_fn_call = trans_create_node_builtin_fn_call_str(c, "import"); - import_fn_call->data.fn_call_expr.params.append(trans_create_node_str_lit_non_c(c, buf_create_from_str("std"))); + import_fn_call->data.fn_call_expr.params.append(trans_create_node_str_lit(c, buf_create_from_str("std"))); AstNode *inner_field_access = trans_create_node_field_access_str(c, import_fn_call, "math"); AstNode *outer_field_access = trans_create_node_field_access_str(c, inner_field_access, "Log2Int"); AstNode *log2int_fn_call = trans_create_node_fn_call_1(c, outer_field_access, zig_type_node); @@ -3391,7 +3383,7 @@ static AstNode *trans_string_literal(Context *c, ResultUsed result_used, TransSc case ZigClangStringLiteral_StringKind_UTF8: { size_t str_len; const char *str_ptr = ZigClangStringLiteral_getString_bytes_begin_size(stmt, &str_len); - AstNode *node = trans_create_node_str_lit_c(c, buf_create_from_mem(str_ptr, str_len)); + AstNode *node = trans_create_node_str_lit(c, buf_create_from_mem(str_ptr, str_len)); return maybe_suppress_result(c, result_used, node); } case ZigClangStringLiteral_StringKind_UTF16: @@ -4890,7 +4882,7 @@ static AstNode *parse_ctok_primary_expr(Context *c, CTokenize *ctok, size_t *tok return trans_create_node_unsigned(c, tok->data.char_lit); case CTokIdStrLit: *tok_i += 1; - return trans_create_node_str_lit_c(c, buf_create_from_buf(&tok->data.str_lit)); + return trans_create_node_str_lit(c, buf_create_from_buf(&tok->data.str_lit)); case CTokIdMinus: *tok_i += 1; return parse_ctok_num_lit(c, ctok, tok_i, true); @@ -4937,7 +4929,7 @@ static AstNode *parse_ctok_primary_expr(Context *c, CTokenize *ctok, size_t *tok // (dest)(x) AstNode *import_builtin = trans_create_node_builtin_fn_call_str(c, "import"); - import_builtin->data.fn_call_expr.params.append(trans_create_node_str_lit_non_c(c, buf_create_from_str("builtin"))); + import_builtin->data.fn_call_expr.params.append(trans_create_node_str_lit(c, buf_create_from_str("builtin"))); AstNode *typeid_type = trans_create_node_field_access_str(c, import_builtin, "TypeId"); AstNode *typeid_pointer = trans_create_node_field_access_str(c, typeid_type, "Pointer"); AstNode *typeid_integer = trans_create_node_field_access_str(c, typeid_type, "Int"); diff --git a/test/compare_output.zig b/test/compare_output.zig index 0842fc4629..1535d0ae52 100644 --- a/test/compare_output.zig +++ b/test/compare_output.zig @@ -7,7 +7,7 @@ pub fn addCases(cases: *tests.CompareOutputContext) void { cases.addC("hello world with libc", \\const c = @cImport(@cInclude("stdio.h")); \\export fn main(argc: c_int, argv: [*][*]u8) c_int { - \\ _ = c.puts(c"Hello, world!"); + \\ _ = c.puts("Hello, world!"); \\ return 0; \\} , "Hello, world!" ++ std.cstr.line_sep); @@ -144,75 +144,75 @@ pub fn addCases(cases: *tests.CompareOutputContext) void { \\ // we want actual \n, not \r\n \\ _ = c._setmode(1, c._O_BINARY); \\ } - \\ _ = c.printf(c"0: %llu\n", + \\ _ = c.printf("0: %llu\n", \\ @as(u64, 0)); - \\ _ = c.printf(c"320402575052271: %llu\n", + \\ _ = c.printf("320402575052271: %llu\n", \\ @as(u64, 320402575052271)); - \\ _ = c.printf(c"0x01236789abcdef: %llu\n", + \\ _ = c.printf("0x01236789abcdef: %llu\n", \\ @as(u64, 0x01236789abcdef)); - \\ _ = c.printf(c"0xffffffffffffffff: %llu\n", + \\ _ = c.printf("0xffffffffffffffff: %llu\n", \\ @as(u64, 0xffffffffffffffff)); - \\ _ = c.printf(c"0x000000ffffffffffffffff: %llu\n", + \\ _ = c.printf("0x000000ffffffffffffffff: %llu\n", \\ @as(u64, 0x000000ffffffffffffffff)); - \\ _ = c.printf(c"0o1777777777777777777777: %llu\n", + \\ _ = c.printf("0o1777777777777777777777: %llu\n", \\ @as(u64, 0o1777777777777777777777)); - \\ _ = c.printf(c"0o0000001777777777777777777777: %llu\n", + \\ _ = c.printf("0o0000001777777777777777777777: %llu\n", \\ @as(u64, 0o0000001777777777777777777777)); - \\ _ = c.printf(c"0b1111111111111111111111111111111111111111111111111111111111111111: %llu\n", + \\ _ = c.printf("0b1111111111111111111111111111111111111111111111111111111111111111: %llu\n", \\ @as(u64, 0b1111111111111111111111111111111111111111111111111111111111111111)); - \\ _ = c.printf(c"0b0000001111111111111111111111111111111111111111111111111111111111111111: %llu\n", + \\ _ = c.printf("0b0000001111111111111111111111111111111111111111111111111111111111111111: %llu\n", \\ @as(u64, 0b0000001111111111111111111111111111111111111111111111111111111111111111)); \\ - \\ _ = c.printf(c"\n"); + \\ _ = c.printf("\n"); \\ - \\ _ = c.printf(c"0.0: %.013a\n", + \\ _ = c.printf("0.0: %.013a\n", \\ @as(f64, 0.0)); - \\ _ = c.printf(c"0e0: %.013a\n", + \\ _ = c.printf("0e0: %.013a\n", \\ @as(f64, 0e0)); - \\ _ = c.printf(c"0.0e0: %.013a\n", + \\ _ = c.printf("0.0e0: %.013a\n", \\ @as(f64, 0.0e0)); - \\ _ = c.printf(c"000000000000000000000000000000000000000000000000000000000.0e0: %.013a\n", + \\ _ = c.printf("000000000000000000000000000000000000000000000000000000000.0e0: %.013a\n", \\ @as(f64, 000000000000000000000000000000000000000000000000000000000.0e0)); - \\ _ = c.printf(c"0.000000000000000000000000000000000000000000000000000000000e0: %.013a\n", + \\ _ = c.printf("0.000000000000000000000000000000000000000000000000000000000e0: %.013a\n", \\ @as(f64, 0.000000000000000000000000000000000000000000000000000000000e0)); - \\ _ = c.printf(c"0.0e000000000000000000000000000000000000000000000000000000000: %.013a\n", + \\ _ = c.printf("0.0e000000000000000000000000000000000000000000000000000000000: %.013a\n", \\ @as(f64, 0.0e000000000000000000000000000000000000000000000000000000000)); - \\ _ = c.printf(c"1.0: %.013a\n", + \\ _ = c.printf("1.0: %.013a\n", \\ @as(f64, 1.0)); - \\ _ = c.printf(c"10.0: %.013a\n", + \\ _ = c.printf("10.0: %.013a\n", \\ @as(f64, 10.0)); - \\ _ = c.printf(c"10.5: %.013a\n", + \\ _ = c.printf("10.5: %.013a\n", \\ @as(f64, 10.5)); - \\ _ = c.printf(c"10.5e5: %.013a\n", + \\ _ = c.printf("10.5e5: %.013a\n", \\ @as(f64, 10.5e5)); - \\ _ = c.printf(c"10.5e+5: %.013a\n", + \\ _ = c.printf("10.5e+5: %.013a\n", \\ @as(f64, 10.5e+5)); - \\ _ = c.printf(c"50.0e-2: %.013a\n", + \\ _ = c.printf("50.0e-2: %.013a\n", \\ @as(f64, 50.0e-2)); - \\ _ = c.printf(c"50e-2: %.013a\n", + \\ _ = c.printf("50e-2: %.013a\n", \\ @as(f64, 50e-2)); \\ - \\ _ = c.printf(c"\n"); + \\ _ = c.printf("\n"); \\ - \\ _ = c.printf(c"0x1.0: %.013a\n", + \\ _ = c.printf("0x1.0: %.013a\n", \\ @as(f64, 0x1.0)); - \\ _ = c.printf(c"0x10.0: %.013a\n", + \\ _ = c.printf("0x10.0: %.013a\n", \\ @as(f64, 0x10.0)); - \\ _ = c.printf(c"0x100.0: %.013a\n", + \\ _ = c.printf("0x100.0: %.013a\n", \\ @as(f64, 0x100.0)); - \\ _ = c.printf(c"0x103.0: %.013a\n", + \\ _ = c.printf("0x103.0: %.013a\n", \\ @as(f64, 0x103.0)); - \\ _ = c.printf(c"0x103.7: %.013a\n", + \\ _ = c.printf("0x103.7: %.013a\n", \\ @as(f64, 0x103.7)); - \\ _ = c.printf(c"0x103.70: %.013a\n", + \\ _ = c.printf("0x103.70: %.013a\n", \\ @as(f64, 0x103.70)); - \\ _ = c.printf(c"0x103.70p4: %.013a\n", + \\ _ = c.printf("0x103.70p4: %.013a\n", \\ @as(f64, 0x103.70p4)); - \\ _ = c.printf(c"0x103.70p5: %.013a\n", + \\ _ = c.printf("0x103.70p5: %.013a\n", \\ @as(f64, 0x103.70p5)); - \\ _ = c.printf(c"0x103.70p+5: %.013a\n", + \\ _ = c.printf("0x103.70p+5: %.013a\n", \\ @as(f64, 0x103.70p+5)); - \\ _ = c.printf(c"0x103.70p-5: %.013a\n", + \\ _ = c.printf("0x103.70p-5: %.013a\n", \\ @as(f64, 0x103.70p-5)); \\ \\ return 0; @@ -323,7 +323,7 @@ pub fn addCases(cases: *tests.CompareOutputContext) void { \\ const x: f64 = small; \\ const y = @floatToInt(i32, x); \\ const z = @intToFloat(f64, y); - \\ _ = c.printf(c"%.2f\n%d\n%.2f\n%.2f\n", x, y, z, @as(f64, -0.4)); + \\ _ = c.printf("%.2f\n%d\n%.2f\n%.2f\n", x, y, z, @as(f64, -0.4)); \\ return 0; \\} , "3.25\n3\n3.00\n-0.40\n"); diff --git a/test/compile_errors.zig b/test/compile_errors.zig index 039afe52df..3343580991 100644 --- a/test/compile_errors.zig +++ b/test/compile_errors.zig @@ -164,7 +164,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { cases.add( "using an unknown len ptr type instead of array", \\const resolutions = [*][*]const u8{ - \\ c"[320 240 ]", + \\ "[320 240 ]", \\ null, \\}; \\comptime { @@ -781,7 +781,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { "peer cast then implicit cast const pointer to mutable C pointer", \\export fn func() void { \\ var strValue: [*c]u8 = undefined; - \\ strValue = strValue orelse c""; + \\ strValue = strValue orelse ""; \\} , "tmp.zig:3:32: error: cast discards const qualifier", @@ -1115,7 +1115,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { "libc headers note", \\const c = @cImport(@cInclude("stdio.h")); \\export fn entry() void { - \\ _ = c.printf(c"hello, world!\n"); + \\ _ = c.printf("hello, world!\n"); \\} , "tmp.zig:1:11: error: C import failed", @@ -3352,7 +3352,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { cases.add( "variable has wrong type", \\export fn f() i32 { - \\ const a = c"a"; + \\ const a = "a"; \\ return a; \\} , @@ -4786,7 +4786,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { cases.add( "assign through constant pointer", \\export fn f() void { - \\ var cstr = c"Hat"; + \\ var cstr = "Hat"; \\ cstr[0] = 'W'; \\} , diff --git a/test/stage1/behavior/array.zig b/test/stage1/behavior/array.zig index 3a9c9a7655..b9000125b3 100644 --- a/test/stage1/behavior/array.zig +++ b/test/stage1/behavior/array.zig @@ -132,9 +132,16 @@ test "single-item pointer to array indexing and slicing" { } fn testSingleItemPtrArrayIndexSlice() void { - var array = "aaaa"; - doSomeMangling(&array); - expect(mem.eql(u8, "azya", array)); + { + var array: [4]u8 = "aaaa".*; + doSomeMangling(&array); + expect(mem.eql(u8, "azya", &array)); + } + { + var array = "aaaa".*; + doSomeMangling(&array); + expect(mem.eql(u8, "azya", &array)); + } } fn doSomeMangling(array: *[4]u8) void { @@ -294,9 +301,16 @@ test "read/write through global variable array of struct fields initialized via } test "implicit cast zero sized array ptr to slice" { - var b = ""; - const c: []const u8 = &b; - expect(c.len == 0); + { + var b = "".*; + const c: []const u8 = &b; + expect(c.len == 0); + } + { + var b: [0]u8 = "".*; + const c: []const u8 = &b; + expect(c.len == 0); + } } test "anonymous list literal syntax" { @@ -333,3 +347,16 @@ test "anonymous literal in array" { S.doTheTest(); comptime S.doTheTest(); } + +test "access the null element of a null terminated array" { + const S = struct { + fn doTheTest() void { + var array: [4]null u8 = .{'a', 'o', 'e', 'u'}; + comptime expect(array[4] == 0); + var len: usize = 4; + expect(array[len] == 0); + } + }; + S.doTheTest(); + comptime S.doTheTest(); +} diff --git a/test/stage1/behavior/bugs/1076.zig b/test/stage1/behavior/bugs/1076.zig index 550ee9703a..fa3caf0df8 100644 --- a/test/stage1/behavior/bugs/1076.zig +++ b/test/stage1/behavior/bugs/1076.zig @@ -8,8 +8,16 @@ test "comptime code should not modify constant data" { } fn testCastPtrOfArrayToSliceAndPtr() void { - var array = "aoeu"; - const x: [*]u8 = &array; - x[0] += 1; - expect(mem.eql(u8, array[0..], "boeu")); + { + var array = "aoeu".*; + const x: [*]u8 = &array; + x[0] += 1; + expect(mem.eql(u8, array[0..], "boeu")); + } + { + var array: [4]u8 = "aoeu".*; + const x: [*]u8 = &array; + x[0] += 1; + expect(mem.eql(u8, array[0..], "boeu")); + } } diff --git a/test/stage1/behavior/cast.zig b/test/stage1/behavior/cast.zig index 98d987a73f..affd7afe5e 100644 --- a/test/stage1/behavior/cast.zig +++ b/test/stage1/behavior/cast.zig @@ -179,18 +179,24 @@ fn gimmeErrOrSlice() anyerror![]u8 { } test "peer type resolution: [0]u8, []const u8, and anyerror![]u8" { - { - var data = "hi"; - const slice = data[0..]; - expect((try peerTypeEmptyArrayAndSliceAndError(true, slice)).len == 0); - expect((try peerTypeEmptyArrayAndSliceAndError(false, slice)).len == 1); - } - comptime { - var data = "hi"; - const slice = data[0..]; - expect((try peerTypeEmptyArrayAndSliceAndError(true, slice)).len == 0); - expect((try peerTypeEmptyArrayAndSliceAndError(false, slice)).len == 1); - } + const S = struct { + fn doTheTest() anyerror!void { + { + var data = "hi".*; + const slice = data[0..]; + expect((try peerTypeEmptyArrayAndSliceAndError(true, slice)).len == 0); + expect((try peerTypeEmptyArrayAndSliceAndError(false, slice)).len == 1); + } + { + var data: [2]u8 = "hi".*; + const slice = data[0..]; + expect((try peerTypeEmptyArrayAndSliceAndError(true, slice)).len == 0); + expect((try peerTypeEmptyArrayAndSliceAndError(false, slice)).len == 1); + } + } + }; + try S.doTheTest(); + try comptime S.doTheTest(); } fn peerTypeEmptyArrayAndSliceAndError(a: bool, slice: []u8) anyerror![]u8 { if (a) { @@ -217,11 +223,20 @@ test "implicit cast from &const [N]T to []const T" { } fn testCastConstArrayRefToConstSlice() void { - const blah = "aoeu"; - const const_array_ref = &blah; - expect(@typeOf(const_array_ref) == *const [4]u8); - const slice: []const u8 = const_array_ref; - expect(mem.eql(u8, slice, "aoeu")); + { + const blah = "aoeu".*; + const const_array_ref = &blah; + expect(@typeOf(const_array_ref) == *const [4]null u8); + const slice: []const u8 = const_array_ref; + expect(mem.eql(u8, slice, "aoeu")); + } + { + const blah: [4]u8 = "aoeu".*; + const const_array_ref = &blah; + expect(@typeOf(const_array_ref) == *const [4]u8); + const slice: []const u8 = const_array_ref; + expect(mem.eql(u8, slice, "aoeu")); + } } test "peer type resolution: error and [N]T" { @@ -310,17 +325,28 @@ test "single-item pointer of array to slice and to unknown length pointer" { } fn testCastPtrOfArrayToSliceAndPtr() void { - var array = "aoeu"; - const x: [*]u8 = &array; - x[0] += 1; - expect(mem.eql(u8, array[0..], "boeu")); - const y: []u8 = &array; - y[0] += 1; - expect(mem.eql(u8, array[0..], "coeu")); + { + var array = "aoeu".*; + const x: [*]u8 = &array; + x[0] += 1; + expect(mem.eql(u8, array[0..], "boeu")); + const y: []u8 = &array; + y[0] += 1; + expect(mem.eql(u8, array[0..], "coeu")); + } + { + var array: [4]u8 = "aoeu".*; + const x: [*]u8 = &array; + x[0] += 1; + expect(mem.eql(u8, array[0..], "boeu")); + const y: []u8 = &array; + y[0] += 1; + expect(mem.eql(u8, array[0..], "coeu")); + } } test "cast *[1][*]const u8 to [*]const ?[*]const u8" { - const window_name = [1][*]const u8{c"window name"}; + const window_name = [1][*]const u8{"window name"}; const x: [*]const ?[*]const u8 = &window_name; expect(mem.eql(u8, std.mem.toSliceConst(u8, x[0].?), "window name")); } @@ -545,7 +571,7 @@ test "implicit cast *[0]T to E![]const u8" { } test "peer cast *[0]T to E![]const T" { - var buffer: [5]u8 = "abcde"; + var buffer: [5]u8 = "abcde".*; var buf: anyerror![]const u8 = buffer[0..]; var b = false; var y = if (b) &[0]u8{} else buf; @@ -553,7 +579,7 @@ test "peer cast *[0]T to E![]const T" { } test "peer cast *[0]T to []const T" { - var buffer: [5]u8 = "abcde"; + var buffer: [5]u8 = "abcde".*; var buf: []const u8 = buffer[0..]; var b = false; var y = if (b) &[0]u8{} else buf; @@ -565,3 +591,33 @@ test "cast from array reference to fn" { const f = @ptrCast(extern fn () void, &global_array); expect(@ptrToInt(f) == @ptrToInt(&global_array)); } + +test "*const [N]null u8 to ?[]const u8" { + const S = struct { + fn doTheTest() void { + var a = "Hello"; + var b: ?[]const u8 = a; + expect(mem.eql(u8, b.?, "Hello")); + } + }; + S.doTheTest(); + comptime S.doTheTest(); +} + +test "peer resolution of string literals" { + const S = struct { + const E = extern enum { a, b, c, d}; + + fn doTheTest(e: E) void { + const cmd = switch (e) { + .a => "one", + .b => "two", + .c => "three", + .d => "four", + }; + expect(mem.eql(u8, cmd, "two")); + } + }; + S.doTheTest(.b); + comptime S.doTheTest(.b); +} diff --git a/test/stage1/behavior/const_slice_child.zig b/test/stage1/behavior/const_slice_child.zig index 13713e1ee7..6720667187 100644 --- a/test/stage1/behavior/const_slice_child.zig +++ b/test/stage1/behavior/const_slice_child.zig @@ -6,12 +6,11 @@ var argv: [*]const [*]const u8 = undefined; test "const slice child" { const strs = [_][*]const u8{ - c"one", - c"two", - c"three", + "one", + "two", + "three", }; - // TODO this should implicitly cast - argv = @ptrCast([*]const [*]const u8, &strs); + argv = &strs; bar(strs.len); } diff --git a/test/stage1/behavior/eval.zig b/test/stage1/behavior/eval.zig index fa899d0cb2..b7bce26568 100644 --- a/test/stage1/behavior/eval.zig +++ b/test/stage1/behavior/eval.zig @@ -736,7 +736,7 @@ test "comptime pointer cast array and then slice" { test "slice bounds in comptime concatenation" { const bs = comptime blk: { - const b = c"........1........"; + const b = "........1........"; break :blk b[8..9]; }; const str = "" ++ bs; diff --git a/test/stage1/behavior/misc.zig b/test/stage1/behavior/misc.zig index 1a227a5b93..a0188dcedd 100644 --- a/test/stage1/behavior/misc.zig +++ b/test/stage1/behavior/misc.zig @@ -204,11 +204,11 @@ test "multiline string" { test "multiline C string" { const s1 = - c\\one - c\\two) - c\\three + \\one + \\two) + \\three ; - const s2 = c"one\ntwo)\nthree"; + const s2 = "one\ntwo)\nthree"; expect(std.cstr.cmp(s1, s2) == 0); } @@ -358,9 +358,12 @@ fn ptrEql(a: *const []const u8, b: *const []const u8) bool { return a == b; } -test "C string concatenation" { - const a = c"OK" ++ c" IT " ++ c"WORKED"; - const b = c"OK IT WORKED"; +test "string concatenation" { + const a = "OK" ++ " IT " ++ "WORKED"; + const b = "OK IT WORKED"; + + comptime expect(@typeOf(a) == *const [12]null u8); + comptime expect(@typeOf(b) == *const [12]null u8); const len = mem.len(u8, b); const len_with_null = len + 1; diff --git a/test/stage1/behavior/pointers.zig b/test/stage1/behavior/pointers.zig index fd11e68473..7d8bdea569 100644 --- a/test/stage1/behavior/pointers.zig +++ b/test/stage1/behavior/pointers.zig @@ -15,7 +15,7 @@ fn testDerefPtr() void { } test "pointer arithmetic" { - var ptr = c"abcd"; + var ptr: [*]const u8 = "abcd"; expect(ptr[0] == 'a'); ptr += 1; diff --git a/test/stage1/behavior/ptrcast.zig b/test/stage1/behavior/ptrcast.zig index bf92888214..ddb5a63eee 100644 --- a/test/stage1/behavior/ptrcast.zig +++ b/test/stage1/behavior/ptrcast.zig @@ -60,7 +60,7 @@ test "comptime ptrcast keeps larger alignment" { } test "implicit optional pointer to optional c_void pointer" { - var buf: [4]u8 = "aoeu"; + var buf: [4]u8 = "aoeu".*; var x: ?[*]u8 = &buf; var y: ?*c_void = x; var z = @ptrCast(*[4]u8, y); diff --git a/test/stage1/behavior/slice.zig b/test/stage1/behavior/slice.zig index d4a8353ca7..ea0a6fe9f4 100644 --- a/test/stage1/behavior/slice.zig +++ b/test/stage1/behavior/slice.zig @@ -36,7 +36,7 @@ fn assertLenIsZero(msg: []const u8) void { } test "C pointer" { - var buf: [*c]const u8 = c"kjdhfkjdhfdkjhfkfjhdfkjdhfkdjhfdkjhf"; + var buf: [*c]const u8 = "kjdhfkjdhfdkjhfkfjhdfkjdhfkdjhfdkjhf"; var len: u32 = 10; var slice = buf[0..len]; expectEqualSlices(u8, "kjdhfkjdhf", slice); diff --git a/test/stage1/behavior/struct.zig b/test/stage1/behavior/struct.zig index 722f44d352..e42bd4e9d7 100644 --- a/test/stage1/behavior/struct.zig +++ b/test/stage1/behavior/struct.zig @@ -493,7 +493,7 @@ test "non-byte-aligned array inside packed struct" { fn doTheTest() void { var foo = Foo{ .a = true, - .b = "abcdefghijklmnopqurstu", + .b = "abcdefghijklmnopqurstu".*, }; bar(foo.b); } diff --git a/test/stage2/compare_output.zig b/test/stage2/compare_output.zig index fdc3d49145..a86811b27b 100644 --- a/test/stage2/compare_output.zig +++ b/test/stage2/compare_output.zig @@ -6,7 +6,7 @@ pub fn addCases(ctx: *TestContext) !void { try ctx.testCompareOutputLibC( \\extern fn puts([*]const u8) void; \\export fn main() c_int { - \\ puts(c"Hello, world!"); + \\ puts("Hello, world!"); \\ return 0; \\} , "Hello, world!" ++ std.cstr.line_sep); @@ -15,7 +15,7 @@ pub fn addCases(ctx: *TestContext) !void { try ctx.testCompareOutputLibC( \\extern fn puts(s: [*]const u8) void; \\export fn main() c_int { - \\ return foo(c"OK"); + \\ return foo("OK"); \\} \\fn foo(s: [*]const u8) c_int { \\ puts(s); diff --git a/test/standalone/hello_world/hello_libc.zig b/test/standalone/hello_world/hello_libc.zig index 05356bf529..c6f290f70e 100644 --- a/test/standalone/hello_world/hello_libc.zig +++ b/test/standalone/hello_world/hello_libc.zig @@ -5,7 +5,7 @@ const c = @cImport({ @cInclude("string.h"); }); -const msg = c"Hello, world!\n"; +const msg = "Hello, world!\n"; export fn main(argc: c_int, argv: **u8) c_int { if (c.printf(msg) != @intCast(c_int, c.strlen(msg))) return -1; diff --git a/test/translate_c.zig b/test/translate_c.zig index f78e2181eb..f543fbc74e 100644 --- a/test/translate_c.zig +++ b/test/translate_c.zig @@ -47,7 +47,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void { \\pub fn foo() void { \\ var a: c_int = undefined; \\ _ = 1; - \\ _ = c"hey"; + \\ _ = "hey"; \\ _ = (1 + 1); \\ _ = (1 - 1); \\ a = 1; @@ -213,9 +213,9 @@ pub fn addCases(cases: *tests.TranslateCContext) void { \\} , \\pub fn foo() void { - \\ _ = c"foo"; - \\ _ = c"foo"; - \\ _ = c"void foo(void)"; + \\ _ = "foo"; + \\ _ = "foo"; + \\ _ = "void foo(void)"; \\} ); @@ -232,7 +232,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void { \\pub fn foo() void { \\ var a: c_int = undefined; \\ _ = 1; - \\ _ = c"hey"; + \\ _ = "hey"; \\ _ = (1 + 1); \\ _ = (1 - 1); \\ a = 1; @@ -543,7 +543,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void { cases.add("#define string", \\#define foo "a string" , - \\pub const foo = c"a string"; + \\pub const foo = "a string"; ); cases.add("__cdecl doesn't mess up function pointers", @@ -617,9 +617,9 @@ pub fn addCases(cases: *tests.TranslateCContext) void { \\#define FOO2 "aoeu\x0007a derp" \\#define FOO_CHAR '\xfF' , - \\pub const FOO = c"aoeu\xab derp"; + \\pub const FOO = "aoeu\xab derp"; , - \\pub const FOO2 = c"aoeuz derp"; + \\pub const FOO2 = "aoeuz derp"; , \\pub const FOO_CHAR = 255; ); @@ -629,9 +629,9 @@ pub fn addCases(cases: *tests.TranslateCContext) void { \\#define FOO2 "aoeu\0234 derp" \\#define FOO_CHAR '\077' , - \\pub const FOO = c"aoeu\x13 derp"; + \\pub const FOO = "aoeu\x13 derp"; , - \\pub const FOO2 = c"aoeu\x134 derp"; + \\pub const FOO2 = "aoeu\x134 derp"; , \\pub const FOO_CHAR = 63; ); @@ -1351,7 +1351,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void { \\} , \\pub fn foo() [*c]const u8 { - \\ return c"bar"; + \\ return "bar"; \\} ); @@ -1523,7 +1523,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void { cases.add("const ptr initializer", \\static const char *v0 = "0.0.0"; , - \\pub var v0: [*c]const u8 = c"0.0.0"; + \\pub var v0: [*c]const u8 = "0.0.0"; ); cases.add("static incomplete array inside function", @@ -1532,7 +1532,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void { \\} , \\pub fn foo() void { - \\ const v2: [*c]const u8 = c"2.2.2"; + \\ const v2: [*c]const u8 = "2.2.2"; \\} ); @@ -1809,7 +1809,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void { \\ var i: u8 = @as(u8, '\x0b'); \\ var j: u8 = @as(u8, '\x00'); \\ var k: u8 = @as(u8, '\"'); - \\ return c"\'\\\x07\x08\x0c\n\r\t\x0b\x00\""; + \\ return "\'\\\x07\x08\x0c\n\r\t\x0b\x00\""; \\} \\ );