aboutsummaryrefslogtreecommitdiff
path: root/src-self-hosted
diff options
context:
space:
mode:
authorIan Simonson <ian.simonson@protonmail.com>2020-04-30 08:38:36 +1000
committerIan Simonson <ian.simonson@protonmail.com>2020-04-30 12:48:27 +1000
commite6fa0beb335ad8ecff005fef924c2a39ed748c56 (patch)
tree51d8dbed193e84d0c0e5843be5acf35ce141b359 /src-self-hosted
parenta08675723cd39e3001327aa52b8af4b1c7bb0f32 (diff)
downloadzig-e6fa0beb335ad8ecff005fef924c2a39ed748c56.tar.gz
zig-e6fa0beb335ad8ecff005fef924c2a39ed748c56.zip
Translate-C convert bools to int in complex expressions
Pre-requisite for having a test case for #5062 In complex C statements which are outside of macros, it is valid C to perform e.g. a bitor between an integer and a boolean `5 | (8 == 9)` Currently this results in a zig error after translating as `c_int | bool` is invalid Zig. Detects if a sub-expression of a numeric operator is boolean and if so converts it to int
Diffstat (limited to 'src-self-hosted')
-rw-r--r--src-self-hosted/translate_c.zig32
1 files changed, 31 insertions, 1 deletions
diff --git a/src-self-hosted/translate_c.zig b/src-self-hosted/translate_c.zig
index c821eb1ac3..e4a41f75e7 100644
--- a/src-self-hosted/translate_c.zig
+++ b/src-self-hosted/translate_c.zig
@@ -1293,7 +1293,37 @@ fn transBinaryOperator(
}
const rhs_node = try transExpr(rp, scope, ZigClangBinaryOperator_getRHS(stmt), .used, .r_value);
- return transCreateNodeInfixOp(rp, scope, lhs_node, op_id, op_token, rhs_node, result_used, true);
+
+ const is_lhs_bool = isBoolRes(lhs_node);
+ const is_rhs_bool = isBoolRes(rhs_node);
+
+ if (!is_lhs_bool and !is_rhs_bool) {
+ return transCreateNodeInfixOp(rp, scope, lhs_node, op_id, op_token, rhs_node, result_used, true);
+ }
+
+ const lhs = if (is_lhs_bool) init: {
+ const cast_node = try transCreateNodeBuiltinFnCall(rp.c, "@boolToInt");
+ try cast_node.params.push(lhs_node);
+ cast_node.rparen_token = try appendToken(rp.c, .RParen, ")");
+ break :init &cast_node.base;
+ } else lhs_node;
+
+ const rhs = if (is_rhs_bool) init: {
+ const cast_node = try transCreateNodeBuiltinFnCall(rp.c, "@boolToInt");
+ try cast_node.params.push(rhs_node);
+ cast_node.rparen_token = try appendToken(rp.c, .RParen, ")");
+ break :init &cast_node.base;
+ } else rhs_node;
+
+ const node = try rp.c.a().create(ast.Node.InfixOp);
+
+ node.* = .{
+ .op_token = op_token,
+ .lhs = lhs,
+ .op = op_id,
+ .rhs = rhs,
+ };
+ return maybeSuppressResult(rp, scope, result_used, &node.base);
}
fn transCompoundStmtInline(