diff --git a/pybind/AE.cpp b/pybind/AE.cpp index d79d181..3c899e3 100644 --- a/pybind/AE.cpp +++ b/pybind/AE.cpp @@ -163,11 +163,11 @@ void bind_abstract_state(py::module& m) { .def("is_int", &IntervalValue::is_int) .def("equals", &IntervalValue::equals, py::arg("other")) .def("eq_interval", [](const IntervalValue &self, const IntervalValue &other) { - return self.operator==(other); - }, py::arg("other")) + return self.operator==(other); + }, py::arg("other")) .def("ne_interval", [](const IntervalValue &self, const IntervalValue &other) { - return self.operator!=(other); - }, py::arg("other")) + return self.operator!=(other); + }, py::arg("other")) .def("getNumeral", &IntervalValue::getNumeral) .def("getIntNumeral", &IntervalValue::getIntNumeral) .def("getRealNumeral", &IntervalValue::getRealNumeral) @@ -394,7 +394,7 @@ void bind_abstract_state(py::module& m) { .def("printAbstractState", &AbstractState::printAbstractState) .def("clone", [](const AbstractState &self) { return std::make_unique(self); // clone - }, py::return_value_policy::move) + }, py::return_value_policy::move) .def("bottom", &AbstractState::bottom) .def("top", &AbstractState::top) .def("inVarToValTable", &AbstractState::inVarToValTable, py::arg("var_id")) diff --git a/pysvf/__init__.py b/pysvf/__init__.py index 246367b..e20a55f 100644 --- a/pysvf/__init__.py +++ b/pysvf/__init__.py @@ -88,7 +88,7 @@ def main(): args = sys.argv[2:] run_svf_tool(tool_name, args) -from .enums import Predicate, OpCode +from .enums import Predicate, OpCode, CopyKind # Import all the module classes and functions from .pysvf import ( releasePAG, diff --git a/pysvf/enums.py b/pysvf/enums.py index 8c144c7..e8706d3 100644 --- a/pysvf/enums.py +++ b/pysvf/enums.py @@ -67,4 +67,21 @@ class PTAType(IntEnum): """Pointer Analysis Types""" Andersen = 0 # Andersen's analysis - Steensgaard = 1 # Steensgaard's analysis \ No newline at end of file + Steensgaard = 1 # Steensgaard's analysis + + +class CopyKind(IntEnum): + """Copy kinds for CopyStmt (mirrors SVF::CopyStmt::CopyKind)""" + + COPYVAL = 0 # Value copies (default one) + ZEXT = 1 # Zero extend integers + SEXT = 2 # Sign extend integers + BITCAST = 3 # Type cast + TRUNC = 4 # Truncate integers + FPTRUNC = 5 # Truncate floating point + FPTOUI = 6 # floating point -> UInt + FPTOSI = 7 # floating point -> SInt + UITOFP = 8 # UInt -> floating point + SITOFP = 9 # SInt -> floating point + INTTOPTR = 10 # Integer -> Pointer + PTRTOINT = 11 # Pointer -> Integer diff --git a/pysvf/pysvf.pyi b/pysvf/pysvf.pyi index 8da22a4..10be21f 100644 --- a/pysvf/pysvf.pyi +++ b/pysvf/pysvf.pyi @@ -1846,16 +1846,18 @@ class IntervalValue: def __init__(self, lb: BoundedInt, ub: BoundedInt) -> None: ... @overload def __init__(self, val: int) -> None: ... - # `__eq__` and `__ne__`'s type annotations are forced as `bool` for all objects, - # use `type: ignore` so that equality operators in C++ and Python are the same - @overload - def __eq__(self, other: 'IntervalValue') -> 'IntervalValue': ... # type: ignore - @overload - def __eq__(self, other: object) -> bool: ... - @overload - def __ne__(self, other: 'IntervalValue') -> 'IntervalValue': ... # type: ignore - @overload - def __ne__(self, other: object) -> bool: ... + def __eq__(self, other: object) -> bool: + """ + Alias for the C++ `IntervalValue::equals`. Python requires the equality operator + to return booleans. + """ + ... + def __ne__(self, other: object) -> bool: + """ + Alias for the C++ `!IntervalValue::equals`. Python requires the inequality operator + to return booleans. + """ + ... def __add__(self, other: 'IntervalValue') -> 'IntervalValue': ... def __sub__(self, other: 'IntervalValue') -> 'IntervalValue': ... def __mul__(self, other: 'IntervalValue') -> 'IntervalValue': ... @@ -1868,9 +1870,9 @@ class IntervalValue: def __and__(self, other: "IntervalValue") -> "IntervalValue": ... def __or__(self, other: "IntervalValue") -> "IntervalValue": ... def __xor__(self, other: "IntervalValue") -> "IntervalValue": ... - def __lshift__(self, bits: int) -> "IntervalValue": ... - def __rshift__(self, bits: int) -> "IntervalValue": ... - def equals(self, other: "IntervalValue") -> "IntervalValue": ... + def __lshift__(self, other: "IntervalValue") -> "IntervalValue": ... + def __rshift__(self, other: "IntervalValue") -> "IntervalValue": ... + def equals(self, other: "IntervalValue") -> bool: ... def lb(self) -> BoundedInt: ... def ub(self) -> BoundedInt: ... def clone(self) -> 'IntervalValue': ... @@ -1894,8 +1896,12 @@ class IntervalValue: def set_to_bottom(self) -> None: ... def set_to_top(self) -> None: ... def toString(self) -> str: ... - def eq_interval(self, other: 'IntervalValue') -> 'IntervalValue': ... - def ne_interval(self, other: 'IntervalValue') -> 'IntervalValue': ... + def eq_interval(self, other: 'IntervalValue') -> 'IntervalValue': + """Alias for the C++ `IntervalValue::operator==`.""" + ... + def ne_interval(self, other: 'IntervalValue') -> 'IntervalValue': + """Alias for the C++ `IntervalValue::operator!=`.""" + ... @staticmethod def top() -> 'IntervalValue': ... @staticmethod @@ -1978,8 +1984,6 @@ class AbstractState: def isVirtualMemAddress(val: int) -> bool: ... @staticmethod def getVirtualMemAddress(idx: int) -> int: ... - def isCmpBranchFeasible(self, cmp: 'CmpStmt', succ: int, abstract_state: AbstractState) -> bool: ... - def isSwitchBranchFeasible(self, switch_var: SVFVar, succ: int, abstract_state: AbstractState) -> bool: ... def inVarToValTable(self, var_id: int) -> bool: ... def inVarToAddrsTable(self, var_id: int) -> bool: ... def inAddrToAddrsTable(self, id: int) -> bool: ...