Fix ir for top level function

pull/1378/head
Simone 2 years ago
parent 90520c591b
commit cc3b342d51
  1. 29
      slither/slithir/convert.py

@ -15,6 +15,7 @@ from slither.core.declarations import (
) )
from slither.core.declarations.custom_error import CustomError from slither.core.declarations.custom_error import CustomError
from slither.core.declarations.function_contract import FunctionContract from slither.core.declarations.function_contract import FunctionContract
from slither.core.declarations.function_top_level import FunctionTopLevel
from slither.core.declarations.solidity_import_placeholder import SolidityImportPlaceHolder from slither.core.declarations.solidity_import_placeholder import SolidityImportPlaceHolder
from slither.core.declarations.solidity_variables import SolidityCustomRevert from slither.core.declarations.solidity_variables import SolidityCustomRevert
from slither.core.expressions import Identifier, Literal from slither.core.expressions import Identifier, Literal
@ -527,9 +528,9 @@ def propagate_types(ir, node: "Node"): # pylint: disable=too-many-locals
if can_be_solidity_func(ir): if can_be_solidity_func(ir):
return convert_to_solidity_func(ir) return convert_to_solidity_func(ir)
# convert library # convert library or top level function
if t in using_for or "*" in using_for: if t in using_for or "*" in using_for:
new_ir = convert_to_library(ir, node, using_for) new_ir = convert_to_library_or_top_level(ir, node, using_for)
if new_ir: if new_ir:
return new_ir return new_ir
@ -1331,8 +1332,24 @@ def convert_to_pop(ir, node):
return ret return ret
def look_for_library(contract, ir, using_for, t): def look_for_library_or_top_level(contract, ir, using_for, t):
for destination in using_for[t]: for destination in using_for[t]:
if isinstance(destination, FunctionTopLevel) and destination.name == ir.function_name:
internalcall = InternalCall(destination, ir.nbr_arguments, ir.lvalue, ir.type_call)
internalcall.set_expression(ir.expression)
internalcall.set_node(ir.node)
internalcall.call_gas = ir.call_gas
internalcall.arguments = [ir.destination] + ir.arguments
return_type = internalcall.function.return_type
if return_type:
if len(return_type) == 1:
internalcall.lvalue.set_type(return_type[0])
elif len(return_type) > 1:
internalcall.lvalue.set_type(return_type)
else:
internalcall.lvalue = None
return internalcall
if isinstance(destination, FunctionContract) and destination.contract.is_library: if isinstance(destination, FunctionContract) and destination.contract.is_library:
lib_contract = destination.contract lib_contract = destination.contract
else: else:
@ -1356,19 +1373,19 @@ def look_for_library(contract, ir, using_for, t):
return None return None
def convert_to_library(ir, node, using_for): def convert_to_library_or_top_level(ir, node, using_for):
# We use contract_declarer, because Solidity resolve the library # We use contract_declarer, because Solidity resolve the library
# before resolving the inheritance. # before resolving the inheritance.
# Though we could use .contract as libraries cannot be shadowed # Though we could use .contract as libraries cannot be shadowed
contract = node.function.contract_declarer contract = node.function.contract_declarer
t = ir.destination.type t = ir.destination.type
if t in using_for: if t in using_for:
new_ir = look_for_library(contract, ir, using_for, t) new_ir = look_for_library_or_top_level(contract, ir, using_for, t)
if new_ir: if new_ir:
return new_ir return new_ir
if "*" in using_for: if "*" in using_for:
new_ir = look_for_library(contract, ir, using_for, "*") new_ir = look_for_library_or_top_level(contract, ir, using_for, "*")
if new_ir: if new_ir:
return new_ir return new_ir

Loading…
Cancel
Save