| author | |
| committer | |
| log | e64eef366c68592f6daf063a8b8f85b8626a1598 |
| tree | 2610e1f4a2f7e26799e1375647dcf366994fb629 |
| parent | b2f8c1f2ef0ab1a9577198f78393a1208b8027fa |
| signature |
6 files changed, 56 insertions(+), 5 deletions(-)
lib/std/zig/c_translation.zig+16| ... | @@ -570,6 +570,22 @@ pub const MacroArithmetic = struct { | ... | @@ -570,6 +570,22 @@ pub const MacroArithmetic = struct { |
| 570 | else => unreachable, | 570 | else => unreachable, |
| 571 | } | 571 | } |
| 572 | } | 572 | } |
| 573 | |||
| 574 | pub fn rem(a: anytype, b: anytype) ArithmeticConversion(@TypeOf(a), @TypeOf(b)) { | ||
| 575 | const ResType = ArithmeticConversion(@TypeOf(a), @TypeOf(b)); | ||
| 576 | const a_casted = cast(ResType, a); | ||
| 577 | const b_casted = cast(ResType, b); | ||
| 578 | switch (@typeInfo(ResType)) { | ||
| 579 | .Int => { | ||
| 580 | if (@typeInfo(ResType).Int.signedness == .signed) { | ||
| 581 | return signedRemainder(a_casted, b_casted); | ||
| 582 | } else { | ||
| 583 | return a_casted % b_casted; | ||
| 584 | } | ||
| 585 | }, | ||
| 586 | else => unreachable, | ||
| 587 | } | ||
| 588 | } | ||
| 573 | }; | 589 | }; |
| 574 | 590 | ||
| 575 | test "Macro suffix functions" { | 591 | test "Macro suffix functions" { |
src/translate_c.zig+1-1| ... | @@ -6237,7 +6237,7 @@ fn parseCMulExpr(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!Node { | ... | @@ -6237,7 +6237,7 @@ fn parseCMulExpr(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!Node { |
| 6237 | .Percent => { | 6237 | .Percent => { |
| 6238 | const lhs = try macroBoolToInt(c, node); | 6238 | const lhs = try macroBoolToInt(c, node); |
| 6239 | const rhs = try macroBoolToInt(c, try parseCCastExpr(c, m, scope)); | 6239 | const rhs = try macroBoolToInt(c, try parseCCastExpr(c, m, scope)); |
| 6240 | node = try Tag.mod.create(c.arena, .{ .lhs = lhs, .rhs = rhs }); | 6240 | node = try Tag.macro_arithmetic.create(c.arena, .{ .op = .rem, .lhs = lhs, .rhs = rhs }); |
| 6241 | }, | 6241 | }, |
| 6242 | else => { | 6242 | else => { |
| 6243 | m.i -= 1; | 6243 | m.i -= 1; |
src/translate_c/ast.zig+1-3| ... | @@ -726,9 +726,7 @@ pub const Payload = struct { | ... | @@ -726,9 +726,7 @@ pub const Payload = struct { |
| 726 | rhs: Node, | 726 | rhs: Node, |
| 727 | }, | 727 | }, |
| 728 | 728 | ||
| 729 | pub const Operator = enum { | 729 | pub const Operator = enum { div, rem }; |
| 730 | div, | ||
| 731 | }; | ||
| 732 | }; | 730 | }; |
| 733 | }; | 731 | }; |
| 734 | 732 |
test/behavior/translate_c_macros.h+3| ... | @@ -56,3 +56,6 @@ typedef _Bool uintptr_t; | ... | @@ -56,3 +56,6 @@ typedef _Bool uintptr_t; |
| 56 | 56 | ||
| 57 | #define DIVIDE_CONSTANT(version) (version / 1000) | 57 | #define DIVIDE_CONSTANT(version) (version / 1000) |
| 58 | #define DIVIDE_ARGS(A, B) (A / B) | 58 | #define DIVIDE_ARGS(A, B) (A / B) |
| 59 | |||
| 60 | #define REMAINDER_CONSTANT(version) (version % 10000) | ||
| 61 | #define REMAINDER_ARGS(A, B) (A % B) | ||
| \ No newline at end of file | |||
test/behavior/translate_c_macros.zig+34| ... | @@ -171,3 +171,37 @@ test "Macro that uses division operator. Issue #13162" { | ... | @@ -171,3 +171,37 @@ test "Macro that uses division operator. Issue #13162" { |
| 171 | ), | 171 | ), |
| 172 | ); | 172 | ); |
| 173 | } | 173 | } |
| 174 | |||
| 175 | test "Macro that uses remainder operator. Issue #13346" { | ||
| 176 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | ||
| 177 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | ||
| 178 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | ||
| 179 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | ||
| 180 | |||
| 181 | try expectEqual(@as(c_int, 2_010), h.REMAINDER_CONSTANT(@as(c_int, 42_010))); | ||
| 182 | try expectEqual(@as(c_uint, 2_030), h.REMAINDER_CONSTANT(@as(c_uint, 42_030))); | ||
| 183 | |||
| 184 | try expectEqual( | ||
| 185 | @as(c_int, 7), | ||
| 186 | h.REMAINDER_ARGS( | ||
| 187 | @as(i8, 17), | ||
| 188 | @as(i8, 10), | ||
| 189 | ), | ||
| 190 | ); | ||
| 191 | |||
| 192 | try expectEqual( | ||
| 193 | @as(c_int, 5), | ||
| 194 | h.REMAINDER_ARGS( | ||
| 195 | @as(c_ushort, 25), | ||
| 196 | @as(c_ushort, 20), | ||
| 197 | ), | ||
| 198 | ); | ||
| 199 | |||
| 200 | try expectEqual( | ||
| 201 | @as(c_int, 1), | ||
| 202 | h.REMAINDER_ARGS( | ||
| 203 | @as(c_int, 5), | ||
| 204 | @as(c_int, -2), | ||
| 205 | ), | ||
| 206 | ); | ||
| 207 | } |
test/translate_c.zig+1-1| ... | @@ -511,7 +511,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void { | ... | @@ -511,7 +511,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void { |
| 511 | \\ _ = @as(c_int, 4) == @as(c_int, 4); | 511 | \\ _ = @as(c_int, 4) == @as(c_int, 4); |
| 512 | \\ _ = @as(c_int, 5) * @as(c_int, 6); | 512 | \\ _ = @as(c_int, 5) * @as(c_int, 6); |
| 513 | \\ _ = baz(@as(c_int, 1), @as(c_int, 2)); | 513 | \\ _ = baz(@as(c_int, 1), @as(c_int, 2)); |
| 514 | \\ _ = @as(c_int, 2) % @as(c_int, 2); | 514 | \\ _ = @import("std").zig.c_translation.MacroArithmetic.rem(@as(c_int, 2), @as(c_int, 2)); |
| 515 | \\ break :blk_1 baz(@as(c_int, 1), @as(c_int, 2)); | 515 | \\ break :blk_1 baz(@as(c_int, 1), @as(c_int, 2)); |
| 516 | \\ }; | 516 | \\ }; |
| 517 | \\} | 517 | \\} |