From 8d49e539951791a25a63f470e8a9935679c7404f Mon Sep 17 00:00:00 2001 From: chriseth Date: Thu, 6 Dec 2018 18:07:08 +0100 Subject: Provide Dialect to EVMCodeTransform. --- libsolidity/codegen/AsmCodeGen.cpp | 2 +- libsolidity/interface/AssemblyStack.cpp | 4 ++-- libyul/backends/evm/EVMCodeTransform.cpp | 2 +- libyul/backends/evm/EVMCodeTransform.h | 10 +++++----- libyul/backends/evm/EVMObjectCompiler.cpp | 8 ++++---- libyul/backends/evm/EVMObjectCompiler.h | 9 +++++---- 6 files changed, 18 insertions(+), 17 deletions(-) diff --git a/libsolidity/codegen/AsmCodeGen.cpp b/libsolidity/codegen/AsmCodeGen.cpp index 3f770f62..45efe55b 100644 --- a/libsolidity/codegen/AsmCodeGen.cpp +++ b/libsolidity/codegen/AsmCodeGen.cpp @@ -189,7 +189,7 @@ void CodeGenerator::assemble( _analysisInfo, _parsedData, _optimize, - false, + Dialect::strictAssemblyForEVM(), false, _identifierAccess, _useNamedLabelsForFunctions diff --git a/libsolidity/interface/AssemblyStack.cpp b/libsolidity/interface/AssemblyStack.cpp index 5952d914..4af1e23d 100644 --- a/libsolidity/interface/AssemblyStack.cpp +++ b/libsolidity/interface/AssemblyStack.cpp @@ -136,7 +136,7 @@ MachineAssemblyObject AssemblyStack::assemble(Machine _machine, bool _optimize) MachineAssemblyObject object; eth::Assembly assembly; EthAssemblyAdapter adapter(assembly); - yul::EVMObjectCompiler::compile(*m_parserResult, adapter, m_language == Language::Yul, false, _optimize); + yul::EVMObjectCompiler::compile(*m_parserResult, adapter, languageToDialect(m_language), false, _optimize); object.bytecode = make_shared(assembly.assemble()); object.assembly = assembly.assemblyString(); return object; @@ -145,7 +145,7 @@ MachineAssemblyObject AssemblyStack::assemble(Machine _machine, bool _optimize) { MachineAssemblyObject object; yul::EVMAssembly assembly(true); - yul::EVMObjectCompiler::compile(*m_parserResult, assembly, m_language == Language::Yul, true, _optimize); + yul::EVMObjectCompiler::compile(*m_parserResult, assembly, languageToDialect(m_language), true, _optimize); object.bytecode = make_shared(assembly.finalize()); /// TODO: fill out text representation return object; diff --git a/libyul/backends/evm/EVMCodeTransform.cpp b/libyul/backends/evm/EVMCodeTransform.cpp index 9d8e9a06..025f937f 100644 --- a/libyul/backends/evm/EVMCodeTransform.cpp +++ b/libyul/backends/evm/EVMCodeTransform.cpp @@ -506,7 +506,7 @@ void CodeTransform::operator()(FunctionDefinition const& _function) m_info, _function.body, m_allowStackOpt, - m_yul, + m_dialect, m_evm15, m_identifierAccess, m_useNamedLabelsForFunctions, diff --git a/libyul/backends/evm/EVMCodeTransform.h b/libyul/backends/evm/EVMCodeTransform.h index 8927e999..e305a68c 100644 --- a/libyul/backends/evm/EVMCodeTransform.h +++ b/libyul/backends/evm/EVMCodeTransform.h @@ -22,8 +22,8 @@ #include #include - #include +#include #include #include @@ -88,7 +88,7 @@ public: AsmAnalysisInfo& _analysisInfo, Block const& _block, bool _allowStackOpt = false, - bool _yul = false, + Dialect const& _dialect, bool _evm15 = false, ExternalIdentifierAccess const& _identifierAccess = ExternalIdentifierAccess(), bool _useNamedLabelsForFunctions = false @@ -97,7 +97,7 @@ public: _analysisInfo, _block, _allowStackOpt, - _yul, + _dialect, _evm15, _identifierAccess, _useNamedLabelsForFunctions, @@ -115,7 +115,7 @@ protected: AsmAnalysisInfo& _analysisInfo, Block const& _block, bool _allowStackOpt, - bool _yul, + Dialect const& _dialect, bool _evm15, ExternalIdentifierAccess const& _identifierAccess, bool _useNamedLabelsForFunctions, @@ -180,7 +180,7 @@ private: AsmAnalysisInfo& m_info; Scope* m_scope = nullptr; bool const m_allowStackOpt = true; - bool m_yul = false; + Dialect const& m_dialect; bool m_evm15 = false; bool m_useNamedLabelsForFunctions = false; ExternalIdentifierAccess m_identifierAccess; diff --git a/libyul/backends/evm/EVMObjectCompiler.cpp b/libyul/backends/evm/EVMObjectCompiler.cpp index 13d4b756..ec849faa 100644 --- a/libyul/backends/evm/EVMObjectCompiler.cpp +++ b/libyul/backends/evm/EVMObjectCompiler.cpp @@ -27,9 +27,9 @@ using namespace yul; using namespace std; -void EVMObjectCompiler::compile(Object& _object, AbstractAssembly& _assembly, bool _yul, bool _evm15, bool _optimize) +void EVMObjectCompiler::compile(Object& _object, AbstractAssembly& _assembly, Dialect const& _dialect, bool _evm15, bool _optimize) { - EVMObjectCompiler compiler(_assembly, _yul, _evm15); + EVMObjectCompiler compiler(_assembly, _dialect, _evm15); compiler.run(_object, _optimize); } @@ -42,7 +42,7 @@ void EVMObjectCompiler::run(Object& _object, bool _optimize) { auto subAssemblyAndID = m_assembly.createSubAssembly(); subIDs[subObject->name] = subAssemblyAndID.second; - compile(*subObject, *subAssemblyAndID.first, m_yul, m_evm15, _optimize); + compile(*subObject, *subAssemblyAndID.first, m_dialect, m_evm15, _optimize); } else { @@ -52,5 +52,5 @@ void EVMObjectCompiler::run(Object& _object, bool _optimize) yulAssert(_object.analysisInfo, "No analysis info."); yulAssert(_object.code, "No code."); - CodeTransform{m_assembly, *_object.analysisInfo, *_object.code, _optimize, m_yul, m_evm15}(*_object.code); + CodeTransform{m_assembly, *_object.analysisInfo, *_object.code, _optimize, m_yul, m_evm15, _optimize}(*_object.code); } diff --git a/libyul/backends/evm/EVMObjectCompiler.h b/libyul/backends/evm/EVMObjectCompiler.h index 826b82a4..bb265ff6 100644 --- a/libyul/backends/evm/EVMObjectCompiler.h +++ b/libyul/backends/evm/EVMObjectCompiler.h @@ -23,20 +23,21 @@ namespace yul { struct Object; class AbstractAssembly; +struct Dialect; class EVMObjectCompiler { public: - static void compile(Object& _object, AbstractAssembly& _assembly, bool _yul, bool _evm15, bool _optimize); + static void compile(Object& _object, AbstractAssembly& _assembly, Dialect const& _dialect, bool _evm15, bool _optimize); private: - EVMObjectCompiler(AbstractAssembly& _assembly, bool _yul, bool _evm15): - m_assembly(_assembly), m_yul(_yul), m_evm15(_evm15) + EVMObjectCompiler(AbstractAssembly& _assembly, Dialect const& _dialect, bool _evm15): + m_assembly(_assembly), m_dialect(_dialect), m_evm15(_evm15) {} void run(Object& _object, bool _optimize); AbstractAssembly& m_assembly; - bool m_yul = false; + Dialect const& m_dialect; bool m_evm15 = false; }; -- cgit From fb3a0ac1c7d2c4624df6ae62d290a2de7768d036 Mon Sep 17 00:00:00 2001 From: chriseth Date: Fri, 7 Dec 2018 00:56:16 +0100 Subject: Codegen for object access. --- Changelog.md | 1 + libsolidity/analysis/ReferencesResolver.cpp | 3 +- libsolidity/analysis/TypeChecker.cpp | 4 +- libsolidity/codegen/AsmCodeGen.cpp | 2 +- libsolidity/codegen/CompilerContext.cpp | 5 +- libsolidity/interface/AssemblyStack.cpp | 27 ++++- libsolidity/interface/AssemblyStack.h | 6 ++ libsolidity/parsing/Parser.cpp | 3 +- libyul/AsmAnalysis.cpp | 16 +-- libyul/AsmAnalysis.h | 4 +- libyul/AsmParser.cpp | 34 +++--- libyul/AsmParser.h | 4 +- libyul/CMakeLists.txt | 1 + libyul/Dialect.cpp | 53 +--------- libyul/Dialect.h | 37 ++----- libyul/ObjectParser.h | 4 +- libyul/backends/evm/EVMCodeTransform.cpp | 63 ++++++----- libyul/backends/evm/EVMCodeTransform.h | 12 +-- libyul/backends/evm/EVMDialect.cpp | 141 +++++++++++++++++++++++++ libyul/backends/evm/EVMDialect.h | 85 +++++++++++++++ libyul/backends/evm/EVMObjectCompiler.cpp | 12 ++- libyul/backends/evm/EVMObjectCompiler.h | 8 +- test/libyul/Common.cpp | 3 +- test/libyul/Parser.cpp | 26 ++--- test/libyul/YulOptimizerTest.cpp | 3 +- test/libyul/objectCompiler/datacopy.yul | 48 +++++++++ test/libyul/objectCompiler/dataoffset_code.yul | 29 +++++ test/libyul/objectCompiler/dataoffset_data.yul | 16 +++ test/libyul/objectCompiler/dataoffset_self.yul | 16 +++ test/libyul/objectCompiler/datasize_code.yul | 29 +++++ test/libyul/objectCompiler/datasize_data.yul | 16 +++ test/libyul/objectCompiler/datasize_self.yul | 16 +++ test/tools/yulopti.cpp | 6 +- 33 files changed, 560 insertions(+), 173 deletions(-) create mode 100644 libyul/backends/evm/EVMDialect.cpp create mode 100644 libyul/backends/evm/EVMDialect.h create mode 100644 test/libyul/objectCompiler/datacopy.yul create mode 100644 test/libyul/objectCompiler/dataoffset_code.yul create mode 100644 test/libyul/objectCompiler/dataoffset_data.yul create mode 100644 test/libyul/objectCompiler/dataoffset_self.yul create mode 100644 test/libyul/objectCompiler/datasize_code.yul create mode 100644 test/libyul/objectCompiler/datasize_data.yul create mode 100644 test/libyul/objectCompiler/datasize_self.yul diff --git a/Changelog.md b/Changelog.md index b5d98484..5bbf5af6 100644 --- a/Changelog.md +++ b/Changelog.md @@ -9,6 +9,7 @@ Compiler Features: * Code Generator: Use binary search for dispatch function if more efficient. The size/speed tradeoff can be tuned using ``--optimize-runs``. * SMTChecker: Support mathematical and cryptographic functions in an uninterpreted way. * Type Checker: Add an additional reason to be displayed when type conversion fails. + * Yul: Support object access via ``datasize``, ``dataoffset`` and ``datacopy`` in standalone assembly mode. Bugfixes: diff --git a/libsolidity/analysis/ReferencesResolver.cpp b/libsolidity/analysis/ReferencesResolver.cpp index ac88a052..76641c04 100644 --- a/libsolidity/analysis/ReferencesResolver.cpp +++ b/libsolidity/analysis/ReferencesResolver.cpp @@ -27,6 +27,7 @@ #include #include #include +#include #include #include @@ -321,7 +322,7 @@ bool ReferencesResolver::visit(InlineAssembly const& _inlineAssembly) errorsIgnored, EVMVersion(), errorTypeForLoose, - yul::Dialect::looseAssemblyForEVM(), + yul::EVMDialect::looseAssemblyForEVM(), resolver ).analyze(_inlineAssembly.operations()); return false; diff --git a/libsolidity/analysis/TypeChecker.cpp b/libsolidity/analysis/TypeChecker.cpp index d41415c0..5bd96f8d 100644 --- a/libsolidity/analysis/TypeChecker.cpp +++ b/libsolidity/analysis/TypeChecker.cpp @@ -27,6 +27,8 @@ #include #include +#include + #include #include @@ -658,7 +660,7 @@ bool TypeChecker::visit(InlineAssembly const& _inlineAssembly) m_errorReporter, m_evmVersion, Error::Type::SyntaxError, - yul::Dialect::looseAssemblyForEVM(), + yul::EVMDialect::looseAssemblyForEVM(), identifierAccess ); if (!analyzer.analyze(_inlineAssembly.operations())) diff --git a/libsolidity/codegen/AsmCodeGen.cpp b/libsolidity/codegen/AsmCodeGen.cpp index 45efe55b..c04c1c34 100644 --- a/libsolidity/codegen/AsmCodeGen.cpp +++ b/libsolidity/codegen/AsmCodeGen.cpp @@ -188,8 +188,8 @@ void CodeGenerator::assemble( assemblyAdapter, _analysisInfo, _parsedData, + *EVMDialect::strictAssemblyForEVM(), _optimize, - Dialect::strictAssemblyForEVM(), false, _identifierAccess, _useNamedLabelsForFunctions diff --git a/libsolidity/codegen/CompilerContext.cpp b/libsolidity/codegen/CompilerContext.cpp index dac09c2e..0b018e1e 100644 --- a/libsolidity/codegen/CompilerContext.cpp +++ b/libsolidity/codegen/CompilerContext.cpp @@ -31,6 +31,7 @@ #include #include #include +#include #include #include @@ -361,7 +362,7 @@ void CompilerContext::appendInlineAssembly( ErrorList errors; ErrorReporter errorReporter(errors); auto scanner = make_shared(langutil::CharStream(_assembly, "--CODEGEN--")); - auto parserResult = yul::Parser(errorReporter, yul::Dialect::strictAssemblyForEVM()).parse(scanner, false); + auto parserResult = yul::Parser(errorReporter, yul::EVMDialect::strictAssemblyForEVM()).parse(scanner, false); #ifdef SOL_OUTPUT_ASM cout << yul::AsmPrinter()(*parserResult) << endl; #endif @@ -373,7 +374,7 @@ void CompilerContext::appendInlineAssembly( errorReporter, m_evmVersion, boost::none, - yul::Dialect::strictAssemblyForEVM(), + yul::EVMDialect::strictAssemblyForEVM(), identifierAccess.resolve ).analyze(*parserResult); if (!parserResult || !errorReporter.errors().empty() || !analyzerResult) diff --git a/libsolidity/interface/AssemblyStack.cpp b/libsolidity/interface/AssemblyStack.cpp index 4af1e23d..b97e00ae 100644 --- a/libsolidity/interface/AssemblyStack.cpp +++ b/libsolidity/interface/AssemblyStack.cpp @@ -32,6 +32,7 @@ #include #include #include +#include #include #include @@ -45,14 +46,14 @@ using namespace dev::solidity; namespace { -yul::Dialect languageToDialect(AssemblyStack::Language _language) +shared_ptr languageToDialect(AssemblyStack::Language _language) { switch (_language) { case AssemblyStack::Language::Assembly: - return yul::Dialect::looseAssemblyForEVM(); + return yul::EVMDialect::looseAssemblyForEVM(); case AssemblyStack::Language::StrictAssembly: - return yul::Dialect::strictAssemblyForEVMObjects(); + return yul::EVMDialect::strictAssemblyForEVMObjects(); case AssemblyStack::Language::Yul: return yul::Dialect::yul(); } @@ -112,6 +113,22 @@ bool AssemblyStack::analyzeParsed(yul::Object& _object) return success; } +void AssemblyStack::compileEVM(yul::AbstractAssembly& _assembly, bool _evm15, bool _optimize) const +{ + shared_ptr dialect; + + if (m_language == Language::Assembly) + dialect = yul::EVMDialect::looseAssemblyForEVM(); + else if (m_language == AssemblyStack::Language::StrictAssembly) + dialect = yul::EVMDialect::strictAssemblyForEVMObjects(); + else if (m_language == AssemblyStack::Language::Yul) + dialect = yul::EVMDialect::yulForEVM(); + else + solAssert(false, "Invalid language."); + + yul::EVMObjectCompiler::compile(*m_parserResult, _assembly, *dialect, _evm15, _optimize); +} + void AssemblyStack::optimize(yul::Object& _object) { solAssert(_object.code, ""); @@ -136,7 +153,7 @@ MachineAssemblyObject AssemblyStack::assemble(Machine _machine, bool _optimize) MachineAssemblyObject object; eth::Assembly assembly; EthAssemblyAdapter adapter(assembly); - yul::EVMObjectCompiler::compile(*m_parserResult, adapter, languageToDialect(m_language), false, _optimize); + compileEVM(adapter, false, _optimize); object.bytecode = make_shared(assembly.assemble()); object.assembly = assembly.assemblyString(); return object; @@ -145,7 +162,7 @@ MachineAssemblyObject AssemblyStack::assemble(Machine _machine, bool _optimize) { MachineAssemblyObject object; yul::EVMAssembly assembly(true); - yul::EVMObjectCompiler::compile(*m_parserResult, assembly, languageToDialect(m_language), true, _optimize); + compileEVM(assembly, true, _optimize); object.bytecode = make_shared(assembly.finalize()); /// TODO: fill out text representation return object; diff --git a/libsolidity/interface/AssemblyStack.h b/libsolidity/interface/AssemblyStack.h index 6cfefcd8..c8e3d35a 100644 --- a/libsolidity/interface/AssemblyStack.h +++ b/libsolidity/interface/AssemblyStack.h @@ -36,6 +36,10 @@ namespace langutil { class Scanner; } +namespace yul +{ +class AbstractAssembly; +} namespace dev { @@ -86,6 +90,8 @@ private: bool analyzeParsed(); bool analyzeParsed(yul::Object& _object); + void compileEVM(yul::AbstractAssembly& _assembly, bool _evm15, bool _optimize) const; + void optimize(yul::Object& _object); Language m_language = Language::Assembly; diff --git a/libsolidity/parsing/Parser.cpp b/libsolidity/parsing/Parser.cpp index 0b4eca7d..26f13f93 100644 --- a/libsolidity/parsing/Parser.cpp +++ b/libsolidity/parsing/Parser.cpp @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include @@ -1012,7 +1013,7 @@ ASTPointer Parser::parseInlineAssembly(ASTPointer con m_scanner->next(); } - yul::Parser asmParser(m_errorReporter); + yul::Parser asmParser(m_errorReporter, yul::EVMDialect::looseAssemblyForEVM()); shared_ptr block = asmParser.parse(m_scanner, true); nodeFactory.markEndPosition(); return nodeFactory.createNode(_docString, block); diff --git a/libyul/AsmAnalysis.cpp b/libyul/AsmAnalysis.cpp index 1be1cf1a..821da005 100644 --- a/libyul/AsmAnalysis.cpp +++ b/libyul/AsmAnalysis.cpp @@ -101,7 +101,7 @@ bool AsmAnalyzer::operator()(Literal const& _literal) } else if (_literal.kind == LiteralKind::Boolean) { - solAssert(m_dialect.flavour == AsmFlavour::Yul, ""); + solAssert(m_dialect->flavour == AsmFlavour::Yul, ""); solAssert(_literal.value == YulString{string("true")} || _literal.value == YulString{string("false")}, ""); } m_info.stackHeightInfo[&_literal] = m_stackHeight; @@ -164,7 +164,7 @@ bool AsmAnalyzer::operator()(Identifier const& _identifier) bool AsmAnalyzer::operator()(FunctionalInstruction const& _instr) { - solAssert(m_dialect.flavour != AsmFlavour::Yul, ""); + solAssert(m_dialect->flavour != AsmFlavour::Yul, ""); bool success = true; for (auto const& arg: _instr.arguments | boost::adaptors::reversed) if (!expectExpression(arg)) @@ -182,9 +182,9 @@ bool AsmAnalyzer::operator()(ExpressionStatement const& _statement) { int initialStackHeight = m_stackHeight; bool success = boost::apply_visitor(*this, _statement.expression); - if (m_stackHeight != initialStackHeight && (m_dialect.flavour != AsmFlavour::Loose || m_errorTypeForLoose)) + if (m_stackHeight != initialStackHeight && (m_dialect->flavour != AsmFlavour::Loose || m_errorTypeForLoose)) { - Error::Type errorType = m_dialect.flavour == AsmFlavour::Loose ? *m_errorTypeForLoose : Error::Type::TypeError; + Error::Type errorType = m_dialect->flavour == AsmFlavour::Loose ? *m_errorTypeForLoose : Error::Type::TypeError; string msg = "Top-level expressions are not supposed to return values (this expression returns " + to_string(m_stackHeight - initialStackHeight) + @@ -299,7 +299,7 @@ bool AsmAnalyzer::operator()(FunctionCall const& _funCall) bool success = true; size_t parameters = 0; size_t returns = 0; - if (BuiltinFunction const* f = m_dialect.builtins->query(_funCall.functionName.name)) + if (BuiltinFunction const* f = m_dialect->builtin(_funCall.functionName.name)) { // TODO: compare types, too parameters = f->parameters.size(); @@ -569,7 +569,7 @@ Scope& AsmAnalyzer::scope(Block const* _block) } void AsmAnalyzer::expectValidType(string const& type, SourceLocation const& _location) { - if (m_dialect.flavour != AsmFlavour::Yul) + if (m_dialect->flavour != AsmFlavour::Yul) return; if (!builtinTypes.count(type)) @@ -629,7 +629,7 @@ void AsmAnalyzer::warnOnInstructions(solidity::Instruction _instr, SourceLocatio if (_instr == solidity::Instruction::JUMP || _instr == solidity::Instruction::JUMPI || _instr == solidity::Instruction::JUMPDEST) { - if (m_dialect.flavour != AsmFlavour::Loose) + if (m_dialect->flavour != AsmFlavour::Loose) solAssert(m_errorTypeForLoose && *m_errorTypeForLoose != Error::Type::Warning, ""); m_errorReporter.error( @@ -644,7 +644,7 @@ void AsmAnalyzer::warnOnInstructions(solidity::Instruction _instr, SourceLocatio void AsmAnalyzer::checkLooseFeature(SourceLocation const& _location, string const& _description) { - if (m_dialect.flavour != AsmFlavour::Loose) + if (m_dialect->flavour != AsmFlavour::Loose) solAssert(false, _description); else if (m_errorTypeForLoose) m_errorReporter.error(*m_errorTypeForLoose, _location, _description); diff --git a/libyul/AsmAnalysis.h b/libyul/AsmAnalysis.h index ec2b8868..21cc1142 100644 --- a/libyul/AsmAnalysis.h +++ b/libyul/AsmAnalysis.h @@ -59,7 +59,7 @@ public: langutil::ErrorReporter& _errorReporter, dev::solidity::EVMVersion _evmVersion, boost::optional _errorTypeForLoose, - Dialect _dialect = Dialect::looseAssemblyForEVM(), + std::shared_ptr _dialect, ExternalIdentifierAccess::Resolver const& _resolver = ExternalIdentifierAccess::Resolver() ): m_resolver(_resolver), @@ -115,7 +115,7 @@ private: AsmAnalysisInfo& m_info; langutil::ErrorReporter& m_errorReporter; dev::solidity::EVMVersion m_evmVersion; - Dialect m_dialect = Dialect::looseAssemblyForEVM(); + std::shared_ptr m_dialect; boost::optional m_errorTypeForLoose; }; diff --git a/libyul/AsmParser.cpp b/libyul/AsmParser.cpp index 33bb42f9..c7302063 100644 --- a/libyul/AsmParser.cpp +++ b/libyul/AsmParser.cpp @@ -107,14 +107,14 @@ Statement Parser::parseStatement() return parseForLoop(); case Token::Assign: { - if (m_dialect.flavour != AsmFlavour::Loose) + if (m_dialect->flavour != AsmFlavour::Loose) break; StackAssignment assignment = createWithLocation(); advance(); expectToken(Token::Colon); assignment.variableName.location = location(); assignment.variableName.name = YulString(currentLiteral()); - if (m_dialect.builtins->query(assignment.variableName.name)) + if (m_dialect->builtin(assignment.variableName.name)) fatalParserError("Identifier expected, got builtin symbol."); else if (instructions().count(assignment.variableName.name.str())) fatalParserError("Identifier expected, got instruction name."); @@ -176,9 +176,9 @@ Statement Parser::parseStatement() if (currentToken() == Token::Assign && peekNextToken() != Token::Colon) { Assignment assignment = createWithLocation(identifier.location); - if (m_dialect.builtins->query(identifier.name)) + if (m_dialect->builtin(identifier.name)) fatalParserError("Cannot assign to builtin function \"" + identifier.name.str() + "\"."); - else if (m_dialect.flavour != AsmFlavour::Yul && instructions().count(identifier.name.str())) + else if (m_dialect->flavour != AsmFlavour::Yul && instructions().count(identifier.name.str())) fatalParserError("Cannot use instruction names for identifier names."); advance(); assignment.variableNames.emplace_back(identifier); @@ -189,7 +189,7 @@ Statement Parser::parseStatement() else { // label - if (m_dialect.flavour != AsmFlavour::Loose) + if (m_dialect->flavour != AsmFlavour::Loose) fatalParserError("Labels are not supported."); Label label = createWithLocation