| ... | @@ -3268,7 +3268,14 @@ fn transCreateCompoundAssign( | ... | @@ -3268,7 +3268,14 @@ fn transCreateCompoundAssign( |
| 3268 | const lhs = ZigClangCompoundAssignOperator_getLHS(stmt); | 3268 | const lhs = ZigClangCompoundAssignOperator_getLHS(stmt); |
| 3269 | const rhs = ZigClangCompoundAssignOperator_getRHS(stmt); | 3269 | const rhs = ZigClangCompoundAssignOperator_getRHS(stmt); |
| 3270 | const loc = ZigClangCompoundAssignOperator_getBeginLoc(stmt); | 3270 | const loc = ZigClangCompoundAssignOperator_getBeginLoc(stmt); |
| 3271 | const is_signed = cIsSignedInteger(getExprQualType(rp.c, lhs)); | 3271 | const lhs_qt = getExprQualType(rp.c, lhs); |
| | 3272 | const rhs_qt = getExprQualType(rp.c, rhs); |
| | 3273 | const is_signed = cIsSignedInteger(lhs_qt); |
| | 3274 | const requires_int_cast = blk: { |
| | 3275 | const are_integers = cIsInteger(lhs_qt) and cIsInteger(rhs_qt); |
| | 3276 | const are_same_sign = cIsSignedInteger(lhs_qt) == cIsSignedInteger(rhs_qt); |
| | 3277 | break :blk are_integers and !are_same_sign; |
| | 3278 | }; |
| 3272 | if (used == .unused) { | 3279 | if (used == .unused) { |
| 3273 | // common case | 3280 | // common case |
| 3274 | // c: lhs += rhs | 3281 | // c: lhs += rhs |
| ... | @@ -3295,15 +3302,18 @@ fn transCreateCompoundAssign( | ... | @@ -3295,15 +3302,18 @@ fn transCreateCompoundAssign( |
| 3295 | | 3302 | |
| 3296 | const lhs_node = try transExpr(rp, scope, lhs, .used, .l_value); | 3303 | const lhs_node = try transExpr(rp, scope, lhs, .used, .l_value); |
| 3297 | const eq_token = try appendToken(rp.c, assign_tok_id, assign_bytes); | 3304 | const eq_token = try appendToken(rp.c, assign_tok_id, assign_bytes); |
| 3298 | var rhs_node = if (is_shift) | 3305 | var rhs_node = if (is_shift or requires_int_cast) |
| 3299 | try transExprCoercing(rp, scope, rhs, .used, .r_value) | 3306 | try transExprCoercing(rp, scope, rhs, .used, .r_value) |
| 3300 | else | 3307 | else |
| 3301 | try transExpr(rp, scope, rhs, .used, .r_value); | 3308 | try transExpr(rp, scope, rhs, .used, .r_value); |
| 3302 | | 3309 | |
| 3303 | if (is_shift) { | 3310 | if (is_shift or requires_int_cast) { |
| 3304 | const cast_node = try rp.c.createBuiltinCall("@intCast", 2); | 3311 | const cast_node = try rp.c.createBuiltinCall("@intCast", 2); |
| 3305 | const rhs_type = try qualTypeToLog2IntRef(rp, getExprQualType(rp.c, rhs), loc); | 3312 | const cast_to_type = if (is_shift) |
| 3306 | cast_node.params()[0] = rhs_type; | 3313 | try qualTypeToLog2IntRef(rp, getExprQualType(rp.c, rhs), loc) |
| | 3314 | else |
| | 3315 | try transQualType(rp, getExprQualType(rp.c, lhs), loc); |
| | 3316 | cast_node.params()[0] = cast_to_type; |
| 3307 | _ = try appendToken(rp.c, .Comma, ","); | 3317 | _ = try appendToken(rp.c, .Comma, ","); |
| 3308 | cast_node.params()[1] = rhs_node; | 3318 | cast_node.params()[1] = rhs_node; |
| 3309 | cast_node.rparen_token = try appendToken(rp.c, .RParen, ")"); | 3319 | cast_node.rparen_token = try appendToken(rp.c, .RParen, ")"); |
| ... | @@ -3358,10 +3368,13 @@ fn transCreateCompoundAssign( | ... | @@ -3358,10 +3368,13 @@ fn transCreateCompoundAssign( |
| 3358 | const bin_token = try appendToken(rp.c, bin_tok_id, bin_bytes); | 3368 | const bin_token = try appendToken(rp.c, bin_tok_id, bin_bytes); |
| 3359 | var rhs_node = try transExpr(rp, scope, rhs, .used, .r_value); | 3369 | var rhs_node = try transExpr(rp, scope, rhs, .used, .r_value); |
| 3360 | | 3370 | |
| 3361 | if (is_shift) { | 3371 | if (is_shift or requires_int_cast) { |
| 3362 | const cast_node = try rp.c.createBuiltinCall("@intCast", 2); | 3372 | const cast_node = try rp.c.createBuiltinCall("@intCast", 2); |
| 3363 | const rhs_type = try qualTypeToLog2IntRef(rp, getExprQualType(rp.c, rhs), loc); | 3373 | const cast_to_type = if (is_shift) |
| 3364 | cast_node.params()[0] = rhs_type; | 3374 | try qualTypeToLog2IntRef(rp, getExprQualType(rp.c, rhs), loc) |
| | 3375 | else |
| | 3376 | try transQualType(rp, getExprQualType(rp.c, lhs), loc); |
| | 3377 | cast_node.params()[0] = cast_to_type; |
| 3365 | _ = try appendToken(rp.c, .Comma, ","); | 3378 | _ = try appendToken(rp.c, .Comma, ","); |
| 3366 | cast_node.params()[1] = rhs_node; | 3379 | cast_node.params()[1] = rhs_node; |
| 3367 | cast_node.rparen_token = try appendToken(rp.c, .RParen, ")"); | 3380 | cast_node.rparen_token = try appendToken(rp.c, .RParen, ")"); |