Skip to content

Commit 6b1b3dc

Browse files
committed
YulNameRepository with node id handles
1 parent 8c6fed7 commit 6b1b3dc

File tree

399 files changed

+4242
-3704
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

399 files changed

+4242
-3704
lines changed

Changelog.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ Compiler Features:
1515

1616

1717
Bugfixes:
18+
* AsmParser: Parsing rules for source location comments have been relaxed: Whitespace between the indices as well as single-quoted code snippets are now allowed.
1819
* SMTChecker: Fix error that reports invalid number of verified checks for BMC and CHC engines.
1920
* SMTChecker: Fix formatting of unary minus expressions in invariants.
2021
* SMTChecker: Fix internal compiler error when reporting proved targets for BMC engine.

libsolidity/analysis/ControlFlowBuilder.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -582,13 +582,13 @@ void ControlFlowBuilder::operator()(yul::FunctionCall const& _functionCall)
582582
solAssert(m_currentNode && m_inlineAssembly, "");
583583
yul::ASTWalker::operator()(_functionCall);
584584

585-
if (auto const *builtinFunction = m_inlineAssembly->dialect().builtin(_functionCall.functionName.name))
585+
if (auto const *builtinFunction = m_inlineAssembly->nameRepository().builtin(_functionCall.functionName.name))
586586
{
587-
if (builtinFunction->controlFlowSideEffects.canTerminate)
587+
if (builtinFunction->data->controlFlowSideEffects.canTerminate)
588588
connect(m_currentNode, m_transactionReturnNode);
589-
if (builtinFunction->controlFlowSideEffects.canRevert)
589+
if (builtinFunction->data->controlFlowSideEffects.canRevert)
590590
connect(m_currentNode, m_revertNode);
591-
if (!builtinFunction->controlFlowSideEffects.canContinue)
591+
if (!builtinFunction->data->controlFlowSideEffects.canContinue)
592592
m_currentNode = newLabel();
593593
}
594594
}

libsolidity/analysis/PostTypeChecker.cpp

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -462,7 +462,8 @@ struct ReservedErrorSelector: public PostTypeChecker::Checker
462462
class YulLValueChecker : public solidity::yul::ASTWalker
463463
{
464464
public:
465-
YulLValueChecker(ASTString const& _identifierName): m_identifierName(_identifierName) {}
465+
YulLValueChecker(ASTString const& _identifierName, yul::YulNameRepository const& _yulNameRepository):
466+
m_identifierName(_identifierName), m_yulNameRepository(_yulNameRepository) {}
466467
bool willBeWrittenTo() const { return m_willBeWrittenTo; }
467468
using solidity::yul::ASTWalker::operator();
468469
void operator()(solidity::yul::Assignment const& _assignment) override
@@ -472,12 +473,13 @@ class YulLValueChecker : public solidity::yul::ASTWalker
472473

473474
if (ranges::any_of(
474475
_assignment.variableNames,
475-
[&](auto const& yulIdentifier) { return yulIdentifier.name.str() == m_identifierName; }
476+
[&](auto const& yulIdentifier) { return m_yulNameRepository.labelOf(yulIdentifier.name) == m_identifierName; }
476477
))
477478
m_willBeWrittenTo = true;
478479
}
479480
private:
480481
ASTString const& m_identifierName;
482+
yul::YulNameRepository const& m_yulNameRepository;
481483
bool m_willBeWrittenTo = false;
482484
};
483485

@@ -505,7 +507,7 @@ class LValueChecker: public ASTConstVisitor
505507
if (m_willBeWrittenTo)
506508
return;
507509

508-
YulLValueChecker yulChecker{m_declaration->name()};
510+
YulLValueChecker yulChecker{m_declaration->name(), _inlineAssembly.nameRepository()};
509511
yulChecker(_inlineAssembly.operations());
510512
m_willBeWrittenTo = yulChecker.willBeWrittenTo();
511513
}

libsolidity/analysis/ReferencesResolver.cpp

