@@ -29,7 +29,7 @@ void ImmutableValidator::analyze()
29
29
{
30
30
m_inCreationContext = true ;
31
31
32
- auto linearizedContracts = m_currentContract .annotation ().linearizedBaseContracts | ranges::views::reverse;
32
+ auto linearizedContracts = m_mostDerivedContract .annotation ().linearizedBaseContracts | ranges::views::reverse;
33
33
34
34
for (ContractDefinition const * contract: linearizedContracts)
35
35
for (VariableDeclaration const * stateVar: contract->stateVariables ())
@@ -62,7 +62,7 @@ void ImmutableValidator::analyze()
62
62
visitCallableIfNew (*modDef);
63
63
}
64
64
65
- checkAllVariablesInitialized (m_currentContract .location ());
65
+ checkAllVariablesInitialized (m_mostDerivedContract .location ());
66
66
}
67
67
68
68
bool ImmutableValidator::visit (Assignment const & _assignment)
@@ -137,7 +137,7 @@ void ImmutableValidator::endVisit(IdentifierPath const& _identifierPath)
137
137
if (auto const callableDef = dynamic_cast <CallableDeclaration const *>(_identifierPath.annotation ().referencedDeclaration ))
138
138
visitCallableIfNew (
139
139
*_identifierPath.annotation ().requiredLookup == VirtualLookup::Virtual ?
140
- callableDef->resolveVirtual (m_currentContract ) :
140
+ callableDef->resolveVirtual (m_mostDerivedContract ) :
141
141
*callableDef
142
142
);
143
143
@@ -147,7 +147,7 @@ void ImmutableValidator::endVisit(IdentifierPath const& _identifierPath)
147
147
void ImmutableValidator::endVisit (Identifier const & _identifier)
148
148
{
149
149
if (auto const callableDef = dynamic_cast <CallableDeclaration const *>(_identifier.annotation ().referencedDeclaration ))
150
- visitCallableIfNew (*_identifier.annotation ().requiredLookup == VirtualLookup::Virtual ? callableDef->resolveVirtual (m_currentContract ) : *callableDef);
150
+ visitCallableIfNew (*_identifier.annotation ().requiredLookup == VirtualLookup::Virtual ? callableDef->resolveVirtual (m_mostDerivedContract ) : *callableDef);
151
151
if (auto const varDecl = dynamic_cast <VariableDeclaration const *>(_identifier.annotation ().referencedDeclaration ))
152
152
analyseVariableReference (*varDecl, _identifier);
153
153
}
@@ -160,15 +160,18 @@ void ImmutableValidator::endVisit(Return const& _return)
160
160
161
161
bool ImmutableValidator::analyseCallable (CallableDeclaration const & _callableDeclaration)
162
162
{
163
- FunctionDefinition const * prevConstructor = m_currentConstructor;
164
- m_currentConstructor = nullptr ;
163
+ ScopedSaveAndRestore constructorGuard{ m_currentConstructor, {}} ;
164
+ ScopedSaveAndRestore constructorContractGuard{m_currentConstructorContract, {}} ;
165
165
166
166
if (FunctionDefinition const * funcDef = dynamic_cast <decltype (funcDef)>(&_callableDeclaration))
167
167
{
168
168
ASTNode::listAccept (funcDef->modifiers (), *this );
169
169
170
170
if (funcDef->isConstructor ())
171
+ {
172
+ m_currentConstructorContract = funcDef->annotation ().contract ;
171
173
m_currentConstructor = funcDef;
174
+ }
172
175
173
176
if (funcDef->isImplemented ())
174
177
funcDef->body ().accept (*this );
@@ -177,8 +180,6 @@ bool ImmutableValidator::analyseCallable(CallableDeclaration const& _callableDec
177
180
if (modDef->isImplemented ())
178
181
modDef->body ().accept (*this );
179
182
180
- m_currentConstructor = prevConstructor;
181
-
182
183
return false ;
183
184
}
184
185
@@ -253,7 +254,8 @@ void ImmutableValidator::analyseVariableReference(VariableDeclaration const& _va
253
254
254
255
void ImmutableValidator::checkAllVariablesInitialized (solidity::langutil::SourceLocation const & _location)
255
256
{
256
- for (ContractDefinition const * contract: m_currentContract.annotation ().linearizedBaseContracts )
257
+ for (ContractDefinition const * contract: m_mostDerivedContract.annotation ().linearizedBaseContracts | ranges::views::reverse)
258
+ {
257
259
for (VariableDeclaration const * varDecl: contract->stateVariables ())
258
260
if (varDecl->immutable ())
259
261
if (!util::contains (m_initializedStateVariables, varDecl))
@@ -263,6 +265,11 @@ void ImmutableValidator::checkAllVariablesInitialized(solidity::langutil::Source
263
265
solidity::langutil::SecondarySourceLocation ().append (" Not initialized: " , varDecl->location ()),
264
266
" Construction control flow ends without initializing all immutable state variables."
265
267
);
268
+
269
+ // Don't check further than the current c'tors contract
270
+ if (contract == m_currentConstructorContract)
271
+ break ;
272
+ }
266
273
}
267
274
268
275
void ImmutableValidator::visitCallableIfNew (Declaration const & _declaration)
0 commit comments