diff --git a/libyul/AsmParser.cpp b/libyul/AsmParser.cpp index 69c43563b..ce25724f9 100644 --- a/libyul/AsmParser.cpp +++ b/libyul/AsmParser.cpp @@ -131,11 +131,13 @@ void Parser::fetchSourceLocationFromComment() m_locationOverride = SourceLocation{}; if (!sourceIndex || !start || !end) m_errorReporter.syntaxError(6367_error, commentLocation, "Invalid value in source location mapping. Could not parse location specification."); - else if (!((start < 0 && end < 0) || (start >= 0 && *start <= *end))) + else if (!((*start < 0 && *end < 0) || (*start >= 0 && *start <= *end))) m_errorReporter.syntaxError(5798_error, commentLocation, "Invalid value in source location mapping. Start offset larger than end offset."); + else if (sourceIndex == -1 && (0 <= *start && *start <= *end)) // Use source index -1 to indicate original source. + m_locationOverride = SourceLocation{*start, *end, ParserBase::currentLocation().source}; else if (!(sourceIndex >= 0 && m_charStreamMap->count(static_cast(*sourceIndex)))) m_errorReporter.syntaxError(2674_error, commentLocation, "Invalid source mapping. Source index not defined via @use-src."); - else if (sourceIndex >= 0) + else { shared_ptr charStream = m_charStreamMap->at(static_cast(*sourceIndex)); solAssert(charStream, ""); diff --git a/test/libyul/Parser.cpp b/test/libyul/Parser.cpp index 7fe43f842..84f9f8045 100644 --- a/test/libyul/Parser.cpp +++ b/test/libyul/Parser.cpp @@ -556,6 +556,28 @@ BOOST_AUTO_TEST_CASE(customSourceLocations_ensure_last_match) CHECK_LOCATION(varDecl.debugData->location, sourceText, 30, 40); } +BOOST_AUTO_TEST_CASE(customSourceLocations_reference_original_sloc) +{ + ErrorList errorList; + ErrorReporter reporter(errorList); + auto const sourceText = R"( + /// @src 1:2:3 + { + /// @src -1:10:20 + let x:bool := true + } + )"; + EVMDialectTyped const& dialect = EVMDialectTyped::instance(EVMVersion{}); + shared_ptr result = parse(sourceText, dialect, reporter); + BOOST_REQUIRE(!!result); + BOOST_REQUIRE(holds_alternative(result->statements.at(0))); + VariableDeclaration const& varDecl = get(result->statements.at(0)); + + // -1 points to original source code, which in this case is `sourceText` (which is also + // available via `0`, that's why the first @src is set to `1` instead.) + CHECK_LOCATION(varDecl.debugData->location, sourceText, 10, 20); +} + BOOST_AUTO_TEST_SUITE_END() } // end namespaces