| ... | @@ -3197,43 +3197,34 @@ fn transCreateCompoundAssign( | ... | @@ -3197,43 +3197,34 @@ fn transCreateCompoundAssign( |
| 3197 | const requires_int_cast = blk: { | 3197 | const requires_int_cast = blk: { |
| 3198 | const are_integers = cIsInteger(lhs_qt) and cIsInteger(rhs_qt); | 3198 | const are_integers = cIsInteger(lhs_qt) and cIsInteger(rhs_qt); |
| 3199 | const are_same_sign = cIsSignedInteger(lhs_qt) == cIsSignedInteger(rhs_qt); | 3199 | const are_same_sign = cIsSignedInteger(lhs_qt) == cIsSignedInteger(rhs_qt); |
| 3200 | break :blk are_integers and !are_same_sign; | 3200 | break :blk are_integers and !(are_same_sign and cIntTypeCmp(lhs_qt, rhs_qt) == .eq); |
| 3201 | }; | 3201 | }; |
| | 3202 | |
| 3202 | if (used == .unused) { | 3203 | if (used == .unused) { |
| 3203 | // common case | 3204 | // common case |
| 3204 | // c: lhs += rhs | 3205 | // c: lhs += rhs |
| 3205 | // zig: lhs += rhs | 3206 | // zig: lhs += rhs |
| | 3207 | const lhs_node = try transExpr(c, scope, lhs, .used); |
| | 3208 | var rhs_node = try transExpr(c, scope, rhs, .used); |
| | 3209 | if (is_ptr_op_signed) rhs_node = try usizeCastForWrappingPtrArithmetic(c.arena, rhs_node); |
| | 3210 | |
| 3206 | if ((is_mod or is_div) and is_signed) { | 3211 | if ((is_mod or is_div) and is_signed) { |
| 3207 | const lhs_node = try transExpr(c, scope, lhs, .used); | 3212 | if (requires_int_cast) rhs_node = try transCCast(c, scope, loc, lhs_qt, rhs_qt, rhs_node); |
| 3208 | const rhs_node = try transExpr(c, scope, rhs, .used); | 3213 | const operands = .{ .lhs = lhs_node, .rhs = rhs_node }; |
| 3209 | const builtin = if (is_mod) | 3214 | const builtin = if (is_mod) |
| 3210 | try Tag.rem.create(c.arena, .{ .lhs = lhs_node, .rhs = rhs_node }) | 3215 | try Tag.rem.create(c.arena, operands) |
| 3211 | else | 3216 | else |
| 3212 | try Tag.div_trunc.create(c.arena, .{ .lhs = lhs_node, .rhs = rhs_node }); | 3217 | try Tag.div_trunc.create(c.arena, operands); |
| 3213 | | 3218 | |
| 3214 | return transCreateNodeInfixOp(c, scope, .assign, lhs_node, builtin, .used); | 3219 | return transCreateNodeInfixOp(c, scope, .assign, lhs_node, builtin, .used); |
| 3215 | } | 3220 | } |
| 3216 | | 3221 | |
| 3217 | const lhs_node = try transExpr(c, scope, lhs, .used); | 3222 | if (is_shift) { |
| 3218 | var rhs_node = if (is_shift or requires_int_cast) | 3223 | const cast_to_type = try qualTypeToLog2IntRef(c, scope, rhs_qt, loc); |
| 3219 | try transExprCoercing(c, scope, rhs, .used) | | |
| 3220 | else | | |
| 3221 | try transExpr(c, scope, rhs, .used); | | |
| 3222 | | | |
| 3223 | if (is_ptr_op_signed) { | | |
| 3224 | rhs_node = try usizeCastForWrappingPtrArithmetic(c.arena, rhs_node); | | |
| 3225 | } | | |
| 3226 | | | |
| 3227 | if (is_shift or requires_int_cast) { | | |
| 3228 | // @intCast(rhs) | | |
| 3229 | const cast_to_type = if (is_shift) | | |
| 3230 | try qualTypeToLog2IntRef(c, scope, getExprQualType(c, rhs), loc) | | |
| 3231 | else | | |
| 3232 | try transQualType(c, scope, getExprQualType(c, lhs), loc); | | |
| 3233 | | | |
| 3234 | rhs_node = try Tag.int_cast.create(c.arena, .{ .lhs = cast_to_type, .rhs = rhs_node }); | 3224 | rhs_node = try Tag.int_cast.create(c.arena, .{ .lhs = cast_to_type, .rhs = rhs_node }); |
| | 3225 | } else if (requires_int_cast) { |
| | 3226 | rhs_node = try transCCast(c, scope, loc, lhs_qt, rhs_qt, rhs_node); |
| 3235 | } | 3227 | } |
| 3236 | | | |
| 3237 | return transCreateNodeInfixOp(c, scope, op, lhs_node, rhs_node, .used); | 3228 | return transCreateNodeInfixOp(c, scope, op, lhs_node, rhs_node, .used); |
| 3238 | } | 3229 | } |
| 3239 | // worst case | 3230 | // worst case |
| ... | @@ -3255,29 +3246,24 @@ fn transCreateCompoundAssign( | ... | @@ -3255,29 +3246,24 @@ fn transCreateCompoundAssign( |
| 3255 | const lhs_node = try Tag.identifier.create(c.arena, ref); | 3246 | const lhs_node = try Tag.identifier.create(c.arena, ref); |
| 3256 | const ref_node = try Tag.deref.create(c.arena, lhs_node); | 3247 | const ref_node = try Tag.deref.create(c.arena, lhs_node); |
| 3257 | | 3248 | |
| | 3249 | var rhs_node = try transExpr(c, &block_scope.base, rhs, .used); |
| | 3250 | if (is_ptr_op_signed) rhs_node = try usizeCastForWrappingPtrArithmetic(c.arena, rhs_node); |
| 3258 | if ((is_mod or is_div) and is_signed) { | 3251 | if ((is_mod or is_div) and is_signed) { |
| 3259 | const rhs_node = try transExpr(c, &block_scope.base, rhs, .used); | 3252 | if (requires_int_cast) rhs_node = try transCCast(c, scope, loc, lhs_qt, rhs_qt, rhs_node); |
| | 3253 | const operands = .{ .lhs = ref_node, .rhs = rhs_node }; |
| 3260 | const builtin = if (is_mod) | 3254 | const builtin = if (is_mod) |
| 3261 | try Tag.rem.create(c.arena, .{ .lhs = ref_node, .rhs = rhs_node }) | 3255 | try Tag.rem.create(c.arena, operands) |
| 3262 | else | 3256 | else |
| 3263 | try Tag.div_trunc.create(c.arena, .{ .lhs = ref_node, .rhs = rhs_node }); | 3257 | try Tag.div_trunc.create(c.arena, operands); |
| 3264 | | 3258 | |
| 3265 | const assign = try transCreateNodeInfixOp(c, &block_scope.base, .assign, ref_node, builtin, .used); | 3259 | const assign = try transCreateNodeInfixOp(c, &block_scope.base, .assign, ref_node, builtin, .used); |
| 3266 | try block_scope.statements.append(assign); | 3260 | try block_scope.statements.append(assign); |
| 3267 | } else { | 3261 | } else { |
| 3268 | var rhs_node = try transExpr(c, &block_scope.base, rhs, .used); | 3262 | if (is_shift) { |
| 3269 | | 3263 | const cast_to_type = try qualTypeToLog2IntRef(c, &block_scope.base, rhs_qt, loc); |
| 3270 | if (is_shift or requires_int_cast) { | | |
| 3271 | // @intCast(rhs) | | |
| 3272 | const cast_to_type = if (is_shift) | | |
| 3273 | try qualTypeToLog2IntRef(c, scope, getExprQualType(c, rhs), loc) | | |
| 3274 | else | | |
| 3275 | try transQualType(c, scope, getExprQualType(c, lhs), loc); | | |
| 3276 | | | |
| 3277 | rhs_node = try Tag.int_cast.create(c.arena, .{ .lhs = cast_to_type, .rhs = rhs_node }); | 3264 | rhs_node = try Tag.int_cast.create(c.arena, .{ .lhs = cast_to_type, .rhs = rhs_node }); |
| 3278 | } | 3265 | } else if (requires_int_cast) { |
| 3279 | if (is_ptr_op_signed) { | 3266 | rhs_node = try transCCast(c, &block_scope.base, loc, lhs_qt, rhs_qt, rhs_node); |
| 3280 | rhs_node = try usizeCastForWrappingPtrArithmetic(c.arena, rhs_node); | | |
| 3281 | } | 3267 | } |
| 3282 | | 3268 | |
| 3283 | const assign = try transCreateNodeInfixOp(c, &block_scope.base, op, ref_node, rhs_node, .used); | 3269 | const assign = try transCreateNodeInfixOp(c, &block_scope.base, op, ref_node, rhs_node, .used); |