diff --git a/src/translate_c.zig b/src/translate_c.zig index 93ad4a421bcc..3792e215509b 100644 --- a/src/translate_c.zig +++ b/src/translate_c.zig @@ -67,6 +67,12 @@ const Scope = struct { mangle_count: u32 = 0, label: ?[]const u8 = null, + /// By default all variables are discarded, since we do not know in advance if they + /// will be used. This maps the variable's name to the Discard payload, so that if + /// the variable is subsequently referenced we can indicate that the discard should + /// be skipped during the intermediate AST -> Zig AST render step. + variable_discards: std.StringArrayHashMap(*ast.Payload.Discard), + /// When the block corresponds to a function, keep track of the return type /// so that the return expression can be cast, if necessary return_type: ?clang.QualType = null, @@ -84,6 +90,7 @@ const Scope = struct { }, .statements = std.ArrayList(Node).init(c.gpa), .variables = AliasList.init(c.gpa), + .variable_discards = std.StringArrayHashMap(*ast.Payload.Discard).init(c.gpa), }; if (labeled) { blk.label = try blk.makeMangledName(c, "blk"); @@ -94,6 +101,7 @@ const Scope = struct { fn deinit(self: *Block) void { self.statements.deinit(); self.variables.deinit(); + self.variable_discards.deinit(); self.* = undefined; } @@ -154,8 +162,9 @@ const Scope = struct { 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); + const discard = try Tag.discard.create(c.arena, .{ .should_skip = false, .value = name_node }); try scope.statements.append(discard); + try scope.variable_discards.putNoClobber(name, discard.castTag(.discard).?); } }; @@ -271,6 +280,24 @@ const Scope = struct { } } } + + fn skipVariableDiscard(inner: *Scope, name: []const u8) void { + var scope = inner; + while (true) { + switch (scope.id) { + .root => return, + .block => { + const block = @fieldParentPtr(Block, "base", scope); + if (block.variable_discards.get(name)) |discard| { + discard.data.should_skip = true; + return; + } + }, + else => {}, + } + scope = scope.parent.?; + } + } }; pub const Context = struct { @@ -834,7 +861,9 @@ 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); + if (node.tag() != .pub_var_simple) { + try bs.discardVariable(c, name); + } } } @@ -1078,14 +1107,16 @@ fn transRecordDecl(c: *Context, scope: *Scope, record_decl: *const clang.RecordD .init = init_node, }, }; - + const node = Node.initPayload(&payload.base); if (toplevel) { - try addTopLevelDecl(c, name, Node.initPayload(&payload.base)); + try addTopLevelDecl(c, name, node); if (!is_unnamed) try c.alias_list.append(.{ .alias = bare_name, .name = name }); } else { - try scope.appendNode(Node.initPayload(&payload.base)); - try bs.discardVariable(c, name); + try scope.appendNode(node); + if (node.tag() != .pub_var_simple) { + try bs.discardVariable(c, name); + } } } @@ -1172,14 +1203,16 @@ fn transEnumDecl(c: *Context, scope: *Scope, enum_decl: *const clang.EnumDecl) E .name = name, }, }; - + const node = Node.initPayload(&payload.base); if (toplevel) { - try addTopLevelDecl(c, name, Node.initPayload(&payload.base)); + try addTopLevelDecl(c, name, node); if (!is_unnamed) try c.alias_list.append(.{ .alias = bare_name, .name = name }); } else { - try scope.appendNode(Node.initPayload(&payload.base)); - try bs.discardVariable(c, name); + try scope.appendNode(node); + if (node.tag() != .pub_var_simple) { + try bs.discardVariable(c, name); + } } } @@ -1789,7 +1822,7 @@ fn transDeclStmtOne( args[0] = try Tag.address_of.create(c.arena, varname); const cleanup_call = try Tag.call.create(c.arena, .{ .lhs = fn_id, .args = args }); - const discard = try Tag.discard.create(c.arena, cleanup_call); + const discard = try Tag.discard.create(c.arena, .{ .should_skip = false, .value = cleanup_call }); const deferred_cleanup = try Tag.@"defer".create(c.arena, discard); try block_scope.statements.append(deferred_cleanup); @@ -1844,6 +1877,7 @@ fn transDeclRefExpr( }); } } + scope.skipVariableDiscard(mangled_name); return ref_expr; } @@ -2478,7 +2512,9 @@ fn transInitListExprRecord( .value = try transExpr(c, scope, elem_expr, .used), }); } - + if (ty_node.castTag(.identifier)) |ident_node| { + scope.skipVariableDiscard(ident_node.data); + } return Tag.container_init.create(c.arena, .{ .lhs = ty_node, .inits = try c.arena.dupe(ast.Payload.ContainerInit.Initializer, field_inits.items), @@ -3870,7 +3906,7 @@ fn maybeSuppressResult( ) TransError!Node { _ = scope; if (used == .used) return result; - return Tag.discard.create(c.arena, result); + return Tag.discard.create(c.arena, .{ .should_skip = false, .value = result }); } fn addTopLevelDecl(c: *Context, name: []const u8, decl_node: Node) !void { @@ -5004,7 +5040,7 @@ fn parseCExpr(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!Node { var last = node; while (true) { // suppress result - const ignore = try Tag.discard.create(c.arena, last); + const ignore = try Tag.discard.create(c.arena, .{ .should_skip = false, .value = last }); try block_scope.statements.append(ignore); last = try parseCCondExpr(c, m, scope); @@ -5303,7 +5339,9 @@ fn parseCPrimaryExprInner(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!N try m.fail(c, "TODO implement function '{s}' in std.c.builtins", .{mangled_name}); return error.ParseError; } - return Tag.identifier.create(c.arena, builtin_typedef_map.get(mangled_name) orelse mangled_name); + const identifier = try Tag.identifier.create(c.arena, builtin_typedef_map.get(mangled_name) orelse mangled_name); + scope.skipVariableDiscard(identifier.castTag(.identifier).?.data); + return identifier; }, .LParen => { const inner_node = try parseCExpr(c, m, scope); diff --git a/src/translate_c/ast.zig b/src/translate_c/ast.zig index cdf8d778b2e8..b167fc57b61e 100644 --- a/src/translate_c/ast.zig +++ b/src/translate_c/ast.zig @@ -248,7 +248,6 @@ pub const Node = extern union { .@"comptime", .@"defer", .asm_simple, - .discard, .std_math_Log2Int, .negate, .negate_wrap, @@ -341,6 +340,7 @@ pub const Node = extern union { .warning, .type, => Payload.Value, + .discard => Payload.Discard, .@"if" => Payload.If, .@"while" => Payload.While, .@"switch", .array_init, .switch_prong => Payload.Switch, @@ -463,6 +463,14 @@ pub const Payload = struct { }, }; + pub const Discard = struct { + base: Payload, + data: struct { + should_skip: bool, + value: Node, + }, + }; + pub const If = struct { base: Payload, data: struct { @@ -1491,6 +1499,8 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex { .pub_inline_fn => return renderMacroFunc(c, node), .discard => { const payload = node.castTag(.discard).?.data; + if (payload.should_skip) return @as(NodeIndex, 0); + const lhs = try c.addNode(.{ .tag = .identifier, .main_token = try c.addToken(.identifier, "_"), @@ -1501,7 +1511,7 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex { .main_token = try c.addToken(.equal, "="), .data = .{ .lhs = lhs, - .rhs = try renderNode(c, payload), + .rhs = try renderNode(c, payload.value), }, }); }, diff --git a/test/translate_c.zig b/test/translate_c.zig index b1ef771c679d..22aa67c77421 100644 --- a/test/translate_c.zig +++ b/test/translate_c.zig @@ -12,11 +12,9 @@ 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; @@ -75,7 +73,6 @@ 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(); \\} }); @@ -128,7 +125,6 @@ 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, @@ -141,7 +137,6 @@ pub fn addCases(cases: *tests.TranslateCContext) void { \\ 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, @@ -178,7 +173,6 @@ pub fn addCases(cases: *tests.TranslateCContext) void { \\ }; \\ _ = union_unnamed_1; \\ const Foo = union_unnamed_1; - \\ _ = Foo; \\ var a: Foo = Foo{ \\ .A = @as(c_int, 0), \\ }; @@ -191,7 +185,6 @@ pub fn addCases(cases: *tests.TranslateCContext) void { \\ }; \\ _ = union_unnamed_2; \\ const Foo_1 = union_unnamed_2; - \\ _ = Foo_1; \\ var a_2: Foo_1 = Foo_1{ \\ .A = @as(c_int, 0), \\ }; @@ -205,7 +198,6 @@ 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); \\} }); @@ -247,7 +239,6 @@ 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)); \\} }); @@ -328,7 +319,6 @@ 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; \\} , @@ -346,7 +336,6 @@ pub fn addCases(cases: *tests.TranslateCContext) void { \\}; , \\pub inline fn A(_x: anytype) MyCStruct { - \\ _ = _x; \\ return @import("std").mem.zeroInit(MyCStruct, .{ \\ .x = _x, \\ }); @@ -377,7 +366,6 @@ 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); \\} }); @@ -387,7 +375,6 @@ 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)); \\} , @@ -450,7 +437,6 @@ 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); @@ -580,7 +566,6 @@ 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)); \\} }); @@ -667,7 +652,6 @@ 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; \\} @@ -763,7 +747,6 @@ 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); @@ -849,7 +832,6 @@ 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; \\} @@ -881,11 +863,8 @@ 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; @@ -895,11 +874,8 @@ 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; @@ -1263,7 +1239,6 @@ pub fn addCases(cases: *tests.TranslateCContext) void { \\pub export fn foo() void { \\ var a: c_int = undefined; \\ _ = a; - \\ _ = a; \\} }); @@ -1275,7 +1250,6 @@ 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); \\} }); @@ -1332,7 +1306,6 @@ pub fn addCases(cases: *tests.TranslateCContext) void { \\pub export fn foo() void { \\ { \\ var i: c_int = 0; - \\ _ = i; \\ while (i != 0) : (i += 1) {} \\ } \\} @@ -1356,7 +1329,6 @@ 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) {} @@ -1400,7 +1372,6 @@ 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)); \\} }); @@ -1424,7 +1395,6 @@ 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; @@ -1461,11 +1431,8 @@ 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; @@ -1486,11 +1453,8 @@ 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; @@ -1527,7 +1491,6 @@ pub fn addCases(cases: *tests.TranslateCContext) void { , &[_][]const u8{ \\pub export fn foo() void { \\ var x: [*c]c_int = undefined; - \\ _ = x; \\ x.* = 1; \\} }); @@ -1541,9 +1504,7 @@ 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.*; \\} }); @@ -1556,7 +1517,6 @@ pub fn addCases(cases: *tests.TranslateCContext) void { , &[_][]const u8{ \\pub export fn foo() c_int { \\ var x: c_int = undefined; - \\ _ = x; \\ return ~x; \\} }); @@ -1574,11 +1534,8 @@ 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)); @@ -1891,13 +1848,10 @@ 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; \\} , @@ -1951,9 +1905,7 @@ pub fn addCases(cases: *tests.TranslateCContext) 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; @@ -1994,9 +1946,7 @@ 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; @@ -2026,13 +1976,11 @@ 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); @@ -2041,7 +1989,6 @@ pub fn addCases(cases: *tests.TranslateCContext) void { \\ } \\ while (true) { \\ var a_1: c_int = 2; - \\ _ = a_1; \\ a_1 = 12; \\ } \\ while (true) { @@ -2063,12 +2010,10 @@ 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; @@ -2152,9 +2097,7 @@ 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) => { @@ -2243,9 +2186,7 @@ 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; \\} @@ -2259,11 +2200,8 @@ 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; @@ -2292,7 +2230,6 @@ 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); \\} }); @@ -2356,13 +2293,11 @@ 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; @@ -2403,37 +2338,21 @@ 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; \\} , @@ -2473,9 +2392,7 @@ 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); \\} }); @@ -2494,23 +2411,14 @@ 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; \\} }); @@ -2526,9 +2434,7 @@ 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; @@ -2545,7 +2451,6 @@ 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); \\ } @@ -2565,7 +2470,6 @@ pub fn addCases(cases: *tests.TranslateCContext) void { \\ return blk: { \\ var a: c_int = 1; \\ _ = a; - \\ _ = a; \\ break :blk a; \\ }; \\} @@ -2591,7 +2495,6 @@ 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; \\} @@ -2611,7 +2514,6 @@ 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)]; \\} , @@ -2626,9 +2528,7 @@ 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; \\} }); @@ -2641,9 +2541,7 @@ 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; \\} }); @@ -2656,9 +2554,7 @@ 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; \\} }); @@ -2667,7 +2563,6 @@ 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); \\} }); @@ -2692,9 +2587,7 @@ 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; @@ -2716,9 +2609,7 @@ 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 {} @@ -2769,13 +2660,9 @@ 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; @@ -2803,7 +2690,6 @@ 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; \\} }); @@ -2824,19 +2710,16 @@ 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; \\} @@ -2862,9 +2745,7 @@ 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(); @@ -2890,9 +2771,7 @@ 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; @@ -2931,9 +2810,7 @@ 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)); \\ } @@ -2953,9 +2830,7 @@ 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)); \\ } @@ -2983,9 +2858,7 @@ 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); @@ -3064,7 +2937,6 @@ 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)); @@ -3124,9 +2996,7 @@ 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; @@ -3221,7 +3091,6 @@ 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.?(); \\} @@ -3304,14 +3173,10 @@ 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; \\} }); @@ -3323,9 +3188,7 @@ 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: { @@ -3352,7 +3215,6 @@ 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)); \\} }); @@ -3365,7 +3227,6 @@ 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; @@ -3379,7 +3240,6 @@ 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; \\} , @@ -3413,12 +3273,10 @@ pub fn addCases(cases: *tests.TranslateCContext) void { \\} \\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))); \\} }); @@ -3433,13 +3291,9 @@ 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))); \\} }); @@ -3450,9 +3304,7 @@ 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; \\} }); @@ -3513,7 +3365,6 @@ 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; \\} }); @@ -3733,7 +3584,6 @@ 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; \\} }); @@ -3747,24 +3597,22 @@ pub fn addCases(cases: *tests.TranslateCContext) void { \\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) + cases.add("discard unused local variables and function parameters", + \\#define FOO(A, B) (A) \\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; + \\pub inline fn FOO(A: anytype, B: anytype) @TypeOf(A) { \\ _ = B; - \\ return A + B; + \\ return A; \\} });