Skip to content

Commit

Permalink
Phi._hash_core: Fix crashes caused by None in src_and_vvars. (#259)
Browse files Browse the repository at this point in the history
  • Loading branch information
ltfish authored Nov 12, 2024
1 parent 5b303e5 commit 9a94cb4
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 2 deletions.
14 changes: 12 additions & 2 deletions ailment/expression.py
Original file line number Diff line number Diff line change
Expand Up @@ -333,7 +333,7 @@ def __init__(
self,
idx,
bits,
src_and_vvars: list[tuple[tuple[int, int], VirtualVariable | None]],
src_and_vvars: list[tuple[tuple[int, int | None], VirtualVariable | None]],
**kwargs,
):
super().__init__(idx, **kwargs)
Expand Down Expand Up @@ -390,7 +390,7 @@ def __repr__(self):
__hash__ = TaggedObject.__hash__

def _hash_core(self):
return stable_hash(("phi", self.bits, tuple(sorted(self.src_and_vvars))))
return stable_hash(("phi", self.bits, tuple(sorted(self.src_and_vvars, key=self._src_and_vvar_filter))))

def copy(self) -> Phi:
return Phi(
Expand Down Expand Up @@ -423,6 +423,16 @@ def replace(self, old_expr, new_expr):
)
return False, self

@staticmethod
def _src_and_vvar_filter(
src_and_vvar: tuple[tuple[int, int | None], VirtualVariable | None]
) -> tuple[tuple[int, int], int]:
src, vvar = src_and_vvar
if src[1] is None:
src = src[0], -1
vvar_id = vvar.varid if vvar is not None else -1
return src, vvar_id


class Op(Expression):
__slots__ = ("op",)
Expand Down
21 changes: 21 additions & 0 deletions tests/test_expression.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# pylint: disable=missing-class-docstring,no-self-use
import unittest

import ailment


class TestExpression(unittest.TestCase):

def test_phi_hashing(self):
vvar_0 = ailment.expression.VirtualVariable(100, 0, 32, ailment.expression.VirtualVariableCategory.REGISTER, 16)
vvar_1 = ailment.expression.VirtualVariable(101, 1, 32, ailment.expression.VirtualVariableCategory.REGISTER, 16)
vvar_2 = ailment.expression.VirtualVariable(102, 2, 32, ailment.expression.VirtualVariableCategory.REGISTER, 16)
phi_expr = ailment.expression.Phi(
0, 32, [((0, None), vvar_0), ((0, 0), vvar_2), ((1, None), vvar_1), ((4, None), None)]
)
h = hash(phi_expr) # should not crash
assert h is not None


if __name__ == "__main__":
unittest.main()

0 comments on commit 9a94cb4

Please sign in to comment.