Detect circular references for library and free functions

This commit is contained in:
Mathias Baumann
2021-03-30 23:06:30 +02:00
committed by chriseth
parent 15fe07bebe
commit e590a99f39
37 changed files with 1168 additions and 288 deletions
+1 -18
View File
@@ -65,24 +65,7 @@ class ASTConstVisitor;
class ASTNode: private boost::noncopyable
{
public:
struct CompareByID
{
using is_transparent = void;
bool operator()(ASTNode const* _lhs, ASTNode const* _rhs) const
{
return _lhs->id() < _rhs->id();
}
bool operator()(ASTNode const* _lhs, int64_t _rhs) const
{
return _lhs->id() < _rhs;
}
bool operator()(int64_t _lhs, ASTNode const* _rhs) const
{
return _lhs < _rhs->id();
}
};
using CompareByID = frontend::ASTCompareByID<ASTNode>;
using SourceLocation = langutil::SourceLocation;
explicit ASTNode(int64_t _id, SourceLocation _location);
+4 -3
View File
@@ -158,9 +158,6 @@ struct ContractDefinitionAnnotation: TypeDeclarationAnnotation, StructurallyDocu
/// List of all (direct and indirect) base contracts in order from derived to
/// base, including the contract itself.
std::vector<ContractDefinition const*> linearizedBaseContracts;
/// List of contracts this contract creates, i.e. which need to be compiled first.
/// Also includes all contracts from @a linearizedBaseContracts.
std::set<ContractDefinition const*> contractDependencies;
/// Mapping containing the nodes that define the arguments for base constructors.
/// These can either be inheritance specifiers or modifier invocations.
std::map<FunctionDefinition const*, ASTNode const*> baseConstructorArguments;
@@ -168,6 +165,10 @@ struct ContractDefinitionAnnotation: TypeDeclarationAnnotation, StructurallyDocu
SetOnce<std::shared_ptr<CallGraph const>> creationCallGraph;
/// A graph with edges representing calls between functions that may happen in a deployed contract.
SetOnce<std::shared_ptr<CallGraph const>> deployedCallGraph;
/// List of contracts whose bytecode is referenced by this contract, e.g. through "new".
/// The Value represents the ast node that referenced the contract.
std::map<ContractDefinition const*, ASTNode const*, ASTCompareByID<ContractDefinition>> contractDependencies;
};
struct CallableDeclarationAnnotation: DeclarationAnnotation
+19
View File
@@ -100,6 +100,25 @@ class StructuredDocumentation;
class VariableScope;
template <class T>
struct ASTCompareByID
{
using is_transparent = void;
bool operator()(T const* _lhs, T const* _rhs) const
{
return _lhs->id() < _rhs->id();
}
bool operator()(T const* _lhs, int64_t _rhs) const
{
return _lhs->id() < _rhs;
}
bool operator()(int64_t _lhs, T const* _rhs) const
{
return _lhs < _rhs->id();
}
};
// Used as pointers to AST nodes, to be replaced by more clever pointers, e.g. pointers which do
// not do reference counting but point to a special memory area that is completely released
// explicitly.
+3 -1
View File
@@ -41,7 +41,9 @@
#include <algorithm>
#include <limits>
#include <type_traits>
#include <range/v3/view/map.hpp>
using namespace ranges;
using namespace std;
using namespace solidity::langutil;
@@ -269,7 +271,7 @@ bool ASTJsonConverter::visit(ContractDefinition const& _node)
make_pair("contractKind", contractKind(_node.contractKind())),
make_pair("abstract", _node.abstract()),
make_pair("baseContracts", toJson(_node.baseContracts())),
make_pair("contractDependencies", getContainerIds(_node.annotation().contractDependencies, true)),
make_pair("contractDependencies", getContainerIds(_node.annotation().contractDependencies | views::keys)),
make_pair("nodes", toJson(_node.subNodes())),
make_pair("scope", idOrNull(_node.scope()))
};
+1 -1
View File
@@ -63,7 +63,7 @@ struct CallGraph
/// Contracts that need to be compiled before this one can be compiled.
/// The value is the ast node that created the dependency.
std::map<ContractDefinition const*, ASTNode const*, ASTNode::CompareByID> bytecodeDependency;
std::map<ContractDefinition const*, ASTNode const*, ASTCompareByID<ContractDefinition>> bytecodeDependency;
/// Events that may get emitted by functions present in the graph.
std::set<EventDefinition const*, ASTNode::CompareByID> emittedEvents;