Coverage Report

Created: 2025-06-24 07:59

/src/solidity/libyul/ControlFlowSideEffects.h
Line
Count
Source
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
#pragma once
20
21
#include <libevmasm/Instruction.h>
22
#include <libevmasm/SemanticInformation.h>
23
24
namespace solidity::yul
25
{
26
27
/**
28
 * Side effects of a user-defined or builtin function.
29
 *
30
 * Each of the three booleans represents a reachability condition. There is an implied
31
 * fourth alternative, which is going out of gas while executing the function. Since
32
 * this can always happen and depends on the supply of gas, it is not considered.
33
 *
34
 * If all three booleans are false, it means that the function always leads to infinite
35
 * recursion.
36
 */
37
struct ControlFlowSideEffects
38
{
39
  /// If true, the function contains at least one reachable branch that terminates successfully.
40
  bool canTerminate = false;
41
  /// If true, the function contains at least one reachable branch that reverts.
42
  bool canRevert = false;
43
  /// If true, the function has a regular outgoing control-flow.
44
  bool canContinue = true;
45
46
  bool terminatesOrReverts() const
47
46.0k
  {
48
46.0k
    return (canTerminate || canRevert) && !canContinue;
49
46.0k
  }
50
51
  static ControlFlowSideEffects fromInstruction(evmasm::Instruction _instruction)
52
18.7M
  {
53
18.7M
    ControlFlowSideEffects controlFlowSideEffects;
54
18.7M
    if (evmasm::SemanticInformation::terminatesControlFlow(_instruction))
55
1.20M
    {
56
1.20M
      controlFlowSideEffects.canContinue = false;
57
1.20M
      if (evmasm::SemanticInformation::reverts(_instruction))
58
481k
      {
59
481k
        controlFlowSideEffects.canTerminate = false;
60
481k
        controlFlowSideEffects.canRevert = true;
61
481k
      }
62
722k
      else
63
722k
      {
64
722k
        controlFlowSideEffects.canTerminate = true;
65
722k
        controlFlowSideEffects.canRevert = false;
66
722k
      }
67
1.20M
    }
68
69
18.7M
    return controlFlowSideEffects;
70
18.7M
  }
71
72
  /// @returns the worst-case control flow side effects.
73
  static ControlFlowSideEffects worst()
74
4.20k
  {
75
4.20k
    return ControlFlowSideEffects{true, true, true};
76
4.20k
  }
77
};
78
79
}