support parenthetical ternary expr and update tests

pull/1501/head
alpharush 2 years ago
parent eb49e396fd
commit a1a0abe17d
  1. 7
      slither/utils/expression_manipulations.py
  2. 21
      tests/slithir/ternary_expressions.sol
  3. 6
      tests/slithir/test_ternary_expressions.py

@ -68,6 +68,13 @@ class SplitTernaryExpression:
false_expression: Union[AssignmentOperation, MemberAccess],
f: Callable,
) -> bool:
# parentetical expression (.. ? .. : ..)
if (
isinstance(next_expr, TupleExpression)
and len(next_expr.expressions) == 1
and isinstance(next_expr.expressions[0], ConditionalExpression)
):
next_expr = next_expr.expressions[0]
if isinstance(next_expr, ConditionalExpression):
f(true_expression, copy.copy(next_expr.then_expression))

@ -1,5 +1,6 @@
interface NameReg {
function addressOf() external payable;
interface Test {
function test() external payable returns (uint);
function testTuple() external payable returns (uint, uint);
}
contract C {
// TODO
@ -26,10 +27,16 @@ contract C {
}
function e(address one, address two) public {
return NameReg(one).addressOf{value: msg.sender == two ? 1 : 2, gas: true ? 2 : gasleft()}();
uint x = Test(one).test{value: msg.sender == two ? 1 : 2, gas: true ? 2 : gasleft()}();
}
// Parenthteical expression
function f(address one, address two) public {
uint x = Test(one).test{value: msg.sender == two ? 1 : 2, gas: true ? (1 == 1 ? 1 : 2) : gasleft()}();
}
// Unused tuple variable
function g(address one) public {
(, uint x) = Test(one).testTuple();
}
// TODO: nested ternary
// function f(address one, address two) public {
// return NameReg(one).addressOf{value: msg.sender == two ? 1 : 2, gas: true ? (1 == 1 ? 1 : 2) : gasleft()}();
// }
}

@ -9,10 +9,10 @@ def test_ternary_conversions() -> None:
slither = Slither("./tests/slithir/ternary_expressions.sol")
for contract in slither.contracts:
for function in contract.functions:
vars_declared = 0
vars_assigned = 0
for node in function.nodes:
if node.type in [NodeType.IF, NodeType.IFLOOP]:
vars_declared = 0
vars_assigned = 0
# Iterate over true and false son
for inner_node in node.sons:
@ -31,7 +31,7 @@ def test_ternary_conversions() -> None:
if isinstance(ir, Assignment):
vars_assigned += 1
assert vars_declared == vars_assigned
assert vars_declared == vars_assigned
if __name__ == "__main__":

Loading…
Cancel
Save