mirror of
https://github.com/ziglang/zig.git
synced 2026-02-17 14:59:14 +00:00
Translate-c fix rhs not cast on array access
Closes #5671. Checks if the rhs is integral and of differing or the same signedness. If they are different does an @intCast to the lhs type
This commit is contained in:
parent
8b82c40104
commit
70cc1751ca
@ -3268,7 +3268,14 @@ fn transCreateCompoundAssign(
|
||||
const lhs = ZigClangCompoundAssignOperator_getLHS(stmt);
|
||||
const rhs = ZigClangCompoundAssignOperator_getRHS(stmt);
|
||||
const loc = ZigClangCompoundAssignOperator_getBeginLoc(stmt);
|
||||
const is_signed = cIsSignedInteger(getExprQualType(rp.c, lhs));
|
||||
const lhs_qt = getExprQualType(rp.c, lhs);
|
||||
const rhs_qt = getExprQualType(rp.c, rhs);
|
||||
const is_signed = cIsSignedInteger(lhs_qt);
|
||||
const requires_int_cast = blk: {
|
||||
const are_integers = cIsInteger(lhs_qt) and cIsInteger(rhs_qt);
|
||||
const are_same_sign = cIsSignedInteger(lhs_qt) == cIsSignedInteger(rhs_qt);
|
||||
break :blk are_integers and !are_same_sign;
|
||||
};
|
||||
if (used == .unused) {
|
||||
// common case
|
||||
// c: lhs += rhs
|
||||
@ -3295,15 +3302,18 @@ fn transCreateCompoundAssign(
|
||||
|
||||
const lhs_node = try transExpr(rp, scope, lhs, .used, .l_value);
|
||||
const eq_token = try appendToken(rp.c, assign_tok_id, assign_bytes);
|
||||
var rhs_node = if (is_shift)
|
||||
var rhs_node = if (is_shift or requires_int_cast)
|
||||
try transExprCoercing(rp, scope, rhs, .used, .r_value)
|
||||
else
|
||||
try transExpr(rp, scope, rhs, .used, .r_value);
|
||||
|
||||
if (is_shift) {
|
||||
if (is_shift or requires_int_cast) {
|
||||
const cast_node = try rp.c.createBuiltinCall("@intCast", 2);
|
||||
const rhs_type = try qualTypeToLog2IntRef(rp, getExprQualType(rp.c, rhs), loc);
|
||||
cast_node.params()[0] = rhs_type;
|
||||
const cast_to_type = if (is_shift)
|
||||
try qualTypeToLog2IntRef(rp, getExprQualType(rp.c, rhs), loc)
|
||||
else
|
||||
try transQualType(rp, getExprQualType(rp.c, lhs), loc);
|
||||
cast_node.params()[0] = cast_to_type;
|
||||
_ = try appendToken(rp.c, .Comma, ",");
|
||||
cast_node.params()[1] = rhs_node;
|
||||
cast_node.rparen_token = try appendToken(rp.c, .RParen, ")");
|
||||
@ -3358,10 +3368,13 @@ fn transCreateCompoundAssign(
|
||||
const bin_token = try appendToken(rp.c, bin_tok_id, bin_bytes);
|
||||
var rhs_node = try transExpr(rp, scope, rhs, .used, .r_value);
|
||||
|
||||
if (is_shift) {
|
||||
if (is_shift or requires_int_cast) {
|
||||
const cast_node = try rp.c.createBuiltinCall("@intCast", 2);
|
||||
const rhs_type = try qualTypeToLog2IntRef(rp, getExprQualType(rp.c, rhs), loc);
|
||||
cast_node.params()[0] = rhs_type;
|
||||
const cast_to_type = if (is_shift)
|
||||
try qualTypeToLog2IntRef(rp, getExprQualType(rp.c, rhs), loc)
|
||||
else
|
||||
try transQualType(rp, getExprQualType(rp.c, lhs), loc);
|
||||
cast_node.params()[0] = cast_to_type;
|
||||
_ = try appendToken(rp.c, .Comma, ",");
|
||||
cast_node.params()[1] = rhs_node;
|
||||
cast_node.rparen_token = try appendToken(rp.c, .RParen, ")");
|
||||
|
||||
@ -268,5 +268,77 @@ pub fn addCases(cases: *tests.RunTranslatedCContext) void {
|
||||
\\ if (count != 4) abort();
|
||||
\\ return 0;
|
||||
\\}
|
||||
,"");
|
||||
, "");
|
||||
|
||||
cases.add("array value type casts properly",
|
||||
\\#include <stdlib.h>
|
||||
\\unsigned int choose[53][10];
|
||||
\\static int hash_binary(int k)
|
||||
\\{
|
||||
\\ choose[0][k] = 3;
|
||||
\\ int sum = 0;
|
||||
\\ sum += choose[0][k];
|
||||
\\ return sum;
|
||||
\\}
|
||||
\\
|
||||
\\int main() {
|
||||
\\ int s = hash_binary(4);
|
||||
\\ if (s != 3) abort();
|
||||
\\ return 0;
|
||||
\\}
|
||||
, "");
|
||||
|
||||
cases.add("array value type casts properly use +=",
|
||||
\\#include <stdlib.h>
|
||||
\\static int hash_binary(int k)
|
||||
\\{
|
||||
\\ unsigned int choose[1][1] = {{3}};
|
||||
\\ int sum = -1;
|
||||
\\ int prev = 0;
|
||||
\\ prev = sum += choose[0][0];
|
||||
\\ if (sum != 2) abort();
|
||||
\\ return sum + prev;
|
||||
\\}
|
||||
\\
|
||||
\\int main() {
|
||||
\\ int x = hash_binary(4);
|
||||
\\ if (x != 4) abort();
|
||||
\\ return 0;
|
||||
\\}
|
||||
, "");
|
||||
|
||||
cases.add("ensure array casts outisde +=",
|
||||
\\#include <stdlib.h>
|
||||
\\static int hash_binary(int k)
|
||||
\\{
|
||||
\\ unsigned int choose[3] = {1, 2, 3};
|
||||
\\ int sum = -2;
|
||||
\\ int prev = sum + choose[k];
|
||||
\\ if (prev != 0) abort();
|
||||
\\ return sum + prev;
|
||||
\\}
|
||||
\\
|
||||
\\int main() {
|
||||
\\ int x = hash_binary(1);
|
||||
\\ if (x != -2) abort();
|
||||
\\ return 0;
|
||||
\\}
|
||||
, "");
|
||||
|
||||
cases.add("array cast int to uint",
|
||||
\\#include <stdlib.h>
|
||||
\\static unsigned int hash_binary(int k)
|
||||
\\{
|
||||
\\ int choose[3] = {-1, -2, 3};
|
||||
\\ unsigned int sum = 2;
|
||||
\\ sum += choose[k];
|
||||
\\ return sum;
|
||||
\\}
|
||||
\\
|
||||
\\int main() {
|
||||
\\ unsigned int x = hash_binary(1);
|
||||
\\ if (x != 0) abort();
|
||||
\\ return 0;
|
||||
\\}
|
||||
, "");
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user