diff options
author | chriseth <c@ethdev.com> | 2016-01-15 23:26:12 +0800 |
---|---|---|
committer | chriseth <c@ethdev.com> | 2016-01-15 23:34:56 +0800 |
commit | 1b1b6651cd60fcaded8043dc00e61df075fe2e4a (patch) | |
tree | 505d2d3d342ef49e449317ca92324614a8d6a9b5 /ControlFlowGraph.cpp | |
parent | 6e98243ead4843a4dd28fcae312f3b8af6cc7b03 (diff) | |
download | dexon-solidity-1b1b6651cd60fcaded8043dc00e61df075fe2e4a.tar dexon-solidity-1b1b6651cd60fcaded8043dc00e61df075fe2e4a.tar.gz dexon-solidity-1b1b6651cd60fcaded8043dc00e61df075fe2e4a.tar.bz2 dexon-solidity-1b1b6651cd60fcaded8043dc00e61df075fe2e4a.tar.lz dexon-solidity-1b1b6651cd60fcaded8043dc00e61df075fe2e4a.tar.xz dexon-solidity-1b1b6651cd60fcaded8043dc00e61df075fe2e4a.tar.zst dexon-solidity-1b1b6651cd60fcaded8043dc00e61df075fe2e4a.zip |
Fix sequence number bug.
This bug resulted in incorrect storage access in some situations.
The reason was that when intersecting states, the sequence numbers
were not handled and thus some operations with too low
sequence numbers were used during code generation.
Diffstat (limited to 'ControlFlowGraph.cpp')
-rw-r--r-- | ControlFlowGraph.cpp | 40 |
1 files changed, 27 insertions, 13 deletions
diff --git a/ControlFlowGraph.cpp b/ControlFlowGraph.cpp index 5adb951a..1ad54d8c 100644 --- a/ControlFlowGraph.cpp +++ b/ControlFlowGraph.cpp @@ -221,22 +221,36 @@ void ControlFlowGraph::gatherKnowledge() KnownStatePointer emptyState = make_shared<KnownState>(); bool unknownJumpEncountered = false; - vector<pair<BlockId, KnownStatePointer>> workQueue({make_pair(BlockId::initial(), emptyState->copy())}); + struct WorkQueueItem { + BlockId blockId; + KnownStatePointer state; + set<BlockId> blocksSeen; + }; + + vector<WorkQueueItem> workQueue{WorkQueueItem{BlockId::initial(), emptyState->copy(), set<BlockId>()}}; + auto addWorkQueueItem = [&](WorkQueueItem const& _currentItem, BlockId _to, KnownStatePointer const& _state) + { + WorkQueueItem item; + item.blockId = _to; + item.state = _state->copy(); + item.blocksSeen = _currentItem.blocksSeen; + item.blocksSeen.insert(_currentItem.blockId); + workQueue.push_back(move(item)); + }; + while (!workQueue.empty()) { + WorkQueueItem item = move(workQueue.back()); + workQueue.pop_back(); //@todo we might have to do something like incrementing the sequence number for each JUMPDEST - assertThrow(!!workQueue.back().first, OptimizerException, ""); - if (!m_blocks.count(workQueue.back().first)) - { - workQueue.pop_back(); + assertThrow(!!item.blockId, OptimizerException, ""); + if (!m_blocks.count(item.blockId)) continue; // too bad, we do not know the tag, probably an invalid jump - } - BasicBlock& block = m_blocks.at(workQueue.back().first); - KnownStatePointer state = workQueue.back().second; - workQueue.pop_back(); + BasicBlock& block = m_blocks.at(item.blockId); + KnownStatePointer state = item.state; if (block.startState) { - state->reduceToCommonKnowledge(*block.startState); + state->reduceToCommonKnowledge(*block.startState, !item.blocksSeen.count(item.blockId)); if (*state == *block.startState) continue; } @@ -270,12 +284,12 @@ void ControlFlowGraph::gatherKnowledge() unknownJumpEncountered = true; for (auto const& it: m_blocks) if (it.second.begin < it.second.end && m_items[it.second.begin].type() == Tag) - workQueue.push_back(make_pair(it.first, emptyState->copy())); + workQueue.push_back(WorkQueueItem{it.first, emptyState, set<BlockId>()}); } } else for (auto tag: tags) - workQueue.push_back(make_pair(BlockId(tag), state->copy())); + addWorkQueueItem(item, BlockId(tag), state); } else if (block.begin <= pc && pc < block.end) state->feedItem(m_items.at(pc++)); @@ -287,7 +301,7 @@ void ControlFlowGraph::gatherKnowledge() block.endType == BasicBlock::EndType::HANDOVER || block.endType == BasicBlock::EndType::JUMPI ) - workQueue.push_back(make_pair(block.next, state->copy())); + addWorkQueueItem(item, block.next, state); } // Remove all blocks we never visited here. This might happen because a tag is pushed but |