/src/solidity/libyul/AsmAnalysis.h
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | This file is part of solidity. |
3 | | |
4 | | solidity is free software: you can redistribute it and/or modify |
5 | | it under the terms of the GNU General Public License as published by |
6 | | the Free Software Foundation, either version 3 of the License, or |
7 | | (at your option) any later version. |
8 | | |
9 | | solidity is distributed in the hope that it will be useful, |
10 | | but WITHOUT ANY WARRANTY; without even the implied warranty of |
11 | | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
12 | | GNU General Public License for more details. |
13 | | |
14 | | You should have received a copy of the GNU General Public License |
15 | | along with solidity. If not, see <http://www.gnu.org/licenses/>. |
16 | | */ |
17 | | // SPDX-License-Identifier: GPL-3.0 |
18 | | /** |
19 | | * Analysis part of inline assembly. |
20 | | */ |
21 | | |
22 | | #pragma once |
23 | | |
24 | | #include <liblangutil/Exceptions.h> |
25 | | #include <liblangutil/EVMVersion.h> |
26 | | |
27 | | #include <libyul/ASTForward.h> |
28 | | #include <libyul/Dialect.h> |
29 | | #include <libyul/Scope.h> |
30 | | |
31 | | #include <libyul/backends/evm/AbstractAssembly.h> |
32 | | #include <libyul/backends/evm/EVMDialect.h> |
33 | | |
34 | | #include <functional> |
35 | | #include <list> |
36 | | #include <memory> |
37 | | #include <optional> |
38 | | #include <utility> |
39 | | |
40 | | namespace solidity::langutil |
41 | | { |
42 | | class ErrorReporter; |
43 | | struct SourceLocation; |
44 | | } |
45 | | |
46 | | namespace solidity::yul |
47 | | { |
48 | | |
49 | | struct AsmAnalysisInfo; |
50 | | |
51 | | /** |
52 | | * Performs the full analysis stage, calls the ScopeFiller internally, then resolves |
53 | | * references and performs other checks. |
54 | | * If all these checks pass, code generation should not throw errors. |
55 | | */ |
56 | | class AsmAnalyzer |
57 | | { |
58 | | public: |
59 | | explicit AsmAnalyzer( |
60 | | AsmAnalysisInfo& _analysisInfo, |
61 | | langutil::ErrorReporter& _errorReporter, |
62 | | Dialect const& _dialect, |
63 | | ExternalIdentifierAccess::Resolver _resolver = ExternalIdentifierAccess::Resolver(), |
64 | | std::set<YulString> _dataNames = {} |
65 | | ): |
66 | | m_resolver(std::move(_resolver)), |
67 | | m_info(_analysisInfo), |
68 | | m_errorReporter(_errorReporter), |
69 | | m_dialect(_dialect), |
70 | | m_dataNames(std::move(_dataNames)) |
71 | 65.8k | { |
72 | 65.8k | if (EVMDialect const* evmDialect = dynamic_cast<EVMDialect const*>(&m_dialect)) |
73 | 65.8k | m_evmVersion = evmDialect->evmVersion(); |
74 | 65.8k | } |
75 | | |
76 | | bool analyze(Block const& _block); |
77 | | |
78 | | /// Performs analysis on the outermost code of the given object and returns the analysis info. |
79 | | /// Asserts on failure. |
80 | | static AsmAnalysisInfo analyzeStrictAssertCorrect(Dialect const& _dialect, Object const& _object); |
81 | | |
82 | | std::vector<YulString> operator()(Literal const& _literal); |
83 | | std::vector<YulString> operator()(Identifier const&); |
84 | | void operator()(ExpressionStatement const&); |
85 | | void operator()(Assignment const& _assignment); |
86 | | void operator()(VariableDeclaration const& _variableDeclaration); |
87 | | void operator()(FunctionDefinition const& _functionDefinition); |
88 | | std::vector<YulString> operator()(FunctionCall const& _functionCall); |
89 | | void operator()(If const& _if); |
90 | | void operator()(Switch const& _switch); |
91 | | void operator()(ForLoop const& _forLoop); |
92 | 30.3k | void operator()(Break const&) { } |
93 | 8.07k | void operator()(Continue const&) { } |
94 | 7.49k | void operator()(Leave const&) { } |
95 | | void operator()(Block const& _block); |
96 | | |
97 | | /// @returns the worst side effects encountered during analysis (including within defined functions). |
98 | 0 | SideEffects const& sideEffects() const { return m_sideEffects; } |
99 | | private: |
100 | | /// Visits the expression, expects that it evaluates to exactly one value and |
101 | | /// returns the type. Reports errors on errors and returns the default type. |
102 | | YulString expectExpression(Expression const& _expr); |
103 | | YulString expectUnlimitedStringLiteral(Literal const& _literal); |
104 | | /// Vists the expression and expects it to return a single boolean value. |
105 | | /// Reports an error otherwise. |
106 | | void expectBoolExpression(Expression const& _expr); |
107 | | |
108 | | /// Verifies that a variable to be assigned to exists, can be assigned to |
109 | | /// and has the same type as the value. |
110 | | void checkAssignment(Identifier const& _variable, YulString _valueType); |
111 | | |
112 | | Scope& scope(Block const* _block); |
113 | | void expectValidIdentifier(YulString _identifier, langutil::SourceLocation const& _location); |
114 | | void expectValidType(YulString _type, langutil::SourceLocation const& _location); |
115 | | void expectType(YulString _expectedType, YulString _givenType, langutil::SourceLocation const& _location); |
116 | | |
117 | | bool validateInstructions(evmasm::Instruction _instr, langutil::SourceLocation const& _location); |
118 | | bool validateInstructions(std::string const& _instrIdentifier, langutil::SourceLocation const& _location); |
119 | | bool validateInstructions(FunctionCall const& _functionCall); |
120 | | |
121 | | yul::ExternalIdentifierAccess::Resolver m_resolver; |
122 | | Scope* m_currentScope = nullptr; |
123 | | /// Variables that are active at the current point in assembly (as opposed to |
124 | | /// "part of the scope but not yet declared") |
125 | | std::set<Scope::Variable const*> m_activeVariables; |
126 | | AsmAnalysisInfo& m_info; |
127 | | langutil::ErrorReporter& m_errorReporter; |
128 | | langutil::EVMVersion m_evmVersion; |
129 | | Dialect const& m_dialect; |
130 | | /// Names of data objects to be referenced by builtin functions with literal arguments. |
131 | | std::set<YulString> m_dataNames; |
132 | | ForLoop const* m_currentForLoop = nullptr; |
133 | | /// Worst side effects encountered during analysis (including within defined functions). |
134 | | SideEffects m_sideEffects; |
135 | | }; |
136 | | |
137 | | } |