authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-08-07 23:10:57-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-08-19 16:45:15-07:00
log507aae4a1a3db498ece2a3a89d74e9e24d952923
treedb52f3b00d0def30488e7ce81adc8685c4945874
parent73bbd1069a993a0e663033ea3b8cd4ed1a123566

make self-hosted the default compiler

stage1 is available behind the -fstage1 flag. closes #89

25 files changed, 176 insertions(+), 213 deletions(-)

CMakeLists.txt+1-1
......@@ -12,7 +12,7 @@ if(NOT CMAKE_BUILD_TYPE)
1212endif()
1313
1414if(NOT CMAKE_INSTALL_PREFIX)
15 set(CMAKE_INSTALL_PREFIX "${CMAKE_BINARY_DIR}/stage1" CACHE STRING
15 set(CMAKE_INSTALL_PREFIX "${CMAKE_BINARY_DIR}/stage2" CACHE STRING
1616 "Directory to install zig to" FORCE)
1717endif()
1818
build.zig+6-10
......@@ -64,9 +64,9 @@ pub fn build(b: *Builder) !void {
6464
6565 const only_install_lib_files = b.option(bool, "lib-files-only", "Only install library files") orelse false;
6666
67 const is_stage1 = b.option(bool, "stage1", "Build the stage1 compiler, put stage2 behind a feature flag") orelse false;
67 const have_stage1 = b.option(bool, "enable-stage1", "Include the stage1 compiler behind a feature flag") orelse false;
6868 const static_llvm = b.option(bool, "static-llvm", "Disable integration with system-installed LLVM, Clang, LLD, and libc++") orelse false;
69 const enable_llvm = b.option(bool, "enable-llvm", "Build self-hosted compiler with LLVM backend enabled") orelse (is_stage1 or static_llvm);
69 const enable_llvm = b.option(bool, "enable-llvm", "Build self-hosted compiler with LLVM backend enabled") orelse (have_stage1 or static_llvm);
7070 const llvm_has_m68k = b.option(
7171 bool,
7272 "llvm-has-m68k",
......@@ -136,7 +136,7 @@ pub fn build(b: *Builder) !void {
136136 };
137137
138138 const main_file: ?[]const u8 = mf: {
139 if (!is_stage1) break :mf "src/main.zig";
139 if (!have_stage1) break :mf "src/main.zig";
140140 if (use_zig0) break :mf null;
141141 break :mf "src/stage1.zig";
142142 };
......@@ -247,7 +247,7 @@ pub fn build(b: *Builder) !void {
247247 }
248248 };
249249
250 if (is_stage1) {
250 if (have_stage1) {
251251 const softfloat = b.addStaticLibrary("softfloat", null);
252252 softfloat.setBuildMode(.ReleaseFast);
253253 softfloat.setTarget(target);
......@@ -359,7 +359,7 @@ pub fn build(b: *Builder) !void {
359359 exe_options.addOption(bool, "enable_tracy_callstack", tracy_callstack);
360360 exe_options.addOption(bool, "enable_tracy_allocation", tracy_allocation);
361361 exe_options.addOption(bool, "value_tracing", value_tracing);
362 exe_options.addOption(bool, "is_stage1", is_stage1);
362 exe_options.addOption(bool, "have_stage1", have_stage1);
363363 if (tracy) |tracy_path| {
364364 const client_cpp = fs.path.join(
365365 b.allocator,
......@@ -394,7 +394,7 @@ pub fn build(b: *Builder) !void {
394394 test_cases_options.addOption(bool, "enable_link_snapshots", enable_link_snapshots);
395395 test_cases_options.addOption(bool, "skip_non_native", skip_non_native);
396396 test_cases_options.addOption(bool, "skip_stage1", skip_stage1);
397 test_cases_options.addOption(bool, "is_stage1", is_stage1);
397 test_cases_options.addOption(bool, "have_stage1", have_stage1);
398398 test_cases_options.addOption(bool, "have_llvm", enable_llvm);
399399 test_cases_options.addOption(bool, "llvm_has_m68k", llvm_has_m68k);
400400 test_cases_options.addOption(bool, "llvm_has_csky", llvm_has_csky);
......@@ -455,7 +455,6 @@ pub fn build(b: *Builder) !void {
455455 skip_libc,
456456 skip_stage1,
457457 false,
458 is_stage1,
459458 ));
460459
461460 toolchain_step.dependOn(tests.addPkgTests(
......@@ -470,7 +469,6 @@ pub fn build(b: *Builder) !void {
470469 true, // skip_libc
471470 skip_stage1,
472471 true, // TODO get these all passing
473 is_stage1,
474472 ));
475473
476474 toolchain_step.dependOn(tests.addPkgTests(
......@@ -485,7 +483,6 @@ pub fn build(b: *Builder) !void {
485483 true, // skip_libc
486484 skip_stage1,
487485 true, // TODO get these all passing
488 is_stage1,
489486 ));
490487
491488 toolchain_step.dependOn(tests.addCompareOutputTests(b, test_filter, modes));
......@@ -525,7 +522,6 @@ pub fn build(b: *Builder) !void {
525522 skip_libc,
526523 skip_stage1,
527524 true, // TODO get these all passing
528 is_stage1,
529525 );
530526
531527 const test_step = b.step("test", "Run all the tests");
ci/azure/build.zig+5-5
......@@ -37,9 +37,9 @@ pub fn build(b: *Builder) !void {
3737 const docs_step = b.step("docs", "Build documentation");
3838 docs_step.dependOn(&docgen_cmd.step);
3939
40 const is_stage1 = b.option(bool, "stage1", "Build the stage1 compiler, put stage2 behind a feature flag") orelse false;
40 const have_stage1 = b.option(bool, "enable-stage1", "Include the stage1 compiler behind a feature flag") orelse false;
4141 const static_llvm = b.option(bool, "static-llvm", "Disable integration with system-installed LLVM, Clang, LLD, and libc++") orelse false;
42 const enable_llvm = b.option(bool, "enable-llvm", "Build self-hosted compiler with LLVM backend enabled") orelse (is_stage1 or static_llvm);
42 const enable_llvm = b.option(bool, "enable-llvm", "Build self-hosted compiler with LLVM backend enabled") orelse (have_stage1 or static_llvm);
4343 const llvm_has_m68k = b.option(
4444 bool,
4545 "llvm-has-m68k",
......@@ -101,7 +101,7 @@ pub fn build(b: *Builder) !void {
101101 break :blk 4;
102102 };
103103
104 const main_file: ?[]const u8 = if (is_stage1) null else "src/main.zig";
104 const main_file: ?[]const u8 = if (have_stage1) null else "src/main.zig";
105105
106106 const exe = b.addExecutable("zig", main_file);
107107 exe.strip = strip;
......@@ -190,7 +190,7 @@ pub fn build(b: *Builder) !void {
190190 if (enable_llvm) {
191191 const cmake_cfg = if (static_llvm) null else findAndParseConfigH(b, config_h_path_option);
192192
193 if (is_stage1) {
193 if (have_stage1) {
194194 const softfloat = b.addStaticLibrary("softfloat", null);
195195 softfloat.setBuildMode(.ReleaseFast);
196196 softfloat.setTarget(target);
......@@ -298,7 +298,7 @@ pub fn build(b: *Builder) !void {
298298 exe_options.addOption(bool, "enable_tracy_callstack", tracy_callstack);
299299 exe_options.addOption(bool, "enable_tracy_allocation", tracy_allocation);
300300 exe_options.addOption(bool, "value_tracing", value_tracing);
301 exe_options.addOption(bool, "is_stage1", is_stage1);
301 exe_options.addOption(bool, "have_stage1", have_stage1);
302302 if (tracy) |tracy_path| {
303303 const client_cpp = fs.path.join(
304304 b.allocator,
ci/azure/macos_script+6-11
......@@ -34,7 +34,7 @@ git fetch --tags
3434mkdir build
3535cd build
3636cmake .. \
37 -DCMAKE_INSTALL_PREFIX="$(pwd)/release" \
37 -DCMAKE_INSTALL_PREFIX="$(pwd)/stage2" \
3838 -DCMAKE_PREFIX_PATH="$PREFIX" \
3939 -DCMAKE_BUILD_TYPE=Release \
4040 -DZIG_TARGET_TRIPLE="$TARGET" \
......@@ -52,23 +52,18 @@ make $JOBS install
5252# Here we rebuild zig but this time using the Zig binary we just now produced to
5353# build zig1.o rather than relying on the one built with stage0. See
5454# https://github.com/ziglang/zig/issues/6830 for more details.
55cmake .. -DZIG_EXECUTABLE="$(pwd)/release/bin/zig"
55cmake .. -DZIG_EXECUTABLE="$(pwd)/stage2/bin/zig"
5656make $JOBS install
5757
58# Build stage2 standalone so that we can test stage2 against stage2 compiler-rt.
59release/bin/zig build -p stage2 -Denable-llvm
58stage2/bin/zig build -p release -Denable-llvm -Denable-stage1
6059
61stage2/bin/zig build test-behavior
62
63# TODO: upgrade these to test stage2 instead of stage1
64# TODO: upgrade these to test stage3 instead of stage2
65release/bin/zig build test-behavior -Denable-macos-sdk -Domit-stage2
6660release/bin/zig build test-compiler-rt -Denable-macos-sdk
61release/bin/zig build test-behavior -Denable-macos-sdk
6762release/bin/zig build test-std -Denable-macos-sdk
6863release/bin/zig build test-universal-libc -Denable-macos-sdk
6964release/bin/zig build test-compare-output -Denable-macos-sdk
7065release/bin/zig build test-standalone -Denable-macos-sdk
71release/bin/zig build test-stack-traces -Denable-macos-sdk
66release/bin/zig build test-stack-traces -Denable-macos-sdk -fstage1
7267release/bin/zig build test-cli -Denable-macos-sdk
7368release/bin/zig build test-asm-link -Denable-macos-sdk
7469release/bin/zig build test-translate-c -Denable-macos-sdk
......@@ -76,7 +71,7 @@ release/bin/zig build test-run-translated-c -Denable-macos-sdk
7671release/bin/zig build docs -Denable-macos-sdk
7772release/bin/zig build test-fmt -Denable-macos-sdk
7873release/bin/zig build test-cases -Denable-macos-sdk -Dsingle-threaded
79release/bin/zig build test-link -Denable-macos-sdk -Domit-stage2
74release/bin/zig build test-link -Denable-macos-sdk
8075
8176if [ "${BUILD_REASON}" != "PullRequest" ]; then
8277 mv ../LICENSE release/
ci/azure/pipelines.yml+1-3
......@@ -68,9 +68,7 @@ jobs:
6868 & "${ZIGPREFIXPATH}/bin/zig.exe" build `
6969 --prefix "$ZIGINSTALLDIR" `
7070 --search-prefix "$ZIGPREFIXPATH" `
71 -Dstage1 `
72 <# stage2 is omitted until we resolve https://github.com/ziglang/zig/issues/6485 #> `
73 -Domit-stage2 `
71 -Denable-stage1 `
7472 -Dstatic-llvm `
7573 -Drelease `
7674 -Dstrip `
ci/srht/freebsd_script+5-4
......@@ -38,10 +38,11 @@ cmake .. \
3838 -GNinja
3939samu install
4040
41# TODO ld.lld: error: undefined symbol: main
42# >>> referenced by crt1_c.c:75 (/usr/src/lib/csu/amd64/crt1_c.c:75)
43# >>> /usr/lib/crt1.o:(_start)
44#release/bin/zig test ../test/behavior.zig -fno-stage1 -fLLVM -I ../test
41# Here we rebuild zig but this time using the Zig binary we just now produced to
42# build zig1.o rather than relying on the one built with stage0. This makes it
43# a stage3 build rather than a stage2 build.
44cmake .. -DZIG_EXECUTABLE="$PREFIX/bin/zig"
45samu install
4546
4647# Here we skip some tests to save time.
4748release/bin/zig build test -Dskip-stage1 -Dskip-non-native
ci/zinc/linux_test.sh+23-25
......@@ -33,41 +33,39 @@ unset CXX
3333
3434ninja install
3535
36STAGE1_ZIG="$DEBUG_STAGING/bin/zig"
37
3836# Here we rebuild zig but this time using the Zig binary we just now produced to
3937# build zig1.o rather than relying on the one built with stage0. See
4038# https://github.com/ziglang/zig/issues/6830 for more details.
41cmake .. -DZIG_EXECUTABLE="$STAGE1_ZIG"
39cmake .. -DZIG_EXECUTABLE="$DEBUG_STAGING/bin/zig"
4240ninja install
4341
4442cd $WORKSPACE
4543
44"$DEBUG_STAGING/bin/zig" build -p stage3 -Denable-stage1 -Dstatic-llvm -Dtarget=native-native-musl --search-prefix "$DEPS_LOCAL"
45
46# simultaneously test building self-hosted without LLVM and with 32-bit arm
47stage3/bin/zig build -Dtarget=arm-linux-musleabihf
48
4649echo "Looking for non-conforming code formatting..."
4750echo "Formatting errors can be fixed by running 'zig fmt' on the files printed here."
48$STAGE1_ZIG fmt --check . --exclude test/cases/
49
50$STAGE1_ZIG build -p stage2 -Dstatic-llvm -Dtarget=native-native-musl --search-prefix "$DEPS_LOCAL"
51stage2/bin/zig build -p stage3 -Dstatic-llvm -Dtarget=native-native-musl --search-prefix "$DEPS_LOCAL"
52stage3/bin/zig build # test building self-hosted without LLVM
53stage3/bin/zig build -Dtarget=arm-linux-musleabihf # test building self-hosted for 32-bit arm
54
55stage3/bin/zig build test-compiler-rt -fqemu -fwasmtime -Denable-llvm
56stage3/bin/zig build test-behavior -fqemu -fwasmtime -Denable-llvm
57stage3/bin/zig build test-std -fqemu -fwasmtime -Denable-llvm
58stage3/bin/zig build test-universal-libc -fqemu -fwasmtime -Denable-llvm
59stage3/bin/zig build test-compare-output -fqemu -fwasmtime -Denable-llvm
60stage3/bin/zig build test-asm-link -fqemu -fwasmtime -Denable-llvm
61stage3/bin/zig build test-fmt -fqemu -fwasmtime -Denable-llvm
62stage3/bin/zig build test-translate-c -fqemu -fwasmtime -Denable-llvm
63stage3/bin/zig build test-run-translated-c -fqemu -fwasmtime -Denable-llvm
64stage3/bin/zig build test-standalone -fqemu -fwasmtime -Denable-llvm
65stage3/bin/zig build test-cli -fqemu -fwasmtime -Denable-llvm
51stage3/bin/zig fmt --check . --exclude test/cases/
52
53stage3/bin/zig build test-compiler-rt -fqemu -fwasmtime -Dstatic-llvm -Dtarget=native-native-musl --search-prefix "$DEPS_LOCAL"
54stage3/bin/zig build test-behavior -fqemu -fwasmtime -Dstatic-llvm -Dtarget=native-native-musl --search-prefix "$DEPS_LOCAL"
55stage3/bin/zig build test-std -fqemu -fwasmtime -Dstatic-llvm -Dtarget=native-native-musl --search-prefix "$DEPS_LOCAL"
56stage3/bin/zig build test-universal-libc -fqemu -fwasmtime -Dstatic-llvm -Dtarget=native-native-musl --search-prefix "$DEPS_LOCAL"
57stage3/bin/zig build test-compare-output -fqemu -fwasmtime -Dstatic-llvm -Dtarget=native-native-musl --search-prefix "$DEPS_LOCAL"
58stage3/bin/zig build test-asm-link -fqemu -fwasmtime -Dstatic-llvm -Dtarget=native-native-musl --search-prefix "$DEPS_LOCAL"
59stage3/bin/zig build test-fmt -fqemu -fwasmtime -Dstatic-llvm -Dtarget=native-native-musl --search-prefix "$DEPS_LOCAL"
60stage3/bin/zig build test-translate-c -fqemu -fwasmtime -Dstatic-llvm -Dtarget=native-native-musl --search-prefix "$DEPS_LOCAL"
61stage3/bin/zig build test-run-translated-c -fqemu -fwasmtime -Dstatic-llvm -Dtarget=native-native-musl --search-prefix "$DEPS_LOCAL"
62stage3/bin/zig build test-standalone -fqemu -fwasmtime -Dstatic-llvm -Dtarget=native-native-musl --search-prefix "$DEPS_LOCAL"
63stage3/bin/zig build test-cli -fqemu -fwasmtime -Dstatic-llvm -Dtarget=native-native-musl --search-prefix "$DEPS_LOCAL"
6664stage3/bin/zig build test-cases -fqemu -fwasmtime -Dstatic-llvm -Dtarget=native-native-musl --search-prefix "$DEPS_LOCAL"
67stage3/bin/zig build test-link -fqemu -fwasmtime -Denable-llvm
65stage3/bin/zig build test-link -fqemu -fwasmtime -Dstatic-llvm -Dtarget=native-native-musl --search-prefix "$DEPS_LOCAL"
66stage3/bin/zig build docs -fqemu -fwasmtime -Dstatic-llvm -Dtarget=native-native-musl --search-prefix "$DEPS_LOCAL"
6867
69$STAGE1_ZIG build test-stack-traces -fqemu -fwasmtime
70$STAGE1_ZIG build docs -fqemu -fwasmtime
68stage3/bin/zig build test-stack-traces -fqemu -fwasmtime -fstage1
7169
7270# Produce the experimental std lib documentation.
7371mkdir -p "$RELEASE_STAGING/docs/std"
......@@ -87,7 +85,7 @@ stage3/bin/zig build \
8785 -Drelease \
8886 -Dstrip \
8987 -Dtarget="$TARGET" \
90 -Dstage1
88 -Denable-stage1
9189
9290# Explicit exit helps show last command duration.
9391exit
doc/docgen.zig+31
......@@ -285,6 +285,7 @@ const Code = struct {
285285 link_objects: []const []const u8,
286286 target_str: ?[]const u8,
287287 link_libc: bool,
288 backend_stage1: bool,
288289 link_mode: ?std.builtin.LinkMode,
289290 disable_cache: bool,
290291 verbose_cimport: bool,
......@@ -554,6 +555,7 @@ fn genToc(allocator: Allocator, tokenizer: *Tokenizer) !Toc {
554555 var link_mode: ?std.builtin.LinkMode = null;
555556 var disable_cache = false;
556557 var verbose_cimport = false;
558 var backend_stage1 = false;
557559
558560 const source_token = while (true) {
559561 const content_tok = try eatToken(tokenizer, Token.Id.Content);
......@@ -586,6 +588,8 @@ fn genToc(allocator: Allocator, tokenizer: *Tokenizer) !Toc {
586588 link_libc = true;
587589 } else if (mem.eql(u8, end_tag_name, "link_mode_dynamic")) {
588590 link_mode = .Dynamic;
591 } else if (mem.eql(u8, end_tag_name, "backend_stage1")) {
592 backend_stage1 = true;
589593 } else if (mem.eql(u8, end_tag_name, "code_end")) {
590594 _ = try eatToken(tokenizer, Token.Id.BracketClose);
591595 break content_tok;
......@@ -609,6 +613,7 @@ fn genToc(allocator: Allocator, tokenizer: *Tokenizer) !Toc {
609613 .link_objects = link_objects.toOwnedSlice(),
610614 .target_str = target_str,
611615 .link_libc = link_libc,
616 .backend_stage1 = backend_stage1,
612617 .link_mode = link_mode,
613618 .disable_cache = disable_cache,
614619 .verbose_cimport = verbose_cimport,
......@@ -1187,6 +1192,9 @@ fn printShell(out: anytype, shell_content: []const u8) !void {
11871192 try out.writeAll("</samp></pre></figure>");
11881193}
11891194
1195// Override this to skip to later tests
1196const debug_start_line = 0;
1197
11901198fn genHtml(
11911199 allocator: Allocator,
11921200 tokenizer: *Tokenizer,
......@@ -1266,6 +1274,13 @@ fn genHtml(
12661274 continue;
12671275 }
12681276
1277 if (debug_start_line > 0) {
1278 const loc = tokenizer.getTokenLocation(code.source_token);
1279 if (debug_start_line > loc.line) {
1280 continue;
1281 }
1282 }
1283
12691284 const raw_source = tokenizer.buffer[code.source_token.start..code.source_token.end];
12701285 const trimmed_raw_source = mem.trim(u8, raw_source, " \n");
12711286 const tmp_source_file_name = try fs.path.join(
......@@ -1311,6 +1326,10 @@ fn genHtml(
13111326 try build_args.append("-lc");
13121327 try shell_out.print("-lc ", .{});
13131328 }
1329 if (code.backend_stage1) {
1330 try build_args.append("-fstage1");
1331 try shell_out.print("-fstage1", .{});
1332 }
13141333 const target = try std.zig.CrossTarget.parse(.{
13151334 .arch_os_abi = code.target_str orelse "native",
13161335 });
......@@ -1443,6 +1462,10 @@ fn genHtml(
14431462 try test_args.append("-lc");
14441463 try shell_out.print("-lc ", .{});
14451464 }
1465 if (code.backend_stage1) {
1466 try test_args.append("-fstage1");
1467 try shell_out.print("-fstage1", .{});
1468 }
14461469 if (code.target_str) |triple| {
14471470 try test_args.appendSlice(&[_][]const u8{ "-target", triple });
14481471 try shell_out.print("-target {s} ", .{triple});
......@@ -1490,6 +1513,14 @@ fn genHtml(
14901513 try shell_out.print("-O {s} ", .{@tagName(code.mode)});
14911514 },
14921515 }
1516 if (code.link_libc) {
1517 try test_args.append("-lc");
1518 try shell_out.print("-lc ", .{});
1519 }
1520 if (code.backend_stage1) {
1521 try test_args.append("-fstage1");
1522 try shell_out.print("-fstage1", .{});
1523 }
14931524 const result = try ChildProcess.exec(.{
14941525 .allocator = allocator,
14951526 .argv = test_args.items,
doc/langref.html.in+69-109
......@@ -1188,6 +1188,7 @@ test "this will be skipped" {
11881188 (The evented IO mode is enabled using the <kbd>--test-evented-io</kbd> command line parameter.)
11891189 </p>
11901190 {#code_begin|test|async_skip#}
1191 {#backend_stage1#}
11911192const std = @import("std");
11921193
11931194test "async skip test" {
......@@ -2768,7 +2769,7 @@ test "comptime @intToPtr" {
27682769 }
27692770}
27702771 {#code_end#}
2771 {#see_also|Optional Pointers|@intToPtr|@ptrToInt|C Pointers|Pointers to Zero Bit Types#}
2772 {#see_also|Optional Pointers|@intToPtr|@ptrToInt|C Pointers#}
27722773 {#header_open|volatile#}
27732774 <p>Loads and stores are assumed to not have side effects. If a given load or store
27742775 should have side effects, such as Memory Mapped Input/Output (MMIO), use {#syntax#}volatile{#endsyntax#}.
......@@ -2862,19 +2863,22 @@ var foo: u8 align(4) = 100;
28622863test "global variable alignment" {
28632864 try expect(@typeInfo(@TypeOf(&foo)).Pointer.alignment == 4);
28642865 try expect(@TypeOf(&foo) == *align(4) u8);
2865 const as_pointer_to_array: *[1]u8 = &foo;
2866 const as_slice: []u8 = as_pointer_to_array;
2867 try expect(@TypeOf(as_slice) == []align(4) u8);
2866 const as_pointer_to_array: *align(4) [1]u8 = &foo;
2867 const as_slice: []align(4) u8 = as_pointer_to_array;
2868 const as_unaligned_slice: []u8 = as_slice;
2869 try expect(as_unaligned_slice[0] == 100);
28682870}
28692871
2870fn derp() align(@sizeOf(usize) * 2) i32 { return 1234; }
2872fn derp() align(@sizeOf(usize) * 2) i32 {
2873 return 1234;
2874}
28712875fn noop1() align(1) void {}
28722876fn noop4() align(4) void {}
28732877
28742878test "function alignment" {
28752879 try expect(derp() == 1234);
2876 try expect(@TypeOf(noop1) == fn() align(1) void);
2877 try expect(@TypeOf(noop4) == fn() align(4) void);
2880 try expect(@TypeOf(noop1) == fn () align(1) void);
2881 try expect(@TypeOf(noop4) == fn () align(4) void);
28782882 noop1();
28792883 noop4();
28802884}
......@@ -3336,6 +3340,7 @@ fn doTheTest() !void {
33363340 Zig allows the address to be taken of a non-byte-aligned field:
33373341 </p>
33383342 {#code_begin|test|pointer_to_non-byte_aligned_field#}
3343 {#backend_stage1#}
33393344const std = @import("std");
33403345const expect = std.testing.expect;
33413346
......@@ -3391,7 +3396,8 @@ fn bar(x: *const u3) u3 {
33913396 <p>
33923397 Pointers to non-ABI-aligned fields share the same address as the other fields within their host integer:
33933398 </p>
3394 {#code_begin|test|pointer_to_non-bit_aligned_field#}
3399 {#code_begin|test|packed_struct_field_addrs#}
3400 {#backend_stage1#}
33953401const std = @import("std");
33963402const expect = std.testing.expect;
33973403
......@@ -3407,7 +3413,7 @@ var bit_field = BitField{
34073413 .c = 3,
34083414};
34093415
3410test "pointer to non-bit-aligned field" {
3416test "pointers of sub-byte-aligned fields share addresses" {
34113417 try expect(@ptrToInt(&bit_field.a) == @ptrToInt(&bit_field.b));
34123418 try expect(@ptrToInt(&bit_field.a) == @ptrToInt(&bit_field.c));
34133419}
......@@ -3438,20 +3444,22 @@ test "pointer to non-bit-aligned field" {
34383444}
34393445 {#code_end#}
34403446 <p>
3441 Packed structs have 1-byte alignment. However if you have an overaligned pointer to a packed struct,
3442 Zig should correctly understand the alignment of fields. However there is
3443 <a href="https://github.com/ziglang/zig/issues/1994">a bug</a>:
3447 Packed structs have the same alignment as their backing integer, however, overaligned
3448 pointers to packed structs can override this:
34443449 </p>
3445 {#code_begin|test_err|expected type '*u32', found '*align(1) u32'#}
3450 {#code_begin|test|overaligned_packed_struct#}
3451const std = @import("std");
3452const expect = std.testing.expect;
3453
34463454const S = packed struct {
34473455 a: u32,
34483456 b: u32,
34493457};
34503458test "overaligned pointer to packed struct" {
3451 var foo: S align(4) = undefined;
3459 var foo: S align(4) = .{ .a = 1, .b = 2 };
34523460 const ptr: *align(4) S = &foo;
34533461 const ptr_to_b: *u32 = &ptr.b;
3454 _ = ptr_to_b;
3462 try expect(ptr_to_b.* == 2);
34553463}
34563464 {#code_end#}
34573465 <p>When this bug is fixed, the above test in the documentation will unexpectedly pass, which will
......@@ -3698,7 +3706,7 @@ test "@tagName" {
36983706 <p>
36993707 By default, enums are not guaranteed to be compatible with the C ABI:
37003708 </p>
3701 {#code_begin|obj_err|parameter of type 'Foo' not allowed in function with calling convention 'C'#}
3709 {#code_begin|obj_err|parameter of type 'test.Foo' not allowed in function with calling convention 'C'#}
37023710const Foo = enum { a, b, c };
37033711export fn entry(foo: Foo) void { _ = foo; }
37043712 {#code_end#}
......@@ -4004,7 +4012,7 @@ fn makeNumber() Number {
40044012 This is typically used for type safety when interacting with C code that does not expose struct details.
40054013 Example:
40064014 </p>
4007 {#code_begin|test_err|expected type '*Derp', found '*Wat'#}
4015 {#code_begin|test_err|expected type '*test.Derp', found '*test.Wat'#}
40084016const Derp = opaque {};
40094017const Wat = opaque {};
40104018
......@@ -4203,7 +4211,7 @@ test "switch on tagged union" {
42034211 When a {#syntax#}switch{#endsyntax#} expression does not have an {#syntax#}else{#endsyntax#} clause,
42044212 it must exhaustively list all the possible values. Failure to do so is a compile error:
42054213 </p>
4206 {#code_begin|test_err|not handled in switch#}
4214 {#code_begin|test_err|unhandled enumeration value#}
42074215const Color = enum {
42084216 auto,
42094217 off,
......@@ -5026,17 +5034,9 @@ test "function" {
50265034 try expect(do_op(sub2, 5, 6) == -1);
50275035}
50285036 {#code_end#}
5029 <p>Function values are like pointers:</p>
5030 {#code_begin|obj#}
5031const assert = @import("std").debug.assert;
5032
5033comptime {
5034 assert(@TypeOf(foo) == fn()void);
5035 assert(@sizeOf(fn()void) == @sizeOf(?fn()void));
5036}
5037
5038fn foo() void { }
5039 {#code_end#}
5037 <p>There is a difference between a function <em>body</em> and a function <em>pointer</em>.
5038 Function bodies are {#link|comptime#}-only types while function {#link|Pointers#} may be
5039 runtime-known.</p>
50405040 {#header_open|Pass-by-value Parameters#}
50415041 <p>
50425042 Primitive types such as {#link|Integers#} and {#link|Floats#} passed as parameters
......@@ -6123,10 +6123,11 @@ test "float widening" {
61236123 two choices about the coercion.
61246124 </p>
61256125 <ul>
6126 <li> Cast {#syntax#}54.0{#endsyntax#} to {#syntax#}comptime_int{#endsyntax#} resulting in {#syntax#}@as(comptime_int, 10){#endsyntax#}, which is casted to {#syntax#}@as(f32, 10){#endsyntax#}</li>
6127 <li> Cast {#syntax#}5{#endsyntax#} to {#syntax#}comptime_float{#endsyntax#} resulting in {#syntax#}@as(comptime_float, 10.8){#endsyntax#}, which is casted to {#syntax#}@as(f32, 10.8){#endsyntax#}</li>
6126 <li>Cast {#syntax#}54.0{#endsyntax#} to {#syntax#}comptime_int{#endsyntax#} resulting in {#syntax#}@as(comptime_int, 10){#endsyntax#}, which is casted to {#syntax#}@as(f32, 10){#endsyntax#}</li>
6127 <li>Cast {#syntax#}5{#endsyntax#} to {#syntax#}comptime_float{#endsyntax#} resulting in {#syntax#}@as(comptime_float, 10.8){#endsyntax#}, which is casted to {#syntax#}@as(f32, 10.8){#endsyntax#}</li>
61286128 </ul>
61296129 {#code_begin|test_err#}
6130 {#backend_stage1#}
61306131// Compile time coercion of float to int
61316132test "implicit cast to comptime_int" {
61326133 var f: f32 = 54.0 / 5;
......@@ -6302,19 +6303,6 @@ test "coercion between unions and enums" {
63026303 {#code_end#}
63036304 {#see_also|union|enum#}
63046305 {#header_close#}
6305 {#header_open|Type Coercion: Zero Bit Types#}
6306 <p>{#link|Zero Bit Types#} may be coerced to single-item {#link|Pointers#},
6307 regardless of const.</p>
6308 <p>TODO document the reasoning for this</p>
6309 <p>TODO document whether vice versa should work and why</p>
6310 {#code_begin|test|coerce_zero_bit_types#}
6311test "coercion of zero bit types" {
6312 var x: void = {};
6313 var y: *void = x;
6314 _ = y;
6315}
6316 {#code_end#}
6317 {#header_close#}
63186306 {#header_open|Type Coercion: undefined#}
63196307 <p>{#link|undefined#} can be cast to any type.</p>
63206308 {#header_close#}
......@@ -6467,7 +6455,6 @@ test "peer type resolution: *const T and ?*T" {
64676455 <li>An {#link|enum#} with only 1 tag.</li>
64686456 <li>A {#link|struct#} with all fields being zero bit types.</li>
64696457 <li>A {#link|union#} with only 1 field which is a zero bit type.</li>
6470 <li>{#link|Pointers to Zero Bit Types#} are themselves zero bit types.</li>
64716458 </ul>
64726459 <p>
64736460 These types can only ever have one possible value, and thus
......@@ -6527,7 +6514,7 @@ test "turn HashMap into a set with void" {
65276514 <p>
65286515 Expressions of type {#syntax#}void{#endsyntax#} are the only ones whose value can be ignored. For example:
65296516 </p>
6530 {#code_begin|test_err|expression value is ignored#}
6517 {#code_begin|test_err|ignored#}
65316518test "ignoring expression value" {
65326519 foo();
65336520}
......@@ -6553,37 +6540,6 @@ fn foo() i32 {
65536540}
65546541 {#code_end#}
65556542 {#header_close#}
6556
6557 {#header_open|Pointers to Zero Bit Types#}
6558 <p>Pointers to zero bit types also have zero bits. They always compare equal to each other:</p>
6559 {#code_begin|test|pointers_to_zero_bits#}
6560const std = @import("std");
6561const expect = std.testing.expect;
6562
6563test "pointer to empty struct" {
6564 const Empty = struct {};
6565 var a = Empty{};
6566 var b = Empty{};
6567 var ptr_a = &a;
6568 var ptr_b = &b;
6569 comptime try expect(ptr_a == ptr_b);
6570}
6571 {#code_end#}
6572 <p>The type being pointed to can only ever be one value; therefore loads and stores are
6573 never generated. {#link|ptrToInt#} and {#link|intToPtr#} are not allowed:</p>
6574 {#code_begin|test_err#}
6575const Empty = struct {};
6576
6577test "@ptrToInt for pointer to zero bit type" {
6578 var a = Empty{};
6579 _ = @ptrToInt(&a);
6580}
6581
6582test "@intToPtr for pointer to zero bit type" {
6583 _ = @intToPtr(*Empty, 0x1);
6584}
6585 {#code_end#}
6586 {#header_close#}
65876543 {#header_close#}
65886544
65896545 {#header_open|Result Location Semantics#}
......@@ -6666,7 +6622,7 @@ fn gimmeTheBiggerInteger(a: u64, b: u64) u64 {
66666622 <p>
66676623 For example, if we were to introduce another function to the above snippet:
66686624 </p>
6669 {#code_begin|test_err|values of type 'type' must be comptime known#}
6625 {#code_begin|test_err|value with comptime only type 'type' depends on runtime control flow#}
66706626fn max(comptime T: type, a: T, b: T) T {
66716627 return if (a > b) a else b;
66726628}
......@@ -6692,7 +6648,7 @@ fn foo(condition: bool) void {
66926648 <p>
66936649 For example:
66946650 </p>
6695 {#code_begin|test_err|operator not allowed for type 'bool'#}
6651 {#code_begin|test_err|operator > not allowed for type 'bool'#}
66966652fn max(comptime T: type, a: T, b: T) T {
66976653 return if (a > b) a else b;
66986654}
......@@ -6837,7 +6793,7 @@ fn performFn(start_value: i32) i32 {
68376793 use a {#syntax#}comptime{#endsyntax#} expression to guarantee that the expression will be evaluated at compile-time.
68386794 If this cannot be accomplished, the compiler will emit an error. For example:
68396795 </p>
6840 {#code_begin|test_err|unable to evaluate constant expression#}
6796 {#code_begin|test_err|comptime call of extern function#}
68416797extern fn exit() noreturn;
68426798
68436799test "foo" {
......@@ -6889,7 +6845,7 @@ test "fibonacci" {
68896845 <p>
68906846 Imagine if we had forgotten the base case of the recursive function and tried to run the tests:
68916847 </p>
6892 {#code_begin|test_err|operation caused overflow#}
6848 {#code_begin|test_err|overflow of integer type#}
68936849const expect = @import("std").testing.expect;
68946850
68956851fn fibonacci(index: u32) u32 {
......@@ -6913,7 +6869,8 @@ test "fibonacci" {
69136869 But what would have happened if we used a signed integer?
69146870 </p>
69156871 {#code_begin|test_err|evaluation exceeded 1000 backwards branches#}
6916const expect = @import("std").testing.expect;
6872 {#backend_stage1#}
6873const assert = @import("std").debug.assert;
69176874
69186875fn fibonacci(index: i32) i32 {
69196876 //if (index < 2) return index;
......@@ -6922,7 +6879,7 @@ fn fibonacci(index: i32) i32 {
69226879
69236880test "fibonacci" {
69246881 comptime {
6925 try expect(fibonacci(7) == 13);
6882 try assert(fibonacci(7) == 13);
69266883 }
69276884}
69286885 {#code_end#}
......@@ -6935,8 +6892,8 @@ test "fibonacci" {
69356892 <p>
69366893 What if we fix the base case, but put the wrong value in the {#syntax#}expect{#endsyntax#} line?
69376894 </p>
6938 {#code_begin|test_err|test "fibonacci"... FAIL (TestUnexpectedResult)#}
6939const expect = @import("std").testing.expect;
6895 {#code_begin|test_err|reached unreachable#}
6896const assert = @import("std").debug.assert;
69406897
69416898fn fibonacci(index: i32) i32 {
69426899 if (index < 2) return index;
......@@ -6945,16 +6902,10 @@ fn fibonacci(index: i32) i32 {
69456902
69466903test "fibonacci" {
69476904 comptime {
6948 try expect(fibonacci(7) == 99999);
6905 try assert(fibonacci(7) == 99999);
69496906 }
69506907}
69516908 {#code_end#}
6952 <p>
6953 What happened is Zig started interpreting the {#syntax#}expect{#endsyntax#} function with the
6954 parameter {#syntax#}ok{#endsyntax#} set to {#syntax#}false{#endsyntax#}. When the interpreter hit
6955 {#syntax#}@panic{#endsyntax#} it emitted a compile error because a panic during compile
6956 causes a compile error if it is detected at compile-time.
6957 </p>
69586909
69596910 <p>
69606911 At container level (outside of any function), all expressions are implicitly
......@@ -7280,6 +7231,7 @@ pub fn main() void {
72807231 </p>
72817232 {#code_begin|exe#}
72827233 {#target_linux_x86_64#}
7234 {#backend_stage1#}
72837235pub fn main() noreturn {
72847236 const msg = "hello world\n";
72857237 _ = syscall3(SYS_write, STDOUT_FILENO, @ptrToInt(msg), msg.len);
......@@ -7497,6 +7449,7 @@ test "global assembly" {
74977449 or resumer (in the case of subsequent suspensions).
74987450 </p>
74997451 {#code_begin|test|suspend_no_resume#}
7452 {#backend_stage1#}
75007453const std = @import("std");
75017454const expect = std.testing.expect;
75027455
......@@ -7524,6 +7477,7 @@ fn func() void {
75247477 {#link|@frame#} provides access to the async function frame pointer.
75257478 </p>
75267479 {#code_begin|test|async_suspend_block#}
7480 {#backend_stage1#}
75277481const std = @import("std");
75287482const expect = std.testing.expect;
75297483
......@@ -7562,6 +7516,7 @@ fn testSuspendBlock() void {
75627516 never returns to its resumer and continues executing.
75637517 </p>
75647518 {#code_begin|test|resume_from_suspend#}
7519 {#backend_stage1#}
75657520const std = @import("std");
75667521const expect = std.testing.expect;
75677522
......@@ -7598,6 +7553,7 @@ fn testResumeFromSuspend(my_result: *i32) void {
75987553 and the return value of the async function would be lost.
75997554 </p>
76007555 {#code_begin|test|async_await#}
7556 {#backend_stage1#}
76017557const std = @import("std");
76027558const expect = std.testing.expect;
76037559
......@@ -7642,6 +7598,7 @@ fn func() void {
76427598 return value directly from the target function's frame.
76437599 </p>
76447600 {#code_begin|test|async_await_sequence#}
7601 {#backend_stage1#}
76457602const std = @import("std");
76467603const expect = std.testing.expect;
76477604
......@@ -7695,6 +7652,7 @@ fn seq(c: u8) void {
76957652 {#syntax#}async{#endsyntax#}/{#syntax#}await{#endsyntax#} usage:
76967653 </p>
76977654 {#code_begin|exe|async#}
7655 {#backend_stage1#}
76987656const std = @import("std");
76997657const Allocator = std.mem.Allocator;
77007658
......@@ -7773,6 +7731,7 @@ fn readFile(allocator: Allocator, filename: []const u8) ![]u8 {
77737731 observe the same behavior, with one tiny difference:
77747732 </p>
77757733 {#code_begin|exe|blocking#}
7734 {#backend_stage1#}
77767735const std = @import("std");
77777736const Allocator = std.mem.Allocator;
77787737
......@@ -7910,6 +7869,7 @@ comptime {
79107869 {#syntax#}await{#endsyntax#} will copy the result from {#syntax#}result_ptr{#endsyntax#}.
79117870 </p>
79127871 {#code_begin|test|async_struct_field_fn_pointer#}
7872 {#backend_stage1#}
79137873const std = @import("std");
79147874const expect = std.testing.expect;
79157875
......@@ -8677,6 +8637,7 @@ test "decl access by string" {
86778637 allows one to, for example, heap-allocate an async function frame:
86788638 </p>
86798639 {#code_begin|test|heap_allocated_frame#}
8640 {#backend_stage1#}
86808641const std = @import("std");
86818642
86828643test "heap allocated frame" {
......@@ -9423,12 +9384,6 @@ const std = @import("std");
94239384const expect = std.testing.expect;
94249385
94259386test "vector @reduce" {
9426 // This test regressed with LLVM 14:
9427 // https://github.com/llvm/llvm-project/issues/55522
9428 // We'll skip this test unless the self-hosted compiler is being used.
9429 // After LLVM 15 is released we can delete this line.
9430 if (@import("builtin").zig_backend == .stage1) return;
9431
94329387 const value = @Vector(4, i32){ 1, -1, 1, -1 };
94339388 const result = value > @splat(4, @as(i32, 0));
94349389 // result is { true, false, true, false };
......@@ -9938,7 +9893,7 @@ pub fn main() void {
99389893 {#header_close#}
99399894 {#header_open|Index out of Bounds#}
99409895 <p>At compile-time:</p>
9941 {#code_begin|test_err|index 5 outside array of size 5#}
9896 {#code_begin|test_err|index 5 outside array of length 5#}
99429897comptime {
99439898 const array: [5]u8 = "hello".*;
99449899 const garbage = array[5];
......@@ -9959,9 +9914,9 @@ fn foo(x: []const u8) u8 {
99599914 {#header_close#}
99609915 {#header_open|Cast Negative Number to Unsigned Integer#}
99619916 <p>At compile-time:</p>
9962 {#code_begin|test_err|attempt to cast negative value to unsigned integer#}
9917 {#code_begin|test_err|type 'u32' cannot represent integer value '-1'#}
99639918comptime {
9964 const value: i32 = -1;
9919 var value: i32 = -1;
99659920 const unsigned = @intCast(u32, value);
99669921 _ = unsigned;
99679922}
......@@ -9982,7 +9937,7 @@ pub fn main() void {
99829937 {#header_close#}
99839938 {#header_open|Cast Truncates Data#}
99849939 <p>At compile-time:</p>
9985 {#code_begin|test_err|cast from 'u16' to 'u8' truncates bits#}
9940 {#code_begin|test_err|type 'u8' cannot represent integer value '300'#}
99869941comptime {
99879942 const spartan_count: u16 = 300;
99889943 const byte = @intCast(u8, spartan_count);
......@@ -10017,7 +9972,7 @@ pub fn main() void {
100179972 <li>{#link|@divExact#} (division)</li>
100189973 </ul>
100199974 <p>Example with addition at compile-time:</p>
10020 {#code_begin|test_err|operation caused overflow#}
9975 {#code_begin|test_err|overflow of integer type 'u8' with value '256'#}
100219976comptime {
100229977 var byte: u8 = 255;
100239978 byte += 1;
......@@ -10118,6 +10073,7 @@ test "wraparound addition and subtraction" {
1011810073 {#header_open|Exact Left Shift Overflow#}
1011910074 <p>At compile-time:</p>
1012010075 {#code_begin|test_err|operation caused overflow#}
10076 {#backend_stage1#}
1012110077comptime {
1012210078 const x = @shlExact(@as(u8, 0b01010101), 2);
1012310079 _ = x;
......@@ -10137,6 +10093,7 @@ pub fn main() void {
1013710093 {#header_open|Exact Right Shift Overflow#}
1013810094 <p>At compile-time:</p>
1013910095 {#code_begin|test_err|exact shift shifted out 1 bits#}
10096 {#backend_stage1#}
1014010097comptime {
1014110098 const x = @shrExact(@as(u8, 0b10101010), 2);
1014210099 _ = x;
......@@ -10200,6 +10157,7 @@ pub fn main() void {
1020010157 {#header_open|Exact Division Remainder#}
1020110158 <p>At compile-time:</p>
1020210159 {#code_begin|test_err|exact division had a remainder#}
10160 {#backend_stage1#}
1020310161comptime {
1020410162 const a: u32 = 10;
1020510163 const b: u32 = 3;
......@@ -10302,7 +10260,7 @@ fn getNumberOrFail() !i32 {
1030210260 {#header_close#}
1030310261 {#header_open|Invalid Error Code#}
1030410262 <p>At compile-time:</p>
10305 {#code_begin|test_err|integer value 11 represents no error#}
10263 {#code_begin|test_err|integer value '11' represents no error#}
1030610264comptime {
1030710265 const err = error.AnError;
1030810266 const number = @errorToInt(err) + 10;
......@@ -10324,7 +10282,7 @@ pub fn main() void {
1032410282 {#header_close#}
1032510283 {#header_open|Invalid Enum Cast#}
1032610284 <p>At compile-time:</p>
10327 {#code_begin|test_err|has no tag matching integer value 3#}
10285 {#code_begin|test_err|enum 'test.Foo' has no tag with value '3'#}
1032810286const Foo = enum {
1032910287 a,
1033010288 b,
......@@ -10356,7 +10314,7 @@ pub fn main() void {
1035610314
1035710315 {#header_open|Invalid Error Set Cast#}
1035810316 <p>At compile-time:</p>
10359 {#code_begin|test_err|error.B not a member of error set 'Set2'#}
10317 {#code_begin|test_err|'error.B' not a member of error set 'error{A,C}'#}
1036010318const Set1 = error{
1036110319 A,
1036210320 B,
......@@ -10417,7 +10375,7 @@ fn foo(bytes: []u8) u32 {
1041710375 {#header_close#}
1041810376 {#header_open|Wrong Union Field Access#}
1041910377 <p>At compile-time:</p>
10420 {#code_begin|test_err|accessing union field 'float' while field 'int' is set#}
10378 {#code_begin|test_err|access of union field 'float' while field 'int' is active#}
1042110379comptime {
1042210380 var f = Foo{ .int = 42 };
1042310381 f.float = 12.34;
......@@ -10509,6 +10467,7 @@ fn bar(f: *Foo) void {
1050910467 </p>
1051010468 <p>At compile-time:</p>
1051110469 {#code_begin|test_err|null pointer casted to type#}
10470 {#backend_stage1#}
1051210471comptime {
1051310472 const opt_ptr: ?*i32 = null;
1051410473 const ptr = @ptrCast(*i32, opt_ptr);
......@@ -10551,7 +10510,8 @@ const expect = std.testing.expect;
1055110510
1055210511test "using an allocator" {
1055310512 var buffer: [100]u8 = undefined;
10554 const allocator = std.heap.FixedBufferAllocator.init(&buffer).allocator();
10513 var fba = std.heap.FixedBufferAllocator.init(&buffer);
10514 const allocator = fba.allocator();
1055510515 const result = try concat(allocator, "foo", "bar");
1055610516 try expect(std.mem.eql(u8, "foobar", result));
1055710517}
......@@ -10647,7 +10607,7 @@ pub fn main() !void {
1064710607 <p>String literals such as {#syntax#}"foo"{#endsyntax#} are in the global constant data section.
1064810608 This is why it is an error to pass a string literal to a mutable slice, like this:
1064910609 </p>
10650 {#code_begin|test_err|cannot cast pointer to array literal to slice type '[]u8'#}
10610 {#code_begin|test_err|expected type '[]u8', found '*const [5:0]u8'#}
1065110611fn foo(s: []u8) void {
1065210612 _ = s;
1065310613}
lib/std/builtin.zig+1-1
......@@ -866,7 +866,7 @@ pub fn panicUnwrapError(st: ?*StackTrace, err: anyerror) noreturn {
866866
867867pub fn panicOutOfBounds(index: usize, len: usize) noreturn {
868868 @setCold(true);
869 std.debug.panic("attempt to index out of bound: index {d}, len {d}", .{ index, len });
869 std.debug.panic("index out of bounds: index {d}, len {d}", .{ index, len });
870870}
871871
872872pub noinline fn returnError(st: *StackTrace) void {
src/Compilation.zig+7-22
......@@ -1040,22 +1040,7 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation {
10401040 const comp = try arena.create(Compilation);
10411041 const root_name = try arena.dupeZ(u8, options.root_name);
10421042
1043 const use_stage1 = options.use_stage1 orelse blk: {
1044 // Even though we may have no Zig code to compile (depending on `options.main_pkg`),
1045 // we may need to use stage1 for building compiler-rt and other dependencies.
1046
1047 if (options.use_llvm) |use_llvm| {
1048 if (!use_llvm) {
1049 break :blk false;
1050 }
1051 }
1052
1053 // If LLVM does not support the target, then we can't use it.
1054 if (!target_util.hasLlvmSupport(options.target, options.target.ofmt))
1055 break :blk false;
1056
1057 break :blk build_options.is_stage1;
1058 };
1043 const use_stage1 = options.use_stage1 orelse false;
10591044
10601045 const cache_mode = if (use_stage1 and !options.disable_lld_caching)
10611046 CacheMode.whole
......@@ -2211,7 +2196,7 @@ pub fn update(comp: *Compilation) !void {
22112196 comp.c_object_work_queue.writeItemAssumeCapacity(key);
22122197 }
22132198
2214 const use_stage1 = build_options.is_stage1 and comp.bin_file.options.use_stage1;
2199 const use_stage1 = build_options.have_stage1 and comp.bin_file.options.use_stage1;
22152200 if (comp.bin_file.options.module) |module| {
22162201 module.compile_log_text.shrinkAndFree(module.gpa, 0);
22172202 module.generation += 1;
......@@ -2387,7 +2372,7 @@ fn flush(comp: *Compilation, prog_node: *std.Progress.Node) !void {
23872372 };
23882373 comp.link_error_flags = comp.bin_file.errorFlags();
23892374
2390 const use_stage1 = build_options.is_stage1 and comp.bin_file.options.use_stage1;
2375 const use_stage1 = build_options.have_stage1 and comp.bin_file.options.use_stage1;
23912376 if (!use_stage1) {
23922377 if (comp.bin_file.options.module) |module| {
23932378 try link.File.C.flushEmitH(module);
......@@ -2845,7 +2830,7 @@ pub fn performAllTheWork(
28452830 comp.work_queue_wait_group.reset();
28462831 defer comp.work_queue_wait_group.wait();
28472832
2848 const use_stage1 = build_options.is_stage1 and comp.bin_file.options.use_stage1;
2833 const use_stage1 = build_options.have_stage1 and comp.bin_file.options.use_stage1;
28492834
28502835 {
28512836 const astgen_frame = tracy.namedFrame("astgen");
......@@ -3430,7 +3415,7 @@ pub fn cImport(comp: *Compilation, c_src: []const u8) !CImportResult {
34303415 var man = comp.obtainCObjectCacheManifest();
34313416 defer man.deinit();
34323417
3433 const use_stage1 = build_options.is_stage1 and comp.bin_file.options.use_stage1;
3418 const use_stage1 = build_options.have_stage1 and comp.bin_file.options.use_stage1;
34343419
34353420 man.hash.add(@as(u16, 0xb945)); // Random number to distinguish translate-c from compiling C objects
34363421 man.hash.add(use_stage1);
......@@ -4745,7 +4730,7 @@ pub fn generateBuiltinZigSource(comp: *Compilation, allocator: Allocator) Alloca
47454730
47464731 const target = comp.getTarget();
47474732 const generic_arch_name = target.cpu.arch.genericName();
4748 const use_stage1 = build_options.is_stage1 and comp.bin_file.options.use_stage1;
4733 const use_stage1 = build_options.have_stage1 and comp.bin_file.options.use_stage1;
47494734
47504735 const zig_backend: std.builtin.CompilerBackend = blk: {
47514736 if (use_stage1) break :blk .stage1;
......@@ -5032,7 +5017,7 @@ fn buildOutputFromZig(
50325017 .link_mode = .Static,
50335018 .function_sections = true,
50345019 .no_builtin = true,
5035 .use_stage1 = build_options.is_stage1 and comp.bin_file.options.use_stage1,
5020 .use_stage1 = build_options.have_stage1 and comp.bin_file.options.use_stage1,
50365021 .want_sanitize_c = false,
50375022 .want_stack_check = false,
50385023 .want_stack_protector = 0,
src/config.zig.in+1-1
......@@ -8,5 +8,5 @@ pub const enable_logging: bool = @ZIG_ENABLE_LOGGING_BOOL@;
88pub const enable_link_snapshots: bool = false;
99pub const enable_tracy = false;
1010pub const value_tracing = false;
11pub const is_stage1 = true;
11pub const have_stage1 = true;
1212pub const skip_non_native = false;
src/link.zig+2-2
......@@ -279,7 +279,7 @@ pub const File = struct {
279279 return &(try MachO.openPath(allocator, options)).base;
280280 }
281281
282 const use_stage1 = build_options.is_stage1 and options.use_stage1;
282 const use_stage1 = build_options.have_stage1 and options.use_stage1;
283283 if (use_stage1 or options.emit == null) {
284284 return switch (options.target.ofmt) {
285285 .coff => &(try Coff.createEmpty(allocator, options)).base,
......@@ -817,7 +817,7 @@ pub const File = struct {
817817 // If there is no Zig code to compile, then we should skip flushing the output file
818818 // because it will not be part of the linker line anyway.
819819 const module_obj_path: ?[]const u8 = if (base.options.module) |module| blk: {
820 const use_stage1 = build_options.is_stage1 and base.options.use_stage1;
820 const use_stage1 = build_options.have_stage1 and base.options.use_stage1;
821821 if (use_stage1) {
822822 const obj_basename = try std.zig.binNameAlloc(arena, .{
823823 .root_name = base.options.root_name,
src/link/Coff.zig+2-2
......@@ -411,7 +411,7 @@ pub fn createEmpty(gpa: Allocator, options: link.Options) !*Coff {
411411 };
412412
413413 const use_llvm = build_options.have_llvm and options.use_llvm;
414 const use_stage1 = build_options.is_stage1 and options.use_stage1;
414 const use_stage1 = build_options.have_stage1 and options.use_stage1;
415415 if (use_llvm and !use_stage1) {
416416 self.llvm_object = try LlvmObject.create(gpa, options);
417417 }
......@@ -949,7 +949,7 @@ fn linkWithLLD(self: *Coff, comp: *Compilation, prog_node: *std.Progress.Node) !
949949 // If there is no Zig code to compile, then we should skip flushing the output file because it
950950 // will not be part of the linker line anyway.
951951 const module_obj_path: ?[]const u8 = if (self.base.options.module) |module| blk: {
952 const use_stage1 = build_options.is_stage1 and self.base.options.use_stage1;
952 const use_stage1 = build_options.have_stage1 and self.base.options.use_stage1;
953953 if (use_stage1) {
954954 const obj_basename = try std.zig.binNameAlloc(arena, .{
955955 .root_name = self.base.options.root_name,
src/link/Elf.zig+1-1
......@@ -328,7 +328,7 @@ pub fn createEmpty(gpa: Allocator, options: link.Options) !*Elf {
328328 .page_size = page_size,
329329 };
330330 const use_llvm = build_options.have_llvm and options.use_llvm;
331 const use_stage1 = build_options.is_stage1 and options.use_stage1;
331 const use_stage1 = build_options.have_stage1 and options.use_stage1;
332332 if (use_llvm and !use_stage1) {
333333 self.llvm_object = try LlvmObject.create(gpa, options);
334334 }
src/link/MachO.zig+2-2
......@@ -272,7 +272,7 @@ pub const Export = struct {
272272pub fn openPath(allocator: Allocator, options: link.Options) !*MachO {
273273 assert(options.target.ofmt == .macho);
274274
275 const use_stage1 = build_options.is_stage1 and options.use_stage1;
275 const use_stage1 = build_options.have_stage1 and options.use_stage1;
276276 if (use_stage1 or options.emit == null) {
277277 return createEmpty(allocator, options);
278278 }
......@@ -363,7 +363,7 @@ pub fn createEmpty(gpa: Allocator, options: link.Options) !*MachO {
363363 const cpu_arch = options.target.cpu.arch;
364364 const page_size: u16 = if (cpu_arch == .aarch64) 0x4000 else 0x1000;
365365 const use_llvm = build_options.have_llvm and options.use_llvm;
366 const use_stage1 = build_options.is_stage1 and options.use_stage1;
366 const use_stage1 = build_options.have_stage1 and options.use_stage1;
367367
368368 const self = try gpa.create(MachO);
369369 errdefer gpa.destroy(self);
src/link/Wasm.zig+3-3
......@@ -356,7 +356,7 @@ pub fn createEmpty(gpa: Allocator, options: link.Options) !*Wasm {
356356 }
357357
358358 const use_llvm = build_options.have_llvm and options.use_llvm;
359 const use_stage1 = build_options.is_stage1 and options.use_stage1;
359 const use_stage1 = build_options.have_stage1 and options.use_stage1;
360360 if (use_llvm and !use_stage1) {
361361 self.llvm_object = try LlvmObject.create(gpa, options);
362362 }
......@@ -2593,7 +2593,7 @@ fn linkWithLLD(self: *Wasm, comp: *Compilation, prog_node: *std.Progress.Node) !
25932593 // If there is no Zig code to compile, then we should skip flushing the output file because it
25942594 // will not be part of the linker line anyway.
25952595 const module_obj_path: ?[]const u8 = if (self.base.options.module) |mod| blk: {
2596 const use_stage1 = build_options.is_stage1 and self.base.options.use_stage1;
2596 const use_stage1 = build_options.have_stage1 and self.base.options.use_stage1;
25972597 if (use_stage1) {
25982598 const obj_basename = try std.zig.binNameAlloc(arena, .{
25992599 .root_name = self.base.options.root_name,
......@@ -2803,7 +2803,7 @@ fn linkWithLLD(self: *Wasm, comp: *Compilation, prog_node: *std.Progress.Node) !
28032803 if (self.base.options.module) |mod| {
28042804 // when we use stage1, we use the exports that stage1 provided us.
28052805 // For stage2, we can directly retrieve them from the module.
2806 const use_stage1 = build_options.is_stage1 and self.base.options.use_stage1;
2806 const use_stage1 = build_options.have_stage1 and self.base.options.use_stage1;
28072807 if (use_stage1) {
28082808 for (comp.export_symbol_names.items) |symbol_name| {
28092809 try argv.append(try std.fmt.allocPrint(arena, "--export={s}", .{symbol_name}));
src/main.zig+1-1
......@@ -2989,7 +2989,7 @@ fn buildOutputType(
29892989 return std.io.getStdOut().writeAll(try comp.generateBuiltinZigSource(arena));
29902990 }
29912991 if (arg_mode == .translate_c) {
2992 const stage1_mode = use_stage1 orelse build_options.is_stage1;
2992 const stage1_mode = use_stage1 orelse false;
29932993 return cmdTranslateC(comp, arena, have_enable_cache, stage1_mode);
29942994 }
29952995
src/stage1.zig+1-1
......@@ -18,7 +18,7 @@ const target_util = @import("target.zig");
1818
1919comptime {
2020 assert(builtin.link_libc);
21 assert(build_options.is_stage1);
21 assert(build_options.have_stage1);
2222 assert(build_options.have_llvm);
2323 if (!builtin.is_test) {
2424 @export(main, .{ .name = "main" });
src/test.zig+1-1
......@@ -25,7 +25,7 @@ const skip_stage1 = builtin.zig_backend != .stage1 or build_options.skip_stage1;
2525const hr = "=" ** 80;
2626
2727test {
28 if (build_options.is_stage1) {
28 if (build_options.have_stage1) {
2929 @import("stage1.zig").os_init();
3030 }
3131
test/cases/safety/empty slice with sentinel out of bounds.zig +1-1
......@@ -2,7 +2,7 @@ const std = @import("std");
22
33pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn {
44 _ = stack_trace;
5 if (std.mem.eql(u8, message, "attempt to index out of bound: index 1, len 0")) {
5 if (std.mem.eql(u8, message, "index out of bounds: index 1, len 0")) {
66 std.process.exit(0);
77 }
88 std.process.exit(1);
test/cases/safety/out of bounds slice access.zig +3-3
......@@ -2,20 +2,20 @@ const std = @import("std");
22
33pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn {
44 _ = stack_trace;
5 if (std.mem.eql(u8, message, "attempt to index out of bound: index 4, len 4")) {
5 if (std.mem.eql(u8, message, "index out of bounds: index 4, len 4")) {
66 std.process.exit(0);
77 }
88 std.process.exit(1);
99}
1010pub fn main() !void {
11 const a = [_]i32{1, 2, 3, 4};
11 const a = [_]i32{ 1, 2, 3, 4 };
1212 baz(bar(&a));
1313 return error.TestFailed;
1414}
1515fn bar(a: []const i32) i32 {
1616 return a[4];
1717}
18fn baz(_: i32) void { }
18fn baz(_: i32) void {}
1919// run
2020// backend=llvm
2121// target=native
test/cases/safety/slice with sentinel out of bounds - runtime len.zig +1-1
......@@ -2,7 +2,7 @@ const std = @import("std");
22
33pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn {
44 _ = stack_trace;
5 if (std.mem.eql(u8, message, "attempt to index out of bound: index 5, len 4")) {
5 if (std.mem.eql(u8, message, "index out of bounds: index 5, len 4")) {
66 std.process.exit(0);
77 }
88 std.process.exit(1);
test/cases/safety/slice with sentinel out of bounds.zig +1-1
......@@ -2,7 +2,7 @@ const std = @import("std");
22
33pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn {
44 _ = stack_trace;
5 if (std.mem.eql(u8, message, "attempt to index out of bound: index 5, len 4")) {
5 if (std.mem.eql(u8, message, "index out of bounds: index 5, len 4")) {
66 std.process.exit(0);
77 }
88 std.process.exit(1);
test/tests.zig+1-2
......@@ -601,7 +601,6 @@ pub fn addPkgTests(
601601 skip_libc: bool,
602602 skip_stage1: bool,
603603 skip_stage2: bool,
604 is_stage1: bool,
605604) *build.Step {
606605 const step = b.step(b.fmt("test-{s}", .{name}), desc);
607606
......@@ -630,7 +629,7 @@ pub fn addPkgTests(
630629 if (test_target.backend) |backend| switch (backend) {
631630 .stage1 => if (skip_stage1) continue,
632631 else => if (skip_stage2) continue,
633 } else if (is_stage1 and skip_stage1) continue;
632 } else if (skip_stage2) continue;
634633
635634 const want_this_mode = for (modes) |m| {
636635 if (m == test_target.mode) break true;