From 37f681c430af65181b9c1a5f5dee774fd043f7ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Tue, 31 Aug 2021 15:08:16 +0200 Subject: [PATCH 1/3] Deduplicate code for printing source locations --- libsolidity/codegen/ir/Common.cpp | 17 ++++++----- libyul/AsmPrinter.cpp | 49 +++++++++++++++++++++---------- libyul/AsmPrinter.h | 8 ++++- 3 files changed, 50 insertions(+), 24 deletions(-) diff --git a/libsolidity/codegen/ir/Common.cpp b/libsolidity/codegen/ir/Common.cpp index 772e9b53e..aec812c12 100644 --- a/libsolidity/codegen/ir/Common.cpp +++ b/libsolidity/codegen/ir/Common.cpp @@ -22,9 +22,13 @@ #include +#include + using namespace std; -using namespace solidity::util; +using namespace solidity::langutil; using namespace solidity::frontend; +using namespace solidity::util; +using namespace solidity::yul; namespace solidity::frontend { @@ -131,12 +135,11 @@ string dispenseLocationComment(langutil::SourceLocation const& _location, IRGene { solAssert(_location.sourceName, ""); _context.markSourceUsed(*_location.sourceName); - return "/// @src " - + to_string(_context.sourceIndices().at(*_location.sourceName)) - + ":" - + to_string(_location.start) - + ":" - + to_string(_location.end); + return AsmPrinter::formatSourceLocationComment( + _location, + _context.sourceIndices(), + true /* _statement */ + ); } string dispenseLocationComment(ASTNode const& _node, IRGenerationContext& _context) diff --git a/libyul/AsmPrinter.cpp b/libyul/AsmPrinter.cpp index 2a7b705f8..680dd89bc 100644 --- a/libyul/AsmPrinter.cpp +++ b/libyul/AsmPrinter.cpp @@ -38,6 +38,7 @@ using namespace std; using namespace solidity; +using namespace solidity::langutil; using namespace solidity::util; using namespace solidity::yul; @@ -256,7 +257,33 @@ string AsmPrinter::appendTypeName(YulString _type, bool _isBoolLiteral) const return ":" + _type.str(); } -string AsmPrinter::formatSourceLocationComment(shared_ptr const& _debugData, bool _statement) +string AsmPrinter::formatSourceLocationComment( + SourceLocation const& _location, + map const& _nameToSourceIndex, + bool _statement +) +{ + yulAssert(!_nameToSourceIndex.empty(), ""); + + string sourceIndex = "-1"; + if (_location.sourceName) + sourceIndex = to_string(_nameToSourceIndex.at(*_location.sourceName)); + + string sourceLocation = + "@src " + + sourceIndex + + ":" + + to_string(_location.start) + + ":" + + to_string(_location.end); + + return + _statement ? + "/// " + sourceLocation : + "/** " + sourceLocation + " */ "; +} + +string AsmPrinter::formatSourceLocationComment(shared_ptr const& _debugData, bool _statement) { if ( !_debugData || @@ -267,19 +294,9 @@ string AsmPrinter::formatSourceLocationComment(shared_ptr const m_lastLocation = _debugData->location; - string sourceIndex = "-1"; - if (_debugData->location.sourceName) - sourceIndex = to_string(m_nameToSourceIndex.at(*_debugData->location.sourceName)); - - string sourceLocation = - "@src " + - sourceIndex + - ":" + - to_string(_debugData->location.start) + - ":" + - to_string(_debugData->location.end); - return - _statement ? - "/// " + sourceLocation + "\n" : - "/** " + sourceLocation + " */ "; + return formatSourceLocationComment( + _debugData->location, + m_nameToSourceIndex, + _statement + ) + (_statement ? "\n" : ""); } diff --git a/libyul/AsmPrinter.h b/libyul/AsmPrinter.h index 940f663b4..1beb964aa 100644 --- a/libyul/AsmPrinter.h +++ b/libyul/AsmPrinter.h @@ -76,6 +76,12 @@ public: std::string operator()(Leave const& _continue); std::string operator()(Block const& _block); + static std::string formatSourceLocationComment( + langutil::SourceLocation const& _location, + std::map const& _nameToSourceIndex, + bool _statement + ); + private: std::string formatTypedName(TypedName _variable); std::string appendTypeName(YulString _type, bool _isBoolLiteral = false) const; @@ -88,7 +94,7 @@ private: } Dialect const* const m_dialect = nullptr; - std::map m_nameToSourceIndex; + std::map m_nameToSourceIndex; langutil::SourceLocation m_lastLocation = {}; }; From d78522b08b4eb654d4e7c0bd662c39448e41ba9e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Thu, 2 Sep 2021 15:17:56 +0200 Subject: [PATCH 2/3] AsmParser: Accept optional code snippets after the @src tags --- libyul/AsmParser.cpp | 18 ++++- scripts/error_codes.py | 1 + test/libyul/Parser.cpp | 172 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 189 insertions(+), 2 deletions(-) diff --git a/libyul/AsmParser.cpp b/libyul/AsmParser.cpp index ca2864a5c..8cd88f411 100644 --- a/libyul/AsmParser.cpp +++ b/libyul/AsmParser.cpp @@ -135,7 +135,8 @@ void Parser::fetchSourceLocationFromComment() regex_constants::ECMAScript | regex_constants::optimize ); static regex const srcTagArgsRegex = regex( - R"~~(^(-1|\d+):(-1|\d+):(-1|\d+)(?:\s+|$))~~", // index and location, e.g.: 1:234:-1 + R"~~(^(-1|\d+):(-1|\d+):(-1|\d+)(?:\s+|$))~~" // index and location, e.g.: 1:234:-1 + R"~~(("(?:[^"\\]|\\.)*"?)?)~~", // optional code snippet, e.g.: "string memory s = \"abc\";..." regex_constants::ECMAScript | regex_constants::optimize ); @@ -164,9 +165,22 @@ void Parser::fetchSourceLocationFromComment() return; } - solAssert(srcTagArgsMatch.size() == 4, ""); + solAssert(srcTagArgsMatch.size() == 5, ""); position += srcTagArgsMatch.position() + srcTagArgsMatch.length(); + if (srcTagArgsMatch[4].matched && ( + !boost::algorithm::ends_with(srcTagArgsMatch[4].str(), "\"") || + boost::algorithm::ends_with(srcTagArgsMatch[4].str(), "\\\"") + )) + { + m_errorReporter.syntaxError( + 1544_error, + commentLocation, + "Invalid code snippet in source location mapping. Quote is not terminated." + ); + return; + } + optional const sourceIndex = toInt(srcTagArgsMatch[1].str()); optional const start = toInt(srcTagArgsMatch[2].str()); optional const end = toInt(srcTagArgsMatch[3].str()); diff --git a/scripts/error_codes.py b/scripts/error_codes.py index 6f3f9ce95..214e6d3d2 100755 --- a/scripts/error_codes.py +++ b/scripts/error_codes.py @@ -192,6 +192,7 @@ def examine_id_coverage(top_dir, source_id_to_file_names, new_ids_only=False): # white list of ids which are not covered by tests white_ids = { "9804", # Tested in test/libyul/ObjectParser.cpp. + "1544", "2674", "6367", "8387", diff --git a/test/libyul/Parser.cpp b/test/libyul/Parser.cpp index 4168b23a3..a973e9e5b 100644 --- a/test/libyul/Parser.cpp +++ b/test/libyul/Parser.cpp @@ -624,6 +624,20 @@ BOOST_AUTO_TEST_CASE(customSourceLocations_two_locations_no_whitespace) CHECK_LOCATION(result->debugData->location, "", -1, -1); } +BOOST_AUTO_TEST_CASE(customSourceLocations_two_locations_separated_with_single_space) +{ + ErrorList errorList; + ErrorReporter reporter(errorList); + auto const sourceText = R"( + /// @src 0:111:222 @src 1:333:444 + {} + )"; + EVMDialectTyped const& dialect = EVMDialectTyped::instance(EVMVersion{}); + shared_ptr result = parse(sourceText, dialect, reporter); + BOOST_REQUIRE(!!result && errorList.size() == 0); + CHECK_LOCATION(result->debugData->location, "source1", 333, 444); +} + BOOST_AUTO_TEST_CASE(customSourceLocations_leading_trailing_whitespace) { ErrorList errorList; @@ -656,6 +670,164 @@ BOOST_AUTO_TEST_CASE(customSourceLocations_reference_original_sloc) CHECK_LOCATION(varDecl.debugData->location, "", 10, 20); } +BOOST_AUTO_TEST_CASE(customSourceLocations_with_code_snippets) +{ + ErrorList errorList; + ErrorReporter reporter(errorList); + auto const sourceText = R"~~~( + { + /// @src 0:149:156 "new C(\"123\")" + let x := 123 + + let y := /** @src 1:96:165 "contract D {..." */ 128 + } + )~~~"; + EVMDialectTyped const& dialect = EVMDialectTyped::instance(EVMVersion{}); + shared_ptr result = parse(sourceText, dialect, reporter); + BOOST_REQUIRE(!!result && errorList.size() == 0); + BOOST_REQUIRE_EQUAL(result->statements.size(), 2); + + BOOST_REQUIRE(holds_alternative(result->statements.at(0))); + VariableDeclaration const& varX = get(result->statements.at(0)); + CHECK_LOCATION(varX.debugData->location, "source0", 149, 156); + + BOOST_REQUIRE(holds_alternative(result->statements.at(1))); + VariableDeclaration const& varY = get(result->statements.at(1)); + BOOST_REQUIRE(!!varY.value); + BOOST_REQUIRE(holds_alternative(*varY.value)); + Literal const& literal128 = get(*varY.value); + CHECK_LOCATION(literal128.debugData->location, "source1", 96, 165); +} + +BOOST_AUTO_TEST_CASE(customSourceLocations_with_code_snippets_empty_snippet) +{ + ErrorList errorList; + ErrorReporter reporter(errorList); + auto const sourceText = R"( + /// @src 0:111:222 "" + {} + )"; + EVMDialectTyped const& dialect = EVMDialectTyped::instance(EVMVersion{}); + shared_ptr result = parse(sourceText, dialect, reporter); + BOOST_REQUIRE(!!result && errorList.size() == 0); + CHECK_LOCATION(result->debugData->location, "source0", 111, 222); +} + +BOOST_AUTO_TEST_CASE(customSourceLocations_with_code_snippets_no_whitespace_before_snippet) +{ + ErrorList errorList; + ErrorReporter reporter(errorList); + auto const sourceText = R"( + /// @src 0:111:222"abc" def + {} + )"; + EVMDialectTyped const& dialect = EVMDialectTyped::instance(EVMVersion{}); + shared_ptr result = parse(sourceText, dialect, reporter); + BOOST_REQUIRE(!!result); + BOOST_REQUIRE(errorList.size() == 1); + BOOST_TEST(errorList[0]->type() == Error::Type::SyntaxError); + BOOST_TEST(errorList[0]->errorId() == 8387_error); + CHECK_LOCATION(result->debugData->location, "", -1, -1); +} + +BOOST_AUTO_TEST_CASE(customSourceLocations_with_code_snippets_no_whitespace_after_snippet) +{ + ErrorList errorList; + ErrorReporter reporter(errorList); + auto const sourceText = R"( + /// @src 0:111:222 "abc"def + {} + )"; + EVMDialectTyped const& dialect = EVMDialectTyped::instance(EVMVersion{}); + shared_ptr result = parse(sourceText, dialect, reporter); + BOOST_REQUIRE(!!result && errorList.size() == 0); + CHECK_LOCATION(result->debugData->location, "source0", 111, 222); +} + +BOOST_AUTO_TEST_CASE(customSourceLocations_two_locations_with_snippets_no_whitespace) +{ + ErrorList errorList; + ErrorReporter reporter(errorList); + auto const sourceText = R"( + /// @src 0:111:222 "abc"@src 1:333:444 "abc" + {} + )"; + EVMDialectTyped const& dialect = EVMDialectTyped::instance(EVMVersion{}); + shared_ptr result = parse(sourceText, dialect, reporter); + BOOST_REQUIRE(!!result && errorList.size() == 0); + CHECK_LOCATION(result->debugData->location, "source1", 333, 444); +} + +BOOST_AUTO_TEST_CASE(customSourceLocations_two_locations_with_snippets_unterminated_quote) +{ + ErrorList errorList; + ErrorReporter reporter(errorList); + auto const sourceText = R"( + /// @src 0:111:222 " abc @src 1:333:444 + {} + )"; + EVMDialectTyped const& dialect = EVMDialectTyped::instance(EVMVersion{}); + shared_ptr result = parse(sourceText, dialect, reporter); + BOOST_REQUIRE(!!result); + BOOST_REQUIRE(errorList.size() == 1); + BOOST_TEST(errorList[0]->type() == Error::Type::SyntaxError); + BOOST_TEST(errorList[0]->errorId() == 1544_error); + CHECK_LOCATION(result->debugData->location, "", -1, -1); +} + +BOOST_AUTO_TEST_CASE(customSourceLocations_with_code_snippets_with_nested_locations) +{ + ErrorList errorList; + ErrorReporter reporter(errorList); + auto const sourceText = R"~~~( + { + /// @src 0:149:156 "new C(\"123\") /// @src 1:3:4 " + let x := 123 + + let y := /** @src 1:96:165 "function f() internal { \"\/** @src 0:6:7 *\/\"; }" */ 128 + } + )~~~"; + EVMDialectTyped const& dialect = EVMDialectTyped::instance(EVMVersion{}); + shared_ptr result = parse(sourceText, dialect, reporter); + BOOST_REQUIRE(!!result && errorList.size() == 0); + BOOST_REQUIRE_EQUAL(result->statements.size(), 2); + + BOOST_REQUIRE(holds_alternative(result->statements.at(0))); + VariableDeclaration const& varX = get(result->statements.at(0)); + CHECK_LOCATION(varX.debugData->location, "source0", 149, 156); + + BOOST_REQUIRE(holds_alternative(result->statements.at(1))); + VariableDeclaration const& varY = get(result->statements.at(1)); + BOOST_REQUIRE(!!varY.value); + BOOST_REQUIRE(holds_alternative(*varY.value)); + Literal const& literal128 = get(*varY.value); + CHECK_LOCATION(literal128.debugData->location, "source1", 96, 165); +} + +BOOST_AUTO_TEST_CASE(customSourceLocations_multiple_src_tags_on_one_line) +{ + ErrorList errorList; + ErrorReporter reporter(errorList); + auto const sourceText = + "{\n" + " /// " + R"~~(@src 1:2:3 ""@src 1:2:4 @src-1:2:5@src 1:2:6 @src 1:2:7 "" @src 1:2:8)~~" + R"~~( X "@src 0:10:20 "new C(\"123\") /// @src 1:4:5 "" XYZ)~~" + R"~~( @src0:20:30 "abc"@src0:2:4 @src-0:2:5@)~~" + R"~~( @some text with random @ signs @@@ @- @** 1:6:7 "src 1:8:9")~~" + "\n" + " let x := 123\n" + "}\n"; + EVMDialectTyped const& dialect = EVMDialectTyped::instance(EVMVersion{}); + shared_ptr result = parse(sourceText, dialect, reporter); + BOOST_REQUIRE(!!result && errorList.size() == 0); + BOOST_REQUIRE_EQUAL(result->statements.size(), 1); + + BOOST_REQUIRE(holds_alternative(result->statements.at(0))); + VariableDeclaration const& varX = get(result->statements.at(0)); + CHECK_LOCATION(varX.debugData->location, "source1", 4, 5); +} + BOOST_AUTO_TEST_SUITE_END() } // end namespaces From 14639efc5d438c21b7688517333167401788c3b9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Tue, 31 Aug 2021 15:10:40 +0200 Subject: [PATCH 3/3] Print code snippets next to source locations in IR output --- libsolidity/ast/ASTJsonConverter.cpp | 1 - libsolidity/codegen/ir/Common.cpp | 3 +- libsolidity/codegen/ir/IRGenerationContext.h | 11 +- libsolidity/codegen/ir/IRGenerator.cpp | 14 +- libsolidity/codegen/ir/IRGenerator.h | 15 +- libsolidity/interface/CompilerStack.cpp | 2 +- libyul/AsmPrinter.cpp | 26 +- libyul/AsmPrinter.h | 16 +- libyul/AssemblyStack.cpp | 4 +- libyul/AssemblyStack.h | 2 +- libyul/Object.cpp | 14 +- libyul/Object.h | 18 +- .../constant_optimizer_yul/output | 12 +- test/cmdlineTests/exp_base_literal/output | 104 ++-- .../output | 8 +- .../ir_compiler_subobjects/output | 30 +- .../output | 4 +- .../output | 4 +- .../keccak_optimization_deploy_code/output | 12 +- .../keccak_optimization_low_runs/output | 8 +- test/cmdlineTests/name_simplifier/output | 18 +- .../cmdlineTests/optimizer_array_sload/output | 28 +- test/cmdlineTests/revert_strings/output | 14 +- .../output.json | 6 +- .../standard_ir_requested/output.json | 14 +- .../standard_viair_requested/output.json | 38 +- test/cmdlineTests/viair_abicoder_v1/output | 20 +- test/cmdlineTests/viair_subobjects/output | 30 +- test/cmdlineTests/yul_optimizer_steps/output | 4 +- .../yul_source_locations/output.json | 156 ++--- .../args | 1 + .../input.sol | 13 + .../output | 578 ++++++++++++++++++ .../yul_string_format_ascii/output.json | 18 +- .../output.json | 18 +- .../output.json | 20 +- .../yul_string_format_ascii_long/output.json | 18 +- .../yul_string_format_hex/output.json | 20 +- 38 files changed, 989 insertions(+), 333 deletions(-) create mode 100644 test/cmdlineTests/yul_source_locations_code_snippet_escaping/args create mode 100644 test/cmdlineTests/yul_source_locations_code_snippet_escaping/input.sol create mode 100644 test/cmdlineTests/yul_source_locations_code_snippet_escaping/output diff --git a/libsolidity/ast/ASTJsonConverter.cpp b/libsolidity/ast/ASTJsonConverter.cpp index f8c284483..b74f71572 100644 --- a/libsolidity/ast/ASTJsonConverter.cpp +++ b/libsolidity/ast/ASTJsonConverter.cpp @@ -26,7 +26,6 @@ #include #include -#include #include #include diff --git a/libsolidity/codegen/ir/Common.cpp b/libsolidity/codegen/ir/Common.cpp index aec812c12..0a445c119 100644 --- a/libsolidity/codegen/ir/Common.cpp +++ b/libsolidity/codegen/ir/Common.cpp @@ -138,7 +138,8 @@ string dispenseLocationComment(langutil::SourceLocation const& _location, IRGene return AsmPrinter::formatSourceLocationComment( _location, _context.sourceIndices(), - true /* _statement */ + true /* _statement */, + _context.soliditySourceProvider() ); } diff --git a/libsolidity/codegen/ir/IRGenerationContext.h b/libsolidity/codegen/ir/IRGenerationContext.h index ee3eaced6..fdc617220 100644 --- a/libsolidity/codegen/ir/IRGenerationContext.h +++ b/libsolidity/codegen/ir/IRGenerationContext.h @@ -29,6 +29,7 @@ #include #include +#include #include #include @@ -72,13 +73,15 @@ public: ExecutionContext _executionContext, RevertStrings _revertStrings, OptimiserSettings _optimiserSettings, - std::map _sourceIndices + std::map _sourceIndices, + langutil::CharStreamProvider const* _soliditySourceProvider ): m_evmVersion(_evmVersion), m_executionContext(_executionContext), m_revertStrings(_revertStrings), m_optimiserSettings(std::move(_optimiserSettings)), - m_sourceIndices(std::move(_sourceIndices)) + m_sourceIndices(std::move(_sourceIndices)), + m_soliditySourceProvider(_soliditySourceProvider) {} MultiUseYulFunctionCollector& functionCollector() { return m_functions; } @@ -171,6 +174,8 @@ public: bool immutableRegistered(VariableDeclaration const& _varDecl) const { return m_immutableVariables.count(&_varDecl); } + langutil::CharStreamProvider const* soliditySourceProvider() const { return m_soliditySourceProvider; } + private: langutil::EVMVersion m_evmVersion; ExecutionContext m_executionContext; @@ -214,6 +219,8 @@ private: std::map m_functionIDs; std::set m_subObjects; + + langutil::CharStreamProvider const* m_soliditySourceProvider = nullptr; }; } diff --git a/libsolidity/codegen/ir/IRGenerator.cpp b/libsolidity/codegen/ir/IRGenerator.cpp index 5affb1c08..30fc149ad 100644 --- a/libsolidity/codegen/ir/IRGenerator.cpp +++ b/libsolidity/codegen/ir/IRGenerator.cpp @@ -45,8 +45,9 @@ using namespace std; using namespace solidity; -using namespace solidity::util; using namespace solidity::frontend; +using namespace solidity::langutil; +using namespace solidity::util; namespace { @@ -115,7 +116,7 @@ pair IRGenerator::run( " * !USE AT YOUR OWN RISK! *\n" " *=====================================================*/\n\n"; - return {warning + ir, warning + asmStack.print()}; + return {warning + ir, warning + asmStack.print(m_context.soliditySourceProvider())}; } string IRGenerator::generate( @@ -1064,7 +1065,14 @@ void IRGenerator::resetContext(ContractDefinition const& _contract, ExecutionCon m_context.internalDispatchClean(), "Reset internal dispatch map without consuming it." ); - IRGenerationContext newContext(m_evmVersion, _context, m_context.revertStrings(), m_optimiserSettings, m_context.sourceIndices()); + IRGenerationContext newContext( + m_evmVersion, + _context, + m_context.revertStrings(), + m_optimiserSettings, + m_context.sourceIndices(), + m_context.soliditySourceProvider() + ); newContext.copyFunctionIDsFrom(m_context); m_context = move(newContext); diff --git a/libsolidity/codegen/ir/IRGenerator.h b/libsolidity/codegen/ir/IRGenerator.h index d5c2cbaec..85b570c7f 100644 --- a/libsolidity/codegen/ir/IRGenerator.h +++ b/libsolidity/codegen/ir/IRGenerator.h @@ -28,7 +28,10 @@ #include #include #include + +#include #include + #include namespace solidity::frontend @@ -45,11 +48,19 @@ public: langutil::EVMVersion _evmVersion, RevertStrings _revertStrings, OptimiserSettings _optimiserSettings, - std::map _sourceIndices + std::map _sourceIndices, + langutil::CharStreamProvider const* _soliditySourceProvider ): m_evmVersion(_evmVersion), m_optimiserSettings(_optimiserSettings), - m_context(_evmVersion, ExecutionContext::Creation, _revertStrings, std::move(_optimiserSettings), std::move(_sourceIndices)), + m_context( + _evmVersion, + ExecutionContext::Creation, + _revertStrings, + std::move(_optimiserSettings), + std::move(_sourceIndices), + _soliditySourceProvider + ), m_utils(_evmVersion, m_context.revertStrings(), m_context.functionCollector()) {} diff --git a/libsolidity/interface/CompilerStack.cpp b/libsolidity/interface/CompilerStack.cpp index cbdfff454..68411b071 100644 --- a/libsolidity/interface/CompilerStack.cpp +++ b/libsolidity/interface/CompilerStack.cpp @@ -1329,7 +1329,7 @@ void CompilerStack::generateIR(ContractDefinition const& _contract) for (auto const& pair: m_contracts) otherYulSources.emplace(pair.second.contract, pair.second.yulIR); - IRGenerator generator(m_evmVersion, m_revertStrings, m_optimiserSettings, sourceIndices()); + IRGenerator generator(m_evmVersion, m_revertStrings, m_optimiserSettings, sourceIndices(), this); tie(compiledContract.yulIR, compiledContract.yulIROptimized) = generator.run( _contract, createCBORMetadata(compiledContract), diff --git a/libyul/AsmPrinter.cpp b/libyul/AsmPrinter.cpp index 680dd89bc..9462bbd5a 100644 --- a/libyul/AsmPrinter.cpp +++ b/libyul/AsmPrinter.cpp @@ -27,6 +27,7 @@ #include #include +#include #include #include @@ -260,15 +261,31 @@ string AsmPrinter::appendTypeName(YulString _type, bool _isBoolLiteral) const string AsmPrinter::formatSourceLocationComment( SourceLocation const& _location, map const& _nameToSourceIndex, - bool _statement + bool _statement, + CharStreamProvider const* _soliditySourceProvider ) { yulAssert(!_nameToSourceIndex.empty(), ""); string sourceIndex = "-1"; + string solidityCodeSnippet = ""; if (_location.sourceName) + { sourceIndex = to_string(_nameToSourceIndex.at(*_location.sourceName)); + if (_soliditySourceProvider) + { + solidityCodeSnippet = escapeAndQuoteString( + _soliditySourceProvider->charStream(*_location.sourceName).singleLineSnippet(_location) + ); + + // On top of escaping quotes we also escape the slash inside any `*/` to guard against + // it prematurely terminating multi-line comment blocks. We do not escape all slashes + // because the ones without `*` are not dangerous and ignoring them reduces visual noise. + boost::replace_all(solidityCodeSnippet, "*/", "*\\/"); + } + } + string sourceLocation = "@src " + sourceIndex + @@ -279,8 +296,8 @@ string AsmPrinter::formatSourceLocationComment( return _statement ? - "/// " + sourceLocation : - "/** " + sourceLocation + " */ "; + "/// " + joinHumanReadable(vector{sourceLocation, solidityCodeSnippet}, " ") : + "/** " + joinHumanReadable(vector{sourceLocation, solidityCodeSnippet}, " ") + " */ "; } string AsmPrinter::formatSourceLocationComment(shared_ptr const& _debugData, bool _statement) @@ -297,6 +314,7 @@ string AsmPrinter::formatSourceLocationComment(shared_ptr const return formatSourceLocationComment( _debugData->location, m_nameToSourceIndex, - _statement + _statement, + m_soliditySourceProvider ) + (_statement ? "\n" : ""); } diff --git a/libyul/AsmPrinter.h b/libyul/AsmPrinter.h index 1beb964aa..de9e8fe90 100644 --- a/libyul/AsmPrinter.h +++ b/libyul/AsmPrinter.h @@ -28,6 +28,7 @@ #include +#include #include #include @@ -46,9 +47,11 @@ class AsmPrinter public: explicit AsmPrinter( Dialect const* _dialect = nullptr, - std::optional>> _sourceIndexToName = {} + std::optional>> _sourceIndexToName = {}, + langutil::CharStreamProvider const* _soliditySourceProvider = nullptr ): - m_dialect(_dialect) + m_dialect(_dialect), + m_soliditySourceProvider(_soliditySourceProvider) { if (_sourceIndexToName) for (auto&& [index, name]: *_sourceIndexToName) @@ -58,8 +61,9 @@ public: explicit AsmPrinter( Dialect const& _dialect, - std::optional>> _sourceIndexToName = {} - ): AsmPrinter(&_dialect, _sourceIndexToName) {} + std::optional>> _sourceIndexToName = {}, + langutil::CharStreamProvider const* _soliditySourceProvider = nullptr + ): AsmPrinter(&_dialect, _sourceIndexToName, _soliditySourceProvider) {} std::string operator()(Literal const& _literal); std::string operator()(Identifier const& _identifier); @@ -79,7 +83,8 @@ public: static std::string formatSourceLocationComment( langutil::SourceLocation const& _location, std::map const& _nameToSourceIndex, - bool _statement + bool _statement, + langutil::CharStreamProvider const* m_soliditySourceProvider = nullptr ); private: @@ -96,6 +101,7 @@ private: Dialect const* const m_dialect = nullptr; std::map m_nameToSourceIndex; langutil::SourceLocation m_lastLocation = {}; + langutil::CharStreamProvider const* m_soliditySourceProvider = nullptr; }; } diff --git a/libyul/AssemblyStack.cpp b/libyul/AssemblyStack.cpp index 8a00608cf..1ed55a2d6 100644 --- a/libyul/AssemblyStack.cpp +++ b/libyul/AssemblyStack.cpp @@ -314,11 +314,11 @@ AssemblyStack::assembleEVMWithDeployed(optional _deployName) const return {make_shared(assembly), {}}; } -string AssemblyStack::print() const +string AssemblyStack::print(CharStreamProvider const* _soliditySourceProvider) const { yulAssert(m_parserResult, ""); yulAssert(m_parserResult->code, ""); - return m_parserResult->toString(&languageToDialect(m_language, m_evmVersion)) + "\n"; + return m_parserResult->toString(&languageToDialect(m_language, m_evmVersion), _soliditySourceProvider) + "\n"; } shared_ptr AssemblyStack::parserResult() const diff --git a/libyul/AssemblyStack.h b/libyul/AssemblyStack.h index 3fcd15998..91ca78af7 100644 --- a/libyul/AssemblyStack.h +++ b/libyul/AssemblyStack.h @@ -116,7 +116,7 @@ public: langutil::ErrorList const& errors() const { return m_errors; } /// Pretty-print the input after having parsed it. - std::string print() const; + std::string print(langutil::CharStreamProvider const* _soliditySourceProvider = nullptr) const; /// Return the parsed and analyzed object. std::shared_ptr parserResult() const; diff --git a/libyul/Object.cpp b/libyul/Object.cpp index a87281cac..eee016aa4 100644 --- a/libyul/Object.cpp +++ b/libyul/Object.cpp @@ -35,8 +35,9 @@ using namespace std; using namespace solidity; -using namespace solidity::yul; +using namespace solidity::langutil; using namespace solidity::util; +using namespace solidity::yul; namespace { @@ -50,12 +51,15 @@ string indent(std::string const& _input) } -string Data::toString(Dialect const*) const +string Data::toString(Dialect const*, CharStreamProvider const*) const { return "data \"" + name.str() + "\" hex\"" + util::toHex(data) + "\""; } -string Object::toString(Dialect const* _dialect) const +string Object::toString( + Dialect const* _dialect, + CharStreamProvider const* _soliditySourceProvider +) const { yulAssert(code, "No code"); yulAssert(debugData, "No debug data"); @@ -70,10 +74,10 @@ string Object::toString(Dialect const* _dialect) const })) + "\n"; - string inner = "code " + AsmPrinter{_dialect, debugData->sourceNames}(*code); + string inner = "code " + AsmPrinter{_dialect, debugData->sourceNames, _soliditySourceProvider}(*code); for (auto const& obj: subObjects) - inner += "\n" + obj->toString(_dialect); + inner += "\n" + obj->toString(_dialect, _soliditySourceProvider); return useSrcComment + "object \"" + name.str() + "\" {\n" + indent(inner) + "\n}"; } diff --git a/libyul/Object.h b/libyul/Object.h index 39fb092d3..480b7e553 100644 --- a/libyul/Object.h +++ b/libyul/Object.h @@ -24,6 +24,8 @@ #include #include +#include + #include #include @@ -49,8 +51,10 @@ struct ObjectNode /// Name of the object. /// Can be empty since .yul files can also just contain code, without explicitly placing it in an object. YulString name; - - virtual std::string toString(Dialect const* _dialect) const = 0; + virtual std::string toString( + Dialect const* _dialect, + langutil::CharStreamProvider const* _soliditySourceProvider + ) const = 0; }; /** @@ -62,7 +66,10 @@ struct Data: public ObjectNode bytes data; - std::string toString(Dialect const* _dialect) const override; + std::string toString( + Dialect const* _dialect, + langutil::CharStreamProvider const* _soliditySourceProvider + ) const override; }; @@ -79,7 +86,10 @@ struct Object: public ObjectNode { public: /// @returns a (parseable) string representation. - std::string toString(Dialect const* _dialect) const; + std::string toString( + Dialect const* _dialect, + langutil::CharStreamProvider const* _soliditySourceProvider = nullptr + ) const; /// @returns the set of names of data objects accessible from within the code of /// this object, including the name of object itself diff --git a/test/cmdlineTests/constant_optimizer_yul/output b/test/cmdlineTests/constant_optimizer_yul/output index 15304fb3b..328ac2544 100644 --- a/test/cmdlineTests/constant_optimizer_yul/output +++ b/test/cmdlineTests/constant_optimizer_yul/output @@ -10,12 +10,12 @@ Optimized IR: object "C_12" { code { { - /// @src 0:61:418 + /// @src 0:61:418 "contract C {..." mstore(64, 128) if callvalue() { revert(0, 0) } - /// @src 0:103:238 + /// @src 0:103:238 "assembly {..." sstore(0, shl(180, 1)) - /// @src 0:61:418 + /// @src 0:61:418 "contract C {..." let _1 := datasize("C_12_deployed") codecopy(128, dataoffset("C_12_deployed"), _1) return(128, _1) @@ -25,12 +25,12 @@ object "C_12" { object "C_12_deployed" { code { { - /// @src 0:61:418 + /// @src 0:61:418 "contract C {..." mstore(64, 128) if callvalue() { revert(0, 0) } - /// @src 0:279:410 + /// @src 0:279:410 "assembly {..." sstore(0, 0x1000000000000000000000000000000000000000000000) - /// @src 0:61:418 + /// @src 0:61:418 "contract C {..." stop() } } diff --git a/test/cmdlineTests/exp_base_literal/output b/test/cmdlineTests/exp_base_literal/output index f4f8042c2..7a7f0647a 100644 --- a/test/cmdlineTests/exp_base_literal/output +++ b/test/cmdlineTests/exp_base_literal/output @@ -10,7 +10,7 @@ IR: /// @use-src 0:"exp_base_literal/input.sol" object "C_81" { code { - /// @src 0:82:370 + /// @src 0:82:370 "contract C {..." mstore(64, 128) if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() } @@ -29,19 +29,19 @@ object "C_81" { revert(0, 0) } - /// @src 0:82:370 + /// @src 0:82:370 "contract C {..." function constructor_C_81() { - /// @src 0:82:370 + /// @src 0:82:370 "contract C {..." } - /// @src 0:82:370 + /// @src 0:82:370 "contract C {..." } /// @use-src 0:"exp_base_literal/input.sol" object "C_81_deployed" { code { - /// @src 0:82:370 + /// @src 0:82:370 "contract C {..." mstore(64, 128) if iszero(lt(calldatasize(), 4)) @@ -288,123 +288,123 @@ object "C_81" { power := exp(1, exponent) } - /// @src 0:96:368 + /// @src 0:96:368 "function f(uint a, uint b, uint c, uint d) public pure returns (uint, int, uint, uint) {..." function fun_f_80(var_a_4, var_b_6, var_c_8, var_d_10) -> var__13, var__15, var__17, var__19 { - /// @src 0:160:164 + /// @src 0:160:164 "uint" let zero_t_uint256_1 := zero_value_for_split_t_uint256() var__13 := zero_t_uint256_1 - /// @src 0:166:169 + /// @src 0:166:169 "int" let zero_t_int256_2 := zero_value_for_split_t_int256() var__15 := zero_t_int256_2 - /// @src 0:171:175 + /// @src 0:171:175 "uint" let zero_t_uint256_3 := zero_value_for_split_t_uint256() var__17 := zero_t_uint256_3 - /// @src 0:177:181 + /// @src 0:177:181 "uint" let zero_t_uint256_4 := zero_value_for_split_t_uint256() var__19 := zero_t_uint256_4 - /// @src 0:196:197 + /// @src 0:196:197 "2" let expr_23 := 0x02 - /// @src 0:199:200 + /// @src 0:199:200 "a" let _5 := var_a_4 let expr_24 := _5 - /// @src 0:196:200 + /// @src 0:196:200 "2**a" let _6 := convert_t_rational_2_by_1_to_t_uint256(expr_23) let expr_25 := checked_exp_t_rational_2_by_1_t_uint256(expr_24) - /// @src 0:187:200 + /// @src 0:187:200 "uint w = 2**a" let var_w_22 := expr_25 - /// @src 0:213:215 + /// @src 0:213:215 "-2" let expr_30 := 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe - /// @src 0:212:216 + /// @src 0:212:216 "(-2)" let expr_31 := expr_30 - /// @src 0:218:219 + /// @src 0:218:219 "b" let _7 := var_b_6 let expr_32 := _7 - /// @src 0:212:219 + /// @src 0:212:219 "(-2)**b" let _8 := convert_t_rational_minus_2_by_1_to_t_int256(expr_31) let expr_33 := checked_exp_t_rational_minus_2_by_1_t_uint256(expr_32) - /// @src 0:204:219 + /// @src 0:204:219 "int x = (-2)**b" let var_x_28 := expr_33 - /// @src 0:232:234 + /// @src 0:232:234 "10" let expr_37 := 0x0a - /// @src 0:236:237 + /// @src 0:236:237 "c" let _9 := var_c_8 let expr_38 := _9 - /// @src 0:232:237 + /// @src 0:232:237 "10**c" let _10 := convert_t_rational_10_by_1_to_t_uint256(expr_37) let expr_39 := checked_exp_t_rational_10_by_1_t_uint256(expr_38) - /// @src 0:223:237 + /// @src 0:223:237 "uint y = 10**c" let var_y_36 := expr_39 - /// @src 0:251:260 + /// @src 0:251:260 "2**256 -1" let expr_47 := 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff - /// @src 0:250:262 + /// @src 0:250:262 "(2**256 -1 )" let expr_48 := expr_47 - /// @src 0:264:265 + /// @src 0:264:265 "d" let _11 := var_d_10 let expr_49 := _11 - /// @src 0:250:265 + /// @src 0:250:265 "(2**256 -1 )**d" let _12 := convert_t_rational_115792089237316195423570985008687907853269984665640564039457584007913129639935_by_1_to_t_uint256(expr_48) let expr_50 := checked_exp_t_rational_115792089237316195423570985008687907853269984665640564039457584007913129639935_by_1_t_uint256(expr_49) - /// @src 0:241:265 + /// @src 0:241:265 "uint z = (2**256 -1 )**d" let var_z_42 := expr_50 - /// @src 0:308:309 + /// @src 0:308:309 "0" let expr_53 := 0x00 - /// @src 0:307:310 + /// @src 0:307:310 "(0)" let expr_54 := expr_53 - /// @src 0:312:313 + /// @src 0:312:313 "a" let _13 := var_a_4 let expr_55 := _13 - /// @src 0:307:313 + /// @src 0:307:313 "(0)**a" let _14 := convert_t_rational_0_by_1_to_t_uint256(expr_54) let expr_56 := checked_exp_t_rational_0_by_1_t_uint256(expr_55) - /// @src 0:303:313 + /// @src 0:303:313 "w = (0)**a" var_w_22 := expr_56 let expr_57 := expr_56 - /// @src 0:322:324 + /// @src 0:322:324 "-1" let expr_61 := 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff - /// @src 0:321:325 + /// @src 0:321:325 "(-1)" let expr_62 := expr_61 - /// @src 0:327:328 + /// @src 0:327:328 "b" let _15 := var_b_6 let expr_63 := _15 - /// @src 0:321:328 + /// @src 0:321:328 "(-1)**b" let _16 := convert_t_rational_minus_1_by_1_to_t_int256(expr_62) let expr_64 := checked_exp_t_rational_minus_1_by_1_t_uint256(expr_63) - /// @src 0:317:328 + /// @src 0:317:328 "x = (-1)**b" var_x_28 := expr_64 let expr_65 := expr_64 - /// @src 0:336:337 + /// @src 0:336:337 "1" let expr_68 := 0x01 - /// @src 0:339:340 + /// @src 0:339:340 "c" let _17 := var_c_8 let expr_69 := _17 - /// @src 0:336:340 + /// @src 0:336:340 "1**c" let _18 := convert_t_rational_1_by_1_to_t_uint256(expr_68) let expr_70 := checked_exp_t_rational_1_by_1_t_uint256(expr_69) - /// @src 0:332:340 + /// @src 0:332:340 "y = 1**c" var_y_36 := expr_70 let expr_71 := expr_70 - /// @src 0:353:354 + /// @src 0:353:354 "w" let _19 := var_w_22 let expr_73 := _19 - /// @src 0:352:364 + /// @src 0:352:364 "(w, x, y, z)" let expr_77_component_1 := expr_73 - /// @src 0:356:357 + /// @src 0:356:357 "x" let _20 := var_x_28 let expr_74 := _20 - /// @src 0:352:364 + /// @src 0:352:364 "(w, x, y, z)" let expr_77_component_2 := expr_74 - /// @src 0:359:360 + /// @src 0:359:360 "y" let _21 := var_y_36 let expr_75 := _21 - /// @src 0:352:364 + /// @src 0:352:364 "(w, x, y, z)" let expr_77_component_3 := expr_75 - /// @src 0:362:363 + /// @src 0:362:363 "z" let _22 := var_z_42 let expr_76 := _22 - /// @src 0:352:364 + /// @src 0:352:364 "(w, x, y, z)" let expr_77_component_4 := expr_76 - /// @src 0:345:364 + /// @src 0:345:364 "return (w, x, y, z)" var__13 := expr_77_component_1 var__15 := expr_77_component_2 var__17 := expr_77_component_3 @@ -412,7 +412,7 @@ object "C_81" { leave } - /// @src 0:82:370 + /// @src 0:82:370 "contract C {..." } diff --git a/test/cmdlineTests/ir_compiler_inheritance_nosubobjects/output b/test/cmdlineTests/ir_compiler_inheritance_nosubobjects/output index 8f948ccb9..12c61e783 100644 --- a/test/cmdlineTests/ir_compiler_inheritance_nosubobjects/output +++ b/test/cmdlineTests/ir_compiler_inheritance_nosubobjects/output @@ -10,7 +10,7 @@ Optimized IR: object "C_7" { code { { - /// @src 0:82:117 + /// @src 0:82:117 "contract C {..." mstore(64, 128) if callvalue() { revert(0, 0) } let _1 := datasize("C_7_deployed") @@ -22,7 +22,7 @@ object "C_7" { object "C_7_deployed" { code { { - /// @src 0:82:117 + /// @src 0:82:117 "contract C {..." mstore(64, 128) revert(0, 0) } @@ -43,7 +43,7 @@ Optimized IR: object "D_10" { code { { - /// @src 0:118:137 + /// @src 0:118:137 "contract D is C {..." mstore(64, 128) if callvalue() { revert(0, 0) } let _1 := datasize("D_10_deployed") @@ -55,7 +55,7 @@ object "D_10" { object "D_10_deployed" { code { { - /// @src 0:118:137 + /// @src 0:118:137 "contract D is C {..." mstore(64, 128) revert(0, 0) } diff --git a/test/cmdlineTests/ir_compiler_subobjects/output b/test/cmdlineTests/ir_compiler_subobjects/output index 9da2e5e7f..8c23c8ad7 100644 --- a/test/cmdlineTests/ir_compiler_subobjects/output +++ b/test/cmdlineTests/ir_compiler_subobjects/output @@ -10,7 +10,7 @@ Optimized IR: object "C_3" { code { { - /// @src 0:82:95 + /// @src 0:82:95 "contract C {}" mstore(64, 128) if callvalue() { revert(0, 0) } let _1 := datasize("C_3_deployed") @@ -22,7 +22,7 @@ object "C_3" { object "C_3_deployed" { code { { - /// @src 0:82:95 + /// @src 0:82:95 "contract C {}" mstore(64, 128) revert(0, 0) } @@ -43,7 +43,7 @@ Optimized IR: object "D_16" { code { { - /// @src 0:96:165 + /// @src 0:96:165 "contract D {..." mstore(64, 128) if callvalue() { revert(0, 0) } let _1 := datasize("D_16_deployed") @@ -55,7 +55,7 @@ object "D_16" { object "D_16_deployed" { code { { - /// @src 0:96:165 + /// @src 0:96:165 "contract D {..." mstore(64, 128) if iszero(lt(calldatasize(), 4)) { @@ -64,22 +64,22 @@ object "D_16" { { if callvalue() { revert(_1, _1) } if slt(add(calldatasize(), not(3)), _1) { revert(_1, _1) } - /// @src 0:149:156 + /// @src 0:149:156 "new C()" let _2 := datasize("C_3") - let _3 := add(/** @src 0:96:165 */ 128, /** @src 0:149:156 */ _2) - if or(gt(_3, 0xffffffffffffffff), lt(_3, /** @src 0:96:165 */ 128)) - /// @src 0:149:156 + let _3 := add(/** @src 0:96:165 "contract D {..." */ 128, /** @src 0:149:156 "new C()" */ _2) + if or(gt(_3, 0xffffffffffffffff), lt(_3, /** @src 0:96:165 "contract D {..." */ 128)) + /// @src 0:149:156 "new C()" { - /// @src 0:96:165 + /// @src 0:96:165 "contract D {..." mstore(_1, shl(224, 0x4e487b71)) mstore(4, 0x41) revert(_1, 0x24) } - /// @src 0:149:156 - datacopy(/** @src 0:96:165 */ 128, /** @src 0:149:156 */ dataoffset("C_3"), _2) - if iszero(create(/** @src 0:96:165 */ _1, 128, /** @src 0:149:156 */ _2)) + /// @src 0:149:156 "new C()" + datacopy(/** @src 0:96:165 "contract D {..." */ 128, /** @src 0:149:156 "new C()" */ dataoffset("C_3"), _2) + if iszero(create(/** @src 0:96:165 "contract D {..." */ _1, 128, /** @src 0:149:156 "new C()" */ _2)) { - /// @src 0:96:165 + /// @src 0:96:165 "contract D {..." let pos := mload(64) returndatacopy(pos, _1, returndatasize()) revert(pos, returndatasize()) @@ -94,7 +94,7 @@ object "D_16" { object "C_3" { code { { - /// @src 0:82:95 + /// @src 0:82:95 "contract C {}" mstore(64, 128) if callvalue() { revert(0, 0) } let _1 := datasize("C_3_deployed") @@ -106,7 +106,7 @@ object "D_16" { object "C_3_deployed" { code { { - /// @src 0:82:95 + /// @src 0:82:95 "contract C {}" mstore(64, 128) revert(0, 0) } diff --git a/test/cmdlineTests/ir_with_assembly_no_memoryguard_creation/output b/test/cmdlineTests/ir_with_assembly_no_memoryguard_creation/output index dff1fb478..930899aea 100644 --- a/test/cmdlineTests/ir_with_assembly_no_memoryguard_creation/output +++ b/test/cmdlineTests/ir_with_assembly_no_memoryguard_creation/output @@ -10,7 +10,7 @@ Optimized IR: object "D_12" { code { { - /// @src 0:82:161 + /// @src 0:82:161 "contract D {..." mstore(64, 128) if callvalue() { revert(0, 0) } let _1 := datasize("D_12_deployed") @@ -22,7 +22,7 @@ object "D_12" { object "D_12_deployed" { code { { - /// @src 0:82:161 + /// @src 0:82:161 "contract D {..." mstore(64, 128) if iszero(lt(calldatasize(), 4)) { diff --git a/test/cmdlineTests/ir_with_assembly_no_memoryguard_runtime/output b/test/cmdlineTests/ir_with_assembly_no_memoryguard_runtime/output index 2fbed1d26..da6540fa7 100644 --- a/test/cmdlineTests/ir_with_assembly_no_memoryguard_runtime/output +++ b/test/cmdlineTests/ir_with_assembly_no_memoryguard_runtime/output @@ -10,7 +10,7 @@ Optimized IR: object "D_8" { code { { - /// @src 0:82:153 + /// @src 0:82:153 "contract D {..." mstore(64, 128) if callvalue() { revert(0, 0) } let _1 := datasize("D_8_deployed") @@ -22,7 +22,7 @@ object "D_8" { object "D_8_deployed" { code { { - /// @src 0:82:153 + /// @src 0:82:153 "contract D {..." mstore(64, 128) if iszero(lt(calldatasize(), 4)) { diff --git a/test/cmdlineTests/keccak_optimization_deploy_code/output b/test/cmdlineTests/keccak_optimization_deploy_code/output index 09ea3d776..4abb046f6 100644 --- a/test/cmdlineTests/keccak_optimization_deploy_code/output +++ b/test/cmdlineTests/keccak_optimization_deploy_code/output @@ -10,13 +10,13 @@ Optimized IR: object "C_12" { code { { - /// @src 0:62:463 + /// @src 0:62:463 "contract C {..." mstore(64, 128) if callvalue() { revert(0, 0) } - /// @src 0:103:275 + /// @src 0:103:275 "assembly {..." mstore(0, 100) sstore(0, keccak256(0, 32)) - /// @src 0:62:463 + /// @src 0:62:463 "contract C {..." let _1 := datasize("C_12_deployed") codecopy(128, dataoffset("C_12_deployed"), _1) return(128, _1) @@ -26,13 +26,13 @@ object "C_12" { object "C_12_deployed" { code { { - /// @src 0:62:463 + /// @src 0:62:463 "contract C {..." mstore(64, 128) if callvalue() { revert(0, 0) } - /// @src 0:317:454 + /// @src 0:317:454 "assembly {..." mstore(0, 100) sstore(0, 17385872270140913825666367956517731270094621555228275961425792378517567244498) - /// @src 0:62:463 + /// @src 0:62:463 "contract C {..." stop() } } diff --git a/test/cmdlineTests/keccak_optimization_low_runs/output b/test/cmdlineTests/keccak_optimization_low_runs/output index 692bd4384..25b678ee0 100644 --- a/test/cmdlineTests/keccak_optimization_low_runs/output +++ b/test/cmdlineTests/keccak_optimization_low_runs/output @@ -10,7 +10,7 @@ Optimized IR: object "C_7" { code { { - /// @src 0:62:285 + /// @src 0:62:285 "contract C {..." mstore(64, 128) if callvalue() { revert(0, 0) } let _1 := datasize("C_7_deployed") @@ -22,13 +22,13 @@ object "C_7" { object "C_7_deployed" { code { { - /// @src 0:62:285 + /// @src 0:62:285 "contract C {..." mstore(64, 128) if callvalue() { revert(0, 0) } - /// @src 0:109:277 + /// @src 0:109:277 "assembly {..." mstore(0, 100) sstore(0, keccak256(0, 32)) - /// @src 0:62:285 + /// @src 0:62:285 "contract C {..." stop() } } diff --git a/test/cmdlineTests/name_simplifier/output b/test/cmdlineTests/name_simplifier/output index fcd70e0b0..36d68bfd9 100644 --- a/test/cmdlineTests/name_simplifier/output +++ b/test/cmdlineTests/name_simplifier/output @@ -10,7 +10,7 @@ Optimized IR: object "C_59" { code { { - /// @src 0:346:625 + /// @src 0:346:625 "contract C {..." mstore(64, 128) if callvalue() { revert(0, 0) } let _1 := datasize("C_59_deployed") @@ -22,7 +22,7 @@ object "C_59" { object "C_59_deployed" { code { { - /// @src 0:346:625 + /// @src 0:346:625 "contract C {..." mstore(64, 128) if iszero(lt(calldatasize(), 4)) { @@ -106,18 +106,18 @@ object "C_59" { mstore(4, 0x32) revert(0, 0x24) } - /// @src 0:381:623 + /// @src 0:381:623 "function sumArray(S[] memory _s) public returns (uint, string memory) {..." function fun_sumArray(var_s_mpos) -> var, var_mpos { - /// @src 0:346:625 + /// @src 0:346:625 "contract C {..." if iszero(mload(var_s_mpos)) { panic_error_0x32() } - sstore(/** @src 0:472:473 */ 0x00, /** @src 0:346:625 */ mload(/** @src 0:469:474 */ mload(/** @src 0:346:625 */ add(var_s_mpos, 32)))) + sstore(/** @src 0:472:473 "0" */ 0x00, /** @src 0:346:625 "contract C {..." */ mload(/** @src 0:469:474 "_s[0]" */ mload(/** @src 0:346:625 "contract C {..." */ add(var_s_mpos, 32)))) if iszero(lt(1, mload(var_s_mpos))) { panic_error_0x32() } - let _1 := mload(/** @src 0:489:494 */ mload(/** @src 0:346:625 */ add(var_s_mpos, 64))) + let _1 := mload(/** @src 0:489:494 "_s[1]" */ mload(/** @src 0:346:625 "contract C {..." */ add(var_s_mpos, 64))) sstore(0x02, _1) - /// @src 0:500:619 + /// @src 0:500:619 "return (t.y[0], \"longstringlongstringlongstringlongstringlongstringlongstringlongstringlongstringlongstringlongstring\")" var := _1 - /// @src 0:346:625 + /// @src 0:346:625 "contract C {..." let memPtr := mload(64) let newFreePtr := add(memPtr, 160) if or(gt(newFreePtr, 0xffffffffffffffff), lt(newFreePtr, memPtr)) { panic_error_0x41() } @@ -127,7 +127,7 @@ object "C_59" { mstore(add(memPtr, 64), "ngstringlongstringlongstringlong") mstore(add(memPtr, 96), "stringlongstringlongstringlongst") mstore(add(memPtr, 128), "ring") - /// @src 0:500:619 + /// @src 0:500:619 "return (t.y[0], \"longstringlongstringlongstringlongstringlongstringlongstringlongstringlongstringlongstringlongstring\")" var_mpos := memPtr } } diff --git a/test/cmdlineTests/optimizer_array_sload/output b/test/cmdlineTests/optimizer_array_sload/output index e7bf19abf..448b0badc 100644 --- a/test/cmdlineTests/optimizer_array_sload/output +++ b/test/cmdlineTests/optimizer_array_sload/output @@ -10,7 +10,7 @@ Optimized IR: object "Arraysum_34" { code { { - /// @src 0:80:429 + /// @src 0:80:429 "contract Arraysum {..." mstore(64, 128) if callvalue() { revert(0, 0) } let _1 := datasize("Arraysum_34_deployed") @@ -22,7 +22,7 @@ object "Arraysum_34" { object "Arraysum_34_deployed" { code { { - /// @src 0:80:429 + /// @src 0:80:429 "contract Arraysum {..." mstore(64, 128) if iszero(lt(calldatasize(), 4)) { @@ -32,27 +32,27 @@ object "Arraysum_34" { if callvalue() { revert(_1, _1) } if slt(add(calldatasize(), not(3)), _1) { revert(_1, _1) } let var_sum := _1 - /// @src 0:368:378 - let var_i := /** @src 0:80:429 */ _1 + /// @src 0:368:378 "uint i = 0" + let var_i := /** @src 0:80:429 "contract Arraysum {..." */ _1 let _2 := sload(_1) - /// @src 0:364:423 + /// @src 0:364:423 "for(uint i = 0; i < values.length; i++)..." for { } - /** @src 0:380:397 */ lt(var_i, _2) - /// @src 0:368:378 + /** @src 0:380:397 "i < values.length" */ lt(var_i, _2) + /// @src 0:368:378 "uint i = 0" { - /// @src 0:80:429 + /// @src 0:80:429 "contract Arraysum {..." if eq(var_i, not(0)) { panic_error_0x11() } - /// @src 0:399:402 - var_i := /** @src 0:80:429 */ add(var_i, 1) + /// @src 0:399:402 "i++" + var_i := /** @src 0:80:429 "contract Arraysum {..." */ add(var_i, 1) } - /// @src 0:399:402 + /// @src 0:399:402 "i++" { - /// @src 0:80:429 + /// @src 0:80:429 "contract Arraysum {..." mstore(_1, _1) let _3 := sload(add(18569430475105882587588266137607568536673111973893317399460219858819262702947, var_i)) if gt(var_sum, not(_3)) { panic_error_0x11() } - /// @src 0:407:423 - var_sum := /** @src 0:80:429 */ add(var_sum, _3) + /// @src 0:407:423 "sum += values[i]" + var_sum := /** @src 0:80:429 "contract Arraysum {..." */ add(var_sum, _3) } let memPos := mload(64) return(memPos, sub(abi_encode_uint256(memPos, var_sum), memPos)) diff --git a/test/cmdlineTests/revert_strings/output b/test/cmdlineTests/revert_strings/output index fde886ed5..989d7594c 100644 --- a/test/cmdlineTests/revert_strings/output +++ b/test/cmdlineTests/revert_strings/output @@ -10,7 +10,7 @@ IR: /// @use-src 0:"revert_strings/input.sol" object "C_15" { code { - /// @src 0:59:147 + /// @src 0:59:147 "contract C {..." mstore(64, 128) if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() } @@ -44,19 +44,19 @@ object "C_15" { } - /// @src 0:59:147 + /// @src 0:59:147 "contract C {..." function constructor_C_15() { - /// @src 0:59:147 + /// @src 0:59:147 "contract C {..." } - /// @src 0:59:147 + /// @src 0:59:147 "contract C {..." } /// @use-src 0:"revert_strings/input.sol" object "C_15_deployed" { code { - /// @src 0:59:147 + /// @src 0:59:147 "contract C {..." mstore(64, 128) if iszero(lt(calldatasize(), 4)) @@ -359,11 +359,11 @@ object "C_15" { } - /// @src 0:93:145 + /// @src 0:93:145 "function f(uint[][] memory, E e) public pure {..." function fun_f_14(var__7_mpos, var_e_10) { } - /// @src 0:59:147 + /// @src 0:59:147 "contract C {..." } diff --git a/test/cmdlineTests/standard_irOptimized_requested/output.json b/test/cmdlineTests/standard_irOptimized_requested/output.json index 2651856c0..696a03573 100644 --- a/test/cmdlineTests/standard_irOptimized_requested/output.json +++ b/test/cmdlineTests/standard_irOptimized_requested/output.json @@ -8,7 +8,7 @@ /// @use-src 0:\"A\" object \"C_7\" { code { - /// @src 0:79:121 + /// @src 0:79:121 \"contract C { function f() public pure {} }\" mstore(64, 128) if callvalue() { @@ -28,7 +28,7 @@ object \"C_7\" { /// @use-src 0:\"A\" object \"C_7_deployed\" { code { - /// @src 0:79:121 + /// @src 0:79:121 \"contract C { function f() public pure {} }\" mstore(64, 128) if iszero(lt(calldatasize(), 4)) { @@ -68,7 +68,7 @@ object \"C_7\" { { tail := add(headStart, 0) } function revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() { revert(0, 0) } - /// @src 0:92:119 + /// @src 0:92:119 \"function f() public pure {}\" function fun_f_6() { } } diff --git a/test/cmdlineTests/standard_ir_requested/output.json b/test/cmdlineTests/standard_ir_requested/output.json index bc61d38bd..a056672b9 100644 --- a/test/cmdlineTests/standard_ir_requested/output.json +++ b/test/cmdlineTests/standard_ir_requested/output.json @@ -9,7 +9,7 @@ /// @use-src 0:\"A\" object \"C_7\" { code { - /// @src 0:79:121 + /// @src 0:79:121 \"contract C { function f() public pure {} }\" mstore(64, 128) if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() } @@ -28,19 +28,19 @@ object \"C_7\" { revert(0, 0) } - /// @src 0:79:121 + /// @src 0:79:121 \"contract C { function f() public pure {} }\" function constructor_C_7() { - /// @src 0:79:121 + /// @src 0:79:121 \"contract C { function f() public pure {} }\" } - /// @src 0:79:121 + /// @src 0:79:121 \"contract C { function f() public pure {} }\" } /// @use-src 0:\"A\" object \"C_7_deployed\" { code { - /// @src 0:79:121 + /// @src 0:79:121 \"contract C { function f() public pure {} }\" mstore(64, 128) if iszero(lt(calldatasize(), 4)) @@ -98,11 +98,11 @@ object \"C_7\" { revert(0, 0) } - /// @src 0:92:119 + /// @src 0:92:119 \"function f() public pure {}\" function fun_f_6() { } - /// @src 0:79:121 + /// @src 0:79:121 \"contract C { function f() public pure {} }\" } diff --git a/test/cmdlineTests/standard_viair_requested/output.json b/test/cmdlineTests/standard_viair_requested/output.json index 3ba066ab4..31ab3de5e 100644 --- a/test/cmdlineTests/standard_viair_requested/output.json +++ b/test/cmdlineTests/standard_viair_requested/output.json @@ -9,7 +9,7 @@ /// @use-src 0:\"A\" object \"C_3\" { code { - /// @src 0:79:92 + /// @src 0:79:92 \"contract C {}\" mstore(64, 128) if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() } @@ -28,19 +28,19 @@ object \"C_3\" { revert(0, 0) } - /// @src 0:79:92 + /// @src 0:79:92 \"contract C {}\" function constructor_C_3() { - /// @src 0:79:92 + /// @src 0:79:92 \"contract C {}\" } - /// @src 0:79:92 + /// @src 0:79:92 \"contract C {}\" } /// @use-src 0:\"A\" object \"C_3_deployed\" { code { - /// @src 0:79:92 + /// @src 0:79:92 \"contract C {}\" mstore(64, 128) if iszero(lt(calldatasize(), 4)) @@ -86,7 +86,7 @@ object \"C_3\" { /// @use-src 0:\"A\" object \"D_16\" { code { - /// @src 0:93:146 + /// @src 0:93:146 \"contract D { function f() public { C c = new C(); } }\" mstore(64, 128) if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() } @@ -105,19 +105,19 @@ object \"D_16\" { revert(0, 0) } - /// @src 0:93:146 + /// @src 0:93:146 \"contract D { function f() public { C c = new C(); } }\" function constructor_D_16() { - /// @src 0:93:146 + /// @src 0:93:146 \"contract D { function f() public { C c = new C(); } }\" } - /// @src 0:93:146 + /// @src 0:93:146 \"contract D { function f() public { C c = new C(); } }\" } /// @use-src 0:\"A\" object \"D_16_deployed\" { code { - /// @src 0:93:146 + /// @src 0:93:146 \"contract D { function f() public { C c = new C(); } }\" mstore(64, 128) if iszero(lt(calldatasize(), 4)) @@ -187,10 +187,10 @@ object \"D_16\" { revert(pos, returndatasize()) } - /// @src 0:106:144 + /// @src 0:106:144 \"function f() public { C c = new C(); }\" function fun_f_15() { - /// @src 0:134:141 + /// @src 0:134:141 \"new C()\" let _1 := allocate_unbounded() let _2 := add(_1, datasize(\"C_3\")) if or(gt(_2, 0xffffffffffffffff), lt(_2, _1)) { panic_error_0x41() } @@ -201,11 +201,11 @@ object \"D_16\" { if iszero(expr_12_address) { revert_forward_1() } - /// @src 0:128:141 + /// @src 0:128:141 \"C c = new C()\" let var_c_8_address := expr_12_address } - /// @src 0:93:146 + /// @src 0:93:146 \"contract D { function f() public { C c = new C(); } }\" } /*=====================================================* @@ -218,7 +218,7 @@ object \"D_16\" { /// @use-src 0:\"A\" object \"C_3\" { code { - /// @src 0:79:92 + /// @src 0:79:92 \"contract C {}\" mstore(64, 128) if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() } @@ -237,19 +237,19 @@ object \"D_16\" { revert(0, 0) } - /// @src 0:79:92 + /// @src 0:79:92 \"contract C {}\" function constructor_C_3() { - /// @src 0:79:92 + /// @src 0:79:92 \"contract C {}\" } - /// @src 0:79:92 + /// @src 0:79:92 \"contract C {}\" } /// @use-src 0:\"A\" object \"C_3_deployed\" { code { - /// @src 0:79:92 + /// @src 0:79:92 \"contract C {}\" mstore(64, 128) if iszero(lt(calldatasize(), 4)) diff --git a/test/cmdlineTests/viair_abicoder_v1/output b/test/cmdlineTests/viair_abicoder_v1/output index c3715f007..3a0d4744b 100644 --- a/test/cmdlineTests/viair_abicoder_v1/output +++ b/test/cmdlineTests/viair_abicoder_v1/output @@ -10,7 +10,7 @@ IR: /// @use-src 0:"viair_abicoder_v1/input.sol" object "test_11" { code { - /// @src 0:79:169 + /// @src 0:79:169 "contract test {..." mstore(64, 128) if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() } @@ -29,19 +29,19 @@ object "test_11" { revert(0, 0) } - /// @src 0:79:169 + /// @src 0:79:169 "contract test {..." function constructor_test_11() { - /// @src 0:79:169 + /// @src 0:79:169 "contract test {..." } - /// @src 0:79:169 + /// @src 0:79:169 "contract test {..." } /// @use-src 0:"viair_abicoder_v1/input.sol" object "test_11_deployed" { code { - /// @src 0:79:169 + /// @src 0:79:169 "contract test {..." mstore(64, 128) if iszero(lt(calldatasize(), 4)) @@ -113,20 +113,20 @@ object "test_11" { ret := 0 } - /// @src 0:99:167 + /// @src 0:99:167 "function f() public pure returns (bool) {..." function fun_f_10() -> var__5 { - /// @src 0:133:137 + /// @src 0:133:137 "bool" let zero_t_bool_1 := zero_value_for_split_t_bool() var__5 := zero_t_bool_1 - /// @src 0:156:160 + /// @src 0:156:160 "true" let expr_7 := 0x01 - /// @src 0:149:160 + /// @src 0:149:160 "return true" var__5 := expr_7 leave } - /// @src 0:79:169 + /// @src 0:79:169 "contract test {..." } diff --git a/test/cmdlineTests/viair_subobjects/output b/test/cmdlineTests/viair_subobjects/output index 03e952c7e..eef7d27e8 100644 --- a/test/cmdlineTests/viair_subobjects/output +++ b/test/cmdlineTests/viair_subobjects/output @@ -16,7 +16,7 @@ Optimized IR: object "C_3" { code { { - /// @src 0:82:95 + /// @src 0:82:95 "contract C {}" mstore(64, 128) if callvalue() { revert(0, 0) } let _1 := datasize("C_3_deployed") @@ -28,7 +28,7 @@ object "C_3" { object "C_3_deployed" { code { { - /// @src 0:82:95 + /// @src 0:82:95 "contract C {}" mstore(64, 128) revert(0, 0) } @@ -55,7 +55,7 @@ Optimized IR: object "D_16" { code { { - /// @src 0:96:165 + /// @src 0:96:165 "contract D {..." mstore(64, 128) if callvalue() { revert(0, 0) } let _1 := datasize("D_16_deployed") @@ -67,7 +67,7 @@ object "D_16" { object "D_16_deployed" { code { { - /// @src 0:96:165 + /// @src 0:96:165 "contract D {..." mstore(64, 128) if iszero(lt(calldatasize(), 4)) { @@ -76,22 +76,22 @@ object "D_16" { { if callvalue() { revert(_1, _1) } if slt(add(calldatasize(), not(3)), _1) { revert(_1, _1) } - /// @src 0:149:156 + /// @src 0:149:156 "new C()" let _2 := datasize("C_3") - let _3 := add(/** @src 0:96:165 */ 128, /** @src 0:149:156 */ _2) - if or(gt(_3, 0xffffffffffffffff), lt(_3, /** @src 0:96:165 */ 128)) - /// @src 0:149:156 + let _3 := add(/** @src 0:96:165 "contract D {..." */ 128, /** @src 0:149:156 "new C()" */ _2) + if or(gt(_3, 0xffffffffffffffff), lt(_3, /** @src 0:96:165 "contract D {..." */ 128)) + /// @src 0:149:156 "new C()" { - /// @src 0:96:165 + /// @src 0:96:165 "contract D {..." mstore(_1, shl(224, 0x4e487b71)) mstore(4, 0x41) revert(_1, 0x24) } - /// @src 0:149:156 - datacopy(/** @src 0:96:165 */ 128, /** @src 0:149:156 */ dataoffset("C_3"), _2) - if iszero(create(/** @src 0:96:165 */ _1, 128, /** @src 0:149:156 */ _2)) + /// @src 0:149:156 "new C()" + datacopy(/** @src 0:96:165 "contract D {..." */ 128, /** @src 0:149:156 "new C()" */ dataoffset("C_3"), _2) + if iszero(create(/** @src 0:96:165 "contract D {..." */ _1, 128, /** @src 0:149:156 "new C()" */ _2)) { - /// @src 0:96:165 + /// @src 0:96:165 "contract D {..." let pos := mload(64) returndatacopy(pos, _1, returndatasize()) revert(pos, returndatasize()) @@ -106,7 +106,7 @@ object "D_16" { object "C_3" { code { { - /// @src 0:82:95 + /// @src 0:82:95 "contract C {}" mstore(64, 128) if callvalue() { revert(0, 0) } let _1 := datasize("C_3_deployed") @@ -118,7 +118,7 @@ object "D_16" { object "C_3_deployed" { code { { - /// @src 0:82:95 + /// @src 0:82:95 "contract C {}" mstore(64, 128) revert(0, 0) } diff --git a/test/cmdlineTests/yul_optimizer_steps/output b/test/cmdlineTests/yul_optimizer_steps/output index 3e4ba5809..478c844db 100644 --- a/test/cmdlineTests/yul_optimizer_steps/output +++ b/test/cmdlineTests/yul_optimizer_steps/output @@ -10,7 +10,7 @@ Optimized IR: object "C_7" { code { { - /// @src 0:80:112 + /// @src 0:80:112 "contract C..." mstore(64, 128) if callvalue() { @@ -29,7 +29,7 @@ object "C_7" { object "C_7_deployed" { code { { - /// @src 0:80:112 + /// @src 0:80:112 "contract C..." mstore(64, 128) if iszero(lt(calldatasize(), 4)) { diff --git a/test/cmdlineTests/yul_source_locations/output.json b/test/cmdlineTests/yul_source_locations/output.json index f6f431177..0839fb1f3 100644 --- a/test/cmdlineTests/yul_source_locations/output.json +++ b/test/cmdlineTests/yul_source_locations/output.json @@ -9,7 +9,7 @@ /// @use-src 0:\"C\" object \"C_54\" { code { - /// @src 0:79:428 + /// @src 0:79:428 \"contract C...\" mstore(64, 160) if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() } @@ -135,31 +135,31 @@ object \"C_54\" { sstore(slot, update_byte_slice_32_shift_0(sload(slot), prepare_store_t_int256(convertedValue_0))) } - /// @src 0:175:223 + /// @src 0:175:223 \"constructor(int _init)...\" function constructor_C_54(var__init_12) { - /// @src 0:175:223 + /// @src 0:175:223 \"constructor(int _init)...\" - /// @src 0:147:149 + /// @src 0:147:149 \"42\" let expr_7 := 0x2a let _3 := convert_t_rational_42_by_1_to_t_int256(expr_7) mstore(128, _3) - /// @src 0:214:219 + /// @src 0:214:219 \"_init\" let _4 := var__init_12 let expr_16 := _4 - /// @src 0:203:219 + /// @src 0:203:219 \"stateVar = _init\" update_storage_value_offset_0t_int256_to_t_int256(0x00, expr_16) let expr_17 := expr_16 } - /// @src 0:79:428 + /// @src 0:79:428 \"contract C...\" } /// @use-src 0:\"C\" object \"C_54_deployed\" { code { - /// @src 0:79:428 + /// @src 0:79:428 \"contract C...\" mstore(64, 128) if iszero(lt(calldatasize(), 4)) @@ -267,7 +267,7 @@ object \"C_54\" { } - /// @src 0:152:171 + /// @src 0:152:171 \"int public stateVar\" function getter_fun_stateVar_10() -> ret { let slot := 0 @@ -276,7 +276,7 @@ object \"C_54\" { ret := read_from_storage_split_dynamic_t_int256(slot, offset) } - /// @src 0:79:428 + /// @src 0:79:428 \"contract C...\" function revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() { revert(0, 0) @@ -298,9 +298,9 @@ object \"C_54\" { converted := cleanup_t_int256(identity(cleanup_t_rational_41_by_1(value))) } - /// @src 0:93:119 + /// @src 0:93:119 \"int constant constVar = 41\" function constant_constVar_5() -> ret { - /// @src 0:117:119 + /// @src 0:117:119 \"41\" let expr_4 := 0x29 let _2 := convert_t_rational_41_by_1_to_t_int256(expr_4) @@ -325,26 +325,26 @@ object \"C_54\" { sum := add(x, y) } - /// @src 0:226:302 + /// @src 0:226:302 \"function f() external pure returns (int)...\" function fun_f_30() -> var__23 { - /// @src 0:262:265 + /// @src 0:262:265 \"int\" let zero_t_int256_1 := zero_value_for_split_t_int256() var__23 := zero_t_int256_1 - /// @src 0:279:287 + /// @src 0:279:287 \"constVar\" let expr_25 := constant_constVar_5() - /// @src 0:290:298 + /// @src 0:290:298 \"immutVar\" let _3 := loadimmutable(\"8\") let expr_26 := _3 - /// @src 0:279:298 + /// @src 0:279:298 \"constVar + immutVar\" let expr_27 := checked_add_t_int256(expr_25, expr_26) - /// @src 0:272:298 + /// @src 0:272:298 \"return constVar + immutVar\" var__23 := expr_27 leave } - /// @src 0:79:428 + /// @src 0:79:428 \"contract C...\" function shift_right_0_unsigned(value) -> newValue { newValue := @@ -395,20 +395,20 @@ object \"C_54\" { sstore(slot, update_byte_slice_32_shift_0(sload(slot), prepare_store_t_int256(convertedValue_0))) } - /// @src 0:304:341 + /// @src 0:304:341 \"modifier m()...\" function modifier_m_40(var__42) -> _5 { _5 := var__42 - /// @src 0:322:332 + /// @src 0:322:332 \"stateVar++\" let _7 := read_from_storage_split_offset_0_t_int256(0x00) let _6 := increment_t_int256(_7) update_storage_value_offset_0t_int256_to_t_int256(0x00, _6) let expr_33 := _7 - /// @src 0:336:337 + /// @src 0:336:337 \"_\" _5 := fun_f2_53_inner(var__42) } - /// @src 0:79:428 + /// @src 0:79:428 \"contract C...\" function cleanup_t_uint160(value) -> cleaned { cleaned := and(value, 0xffffffffffffffffffffffffffffffffffffffff) @@ -490,19 +490,19 @@ object \"C_54\" { revert(pos, returndatasize()) } - /// @src 0:343:426 + /// @src 0:343:426 \"function f2() m public returns (int)...\" function fun_f2_53_inner(_8) -> var__42 { var__42 := _8 - /// @src 0:392:400 + /// @src 0:392:400 \"stateVar\" let _9 := read_from_storage_split_offset_0_t_int256(0x00) let expr_44 := _9 - /// @src 0:403:407 + /// @src 0:403:407 \"this\" let expr_45_address := address() - /// @src 0:403:409 + /// @src 0:403:409 \"this.f\" let expr_46_address := convert_t_contract$_C_$54_to_t_address(expr_45_address) let expr_46_functionSelector := 0x26121ff0 - /// @src 0:403:411 + /// @src 0:403:411 \"this.f()\" if iszero(extcodesize(expr_46_address)) { revert_error_0cc013b6b3b6beabea4e3a74a6d380f0df81852ca99887912475e1f66b2a2c20() } // storage for arguments and returned data @@ -523,31 +523,31 @@ object \"C_54\" { // decode return parameters from external try-call into retVars expr_47 := abi_decode_tuple_t_int256_fromMemory(_10, add(_10, returndatasize())) } - /// @src 0:392:411 + /// @src 0:392:411 \"stateVar + this.f()\" let expr_48 := checked_add_t_int256(expr_44, expr_47) - /// @src 0:414:422 + /// @src 0:414:422 \"immutVar\" let _13 := loadimmutable(\"8\") let expr_49 := _13 - /// @src 0:392:422 + /// @src 0:392:422 \"stateVar + this.f() + immutVar\" let expr_50 := checked_add_t_int256(expr_48, expr_49) - /// @src 0:385:422 + /// @src 0:385:422 \"return stateVar + this.f() + immutVar\" var__42 := expr_50 leave } - /// @src 0:79:428 + /// @src 0:79:428 \"contract C...\" - /// @src 0:343:426 + /// @src 0:343:426 \"function f2() m public returns (int)...\" function fun_f2_53() -> var__42 { - /// @src 0:375:378 + /// @src 0:375:378 \"int\" let zero_t_int256_4 := zero_value_for_split_t_int256() var__42 := zero_t_int256_4 var__42 := modifier_m_40(var__42) } - /// @src 0:79:428 + /// @src 0:79:428 \"contract C...\" } @@ -567,7 +567,7 @@ object \"C_54\" { /// @use-src 0:\"C\", 1:\"D\" object \"D_72\" { code { - /// @src 1:91:166 + /// @src 1:91:166 \"contract D is C(3)...\" mstore(64, 160) if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() } @@ -731,26 +731,26 @@ object \"D_72\" { sstore(slot, update_byte_slice_32_shift_0(sload(slot), prepare_store_t_int256(convertedValue_0))) } - /// @src 1:113:164 + /// @src 1:113:164 \"constructor(int _init2)...\" function constructor_D_72(var__init2_63) { - /// @src 1:107:108 + /// @src 1:107:108 \"3\" let expr_60 := 0x03 let _3 := convert_t_rational_3_by_1_to_t_int256(expr_60) - /// @src 1:113:164 + /// @src 1:113:164 \"constructor(int _init2)...\" constructor_C_54(_3) - /// @src 1:154:160 + /// @src 1:154:160 \"_init2\" let _4 := var__init2_63 let expr_67 := _4 - /// @src 1:142:160 + /// @src 1:142:160 \"stateVar += _init2\" let _5 := read_from_storage_split_offset_0_t_int256(0x00) let expr_68 := checked_add_t_int256(_5, expr_67) update_storage_value_offset_0t_int256_to_t_int256(0x00, expr_68) } - /// @src 1:91:166 + /// @src 1:91:166 \"contract D is C(3)...\" function cleanup_t_rational_42_by_1(value) -> cleaned { cleaned := value @@ -760,31 +760,31 @@ object \"D_72\" { converted := cleanup_t_int256(identity(cleanup_t_rational_42_by_1(value))) } - /// @src 0:175:223 + /// @src 0:175:223 \"constructor(int _init)...\" function constructor_C_54(var__init_12) { - /// @src 0:175:223 + /// @src 0:175:223 \"constructor(int _init)...\" - /// @src 0:147:149 + /// @src 0:147:149 \"42\" let expr_7 := 0x2a let _6 := convert_t_rational_42_by_1_to_t_int256(expr_7) mstore(128, _6) - /// @src 0:214:219 + /// @src 0:214:219 \"_init\" let _7 := var__init_12 let expr_16 := _7 - /// @src 0:203:219 + /// @src 0:203:219 \"stateVar = _init\" update_storage_value_offset_0t_int256_to_t_int256(0x00, expr_16) let expr_17 := expr_16 } - /// @src 1:91:166 + /// @src 1:91:166 \"contract D is C(3)...\" } /// @use-src 0:\"C\", 1:\"D\" object \"D_72_deployed\" { code { - /// @src 1:91:166 + /// @src 1:91:166 \"contract D is C(3)...\" mstore(64, 128) if iszero(lt(calldatasize(), 4)) @@ -892,7 +892,7 @@ object \"D_72\" { } - /// @src 0:152:171 + /// @src 0:152:171 \"int public stateVar\" function getter_fun_stateVar_10() -> ret { let slot := 0 @@ -901,7 +901,7 @@ object \"D_72\" { ret := read_from_storage_split_dynamic_t_int256(slot, offset) } - /// @src 1:91:166 + /// @src 1:91:166 \"contract D is C(3)...\" function revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() { revert(0, 0) @@ -923,9 +923,9 @@ object \"D_72\" { converted := cleanup_t_int256(identity(cleanup_t_rational_41_by_1(value))) } - /// @src 0:93:119 + /// @src 0:93:119 \"int constant constVar = 41\" function constant_constVar_5() -> ret { - /// @src 0:117:119 + /// @src 0:117:119 \"41\" let expr_4 := 0x29 let _2 := convert_t_rational_41_by_1_to_t_int256(expr_4) @@ -950,26 +950,26 @@ object \"D_72\" { sum := add(x, y) } - /// @src 0:226:302 + /// @src 0:226:302 \"function f() external pure returns (int)...\" function fun_f_30() -> var__23 { - /// @src 0:262:265 + /// @src 0:262:265 \"int\" let zero_t_int256_1 := zero_value_for_split_t_int256() var__23 := zero_t_int256_1 - /// @src 0:279:287 + /// @src 0:279:287 \"constVar\" let expr_25 := constant_constVar_5() - /// @src 0:290:298 + /// @src 0:290:298 \"immutVar\" let _3 := loadimmutable(\"8\") let expr_26 := _3 - /// @src 0:279:298 + /// @src 0:279:298 \"constVar + immutVar\" let expr_27 := checked_add_t_int256(expr_25, expr_26) - /// @src 0:272:298 + /// @src 0:272:298 \"return constVar + immutVar\" var__23 := expr_27 leave } - /// @src 1:91:166 + /// @src 1:91:166 \"contract D is C(3)...\" function shift_right_0_unsigned(value) -> newValue { newValue := @@ -1020,20 +1020,20 @@ object \"D_72\" { sstore(slot, update_byte_slice_32_shift_0(sload(slot), prepare_store_t_int256(convertedValue_0))) } - /// @src 0:304:341 + /// @src 0:304:341 \"modifier m()...\" function modifier_m_40(var__42) -> _5 { _5 := var__42 - /// @src 0:322:332 + /// @src 0:322:332 \"stateVar++\" let _7 := read_from_storage_split_offset_0_t_int256(0x00) let _6 := increment_t_int256(_7) update_storage_value_offset_0t_int256_to_t_int256(0x00, _6) let expr_33 := _7 - /// @src 0:336:337 + /// @src 0:336:337 \"_\" _5 := fun_f2_53_inner(var__42) } - /// @src 1:91:166 + /// @src 1:91:166 \"contract D is C(3)...\" function cleanup_t_uint160(value) -> cleaned { cleaned := and(value, 0xffffffffffffffffffffffffffffffffffffffff) @@ -1115,19 +1115,19 @@ object \"D_72\" { revert(pos, returndatasize()) } - /// @src 0:343:426 + /// @src 0:343:426 \"function f2() m public returns (int)...\" function fun_f2_53_inner(_8) -> var__42 { var__42 := _8 - /// @src 0:392:400 + /// @src 0:392:400 \"stateVar\" let _9 := read_from_storage_split_offset_0_t_int256(0x00) let expr_44 := _9 - /// @src 0:403:407 + /// @src 0:403:407 \"this\" let expr_45_address := address() - /// @src 0:403:409 + /// @src 0:403:409 \"this.f\" let expr_46_address := convert_t_contract$_C_$54_to_t_address(expr_45_address) let expr_46_functionSelector := 0x26121ff0 - /// @src 0:403:411 + /// @src 0:403:411 \"this.f()\" if iszero(extcodesize(expr_46_address)) { revert_error_0cc013b6b3b6beabea4e3a74a6d380f0df81852ca99887912475e1f66b2a2c20() } // storage for arguments and returned data @@ -1148,31 +1148,31 @@ object \"D_72\" { // decode return parameters from external try-call into retVars expr_47 := abi_decode_tuple_t_int256_fromMemory(_10, add(_10, returndatasize())) } - /// @src 0:392:411 + /// @src 0:392:411 \"stateVar + this.f()\" let expr_48 := checked_add_t_int256(expr_44, expr_47) - /// @src 0:414:422 + /// @src 0:414:422 \"immutVar\" let _13 := loadimmutable(\"8\") let expr_49 := _13 - /// @src 0:392:422 + /// @src 0:392:422 \"stateVar + this.f() + immutVar\" let expr_50 := checked_add_t_int256(expr_48, expr_49) - /// @src 0:385:422 + /// @src 0:385:422 \"return stateVar + this.f() + immutVar\" var__42 := expr_50 leave } - /// @src 1:91:166 + /// @src 1:91:166 \"contract D is C(3)...\" - /// @src 0:343:426 + /// @src 0:343:426 \"function f2() m public returns (int)...\" function fun_f2_53() -> var__42 { - /// @src 0:375:378 + /// @src 0:375:378 \"int\" let zero_t_int256_4 := zero_value_for_split_t_int256() var__42 := zero_t_int256_4 var__42 := modifier_m_40(var__42) } - /// @src 1:91:166 + /// @src 1:91:166 \"contract D is C(3)...\" } diff --git a/test/cmdlineTests/yul_source_locations_code_snippet_escaping/args b/test/cmdlineTests/yul_source_locations_code_snippet_escaping/args new file mode 100644 index 000000000..7282a28fe --- /dev/null +++ b/test/cmdlineTests/yul_source_locations_code_snippet_escaping/args @@ -0,0 +1 @@ +--ir-optimized --ir --optimize diff --git a/test/cmdlineTests/yul_source_locations_code_snippet_escaping/input.sol b/test/cmdlineTests/yul_source_locations_code_snippet_escaping/input.sol new file mode 100644 index 000000000..598f3b280 --- /dev/null +++ b/test/cmdlineTests/yul_source_locations_code_snippet_escaping/input.sol @@ -0,0 +1,13 @@ +// SPDX-License-Identifier: GPL-3.0 +pragma solidity >=0.0.0; + +// Intentionally badly wrapped and commented in weird places to get source locations inside code +// snippets in generated Yul. Also contains stuff that could break the assembly if not escaped properly. + +contract C {} contract D /** @src 0:96:165 "contract D {..." */ { + function f() /* @use-src 0:"input.sol", 1:"#utility.yul" @ast-id 15 */ public returns (string memory) { C c = new /// @src 0:149:156 "new C()" + C(); c; + string memory s = "/*"; s; return "/** @src 0:96:165 \"contract D {...\" */" + ; + } +} diff --git a/test/cmdlineTests/yul_source_locations_code_snippet_escaping/output b/test/cmdlineTests/yul_source_locations_code_snippet_escaping/output new file mode 100644 index 000000000..6563ceb3e --- /dev/null +++ b/test/cmdlineTests/yul_source_locations_code_snippet_escaping/output @@ -0,0 +1,578 @@ +IR: +/*=====================================================* + * WARNING * + * Solidity to Yul compilation is still EXPERIMENTAL * + * It can result in LOSS OF FUNDS or worse * + * !USE AT YOUR OWN RISK! * + *=====================================================*/ + + +/// @use-src 0:"yul_source_locations_code_snippet_escaping/input.sol" +object "C_2" { + code { + /// @src 0:265:278 "contract C {}" + mstore(64, 128) + if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() } + + constructor_C_2() + + let _1 := allocate_unbounded() + codecopy(_1, dataoffset("C_2_deployed"), datasize("C_2_deployed")) + + return(_1, datasize("C_2_deployed")) + + function allocate_unbounded() -> memPtr { + memPtr := mload(64) + } + + function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() { + revert(0, 0) + } + + /// @src 0:265:278 "contract C {}" + function constructor_C_2() { + + /// @src 0:265:278 "contract C {}" + + } + /// @src 0:265:278 "contract C {}" + + } + /// @use-src 0:"yul_source_locations_code_snippet_escaping/input.sol" + object "C_2_deployed" { + code { + /// @src 0:265:278 "contract C {}" + mstore(64, 128) + + if iszero(lt(calldatasize(), 4)) + { + let selector := shift_right_224_unsigned(calldataload(0)) + switch selector + + default {} + } + if iszero(calldatasize()) { } + revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() + + function shift_right_224_unsigned(value) -> newValue { + newValue := + + shr(224, value) + + } + + function allocate_unbounded() -> memPtr { + memPtr := mload(64) + } + + function revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() { + revert(0, 0) + } + + } + + data ".metadata" hex"" + } + +} + + +Optimized IR: +/*=====================================================* + * WARNING * + * Solidity to Yul compilation is still EXPERIMENTAL * + * It can result in LOSS OF FUNDS or worse * + * !USE AT YOUR OWN RISK! * + *=====================================================*/ + +/// @use-src 0:"yul_source_locations_code_snippet_escaping/input.sol" +object "C_2" { + code { + { + /// @src 0:265:278 "contract C {}" + mstore(64, 128) + if callvalue() { revert(0, 0) } + let _1 := datasize("C_2_deployed") + codecopy(128, dataoffset("C_2_deployed"), _1) + return(128, _1) + } + } + /// @use-src 0:"yul_source_locations_code_snippet_escaping/input.sol" + object "C_2_deployed" { + code { + { + /// @src 0:265:278 "contract C {}" + mstore(64, 128) + revert(0, 0) + } + } + data ".metadata" hex"" + } +} + +IR: +/*=====================================================* + * WARNING * + * Solidity to Yul compilation is still EXPERIMENTAL * + * It can result in LOSS OF FUNDS or worse * + * !USE AT YOUR OWN RISK! * + *=====================================================*/ + + +/// @use-src 0:"yul_source_locations_code_snippet_escaping/input.sol" +object "D_27" { + code { + /// @src 0:279:599 "contract D /** @src 0:96:165 \"contract D {...\" *\/ {..." + mstore(64, 128) + if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() } + + constructor_D_27() + + let _1 := allocate_unbounded() + codecopy(_1, dataoffset("D_27_deployed"), datasize("D_27_deployed")) + + return(_1, datasize("D_27_deployed")) + + function allocate_unbounded() -> memPtr { + memPtr := mload(64) + } + + function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() { + revert(0, 0) + } + + /// @src 0:279:599 "contract D /** @src 0:96:165 \"contract D {...\" *\/ {..." + function constructor_D_27() { + + /// @src 0:279:599 "contract D /** @src 0:96:165 \"contract D {...\" *\/ {..." + + } + /// @src 0:279:599 "contract D /** @src 0:96:165 \"contract D {...\" *\/ {..." + + } + /// @use-src 0:"yul_source_locations_code_snippet_escaping/input.sol" + object "D_27_deployed" { + code { + /// @src 0:279:599 "contract D /** @src 0:96:165 \"contract D {...\" *\/ {..." + mstore(64, 128) + + if iszero(lt(calldatasize(), 4)) + { + let selector := shift_right_224_unsigned(calldataload(0)) + switch selector + + case 0x26121ff0 + { + // f() + + if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() } + abi_decode_tuple_(4, calldatasize()) + let ret_0 := fun_f_26() + let memPos := allocate_unbounded() + let memEnd := abi_encode_tuple_t_string_memory_ptr__to_t_string_memory_ptr__fromStack(memPos , ret_0) + return(memPos, sub(memEnd, memPos)) + } + + default {} + } + if iszero(calldatasize()) { } + revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() + + function shift_right_224_unsigned(value) -> newValue { + newValue := + + shr(224, value) + + } + + function allocate_unbounded() -> memPtr { + memPtr := mload(64) + } + + function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() { + revert(0, 0) + } + + function revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() { + revert(0, 0) + } + + function abi_decode_tuple_(headStart, dataEnd) { + if slt(sub(dataEnd, headStart), 0) { revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() } + + } + + function array_length_t_string_memory_ptr(value) -> length { + + length := mload(value) + + } + + function array_storeLengthForEncoding_t_string_memory_ptr_fromStack(pos, length) -> updated_pos { + mstore(pos, length) + updated_pos := add(pos, 0x20) + } + + function copy_memory_to_memory(src, dst, length) { + let i := 0 + for { } lt(i, length) { i := add(i, 32) } + { + mstore(add(dst, i), mload(add(src, i))) + } + if gt(i, length) + { + // clear end + mstore(add(dst, length), 0) + } + } + + function round_up_to_mul_of_32(value) -> result { + result := and(add(value, 31), not(31)) + } + + function abi_encode_t_string_memory_ptr_to_t_string_memory_ptr_fromStack(value, pos) -> end { + let length := array_length_t_string_memory_ptr(value) + pos := array_storeLengthForEncoding_t_string_memory_ptr_fromStack(pos, length) + copy_memory_to_memory(add(value, 0x20), pos, length) + end := add(pos, round_up_to_mul_of_32(length)) + } + + function abi_encode_tuple_t_string_memory_ptr__to_t_string_memory_ptr__fromStack(headStart , value0) -> tail { + tail := add(headStart, 32) + + mstore(add(headStart, 0), sub(tail, headStart)) + tail := abi_encode_t_string_memory_ptr_to_t_string_memory_ptr_fromStack(value0, tail) + + } + + function revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() { + revert(0, 0) + } + + function zero_value_for_split_t_string_memory_ptr() -> ret { + ret := 96 + } + + function panic_error_0x41() { + mstore(0, 35408467139433450592217433187231851964531694900788300625387963629091585785856) + mstore(4, 0x41) + revert(0, 0x24) + } + + function abi_encode_tuple__to__fromStack(headStart ) -> tail { + tail := add(headStart, 0) + + } + + function revert_forward_1() { + let pos := allocate_unbounded() + returndatacopy(pos, 0, returndatasize()) + revert(pos, returndatasize()) + } + + function finalize_allocation(memPtr, size) { + let newFreePtr := add(memPtr, round_up_to_mul_of_32(size)) + // protect against overflow + if or(gt(newFreePtr, 0xffffffffffffffff), lt(newFreePtr, memPtr)) { panic_error_0x41() } + mstore(64, newFreePtr) + } + + function allocate_memory(size) -> memPtr { + memPtr := allocate_unbounded() + finalize_allocation(memPtr, size) + } + + function array_allocation_size_t_string_memory_ptr(length) -> size { + // Make sure we can allocate memory without overflow + if gt(length, 0xffffffffffffffff) { panic_error_0x41() } + + size := round_up_to_mul_of_32(length) + + // add length slot + size := add(size, 0x20) + + } + + function allocate_memory_array_t_string_memory_ptr(length) -> memPtr { + let allocSize := array_allocation_size_t_string_memory_ptr(length) + memPtr := allocate_memory(allocSize) + + mstore(memPtr, length) + + } + + function store_literal_in_memory_c077635d0709aa1fd7cea2045028c270f982d687d1647e48e759eec32ec54a50(memPtr) { + + mstore(add(memPtr, 0), "/*") + + } + + function copy_literal_to_memory_c077635d0709aa1fd7cea2045028c270f982d687d1647e48e759eec32ec54a50() -> memPtr { + memPtr := allocate_memory_array_t_string_memory_ptr(2) + store_literal_in_memory_c077635d0709aa1fd7cea2045028c270f982d687d1647e48e759eec32ec54a50(add(memPtr, 32)) + } + + function convert_t_stringliteral_c077635d0709aa1fd7cea2045028c270f982d687d1647e48e759eec32ec54a50_to_t_string_memory_ptr() -> converted { + converted := copy_literal_to_memory_c077635d0709aa1fd7cea2045028c270f982d687d1647e48e759eec32ec54a50() + } + + function store_literal_in_memory_5bde9a896e3f09acac1496d16642fcdd887d2a000bf1ab18bdff3f17b91e320b(memPtr) { + + mstore(add(memPtr, 0), 0x2f2a2a204073726320303a39363a313635202022636f6e74726163742044207b) + + mstore(add(memPtr, 32), 0x2e2e2e22202a2f00000000000000000000000000000000000000000000000000) + + } + + function copy_literal_to_memory_5bde9a896e3f09acac1496d16642fcdd887d2a000bf1ab18bdff3f17b91e320b() -> memPtr { + memPtr := allocate_memory_array_t_string_memory_ptr(39) + store_literal_in_memory_5bde9a896e3f09acac1496d16642fcdd887d2a000bf1ab18bdff3f17b91e320b(add(memPtr, 32)) + } + + function convert_t_stringliteral_5bde9a896e3f09acac1496d16642fcdd887d2a000bf1ab18bdff3f17b91e320b_to_t_string_memory_ptr() -> converted { + converted := copy_literal_to_memory_5bde9a896e3f09acac1496d16642fcdd887d2a000bf1ab18bdff3f17b91e320b() + } + + /// @src 0:336:597 "function f() /* @use-src 0:\"input.sol\", 1:\"#utility.yul\" @ast-id 15 *\/ public returns (string memory) { C c = new /// @src 0:149:156 \"new C()\"..." + function fun_f_26() -> var__5_mpos { + /// @src 0:423:436 "string memory" + let zero_t_string_memory_ptr_1_mpos := zero_value_for_split_t_string_memory_ptr() + var__5_mpos := zero_t_string_memory_ptr_1_mpos + + /// @src 0:446:491 "new /// @src 0:149:156 \"new C()\"..." + let _2 := allocate_unbounded() + let _3 := add(_2, datasize("C_2")) + if or(gt(_3, 0xffffffffffffffff), lt(_3, _2)) { panic_error_0x41() } + datacopy(_2, dataoffset("C_2"), datasize("C_2")) + _3 := abi_encode_tuple__to__fromStack(_3) + + let expr_13_address := create(0, _2, sub(_3, _2)) + + if iszero(expr_13_address) { revert_forward_1() } + + /// @src 0:440:491 "C c = new /// @src 0:149:156 \"new C()\"..." + let var_c_9_address := expr_13_address + /// @src 0:493:494 "c" + let _4_address := var_c_9_address + let expr_15_address := _4_address + /// @src 0:504:526 "string memory s = \"/*\"" + let var_s_18_mpos := convert_t_stringliteral_c077635d0709aa1fd7cea2045028c270f982d687d1647e48e759eec32ec54a50_to_t_string_memory_ptr() + /// @src 0:528:529 "s" + let _5_mpos := var_s_18_mpos + let expr_21_mpos := _5_mpos + /// @src 0:531:581 "return \"/** @src 0:96:165 \\\"contract D {...\\\" *\/\"" + var__5_mpos := convert_t_stringliteral_5bde9a896e3f09acac1496d16642fcdd887d2a000bf1ab18bdff3f17b91e320b_to_t_string_memory_ptr() + leave + + } + /// @src 0:279:599 "contract D /** @src 0:96:165 \"contract D {...\" *\/ {..." + + } + /*=====================================================* + * WARNING * + * Solidity to Yul compilation is still EXPERIMENTAL * + * It can result in LOSS OF FUNDS or worse * + * !USE AT YOUR OWN RISK! * + *=====================================================*/ + + /// @use-src 0:"yul_source_locations_code_snippet_escaping/input.sol" + object "C_2" { + code { + /// @src 0:265:278 "contract C {}" + mstore(64, 128) + if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() } + + constructor_C_2() + + let _1 := allocate_unbounded() + codecopy(_1, dataoffset("C_2_deployed"), datasize("C_2_deployed")) + + return(_1, datasize("C_2_deployed")) + + function allocate_unbounded() -> memPtr { + memPtr := mload(64) + } + + function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() { + revert(0, 0) + } + + /// @src 0:265:278 "contract C {}" + function constructor_C_2() { + + /// @src 0:265:278 "contract C {}" + + } + /// @src 0:265:278 "contract C {}" + + } + /// @use-src 0:"yul_source_locations_code_snippet_escaping/input.sol" + object "C_2_deployed" { + code { + /// @src 0:265:278 "contract C {}" + mstore(64, 128) + + if iszero(lt(calldatasize(), 4)) + { + let selector := shift_right_224_unsigned(calldataload(0)) + switch selector + + default {} + } + if iszero(calldatasize()) { } + revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() + + function shift_right_224_unsigned(value) -> newValue { + newValue := + + shr(224, value) + + } + + function allocate_unbounded() -> memPtr { + memPtr := mload(64) + } + + function revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() { + revert(0, 0) + } + + } + + data ".metadata" hex"" + } + + } + + data ".metadata" hex"" + } + +} + + +Optimized IR: +/*=====================================================* + * WARNING * + * Solidity to Yul compilation is still EXPERIMENTAL * + * It can result in LOSS OF FUNDS or worse * + * !USE AT YOUR OWN RISK! * + *=====================================================*/ + +/// @use-src 0:"yul_source_locations_code_snippet_escaping/input.sol" +object "D_27" { + code { + { + /// @src 0:279:599 "contract D /** @src 0:96:165 \"contract D {...\" *\/ {..." + mstore(64, 128) + if callvalue() { revert(0, 0) } + let _1 := datasize("D_27_deployed") + codecopy(128, dataoffset("D_27_deployed"), _1) + return(128, _1) + } + } + /// @use-src 0:"yul_source_locations_code_snippet_escaping/input.sol" + object "D_27_deployed" { + code { + { + /// @src 0:279:599 "contract D /** @src 0:96:165 \"contract D {...\" *\/ {..." + mstore(64, 128) + if iszero(lt(calldatasize(), 4)) + { + let _1 := 0 + if eq(0x26121ff0, shr(224, calldataload(_1))) + { + if callvalue() { revert(_1, _1) } + if slt(add(calldatasize(), not(3)), _1) { revert(_1, _1) } + /// @src 0:446:491 "new /// @src 0:149:156 \"new C()\"..." + let _2 := datasize("C_2") + let _3 := add(/** @src 0:279:599 "contract D /** @src 0:96:165 \"contract D {...\" *\/ {..." */ 128, /** @src 0:446:491 "new /// @src 0:149:156 \"new C()\"..." */ _2) + if or(gt(_3, 0xffffffffffffffff), lt(_3, /** @src 0:279:599 "contract D /** @src 0:96:165 \"contract D {...\" *\/ {..." */ 128)) + /// @src 0:446:491 "new /// @src 0:149:156 \"new C()\"..." + { panic_error_0x41() } + datacopy(/** @src 0:279:599 "contract D /** @src 0:96:165 \"contract D {...\" *\/ {..." */ 128, /** @src 0:446:491 "new /// @src 0:149:156 \"new C()\"..." */ dataoffset("C_2"), _2) + if iszero(create(/** @src 0:279:599 "contract D /** @src 0:96:165 \"contract D {...\" *\/ {..." */ _1, 128, /** @src 0:446:491 "new /// @src 0:149:156 \"new C()\"..." */ _2)) + { + /// @src 0:279:599 "contract D /** @src 0:96:165 \"contract D {...\" *\/ {..." + let pos := mload(64) + returndatacopy(pos, _1, returndatasize()) + revert(pos, returndatasize()) + } + mstore(add(allocate_memory_array_string(), 32), "/*") + let memPtr := allocate_memory_array_string_482() + mstore(add(memPtr, 32), 0x2f2a2a204073726320303a39363a313635202022636f6e74726163742044207b) + mstore(add(memPtr, 64), shl(200, 0x2e2e2e22202a2f)) + let memPos := mload(64) + return(memPos, sub(abi_encode_string(memPos, memPtr), memPos)) + } + } + revert(0, 0) + } + function abi_encode_string(headStart, value0) -> tail + { + let _1 := 32 + mstore(headStart, _1) + let length := mload(value0) + mstore(add(headStart, _1), length) + let i := 0 + for { } lt(i, length) { i := add(i, _1) } + { + mstore(add(add(headStart, i), 64), mload(add(add(value0, i), _1))) + } + if gt(i, length) + { + mstore(add(add(headStart, length), 64), 0) + } + tail := add(add(headStart, and(add(length, 31), not(31))), 64) + } + function panic_error_0x41() + { + mstore(0, shl(224, 0x4e487b71)) + mstore(4, 0x41) + revert(0, 0x24) + } + function allocate_memory_array_string() -> memPtr + { + let memPtr_1 := mload(64) + let newFreePtr := add(memPtr_1, 64) + if or(gt(newFreePtr, 0xffffffffffffffff), lt(newFreePtr, memPtr_1)) { panic_error_0x41() } + mstore(64, newFreePtr) + memPtr := memPtr_1 + mstore(memPtr_1, 2) + } + function allocate_memory_array_string_482() -> memPtr + { + let memPtr_1 := mload(64) + let newFreePtr := add(memPtr_1, 96) + if or(gt(newFreePtr, 0xffffffffffffffff), lt(newFreePtr, memPtr_1)) { panic_error_0x41() } + mstore(64, newFreePtr) + memPtr := memPtr_1 + mstore(memPtr_1, 39) + } + } + /// @use-src 0:"yul_source_locations_code_snippet_escaping/input.sol" + object "C_2" { + code { + { + /// @src 0:265:278 "contract C {}" + mstore(64, 128) + if callvalue() { revert(0, 0) } + let _1 := datasize("C_2_deployed") + codecopy(128, dataoffset("C_2_deployed"), _1) + return(128, _1) + } + } + /// @use-src 0:"yul_source_locations_code_snippet_escaping/input.sol" + object "C_2_deployed" { + code { + { + /// @src 0:265:278 "contract C {}" + mstore(64, 128) + revert(0, 0) + } + } + data ".metadata" hex"" + } + } + data ".metadata" hex"" + } +} diff --git a/test/cmdlineTests/yul_string_format_ascii/output.json b/test/cmdlineTests/yul_string_format_ascii/output.json index 4c42c4f78..221c9d306 100644 --- a/test/cmdlineTests/yul_string_format_ascii/output.json +++ b/test/cmdlineTests/yul_string_format_ascii/output.json @@ -9,7 +9,7 @@ /// @use-src 0:\"A\" object \"C_11\" { code { - /// @src 0:78:164 + /// @src 0:78:164 \"contract C { function f() external pure returns (string memory) { return \\\"abcabc\\\"; } }\" mstore(64, 128) if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() } @@ -28,19 +28,19 @@ object \"C_11\" { revert(0, 0) } - /// @src 0:78:164 + /// @src 0:78:164 \"contract C { function f() external pure returns (string memory) { return \\\"abcabc\\\"; } }\" function constructor_C_11() { - /// @src 0:78:164 + /// @src 0:78:164 \"contract C { function f() external pure returns (string memory) { return \\\"abcabc\\\"; } }\" } - /// @src 0:78:164 + /// @src 0:78:164 \"contract C { function f() external pure returns (string memory) { return \\\"abcabc\\\"; } }\" } /// @use-src 0:\"A\" object \"C_11_deployed\" { code { - /// @src 0:78:164 + /// @src 0:78:164 \"contract C { function f() external pure returns (string memory) { return \\\"abcabc\\\"; } }\" mstore(64, 128) if iszero(lt(calldatasize(), 4)) @@ -192,18 +192,18 @@ object \"C_11\" { converted := copy_literal_to_memory_9f0adad0a59b05d2e04a1373342b10b9eb16c57c164c8a3bfcbf46dccee39a21() } - /// @src 0:91:162 + /// @src 0:91:162 \"function f() external pure returns (string memory) { return \\\"abcabc\\\"; }\" function fun_f_10() -> var__5_mpos { - /// @src 0:127:140 + /// @src 0:127:140 \"string memory\" let zero_t_string_memory_ptr_1_mpos := zero_value_for_split_t_string_memory_ptr() var__5_mpos := zero_t_string_memory_ptr_1_mpos - /// @src 0:144:159 + /// @src 0:144:159 \"return \\\"abcabc\\\"\" var__5_mpos := convert_t_stringliteral_9f0adad0a59b05d2e04a1373342b10b9eb16c57c164c8a3bfcbf46dccee39a21_to_t_string_memory_ptr() leave } - /// @src 0:78:164 + /// @src 0:78:164 \"contract C { function f() external pure returns (string memory) { return \\\"abcabc\\\"; } }\" } diff --git a/test/cmdlineTests/yul_string_format_ascii_bytes32/output.json b/test/cmdlineTests/yul_string_format_ascii_bytes32/output.json index 0832d0e4e..0c8fbe701 100644 --- a/test/cmdlineTests/yul_string_format_ascii_bytes32/output.json +++ b/test/cmdlineTests/yul_string_format_ascii_bytes32/output.json @@ -9,7 +9,7 @@ /// @use-src 0:\"A\" object \"C_11\" { code { - /// @src 0:78:158 + /// @src 0:78:158 \"contract C { function f() external pure returns (bytes32) { return \\\"abcabc\\\"; } }\" mstore(64, 128) if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() } @@ -28,19 +28,19 @@ object \"C_11\" { revert(0, 0) } - /// @src 0:78:158 + /// @src 0:78:158 \"contract C { function f() external pure returns (bytes32) { return \\\"abcabc\\\"; } }\" function constructor_C_11() { - /// @src 0:78:158 + /// @src 0:78:158 \"contract C { function f() external pure returns (bytes32) { return \\\"abcabc\\\"; } }\" } - /// @src 0:78:158 + /// @src 0:78:158 \"contract C { function f() external pure returns (bytes32) { return \\\"abcabc\\\"; } }\" } /// @use-src 0:\"A\" object \"C_11_deployed\" { code { - /// @src 0:78:158 + /// @src 0:78:158 \"contract C { function f() external pure returns (bytes32) { return \\\"abcabc\\\"; } }\" mstore(64, 128) if iszero(lt(calldatasize(), 4)) @@ -116,18 +116,18 @@ object \"C_11\" { converted := 0x6162636162630000000000000000000000000000000000000000000000000000 } - /// @src 0:91:156 + /// @src 0:91:156 \"function f() external pure returns (bytes32) { return \\\"abcabc\\\"; }\" function fun_f_10() -> var__5 { - /// @src 0:127:134 + /// @src 0:127:134 \"bytes32\" let zero_t_bytes32_1 := zero_value_for_split_t_bytes32() var__5 := zero_t_bytes32_1 - /// @src 0:138:153 + /// @src 0:138:153 \"return \\\"abcabc\\\"\" var__5 := convert_t_stringliteral_9f0adad0a59b05d2e04a1373342b10b9eb16c57c164c8a3bfcbf46dccee39a21_to_t_bytes32() leave } - /// @src 0:78:158 + /// @src 0:78:158 \"contract C { function f() external pure returns (bytes32) { return \\\"abcabc\\\"; } }\" } diff --git a/test/cmdlineTests/yul_string_format_ascii_bytes32_from_number/output.json b/test/cmdlineTests/yul_string_format_ascii_bytes32_from_number/output.json index f6c63057c..f495dc98a 100644 --- a/test/cmdlineTests/yul_string_format_ascii_bytes32_from_number/output.json +++ b/test/cmdlineTests/yul_string_format_ascii_bytes32_from_number/output.json @@ -9,7 +9,7 @@ /// @use-src 0:\"A\" object \"C_11\" { code { - /// @src 0:78:159 + /// @src 0:78:159 \"contract C { function f() external pure returns (bytes4) { return 0x61626364; } }\" mstore(64, 128) if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() } @@ -28,19 +28,19 @@ object \"C_11\" { revert(0, 0) } - /// @src 0:78:159 + /// @src 0:78:159 \"contract C { function f() external pure returns (bytes4) { return 0x61626364; } }\" function constructor_C_11() { - /// @src 0:78:159 + /// @src 0:78:159 \"contract C { function f() external pure returns (bytes4) { return 0x61626364; } }\" } - /// @src 0:78:159 + /// @src 0:78:159 \"contract C { function f() external pure returns (bytes4) { return 0x61626364; } }\" } /// @use-src 0:\"A\" object \"C_11_deployed\" { code { - /// @src 0:78:159 + /// @src 0:78:159 \"contract C { function f() external pure returns (bytes4) { return 0x61626364; } }\" mstore(64, 128) if iszero(lt(calldatasize(), 4)) @@ -127,20 +127,20 @@ object \"C_11\" { converted := cleanup_t_bytes4(shift_left_224(cleanup_t_rational_1633837924_by_1(value))) } - /// @src 0:91:157 + /// @src 0:91:157 \"function f() external pure returns (bytes4) { return 0x61626364; }\" function fun_f_10() -> var__5 { - /// @src 0:127:133 + /// @src 0:127:133 \"bytes4\" let zero_t_bytes4_1 := zero_value_for_split_t_bytes4() var__5 := zero_t_bytes4_1 - /// @src 0:144:154 + /// @src 0:144:154 \"0x61626364\" let expr_7 := 0x61626364 - /// @src 0:137:154 + /// @src 0:137:154 \"return 0x61626364\" var__5 := convert_t_rational_1633837924_by_1_to_t_bytes4(expr_7) leave } - /// @src 0:78:159 + /// @src 0:78:159 \"contract C { function f() external pure returns (bytes4) { return 0x61626364; } }\" } diff --git a/test/cmdlineTests/yul_string_format_ascii_long/output.json b/test/cmdlineTests/yul_string_format_ascii_long/output.json index c1f4cd6e2..c32952157 100644 --- a/test/cmdlineTests/yul_string_format_ascii_long/output.json +++ b/test/cmdlineTests/yul_string_format_ascii_long/output.json @@ -9,7 +9,7 @@ /// @use-src 0:\"A\" object \"C_11\" { code { - /// @src 0:78:243 + /// @src 0:78:243 \"contract C { function f() external pure returns (string memory) { return \\\"abcdabcdcafecafeabcdabcdcafecafeffffzzzzoooo0123456789,.<,>.?:;'[{]}|`~!@#$%^&*()-_=+\\\"; } }\" mstore(64, 128) if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() } @@ -28,19 +28,19 @@ object \"C_11\" { revert(0, 0) } - /// @src 0:78:243 + /// @src 0:78:243 \"contract C { function f() external pure returns (string memory) { return \\\"abcdabcdcafecafeabcdabcdcafecafeffffzzzzoooo0123456789,.<,>.?:;'[{]}|`~!@#$%^&*()-_=+\\\"; } }\" function constructor_C_11() { - /// @src 0:78:243 + /// @src 0:78:243 \"contract C { function f() external pure returns (string memory) { return \\\"abcdabcdcafecafeabcdabcdcafecafeffffzzzzoooo0123456789,.<,>.?:;'[{]}|`~!@#$%^&*()-_=+\\\"; } }\" } - /// @src 0:78:243 + /// @src 0:78:243 \"contract C { function f() external pure returns (string memory) { return \\\"abcdabcdcafecafeabcdabcdcafecafeffffzzzzoooo0123456789,.<,>.?:;'[{]}|`~!@#$%^&*()-_=+\\\"; } }\" } /// @use-src 0:\"A\" object \"C_11_deployed\" { code { - /// @src 0:78:243 + /// @src 0:78:243 \"contract C { function f() external pure returns (string memory) { return \\\"abcdabcdcafecafeabcdabcdcafecafeffffzzzzoooo0123456789,.<,>.?:;'[{]}|`~!@#$%^&*()-_=+\\\"; } }\" mstore(64, 128) if iszero(lt(calldatasize(), 4)) @@ -196,18 +196,18 @@ object \"C_11\" { converted := copy_literal_to_memory_d6604f85ac07e2b33103a620b3d3d75b0473c7214912beded67b9b624d41c571() } - /// @src 0:91:241 + /// @src 0:91:241 \"function f() external pure returns (string memory) { return \\\"abcdabcdcafecafeabcdabcdcafecafeffffzzzzoooo0123456789,.<,>.?:;'[{]}|`~!@#$%^&*()-_=+\\\"; }\" function fun_f_10() -> var__5_mpos { - /// @src 0:127:140 + /// @src 0:127:140 \"string memory\" let zero_t_string_memory_ptr_1_mpos := zero_value_for_split_t_string_memory_ptr() var__5_mpos := zero_t_string_memory_ptr_1_mpos - /// @src 0:144:238 + /// @src 0:144:238 \"return \\\"abcdabcdcafecafeabcdabcdcafecafeffffzzzzoooo0123456789,.<,>.?:;'[{]}|`~!@#$%^&*()-_=+\\\"\" var__5_mpos := convert_t_stringliteral_d6604f85ac07e2b33103a620b3d3d75b0473c7214912beded67b9b624d41c571_to_t_string_memory_ptr() leave } - /// @src 0:78:243 + /// @src 0:78:243 \"contract C { function f() external pure returns (string memory) { return \\\"abcdabcdcafecafeabcdabcdcafecafeffffzzzzoooo0123456789,.<,>.?:;'[{]}|`~!@#$%^&*()-_=+\\\"; } }\" } diff --git a/test/cmdlineTests/yul_string_format_hex/output.json b/test/cmdlineTests/yul_string_format_hex/output.json index a5a46751a..98e3c8e46 100644 --- a/test/cmdlineTests/yul_string_format_hex/output.json +++ b/test/cmdlineTests/yul_string_format_hex/output.json @@ -9,7 +9,7 @@ /// @use-src 0:\"A\" object \"C_11\" { code { - /// @src 0:78:159 + /// @src 0:78:159 \"contract C { function f() external pure returns (bytes4) { return 0xaabbccdd; } }\" mstore(64, 128) if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() } @@ -28,19 +28,19 @@ object \"C_11\" { revert(0, 0) } - /// @src 0:78:159 + /// @src 0:78:159 \"contract C { function f() external pure returns (bytes4) { return 0xaabbccdd; } }\" function constructor_C_11() { - /// @src 0:78:159 + /// @src 0:78:159 \"contract C { function f() external pure returns (bytes4) { return 0xaabbccdd; } }\" } - /// @src 0:78:159 + /// @src 0:78:159 \"contract C { function f() external pure returns (bytes4) { return 0xaabbccdd; } }\" } /// @use-src 0:\"A\" object \"C_11_deployed\" { code { - /// @src 0:78:159 + /// @src 0:78:159 \"contract C { function f() external pure returns (bytes4) { return 0xaabbccdd; } }\" mstore(64, 128) if iszero(lt(calldatasize(), 4)) @@ -127,20 +127,20 @@ object \"C_11\" { converted := cleanup_t_bytes4(shift_left_224(cleanup_t_rational_2864434397_by_1(value))) } - /// @src 0:91:157 + /// @src 0:91:157 \"function f() external pure returns (bytes4) { return 0xaabbccdd; }\" function fun_f_10() -> var__5 { - /// @src 0:127:133 + /// @src 0:127:133 \"bytes4\" let zero_t_bytes4_1 := zero_value_for_split_t_bytes4() var__5 := zero_t_bytes4_1 - /// @src 0:144:154 + /// @src 0:144:154 \"0xaabbccdd\" let expr_7 := 0xaabbccdd - /// @src 0:137:154 + /// @src 0:137:154 \"return 0xaabbccdd\" var__5 := convert_t_rational_2864434397_by_1_to_t_bytes4(expr_7) leave } - /// @src 0:78:159 + /// @src 0:78:159 \"contract C { function f() external pure returns (bytes4) { return 0xaabbccdd; } }\" }