diff options
Diffstat (limited to 'test')
29 files changed, 799 insertions, 132 deletions
diff --git a/test/InteractiveTests.h b/test/InteractiveTests.h new file mode 100644 index 00000000..be076059 --- /dev/null +++ b/test/InteractiveTests.h @@ -0,0 +1,63 @@ +/* + 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 <http://www.gnu.org/licenses/>. +*/ + +#pragma once + +#include <test/TestCase.h> +#include <test/libsolidity/ASTJSONTest.h> +#include <test/libsolidity/SyntaxTest.h> +#include <test/libsolidity/SMTCheckerJSONTest.h> +#include <test/libyul/YulOptimizerTest.h> +#include <test/libyul/ObjectCompilerTest.h> + +#include <boost/filesystem.hpp> + +namespace dev +{ +namespace solidity +{ +namespace test +{ + +/** Container for all information regarding a testsuite */ +struct Testsuite +{ + char const* title; + boost::filesystem::path const path; + boost::filesystem::path const subpath; + bool smt; + bool ipc; + TestCase::TestCaseCreator testCaseCreator; +}; + + +/// Array of testsuits that can be run interactively as well as automatically +Testsuite const g_interactiveTestsuites[] = { +/* + Title Path Subpath SMT IPC Creator function */ + {"Yul Optimizer", "libyul", "yulOptimizerTests", false, false, &yul::test::YulOptimizerTest::create}, + {"Yul Object Compiler", "libyul", "objectCompiler", false, false, &yul::test::ObjectCompilerTest::create}, + {"Syntax", "libsolidity", "syntaxTests", false, false, &SyntaxTest::create}, + {"JSON AST", "libsolidity", "ASTJSON", false, false, &ASTJSONTest::create}, + {"SMT Checker", "libsolidity", "smtCheckerTests", true, false, &SyntaxTest::create}, + {"SMT Checker JSON", "libsolidity", "smtCheckerTestsJSON", true, false, &SMTCheckerTest::create} +}; + +} +} +} + diff --git a/test/boostTest.cpp b/test/boostTest.cpp index ff443d11..d6e75cb9 100644 --- a/test/boostTest.cpp +++ b/test/boostTest.cpp @@ -35,16 +35,13 @@ #pragma GCC diagnostic pop +#include <test/InteractiveTests.h> #include <test/Options.h> -#include <test/libsolidity/ASTJSONTest.h> -#include <test/libsolidity/SyntaxTest.h> -#include <test/libsolidity/SMTCheckerJSONTest.h> -#include <test/libyul/YulOptimizerTest.h> -#include <test/libyul/ObjectCompilerTest.h> #include <boost/algorithm/string.hpp> #include <boost/algorithm/string/predicate.hpp> #include <boost/filesystem.hpp> +#include <string> using namespace boost::unit_test; using namespace dev::solidity::test; @@ -129,46 +126,26 @@ test_suite* init_unit_test_suite( int /*argc*/, char* /*argv*/[] ) master_test_suite_t& master = framework::master_test_suite(); master.p_name.value = "SolidityTests"; dev::test::Options::get().validate(); - solAssert(registerTests( - master, - dev::test::Options::get().testPath / "libsolidity", - "syntaxTests", - SyntaxTest::create - ) > 0, "no syntax tests found"); - solAssert(registerTests( - master, - dev::test::Options::get().testPath / "libsolidity", - "ASTJSON", - ASTJSONTest::create - ) > 0, "no JSON AST tests found"); - solAssert(registerTests( - master, - dev::test::Options::get().testPath / "libyul", - "yulOptimizerTests", - yul::test::YulOptimizerTest::create - ) > 0, "no Yul Optimizer tests found"); - solAssert(registerTests( - master, - dev::test::Options::get().testPath / "libyul", - "objectCompiler", - yul::test::ObjectCompilerTest::create - ) > 0, "no Yul Object compiler tests found"); - if (!dev::test::Options::get().disableSMT) + + // Include the interactive tests in the automatic tests as well + for (auto const& ts: g_interactiveTestsuites) { - solAssert(registerTests( - master, - dev::test::Options::get().testPath / "libsolidity", - "smtCheckerTests", - SyntaxTest::create - ) > 0, "no SMT checker tests found"); + auto const& options = dev::test::Options::get(); + + if (ts.smt && options.disableSMT) + continue; + + if (ts.ipc && options.disableIPC) + continue; solAssert(registerTests( master, - dev::test::Options::get().testPath / "libsolidity", - "smtCheckerTestsJSON", - SMTCheckerTest::create - ) > 0, "no SMT checker JSON tests found"); + options.testPath / ts.path, + ts.subpath, + ts.testCaseCreator + ) > 0, std::string("no ") + ts.title + " tests found"); } + if (dev::test::Options::get().disableIPC) { for (auto suite: { @@ -183,11 +160,13 @@ test_suite* init_unit_test_suite( int /*argc*/, char* /*argv*/[] ) "LLLEndToEndTest", #endif "GasMeterTests", + "GasCostTests", "SolidityEndToEndTest", "SolidityOptimizer" }) removeTestSuite(suite); } + if (dev::test::Options::get().disableSMT) removeTestSuite("SMTChecker"); diff --git a/test/cmdlineTests/data_storage.sol b/test/cmdlineTests/data_storage.sol new file mode 100644 index 00000000..cc602cc9 --- /dev/null +++ b/test/cmdlineTests/data_storage.sol @@ -0,0 +1,15 @@ +pragma solidity >=0.0; + +contract C { + function f() pure public { + require(false, "1234567890123456789012345678901"); + require(false, "12345678901234567890123456789012"); + require(false, "123456789012345678901234567890123"); + require(false, "1234567890123456789012345678901234"); + require(false, "12345678901234567890123456789012345"); + require(false, "123456789012345678901234567890123456"); + require(false, "123456789012345678901234567890121234567890123456789012345678901"); + require(false, "1234567890123456789012345678901212345678901234567890123456789012"); + require(false, "12345678901234567890123456789012123456789012345678901234567890123"); + } +} diff --git a/test/cmdlineTests/data_storage.sol.args b/test/cmdlineTests/data_storage.sol.args new file mode 100644 index 00000000..3684987e --- /dev/null +++ b/test/cmdlineTests/data_storage.sol.args @@ -0,0 +1 @@ +--gas diff --git a/test/cmdlineTests/data_storage.sol.stdout b/test/cmdlineTests/data_storage.sol.stdout new file mode 100644 index 00000000..4a5250f7 --- /dev/null +++ b/test/cmdlineTests/data_storage.sol.stdout @@ -0,0 +1,7 @@ + +======= data_storage.sol:C ======= +Gas estimation: +construction: + 306 + 264400 = 264706 +external: + f(): 263 diff --git a/test/libsolidity/GasCosts.cpp b/test/libsolidity/GasCosts.cpp new file mode 100644 index 00000000..15658a91 --- /dev/null +++ b/test/libsolidity/GasCosts.cpp @@ -0,0 +1,89 @@ +/* + 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 <http://www.gnu.org/licenses/>. +*/ +/** + * Tests that check that the cost of certain operations stay within range. + */ + +#include <test/libsolidity/SolidityExecutionFramework.h> + +#include <cmath> + +using namespace std; +using namespace langutil; +using namespace dev::eth; +using namespace dev::solidity; +using namespace dev::test; + +namespace dev +{ +namespace solidity +{ +namespace test +{ + +#define CHECK_GAS(_gasNoOpt, _gasOpt, _tolerance) \ + do \ + { \ + u256 gasOpt{_gasOpt}; \ + u256 gasNoOpt{_gasNoOpt}; \ + u256 tolerance{_tolerance}; \ + u256 gas = m_optimize ? gasOpt : gasNoOpt; \ + u256 diff = gas < m_gasUsed ? m_gasUsed - gas : gas - m_gasUsed; \ + BOOST_CHECK_MESSAGE( \ + diff <= tolerance, \ + "Gas used: " + \ + m_gasUsed.str() + \ + " - expected: " + \ + gas.str() + \ + " (tolerance: " + \ + tolerance.str() + \ + ")" \ + ); \ + } while(0) + +BOOST_FIXTURE_TEST_SUITE(GasCostTests, SolidityExecutionFramework) + +BOOST_AUTO_TEST_CASE(string_storage) +{ + char const* sourceCode = R"( + contract C { + function f() pure public { + require(false, "Not Authorized. This function can only be called by the custodian or owner of this contract"); + } + } + )"; + compileAndRun(sourceCode); + + if (Options::get().evmVersion() <= EVMVersion::byzantium()) + CHECK_GAS(134435, 130591, 100); + else + CHECK_GAS(127225, 124873, 100); + if (Options::get().evmVersion() >= EVMVersion::byzantium()) + { + callContractFunction("f()"); + if (Options::get().evmVersion() == EVMVersion::byzantium()) + CHECK_GAS(21551, 21526, 20); + else + CHECK_GAS(21546, 21526, 20); + } +} + +BOOST_AUTO_TEST_SUITE_END() + +} +} +} diff --git a/test/libsolidity/SolidityEndToEndTest.cpp b/test/libsolidity/SolidityEndToEndTest.cpp index c6135a72..dfa60fc5 100644 --- a/test/libsolidity/SolidityEndToEndTest.cpp +++ b/test/libsolidity/SolidityEndToEndTest.cpp @@ -12245,7 +12245,7 @@ BOOST_AUTO_TEST_CASE(include_creation_bytecode_only_once) compileAndRun(sourceCode); BOOST_CHECK_LE( double(m_compiler.object("Double").bytecode.size()), - 1.1 * double(m_compiler.object("Single").bytecode.size()) + 1.2 * double(m_compiler.object("Single").bytecode.size()) ); } diff --git a/test/libsolidity/smtCheckerTests/functions/functions_identity_as_tuple.sol b/test/libsolidity/smtCheckerTests/functions/functions_identity_as_tuple.sol index 3793f411..2ecff63e 100644 --- a/test/libsolidity/smtCheckerTests/functions/functions_identity_as_tuple.sol +++ b/test/libsolidity/smtCheckerTests/functions/functions_identity_as_tuple.sol @@ -12,3 +12,4 @@ contract C } // ---- +// Warning: (153-156): Assertion checker does not yet implement tuples and inline arrays. diff --git a/test/libsolidity/smtCheckerTests/functions/functions_identity_as_tuple_fail.sol b/test/libsolidity/smtCheckerTests/functions/functions_identity_as_tuple_fail.sol index e3c80594..a9bde9e4 100644 --- a/test/libsolidity/smtCheckerTests/functions/functions_identity_as_tuple_fail.sol +++ b/test/libsolidity/smtCheckerTests/functions/functions_identity_as_tuple_fail.sol @@ -12,4 +12,5 @@ contract C } // ---- +// Warning: (153-156): Assertion checker does not yet implement tuples and inline arrays. // Warning: (163-176): Assertion violation happens here diff --git a/test/libsolidity/smtCheckerTests/special/msg_data.sol b/test/libsolidity/smtCheckerTests/special/msg_data.sol index 7e748f09..b667f971 100644 --- a/test/libsolidity/smtCheckerTests/special/msg_data.sol +++ b/test/libsolidity/smtCheckerTests/special/msg_data.sol @@ -8,7 +8,6 @@ contract C } // ---- // Warning: (86-101): Assertion checker does not yet support this expression. -// Warning: (86-94): Assertion checker does not yet support this special variable. -// Warning: (86-94): Assertion checker does not yet implement this type. +// Warning: (86-94): Assertion checker does not yet support this global variable. // Warning: (86-101): Internal error: Expression undefined for SMT solver. // Warning: (79-106): Assertion violation happens here diff --git a/test/libsolidity/smtCheckerTests/types/bytes_1.sol b/test/libsolidity/smtCheckerTests/types/bytes_1.sol new file mode 100644 index 00000000..fb957421 --- /dev/null +++ b/test/libsolidity/smtCheckerTests/types/bytes_1.sol @@ -0,0 +1,16 @@ +pragma experimental SMTChecker; + +contract C +{ + function f(bytes memory b) public pure returns (bytes memory) { + bytes memory c = b; + return b; + } +} +// ---- +// Warning: (113-127): Unused local variable. +// Warning: (113-127): Assertion checker does not yet support the type of this variable. +// Warning: (58-72): Assertion checker does not yet support the type of this variable. +// Warning: (95-107): Assertion checker does not yet support the type of this variable. +// Warning: (130-131): Internal error: Expression undefined for SMT solver. +// Warning: (130-131): Assertion checker does not yet implement this type. diff --git a/test/libsolidity/smtCheckerTestsJSON/multi.json b/test/libsolidity/smtCheckerTestsJSON/multi.json index 2ed5150d..df45fbf4 100644 --- a/test/libsolidity/smtCheckerTestsJSON/multi.json +++ b/test/libsolidity/smtCheckerTestsJSON/multi.json @@ -1,11 +1,11 @@ { - "auxiliaryInput": - { - "smtlib2responses": - { - "0x0426cd198d1e7123a28ffac2b759a666b86508ad046babf5166500dd6d8ed308": "unsat\n(error \"line 31 column 26: model is not available\")", - "0xa51ca41ae407f5a727f27101cbc079834743cc8955f9f585582034ca634953f6": "sat\n((|EVALEXPR_0| 1))", - "0xe9477f683ff20aa57fcb08682150f86c5917e1d4c0686b278ab9b73446d0682c": "sat\n((|EVALEXPR_0| 0))" - } - } + "auxiliaryInput": + { + "smtlib2responses": + { + "0x47826ec8b83cfec30171b34f944aed6c33ecd12f02b9ad522ca45317c9bd5f45": "sat\n((|EVALEXPR_0| 1))", + "0x734c058efe9d6ec224de3cf2bdfa6c936a1c9c159c040c128d631145b2fed195": "unsat\n", + "0xa0c072acdbe5181dd56cbad8960cb5bb0b9e97fd598cfd895467bd73bbcca028": "sat\n((|EVALEXPR_0| 0))" + } + } } diff --git a/test/libsolidity/smtCheckerTestsJSON/simple.json b/test/libsolidity/smtCheckerTestsJSON/simple.json index fd976b63..b82d93b8 100644 --- a/test/libsolidity/smtCheckerTestsJSON/simple.json +++ b/test/libsolidity/smtCheckerTestsJSON/simple.json @@ -1,9 +1,9 @@ { - "auxiliaryInput": - { - "smtlib2responses": - { - "0xe9477f683ff20aa57fcb08682150f86c5917e1d4c0686b278ab9b73446d0682c": "sat\n((|EVALEXPR_0| 0))" - } - } + "auxiliaryInput": + { + "smtlib2responses": + { + "0xa0c072acdbe5181dd56cbad8960cb5bb0b9e97fd598cfd895467bd73bbcca028": "sat\n((|EVALEXPR_0| 0))\n" + } + } } diff --git a/test/libsolidity/syntaxTests/nameAndTypeResolution/313_fixed_type_size_capabilities.sol b/test/libsolidity/syntaxTests/nameAndTypeResolution/313_fixed_type_size_capabilities.sol index 441cf81e..295cf4ea 100644 --- a/test/libsolidity/syntaxTests/nameAndTypeResolution/313_fixed_type_size_capabilities.sol +++ b/test/libsolidity/syntaxTests/nameAndTypeResolution/313_fixed_type_size_capabilities.sol @@ -10,4 +10,5 @@ contract test { } } // ---- -// Warning: (20-707): Function state mutability can be restricted to pure +// TypeError: (153-250): Type rational_const 9208...(70 digits omitted)...7637 / 1000...(71 digits omitted)...0000 is not implicitly convertible to expected type ufixed256x77, but it can be explicitly converted. +// TypeError: (470-566): Type rational_const -933...(70 digits omitted)...0123 / 1000...(70 digits omitted)...0000 is not implicitly convertible to expected type fixed256x76, but it can be explicitly converted. diff --git a/test/libsolidity/syntaxTests/types/rational_number_literal_to_fixed_implicit.sol b/test/libsolidity/syntaxTests/types/rational_number_literal_to_fixed_implicit.sol new file mode 100644 index 00000000..ca50e03b --- /dev/null +++ b/test/libsolidity/syntaxTests/types/rational_number_literal_to_fixed_implicit.sol @@ -0,0 +1,15 @@ +contract C { + function literalToUFixed() public pure { + ufixed8x2 a = 0.10; + ufixed8x2 b = 0.00; + ufixed8x2 c = 2.55; + a; b; c; + } + function literalToFixed() public pure { + fixed8x1 a = 0.1; + fixed8x1 b = 12.7; + fixed8x1 c = -12.8; + a; b; c; + } +} +// ---- diff --git a/test/libsolidity/syntaxTests/types/too_small_negative_numbers.sol b/test/libsolidity/syntaxTests/types/too_small_negative_numbers.sol index 66bd9a8e..f86ffcdd 100644 --- a/test/libsolidity/syntaxTests/types/too_small_negative_numbers.sol +++ b/test/libsolidity/syntaxTests/types/too_small_negative_numbers.sol @@ -2,3 +2,4 @@ contract C { fixed8x80 a = -1e-100; } // ---- +// TypeError: (29-36): Type rational_const -1 / 1000...(93 digits omitted)...0000 is not implicitly convertible to expected type fixed8x80, but it can be explicitly converted. diff --git a/test/libyul/Common.cpp b/test/libyul/Common.cpp index 0f2529de..a337fa8d 100644 --- a/test/libyul/Common.cpp +++ b/test/libyul/Common.cpp @@ -29,6 +29,7 @@ #include <libyul/AsmParser.h> #include <libyul/AsmAnalysis.h> #include <libyul/AsmPrinter.h> +#include <libyul/backends/evm/EVMDialect.h> #include <liblangutil/Scanner.h> #include <liblangutil/ErrorReporter.h> @@ -54,7 +55,7 @@ void yul::test::printErrors(ErrorList const& _errors) pair<shared_ptr<Block>, shared_ptr<yul::AsmAnalysisInfo>> yul::test::parse(string const& _source, bool _yul) { - Dialect dialect = _yul ? yul::Dialect::yul() : yul::Dialect::strictAssemblyForEVM(); + shared_ptr<Dialect> dialect = _yul ? yul::Dialect::yul() : yul::EVMDialect::strictAssemblyForEVM(); ErrorList errors; ErrorReporter errorReporter(errors); auto scanner = make_shared<Scanner>(CharStream(_source, "")); diff --git a/test/libyul/Parser.cpp b/test/libyul/Parser.cpp index eb2e735a..5e9fba86 100644 --- a/test/libyul/Parser.cpp +++ b/test/libyul/Parser.cpp @@ -49,7 +49,7 @@ namespace test namespace { -bool parse(string const& _source, Dialect const& _dialect, ErrorReporter& errorReporter) +bool parse(string const& _source, std::shared_ptr<Dialect> _dialect, ErrorReporter& errorReporter) { try { @@ -74,7 +74,7 @@ bool parse(string const& _source, Dialect const& _dialect, ErrorReporter& errorR return false; } -boost::optional<Error> parseAndReturnFirstError(string const& _source, Dialect const& _dialect, bool _allowWarnings = true) +boost::optional<Error> parseAndReturnFirstError(string const& _source, shared_ptr<Dialect> _dialect, bool _allowWarnings = true) { ErrorList errors; ErrorReporter errorReporter(errors); @@ -99,12 +99,12 @@ boost::optional<Error> parseAndReturnFirstError(string const& _source, Dialect c return {}; } -bool successParse(std::string const& _source, Dialect const& _dialect = Dialect::yul(), bool _allowWarnings = true) +bool successParse(std::string const& _source, shared_ptr<Dialect> _dialect = Dialect::yul(), bool _allowWarnings = true) { return !parseAndReturnFirstError(_source, _dialect, _allowWarnings); } -Error expectError(std::string const& _source, Dialect const& _dialect = Dialect::yul(), bool _allowWarnings = false) +Error expectError(std::string const& _source, shared_ptr<Dialect> _dialect = Dialect::yul(), bool _allowWarnings = false) { auto error = parseAndReturnFirstError(_source, _dialect, _allowWarnings); @@ -306,16 +306,17 @@ BOOST_AUTO_TEST_CASE(if_statement_invalid) BOOST_AUTO_TEST_CASE(builtins_parser) { - struct SimpleBuiltins: public Builtins + struct SimpleDialect: public Dialect { - BuiltinFunction const* query(YulString _name) const override + SimpleDialect(): Dialect(AsmFlavour::Strict) {} + BuiltinFunction const* builtin(YulString _name) const override { return _name == YulString{"builtin"} ? &f : nullptr; } BuiltinFunction f; }; - Dialect dialect(AsmFlavour::Strict, make_shared<SimpleBuiltins>()); + shared_ptr<Dialect> dialect = make_shared<SimpleDialect>(); CHECK_ERROR_DIALECT("{ let builtin := 6 }", ParserError, "Cannot use builtin function name \"builtin\" as identifier name.", dialect); CHECK_ERROR_DIALECT("{ function builtin() {} }", ParserError, "Cannot use builtin function name \"builtin\" as identifier name.", dialect); CHECK_ERROR_DIALECT("{ builtin := 6 }", ParserError, "Cannot assign to builtin function \"builtin\".", dialect); @@ -323,16 +324,17 @@ BOOST_AUTO_TEST_CASE(builtins_parser) BOOST_AUTO_TEST_CASE(builtins_analysis) { - struct SimpleBuiltinsAnalysis: public Builtins + struct SimpleDialect: public Dialect { - yul::BuiltinFunction const* query(YulString _name) const override + SimpleDialect(): Dialect(AsmFlavour::Strict) {} + BuiltinFunction const* builtin(YulString _name) const override { - return _name == YulString("builtin") ? &m_builtin : nullptr; + return _name == YulString{"builtin"} ? &f : nullptr; } - BuiltinFunction m_builtin{YulString{"builtin"}, vector<Type>(2), vector<Type>(3), false}; + BuiltinFunction f{YulString{"builtin"}, vector<Type>(2), vector<Type>(3), false}; }; - Dialect dialect(AsmFlavour::Strict, make_shared<SimpleBuiltinsAnalysis>()); + shared_ptr<Dialect> dialect = make_shared<SimpleDialect>(); BOOST_CHECK(successParse("{ let a, b, c := builtin(1, 2) }", dialect)); CHECK_ERROR_DIALECT("{ let a, b, c := builtin(1) }", TypeError, "Function expects 2 arguments but got 1", dialect); CHECK_ERROR_DIALECT("{ let a, b := builtin(1, 2) }", DeclarationError, "Variable count mismatch: 2 variables and 3 values.", dialect); diff --git a/test/libyul/StackReuseCodegen.cpp b/test/libyul/StackReuseCodegen.cpp new file mode 100644 index 00000000..97be11d3 --- /dev/null +++ b/test/libyul/StackReuseCodegen.cpp @@ -0,0 +1,353 @@ +/* + 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 <http://www.gnu.org/licenses/>. +*/ +/** + * Unit tests for stack-reusing code generator. + */ + +#include <test/Options.h> + +#include <libsolidity/interface/AssemblyStack.h> +#include <libevmasm/Instruction.h> + +using namespace std; + +namespace dev +{ +namespace yul +{ +namespace test +{ + +namespace +{ +string assemble(string const& _input) +{ + solidity::AssemblyStack asmStack; + BOOST_REQUIRE_MESSAGE(asmStack.parseAndAnalyze("", _input), "Source did not parse: " + _input); + return solidity::disassemble(asmStack.assemble(solidity::AssemblyStack::Machine::EVM, true).bytecode->bytecode); +} +} + +BOOST_AUTO_TEST_SUITE(StackReuseCodegen) + +BOOST_AUTO_TEST_CASE(smoke_test) +{ + string out = assemble("{}"); + BOOST_CHECK_EQUAL(out, ""); +} + +BOOST_AUTO_TEST_CASE(single_var) +{ + string out = assemble("{ let x }"); + BOOST_CHECK_EQUAL(out, "PUSH1 0x0 POP "); +} + +BOOST_AUTO_TEST_CASE(single_var_assigned) +{ + string out = assemble("{ let x := 1 }"); + BOOST_CHECK_EQUAL(out, "PUSH1 0x1 POP "); +} + +BOOST_AUTO_TEST_CASE(single_var_assigned_plus_code) +{ + string out = assemble("{ let x := 1 mstore(3, 4) }"); + BOOST_CHECK_EQUAL(out, "PUSH1 0x1 POP PUSH1 0x4 PUSH1 0x3 MSTORE "); +} + +BOOST_AUTO_TEST_CASE(single_var_assigned_plus_code_and_reused) +{ + string out = assemble("{ let x := 1 mstore(3, 4) pop(mload(x)) }"); + BOOST_CHECK_EQUAL(out, "PUSH1 0x1 PUSH1 0x4 PUSH1 0x3 MSTORE DUP1 MLOAD POP POP "); +} + +BOOST_AUTO_TEST_CASE(multi_reuse_single_slot) +{ + string out = assemble("{ let x := 1 x := 6 let y := 2 y := 4 }"); + BOOST_CHECK_EQUAL(out, "PUSH1 0x1 PUSH1 0x6 SWAP1 POP POP PUSH1 0x2 PUSH1 0x4 SWAP1 POP POP "); +} + +BOOST_AUTO_TEST_CASE(multi_reuse_single_slot_nested) +{ + string out = assemble("{ let x := 1 x := 6 { let y := 2 y := 4 } }"); + BOOST_CHECK_EQUAL(out, "PUSH1 0x1 PUSH1 0x6 SWAP1 POP POP PUSH1 0x2 PUSH1 0x4 SWAP1 POP POP "); +} + +BOOST_AUTO_TEST_CASE(multi_reuse_same_variable_name) +{ + string out = assemble("{ let z := mload(0) { let x := 1 x := 6 z := x } { let x := 2 z := x x := 4 } }"); + BOOST_CHECK_EQUAL(out, + "PUSH1 0x0 MLOAD " + "PUSH1 0x1 PUSH1 0x6 SWAP1 POP DUP1 SWAP2 POP POP " + "PUSH1 0x2 DUP1 SWAP2 POP PUSH1 0x4 SWAP1 POP POP " + "POP " + ); +} + +BOOST_AUTO_TEST_CASE(last_use_in_nested_block) +{ + string out = assemble("{ let z := 0 { pop(z) } let x := 1 }"); + BOOST_CHECK_EQUAL(out, "PUSH1 0x0 DUP1 POP POP PUSH1 0x1 POP "); +} + +BOOST_AUTO_TEST_CASE(if_) +{ + // z is only removed after the if (after the jumpdest) + string out = assemble("{ let z := mload(0) if z { let x := z } let t := 3 }"); + BOOST_CHECK_EQUAL(out, "PUSH1 0x0 MLOAD DUP1 ISZERO PUSH1 0xA JUMPI DUP1 POP JUMPDEST POP PUSH1 0x3 POP "); +} + +BOOST_AUTO_TEST_CASE(switch_) +{ + string out = assemble("{ let z := 0 switch z case 0 { let x := 2 let y := 3 } default { z := 3 } let t := 9 }"); + BOOST_CHECK_EQUAL(out, + "PUSH1 0x0 DUP1 " + "PUSH1 0x0 DUP2 EQ PUSH1 0x11 JUMPI " + "PUSH1 0x3 SWAP2 POP PUSH1 0x18 JUMP " + "JUMPDEST PUSH1 0x2 POP PUSH1 0x3 POP " + "JUMPDEST POP POP " // This is where z and its copy (switch condition) can be removed. + "PUSH1 0x9 POP " + ); +} + +BOOST_AUTO_TEST_CASE(reuse_slots) +{ + // x and y should reuse the slots of b and d + string out = assemble("{ let a, b, c, d let x := 2 let y := 3 mstore(x, a) mstore(y, c) }"); + BOOST_CHECK_EQUAL(out, + "PUSH1 0x0 PUSH1 0x0 PUSH1 0x0 PUSH1 0x0 " + "POP " // d is removed right away + "PUSH1 0x2 SWAP2 POP " // x is stored at b's slot + "PUSH1 0x3 DUP4 DUP4 MSTORE " + "DUP2 DUP2 MSTORE " + "POP POP POP POP " + ); +} + +BOOST_AUTO_TEST_CASE(for_1) +{ + // Special scoping rules, but can remove z early + string out = assemble("{ for { let z := 0 } 1 { } { let x := 3 } let t := 2 }"); + BOOST_CHECK_EQUAL(out, + "PUSH1 0x0 POP " + "JUMPDEST PUSH1 0x1 ISZERO PUSH1 0x11 JUMPI " + "PUSH1 0x3 POP JUMPDEST PUSH1 0x3 JUMP " + "JUMPDEST PUSH1 0x2 POP " + ); +} + +BOOST_AUTO_TEST_CASE(for_2) +{ + // Special scoping rules, cannot remove z until after the loop! + string out = assemble("{ for { let z := 0 } 1 { } { z := 8 let x := 3 } let t := 2 }"); + BOOST_CHECK_EQUAL(out, + "PUSH1 0x0 " + "JUMPDEST PUSH1 0x1 ISZERO PUSH1 0x14 JUMPI " + "PUSH1 0x8 SWAP1 POP " + "PUSH1 0x3 POP " + "JUMPDEST PUSH1 0x2 JUMP " + "JUMPDEST POP " // z is removed + "PUSH1 0x2 POP " + ); +} + +BOOST_AUTO_TEST_CASE(function_trivial) +{ + string in = R"({ + function f() { } + })"; + BOOST_CHECK_EQUAL(assemble(in), + "PUSH1 0x5 JUMP JUMPDEST JUMP JUMPDEST " + ); +} + +BOOST_AUTO_TEST_CASE(function_retparam) +{ + string in = R"({ + function f() -> x, y { } + })"; + BOOST_CHECK_EQUAL(assemble(in), + "PUSH1 0xB JUMP " + "JUMPDEST PUSH1 0x0 PUSH1 0x0 SWAP1 SWAP2 JUMP " + "JUMPDEST " + ); +} + +BOOST_AUTO_TEST_CASE(function_params) +{ + string in = R"({ + function f(a, b) { } + })"; + BOOST_CHECK_EQUAL(assemble(in), "PUSH1 0x7 JUMP JUMPDEST POP POP JUMP JUMPDEST "); +} + +BOOST_AUTO_TEST_CASE(function_params_and_retparams) +{ + string in = R"({ + function f(a, b, c, d) -> x, y { } + })"; + // This does not re-use the parameters for the return parameters + // We do not expect parameters to be fully unused, so the stack + // layout for a function is still fixed, even though parameters + // can be re-used. + BOOST_CHECK_EQUAL(assemble(in), + "PUSH1 0x10 JUMP JUMPDEST PUSH1 0x0 PUSH1 0x0 SWAP5 POP SWAP5 SWAP3 POP POP POP JUMP JUMPDEST " + ); +} + +BOOST_AUTO_TEST_CASE(function_params_and_retparams_partly_unused) +{ + string in = R"({ + function f(a, b, c, d) -> x, y { b := 3 let s := 9 y := 2 mstore(s, y) } + })"; + BOOST_CHECK_EQUAL(assemble(in), + "PUSH1 0x1E JUMP " + "JUMPDEST PUSH1 0x0 PUSH1 0x0 " + "PUSH1 0x3 SWAP4 POP " + "PUSH1 0x9 PUSH1 0x2 SWAP2 POP " + "DUP2 DUP2 MSTORE " + "POP SWAP5 POP SWAP5 SWAP3 POP POP POP JUMP " + "JUMPDEST " + ); +} + +BOOST_AUTO_TEST_CASE(function_with_body_embedded) +{ + string in = R"({ + let b := 3 + function f(a, r) -> t { + // r could be removed right away, but a cannot - this is not implemented, though + let x := a a := 3 t := a + } + b := 7 + })"; + BOOST_CHECK_EQUAL(assemble(in), + "PUSH1 0x3 PUSH1 " + "0x16 JUMP " + "JUMPDEST PUSH1 0x0 " // start of f, initialize t + "DUP2 POP " // let x := a + "PUSH1 0x3 SWAP2 POP " + "DUP2 SWAP1 POP " + "SWAP3 SWAP2 POP POP JUMP " + "JUMPDEST PUSH1 0x7 SWAP1 " + "POP POP " + ); +} + +BOOST_AUTO_TEST_CASE(function_call) +{ + string in = R"({ + let b := f(1, 2) + function f(a, r) -> t { } + b := f(3, 4) + })"; + BOOST_CHECK_EQUAL(assemble(in), + "PUSH1 0x9 PUSH1 0x2 PUSH1 0x1 PUSH1 0xD JUMP " + "JUMPDEST PUSH1 0x15 JUMP " // jump over f + "JUMPDEST PUSH1 0x0 SWAP3 SWAP2 POP POP JUMP " // f + "JUMPDEST PUSH1 0x1F PUSH1 0x4 PUSH1 0x3 PUSH1 0xD JUMP " + "JUMPDEST SWAP1 POP POP " + ); +} + + +BOOST_AUTO_TEST_CASE(functions_multi_return) +{ + string in = R"({ + function f(a, b) -> t { } + function g() -> r, s { } + let x := f(1, 2) + x := f(3, 4) + let y, z := g() + y, z := g() + let unused := 7 + })"; + BOOST_CHECK_EQUAL(assemble(in), + "PUSH1 0xB JUMP " + "JUMPDEST PUSH1 0x0 SWAP3 SWAP2 POP POP JUMP " // f + "JUMPDEST PUSH1 0x17 JUMP " + "JUMPDEST PUSH1 0x0 PUSH1 0x0 SWAP1 SWAP2 JUMP " // g + "JUMPDEST PUSH1 0x21 PUSH1 0x2 PUSH1 0x1 PUSH1 0x3 JUMP " // f(1, 2) + "JUMPDEST PUSH1 0x2B PUSH1 0x4 PUSH1 0x3 PUSH1 0x3 JUMP " // f(3, 4) + "JUMPDEST SWAP1 POP " // assignment to x + "POP " // remove x + "PUSH1 0x34 PUSH1 0xF JUMP " // g() + "JUMPDEST PUSH1 0x3A PUSH1 0xF JUMP " // g() + "JUMPDEST SWAP2 POP SWAP2 POP " // assignments + "POP POP " // removal of y and z + "PUSH1 0x7 POP " + ); +} + +BOOST_AUTO_TEST_CASE(reuse_slots_function) +{ + string in = R"({ + function f() -> x, y, z, t {} + let a, b, c, d := f() let x1 := 2 let y1 := 3 mstore(x1, a) mstore(y1, c) + })"; + BOOST_CHECK_EQUAL(assemble(in), + "PUSH1 0x11 JUMP " + "JUMPDEST PUSH1 0x0 PUSH1 0x0 PUSH1 0x0 PUSH1 0x0 SWAP1 SWAP2 SWAP3 SWAP4 JUMP " + "JUMPDEST PUSH1 0x17 PUSH1 0x3 JUMP " + // Stack: a b c d + "JUMPDEST POP " // d is unused + // Stack: a b c + "PUSH1 0x2 SWAP2 POP " // x1 reuses b's slot + "PUSH1 0x3 " + // Stack: a x1 c y1 + "DUP4 DUP4 MSTORE " + "DUP2 DUP2 MSTORE " + "POP POP POP POP " + ); +} + +BOOST_AUTO_TEST_CASE(reuse_slots_function_with_gaps) +{ + string in = R"({ + // Only x3 is actually used, the slots of + // x1 and x2 will be reused right away. + let x1 := 5 let x2 := 6 let x3 := 7 + mstore(x1, x2) + function f() -> x, y, z, t {} + let a, b, c, d := f() mstore(x3, a) mstore(c, d) + })"; + BOOST_CHECK_EQUAL(assemble(in), + "PUSH1 0x5 PUSH1 0x6 PUSH1 0x7 " + "DUP2 DUP4 MSTORE " + "PUSH1 0x1A JUMP " // jump across function + "JUMPDEST PUSH1 0x0 PUSH1 0x0 PUSH1 0x0 PUSH1 0x0 SWAP1 SWAP2 SWAP3 SWAP4 JUMP " + "JUMPDEST PUSH1 0x20 PUSH1 0xC JUMP " + // stack: x1 x2 x3 a b c d + "JUMPDEST SWAP6 POP " // move d into x1 + // stack: d x2 x3 a b c + "SWAP4 POP " + // stack: d c x3 a b + "POP " + // stack: d c x3 a + "DUP1 DUP3 MSTORE " + "POP POP " + // stack: d c + "DUP2 DUP2 MSTORE " + "POP POP " + ); +} + + +BOOST_AUTO_TEST_SUITE_END() + +} +} +} diff --git a/test/libyul/YulOptimizerTest.cpp b/test/libyul/YulOptimizerTest.cpp index ba7eced3..68226e33 100644 --- a/test/libyul/YulOptimizerTest.cpp +++ b/test/libyul/YulOptimizerTest.cpp @@ -41,6 +41,7 @@ #include <libyul/optimiser/RedundantAssignEliminator.h> #include <libyul/optimiser/StructuralSimplifier.h> #include <libyul/optimiser/Suite.h> +#include <libyul/backends/evm/EVMDialect.h> #include <libyul/AsmPrinter.h> #include <libyul/AsmParser.h> #include <libyul/AsmAnalysis.h> @@ -262,7 +263,7 @@ void YulOptimizerTest::printIndented(ostream& _stream, string const& _output, st bool YulOptimizerTest::parse(ostream& _stream, string const& _linePrefix, bool const _formatted) { - yul::Dialect dialect = m_yul ? yul::Dialect::yul() : yul::Dialect::strictAssemblyForEVM(); + shared_ptr<yul::Dialect> dialect = m_yul ? yul::Dialect::yul() : yul::EVMDialect::strictAssemblyForEVM(); ErrorList errors; ErrorReporter errorReporter(errors); shared_ptr<Scanner> scanner = make_shared<Scanner>(CharStream(m_source, "")); diff --git a/test/libyul/objectCompiler/datacopy.yul b/test/libyul/objectCompiler/datacopy.yul new file mode 100644 index 00000000..2259e5dc --- /dev/null +++ b/test/libyul/objectCompiler/datacopy.yul @@ -0,0 +1,48 @@ +object "a" { + code { + datacopy(0, dataoffset("sub"), datasize("sub")) + return(0, datasize("sub")) + } + object "sub" { + code { + sstore(0, dataoffset("sub")) + mstore(0, datasize("data1")) + } + data "data1" "Hello, World!" + } +} +// ---- +// Assembly: +// /* "source":26:73 */ +// dataSize(sub_0) +// dataOffset(sub_0) +// /* "source":35:36 */ +// 0x00 +// /* "source":26:73 */ +// codecopy +// /* "source":78:104 */ +// dataSize(sub_0) +// /* "source":85:86 */ +// 0x00 +// /* "source":78:104 */ +// return +// stop +// +// sub_0: assembly { +// /* "source":143:171 */ +// 0x00 +// /* "source":150:151 */ +// 0x00 +// /* "source":143:171 */ +// sstore +// /* "source":178:206 */ +// 0x0d +// /* "source":185:186 */ +// 0x00 +// /* "source":178:206 */ +// mstore +// stop +// data_acaf3289d7b601cbd114fb36c4d29c85bbfd5e133f14cb355c3fd8d99367964f 48656c6c6f2c20576f726c6421 +// } +// Bytecode: 600b600d600039600b6000f3fe6000600055600d600052fe +// Opcodes: PUSH1 0xB PUSH1 0xD PUSH1 0x0 CODECOPY PUSH1 0xB PUSH1 0x0 RETURN INVALID PUSH1 0x0 PUSH1 0x0 SSTORE PUSH1 0xD PUSH1 0x0 MSTORE INVALID diff --git a/test/libyul/objectCompiler/dataoffset_code.yul b/test/libyul/objectCompiler/dataoffset_code.yul new file mode 100644 index 00000000..725267f2 --- /dev/null +++ b/test/libyul/objectCompiler/dataoffset_code.yul @@ -0,0 +1,29 @@ +object "a" { + code { sstore(0, dataoffset("sub")) } + object "sub" { + code { sstore(0, 8) } + data "data1" "Hello, World!" + } +} +// ---- +// Assembly: +// /* "source":22:50 */ +// dataOffset(sub_0) +// /* "source":29:30 */ +// 0x00 +// /* "source":22:50 */ +// sstore +// stop +// +// sub_0: assembly { +// /* "source":91:92 */ +// 0x08 +// /* "source":88:89 */ +// 0x00 +// /* "source":81:93 */ +// sstore +// stop +// data_acaf3289d7b601cbd114fb36c4d29c85bbfd5e133f14cb355c3fd8d99367964f 48656c6c6f2c20576f726c6421 +// } +// Bytecode: 6006600055fe6008600055fe +// Opcodes: PUSH1 0x6 PUSH1 0x0 SSTORE INVALID PUSH1 0x8 PUSH1 0x0 SSTORE INVALID diff --git a/test/libyul/objectCompiler/dataoffset_data.yul b/test/libyul/objectCompiler/dataoffset_data.yul new file mode 100644 index 00000000..9a0a461d --- /dev/null +++ b/test/libyul/objectCompiler/dataoffset_data.yul @@ -0,0 +1,16 @@ +object "a" { + code { sstore(0, dataoffset("data1")) } + data "data1" "Hello, World!" +} +// ---- +// Assembly: +// /* "source":22:52 */ +// data_acaf3289d7b601cbd114fb36c4d29c85bbfd5e133f14cb355c3fd8d99367964f +// /* "source":29:30 */ +// 0x00 +// /* "source":22:52 */ +// sstore +// stop +// data_acaf3289d7b601cbd114fb36c4d29c85bbfd5e133f14cb355c3fd8d99367964f 48656c6c6f2c20576f726c6421 +// Bytecode: 6006600055fe48656c6c6f2c20576f726c6421 +// Opcodes: PUSH1 0x6 PUSH1 0x0 SSTORE INVALID 0x48 PUSH6 0x6C6C6F2C2057 PUSH16 0x726C6421000000000000000000000000 diff --git a/test/libyul/objectCompiler/dataoffset_self.yul b/test/libyul/objectCompiler/dataoffset_self.yul new file mode 100644 index 00000000..b7740735 --- /dev/null +++ b/test/libyul/objectCompiler/dataoffset_self.yul @@ -0,0 +1,16 @@ +object "a" { + code { sstore(0, dataoffset("a")) } + data "data1" "Hello, World!" +} +// ---- +// Assembly: +// /* "source":22:48 */ +// 0x00 +// /* "source":29:30 */ +// 0x00 +// /* "source":22:48 */ +// sstore +// stop +// data_acaf3289d7b601cbd114fb36c4d29c85bbfd5e133f14cb355c3fd8d99367964f 48656c6c6f2c20576f726c6421 +// Bytecode: 6000600055fe +// Opcodes: PUSH1 0x0 PUSH1 0x0 SSTORE INVALID diff --git a/test/libyul/objectCompiler/datasize_code.yul b/test/libyul/objectCompiler/datasize_code.yul new file mode 100644 index 00000000..cff68515 --- /dev/null +++ b/test/libyul/objectCompiler/datasize_code.yul @@ -0,0 +1,29 @@ +object "a" { + code { sstore(0, datasize("sub")) } + object "sub" { + code { sstore(0, 8) } + data "data1" "Hello, World!" + } +} +// ---- +// Assembly: +// /* "source":22:48 */ +// dataSize(sub_0) +// /* "source":29:30 */ +// 0x00 +// /* "source":22:48 */ +// sstore +// stop +// +// sub_0: assembly { +// /* "source":89:90 */ +// 0x08 +// /* "source":86:87 */ +// 0x00 +// /* "source":79:91 */ +// sstore +// stop +// data_acaf3289d7b601cbd114fb36c4d29c85bbfd5e133f14cb355c3fd8d99367964f 48656c6c6f2c20576f726c6421 +// } +// Bytecode: 6006600055fe +// Opcodes: PUSH1 0x6 PUSH1 0x0 SSTORE INVALID diff --git a/test/libyul/objectCompiler/datasize_data.yul b/test/libyul/objectCompiler/datasize_data.yul new file mode 100644 index 00000000..f8341469 --- /dev/null +++ b/test/libyul/objectCompiler/datasize_data.yul @@ -0,0 +1,16 @@ +object "a" { + code { sstore(0, datasize("data1")) } + data "data1" "Hello, World!" +} +// ---- +// Assembly: +// /* "source":22:50 */ +// 0x0d +// /* "source":29:30 */ +// 0x00 +// /* "source":22:50 */ +// sstore +// stop +// data_acaf3289d7b601cbd114fb36c4d29c85bbfd5e133f14cb355c3fd8d99367964f 48656c6c6f2c20576f726c6421 +// Bytecode: 600d600055fe +// Opcodes: PUSH1 0xD PUSH1 0x0 SSTORE INVALID diff --git a/test/libyul/objectCompiler/datasize_self.yul b/test/libyul/objectCompiler/datasize_self.yul new file mode 100644 index 00000000..4579fe67 --- /dev/null +++ b/test/libyul/objectCompiler/datasize_self.yul @@ -0,0 +1,16 @@ +object "a" { + code { sstore(0, datasize("a")) } + data "data1" "Hello, World!" +} +// ---- +// Assembly: +// /* "source":22:46 */ +// bytecodeSize +// /* "source":29:30 */ +// 0x00 +// /* "source":22:46 */ +// sstore +// stop +// data_acaf3289d7b601cbd114fb36c4d29c85bbfd5e133f14cb355c3fd8d99367964f 48656c6c6f2c20576f726c6421 +// Bytecode: 6006600055fe +// Opcodes: PUSH1 0x6 PUSH1 0x0 SSTORE INVALID diff --git a/test/tools/isoltest.cpp b/test/tools/isoltest.cpp index 13585887..e5578045 100644 --- a/test/tools/isoltest.cpp +++ b/test/tools/isoltest.cpp @@ -19,11 +19,7 @@ #include <test/Common.h> #include <test/libsolidity/AnalysisFramework.h> -#include <test/libsolidity/SyntaxTest.h> -#include <test/libsolidity/ASTJSONTest.h> -#include <test/libsolidity/SMTCheckerJSONTest.h> -#include <test/libyul/YulOptimizerTest.h> -#include <test/libyul/ObjectCompilerTest.h> +#include <test/InteractiveTests.h> #include <boost/algorithm/string.hpp> #include <boost/algorithm/string/replace.hpp> @@ -380,59 +376,13 @@ Allowed options)", TestStats global_stats{0, 0}; // Actually run the tests. - // If you add new tests here, you also have to add them in boostTest.cpp - if (auto stats = runTestSuite("Syntax", testPath / "libsolidity", "syntaxTests", SyntaxTest::create, formatted)) - global_stats += *stats; - else - return 1; - - if (auto stats = runTestSuite("JSON AST", testPath / "libsolidity", "ASTJSON", ASTJSONTest::create, formatted)) - global_stats += *stats; - else - return 1; - - if (auto stats = runTestSuite( - "Yul Optimizer", - testPath / "libyul", - "yulOptimizerTests", - yul::test::YulOptimizerTest::create, - formatted - )) - global_stats += *stats; - else - return 1; - - if (auto stats = runTestSuite( - "Yul Object Compiler", - testPath / "libyul", - "objectCompiler", - yul::test::ObjectCompilerTest::create, - formatted - )) - global_stats += *stats; - else - return 1; - - if (!disableSMT) + // Interactive tests are added in InteractiveTests.h + for (auto const& ts: g_interactiveTestsuites) { - if (auto stats = runTestSuite( - "SMT Checker", - testPath / "libsolidity", - "smtCheckerTests", - SyntaxTest::create, - formatted - )) - global_stats += *stats; - else - return 1; + if (ts.smt && disableSMT) + continue; - if (auto stats = runTestSuite( - "SMT Checker JSON", - testPath / "libsolidity", - "smtCheckerTestsJSON", - SMTCheckerTest::create, - formatted - )) + if (auto stats = runTestSuite(ts.title, testPath / ts.path, ts.subpath, ts.testCaseCreator, formatted)) global_stats += *stats; else return 1; diff --git a/test/tools/yulopti.cpp b/test/tools/yulopti.cpp index 477de42f..3dc35f73 100644 --- a/test/tools/yulopti.cpp +++ b/test/tools/yulopti.cpp @@ -49,6 +49,8 @@ #include <libyul/optimiser/StructuralSimplifier.h> #include <libyul/optimiser/VarDeclPropagator.h> +#include <libyul/backends/evm/EVMDialect.h> + #include <libdevcore/JSON.h> #include <boost/program_options.hpp> @@ -83,7 +85,7 @@ public: { ErrorReporter errorReporter(m_errors); shared_ptr<Scanner> scanner = make_shared<Scanner>(CharStream(_input, "")); - m_ast = yul::Parser(errorReporter, yul::Dialect::strictAssemblyForEVM()).parse(scanner, false); + m_ast = yul::Parser(errorReporter, yul::EVMDialect::strictAssemblyForEVM()).parse(scanner, false); if (!m_ast || !errorReporter.errors().empty()) { cout << "Error parsing source." << endl; @@ -96,7 +98,7 @@ public: errorReporter, EVMVersion::byzantium(), langutil::Error::Type::SyntaxError, - Dialect::strictAssemblyForEVM() + EVMDialect::strictAssemblyForEVM() ); if (!analyzer.analyze(*m_ast) || !errorReporter.errors().empty()) { |