From cf65ab86011c3098bff131d6b98e13a494fc4814 Mon Sep 17 00:00:00 2001
From: Andrew Kelley
Date: Mon, 21 Jun 2021 18:59:51 -0700
Subject: [PATCH 01/15] run AstGen even when using the stage1 backend
This change reduces the amount of divergence in the compiler's main
pipeline logic enough to run AstGen for all files in the compilation,
regardless of whether the stage1 or stage2 backend is being used.
Practically, this means that all Zig code is subject to new compile
errors, such as unused local variables.
Additionally:
* remove leftover unsound asserts from recent hash map changes
* fix sub-Compilation errors not indenting correctly
---
src/Compilation.zig | 107 +++++++++++++++++++++++---------------------
1 file changed, 56 insertions(+), 51 deletions(-)
diff --git a/src/Compilation.zig b/src/Compilation.zig
index 7dbfb5068a4f..57320109da83 100644
--- a/src/Compilation.zig
+++ b/src/Compilation.zig
@@ -342,6 +342,7 @@ pub const AllErrors = struct {
const stderr = stderr_file.writer();
switch (msg) {
.src => |src| {
+ try stderr.writeByteNTimes(' ', indent);
ttyconf.setColor(stderr, .Bold);
try stderr.print("{s}:{d}:{d}: ", .{
src.src_path,
@@ -349,7 +350,6 @@ pub const AllErrors = struct {
src.column + 1,
});
ttyconf.setColor(stderr, color);
- try stderr.writeByteNTimes(' ', indent);
try stderr.writeAll(kind);
ttyconf.setColor(stderr, .Reset);
ttyconf.setColor(stderr, .Bold);
@@ -731,6 +731,7 @@ fn addPackageTableToCacheHash(
hash: *Cache.HashHelper,
arena: *std.heap.ArenaAllocator,
pkg_table: Package.Table,
+ seen_table: *std.AutoHashMap(*Package, void),
hash_type: union(enum) { path_bytes, files: *Cache.Manifest },
) (error{OutOfMemory} || std.os.GetCwdError)!void {
const allocator = &arena.allocator;
@@ -755,6 +756,8 @@ fn addPackageTableToCacheHash(
}.lessThan);
for (packages) |pkg| {
+ if ((try seen_table.getOrPut(pkg.value)).found_existing) continue;
+
// Finally insert the package name and path to the cache hash.
hash.addBytes(pkg.key);
switch (hash_type) {
@@ -770,7 +773,7 @@ fn addPackageTableToCacheHash(
},
}
// 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);
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(single_threaded);
@@ -1137,36 +1141,32 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation {
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(
- gpa,
- zig_cache_artifact_directory,
- null,
- "builtin.zig",
- );
- errdefer builtin_pkg.destroy(gpa);
+ const builtin_pkg = try Package.createWithDir(
+ gpa,
+ zig_cache_artifact_directory,
+ null,
+ "builtin.zig",
+ );
+ errdefer builtin_pkg.destroy(gpa);
- const std_pkg = try Package.createWithDir(
- gpa,
- options.zig_lib_directory,
- "std",
- "std.zig",
- );
- errdefer std_pkg.destroy(gpa);
+ const std_pkg = try Package.createWithDir(
+ gpa,
+ options.zig_lib_directory,
+ "std",
+ "std.zig",
+ );
+ errdefer std_pkg.destroy(gpa);
- try root_pkg.addAndAdopt(gpa, "builtin", builtin_pkg);
- try root_pkg.add(gpa, "root", root_pkg);
- try root_pkg.addAndAdopt(gpa, "std", std_pkg);
+ try root_pkg.addAndAdopt(gpa, "builtin", builtin_pkg);
+ try root_pkg.add(gpa, "root", root_pkg);
+ try root_pkg.addAndAdopt(gpa, "std", std_pkg);
- try std_pkg.add(gpa, "builtin", builtin_pkg);
- try std_pkg.add(gpa, "root", root_pkg);
- try std_pkg.add(gpa, "std", std_pkg);
+ try std_pkg.add(gpa, "builtin", builtin_pkg);
+ try std_pkg.add(gpa, "root", root_pkg);
+ try std_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, "std", std_pkg);
+ try builtin_pkg.add(gpa, "builtin", builtin_pkg);
// Pre-open the directory handles for cached ZIR code so that it does not need
// to redundantly happen for each AstGen operation.
@@ -1625,30 +1625,31 @@ pub fn update(self: *Compilation) !void {
// Add a Job for each C object.
try self.c_object_work_queue.ensureUnusedCapacity(self.c_object_table.count());
for (self.c_object_table.keys()) |key| {
- assert(@ptrToInt(key) != 0xaaaa_aaaa_aaaa_aaaa);
self.c_object_work_queue.writeItemAssumeCapacity(key);
}
const use_stage1 = build_options.omit_stage2 or
(build_options.is_stage1 and self.bin_file.options.use_llvm);
- if (!use_stage1) {
- if (self.bin_file.options.module) |module| {
- module.compile_log_text.shrinkAndFree(module.gpa, 0);
- module.generation += 1;
-
- // Make sure std.zig is inside the import_table. We unconditionally need
- // it for start.zig.
- const std_pkg = module.root_pkg.table.get("std").?;
- _ = try module.importPkg(std_pkg);
-
- // 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
- // to update it.
- try self.astgen_work_queue.ensureUnusedCapacity(module.import_table.count());
- for (module.import_table.values()) |value| {
- self.astgen_work_queue.writeItemAssumeCapacity(value);
- }
+ if (self.bin_file.options.module) |module| {
+ module.compile_log_text.shrinkAndFree(module.gpa, 0);
+ module.generation += 1;
+
+ // Make sure std.zig is inside the import_table. We unconditionally need
+ // it for start.zig.
+ const std_pkg = module.root_pkg.table.get("std").?;
+ _ = try module.importPkg(std_pkg);
+
+ // 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
+ // 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());
+ for (module.import_table.values()) |value| {
+ self.astgen_work_queue.writeItemAssumeCapacity(value);
+ }
+ if (!use_stage1) {
try self.work_queue.writeItem(.{ .analyze_pkg = std_pkg });
}
}
@@ -1936,7 +1937,6 @@ pub fn performAllTheWork(self: *Compilation) error{ TimerUnsupported, OutOfMemor
}
while (self.c_object_work_queue.readItem()) |c_object| {
- assert(@ptrToInt(c_object) != 0xaaaa_aaaa_aaaa_aaaa);
self.work_queue_wait_group.start();
try self.thread_pool.spawn(workerUpdateCObject, .{
self, c_object, &c_obj_prog_node, &self.work_queue_wait_group,
@@ -3830,9 +3830,8 @@ fn updateStage1Module(comp: *Compilation, main_progress_node: *std.Progress.Node
_ = try man.addFile(main_zig_file, null);
{
- var local_arena = std.heap.ArenaAllocator.init(comp.gpa);
- defer local_arena.deinit();
- try addPackageTableToCacheHash(&man.hash, &local_arena, mod.root_pkg.table, .{ .files = &man });
+ var seen_table = std.AutoHashMap(*Package, void).init(&arena_allocator.allocator);
+ try addPackageTableToCacheHash(&man.hash, &arena_allocator, mod.root_pkg.table, &seen_table, .{ .files = &man });
}
man.hash.add(comp.bin_file.options.valgrind);
man.hash.add(comp.bin_file.options.single_threaded);
@@ -4103,6 +4102,12 @@ fn createStage1Pkg(
var children = std.ArrayList(*stage1.Pkg).init(arena);
var it = pkg.table.iterator();
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));
}
break :blk children.items;
From 96ebf9396f31c8645a2d0f064f211a25796f4c3e Mon Sep 17 00:00:00 2001
From: Andrew Kelley
Date: Mon, 21 Jun 2021 19:06:33 -0700
Subject: [PATCH 02/15] ci: no need for --ast-check
since zig will now run AstGen even when using the stage1 backend.
---
ci/azure/linux_script | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/ci/azure/linux_script b/ci/azure/linux_script
index 33c44c51e06c..33ad349044ce 100755
--- a/ci/azure/linux_script
+++ b/ci/azure/linux_script
@@ -59,9 +59,9 @@ unset CXX
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.
-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
# build zig1.o rather than relying on the one built with stage0. See
From c3f637a54cbb36c5dd6ec9e772ddc0930316d790 Mon Sep 17 00:00:00 2001
From: Andrew Kelley
Date: Tue, 22 Jun 2021 12:11:28 -0700
Subject: [PATCH 03/15] cmake: debug builds of zig enable logging by default
when logging is enabled, the --debug-log flag is available.
---
CMakeLists.txt | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/CMakeLists.txt b/CMakeLists.txt
index a2bf856b9c83..bc946e2a348a 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -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_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_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")
set(ZIG_USE_LLVM_CONFIG ON CACHE BOOL "use llvm-config to find LLVM libraries")
From 6fb45807abab49982c12b71112e9acb39cf94270 Mon Sep 17 00:00:00 2001
From: Andrew Kelley
Date: Tue, 22 Jun 2021 12:17:24 -0700
Subject: [PATCH 04/15] progress bar: call it "AST Lowering" instead of
"AstGen"
---
src/Compilation.zig | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/Compilation.zig b/src/Compilation.zig
index 57320109da83..93146338f5fd 100644
--- a/src/Compilation.zig
+++ b/src/Compilation.zig
@@ -1916,7 +1916,7 @@ pub fn performAllTheWork(self: *Compilation) error{ TimerUnsupported, OutOfMemor
// (at least for now) single-threaded main work queue. However, C object compilation
// 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();
var c_obj_prog_node = main_progress_node.start("Compile C Objects", self.c_source_files.len);
From 150515f44db9cecbda31d579861dc6f6080c2f75 Mon Sep 17 00:00:00 2001
From: Andrew Kelley
Date: Tue, 22 Jun 2021 16:11:02 -0700
Subject: [PATCH 05/15] stage2: slightly improve error reporting for missing
imports
There is now a distinction between `@import` with a .zig extension and
without. Without a .zig extension it assumes it is a package name, and
returns error.PackageNotFound if not mapped into the package table.
---
src/Compilation.zig | 21 +++++++++++++++++----
src/Module.zig | 3 +++
src/codegen/x86_64.zig | 1 -
3 files changed, 20 insertions(+), 5 deletions(-)
diff --git a/src/Compilation.zig b/src/Compilation.zig
index 93146338f5fd..ef04ebe27673 100644
--- a/src/Compilation.zig
+++ b/src/Compilation.zig
@@ -2319,6 +2319,9 @@ fn workerAstGenFile(
break :blk mod.importFile(file, import_path) catch continue;
};
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();
comp.thread_pool.spawn(workerAstGenFile, .{
comp, import_result.file, prog_node, wg,
@@ -2540,13 +2543,23 @@ fn reportRetryableAstGenError(
file.status = .retryable_failure;
- const err_msg = try Module.ErrorMsg.create(gpa, .{
+ const src_loc: Module.SrcLoc = .{
.file_scope = file,
.parent_decl_node = 0,
.lazy = .entire_file,
- }, "unable to load {s}: {s}", .{
- file.sub_file_path, @errorName(err),
- });
+ };
+
+ 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),
+ });
errdefer err_msg.destroy(gpa);
{
diff --git a/src/Module.zig b/src/Module.zig
index 5e9438264841..e168f6aac786 100644
--- a/src/Module.zig
+++ b/src/Module.zig
@@ -3185,6 +3185,9 @@ pub fn importFile(
if (cur_file.pkg.table.get(import_string)) |pkg| {
return mod.importPkg(pkg);
}
+ if (!mem.endsWith(u8, import_string, ".zig")) {
+ return error.PackageNotFound;
+ }
const gpa = mod.gpa;
// The resolved path is used as the key in the import table, to detect if
diff --git a/src/codegen/x86_64.zig b/src/codegen/x86_64.zig
index 0e1ffefe7581..2964d7245e18 100644
--- a/src/codegen/x86_64.zig
+++ b/src/codegen/x86_64.zig
@@ -4,7 +4,6 @@ const mem = std.mem;
const assert = std.debug.assert;
const ArrayList = std.ArrayList;
const Allocator = std.mem.Allocator;
-const Type = @import("../Type.zig");
const DW = std.dwarf;
// zig fmt: off
From af40e3f54c12857bb5ac541f8a3e1a9b5f93a626 Mon Sep 17 00:00:00 2001
From: Andrew Kelley
Date: Tue, 22 Jun 2021 16:14:03 -0700
Subject: [PATCH 06/15] stage2: glue code to AstGen root source file when using
stage1
Normally we rely on importing std to in turn import the root
in the start code, but when using the stage1 won't happen,
so in order to run AstGen on the root we put it into the
import_table here.
---
src/Compilation.zig | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/src/Compilation.zig b/src/Compilation.zig
index ef04ebe27673..93990b052853 100644
--- a/src/Compilation.zig
+++ b/src/Compilation.zig
@@ -1639,6 +1639,14 @@ pub fn update(self: *Compilation) !void {
const std_pkg = module.root_pkg.table.get("std").?;
_ = 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
// it changed, and, if so, re-compute ZIR and then queue the job
// to update it.
From 189fc964f749eeb83f184fa497438cb06e0008a0 Mon Sep 17 00:00:00 2001
From: Andrew Kelley
Date: Tue, 22 Jun 2021 16:26:56 -0700
Subject: [PATCH 07/15] fix unused parameters in compare_output test cases
---
test/compare_output.zig | 18 ++++++++++++++++--
1 file changed, 16 insertions(+), 2 deletions(-)
diff --git a/test/compare_output.zig b/test/compare_output.zig
index b6d333a07320..742e43e6c7fc 100644
--- a/test/compare_output.zig
+++ b/test/compare_output.zig
@@ -10,6 +10,8 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
\\ @cInclude("stdio.h");
\\});
\\pub export fn main(argc: c_int, argv: [*][*]u8) c_int {
+ \\ _ = argc;
+ \\ _ = argv;
\\ _ = c.puts("Hello, world!");
\\ return 0;
\\}
@@ -143,6 +145,8 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
\\});
\\
\\pub export fn main(argc: c_int, argv: [*][*]u8) c_int {
+ \\ _ = argc;
+ \\ _ = argv;
\\ if (is_windows) {
\\ // we want actual \n, not \r\n
\\ _ = c._setmode(1, c._O_BINARY);
@@ -265,8 +269,10 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
\\const y : u16 = 5678;
\\pub fn main() void {
\\ var x_local : i32 = print_ok(x);
+ \\ _ = x_local;
\\}
\\fn print_ok(val: @TypeOf(x)) @TypeOf(foo) {
+ \\ _ = val;
\\ const stdout = io.getStdOut().writer();
\\ stdout.print("OK\n", .{}) catch unreachable;
\\ return 0;
@@ -318,6 +324,8 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
\\});
\\
\\pub export fn main(argc: c_int, argv: [*][*]u8) c_int {
+ \\ _ = argc;
+ \\ _ = argv;
\\ if (is_windows) {
\\ // we want actual \n, not \r\n
\\ _ = c._setmode(1, c._O_BINARY);
@@ -337,13 +345,19 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
\\const Foo = struct {
\\ field1: Bar,
\\
- \\ fn method(a: *const Foo) bool { return true; }
+ \\ fn method(a: *const Foo) bool {
+ \\ _ = a;
+ \\ return true;
+ \\ }
\\};
\\
\\const Bar = struct {
\\ field2: i32,
\\
- \\ fn method(b: *const Bar) bool { return true; }
+ \\ fn method(b: *const Bar) bool {
+ \\ _ = b;
+ \\ return true;
+ \\ }
\\};
\\
\\pub fn main() void {
From 3a4a710894698f589a9f1a0f6fcc7517aec532cb Mon Sep 17 00:00:00 2001
From: Andrew Kelley
Date: Tue, 22 Jun 2021 16:50:31 -0700
Subject: [PATCH 08/15] update godbolt test case for unused parameter
---
test/cli.zig | 2 ++
1 file changed, 2 insertions(+)
diff --git a/test/cli.zig b/test/cli.zig
index 556452f832ee..e3a00fe735ad 100644
--- a/test/cli.zig
+++ b/test/cli.zig
@@ -116,6 +116,8 @@ fn testGodboltApi(zig_exe: []const u8, dir_path: []const u8) anyerror!void {
\\}
\\extern fn zig_panic() noreturn;
\\pub fn panic(msg: []const u8, error_return_trace: ?*@import("std").builtin.StackTrace) noreturn {
+ \\ _ = msg;
+ \\ _ = error_return_trace;
\\ zig_panic();
\\}
);
From 84fe5d46817712f9d17f5a2197de577a453b3e62 Mon Sep 17 00:00:00 2001
From: Andrew Kelley
Date: Tue, 22 Jun 2021 16:50:55 -0700
Subject: [PATCH 09/15] fix unused variable errors in runtime safety test cases
---
test/runtime_safety.zig | 165 ++++++++++++++++++++++++++++++++++++++--
1 file changed, 160 insertions(+), 5 deletions(-)
diff --git a/test/runtime_safety.zig b/test/runtime_safety.zig
index 16286e0a56cc..6d68a2e1ddcc 100644
--- a/test/runtime_safety.zig
+++ b/test/runtime_safety.zig
@@ -4,6 +4,7 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
{
const check_panic_msg =
\\pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn {
+ \\ _ = stack_trace;
\\ if (std.mem.eql(u8, message, "reached unreachable code")) {
\\ std.process.exit(126); // good
\\ }
@@ -45,6 +46,7 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
{
const check_panic_msg =
\\pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn {
+ \\ _ = stack_trace;
\\ if (std.mem.eql(u8, message, "invalid enum value")) {
\\ std.process.exit(126); // good
\\ }
@@ -62,6 +64,7 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
\\ var e: E = undefined;
\\ @memset(@ptrCast([*]u8, &e), 0x55, @sizeOf(E));
\\ var n = @tagName(e);
+ \\ _ = n;
\\}
);
@@ -76,6 +79,7 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
\\ @memset(@ptrCast([*]u8, &u), 0x55, @sizeOf(U));
\\ var t: @typeInfo(U).Union.tag_type.? = u;
\\ var n = @tagName(t);
+ \\ _ = n;
\\}
);
}
@@ -83,6 +87,7 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
{
const check_panic_msg =
\\pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn {
+ \\ _ = stack_trace;
\\ if (std.mem.eql(u8, message, "index out of bounds")) {
\\ std.process.exit(126); // good
\\ }
@@ -96,6 +101,7 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
\\pub fn main() void {
\\ var buf = [4]u8{'a','b','c',0};
\\ const slice = buf[0..4 :0];
+ \\ _ = slice;
\\}
);
cases.addRuntimeSafety("slicing operator with sentinel",
@@ -104,6 +110,7 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
\\pub fn main() void {
\\ var buf = [4]u8{'a','b','c',0};
\\ const slice = buf[0..:0];
+ \\ _ = slice;
\\}
);
cases.addRuntimeSafety("slicing operator with sentinel",
@@ -112,6 +119,7 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
\\pub fn main() void {
\\ var buf_zero = [0]u8{};
\\ const slice = buf_zero[0..0 :0];
+ \\ _ = slice;
\\}
);
cases.addRuntimeSafety("slicing operator with sentinel",
@@ -120,6 +128,7 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
\\pub fn main() void {
\\ var buf_zero = [0]u8{};
\\ const slice = buf_zero[0..:0];
+ \\ _ = slice;
\\}
);
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'};
\\ @ptrCast(*[3]u8, &buf_sentinel)[2] = 0;
\\ const slice = buf_sentinel[0..3 :0];
+ \\ _ = slice;
\\}
);
cases.addRuntimeSafety("slicing operator with sentinel",
@@ -137,6 +147,7 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
\\pub fn main() void {
\\ var buf_slice: []const u8 = &[3]u8{ 'a', 'b', 0 };
\\ const slice = buf_slice[0..3 :0];
+ \\ _ = slice;
\\}
);
cases.addRuntimeSafety("slicing operator with sentinel",
@@ -145,6 +156,7 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
\\pub fn main() void {
\\ var buf_slice: []const u8 = &[3]u8{ 'a', 'b', 0 };
\\ const slice = buf_slice[0.. :0];
+ \\ _ = slice;
\\}
);
}
@@ -153,6 +165,7 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
\\const std = @import("std");
\\const V = @import("std").meta.Vector;
\\pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn {
+ \\ _ = stack_trace;
\\ if (std.mem.eql(u8, message, "integer cast truncated bits")) {
\\ std.process.exit(126); // good
\\ }
@@ -161,6 +174,7 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
\\pub fn main() void {
\\ var x = @splat(4, @as(u32, 0xdeadbeef));
\\ var y = @intCast(V(4, u16), x);
+ \\ _ = y;
\\}
);
@@ -168,6 +182,7 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
\\const std = @import("std");
\\const V = @import("std").meta.Vector;
\\pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn {
+ \\ _ = stack_trace;
\\ if (std.mem.eql(u8, message, "integer cast truncated bits")) {
\\ std.process.exit(126); // good
\\ }
@@ -176,6 +191,7 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
\\pub fn main() void {
\\ var x = @splat(4, @as(u32, 0x80000000));
\\ var y = @intCast(V(4, i32), x);
+ \\ _ = y;
\\}
);
@@ -183,6 +199,7 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
\\const std = @import("std");
\\const V = @import("std").meta.Vector;
\\pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn {
+ \\ _ = stack_trace;
\\ if (std.mem.eql(u8, message, "attempt to cast negative value to unsigned integer")) {
\\ std.process.exit(126); // good
\\ }
@@ -191,12 +208,14 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
\\pub fn main() void {
\\ var x = @splat(4, @as(i32, -2147483647));
\\ var y = @intCast(V(4, u32), x);
+ \\ _ = y;
\\}
);
cases.addRuntimeSafety("shift left by huge amount",
\\const std = @import("std");
\\pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn {
+ \\ _ = stack_trace;
\\ if (std.mem.eql(u8, message, "shift amount is greater than the type size")) {
\\ std.process.exit(126); // good
\\ }
@@ -206,12 +225,14 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
\\ var x: u24 = 42;
\\ var y: u5 = 24;
\\ var z = x >> y;
+ \\ _ = z;
\\}
);
cases.addRuntimeSafety("shift right by huge amount",
\\const std = @import("std");
\\pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn {
+ \\ _ = stack_trace;
\\ if (std.mem.eql(u8, message, "shift amount is greater than the type size")) {
\\ std.process.exit(126); // good
\\ }
@@ -221,12 +242,14 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
\\ var x: u24 = 42;
\\ var y: u5 = 24;
\\ var z = x << y;
+ \\ _ = z;
\\}
);
cases.addRuntimeSafety("slice sentinel mismatch - optional pointers",
\\const std = @import("std");
\\pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn {
+ \\ _ = stack_trace;
\\ if (std.mem.eql(u8, message, "sentinel mismatch")) {
\\ std.process.exit(126); // good
\\ }
@@ -235,12 +258,14 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
\\pub fn main() void {
\\ var buf: [4]?*i32 = undefined;
\\ const slice = buf[0..3 :null];
+ \\ _ = slice;
\\}
);
cases.addRuntimeSafety("slice sentinel mismatch - floats",
\\const std = @import("std");
\\pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn {
+ \\ _ = stack_trace;
\\ if (std.mem.eql(u8, message, "sentinel mismatch")) {
\\ std.process.exit(126); // good
\\ }
@@ -249,12 +274,14 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
\\pub fn main() void {
\\ var buf: [4]f32 = undefined;
\\ const slice = buf[0..3 :1.2];
+ \\ _ = slice;
\\}
);
cases.addRuntimeSafety("pointer slice sentinel mismatch",
\\const std = @import("std");
\\pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn {
+ \\ _ = stack_trace;
\\ if (std.mem.eql(u8, message, "sentinel mismatch")) {
\\ std.process.exit(126); // good
\\ }
@@ -264,12 +291,14 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
\\ var buf: [4]u8 = undefined;
\\ const ptr: [*]u8 = &buf;
\\ const slice = ptr[0..3 :0];
+ \\ _ = slice;
\\}
);
cases.addRuntimeSafety("slice slice sentinel mismatch",
\\const std = @import("std");
\\pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn {
+ \\ _ = stack_trace;
\\ if (std.mem.eql(u8, message, "sentinel mismatch")) {
\\ std.process.exit(126); // good
\\ }
@@ -279,12 +308,14 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
\\ var buf: [4]u8 = undefined;
\\ const slice = buf[0..];
\\ const slice2 = slice[0..3 :0];
+ \\ _ = slice2;
\\}
);
cases.addRuntimeSafety("array slice sentinel mismatch",
\\const std = @import("std");
\\pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn {
+ \\ _ = stack_trace;
\\ if (std.mem.eql(u8, message, "sentinel mismatch")) {
\\ std.process.exit(126); // good
\\ }
@@ -293,12 +324,14 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
\\pub fn main() void {
\\ var buf: [4]u8 = undefined;
\\ const slice = buf[0..3 :0];
+ \\ _ = slice;
\\}
);
cases.addRuntimeSafety("intToPtr with misaligned address",
\\const std = @import("std");
\\pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn {
+ \\ _ = stack_trace;
\\ if (std.mem.eql(u8, message, "incorrect alignment")) {
\\ std.os.exit(126); // good
\\ }
@@ -307,16 +340,20 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
\\pub fn main() void {
\\ var x: usize = 5;
\\ var y = @intToPtr([*]align(4) u8, x);
+ \\ _ = y;
\\}
);
cases.addRuntimeSafety("resuming a non-suspended function which never been suspended",
\\const std = @import("std");
\\pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn {
+ \\ _ = message;
+ \\ _ = stack_trace;
\\ std.os.exit(126);
\\}
\\fn foo() void {
\\ var f = async bar(@frame());
+ \\ _ = f;
\\ 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",
\\const std = @import("std");
\\pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn {
+ \\ _ = message;
+ \\ _ = stack_trace;
\\ std.os.exit(126);
\\}
\\fn foo() void {
@@ -342,6 +381,7 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
\\ global_frame = @frame();
\\ }
\\ var f = async bar(@frame());
+ \\ _ = f;
\\ std.os.exit(0);
\\}
\\
@@ -363,6 +403,8 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
cases.addRuntimeSafety("nosuspend function call, callee suspends",
\\const std = @import("std");
\\pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn {
+ \\ _ = message;
+ \\ _ = stack_trace;
\\ std.os.exit(126);
\\}
\\pub fn main() void {
@@ -379,6 +421,8 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
cases.addRuntimeSafety("awaiting twice",
\\const std = @import("std");
\\pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn {
+ \\ _ = message;
+ \\ _ = stack_trace;
\\ std.os.exit(126);
\\}
\\var frame: anyframe = undefined;
@@ -404,12 +448,15 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
cases.addRuntimeSafety("@asyncCall with too small a frame",
\\const std = @import("std");
\\pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn {
+ \\ _ = message;
+ \\ _ = stack_trace;
\\ std.os.exit(126);
\\}
\\pub fn main() void {
\\ var bytes: [1]u8 align(16) = undefined;
\\ var ptr = other;
\\ var frame = @asyncCall(&bytes, {}, ptr, .{});
+ \\ _ = frame;
\\}
\\fn other() callconv(.Async) void {
\\ suspend {}
@@ -419,6 +466,8 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
cases.addRuntimeSafety("resuming a function which is awaiting a frame",
\\const std = @import("std");
\\pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn {
+ \\ _ = message;
+ \\ _ = stack_trace;
\\ std.os.exit(126);
\\}
\\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",
\\const std = @import("std");
\\pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn {
+ \\ _ = message;
+ \\ _ = stack_trace;
\\ std.os.exit(126);
\\}
\\pub fn main() void {
@@ -454,6 +505,8 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
cases.addRuntimeSafety("invalid resume of async function",
\\const std = @import("std");
\\pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn {
+ \\ _ = message;
+ \\ _ = stack_trace;
\\ std.os.exit(126);
\\}
\\pub fn main() void {
@@ -469,61 +522,78 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
cases.addRuntimeSafety(".? operator on null pointer",
\\const std = @import("std");
\\pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn {
+ \\ _ = message;
+ \\ _ = stack_trace;
\\ std.os.exit(126);
\\}
\\pub fn main() void {
\\ var ptr: ?*i32 = null;
\\ var b = ptr.?;
+ \\ _ = b;
\\}
);
cases.addRuntimeSafety(".? operator on C pointer",
\\const std = @import("std");
\\pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn {
+ \\ _ = message;
+ \\ _ = stack_trace;
\\ std.os.exit(126);
\\}
\\pub fn main() void {
\\ var ptr: [*c]i32 = null;
\\ var b = ptr.?;
+ \\ _ = b;
\\}
);
cases.addRuntimeSafety("@intToPtr address zero to non-optional pointer",
\\const std = @import("std");
\\pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn {
+ \\ _ = message;
+ \\ _ = stack_trace;
\\ std.os.exit(126);
\\}
\\pub fn main() void {
\\ var zero: usize = 0;
\\ var b = @intToPtr(*i32, zero);
+ \\ _ = b;
\\}
);
cases.addRuntimeSafety("@intToPtr address zero to non-optional byte-aligned pointer",
\\const std = @import("std");
\\pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn {
+ \\ _ = message;
+ \\ _ = stack_trace;
\\ std.os.exit(126);
\\}
\\pub fn main() void {
\\ var zero: usize = 0;
\\ var b = @intToPtr(*u8, zero);
+ \\ _ = b;
\\}
);
cases.addRuntimeSafety("pointer casting null to non-optional pointer",
\\const std = @import("std");
\\pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn {
+ \\ _ = message;
+ \\ _ = stack_trace;
\\ std.os.exit(126);
\\}
\\pub fn main() void {
\\ var c_ptr: [*c]u8 = 0;
\\ var zig_ptr: *u8 = c_ptr;
+ \\ _ = zig_ptr;
\\}
);
cases.addRuntimeSafety("@intToEnum - no matching tag value",
\\const std = @import("std");
\\pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn {
+ \\ _ = message;
+ \\ _ = stack_trace;
\\ std.os.exit(126);
\\}
\\const Foo = enum {
@@ -537,12 +607,14 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
\\fn bar(a: u2) Foo {
\\ return @intToEnum(Foo, a);
\\}
- \\fn baz(a: Foo) void {}
+ \\fn baz(_: Foo) void {}
);
cases.addRuntimeSafety("@floatToInt cannot fit - negative to unsigned",
\\const std = @import("std");
\\pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn {
+ \\ _ = message;
+ \\ _ = stack_trace;
\\ std.os.exit(126);
\\}
\\pub fn main() void {
@@ -551,12 +623,14 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
\\fn bar(a: f32) u8 {
\\ return @floatToInt(u8, a);
\\}
- \\fn baz(a: u8) void { }
+ \\fn baz(_: u8) void { }
);
cases.addRuntimeSafety("@floatToInt cannot fit - negative out of range",
\\const std = @import("std");
\\pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn {
+ \\ _ = message;
+ \\ _ = stack_trace;
\\ std.os.exit(126);
\\}
\\pub fn main() void {
@@ -565,12 +639,14 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
\\fn bar(a: f32) i8 {
\\ return @floatToInt(i8, a);
\\}
- \\fn baz(a: i8) void { }
+ \\fn baz(_: i8) void { }
);
cases.addRuntimeSafety("@floatToInt cannot fit - positive out of range",
\\const std = @import("std");
\\pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn {
+ \\ _ = message;
+ \\ _ = stack_trace;
\\ std.os.exit(126);
\\}
\\pub fn main() void {
@@ -579,12 +655,14 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
\\fn bar(a: f32) u8 {
\\ return @floatToInt(u8, a);
\\}
- \\fn baz(a: u8) void { }
+ \\fn baz(_: u8) void { }
);
cases.addRuntimeSafety("calling panic",
\\const std = @import("std");
\\pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn {
+ \\ _ = message;
+ \\ _ = stack_trace;
\\ std.os.exit(126);
\\}
\\pub fn main() void {
@@ -595,6 +673,8 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
cases.addRuntimeSafety("out of bounds slice access",
\\const std = @import("std");
\\pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn {
+ \\ _ = message;
+ \\ _ = stack_trace;
\\ std.os.exit(126);
\\}
\\pub fn main() void {
@@ -604,12 +684,14 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
\\fn bar(a: []const i32) i32 {
\\ return a[4];
\\}
- \\fn baz(a: i32) void { }
+ \\fn baz(_: i32) void { }
);
cases.addRuntimeSafety("integer addition overflow",
\\const std = @import("std");
\\pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn {
+ \\ _ = message;
+ \\ _ = stack_trace;
\\ std.os.exit(126);
\\}
\\pub fn main() !void {
@@ -624,12 +706,15 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
cases.addRuntimeSafety("vector integer addition overflow",
\\const std = @import("std");
\\pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn {
+ \\ _ = message;
+ \\ _ = stack_trace;
\\ std.os.exit(126);
\\}
\\pub fn main() void {
\\ var a: std.meta.Vector(4, i32) = [_]i32{ 1, 2, 2147483643, 4 };
\\ var b: std.meta.Vector(4, i32) = [_]i32{ 5, 6, 7, 8 };
\\ 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) {
\\ return a + b;
@@ -639,12 +724,15 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
cases.addRuntimeSafety("vector integer subtraction overflow",
\\const std = @import("std");
\\pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn {
+ \\ _ = message;
+ \\ _ = stack_trace;
\\ std.os.exit(126);
\\}
\\pub fn main() void {
\\ var a: std.meta.Vector(4, u32) = [_]u32{ 1, 2, 8, 4 };
\\ var b: std.meta.Vector(4, u32) = [_]u32{ 5, 6, 7, 8 };
\\ 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) {
\\ return a - b;
@@ -654,12 +742,15 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
cases.addRuntimeSafety("vector integer multiplication overflow",
\\const std = @import("std");
\\pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn {
+ \\ _ = message;
+ \\ _ = stack_trace;
\\ std.os.exit(126);
\\}
\\pub fn main() void {
\\ var a: std.meta.Vector(4, u8) = [_]u8{ 1, 2, 200, 4 };
\\ var b: std.meta.Vector(4, u8) = [_]u8{ 5, 6, 2, 8 };
\\ 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) {
\\ return a * b;
@@ -669,11 +760,14 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
cases.addRuntimeSafety("vector integer negation overflow",
\\const std = @import("std");
\\pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn {
+ \\ _ = message;
+ \\ _ = stack_trace;
\\ std.os.exit(126);
\\}
\\pub fn main() void {
\\ var a: std.meta.Vector(4, i16) = [_]i16{ 1, -32768, 200, 4 };
\\ const x = neg(a);
+ \\ _ = x;
\\}
\\fn neg(a: std.meta.Vector(4, i16)) std.meta.Vector(4, i16) {
\\ return -a;
@@ -683,6 +777,8 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
cases.addRuntimeSafety("integer subtraction overflow",
\\const std = @import("std");
\\pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn {
+ \\ _ = message;
+ \\ _ = stack_trace;
\\ std.os.exit(126);
\\}
\\pub fn main() !void {
@@ -697,6 +793,8 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
cases.addRuntimeSafety("integer multiplication overflow",
\\const std = @import("std");
\\pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn {
+ \\ _ = message;
+ \\ _ = stack_trace;
\\ std.os.exit(126);
\\}
\\pub fn main() !void {
@@ -711,6 +809,8 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
cases.addRuntimeSafety("integer negation overflow",
\\const std = @import("std");
\\pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn {
+ \\ _ = message;
+ \\ _ = stack_trace;
\\ std.os.exit(126);
\\}
\\pub fn main() !void {
@@ -725,6 +825,8 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
cases.addRuntimeSafety("signed integer division overflow",
\\const std = @import("std");
\\pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn {
+ \\ _ = message;
+ \\ _ = stack_trace;
\\ std.os.exit(126);
\\}
\\pub fn main() !void {
@@ -739,6 +841,8 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
cases.addRuntimeSafety("signed integer division overflow - vectors",
\\const std = @import("std");
\\pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn {
+ \\ _ = message;
+ \\ _ = stack_trace;
\\ std.os.exit(126);
\\}
\\pub fn main() !void {
@@ -755,6 +859,8 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
cases.addRuntimeSafety("signed shift left overflow",
\\const std = @import("std");
\\pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn {
+ \\ _ = message;
+ \\ _ = stack_trace;
\\ std.os.exit(126);
\\}
\\pub fn main() !void {
@@ -769,6 +875,8 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
cases.addRuntimeSafety("unsigned shift left overflow",
\\const std = @import("std");
\\pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn {
+ \\ _ = message;
+ \\ _ = stack_trace;
\\ std.os.exit(126);
\\}
\\pub fn main() !void {
@@ -783,6 +891,8 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
cases.addRuntimeSafety("signed shift right overflow",
\\const std = @import("std");
\\pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn {
+ \\ _ = message;
+ \\ _ = stack_trace;
\\ std.os.exit(126);
\\}
\\pub fn main() !void {
@@ -797,6 +907,8 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
cases.addRuntimeSafety("unsigned shift right overflow",
\\const std = @import("std");
\\pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn {
+ \\ _ = message;
+ \\ _ = stack_trace;
\\ std.os.exit(126);
\\}
\\pub fn main() !void {
@@ -811,10 +923,13 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
cases.addRuntimeSafety("integer division by zero",
\\const std = @import("std");
\\pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn {
+ \\ _ = message;
+ \\ _ = stack_trace;
\\ std.os.exit(126);
\\}
\\pub fn main() void {
\\ const x = div0(999, 0);
+ \\ _ = x;
\\}
\\fn div0(a: i32, b: i32) i32 {
\\ return @divTrunc(a, b);
@@ -824,12 +939,15 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
cases.addRuntimeSafety("integer division by zero - vectors",
\\const std = @import("std");
\\pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn {
+ \\ _ = message;
+ \\ _ = stack_trace;
\\ std.os.exit(126);
\\}
\\pub fn main() void {
\\ 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};
\\ 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) {
\\ return @divTrunc(a, b);
@@ -839,6 +957,8 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
cases.addRuntimeSafety("exact division failure",
\\const std = @import("std");
\\pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn {
+ \\ _ = message;
+ \\ _ = stack_trace;
\\ std.os.exit(126);
\\}
\\pub fn main() !void {
@@ -853,12 +973,15 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
cases.addRuntimeSafety("exact division failure - vectors",
\\const std = @import("std");
\\pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn {
+ \\ _ = message;
+ \\ _ = stack_trace;
\\ std.os.exit(126);
\\}
\\pub fn main() !void {
\\ 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};
\\ 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) {
\\ 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",
\\const std = @import("std");
\\pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn {
+ \\ _ = message;
+ \\ _ = stack_trace;
\\ std.os.exit(126);
\\}
\\pub fn main() !void {
@@ -882,6 +1007,8 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
cases.addRuntimeSafety("value does not fit in shortening cast",
\\const std = @import("std");
\\pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn {
+ \\ _ = message;
+ \\ _ = stack_trace;
\\ std.os.exit(126);
\\}
\\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",
\\const std = @import("std");
\\pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn {
+ \\ _ = message;
+ \\ _ = stack_trace;
\\ std.os.exit(126);
\\}
\\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",
\\const std = @import("std");
\\pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn {
+ \\ _ = message;
+ \\ _ = stack_trace;
\\ std.os.exit(126);
\\}
\\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",
\\const std = @import("std");
\\pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn {
+ \\ _ = message;
+ \\ _ = stack_trace;
\\ std.os.exit(126);
\\}
\\pub fn main() void {
\\ var value: c_short = -1;
\\ var casted = @intCast(u32, value);
+ \\ _ = casted;
\\}
);
cases.addRuntimeSafety("unsigned integer not fitting in cast to signed integer - same bit count",
\\const std = @import("std");
\\pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn {
+ \\ _ = message;
+ \\ _ = stack_trace;
\\ std.os.exit(126);
\\}
\\pub fn main() void {
\\ var value: u8 = 245;
\\ var casted = @intCast(i8, value);
+ \\ _ = casted;
\\}
);
cases.addRuntimeSafety("unwrap error",
\\const std = @import("std");
\\pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn {
+ \\ _ = stack_trace;
\\ if (std.mem.eql(u8, message, "attempt to unwrap error: Whatever")) {
\\ std.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",
\\const std = @import("std");
\\pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn {
+ \\ _ = message;
+ \\ _ = stack_trace;
\\ std.os.exit(126);
\\}
\\pub fn main() void {
@@ -975,6 +1115,8 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
cases.addRuntimeSafety("@errSetCast error not present in destination",
\\const std = @import("std");
\\pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn {
+ \\ _ = message;
+ \\ _ = stack_trace;
\\ std.os.exit(126);
\\}
\\const Set1 = error{A, B};
@@ -990,6 +1132,8 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
cases.addRuntimeSafety("@alignCast misaligned",
\\const std = @import("std");
\\pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn {
+ \\ _ = message;
+ \\ _ = stack_trace;
\\ std.os.exit(126);
\\}
\\pub fn main() !void {
@@ -1007,6 +1151,8 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
cases.addRuntimeSafety("bad union field access",
\\const std = @import("std");
\\pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn {
+ \\ _ = message;
+ \\ _ = stack_trace;
\\ std.os.exit(126);
\\}
\\
@@ -1031,6 +1177,8 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
cases.addRuntimeSafety("@intCast to u0",
\\const std = @import("std");
\\pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn {
+ \\ _ = message;
+ \\ _ = stack_trace;
\\ std.os.exit(126);
\\}
\\
@@ -1040,6 +1188,7 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
\\
\\fn bar(one: u1, not_zero: i32) void {
\\ var x = one << @intCast(u0, not_zero);
+ \\ _ = x;
\\}
);
@@ -1049,6 +1198,8 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
\\const std = @import("std");
\\
\\pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn {
+ \\ _ = message;
+ \\ _ = stack_trace;
\\ std.os.exit(126);
\\}
\\
@@ -1058,6 +1209,7 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
\\ const p = nonFailing();
\\ resume p;
\\ const p2 = async printTrace(p);
+ \\ _ = p2;
\\}
\\
\\fn nonFailing() anyframe->anyerror!void {
@@ -1084,12 +1236,15 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
cases.addRuntimeSafety("slicing null C pointer",
\\const std = @import("std");
\\pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn {
+ \\ _ = message;
+ \\ _ = stack_trace;
\\ std.os.exit(126);
\\}
\\
\\pub fn main() void {
\\ var ptr: [*c]const u32 = null;
\\ var slice = ptr[0..3];
+ \\ _ = slice;
\\}
);
}
From 960932a4bf4f470e7a3f32b2d56035fc4b530ba8 Mon Sep 17 00:00:00 2001
From: Jacob G-W
Date: Wed, 23 Jun 2021 09:46:50 -0400
Subject: [PATCH 10/15] astgen: error on struct field with no type
---
src/AstGen.zig | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/src/AstGen.zig b/src/AstGen.zig
index c79d74fdd949..72839521fed3 100644
--- a/src/AstGen.zig
+++ b/src/AstGen.zig
@@ -3558,6 +3558,10 @@ fn structDeclInner(
const field_name = try astgen.identAsString(member.ast.name_token);
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")
.none
else
From 2beb21c4e4a59190c998e07596e323d5ace68a21 Mon Sep 17 00:00:00 2001
From: Andrew Kelley
Date: Wed, 23 Jun 2021 10:06:52 -0700
Subject: [PATCH 11/15] stage2: fix crash when using stage1 backend
Calling processOutdatedAndDeletedDecls() should not happen when using
the stage1 backend. Problem solved with checking a simple flag.
---
src/Compilation.zig | 10 +++++++---
1 file changed, 7 insertions(+), 3 deletions(-)
diff --git a/src/Compilation.zig b/src/Compilation.zig
index 93990b052853..ea878056ae7c 100644
--- a/src/Compilation.zig
+++ b/src/Compilation.zig
@@ -1952,9 +1952,13 @@ pub fn performAllTheWork(self: *Compilation) error{ TimerUnsupported, OutOfMemor
}
}
- // Iterate over all the files and look for outdated and deleted declarations.
- if (self.bin_file.options.module) |mod| {
- try mod.processOutdatedAndDeletedDecls();
+ 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.
+ if (self.bin_file.options.module) |mod| {
+ try mod.processOutdatedAndDeletedDecls();
+ }
}
while (self.work_queue.readItem()) |work_item| switch (work_item) {
From 8a5fb4c248272644b5db84a8e453b8d7051fafb0 Mon Sep 17 00:00:00 2001
From: Evan Haas
Date: Tue, 22 Jun 2021 21:24:13 -0700
Subject: [PATCH 12/15] translate-c: Ensure all local variables and function
params are used
---
src/translate_c.zig | 16 ++-
test/translate_c.zig | 229 +++++++++++++++++++++++++++++++++++++++++++
2 files changed, 244 insertions(+), 1 deletion(-)
diff --git a/src/translate_c.zig b/src/translate_c.zig
index 99adad51faa7..4e1fff5268c4 100644
--- a/src/translate_c.zig
+++ b/src/translate_c.zig
@@ -151,6 +151,12 @@ const Scope = struct {
return true;
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 {
@@ -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 });
try block_scope.statements.append(redecl_node);
}
+ try block_scope.discardVariable(c, mangled_param_name);
param_id += 1;
}
@@ -827,6 +834,7 @@ fn transTypeDef(c: *Context, scope: *Scope, typedef_decl: *const clang.TypedefNa
try addTopLevelDecl(c, name, node);
} else {
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 });
} else {
try scope.appendNode(Node.initPayload(&payload.base));
+ try bs.discardVariable(c, name);
}
}
@@ -1766,6 +1775,7 @@ fn transDeclStmtOne(
node = try Tag.static_local_var.create(c.arena, .{ .name = mangled_name, .init = node });
}
try block_scope.statements.append(node);
+ try block_scope.discardVariable(c, mangled_name);
const cleanup_attr = var_decl.getCleanupAttribute();
if (cleanup_attr) |fn_decl| {
@@ -4903,6 +4913,10 @@ fn transMacroDefine(c: *Context, m: *MacroCtx) ParseError!void {
const scope = &c.global_scope.base;
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().?;
if (last != .Eof and last != .Nl)
return m.fail(c, "unable to translate C expr: unexpected token .{s}", .{@tagName(last)});
@@ -4933,7 +4947,7 @@ fn transMacroFnDefine(c: *Context, m: *MacroCtx) ParseError!void {
.name = mangled_name,
.type = Tag.@"anytype".init(),
});
-
+ try block_scope.discardVariable(c, mangled_name);
if (m.peek().? != .Comma) break;
_ = m.next();
}
diff --git a/test/translate_c.zig b/test/translate_c.zig
index a6a652681c9b..b1ef771c679d 100644
--- a/test/translate_c.zig
+++ b/test/translate_c.zig
@@ -12,9 +12,11 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
, &[_][]const u8{
\\pub export fn foo(arg_x: c_ulong) c_ulong {
\\ var x = arg_x;
+ \\ _ = x;
\\ const union_unnamed_1 = extern union {
\\ _x: c_ulong,
\\ };
+ \\ _ = union_unnamed_1;
\\ return (union_unnamed_1{
\\ ._x = x,
\\ })._x;
@@ -54,8 +56,10 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\pub export fn foo() void {
\\ while (true) if (true) {
\\ var a: c_int = 1;
+ \\ _ = a;
\\ } else {
\\ var b: c_int = 2;
+ \\ _ = b;
\\ };
\\ if (true) if (true) {};
\\}
@@ -71,6 +75,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\pub extern fn bar(...) c_int;
\\pub export fn foo() void {
\\ var a: c_int = undefined;
+ \\ _ = a;
\\ if (a != 0) a = 2 else _ = bar();
\\}
});
@@ -123,22 +128,26 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\ B: c_int,
\\ C: c_int,
\\ };
+ \\ _ = struct_Foo;
\\ var a: struct_Foo = struct_Foo{
\\ .A = @as(c_int, 0),
\\ .B = 0,
\\ .C = 0,
\\ };
+ \\ _ = a;
\\ {
\\ const struct_Foo_1 = extern struct {
\\ A: c_int,
\\ B: c_int,
\\ C: c_int,
\\ };
+ \\ _ = struct_Foo_1;
\\ var a_2: struct_Foo_1 = struct_Foo_1{
\\ .A = @as(c_int, 0),
\\ .B = 0,
\\ .C = 0,
\\ };
+ \\ _ = a_2;
\\ }
\\}
});
@@ -167,20 +176,26 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\ B: c_int,
\\ C: c_int,
\\ };
+ \\ _ = union_unnamed_1;
\\ const Foo = union_unnamed_1;
+ \\ _ = Foo;
\\ var a: Foo = Foo{
\\ .A = @as(c_int, 0),
\\ };
+ \\ _ = a;
\\ {
\\ const union_unnamed_2 = extern union {
\\ A: c_int,
\\ B: c_int,
\\ C: c_int,
\\ };
+ \\ _ = union_unnamed_2;
\\ const Foo_1 = union_unnamed_2;
+ \\ _ = Foo_1;
\\ var a_2: Foo_1 = Foo_1{
\\ .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)
, &[_][]const u8{
\\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);
\\}
});
@@ -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 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));
\\}
});
@@ -246,6 +263,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\ const bar_1 = struct {
\\ threadlocal var static: c_int = 2;
\\ };
+ \\ _ = bar_1;
\\ return 0;
\\}
});
@@ -264,6 +282,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\}
\\pub export fn bar() c_int {
\\ var a: c_int = 2;
+ \\ _ = a;
\\ return 0;
\\}
\\pub export fn baz() c_int {
@@ -278,6 +297,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
, &[_][]const u8{
\\pub export fn main() void {
\\ 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 inline fn CLITERAL(type_1: anytype) @TypeOf(type_1) {
+ \\ _ = type_1;
\\ return type_1;
\\}
,
@@ -325,6 +346,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\};
,
\\pub inline fn A(_x: anytype) MyCStruct {
+ \\ _ = _x;
\\ return @import("std").mem.zeroInit(MyCStruct, .{
\\ .x = _x,
\\ });
@@ -355,6 +377,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\#define __ferror_unlocked_body(_fp) (((_fp)->_flags & _IO_ERR_SEEN) != 0)
, &[_][]const u8{
\\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);
\\}
});
@@ -364,6 +387,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\#define BAR 1 && 2 > 4
, &[_][]const u8{
\\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));
\\}
,
@@ -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))) {
+ \\ _ = x;
\\ return blk: {
\\ _ = &x;
\\ _ = @as(c_int, 3);
@@ -555,6 +580,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\};
\\pub export fn foo(arg_x: [*c]outer) void {
\\ var x = arg_x;
+ \\ _ = 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 export fn function(arg_opaque_1: ?*struct_opaque) void {
\\ var opaque_1 = arg_opaque_1;
+ \\ _ = 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 other_fn() void {
\\ var ARR: [16]u8 align(16) = undefined;
+ \\ _ = ARR;
\\}
});
@@ -708,11 +737,17 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
, &[_][]const u8{
\\pub export fn foo() void {
\\ var a: c_int = undefined;
+ \\ _ = a;
\\ var b: u8 = 123;
+ \\ _ = b;
\\ const c: c_int = undefined;
+ \\ _ = c;
\\ const d: c_uint = @bitCast(c_uint, @as(c_int, 440));
+ \\ _ = d;
\\ var e: c_int = 10;
+ \\ _ = e;
\\ var f: c_uint = 10;
+ \\ _ = f;
\\}
});
@@ -728,6 +763,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
, &[_][]const u8{
\\pub export fn foo() void {
\\ var a: c_int = undefined;
+ \\ _ = a;
\\ _ = @as(c_int, 1);
\\ _ = "hey";
\\ _ = @as(c_int, 1) + @as(c_int, 1);
@@ -771,6 +807,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\ const v2 = struct {
\\ 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 export fn bar() void {
\\ 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)));
+ \\ _ = typed_func_ptr;
\\}
});
@@ -842,8 +881,11 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
, &[_][]const u8{
\\pub export fn s() c_int {
\\ var a: c_int = undefined;
+ \\ _ = a;
\\ var b: c_int = undefined;
+ \\ _ = b;
\\ var c: c_int = undefined;
+ \\ _ = c;
\\ 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 {
\\ var a: c_uint = undefined;
+ \\ _ = a;
\\ var b: c_uint = undefined;
+ \\ _ = b;
\\ var c: c_uint = undefined;
+ \\ _ = c;
\\ 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 {
\\ var a: c_int = undefined;
\\ _ = a;
+ \\ _ = a;
\\}
});
@@ -1229,6 +1275,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
, &[_][]const u8{
\\pub export fn foo() ?*c_void {
\\ var x: [*c]c_ushort = undefined;
+ \\ _ = x;
\\ return @ptrCast(?*c_void, x);
\\}
});
@@ -1285,6 +1332,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\pub export fn foo() void {
\\ {
\\ var i: c_int = 0;
+ \\ _ = i;
\\ while (i != 0) : (i += 1) {}
\\ }
\\}
@@ -1308,6 +1356,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
, &[_][]const u8{
\\pub export fn foo() void {
\\ var i: c_int = undefined;
+ \\ _ = i;
\\ {
\\ i = 3;
\\ while (i != 0) : (i -= 1) {}
@@ -1351,6 +1400,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
, &[_][]const u8{
\\pub export fn ptrcast() [*c]f32 {
\\ var a: [*c]c_int = undefined;
+ \\ _ = 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{
\\pub export fn test_ptr_cast() void {
\\ var p: ?*c_void = undefined;
+ \\ _ = 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));
+ \\ _ = to_short;
\\ 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));
+ \\ _ = to_longlong;
\\ }
\\ {
\\ 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));
+ \\ _ = to_short;
\\ 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));
+ \\ _ = to_longlong;
\\ }
\\}
});
@@ -1402,8 +1461,11 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
, &[_][]const u8{
\\pub export fn while_none_bool() c_int {
\\ var a: c_int = undefined;
+ \\ _ = a;
\\ var b: f32 = undefined;
+ \\ _ = b;
\\ var c: ?*c_void = undefined;
+ \\ _ = c;
\\ while (a != 0) return 0;
\\ while (b != 0) return 1;
\\ while (c != null) return 2;
@@ -1424,8 +1486,11 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
, &[_][]const u8{
\\pub export fn for_none_bool() c_int {
\\ var a: c_int = undefined;
+ \\ _ = a;
\\ var b: f32 = undefined;
+ \\ _ = b;
\\ var c: ?*c_void = undefined;
+ \\ _ = c;
\\ while (a != 0) return 0;
\\ while (b != 0) return 1;
\\ while (c != null) return 2;
@@ -1462,6 +1527,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
, &[_][]const u8{
\\pub export fn foo() void {
\\ var x: [*c]c_int = undefined;
+ \\ _ = x;
\\ x.* = 1;
\\}
});
@@ -1475,7 +1541,9 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
, &[_][]const u8{
\\pub export fn foo() c_int {
\\ var x: c_int = 1234;
+ \\ _ = x;
\\ var ptr: [*c]c_int = &x;
+ \\ _ = ptr;
\\ return ptr.*;
\\}
});
@@ -1488,6 +1556,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
, &[_][]const u8{
\\pub export fn foo() c_int {
\\ var x: c_int = undefined;
+ \\ _ = x;
\\ return ~x;
\\}
});
@@ -1505,8 +1574,11 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
, &[_][]const u8{
\\pub export fn foo() c_int {
\\ var a: c_int = undefined;
+ \\ _ = a;
\\ var b: f32 = undefined;
+ \\ _ = b;
\\ var c: ?*c_void = undefined;
+ \\ _ = c;
\\ return @boolToInt(!(a == @as(c_int, 0)));
\\ return @boolToInt(!(a != 0));
\\ return @boolToInt(!(b != 0));
@@ -1628,9 +1700,11 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\ var arr: [10]u8 = [1]u8{
\\ 1,
\\ } ++ [1]u8{0} ** 9;
+ \\ _ = arr;
\\ var arr1: [10][*c]u8 = [1][*c]u8{
\\ null,
\\ } ++ [1][*c]u8{null} ** 9;
+ \\ _ = arr1;
\\}
});
@@ -1817,10 +1891,13 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\pub extern var c: c_int;
,
\\pub inline fn BASIC(c_1: anytype) @TypeOf(c_1 * @as(c_int, 2)) {
+ \\ _ = c_1;
\\ return c_1 * @as(c_int, 2);
\\}
,
\\pub inline fn FOO(L: anytype, b: anytype) @TypeOf(L + b) {
+ \\ _ = L;
+ \\ _ = b;
\\ return L + b;
\\}
,
@@ -1872,13 +1949,18 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\pub var c: c_int = 4;
\\pub export fn foo(arg_c_1: u8) void {
\\ var c_1 = arg_c_1;
+ \\ _ = c_1;
\\ var a_2: c_int = undefined;
+ \\ _ = a_2;
\\ var b_3: u8 = 123;
+ \\ _ = b_3;
\\ b_3 = @bitCast(u8, @truncate(i8, a_2));
\\ {
\\ var d: c_int = 5;
+ \\ _ = d;
\\ }
\\ 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{
\\pub export fn foo() void {
\\ var a: c_int = undefined;
+ \\ _ = a;
\\ var b: c_int = undefined;
+ \\ _ = b;
\\ a = blk: {
\\ const tmp = @as(c_int, 2);
\\ b = tmp;
@@ -1942,11 +2026,13 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
, &[_][]const u8{
\\pub export fn foo() c_int {
\\ var a: c_int = 5;
+ \\ _ = a;
\\ while (true) {
\\ a = 2;
\\ }
\\ while (true) {
\\ var a_1: c_int = 4;
+ \\ _ = a_1;
\\ a_1 = 9;
\\ return blk: {
\\ _ = @as(c_int, 6);
@@ -1955,6 +2041,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\ }
\\ while (true) {
\\ var a_1: c_int = 2;
+ \\ _ = a_1;
\\ a_1 = 12;
\\ }
\\ while (true) {
@@ -1976,9 +2063,12 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\pub export fn foo() void {
\\ {
\\ var i: c_int = 2;
+ \\ _ = i;
\\ var b: c_int = 4;
+ \\ _ = b;
\\ while ((i + @as(c_int, 2)) != 0) : (i = 2) {
\\ var a: c_int = 2;
+ \\ _ = a;
\\ _ = blk: {
\\ _ = blk_1: {
\\ a = 6;
@@ -1989,6 +2079,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\ }
\\ }
\\ var i: u8 = 2;
+ \\ _ = i;
\\}
});
@@ -2061,7 +2152,9 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
, &[_][]const u8{
\\pub export fn switch_fn(arg_i: c_int) void {
\\ var i = arg_i;
+ \\ _ = i;
\\ var res: c_int = 0;
+ \\ _ = res;
\\ while (true) {
\\ switch (i) {
\\ @as(c_int, 0) => {
@@ -2150,7 +2243,9 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
, &[_][]const u8{
\\pub export fn max(arg_a: c_int) void {
\\ var a = arg_a;
+ \\ _ = a;
\\ var tmp: c_int = undefined;
+ \\ _ = tmp;
\\ tmp = a;
\\ a = tmp;
\\}
@@ -2164,8 +2259,11 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
, &[_][]const u8{
\\pub export fn max(arg_a: c_int) void {
\\ var a = arg_a;
+ \\ _ = a;
\\ var b: c_int = undefined;
+ \\ _ = b;
\\ var c: c_int = undefined;
+ \\ _ = c;
\\ c = blk: {
\\ const tmp = a;
\\ b = tmp;
@@ -2194,6 +2292,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
, &[_][]const u8{
\\pub export fn float_to_int(arg_a: f32) c_int {
\\ var a = arg_a;
+ \\ _ = a;
\\ return @floatToInt(c_int, a);
\\}
});
@@ -2217,16 +2316,27 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
, &[_][]const u8{
\\pub export fn escapes() [*c]const u8 {
\\ var a: u8 = '\'';
+ \\ _ = a;
\\ var b: u8 = '\\';
+ \\ _ = b;
\\ var c: u8 = '\x07';
+ \\ _ = c;
\\ var d: u8 = '\x08';
+ \\ _ = d;
\\ var e: u8 = '\x0c';
+ \\ _ = e;
\\ var f: u8 = '\n';
+ \\ _ = f;
\\ var g: u8 = '\r';
+ \\ _ = g;
\\ var h: u8 = '\t';
+ \\ _ = h;
\\ var i: u8 = '\x0b';
+ \\ _ = i;
\\ var j: u8 = '\x00';
+ \\ _ = j;
\\ var k: u8 = '"';
+ \\ _ = k;
\\ return "'\\\x07\x08\x0c\n\r\t\x0b\x00\"";
\\}
});
@@ -2246,11 +2356,13 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
, &[_][]const u8{
\\pub export fn foo() void {
\\ var a: c_int = 2;
+ \\ _ = a;
\\ while (true) {
\\ a = a - @as(c_int, 1);
\\ if (!(a != 0)) break;
\\ }
\\ var b: c_int = 2;
+ \\ _ = b;
\\ while (true) {
\\ b = b - @as(c_int, 1);
\\ if (!(b != 0)) break;
@@ -2291,21 +2403,37 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\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 {
\\ var a = arg_a;
+ \\ _ = a;
\\ var b = arg_b;
+ \\ _ = b;
\\ var c = arg_c;
+ \\ _ = c;
\\ var d: enum_Foo = @bitCast(c_uint, FooA);
+ \\ _ = d;
\\ var e: c_int = @boolToInt((a != 0) and (b != 0));
+ \\ _ = e;
\\ var f: c_int = @boolToInt((b != 0) and (c != null));
+ \\ _ = f;
\\ var g: c_int = @boolToInt((a != 0) and (c != null));
+ \\ _ = g;
\\ var h: c_int = @boolToInt((a != 0) or (b != 0));
+ \\ _ = h;
\\ var i: c_int = @boolToInt((b != 0) or (c != null));
+ \\ _ = i;
\\ var j: c_int = @boolToInt((a != 0) or (c != null));
+ \\ _ = j;
\\ 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));
+ \\ _ = l;
\\ var m: c_int = @boolToInt((c != null) or (d != 0));
+ \\ _ = m;
\\ var td: SomeTypedef = 44;
+ \\ _ = td;
\\ var o: c_int = @boolToInt((td != 0) or (b != 0));
+ \\ _ = o;
\\ var p: c_int = @boolToInt((c != null) and (td != 0));
+ \\ _ = 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{
\\pub export fn max(arg_a: c_int, arg_b: c_int) c_int {
\\ var a = arg_a;
+ \\ _ = a;
\\ var b = arg_b;
+ \\ _ = b;
\\ return (a & b) ^ (a | b);
\\}
});
@@ -2364,14 +2494,23 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
, &[_][]const u8{
\\pub export fn test_comparisons(arg_a: c_int, arg_b: c_int) c_int {
\\ var a = arg_a;
+ \\ _ = a;
\\ var b = arg_b;
+ \\ _ = b;
\\ var c: c_int = @boolToInt(a < b);
+ \\ _ = c;
\\ var d: c_int = @boolToInt(a > b);
+ \\ _ = d;
\\ var e: c_int = @boolToInt(a <= b);
+ \\ _ = e;
\\ var f: c_int = @boolToInt(a >= b);
+ \\ _ = f;
\\ var g: c_int = @boolToInt(c < d);
+ \\ _ = g;
\\ var h: c_int = @boolToInt(e < f);
+ \\ _ = h;
\\ var i: c_int = @boolToInt(g < h);
+ \\ _ = i;
\\ return i;
\\}
});
@@ -2387,7 +2526,9 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
, &[_][]const u8{
\\pub export fn max(arg_a: c_int, arg_b: c_int) c_int {
\\ var a = arg_a;
+ \\ _ = a;
\\ var b = arg_b;
+ \\ _ = b;
\\ if (a == b) return a;
\\ if (a != b) return b;
\\ return a;
@@ -2404,6 +2545,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\pub const yes = [*c]u8;
\\pub export fn foo() void {
\\ var a: yes = undefined;
+ \\ _ = a;
\\ if (a != null) {
\\ _ = @as(c_int, 2);
\\ }
@@ -2423,6 +2565,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\ return blk: {
\\ var a: c_int = 1;
\\ _ = a;
+ \\ _ = a;
\\ break :blk a;
\\ };
\\}
@@ -2448,6 +2591,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\pub export var b: f32 = 2.0;
\\pub export fn foo() void {
\\ var c: [*c]struct_Foo = undefined;
+ \\ _ = c;
\\ _ = a.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 fn foo(arg_index: c_int) c_int {
\\ var index = arg_index;
+ \\ _ = index;
\\ return array[@intCast(c_uint, index)];
\\}
,
@@ -2481,7 +2626,9 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
, &[_][]const u8{
\\pub export fn foo() void {
\\ var a: [10]c_int = undefined;
+ \\ _ = a;
\\ var i: c_int = 0;
+ \\ _ = i;
\\ a[@intCast(c_uint, i)] = 0;
\\}
});
@@ -2494,7 +2641,9 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
, &[_][]const u8{
\\pub export fn foo() void {
\\ var a: [10]c_longlong = undefined;
+ \\ _ = a;
\\ var i: c_longlong = 0;
+ \\ _ = i;
\\ a[@intCast(usize, i)] = 0;
\\}
});
@@ -2507,7 +2656,9 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
, &[_][]const u8{
\\pub export fn foo() void {
\\ var a: [10]c_uint = undefined;
+ \\ _ = a;
\\ var i: c_uint = 0;
+ \\ _ = i;
\\ a[i] = 0;
\\}
});
@@ -2516,6 +2667,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\#define CALL(arg) bar(arg)
, &[_][]const u8{
\\pub inline fn CALL(arg: anytype) @TypeOf(bar(arg)) {
+ \\ _ = arg;
\\ return bar(arg);
\\}
});
@@ -2524,6 +2676,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\#define CALL(arg) bar()
, &[_][]const u8{
\\pub inline fn CALL(arg: anytype) @TypeOf(bar()) {
+ \\ _ = arg;
\\ return bar();
\\}
});
@@ -2539,7 +2692,9 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
, &[_][]const u8{
\\pub export fn max(arg_a: c_int, arg_b: c_int) c_int {
\\ var a = arg_a;
+ \\ _ = a;
\\ var b = arg_b;
+ \\ _ = b;
\\ if ((a < b) or (a == b)) return b;
\\ if ((a >= b) and (a == b)) return a;
\\ return a;
@@ -2561,7 +2716,9 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
, &[_][]const u8{
\\pub export fn max(arg_a: c_int, arg_b: c_int) c_int {
\\ var a = arg_a;
+ \\ _ = a;
\\ var b = arg_b;
+ \\ _ = b;
\\ if (a < b) return b;
\\ if (a < b) return b else return a;
\\ if (a < b) {} else {}
@@ -2582,12 +2739,14 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\pub export fn foo() void {
\\ if (true) {
\\ var a: c_int = 2;
+ \\ _ = a;
\\ }
\\ if ((blk: {
\\ _ = @as(c_int, 2);
\\ break :blk @as(c_int, 5);
\\ }) != 0) {
\\ 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 {
\\ var a = arg_a;
+ \\ _ = a;
\\ var b = arg_b;
+ \\ _ = b;
\\ var c = arg_c;
+ \\ _ = c;
\\ var d = arg_d;
+ \\ _ = d;
\\ if (a != 0) return 0;
\\ if (b != 0) return 1;
\\ if (c != null) return 2;
@@ -2640,6 +2803,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
, &[_][]const u8{
\\pub export fn abs(arg_a: c_int) c_int {
\\ var a = arg_a;
+ \\ _ = a;
\\ return if (a < @as(c_int, 0)) -a else a;
\\}
});
@@ -2660,16 +2824,19 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
, &[_][]const u8{
\\pub export fn foo1(arg_a: c_uint) c_uint {
\\ var a = arg_a;
+ \\ _ = a;
\\ a +%= 1;
\\ return a;
\\}
\\pub export fn foo2(arg_a: c_int) c_int {
\\ var a = arg_a;
+ \\ _ = a;
\\ a += 1;
\\ return a;
\\}
\\pub export fn foo3(arg_a: [*c]c_int) [*c]c_int {
\\ var a = arg_a;
+ \\ _ = a;
\\ a += 1;
\\ return a;
\\}
@@ -2695,7 +2862,9 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\}
\\pub export fn bar() void {
\\ var f: ?fn () callconv(.C) void = foo;
+ \\ _ = f;
\\ var b: ?fn () callconv(.C) c_int = baz;
+ \\ _ = b;
\\ f.?();
\\ f.?();
\\ foo();
@@ -2721,7 +2890,9 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
, &[_][]const u8{
\\pub export fn foo() void {
\\ var i: c_int = 0;
+ \\ _ = i;
\\ var u: c_uint = 0;
+ \\ _ = u;
\\ i += 1;
\\ i -= 1;
\\ u +%= 1;
@@ -2760,7 +2931,9 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
, &[_][]const u8{
\\pub export fn log2(arg_a: c_uint) c_int {
\\ var a = arg_a;
+ \\ _ = a;
\\ var i: c_int = 0;
+ \\ _ = i;
\\ while (a > @bitCast(c_uint, @as(c_int, 0))) {
\\ 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{
\\pub export fn log2(arg_a: u32) c_int {
\\ var a = arg_a;
+ \\ _ = a;
\\ var i: c_int = 0;
+ \\ _ = i;
\\ while (a > @bitCast(c_uint, @as(c_int, 0))) {
\\ 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{
\\pub export fn foo() void {
\\ var a: c_int = 0;
+ \\ _ = a;
\\ var b: c_uint = 0;
+ \\ _ = b;
\\ a += blk: {
\\ const ref = &a;
\\ ref.* += @as(c_int, 1);
@@ -2887,6 +3064,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
, &[_][]const u8{
\\pub export fn foo() void {
\\ var a: c_uint = 0;
+ \\ _ = a;
\\ a +%= blk: {
\\ const ref = &a;
\\ ref.* +%= @bitCast(c_uint, @as(c_int, 1));
@@ -2946,7 +3124,9 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
, &[_][]const u8{
\\pub export fn foo() void {
\\ var i: c_int = 0;
+ \\ _ = i;
\\ var u: c_uint = 0;
+ \\ _ = u;
\\ i += 1;
\\ i -= 1;
\\ u +%= 1;
@@ -3041,6 +3221,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\pub fn bar() callconv(.C) void {}
\\pub export fn foo(arg_baz: ?fn () callconv(.C) [*c]c_int) void {
\\ var baz = arg_baz;
+ \\ _ = baz;
\\ bar();
\\ _ = baz.?();
\\}
@@ -3082,6 +3263,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\#define BAZ (uint32_t)(2)
, &[_][]const u8{
\\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));
\\}
,
@@ -3122,10 +3304,14 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\#define MAX(a, b) ((b) > (a) ? (b) : (a))
, &[_][]const u8{
\\pub inline fn MIN(a: anytype, b: anytype) @TypeOf(if (b < a) b else a) {
+ \\ _ = a;
+ \\ _ = b;
\\ return 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;
\\}
});
@@ -3137,7 +3323,9 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
, &[_][]const u8{
\\pub export fn foo(arg_p: [*c]c_int, arg_x: c_int) c_int {
\\ var p = arg_p;
+ \\ _ = p;
\\ var x = arg_x;
+ \\ _ = x;
\\ return blk: {
\\ const tmp = x;
\\ (blk_1: {
@@ -3164,6 +3352,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\}
\\pub export fn bar(arg_x: c_long) c_ushort {
\\ var x = arg_x;
+ \\ _ = x;
\\ return @bitCast(c_ushort, @truncate(c_short, x));
\\}
});
@@ -3176,6 +3365,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
, &[_][]const u8{
\\pub export fn foo(arg_bar_1: c_int) void {
\\ var bar_1 = arg_bar_1;
+ \\ _ = bar_1;
\\ bar_1 = 2;
\\}
\\pub export var bar: c_int = 4;
@@ -3189,6 +3379,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
, &[_][]const u8{
\\pub export fn foo(arg_bar_1: c_int) void {
\\ var bar_1 = arg_bar_1;
+ \\ _ = bar_1;
\\ bar_1 = 2;
\\}
,
@@ -3218,13 +3409,16 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
, &[_][]const u8{
\\pub export fn foo(arg_a: [*c]c_int) void {
\\ var a = arg_a;
+ \\ _ = a;
\\}
\\pub export fn bar(arg_a: [*c]const c_int) void {
\\ var a = arg_a;
+ \\ _ = a;
\\ foo(@intToPtr([*c]c_int, @ptrToInt(a)));
\\}
\\pub export fn baz(arg_a: [*c]volatile c_int) void {
\\ var a = arg_a;
+ \\ _ = a;
\\ foo(@intToPtr([*c]c_int, @ptrToInt(a)));
\\}
});
@@ -3239,9 +3433,13 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
, &[_][]const u8{
\\pub export fn foo(arg_x: bool) bool {
\\ var x = arg_x;
+ \\ _ = x;
\\ 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);
+ \\ _ = b;
\\ var c: bool = @ptrToInt(foo) != 0;
+ \\ _ = c;
\\ 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{
\\pub export fn max(x: c_int, arg_y: c_int) c_int {
+ \\ _ = x;
\\ var y = arg_y;
+ \\ _ = y;
\\ return if (x > y) x else y;
\\}
});
@@ -3313,6 +3513,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\
, &[_][]const u8{
\\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;
\\}
});
@@ -3532,6 +3733,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\ const foo = struct {
\\ var static: struct_FOO = @import("std").mem.zeroes(struct_FOO);
\\ };
+ \\ _ = foo;
\\ 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 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 _");
+ });
}
From de9306096e17519dfb730457059ce08496e5f758 Mon Sep 17 00:00:00 2001
From: Evan Haas
Date: Wed, 23 Jun 2021 10:22:41 -0700
Subject: [PATCH 13/15] translate-c: remove explicit `comptime` from shuffle
mask expression
---
src/translate_c.zig | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/src/translate_c.zig b/src/translate_c.zig
index 4e1fff5268c4..5edcb616abe2 100644
--- a/src/translate_c.zig
+++ b/src/translate_c.zig
@@ -1361,11 +1361,10 @@ fn makeShuffleMask(c: *Context, scope: *Scope, expr: *const clang.ShuffleVectorE
init.* = converted_index;
}
- const mask_init = try Tag.array_init.create(c.arena, .{
+ return Tag.array_init.create(c.arena, .{
.cond = mask_type,
.cases = init_list,
});
- return Tag.@"comptime".create(c.arena, mask_init);
}
/// @typeInfo(@TypeOf(vec_node)).Vector.
From 32595320807fdb8a175674621b0b2216527f9d4f Mon Sep 17 00:00:00 2001
From: Andrew Kelley
Date: Wed, 23 Jun 2021 11:32:28 -0700
Subject: [PATCH 14/15] langref: fix unused vars
---
doc/langref.html.in | 78 +++++++++++++++++++++++++++++++--------------
1 file changed, 54 insertions(+), 24 deletions(-)
diff --git a/doc/langref.html.in b/doc/langref.html.in
index 7bb75673e145..50c589be3b33 100644
--- a/doc/langref.html.in
+++ b/doc/langref.html.in
@@ -965,7 +965,7 @@ test "thread local storage" {
thread2.wait();
}
-fn testTls(context: void) void {
+fn testTls(_: void) void {
assert(x == 1234);
x += 1;
assert(x == 1235);
@@ -2502,6 +2502,8 @@ test "struct namespaced variable" {
// you can still instantiate an empty struct
const does_nothing = Empty {};
+
+ _ = does_nothing;
}
// 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 { }
{#code_end#}
- 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:
{#code_begin|obj#}
-const Foo = extern enum { a, b, c };
-export fn entry(foo: Foo) void { }
+const Foo = enum(c_int) { a, b, c };
+export fn entry(foo: Foo) void { _ = foo; }
{#code_end#}
{#header_close#}
@@ -3392,9 +3395,11 @@ test "inside test block" {
test "separate scopes" {
{
const pi = 3.14;
+ _ = pi;
}
{
var pi: bool = true;
+ _ = pi;
}
}
{#code_end#}
@@ -3432,7 +3437,7 @@ test "switch simple" {
// Switching on arbitrary expressions is allowed as long as the
// expression is known at compile-time.
zz => zz,
- comptime blk: {
+ blk: {
const d: u32 = 5;
const e: u32 = 100;
break :blk d + e;
@@ -3831,7 +3836,7 @@ test "for basics" {
// To access the index of iteration, specify a second capture value.
// This is zero-indexed.
var sum2: i32 = 0;
- for (items) |value, i| {
+ for (items) |_, i| {
try expect(@TypeOf(i) == usize);
sum2 += @intCast(i32, i);
}
@@ -3984,7 +3989,7 @@ test "if optional" {
}
const b: ?u32 = null;
- if (b) |value| {
+ if (b) |_| {
unreachable;
} else {
try expect(true);
@@ -4021,11 +4026,13 @@ test "if error union" {
if (a) |value| {
try expect(value == 0);
} else |err| {
+ _ = err;
unreachable;
}
const b: anyerror!u32 = error.BadValue;
if (b) |value| {
+ _ = value;
unreachable;
} else |err| {
try expect(err == error.BadValue);
@@ -4045,13 +4052,13 @@ test "if error union" {
var c: anyerror!u32 = 3;
if (c) |*value| {
value.* = 9;
- } else |err| {
+ } else |_| {
unreachable;
}
if (c) |value| {
try expect(value == 9);
- } else |err| {
+ } else |_| {
unreachable;
}
}
@@ -4064,18 +4071,20 @@ test "if error union with optional" {
if (a) |optional_value| {
try expect(optional_value.? == 0);
} else |err| {
+ _ = err;
unreachable;
}
const b: anyerror!?u32 = null;
if (b) |optional_value| {
try expect(optional_value == null);
- } else |err| {
+ } else |_| {
unreachable;
}
const c: anyerror!?u32 = error.BadValue;
if (c) |optional_value| {
+ _ = optional_value;
unreachable;
} else |err| {
try expect(err == error.BadValue);
@@ -4087,13 +4096,13 @@ test "if error union with optional" {
if (optional_value.*) |*value| {
value.* = 9;
}
- } else |err| {
+ } else |_| {
unreachable;
}
if (d) |optional_value| {
try expect(optional_value.? == 9);
- } else |err| {
+ } else |_| {
unreachable;
}
}
@@ -4246,6 +4255,7 @@ test "type of unreachable" {
{#code_begin|test#}
fn foo(condition: bool, b: u32) void {
const a = if (condition) b else return;
+ _ = a;
@panic("do something with a");
}
test "noreturn" {
@@ -4574,7 +4584,7 @@ test "parse u64" {
{#code_begin|syntax#}
fn doAThing(str: []u8) void {
const number = parseU64(str, 10) catch 13;
- // ...
+ _ = number; // ...
}
{#code_end#}
@@ -4589,7 +4599,7 @@ fn doAThing(str: []u8) void {
{#code_begin|syntax#}
fn doAThing(str: []u8) !void {
const number = parseU64(str, 10) catch |err| return err;
- // ...
+ _ = number; // ...
}
{#code_end#}
@@ -4598,7 +4608,7 @@ fn doAThing(str: []u8) !void {
{#code_begin|syntax#}
fn doAThing(str: []u8) !void {
const number = try parseU64(str, 10);
- // ...
+ _ = number; // ...
}
{#code_end#}
@@ -5022,7 +5032,7 @@ extern fn malloc(size: size_t) ?*u8;
fn doAThing() ?*Foo {
const ptr = malloc(1234) orelse return null;
- // ...
+ _ = ptr; // ...
}
{#code_end#}
@@ -5135,6 +5145,7 @@ test "optional pointers" {
test "type coercion - variable declaration" {
var a: u8 = 1;
var b: u16 = a;
+ _ = b;
}
test "type coercion - function call" {
@@ -5142,11 +5153,14 @@ test "type coercion - function call" {
foo(a);
}
-fn foo(b: u16) void {}
+fn foo(b: u16) void {
+ _ = b;
+}
test "type coercion - @as builtin" {
var a: u8 = 1;
var b = @as(u16, a);
+ _ = b;
}
{#code_end#}
@@ -5174,7 +5188,7 @@ test "type coercion - const qualification" {
foo(b);
}
-fn foo(a: *const i32) void {}
+fn foo(_: *const i32) void {}
{#code_end#}
In addition, pointers coerce to const optional pointers:
@@ -5424,7 +5438,7 @@ test "coercion between unions and enums" {
test "coercion of zero bit types" {
var x: void = {};
var y: *void = x;
- //var z: void = y; // TODO
+ _ = y;
}
{#code_end#}
{#header_close#}
@@ -6569,6 +6583,7 @@ var x: i32 = 1;
test "suspend with no resume" {
var frame = async func();
try expect(x == 2);
+ _ = frame;
}
fn func() void {
@@ -6800,6 +6815,7 @@ fn amain() !void {
var global_download_frame: anyframe = undefined;
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");
errdefer allocator.free(result);
suspend {
@@ -6811,6 +6827,7 @@ fn fetchUrl(allocator: *Allocator, url: []const u8) ![]u8 {
var global_file_frame: anyframe = undefined;
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");
errdefer allocator.free(result);
suspend {
@@ -6869,6 +6886,7 @@ fn amain() !void {
}
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");
errdefer allocator.free(result);
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 {
+ _ = 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");
errdefer allocator.free(result);
std.debug.print("readFile returning\n", .{});
@@ -8584,6 +8603,7 @@ fn List(comptime T: type) type {
test "integer cast panic" {
var a: u16 = 0xabcd;
var b: u8 = @intCast(u8, a);
+ _ = b;
}
{#code_end#}
@@ -8839,6 +8859,7 @@ comptime {
{#code_begin|exe_err#}
pub fn main() void {
var x = foo("hello");
+ _ = x;
}
fn foo(x: []const u8) u8 {
@@ -9107,6 +9128,7 @@ pub fn main() void {
comptime {
const optional_number: ?i32 = null;
const number = optional_number.?;
+ _ = number;
}
{#code_end#}
At runtime:
@@ -9140,6 +9162,7 @@ pub fn main() void {
{#code_begin|test_err|caught unexpected error 'UnableToReturnNumber'#}
comptime {
const number = getNumberOrFail() catch unreachable;
+ _ = number;
}
fn getNumberOrFail() !i32 {
@@ -9187,6 +9210,7 @@ comptime {
const err = error.AnError;
const number = @errorToInt(err) + 10;
const invalid_err = @intToError(number);
+ _ = invalid_err;
}
{#code_end#}
At runtime:
@@ -9197,7 +9221,7 @@ pub fn main() void {
var err = error.AnError;
var number = @errorToInt(err) + 500;
var invalid_err = @intToError(number);
- std.debug.print("value: {}\n", .{number});
+ std.debug.print("value: {}\n", .{invalid_err});
}
{#code_end#}
{#header_close#}
@@ -9212,6 +9236,7 @@ const Foo = enum {
comptime {
const a: u2 = 3;
const b = @intToEnum(Foo, a);
+ _ = b;
}
{#code_end#}
At runtime:
@@ -9396,6 +9421,7 @@ comptime {
pub fn main() void {
var opt_ptr: ?*i32 = null;
var ptr = @ptrCast(*i32, opt_ptr);
+ _ = ptr;
}
{#code_end#}
{#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:
{#code_begin|test_err|expected type '[]u8'#}
-fn foo(s: []u8) void {}
+fn foo(s: []u8) void {
+ _ = s;
+}
test "string literal to mutable slice" {
foo("hello");
@@ -9531,7 +9559,9 @@ test "string literal to mutable slice" {
{#code_end#}
However if you make the slice constant, then it works:
{#code_begin|test|strlit#}
-fn foo(s: []const u8) void {}
+fn foo(s: []const u8) void {
+ _ = s;
+}
test "string literal to constant slice" {
foo("hello");
@@ -10476,7 +10506,7 @@ coding style.
{#header_close#}
{#header_open|Examples#}
- {#code_begin|syntax#}
+ {#syntax#}
const namespace_name = @import("dir_name/file_name.zig");
const TypeName = @import("dir_name/TypeName.zig");
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.
fn readU32Be() u32 {}
- {#code_end#}
+ {#endsyntax#}
See the Zig Standard Library for more examples.
From 29314b64bd91be91e8f1d48a1b71eba68569be94 Mon Sep 17 00:00:00 2001
From: Evan Haas
Date: Wed, 23 Jun 2021 11:28:41 -0700
Subject: [PATCH 15/15] translate-c: ensure scoped (non-public) enum constants
are used
---
src/translate_c.zig | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/src/translate_c.zig b/src/translate_c.zig
index 5edcb616abe2..93ad4a421bcc 100644
--- a/src/translate_c.zig
+++ b/src/translate_c.zig
@@ -1137,8 +1137,10 @@ fn transEnumDecl(c: *Context, scope: *Scope, enum_decl: *const clang.EnumDecl) E
});
if (toplevel)
try addTopLevelDecl(c, enum_val_name, enum_const_def)
- else
+ else {
try scope.appendNode(enum_const_def);
+ try bs.discardVariable(c, enum_val_name);
+ }
}
const int_type = enum_decl.getIntegerType();
@@ -1177,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 });
} else {
try scope.appendNode(Node.initPayload(&payload.base));
+ try bs.discardVariable(c, name);
}
}