Merge branch 'dev' into dev-ssa

pull/87/head
Josselin 6 years ago
commit c2a541b92d
  1. 47
      slither/slithir/convert.py
  2. 9
      slither/slithir/operations/call.py
  3. 10
      slither/slithir/operations/init_array.py
  4. 9
      slither/slithir/operations/operation.py
  5. 12
      slither/slithir/operations/return_operation.py

@ -156,12 +156,23 @@ def propage_type_and_convert_call(result, node):
new_ins = propagate_types(ins, node)
if new_ins:
if isinstance(new_ins, (list,)):
assert len(new_ins) == 2
new_ins[0].set_node(ins.node)
new_ins[1].set_node(ins.node)
result.insert(idx, new_ins[0])
result.insert(idx+1, new_ins[1])
idx = idx + 1
if len(new_ins) == 2:
new_ins[0].set_node(ins.node)
new_ins[1].set_node(ins.node)
del result[idx]
result.insert(idx, new_ins[0])
result.insert(idx+1, new_ins[1])
idx = idx + 1
else:
assert len(new_ins) == 3
new_ins[0].set_node(ins.node)
new_ins[1].set_node(ins.node)
new_ins[2].set_node(ins.node)
del result[idx]
result.insert(idx, new_ins[0])
result.insert(idx+1, new_ins[1])
result.insert(idx+2, new_ins[2])
idx = idx + 2
else:
new_ins.set_node(ins.node)
result[idx] = new_ins
@ -220,8 +231,12 @@ def convert_to_push(ir, node):
The checks must be done by the caller
May necessitate to create an intermediate operation (InitArray)
Necessitate to return the lenght (see push documentation)
As a result, the function return may return a list
"""
lvalue = ir.lvalue
if isinstance(ir.arguments[0], list):
ret = []
@ -236,9 +251,25 @@ def convert_to_push(ir, node):
ir.lvalue.set_type(ArrayType(t, length))
ret.append(ir)
if lvalue:
length = Length(ir.array, lvalue)
length.lvalue.points_to = ir.lvalue
ret.append(length)
return ret
ir = Push(ir.destination, ir.arguments[0])
if lvalue:
ret = []
ret.append(ir)
length = Length(ir.array, lvalue)
length.lvalue.points_to = ir.lvalue
ret.append(length)
return ret
return ir
def look_for_library(contract, ir, node, using_for, t):
@ -472,11 +503,11 @@ def propagate_types(ir, node):
assert False
elif isinstance(ir, Member):
# TODO we should convert the reference to a temporary if the member is a length or a balance
if ir.variable_right == 'length' and isinstance(ir.variable_left.type, (ElementaryType, ArrayType)):
if ir.variable_right == 'length' and not isinstance(ir.variable_left, Contract) and isinstance(ir.variable_left.type, (ElementaryType, ArrayType)):
length = Length(ir.variable_left, ir.lvalue)
ir.lvalue.points_to = ir.variable_left
return ir
if ir.variable_right == 'balance' and isinstance(ir.variable_left.type, ElementaryType):
if ir.variable_right == 'balance'and not isinstance(ir.variable_left, Contract) and isinstance(ir.variable_left.type, ElementaryType):
return Balance(ir.variable_left, ir.lvalue)
left = ir.variable_left
if isinstance(left, (Variable, SolidityVariable)):

@ -15,12 +15,3 @@ class Call(Operation):
def arguments(self, v):
self._arguments = v
# if array inside the parameters
def _unroll(self, l):
ret = []
for x in l:
if not isinstance(x, list):
ret += [x]
else:
ret += self._unroll(x)
return ret

@ -21,16 +21,6 @@ class InitArray(OperationWithLValue):
self._init_values = init_values
self._lvalue = lvalue
# if array inside the init values
def _unroll(self, l):
ret = []
for x in l:
if not isinstance(x, list):
ret += [x]
else:
ret += self._unroll(x)
return ret
@property
def read(self):
return self._unroll(self.init_values)

@ -29,3 +29,12 @@ class Operation(Context, ChildNode, AbstractOperation):
"""
return self.read
# if array inside the parameters
def _unroll(self, l):
ret = []
for x in l:
if not isinstance(x, list):
ret += [x]
else:
ret += self._unroll(x)
return ret

@ -18,14 +18,20 @@ class Return(Operation):
else:
values = [values]
else:
for value in values:
assert is_valid_rvalue(value) or isinstance(value, TupleVariable)
self._valid_value(values)
super(Return, self).__init__()
self._values = values
def _valid_value(self, value):
if isinstance(value, list):
assert all(self._valid_value(v) for v in value)
else:
assert is_valid_rvalue(value) or isinstance(value, TupleVariable)
return True
@property
def read(self):
return self.values
return self._unroll(self.values)
@property
def values(self):

Loading…
Cancel
Save