diff --git a/lib/std/zig/c_translation.zig b/lib/std/zig/c_translation.zig index bcf3b310ea..7b21fba93a 100644 --- a/lib/std/zig/c_translation.zig +++ b/lib/std/zig/c_translation.zig @@ -404,6 +404,10 @@ pub const Macros = struct { else => unreachable, // return type will be a compile error otherwise } } + + pub inline fn DISCARD(x: anytype) void { + _ = x; + } }; test "Macro suffix functions" { diff --git a/src/translate_c.zig b/src/translate_c.zig index e6d6392a9c..e11fc5b736 100644 --- a/src/translate_c.zig +++ b/src/translate_c.zig @@ -4978,6 +4978,17 @@ const PatternList = struct { , "WL_CONTAINER_OF", }, + + [2][]const u8{ "IGNORE_ME(X) ((void)(X))", "DISCARD" }, + [2][]const u8{ "IGNORE_ME(X) (void)(X)", "DISCARD" }, + [2][]const u8{ "IGNORE_ME(X) ((const void)(X))", "DISCARD" }, + [2][]const u8{ "IGNORE_ME(X) (const void)(X)", "DISCARD" }, + [2][]const u8{ "IGNORE_ME(X) ((volatile void)(X))", "DISCARD" }, + [2][]const u8{ "IGNORE_ME(X) (volatile void)(X)", "DISCARD" }, + [2][]const u8{ "IGNORE_ME(X) ((const volatile void)(X))", "DISCARD" }, + [2][]const u8{ "IGNORE_ME(X) (const volatile void)(X)", "DISCARD" }, + [2][]const u8{ "IGNORE_ME(X) ((volatile const void)(X))", "DISCARD" }, + [2][]const u8{ "IGNORE_ME(X) (volatile const void)(X)", "DISCARD" }, }; /// Assumes that `ms` represents a tokenized function-like macro. @@ -5152,6 +5163,16 @@ test "Macro matching" { try helper.checkMacro(allocator, pattern_list, "NO_MATCH(X, Y) (X + Y)", null); try helper.checkMacro(allocator, pattern_list, "CAST_OR_CALL(X, Y) (X)(Y)", "CAST_OR_CALL"); + try helper.checkMacro(allocator, pattern_list, "IGNORE_ME(X) (void)(X)", "DISCARD"); + try helper.checkMacro(allocator, pattern_list, "IGNORE_ME(X) ((void)(X))", "DISCARD"); + try helper.checkMacro(allocator, pattern_list, "IGNORE_ME(X) (const void)(X)", "DISCARD"); + try helper.checkMacro(allocator, pattern_list, "IGNORE_ME(X) ((const void)(X))", "DISCARD"); + try helper.checkMacro(allocator, pattern_list, "IGNORE_ME(X) (volatile void)(X)", "DISCARD"); + try helper.checkMacro(allocator, pattern_list, "IGNORE_ME(X) ((volatile void)(X))", "DISCARD"); + try helper.checkMacro(allocator, pattern_list, "IGNORE_ME(X) (const volatile void)(X)", "DISCARD"); + try helper.checkMacro(allocator, pattern_list, "IGNORE_ME(X) ((const volatile void)(X))", "DISCARD"); + try helper.checkMacro(allocator, pattern_list, "IGNORE_ME(X) (volatile const void)(X)", "DISCARD"); + try helper.checkMacro(allocator, pattern_list, "IGNORE_ME(X) ((volatile const void)(X))", "DISCARD"); } const MacroCtx = struct { diff --git a/test/behavior/translate_c_macros.h b/test/behavior/translate_c_macros.h index 6f458684c7..bff4cdfe23 100644 --- a/test/behavior/translate_c_macros.h +++ b/test/behavior/translate_c_macros.h @@ -18,3 +18,15 @@ struct Foo { #define SIZE_OF_FOO sizeof(struct Foo) #define MAP_FAILED ((void *) -1) + +#define IGNORE_ME_1(x) ((void)(x)) +#define IGNORE_ME_2(x) ((const void)(x)) +#define IGNORE_ME_3(x) ((volatile void)(x)) +#define IGNORE_ME_4(x) ((const volatile void)(x)) +#define IGNORE_ME_5(x) ((volatile const void)(x)) + +#define IGNORE_ME_6(x) (void)(x) +#define IGNORE_ME_7(x) (const void)(x) +#define IGNORE_ME_8(x) (volatile void)(x) +#define IGNORE_ME_9(x) (const volatile void)(x) +#define IGNORE_ME_10(x) (volatile const void)(x) diff --git a/test/behavior/translate_c_macros.zig b/test/behavior/translate_c_macros.zig index 8de06ae8ea..0daf4cec90 100644 --- a/test/behavior/translate_c_macros.zig +++ b/test/behavior/translate_c_macros.zig @@ -24,3 +24,16 @@ test "reference to a struct type" { test "cast negative integer to pointer" { try expectEqual(@intToPtr(?*c_void, @bitCast(usize, @as(isize, -1))), h.MAP_FAILED); } + +test "casting to void with a macro" { + h.IGNORE_ME_1(42); + h.IGNORE_ME_2(42); + h.IGNORE_ME_3(42); + h.IGNORE_ME_4(42); + h.IGNORE_ME_5(42); + h.IGNORE_ME_6(42); + h.IGNORE_ME_7(42); + h.IGNORE_ME_8(42); + h.IGNORE_ME_9(42); + h.IGNORE_ME_10(42); +}