Skip to content

Commit 0f6fd82

Browse files
authored
[mypyc] ircheck: Check for incompatible signs in int ops (#20685)
This is still a bit lenient, and only the most problematic issues are reported.
1 parent 375ad43 commit 0f6fd82

File tree

1 file changed

+19
-0
lines changed

1 file changed

+19
-0
lines changed

mypyc/analysis/ircheck.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -241,6 +241,10 @@ def expect_non_float(self, op: Op, v: Value) -> None:
241241
if is_float_rprimitive(v.type):
242242
self.fail(op, "Float not expected")
243243

244+
def expect_primitive_type(self, op: Op, v: Value) -> None:
245+
if not isinstance(v.type, RPrimitive):
246+
self.fail(op, f"RPrimitive expected, got {type(v.type).__name__}")
247+
244248
def visit_goto(self, op: Goto) -> None:
245249
self.check_control_op_targets(op)
246250

@@ -397,8 +401,23 @@ def visit_load_global(self, op: LoadGlobal) -> None:
397401
pass
398402

399403
def visit_int_op(self, op: IntOp) -> None:
404+
self.expect_primitive_type(op, op.lhs)
405+
self.expect_primitive_type(op, op.rhs)
400406
self.expect_non_float(op, op.lhs)
401407
self.expect_non_float(op, op.rhs)
408+
left = op.lhs.type
409+
right = op.rhs.type
410+
op_str = op.op_str[op.op]
411+
if (
412+
isinstance(left, RPrimitive)
413+
and isinstance(right, RPrimitive)
414+
and left.is_signed != right.is_signed
415+
and (
416+
op_str in ("+", "-", "*", "/", "%")
417+
or (op_str not in ("<<", ">>") and left.size != right.size)
418+
)
419+
):
420+
self.fail(op, f"Operand types have incompatible signs: {op.lhs.type}, {op.rhs.type}")
402421

403422
def visit_comparison_op(self, op: ComparisonOp) -> None:
404423
self.check_compatibility(op, op.lhs.type, op.rhs.type)

0 commit comments

Comments
 (0)