Merge pull request #9191 from ziglang/stage1-astcheck

run AstGen even when using the stage1 backend
This commit is contained in:
Andrew Kelley 2021-06-23 18:09:19 -04:00 committed by GitHub
commit 31c49ad64d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 583 additions and 96 deletions

View File

@ -91,7 +91,12 @@ set(ZIG_TARGET_MCPU "baseline" CACHE STRING "-mcpu parameter to output binaries
set(ZIG_EXECUTABLE "" CACHE STRING "(when cross compiling) path to already-built zig binary") set(ZIG_EXECUTABLE "" CACHE STRING "(when cross compiling) path to already-built zig binary")
set(ZIG_SINGLE_THREADED off CACHE BOOL "limit the zig compiler to use only 1 thread") set(ZIG_SINGLE_THREADED off CACHE BOOL "limit the zig compiler to use only 1 thread")
set(ZIG_OMIT_STAGE2 off CACHE BOOL "omit the stage2 backend from stage1") set(ZIG_OMIT_STAGE2 off CACHE BOOL "omit the stage2 backend from stage1")
set(ZIG_ENABLE_LOGGING off CACHE BOOL "enable logging")
if("${CMAKE_BUILD_TYPE}" STREQUAL "Debug")
set(ZIG_ENABLE_LOGGING ON CACHE BOOL "enable logging")
else()
set(ZIG_ENABLE_LOGGING OFF CACHE BOOL "enable logging")
endif()
if("${ZIG_TARGET_TRIPLE}" STREQUAL "native") if("${ZIG_TARGET_TRIPLE}" STREQUAL "native")
set(ZIG_USE_LLVM_CONFIG ON CACHE BOOL "use llvm-config to find LLVM libraries") set(ZIG_USE_LLVM_CONFIG ON CACHE BOOL "use llvm-config to find LLVM libraries")

View File

@ -59,9 +59,9 @@ unset CXX
make $JOBS install make $JOBS install
# Look for formatting errors and AST errors. # Look for non-conforming code formatting.
# Formatting errors can be fixed by running `zig fmt` on the files printed here. # Formatting errors can be fixed by running `zig fmt` on the files printed here.
release/bin/zig fmt --check --ast-check .. release/bin/zig fmt --check ..
# Here we rebuild zig but this time using the Zig binary we just now produced to # Here we rebuild zig but this time using the Zig binary we just now produced to
# build zig1.o rather than relying on the one built with stage0. See # build zig1.o rather than relying on the one built with stage0. See

View File

@ -965,7 +965,7 @@ test "thread local storage" {
thread2.wait(); thread2.wait();
} }
fn testTls(context: void) void { fn testTls(_: void) void {
assert(x == 1234); assert(x == 1234);
x += 1; x += 1;
assert(x == 1235); assert(x == 1235);
@ -2502,6 +2502,8 @@ test "struct namespaced variable" {
// you can still instantiate an empty struct // you can still instantiate an empty struct
const does_nothing = Empty {}; const does_nothing = Empty {};
_ = does_nothing;
} }
// struct field order is determined by the compiler for optimal performance. // struct field order is determined by the compiler for optimal performance.
@ -3026,11 +3028,12 @@ const Foo = enum { a, b, c };
export fn entry(foo: Foo) void { } export fn entry(foo: Foo) void { }
{#code_end#} {#code_end#}
<p> <p>
For a C-ABI-compatible enum, use {#syntax#}extern enum{#endsyntax#}: For a C-ABI-compatible enum, provide an explicit tag type to
the enum:
</p> </p>
{#code_begin|obj#} {#code_begin|obj#}
const Foo = extern enum { a, b, c }; const Foo = enum(c_int) { a, b, c };
export fn entry(foo: Foo) void { } export fn entry(foo: Foo) void { _ = foo; }
{#code_end#} {#code_end#}
{#header_close#} {#header_close#}
@ -3392,9 +3395,11 @@ test "inside test block" {
test "separate scopes" { test "separate scopes" {
{ {
const pi = 3.14; const pi = 3.14;
_ = pi;
} }
{ {
var pi: bool = true; var pi: bool = true;
_ = pi;
} }
} }
{#code_end#} {#code_end#}
@ -3432,7 +3437,7 @@ test "switch simple" {
// Switching on arbitrary expressions is allowed as long as the // Switching on arbitrary expressions is allowed as long as the
// expression is known at compile-time. // expression is known at compile-time.
zz => zz, zz => zz,
comptime blk: { blk: {
const d: u32 = 5; const d: u32 = 5;
const e: u32 = 100; const e: u32 = 100;
break :blk d + e; break :blk d + e;
@ -3831,7 +3836,7 @@ test "for basics" {
// To access the index of iteration, specify a second capture value. // To access the index of iteration, specify a second capture value.
// This is zero-indexed. // This is zero-indexed.
var sum2: i32 = 0; var sum2: i32 = 0;
for (items) |value, i| { for (items) |_, i| {
try expect(@TypeOf(i) == usize); try expect(@TypeOf(i) == usize);
sum2 += @intCast(i32, i); sum2 += @intCast(i32, i);
} }
@ -3984,7 +3989,7 @@ test "if optional" {
} }
const b: ?u32 = null; const b: ?u32 = null;
if (b) |value| { if (b) |_| {
unreachable; unreachable;
} else { } else {
try expect(true); try expect(true);
@ -4021,11 +4026,13 @@ test "if error union" {
if (a) |value| { if (a) |value| {
try expect(value == 0); try expect(value == 0);
} else |err| { } else |err| {
_ = err;
unreachable; unreachable;
} }
const b: anyerror!u32 = error.BadValue; const b: anyerror!u32 = error.BadValue;
if (b) |value| { if (b) |value| {
_ = value;
unreachable; unreachable;
} else |err| { } else |err| {
try expect(err == error.BadValue); try expect(err == error.BadValue);
@ -4045,13 +4052,13 @@ test "if error union" {
var c: anyerror!u32 = 3; var c: anyerror!u32 = 3;
if (c) |*value| { if (c) |*value| {
value.* = 9; value.* = 9;
} else |err| { } else |_| {
unreachable; unreachable;
} }
if (c) |value| { if (c) |value| {
try expect(value == 9); try expect(value == 9);
} else |err| { } else |_| {
unreachable; unreachable;
} }
} }
@ -4064,18 +4071,20 @@ test "if error union with optional" {
if (a) |optional_value| { if (a) |optional_value| {
try expect(optional_value.? == 0); try expect(optional_value.? == 0);
} else |err| { } else |err| {
_ = err;
unreachable; unreachable;
} }
const b: anyerror!?u32 = null; const b: anyerror!?u32 = null;
if (b) |optional_value| { if (b) |optional_value| {
try expect(optional_value == null); try expect(optional_value == null);
} else |err| { } else |_| {
unreachable; unreachable;
} }
const c: anyerror!?u32 = error.BadValue; const c: anyerror!?u32 = error.BadValue;
if (c) |optional_value| { if (c) |optional_value| {
_ = optional_value;
unreachable; unreachable;
} else |err| { } else |err| {
try expect(err == error.BadValue); try expect(err == error.BadValue);
@ -4087,13 +4096,13 @@ test "if error union with optional" {
if (optional_value.*) |*value| { if (optional_value.*) |*value| {
value.* = 9; value.* = 9;
} }
} else |err| { } else |_| {
unreachable; unreachable;
} }
if (d) |optional_value| { if (d) |optional_value| {
try expect(optional_value.? == 9); try expect(optional_value.? == 9);
} else |err| { } else |_| {
unreachable; unreachable;
} }
} }
@ -4246,6 +4255,7 @@ test "type of unreachable" {
{#code_begin|test#} {#code_begin|test#}
fn foo(condition: bool, b: u32) void { fn foo(condition: bool, b: u32) void {
const a = if (condition) b else return; const a = if (condition) b else return;
_ = a;
@panic("do something with a"); @panic("do something with a");
} }
test "noreturn" { test "noreturn" {
@ -4574,7 +4584,7 @@ test "parse u64" {
{#code_begin|syntax#} {#code_begin|syntax#}
fn doAThing(str: []u8) void { fn doAThing(str: []u8) void {
const number = parseU64(str, 10) catch 13; const number = parseU64(str, 10) catch 13;
// ... _ = number; // ...
} }
{#code_end#} {#code_end#}
<p> <p>
@ -4589,7 +4599,7 @@ fn doAThing(str: []u8) void {
{#code_begin|syntax#} {#code_begin|syntax#}
fn doAThing(str: []u8) !void { fn doAThing(str: []u8) !void {
const number = parseU64(str, 10) catch |err| return err; const number = parseU64(str, 10) catch |err| return err;
// ... _ = number; // ...
} }
{#code_end#} {#code_end#}
<p> <p>
@ -4598,7 +4608,7 @@ fn doAThing(str: []u8) !void {
{#code_begin|syntax#} {#code_begin|syntax#}
fn doAThing(str: []u8) !void { fn doAThing(str: []u8) !void {
const number = try parseU64(str, 10); const number = try parseU64(str, 10);
// ... _ = number; // ...
} }
{#code_end#} {#code_end#}
<p> <p>
@ -5022,7 +5032,7 @@ extern fn malloc(size: size_t) ?*u8;
fn doAThing() ?*Foo { fn doAThing() ?*Foo {
const ptr = malloc(1234) orelse return null; const ptr = malloc(1234) orelse return null;
// ... _ = ptr; // ...
} }
{#code_end#} {#code_end#}
<p> <p>
@ -5135,6 +5145,7 @@ test "optional pointers" {
test "type coercion - variable declaration" { test "type coercion - variable declaration" {
var a: u8 = 1; var a: u8 = 1;
var b: u16 = a; var b: u16 = a;
_ = b;
} }
test "type coercion - function call" { test "type coercion - function call" {
@ -5142,11 +5153,14 @@ test "type coercion - function call" {
foo(a); foo(a);
} }
fn foo(b: u16) void {} fn foo(b: u16) void {
_ = b;
}
test "type coercion - @as builtin" { test "type coercion - @as builtin" {
var a: u8 = 1; var a: u8 = 1;
var b = @as(u16, a); var b = @as(u16, a);
_ = b;
} }
{#code_end#} {#code_end#}
<p> <p>
@ -5174,7 +5188,7 @@ test "type coercion - const qualification" {
foo(b); foo(b);
} }
fn foo(a: *const i32) void {} fn foo(_: *const i32) void {}
{#code_end#} {#code_end#}
<p> <p>
In addition, pointers coerce to const optional pointers: In addition, pointers coerce to const optional pointers:
@ -5424,7 +5438,7 @@ test "coercion between unions and enums" {
test "coercion of zero bit types" { test "coercion of zero bit types" {
var x: void = {}; var x: void = {};
var y: *void = x; var y: *void = x;
//var z: void = y; // TODO _ = y;
} }
{#code_end#} {#code_end#}
{#header_close#} {#header_close#}
@ -6569,6 +6583,7 @@ var x: i32 = 1;
test "suspend with no resume" { test "suspend with no resume" {
var frame = async func(); var frame = async func();
try expect(x == 2); try expect(x == 2);
_ = frame;
} }
fn func() void { fn func() void {
@ -6800,6 +6815,7 @@ fn amain() !void {
var global_download_frame: anyframe = undefined; var global_download_frame: anyframe = undefined;
fn fetchUrl(allocator: *Allocator, url: []const u8) ![]u8 { fn fetchUrl(allocator: *Allocator, url: []const u8) ![]u8 {
_ = url; // this is just an example, we don't actually do it!
const result = try std.mem.dupe(allocator, u8, "this is the downloaded url contents"); const result = try std.mem.dupe(allocator, u8, "this is the downloaded url contents");
errdefer allocator.free(result); errdefer allocator.free(result);
suspend { suspend {
@ -6811,6 +6827,7 @@ fn fetchUrl(allocator: *Allocator, url: []const u8) ![]u8 {
var global_file_frame: anyframe = undefined; var global_file_frame: anyframe = undefined;
fn readFile(allocator: *Allocator, filename: []const u8) ![]u8 { fn readFile(allocator: *Allocator, filename: []const u8) ![]u8 {
_ = filename; // this is just an example, we don't actually do it!
const result = try std.mem.dupe(allocator, u8, "this is the file contents"); const result = try std.mem.dupe(allocator, u8, "this is the file contents");
errdefer allocator.free(result); errdefer allocator.free(result);
suspend { suspend {
@ -6869,6 +6886,7 @@ fn amain() !void {
} }
fn fetchUrl(allocator: *Allocator, url: []const u8) ![]u8 { fn fetchUrl(allocator: *Allocator, url: []const u8) ![]u8 {
_ = url; // this is just an example, we don't actually do it!
const result = try std.mem.dupe(allocator, u8, "this is the downloaded url contents"); const result = try std.mem.dupe(allocator, u8, "this is the downloaded url contents");
errdefer allocator.free(result); errdefer allocator.free(result);
std.debug.print("fetchUrl returning\n", .{}); std.debug.print("fetchUrl returning\n", .{});
@ -6876,6 +6894,7 @@ fn fetchUrl(allocator: *Allocator, url: []const u8) ![]u8 {
} }
fn readFile(allocator: *Allocator, filename: []const u8) ![]u8 { fn readFile(allocator: *Allocator, filename: []const u8) ![]u8 {
_ = filename; // this is just an example, we don't actually do it!
const result = try std.mem.dupe(allocator, u8, "this is the file contents"); const result = try std.mem.dupe(allocator, u8, "this is the file contents");
errdefer allocator.free(result); errdefer allocator.free(result);
std.debug.print("readFile returning\n", .{}); std.debug.print("readFile returning\n", .{});
@ -8584,6 +8603,7 @@ fn List(comptime T: type) type {
test "integer cast panic" { test "integer cast panic" {
var a: u16 = 0xabcd; var a: u16 = 0xabcd;
var b: u8 = @intCast(u8, a); var b: u8 = @intCast(u8, a);
_ = b;
} }
{#code_end#} {#code_end#}
<p> <p>
@ -8839,6 +8859,7 @@ comptime {
{#code_begin|exe_err#} {#code_begin|exe_err#}
pub fn main() void { pub fn main() void {
var x = foo("hello"); var x = foo("hello");
_ = x;
} }
fn foo(x: []const u8) u8 { fn foo(x: []const u8) u8 {
@ -9107,6 +9128,7 @@ pub fn main() void {
comptime { comptime {
const optional_number: ?i32 = null; const optional_number: ?i32 = null;
const number = optional_number.?; const number = optional_number.?;
_ = number;
} }
{#code_end#} {#code_end#}
<p>At runtime:</p> <p>At runtime:</p>
@ -9140,6 +9162,7 @@ pub fn main() void {
{#code_begin|test_err|caught unexpected error 'UnableToReturnNumber'#} {#code_begin|test_err|caught unexpected error 'UnableToReturnNumber'#}
comptime { comptime {
const number = getNumberOrFail() catch unreachable; const number = getNumberOrFail() catch unreachable;
_ = number;
} }
fn getNumberOrFail() !i32 { fn getNumberOrFail() !i32 {
@ -9187,6 +9210,7 @@ comptime {
const err = error.AnError; const err = error.AnError;
const number = @errorToInt(err) + 10; const number = @errorToInt(err) + 10;
const invalid_err = @intToError(number); const invalid_err = @intToError(number);
_ = invalid_err;
} }
{#code_end#} {#code_end#}
<p>At runtime:</p> <p>At runtime:</p>
@ -9197,7 +9221,7 @@ pub fn main() void {
var err = error.AnError; var err = error.AnError;
var number = @errorToInt(err) + 500; var number = @errorToInt(err) + 500;
var invalid_err = @intToError(number); var invalid_err = @intToError(number);
std.debug.print("value: {}\n", .{number}); std.debug.print("value: {}\n", .{invalid_err});
} }
{#code_end#} {#code_end#}
{#header_close#} {#header_close#}
@ -9212,6 +9236,7 @@ const Foo = enum {
comptime { comptime {
const a: u2 = 3; const a: u2 = 3;
const b = @intToEnum(Foo, a); const b = @intToEnum(Foo, a);
_ = b;
} }
{#code_end#} {#code_end#}
<p>At runtime:</p> <p>At runtime:</p>
@ -9396,6 +9421,7 @@ comptime {
pub fn main() void { pub fn main() void {
var opt_ptr: ?*i32 = null; var opt_ptr: ?*i32 = null;
var ptr = @ptrCast(*i32, opt_ptr); var ptr = @ptrCast(*i32, opt_ptr);
_ = ptr;
} }
{#code_end#} {#code_end#}
{#header_close#} {#header_close#}
@ -9523,7 +9549,9 @@ pub fn main() !void {
This is why it is an error to pass a string literal to a mutable slice, like this: This is why it is an error to pass a string literal to a mutable slice, like this:
</p> </p>
{#code_begin|test_err|expected type '[]u8'#} {#code_begin|test_err|expected type '[]u8'#}
fn foo(s: []u8) void {} fn foo(s: []u8) void {
_ = s;
}
test "string literal to mutable slice" { test "string literal to mutable slice" {
foo("hello"); foo("hello");
@ -9531,7 +9559,9 @@ test "string literal to mutable slice" {
{#code_end#} {#code_end#}
<p>However if you make the slice constant, then it works:</p> <p>However if you make the slice constant, then it works:</p>
{#code_begin|test|strlit#} {#code_begin|test|strlit#}
fn foo(s: []const u8) void {} fn foo(s: []const u8) void {
_ = s;
}
test "string literal to constant slice" { test "string literal to constant slice" {
foo("hello"); foo("hello");
@ -10476,7 +10506,7 @@ coding style.
</p> </p>
{#header_close#} {#header_close#}
{#header_open|Examples#} {#header_open|Examples#}
{#code_begin|syntax#} <pre>{#syntax#}
const namespace_name = @import("dir_name/file_name.zig"); const namespace_name = @import("dir_name/file_name.zig");
const TypeName = @import("dir_name/TypeName.zig"); const TypeName = @import("dir_name/TypeName.zig");
var global_var: i32 = undefined; var global_var: i32 = undefined;
@ -10520,7 +10550,7 @@ const XmlParser = struct {
// The initials BE (Big Endian) are just another word in Zig identifier names. // The initials BE (Big Endian) are just another word in Zig identifier names.
fn readU32Be() u32 {} fn readU32Be() u32 {}
{#code_end#} {#endsyntax#}</pre>
<p> <p>
See the Zig Standard Library for more examples. See the Zig Standard Library for more examples.
</p> </p>

View File

@ -3558,6 +3558,10 @@ fn structDeclInner(
const field_name = try astgen.identAsString(member.ast.name_token); const field_name = try astgen.identAsString(member.ast.name_token);
fields_data.appendAssumeCapacity(field_name); fields_data.appendAssumeCapacity(field_name);
if (member.ast.type_expr == 0) {
return astgen.failTok(member.ast.name_token, "struct field missing type", .{});
}
const field_type: Zir.Inst.Ref = if (node_tags[member.ast.type_expr] == .@"anytype") const field_type: Zir.Inst.Ref = if (node_tags[member.ast.type_expr] == .@"anytype")
.none .none
else else

View File

@ -342,6 +342,7 @@ pub const AllErrors = struct {
const stderr = stderr_file.writer(); const stderr = stderr_file.writer();
switch (msg) { switch (msg) {
.src => |src| { .src => |src| {
try stderr.writeByteNTimes(' ', indent);
ttyconf.setColor(stderr, .Bold); ttyconf.setColor(stderr, .Bold);
try stderr.print("{s}:{d}:{d}: ", .{ try stderr.print("{s}:{d}:{d}: ", .{
src.src_path, src.src_path,
@ -349,7 +350,6 @@ pub const AllErrors = struct {
src.column + 1, src.column + 1,
}); });
ttyconf.setColor(stderr, color); ttyconf.setColor(stderr, color);
try stderr.writeByteNTimes(' ', indent);
try stderr.writeAll(kind); try stderr.writeAll(kind);
ttyconf.setColor(stderr, .Reset); ttyconf.setColor(stderr, .Reset);
ttyconf.setColor(stderr, .Bold); ttyconf.setColor(stderr, .Bold);
@ -731,6 +731,7 @@ fn addPackageTableToCacheHash(
hash: *Cache.HashHelper, hash: *Cache.HashHelper,
arena: *std.heap.ArenaAllocator, arena: *std.heap.ArenaAllocator,
pkg_table: Package.Table, pkg_table: Package.Table,
seen_table: *std.AutoHashMap(*Package, void),
hash_type: union(enum) { path_bytes, files: *Cache.Manifest }, hash_type: union(enum) { path_bytes, files: *Cache.Manifest },
) (error{OutOfMemory} || std.os.GetCwdError)!void { ) (error{OutOfMemory} || std.os.GetCwdError)!void {
const allocator = &arena.allocator; const allocator = &arena.allocator;
@ -755,6 +756,8 @@ fn addPackageTableToCacheHash(
}.lessThan); }.lessThan);
for (packages) |pkg| { for (packages) |pkg| {
if ((try seen_table.getOrPut(pkg.value)).found_existing) continue;
// Finally insert the package name and path to the cache hash. // Finally insert the package name and path to the cache hash.
hash.addBytes(pkg.key); hash.addBytes(pkg.key);
switch (hash_type) { switch (hash_type) {
@ -770,7 +773,7 @@ fn addPackageTableToCacheHash(
}, },
} }
// Recurse to handle the package's dependencies // Recurse to handle the package's dependencies
try addPackageTableToCacheHash(hash, arena, pkg.value.table, hash_type); try addPackageTableToCacheHash(hash, arena, pkg.value.table, seen_table, hash_type);
} }
} }
@ -1116,7 +1119,8 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation {
{ {
var local_arena = std.heap.ArenaAllocator.init(gpa); var local_arena = std.heap.ArenaAllocator.init(gpa);
defer local_arena.deinit(); defer local_arena.deinit();
try addPackageTableToCacheHash(&hash, &local_arena, root_pkg.table, .path_bytes); var seen_table = std.AutoHashMap(*Package, void).init(&local_arena.allocator);
try addPackageTableToCacheHash(&hash, &local_arena, root_pkg.table, &seen_table, .path_bytes);
} }
hash.add(valgrind); hash.add(valgrind);
hash.add(single_threaded); hash.add(single_threaded);
@ -1137,9 +1141,6 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation {
artifact_sub_dir, artifact_sub_dir,
}; };
// If we rely on stage1, we must not redundantly add these packages.
const use_stage1 = build_options.is_stage1 and use_llvm;
if (!use_stage1) {
const builtin_pkg = try Package.createWithDir( const builtin_pkg = try Package.createWithDir(
gpa, gpa,
zig_cache_artifact_directory, zig_cache_artifact_directory,
@ -1166,7 +1167,6 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation {
try builtin_pkg.add(gpa, "std", std_pkg); try builtin_pkg.add(gpa, "std", std_pkg);
try builtin_pkg.add(gpa, "builtin", builtin_pkg); try builtin_pkg.add(gpa, "builtin", builtin_pkg);
}
// Pre-open the directory handles for cached ZIR code so that it does not need // Pre-open the directory handles for cached ZIR code so that it does not need
// to redundantly happen for each AstGen operation. // to redundantly happen for each AstGen operation.
@ -1625,13 +1625,11 @@ pub fn update(self: *Compilation) !void {
// Add a Job for each C object. // Add a Job for each C object.
try self.c_object_work_queue.ensureUnusedCapacity(self.c_object_table.count()); try self.c_object_work_queue.ensureUnusedCapacity(self.c_object_table.count());
for (self.c_object_table.keys()) |key| { for (self.c_object_table.keys()) |key| {
assert(@ptrToInt(key) != 0xaaaa_aaaa_aaaa_aaaa);
self.c_object_work_queue.writeItemAssumeCapacity(key); self.c_object_work_queue.writeItemAssumeCapacity(key);
} }
const use_stage1 = build_options.omit_stage2 or const use_stage1 = build_options.omit_stage2 or
(build_options.is_stage1 and self.bin_file.options.use_llvm); (build_options.is_stage1 and self.bin_file.options.use_llvm);
if (!use_stage1) {
if (self.bin_file.options.module) |module| { if (self.bin_file.options.module) |module| {
module.compile_log_text.shrinkAndFree(module.gpa, 0); module.compile_log_text.shrinkAndFree(module.gpa, 0);
module.generation += 1; module.generation += 1;
@ -1641,14 +1639,25 @@ pub fn update(self: *Compilation) !void {
const std_pkg = module.root_pkg.table.get("std").?; const std_pkg = module.root_pkg.table.get("std").?;
_ = try module.importPkg(std_pkg); _ = try module.importPkg(std_pkg);
// Normally we rely on importing std to in turn import the root source file
// in the start code, but when using the stage1 backend that won't happen,
// so in order to run AstGen on the root source file we put it into the
// import_table here.
if (use_stage1) {
_ = try module.importPkg(module.root_pkg);
}
// Put a work item in for every known source file to detect if // Put a work item in for every known source file to detect if
// it changed, and, if so, re-compute ZIR and then queue the job // it changed, and, if so, re-compute ZIR and then queue the job
// to update it. // to update it.
// We still want AstGen work items for stage1 so that we expose compile errors
// that are implemented in stage2 but not stage1.
try self.astgen_work_queue.ensureUnusedCapacity(module.import_table.count()); try self.astgen_work_queue.ensureUnusedCapacity(module.import_table.count());
for (module.import_table.values()) |value| { for (module.import_table.values()) |value| {
self.astgen_work_queue.writeItemAssumeCapacity(value); self.astgen_work_queue.writeItemAssumeCapacity(value);
} }
if (!use_stage1) {
try self.work_queue.writeItem(.{ .analyze_pkg = std_pkg }); try self.work_queue.writeItem(.{ .analyze_pkg = std_pkg });
} }
} }
@ -1915,7 +1924,7 @@ pub fn performAllTheWork(self: *Compilation) error{ TimerUnsupported, OutOfMemor
// (at least for now) single-threaded main work queue. However, C object compilation // (at least for now) single-threaded main work queue. However, C object compilation
// only needs to be finished by the end of this function. // only needs to be finished by the end of this function.
var zir_prog_node = main_progress_node.start("AstGen", self.astgen_work_queue.count); var zir_prog_node = main_progress_node.start("AST Lowering", self.astgen_work_queue.count);
defer zir_prog_node.end(); defer zir_prog_node.end();
var c_obj_prog_node = main_progress_node.start("Compile C Objects", self.c_source_files.len); var c_obj_prog_node = main_progress_node.start("Compile C Objects", self.c_source_files.len);
@ -1936,7 +1945,6 @@ pub fn performAllTheWork(self: *Compilation) error{ TimerUnsupported, OutOfMemor
} }
while (self.c_object_work_queue.readItem()) |c_object| { while (self.c_object_work_queue.readItem()) |c_object| {
assert(@ptrToInt(c_object) != 0xaaaa_aaaa_aaaa_aaaa);
self.work_queue_wait_group.start(); self.work_queue_wait_group.start();
try self.thread_pool.spawn(workerUpdateCObject, .{ try self.thread_pool.spawn(workerUpdateCObject, .{
self, c_object, &c_obj_prog_node, &self.work_queue_wait_group, self, c_object, &c_obj_prog_node, &self.work_queue_wait_group,
@ -1944,10 +1952,14 @@ pub fn performAllTheWork(self: *Compilation) error{ TimerUnsupported, OutOfMemor
} }
} }
const use_stage1 = build_options.omit_stage2 or
(build_options.is_stage1 and self.bin_file.options.use_llvm);
if (!use_stage1) {
// Iterate over all the files and look for outdated and deleted declarations. // Iterate over all the files and look for outdated and deleted declarations.
if (self.bin_file.options.module) |mod| { if (self.bin_file.options.module) |mod| {
try mod.processOutdatedAndDeletedDecls(); try mod.processOutdatedAndDeletedDecls();
} }
}
while (self.work_queue.readItem()) |work_item| switch (work_item) { while (self.work_queue.readItem()) |work_item| switch (work_item) {
.codegen_decl => |decl| switch (decl.analysis) { .codegen_decl => |decl| switch (decl.analysis) {
@ -2319,6 +2331,9 @@ fn workerAstGenFile(
break :blk mod.importFile(file, import_path) catch continue; break :blk mod.importFile(file, import_path) catch continue;
}; };
if (import_result.is_new) { if (import_result.is_new) {
log.debug("AstGen of {s} has import '{s}'; queuing AstGen of {s}", .{
file.sub_file_path, import_path, import_result.file.sub_file_path,
});
wg.start(); wg.start();
comp.thread_pool.spawn(workerAstGenFile, .{ comp.thread_pool.spawn(workerAstGenFile, .{
comp, import_result.file, prog_node, wg, comp, import_result.file, prog_node, wg,
@ -2540,11 +2555,21 @@ fn reportRetryableAstGenError(
file.status = .retryable_failure; file.status = .retryable_failure;
const err_msg = try Module.ErrorMsg.create(gpa, .{ const src_loc: Module.SrcLoc = .{
.file_scope = file, .file_scope = file,
.parent_decl_node = 0, .parent_decl_node = 0,
.lazy = .entire_file, .lazy = .entire_file,
}, "unable to load {s}: {s}", .{ };
const err_msg = if (file.pkg.root_src_directory.path) |dir_path|
try Module.ErrorMsg.create(
gpa,
src_loc,
"unable to load {s}" ++ std.fs.path.sep_str ++ "{s}: {s}",
.{ dir_path, file.sub_file_path, @errorName(err) },
)
else
try Module.ErrorMsg.create(gpa, src_loc, "unable to load {s}: {s}", .{
file.sub_file_path, @errorName(err), file.sub_file_path, @errorName(err),
}); });
errdefer err_msg.destroy(gpa); errdefer err_msg.destroy(gpa);
@ -3830,9 +3855,8 @@ fn updateStage1Module(comp: *Compilation, main_progress_node: *std.Progress.Node
_ = try man.addFile(main_zig_file, null); _ = try man.addFile(main_zig_file, null);
{ {
var local_arena = std.heap.ArenaAllocator.init(comp.gpa); var seen_table = std.AutoHashMap(*Package, void).init(&arena_allocator.allocator);
defer local_arena.deinit(); try addPackageTableToCacheHash(&man.hash, &arena_allocator, mod.root_pkg.table, &seen_table, .{ .files = &man });
try addPackageTableToCacheHash(&man.hash, &local_arena, mod.root_pkg.table, .{ .files = &man });
} }
man.hash.add(comp.bin_file.options.valgrind); man.hash.add(comp.bin_file.options.valgrind);
man.hash.add(comp.bin_file.options.single_threaded); man.hash.add(comp.bin_file.options.single_threaded);
@ -4103,6 +4127,12 @@ fn createStage1Pkg(
var children = std.ArrayList(*stage1.Pkg).init(arena); var children = std.ArrayList(*stage1.Pkg).init(arena);
var it = pkg.table.iterator(); var it = pkg.table.iterator();
while (it.next()) |entry| { while (it.next()) |entry| {
if (mem.eql(u8, entry.key_ptr.*, "std") or
mem.eql(u8, entry.key_ptr.*, "builtin") or
mem.eql(u8, entry.key_ptr.*, "root"))
{
continue;
}
try children.append(try createStage1Pkg(arena, entry.key_ptr.*, entry.value_ptr.*, child_pkg)); try children.append(try createStage1Pkg(arena, entry.key_ptr.*, entry.value_ptr.*, child_pkg));
} }
break :blk children.items; break :blk children.items;

View File

@ -3185,6 +3185,9 @@ pub fn importFile(
if (cur_file.pkg.table.get(import_string)) |pkg| { if (cur_file.pkg.table.get(import_string)) |pkg| {
return mod.importPkg(pkg); return mod.importPkg(pkg);
} }
if (!mem.endsWith(u8, import_string, ".zig")) {
return error.PackageNotFound;
}
const gpa = mod.gpa; const gpa = mod.gpa;
// The resolved path is used as the key in the import table, to detect if // The resolved path is used as the key in the import table, to detect if

View File

@ -4,7 +4,6 @@ const mem = std.mem;
const assert = std.debug.assert; const assert = std.debug.assert;
const ArrayList = std.ArrayList; const ArrayList = std.ArrayList;
const Allocator = std.mem.Allocator; const Allocator = std.mem.Allocator;
const Type = @import("../Type.zig");
const DW = std.dwarf; const DW = std.dwarf;
// zig fmt: off // zig fmt: off

View File

@ -151,6 +151,12 @@ const Scope = struct {
return true; return true;
return scope.base.parent.?.contains(name); return scope.base.parent.?.contains(name);
} }
fn discardVariable(scope: *Block, c: *Context, name: []const u8) Error!void {
const name_node = try Tag.identifier.create(c.arena, name);
const discard = try Tag.discard.create(c.arena, name_node);
try scope.statements.append(discard);
}
}; };
const Root = struct { const Root = struct {
@ -625,6 +631,7 @@ fn visitFnDecl(c: *Context, fn_decl: *const clang.FunctionDecl) Error!void {
const redecl_node = try Tag.arg_redecl.create(c.arena, .{ .actual = mangled_param_name, .mangled = arg_name }); const redecl_node = try Tag.arg_redecl.create(c.arena, .{ .actual = mangled_param_name, .mangled = arg_name });
try block_scope.statements.append(redecl_node); try block_scope.statements.append(redecl_node);
} }
try block_scope.discardVariable(c, mangled_param_name);
param_id += 1; param_id += 1;
} }
@ -827,6 +834,7 @@ fn transTypeDef(c: *Context, scope: *Scope, typedef_decl: *const clang.TypedefNa
try addTopLevelDecl(c, name, node); try addTopLevelDecl(c, name, node);
} else { } else {
try scope.appendNode(node); try scope.appendNode(node);
try bs.discardVariable(c, name);
} }
} }
@ -1077,6 +1085,7 @@ fn transRecordDecl(c: *Context, scope: *Scope, record_decl: *const clang.RecordD
try c.alias_list.append(.{ .alias = bare_name, .name = name }); try c.alias_list.append(.{ .alias = bare_name, .name = name });
} else { } else {
try scope.appendNode(Node.initPayload(&payload.base)); try scope.appendNode(Node.initPayload(&payload.base));
try bs.discardVariable(c, name);
} }
} }
@ -1128,8 +1137,10 @@ fn transEnumDecl(c: *Context, scope: *Scope, enum_decl: *const clang.EnumDecl) E
}); });
if (toplevel) if (toplevel)
try addTopLevelDecl(c, enum_val_name, enum_const_def) try addTopLevelDecl(c, enum_val_name, enum_const_def)
else else {
try scope.appendNode(enum_const_def); try scope.appendNode(enum_const_def);
try bs.discardVariable(c, enum_val_name);
}
} }
const int_type = enum_decl.getIntegerType(); const int_type = enum_decl.getIntegerType();
@ -1168,6 +1179,7 @@ fn transEnumDecl(c: *Context, scope: *Scope, enum_decl: *const clang.EnumDecl) E
try c.alias_list.append(.{ .alias = bare_name, .name = name }); try c.alias_list.append(.{ .alias = bare_name, .name = name });
} else { } else {
try scope.appendNode(Node.initPayload(&payload.base)); try scope.appendNode(Node.initPayload(&payload.base));
try bs.discardVariable(c, name);
} }
} }
@ -1352,11 +1364,10 @@ fn makeShuffleMask(c: *Context, scope: *Scope, expr: *const clang.ShuffleVectorE
init.* = converted_index; init.* = converted_index;
} }
const mask_init = try Tag.array_init.create(c.arena, .{ return Tag.array_init.create(c.arena, .{
.cond = mask_type, .cond = mask_type,
.cases = init_list, .cases = init_list,
}); });
return Tag.@"comptime".create(c.arena, mask_init);
} }
/// @typeInfo(@TypeOf(vec_node)).Vector.<field> /// @typeInfo(@TypeOf(vec_node)).Vector.<field>
@ -1766,6 +1777,7 @@ fn transDeclStmtOne(
node = try Tag.static_local_var.create(c.arena, .{ .name = mangled_name, .init = node }); node = try Tag.static_local_var.create(c.arena, .{ .name = mangled_name, .init = node });
} }
try block_scope.statements.append(node); try block_scope.statements.append(node);
try block_scope.discardVariable(c, mangled_name);
const cleanup_attr = var_decl.getCleanupAttribute(); const cleanup_attr = var_decl.getCleanupAttribute();
if (cleanup_attr) |fn_decl| { if (cleanup_attr) |fn_decl| {
@ -4903,6 +4915,10 @@ fn transMacroDefine(c: *Context, m: *MacroCtx) ParseError!void {
const scope = &c.global_scope.base; const scope = &c.global_scope.base;
const init_node = try parseCExpr(c, m, scope); const init_node = try parseCExpr(c, m, scope);
if (init_node.castTag(.identifier)) |ident_node| {
if (mem.eql(u8, "_", ident_node.data))
return m.fail(c, "unable to translate C expr: illegal identifier _", .{});
}
const last = m.next().?; const last = m.next().?;
if (last != .Eof and last != .Nl) if (last != .Eof and last != .Nl)
return m.fail(c, "unable to translate C expr: unexpected token .{s}", .{@tagName(last)}); return m.fail(c, "unable to translate C expr: unexpected token .{s}", .{@tagName(last)});
@ -4933,7 +4949,7 @@ fn transMacroFnDefine(c: *Context, m: *MacroCtx) ParseError!void {
.name = mangled_name, .name = mangled_name,
.type = Tag.@"anytype".init(), .type = Tag.@"anytype".init(),
}); });
try block_scope.discardVariable(c, mangled_name);
if (m.peek().? != .Comma) break; if (m.peek().? != .Comma) break;
_ = m.next(); _ = m.next();
} }

View File

@ -116,6 +116,8 @@ fn testGodboltApi(zig_exe: []const u8, dir_path: []const u8) anyerror!void {
\\} \\}
\\extern fn zig_panic() noreturn; \\extern fn zig_panic() noreturn;
\\pub fn panic(msg: []const u8, error_return_trace: ?*@import("std").builtin.StackTrace) noreturn { \\pub fn panic(msg: []const u8, error_return_trace: ?*@import("std").builtin.StackTrace) noreturn {
\\ _ = msg;
\\ _ = error_return_trace;
\\ zig_panic(); \\ zig_panic();
\\} \\}
); );

View File

@ -10,6 +10,8 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
\\ @cInclude("stdio.h"); \\ @cInclude("stdio.h");
\\}); \\});
\\pub export fn main(argc: c_int, argv: [*][*]u8) c_int { \\pub export fn main(argc: c_int, argv: [*][*]u8) c_int {
\\ _ = argc;
\\ _ = argv;
\\ _ = c.puts("Hello, world!"); \\ _ = c.puts("Hello, world!");
\\ return 0; \\ return 0;
\\} \\}
@ -143,6 +145,8 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
\\}); \\});
\\ \\
\\pub export fn main(argc: c_int, argv: [*][*]u8) c_int { \\pub export fn main(argc: c_int, argv: [*][*]u8) c_int {
\\ _ = argc;
\\ _ = argv;
\\ if (is_windows) { \\ if (is_windows) {
\\ // we want actual \n, not \r\n \\ // we want actual \n, not \r\n
\\ _ = c._setmode(1, c._O_BINARY); \\ _ = c._setmode(1, c._O_BINARY);
@ -265,8 +269,10 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
\\const y : u16 = 5678; \\const y : u16 = 5678;
\\pub fn main() void { \\pub fn main() void {
\\ var x_local : i32 = print_ok(x); \\ var x_local : i32 = print_ok(x);
\\ _ = x_local;
\\} \\}
\\fn print_ok(val: @TypeOf(x)) @TypeOf(foo) { \\fn print_ok(val: @TypeOf(x)) @TypeOf(foo) {
\\ _ = val;
\\ const stdout = io.getStdOut().writer(); \\ const stdout = io.getStdOut().writer();
\\ stdout.print("OK\n", .{}) catch unreachable; \\ stdout.print("OK\n", .{}) catch unreachable;
\\ return 0; \\ return 0;
@ -318,6 +324,8 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
\\}); \\});
\\ \\
\\pub export fn main(argc: c_int, argv: [*][*]u8) c_int { \\pub export fn main(argc: c_int, argv: [*][*]u8) c_int {
\\ _ = argc;
\\ _ = argv;
\\ if (is_windows) { \\ if (is_windows) {
\\ // we want actual \n, not \r\n \\ // we want actual \n, not \r\n
\\ _ = c._setmode(1, c._O_BINARY); \\ _ = c._setmode(1, c._O_BINARY);
@ -337,13 +345,19 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
\\const Foo = struct { \\const Foo = struct {
\\ field1: Bar, \\ field1: Bar,
\\ \\
\\ fn method(a: *const Foo) bool { return true; } \\ fn method(a: *const Foo) bool {
\\ _ = a;
\\ return true;
\\ }
\\}; \\};
\\ \\
\\const Bar = struct { \\const Bar = struct {
\\ field2: i32, \\ field2: i32,
\\ \\
\\ fn method(b: *const Bar) bool { return true; } \\ fn method(b: *const Bar) bool {
\\ _ = b;
\\ return true;
\\ }
\\}; \\};
\\ \\
\\pub fn main() void { \\pub fn main() void {

View File

@ -4,6 +4,7 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
{ {
const check_panic_msg = const check_panic_msg =
\\pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn { \\pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn {
\\ _ = stack_trace;
\\ if (std.mem.eql(u8, message, "reached unreachable code")) { \\ if (std.mem.eql(u8, message, "reached unreachable code")) {
\\ std.process.exit(126); // good \\ std.process.exit(126); // good
\\ } \\ }
@ -45,6 +46,7 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
{ {
const check_panic_msg = const check_panic_msg =
\\pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn { \\pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn {
\\ _ = stack_trace;
\\ if (std.mem.eql(u8, message, "invalid enum value")) { \\ if (std.mem.eql(u8, message, "invalid enum value")) {
\\ std.process.exit(126); // good \\ std.process.exit(126); // good
\\ } \\ }
@ -62,6 +64,7 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
\\ var e: E = undefined; \\ var e: E = undefined;
\\ @memset(@ptrCast([*]u8, &e), 0x55, @sizeOf(E)); \\ @memset(@ptrCast([*]u8, &e), 0x55, @sizeOf(E));
\\ var n = @tagName(e); \\ var n = @tagName(e);
\\ _ = n;
\\} \\}
); );
@ -76,6 +79,7 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
\\ @memset(@ptrCast([*]u8, &u), 0x55, @sizeOf(U)); \\ @memset(@ptrCast([*]u8, &u), 0x55, @sizeOf(U));
\\ var t: @typeInfo(U).Union.tag_type.? = u; \\ var t: @typeInfo(U).Union.tag_type.? = u;
\\ var n = @tagName(t); \\ var n = @tagName(t);
\\ _ = n;
\\} \\}
); );
} }
@ -83,6 +87,7 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
{ {
const check_panic_msg = const check_panic_msg =
\\pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn { \\pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn {
\\ _ = stack_trace;
\\ if (std.mem.eql(u8, message, "index out of bounds")) { \\ if (std.mem.eql(u8, message, "index out of bounds")) {
\\ std.process.exit(126); // good \\ std.process.exit(126); // good
\\ } \\ }
@ -96,6 +101,7 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
\\pub fn main() void { \\pub fn main() void {
\\ var buf = [4]u8{'a','b','c',0}; \\ var buf = [4]u8{'a','b','c',0};
\\ const slice = buf[0..4 :0]; \\ const slice = buf[0..4 :0];
\\ _ = slice;
\\} \\}
); );
cases.addRuntimeSafety("slicing operator with sentinel", cases.addRuntimeSafety("slicing operator with sentinel",
@ -104,6 +110,7 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
\\pub fn main() void { \\pub fn main() void {
\\ var buf = [4]u8{'a','b','c',0}; \\ var buf = [4]u8{'a','b','c',0};
\\ const slice = buf[0..:0]; \\ const slice = buf[0..:0];
\\ _ = slice;
\\} \\}
); );
cases.addRuntimeSafety("slicing operator with sentinel", cases.addRuntimeSafety("slicing operator with sentinel",
@ -112,6 +119,7 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
\\pub fn main() void { \\pub fn main() void {
\\ var buf_zero = [0]u8{}; \\ var buf_zero = [0]u8{};
\\ const slice = buf_zero[0..0 :0]; \\ const slice = buf_zero[0..0 :0];
\\ _ = slice;
\\} \\}
); );
cases.addRuntimeSafety("slicing operator with sentinel", cases.addRuntimeSafety("slicing operator with sentinel",
@ -120,6 +128,7 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
\\pub fn main() void { \\pub fn main() void {
\\ var buf_zero = [0]u8{}; \\ var buf_zero = [0]u8{};
\\ const slice = buf_zero[0..:0]; \\ const slice = buf_zero[0..:0];
\\ _ = slice;
\\} \\}
); );
cases.addRuntimeSafety("slicing operator with sentinel", cases.addRuntimeSafety("slicing operator with sentinel",
@ -129,6 +138,7 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
\\ var buf_sentinel = [2:0]u8{'a','b'}; \\ var buf_sentinel = [2:0]u8{'a','b'};
\\ @ptrCast(*[3]u8, &buf_sentinel)[2] = 0; \\ @ptrCast(*[3]u8, &buf_sentinel)[2] = 0;
\\ const slice = buf_sentinel[0..3 :0]; \\ const slice = buf_sentinel[0..3 :0];
\\ _ = slice;
\\} \\}
); );
cases.addRuntimeSafety("slicing operator with sentinel", cases.addRuntimeSafety("slicing operator with sentinel",
@ -137,6 +147,7 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
\\pub fn main() void { \\pub fn main() void {
\\ var buf_slice: []const u8 = &[3]u8{ 'a', 'b', 0 }; \\ var buf_slice: []const u8 = &[3]u8{ 'a', 'b', 0 };
\\ const slice = buf_slice[0..3 :0]; \\ const slice = buf_slice[0..3 :0];
\\ _ = slice;
\\} \\}
); );
cases.addRuntimeSafety("slicing operator with sentinel", cases.addRuntimeSafety("slicing operator with sentinel",
@ -145,6 +156,7 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
\\pub fn main() void { \\pub fn main() void {
\\ var buf_slice: []const u8 = &[3]u8{ 'a', 'b', 0 }; \\ var buf_slice: []const u8 = &[3]u8{ 'a', 'b', 0 };
\\ const slice = buf_slice[0.. :0]; \\ const slice = buf_slice[0.. :0];
\\ _ = slice;
\\} \\}
); );
} }
@ -153,6 +165,7 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
\\const std = @import("std"); \\const std = @import("std");
\\const V = @import("std").meta.Vector; \\const V = @import("std").meta.Vector;
\\pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn { \\pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn {
\\ _ = stack_trace;
\\ if (std.mem.eql(u8, message, "integer cast truncated bits")) { \\ if (std.mem.eql(u8, message, "integer cast truncated bits")) {
\\ std.process.exit(126); // good \\ std.process.exit(126); // good
\\ } \\ }
@ -161,6 +174,7 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
\\pub fn main() void { \\pub fn main() void {
\\ var x = @splat(4, @as(u32, 0xdeadbeef)); \\ var x = @splat(4, @as(u32, 0xdeadbeef));
\\ var y = @intCast(V(4, u16), x); \\ var y = @intCast(V(4, u16), x);
\\ _ = y;
\\} \\}
); );
@ -168,6 +182,7 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
\\const std = @import("std"); \\const std = @import("std");
\\const V = @import("std").meta.Vector; \\const V = @import("std").meta.Vector;
\\pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn { \\pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn {
\\ _ = stack_trace;
\\ if (std.mem.eql(u8, message, "integer cast truncated bits")) { \\ if (std.mem.eql(u8, message, "integer cast truncated bits")) {
\\ std.process.exit(126); // good \\ std.process.exit(126); // good
\\ } \\ }
@ -176,6 +191,7 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
\\pub fn main() void { \\pub fn main() void {
\\ var x = @splat(4, @as(u32, 0x80000000)); \\ var x = @splat(4, @as(u32, 0x80000000));
\\ var y = @intCast(V(4, i32), x); \\ var y = @intCast(V(4, i32), x);
\\ _ = y;
\\} \\}
); );
@ -183,6 +199,7 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
\\const std = @import("std"); \\const std = @import("std");
\\const V = @import("std").meta.Vector; \\const V = @import("std").meta.Vector;
\\pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn { \\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")) { \\ if (std.mem.eql(u8, message, "attempt to cast negative value to unsigned integer")) {
\\ std.process.exit(126); // good \\ std.process.exit(126); // good
\\ } \\ }
@ -191,12 +208,14 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
\\pub fn main() void { \\pub fn main() void {
\\ var x = @splat(4, @as(i32, -2147483647)); \\ var x = @splat(4, @as(i32, -2147483647));
\\ var y = @intCast(V(4, u32), x); \\ var y = @intCast(V(4, u32), x);
\\ _ = y;
\\} \\}
); );
cases.addRuntimeSafety("shift left by huge amount", cases.addRuntimeSafety("shift left by huge amount",
\\const std = @import("std"); \\const std = @import("std");
\\pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn { \\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")) { \\ if (std.mem.eql(u8, message, "shift amount is greater than the type size")) {
\\ std.process.exit(126); // good \\ std.process.exit(126); // good
\\ } \\ }
@ -206,12 +225,14 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
\\ var x: u24 = 42; \\ var x: u24 = 42;
\\ var y: u5 = 24; \\ var y: u5 = 24;
\\ var z = x >> y; \\ var z = x >> y;
\\ _ = z;
\\} \\}
); );
cases.addRuntimeSafety("shift right by huge amount", cases.addRuntimeSafety("shift right by huge amount",
\\const std = @import("std"); \\const std = @import("std");
\\pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn { \\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")) { \\ if (std.mem.eql(u8, message, "shift amount is greater than the type size")) {
\\ std.process.exit(126); // good \\ std.process.exit(126); // good
\\ } \\ }
@ -221,12 +242,14 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
\\ var x: u24 = 42; \\ var x: u24 = 42;
\\ var y: u5 = 24; \\ var y: u5 = 24;
\\ var z = x << y; \\ var z = x << y;
\\ _ = z;
\\} \\}
); );
cases.addRuntimeSafety("slice sentinel mismatch - optional pointers", cases.addRuntimeSafety("slice sentinel mismatch - optional pointers",
\\const std = @import("std"); \\const std = @import("std");
\\pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn { \\pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn {
\\ _ = stack_trace;
\\ if (std.mem.eql(u8, message, "sentinel mismatch")) { \\ if (std.mem.eql(u8, message, "sentinel mismatch")) {
\\ std.process.exit(126); // good \\ std.process.exit(126); // good
\\ } \\ }
@ -235,12 +258,14 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
\\pub fn main() void { \\pub fn main() void {
\\ var buf: [4]?*i32 = undefined; \\ var buf: [4]?*i32 = undefined;
\\ const slice = buf[0..3 :null]; \\ const slice = buf[0..3 :null];
\\ _ = slice;
\\} \\}
); );
cases.addRuntimeSafety("slice sentinel mismatch - floats", cases.addRuntimeSafety("slice sentinel mismatch - floats",
\\const std = @import("std"); \\const std = @import("std");
\\pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn { \\pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn {
\\ _ = stack_trace;
\\ if (std.mem.eql(u8, message, "sentinel mismatch")) { \\ if (std.mem.eql(u8, message, "sentinel mismatch")) {
\\ std.process.exit(126); // good \\ std.process.exit(126); // good
\\ } \\ }
@ -249,12 +274,14 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
\\pub fn main() void { \\pub fn main() void {
\\ var buf: [4]f32 = undefined; \\ var buf: [4]f32 = undefined;
\\ const slice = buf[0..3 :1.2]; \\ const slice = buf[0..3 :1.2];
\\ _ = slice;
\\} \\}
); );
cases.addRuntimeSafety("pointer slice sentinel mismatch", cases.addRuntimeSafety("pointer slice sentinel mismatch",
\\const std = @import("std"); \\const std = @import("std");
\\pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn { \\pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn {
\\ _ = stack_trace;
\\ if (std.mem.eql(u8, message, "sentinel mismatch")) { \\ if (std.mem.eql(u8, message, "sentinel mismatch")) {
\\ std.process.exit(126); // good \\ std.process.exit(126); // good
\\ } \\ }
@ -264,12 +291,14 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
\\ var buf: [4]u8 = undefined; \\ var buf: [4]u8 = undefined;
\\ const ptr: [*]u8 = &buf; \\ const ptr: [*]u8 = &buf;
\\ const slice = ptr[0..3 :0]; \\ const slice = ptr[0..3 :0];
\\ _ = slice;
\\} \\}
); );
cases.addRuntimeSafety("slice slice sentinel mismatch", cases.addRuntimeSafety("slice slice sentinel mismatch",
\\const std = @import("std"); \\const std = @import("std");
\\pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn { \\pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn {
\\ _ = stack_trace;
\\ if (std.mem.eql(u8, message, "sentinel mismatch")) { \\ if (std.mem.eql(u8, message, "sentinel mismatch")) {
\\ std.process.exit(126); // good \\ std.process.exit(126); // good
\\ } \\ }
@ -279,12 +308,14 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
\\ var buf: [4]u8 = undefined; \\ var buf: [4]u8 = undefined;
\\ const slice = buf[0..]; \\ const slice = buf[0..];
\\ const slice2 = slice[0..3 :0]; \\ const slice2 = slice[0..3 :0];
\\ _ = slice2;
\\} \\}
); );
cases.addRuntimeSafety("array slice sentinel mismatch", cases.addRuntimeSafety("array slice sentinel mismatch",
\\const std = @import("std"); \\const std = @import("std");
\\pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn { \\pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn {
\\ _ = stack_trace;
\\ if (std.mem.eql(u8, message, "sentinel mismatch")) { \\ if (std.mem.eql(u8, message, "sentinel mismatch")) {
\\ std.process.exit(126); // good \\ std.process.exit(126); // good
\\ } \\ }
@ -293,12 +324,14 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
\\pub fn main() void { \\pub fn main() void {
\\ var buf: [4]u8 = undefined; \\ var buf: [4]u8 = undefined;
\\ const slice = buf[0..3 :0]; \\ const slice = buf[0..3 :0];
\\ _ = slice;
\\} \\}
); );
cases.addRuntimeSafety("intToPtr with misaligned address", cases.addRuntimeSafety("intToPtr with misaligned address",
\\const std = @import("std"); \\const std = @import("std");
\\pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn { \\pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn {
\\ _ = stack_trace;
\\ if (std.mem.eql(u8, message, "incorrect alignment")) { \\ if (std.mem.eql(u8, message, "incorrect alignment")) {
\\ std.os.exit(126); // good \\ std.os.exit(126); // good
\\ } \\ }
@ -307,16 +340,20 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
\\pub fn main() void { \\pub fn main() void {
\\ var x: usize = 5; \\ var x: usize = 5;
\\ var y = @intToPtr([*]align(4) u8, x); \\ var y = @intToPtr([*]align(4) u8, x);
\\ _ = y;
\\} \\}
); );
cases.addRuntimeSafety("resuming a non-suspended function which never been suspended", cases.addRuntimeSafety("resuming a non-suspended function which never been suspended",
\\const std = @import("std"); \\const std = @import("std");
\\pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn { \\pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn {
\\ _ = message;
\\ _ = stack_trace;
\\ std.os.exit(126); \\ std.os.exit(126);
\\} \\}
\\fn foo() void { \\fn foo() void {
\\ var f = async bar(@frame()); \\ var f = async bar(@frame());
\\ _ = f;
\\ std.os.exit(0); \\ std.os.exit(0);
\\} \\}
\\ \\
@ -335,6 +372,8 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
cases.addRuntimeSafety("resuming a non-suspended function which has been suspended and resumed", cases.addRuntimeSafety("resuming a non-suspended function which has been suspended and resumed",
\\const std = @import("std"); \\const std = @import("std");
\\pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn { \\pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn {
\\ _ = message;
\\ _ = stack_trace;
\\ std.os.exit(126); \\ std.os.exit(126);
\\} \\}
\\fn foo() void { \\fn foo() void {
@ -342,6 +381,7 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
\\ global_frame = @frame(); \\ global_frame = @frame();
\\ } \\ }
\\ var f = async bar(@frame()); \\ var f = async bar(@frame());
\\ _ = f;
\\ std.os.exit(0); \\ std.os.exit(0);
\\} \\}
\\ \\
@ -363,6 +403,8 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
cases.addRuntimeSafety("nosuspend function call, callee suspends", cases.addRuntimeSafety("nosuspend function call, callee suspends",
\\const std = @import("std"); \\const std = @import("std");
\\pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn { \\pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn {
\\ _ = message;
\\ _ = stack_trace;
\\ std.os.exit(126); \\ std.os.exit(126);
\\} \\}
\\pub fn main() void { \\pub fn main() void {
@ -379,6 +421,8 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
cases.addRuntimeSafety("awaiting twice", cases.addRuntimeSafety("awaiting twice",
\\const std = @import("std"); \\const std = @import("std");
\\pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn { \\pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn {
\\ _ = message;
\\ _ = stack_trace;
\\ std.os.exit(126); \\ std.os.exit(126);
\\} \\}
\\var frame: anyframe = undefined; \\var frame: anyframe = undefined;
@ -404,12 +448,15 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
cases.addRuntimeSafety("@asyncCall with too small a frame", cases.addRuntimeSafety("@asyncCall with too small a frame",
\\const std = @import("std"); \\const std = @import("std");
\\pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn { \\pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn {
\\ _ = message;
\\ _ = stack_trace;
\\ std.os.exit(126); \\ std.os.exit(126);
\\} \\}
\\pub fn main() void { \\pub fn main() void {
\\ var bytes: [1]u8 align(16) = undefined; \\ var bytes: [1]u8 align(16) = undefined;
\\ var ptr = other; \\ var ptr = other;
\\ var frame = @asyncCall(&bytes, {}, ptr, .{}); \\ var frame = @asyncCall(&bytes, {}, ptr, .{});
\\ _ = frame;
\\} \\}
\\fn other() callconv(.Async) void { \\fn other() callconv(.Async) void {
\\ suspend {} \\ suspend {}
@ -419,6 +466,8 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
cases.addRuntimeSafety("resuming a function which is awaiting a frame", cases.addRuntimeSafety("resuming a function which is awaiting a frame",
\\const std = @import("std"); \\const std = @import("std");
\\pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn { \\pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn {
\\ _ = message;
\\ _ = stack_trace;
\\ std.os.exit(126); \\ std.os.exit(126);
\\} \\}
\\pub fn main() void { \\pub fn main() void {
@ -437,6 +486,8 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
cases.addRuntimeSafety("resuming a function which is awaiting a call", cases.addRuntimeSafety("resuming a function which is awaiting a call",
\\const std = @import("std"); \\const std = @import("std");
\\pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn { \\pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn {
\\ _ = message;
\\ _ = stack_trace;
\\ std.os.exit(126); \\ std.os.exit(126);
\\} \\}
\\pub fn main() void { \\pub fn main() void {
@ -454,6 +505,8 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
cases.addRuntimeSafety("invalid resume of async function", cases.addRuntimeSafety("invalid resume of async function",
\\const std = @import("std"); \\const std = @import("std");
\\pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn { \\pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn {
\\ _ = message;
\\ _ = stack_trace;
\\ std.os.exit(126); \\ std.os.exit(126);
\\} \\}
\\pub fn main() void { \\pub fn main() void {
@ -469,61 +522,78 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
cases.addRuntimeSafety(".? operator on null pointer", cases.addRuntimeSafety(".? operator on null pointer",
\\const std = @import("std"); \\const std = @import("std");
\\pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn { \\pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn {
\\ _ = message;
\\ _ = stack_trace;
\\ std.os.exit(126); \\ std.os.exit(126);
\\} \\}
\\pub fn main() void { \\pub fn main() void {
\\ var ptr: ?*i32 = null; \\ var ptr: ?*i32 = null;
\\ var b = ptr.?; \\ var b = ptr.?;
\\ _ = b;
\\} \\}
); );
cases.addRuntimeSafety(".? operator on C pointer", cases.addRuntimeSafety(".? operator on C pointer",
\\const std = @import("std"); \\const std = @import("std");
\\pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn { \\pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn {
\\ _ = message;
\\ _ = stack_trace;
\\ std.os.exit(126); \\ std.os.exit(126);
\\} \\}
\\pub fn main() void { \\pub fn main() void {
\\ var ptr: [*c]i32 = null; \\ var ptr: [*c]i32 = null;
\\ var b = ptr.?; \\ var b = ptr.?;
\\ _ = b;
\\} \\}
); );
cases.addRuntimeSafety("@intToPtr address zero to non-optional pointer", cases.addRuntimeSafety("@intToPtr address zero to non-optional pointer",
\\const std = @import("std"); \\const std = @import("std");
\\pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn { \\pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn {
\\ _ = message;
\\ _ = stack_trace;
\\ std.os.exit(126); \\ std.os.exit(126);
\\} \\}
\\pub fn main() void { \\pub fn main() void {
\\ var zero: usize = 0; \\ var zero: usize = 0;
\\ var b = @intToPtr(*i32, zero); \\ var b = @intToPtr(*i32, zero);
\\ _ = b;
\\} \\}
); );
cases.addRuntimeSafety("@intToPtr address zero to non-optional byte-aligned pointer", cases.addRuntimeSafety("@intToPtr address zero to non-optional byte-aligned pointer",
\\const std = @import("std"); \\const std = @import("std");
\\pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn { \\pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn {
\\ _ = message;
\\ _ = stack_trace;
\\ std.os.exit(126); \\ std.os.exit(126);
\\} \\}
\\pub fn main() void { \\pub fn main() void {
\\ var zero: usize = 0; \\ var zero: usize = 0;
\\ var b = @intToPtr(*u8, zero); \\ var b = @intToPtr(*u8, zero);
\\ _ = b;
\\} \\}
); );
cases.addRuntimeSafety("pointer casting null to non-optional pointer", cases.addRuntimeSafety("pointer casting null to non-optional pointer",
\\const std = @import("std"); \\const std = @import("std");
\\pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn { \\pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn {
\\ _ = message;
\\ _ = stack_trace;
\\ std.os.exit(126); \\ std.os.exit(126);
\\} \\}
\\pub fn main() void { \\pub fn main() void {
\\ var c_ptr: [*c]u8 = 0; \\ var c_ptr: [*c]u8 = 0;
\\ var zig_ptr: *u8 = c_ptr; \\ var zig_ptr: *u8 = c_ptr;
\\ _ = zig_ptr;
\\} \\}
); );
cases.addRuntimeSafety("@intToEnum - no matching tag value", cases.addRuntimeSafety("@intToEnum - no matching tag value",
\\const std = @import("std"); \\const std = @import("std");
\\pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn { \\pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn {
\\ _ = message;
\\ _ = stack_trace;
\\ std.os.exit(126); \\ std.os.exit(126);
\\} \\}
\\const Foo = enum { \\const Foo = enum {
@ -537,12 +607,14 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
\\fn bar(a: u2) Foo { \\fn bar(a: u2) Foo {
\\ return @intToEnum(Foo, a); \\ return @intToEnum(Foo, a);
\\} \\}
\\fn baz(a: Foo) void {} \\fn baz(_: Foo) void {}
); );
cases.addRuntimeSafety("@floatToInt cannot fit - negative to unsigned", cases.addRuntimeSafety("@floatToInt cannot fit - negative to unsigned",
\\const std = @import("std"); \\const std = @import("std");
\\pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn { \\pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn {
\\ _ = message;
\\ _ = stack_trace;
\\ std.os.exit(126); \\ std.os.exit(126);
\\} \\}
\\pub fn main() void { \\pub fn main() void {
@ -551,12 +623,14 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
\\fn bar(a: f32) u8 { \\fn bar(a: f32) u8 {
\\ return @floatToInt(u8, a); \\ return @floatToInt(u8, a);
\\} \\}
\\fn baz(a: u8) void { } \\fn baz(_: u8) void { }
); );
cases.addRuntimeSafety("@floatToInt cannot fit - negative out of range", cases.addRuntimeSafety("@floatToInt cannot fit - negative out of range",
\\const std = @import("std"); \\const std = @import("std");
\\pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn { \\pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn {
\\ _ = message;
\\ _ = stack_trace;
\\ std.os.exit(126); \\ std.os.exit(126);
\\} \\}
\\pub fn main() void { \\pub fn main() void {
@ -565,12 +639,14 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
\\fn bar(a: f32) i8 { \\fn bar(a: f32) i8 {
\\ return @floatToInt(i8, a); \\ return @floatToInt(i8, a);
\\} \\}
\\fn baz(a: i8) void { } \\fn baz(_: i8) void { }
); );
cases.addRuntimeSafety("@floatToInt cannot fit - positive out of range", cases.addRuntimeSafety("@floatToInt cannot fit - positive out of range",
\\const std = @import("std"); \\const std = @import("std");
\\pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn { \\pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn {
\\ _ = message;
\\ _ = stack_trace;
\\ std.os.exit(126); \\ std.os.exit(126);
\\} \\}
\\pub fn main() void { \\pub fn main() void {
@ -579,12 +655,14 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
\\fn bar(a: f32) u8 { \\fn bar(a: f32) u8 {
\\ return @floatToInt(u8, a); \\ return @floatToInt(u8, a);
\\} \\}
\\fn baz(a: u8) void { } \\fn baz(_: u8) void { }
); );
cases.addRuntimeSafety("calling panic", cases.addRuntimeSafety("calling panic",
\\const std = @import("std"); \\const std = @import("std");
\\pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn { \\pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn {
\\ _ = message;
\\ _ = stack_trace;
\\ std.os.exit(126); \\ std.os.exit(126);
\\} \\}
\\pub fn main() void { \\pub fn main() void {
@ -595,6 +673,8 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
cases.addRuntimeSafety("out of bounds slice access", cases.addRuntimeSafety("out of bounds slice access",
\\const std = @import("std"); \\const std = @import("std");
\\pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn { \\pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn {
\\ _ = message;
\\ _ = stack_trace;
\\ std.os.exit(126); \\ std.os.exit(126);
\\} \\}
\\pub fn main() void { \\pub fn main() void {
@ -604,12 +684,14 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
\\fn bar(a: []const i32) i32 { \\fn bar(a: []const i32) i32 {
\\ return a[4]; \\ return a[4];
\\} \\}
\\fn baz(a: i32) void { } \\fn baz(_: i32) void { }
); );
cases.addRuntimeSafety("integer addition overflow", cases.addRuntimeSafety("integer addition overflow",
\\const std = @import("std"); \\const std = @import("std");
\\pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn { \\pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn {
\\ _ = message;
\\ _ = stack_trace;
\\ std.os.exit(126); \\ std.os.exit(126);
\\} \\}
\\pub fn main() !void { \\pub fn main() !void {
@ -624,12 +706,15 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
cases.addRuntimeSafety("vector integer addition overflow", cases.addRuntimeSafety("vector integer addition overflow",
\\const std = @import("std"); \\const std = @import("std");
\\pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn { \\pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn {
\\ _ = message;
\\ _ = stack_trace;
\\ std.os.exit(126); \\ std.os.exit(126);
\\} \\}
\\pub fn main() void { \\pub fn main() void {
\\ var a: std.meta.Vector(4, i32) = [_]i32{ 1, 2, 2147483643, 4 }; \\ var a: std.meta.Vector(4, i32) = [_]i32{ 1, 2, 2147483643, 4 };
\\ var b: std.meta.Vector(4, i32) = [_]i32{ 5, 6, 7, 8 }; \\ var b: std.meta.Vector(4, i32) = [_]i32{ 5, 6, 7, 8 };
\\ const x = add(a, b); \\ const x = add(a, b);
\\ _ = x;
\\} \\}
\\fn add(a: std.meta.Vector(4, i32), b: std.meta.Vector(4, i32)) std.meta.Vector(4, i32) { \\fn add(a: std.meta.Vector(4, i32), b: std.meta.Vector(4, i32)) std.meta.Vector(4, i32) {
\\ return a + b; \\ return a + b;
@ -639,12 +724,15 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
cases.addRuntimeSafety("vector integer subtraction overflow", cases.addRuntimeSafety("vector integer subtraction overflow",
\\const std = @import("std"); \\const std = @import("std");
\\pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn { \\pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn {
\\ _ = message;
\\ _ = stack_trace;
\\ std.os.exit(126); \\ std.os.exit(126);
\\} \\}
\\pub fn main() void { \\pub fn main() void {
\\ var a: std.meta.Vector(4, u32) = [_]u32{ 1, 2, 8, 4 }; \\ var a: std.meta.Vector(4, u32) = [_]u32{ 1, 2, 8, 4 };
\\ var b: std.meta.Vector(4, u32) = [_]u32{ 5, 6, 7, 8 }; \\ var b: std.meta.Vector(4, u32) = [_]u32{ 5, 6, 7, 8 };
\\ const x = sub(b, a); \\ const x = sub(b, a);
\\ _ = x;
\\} \\}
\\fn sub(a: std.meta.Vector(4, u32), b: std.meta.Vector(4, u32)) std.meta.Vector(4, u32) { \\fn sub(a: std.meta.Vector(4, u32), b: std.meta.Vector(4, u32)) std.meta.Vector(4, u32) {
\\ return a - b; \\ return a - b;
@ -654,12 +742,15 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
cases.addRuntimeSafety("vector integer multiplication overflow", cases.addRuntimeSafety("vector integer multiplication overflow",
\\const std = @import("std"); \\const std = @import("std");
\\pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn { \\pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn {
\\ _ = message;
\\ _ = stack_trace;
\\ std.os.exit(126); \\ std.os.exit(126);
\\} \\}
\\pub fn main() void { \\pub fn main() void {
\\ var a: std.meta.Vector(4, u8) = [_]u8{ 1, 2, 200, 4 }; \\ var a: std.meta.Vector(4, u8) = [_]u8{ 1, 2, 200, 4 };
\\ var b: std.meta.Vector(4, u8) = [_]u8{ 5, 6, 2, 8 }; \\ var b: std.meta.Vector(4, u8) = [_]u8{ 5, 6, 2, 8 };
\\ const x = mul(b, a); \\ const x = mul(b, a);
\\ _ = x;
\\} \\}
\\fn mul(a: std.meta.Vector(4, u8), b: std.meta.Vector(4, u8)) std.meta.Vector(4, u8) { \\fn mul(a: std.meta.Vector(4, u8), b: std.meta.Vector(4, u8)) std.meta.Vector(4, u8) {
\\ return a * b; \\ return a * b;
@ -669,11 +760,14 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
cases.addRuntimeSafety("vector integer negation overflow", cases.addRuntimeSafety("vector integer negation overflow",
\\const std = @import("std"); \\const std = @import("std");
\\pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn { \\pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn {
\\ _ = message;
\\ _ = stack_trace;
\\ std.os.exit(126); \\ std.os.exit(126);
\\} \\}
\\pub fn main() void { \\pub fn main() void {
\\ var a: std.meta.Vector(4, i16) = [_]i16{ 1, -32768, 200, 4 }; \\ var a: std.meta.Vector(4, i16) = [_]i16{ 1, -32768, 200, 4 };
\\ const x = neg(a); \\ const x = neg(a);
\\ _ = x;
\\} \\}
\\fn neg(a: std.meta.Vector(4, i16)) std.meta.Vector(4, i16) { \\fn neg(a: std.meta.Vector(4, i16)) std.meta.Vector(4, i16) {
\\ return -a; \\ return -a;
@ -683,6 +777,8 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
cases.addRuntimeSafety("integer subtraction overflow", cases.addRuntimeSafety("integer subtraction overflow",
\\const std = @import("std"); \\const std = @import("std");
\\pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn { \\pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn {
\\ _ = message;
\\ _ = stack_trace;
\\ std.os.exit(126); \\ std.os.exit(126);
\\} \\}
\\pub fn main() !void { \\pub fn main() !void {
@ -697,6 +793,8 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
cases.addRuntimeSafety("integer multiplication overflow", cases.addRuntimeSafety("integer multiplication overflow",
\\const std = @import("std"); \\const std = @import("std");
\\pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn { \\pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn {
\\ _ = message;
\\ _ = stack_trace;
\\ std.os.exit(126); \\ std.os.exit(126);
\\} \\}
\\pub fn main() !void { \\pub fn main() !void {
@ -711,6 +809,8 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
cases.addRuntimeSafety("integer negation overflow", cases.addRuntimeSafety("integer negation overflow",
\\const std = @import("std"); \\const std = @import("std");
\\pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn { \\pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn {
\\ _ = message;
\\ _ = stack_trace;
\\ std.os.exit(126); \\ std.os.exit(126);
\\} \\}
\\pub fn main() !void { \\pub fn main() !void {
@ -725,6 +825,8 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
cases.addRuntimeSafety("signed integer division overflow", cases.addRuntimeSafety("signed integer division overflow",
\\const std = @import("std"); \\const std = @import("std");
\\pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn { \\pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn {
\\ _ = message;
\\ _ = stack_trace;
\\ std.os.exit(126); \\ std.os.exit(126);
\\} \\}
\\pub fn main() !void { \\pub fn main() !void {
@ -739,6 +841,8 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
cases.addRuntimeSafety("signed integer division overflow - vectors", cases.addRuntimeSafety("signed integer division overflow - vectors",
\\const std = @import("std"); \\const std = @import("std");
\\pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn { \\pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn {
\\ _ = message;
\\ _ = stack_trace;
\\ std.os.exit(126); \\ std.os.exit(126);
\\} \\}
\\pub fn main() !void { \\pub fn main() !void {
@ -755,6 +859,8 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
cases.addRuntimeSafety("signed shift left overflow", cases.addRuntimeSafety("signed shift left overflow",
\\const std = @import("std"); \\const std = @import("std");
\\pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn { \\pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn {
\\ _ = message;
\\ _ = stack_trace;
\\ std.os.exit(126); \\ std.os.exit(126);
\\} \\}
\\pub fn main() !void { \\pub fn main() !void {
@ -769,6 +875,8 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
cases.addRuntimeSafety("unsigned shift left overflow", cases.addRuntimeSafety("unsigned shift left overflow",
\\const std = @import("std"); \\const std = @import("std");
\\pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn { \\pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn {
\\ _ = message;
\\ _ = stack_trace;
\\ std.os.exit(126); \\ std.os.exit(126);
\\} \\}
\\pub fn main() !void { \\pub fn main() !void {
@ -783,6 +891,8 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
cases.addRuntimeSafety("signed shift right overflow", cases.addRuntimeSafety("signed shift right overflow",
\\const std = @import("std"); \\const std = @import("std");
\\pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn { \\pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn {
\\ _ = message;
\\ _ = stack_trace;
\\ std.os.exit(126); \\ std.os.exit(126);
\\} \\}
\\pub fn main() !void { \\pub fn main() !void {
@ -797,6 +907,8 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
cases.addRuntimeSafety("unsigned shift right overflow", cases.addRuntimeSafety("unsigned shift right overflow",
\\const std = @import("std"); \\const std = @import("std");
\\pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn { \\pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn {
\\ _ = message;
\\ _ = stack_trace;
\\ std.os.exit(126); \\ std.os.exit(126);
\\} \\}
\\pub fn main() !void { \\pub fn main() !void {
@ -811,10 +923,13 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
cases.addRuntimeSafety("integer division by zero", cases.addRuntimeSafety("integer division by zero",
\\const std = @import("std"); \\const std = @import("std");
\\pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn { \\pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn {
\\ _ = message;
\\ _ = stack_trace;
\\ std.os.exit(126); \\ std.os.exit(126);
\\} \\}
\\pub fn main() void { \\pub fn main() void {
\\ const x = div0(999, 0); \\ const x = div0(999, 0);
\\ _ = x;
\\} \\}
\\fn div0(a: i32, b: i32) i32 { \\fn div0(a: i32, b: i32) i32 {
\\ return @divTrunc(a, b); \\ return @divTrunc(a, b);
@ -824,12 +939,15 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
cases.addRuntimeSafety("integer division by zero - vectors", cases.addRuntimeSafety("integer division by zero - vectors",
\\const std = @import("std"); \\const std = @import("std");
\\pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn { \\pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn {
\\ _ = message;
\\ _ = stack_trace;
\\ std.os.exit(126); \\ std.os.exit(126);
\\} \\}
\\pub fn main() void { \\pub fn main() void {
\\ var a: std.meta.Vector(4, i32) = [4]i32{111, 222, 333, 444}; \\ var a: std.meta.Vector(4, i32) = [4]i32{111, 222, 333, 444};
\\ var b: std.meta.Vector(4, i32) = [4]i32{111, 0, 333, 444}; \\ var b: std.meta.Vector(4, i32) = [4]i32{111, 0, 333, 444};
\\ const x = div0(a, b); \\ const x = div0(a, b);
\\ _ = x;
\\} \\}
\\fn div0(a: std.meta.Vector(4, i32), b: std.meta.Vector(4, i32)) std.meta.Vector(4, i32) { \\fn div0(a: std.meta.Vector(4, i32), b: std.meta.Vector(4, i32)) std.meta.Vector(4, i32) {
\\ return @divTrunc(a, b); \\ return @divTrunc(a, b);
@ -839,6 +957,8 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
cases.addRuntimeSafety("exact division failure", cases.addRuntimeSafety("exact division failure",
\\const std = @import("std"); \\const std = @import("std");
\\pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn { \\pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn {
\\ _ = message;
\\ _ = stack_trace;
\\ std.os.exit(126); \\ std.os.exit(126);
\\} \\}
\\pub fn main() !void { \\pub fn main() !void {
@ -853,12 +973,15 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
cases.addRuntimeSafety("exact division failure - vectors", cases.addRuntimeSafety("exact division failure - vectors",
\\const std = @import("std"); \\const std = @import("std");
\\pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn { \\pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn {
\\ _ = message;
\\ _ = stack_trace;
\\ std.os.exit(126); \\ std.os.exit(126);
\\} \\}
\\pub fn main() !void { \\pub fn main() !void {
\\ var a: std.meta.Vector(4, i32) = [4]i32{111, 222, 333, 444}; \\ var a: std.meta.Vector(4, i32) = [4]i32{111, 222, 333, 444};
\\ var b: std.meta.Vector(4, i32) = [4]i32{111, 222, 333, 441}; \\ var b: std.meta.Vector(4, i32) = [4]i32{111, 222, 333, 441};
\\ const x = divExact(a, b); \\ const x = divExact(a, b);
\\ _ = x;
\\} \\}
\\fn divExact(a: std.meta.Vector(4, i32), b: std.meta.Vector(4, i32)) std.meta.Vector(4, i32) { \\fn divExact(a: std.meta.Vector(4, i32), b: std.meta.Vector(4, i32)) std.meta.Vector(4, i32) {
\\ return @divExact(a, b); \\ return @divExact(a, b);
@ -868,6 +991,8 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
cases.addRuntimeSafety("cast []u8 to bigger slice of wrong size", cases.addRuntimeSafety("cast []u8 to bigger slice of wrong size",
\\const std = @import("std"); \\const std = @import("std");
\\pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn { \\pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn {
\\ _ = message;
\\ _ = stack_trace;
\\ std.os.exit(126); \\ std.os.exit(126);
\\} \\}
\\pub fn main() !void { \\pub fn main() !void {
@ -882,6 +1007,8 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
cases.addRuntimeSafety("value does not fit in shortening cast", cases.addRuntimeSafety("value does not fit in shortening cast",
\\const std = @import("std"); \\const std = @import("std");
\\pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn { \\pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn {
\\ _ = message;
\\ _ = stack_trace;
\\ std.os.exit(126); \\ std.os.exit(126);
\\} \\}
\\pub fn main() !void { \\pub fn main() !void {
@ -896,6 +1023,8 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
cases.addRuntimeSafety("value does not fit in shortening cast - u0", cases.addRuntimeSafety("value does not fit in shortening cast - u0",
\\const std = @import("std"); \\const std = @import("std");
\\pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn { \\pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn {
\\ _ = message;
\\ _ = stack_trace;
\\ std.os.exit(126); \\ std.os.exit(126);
\\} \\}
\\pub fn main() !void { \\pub fn main() !void {
@ -910,6 +1039,8 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
cases.addRuntimeSafety("signed integer not fitting in cast to unsigned integer", cases.addRuntimeSafety("signed integer not fitting in cast to unsigned integer",
\\const std = @import("std"); \\const std = @import("std");
\\pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn { \\pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn {
\\ _ = message;
\\ _ = stack_trace;
\\ std.os.exit(126); \\ std.os.exit(126);
\\} \\}
\\pub fn main() !void { \\pub fn main() !void {
@ -924,28 +1055,35 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
cases.addRuntimeSafety("signed integer not fitting in cast to unsigned integer - widening", cases.addRuntimeSafety("signed integer not fitting in cast to unsigned integer - widening",
\\const std = @import("std"); \\const std = @import("std");
\\pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn { \\pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn {
\\ _ = message;
\\ _ = stack_trace;
\\ std.os.exit(126); \\ std.os.exit(126);
\\} \\}
\\pub fn main() void { \\pub fn main() void {
\\ var value: c_short = -1; \\ var value: c_short = -1;
\\ var casted = @intCast(u32, value); \\ var casted = @intCast(u32, value);
\\ _ = casted;
\\} \\}
); );
cases.addRuntimeSafety("unsigned integer not fitting in cast to signed integer - same bit count", cases.addRuntimeSafety("unsigned integer not fitting in cast to signed integer - same bit count",
\\const std = @import("std"); \\const std = @import("std");
\\pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn { \\pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn {
\\ _ = message;
\\ _ = stack_trace;
\\ std.os.exit(126); \\ std.os.exit(126);
\\} \\}
\\pub fn main() void { \\pub fn main() void {
\\ var value: u8 = 245; \\ var value: u8 = 245;
\\ var casted = @intCast(i8, value); \\ var casted = @intCast(i8, value);
\\ _ = casted;
\\} \\}
); );
cases.addRuntimeSafety("unwrap error", cases.addRuntimeSafety("unwrap error",
\\const std = @import("std"); \\const std = @import("std");
\\pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn { \\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")) { \\ if (std.mem.eql(u8, message, "attempt to unwrap error: Whatever")) {
\\ std.os.exit(126); // good \\ std.os.exit(126); // good
\\ } \\ }
@ -962,6 +1100,8 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
cases.addRuntimeSafety("cast integer to global error and no code matches", cases.addRuntimeSafety("cast integer to global error and no code matches",
\\const std = @import("std"); \\const std = @import("std");
\\pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn { \\pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn {
\\ _ = message;
\\ _ = stack_trace;
\\ std.os.exit(126); \\ std.os.exit(126);
\\} \\}
\\pub fn main() void { \\pub fn main() void {
@ -975,6 +1115,8 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
cases.addRuntimeSafety("@errSetCast error not present in destination", cases.addRuntimeSafety("@errSetCast error not present in destination",
\\const std = @import("std"); \\const std = @import("std");
\\pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn { \\pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn {
\\ _ = message;
\\ _ = stack_trace;
\\ std.os.exit(126); \\ std.os.exit(126);
\\} \\}
\\const Set1 = error{A, B}; \\const Set1 = error{A, B};
@ -990,6 +1132,8 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
cases.addRuntimeSafety("@alignCast misaligned", cases.addRuntimeSafety("@alignCast misaligned",
\\const std = @import("std"); \\const std = @import("std");
\\pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn { \\pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn {
\\ _ = message;
\\ _ = stack_trace;
\\ std.os.exit(126); \\ std.os.exit(126);
\\} \\}
\\pub fn main() !void { \\pub fn main() !void {
@ -1007,6 +1151,8 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
cases.addRuntimeSafety("bad union field access", cases.addRuntimeSafety("bad union field access",
\\const std = @import("std"); \\const std = @import("std");
\\pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn { \\pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn {
\\ _ = message;
\\ _ = stack_trace;
\\ std.os.exit(126); \\ std.os.exit(126);
\\} \\}
\\ \\
@ -1031,6 +1177,8 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
cases.addRuntimeSafety("@intCast to u0", cases.addRuntimeSafety("@intCast to u0",
\\const std = @import("std"); \\const std = @import("std");
\\pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn { \\pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn {
\\ _ = message;
\\ _ = stack_trace;
\\ std.os.exit(126); \\ std.os.exit(126);
\\} \\}
\\ \\
@ -1040,6 +1188,7 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
\\ \\
\\fn bar(one: u1, not_zero: i32) void { \\fn bar(one: u1, not_zero: i32) void {
\\ var x = one << @intCast(u0, not_zero); \\ var x = one << @intCast(u0, not_zero);
\\ _ = x;
\\} \\}
); );
@ -1049,6 +1198,8 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
\\const std = @import("std"); \\const std = @import("std");
\\ \\
\\pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn { \\pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn {
\\ _ = message;
\\ _ = stack_trace;
\\ std.os.exit(126); \\ std.os.exit(126);
\\} \\}
\\ \\
@ -1058,6 +1209,7 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
\\ const p = nonFailing(); \\ const p = nonFailing();
\\ resume p; \\ resume p;
\\ const p2 = async printTrace(p); \\ const p2 = async printTrace(p);
\\ _ = p2;
\\} \\}
\\ \\
\\fn nonFailing() anyframe->anyerror!void { \\fn nonFailing() anyframe->anyerror!void {
@ -1084,12 +1236,15 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
cases.addRuntimeSafety("slicing null C pointer", cases.addRuntimeSafety("slicing null C pointer",
\\const std = @import("std"); \\const std = @import("std");
\\pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn { \\pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn {
\\ _ = message;
\\ _ = stack_trace;
\\ std.os.exit(126); \\ std.os.exit(126);
\\} \\}
\\ \\
\\pub fn main() void { \\pub fn main() void {
\\ var ptr: [*c]const u32 = null; \\ var ptr: [*c]const u32 = null;
\\ var slice = ptr[0..3]; \\ var slice = ptr[0..3];
\\ _ = slice;
\\} \\}
); );
} }

View File

@ -12,9 +12,11 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
, &[_][]const u8{ , &[_][]const u8{
\\pub export fn foo(arg_x: c_ulong) c_ulong { \\pub export fn foo(arg_x: c_ulong) c_ulong {
\\ var x = arg_x; \\ var x = arg_x;
\\ _ = x;
\\ const union_unnamed_1 = extern union { \\ const union_unnamed_1 = extern union {
\\ _x: c_ulong, \\ _x: c_ulong,
\\ }; \\ };
\\ _ = union_unnamed_1;
\\ return (union_unnamed_1{ \\ return (union_unnamed_1{
\\ ._x = x, \\ ._x = x,
\\ })._x; \\ })._x;
@ -54,8 +56,10 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\pub export fn foo() void { \\pub export fn foo() void {
\\ while (true) if (true) { \\ while (true) if (true) {
\\ var a: c_int = 1; \\ var a: c_int = 1;
\\ _ = a;
\\ } else { \\ } else {
\\ var b: c_int = 2; \\ var b: c_int = 2;
\\ _ = b;
\\ }; \\ };
\\ if (true) if (true) {}; \\ if (true) if (true) {};
\\} \\}
@ -71,6 +75,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\pub extern fn bar(...) c_int; \\pub extern fn bar(...) c_int;
\\pub export fn foo() void { \\pub export fn foo() void {
\\ var a: c_int = undefined; \\ var a: c_int = undefined;
\\ _ = a;
\\ if (a != 0) a = 2 else _ = bar(); \\ if (a != 0) a = 2 else _ = bar();
\\} \\}
}); });
@ -123,22 +128,26 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\ B: c_int, \\ B: c_int,
\\ C: c_int, \\ C: c_int,
\\ }; \\ };
\\ _ = struct_Foo;
\\ var a: struct_Foo = struct_Foo{ \\ var a: struct_Foo = struct_Foo{
\\ .A = @as(c_int, 0), \\ .A = @as(c_int, 0),
\\ .B = 0, \\ .B = 0,
\\ .C = 0, \\ .C = 0,
\\ }; \\ };
\\ _ = a;
\\ { \\ {
\\ const struct_Foo_1 = extern struct { \\ const struct_Foo_1 = extern struct {
\\ A: c_int, \\ A: c_int,
\\ B: c_int, \\ B: c_int,
\\ C: c_int, \\ C: c_int,
\\ }; \\ };
\\ _ = struct_Foo_1;
\\ var a_2: struct_Foo_1 = struct_Foo_1{ \\ var a_2: struct_Foo_1 = struct_Foo_1{
\\ .A = @as(c_int, 0), \\ .A = @as(c_int, 0),
\\ .B = 0, \\ .B = 0,
\\ .C = 0, \\ .C = 0,
\\ }; \\ };
\\ _ = a_2;
\\ } \\ }
\\} \\}
}); });
@ -167,20 +176,26 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\ B: c_int, \\ B: c_int,
\\ C: c_int, \\ C: c_int,
\\ }; \\ };
\\ _ = union_unnamed_1;
\\ const Foo = union_unnamed_1; \\ const Foo = union_unnamed_1;
\\ _ = Foo;
\\ var a: Foo = Foo{ \\ var a: Foo = Foo{
\\ .A = @as(c_int, 0), \\ .A = @as(c_int, 0),
\\ }; \\ };
\\ _ = a;
\\ { \\ {
\\ const union_unnamed_2 = extern union { \\ const union_unnamed_2 = extern union {
\\ A: c_int, \\ A: c_int,
\\ B: c_int, \\ B: c_int,
\\ C: c_int, \\ C: c_int,
\\ }; \\ };
\\ _ = union_unnamed_2;
\\ const Foo_1 = union_unnamed_2; \\ const Foo_1 = union_unnamed_2;
\\ _ = Foo_1;
\\ var a_2: Foo_1 = Foo_1{ \\ var a_2: Foo_1 = Foo_1{
\\ .A = @as(c_int, 0), \\ .A = @as(c_int, 0),
\\ }; \\ };
\\ _ = a_2;
\\ } \\ }
\\} \\}
}); });
@ -190,6 +205,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\#define MEM_PHYSICAL_TO_K0(x) (void*)((uint32_t)(x) + SYS_BASE_CACHED) \\#define MEM_PHYSICAL_TO_K0(x) (void*)((uint32_t)(x) + SYS_BASE_CACHED)
, &[_][]const u8{ , &[_][]const u8{
\\pub inline fn MEM_PHYSICAL_TO_K0(x: anytype) ?*c_void { \\pub inline fn MEM_PHYSICAL_TO_K0(x: anytype) ?*c_void {
\\ _ = x;
\\ return @import("std").zig.c_translation.cast(?*c_void, @import("std").zig.c_translation.cast(u32, x) + SYS_BASE_CACHED); \\ return @import("std").zig.c_translation.cast(?*c_void, @import("std").zig.c_translation.cast(u32, x) + SYS_BASE_CACHED);
\\} \\}
}); });
@ -231,6 +247,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\pub const VALUE = ((((@as(c_int, 1) + (@as(c_int, 2) * @as(c_int, 3))) + (@as(c_int, 4) * @as(c_int, 5))) + @as(c_int, 6)) << @as(c_int, 7)) | @boolToInt(@as(c_int, 8) == @as(c_int, 9)); \\pub const VALUE = ((((@as(c_int, 1) + (@as(c_int, 2) * @as(c_int, 3))) + (@as(c_int, 4) * @as(c_int, 5))) + @as(c_int, 6)) << @as(c_int, 7)) | @boolToInt(@as(c_int, 8) == @as(c_int, 9));
, ,
\\pub inline fn _AL_READ3BYTES(p: anytype) @TypeOf((@import("std").zig.c_translation.cast([*c]u8, p).* | ((@import("std").zig.c_translation.cast([*c]u8, p) + @as(c_int, 1)).* << @as(c_int, 8))) | ((@import("std").zig.c_translation.cast([*c]u8, p) + @as(c_int, 2)).* << @as(c_int, 16))) { \\pub inline fn _AL_READ3BYTES(p: anytype) @TypeOf((@import("std").zig.c_translation.cast([*c]u8, p).* | ((@import("std").zig.c_translation.cast([*c]u8, p) + @as(c_int, 1)).* << @as(c_int, 8))) | ((@import("std").zig.c_translation.cast([*c]u8, p) + @as(c_int, 2)).* << @as(c_int, 16))) {
\\ _ = p;
\\ return (@import("std").zig.c_translation.cast([*c]u8, p).* | ((@import("std").zig.c_translation.cast([*c]u8, p) + @as(c_int, 1)).* << @as(c_int, 8))) | ((@import("std").zig.c_translation.cast([*c]u8, p) + @as(c_int, 2)).* << @as(c_int, 16)); \\ return (@import("std").zig.c_translation.cast([*c]u8, p).* | ((@import("std").zig.c_translation.cast([*c]u8, p) + @as(c_int, 1)).* << @as(c_int, 8))) | ((@import("std").zig.c_translation.cast([*c]u8, p) + @as(c_int, 2)).* << @as(c_int, 16));
\\} \\}
}); });
@ -246,6 +263,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\ const bar_1 = struct { \\ const bar_1 = struct {
\\ threadlocal var static: c_int = 2; \\ threadlocal var static: c_int = 2;
\\ }; \\ };
\\ _ = bar_1;
\\ return 0; \\ return 0;
\\} \\}
}); });
@ -264,6 +282,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\} \\}
\\pub export fn bar() c_int { \\pub export fn bar() c_int {
\\ var a: c_int = 2; \\ var a: c_int = 2;
\\ _ = a;
\\ return 0; \\ return 0;
\\} \\}
\\pub export fn baz() c_int { \\pub export fn baz() c_int {
@ -278,6 +297,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
, &[_][]const u8{ , &[_][]const u8{
\\pub export fn main() void { \\pub export fn main() void {
\\ var a: c_int = @bitCast(c_int, @truncate(c_uint, @alignOf(c_int))); \\ var a: c_int = @bitCast(c_int, @truncate(c_uint, @alignOf(c_int)));
\\ _ = a;
\\} \\}
}); });
@ -308,6 +328,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\pub const Color = struct_Color; \\pub const Color = struct_Color;
, ,
\\pub inline fn CLITERAL(type_1: anytype) @TypeOf(type_1) { \\pub inline fn CLITERAL(type_1: anytype) @TypeOf(type_1) {
\\ _ = type_1;
\\ return type_1; \\ return type_1;
\\} \\}
, ,
@ -325,6 +346,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\}; \\};
, ,
\\pub inline fn A(_x: anytype) MyCStruct { \\pub inline fn A(_x: anytype) MyCStruct {
\\ _ = _x;
\\ return @import("std").mem.zeroInit(MyCStruct, .{ \\ return @import("std").mem.zeroInit(MyCStruct, .{
\\ .x = _x, \\ .x = _x,
\\ }); \\ });
@ -355,6 +377,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\#define __ferror_unlocked_body(_fp) (((_fp)->_flags & _IO_ERR_SEEN) != 0) \\#define __ferror_unlocked_body(_fp) (((_fp)->_flags & _IO_ERR_SEEN) != 0)
, &[_][]const u8{ , &[_][]const u8{
\\pub inline fn __ferror_unlocked_body(_fp: anytype) @TypeOf((_fp.*._flags & _IO_ERR_SEEN) != @as(c_int, 0)) { \\pub inline fn __ferror_unlocked_body(_fp: anytype) @TypeOf((_fp.*._flags & _IO_ERR_SEEN) != @as(c_int, 0)) {
\\ _ = _fp;
\\ return (_fp.*._flags & _IO_ERR_SEEN) != @as(c_int, 0); \\ return (_fp.*._flags & _IO_ERR_SEEN) != @as(c_int, 0);
\\} \\}
}); });
@ -364,6 +387,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\#define BAR 1 && 2 > 4 \\#define BAR 1 && 2 > 4
, &[_][]const u8{ , &[_][]const u8{
\\pub inline fn FOO(x: anytype) @TypeOf(@boolToInt(x >= @as(c_int, 0)) + @boolToInt(x >= @as(c_int, 0))) { \\pub inline fn FOO(x: anytype) @TypeOf(@boolToInt(x >= @as(c_int, 0)) + @boolToInt(x >= @as(c_int, 0))) {
\\ _ = x;
\\ return @boolToInt(x >= @as(c_int, 0)) + @boolToInt(x >= @as(c_int, 0)); \\ return @boolToInt(x >= @as(c_int, 0)) + @boolToInt(x >= @as(c_int, 0));
\\} \\}
, ,
@ -426,6 +450,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\}; \\};
, ,
\\pub inline fn bar(x: anytype) @TypeOf(baz(@as(c_int, 1), @as(c_int, 2))) { \\pub inline fn bar(x: anytype) @TypeOf(baz(@as(c_int, 1), @as(c_int, 2))) {
\\ _ = x;
\\ return blk: { \\ return blk: {
\\ _ = &x; \\ _ = &x;
\\ _ = @as(c_int, 3); \\ _ = @as(c_int, 3);
@ -555,6 +580,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\}; \\};
\\pub export fn foo(arg_x: [*c]outer) void { \\pub export fn foo(arg_x: [*c]outer) void {
\\ var x = arg_x; \\ var x = arg_x;
\\ _ = x;
\\ x.*.unnamed_0.unnamed_0.y = @bitCast(c_int, @as(c_uint, x.*.unnamed_0.x)); \\ x.*.unnamed_0.unnamed_0.y = @bitCast(c_int, @as(c_uint, x.*.unnamed_0.x));
\\} \\}
}); });
@ -641,7 +667,9 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\pub const struct_opaque_2 = opaque {}; \\pub const struct_opaque_2 = opaque {};
\\pub export fn function(arg_opaque_1: ?*struct_opaque) void { \\pub export fn function(arg_opaque_1: ?*struct_opaque) void {
\\ var opaque_1 = arg_opaque_1; \\ var opaque_1 = arg_opaque_1;
\\ _ = opaque_1;
\\ var cast: ?*struct_opaque_2 = @ptrCast(?*struct_opaque_2, opaque_1); \\ var cast: ?*struct_opaque_2 = @ptrCast(?*struct_opaque_2, opaque_1);
\\ _ = cast;
\\} \\}
}); });
@ -673,6 +701,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\pub export fn my_fn() align(128) void {} \\pub export fn my_fn() align(128) void {}
\\pub export fn other_fn() void { \\pub export fn other_fn() void {
\\ var ARR: [16]u8 align(16) = undefined; \\ var ARR: [16]u8 align(16) = undefined;
\\ _ = ARR;
\\} \\}
}); });
@ -708,11 +737,17 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
, &[_][]const u8{ , &[_][]const u8{
\\pub export fn foo() void { \\pub export fn foo() void {
\\ var a: c_int = undefined; \\ var a: c_int = undefined;
\\ _ = a;
\\ var b: u8 = 123; \\ var b: u8 = 123;
\\ _ = b;
\\ const c: c_int = undefined; \\ const c: c_int = undefined;
\\ _ = c;
\\ const d: c_uint = @bitCast(c_uint, @as(c_int, 440)); \\ const d: c_uint = @bitCast(c_uint, @as(c_int, 440));
\\ _ = d;
\\ var e: c_int = 10; \\ var e: c_int = 10;
\\ _ = e;
\\ var f: c_uint = 10; \\ var f: c_uint = 10;
\\ _ = f;
\\} \\}
}); });
@ -728,6 +763,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
, &[_][]const u8{ , &[_][]const u8{
\\pub export fn foo() void { \\pub export fn foo() void {
\\ var a: c_int = undefined; \\ var a: c_int = undefined;
\\ _ = a;
\\ _ = @as(c_int, 1); \\ _ = @as(c_int, 1);
\\ _ = "hey"; \\ _ = "hey";
\\ _ = @as(c_int, 1) + @as(c_int, 1); \\ _ = @as(c_int, 1) + @as(c_int, 1);
@ -771,6 +807,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\ const v2 = struct { \\ const v2 = struct {
\\ const static: [5:0]u8 = "2.2.2".*; \\ const static: [5:0]u8 = "2.2.2".*;
\\ }; \\ };
\\ _ = v2;
\\} \\}
}); });
@ -812,7 +849,9 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\pub extern fn foo() void; \\pub extern fn foo() void;
\\pub export fn bar() void { \\pub export fn bar() void {
\\ var func_ptr: ?*c_void = @ptrCast(?*c_void, foo); \\ var func_ptr: ?*c_void = @ptrCast(?*c_void, foo);
\\ _ = func_ptr;
\\ var typed_func_ptr: ?fn () callconv(.C) void = @intToPtr(?fn () callconv(.C) void, @intCast(c_ulong, @ptrToInt(func_ptr))); \\ var typed_func_ptr: ?fn () callconv(.C) void = @intToPtr(?fn () callconv(.C) void, @intCast(c_ulong, @ptrToInt(func_ptr)));
\\ _ = typed_func_ptr;
\\} \\}
}); });
@ -842,8 +881,11 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
, &[_][]const u8{ , &[_][]const u8{
\\pub export fn s() c_int { \\pub export fn s() c_int {
\\ var a: c_int = undefined; \\ var a: c_int = undefined;
\\ _ = a;
\\ var b: c_int = undefined; \\ var b: c_int = undefined;
\\ _ = b;
\\ var c: c_int = undefined; \\ var c: c_int = undefined;
\\ _ = c;
\\ c = a + b; \\ c = a + b;
\\ c = a - b; \\ c = a - b;
\\ c = a * b; \\ c = a * b;
@ -853,8 +895,11 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\} \\}
\\pub export fn u() c_uint { \\pub export fn u() c_uint {
\\ var a: c_uint = undefined; \\ var a: c_uint = undefined;
\\ _ = a;
\\ var b: c_uint = undefined; \\ var b: c_uint = undefined;
\\ _ = b;
\\ var c: c_uint = undefined; \\ var c: c_uint = undefined;
\\ _ = c;
\\ c = a +% b; \\ c = a +% b;
\\ c = a -% b; \\ c = a -% b;
\\ c = a *% b; \\ c = a *% b;
@ -1218,6 +1263,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\pub export fn foo() void { \\pub export fn foo() void {
\\ var a: c_int = undefined; \\ var a: c_int = undefined;
\\ _ = a; \\ _ = a;
\\ _ = a;
\\} \\}
}); });
@ -1229,6 +1275,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
, &[_][]const u8{ , &[_][]const u8{
\\pub export fn foo() ?*c_void { \\pub export fn foo() ?*c_void {
\\ var x: [*c]c_ushort = undefined; \\ var x: [*c]c_ushort = undefined;
\\ _ = x;
\\ return @ptrCast(?*c_void, x); \\ return @ptrCast(?*c_void, x);
\\} \\}
}); });
@ -1285,6 +1332,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\pub export fn foo() void { \\pub export fn foo() void {
\\ { \\ {
\\ var i: c_int = 0; \\ var i: c_int = 0;
\\ _ = i;
\\ while (i != 0) : (i += 1) {} \\ while (i != 0) : (i += 1) {}
\\ } \\ }
\\} \\}
@ -1308,6 +1356,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
, &[_][]const u8{ , &[_][]const u8{
\\pub export fn foo() void { \\pub export fn foo() void {
\\ var i: c_int = undefined; \\ var i: c_int = undefined;
\\ _ = i;
\\ { \\ {
\\ i = 3; \\ i = 3;
\\ while (i != 0) : (i -= 1) {} \\ while (i != 0) : (i -= 1) {}
@ -1351,6 +1400,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
, &[_][]const u8{ , &[_][]const u8{
\\pub export fn ptrcast() [*c]f32 { \\pub export fn ptrcast() [*c]f32 {
\\ var a: [*c]c_int = undefined; \\ var a: [*c]c_int = undefined;
\\ _ = a;
\\ return @ptrCast([*c]f32, @alignCast(@import("std").meta.alignment(f32), a)); \\ return @ptrCast([*c]f32, @alignCast(@import("std").meta.alignment(f32), a));
\\} \\}
}); });
@ -1374,17 +1424,26 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
, &[_][]const u8{ , &[_][]const u8{
\\pub export fn test_ptr_cast() void { \\pub export fn test_ptr_cast() void {
\\ var p: ?*c_void = undefined; \\ var p: ?*c_void = undefined;
\\ _ = p;
\\ { \\ {
\\ var to_char: [*c]u8 = @ptrCast([*c]u8, @alignCast(@import("std").meta.alignment(u8), p)); \\ var to_char: [*c]u8 = @ptrCast([*c]u8, @alignCast(@import("std").meta.alignment(u8), p));
\\ _ = to_char;
\\ var to_short: [*c]c_short = @ptrCast([*c]c_short, @alignCast(@import("std").meta.alignment(c_short), p)); \\ var to_short: [*c]c_short = @ptrCast([*c]c_short, @alignCast(@import("std").meta.alignment(c_short), p));
\\ _ = to_short;
\\ var to_int: [*c]c_int = @ptrCast([*c]c_int, @alignCast(@import("std").meta.alignment(c_int), p)); \\ var to_int: [*c]c_int = @ptrCast([*c]c_int, @alignCast(@import("std").meta.alignment(c_int), p));
\\ _ = to_int;
\\ var to_longlong: [*c]c_longlong = @ptrCast([*c]c_longlong, @alignCast(@import("std").meta.alignment(c_longlong), p)); \\ var to_longlong: [*c]c_longlong = @ptrCast([*c]c_longlong, @alignCast(@import("std").meta.alignment(c_longlong), p));
\\ _ = to_longlong;
\\ } \\ }
\\ { \\ {
\\ var to_char: [*c]u8 = @ptrCast([*c]u8, @alignCast(@import("std").meta.alignment(u8), p)); \\ var to_char: [*c]u8 = @ptrCast([*c]u8, @alignCast(@import("std").meta.alignment(u8), p));
\\ _ = to_char;
\\ var to_short: [*c]c_short = @ptrCast([*c]c_short, @alignCast(@import("std").meta.alignment(c_short), p)); \\ var to_short: [*c]c_short = @ptrCast([*c]c_short, @alignCast(@import("std").meta.alignment(c_short), p));
\\ _ = to_short;
\\ var to_int: [*c]c_int = @ptrCast([*c]c_int, @alignCast(@import("std").meta.alignment(c_int), p)); \\ var to_int: [*c]c_int = @ptrCast([*c]c_int, @alignCast(@import("std").meta.alignment(c_int), p));
\\ _ = to_int;
\\ var to_longlong: [*c]c_longlong = @ptrCast([*c]c_longlong, @alignCast(@import("std").meta.alignment(c_longlong), p)); \\ var to_longlong: [*c]c_longlong = @ptrCast([*c]c_longlong, @alignCast(@import("std").meta.alignment(c_longlong), p));
\\ _ = to_longlong;
\\ } \\ }
\\} \\}
}); });
@ -1402,8 +1461,11 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
, &[_][]const u8{ , &[_][]const u8{
\\pub export fn while_none_bool() c_int { \\pub export fn while_none_bool() c_int {
\\ var a: c_int = undefined; \\ var a: c_int = undefined;
\\ _ = a;
\\ var b: f32 = undefined; \\ var b: f32 = undefined;
\\ _ = b;
\\ var c: ?*c_void = undefined; \\ var c: ?*c_void = undefined;
\\ _ = c;
\\ while (a != 0) return 0; \\ while (a != 0) return 0;
\\ while (b != 0) return 1; \\ while (b != 0) return 1;
\\ while (c != null) return 2; \\ while (c != null) return 2;
@ -1424,8 +1486,11 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
, &[_][]const u8{ , &[_][]const u8{
\\pub export fn for_none_bool() c_int { \\pub export fn for_none_bool() c_int {
\\ var a: c_int = undefined; \\ var a: c_int = undefined;
\\ _ = a;
\\ var b: f32 = undefined; \\ var b: f32 = undefined;
\\ _ = b;
\\ var c: ?*c_void = undefined; \\ var c: ?*c_void = undefined;
\\ _ = c;
\\ while (a != 0) return 0; \\ while (a != 0) return 0;
\\ while (b != 0) return 1; \\ while (b != 0) return 1;
\\ while (c != null) return 2; \\ while (c != null) return 2;
@ -1462,6 +1527,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
, &[_][]const u8{ , &[_][]const u8{
\\pub export fn foo() void { \\pub export fn foo() void {
\\ var x: [*c]c_int = undefined; \\ var x: [*c]c_int = undefined;
\\ _ = x;
\\ x.* = 1; \\ x.* = 1;
\\} \\}
}); });
@ -1475,7 +1541,9 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
, &[_][]const u8{ , &[_][]const u8{
\\pub export fn foo() c_int { \\pub export fn foo() c_int {
\\ var x: c_int = 1234; \\ var x: c_int = 1234;
\\ _ = x;
\\ var ptr: [*c]c_int = &x; \\ var ptr: [*c]c_int = &x;
\\ _ = ptr;
\\ return ptr.*; \\ return ptr.*;
\\} \\}
}); });
@ -1488,6 +1556,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
, &[_][]const u8{ , &[_][]const u8{
\\pub export fn foo() c_int { \\pub export fn foo() c_int {
\\ var x: c_int = undefined; \\ var x: c_int = undefined;
\\ _ = x;
\\ return ~x; \\ return ~x;
\\} \\}
}); });
@ -1505,8 +1574,11 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
, &[_][]const u8{ , &[_][]const u8{
\\pub export fn foo() c_int { \\pub export fn foo() c_int {
\\ var a: c_int = undefined; \\ var a: c_int = undefined;
\\ _ = a;
\\ var b: f32 = undefined; \\ var b: f32 = undefined;
\\ _ = b;
\\ var c: ?*c_void = undefined; \\ var c: ?*c_void = undefined;
\\ _ = c;
\\ return @boolToInt(!(a == @as(c_int, 0))); \\ return @boolToInt(!(a == @as(c_int, 0)));
\\ return @boolToInt(!(a != 0)); \\ return @boolToInt(!(a != 0));
\\ return @boolToInt(!(b != 0)); \\ return @boolToInt(!(b != 0));
@ -1628,9 +1700,11 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\ var arr: [10]u8 = [1]u8{ \\ var arr: [10]u8 = [1]u8{
\\ 1, \\ 1,
\\ } ++ [1]u8{0} ** 9; \\ } ++ [1]u8{0} ** 9;
\\ _ = arr;
\\ var arr1: [10][*c]u8 = [1][*c]u8{ \\ var arr1: [10][*c]u8 = [1][*c]u8{
\\ null, \\ null,
\\ } ++ [1][*c]u8{null} ** 9; \\ } ++ [1][*c]u8{null} ** 9;
\\ _ = arr1;
\\} \\}
}); });
@ -1817,10 +1891,13 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\pub extern var c: c_int; \\pub extern var c: c_int;
, ,
\\pub inline fn BASIC(c_1: anytype) @TypeOf(c_1 * @as(c_int, 2)) { \\pub inline fn BASIC(c_1: anytype) @TypeOf(c_1 * @as(c_int, 2)) {
\\ _ = c_1;
\\ return c_1 * @as(c_int, 2); \\ return c_1 * @as(c_int, 2);
\\} \\}
, ,
\\pub inline fn FOO(L: anytype, b: anytype) @TypeOf(L + b) { \\pub inline fn FOO(L: anytype, b: anytype) @TypeOf(L + b) {
\\ _ = L;
\\ _ = b;
\\ return L + b; \\ return L + b;
\\} \\}
, ,
@ -1872,13 +1949,18 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\pub var c: c_int = 4; \\pub var c: c_int = 4;
\\pub export fn foo(arg_c_1: u8) void { \\pub export fn foo(arg_c_1: u8) void {
\\ var c_1 = arg_c_1; \\ var c_1 = arg_c_1;
\\ _ = c_1;
\\ var a_2: c_int = undefined; \\ var a_2: c_int = undefined;
\\ _ = a_2;
\\ var b_3: u8 = 123; \\ var b_3: u8 = 123;
\\ _ = b_3;
\\ b_3 = @bitCast(u8, @truncate(i8, a_2)); \\ b_3 = @bitCast(u8, @truncate(i8, a_2));
\\ { \\ {
\\ var d: c_int = 5; \\ var d: c_int = 5;
\\ _ = d;
\\ } \\ }
\\ var d: c_uint = @bitCast(c_uint, @as(c_int, 440)); \\ var d: c_uint = @bitCast(c_uint, @as(c_int, 440));
\\ _ = d;
\\} \\}
}); });
@ -1912,7 +1994,9 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
, &[_][]const u8{ , &[_][]const u8{
\\pub export fn foo() void { \\pub export fn foo() void {
\\ var a: c_int = undefined; \\ var a: c_int = undefined;
\\ _ = a;
\\ var b: c_int = undefined; \\ var b: c_int = undefined;
\\ _ = b;
\\ a = blk: { \\ a = blk: {
\\ const tmp = @as(c_int, 2); \\ const tmp = @as(c_int, 2);
\\ b = tmp; \\ b = tmp;
@ -1942,11 +2026,13 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
, &[_][]const u8{ , &[_][]const u8{
\\pub export fn foo() c_int { \\pub export fn foo() c_int {
\\ var a: c_int = 5; \\ var a: c_int = 5;
\\ _ = a;
\\ while (true) { \\ while (true) {
\\ a = 2; \\ a = 2;
\\ } \\ }
\\ while (true) { \\ while (true) {
\\ var a_1: c_int = 4; \\ var a_1: c_int = 4;
\\ _ = a_1;
\\ a_1 = 9; \\ a_1 = 9;
\\ return blk: { \\ return blk: {
\\ _ = @as(c_int, 6); \\ _ = @as(c_int, 6);
@ -1955,6 +2041,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\ } \\ }
\\ while (true) { \\ while (true) {
\\ var a_1: c_int = 2; \\ var a_1: c_int = 2;
\\ _ = a_1;
\\ a_1 = 12; \\ a_1 = 12;
\\ } \\ }
\\ while (true) { \\ while (true) {
@ -1976,9 +2063,12 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\pub export fn foo() void { \\pub export fn foo() void {
\\ { \\ {
\\ var i: c_int = 2; \\ var i: c_int = 2;
\\ _ = i;
\\ var b: c_int = 4; \\ var b: c_int = 4;
\\ _ = b;
\\ while ((i + @as(c_int, 2)) != 0) : (i = 2) { \\ while ((i + @as(c_int, 2)) != 0) : (i = 2) {
\\ var a: c_int = 2; \\ var a: c_int = 2;
\\ _ = a;
\\ _ = blk: { \\ _ = blk: {
\\ _ = blk_1: { \\ _ = blk_1: {
\\ a = 6; \\ a = 6;
@ -1989,6 +2079,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\ } \\ }
\\ } \\ }
\\ var i: u8 = 2; \\ var i: u8 = 2;
\\ _ = i;
\\} \\}
}); });
@ -2061,7 +2152,9 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
, &[_][]const u8{ , &[_][]const u8{
\\pub export fn switch_fn(arg_i: c_int) void { \\pub export fn switch_fn(arg_i: c_int) void {
\\ var i = arg_i; \\ var i = arg_i;
\\ _ = i;
\\ var res: c_int = 0; \\ var res: c_int = 0;
\\ _ = res;
\\ while (true) { \\ while (true) {
\\ switch (i) { \\ switch (i) {
\\ @as(c_int, 0) => { \\ @as(c_int, 0) => {
@ -2150,7 +2243,9 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
, &[_][]const u8{ , &[_][]const u8{
\\pub export fn max(arg_a: c_int) void { \\pub export fn max(arg_a: c_int) void {
\\ var a = arg_a; \\ var a = arg_a;
\\ _ = a;
\\ var tmp: c_int = undefined; \\ var tmp: c_int = undefined;
\\ _ = tmp;
\\ tmp = a; \\ tmp = a;
\\ a = tmp; \\ a = tmp;
\\} \\}
@ -2164,8 +2259,11 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
, &[_][]const u8{ , &[_][]const u8{
\\pub export fn max(arg_a: c_int) void { \\pub export fn max(arg_a: c_int) void {
\\ var a = arg_a; \\ var a = arg_a;
\\ _ = a;
\\ var b: c_int = undefined; \\ var b: c_int = undefined;
\\ _ = b;
\\ var c: c_int = undefined; \\ var c: c_int = undefined;
\\ _ = c;
\\ c = blk: { \\ c = blk: {
\\ const tmp = a; \\ const tmp = a;
\\ b = tmp; \\ b = tmp;
@ -2194,6 +2292,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
, &[_][]const u8{ , &[_][]const u8{
\\pub export fn float_to_int(arg_a: f32) c_int { \\pub export fn float_to_int(arg_a: f32) c_int {
\\ var a = arg_a; \\ var a = arg_a;
\\ _ = a;
\\ return @floatToInt(c_int, a); \\ return @floatToInt(c_int, a);
\\} \\}
}); });
@ -2217,16 +2316,27 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
, &[_][]const u8{ , &[_][]const u8{
\\pub export fn escapes() [*c]const u8 { \\pub export fn escapes() [*c]const u8 {
\\ var a: u8 = '\''; \\ var a: u8 = '\'';
\\ _ = a;
\\ var b: u8 = '\\'; \\ var b: u8 = '\\';
\\ _ = b;
\\ var c: u8 = '\x07'; \\ var c: u8 = '\x07';
\\ _ = c;
\\ var d: u8 = '\x08'; \\ var d: u8 = '\x08';
\\ _ = d;
\\ var e: u8 = '\x0c'; \\ var e: u8 = '\x0c';
\\ _ = e;
\\ var f: u8 = '\n'; \\ var f: u8 = '\n';
\\ _ = f;
\\ var g: u8 = '\r'; \\ var g: u8 = '\r';
\\ _ = g;
\\ var h: u8 = '\t'; \\ var h: u8 = '\t';
\\ _ = h;
\\ var i: u8 = '\x0b'; \\ var i: u8 = '\x0b';
\\ _ = i;
\\ var j: u8 = '\x00'; \\ var j: u8 = '\x00';
\\ _ = j;
\\ var k: u8 = '"'; \\ var k: u8 = '"';
\\ _ = k;
\\ return "'\\\x07\x08\x0c\n\r\t\x0b\x00\""; \\ return "'\\\x07\x08\x0c\n\r\t\x0b\x00\"";
\\} \\}
}); });
@ -2246,11 +2356,13 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
, &[_][]const u8{ , &[_][]const u8{
\\pub export fn foo() void { \\pub export fn foo() void {
\\ var a: c_int = 2; \\ var a: c_int = 2;
\\ _ = a;
\\ while (true) { \\ while (true) {
\\ a = a - @as(c_int, 1); \\ a = a - @as(c_int, 1);
\\ if (!(a != 0)) break; \\ if (!(a != 0)) break;
\\ } \\ }
\\ var b: c_int = 2; \\ var b: c_int = 2;
\\ _ = b;
\\ while (true) { \\ while (true) {
\\ b = b - @as(c_int, 1); \\ b = b - @as(c_int, 1);
\\ if (!(b != 0)) break; \\ if (!(b != 0)) break;
@ -2291,21 +2403,37 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\pub const SomeTypedef = c_int; \\pub const SomeTypedef = c_int;
\\pub export fn and_or_non_bool(arg_a: c_int, arg_b: f32, arg_c: ?*c_void) c_int { \\pub export fn and_or_non_bool(arg_a: c_int, arg_b: f32, arg_c: ?*c_void) c_int {
\\ var a = arg_a; \\ var a = arg_a;
\\ _ = a;
\\ var b = arg_b; \\ var b = arg_b;
\\ _ = b;
\\ var c = arg_c; \\ var c = arg_c;
\\ _ = c;
\\ var d: enum_Foo = @bitCast(c_uint, FooA); \\ var d: enum_Foo = @bitCast(c_uint, FooA);
\\ _ = d;
\\ var e: c_int = @boolToInt((a != 0) and (b != 0)); \\ var e: c_int = @boolToInt((a != 0) and (b != 0));
\\ _ = e;
\\ var f: c_int = @boolToInt((b != 0) and (c != null)); \\ var f: c_int = @boolToInt((b != 0) and (c != null));
\\ _ = f;
\\ var g: c_int = @boolToInt((a != 0) and (c != null)); \\ var g: c_int = @boolToInt((a != 0) and (c != null));
\\ _ = g;
\\ var h: c_int = @boolToInt((a != 0) or (b != 0)); \\ var h: c_int = @boolToInt((a != 0) or (b != 0));
\\ _ = h;
\\ var i: c_int = @boolToInt((b != 0) or (c != null)); \\ var i: c_int = @boolToInt((b != 0) or (c != null));
\\ _ = i;
\\ var j: c_int = @boolToInt((a != 0) or (c != null)); \\ var j: c_int = @boolToInt((a != 0) or (c != null));
\\ _ = j;
\\ var k: c_int = @boolToInt((a != 0) or (@bitCast(c_int, d) != 0)); \\ var k: c_int = @boolToInt((a != 0) or (@bitCast(c_int, d) != 0));
\\ _ = k;
\\ var l: c_int = @boolToInt((@bitCast(c_int, d) != 0) and (b != 0)); \\ var l: c_int = @boolToInt((@bitCast(c_int, d) != 0) and (b != 0));
\\ _ = l;
\\ var m: c_int = @boolToInt((c != null) or (d != 0)); \\ var m: c_int = @boolToInt((c != null) or (d != 0));
\\ _ = m;
\\ var td: SomeTypedef = 44; \\ var td: SomeTypedef = 44;
\\ _ = td;
\\ var o: c_int = @boolToInt((td != 0) or (b != 0)); \\ var o: c_int = @boolToInt((td != 0) or (b != 0));
\\ _ = o;
\\ var p: c_int = @boolToInt((c != null) and (td != 0)); \\ var p: c_int = @boolToInt((c != null) and (td != 0));
\\ _ = p;
\\ return (((((((((e + f) + g) + h) + i) + j) + k) + l) + m) + o) + p; \\ return (((((((((e + f) + g) + h) + i) + j) + k) + l) + m) + o) + p;
\\} \\}
, ,
@ -2345,7 +2473,9 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
, &[_][]const u8{ , &[_][]const u8{
\\pub export fn max(arg_a: c_int, arg_b: c_int) c_int { \\pub export fn max(arg_a: c_int, arg_b: c_int) c_int {
\\ var a = arg_a; \\ var a = arg_a;
\\ _ = a;
\\ var b = arg_b; \\ var b = arg_b;
\\ _ = b;
\\ return (a & b) ^ (a | b); \\ return (a & b) ^ (a | b);
\\} \\}
}); });
@ -2364,14 +2494,23 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
, &[_][]const u8{ , &[_][]const u8{
\\pub export fn test_comparisons(arg_a: c_int, arg_b: c_int) c_int { \\pub export fn test_comparisons(arg_a: c_int, arg_b: c_int) c_int {
\\ var a = arg_a; \\ var a = arg_a;
\\ _ = a;
\\ var b = arg_b; \\ var b = arg_b;
\\ _ = b;
\\ var c: c_int = @boolToInt(a < b); \\ var c: c_int = @boolToInt(a < b);
\\ _ = c;
\\ var d: c_int = @boolToInt(a > b); \\ var d: c_int = @boolToInt(a > b);
\\ _ = d;
\\ var e: c_int = @boolToInt(a <= b); \\ var e: c_int = @boolToInt(a <= b);
\\ _ = e;
\\ var f: c_int = @boolToInt(a >= b); \\ var f: c_int = @boolToInt(a >= b);
\\ _ = f;
\\ var g: c_int = @boolToInt(c < d); \\ var g: c_int = @boolToInt(c < d);
\\ _ = g;
\\ var h: c_int = @boolToInt(e < f); \\ var h: c_int = @boolToInt(e < f);
\\ _ = h;
\\ var i: c_int = @boolToInt(g < h); \\ var i: c_int = @boolToInt(g < h);
\\ _ = i;
\\ return i; \\ return i;
\\} \\}
}); });
@ -2387,7 +2526,9 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
, &[_][]const u8{ , &[_][]const u8{
\\pub export fn max(arg_a: c_int, arg_b: c_int) c_int { \\pub export fn max(arg_a: c_int, arg_b: c_int) c_int {
\\ var a = arg_a; \\ var a = arg_a;
\\ _ = a;
\\ var b = arg_b; \\ var b = arg_b;
\\ _ = b;
\\ if (a == b) return a; \\ if (a == b) return a;
\\ if (a != b) return b; \\ if (a != b) return b;
\\ return a; \\ return a;
@ -2404,6 +2545,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\pub const yes = [*c]u8; \\pub const yes = [*c]u8;
\\pub export fn foo() void { \\pub export fn foo() void {
\\ var a: yes = undefined; \\ var a: yes = undefined;
\\ _ = a;
\\ if (a != null) { \\ if (a != null) {
\\ _ = @as(c_int, 2); \\ _ = @as(c_int, 2);
\\ } \\ }
@ -2423,6 +2565,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\ return blk: { \\ return blk: {
\\ var a: c_int = 1; \\ var a: c_int = 1;
\\ _ = a; \\ _ = a;
\\ _ = a;
\\ break :blk a; \\ break :blk a;
\\ }; \\ };
\\} \\}
@ -2448,6 +2591,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\pub export var b: f32 = 2.0; \\pub export var b: f32 = 2.0;
\\pub export fn foo() void { \\pub export fn foo() void {
\\ var c: [*c]struct_Foo = undefined; \\ var c: [*c]struct_Foo = undefined;
\\ _ = c;
\\ _ = a.b; \\ _ = a.b;
\\ _ = c.*.b; \\ _ = c.*.b;
\\} \\}
@ -2467,6 +2611,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\pub export var array: [100]c_int = [1]c_int{0} ** 100; \\pub export var array: [100]c_int = [1]c_int{0} ** 100;
\\pub export fn foo(arg_index: c_int) c_int { \\pub export fn foo(arg_index: c_int) c_int {
\\ var index = arg_index; \\ var index = arg_index;
\\ _ = index;
\\ return array[@intCast(c_uint, index)]; \\ return array[@intCast(c_uint, index)];
\\} \\}
, ,
@ -2481,7 +2626,9 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
, &[_][]const u8{ , &[_][]const u8{
\\pub export fn foo() void { \\pub export fn foo() void {
\\ var a: [10]c_int = undefined; \\ var a: [10]c_int = undefined;
\\ _ = a;
\\ var i: c_int = 0; \\ var i: c_int = 0;
\\ _ = i;
\\ a[@intCast(c_uint, i)] = 0; \\ a[@intCast(c_uint, i)] = 0;
\\} \\}
}); });
@ -2494,7 +2641,9 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
, &[_][]const u8{ , &[_][]const u8{
\\pub export fn foo() void { \\pub export fn foo() void {
\\ var a: [10]c_longlong = undefined; \\ var a: [10]c_longlong = undefined;
\\ _ = a;
\\ var i: c_longlong = 0; \\ var i: c_longlong = 0;
\\ _ = i;
\\ a[@intCast(usize, i)] = 0; \\ a[@intCast(usize, i)] = 0;
\\} \\}
}); });
@ -2507,7 +2656,9 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
, &[_][]const u8{ , &[_][]const u8{
\\pub export fn foo() void { \\pub export fn foo() void {
\\ var a: [10]c_uint = undefined; \\ var a: [10]c_uint = undefined;
\\ _ = a;
\\ var i: c_uint = 0; \\ var i: c_uint = 0;
\\ _ = i;
\\ a[i] = 0; \\ a[i] = 0;
\\} \\}
}); });
@ -2516,6 +2667,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\#define CALL(arg) bar(arg) \\#define CALL(arg) bar(arg)
, &[_][]const u8{ , &[_][]const u8{
\\pub inline fn CALL(arg: anytype) @TypeOf(bar(arg)) { \\pub inline fn CALL(arg: anytype) @TypeOf(bar(arg)) {
\\ _ = arg;
\\ return bar(arg); \\ return bar(arg);
\\} \\}
}); });
@ -2524,6 +2676,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\#define CALL(arg) bar() \\#define CALL(arg) bar()
, &[_][]const u8{ , &[_][]const u8{
\\pub inline fn CALL(arg: anytype) @TypeOf(bar()) { \\pub inline fn CALL(arg: anytype) @TypeOf(bar()) {
\\ _ = arg;
\\ return bar(); \\ return bar();
\\} \\}
}); });
@ -2539,7 +2692,9 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
, &[_][]const u8{ , &[_][]const u8{
\\pub export fn max(arg_a: c_int, arg_b: c_int) c_int { \\pub export fn max(arg_a: c_int, arg_b: c_int) c_int {
\\ var a = arg_a; \\ var a = arg_a;
\\ _ = a;
\\ var b = arg_b; \\ var b = arg_b;
\\ _ = b;
\\ if ((a < b) or (a == b)) return b; \\ if ((a < b) or (a == b)) return b;
\\ if ((a >= b) and (a == b)) return a; \\ if ((a >= b) and (a == b)) return a;
\\ return a; \\ return a;
@ -2561,7 +2716,9 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
, &[_][]const u8{ , &[_][]const u8{
\\pub export fn max(arg_a: c_int, arg_b: c_int) c_int { \\pub export fn max(arg_a: c_int, arg_b: c_int) c_int {
\\ var a = arg_a; \\ var a = arg_a;
\\ _ = a;
\\ var b = arg_b; \\ var b = arg_b;
\\ _ = b;
\\ if (a < b) return b; \\ if (a < b) return b;
\\ if (a < b) return b else return a; \\ if (a < b) return b else return a;
\\ if (a < b) {} else {} \\ if (a < b) {} else {}
@ -2582,12 +2739,14 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\pub export fn foo() void { \\pub export fn foo() void {
\\ if (true) { \\ if (true) {
\\ var a: c_int = 2; \\ var a: c_int = 2;
\\ _ = a;
\\ } \\ }
\\ if ((blk: { \\ if ((blk: {
\\ _ = @as(c_int, 2); \\ _ = @as(c_int, 2);
\\ break :blk @as(c_int, 5); \\ break :blk @as(c_int, 5);
\\ }) != 0) { \\ }) != 0) {
\\ var a: c_int = 2; \\ var a: c_int = 2;
\\ _ = a;
\\ } \\ }
\\} \\}
}); });
@ -2610,9 +2769,13 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\; \\;
\\pub export fn if_none_bool(arg_a: c_int, arg_b: f32, arg_c: ?*c_void, arg_d: enum_SomeEnum) c_int { \\pub export fn if_none_bool(arg_a: c_int, arg_b: f32, arg_c: ?*c_void, arg_d: enum_SomeEnum) c_int {
\\ var a = arg_a; \\ var a = arg_a;
\\ _ = a;
\\ var b = arg_b; \\ var b = arg_b;
\\ _ = b;
\\ var c = arg_c; \\ var c = arg_c;
\\ _ = c;
\\ var d = arg_d; \\ var d = arg_d;
\\ _ = d;
\\ if (a != 0) return 0; \\ if (a != 0) return 0;
\\ if (b != 0) return 1; \\ if (b != 0) return 1;
\\ if (c != null) return 2; \\ if (c != null) return 2;
@ -2640,6 +2803,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
, &[_][]const u8{ , &[_][]const u8{
\\pub export fn abs(arg_a: c_int) c_int { \\pub export fn abs(arg_a: c_int) c_int {
\\ var a = arg_a; \\ var a = arg_a;
\\ _ = a;
\\ return if (a < @as(c_int, 0)) -a else a; \\ return if (a < @as(c_int, 0)) -a else a;
\\} \\}
}); });
@ -2660,16 +2824,19 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
, &[_][]const u8{ , &[_][]const u8{
\\pub export fn foo1(arg_a: c_uint) c_uint { \\pub export fn foo1(arg_a: c_uint) c_uint {
\\ var a = arg_a; \\ var a = arg_a;
\\ _ = a;
\\ a +%= 1; \\ a +%= 1;
\\ return a; \\ return a;
\\} \\}
\\pub export fn foo2(arg_a: c_int) c_int { \\pub export fn foo2(arg_a: c_int) c_int {
\\ var a = arg_a; \\ var a = arg_a;
\\ _ = a;
\\ a += 1; \\ a += 1;
\\ return a; \\ return a;
\\} \\}
\\pub export fn foo3(arg_a: [*c]c_int) [*c]c_int { \\pub export fn foo3(arg_a: [*c]c_int) [*c]c_int {
\\ var a = arg_a; \\ var a = arg_a;
\\ _ = a;
\\ a += 1; \\ a += 1;
\\ return a; \\ return a;
\\} \\}
@ -2695,7 +2862,9 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\} \\}
\\pub export fn bar() void { \\pub export fn bar() void {
\\ var f: ?fn () callconv(.C) void = foo; \\ var f: ?fn () callconv(.C) void = foo;
\\ _ = f;
\\ var b: ?fn () callconv(.C) c_int = baz; \\ var b: ?fn () callconv(.C) c_int = baz;
\\ _ = b;
\\ f.?(); \\ f.?();
\\ f.?(); \\ f.?();
\\ foo(); \\ foo();
@ -2721,7 +2890,9 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
, &[_][]const u8{ , &[_][]const u8{
\\pub export fn foo() void { \\pub export fn foo() void {
\\ var i: c_int = 0; \\ var i: c_int = 0;
\\ _ = i;
\\ var u: c_uint = 0; \\ var u: c_uint = 0;
\\ _ = u;
\\ i += 1; \\ i += 1;
\\ i -= 1; \\ i -= 1;
\\ u +%= 1; \\ u +%= 1;
@ -2760,7 +2931,9 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
, &[_][]const u8{ , &[_][]const u8{
\\pub export fn log2(arg_a: c_uint) c_int { \\pub export fn log2(arg_a: c_uint) c_int {
\\ var a = arg_a; \\ var a = arg_a;
\\ _ = a;
\\ var i: c_int = 0; \\ var i: c_int = 0;
\\ _ = i;
\\ while (a > @bitCast(c_uint, @as(c_int, 0))) { \\ while (a > @bitCast(c_uint, @as(c_int, 0))) {
\\ a >>= @intCast(@import("std").math.Log2Int(c_int), @as(c_int, 1)); \\ a >>= @intCast(@import("std").math.Log2Int(c_int), @as(c_int, 1));
\\ } \\ }
@ -2780,7 +2953,9 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
, &[_][]const u8{ , &[_][]const u8{
\\pub export fn log2(arg_a: u32) c_int { \\pub export fn log2(arg_a: u32) c_int {
\\ var a = arg_a; \\ var a = arg_a;
\\ _ = a;
\\ var i: c_int = 0; \\ var i: c_int = 0;
\\ _ = i;
\\ while (a > @bitCast(c_uint, @as(c_int, 0))) { \\ while (a > @bitCast(c_uint, @as(c_int, 0))) {
\\ a >>= @intCast(@import("std").math.Log2Int(c_int), @as(c_int, 1)); \\ a >>= @intCast(@import("std").math.Log2Int(c_int), @as(c_int, 1));
\\ } \\ }
@ -2808,7 +2983,9 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
, &[_][]const u8{ , &[_][]const u8{
\\pub export fn foo() void { \\pub export fn foo() void {
\\ var a: c_int = 0; \\ var a: c_int = 0;
\\ _ = a;
\\ var b: c_uint = 0; \\ var b: c_uint = 0;
\\ _ = b;
\\ a += blk: { \\ a += blk: {
\\ const ref = &a; \\ const ref = &a;
\\ ref.* += @as(c_int, 1); \\ ref.* += @as(c_int, 1);
@ -2887,6 +3064,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
, &[_][]const u8{ , &[_][]const u8{
\\pub export fn foo() void { \\pub export fn foo() void {
\\ var a: c_uint = 0; \\ var a: c_uint = 0;
\\ _ = a;
\\ a +%= blk: { \\ a +%= blk: {
\\ const ref = &a; \\ const ref = &a;
\\ ref.* +%= @bitCast(c_uint, @as(c_int, 1)); \\ ref.* +%= @bitCast(c_uint, @as(c_int, 1));
@ -2946,7 +3124,9 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
, &[_][]const u8{ , &[_][]const u8{
\\pub export fn foo() void { \\pub export fn foo() void {
\\ var i: c_int = 0; \\ var i: c_int = 0;
\\ _ = i;
\\ var u: c_uint = 0; \\ var u: c_uint = 0;
\\ _ = u;
\\ i += 1; \\ i += 1;
\\ i -= 1; \\ i -= 1;
\\ u +%= 1; \\ u +%= 1;
@ -3041,6 +3221,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\pub fn bar() callconv(.C) void {} \\pub fn bar() callconv(.C) void {}
\\pub export fn foo(arg_baz: ?fn () callconv(.C) [*c]c_int) void { \\pub export fn foo(arg_baz: ?fn () callconv(.C) [*c]c_int) void {
\\ var baz = arg_baz; \\ var baz = arg_baz;
\\ _ = baz;
\\ bar(); \\ bar();
\\ _ = baz.?(); \\ _ = baz.?();
\\} \\}
@ -3082,6 +3263,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\#define BAZ (uint32_t)(2) \\#define BAZ (uint32_t)(2)
, &[_][]const u8{ , &[_][]const u8{
\\pub inline fn FOO(bar: anytype) @TypeOf(baz(@import("std").zig.c_translation.cast(?*c_void, baz))) { \\pub inline fn FOO(bar: anytype) @TypeOf(baz(@import("std").zig.c_translation.cast(?*c_void, baz))) {
\\ _ = bar;
\\ return baz(@import("std").zig.c_translation.cast(?*c_void, baz)); \\ return baz(@import("std").zig.c_translation.cast(?*c_void, baz));
\\} \\}
, ,
@ -3122,10 +3304,14 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\#define MAX(a, b) ((b) > (a) ? (b) : (a)) \\#define MAX(a, b) ((b) > (a) ? (b) : (a))
, &[_][]const u8{ , &[_][]const u8{
\\pub inline fn MIN(a: anytype, b: anytype) @TypeOf(if (b < a) b else a) { \\pub inline fn MIN(a: anytype, b: anytype) @TypeOf(if (b < a) b else a) {
\\ _ = a;
\\ _ = b;
\\ return if (b < a) b else a; \\ return if (b < a) b else a;
\\} \\}
, ,
\\pub inline fn MAX(a: anytype, b: anytype) @TypeOf(if (b > a) b else a) { \\pub inline fn MAX(a: anytype, b: anytype) @TypeOf(if (b > a) b else a) {
\\ _ = a;
\\ _ = b;
\\ return if (b > a) b else a; \\ return if (b > a) b else a;
\\} \\}
}); });
@ -3137,7 +3323,9 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
, &[_][]const u8{ , &[_][]const u8{
\\pub export fn foo(arg_p: [*c]c_int, arg_x: c_int) c_int { \\pub export fn foo(arg_p: [*c]c_int, arg_x: c_int) c_int {
\\ var p = arg_p; \\ var p = arg_p;
\\ _ = p;
\\ var x = arg_x; \\ var x = arg_x;
\\ _ = x;
\\ return blk: { \\ return blk: {
\\ const tmp = x; \\ const tmp = x;
\\ (blk_1: { \\ (blk_1: {
@ -3164,6 +3352,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\} \\}
\\pub export fn bar(arg_x: c_long) c_ushort { \\pub export fn bar(arg_x: c_long) c_ushort {
\\ var x = arg_x; \\ var x = arg_x;
\\ _ = x;
\\ return @bitCast(c_ushort, @truncate(c_short, x)); \\ return @bitCast(c_ushort, @truncate(c_short, x));
\\} \\}
}); });
@ -3176,6 +3365,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
, &[_][]const u8{ , &[_][]const u8{
\\pub export fn foo(arg_bar_1: c_int) void { \\pub export fn foo(arg_bar_1: c_int) void {
\\ var bar_1 = arg_bar_1; \\ var bar_1 = arg_bar_1;
\\ _ = bar_1;
\\ bar_1 = 2; \\ bar_1 = 2;
\\} \\}
\\pub export var bar: c_int = 4; \\pub export var bar: c_int = 4;
@ -3189,6 +3379,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
, &[_][]const u8{ , &[_][]const u8{
\\pub export fn foo(arg_bar_1: c_int) void { \\pub export fn foo(arg_bar_1: c_int) void {
\\ var bar_1 = arg_bar_1; \\ var bar_1 = arg_bar_1;
\\ _ = bar_1;
\\ bar_1 = 2; \\ bar_1 = 2;
\\} \\}
, ,
@ -3218,13 +3409,16 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
, &[_][]const u8{ , &[_][]const u8{
\\pub export fn foo(arg_a: [*c]c_int) void { \\pub export fn foo(arg_a: [*c]c_int) void {
\\ var a = arg_a; \\ var a = arg_a;
\\ _ = a;
\\} \\}
\\pub export fn bar(arg_a: [*c]const c_int) void { \\pub export fn bar(arg_a: [*c]const c_int) void {
\\ var a = arg_a; \\ var a = arg_a;
\\ _ = a;
\\ foo(@intToPtr([*c]c_int, @ptrToInt(a))); \\ foo(@intToPtr([*c]c_int, @ptrToInt(a)));
\\} \\}
\\pub export fn baz(arg_a: [*c]volatile c_int) void { \\pub export fn baz(arg_a: [*c]volatile c_int) void {
\\ var a = arg_a; \\ var a = arg_a;
\\ _ = a;
\\ foo(@intToPtr([*c]c_int, @ptrToInt(a))); \\ foo(@intToPtr([*c]c_int, @ptrToInt(a)));
\\} \\}
}); });
@ -3239,9 +3433,13 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
, &[_][]const u8{ , &[_][]const u8{
\\pub export fn foo(arg_x: bool) bool { \\pub export fn foo(arg_x: bool) bool {
\\ var x = arg_x; \\ var x = arg_x;
\\ _ = x;
\\ var a: bool = @as(c_int, @boolToInt(x)) != @as(c_int, 1); \\ var a: bool = @as(c_int, @boolToInt(x)) != @as(c_int, 1);
\\ _ = a;
\\ var b: bool = @as(c_int, @boolToInt(a)) != @as(c_int, 0); \\ var b: bool = @as(c_int, @boolToInt(a)) != @as(c_int, 0);
\\ _ = b;
\\ var c: bool = @ptrToInt(foo) != 0; \\ var c: bool = @ptrToInt(foo) != 0;
\\ _ = c;
\\ return foo(@as(c_int, @boolToInt(c)) != @as(c_int, @boolToInt(b))); \\ return foo(@as(c_int, @boolToInt(c)) != @as(c_int, @boolToInt(b)));
\\} \\}
}); });
@ -3252,7 +3450,9 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\} \\}
, &[_][]const u8{ , &[_][]const u8{
\\pub export fn max(x: c_int, arg_y: c_int) c_int { \\pub export fn max(x: c_int, arg_y: c_int) c_int {
\\ _ = x;
\\ var y = arg_y; \\ var y = arg_y;
\\ _ = y;
\\ return if (x > y) x else y; \\ return if (x > y) x else y;
\\} \\}
}); });
@ -3313,6 +3513,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\ \\
, &[_][]const u8{ , &[_][]const u8{
\\pub inline fn DefaultScreen(dpy: anytype) @TypeOf(@import("std").zig.c_translation.cast(_XPrivDisplay, dpy).*.default_screen) { \\pub inline fn DefaultScreen(dpy: anytype) @TypeOf(@import("std").zig.c_translation.cast(_XPrivDisplay, dpy).*.default_screen) {
\\ _ = dpy;
\\ return @import("std").zig.c_translation.cast(_XPrivDisplay, dpy).*.default_screen; \\ return @import("std").zig.c_translation.cast(_XPrivDisplay, dpy).*.default_screen;
\\} \\}
}); });
@ -3532,6 +3733,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\ const foo = struct { \\ const foo = struct {
\\ var static: struct_FOO = @import("std").mem.zeroes(struct_FOO); \\ var static: struct_FOO = @import("std").mem.zeroes(struct_FOO);
\\ }; \\ };
\\ _ = foo;
\\ return foo.static.x; \\ return foo.static.x;
\\} \\}
}); });
@ -3544,4 +3746,31 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\pub const MAP_FAILED = @import("std").zig.c_translation.cast(?*c_void, -@as(c_int, 1)); \\pub const MAP_FAILED = @import("std").zig.c_translation.cast(?*c_void, -@as(c_int, 1));
\\pub const INVALID_HANDLE_VALUE = @import("std").zig.c_translation.cast(?*c_void, @import("std").zig.c_translation.cast(LONG_PTR, -@as(c_int, 1))); \\pub const INVALID_HANDLE_VALUE = @import("std").zig.c_translation.cast(?*c_void, @import("std").zig.c_translation.cast(LONG_PTR, -@as(c_int, 1)));
}); });
cases.add("discard local variables and function parameters",
\\#define FOO(A, B) (A) + (B)
\\int bar(int x, int y) {
\\ return x;
\\}
, &[_][]const u8{
\\pub export fn bar(arg_x: c_int, arg_y: c_int) c_int {
\\ var x = arg_x;
\\ _ = x;
\\ var y = arg_y;
\\ _ = y;
\\ return x;
\\}
,
\\pub inline fn FOO(A: anytype, B: anytype) @TypeOf(A + B) {
\\ _ = A;
\\ _ = B;
\\ return A + B;
\\}
});
cases.add("Don't allow underscore identifier in macros",
\\#define FOO _
, &[_][]const u8{
\\pub const FOO = @compileError("unable to translate C expr: illegal identifier _");
});
} }