mirror of
https://codeberg.org/ziglang/zig.git
synced 2025-12-06 05:44:20 +00:00
migrate runtime safety tests to the new test harness
* migrate runtime safety tests to the new test harness
- this required adding compare output / execution support for stage1
to the test harness.
* rename `zig build test-stage2` to `zig build test-cases` since it now
does quite a bit of stage1 testing actually. I named it this way
since the main directory in the source tree associated with these
tests is "test/cases/".
* add some documentation for the test manifest format.
This commit is contained in:
parent
f32928c50d
commit
66f3efb63b
76 changed files with 1410 additions and 1243 deletions
27
build.zig
27
build.zig
|
|
@ -40,10 +40,10 @@ pub fn build(b: *Builder) !void {
|
|||
|
||||
const toolchain_step = b.step("test-toolchain", "Run the tests for the toolchain");
|
||||
|
||||
var test_stage2 = b.addTest("src/test.zig");
|
||||
test_stage2.setBuildMode(mode);
|
||||
test_stage2.addPackagePath("test_cases", "test/cases.zig");
|
||||
test_stage2.single_threaded = single_threaded;
|
||||
var test_cases = b.addTest("src/test.zig");
|
||||
test_cases.setBuildMode(mode);
|
||||
test_cases.addPackagePath("test_cases", "test/cases.zig");
|
||||
test_cases.single_threaded = single_threaded;
|
||||
|
||||
const fmt_build_zig = b.addFmt(&[_][]const u8{"build.zig"});
|
||||
|
||||
|
|
@ -158,7 +158,7 @@ pub fn build(b: *Builder) !void {
|
|||
if (target.isWindows() and target.getAbi() == .gnu) {
|
||||
// LTO is currently broken on mingw, this can be removed when it's fixed.
|
||||
exe.want_lto = false;
|
||||
test_stage2.want_lto = false;
|
||||
test_cases.want_lto = false;
|
||||
}
|
||||
|
||||
const exe_options = b.addOptions();
|
||||
|
|
@ -175,7 +175,7 @@ pub fn build(b: *Builder) !void {
|
|||
|
||||
if (link_libc) {
|
||||
exe.linkLibC();
|
||||
test_stage2.linkLibC();
|
||||
test_cases.linkLibC();
|
||||
}
|
||||
|
||||
const is_debug = mode == .Debug;
|
||||
|
|
@ -258,7 +258,7 @@ pub fn build(b: *Builder) !void {
|
|||
zig0.defineCMacro("ZIG_VERSION_PATCH", b.fmt("{d}", .{zig_version.patch}));
|
||||
zig0.defineCMacro("ZIG_VERSION_STRING", b.fmt("\"{s}\"", .{version}));
|
||||
|
||||
for ([_]*std.build.LibExeObjStep{ zig0, exe, test_stage2 }) |artifact| {
|
||||
for ([_]*std.build.LibExeObjStep{ zig0, exe, test_cases }) |artifact| {
|
||||
artifact.addIncludePath("src");
|
||||
artifact.addIncludePath("deps/SoftFloat-3e/source/include");
|
||||
artifact.addIncludePath("deps/SoftFloat-3e-prebuilt");
|
||||
|
|
@ -335,11 +335,11 @@ pub fn build(b: *Builder) !void {
|
|||
}
|
||||
|
||||
try addCmakeCfgOptionsToExe(b, cfg, exe, use_zig_libcxx);
|
||||
try addCmakeCfgOptionsToExe(b, cfg, test_stage2, use_zig_libcxx);
|
||||
try addCmakeCfgOptionsToExe(b, cfg, test_cases, use_zig_libcxx);
|
||||
} else {
|
||||
// Here we are -Denable-llvm but no cmake integration.
|
||||
try addStaticLlvmOptionsToExe(exe);
|
||||
try addStaticLlvmOptionsToExe(test_stage2);
|
||||
try addStaticLlvmOptionsToExe(test_cases);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -381,7 +381,7 @@ pub fn build(b: *Builder) !void {
|
|||
const test_filter = b.option([]const u8, "test-filter", "Skip tests that do not match filter");
|
||||
|
||||
const test_stage2_options = b.addOptions();
|
||||
test_stage2.addOptions("build_options", test_stage2_options);
|
||||
test_cases.addOptions("build_options", test_stage2_options);
|
||||
|
||||
test_stage2_options.addOption(bool, "enable_logging", enable_logging);
|
||||
test_stage2_options.addOption(bool, "enable_link_snapshots", enable_link_snapshots);
|
||||
|
|
@ -404,10 +404,10 @@ pub fn build(b: *Builder) !void {
|
|||
test_stage2_options.addOption([:0]const u8, "version", try b.allocator.dupeZ(u8, version));
|
||||
test_stage2_options.addOption(std.SemanticVersion, "semver", semver);
|
||||
|
||||
const test_stage2_step = b.step("test-stage2", "Run the stage2 compiler tests");
|
||||
test_stage2_step.dependOn(&test_stage2.step);
|
||||
const test_cases_step = b.step("test-cases", "Run the main compiler test cases");
|
||||
test_cases_step.dependOn(&test_cases.step);
|
||||
if (!skip_stage2_tests) {
|
||||
toolchain_step.dependOn(test_stage2_step);
|
||||
toolchain_step.dependOn(test_cases_step);
|
||||
}
|
||||
|
||||
var chosen_modes: [4]builtin.Mode = undefined;
|
||||
|
|
@ -485,7 +485,6 @@ pub fn build(b: *Builder) !void {
|
|||
toolchain_step.dependOn(tests.addStackTraceTests(b, test_filter, modes));
|
||||
toolchain_step.dependOn(tests.addCliTests(b, test_filter, modes));
|
||||
toolchain_step.dependOn(tests.addAssembleAndLinkTests(b, test_filter, modes));
|
||||
toolchain_step.dependOn(tests.addRuntimeSafetyTests(b, test_filter, modes));
|
||||
toolchain_step.dependOn(tests.addTranslateCTests(b, test_filter));
|
||||
if (!skip_run_translated_c) {
|
||||
toolchain_step.dependOn(tests.addRunTranslatedCTests(b, test_filter, target));
|
||||
|
|
|
|||
|
|
@ -71,12 +71,11 @@ release/bin/zig build test-standalone -Denable-macos-sdk
|
|||
release/bin/zig build test-stack-traces -Denable-macos-sdk
|
||||
release/bin/zig build test-cli -Denable-macos-sdk
|
||||
release/bin/zig build test-asm-link -Denable-macos-sdk
|
||||
release/bin/zig build test-runtime-safety -Denable-macos-sdk
|
||||
release/bin/zig build test-translate-c -Denable-macos-sdk
|
||||
release/bin/zig build test-run-translated-c -Denable-macos-sdk
|
||||
release/bin/zig build docs -Denable-macos-sdk
|
||||
release/bin/zig build test-fmt -Denable-macos-sdk
|
||||
release/bin/zig build test-stage2 -Denable-macos-sdk
|
||||
release/bin/zig build test-cases -Denable-macos-sdk
|
||||
|
||||
if [ "${BUILD_REASON}" != "PullRequest" ]; then
|
||||
mv ../LICENSE release/
|
||||
|
|
|
|||
|
|
@ -34,12 +34,11 @@ case "$1" in
|
|||
./build/zig build $BUILD_FLAGS test-stack-traces
|
||||
./build/zig build $BUILD_FLAGS test-cli
|
||||
./build/zig build $BUILD_FLAGS test-asm-link
|
||||
./build/zig build $BUILD_FLAGS test-runtime-safety
|
||||
./build/zig build $BUILD_FLAGS test-translate-c
|
||||
;;
|
||||
7)
|
||||
./build/zig build $BUILD_FLAGS # test building self-hosted without LLVM
|
||||
./build/zig build $BUILD_FLAGS test-stage2
|
||||
./build/zig build $BUILD_FLAGS test-cases
|
||||
;;
|
||||
'')
|
||||
echo "error: expecting test group argument"
|
||||
|
|
|
|||
|
|
@ -69,12 +69,11 @@ $ZIG build test-standalone -fqemu -fwasmtime
|
|||
$ZIG build test-stack-traces -fqemu -fwasmtime
|
||||
$ZIG build test-cli -fqemu -fwasmtime
|
||||
$ZIG build test-asm-link -fqemu -fwasmtime
|
||||
$ZIG build test-runtime-safety -fqemu -fwasmtime
|
||||
$ZIG build test-translate-c -fqemu -fwasmtime
|
||||
$ZIG build test-run-translated-c -fqemu -fwasmtime
|
||||
$ZIG build docs -fqemu -fwasmtime
|
||||
$ZIG build test-fmt -fqemu -fwasmtime
|
||||
$ZIG build test-stage2 -fqemu -fwasmtime
|
||||
$ZIG build test-cases -fqemu -fwasmtime
|
||||
|
||||
# Produce the experimental std lib documentation.
|
||||
mkdir -p "$RELEASE_STAGING/docs/std"
|
||||
|
|
|
|||
17
src/test.zig
17
src/test.zig
|
|
@ -1394,7 +1394,22 @@ pub const TestContext = struct {
|
|||
}
|
||||
},
|
||||
.CompareObjectFile => @panic("TODO implement in the test harness"),
|
||||
.Execution => @panic("TODO implement in the test harness"),
|
||||
.Execution => |expected_stdout| {
|
||||
switch (result.term) {
|
||||
.Exited => |code| {
|
||||
if (code != 0) {
|
||||
dumpArgs(zig_args.items);
|
||||
return error.CompilationFailed;
|
||||
}
|
||||
},
|
||||
else => {
|
||||
dumpArgs(zig_args.items);
|
||||
return error.CompilationCrashed;
|
||||
},
|
||||
}
|
||||
try std.testing.expectEqualStrings("", result.stderr);
|
||||
try std.testing.expectEqualStrings(expected_stdout, result.stdout);
|
||||
},
|
||||
.Header => @panic("TODO implement in the test harness"),
|
||||
}
|
||||
return;
|
||||
|
|
|
|||
61
test/cases/README.md
Normal file
61
test/cases/README.md
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
# Test Case Quick Reference
|
||||
|
||||
Use comments at the **end of the file** to indicate metadata about the test
|
||||
case. Here are examples of different kinds of tests:
|
||||
|
||||
## Compile Error Test
|
||||
|
||||
If you want it to be run with `zig test` and match expected error messages:
|
||||
|
||||
```zig
|
||||
// error
|
||||
// is_test=1
|
||||
//
|
||||
// :4:13: error: 'try' outside function scope
|
||||
```
|
||||
|
||||
## Execution
|
||||
|
||||
This will do `zig run` on the code and expect exit code 0.
|
||||
|
||||
```zig
|
||||
// run
|
||||
```
|
||||
|
||||
## Incremental Compilation
|
||||
|
||||
Make multiple files that have ".", and then an integer, before the ".zig"
|
||||
extension, like this:
|
||||
|
||||
```
|
||||
hello.0.zig
|
||||
hello.1.zig
|
||||
hello.2.zig
|
||||
```
|
||||
|
||||
Each file can be a different kind of test, such as expecting compile errors,
|
||||
or expecting to be run and exit(0). The test harness will use these to simulate
|
||||
incremental compilation.
|
||||
|
||||
At the time of writing there is no way to specify multiple files being changed
|
||||
as part of an update.
|
||||
|
||||
## Subdirectories
|
||||
|
||||
Subdirectories do not have any semantic meaning but they can be used for
|
||||
organization since the test harness will recurse into them. The full directory
|
||||
path will be prepended as a prefix on the test case name.
|
||||
|
||||
## Limiting which Backends and Targets are Tested
|
||||
|
||||
```zig
|
||||
// run
|
||||
// backend=stage2,llvm
|
||||
// target=x86_64-linux,x86_64-macos
|
||||
```
|
||||
|
||||
Possible backends are:
|
||||
|
||||
* `stage1`: equivalent to `-fstage1`.
|
||||
* `stage2`: equivalent to passing `-fno-stage1 -fno-LLVM`.
|
||||
* `llvm`: equivalent to `-fLLVM -fno-stage1`.
|
||||
21
test/cases/safety/@alignCast misaligned.zig
Normal file
21
test/cases/safety/@alignCast misaligned.zig
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
const std = @import("std");
|
||||
|
||||
pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn {
|
||||
_ = message;
|
||||
_ = stack_trace;
|
||||
std.process.exit(0);
|
||||
}
|
||||
|
||||
pub fn main() !void {
|
||||
var array align(4) = [_]u32{0x11111111, 0x11111111};
|
||||
const bytes = std.mem.sliceAsBytes(array[0..]);
|
||||
if (foo(bytes) != 0x11111111) return error.Wrong;
|
||||
return error.TestFailed;
|
||||
}
|
||||
fn foo(bytes: []u8) u32 {
|
||||
const slice4 = bytes[1..5];
|
||||
const int_slice = std.mem.bytesAsSlice(u32, @alignCast(4, slice4));
|
||||
return int_slice[0];
|
||||
}
|
||||
// run
|
||||
// backend=stage1
|
||||
19
test/cases/safety/@asyncCall with too small a frame.zig
Normal file
19
test/cases/safety/@asyncCall with too small a frame.zig
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
const std = @import("std");
|
||||
|
||||
pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn {
|
||||
_ = message;
|
||||
_ = stack_trace;
|
||||
std.process.exit(0);
|
||||
}
|
||||
pub fn main() !void {
|
||||
var bytes: [1]u8 align(16) = undefined;
|
||||
var ptr = other;
|
||||
var frame = @asyncCall(&bytes, {}, ptr, .{});
|
||||
_ = frame;
|
||||
return error.TestFailed;
|
||||
}
|
||||
fn other() callconv(.Async) void {
|
||||
suspend {}
|
||||
}
|
||||
// run
|
||||
// backend=stage1
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
const std = @import("std");
|
||||
|
||||
pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn {
|
||||
_ = message;
|
||||
_ = stack_trace;
|
||||
std.process.exit(0);
|
||||
}
|
||||
const Set1 = error{A, B};
|
||||
const Set2 = error{A, C};
|
||||
pub fn main() !void {
|
||||
foo(Set1.B) catch {};
|
||||
return error.TestFailed;
|
||||
}
|
||||
fn foo(set1: Set1) Set2 {
|
||||
return @errSetCast(Set2, set1);
|
||||
}
|
||||
// run
|
||||
// backend=stage1
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
const std = @import("std");
|
||||
|
||||
pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn {
|
||||
_ = message;
|
||||
_ = stack_trace;
|
||||
std.process.exit(0);
|
||||
}
|
||||
pub fn main() !void {
|
||||
baz(bar(-129.1));
|
||||
return error.TestFailed;
|
||||
}
|
||||
fn bar(a: f32) i8 {
|
||||
return @floatToInt(i8, a);
|
||||
}
|
||||
fn baz(_: i8) void { }
|
||||
// run
|
||||
// backend=stage1
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
const std = @import("std");
|
||||
|
||||
pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn {
|
||||
_ = message;
|
||||
_ = stack_trace;
|
||||
std.process.exit(0);
|
||||
}
|
||||
pub fn main() !void {
|
||||
baz(bar(-1.1));
|
||||
return error.TestFailed;
|
||||
}
|
||||
fn bar(a: f32) u8 {
|
||||
return @floatToInt(u8, a);
|
||||
}
|
||||
fn baz(_: u8) void { }
|
||||
// run
|
||||
// backend=stage1
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
const std = @import("std");
|
||||
|
||||
pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn {
|
||||
_ = message;
|
||||
_ = stack_trace;
|
||||
std.process.exit(0);
|
||||
}
|
||||
pub fn main() !void {
|
||||
baz(bar(256.2));
|
||||
return error.TestFailed;
|
||||
}
|
||||
fn bar(a: f32) u8 {
|
||||
return @floatToInt(u8, a);
|
||||
}
|
||||
fn baz(_: u8) void { }
|
||||
// run
|
||||
// backend=stage1
|
||||
19
test/cases/safety/@intCast to u0.zig
Normal file
19
test/cases/safety/@intCast to u0.zig
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
const std = @import("std");
|
||||
|
||||
pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn {
|
||||
_ = message;
|
||||
_ = stack_trace;
|
||||
std.process.exit(0);
|
||||
}
|
||||
|
||||
pub fn main() !void {
|
||||
bar(1, 1);
|
||||
return error.TestFailed;
|
||||
}
|
||||
|
||||
fn bar(one: u1, not_zero: i32) void {
|
||||
var x = one << @intCast(u0, not_zero);
|
||||
_ = x;
|
||||
}
|
||||
// run
|
||||
// backend=stage1
|
||||
22
test/cases/safety/@intToEnum - no matching tag value.zig
Normal file
22
test/cases/safety/@intToEnum - no matching tag value.zig
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
const std = @import("std");
|
||||
|
||||
pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn {
|
||||
_ = message;
|
||||
_ = stack_trace;
|
||||
std.process.exit(0);
|
||||
}
|
||||
const Foo = enum {
|
||||
A,
|
||||
B,
|
||||
C,
|
||||
};
|
||||
pub fn main() !void {
|
||||
baz(bar(3));
|
||||
return error.TestFailed;
|
||||
}
|
||||
fn bar(a: u2) Foo {
|
||||
return @intToEnum(Foo, a);
|
||||
}
|
||||
fn baz(_: Foo) void {}
|
||||
// run
|
||||
// backend=stage1
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
const std = @import("std");
|
||||
|
||||
pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn {
|
||||
_ = message;
|
||||
_ = stack_trace;
|
||||
std.process.exit(0);
|
||||
}
|
||||
pub fn main() !void {
|
||||
var zero: usize = 0;
|
||||
var b = @intToPtr(*u8, zero);
|
||||
_ = b;
|
||||
return error.TestFailed;
|
||||
}
|
||||
// run
|
||||
// backend=stage1
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
const std = @import("std");
|
||||
|
||||
pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn {
|
||||
_ = message;
|
||||
_ = stack_trace;
|
||||
std.process.exit(0);
|
||||
}
|
||||
pub fn main() !void {
|
||||
var zero: usize = 0;
|
||||
var b = @intToPtr(*i32, zero);
|
||||
_ = b;
|
||||
return error.TestFailed;
|
||||
}
|
||||
// run
|
||||
// backend=stage1
|
||||
24
test/cases/safety/@tagName on corrupted enum value.zig
Normal file
24
test/cases/safety/@tagName on corrupted enum value.zig
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
const std = @import("std");
|
||||
|
||||
pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn {
|
||||
_ = stack_trace;
|
||||
if (std.mem.eql(u8, message, "invalid enum value")) {
|
||||
std.process.exit(0);
|
||||
}
|
||||
std.process.exit(1);
|
||||
}
|
||||
|
||||
const E = enum(u32) {
|
||||
X = 1,
|
||||
};
|
||||
|
||||
pub fn main() !void {
|
||||
var e: E = undefined;
|
||||
@memset(@ptrCast([*]u8, &e), 0x55, @sizeOf(E));
|
||||
var n = @tagName(e);
|
||||
_ = n;
|
||||
return error.TestFailed;
|
||||
}
|
||||
|
||||
// run
|
||||
// backend=stage1
|
||||
25
test/cases/safety/@tagName on corrupted union value.zig
Normal file
25
test/cases/safety/@tagName on corrupted union value.zig
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
const std = @import("std");
|
||||
|
||||
pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn {
|
||||
_ = stack_trace;
|
||||
if (std.mem.eql(u8, message, "invalid enum value")) {
|
||||
std.process.exit(0);
|
||||
}
|
||||
std.process.exit(1);
|
||||
}
|
||||
|
||||
const U = union(enum(u32)) {
|
||||
X: u8,
|
||||
};
|
||||
|
||||
pub fn main() !void {
|
||||
var u: U = undefined;
|
||||
@memset(@ptrCast([*]u8, &u), 0x55, @sizeOf(U));
|
||||
var t: @typeInfo(U).Union.tag_type.? = u;
|
||||
var n = @tagName(t);
|
||||
_ = n;
|
||||
return error.TestFailed;
|
||||
}
|
||||
|
||||
// run
|
||||
// backend=stage1
|
||||
18
test/cases/safety/array slice sentinel mismatch.zig
Normal file
18
test/cases/safety/array slice sentinel mismatch.zig
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
const std = @import("std");
|
||||
|
||||
pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn {
|
||||
_ = stack_trace;
|
||||
if (std.mem.eql(u8, message, "sentinel mismatch")) {
|
||||
std.process.exit(0);
|
||||
}
|
||||
std.process.exit(1);
|
||||
}
|
||||
pub fn main() !void {
|
||||
var buf: [4]u8 = undefined;
|
||||
const slice = buf[0..3 :0];
|
||||
_ = slice;
|
||||
return error.TestFailed;
|
||||
}
|
||||
// run
|
||||
// backend=stage1
|
||||
|
||||
28
test/cases/safety/awaiting twice.zig
Normal file
28
test/cases/safety/awaiting twice.zig
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
const std = @import("std");
|
||||
|
||||
pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn {
|
||||
_ = message;
|
||||
_ = stack_trace;
|
||||
std.process.exit(0);
|
||||
}
|
||||
var frame: anyframe = undefined;
|
||||
|
||||
pub fn main() !void {
|
||||
_ = async amain();
|
||||
resume frame;
|
||||
return error.TestFailed;
|
||||
}
|
||||
|
||||
fn amain() void {
|
||||
var f = async func();
|
||||
await f;
|
||||
await f;
|
||||
}
|
||||
|
||||
fn func() void {
|
||||
suspend {
|
||||
frame = @frame();
|
||||
}
|
||||
}
|
||||
// run
|
||||
// backend=stage1
|
||||
24
test/cases/safety/bad union field access.zig
Normal file
24
test/cases/safety/bad union field access.zig
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
const std = @import("std");
|
||||
|
||||
pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn {
|
||||
_ = message;
|
||||
_ = stack_trace;
|
||||
std.process.exit(0);
|
||||
}
|
||||
|
||||
const Foo = union {
|
||||
float: f32,
|
||||
int: u32,
|
||||
};
|
||||
|
||||
pub fn main() !void {
|
||||
var f = Foo { .int = 42 };
|
||||
bar(&f);
|
||||
return error.TestFailed;
|
||||
}
|
||||
|
||||
fn bar(f: *Foo) void {
|
||||
f.float = 12.34;
|
||||
}
|
||||
// run
|
||||
// backend=stage1
|
||||
15
test/cases/safety/calling panic.zig
Normal file
15
test/cases/safety/calling panic.zig
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
const std = @import("std");
|
||||
|
||||
pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn {
|
||||
_ = stack_trace;
|
||||
if (std.mem.eql(u8, message, "oh no")) {
|
||||
std.process.exit(0);
|
||||
}
|
||||
std.process.exit(1);
|
||||
}
|
||||
pub fn main() !void {
|
||||
if (true) @panic("oh no");
|
||||
return error.TestFailed;
|
||||
}
|
||||
// run
|
||||
// backend=stage1
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
const std = @import("std");
|
||||
|
||||
pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn {
|
||||
_ = message;
|
||||
_ = stack_trace;
|
||||
std.process.exit(0);
|
||||
}
|
||||
|
||||
pub fn main() !void {
|
||||
const x = widenSlice(&[_]u8{1, 2, 3, 4, 5});
|
||||
if (x.len == 0) return error.Whatever;
|
||||
return error.TestFailed;
|
||||
}
|
||||
fn widenSlice(slice: []align(1) const u8) []align(1) const i32 {
|
||||
return std.mem.bytesAsSlice(i32, slice);
|
||||
}
|
||||
// run
|
||||
// backend=stage1
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
const std = @import("std");
|
||||
|
||||
pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn {
|
||||
_ = message;
|
||||
_ = stack_trace;
|
||||
std.process.exit(0);
|
||||
}
|
||||
pub fn main() !void {
|
||||
bar(9999) catch {};
|
||||
return error.TestFailed;
|
||||
}
|
||||
fn bar(x: u16) anyerror {
|
||||
return @intToError(x);
|
||||
}
|
||||
// run
|
||||
// backend=stage1
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
const std = @import("std");
|
||||
|
||||
pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn {
|
||||
_ = stack_trace;
|
||||
if (std.mem.eql(u8, message, "index out of bounds")) {
|
||||
std.process.exit(0);
|
||||
}
|
||||
std.process.exit(1);
|
||||
}
|
||||
|
||||
pub fn main() !void {
|
||||
var buf_zero = [0]u8{};
|
||||
const input: []u8 = &buf_zero;
|
||||
const slice = input[0..0 :0];
|
||||
_ = slice;
|
||||
return error.TestFailed;
|
||||
}
|
||||
|
||||
// run
|
||||
// backend=stage1
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
const std = @import("std");
|
||||
|
||||
|
||||
pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn {
|
||||
_ = message;
|
||||
_ = stack_trace;
|
||||
std.process.exit(0);
|
||||
}
|
||||
|
||||
var failing_frame: @Frame(failing) = undefined;
|
||||
|
||||
pub fn main() !void {
|
||||
const p = nonFailing();
|
||||
resume p;
|
||||
const p2 = async printTrace(p);
|
||||
_ = p2;
|
||||
return error.TestFailed;
|
||||
}
|
||||
|
||||
fn nonFailing() anyframe->anyerror!void {
|
||||
failing_frame = async failing();
|
||||
return &failing_frame;
|
||||
}
|
||||
|
||||
fn failing() anyerror!void {
|
||||
suspend {}
|
||||
return second();
|
||||
}
|
||||
|
||||
fn second() callconv(.Async) anyerror!void {
|
||||
return error.Fail;
|
||||
}
|
||||
|
||||
fn printTrace(p: anyframe->anyerror!void) void {
|
||||
(await p) catch unreachable;
|
||||
}
|
||||
// run
|
||||
// backend=stage1
|
||||
20
test/cases/safety/exact division failure - vectors.zig
Normal file
20
test/cases/safety/exact division failure - vectors.zig
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
const std = @import("std");
|
||||
|
||||
pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn {
|
||||
_ = message;
|
||||
_ = stack_trace;
|
||||
std.process.exit(0);
|
||||
}
|
||||
|
||||
pub fn main() !void {
|
||||
var a: @Vector(4, i32) = [4]i32{111, 222, 333, 444};
|
||||
var b: @Vector(4, i32) = [4]i32{111, 222, 333, 441};
|
||||
const x = divExact(a, b);
|
||||
_ = x;
|
||||
return error.TestFailed;
|
||||
}
|
||||
fn divExact(a: @Vector(4, i32), b: @Vector(4, i32)) @Vector(4, i32) {
|
||||
return @divExact(a, b);
|
||||
}
|
||||
// run
|
||||
// backend=stage1
|
||||
18
test/cases/safety/exact division failure.zig
Normal file
18
test/cases/safety/exact division failure.zig
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
const std = @import("std");
|
||||
|
||||
pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn {
|
||||
_ = message;
|
||||
_ = stack_trace;
|
||||
std.process.exit(0);
|
||||
}
|
||||
|
||||
pub fn main() !void {
|
||||
const x = divExact(10, 3);
|
||||
if (x == 0) return error.Whatever;
|
||||
return error.TestFailed;
|
||||
}
|
||||
fn divExact(a: i32, b: i32) i32 {
|
||||
return @divExact(a, b);
|
||||
}
|
||||
// run
|
||||
// backend=stage1
|
||||
17
test/cases/safety/intToPtr with misaligned address.zig
Normal file
17
test/cases/safety/intToPtr with misaligned address.zig
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
const std = @import("std");
|
||||
|
||||
pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn {
|
||||
_ = stack_trace;
|
||||
if (std.mem.eql(u8, message, "incorrect alignment")) {
|
||||
std.process.exit(0);
|
||||
}
|
||||
std.process.exit(1);
|
||||
}
|
||||
pub fn main() !void {
|
||||
var x: usize = 5;
|
||||
var y = @intToPtr([*]align(4) u8, x);
|
||||
_ = y;
|
||||
return error.TestFailed;
|
||||
}
|
||||
// run
|
||||
// backend=stage1
|
||||
22
test/cases/safety/integer addition overflow.zig
Normal file
22
test/cases/safety/integer addition overflow.zig
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
const std = @import("std");
|
||||
|
||||
pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn {
|
||||
_ = stack_trace;
|
||||
if (std.mem.eql(u8, message, "integer overflow")) {
|
||||
std.process.exit(0);
|
||||
}
|
||||
std.process.exit(1);
|
||||
}
|
||||
|
||||
pub fn main() !void {
|
||||
const x = add(65530, 10);
|
||||
if (x == 0) return error.Whatever;
|
||||
return error.TestFailed;
|
||||
}
|
||||
|
||||
fn add(a: u16, b: u16) u16 {
|
||||
return a + b;
|
||||
}
|
||||
|
||||
// run
|
||||
// backend=stage1
|
||||
19
test/cases/safety/integer division by zero - vectors.zig
Normal file
19
test/cases/safety/integer division by zero - vectors.zig
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
const std = @import("std");
|
||||
|
||||
pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn {
|
||||
_ = message;
|
||||
_ = stack_trace;
|
||||
std.process.exit(0);
|
||||
}
|
||||
pub fn main() !void {
|
||||
var a: @Vector(4, i32) = [4]i32{111, 222, 333, 444};
|
||||
var b: @Vector(4, i32) = [4]i32{111, 0, 333, 444};
|
||||
const x = div0(a, b);
|
||||
_ = x;
|
||||
return error.TestFailed;
|
||||
}
|
||||
fn div0(a: @Vector(4, i32), b: @Vector(4, i32)) @Vector(4, i32) {
|
||||
return @divTrunc(a, b);
|
||||
}
|
||||
// run
|
||||
// backend=stage1
|
||||
17
test/cases/safety/integer division by zero.zig
Normal file
17
test/cases/safety/integer division by zero.zig
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
const std = @import("std");
|
||||
|
||||
pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn {
|
||||
_ = message;
|
||||
_ = stack_trace;
|
||||
std.process.exit(0);
|
||||
}
|
||||
pub fn main() !void {
|
||||
const x = div0(999, 0);
|
||||
_ = x;
|
||||
return error.TestFailed;
|
||||
}
|
||||
fn div0(a: i32, b: i32) i32 {
|
||||
return @divTrunc(a, b);
|
||||
}
|
||||
// run
|
||||
// backend=stage1
|
||||
18
test/cases/safety/integer multiplication overflow.zig
Normal file
18
test/cases/safety/integer multiplication overflow.zig
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
const std = @import("std");
|
||||
|
||||
pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn {
|
||||
_ = message;
|
||||
_ = stack_trace;
|
||||
std.process.exit(0);
|
||||
}
|
||||
|
||||
pub fn main() !void {
|
||||
const x = mul(300, 6000);
|
||||
if (x == 0) return error.Whatever;
|
||||
return error.TestFailed;
|
||||
}
|
||||
fn mul(a: u16, b: u16) u16 {
|
||||
return a * b;
|
||||
}
|
||||
// run
|
||||
// backend=stage1
|
||||
18
test/cases/safety/integer negation overflow.zig
Normal file
18
test/cases/safety/integer negation overflow.zig
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
const std = @import("std");
|
||||
|
||||
pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn {
|
||||
_ = message;
|
||||
_ = stack_trace;
|
||||
std.process.exit(0);
|
||||
}
|
||||
|
||||
pub fn main() !void {
|
||||
const x = neg(-32768);
|
||||
if (x == 32767) return error.Whatever;
|
||||
return error.TestFailed;
|
||||
}
|
||||
fn neg(a: i16) i16 {
|
||||
return -a;
|
||||
}
|
||||
// run
|
||||
// backend=stage1
|
||||
18
test/cases/safety/integer subtraction overflow.zig
Normal file
18
test/cases/safety/integer subtraction overflow.zig
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
const std = @import("std");
|
||||
|
||||
pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn {
|
||||
_ = message;
|
||||
_ = stack_trace;
|
||||
std.process.exit(0);
|
||||
}
|
||||
|
||||
pub fn main() !void {
|
||||
const x = sub(10, 20);
|
||||
if (x == 0) return error.Whatever;
|
||||
return error.TestFailed;
|
||||
}
|
||||
fn sub(a: u16, b: u16) u16 {
|
||||
return a - b;
|
||||
}
|
||||
// run
|
||||
// backend=stage1
|
||||
18
test/cases/safety/invalid resume of async function.zig
Normal file
18
test/cases/safety/invalid resume of async function.zig
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
const std = @import("std");
|
||||
|
||||
pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn {
|
||||
_ = message;
|
||||
_ = stack_trace;
|
||||
std.process.exit(0);
|
||||
}
|
||||
pub fn main() !void {
|
||||
var p = async suspendOnce();
|
||||
resume p; //ok
|
||||
resume p; //bad
|
||||
return error.TestFailed;
|
||||
}
|
||||
fn suspendOnce() void {
|
||||
suspend {}
|
||||
}
|
||||
// run
|
||||
// backend=stage1
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
const std = @import("std");
|
||||
|
||||
pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn {
|
||||
_ = message;
|
||||
_ = stack_trace;
|
||||
std.process.exit(0);
|
||||
}
|
||||
pub fn main() !void {
|
||||
_ = nosuspend add(101, 100);
|
||||
return error.TestFailed;
|
||||
}
|
||||
fn add(a: i32, b: i32) i32 {
|
||||
if (a > 100) {
|
||||
suspend {}
|
||||
}
|
||||
return a + b;
|
||||
}
|
||||
// run
|
||||
// backend=stage1
|
||||
15
test/cases/safety/optional unwrap operator on C pointer.zig
Normal file
15
test/cases/safety/optional unwrap operator on C pointer.zig
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
const std = @import("std");
|
||||
|
||||
pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn {
|
||||
_ = message;
|
||||
_ = stack_trace;
|
||||
std.process.exit(0);
|
||||
}
|
||||
pub fn main() !void {
|
||||
var ptr: [*c]i32 = null;
|
||||
var b = ptr.?;
|
||||
_ = b;
|
||||
return error.TestFailed;
|
||||
}
|
||||
// run
|
||||
// backend=stage1
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
const std = @import("std");
|
||||
|
||||
pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn {
|
||||
_ = message;
|
||||
_ = stack_trace;
|
||||
std.process.exit(0);
|
||||
}
|
||||
pub fn main() !void {
|
||||
var ptr: ?*i32 = null;
|
||||
var b = ptr.?;
|
||||
_ = b;
|
||||
return error.TestFailed;
|
||||
}
|
||||
// run
|
||||
// backend=stage1
|
||||
18
test/cases/safety/out of bounds slice access.zig
Normal file
18
test/cases/safety/out of bounds slice access.zig
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
const std = @import("std");
|
||||
|
||||
pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn {
|
||||
_ = message;
|
||||
_ = stack_trace;
|
||||
std.process.exit(0);
|
||||
}
|
||||
pub fn main() !void {
|
||||
const a = [_]i32{1, 2, 3, 4};
|
||||
baz(bar(&a));
|
||||
return error.TestFailed;
|
||||
}
|
||||
fn bar(a: []const i32) i32 {
|
||||
return a[4];
|
||||
}
|
||||
fn baz(_: i32) void { }
|
||||
// run
|
||||
// backend=stage1
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
const std = @import("std");
|
||||
|
||||
pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn {
|
||||
_ = message;
|
||||
_ = stack_trace;
|
||||
std.process.exit(0);
|
||||
}
|
||||
pub fn main() !void {
|
||||
var c_ptr: [*c]u8 = 0;
|
||||
var zig_ptr: *u8 = c_ptr;
|
||||
_ = zig_ptr;
|
||||
return error.TestFailed;
|
||||
}
|
||||
// run
|
||||
// backend=stage1
|
||||
20
test/cases/safety/pointer slice sentinel mismatch.zig
Normal file
20
test/cases/safety/pointer slice sentinel mismatch.zig
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
const std = @import("std");
|
||||
|
||||
pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn {
|
||||
_ = stack_trace;
|
||||
if (std.mem.eql(u8, message, "sentinel mismatch")) {
|
||||
std.process.exit(0);
|
||||
}
|
||||
std.process.exit(1);
|
||||
}
|
||||
|
||||
pub fn main() !void {
|
||||
var buf: [4]u8 = undefined;
|
||||
const ptr: [*]u8 = &buf;
|
||||
const slice = ptr[0..3 :0];
|
||||
_ = slice;
|
||||
return error.TestFailed;
|
||||
}
|
||||
|
||||
// run
|
||||
// backend=stage1
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
const std = @import("std");
|
||||
|
||||
pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn {
|
||||
_ = message;
|
||||
_ = stack_trace;
|
||||
std.process.exit(0);
|
||||
}
|
||||
pub fn main() !void {
|
||||
var frame = async first();
|
||||
resume frame;
|
||||
return error.TestFailed;
|
||||
}
|
||||
fn first() void {
|
||||
other();
|
||||
}
|
||||
fn other() void {
|
||||
suspend {}
|
||||
}
|
||||
// run
|
||||
// backend=stage1
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
const std = @import("std");
|
||||
|
||||
pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn {
|
||||
_ = message;
|
||||
_ = stack_trace;
|
||||
std.process.exit(0);
|
||||
}
|
||||
pub fn main() !void {
|
||||
var frame = async first();
|
||||
resume frame;
|
||||
return error.TestFailed;
|
||||
}
|
||||
fn first() void {
|
||||
var frame = async other();
|
||||
await frame;
|
||||
}
|
||||
fn other() void {
|
||||
suspend {}
|
||||
}
|
||||
// run
|
||||
// backend=stage1
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
const std = @import("std");
|
||||
|
||||
pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn {
|
||||
_ = message;
|
||||
_ = stack_trace;
|
||||
std.process.exit(0);
|
||||
}
|
||||
fn foo() void {
|
||||
suspend {
|
||||
global_frame = @frame();
|
||||
}
|
||||
var f = async bar(@frame());
|
||||
_ = f;
|
||||
std.os.exit(1);
|
||||
}
|
||||
|
||||
fn bar(frame: anyframe) void {
|
||||
suspend {
|
||||
resume frame;
|
||||
}
|
||||
std.os.exit(1);
|
||||
}
|
||||
|
||||
var global_frame: anyframe = undefined;
|
||||
pub fn main() !void {
|
||||
_ = async foo();
|
||||
resume global_frame;
|
||||
std.os.exit(1);
|
||||
}
|
||||
// run
|
||||
// backend=stage1
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
const std = @import("std");
|
||||
|
||||
pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn {
|
||||
_ = message;
|
||||
_ = stack_trace;
|
||||
std.process.exit(0);
|
||||
}
|
||||
fn foo() void {
|
||||
var f = async bar(@frame());
|
||||
_ = f;
|
||||
std.os.exit(1);
|
||||
}
|
||||
|
||||
fn bar(frame: anyframe) void {
|
||||
suspend {
|
||||
resume frame;
|
||||
}
|
||||
std.os.exit(1);
|
||||
}
|
||||
|
||||
pub fn main() !void {
|
||||
_ = async foo();
|
||||
return error.TestFailed;
|
||||
}
|
||||
// run
|
||||
// backend=stage1
|
||||
20
test/cases/safety/shift left by huge amount.zig
Normal file
20
test/cases/safety/shift left by huge amount.zig
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
const std = @import("std");
|
||||
|
||||
pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn {
|
||||
_ = stack_trace;
|
||||
if (std.mem.eql(u8, message, "shift amount is greater than the type size")) {
|
||||
std.process.exit(0);
|
||||
}
|
||||
std.process.exit(1);
|
||||
}
|
||||
|
||||
pub fn main() !void {
|
||||
var x: u24 = 42;
|
||||
var y: u5 = 24;
|
||||
var z = x >> y;
|
||||
_ = z;
|
||||
return error.TestFailed;
|
||||
}
|
||||
|
||||
// run
|
||||
// backend=stage1
|
||||
20
test/cases/safety/shift right by huge amount.zig
Normal file
20
test/cases/safety/shift right by huge amount.zig
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
const std = @import("std");
|
||||
|
||||
pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn {
|
||||
_ = stack_trace;
|
||||
if (std.mem.eql(u8, message, "shift amount is greater than the type size")) {
|
||||
std.process.exit(0);
|
||||
}
|
||||
std.process.exit(1);
|
||||
}
|
||||
|
||||
pub fn main() !void {
|
||||
var x: u24 = 42;
|
||||
var y: u5 = 24;
|
||||
var z = x << y;
|
||||
_ = z;
|
||||
return error.TestFailed;
|
||||
}
|
||||
|
||||
// run
|
||||
// backend=stage1
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
const std = @import("std");
|
||||
|
||||
pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn {
|
||||
_ = message;
|
||||
_ = stack_trace;
|
||||
std.process.exit(0);
|
||||
}
|
||||
|
||||
pub fn main() !void {
|
||||
var a: @Vector(4, i16) = [_]i16{ 1, 2, -32768, 4 };
|
||||
var b: @Vector(4, i16) = [_]i16{ 1, 2, -1, 4 };
|
||||
const x = div(a, b);
|
||||
if (x[2] == 32767) return error.Whatever;
|
||||
return error.TestFailed;
|
||||
}
|
||||
fn div(a: @Vector(4, i16), b: @Vector(4, i16)) @Vector(4, i16) {
|
||||
return @divTrunc(a, b);
|
||||
}
|
||||
// run
|
||||
// backend=stage1
|
||||
18
test/cases/safety/signed integer division overflow.zig
Normal file
18
test/cases/safety/signed integer division overflow.zig
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
const std = @import("std");
|
||||
|
||||
pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn {
|
||||
_ = message;
|
||||
_ = stack_trace;
|
||||
std.process.exit(0);
|
||||
}
|
||||
|
||||
pub fn main() !void {
|
||||
const x = div(-32768, -1);
|
||||
if (x == 32767) return error.Whatever;
|
||||
return error.TestFailed;
|
||||
}
|
||||
fn div(a: i16, b: i16) i16 {
|
||||
return @divTrunc(a, b);
|
||||
}
|
||||
// run
|
||||
// backend=stage1
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
const std = @import("std");
|
||||
|
||||
pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn {
|
||||
_ = message;
|
||||
_ = stack_trace;
|
||||
std.process.exit(0);
|
||||
}
|
||||
pub fn main() !void {
|
||||
var value: c_short = -1;
|
||||
var casted = @intCast(u32, value);
|
||||
_ = casted;
|
||||
return error.TestFailed;
|
||||
}
|
||||
// run
|
||||
// backend=stage1
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
const std = @import("std");
|
||||
|
||||
pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn {
|
||||
_ = message;
|
||||
_ = stack_trace;
|
||||
std.process.exit(0);
|
||||
}
|
||||
|
||||
pub fn main() !void {
|
||||
const x = unsigned_cast(-10);
|
||||
if (x == 0) return error.Whatever;
|
||||
return error.TestFailed;
|
||||
}
|
||||
fn unsigned_cast(x: i32) u32 {
|
||||
return @intCast(u32, x);
|
||||
}
|
||||
// run
|
||||
// backend=stage1
|
||||
18
test/cases/safety/signed shift left overflow.zig
Normal file
18
test/cases/safety/signed shift left overflow.zig
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
const std = @import("std");
|
||||
|
||||
pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn {
|
||||
_ = message;
|
||||
_ = stack_trace;
|
||||
std.process.exit(0);
|
||||
}
|
||||
|
||||
pub fn main() !void {
|
||||
const x = shl(-16385, 1);
|
||||
if (x == 0) return error.Whatever;
|
||||
return error.TestFailed;
|
||||
}
|
||||
fn shl(a: i16, b: u4) i16 {
|
||||
return @shlExact(a, b);
|
||||
}
|
||||
// run
|
||||
// backend=stage1
|
||||
18
test/cases/safety/signed shift right overflow.zig
Normal file
18
test/cases/safety/signed shift right overflow.zig
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
const std = @import("std");
|
||||
|
||||
pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn {
|
||||
_ = message;
|
||||
_ = stack_trace;
|
||||
std.process.exit(0);
|
||||
}
|
||||
|
||||
pub fn main() !void {
|
||||
const x = shr(-16385, 1);
|
||||
if (x == 0) return error.Whatever;
|
||||
return error.TestFailed;
|
||||
}
|
||||
fn shr(a: i16, b: u4) i16 {
|
||||
return @shrExact(a, b);
|
||||
}
|
||||
// run
|
||||
// backend=stage1
|
||||
19
test/cases/safety/signed-unsigned vector cast.zig
Normal file
19
test/cases/safety/signed-unsigned vector cast.zig
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
const std = @import("std");
|
||||
|
||||
pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn {
|
||||
_ = stack_trace;
|
||||
if (std.mem.eql(u8, message, "attempt to cast negative value to unsigned integer")) {
|
||||
std.process.exit(0);
|
||||
}
|
||||
std.process.exit(1);
|
||||
}
|
||||
|
||||
pub fn main() !void {
|
||||
var x = @splat(4, @as(i32, -2147483647));
|
||||
var y = @intCast(@Vector(4, u32), x);
|
||||
_ = y;
|
||||
return error.TestFailed;
|
||||
}
|
||||
|
||||
// run
|
||||
// backend=stage1
|
||||
19
test/cases/safety/slice sentinel mismatch - floats.zig
Normal file
19
test/cases/safety/slice sentinel mismatch - floats.zig
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
const std = @import("std");
|
||||
|
||||
pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn {
|
||||
_ = stack_trace;
|
||||
if (std.mem.eql(u8, message, "sentinel mismatch")) {
|
||||
std.process.exit(0);
|
||||
}
|
||||
std.process.exit(1);
|
||||
}
|
||||
|
||||
pub fn main() !void {
|
||||
var buf: [4]f32 = undefined;
|
||||
const slice = buf[0..3 :1.2];
|
||||
_ = slice;
|
||||
return error.TestFailed;
|
||||
}
|
||||
|
||||
// run
|
||||
// backend=stage1
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
const std = @import("std");
|
||||
|
||||
pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn {
|
||||
_ = stack_trace;
|
||||
if (std.mem.eql(u8, message, "sentinel mismatch")) {
|
||||
std.process.exit(0);
|
||||
}
|
||||
std.process.exit(1);
|
||||
}
|
||||
|
||||
pub fn main() !void {
|
||||
var buf: [4]?*i32 = undefined;
|
||||
const slice = buf[0..3 :null];
|
||||
_ = slice;
|
||||
return error.TestFailed;
|
||||
}
|
||||
|
||||
// run
|
||||
// backend=stage1
|
||||
18
test/cases/safety/slice slice sentinel mismatch.zig
Normal file
18
test/cases/safety/slice slice sentinel mismatch.zig
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
const std = @import("std");
|
||||
|
||||
pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn {
|
||||
_ = stack_trace;
|
||||
if (std.mem.eql(u8, message, "sentinel mismatch")) {
|
||||
std.process.exit(0);
|
||||
}
|
||||
std.process.exit(1);
|
||||
}
|
||||
pub fn main() !void {
|
||||
var buf: [4]u8 = undefined;
|
||||
const slice = buf[0..];
|
||||
const slice2 = slice[0..3 :0];
|
||||
_ = slice2;
|
||||
return error.TestFailed;
|
||||
}
|
||||
// run
|
||||
// backend=stage1
|
||||
20
test/cases/safety/slice with sentinel out of bounds.zig
Normal file
20
test/cases/safety/slice with sentinel out of bounds.zig
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
const std = @import("std");
|
||||
|
||||
pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn {
|
||||
_ = stack_trace;
|
||||
if (std.mem.eql(u8, message, "index out of bounds")) {
|
||||
std.process.exit(0);
|
||||
}
|
||||
std.process.exit(1);
|
||||
}
|
||||
|
||||
pub fn main() !void {
|
||||
var buf = [4]u8{ 'a', 'b', 'c', 0 };
|
||||
const input: []u8 = &buf;
|
||||
const slice = input[0..4 :0];
|
||||
_ = slice;
|
||||
return error.TestFailed;
|
||||
}
|
||||
|
||||
// run
|
||||
// backend=stage1
|
||||
16
test/cases/safety/slicing null C pointer.zig
Normal file
16
test/cases/safety/slicing null C pointer.zig
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
const std = @import("std");
|
||||
|
||||
pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn {
|
||||
_ = message;
|
||||
_ = stack_trace;
|
||||
std.process.exit(0);
|
||||
}
|
||||
|
||||
pub fn main() !void {
|
||||
var ptr: [*c]const u32 = null;
|
||||
var slice = ptr[0..3];
|
||||
_ = slice;
|
||||
return error.TestFailed;
|
||||
}
|
||||
// run
|
||||
// backend=stage1
|
||||
25
test/cases/safety/switch on corrupted enum value.zig
Normal file
25
test/cases/safety/switch on corrupted enum value.zig
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
const std = @import("std");
|
||||
|
||||
pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn {
|
||||
_ = stack_trace;
|
||||
if (std.mem.eql(u8, message, "reached unreachable code")) {
|
||||
std.process.exit(0);
|
||||
}
|
||||
std.process.exit(1);
|
||||
}
|
||||
|
||||
const E = enum(u32) {
|
||||
X = 1,
|
||||
};
|
||||
|
||||
pub fn main() !void {
|
||||
var e: E = undefined;
|
||||
@memset(@ptrCast([*]u8, &e), 0x55, @sizeOf(E));
|
||||
switch (e) {
|
||||
.X => @breakpoint(),
|
||||
}
|
||||
return error.TestFailed;
|
||||
}
|
||||
|
||||
// run
|
||||
// backend=stage1
|
||||
25
test/cases/safety/switch on corrupted union value.zig
Normal file
25
test/cases/safety/switch on corrupted union value.zig
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
const std = @import("std");
|
||||
|
||||
pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn {
|
||||
_ = stack_trace;
|
||||
if (std.mem.eql(u8, message, "reached unreachable code")) {
|
||||
std.process.exit(0);
|
||||
}
|
||||
std.process.exit(1);
|
||||
}
|
||||
|
||||
const U = union(enum(u32)) {
|
||||
X: u8,
|
||||
};
|
||||
|
||||
pub fn main() !void {
|
||||
var u: U = undefined;
|
||||
@memset(@ptrCast([*]u8, &u), 0x55, @sizeOf(U));
|
||||
switch (u) {
|
||||
.X => @breakpoint(),
|
||||
}
|
||||
return error.TestFailed;
|
||||
}
|
||||
|
||||
// run
|
||||
// backend=stage1
|
||||
19
test/cases/safety/truncating vector cast.zig
Normal file
19
test/cases/safety/truncating vector cast.zig
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
const std = @import("std");
|
||||
|
||||
pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn {
|
||||
_ = stack_trace;
|
||||
if (std.mem.eql(u8, message, "integer cast truncated bits")) {
|
||||
std.process.exit(0);
|
||||
}
|
||||
std.process.exit(1);
|
||||
}
|
||||
|
||||
pub fn main() !void {
|
||||
var x = @splat(4, @as(u32, 0xdeadbeef));
|
||||
var y = @intCast(@Vector(4, u16), x);
|
||||
_ = y;
|
||||
return error.TestFailed;
|
||||
}
|
||||
|
||||
// run
|
||||
// backend=stage1
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
const std = @import("std");
|
||||
|
||||
pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn {
|
||||
_ = message;
|
||||
_ = stack_trace;
|
||||
std.process.exit(0);
|
||||
}
|
||||
pub fn main() !void {
|
||||
var value: u8 = 245;
|
||||
var casted = @intCast(i8, value);
|
||||
_ = casted;
|
||||
return error.TestFailed;
|
||||
}
|
||||
// run
|
||||
// backend=stage1
|
||||
18
test/cases/safety/unsigned shift left overflow.zig
Normal file
18
test/cases/safety/unsigned shift left overflow.zig
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
const std = @import("std");
|
||||
|
||||
pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn {
|
||||
_ = message;
|
||||
_ = stack_trace;
|
||||
std.process.exit(0);
|
||||
}
|
||||
|
||||
pub fn main() !void {
|
||||
const x = shl(0b0010111111111111, 3);
|
||||
if (x == 0) return error.Whatever;
|
||||
return error.TestFailed;
|
||||
}
|
||||
fn shl(a: u16, b: u4) u16 {
|
||||
return @shlExact(a, b);
|
||||
}
|
||||
// run
|
||||
// backend=stage1
|
||||
18
test/cases/safety/unsigned shift right overflow.zig
Normal file
18
test/cases/safety/unsigned shift right overflow.zig
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
const std = @import("std");
|
||||
|
||||
pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn {
|
||||
_ = message;
|
||||
_ = stack_trace;
|
||||
std.process.exit(0);
|
||||
}
|
||||
|
||||
pub fn main() !void {
|
||||
const x = shr(0b0010111111111111, 3);
|
||||
if (x == 0) return error.Whatever;
|
||||
return error.TestFailed;
|
||||
}
|
||||
fn shr(a: u16, b: u4) u16 {
|
||||
return @shrExact(a, b);
|
||||
}
|
||||
// run
|
||||
// backend=stage1
|
||||
19
test/cases/safety/unsigned-signed vector cast.zig
Normal file
19
test/cases/safety/unsigned-signed vector cast.zig
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
const std = @import("std");
|
||||
|
||||
pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn {
|
||||
_ = stack_trace;
|
||||
if (std.mem.eql(u8, message, "integer cast truncated bits")) {
|
||||
std.process.exit(0);
|
||||
}
|
||||
std.process.exit(1);
|
||||
}
|
||||
|
||||
pub fn main() !void {
|
||||
var x = @splat(4, @as(u32, 0x80000000));
|
||||
var y = @intCast(@Vector(4, i32), x);
|
||||
_ = y;
|
||||
return error.TestFailed;
|
||||
}
|
||||
|
||||
// run
|
||||
// backend=stage1
|
||||
18
test/cases/safety/unwrap error.zig
Normal file
18
test/cases/safety/unwrap error.zig
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
const std = @import("std");
|
||||
|
||||
pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn {
|
||||
_ = stack_trace;
|
||||
if (std.mem.eql(u8, message, "attempt to unwrap error: Whatever")) {
|
||||
std.process.exit(0);
|
||||
}
|
||||
std.process.exit(1);
|
||||
}
|
||||
pub fn main() !void {
|
||||
bar() catch unreachable;
|
||||
return error.TestFailed;
|
||||
}
|
||||
fn bar() !void {
|
||||
return error.Whatever;
|
||||
}
|
||||
// run
|
||||
// backend=stage1
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
const std = @import("std");
|
||||
|
||||
pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn {
|
||||
_ = message;
|
||||
_ = stack_trace;
|
||||
std.process.exit(0);
|
||||
}
|
||||
|
||||
pub fn main() !void {
|
||||
const x = shorten_cast(1);
|
||||
if (x == 0) return error.Whatever;
|
||||
return error.TestFailed;
|
||||
}
|
||||
fn shorten_cast(x: u8) u0 {
|
||||
return @intCast(u0, x);
|
||||
}
|
||||
// run
|
||||
// backend=stage1
|
||||
18
test/cases/safety/value does not fit in shortening cast.zig
Normal file
18
test/cases/safety/value does not fit in shortening cast.zig
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
const std = @import("std");
|
||||
|
||||
pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn {
|
||||
_ = message;
|
||||
_ = stack_trace;
|
||||
std.process.exit(0);
|
||||
}
|
||||
|
||||
pub fn main() !void {
|
||||
const x = shorten_cast(200);
|
||||
if (x == 0) return error.Whatever;
|
||||
return error.TestFailed;
|
||||
}
|
||||
fn shorten_cast(x: i32) i8 {
|
||||
return @intCast(i8, x);
|
||||
}
|
||||
// run
|
||||
// backend=stage1
|
||||
19
test/cases/safety/vector integer addition overflow.zig
Normal file
19
test/cases/safety/vector integer addition overflow.zig
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
const std = @import("std");
|
||||
|
||||
pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn {
|
||||
_ = message;
|
||||
_ = stack_trace;
|
||||
std.process.exit(0);
|
||||
}
|
||||
pub fn main() !void {
|
||||
var a: @Vector(4, i32) = [_]i32{ 1, 2, 2147483643, 4 };
|
||||
var b: @Vector(4, i32) = [_]i32{ 5, 6, 7, 8 };
|
||||
const x = add(a, b);
|
||||
_ = x;
|
||||
return error.TestFailed;
|
||||
}
|
||||
fn add(a: @Vector(4, i32), b: @Vector(4, i32)) @Vector(4, i32) {
|
||||
return a + b;
|
||||
}
|
||||
// run
|
||||
// backend=stage1
|
||||
19
test/cases/safety/vector integer multiplication overflow.zig
Normal file
19
test/cases/safety/vector integer multiplication overflow.zig
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
const std = @import("std");
|
||||
|
||||
pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn {
|
||||
_ = message;
|
||||
_ = stack_trace;
|
||||
std.process.exit(0);
|
||||
}
|
||||
pub fn main() !void {
|
||||
var a: @Vector(4, u8) = [_]u8{ 1, 2, 200, 4 };
|
||||
var b: @Vector(4, u8) = [_]u8{ 5, 6, 2, 8 };
|
||||
const x = mul(b, a);
|
||||
_ = x;
|
||||
return error.TestFailed;
|
||||
}
|
||||
fn mul(a: @Vector(4, u8), b: @Vector(4, u8)) @Vector(4, u8) {
|
||||
return a * b;
|
||||
}
|
||||
// run
|
||||
// backend=stage1
|
||||
18
test/cases/safety/vector integer negation overflow.zig
Normal file
18
test/cases/safety/vector integer negation overflow.zig
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
const std = @import("std");
|
||||
|
||||
pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn {
|
||||
_ = message;
|
||||
_ = stack_trace;
|
||||
std.process.exit(0);
|
||||
}
|
||||
pub fn main() !void {
|
||||
var a: @Vector(4, i16) = [_]i16{ 1, -32768, 200, 4 };
|
||||
const x = neg(a);
|
||||
_ = x;
|
||||
return error.TestFailed;
|
||||
}
|
||||
fn neg(a: @Vector(4, i16)) @Vector(4, i16) {
|
||||
return -a;
|
||||
}
|
||||
// run
|
||||
// backend=stage1
|
||||
19
test/cases/safety/vector integer subtraction overflow.zig
Normal file
19
test/cases/safety/vector integer subtraction overflow.zig
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
const std = @import("std");
|
||||
|
||||
pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn {
|
||||
_ = message;
|
||||
_ = stack_trace;
|
||||
std.process.exit(0);
|
||||
}
|
||||
pub fn main() !void {
|
||||
var a: @Vector(4, u32) = [_]u32{ 1, 2, 8, 4 };
|
||||
var b: @Vector(4, u32) = [_]u32{ 5, 6, 7, 8 };
|
||||
const x = sub(b, a);
|
||||
_ = x;
|
||||
return error.TestFailed;
|
||||
}
|
||||
fn sub(a: @Vector(4, u32), b: @Vector(4, u32)) @Vector(4, u32) {
|
||||
return a - b;
|
||||
}
|
||||
// run
|
||||
// backend=stage1
|
||||
File diff suppressed because it is too large
Load diff
|
|
@ -18,7 +18,6 @@ const compare_output = @import("compare_output.zig");
|
|||
const standalone = @import("standalone.zig");
|
||||
const stack_traces = @import("stack_traces.zig");
|
||||
const assemble_and_link = @import("assemble_and_link.zig");
|
||||
const runtime_safety = @import("runtime_safety.zig");
|
||||
const translate_c = @import("translate_c.zig");
|
||||
const run_translated_c = @import("run_translated_c.zig");
|
||||
const gen_h = @import("gen_h.zig");
|
||||
|
|
@ -455,21 +454,6 @@ pub fn addStackTraceTests(b: *build.Builder, test_filter: ?[]const u8, modes: []
|
|||
return cases.step;
|
||||
}
|
||||
|
||||
pub fn addRuntimeSafetyTests(b: *build.Builder, test_filter: ?[]const u8, modes: []const Mode) *build.Step {
|
||||
const cases = b.allocator.create(CompareOutputContext) catch unreachable;
|
||||
cases.* = CompareOutputContext{
|
||||
.b = b,
|
||||
.step = b.step("test-runtime-safety", "Run the runtime safety tests"),
|
||||
.test_index = 0,
|
||||
.test_filter = test_filter,
|
||||
.modes = modes,
|
||||
};
|
||||
|
||||
runtime_safety.addCases(cases);
|
||||
|
||||
return cases.step;
|
||||
}
|
||||
|
||||
pub fn addStandaloneTests(
|
||||
b: *build.Builder,
|
||||
test_filter: ?[]const u8,
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue