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 intmaster
parent
a08675723c
commit
e6fa0beb33
|
@ -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(
|
||||
|
|
|
@ -195,4 +195,52 @@ pub fn addCases(cases: *tests.RunTranslatedCContext) void {
|
|||
\\ return 0;
|
||||
\\}
|
||||
, "");
|
||||
|
||||
cases.add("case boolean expression converted to int",
|
||||
\\#include <stdlib.h>
|
||||
\\int main(int argc, char **argv) {
|
||||
\\ int value = 1 + 2 * 3 + 4 * 5 + 6 << 7 | 8 == 9;
|
||||
\\ if (value != 4224) abort();
|
||||
\\ return 0;
|
||||
\\}
|
||||
, "");
|
||||
|
||||
cases.add("case boolean expression on left converted to int",
|
||||
\\#include <stdlib.h>
|
||||
\\int main(int argc, char **argv) {
|
||||
\\ int value = 8 == 9 | 1 + 2 * 3 + 4 * 5 + 6 << 7;
|
||||
\\ if (value != 4224) abort();
|
||||
\\ return 0;
|
||||
\\}
|
||||
, "");
|
||||
|
||||
cases.add("case boolean and operator+ converts bool to int",
|
||||
\\#include <stdlib.h>
|
||||
\\int main(int argc, char **argv) {
|
||||
\\ int value = (8 == 9) + 3;
|
||||
\\ int value2 = 3 + (8 == 9);
|
||||
\\ if (value != value2) abort();
|
||||
\\ return 0;
|
||||
\\}
|
||||
, "");
|
||||
|
||||
cases.add("case boolean and operator<",
|
||||
\\#include <stdlib.h>
|
||||
\\int main(int argc, char **argv) {
|
||||
\\ int value = (8 == 9) < 3;
|
||||
\\ if (value == 0) abort();
|
||||
\\ return 0;
|
||||
\\}
|
||||
, "");
|
||||
|
||||
cases.add("case boolean and operator*",
|
||||
\\#include <stdlib.h>
|
||||
\\int main(int argc, char **argv) {
|
||||
\\ int value = (8 == 9) * 3;
|
||||
\\ int value2 = 3 * (9 == 9);
|
||||
\\ if (value != 0) abort();
|
||||
\\ if (value2 == 0) abort();
|
||||
\\ return 0;
|
||||
\\}
|
||||
, "");
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue