diff --git a/libsolidity/analysis/ReferencesResolver.cpp b/libsolidity/analysis/ReferencesResolver.cpp index b73cb9114..cfb89f0be 100644 --- a/libsolidity/analysis/ReferencesResolver.cpp +++ b/libsolidity/analysis/ReferencesResolver.cpp @@ -324,9 +324,8 @@ bool ReferencesResolver::visit(InlineAssembly const& _inlineAssembly) yul::AsmAnalyzer( analysisInfo, errorsIgnored, - EVMVersion(), errorTypeForLoose, - yul::EVMDialect::looseAssemblyForEVM(), + yul::EVMDialect::looseAssemblyForEVM(EVMVersion::constantinople()), resolver ).analyze(_inlineAssembly.operations()); return false; diff --git a/libsolidity/analysis/TypeChecker.cpp b/libsolidity/analysis/TypeChecker.cpp index 9fb3392b1..0208fc7ac 100644 --- a/libsolidity/analysis/TypeChecker.cpp +++ b/libsolidity/analysis/TypeChecker.cpp @@ -713,9 +713,8 @@ bool TypeChecker::visit(InlineAssembly const& _inlineAssembly) yul::AsmAnalyzer analyzer( *_inlineAssembly.annotation().analysisInfo, m_errorReporter, - m_evmVersion, Error::Type::SyntaxError, - yul::EVMDialect::looseAssemblyForEVM(), + yul::EVMDialect::looseAssemblyForEVM(m_evmVersion), identifierAccess ); if (!analyzer.analyze(_inlineAssembly.operations())) diff --git a/libsolidity/codegen/CompilerContext.cpp b/libsolidity/codegen/CompilerContext.cpp index a9d06f943..8085751bc 100644 --- a/libsolidity/codegen/CompilerContext.cpp +++ b/libsolidity/codegen/CompilerContext.cpp @@ -376,7 +376,7 @@ void CompilerContext::appendInlineAssembly( ErrorList errors; ErrorReporter errorReporter(errors); auto scanner = make_shared(langutil::CharStream(_assembly, "--CODEGEN--")); - auto parserResult = yul::Parser(errorReporter, yul::EVMDialect::strictAssemblyForEVM()).parse(scanner, false); + auto parserResult = yul::Parser(errorReporter, yul::EVMDialect::strictAssemblyForEVM(m_evmVersion)).parse(scanner, false); #ifdef SOL_OUTPUT_ASM cout << yul::AsmPrinter()(*parserResult) << endl; #endif @@ -386,9 +386,8 @@ void CompilerContext::appendInlineAssembly( analyzerResult = yul::AsmAnalyzer( analysisInfo, errorReporter, - m_evmVersion, boost::none, - yul::EVMDialect::strictAssemblyForEVM(), + yul::EVMDialect::strictAssemblyForEVM(m_evmVersion), identifierAccess.resolve ).analyze(*parserResult); if (!parserResult || !errorReporter.errors().empty() || !analyzerResult) @@ -409,7 +408,7 @@ void CompilerContext::appendInlineAssembly( } solAssert(errorReporter.errors().empty(), "Failed to analyze inline assembly block."); - yul::CodeGenerator::assemble(*parserResult, analysisInfo, *m_asm, identifierAccess, _system); + yul::CodeGenerator::assemble(*parserResult, analysisInfo, *m_asm, m_evmVersion, identifierAccess, _system); // Reset the source location to the one of the node (instead of the CODEGEN source location) updateSourceLocation(); diff --git a/libsolidity/codegen/ContractCompiler.cpp b/libsolidity/codegen/ContractCompiler.cpp index 31342816c..beaa95ae0 100644 --- a/libsolidity/codegen/ContractCompiler.cpp +++ b/libsolidity/codegen/ContractCompiler.cpp @@ -719,6 +719,7 @@ bool ContractCompiler::visit(InlineAssembly const& _inlineAssembly) _inlineAssembly.operations(), *_inlineAssembly.annotation().analysisInfo, *m_context.assemblyPtr(), + m_context.evmVersion(), identifierAccess ); m_context.setStackOffset(startStackHeight); diff --git a/libsolidity/parsing/Parser.cpp b/libsolidity/parsing/Parser.cpp index c6bfadadd..d04e4e759 100644 --- a/libsolidity/parsing/Parser.cpp +++ b/libsolidity/parsing/Parser.cpp @@ -1041,7 +1041,8 @@ ASTPointer Parser::parseInlineAssembly(ASTPointer con m_scanner->next(); } - yul::Parser asmParser(m_errorReporter, yul::EVMDialect::looseAssemblyForEVM()); + // Using latest EVM Version for now, it will be run again later. + yul::Parser asmParser(m_errorReporter, yul::EVMDialect::looseAssemblyForEVM(EVMVersion::constantinople())); shared_ptr block = asmParser.parse(m_scanner, true); if (block == nullptr) BOOST_THROW_EXCEPTION(FatalError()); diff --git a/libyul/AsmAnalysis.cpp b/libyul/AsmAnalysis.cpp index f898f70c0..a12927a31 100644 --- a/libyul/AsmAnalysis.cpp +++ b/libyul/AsmAnalysis.cpp @@ -60,7 +60,6 @@ bool AsmAnalyzer::analyze(Block const& _block) AsmAnalysisInfo AsmAnalyzer::analyzeStrictAssertCorrect( shared_ptr _dialect, - EVMVersion _evmVersion, Block const& _ast ) { @@ -70,7 +69,6 @@ AsmAnalysisInfo AsmAnalyzer::analyzeStrictAssertCorrect( bool success = yul::AsmAnalyzer( analysisInfo, errors, - _evmVersion, Error::Type::SyntaxError, _dialect ).analyze(_ast); diff --git a/libyul/AsmAnalysis.h b/libyul/AsmAnalysis.h index 19b0558cc..463c34c59 100644 --- a/libyul/AsmAnalysis.h +++ b/libyul/AsmAnalysis.h @@ -28,6 +28,7 @@ #include #include +#include #include #include @@ -57,7 +58,6 @@ public: explicit AsmAnalyzer( AsmAnalysisInfo& _analysisInfo, langutil::ErrorReporter& _errorReporter, - dev::solidity::EVMVersion _evmVersion, boost::optional _errorTypeForLoose, std::shared_ptr _dialect, ExternalIdentifierAccess::Resolver const& _resolver = ExternalIdentifierAccess::Resolver() @@ -65,16 +65,17 @@ public: m_resolver(_resolver), m_info(_analysisInfo), m_errorReporter(_errorReporter), - m_evmVersion(_evmVersion), m_dialect(std::move(_dialect)), m_errorTypeForLoose(_errorTypeForLoose) - {} + { + if (EVMDialect const* evmDialect = dynamic_cast(m_dialect.get())) + m_evmVersion = evmDialect->evmVersion(); + } bool analyze(Block const& _block); static AsmAnalysisInfo analyzeStrictAssertCorrect( std::shared_ptr _dialect, - dev::solidity::EVMVersion _evmVersion, Block const& _ast ); diff --git a/libyul/AssemblyStack.cpp b/libyul/AssemblyStack.cpp index 1e0bdbbbf..ef2307ec4 100644 --- a/libyul/AssemblyStack.cpp +++ b/libyul/AssemblyStack.cpp @@ -43,14 +43,14 @@ using namespace yul; namespace { -shared_ptr languageToDialect(AssemblyStack::Language _language) +shared_ptr languageToDialect(AssemblyStack::Language _language, EVMVersion _version) { switch (_language) { case AssemblyStack::Language::Assembly: - return EVMDialect::looseAssemblyForEVM(); + return EVMDialect::looseAssemblyForEVM(_version); case AssemblyStack::Language::StrictAssembly: - return EVMDialect::strictAssemblyForEVMObjects(); + return EVMDialect::strictAssemblyForEVMObjects(_version); case AssemblyStack::Language::Yul: return Dialect::yul(); } @@ -72,7 +72,7 @@ bool AssemblyStack::parseAndAnalyze(std::string const& _sourceName, std::string m_errors.clear(); m_analysisSuccessful = false; m_scanner = make_shared(CharStream(_source, _sourceName)); - m_parserResult = ObjectParser(m_errorReporter, languageToDialect(m_language)).parse(m_scanner, false); + m_parserResult = ObjectParser(m_errorReporter, languageToDialect(m_language, m_evmVersion)).parse(m_scanner, false); if (!m_errorReporter.errors().empty()) return false; solAssert(m_parserResult, ""); @@ -103,7 +103,7 @@ bool AssemblyStack::analyzeParsed(Object& _object) { solAssert(_object.code, ""); _object.analysisInfo = make_shared(); - AsmAnalyzer analyzer(*_object.analysisInfo, m_errorReporter, m_evmVersion, boost::none, languageToDialect(m_language)); + AsmAnalyzer analyzer(*_object.analysisInfo, m_errorReporter, boost::none, languageToDialect(m_language, m_evmVersion)); bool success = analyzer.analyze(*_object.code); for (auto& subNode: _object.subObjects) if (auto subObject = dynamic_cast(subNode.get())) @@ -117,11 +117,11 @@ void AssemblyStack::compileEVM(AbstractAssembly& _assembly, bool _evm15, bool _o shared_ptr dialect; if (m_language == Language::Assembly) - dialect = EVMDialect::looseAssemblyForEVM(); + dialect = EVMDialect::looseAssemblyForEVM(m_evmVersion); else if (m_language == AssemblyStack::Language::StrictAssembly) - dialect = EVMDialect::strictAssemblyForEVMObjects(); + dialect = EVMDialect::strictAssemblyForEVMObjects(m_evmVersion); else if (m_language == AssemblyStack::Language::Yul) - dialect = EVMDialect::yulForEVM(); + dialect = EVMDialect::yulForEVM(m_evmVersion); else solAssert(false, "Invalid language."); @@ -135,7 +135,7 @@ void AssemblyStack::optimize(Object& _object) for (auto& subNode: _object.subObjects) if (auto subObject = dynamic_cast(subNode.get())) optimize(*subObject); - OptimiserSuite::run(languageToDialect(m_language), *_object.code, *_object.analysisInfo); + OptimiserSuite::run(languageToDialect(m_language, m_evmVersion), *_object.code, *_object.analysisInfo); } MachineAssemblyObject AssemblyStack::assemble(Machine _machine, bool _optimize) const diff --git a/libyul/CompilabilityChecker.cpp b/libyul/CompilabilityChecker.cpp index 67b2dfdfb..e20140e27 100644 --- a/libyul/CompilabilityChecker.cpp +++ b/libyul/CompilabilityChecker.cpp @@ -45,7 +45,7 @@ std::map CompilabilityChecker::run(std::shared_ptr _dia bool optimize = true; yul::AsmAnalysisInfo analysisInfo = - yul::AsmAnalyzer::analyzeStrictAssertCorrect(noOutputDialect, EVMVersion(), _ast); + yul::AsmAnalyzer::analyzeStrictAssertCorrect(noOutputDialect, _ast); NoOutputAssembly assembly; CodeTransform transform(assembly, analysisInfo, _ast, *noOutputDialect, optimize); diff --git a/libyul/backends/evm/AsmCodeGen.cpp b/libyul/backends/evm/AsmCodeGen.cpp index eb973329c..905f09752 100644 --- a/libyul/backends/evm/AsmCodeGen.cpp +++ b/libyul/backends/evm/AsmCodeGen.cpp @@ -177,13 +177,14 @@ void CodeGenerator::assemble( Block const& _parsedData, AsmAnalysisInfo& _analysisInfo, eth::Assembly& _assembly, + dev::solidity::EVMVersion _evmVersion, ExternalIdentifierAccess const& _identifierAccess, bool _useNamedLabelsForFunctions, bool _optimize ) { EthAssemblyAdapter assemblyAdapter(_assembly); - shared_ptr dialect = EVMDialect::strictAssemblyForEVM(); + shared_ptr dialect = EVMDialect::strictAssemblyForEVM(_evmVersion); CodeTransform transform( assemblyAdapter, _analysisInfo, diff --git a/libyul/backends/evm/AsmCodeGen.h b/libyul/backends/evm/AsmCodeGen.h index 99c7ff15d..0b86e6e9d 100644 --- a/libyul/backends/evm/AsmCodeGen.h +++ b/libyul/backends/evm/AsmCodeGen.h @@ -79,6 +79,7 @@ public: Block const& _parsedData, AsmAnalysisInfo& _analysisInfo, dev::eth::Assembly& _assembly, + dev::solidity::EVMVersion _evmVersion, ExternalIdentifierAccess const& _identifierAccess = ExternalIdentifierAccess(), bool _useNamedLabelsForFunctions = false, bool _optimize = false diff --git a/libyul/backends/evm/EVMDialect.cpp b/libyul/backends/evm/EVMDialect.cpp index 185021174..9aec768a6 100644 --- a/libyul/backends/evm/EVMDialect.cpp +++ b/libyul/backends/evm/EVMDialect.cpp @@ -37,8 +37,8 @@ using namespace yul; using namespace dev::solidity; -EVMDialect::EVMDialect(AsmFlavour _flavour, bool _objectAccess): - Dialect{_flavour}, m_objectAccess(_objectAccess) +EVMDialect::EVMDialect(AsmFlavour _flavour, bool _objectAccess, EVMVersion _evmVersion): + Dialect{_flavour}, m_objectAccess(_objectAccess), m_evmVersion(_evmVersion) { // The EVM instructions will be moved to builtins at some point. if (!m_objectAccess) @@ -91,24 +91,24 @@ BuiltinFunctionForEVM const* EVMDialect::builtin(YulString _name) const return nullptr; } -shared_ptr EVMDialect::looseAssemblyForEVM() +shared_ptr EVMDialect::looseAssemblyForEVM(EVMVersion _version) { - return make_shared(AsmFlavour::Loose, false); + return make_shared(AsmFlavour::Loose, false, _version); } -shared_ptr EVMDialect::strictAssemblyForEVM() +shared_ptr EVMDialect::strictAssemblyForEVM(EVMVersion _version) { - return make_shared(AsmFlavour::Strict, false); + return make_shared(AsmFlavour::Strict, false, _version); } -shared_ptr EVMDialect::strictAssemblyForEVMObjects() +shared_ptr EVMDialect::strictAssemblyForEVMObjects(EVMVersion _version) { - return make_shared(AsmFlavour::Strict, true); + return make_shared(AsmFlavour::Strict, true, _version); } -shared_ptr EVMDialect::yulForEVM() +shared_ptr EVMDialect::yulForEVM(EVMVersion _version) { - return make_shared(AsmFlavour::Yul, false); + return make_shared(AsmFlavour::Yul, false, _version); } void EVMDialect::setSubIDs(map _subIDs) diff --git a/libyul/backends/evm/EVMDialect.h b/libyul/backends/evm/EVMDialect.h index 7a2b95f7a..61b0a0ae9 100644 --- a/libyul/backends/evm/EVMDialect.h +++ b/libyul/backends/evm/EVMDialect.h @@ -23,6 +23,7 @@ #include #include +#include #include @@ -49,15 +50,17 @@ struct BuiltinFunctionForEVM: BuiltinFunction */ struct EVMDialect: public Dialect { - EVMDialect(AsmFlavour _flavour, bool _objectAccess); + EVMDialect(AsmFlavour _flavour, bool _objectAccess, dev::solidity::EVMVersion _evmVersion); /// @returns the builtin function of the given name or a nullptr if it is not a builtin function. BuiltinFunctionForEVM const* builtin(YulString _name) const override; - static std::shared_ptr looseAssemblyForEVM(); - static std::shared_ptr strictAssemblyForEVM(); - static std::shared_ptr strictAssemblyForEVMObjects(); - static std::shared_ptr yulForEVM(); + static std::shared_ptr looseAssemblyForEVM(dev::solidity::EVMVersion _version); + static std::shared_ptr strictAssemblyForEVM(dev::solidity::EVMVersion _version); + static std::shared_ptr strictAssemblyForEVMObjects(dev::solidity::EVMVersion _version); + static std::shared_ptr yulForEVM(dev::solidity::EVMVersion _version); + + dev::solidity::EVMVersion evmVersion() const { return m_evmVersion; } bool providesObjectAccess() const { return m_objectAccess; } @@ -77,6 +80,7 @@ protected: ); bool m_objectAccess; + dev::solidity::EVMVersion m_evmVersion; Object const* m_currentObject = nullptr; /// Mapping from named objects to abstract assembly sub IDs. std::map m_subIDs; diff --git a/libyul/backends/evm/NoOutputAssembly.cpp b/libyul/backends/evm/NoOutputAssembly.cpp index 4bf585736..517a3fa1c 100644 --- a/libyul/backends/evm/NoOutputAssembly.cpp +++ b/libyul/backends/evm/NoOutputAssembly.cpp @@ -143,7 +143,7 @@ AbstractAssembly::SubID NoOutputAssembly::appendData(bytes const&) } NoOutputEVMDialect::NoOutputEVMDialect(shared_ptr const& _copyFrom): - EVMDialect(_copyFrom->flavour, _copyFrom->providesObjectAccess()) + EVMDialect(_copyFrom->flavour, _copyFrom->providesObjectAccess(), _copyFrom->evmVersion()) { for (auto& fun: m_functions) { diff --git a/libyul/optimiser/Suite.h b/libyul/optimiser/Suite.h index 8aeef7608..aed26b714 100644 --- a/libyul/optimiser/Suite.h +++ b/libyul/optimiser/Suite.h @@ -22,6 +22,7 @@ #include #include +#include #include diff --git a/test/libyul/Common.cpp b/test/libyul/Common.cpp index f9cd6420c..21e3e591f 100644 --- a/test/libyul/Common.cpp +++ b/test/libyul/Common.cpp @@ -46,7 +46,7 @@ namespace { shared_ptr defaultDialect(bool _yul) { - return _yul ? yul::Dialect::yul() : yul::EVMDialect::strictAssemblyForEVM(); + return _yul ? yul::Dialect::yul() : yul::EVMDialect::strictAssemblyForEVM(dev::test::Options::get().evmVersion()); } } diff --git a/test/libyul/CompilabilityChecker.cpp b/test/libyul/CompilabilityChecker.cpp index 9bb31997e..ffd3e1816 100644 --- a/test/libyul/CompilabilityChecker.cpp +++ b/test/libyul/CompilabilityChecker.cpp @@ -39,7 +39,7 @@ string check(string const& _input) { shared_ptr ast = yul::test::parse(_input, false).first; BOOST_REQUIRE(ast); - map functions = CompilabilityChecker::run(EVMDialect::strictAssemblyForEVM(), *ast); + map functions = CompilabilityChecker::run(EVMDialect::strictAssemblyForEVM(dev::test::Options::get().evmVersion()), *ast); string out; for (auto const& function: functions) out += function.first.str() + ": " + to_string(function.second) + " "; diff --git a/test/libyul/Parser.cpp b/test/libyul/Parser.cpp index 41e0b0135..fa8e593d5 100644 --- a/test/libyul/Parser.cpp +++ b/test/libyul/Parser.cpp @@ -61,7 +61,6 @@ bool parse(string const& _source, std::shared_ptr _dialect, ErrorReport return (yul::AsmAnalyzer( analysisInfo, errorReporter, - dev::test::Options::get().evmVersion(), boost::none, _dialect )).analyze(*parserResult); diff --git a/test/libyul/YulOptimizerTest.cpp b/test/libyul/YulOptimizerTest.cpp index c12121369..26eb1a644 100644 --- a/test/libyul/YulOptimizerTest.cpp +++ b/test/libyul/YulOptimizerTest.cpp @@ -300,7 +300,7 @@ bool YulOptimizerTest::parse(ostream& _stream, string const& _linePrefix, bool c printErrors(_stream, stack.errors()); return false; } - m_dialect = m_yul ? Dialect::yul() : EVMDialect::strictAssemblyForEVMObjects(); + m_dialect = m_yul ? Dialect::yul() : EVMDialect::strictAssemblyForEVMObjects(dev::test::Options::get().evmVersion()); m_ast = stack.parserResult()->code; m_analysisInfo = stack.parserResult()->analysisInfo; return true; diff --git a/test/tools/yulopti.cpp b/test/tools/yulopti.cpp index f77c630ff..01520a17e 100644 --- a/test/tools/yulopti.cpp +++ b/test/tools/yulopti.cpp @@ -99,7 +99,6 @@ public: AsmAnalyzer analyzer( *m_analysisInfo, errorReporter, - EVMVersion::byzantium(), langutil::Error::Type::SyntaxError, m_dialect ); @@ -207,7 +206,7 @@ public: private: ErrorList m_errors; shared_ptr m_ast; - shared_ptr m_dialect{EVMDialect::strictAssemblyForEVMObjects()}; + shared_ptr m_dialect{EVMDialect::strictAssemblyForEVMObjects(EVMVersion::constantinople())}; shared_ptr m_analysisInfo; shared_ptr m_nameDispenser; };