Commit 9fd3aeb808

Evan Haas <evan@lagerdata.com>
2021-08-03 07:44:20
translate-c: handle macros that cast to cv void
Fixes #9507
1 parent fdd9724
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" {
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 {
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)
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);
+}