aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--CMakeLists.txt2
-rw-r--r--Changelog.md5
-rw-r--r--docs/conf.py4
-rw-r--r--libevmasm/Assembly.cpp61
-rw-r--r--test/libsolidity/SolidityOptimizer.cpp20
5 files changed, 53 insertions, 39 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 20c96869..992ce392 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -8,7 +8,7 @@ include(EthPolicy)
eth_policy()
# project name and version should be set after cmake_policy CMP0048
-set(PROJECT_VERSION "0.4.5")
+set(PROJECT_VERSION "0.4.6")
project(solidity VERSION ${PROJECT_VERSION})
# Let's find our dependencies
diff --git a/Changelog.md b/Changelog.md
index abd8d593..eb1e5e72 100644
--- a/Changelog.md
+++ b/Changelog.md
@@ -1,3 +1,8 @@
+### 0.4.6 (2016-11-22)
+
+Bugfixes:
+ * Optimizer: Knowledge about state was not correctly cleared for JUMPDESTs
+
### 0.4.5 (2016-11-21)
Features:
diff --git a/docs/conf.py b/docs/conf.py
index e17d5fd8..bf0accb9 100644
--- a/docs/conf.py
+++ b/docs/conf.py
@@ -56,9 +56,9 @@ copyright = '2016, Ethereum'
# built documents.
#
# The short X.Y version.
-version = '0.4.5'
+version = '0.4.6'
# The full version, including alpha/beta/rc tags.
-release = '0.4.5-develop'
+release = '0.4.6-develop'
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
diff --git a/libevmasm/Assembly.cpp b/libevmasm/Assembly.cpp
index a3037456..c394afa2 100644
--- a/libevmasm/Assembly.cpp
+++ b/libevmasm/Assembly.cpp
@@ -360,46 +360,35 @@ map<u256, u256> Assembly::optimiseInternal(bool _enable, bool _isCreation, size_
auto iter = m_items.begin();
while (iter != m_items.end())
{
- auto end = iter;
- while (end != m_items.end())
- if (SemanticInformation::altersControlFlow(*end++))
- break;
-
KnownState emptyState;
CommonSubexpressionEliminator eliminator(emptyState);
- auto blockIter = iter;
- auto const blockEnd = end;
- while (blockIter < blockEnd)
+ auto orig = iter;
+ iter = eliminator.feedItems(iter, m_items.end());
+ bool shouldReplace = false;
+ AssemblyItems optimisedChunk;
+ try
+ {
+ optimisedChunk = eliminator.getOptimizedItems();
+ shouldReplace = (optimisedChunk.size() < size_t(iter - orig));
+ }
+ catch (StackTooDeepException const&)
+ {
+ // This might happen if the opcode reconstruction is not as efficient
+ // as the hand-crafted code.
+ }
+ catch (ItemNotAvailableException const&)
{
- auto orig = blockIter;
- blockIter = eliminator.feedItems(blockIter, blockEnd);
- bool shouldReplace = false;
- AssemblyItems optimisedChunk;
- try
- {
- optimisedChunk = eliminator.getOptimizedItems();
- shouldReplace = (optimisedChunk.size() < size_t(blockIter - orig));
- }
- catch (StackTooDeepException const&)
- {
- // This might happen if the opcode reconstruction is not as efficient
- // as the hand-crafted code.
- }
- catch (ItemNotAvailableException const&)
- {
- // This might happen if e.g. associativity and commutativity rules
- // reorganise the expression tree, but not all leaves are available.
- }
-
- if (shouldReplace)
- {
- count++;
- optimisedItems += optimisedChunk;
- }
- else
- copy(orig, blockIter, back_inserter(optimisedItems));
+ // This might happen if e.g. associativity and commutativity rules
+ // reorganise the expression tree, but not all leaves are available.
}
- iter = end;
+
+ if (shouldReplace)
+ {
+ count++;
+ optimisedItems += optimisedChunk;
+ }
+ else
+ copy(orig, iter, back_inserter(optimisedItems));
}
if (optimisedItems.size() < m_items.size())
{
diff --git a/test/libsolidity/SolidityOptimizer.cpp b/test/libsolidity/SolidityOptimizer.cpp
index 4991cf24..017fc0e9 100644
--- a/test/libsolidity/SolidityOptimizer.cpp
+++ b/test/libsolidity/SolidityOptimizer.cpp
@@ -1246,6 +1246,26 @@ BOOST_AUTO_TEST_CASE(dead_code_elimination_across_assemblies)
compareVersions("test()");
}
+BOOST_AUTO_TEST_CASE(invalid_state_at_control_flow_join)
+{
+ char const* sourceCode = R"(
+ contract Test {
+ uint256 public totalSupply = 100;
+ function f() returns (uint r) {
+ if (false)
+ r = totalSupply;
+ totalSupply -= 10;
+ }
+ function test() returns (uint) {
+ f();
+ return this.totalSupply();
+ }
+ }
+ )";
+ compileBothVersions(sourceCode);
+ compareVersions("test()");
+}
+
BOOST_AUTO_TEST_SUITE_END()
}