From 5449ad3c5212a8ffacb57e8d66712e66bd798242 Mon Sep 17 00:00:00 2001 From: Daniel Kirchner Date: Mon, 9 Aug 2021 18:59:29 +0200 Subject: [PATCH] A first stack shuffling unit test. --- test/CMakeLists.txt | 1 + test/libyul/StackShufflingTest.cpp | 83 ++++++++++++++++++++++++++++++ 2 files changed, 84 insertions(+) create mode 100644 test/libyul/StackShufflingTest.cpp diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index f35660741..2c3615904 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -145,6 +145,7 @@ set(libyul_sources libyul/Parser.cpp libyul/StackLayoutGeneratorTest.cpp libyul/StackLayoutGeneratorTest.h + libyul/StackShufflingTest.cpp libyul/SyntaxTest.h libyul/SyntaxTest.cpp libyul/YulInterpreterTest.cpp diff --git a/test/libyul/StackShufflingTest.cpp b/test/libyul/StackShufflingTest.cpp new file mode 100644 index 000000000..f33134318 --- /dev/null +++ b/test/libyul/StackShufflingTest.cpp @@ -0,0 +1,83 @@ +/* + This file is part of solidity. + + solidity is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + solidity is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with solidity. If not, see . +*/ +/** + * Unit tests for stack shuffling. + */ +#include + +#include +#include + +#include + +using namespace std; + +namespace solidity::yul::test +{ + +BOOST_AUTO_TEST_SUITE(StackHelpers) + +BOOST_AUTO_TEST_CASE(avoid_deep_dup) +{ + vector variableContainer; + for (size_t i = 0; i < 15; ++i) + variableContainer.emplace_back(Scope::Variable{YulString{}, YulString("v" + to_string(i))}); + Stack from = {{ + VariableSlot{variableContainer[0]}, + VariableSlot{variableContainer[1]}, + VariableSlot{variableContainer[2]}, + VariableSlot{variableContainer[3]}, + VariableSlot{variableContainer[4]}, + VariableSlot{variableContainer[5]}, + VariableSlot{variableContainer[6]}, + VariableSlot{variableContainer[7]}, + VariableSlot{variableContainer[8]}, + VariableSlot{variableContainer[9]}, + VariableSlot{variableContainer[10]}, + VariableSlot{variableContainer[11]}, + VariableSlot{variableContainer[12]}, + VariableSlot{variableContainer[12]}, + VariableSlot{variableContainer[13]}, + VariableSlot{variableContainer[14]} + }}; + Stack to = {{ + VariableSlot{variableContainer[0]}, + VariableSlot{variableContainer[1]}, + VariableSlot{variableContainer[2]}, + VariableSlot{variableContainer[3]}, + VariableSlot{variableContainer[4]}, + VariableSlot{variableContainer[5]}, + VariableSlot{variableContainer[6]}, + VariableSlot{variableContainer[7]}, + VariableSlot{variableContainer[8]}, + VariableSlot{variableContainer[9]}, + VariableSlot{variableContainer[10]}, + VariableSlot{variableContainer[11]}, + VariableSlot{variableContainer[12]}, + VariableSlot{variableContainer[12]}, + VariableSlot{variableContainer[13]}, + VariableSlot{variableContainer[14]}, + VariableSlot{variableContainer[14]}, // While "optimal", bringing this slot up first will make the next unreachable. + VariableSlot{variableContainer[0]} + }}; + auto unreachable = OptimizedEVMCodeTransform::tryCreateStackLayout(from, to, {}); + BOOST_CHECK(unreachable.empty()); +} + +BOOST_AUTO_TEST_SUITE_END() + +} // end namespaces