Coverage Report

Created: 2026-10-26 06:53

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/solidity/libsolidity/analysis/ImmutableValidator.cpp
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
#include <libsolidity/analysis/ImmutableValidator.h>
20
21
#include <range/v3/view/reverse.hpp>
22
23
using namespace solidity::frontend;
24
using namespace solidity::langutil;
25
26
void ImmutableValidator::analyze()
27
19.1k
{
28
19.1k
  auto linearizedContracts = m_mostDerivedContract.annotation().linearizedBaseContracts | ranges::views::reverse;
29
30
19.1k
  for (ContractDefinition const* contract: linearizedContracts)
31
21.1k
  {
32
21.1k
    for (FunctionDefinition const* function: contract->definedFunctions())
33
22.6k
      function->accept(*this);
34
35
21.1k
    for (ModifierDefinition const* modifier: contract->functionModifiers())
36
513
      modifier->accept(*this);
37
21.1k
  }
38
19.1k
}
39
40
bool ImmutableValidator::visit(FunctionDefinition const& _functionDefinition)
41
22.6k
{
42
22.6k
  return !_functionDefinition.isConstructor();
43
22.6k
}
44
45
void ImmutableValidator::endVisit(MemberAccess const& _memberAccess)
46
306k
{
47
306k
  analyseVariableReference(_memberAccess.annotation().referencedDeclaration, _memberAccess);
48
306k
}
49
50
void ImmutableValidator::endVisit(Identifier const& _identifier)
51
214k
{
52
214k
  analyseVariableReference(_identifier.annotation().referencedDeclaration, _identifier);
53
214k
}
54
55
void ImmutableValidator::analyseVariableReference(Declaration const* _reference, Expression const& _expression)
56
520k
{
57
520k
  auto const* variable = dynamic_cast<VariableDeclaration const*>(_reference);
58
520k
  if (!variable || !variable->isStateVariable() || !variable->immutable())
59
520k
    return;
60
61
  // If this is not an ordinary assignment, we write and read at the same time.
62
160
  if (_expression.annotation().willBeWrittenTo)
63
9
    m_errorReporter.typeError(
64
9
      1581_error,
65
9
      _expression.location(),
66
9
      "Cannot write to immutable here: Immutable variables can only be initialized inline or assigned directly in the constructor."
67
9
    );
68
160
}