18
18
#include < libsolidity/analysis/ControlFlowBuilder.h>
19
19
20
20
using namespace dev ;
21
+ using namespace langutil ;
21
22
using namespace solidity ;
22
23
using namespace std ;
23
24
@@ -53,6 +54,7 @@ bool ControlFlowBuilder::visit(BinaryOperation const& _operation)
53
54
case Token::Or:
54
55
case Token::And:
55
56
{
57
+ visitNode (_operation);
56
58
appendControlFlow (_operation.leftExpression ());
57
59
58
60
auto nodes = splitFlow<2 >();
@@ -62,14 +64,14 @@ bool ControlFlowBuilder::visit(BinaryOperation const& _operation)
62
64
return false ;
63
65
}
64
66
default :
65
- break ;
67
+ return ASTConstVisitor::visit (_operation) ;
66
68
}
67
- return ASTConstVisitor::visit (_operation);
68
69
}
69
70
70
71
bool ControlFlowBuilder::visit (Conditional const & _conditional)
71
72
{
72
73
solAssert (!!m_currentNode, " " );
74
+ visitNode (_conditional);
73
75
74
76
_conditional.condition ().accept (*this );
75
77
@@ -86,6 +88,7 @@ bool ControlFlowBuilder::visit(Conditional const& _conditional)
86
88
bool ControlFlowBuilder::visit (IfStatement const & _ifStatement)
87
89
{
88
90
solAssert (!!m_currentNode, " " );
91
+ visitNode (_ifStatement);
89
92
90
93
_ifStatement.condition ().accept (*this );
91
94
@@ -106,6 +109,7 @@ bool ControlFlowBuilder::visit(IfStatement const& _ifStatement)
106
109
bool ControlFlowBuilder::visit (ForStatement const & _forStatement)
107
110
{
108
111
solAssert (!!m_currentNode, " " );
112
+ visitNode (_forStatement);
109
113
110
114
if (_forStatement.initializationExpression ())
111
115
_forStatement.initializationExpression ()->accept (*this );
@@ -139,6 +143,7 @@ bool ControlFlowBuilder::visit(ForStatement const& _forStatement)
139
143
bool ControlFlowBuilder::visit (WhileStatement const & _whileStatement)
140
144
{
141
145
solAssert (!!m_currentNode, " " );
146
+ visitNode (_whileStatement);
142
147
143
148
if (_whileStatement.isDoWhile ())
144
149
{
@@ -183,28 +188,31 @@ bool ControlFlowBuilder::visit(WhileStatement const& _whileStatement)
183
188
return false ;
184
189
}
185
190
186
- bool ControlFlowBuilder::visit (Break const &)
191
+ bool ControlFlowBuilder::visit (Break const & _break )
187
192
{
188
193
solAssert (!!m_currentNode, " " );
189
194
solAssert (!!m_breakJump, " " );
195
+ visitNode (_break);
190
196
connect (m_currentNode, m_breakJump);
191
197
m_currentNode = newLabel ();
192
198
return false ;
193
199
}
194
200
195
- bool ControlFlowBuilder::visit (Continue const &)
201
+ bool ControlFlowBuilder::visit (Continue const & _continue )
196
202
{
197
203
solAssert (!!m_currentNode, " " );
198
204
solAssert (!!m_continueJump, " " );
205
+ visitNode (_continue);
199
206
connect (m_currentNode, m_continueJump);
200
207
m_currentNode = newLabel ();
201
208
return false ;
202
209
}
203
210
204
- bool ControlFlowBuilder::visit (Throw const &)
211
+ bool ControlFlowBuilder::visit (Throw const & _throw )
205
212
{
206
213
solAssert (!!m_currentNode, " " );
207
214
solAssert (!!m_revertNode, " " );
215
+ visitNode (_throw);
208
216
connect (m_currentNode, m_revertNode);
209
217
m_currentNode = newLabel ();
210
218
return false ;
@@ -232,6 +240,7 @@ bool ControlFlowBuilder::visit(FunctionCall const& _functionCall)
232
240
{
233
241
case FunctionType::Kind::Revert:
234
242
solAssert (!!m_revertNode, " " );
243
+ visitNode (_functionCall);
235
244
_functionCall.expression ().accept (*this );
236
245
ASTNode::listAccept (_functionCall.arguments (), *this );
237
246
connect (m_currentNode, m_revertNode);
@@ -241,6 +250,7 @@ bool ControlFlowBuilder::visit(FunctionCall const& _functionCall)
241
250
case FunctionType::Kind::Assert:
242
251
{
243
252
solAssert (!!m_revertNode, " " );
253
+ visitNode (_functionCall);
244
254
_functionCall.expression ().accept (*this );
245
255
ASTNode::listAccept (_functionCall.arguments (), *this );
246
256
connect (m_currentNode, m_revertNode);
@@ -314,6 +324,7 @@ bool ControlFlowBuilder::visit(Return const& _return)
314
324
{
315
325
solAssert (!!m_currentNode, " " );
316
326
solAssert (!!m_returnNode, " " );
327
+ visitNode (_return);
317
328
if (_return.expression ())
318
329
{
319
330
appendControlFlow (*_return.expression ());
@@ -327,11 +338,12 @@ bool ControlFlowBuilder::visit(Return const& _return)
327
338
}
328
339
connect (m_currentNode, m_returnNode);
329
340
m_currentNode = newLabel ();
330
- return true ;
341
+ return false ;
331
342
}
332
343
333
- bool ControlFlowBuilder::visit (FunctionTypeName const &)
344
+ bool ControlFlowBuilder::visit (FunctionTypeName const & _functionTypeName )
334
345
{
346
+ visitNode (_functionTypeName);
335
347
// Do not visit the parameters and return values of a function type name.
336
348
// We do not want to consider them as variable declarations for the control flow graph.
337
349
return false ;
@@ -340,6 +352,7 @@ bool ControlFlowBuilder::visit(FunctionTypeName const&)
340
352
bool ControlFlowBuilder::visit (InlineAssembly const & _inlineAssembly)
341
353
{
342
354
solAssert (!!m_currentNode, " " );
355
+ visitNode (_inlineAssembly);
343
356
for (auto const & ref: _inlineAssembly.annotation ().externalReferences )
344
357
{
345
358
if (auto variableDeclaration = dynamic_cast <VariableDeclaration const *>(ref.second .declaration ))
@@ -355,6 +368,7 @@ bool ControlFlowBuilder::visit(InlineAssembly const& _inlineAssembly)
355
368
bool ControlFlowBuilder::visit (VariableDeclaration const & _variableDeclaration)
356
369
{
357
370
solAssert (!!m_currentNode, " " );
371
+ visitNode (_variableDeclaration);
358
372
359
373
m_currentNode->variableOccurrences .emplace_back (
360
374
_variableDeclaration,
@@ -382,6 +396,7 @@ bool ControlFlowBuilder::visit(VariableDeclaration const& _variableDeclaration)
382
396
bool ControlFlowBuilder::visit (VariableDeclarationStatement const & _variableDeclarationStatement)
383
397
{
384
398
solAssert (!!m_currentNode, " " );
399
+ visitNode (_variableDeclarationStatement);
385
400
386
401
for (auto const & var: _variableDeclarationStatement.declarations ())
387
402
if (var)
@@ -417,6 +432,7 @@ bool ControlFlowBuilder::visit(VariableDeclarationStatement const& _variableDecl
417
432
bool ControlFlowBuilder::visit (Identifier const & _identifier)
418
433
{
419
434
solAssert (!!m_currentNode, " " );
435
+ visitNode (_identifier);
420
436
421
437
if (auto const * variableDeclaration = dynamic_cast <VariableDeclaration const *>(_identifier.annotation ().referencedDeclaration ))
422
438
m_currentNode->variableOccurrences .emplace_back (
@@ -430,7 +446,12 @@ bool ControlFlowBuilder::visit(Identifier const& _identifier)
430
446
return true ;
431
447
}
432
448
433
-
449
+ bool ControlFlowBuilder::visitNode (ASTNode const & _node)
450
+ {
451
+ solAssert (!!m_currentNode, " " );
452
+ m_currentNode->location = langutil::SourceLocation::smallestCovering (m_currentNode->location , _node.location ());
453
+ return true ;
454
+ }
434
455
435
456
void ControlFlowBuilder::appendControlFlow (ASTNode const & _node)
436
457
{
0 commit comments