mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Merge 2059fdf054
into bdd2f02c83
This commit is contained in:
commit
3572b51b4c
@ -188,6 +188,8 @@ set(sources
|
|||||||
experimental/analysis/Analysis.h
|
experimental/analysis/Analysis.h
|
||||||
experimental/analysis/DebugWarner.cpp
|
experimental/analysis/DebugWarner.cpp
|
||||||
experimental/analysis/DebugWarner.h
|
experimental/analysis/DebugWarner.h
|
||||||
|
experimental/analysis/FunctionCallGraph.cpp
|
||||||
|
experimental/analysis/FunctionCallGraph.h
|
||||||
experimental/analysis/TypeClassRegistration.cpp
|
experimental/analysis/TypeClassRegistration.cpp
|
||||||
experimental/analysis/TypeClassRegistration.h
|
experimental/analysis/TypeClassRegistration.h
|
||||||
experimental/analysis/TypeInference.cpp
|
experimental/analysis/TypeInference.cpp
|
||||||
@ -196,6 +198,8 @@ set(sources
|
|||||||
experimental/analysis/TypeRegistration.h
|
experimental/analysis/TypeRegistration.h
|
||||||
experimental/analysis/SyntaxRestrictor.cpp
|
experimental/analysis/SyntaxRestrictor.cpp
|
||||||
experimental/analysis/SyntaxRestrictor.h
|
experimental/analysis/SyntaxRestrictor.h
|
||||||
|
experimental/ast/CallGraph.cpp
|
||||||
|
experimental/ast/CallGraph.h
|
||||||
experimental/ast/Type.cpp
|
experimental/ast/Type.cpp
|
||||||
experimental/ast/Type.h
|
experimental/ast/Type.h
|
||||||
experimental/ast/TypeSystem.cpp
|
experimental/ast/TypeSystem.cpp
|
||||||
|
@ -99,14 +99,14 @@ private:
|
|||||||
|
|
||||||
/// Starts at @a _entry and parses the control flow of @a _node.
|
/// Starts at @a _entry and parses the control flow of @a _node.
|
||||||
/// @returns The node at which the parsed control flow ends.
|
/// @returns The node at which the parsed control flow ends.
|
||||||
/// m_currentNode is not affected (it is saved and restored).
|
/// m_currentFunction is not affected (it is saved and restored).
|
||||||
CFGNode* createFlow(CFGNode* _entry, ASTNode const& _node);
|
CFGNode* createFlow(CFGNode* _entry, ASTNode const& _node);
|
||||||
|
|
||||||
/// Creates an arc from @a _from to @a _to.
|
/// Creates an arc from @a _from to @a _to.
|
||||||
static void connect(CFGNode* _from, CFGNode* _to);
|
static void connect(CFGNode* _from, CFGNode* _to);
|
||||||
|
|
||||||
/// Splits the control flow starting at the current node into n paths.
|
/// Splits the control flow starting at the current node into n paths.
|
||||||
/// m_currentNode is set to nullptr and has to be set manually or
|
/// m_currentFunction is set to nullptr and has to be set manually or
|
||||||
/// using mergeFlow later.
|
/// using mergeFlow later.
|
||||||
template<size_t n>
|
template<size_t n>
|
||||||
std::array<CFGNode*, n> splitFlow()
|
std::array<CFGNode*, n> splitFlow()
|
||||||
@ -122,7 +122,7 @@ private:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Splits the control flow starting at the current node into @a _n paths.
|
/// Splits the control flow starting at the current node into @a _n paths.
|
||||||
/// m_currentNode is set to nullptr and has to be set manually or
|
/// m_currentFunction is set to nullptr and has to be set manually or
|
||||||
/// using mergeFlow later.
|
/// using mergeFlow later.
|
||||||
std::vector<CFGNode*> splitFlow(size_t n)
|
std::vector<CFGNode*> splitFlow(size_t n)
|
||||||
{
|
{
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
// SPDX-License-Identifier: GPL-3.0
|
// SPDX-License-Identifier: GPL-3.0
|
||||||
#include <libsolidity/experimental/analysis/Analysis.h>
|
#include <libsolidity/experimental/analysis/Analysis.h>
|
||||||
#include <libsolidity/experimental/analysis/DebugWarner.h>
|
#include <libsolidity/experimental/analysis/DebugWarner.h>
|
||||||
|
#include <libsolidity/experimental/analysis/FunctionCallGraph.h>
|
||||||
#include <libsolidity/experimental/analysis/SyntaxRestrictor.h>
|
#include <libsolidity/experimental/analysis/SyntaxRestrictor.h>
|
||||||
#include <libsolidity/experimental/analysis/TypeClassRegistration.h>
|
#include <libsolidity/experimental/analysis/TypeClassRegistration.h>
|
||||||
#include <libsolidity/experimental/analysis/TypeInference.h>
|
#include <libsolidity/experimental/analysis/TypeInference.h>
|
||||||
@ -35,9 +36,11 @@ struct Analysis::AnnotationContainer
|
|||||||
|
|
||||||
struct Analysis::GlobalAnnotationContainer
|
struct Analysis::GlobalAnnotationContainer
|
||||||
{
|
{
|
||||||
|
FunctionCallGraph::GlobalAnnotation functionCallGraphAnnotation;
|
||||||
TypeClassRegistration::GlobalAnnotation typeClassRegistrationAnnotation;
|
TypeClassRegistration::GlobalAnnotation typeClassRegistrationAnnotation;
|
||||||
TypeRegistration::GlobalAnnotation typeRegistrationAnnotation;
|
TypeRegistration::GlobalAnnotation typeRegistrationAnnotation;
|
||||||
TypeInference::GlobalAnnotation typeInferenceAnnotation;
|
TypeInference::GlobalAnnotation typeInferenceAnnotation;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
@ -52,7 +55,6 @@ TypeClassRegistration::GlobalAnnotation const& solidity::frontend::experimental:
|
|||||||
return analysis.annotationContainer().typeClassRegistrationAnnotation;
|
return analysis.annotationContainer().typeClassRegistrationAnnotation;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
TypeClassRegistration::GlobalAnnotation& solidity::frontend::experimental::detail::AnnotationFetcher<TypeClassRegistration>::get()
|
TypeClassRegistration::GlobalAnnotation& solidity::frontend::experimental::detail::AnnotationFetcher<TypeClassRegistration>::get()
|
||||||
{
|
{
|
||||||
@ -65,6 +67,18 @@ TypeClassRegistration::Annotation const& solidity::frontend::experimental::detai
|
|||||||
return analysis.annotationContainer(_node).typeClassRegistrationAnnotation;
|
return analysis.annotationContainer(_node).typeClassRegistrationAnnotation;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<>
|
||||||
|
FunctionCallGraph::GlobalAnnotation const& solidity::frontend::experimental::detail::ConstAnnotationFetcher<FunctionCallGraph>::get() const
|
||||||
|
{
|
||||||
|
return analysis.annotationContainer().functionCallGraphAnnotation;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<>
|
||||||
|
FunctionCallGraph::GlobalAnnotation& solidity::frontend::experimental::detail::AnnotationFetcher<FunctionCallGraph>::get()
|
||||||
|
{
|
||||||
|
return analysis.annotationContainer().functionCallGraphAnnotation;
|
||||||
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
TypeRegistration::Annotation& solidity::frontend::experimental::detail::AnnotationFetcher<TypeRegistration>::get(ASTNode const& _node)
|
TypeRegistration::Annotation& solidity::frontend::experimental::detail::AnnotationFetcher<TypeRegistration>::get(ASTNode const& _node)
|
||||||
{
|
{
|
||||||
@ -77,7 +91,6 @@ TypeRegistration::GlobalAnnotation const& solidity::frontend::experimental::deta
|
|||||||
return analysis.annotationContainer().typeRegistrationAnnotation;
|
return analysis.annotationContainer().typeRegistrationAnnotation;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
TypeRegistration::GlobalAnnotation& solidity::frontend::experimental::detail::AnnotationFetcher<TypeRegistration>::get()
|
TypeRegistration::GlobalAnnotation& solidity::frontend::experimental::detail::AnnotationFetcher<TypeRegistration>::get()
|
||||||
{
|
{
|
||||||
@ -108,7 +121,6 @@ TypeInference::GlobalAnnotation const& solidity::frontend::experimental::detail:
|
|||||||
return analysis.annotationContainer().typeInferenceAnnotation;
|
return analysis.annotationContainer().typeInferenceAnnotation;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
TypeInference::GlobalAnnotation& solidity::frontend::experimental::detail::AnnotationFetcher<TypeInference>::get()
|
TypeInference::GlobalAnnotation& solidity::frontend::experimental::detail::AnnotationFetcher<TypeInference>::get()
|
||||||
{
|
{
|
||||||
@ -151,6 +163,7 @@ bool Analysis::check(std::vector<std::shared_ptr<SourceUnit const>> const& _sour
|
|||||||
{
|
{
|
||||||
using AnalysisSteps = std::tuple<
|
using AnalysisSteps = std::tuple<
|
||||||
SyntaxRestrictor,
|
SyntaxRestrictor,
|
||||||
|
FunctionCallGraph,
|
||||||
TypeClassRegistration,
|
TypeClassRegistration,
|
||||||
TypeRegistration,
|
TypeRegistration,
|
||||||
TypeInference,
|
TypeInference,
|
||||||
|
73
libsolidity/experimental/analysis/FunctionCallGraph.cpp
Normal file
73
libsolidity/experimental/analysis/FunctionCallGraph.cpp
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
/*
|
||||||
|
This file is part of solidity.
|
||||||
|
|
||||||
|
solidity is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
solidity is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with solidity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
// SPDX-License-Identifier: GPL-3.0
|
||||||
|
|
||||||
|
#include <libsolidity/experimental/analysis/Analysis.h>
|
||||||
|
#include <libsolidity/experimental/analysis/FunctionCallGraph.h>
|
||||||
|
|
||||||
|
using namespace solidity::frontend::experimental;
|
||||||
|
using namespace solidity::util;
|
||||||
|
|
||||||
|
FunctionCallGraph::FunctionCallGraph(solidity::frontend::experimental::Analysis& _analysis):
|
||||||
|
m_analysis(_analysis),
|
||||||
|
m_errorReporter(_analysis.errorReporter())
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
bool FunctionCallGraph::analyze(SourceUnit const& _sourceUnit)
|
||||||
|
{
|
||||||
|
_sourceUnit.accept(*this);
|
||||||
|
// TODO remove debug output before merge
|
||||||
|
//std::cout << annotation().functionCallGraph << std::endl;
|
||||||
|
return !m_errorReporter.hasErrors();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool FunctionCallGraph::visit(FunctionDefinition const& _functionDefinition)
|
||||||
|
{
|
||||||
|
solAssert(!m_currentFunction);
|
||||||
|
m_currentFunction = &_functionDefinition;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FunctionCallGraph::endVisit(FunctionDefinition const&)
|
||||||
|
{
|
||||||
|
// If we're done visiting a function declaration without said function referencing/calling
|
||||||
|
// another function in its body - insert it into the graph without child nodes.
|
||||||
|
if (!annotation().functionCallGraph.edges.count(m_currentFunction))
|
||||||
|
annotation().functionCallGraph.edges.insert({m_currentFunction, {}});
|
||||||
|
m_currentFunction = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool FunctionCallGraph::visit(Identifier const& _identifier)
|
||||||
|
{
|
||||||
|
auto callee = dynamic_cast<FunctionDefinition const*>(_identifier.annotation().referencedDeclaration);
|
||||||
|
// Check that the identifier is within a function body and is a function, and add it to the graph
|
||||||
|
// as an ``m_currentFunction`` -> ``callee`` edge.
|
||||||
|
if (m_currentFunction && callee)
|
||||||
|
add(m_currentFunction, callee);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FunctionCallGraph::add(FunctionDefinition const* _caller, FunctionDefinition const* _callee)
|
||||||
|
{
|
||||||
|
annotation().functionCallGraph.edges[_caller].insert(_callee);
|
||||||
|
}
|
||||||
|
|
||||||
|
FunctionCallGraph::GlobalAnnotation& FunctionCallGraph::annotation()
|
||||||
|
{
|
||||||
|
return m_analysis.annotation<FunctionCallGraph>();
|
||||||
|
}
|
57
libsolidity/experimental/analysis/FunctionCallGraph.h
Normal file
57
libsolidity/experimental/analysis/FunctionCallGraph.h
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
/*
|
||||||
|
This file is part of solidity.
|
||||||
|
|
||||||
|
solidity is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
solidity is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with solidity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
// SPDX-License-Identifier: GPL-3.0
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <liblangutil/ErrorReporter.h>
|
||||||
|
#include <libsolidity/ast/ASTForward.h>
|
||||||
|
#include <libsolidity/ast/ASTVisitor.h>
|
||||||
|
#include <libsolidity/experimental/ast/CallGraph.h>
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
namespace solidity::frontend::experimental
|
||||||
|
{
|
||||||
|
|
||||||
|
class Analysis;
|
||||||
|
|
||||||
|
class FunctionCallGraph: private ASTConstVisitor
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
FunctionCallGraph(Analysis& _analysis);
|
||||||
|
bool analyze(SourceUnit const& _sourceUnit);
|
||||||
|
|
||||||
|
struct Annotation {};
|
||||||
|
struct GlobalAnnotation
|
||||||
|
{
|
||||||
|
CallGraph functionCallGraph;
|
||||||
|
};
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool visit(FunctionDefinition const& _functionDefinition) override;
|
||||||
|
void endVisit(FunctionDefinition const&) override;
|
||||||
|
bool visit(Identifier const& _identifier) override;
|
||||||
|
void add(FunctionDefinition const* _caller, FunctionDefinition const* _callee);
|
||||||
|
GlobalAnnotation& annotation();
|
||||||
|
|
||||||
|
Analysis& m_analysis;
|
||||||
|
langutil::ErrorReporter& m_errorReporter;
|
||||||
|
FunctionDefinition const* m_currentFunction = nullptr;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
39
libsolidity/experimental/ast/CallGraph.cpp
Normal file
39
libsolidity/experimental/ast/CallGraph.cpp
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
/*
|
||||||
|
This file is part of solidity.
|
||||||
|
|
||||||
|
solidity is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
solidity is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with solidity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
// SPDX-License-Identifier: GPL-3.0
|
||||||
|
|
||||||
|
#include <libsolidity/experimental/ast/CallGraph.h>
|
||||||
|
|
||||||
|
using namespace solidity::frontend::experimental;
|
||||||
|
|
||||||
|
// TODO remove before merge (delete entire file)
|
||||||
|
std::ostream& solidity::frontend::experimental::operator<<(std::ostream& _out, CallGraph const& _callGraph)
|
||||||
|
{
|
||||||
|
_out << "EDGES" << "\n";
|
||||||
|
_out << "===================" << std::endl;
|
||||||
|
for (auto [top, subs]: _callGraph.edges)
|
||||||
|
{
|
||||||
|
std::string topName = top->name().empty() ? "fallback" : top->name();
|
||||||
|
_out << "(" << topName <<") --> {";
|
||||||
|
for (auto sub: subs)
|
||||||
|
{
|
||||||
|
_out << sub->name() << ",";
|
||||||
|
}
|
||||||
|
_out << "}" << std::endl;
|
||||||
|
}
|
||||||
|
return _out;
|
||||||
|
}
|
42
libsolidity/experimental/ast/CallGraph.h
Normal file
42
libsolidity/experimental/ast/CallGraph.h
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
/*
|
||||||
|
This file is part of solidity.
|
||||||
|
|
||||||
|
solidity is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
solidity is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with solidity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
// SPDX-License-Identifier: GPL-3.0
|
||||||
|
|
||||||
|
/// Data structure representing a function call graph.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <libsolidity/ast/AST.h>
|
||||||
|
|
||||||
|
#include <map>
|
||||||
|
#include <set>
|
||||||
|
#include <ostream>
|
||||||
|
|
||||||
|
namespace solidity::frontend::experimental
|
||||||
|
{
|
||||||
|
|
||||||
|
struct CallGraph
|
||||||
|
{
|
||||||
|
/// Graph edges. Edges are directed and lead from the caller to the callee.
|
||||||
|
/// The map contains a key for every possible caller, even if does not actually perform
|
||||||
|
/// any calls.
|
||||||
|
std::map<FunctionDefinition const*, std::set<FunctionDefinition const*>> edges;
|
||||||
|
};
|
||||||
|
|
||||||
|
std::ostream& operator<<(std::ostream& _out, CallGraph const& _callGraph);
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,113 @@
|
|||||||
|
// fallback---------->f----------+
|
||||||
|
// | |
|
||||||
|
// | |
|
||||||
|
// | |
|
||||||
|
// | |
|
||||||
|
// v v
|
||||||
|
// g h
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// add
|
||||||
|
//
|
||||||
|
// unreferenced
|
||||||
|
|
||||||
|
pragma experimental solidity;
|
||||||
|
|
||||||
|
type uint256 = __builtin("word");
|
||||||
|
|
||||||
|
instantiation uint256: + {
|
||||||
|
function add(x, y) -> uint256 {
|
||||||
|
let a = uint256.rep(x);
|
||||||
|
let b = uint256.rep(y);
|
||||||
|
assembly {
|
||||||
|
a := add(a,b)
|
||||||
|
}
|
||||||
|
return uint256.abs(a);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function unreferenced(x:uint256) -> uint256
|
||||||
|
{
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
|
||||||
|
function f(x:uint256) -> uint256
|
||||||
|
{
|
||||||
|
return g(h(x));
|
||||||
|
}
|
||||||
|
|
||||||
|
function g(x:uint256) -> uint256
|
||||||
|
{
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
|
||||||
|
function h(x:uint256) -> uint256
|
||||||
|
{
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
|
||||||
|
contract C {
|
||||||
|
fallback() external {
|
||||||
|
let a: uint256->uint256 = f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// ====
|
||||||
|
// EVMVersion: >=constantinople
|
||||||
|
// ----
|
||||||
|
// Warning 2264: (278-307): Experimental features are turned on. Do not use experimental features on live deployments.
|
||||||
|
// Info 4164: (309-342): Inferred type: word:(type, +)
|
||||||
|
// Info 4164: (344-564): Inferred type: void
|
||||||
|
// Info 4164: (375-562): Inferred type: (word, word) -> word
|
||||||
|
// Info 4164: (387-393): Inferred type: (word, word)
|
||||||
|
// Info 4164: (388-389): Inferred type: word
|
||||||
|
// Info 4164: (391-392): Inferred type: word
|
||||||
|
// Info 4164: (397-404): Inferred type: word
|
||||||
|
// Info 4164: (419-420): Inferred type: word
|
||||||
|
// Info 4164: (423-437): Inferred type: word
|
||||||
|
// Info 4164: (423-434): Inferred type: word -> word
|
||||||
|
// Info 4164: (423-430): Inferred type: word
|
||||||
|
// Info 4164: (435-436): Inferred type: word
|
||||||
|
// Info 4164: (451-452): Inferred type: word
|
||||||
|
// Info 4164: (455-469): Inferred type: word
|
||||||
|
// Info 4164: (455-466): Inferred type: word -> word
|
||||||
|
// Info 4164: (455-462): Inferred type: word
|
||||||
|
// Info 4164: (467-468): Inferred type: word
|
||||||
|
// Info 4164: (541-555): Inferred type: word
|
||||||
|
// Info 4164: (541-552): Inferred type: word -> word
|
||||||
|
// Info 4164: (541-548): Inferred type: word
|
||||||
|
// Info 4164: (553-554): Inferred type: word
|
||||||
|
// Info 4164: (566-627): Inferred type: word -> word
|
||||||
|
// Info 4164: (587-598): Inferred type: word
|
||||||
|
// Info 4164: (588-597): Inferred type: word
|
||||||
|
// Info 4164: (590-597): Inferred type: word
|
||||||
|
// Info 4164: (602-609): Inferred type: word
|
||||||
|
// Info 4164: (623-624): Inferred type: word
|
||||||
|
// Info 4164: (629-685): Inferred type: word -> word
|
||||||
|
// Info 4164: (639-650): Inferred type: word
|
||||||
|
// Info 4164: (640-649): Inferred type: word
|
||||||
|
// Info 4164: (642-649): Inferred type: word
|
||||||
|
// Info 4164: (654-661): Inferred type: word
|
||||||
|
// Info 4164: (675-682): Inferred type: word
|
||||||
|
// Info 4164: (675-676): Inferred type: word -> word
|
||||||
|
// Info 4164: (677-681): Inferred type: word
|
||||||
|
// Info 4164: (677-678): Inferred type: word -> word
|
||||||
|
// Info 4164: (679-680): Inferred type: word
|
||||||
|
// Info 4164: (687-737): Inferred type: word -> word
|
||||||
|
// Info 4164: (697-708): Inferred type: word
|
||||||
|
// Info 4164: (698-707): Inferred type: word
|
||||||
|
// Info 4164: (700-707): Inferred type: word
|
||||||
|
// Info 4164: (712-719): Inferred type: word
|
||||||
|
// Info 4164: (733-734): Inferred type: word
|
||||||
|
// Info 4164: (739-789): Inferred type: word -> word
|
||||||
|
// Info 4164: (749-760): Inferred type: word
|
||||||
|
// Info 4164: (750-759): Inferred type: word
|
||||||
|
// Info 4164: (752-759): Inferred type: word
|
||||||
|
// Info 4164: (764-771): Inferred type: word
|
||||||
|
// Info 4164: (785-786): Inferred type: word
|
||||||
|
// Info 4164: (808-872): Inferred type: () -> ()
|
||||||
|
// Info 4164: (816-818): Inferred type: ()
|
||||||
|
// Info 4164: (842-861): Inferred type: word -> word
|
||||||
|
// Info 4164: (845-861): Inferred type: word -> word
|
||||||
|
// Info 4164: (845-852): Inferred type: word
|
||||||
|
// Info 4164: (854-861): Inferred type: word
|
||||||
|
// Info 4164: (864-865): Inferred type: word -> word
|
@ -0,0 +1,92 @@
|
|||||||
|
// a<------b
|
||||||
|
// | ^
|
||||||
|
// | |
|
||||||
|
// | |
|
||||||
|
// | |
|
||||||
|
// | |
|
||||||
|
// +------>c------->d-------->e------->f
|
||||||
|
// ^ |
|
||||||
|
// | |
|
||||||
|
// | |
|
||||||
|
// | |
|
||||||
|
// | v
|
||||||
|
// h<-------g
|
||||||
|
|
||||||
|
pragma experimental solidity;
|
||||||
|
|
||||||
|
function a()
|
||||||
|
{
|
||||||
|
c();
|
||||||
|
}
|
||||||
|
|
||||||
|
function b()
|
||||||
|
{
|
||||||
|
a();
|
||||||
|
}
|
||||||
|
|
||||||
|
function c()
|
||||||
|
{
|
||||||
|
b();
|
||||||
|
d();
|
||||||
|
}
|
||||||
|
|
||||||
|
function d()
|
||||||
|
{
|
||||||
|
e();
|
||||||
|
}
|
||||||
|
|
||||||
|
function e()
|
||||||
|
{
|
||||||
|
f();
|
||||||
|
}
|
||||||
|
|
||||||
|
function f()
|
||||||
|
{
|
||||||
|
g();
|
||||||
|
}
|
||||||
|
|
||||||
|
function g()
|
||||||
|
{
|
||||||
|
h();
|
||||||
|
}
|
||||||
|
|
||||||
|
function h()
|
||||||
|
{
|
||||||
|
e();
|
||||||
|
}
|
||||||
|
// ----
|
||||||
|
// Warning 2264: (366-395): Experimental features are turned on. Do not use experimental features on live deployments.
|
||||||
|
// Info 4164: (397-422): Inferred type: () -> ()
|
||||||
|
// Info 4164: (407-409): Inferred type: ()
|
||||||
|
// Info 4164: (416-419): Inferred type: ()
|
||||||
|
// Info 4164: (416-417): Inferred type: () -> ()
|
||||||
|
// Info 4164: (424-449): Inferred type: () -> ()
|
||||||
|
// Info 4164: (434-436): Inferred type: ()
|
||||||
|
// Info 4164: (443-446): Inferred type: ()
|
||||||
|
// Info 4164: (443-444): Inferred type: () -> ()
|
||||||
|
// Info 4164: (451-485): Inferred type: () -> ()
|
||||||
|
// Info 4164: (461-463): Inferred type: ()
|
||||||
|
// Info 4164: (470-473): Inferred type: ()
|
||||||
|
// Info 4164: (470-471): Inferred type: () -> ()
|
||||||
|
// Info 4164: (479-482): Inferred type: ()
|
||||||
|
// Info 4164: (479-480): Inferred type: () -> ()
|
||||||
|
// Info 4164: (487-512): Inferred type: () -> ()
|
||||||
|
// Info 4164: (497-499): Inferred type: ()
|
||||||
|
// Info 4164: (506-509): Inferred type: ()
|
||||||
|
// Info 4164: (506-507): Inferred type: () -> ()
|
||||||
|
// Info 4164: (514-539): Inferred type: () -> ()
|
||||||
|
// Info 4164: (524-526): Inferred type: ()
|
||||||
|
// Info 4164: (533-536): Inferred type: ()
|
||||||
|
// Info 4164: (533-534): Inferred type: () -> ()
|
||||||
|
// Info 4164: (541-566): Inferred type: () -> ()
|
||||||
|
// Info 4164: (551-553): Inferred type: ()
|
||||||
|
// Info 4164: (560-563): Inferred type: ()
|
||||||
|
// Info 4164: (560-561): Inferred type: () -> ()
|
||||||
|
// Info 4164: (568-593): Inferred type: () -> ()
|
||||||
|
// Info 4164: (578-580): Inferred type: ()
|
||||||
|
// Info 4164: (587-590): Inferred type: ()
|
||||||
|
// Info 4164: (587-588): Inferred type: () -> ()
|
||||||
|
// Info 4164: (595-620): Inferred type: () -> ()
|
||||||
|
// Info 4164: (605-607): Inferred type: ()
|
||||||
|
// Info 4164: (614-617): Inferred type: ()
|
||||||
|
// Info 4164: (614-615): Inferred type: () -> ()
|
Loading…
Reference in New Issue
Block a user