Skip to content

Commit

Permalink
Debug attributes get only parsed, if debug attribute cache was set.
Browse files Browse the repository at this point in the history
  • Loading branch information
aarlt committed Sep 4, 2024
1 parent 95547c2 commit b05c686
Show file tree
Hide file tree
Showing 15 changed files with 70 additions and 35 deletions.
27 changes: 14 additions & 13 deletions libyul/AsmParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -62,35 +62,34 @@ std::optional<int> toInt(std::string const& _value)

langutil::DebugData::ConstPtr Parser::createDebugData() const
{
solAssert(m_debugAttributeCache);
switch (m_useSourceLocationFrom)
{
case UseSourceLocationFrom::Scanner:
return DebugData::create(
ParserBase::currentLocation(),
ParserBase::currentLocation(),
{},
m_currentDebugAttributes.has_value()
? DebugData::Attributes({m_debugAttributeCache->set(*m_currentDebugAttributes)})
: DebugData::Attributes({})
m_debugAttributeCache
? m_currentDebugAttributes.has_value() ? DebugData::Attributes({m_debugAttributeCache->set(*m_currentDebugAttributes)}) : DebugData::Attributes({})
: std::nullopt
);
case UseSourceLocationFrom::LocationOverride:
return DebugData::create(
m_locationOverride,
m_locationOverride,
{},
m_currentDebugAttributes.has_value()
? DebugData::Attributes({m_debugAttributeCache->set(*m_currentDebugAttributes)})
: DebugData::Attributes({})
m_debugAttributeCache
? m_currentDebugAttributes.has_value() ? DebugData::Attributes({m_debugAttributeCache->set(*m_currentDebugAttributes)}) : DebugData::Attributes({})
: std::nullopt
);
case UseSourceLocationFrom::Comments:
return DebugData::create(
ParserBase::currentLocation(),
m_locationFromComment,
m_astIDFromComment,
m_currentDebugAttributes.has_value()
? DebugData::Attributes({m_debugAttributeCache->set(*m_currentDebugAttributes)})
: DebugData::Attributes({})
m_debugAttributeCache
? m_currentDebugAttributes.has_value() ? DebugData::Attributes({m_debugAttributeCache->set(*m_currentDebugAttributes)}) : DebugData::Attributes({})
: std::nullopt
);
}
solAssert(false, "");
Expand Down Expand Up @@ -200,7 +199,7 @@ void Parser::fetchDebugDataFromComment()
else
break;
}
else if (match[1] == "@debug.set")
else if (match[1] == "@debug.set" && m_debugAttributeCache)
{
if (auto parseResult = parseDebugDataAttributeOperationComment(match[1], commentLiteral, m_scanner->currentCommentLocation()))
{
Expand All @@ -211,7 +210,7 @@ void Parser::fetchDebugDataFromComment()
else
break;
}
else if (match[1] == "@debug.merge")
else if (match[1] == "@debug.merge" && m_debugAttributeCache)
{
if (auto parseResult = parseDebugDataAttributeOperationComment(match[1], commentLiteral, m_scanner->currentCommentLocation()))
{
Expand All @@ -226,7 +225,7 @@ void Parser::fetchDebugDataFromComment()
else
break;
}
else if (match[1] == "@debug.patch")
else if (match[1] == "@debug.patch" && m_debugAttributeCache)
{
if (auto parseResult = parseDebugDataAttributeOperationComment(match[1], commentLiteral, m_scanner->currentCommentLocation()))
{
Expand All @@ -251,6 +250,7 @@ std::optional<std::pair<std::string_view, std::optional<Json>>> Parser::parseDeb
langutil::SourceLocation const& _location
)
{
solAssert(m_debugAttributeCache, "debug attributes can only be used with valid debug attribute cache");
std::optional<Json> jsonData;
try
{
Expand Down Expand Up @@ -278,6 +278,7 @@ std::optional<std::pair<std::string_view, std::optional<Json>>> Parser::parseDeb

void Parser::applyDebugDataAttributePatch(Json const& _jsonPatch, langutil::SourceLocation const& _location)
{
solAssert(m_debugAttributeCache, "debug attributes can only be used with valid debug attribute cache");
try
{
if (!m_currentDebugAttributes.has_value())
Expand Down
7 changes: 4 additions & 3 deletions libyul/AsmParser.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@

#include <map>
#include <memory>
#include <utility>
#include <variant>
#include <string_view>

Expand All @@ -60,7 +61,7 @@ class Parser: public langutil::ParserBase
langutil::ErrorReporter& _errorReporter,
Dialect const& _dialect,
std::optional<langutil::SourceLocation> _locationOverride = {},
DebugAttributeCache::Ptr debugAttributesCache = {}
DebugAttributeCache::Ptr _debugAttributesCache = {}
):
ParserBase(_errorReporter),
m_dialect(_dialect),
Expand All @@ -70,7 +71,7 @@ class Parser: public langutil::ParserBase
UseSourceLocationFrom::LocationOverride :
UseSourceLocationFrom::Scanner
},
m_debugAttributeCache(debugAttributesCache == nullptr ? std::make_shared<DebugAttributeCache>() : debugAttributesCache)
m_debugAttributeCache(std::move(_debugAttributesCache))
{}

/// Constructs a Yul parser that is using the debug data
Expand All @@ -89,7 +90,7 @@ class Parser: public langutil::ParserBase
UseSourceLocationFrom::Comments :
UseSourceLocationFrom::Scanner
},
m_debugAttributeCache(debugAttributesCache == nullptr ? std::make_shared<DebugAttributeCache>() : debugAttributesCache)
m_debugAttributeCache(std::move(debugAttributesCache))
{}

/// Parses an inline assembly block starting with `{` and ending with `}`.
Expand Down
2 changes: 1 addition & 1 deletion libyul/ObjectParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ std::optional<SourceNameMap> ObjectParser::tryParseSourceNameMapping() const

std::shared_ptr<AST> ObjectParser::parseBlock(std::optional<SourceNameMap> _sourceNames)
{
Parser parser(m_errorReporter, m_dialect, std::move(_sourceNames));
Parser parser(m_errorReporter, m_dialect, std::move(_sourceNames), m_cache);
auto ast = parser.parseInline(m_scanner);
yulAssert(ast || m_errorReporter.hasErrors(), "Invalid block but no error!");
return ast;
Expand Down
8 changes: 5 additions & 3 deletions libyul/ObjectParser.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,9 @@

#pragma once

#include <libyul/Object.h>
#include <libyul/Dialect.h>
#include <libyul/AsmParser.h>
#include <libyul/Object.h>

#include <liblangutil/ErrorReporter.h>
#include <liblangutil/ParserBase.h>
Expand All @@ -45,8 +46,8 @@ namespace solidity::yul
class ObjectParser: public langutil::ParserBase
{
public:
explicit ObjectParser(langutil::ErrorReporter& _errorReporter, Dialect const& _dialect):
ParserBase(_errorReporter), m_dialect(_dialect) {}
explicit ObjectParser(langutil::ErrorReporter& _errorReporter, Dialect const& _dialect, Parser::DebugAttributeCache::Ptr _cache = {}):
ParserBase(_errorReporter), m_dialect(_dialect), m_cache(std::move(_cache)) {}

/// Parses a Yul object.
/// Falls back to code-only parsing if the source starts with `{`.
Expand All @@ -66,6 +67,7 @@ class ObjectParser: public langutil::ParserBase
void addNamedSubObject(Object& _container, std::string_view _name, std::shared_ptr<ObjectNode> _subObject);

Dialect const& m_dialect;
Parser::DebugAttributeCache::Ptr m_cache;
};

}
2 changes: 1 addition & 1 deletion libyul/YulStack.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ bool YulStack::parse(std::string const& _sourceName, std::string const& _source)
{
m_charStream = std::make_unique<CharStream>(_source, _sourceName);
std::shared_ptr<Scanner> scanner = std::make_shared<Scanner>(*m_charStream);
m_parserResult = ObjectParser(m_errorReporter, languageToDialect(m_language, m_evmVersion)).parse(scanner, false);
m_parserResult = ObjectParser(m_errorReporter, languageToDialect(m_language, m_evmVersion), m_cache).parse(scanner, false);
}
catch (UnimplementedFeatureError const& _error)
{
Expand Down
8 changes: 6 additions & 2 deletions libyul/YulStack.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@

#include <memory>
#include <string>
#include <utility>

namespace solidity::evmasm
{
Expand Down Expand Up @@ -91,15 +92,17 @@ class YulStack: public langutil::CharStreamProvider
Language _language,
solidity::frontend::OptimiserSettings _optimiserSettings,
langutil::DebugInfoSelection const& _debugInfoSelection,
std::shared_ptr<ObjectOptimizer> _objectOptimizer = nullptr
std::shared_ptr<ObjectOptimizer> _objectOptimizer = nullptr,
Parser::DebugAttributeCache::Ptr _cache = {}
):
m_language(_language),
m_evmVersion(_evmVersion),
m_eofVersion(_eofVersion),
m_optimiserSettings(std::move(_optimiserSettings)),
m_debugInfoSelection(_debugInfoSelection),
m_errorReporter(m_errors),
m_objectOptimizer(_objectOptimizer ? std::move(_objectOptimizer) : std::make_shared<ObjectOptimizer>())
m_objectOptimizer(_objectOptimizer ? std::move(_objectOptimizer) : std::make_shared<ObjectOptimizer>()),
m_cache(std::move(_cache))
{}

/// @returns the char stream used during parsing
Expand Down Expand Up @@ -177,6 +180,7 @@ class YulStack: public langutil::CharStreamProvider
langutil::ErrorReporter m_errorReporter;

std::shared_ptr<ObjectOptimizer> m_objectOptimizer;
Parser::DebugAttributeCache::Ptr m_cache;
};

}
15 changes: 11 additions & 4 deletions test/libyul/Common.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@
* Common functions the Yul tests.
*/

#include "libyul/AsmParser.h"


#include <test/libyul/Common.h>

#include <test/Common.h>
Expand All @@ -36,6 +39,7 @@

#include <boost/test/unit_test.hpp>

#include <utility>
#include <variant>

using namespace solidity;
Expand All @@ -50,7 +54,7 @@ Dialect const& defaultDialect()
}
}

std::pair<std::shared_ptr<AST const>, std::shared_ptr<yul::AsmAnalysisInfo>> yul::test::parse(std::string const& _source)
std::pair<std::shared_ptr<AST const>, std::shared_ptr<yul::AsmAnalysisInfo>> yul::test::parse(std::string const& _source, Parser::DebugAttributeCache::Ptr _cache)
{
YulStack stack(
solidity::test::CommonOptions::get().evmVersion(),
Expand All @@ -59,7 +63,9 @@ std::pair<std::shared_ptr<AST const>, std::shared_ptr<yul::AsmAnalysisInfo>> yul
solidity::test::CommonOptions::get().optimize ?
solidity::frontend::OptimiserSettings::standard() :
solidity::frontend::OptimiserSettings::minimal(),
DebugInfoSelection::ExceptExperimental()
DebugInfoSelection::ExceptExperimental(),
nullptr,
std::move(_cache)
);
if (!stack.parseAndAnalyze("", _source) || !stack.errors().empty())
BOOST_FAIL("Invalid source.");
Expand All @@ -69,13 +75,14 @@ std::pair<std::shared_ptr<AST const>, std::shared_ptr<yul::AsmAnalysisInfo>> yul
std::pair<std::shared_ptr<Object>, std::shared_ptr<yul::AsmAnalysisInfo>> yul::test::parse(
std::string const& _source,
Dialect const& _dialect,
ErrorList& _errors
ErrorList& _errors,
Parser::DebugAttributeCache::Ptr _cache
)
{
ErrorReporter errorReporter(_errors);
CharStream stream(_source, "");
std::shared_ptr<Scanner> scanner = std::make_shared<Scanner>(stream);
std::shared_ptr<Object> parserResult = yul::ObjectParser(errorReporter, _dialect).parse(scanner, false);
std::shared_ptr<Object> parserResult = yul::ObjectParser(errorReporter, _dialect, std::move(_cache)).parse(scanner, false);
if (!parserResult)
return {};
if (!parserResult->hasCode() || errorReporter.hasErrors())
Expand Down
6 changes: 4 additions & 2 deletions test/libyul/Common.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@

#include <liblangutil/EVMVersion.h>

#include <libyul/AsmParser.h>

#include <string>
#include <vector>
#include <memory>
Expand All @@ -46,10 +48,10 @@ namespace solidity::yul::test
{

std::pair<std::shared_ptr<AST const>, std::shared_ptr<AsmAnalysisInfo>>
parse(std::string const& _source);
parse(std::string const& _source, Parser::DebugAttributeCache::Ptr _cache = {});

std::pair<std::shared_ptr<Object>, std::shared_ptr<AsmAnalysisInfo>>
parse(std::string const& _source, Dialect const& _dialect, langutil::ErrorList& _errors);
parse(std::string const& _source, Dialect const& _dialect, langutil::ErrorList& _errors, Parser::DebugAttributeCache::Ptr _cache = {});

Block disambiguate(std::string const& _source);
std::string format(std::string const& _source);
Expand Down
9 changes: 5 additions & 4 deletions test/libyul/Parser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1007,7 +1007,8 @@ BOOST_AUTO_TEST_CASE(ethdebug_debug_attributes_empty)
auto const sourceText = R"(
{}
)";
EVMDialectTyped const& dialect = EVMDialectTyped::instance(EVMVersion{});
auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{});
BOOST_REQUIRE(cache->cache().size() == 0);
std::shared_ptr<AST> result = parse(sourceText, dialect, reporter, cache);
BOOST_REQUIRE(cache->cache().size() == 0);
}
Expand All @@ -1021,7 +1022,7 @@ BOOST_AUTO_TEST_CASE(ethdebug_debug_attributes_set_empty)
/// @debug.set {}
{}
)";
EVMDialectTyped const& dialect = EVMDialectTyped::instance(EVMVersion{});
auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{});
std::shared_ptr<AST> result = parse(sourceText, dialect, reporter, cache);
BOOST_REQUIRE(cache->cache().size() == 1);
}
Expand All @@ -1036,7 +1037,7 @@ BOOST_AUTO_TEST_CASE(ethdebug_debug_attributes_set)
/// @debug.set {"hello": "world"}
{}
)";
EVMDialectTyped const& dialect = EVMDialectTyped::instance(EVMVersion{});
auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{});
std::shared_ptr<AST> result = parse(sourceText, dialect, reporter, cache);
BOOST_REQUIRE(cache->cache().size() == 1);
}
Expand All @@ -1055,7 +1056,7 @@ BOOST_AUTO_TEST_CASE(ethdebug_debug_attributes_multiple_set)
{}
}
)";
EVMDialectTyped const& dialect = EVMDialectTyped::instance(EVMVersion{});
auto const& dialect = EVMDialect::strictAssemblyForEVM(EVMVersion{});
std::shared_ptr<AST> result = parse(sourceText, dialect, reporter, cache);
BOOST_REQUIRE(cache->cache().size() == 2);
}
Expand Down
5 changes: 4 additions & 1 deletion test/libyul/SyntaxTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,10 @@ void SyntaxTest::parseAndAnalyze()

