@@ -65,20 +65,20 @@ void DataFlowAnalyzer::operator()(ExpressionStatement& _statement)
65
65
if (auto vars = isSimpleStore (StoreLoadLocation::Storage, _statement))
66
66
{
67
67
ASTModifier::operator ()(_statement);
68
- cxx20::erase_if (m_storage , mapTuple ([&](auto && key, auto && value) {
68
+ cxx20::erase_if (m_state. storage , mapTuple ([&](auto && key, auto && value) {
69
69
return
70
70
!m_knowledgeBase.knownToBeDifferent (vars->first , key) &&
71
71
!m_knowledgeBase.knownToBeEqual (vars->second , value);
72
72
}));
73
- m_storage [vars->first ] = vars->second ;
73
+ m_state. storage [vars->first ] = vars->second ;
74
74
}
75
75
else if (auto vars = isSimpleStore (StoreLoadLocation::Memory, _statement))
76
76
{
77
77
ASTModifier::operator ()(_statement);
78
- cxx20::erase_if (m_memory , mapTuple ([&](auto && key, auto && /* value */ ) {
78
+ cxx20::erase_if (m_state. memory , mapTuple ([&](auto && key, auto && /* value */ ) {
79
79
return !m_knowledgeBase.knownToBeDifferentByAtLeast32 (vars->first , key);
80
80
}));
81
- m_memory [vars->first ] = vars->second ;
81
+ m_state. memory [vars->first ] = vars->second ;
82
82
}
83
83
else
84
84
{
@@ -117,8 +117,8 @@ void DataFlowAnalyzer::operator()(VariableDeclaration& _varDecl)
117
117
void DataFlowAnalyzer::operator ()(If& _if)
118
118
{
119
119
clearKnowledgeIfInvalidated (*_if.condition );
120
- unordered_map<YulString, YulString> storage = m_storage ;
121
- unordered_map<YulString, YulString> memory = m_memory ;
120
+ unordered_map<YulString, YulString> storage = m_state. storage ;
121
+ unordered_map<YulString, YulString> memory = m_state. memory ;
122
122
123
123
ASTModifier::operator ()(_if);
124
124
@@ -134,8 +134,8 @@ void DataFlowAnalyzer::operator()(Switch& _switch)
134
134
set<YulString> assignedVariables;
135
135
for (auto & _case: _switch.cases )
136
136
{
137
- unordered_map<YulString, YulString> storage = m_storage ;
138
- unordered_map<YulString, YulString> memory = m_memory ;
137
+ unordered_map<YulString, YulString> storage = m_state. storage ;
138
+ unordered_map<YulString, YulString> memory = m_state. memory ;
139
139
(*this )(_case.body );
140
140
joinKnowledge (storage, memory);
141
141
@@ -154,11 +154,8 @@ void DataFlowAnalyzer::operator()(FunctionDefinition& _fun)
154
154
{
155
155
// Save all information. We might rather reinstantiate this class,
156
156
// but this could be difficult if it is subclassed.
157
- ScopedSaveAndRestore valueResetter (m_value , {});
157
+ ScopedSaveAndRestore stateResetter (m_state , {});
158
158
ScopedSaveAndRestore loopDepthResetter (m_loopDepth, 0u );
159
- ScopedSaveAndRestore referencesResetter (m_references, {});
160
- ScopedSaveAndRestore storageResetter (m_storage, {});
161
- ScopedSaveAndRestore memoryResetter (m_memory, {});
162
159
pushScope (true );
163
160
164
161
for (auto const & parameter: _fun.parameters )
@@ -221,15 +218,15 @@ void DataFlowAnalyzer::operator()(Block& _block)
221
218
222
219
optional<YulString> DataFlowAnalyzer::storageValue (YulString _key) const
223
220
{
224
- if (YulString const * value = util::valueOrNullptr (m_storage , _key))
221
+ if (YulString const * value = util::valueOrNullptr (m_state. storage , _key))
225
222
return *value;
226
223
else
227
224
return nullopt;
228
225
}
229
226
230
227
optional<YulString> DataFlowAnalyzer::memoryValue (YulString _key) const
231
228
{
232
- if (YulString const * value = util::valueOrNullptr (m_memory , _key))
229
+ if (YulString const * value = util::valueOrNullptr (m_state. memory , _key))
233
230
return *value;
234
231
else
235
232
return nullopt;
@@ -259,17 +256,17 @@ void DataFlowAnalyzer::handleAssignment(set<YulString> const& _variables, Expres
259
256
auto const & referencedVariables = movableChecker.referencedVariables ();
260
257
for (auto const & name: _variables)
261
258
{
262
- m_references [name] = referencedVariables;
259
+ m_state. references [name] = referencedVariables;
263
260
if (!_isDeclaration)
264
261
{
265
262
// assignment to slot denoted by "name"
266
- m_storage .erase (name);
263
+ m_state. storage .erase (name);
267
264
// assignment to slot contents denoted by "name"
268
- cxx20::erase_if (m_storage , mapTuple ([&name](auto && /* key */ , auto && value) { return value == name; }));
265
+ cxx20::erase_if (m_state. storage , mapTuple ([&name](auto && /* key */ , auto && value) { return value == name; }));
269
266
// assignment to slot denoted by "name"
270
- m_memory .erase (name);
267
+ m_state. memory .erase (name);
271
268
// assignment to slot contents denoted by "name"
272
- cxx20::erase_if (m_memory , mapTuple ([&name](auto && /* key */ , auto && value) { return value == name; }));
269
+ cxx20::erase_if (m_state. memory , mapTuple ([&name](auto && /* key */ , auto && value) { return value == name; }));
273
270
}
274
271
}
275
272
@@ -282,9 +279,9 @@ void DataFlowAnalyzer::handleAssignment(set<YulString> const& _variables, Expres
282
279
// On the other hand, if we knew the value in the slot
283
280
// already, then the sload() / mload() would have been replaced by a variable anyway.
284
281
if (auto key = isSimpleLoad (StoreLoadLocation::Memory, *_value))
285
- m_memory [*key] = variable;
282
+ m_state. memory [*key] = variable;
286
283
else if (auto key = isSimpleLoad (StoreLoadLocation::Storage, *_value))
287
- m_storage [*key] = variable;
284
+ m_state. storage [*key] = variable;
288
285
}
289
286
}
290
287
}
@@ -298,8 +295,8 @@ void DataFlowAnalyzer::popScope()
298
295
{
299
296
for (auto const & name: m_variableScopes.back ().variables )
300
297
{
301
- m_value .erase (name);
302
- m_references .erase (name);
298
+ m_state. value .erase (name);
299
+ m_state. references .erase (name);
303
300
}
304
301
m_variableScopes.pop_back ();
305
302
}
@@ -325,53 +322,53 @@ void DataFlowAnalyzer::clearValues(set<YulString> _variables)
325
322
auto eraseCondition = mapTuple ([&_variables](auto && key, auto && value) {
326
323
return _variables.count (key) || _variables.count (value);
327
324
});
328
- cxx20::erase_if (m_storage , eraseCondition);
329
- cxx20::erase_if (m_memory , eraseCondition);
325
+ cxx20::erase_if (m_state. storage , eraseCondition);
326
+ cxx20::erase_if (m_state. memory , eraseCondition);
330
327
331
328
// Also clear variables that reference variables to be cleared.
332
329
for (auto const & variableToClear: _variables)
333
- for (auto const & [ref, names]: m_references )
330
+ for (auto const & [ref, names]: m_state. references )
334
331
if (names.count (variableToClear))
335
332
_variables.emplace (ref);
336
333
337
334
// Clear the value and update the reference relation.
338
335
for (auto const & name: _variables)
339
336
{
340
- m_value .erase (name);
341
- m_references .erase (name);
337
+ m_state. value .erase (name);
338
+ m_state. references .erase (name);
342
339
}
343
340
}
344
341
345
342
void DataFlowAnalyzer::assignValue (YulString _variable, Expression const * _value)
346
343
{
347
- m_value [_variable] = {_value, m_loopDepth};
344
+ m_state. value [_variable] = {_value, m_loopDepth};
348
345
}
349
346
350
347
void DataFlowAnalyzer::clearKnowledgeIfInvalidated (Block const & _block)
351
348
{
352
349
SideEffectsCollector sideEffects (m_dialect, _block, &m_functionSideEffects);
353
350
if (sideEffects.invalidatesStorage ())
354
- m_storage .clear ();
351
+ m_state. storage .clear ();
355
352
if (sideEffects.invalidatesMemory ())
356
- m_memory .clear ();
353
+ m_state. memory .clear ();
357
354
}
358
355
359
356
void DataFlowAnalyzer::clearKnowledgeIfInvalidated (Expression const & _expr)
360
357
{
361
358
SideEffectsCollector sideEffects (m_dialect, _expr, &m_functionSideEffects);
362
359
if (sideEffects.invalidatesStorage ())
363
- m_storage .clear ();
360
+ m_state. storage .clear ();
364
361
if (sideEffects.invalidatesMemory ())
365
- m_memory .clear ();
362
+ m_state. memory .clear ();
366
363
}
367
364
368
365
void DataFlowAnalyzer::joinKnowledge (
369
366
unordered_map<YulString, YulString> const & _olderStorage,
370
367
unordered_map<YulString, YulString> const & _olderMemory
371
368
)
372
369
{
373
- joinKnowledgeHelper (m_storage , _olderStorage);
374
- joinKnowledgeHelper (m_memory , _olderMemory);
370
+ joinKnowledgeHelper (m_state. storage , _olderStorage);
371
+ joinKnowledgeHelper (m_state. memory , _olderMemory);
375
372
}
376
373
377
374
void DataFlowAnalyzer::joinKnowledgeHelper (
@@ -381,8 +378,8 @@ void DataFlowAnalyzer::joinKnowledgeHelper(
381
378
{
382
379
// We clear if the key does not exist in the older map or if the value is different.
383
380
// This also works for memory because _older is an "older version"
384
- // of m_memory and thus any overlapping write would have cleared the keys
385
- // that are not known to be different inside m_memory already.
381
+ // of m_state.memory and thus any overlapping write would have cleared the keys
382
+ // that are not known to be different inside m_state.memory already.
386
383
cxx20::erase_if (_this, mapTuple ([&_older](auto && key, auto && currentValue){
387
384
YulString const * oldValue = util::valueOrNullptr (_older, key);
388
385
return !oldValue || *oldValue != currentValue;
@@ -433,4 +430,3 @@ std::optional<YulString> DataFlowAnalyzer::isSimpleLoad(
433
430
return key->name ;
434
431
return {};
435
432
}
436
-
0 commit comments