Coverage Report

Created: 2022-08-24 06:40

/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
66.5k
  {
72
66.5k
    if (EVMDialect const* evmDialect = dynamic_cast<EVMDialect const*>(&m_dialect))
73
66.5k
      m_evmVersion = evmDialect->evmVersion();
74
66.5k
  }
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
9.26k
  void operator()(Break const&) { }
93
662
  void operator()(Continue const&) { }
94
4.66k
  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
}