ErrorList errorList{};
soltestAssert(m_dialect, "");
if (m_debugAttributesEnabled && m_debugAttributesCache == nullptr)
m_debugAttributesCache = std::make_shared<Parser::DebugAttributeCache>();
// Silently ignoring the results.
yul::test::parse(source, *m_dialect, errorList);
yul::test::parse(source, *m_dialect, errorList, m_debugAttributesCache);
for (auto const& error: errorList)
{
int locationStart = -1;
Expand Down Expand Up @@ -75,5 +77,6 @@ SyntaxTest::SyntaxTest(std::string const& _filename, langutil::EVMVersion _evmVe
CommonSyntaxTest(_filename, _evmVersion)
{
std::string dialectName = m_reader.stringSetting("dialect", "evm");
m_debugAttributesEnabled = m_reader.boolSetting("enableDebugAttributes", false);
m_dialect = &dialect(dialectName, solidity::test::CommonOptions::get().evmVersion());
}
8 changes: 7 additions & 1 deletion test/libyul/SyntaxTest.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,12 @@

#pragma once

#include <test/CommonSyntaxTest.h>
#include "libyul/AsmParser.h"
#include "libyul/optimiser/SimplificationRules.h"


#include <libyul/Dialect.h>
#include <test/CommonSyntaxTest.h>

namespace solidity::yul::test
{
Expand All @@ -40,6 +44,8 @@ class SyntaxTest: public solidity::test::CommonSyntaxTest

private:
Dialect const* m_dialect = nullptr;
bool m_debugAttributesEnabled = false;
Parser::DebugAttributeCache::Ptr m_debugAttributesCache;
};

}
2 changes: 2 additions & 0 deletions test/libyul/yulSyntaxTests/invalid/invalid_debug_merge.yul
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,7 @@ object "object" {
/// @debug.merge {"HELLO": 2
}
}
// ====
// enableDebugAttributes: true
// ----
// SyntaxError 5721: (37-65): @debug.merge: Could not parse debug data: parse error at line 1, column 12: syntax error while parsing object - unexpected end of input; expected '}'
2 changes: 2 additions & 0 deletions test/libyul/yulSyntaxTests/invalid/invalid_debug_patch.yul
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,7 @@ object "object" {
/// @debug.patch {"HELLO": invalid
}
}
// ====
// enableDebugAttributes: true
// ----
// SyntaxError 5721: (37-71): @debug.patch: Could not parse debug data: parse error at line 1, column 11: syntax error while parsing value - unexpected end of input; expected '[', '{', or a literal
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,7 @@ object "object" {
/// @debug.patch { "op": "unknown_operation", "path": "/variable_a", "value": ["test"] }
}
}
// ====
// enableDebugAttributes: true
// ----
// SyntaxError 9426: (37-125): @debug.patch: Could not patch debug data: parse error: operation value 'unknown_operation' is invalid
2 changes: 2 additions & 0 deletions test/libyul/yulSyntaxTests/invalid/invalid_debug_set.yul
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,7 @@ object "object" {
/// @debug.set {"HELLO": "WORLD
}
}
// ====
// enableDebugAttributes: true
// ----
// SyntaxError 5721: (37-68): @debug.set: Could not parse debug data: parse error at line 1, column 17: syntax error while parsing value - invalid string: missing closing quote; last read: '"WORLD'

0 comments on commit b05c686

Please sign in to comment.