authorgravatar for evan@lagerdata.comEvan Haas <evan@lagerdata.com> 2021-11-20 16:03:16-08:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-11-20 19:52:06-05:00
logc6b4fe00660d00d0748dc01f660ed7ac24f54db0
tree0488f38760efe0c1f8de1955e825de949dc2ecc7
parent4e5a88b28882eda156a46ecc7f70887a7bc0b49b

translate-c: coerce boolean results to c_int when negated

Fixes #10175

2 files changed, 20 insertions(+), 1 deletions(-)

src/translate_c.zig+7-1
...@@ -3648,7 +3648,13 @@ fn transUnaryOperator(c: *Context, scope: *Scope, stmt: *const clang.UnaryOperat...@@ -3648,7 +3648,13 @@ fn transUnaryOperator(c: *Context, scope: *Scope, stmt: *const clang.UnaryOperat
3648 .Plus => return transExpr(c, scope, op_expr, used),3648 .Plus => return transExpr(c, scope, op_expr, used),
3649 .Minus => {3649 .Minus => {
3650 if (!qualTypeHasWrappingOverflow(op_expr.getType())) {3650 if (!qualTypeHasWrappingOverflow(op_expr.getType())) {
3651 return Tag.negate.create(c.arena, try transExpr(c, scope, op_expr, .used));3651 const sub_expr_node = try transExpr(c, scope, op_expr, .used);
3652 const to_negate = if (isBoolRes(sub_expr_node)) blk: {
3653 const ty_node = try Tag.type.create(c.arena, "c_int");
3654 const int_node = try Tag.bool_to_int.create(c.arena, sub_expr_node);
3655 break :blk try Tag.as.create(c.arena, .{ .lhs = ty_node, .rhs = int_node });
3656 } else sub_expr_node;
3657 return Tag.negate.create(c.arena, to_negate);
3652 } else if (cIsUnsignedInteger(op_expr.getType())) {3658 } else if (cIsUnsignedInteger(op_expr.getType())) {
3653 // use -% x for unsigned integers3659 // use -% x for unsigned integers
3654 return Tag.negate_wrap.create(c.arena, try transExpr(c, scope, op_expr, .used));3660 return Tag.negate_wrap.create(c.arena, try transExpr(c, scope, op_expr, .used));
test/run_translated_c.zig+13
...@@ -1796,4 +1796,17 @@ pub fn addCases(cases: *tests.RunTranslatedCContext) void {...@@ -1796,4 +1796,17 @@ pub fn addCases(cases: *tests.RunTranslatedCContext) void {
1796 \\ return 0;1796 \\ return 0;
1797 \\}1797 \\}
1798 , "");1798 , "");
1799
1800 cases.add("Boolean expression coerced to int. Issue #10175",
1801 \\#include <stdlib.h>
1802 \\int sign(int v) {
1803 \\ return -(v < 0);
1804 \\}
1805 \\int main(void) {
1806 \\ if (sign(-5) != -1) abort();
1807 \\ if (sign(5) != 0) abort();
1808 \\ if (sign(0) != 0) abort();
1809 \\ return 0;
1810 \\}
1811 , "");
1799}1812}