Commit e64eef366c

Nathan Bourgeois <IridescentRosesFall@gmail.com>
2022-11-03 13:07:00
Translate-C Remainder Macro Fix
1 parent b2f8c1f
lib/std/zig/c_translation.zig
@@ -570,6 +570,22 @@ pub const MacroArithmetic = struct {
             else => unreachable,
         }
     }
+
+    pub fn rem(a: anytype, b: anytype) ArithmeticConversion(@TypeOf(a), @TypeOf(b)) {
+        const ResType = ArithmeticConversion(@TypeOf(a), @TypeOf(b));
+        const a_casted = cast(ResType, a);
+        const b_casted = cast(ResType, b);
+        switch (@typeInfo(ResType)) {
+            .Int => {
+                if (@typeInfo(ResType).Int.signedness == .signed) {
+                    return signedRemainder(a_casted, b_casted);
+                } else {
+                    return a_casted % b_casted;
+                }
+            },
+            else => unreachable,
+        }
+    }
 };
 
 test "Macro suffix functions" {
src/translate_c/ast.zig
@@ -726,9 +726,7 @@ pub const Payload = struct {
             rhs: Node,
         },
 
-        pub const Operator = enum {
-            div,
-        };
+        pub const Operator = enum { div, rem };
     };
 };
 
src/translate_c.zig
@@ -6237,7 +6237,7 @@ fn parseCMulExpr(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!Node {
             .Percent => {
                 const lhs = try macroBoolToInt(c, node);
                 const rhs = try macroBoolToInt(c, try parseCCastExpr(c, m, scope));
-                node = try Tag.mod.create(c.arena, .{ .lhs = lhs, .rhs = rhs });
+                node = try Tag.macro_arithmetic.create(c.arena, .{ .op = .rem, .lhs = lhs, .rhs = rhs });
             },
             else => {
                 m.i -= 1;
test/behavior/translate_c_macros.h
@@ -56,3 +56,6 @@ typedef _Bool uintptr_t;
 
 #define DIVIDE_CONSTANT(version) (version / 1000)
 #define DIVIDE_ARGS(A, B) (A / B)
+
+#define REMAINDER_CONSTANT(version) (version % 10000)
+#define REMAINDER_ARGS(A, B) (A % B)
\ No newline at end of file
test/behavior/translate_c_macros.zig
@@ -171,3 +171,37 @@ test "Macro that uses division operator. Issue #13162" {
         ),
     );
 }
+
+test "Macro that uses remainder operator. Issue #13346" {
+    if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
+    if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
+    if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
+    if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
+
+    try expectEqual(@as(c_int, 2_010), h.REMAINDER_CONSTANT(@as(c_int, 42_010)));
+    try expectEqual(@as(c_uint, 2_030), h.REMAINDER_CONSTANT(@as(c_uint, 42_030)));
+
+    try expectEqual(
+        @as(c_int, 7),
+        h.REMAINDER_ARGS(
+            @as(i8, 17),
+            @as(i8, 10),
+        ),
+    );
+
+    try expectEqual(
+        @as(c_int, 5),
+        h.REMAINDER_ARGS(
+            @as(c_ushort, 25),
+            @as(c_ushort, 20),
+        ),
+    );
+
+    try expectEqual(
+        @as(c_int, 1),
+        h.REMAINDER_ARGS(
+            @as(c_int, 5),
+            @as(c_int, -2),
+        ),
+    );
+}
test/translate_c.zig
@@ -511,7 +511,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
         \\        _ = @as(c_int, 4) == @as(c_int, 4);
         \\        _ = @as(c_int, 5) * @as(c_int, 6);
         \\        _ = baz(@as(c_int, 1), @as(c_int, 2));
-        \\        _ = @as(c_int, 2) % @as(c_int, 2);
+        \\        _ = @import("std").zig.c_translation.MacroArithmetic.rem(@as(c_int, 2), @as(c_int, 2));
         \\        break :blk_1 baz(@as(c_int, 1), @as(c_int, 2));
         \\    };
         \\}