From c6b4fe00660d00d0748dc01f660ed7ac24f54db0 Mon Sep 17 00:00:00 2001 From: Evan Haas Date: Sat, 20 Nov 2021 16:03:16 -0800 Subject: [PATCH] translate-c: coerce boolean results to c_int when negated Fixes #10175 --- src/translate_c.zig | 8 +++++++- test/run_translated_c.zig | 13 +++++++++++++ 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/src/translate_c.zig b/src/translate_c.zig index 5358154e5d..b76bb59300 100644 --- a/src/translate_c.zig +++ b/src/translate_c.zig @@ -3648,7 +3648,13 @@ fn transUnaryOperator(c: *Context, scope: *Scope, stmt: *const clang.UnaryOperat .Plus => return transExpr(c, scope, op_expr, used), .Minus => { if (!qualTypeHasWrappingOverflow(op_expr.getType())) { - return Tag.negate.create(c.arena, try transExpr(c, scope, op_expr, .used)); + const sub_expr_node = try transExpr(c, scope, op_expr, .used); + const to_negate = if (isBoolRes(sub_expr_node)) blk: { + const ty_node = try Tag.type.create(c.arena, "c_int"); + const int_node = try Tag.bool_to_int.create(c.arena, sub_expr_node); + break :blk try Tag.as.create(c.arena, .{ .lhs = ty_node, .rhs = int_node }); + } else sub_expr_node; + return Tag.negate.create(c.arena, to_negate); } else if (cIsUnsignedInteger(op_expr.getType())) { // use -% x for unsigned integers return Tag.negate_wrap.create(c.arena, try transExpr(c, scope, op_expr, .used)); diff --git a/test/run_translated_c.zig b/test/run_translated_c.zig index 147b7544a3..99ff869b11 100644 --- a/test/run_translated_c.zig +++ b/test/run_translated_c.zig @@ -1796,4 +1796,17 @@ pub fn addCases(cases: *tests.RunTranslatedCContext) void { \\ return 0; \\} , ""); + + cases.add("Boolean expression coerced to int. Issue #10175", + \\#include + \\int sign(int v) { + \\ return -(v < 0); + \\} + \\int main(void) { + \\ if (sign(-5) != -1) abort(); + \\ if (sign(5) != 0) abort(); + \\ if (sign(0) != 0) abort(); + \\ return 0; + \\} + , ""); }