Lines changed: 21 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -236,7 +236,9 @@ bool ReferencesResolver::visit(UsingForDirective const& _usingFor)
236236
bool ReferencesResolver::visit(InlineAssembly const& _inlineAssembly)
237237
{
238238
m_yulAnnotation = &_inlineAssembly.annotation();
239+
m_yulNameRepository = &_inlineAssembly.nameRepository();
239240
(*this)(_inlineAssembly.operations());
241+
m_yulNameRepository = nullptr;
240242
m_yulAnnotation = nullptr;
241243

242244
return false;
@@ -270,12 +272,13 @@ bool ReferencesResolver::visit(BinaryOperation const& _binaryOperation)
270272

271273
void ReferencesResolver::operator()(yul::FunctionDefinition const& _function)
272274
{
275+
solAssert(m_yulNameRepository != nullptr);
273276
solAssert(nativeLocationOf(_function) == originLocationOf(_function), "");
274-
validateYulIdentifierName(_function.name, nativeLocationOf(_function));
277+
validateYulIdentifierName(m_yulNameRepository->labelOf(_function.name), nativeLocationOf(_function));
275278
for (yul::TypedName const& varName: _function.parameters + _function.returnVariables)
276279
{
277280
solAssert(nativeLocationOf(varName) == originLocationOf(varName), "");
278-
validateYulIdentifierName(varName.name, nativeLocationOf(varName));
281+
validateYulIdentifierName(m_yulNameRepository->labelOf(varName.name), nativeLocationOf(varName));
279282
}
280283

281284
bool wasInsideFunction = m_yulInsideFunction;
@@ -286,12 +289,13 @@ void ReferencesResolver::operator()(yul::FunctionDefinition const& _function)
286289

287290
void ReferencesResolver::operator()(yul::Identifier const& _identifier)
288291
{
292+
solAssert(m_yulNameRepository != nullptr);
289293
solAssert(nativeLocationOf(_identifier) == originLocationOf(_identifier), "");
290-
294+
auto const identifierLabel = m_yulNameRepository->labelOf(_identifier.name);
291295
if (m_resolver.experimentalSolidity())
292296
{
293297
std::vector<std::string> splitName;
294-
boost::split(splitName, _identifier.name.str(), boost::is_any_of("."));
298+
boost::split(splitName, identifierLabel, boost::is_any_of("."));
295299
solAssert(!splitName.empty());
296300
if (splitName.size() > 2)
297301
{
@@ -332,22 +336,22 @@ void ReferencesResolver::operator()(yul::Identifier const& _identifier)
332336
static std::set<std::string> suffixes{"slot", "offset", "length", "address", "selector"};
333337
std::string suffix;
334338
for (std::string const& s: suffixes)
335-
if (boost::algorithm::ends_with(_identifier.name.str(), "." + s))
339+
if (boost::algorithm::ends_with(identifierLabel, "." + s))
336340
suffix = s;
337341

338342
// Could also use `pathFromCurrentScope`, split by '.'.
339343
// If we do that, suffix should only be set for when it has a special
340344
// meaning, not for normal identifierPaths.
341-
auto declarations = m_resolver.nameFromCurrentScope(_identifier.name.str());
345+
auto declarations = m_resolver.nameFromCurrentScope(std::string(identifierLabel));
342346
if (!suffix.empty())
343347
{
344348
// special mode to access storage variables
345349
if (!declarations.empty())
346350
// the special identifier exists itself, we should not allow that.
347351
return;
348-
std::string realName = _identifier.name.str().substr(0, _identifier.name.str().size() - suffix.size() - 1);
352+
auto const realName = identifierLabel.substr(0, identifierLabel.size() - suffix.size() - 1);
349353
solAssert(!realName.empty(), "Empty name.");
350-
declarations = m_resolver.nameFromCurrentScope(realName);
354+
declarations = m_resolver.nameFromCurrentScope(std::string(realName));
351355
if (!declarations.empty())
352356
// To support proper path resolution, we have to use pathFromCurrentScope.
353357
solAssert(!util::contains(realName, '.'), "");
@@ -364,8 +368,8 @@ void ReferencesResolver::operator()(yul::Identifier const& _identifier)
364368
else if (declarations.size() == 0)
365369
{
366370
if (
367-
boost::algorithm::ends_with(_identifier.name.str(), "_slot") ||
368-
boost::algorithm::ends_with(_identifier.name.str(), "_offset")
371+
boost::algorithm::ends_with(identifierLabel, "_slot") ||
372+
boost::algorithm::ends_with(identifierLabel, "_offset")
369373
)
370374
m_errorReporter.declarationError(
371375
9467_error,
@@ -391,13 +395,14 @@ void ReferencesResolver::operator()(yul::Identifier const& _identifier)
391395

392396
void ReferencesResolver::operator()(yul::VariableDeclaration const& _varDecl)
393397
{
398+
solAssert(m_yulNameRepository != nullptr);
394399
for (auto const& identifier: _varDecl.variables)
395400
{
396401
solAssert(nativeLocationOf(identifier) == originLocationOf(identifier), "");
397-
validateYulIdentifierName(identifier.name, nativeLocationOf(identifier));
402+
validateYulIdentifierName(m_yulNameRepository->labelOf(identifier.name), nativeLocationOf(identifier));
398403

399404
if (
400-
auto declarations = m_resolver.nameFromCurrentScope(identifier.name.str());
405+
auto declarations = m_resolver.nameFromCurrentScope(std::string(m_yulNameRepository->labelOf(identifier.name)));
401406
!declarations.empty()
402407
)
403408
{
@@ -488,19 +493,19 @@ void ReferencesResolver::resolveInheritDoc(StructuredDocumentation const& _docum
488493
}
489494
}
490495

491-
void ReferencesResolver::validateYulIdentifierName(yul::YulString _name, SourceLocation const& _location)
496+
void ReferencesResolver::validateYulIdentifierName(std::string_view const _name, SourceLocation const& _location)
492497
{
493-
if (util::contains(_name.str(), '.'))
498+
if (util::contains(_name, '.'))
494499
m_errorReporter.declarationError(
495500
3927_error,
496501
_location,
497502
"User-defined identifiers in inline assembly cannot contain '.'."
498503
);
499504

500-
if (std::set<std::string>{"this", "super", "_"}.count(_name.str()))
505+
if (std::set<std::string, std::less<>>{"this", "super", "_"}.count(_name))
501506
m_errorReporter.declarationError(
502507
4113_error,
503508
_location,
504-
"The identifier name \"" + _name.str() + "\" is reserved."
509+
fmt::format("The identifier name \"{}\" is reserved.", _name)
505510
);
506511
}

libsolidity/analysis/ReferencesResolver.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ class ReferencesResolver: private ASTConstVisitor, private yul::ASTWalker
9494
void resolveInheritDoc(StructuredDocumentation const& _documentation, StructurallyDocumentedAnnotation& _annotation);
9595

9696
/// Checks if the name contains a '.'.
97-
void validateYulIdentifierName(yul::YulString _name, langutil::SourceLocation const& _location);
97+
void validateYulIdentifierName(std::string_view _name, langutil::SourceLocation const& _location);
9898

9999
langutil::ErrorReporter& m_errorReporter;
100100
NameAndTypeResolver& m_resolver;
@@ -104,6 +104,7 @@ class ReferencesResolver: private ASTConstVisitor, private yul::ASTWalker
104104
bool const m_resolveInsideCode;
105105

106106
InlineAssemblyAnnotation* m_yulAnnotation = nullptr;
107+
yul::YulNameRepository const* m_yulNameRepository = nullptr;
107108
bool m_yulInsideFunction = false;
108109
bool m_typeContext = false;
109110
};

libsolidity/analysis/SyntaxChecker.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -354,7 +354,7 @@ bool SyntaxChecker::visit(InlineAssembly const& _inlineAssembly)
354354
if (!m_useYulOptimizer)
355355
return false;
356356

357-
if (yul::MSizeFinder::containsMSize(_inlineAssembly.dialect(), _inlineAssembly.operations()))
357+
if (yul::MSizeFinder::containsMSize(_inlineAssembly.nameRepository(), _inlineAssembly.operations()))
358358
m_errorReporter.syntaxError(
359359
6553_error,
360360
_inlineAssembly.location(),

libsolidity/analysis/TypeChecker.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -944,7 +944,7 @@ bool TypeChecker::visit(InlineAssembly const& _inlineAssembly)
944944
yul::AsmAnalyzer analyzer(
945945
*_inlineAssembly.annotation().analysisInfo,
946946
m_errorReporter,
947-
_inlineAssembly.dialect(),
947+
_inlineAssembly.nameRepository(),
948948
identifierAccess
949949
);
950950
if (!analyzer.analyze(_inlineAssembly.operations()))

libsolidity/analysis/ViewPureChecker.cpp

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -38,10 +38,10 @@ class AssemblyViewPureChecker
3838
{
3939
public:
4040
explicit AssemblyViewPureChecker(
41-
yul::Dialect const& _dialect,
41+
yul::YulNameRepository const& _yulNameRepository,
4242
std::function<void(StateMutability, SourceLocation const&)> _reportMutability
4343
):
44-
m_dialect(_dialect),
44+
m_yulNameRepository(_yulNameRepository),
4545
m_reportMutability(std::move(_reportMutability)) {}
4646

4747
void operator()(yul::Literal const&) {}
@@ -65,10 +65,10 @@ class AssemblyViewPureChecker
6565
}
6666
void operator()(yul::FunctionCall const& _funCall)
6767
{
68-
if (yul::EVMDialect const* dialect = dynamic_cast<decltype(dialect)>(&m_dialect))
69-
if (yul::BuiltinFunctionForEVM const* fun = dialect->builtin(_funCall.functionName.name))
70-
if (fun->instruction)
71-
checkInstruction(nativeLocationOf(_funCall), *fun->instruction);
68+
if (yul::EVMDialect const* dialect = dynamic_cast<decltype(dialect)>(&m_yulNameRepository.dialect()))
69+
if (auto const* fun = m_yulNameRepository.builtin(_funCall.functionName.name))
70+
if (auto const* evmFun = dynamic_cast<yul::BuiltinFunctionForEVM const*>(fun->data); evmFun->instruction)
71+
checkInstruction(nativeLocationOf(_funCall), *evmFun->instruction);
7272

7373
for (auto const& arg: _funCall.arguments)
7474
std::visit(*this, arg);
@@ -119,7 +119,7 @@ class AssemblyViewPureChecker
119119
m_reportMutability(StateMutability::View, _location);
120120
}
121121

122-
yul::Dialect const& m_dialect;
122+
yul::YulNameRepository const& m_yulNameRepository;
123123
std::function<void(StateMutability, SourceLocation const&)> m_reportMutability;
124124
};
125125

@@ -224,7 +224,7 @@ void ViewPureChecker::endVisit(Identifier const& _identifier)
224224
void ViewPureChecker::endVisit(InlineAssembly const& _inlineAssembly)
225225
{
226226
AssemblyViewPureChecker{
227-
_inlineAssembly.dialect(),
227+
_inlineAssembly.nameRepository(),
228228
[&](StateMutability _mutability, SourceLocation const& _location) { reportMutability(_mutability, _location); }
229229
}(_inlineAssembly.operations());
230230
}

libsolidity/ast/AST.cpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
#include <libsolidity/ast/TypeProvider.h>
3030
#include <libsolutil/FunctionSelector.h>
3131
#include <libsolutil/Keccak256.h>
32+
#include <libyul/YulName.h>
3233

3334
#include <range/v3/range/conversion.hpp>
3435
#include <range/v3/view/tail.hpp>
@@ -38,6 +39,7 @@
3839

3940
#include <functional>
4041
#include <utility>
42+
#include <memory>
4143

4244
using namespace solidity;
4345
using namespace solidity::frontend;
@@ -1060,6 +1062,24 @@ TryCatchClause const* TryStatement::fallbackClause() const {
10601062
return findClause(m_clauses);
10611063
}
10621064

1065+
InlineAssembly::InlineAssembly(
1066+
int64_t _id,
1067+
SourceLocation const& _location,
1068+
ASTPointer<ASTString> const& _docString,
1069+
std::unique_ptr<yul::YulNameRepository> _yulNameRepository,
1070+
ASTPointer<std::vector<ASTPointer<ASTString>>> _flags,
1071+
std::shared_ptr<yul::Block> _operations
1072+
):
1073+
Statement(_id, _location, _docString),
1074+
m_yulNameRepository(std::move(_yulNameRepository)),
1075+
m_flags(std::move(_flags)),
1076+
m_operations(std::move(_operations))
1077+
{
1078+
solAssert(m_yulNameRepository != nullptr);
1079+
}
1080+
1081+
InlineAssembly::~InlineAssembly() = default;
1082+
10631083
/// Experimental Solidity nodes
10641084
/// @{
10651085
TypeClassDefinitionAnnotation& TypeClassDefinition::annotation() const

libsolidity/ast/AST.h

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ namespace solidity::yul
4949
{
5050
// Forward-declaration to <yul/AST.h>
5151
struct Block;
52-
struct Dialect;
52+
class YulNameRepository;
5353
}
5454

5555
namespace solidity::frontend
@@ -1567,26 +1567,22 @@ class InlineAssembly: public Statement
15671567
int64_t _id,
15681568
SourceLocation const& _location,
15691569
ASTPointer<ASTString> const& _docString,
1570-
yul::Dialect const& _dialect,
1570+
std::unique_ptr<yul::YulNameRepository> _yulNameRepository,
15711571
ASTPointer<std::vector<ASTPointer<ASTString>>> _flags,
15721572
std::shared_ptr<yul::Block> _operations
1573-
):
1574-
Statement(_id, _location, _docString),
1575-
m_dialect(_dialect),
1576-
m_flags(std::move(_flags)),
1577-
m_operations(std::move(_operations))
1578-
{}
1573+
);
1574+
~InlineAssembly() override;
15791575
void accept(ASTVisitor& _visitor) override;
15801576
void accept(ASTConstVisitor& _visitor) const override;
15811577

1582-
yul::Dialect const& dialect() const { return m_dialect; }
1578+
yul::YulNameRepository& nameRepository() const { return *m_yulNameRepository; }
15831579
yul::Block const& operations() const { return *m_operations; }
15841580
ASTPointer<std::vector<ASTPointer<ASTString>>> const& flags() const { return m_flags; }
15851581

15861582
InlineAssemblyAnnotation& annotation() const override;
15871583

15881584
private:
1589-
yul::Dialect const& m_dialect;
1585+
std::unique_ptr<yul::YulNameRepository> mutable m_yulNameRepository;
15901586
ASTPointer<std::vector<ASTPointer<ASTString>>> m_flags;
15911587
std::shared_ptr<yul::Block> m_operations;
15921588
};

0 commit comments

Comments
 (0)