Skip to content

Commit 3d9a180

Browse files
authored
Merge pull request #1417 from ethereum/fixOptimizer
Optimizer: Clear state for JUMPDESTs.
2 parents aa48008 + 7fb7d5a commit 3d9a180

File tree

3 files changed

+50
-36
lines changed

3 files changed

+50
-36
lines changed

Changelog.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
### 0.4.6 (2016-11-22)
2+
3+
Bugfixes:
4+
* Optimizer: Knowledge about state was not correctly cleared for JUMPDESTs
5+
16
### 0.4.5 (2016-11-21)
27

38
Features:

libevmasm/Assembly.cpp

Lines changed: 25 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -360,46 +360,35 @@ map<u256, u256> Assembly::optimiseInternal(bool _enable, bool _isCreation, size_
360360
auto iter = m_items.begin();
361361
while (iter != m_items.end())
362362
{
363-
auto end = iter;
364-
while (end != m_items.end())
365-
if (SemanticInformation::altersControlFlow(*end++))
366-
break;
367-
368363
KnownState emptyState;
369364
CommonSubexpressionEliminator eliminator(emptyState);
370-
auto blockIter = iter;
371-
auto const blockEnd = end;
372-
while (blockIter < blockEnd)
365+
auto orig = iter;
366+
iter = eliminator.feedItems(iter, m_items.end());
367+
bool shouldReplace = false;
368+
AssemblyItems optimisedChunk;
369+
try
370+
{
371+
optimisedChunk = eliminator.getOptimizedItems();
372+
shouldReplace = (optimisedChunk.size() < size_t(iter - orig));
373+
}
374+
catch (StackTooDeepException const&)
375+
{
376+
// This might happen if the opcode reconstruction is not as efficient
377+
// as the hand-crafted code.
378+
}
379+
catch (ItemNotAvailableException const&)
373380
{
374-
auto orig = blockIter;
375-
blockIter = eliminator.feedItems(blockIter, blockEnd);
376-
bool shouldReplace = false;
377-
AssemblyItems optimisedChunk;
378-
try
379-
{
380-
optimisedChunk = eliminator.getOptimizedItems();
381-
shouldReplace = (optimisedChunk.size() < size_t(blockIter - orig));
382-
}
383-
catch (StackTooDeepException const&)
384-
{
385-
// This might happen if the opcode reconstruction is not as efficient
386-
// as the hand-crafted code.
387-
}
388-
catch (ItemNotAvailableException const&)
389-
{
390-
// This might happen if e.g. associativity and commutativity rules
391-
// reorganise the expression tree, but not all leaves are available.
392-
}
393-
394-
if (shouldReplace)
395-
{
396-
count++;
397-
optimisedItems += optimisedChunk;
398-
}
399-
else
400-
copy(orig, blockIter, back_inserter(optimisedItems));
381+
// This might happen if e.g. associativity and commutativity rules
382+
// reorganise the expression tree, but not all leaves are available.
401383
}
402-
iter = end;
384+
385+
if (shouldReplace)
386+
{
387+
count++;
388+
optimisedItems += optimisedChunk;
389+
}
390+
else
391+
copy(orig, iter, back_inserter(optimisedItems));
403392
}
404393
if (optimisedItems.size() < m_items.size())
405394
{

test/libsolidity/SolidityOptimizer.cpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1246,6 +1246,26 @@ BOOST_AUTO_TEST_CASE(dead_code_elimination_across_assemblies)
12461246
compareVersions("test()");
12471247
}
12481248

1249+
BOOST_AUTO_TEST_CASE(invalid_state_at_control_flow_join)
1250+
{
1251+
char const* sourceCode = R"(
1252+
contract Test {
1253+
uint256 public totalSupply = 100;
1254+
function f() returns (uint r) {
1255+
if (false)
1256+
r = totalSupply;
1257+
totalSupply -= 10;
1258+
}
1259+
function test() returns (uint) {
1260+
f();
1261+
return this.totalSupply();
1262+
}
1263+
}
1264+
)";
1265+
compileBothVersions(sourceCode);
1266+
compareVersions("test()");
1267+
}
1268+
12491269
BOOST_AUTO_TEST_SUITE_END()
12501270

12511271
}

0 commit comments

Comments
 (0)