mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Merge remote-tracking branch 'origin/develop' into develop_060
This commit is contained in:
commit
1ebcc757e1
@ -40,7 +40,7 @@ GasMeter::GasConsumption PathGasMeter::estimateMax(
|
|||||||
shared_ptr<KnownState> const& _state
|
shared_ptr<KnownState> const& _state
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
auto path = unique_ptr<GasPath>(new GasPath());
|
auto path = make_unique<GasPath>();
|
||||||
path->index = _startIndex;
|
path->index = _startIndex;
|
||||||
path->state = _state->copy();
|
path->state = _state->copy();
|
||||||
queue(move(path));
|
queue(move(path));
|
||||||
@ -120,7 +120,7 @@ GasMeter::GasConsumption PathGasMeter::handleQueueItem()
|
|||||||
|
|
||||||
for (u256 const& tag: jumpTags)
|
for (u256 const& tag: jumpTags)
|
||||||
{
|
{
|
||||||
auto newPath = unique_ptr<GasPath>(new GasPath());
|
auto newPath = make_unique<GasPath>();
|
||||||
newPath->index = m_items.size();
|
newPath->index = m_items.size();
|
||||||
if (m_tagPositions.count(tag))
|
if (m_tagPositions.count(tag))
|
||||||
newPath->index = m_tagPositions.at(tag);
|
newPath->index = m_tagPositions.at(tag);
|
||||||
|
@ -35,7 +35,7 @@ unique_ptr<FunctionFlow> ControlFlowBuilder::createFunctionFlow(
|
|||||||
FunctionDefinition const& _function
|
FunctionDefinition const& _function
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
auto functionFlow = unique_ptr<FunctionFlow>(new FunctionFlow());
|
auto functionFlow = make_unique<FunctionFlow>();
|
||||||
functionFlow->entry = _nodeContainer.newNode();
|
functionFlow->entry = _nodeContainer.newNode();
|
||||||
functionFlow->exit = _nodeContainer.newNode();
|
functionFlow->exit = _nodeContainer.newNode();
|
||||||
functionFlow->revert = _nodeContainer.newNode();
|
functionFlow->revert = _nodeContainer.newNode();
|
||||||
|
@ -48,7 +48,7 @@ NameAndTypeResolver::NameAndTypeResolver(
|
|||||||
m_globalContext(_globalContext)
|
m_globalContext(_globalContext)
|
||||||
{
|
{
|
||||||
if (!m_scopes[nullptr])
|
if (!m_scopes[nullptr])
|
||||||
m_scopes[nullptr].reset(new DeclarationContainer());
|
m_scopes[nullptr] = make_shared<DeclarationContainer>();
|
||||||
for (Declaration const* declaration: _globalContext.declarations())
|
for (Declaration const* declaration: _globalContext.declarations())
|
||||||
{
|
{
|
||||||
solAssert(m_scopes[nullptr]->registerDeclaration(*declaration), "Unable to register global declaration.");
|
solAssert(m_scopes[nullptr]->registerDeclaration(*declaration), "Unable to register global declaration.");
|
||||||
@ -545,7 +545,7 @@ bool DeclarationRegistrationHelper::visit(SourceUnit& _sourceUnit)
|
|||||||
{
|
{
|
||||||
if (!m_scopes[&_sourceUnit])
|
if (!m_scopes[&_sourceUnit])
|
||||||
// By importing, it is possible that the container already exists.
|
// By importing, it is possible that the container already exists.
|
||||||
m_scopes[&_sourceUnit].reset(new DeclarationContainer(m_currentScope, m_scopes[m_currentScope].get()));
|
m_scopes[&_sourceUnit] = make_shared<DeclarationContainer>(m_currentScope, m_scopes[m_currentScope].get());
|
||||||
m_currentScope = &_sourceUnit;
|
m_currentScope = &_sourceUnit;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -561,7 +561,7 @@ bool DeclarationRegistrationHelper::visit(ImportDirective& _import)
|
|||||||
SourceUnit const* importee = _import.annotation().sourceUnit;
|
SourceUnit const* importee = _import.annotation().sourceUnit;
|
||||||
solAssert(!!importee, "");
|
solAssert(!!importee, "");
|
||||||
if (!m_scopes[importee])
|
if (!m_scopes[importee])
|
||||||
m_scopes[importee].reset(new DeclarationContainer(nullptr, m_scopes[nullptr].get()));
|
m_scopes[importee] = make_shared<DeclarationContainer>(nullptr, m_scopes[nullptr].get());
|
||||||
m_scopes[&_import] = m_scopes[importee];
|
m_scopes[&_import] = m_scopes[importee];
|
||||||
registerDeclaration(_import, false);
|
registerDeclaration(_import, false);
|
||||||
return true;
|
return true;
|
||||||
@ -720,7 +720,7 @@ void DeclarationRegistrationHelper::enterNewSubScope(ASTNode& _subScope)
|
|||||||
{
|
{
|
||||||
map<ASTNode const*, shared_ptr<DeclarationContainer>>::iterator iter;
|
map<ASTNode const*, shared_ptr<DeclarationContainer>>::iterator iter;
|
||||||
bool newlyAdded;
|
bool newlyAdded;
|
||||||
shared_ptr<DeclarationContainer> container(new DeclarationContainer(m_currentScope, m_scopes[m_currentScope].get()));
|
shared_ptr<DeclarationContainer> container{make_shared<DeclarationContainer>(m_currentScope, m_scopes[m_currentScope].get())};
|
||||||
tie(iter, newlyAdded) = m_scopes.emplace(&_subScope, move(container));
|
tie(iter, newlyAdded) = m_scopes.emplace(&_subScope, move(container));
|
||||||
solAssert(newlyAdded, "Unable to add new scope.");
|
solAssert(newlyAdded, "Unable to add new scope.");
|
||||||
m_currentScope = &_subScope;
|
m_currentScope = &_subScope;
|
||||||
|
@ -55,11 +55,6 @@ ASTNode::ASTNode(SourceLocation const& _location):
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
ASTNode::~ASTNode()
|
|
||||||
{
|
|
||||||
delete m_annotation;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ASTNode::resetID()
|
void ASTNode::resetID()
|
||||||
{
|
{
|
||||||
IDDispenser::reset();
|
IDDispenser::reset();
|
||||||
@ -68,14 +63,14 @@ void ASTNode::resetID()
|
|||||||
ASTAnnotation& ASTNode::annotation() const
|
ASTAnnotation& ASTNode::annotation() const
|
||||||
{
|
{
|
||||||
if (!m_annotation)
|
if (!m_annotation)
|
||||||
m_annotation = new ASTAnnotation();
|
m_annotation = make_unique<ASTAnnotation>();
|
||||||
return *m_annotation;
|
return *m_annotation;
|
||||||
}
|
}
|
||||||
|
|
||||||
SourceUnitAnnotation& SourceUnit::annotation() const
|
SourceUnitAnnotation& SourceUnit::annotation() const
|
||||||
{
|
{
|
||||||
if (!m_annotation)
|
if (!m_annotation)
|
||||||
m_annotation = new SourceUnitAnnotation();
|
m_annotation = make_unique<SourceUnitAnnotation>();
|
||||||
return dynamic_cast<SourceUnitAnnotation&>(*m_annotation);
|
return dynamic_cast<SourceUnitAnnotation&>(*m_annotation);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -99,7 +94,7 @@ set<SourceUnit const*> SourceUnit::referencedSourceUnits(bool _recurse, set<Sour
|
|||||||
ImportAnnotation& ImportDirective::annotation() const
|
ImportAnnotation& ImportDirective::annotation() const
|
||||||
{
|
{
|
||||||
if (!m_annotation)
|
if (!m_annotation)
|
||||||
m_annotation = new ImportAnnotation();
|
m_annotation = make_unique<ImportAnnotation>();
|
||||||
return dynamic_cast<ImportAnnotation&>(*m_annotation);
|
return dynamic_cast<ImportAnnotation&>(*m_annotation);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -177,7 +172,7 @@ vector<EventDefinition const*> const& ContractDefinition::interfaceEvents() cons
|
|||||||
if (!m_interfaceEvents)
|
if (!m_interfaceEvents)
|
||||||
{
|
{
|
||||||
set<string> eventsSeen;
|
set<string> eventsSeen;
|
||||||
m_interfaceEvents.reset(new vector<EventDefinition const*>());
|
m_interfaceEvents = make_unique<vector<EventDefinition const*>>();
|
||||||
for (ContractDefinition const* contract: annotation().linearizedBaseContracts)
|
for (ContractDefinition const* contract: annotation().linearizedBaseContracts)
|
||||||
for (EventDefinition const* e: contract->events())
|
for (EventDefinition const* e: contract->events())
|
||||||
{
|
{
|
||||||
@ -202,7 +197,7 @@ vector<pair<FixedHash<4>, FunctionTypePointer>> const& ContractDefinition::inter
|
|||||||
if (!m_interfaceFunctionList)
|
if (!m_interfaceFunctionList)
|
||||||
{
|
{
|
||||||
set<string> signaturesSeen;
|
set<string> signaturesSeen;
|
||||||
m_interfaceFunctionList.reset(new vector<pair<FixedHash<4>, FunctionTypePointer>>());
|
m_interfaceFunctionList = make_unique<vector<pair<FixedHash<4>, FunctionTypePointer>>>();
|
||||||
for (ContractDefinition const* contract: annotation().linearizedBaseContracts)
|
for (ContractDefinition const* contract: annotation().linearizedBaseContracts)
|
||||||
{
|
{
|
||||||
vector<FunctionTypePointer> functions;
|
vector<FunctionTypePointer> functions;
|
||||||
@ -234,7 +229,7 @@ vector<Declaration const*> const& ContractDefinition::inheritableMembers() const
|
|||||||
{
|
{
|
||||||
if (!m_inheritableMembers)
|
if (!m_inheritableMembers)
|
||||||
{
|
{
|
||||||
m_inheritableMembers.reset(new vector<Declaration const*>());
|
m_inheritableMembers = make_unique<vector<Declaration const*>>();
|
||||||
auto addInheritableMember = [&](Declaration const* _decl)
|
auto addInheritableMember = [&](Declaration const* _decl)
|
||||||
{
|
{
|
||||||
solAssert(_decl, "addInheritableMember got a nullpointer.");
|
solAssert(_decl, "addInheritableMember got a nullpointer.");
|
||||||
@ -268,14 +263,14 @@ TypePointer ContractDefinition::type() const
|
|||||||
ContractDefinitionAnnotation& ContractDefinition::annotation() const
|
ContractDefinitionAnnotation& ContractDefinition::annotation() const
|
||||||
{
|
{
|
||||||
if (!m_annotation)
|
if (!m_annotation)
|
||||||
m_annotation = new ContractDefinitionAnnotation();
|
m_annotation = make_unique<ContractDefinitionAnnotation>();
|
||||||
return dynamic_cast<ContractDefinitionAnnotation&>(*m_annotation);
|
return dynamic_cast<ContractDefinitionAnnotation&>(*m_annotation);
|
||||||
}
|
}
|
||||||
|
|
||||||
TypeNameAnnotation& TypeName::annotation() const
|
TypeNameAnnotation& TypeName::annotation() const
|
||||||
{
|
{
|
||||||
if (!m_annotation)
|
if (!m_annotation)
|
||||||
m_annotation = new TypeNameAnnotation();
|
m_annotation = make_unique<TypeNameAnnotation>();
|
||||||
return dynamic_cast<TypeNameAnnotation&>(*m_annotation);
|
return dynamic_cast<TypeNameAnnotation&>(*m_annotation);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -287,7 +282,7 @@ TypePointer StructDefinition::type() const
|
|||||||
TypeDeclarationAnnotation& StructDefinition::annotation() const
|
TypeDeclarationAnnotation& StructDefinition::annotation() const
|
||||||
{
|
{
|
||||||
if (!m_annotation)
|
if (!m_annotation)
|
||||||
m_annotation = new TypeDeclarationAnnotation();
|
m_annotation = make_unique<TypeDeclarationAnnotation>();
|
||||||
return dynamic_cast<TypeDeclarationAnnotation&>(*m_annotation);
|
return dynamic_cast<TypeDeclarationAnnotation&>(*m_annotation);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -306,7 +301,7 @@ TypePointer EnumDefinition::type() const
|
|||||||
TypeDeclarationAnnotation& EnumDefinition::annotation() const
|
TypeDeclarationAnnotation& EnumDefinition::annotation() const
|
||||||
{
|
{
|
||||||
if (!m_annotation)
|
if (!m_annotation)
|
||||||
m_annotation = new TypeDeclarationAnnotation();
|
m_annotation = make_unique<TypeDeclarationAnnotation>();
|
||||||
return dynamic_cast<TypeDeclarationAnnotation&>(*m_annotation);
|
return dynamic_cast<TypeDeclarationAnnotation&>(*m_annotation);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -366,7 +361,7 @@ string FunctionDefinition::externalSignature() const
|
|||||||
FunctionDefinitionAnnotation& FunctionDefinition::annotation() const
|
FunctionDefinitionAnnotation& FunctionDefinition::annotation() const
|
||||||
{
|
{
|
||||||
if (!m_annotation)
|
if (!m_annotation)
|
||||||
m_annotation = new FunctionDefinitionAnnotation();
|
m_annotation = make_unique<FunctionDefinitionAnnotation>();
|
||||||
return dynamic_cast<FunctionDefinitionAnnotation&>(*m_annotation);
|
return dynamic_cast<FunctionDefinitionAnnotation&>(*m_annotation);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -378,7 +373,7 @@ TypePointer ModifierDefinition::type() const
|
|||||||
ModifierDefinitionAnnotation& ModifierDefinition::annotation() const
|
ModifierDefinitionAnnotation& ModifierDefinition::annotation() const
|
||||||
{
|
{
|
||||||
if (!m_annotation)
|
if (!m_annotation)
|
||||||
m_annotation = new ModifierDefinitionAnnotation();
|
m_annotation = make_unique<ModifierDefinitionAnnotation>();
|
||||||
return dynamic_cast<ModifierDefinitionAnnotation&>(*m_annotation);
|
return dynamic_cast<ModifierDefinitionAnnotation&>(*m_annotation);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -398,14 +393,14 @@ FunctionTypePointer EventDefinition::functionType(bool _internal) const
|
|||||||
EventDefinitionAnnotation& EventDefinition::annotation() const
|
EventDefinitionAnnotation& EventDefinition::annotation() const
|
||||||
{
|
{
|
||||||
if (!m_annotation)
|
if (!m_annotation)
|
||||||
m_annotation = new EventDefinitionAnnotation();
|
m_annotation = make_unique<EventDefinitionAnnotation>();
|
||||||
return dynamic_cast<EventDefinitionAnnotation&>(*m_annotation);
|
return dynamic_cast<EventDefinitionAnnotation&>(*m_annotation);
|
||||||
}
|
}
|
||||||
|
|
||||||
UserDefinedTypeNameAnnotation& UserDefinedTypeName::annotation() const
|
UserDefinedTypeNameAnnotation& UserDefinedTypeName::annotation() const
|
||||||
{
|
{
|
||||||
if (!m_annotation)
|
if (!m_annotation)
|
||||||
m_annotation = new UserDefinedTypeNameAnnotation();
|
m_annotation = make_unique<UserDefinedTypeNameAnnotation>();
|
||||||
return dynamic_cast<UserDefinedTypeNameAnnotation&>(*m_annotation);
|
return dynamic_cast<UserDefinedTypeNameAnnotation&>(*m_annotation);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -619,63 +614,63 @@ FunctionTypePointer VariableDeclaration::functionType(bool _internal) const
|
|||||||
VariableDeclarationAnnotation& VariableDeclaration::annotation() const
|
VariableDeclarationAnnotation& VariableDeclaration::annotation() const
|
||||||
{
|
{
|
||||||
if (!m_annotation)
|
if (!m_annotation)
|
||||||
m_annotation = new VariableDeclarationAnnotation();
|
m_annotation = make_unique<VariableDeclarationAnnotation>();
|
||||||
return dynamic_cast<VariableDeclarationAnnotation&>(*m_annotation);
|
return dynamic_cast<VariableDeclarationAnnotation&>(*m_annotation);
|
||||||
}
|
}
|
||||||
|
|
||||||
StatementAnnotation& Statement::annotation() const
|
StatementAnnotation& Statement::annotation() const
|
||||||
{
|
{
|
||||||
if (!m_annotation)
|
if (!m_annotation)
|
||||||
m_annotation = new StatementAnnotation();
|
m_annotation = make_unique<StatementAnnotation>();
|
||||||
return dynamic_cast<StatementAnnotation&>(*m_annotation);
|
return dynamic_cast<StatementAnnotation&>(*m_annotation);
|
||||||
}
|
}
|
||||||
|
|
||||||
InlineAssemblyAnnotation& InlineAssembly::annotation() const
|
InlineAssemblyAnnotation& InlineAssembly::annotation() const
|
||||||
{
|
{
|
||||||
if (!m_annotation)
|
if (!m_annotation)
|
||||||
m_annotation = new InlineAssemblyAnnotation();
|
m_annotation = make_unique<InlineAssemblyAnnotation>();
|
||||||
return dynamic_cast<InlineAssemblyAnnotation&>(*m_annotation);
|
return dynamic_cast<InlineAssemblyAnnotation&>(*m_annotation);
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnAnnotation& Return::annotation() const
|
ReturnAnnotation& Return::annotation() const
|
||||||
{
|
{
|
||||||
if (!m_annotation)
|
if (!m_annotation)
|
||||||
m_annotation = new ReturnAnnotation();
|
m_annotation = make_unique<ReturnAnnotation>();
|
||||||
return dynamic_cast<ReturnAnnotation&>(*m_annotation);
|
return dynamic_cast<ReturnAnnotation&>(*m_annotation);
|
||||||
}
|
}
|
||||||
|
|
||||||
ExpressionAnnotation& Expression::annotation() const
|
ExpressionAnnotation& Expression::annotation() const
|
||||||
{
|
{
|
||||||
if (!m_annotation)
|
if (!m_annotation)
|
||||||
m_annotation = new ExpressionAnnotation();
|
m_annotation = make_unique<ExpressionAnnotation>();
|
||||||
return dynamic_cast<ExpressionAnnotation&>(*m_annotation);
|
return dynamic_cast<ExpressionAnnotation&>(*m_annotation);
|
||||||
}
|
}
|
||||||
|
|
||||||
MemberAccessAnnotation& MemberAccess::annotation() const
|
MemberAccessAnnotation& MemberAccess::annotation() const
|
||||||
{
|
{
|
||||||
if (!m_annotation)
|
if (!m_annotation)
|
||||||
m_annotation = new MemberAccessAnnotation();
|
m_annotation = make_unique<MemberAccessAnnotation>();
|
||||||
return dynamic_cast<MemberAccessAnnotation&>(*m_annotation);
|
return dynamic_cast<MemberAccessAnnotation&>(*m_annotation);
|
||||||
}
|
}
|
||||||
|
|
||||||
BinaryOperationAnnotation& BinaryOperation::annotation() const
|
BinaryOperationAnnotation& BinaryOperation::annotation() const
|
||||||
{
|
{
|
||||||
if (!m_annotation)
|
if (!m_annotation)
|
||||||
m_annotation = new BinaryOperationAnnotation();
|
m_annotation = make_unique<BinaryOperationAnnotation>();
|
||||||
return dynamic_cast<BinaryOperationAnnotation&>(*m_annotation);
|
return dynamic_cast<BinaryOperationAnnotation&>(*m_annotation);
|
||||||
}
|
}
|
||||||
|
|
||||||
FunctionCallAnnotation& FunctionCall::annotation() const
|
FunctionCallAnnotation& FunctionCall::annotation() const
|
||||||
{
|
{
|
||||||
if (!m_annotation)
|
if (!m_annotation)
|
||||||
m_annotation = new FunctionCallAnnotation();
|
m_annotation = make_unique<FunctionCallAnnotation>();
|
||||||
return dynamic_cast<FunctionCallAnnotation&>(*m_annotation);
|
return dynamic_cast<FunctionCallAnnotation&>(*m_annotation);
|
||||||
}
|
}
|
||||||
|
|
||||||
IdentifierAnnotation& Identifier::annotation() const
|
IdentifierAnnotation& Identifier::annotation() const
|
||||||
{
|
{
|
||||||
if (!m_annotation)
|
if (!m_annotation)
|
||||||
m_annotation = new IdentifierAnnotation();
|
m_annotation = make_unique<IdentifierAnnotation>();
|
||||||
return dynamic_cast<IdentifierAnnotation&>(*m_annotation);
|
return dynamic_cast<IdentifierAnnotation&>(*m_annotation);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -67,7 +67,7 @@ public:
|
|||||||
using SourceLocation = langutil::SourceLocation;
|
using SourceLocation = langutil::SourceLocation;
|
||||||
|
|
||||||
explicit ASTNode(SourceLocation const& _location);
|
explicit ASTNode(SourceLocation const& _location);
|
||||||
virtual ~ASTNode();
|
virtual ~ASTNode() {}
|
||||||
|
|
||||||
/// @returns an identifier of this AST node that is unique for a single compilation run.
|
/// @returns an identifier of this AST node that is unique for a single compilation run.
|
||||||
size_t id() const { return m_id; }
|
size_t id() const { return m_id; }
|
||||||
@ -111,7 +111,7 @@ public:
|
|||||||
protected:
|
protected:
|
||||||
size_t const m_id = 0;
|
size_t const m_id = 0;
|
||||||
/// Annotation - is specialised in derived classes, is created upon request (because of polymorphism).
|
/// Annotation - is specialised in derived classes, is created upon request (because of polymorphism).
|
||||||
mutable ASTAnnotation* m_annotation = nullptr;
|
mutable std::unique_ptr<ASTAnnotation> m_annotation;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
SourceLocation m_location;
|
SourceLocation m_location;
|
||||||
|
@ -329,7 +329,7 @@ MemberList const& Type::members(ContractDefinition const* _currentScope) const
|
|||||||
MemberList::MemberMap members = nativeMembers(_currentScope);
|
MemberList::MemberMap members = nativeMembers(_currentScope);
|
||||||
if (_currentScope)
|
if (_currentScope)
|
||||||
members += boundFunctions(*this, *_currentScope);
|
members += boundFunctions(*this, *_currentScope);
|
||||||
m_members[_currentScope] = unique_ptr<MemberList>(new MemberList(move(members)));
|
m_members[_currentScope] = make_unique<MemberList>(move(members));
|
||||||
}
|
}
|
||||||
return *m_members[_currentScope];
|
return *m_members[_currentScope];
|
||||||
}
|
}
|
||||||
|
@ -345,7 +345,7 @@ bool ExpressionCompiler::visit(TupleExpression const& _tuple)
|
|||||||
if (_tuple.components().size() == 1)
|
if (_tuple.components().size() == 1)
|
||||||
m_currentLValue = move(lvalues[0]);
|
m_currentLValue = move(lvalues[0]);
|
||||||
else
|
else
|
||||||
m_currentLValue.reset(new TupleObject(m_context, move(lvalues)));
|
m_currentLValue = make_unique<TupleObject>(m_context, move(lvalues));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
@ -149,7 +149,7 @@ template <class _LValueType, class... _Arguments>
|
|||||||
void ExpressionCompiler::setLValue(Expression const& _expression, _Arguments const&... _arguments)
|
void ExpressionCompiler::setLValue(Expression const& _expression, _Arguments const&... _arguments)
|
||||||
{
|
{
|
||||||
solAssert(!m_currentLValue, "Current LValue not reset before trying to set new one.");
|
solAssert(!m_currentLValue, "Current LValue not reset before trying to set new one.");
|
||||||
std::unique_ptr<_LValueType> lvalue(new _LValueType(m_context, _arguments...));
|
std::unique_ptr<_LValueType> lvalue = std::make_unique<_LValueType>(m_context, _arguments...);
|
||||||
if (_expression.annotation().lValueRequested)
|
if (_expression.annotation().lValueRequested)
|
||||||
m_currentLValue = move(lvalue);
|
m_currentLValue = move(lvalue);
|
||||||
else
|
else
|
||||||
|
@ -529,7 +529,7 @@ string const* CompilerStack::sourceMapping(string const& _contractName) const
|
|||||||
if (!c.sourceMapping)
|
if (!c.sourceMapping)
|
||||||
{
|
{
|
||||||
if (auto items = assemblyItems(_contractName))
|
if (auto items = assemblyItems(_contractName))
|
||||||
c.sourceMapping.reset(new string(computeSourceMapping(*items)));
|
c.sourceMapping = make_unique<string>(computeSourceMapping(*items));
|
||||||
}
|
}
|
||||||
return c.sourceMapping.get();
|
return c.sourceMapping.get();
|
||||||
}
|
}
|
||||||
@ -543,7 +543,7 @@ string const* CompilerStack::runtimeSourceMapping(string const& _contractName) c
|
|||||||
if (!c.runtimeSourceMapping)
|
if (!c.runtimeSourceMapping)
|
||||||
{
|
{
|
||||||
if (auto items = runtimeAssemblyItems(_contractName))
|
if (auto items = runtimeAssemblyItems(_contractName))
|
||||||
c.runtimeSourceMapping.reset(new string(computeSourceMapping(*items)));
|
c.runtimeSourceMapping = make_unique<string>(computeSourceMapping(*items));
|
||||||
}
|
}
|
||||||
return c.runtimeSourceMapping.get();
|
return c.runtimeSourceMapping.get();
|
||||||
}
|
}
|
||||||
@ -680,7 +680,7 @@ Json::Value const& CompilerStack::contractABI(Contract const& _contract) const
|
|||||||
|
|
||||||
// caches the result
|
// caches the result
|
||||||
if (!_contract.abi)
|
if (!_contract.abi)
|
||||||
_contract.abi.reset(new Json::Value(ABI::generate(*_contract.contract)));
|
_contract.abi = make_unique<Json::Value>(ABI::generate(*_contract.contract));
|
||||||
|
|
||||||
return *_contract.abi;
|
return *_contract.abi;
|
||||||
}
|
}
|
||||||
@ -702,7 +702,7 @@ Json::Value const& CompilerStack::storageLayout(Contract const& _contract) const
|
|||||||
|
|
||||||
// caches the result
|
// caches the result
|
||||||
if (!_contract.storageLayout)
|
if (!_contract.storageLayout)
|
||||||
_contract.storageLayout.reset(new Json::Value(StorageLayout().generate(*_contract.contract)));
|
_contract.storageLayout = make_unique<Json::Value>(StorageLayout().generate(*_contract.contract));
|
||||||
|
|
||||||
return *_contract.storageLayout;
|
return *_contract.storageLayout;
|
||||||
}
|
}
|
||||||
@ -724,7 +724,7 @@ Json::Value const& CompilerStack::natspecUser(Contract const& _contract) const
|
|||||||
|
|
||||||
// caches the result
|
// caches the result
|
||||||
if (!_contract.userDocumentation)
|
if (!_contract.userDocumentation)
|
||||||
_contract.userDocumentation.reset(new Json::Value(Natspec::userDocumentation(*_contract.contract)));
|
_contract.userDocumentation = make_unique<Json::Value>(Natspec::userDocumentation(*_contract.contract));
|
||||||
|
|
||||||
return *_contract.userDocumentation;
|
return *_contract.userDocumentation;
|
||||||
}
|
}
|
||||||
@ -746,7 +746,7 @@ Json::Value const& CompilerStack::natspecDev(Contract const& _contract) const
|
|||||||
|
|
||||||
// caches the result
|
// caches the result
|
||||||
if (!_contract.devDocumentation)
|
if (!_contract.devDocumentation)
|
||||||
_contract.devDocumentation.reset(new Json::Value(Natspec::devDocumentation(*_contract.contract)));
|
_contract.devDocumentation = make_unique<Json::Value>(Natspec::devDocumentation(*_contract.contract));
|
||||||
|
|
||||||
return *_contract.devDocumentation;
|
return *_contract.devDocumentation;
|
||||||
}
|
}
|
||||||
@ -779,7 +779,7 @@ string const& CompilerStack::metadata(Contract const& _contract) const
|
|||||||
|
|
||||||
// cache the result
|
// cache the result
|
||||||
if (!_contract.metadata)
|
if (!_contract.metadata)
|
||||||
_contract.metadata.reset(new string(createMetadata(_contract)));
|
_contract.metadata = make_unique<string>(createMetadata(_contract));
|
||||||
|
|
||||||
return *_contract.metadata;
|
return *_contract.metadata;
|
||||||
}
|
}
|
||||||
|
@ -368,7 +368,7 @@ ASTPointer<InheritanceSpecifier> Parser::parseInheritanceSpecifier()
|
|||||||
if (m_scanner->currentToken() == Token::LParen)
|
if (m_scanner->currentToken() == Token::LParen)
|
||||||
{
|
{
|
||||||
m_scanner->next();
|
m_scanner->next();
|
||||||
arguments.reset(new vector<ASTPointer<Expression>>(parseFunctionCallListArguments()));
|
arguments = make_unique<vector<ASTPointer<Expression>>>(parseFunctionCallListArguments());
|
||||||
nodeFactory.markEndPosition();
|
nodeFactory.markEndPosition();
|
||||||
expectToken(Token::RParen);
|
expectToken(Token::RParen);
|
||||||
}
|
}
|
||||||
@ -892,7 +892,7 @@ ASTPointer<ModifierInvocation> Parser::parseModifierInvocation()
|
|||||||
if (m_scanner->currentToken() == Token::LParen)
|
if (m_scanner->currentToken() == Token::LParen)
|
||||||
{
|
{
|
||||||
m_scanner->next();
|
m_scanner->next();
|
||||||
arguments.reset(new vector<ASTPointer<Expression>>(parseFunctionCallListArguments()));
|
arguments = make_unique<vector<ASTPointer<Expression>>>(parseFunctionCallListArguments());
|
||||||
nodeFactory.markEndPosition();
|
nodeFactory.markEndPosition();
|
||||||
expectToken(Token::RParen);
|
expectToken(Token::RParen);
|
||||||
}
|
}
|
||||||
|
@ -210,7 +210,7 @@ Statement Parser::parseStatement()
|
|||||||
|
|
||||||
expectToken(Token::AssemblyAssign);
|
expectToken(Token::AssemblyAssign);
|
||||||
|
|
||||||
assignment.value.reset(new Expression(parseExpression()));
|
assignment.value = make_unique<Expression>(parseExpression());
|
||||||
assignment.location.end = locationOf(*assignment.value).end;
|
assignment.location.end = locationOf(*assignment.value).end;
|
||||||
|
|
||||||
return Statement{std::move(assignment)};
|
return Statement{std::move(assignment)};
|
||||||
|
@ -184,6 +184,18 @@ void OptimiserSuite::run(
|
|||||||
}, ast);
|
}, ast);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
// Prune a bit more in SSA
|
||||||
|
suite.runSequence({
|
||||||
|
ExpressionSplitter::name,
|
||||||
|
SSATransform::name,
|
||||||
|
RedundantAssignEliminator::name,
|
||||||
|
UnusedPruner::name,
|
||||||
|
RedundantAssignEliminator::name,
|
||||||
|
UnusedPruner::name,
|
||||||
|
}, ast);
|
||||||
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
// Turn into SSA again and simplify
|
// Turn into SSA again and simplify
|
||||||
suite.runSequence({
|
suite.runSequence({
|
||||||
|
@ -1003,7 +1003,7 @@ bool CommandLineInterface::processInput()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
m_compiler.reset(new CompilerStack(fileReader));
|
m_compiler = make_unique<CompilerStack>(fileReader);
|
||||||
|
|
||||||
unique_ptr<SourceReferenceFormatter> formatter;
|
unique_ptr<SourceReferenceFormatter> formatter;
|
||||||
if (m_args.count(g_argOldReporter))
|
if (m_args.count(g_argOldReporter))
|
||||||
|
@ -33,24 +33,21 @@
|
|||||||
using namespace std;
|
using namespace std;
|
||||||
using namespace dev;
|
using namespace dev;
|
||||||
using namespace dev::test;
|
using namespace dev::test;
|
||||||
|
using namespace evmc::literals;
|
||||||
|
|
||||||
|
evmc::VM& EVMHost::getVM(string const& _path)
|
||||||
evmc::VM* EVMHost::getVM(string const& _path)
|
|
||||||
{
|
{
|
||||||
static unique_ptr<evmc::VM> theVM;
|
static evmc::VM theVM;
|
||||||
if (!theVM && !_path.empty())
|
if (!theVM && !_path.empty())
|
||||||
{
|
{
|
||||||
evmc_loader_error_code errorCode = {};
|
evmc_loader_error_code errorCode = {};
|
||||||
evmc_vm* vm = evmc_load_and_configure(_path.c_str(), &errorCode);
|
auto vm = evmc::VM{evmc_load_and_configure(_path.c_str(), &errorCode)};
|
||||||
if (vm && errorCode == EVMC_LOADER_SUCCESS)
|
if (vm && errorCode == EVMC_LOADER_SUCCESS)
|
||||||
{
|
{
|
||||||
if (evmc_vm_has_capability(vm, EVMC_CAPABILITY_EVM1))
|
if (vm.get_capabilities() & EVMC_CAPABILITY_EVM1)
|
||||||
theVM = make_unique<evmc::VM>(vm);
|
theVM = std::move(vm);
|
||||||
else
|
else
|
||||||
{
|
|
||||||
evmc_destroy(vm);
|
|
||||||
cerr << "VM loaded does not support EVM1" << endl;
|
cerr << "VM loaded does not support EVM1" << endl;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -60,10 +57,10 @@ evmc::VM* EVMHost::getVM(string const& _path)
|
|||||||
cerr << endl;
|
cerr << endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return theVM.get();
|
return theVM;
|
||||||
}
|
}
|
||||||
|
|
||||||
EVMHost::EVMHost(langutil::EVMVersion _evmVersion, evmc::VM* _vm):
|
EVMHost::EVMHost(langutil::EVMVersion _evmVersion, evmc::VM& _vm):
|
||||||
m_vm(_vm),
|
m_vm(_vm),
|
||||||
m_evmVersion(_evmVersion)
|
m_evmVersion(_evmVersion)
|
||||||
{
|
{
|
||||||
@ -118,21 +115,21 @@ void EVMHost::selfdestruct(const evmc::address& _addr, const evmc::address& _ben
|
|||||||
|
|
||||||
evmc::result EVMHost::call(evmc_message const& _message) noexcept
|
evmc::result EVMHost::call(evmc_message const& _message) noexcept
|
||||||
{
|
{
|
||||||
if (_message.destination == convertToEVMC(Address(1)))
|
if (_message.destination == 0x0000000000000000000000000000000000000001_address)
|
||||||
return precompileECRecover(_message);
|
return precompileECRecover(_message);
|
||||||
else if (_message.destination == convertToEVMC(Address(2)))
|
else if (_message.destination == 0x0000000000000000000000000000000000000002_address)
|
||||||
return precompileSha256(_message);
|
return precompileSha256(_message);
|
||||||
else if (_message.destination == convertToEVMC(Address(3)))
|
else if (_message.destination == 0x0000000000000000000000000000000000000003_address)
|
||||||
return precompileRipeMD160(_message);
|
return precompileRipeMD160(_message);
|
||||||
else if (_message.destination == convertToEVMC(Address(4)))
|
else if (_message.destination == 0x0000000000000000000000000000000000000004_address)
|
||||||
return precompileIdentity(_message);
|
return precompileIdentity(_message);
|
||||||
else if (_message.destination == convertToEVMC(Address(5)))
|
else if (_message.destination == 0x0000000000000000000000000000000000000005_address)
|
||||||
return precompileModExp(_message);
|
return precompileModExp(_message);
|
||||||
else if (_message.destination == convertToEVMC(Address(6)))
|
else if (_message.destination == 0x0000000000000000000000000000000000000006_address)
|
||||||
return precompileALTBN128G1Add(_message);
|
return precompileALTBN128G1Add(_message);
|
||||||
else if (_message.destination == convertToEVMC(Address(7)))
|
else if (_message.destination == 0x0000000000000000000000000000000000000007_address)
|
||||||
return precompileALTBN128G1Mul(_message);
|
return precompileALTBN128G1Mul(_message);
|
||||||
else if (_message.destination == convertToEVMC(Address(8)))
|
else if (_message.destination == 0x0000000000000000000000000000000000000008_address)
|
||||||
return precompileALTBN128PairingProduct(_message);
|
return precompileALTBN128PairingProduct(_message);
|
||||||
|
|
||||||
State stateBackup = m_state;
|
State stateBackup = m_state;
|
||||||
@ -192,7 +189,7 @@ evmc::result EVMHost::call(evmc_message const& _message) noexcept
|
|||||||
|
|
||||||
evmc::address currentAddress = m_currentAddress;
|
evmc::address currentAddress = m_currentAddress;
|
||||||
m_currentAddress = message.destination;
|
m_currentAddress = message.destination;
|
||||||
evmc::result result = m_vm->execute(*this, m_evmRevision, message, code.data(), code.size());
|
evmc::result result = m_vm.execute(*this, m_evmRevision, message, code.data(), code.size());
|
||||||
m_currentAddress = currentAddress;
|
m_currentAddress = currentAddress;
|
||||||
|
|
||||||
if (message.kind == EVMC_CREATE)
|
if (message.kind == EVMC_CREATE)
|
||||||
@ -224,10 +221,11 @@ evmc_tx_context EVMHost::get_tx_context() noexcept
|
|||||||
ctx.block_timestamp = m_state.timestamp;
|
ctx.block_timestamp = m_state.timestamp;
|
||||||
ctx.block_number = m_state.blockNumber;
|
ctx.block_number = m_state.blockNumber;
|
||||||
ctx.block_coinbase = m_coinbase;
|
ctx.block_coinbase = m_coinbase;
|
||||||
|
// TODO: support short literals in EVMC and use them here
|
||||||
ctx.block_difficulty = convertToEVMC(u256("200000000"));
|
ctx.block_difficulty = convertToEVMC(u256("200000000"));
|
||||||
ctx.block_gas_limit = 20000000;
|
ctx.block_gas_limit = 20000000;
|
||||||
ctx.tx_gas_price = convertToEVMC(u256("3000000000"));
|
ctx.tx_gas_price = convertToEVMC(u256("3000000000"));
|
||||||
ctx.tx_origin = convertToEVMC(Address("0x9292929292929292929292929292929292929292"));
|
ctx.tx_origin = 0x9292929292929292929292929292929292929292_address;
|
||||||
// Mainnet according to EIP-155
|
// Mainnet according to EIP-155
|
||||||
ctx.chain_id = convertToEVMC(u256(1));
|
ctx.chain_id = convertToEVMC(u256(1));
|
||||||
return ctx;
|
return ctx;
|
||||||
|
@ -40,9 +40,9 @@ public:
|
|||||||
/// Tries to dynamically load libevmone. @returns nullptr on failure.
|
/// Tries to dynamically load libevmone. @returns nullptr on failure.
|
||||||
/// The path has to be provided for the first successful run and will be ignored
|
/// The path has to be provided for the first successful run and will be ignored
|
||||||
/// afterwards.
|
/// afterwards.
|
||||||
static evmc::VM* getVM(std::string const& _path = {});
|
static evmc::VM& getVM(std::string const& _path = {});
|
||||||
|
|
||||||
explicit EVMHost(langutil::EVMVersion _evmVersion, evmc::VM* _vm = getVM());
|
explicit EVMHost(langutil::EVMVersion _evmVersion, evmc::VM& _vm = getVM());
|
||||||
|
|
||||||
struct Account
|
struct Account
|
||||||
{
|
{
|
||||||
@ -179,7 +179,7 @@ private:
|
|||||||
/// @note The return value is only valid as long as @a _data is alive!
|
/// @note The return value is only valid as long as @a _data is alive!
|
||||||
static evmc::result resultWithGas(evmc_message const& _message, bytes const& _data) noexcept;
|
static evmc::result resultWithGas(evmc_message const& _message, bytes const& _data) noexcept;
|
||||||
|
|
||||||
evmc::VM* m_vm = nullptr;
|
evmc::VM& m_vm;
|
||||||
// EVM version requested by the testing tool
|
// EVM version requested by the testing tool
|
||||||
langutil::EVMVersion m_evmVersion;
|
langutil::EVMVersion m_evmVersion;
|
||||||
// EVM version requested from EVMC (matches the above)
|
// EVM version requested from EVMC (matches the above)
|
||||||
|
@ -96,7 +96,7 @@ int registerTests(
|
|||||||
{
|
{
|
||||||
static vector<unique_ptr<string>> filenames;
|
static vector<unique_ptr<string>> filenames;
|
||||||
|
|
||||||
filenames.emplace_back(new string(_path.string()));
|
filenames.emplace_back(make_unique<string>(_path.string()));
|
||||||
_suite.add(make_test_case(
|
_suite.add(make_test_case(
|
||||||
[config, _testCaseCreator]
|
[config, _testCaseCreator]
|
||||||
{
|
{
|
||||||
|
@ -223,7 +223,7 @@ protected:
|
|||||||
void deployRegistrar()
|
void deployRegistrar()
|
||||||
{
|
{
|
||||||
if (!s_compiledRegistrar)
|
if (!s_compiledRegistrar)
|
||||||
s_compiledRegistrar.reset(new bytes(compileContract(registrarCode, "GlobalRegistrar")));
|
s_compiledRegistrar = make_unique<bytes>(compileContract(registrarCode, "GlobalRegistrar"));
|
||||||
|
|
||||||
sendMessage(*s_compiledRegistrar, true);
|
sendMessage(*s_compiledRegistrar, true);
|
||||||
BOOST_REQUIRE(m_transactionSuccessful);
|
BOOST_REQUIRE(m_transactionSuccessful);
|
||||||
|
@ -132,7 +132,7 @@ protected:
|
|||||||
void deployRegistrar()
|
void deployRegistrar()
|
||||||
{
|
{
|
||||||
if (!s_compiledRegistrar)
|
if (!s_compiledRegistrar)
|
||||||
s_compiledRegistrar.reset(new bytes(compileContract(registrarCode, "FixedFeeRegistrar")));
|
s_compiledRegistrar = make_unique<bytes>(compileContract(registrarCode, "FixedFeeRegistrar"));
|
||||||
|
|
||||||
sendMessage(*s_compiledRegistrar, true);
|
sendMessage(*s_compiledRegistrar, true);
|
||||||
BOOST_REQUIRE(m_transactionSuccessful);
|
BOOST_REQUIRE(m_transactionSuccessful);
|
||||||
|
@ -451,7 +451,7 @@ protected:
|
|||||||
)
|
)
|
||||||
{
|
{
|
||||||
if (!s_compiledWallet)
|
if (!s_compiledWallet)
|
||||||
s_compiledWallet.reset(new bytes(compileContract(walletCode, "Wallet")));
|
s_compiledWallet = make_unique<bytes>(compileContract(walletCode, "Wallet"));
|
||||||
|
|
||||||
bytes args = encodeArgs(u256(0x60), _required, _dailyLimit, u256(_owners.size()), _owners);
|
bytes args = encodeArgs(u256(0x60), _required, _dailyLimit, u256(_owners.size()), _owners);
|
||||||
sendMessage(*s_compiledWallet + args, true, _value);
|
sendMessage(*s_compiledWallet + args, true, _value);
|
||||||
|
@ -18,7 +18,7 @@
|
|||||||
* Unit tests for the StringUtils routines.
|
* Unit tests for the StringUtils routines.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <libdevcore/Common.h>
|
||||||
#include <libdevcore/CommonData.h>
|
#include <libdevcore/CommonData.h>
|
||||||
#include <libdevcore/FixedHash.h>
|
#include <libdevcore/FixedHash.h>
|
||||||
#include <libsolidity/ast/Types.h> // for IntegerType
|
#include <libsolidity/ast/Types.h> // for IntegerType
|
||||||
@ -28,6 +28,9 @@
|
|||||||
using namespace std;
|
using namespace std;
|
||||||
using namespace dev::solidity;
|
using namespace dev::solidity;
|
||||||
|
|
||||||
|
// TODO: Fix Boost...
|
||||||
|
BOOST_TEST_DONT_PRINT_LOG_VALUE(dev::bytes);
|
||||||
|
|
||||||
namespace dev
|
namespace dev
|
||||||
{
|
{
|
||||||
namespace test
|
namespace test
|
||||||
@ -35,9 +38,62 @@ namespace test
|
|||||||
|
|
||||||
BOOST_AUTO_TEST_SUITE(CommonData)
|
BOOST_AUTO_TEST_SUITE(CommonData)
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(test_to_hex)
|
BOOST_AUTO_TEST_CASE(fromhex_char)
|
||||||
{
|
{
|
||||||
BOOST_CHECK_EQUAL(toHex(fromHex("FF"), HexPrefix::DontAdd, HexCase::Lower), "ff");
|
BOOST_CHECK_EQUAL(fromHex('0', WhenError::DontThrow), 0x0);
|
||||||
|
BOOST_CHECK_EQUAL(fromHex('a', WhenError::DontThrow), 0xa);
|
||||||
|
BOOST_CHECK_EQUAL(fromHex('x', WhenError::DontThrow), -1);
|
||||||
|
BOOST_CHECK_EQUAL(fromHex('x', static_cast<WhenError>(42)), -1);
|
||||||
|
|
||||||
|
BOOST_CHECK_EQUAL(fromHex('0', WhenError::Throw), 0x0);
|
||||||
|
BOOST_CHECK_EQUAL(fromHex('a', WhenError::Throw), 0xa);
|
||||||
|
BOOST_CHECK_THROW(fromHex('x', WhenError::Throw), BadHexCharacter);
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(fromhex_string)
|
||||||
|
{
|
||||||
|
bytes expectation_even = {{0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff}};
|
||||||
|
bytes expectation_odd = {{0x00, 0x01, 0x12, 0x23, 0x34, 0x45, 0x56, 0x67, 0x78, 0x89, 0x9a, 0xab, 0xbc, 0xcd, 0xde, 0xef, 0xf0}};
|
||||||
|
|
||||||
|
// Defaults to WhenError::DontThrow
|
||||||
|
BOOST_CHECK_EQUAL(fromHex(""), bytes());
|
||||||
|
BOOST_CHECK_EQUAL(fromHex("00112233445566778899aabbccddeeff"), expectation_even);
|
||||||
|
BOOST_CHECK_EQUAL(fromHex("0x00112233445566778899aabbccddeeff"), expectation_even);
|
||||||
|
BOOST_CHECK_EQUAL(fromHex("0x00112233445566778899aabbccddeeff0"), expectation_odd);
|
||||||
|
BOOST_CHECK_EQUAL(fromHex("gg"), bytes());
|
||||||
|
BOOST_CHECK_EQUAL(fromHex("0xgg"), bytes());
|
||||||
|
|
||||||
|
BOOST_CHECK_EQUAL(fromHex("", WhenError::Throw), bytes());
|
||||||
|
BOOST_CHECK_EQUAL(fromHex("00112233445566778899aabbccddeeff", WhenError::Throw), expectation_even);
|
||||||
|
BOOST_CHECK_EQUAL(fromHex("0x00112233445566778899aabbccddeeff", WhenError::Throw), expectation_even);
|
||||||
|
BOOST_CHECK_EQUAL(fromHex("0x00112233445566778899aabbccddeeff0", WhenError::Throw), expectation_odd);
|
||||||
|
BOOST_CHECK_THROW(fromHex("gg", WhenError::Throw), BadHexCharacter);
|
||||||
|
BOOST_CHECK_THROW(fromHex("0xgg", WhenError::Throw), BadHexCharacter);
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(tohex_uint8)
|
||||||
|
{
|
||||||
|
BOOST_CHECK_EQUAL(toHex(0xaa), "aa");
|
||||||
|
BOOST_CHECK_EQUAL(toHex(0xaa, HexCase::Lower), "aa");
|
||||||
|
BOOST_CHECK_EQUAL(toHex(0xaa, HexCase::Upper), "AA");
|
||||||
|
BOOST_CHECK_THROW(toHex(0xaa, HexCase::Mixed), BadHexCase);
|
||||||
|
// Defaults to lower case on invalid setting.
|
||||||
|
BOOST_CHECK_EQUAL(toHex(0xaa, static_cast<HexCase>(42)), "aa");
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(tohex_bytes)
|
||||||
|
{
|
||||||
|
BOOST_CHECK_EQUAL(toHex(fromHex("00112233445566778899aAbBcCdDeEfF"), HexPrefix::DontAdd, HexCase::Lower), "00112233445566778899aabbccddeeff");
|
||||||
|
BOOST_CHECK_EQUAL(toHex(fromHex("00112233445566778899aAbBcCdDeEfF"), HexPrefix::DontAdd, HexCase::Upper), "00112233445566778899AABBCCDDEEFF");
|
||||||
|
BOOST_CHECK_EQUAL(toHex(fromHex("00112233445566778899aAbBcCdDeEfF"), HexPrefix::DontAdd, HexCase::Mixed), "00112233445566778899aabbCCDDeeff");
|
||||||
|
// Defaults to lower case on invalid setting.
|
||||||
|
BOOST_CHECK_EQUAL(toHex(fromHex("00112233445566778899aAbBcCdDeEfF"), HexPrefix::DontAdd, static_cast<HexCase>(42)), "00112233445566778899aabbccddeeff");
|
||||||
|
|
||||||
|
BOOST_CHECK_EQUAL(toHex(fromHex("00112233445566778899aAbBcCdDeEfF"), HexPrefix::Add, HexCase::Lower), "0x00112233445566778899aabbccddeeff");
|
||||||
|
BOOST_CHECK_EQUAL(toHex(fromHex("00112233445566778899aAbBcCdDeEfF"), HexPrefix::Add, HexCase::Upper), "0x00112233445566778899AABBCCDDEEFF");
|
||||||
|
BOOST_CHECK_EQUAL(toHex(fromHex("00112233445566778899AaBbCcDdEeFf"), HexPrefix::Add, HexCase::Mixed), "0x00112233445566778899aabbCCDDeeff");
|
||||||
|
// Defaults to lower case on invalid setting.
|
||||||
|
BOOST_CHECK_EQUAL(toHex(fromHex("00112233445566778899aAbBcCdDeEfF"), HexPrefix::Add, static_cast<HexCase>(42)), "0x00112233445566778899aabbccddeeff");
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(test_format_number)
|
BOOST_AUTO_TEST_CASE(test_format_number)
|
||||||
|
@ -36,7 +36,7 @@ class ABIJsonTest: public TestCase
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
static std::unique_ptr<TestCase> create(Config const& _config)
|
static std::unique_ptr<TestCase> create(Config const& _config)
|
||||||
{ return std::unique_ptr<TestCase>(new ABIJsonTest(_config.filename)); }
|
{ return std::make_unique<ABIJsonTest>(_config.filename); }
|
||||||
ABIJsonTest(std::string const& _filename);
|
ABIJsonTest(std::string const& _filename);
|
||||||
|
|
||||||
TestResult run(std::ostream& _stream, std::string const& _linePrefix = "", bool const _formatted = false) override;
|
TestResult run(std::ostream& _stream, std::string const& _linePrefix = "", bool const _formatted = false) override;
|
||||||
|
@ -36,7 +36,7 @@ class ASTJSONTest: public TestCase
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
static std::unique_ptr<TestCase> create(Config const& _config)
|
static std::unique_ptr<TestCase> create(Config const& _config)
|
||||||
{ return std::unique_ptr<TestCase>(new ASTJSONTest(_config.filename)); }
|
{ return std::make_unique<ASTJSONTest>(_config.filename); }
|
||||||
ASTJSONTest(std::string const& _filename);
|
ASTJSONTest(std::string const& _filename);
|
||||||
|
|
||||||
TestResult run(std::ostream& _stream, std::string const& _linePrefix = "", bool const _formatted = false) override;
|
TestResult run(std::ostream& _stream, std::string const& _linePrefix = "", bool const _formatted = false) override;
|
||||||
|
@ -37,7 +37,7 @@ class EWasmTranslationTest: public dev::solidity::test::EVMVersionRestrictedTest
|
|||||||
public:
|
public:
|
||||||
static std::unique_ptr<TestCase> create(Config const& _config)
|
static std::unique_ptr<TestCase> create(Config const& _config)
|
||||||
{
|
{
|
||||||
return std::unique_ptr<TestCase>(new EWasmTranslationTest(_config.filename));
|
return std::make_unique<EWasmTranslationTest>(_config.filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
explicit EWasmTranslationTest(std::string const& _filename);
|
explicit EWasmTranslationTest(std::string const& _filename);
|
||||||
|
@ -34,7 +34,7 @@ class FunctionSideEffects: public dev::solidity::test::TestCase
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
static std::unique_ptr<TestCase> create(Config const& _config)
|
static std::unique_ptr<TestCase> create(Config const& _config)
|
||||||
{ return std::unique_ptr<TestCase>(new FunctionSideEffects(_config.filename)); }
|
{ return std::make_unique<FunctionSideEffects>(_config.filename); }
|
||||||
explicit FunctionSideEffects(std::string const& _filename);
|
explicit FunctionSideEffects(std::string const& _filename);
|
||||||
|
|
||||||
TestResult run(std::ostream& _stream, std::string const& _linePrefix = "", bool const _formatted = false) override;
|
TestResult run(std::ostream& _stream, std::string const& _linePrefix = "", bool const _formatted = false) override;
|
||||||
|
@ -42,7 +42,7 @@ class ObjectCompilerTest: public dev::solidity::test::TestCase
|
|||||||
public:
|
public:
|
||||||
static std::unique_ptr<TestCase> create(Config const& _config)
|
static std::unique_ptr<TestCase> create(Config const& _config)
|
||||||
{
|
{
|
||||||
return std::unique_ptr<TestCase>(new ObjectCompilerTest(_config.filename));
|
return std::make_unique<ObjectCompilerTest>(_config.filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
explicit ObjectCompilerTest(std::string const& _filename);
|
explicit ObjectCompilerTest(std::string const& _filename);
|
||||||
|
@ -42,7 +42,7 @@ class YulInterpreterTest: public dev::solidity::test::EVMVersionRestrictedTestCa
|
|||||||
public:
|
public:
|
||||||
static std::unique_ptr<TestCase> create(Config const& _config)
|
static std::unique_ptr<TestCase> create(Config const& _config)
|
||||||
{
|
{
|
||||||
return std::unique_ptr<TestCase>(new YulInterpreterTest(_config.filename));
|
return std::make_unique<YulInterpreterTest>(_config.filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
explicit YulInterpreterTest(std::string const& _filename);
|
explicit YulInterpreterTest(std::string const& _filename);
|
||||||
|
@ -424,7 +424,11 @@ void YulOptimizerTest::disambiguate()
|
|||||||
void YulOptimizerTest::updateContext()
|
void YulOptimizerTest::updateContext()
|
||||||
{
|
{
|
||||||
m_nameDispenser = make_unique<NameDispenser>(*m_dialect, *m_ast, m_reservedIdentifiers);
|
m_nameDispenser = make_unique<NameDispenser>(*m_dialect, *m_ast, m_reservedIdentifiers);
|
||||||
m_context = unique_ptr<OptimiserStepContext>(new OptimiserStepContext{*m_dialect, *m_nameDispenser, m_reservedIdentifiers});
|
m_context = make_unique<OptimiserStepContext>(OptimiserStepContext{
|
||||||
|
*m_dialect,
|
||||||
|
*m_nameDispenser,
|
||||||
|
m_reservedIdentifiers
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void YulOptimizerTest::printErrors(ostream& _stream, ErrorList const& _errors)
|
void YulOptimizerTest::printErrors(ostream& _stream, ErrorList const& _errors)
|
||||||
|
@ -51,7 +51,7 @@ class YulOptimizerTest: public dev::solidity::test::EVMVersionRestrictedTestCase
|
|||||||
public:
|
public:
|
||||||
static std::unique_ptr<TestCase> create(Config const& _config)
|
static std::unique_ptr<TestCase> create(Config const& _config)
|
||||||
{
|
{
|
||||||
return std::unique_ptr<TestCase>(new YulOptimizerTest(_config.filename));
|
return std::make_unique<YulOptimizerTest>(_config.filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
explicit YulOptimizerTest(std::string const& _filename);
|
explicit YulOptimizerTest(std::string const& _filename);
|
||||||
|
@ -0,0 +1,20 @@
|
|||||||
|
{
|
||||||
|
let x := 0
|
||||||
|
switch mload(x)
|
||||||
|
case 0 { x := x }
|
||||||
|
case 1 { x := 1 }
|
||||||
|
default { invalid() }
|
||||||
|
mstore(1, 1)
|
||||||
|
}
|
||||||
|
// ====
|
||||||
|
// step: fullSuite
|
||||||
|
// ----
|
||||||
|
// {
|
||||||
|
// {
|
||||||
|
// switch mload(0)
|
||||||
|
// case 0 { }
|
||||||
|
// case 1 { }
|
||||||
|
// default { invalid() }
|
||||||
|
// mstore(1, 1)
|
||||||
|
// }
|
||||||
|
// }
|
@ -142,7 +142,7 @@ DEFINE_PROTO_FUZZER(Contract const& _input)
|
|||||||
|
|
||||||
// We target the default EVM which is the latest
|
// We target the default EVM which is the latest
|
||||||
langutil::EVMVersion version = {};
|
langutil::EVMVersion version = {};
|
||||||
EVMHost hostContext(version, &evmone);
|
EVMHost hostContext(version, evmone);
|
||||||
|
|
||||||
// Deploy contract and signal failure if deploy failed
|
// Deploy contract and signal failure if deploy failed
|
||||||
evmc::result createResult = deployContract(hostContext, byteCode);
|
evmc::result createResult = deployContract(hostContext, byteCode);
|
||||||
|
@ -90,12 +90,35 @@ string ProtoConverter::visit(Literal const& _x)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ProtoConverter::consolidateVarDeclsInFunctionDef()
|
||||||
|
{
|
||||||
|
m_currentFuncVars.clear();
|
||||||
|
auto const& scopes = m_funcVars.back();
|
||||||
|
for (auto const& s: scopes)
|
||||||
|
for (auto const& var: s)
|
||||||
|
m_currentFuncVars.push_back(&var);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ProtoConverter::consolidateGlobalVarDecls()
|
||||||
|
{
|
||||||
|
m_currentGlobalVars.clear();
|
||||||
|
for (auto const& scope: m_globalVars)
|
||||||
|
for (auto const& var: scope)
|
||||||
|
m_currentGlobalVars.push_back(&var);
|
||||||
|
}
|
||||||
|
|
||||||
bool ProtoConverter::varDeclAvailable()
|
bool ProtoConverter::varDeclAvailable()
|
||||||
{
|
{
|
||||||
if (m_inFunctionDef)
|
if (m_inFunctionDef)
|
||||||
return m_scopeVars.top().size() > 0;
|
{
|
||||||
|
consolidateVarDeclsInFunctionDef();
|
||||||
|
return m_currentFuncVars.size() > 0;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
return m_variables.size() > 0;
|
{
|
||||||
|
consolidateGlobalVarDecls();
|
||||||
|
return m_currentGlobalVars.size() > 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ProtoConverter::functionCallNotPossible(FunctionCall_Returns _type)
|
bool ProtoConverter::functionCallNotPossible(FunctionCall_Returns _type)
|
||||||
@ -109,14 +132,14 @@ void ProtoConverter::visit(VarRef const& _x)
|
|||||||
if (m_inFunctionDef)
|
if (m_inFunctionDef)
|
||||||
{
|
{
|
||||||
// Ensure that there is at least one variable declaration to reference in function scope.
|
// Ensure that there is at least one variable declaration to reference in function scope.
|
||||||
yulAssert(m_scopeVars.top().size() > 0, "Proto fuzzer: No variables to reference.");
|
yulAssert(m_currentFuncVars.size() > 0, "Proto fuzzer: No variables to reference.");
|
||||||
m_output << m_scopeVars.top()[_x.varnum() % m_scopeVars.top().size()];
|
m_output << *m_currentFuncVars[_x.varnum() % m_currentFuncVars.size()];
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Ensure that there is at least one variable declaration to reference in nested scopes.
|
// Ensure that there is at least one variable declaration to reference in nested scopes.
|
||||||
yulAssert(m_variables.size() > 0, "Proto fuzzer: No variables to reference.");
|
yulAssert(m_currentGlobalVars.size() > 0, "Proto fuzzer: No global variables to reference.");
|
||||||
m_output << m_variables[_x.varnum() % m_variables.size()];
|
m_output << *m_currentGlobalVars[_x.varnum() % m_currentGlobalVars.size()];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -258,8 +281,10 @@ void ProtoConverter::visit(VarDecl const& _x)
|
|||||||
m_output << "let " << varName << " := ";
|
m_output << "let " << varName << " := ";
|
||||||
visit(_x.expr());
|
visit(_x.expr());
|
||||||
m_output << "\n";
|
m_output << "\n";
|
||||||
m_scopeVars.top().push_back(varName);
|
if (m_inFunctionDef)
|
||||||
m_variables.push_back(varName);
|
m_funcVars.back().back().push_back(varName);
|
||||||
|
else
|
||||||
|
m_globalVars.back().push_back(varName);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ProtoConverter::visit(TypedVarDecl const& _x)
|
void ProtoConverter::visit(TypedVarDecl const& _x)
|
||||||
@ -324,8 +349,10 @@ void ProtoConverter::visit(TypedVarDecl const& _x)
|
|||||||
m_output << " : u256\n";
|
m_output << " : u256\n";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
m_scopeVars.top().push_back(varName);
|
if (m_inFunctionDef)
|
||||||
m_variables.push_back(varName);
|
m_funcVars.back().back().push_back(varName);
|
||||||
|
else
|
||||||
|
m_globalVars.back().push_back(varName);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ProtoConverter::visit(UnaryOp const& _x)
|
void ProtoConverter::visit(UnaryOp const& _x)
|
||||||
@ -1106,12 +1133,19 @@ void ProtoConverter::visit(Statement const& _x)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ProtoConverter::openScope(vector<string> const& _funcParams)
|
void ProtoConverter::openBlockScope()
|
||||||
{
|
{
|
||||||
m_scopeVars.push({});
|
m_scopeFuncs.push_back({});
|
||||||
m_scopeFuncs.push({});
|
// Create new block scope inside current function scope
|
||||||
if (!_funcParams.empty())
|
if (m_inFunctionDef)
|
||||||
addVarsToScope(_funcParams);
|
m_funcVars.back().push_back(vector<string>{});
|
||||||
|
else
|
||||||
|
m_globalVars.push_back(vector<string>{});
|
||||||
|
}
|
||||||
|
|
||||||
|
void ProtoConverter::openFunctionScope(vector<string> const& _funcParams)
|
||||||
|
{
|
||||||
|
m_funcVars.push_back(vector<vector<string>>({_funcParams}));
|
||||||
}
|
}
|
||||||
|
|
||||||
void ProtoConverter::updateFunctionMaps(string const& _var)
|
void ProtoConverter::updateFunctionMaps(string const& _var)
|
||||||
@ -1128,21 +1162,9 @@ void ProtoConverter::updateFunctionMaps(string const& _var)
|
|||||||
yulAssert(erased == 2, "Proto fuzzer: Function maps not updated");
|
yulAssert(erased == 2, "Proto fuzzer: Function maps not updated");
|
||||||
}
|
}
|
||||||
|
|
||||||
void ProtoConverter::closeScope()
|
void ProtoConverter::closeBlockScope()
|
||||||
{
|
{
|
||||||
for (auto const& var: m_scopeVars.top())
|
for (auto const& f: m_scopeFuncs.back())
|
||||||
{
|
|
||||||
unsigned numVarsRemoved = m_variables.size();
|
|
||||||
m_variables.erase(remove(m_variables.begin(), m_variables.end(), var), m_variables.end());
|
|
||||||
numVarsRemoved -= m_variables.size();
|
|
||||||
yulAssert(
|
|
||||||
numVarsRemoved == 1,
|
|
||||||
"Proto fuzzer: Nothing or too much went out of scope"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
m_scopeVars.pop();
|
|
||||||
|
|
||||||
for (auto const& f: m_scopeFuncs.top())
|
|
||||||
{
|
{
|
||||||
unsigned numFuncsRemoved = m_functions.size();
|
unsigned numFuncsRemoved = m_functions.size();
|
||||||
m_functions.erase(remove(m_functions.begin(), m_functions.end(), f), m_functions.end());
|
m_functions.erase(remove(m_functions.begin(), m_functions.end(), f), m_functions.end());
|
||||||
@ -1153,21 +1175,40 @@ void ProtoConverter::closeScope()
|
|||||||
);
|
);
|
||||||
updateFunctionMaps(f);
|
updateFunctionMaps(f);
|
||||||
}
|
}
|
||||||
m_scopeFuncs.pop();
|
if (!m_scopeFuncs.empty())
|
||||||
|
m_scopeFuncs.pop_back();
|
||||||
|
if (!m_inFunctionDef)
|
||||||
|
{
|
||||||
|
if (!m_globalVars.empty())
|
||||||
|
m_globalVars.pop_back();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Variables that have been declared in a
|
||||||
|
// function block, go out of scope
|
||||||
|
if (!m_funcVars.empty())
|
||||||
|
if (!m_funcVars.back().empty())
|
||||||
|
m_funcVars.back().pop_back();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ProtoConverter::closeFunctionScope()
|
||||||
|
{
|
||||||
|
if (!m_funcVars.empty())
|
||||||
|
m_funcVars.pop_back();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ProtoConverter::addVarsToScope(vector<string> const& _vars)
|
void ProtoConverter::addVarsToScope(vector<string> const& _vars)
|
||||||
{
|
{
|
||||||
for (string const& i: _vars)
|
if (m_inFunctionDef)
|
||||||
{
|
m_funcVars.back().back().insert(m_funcVars.back().back().end(), _vars.begin(), _vars.end());
|
||||||
m_variables.push_back(i);
|
else
|
||||||
m_scopeVars.top().push_back(i);
|
m_globalVars.back().insert(m_globalVars.back().end(), _vars.begin(), _vars.end());
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ProtoConverter::visit(Block const& _x, vector<string> _funcParams)
|
void ProtoConverter::visit(Block const& _x)
|
||||||
{
|
{
|
||||||
openScope(_funcParams);
|
openBlockScope();
|
||||||
|
|
||||||
// Register function declarations in this scope unless this
|
// Register function declarations in this scope unless this
|
||||||
// scope belongs to for-init (in which function declarations
|
// scope belongs to for-init (in which function declarations
|
||||||
@ -1185,7 +1226,7 @@ void ProtoConverter::visit(Block const& _x, vector<string> _funcParams)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
m_output << "{}\n";
|
m_output << "{}\n";
|
||||||
closeScope();
|
closeBlockScope();
|
||||||
}
|
}
|
||||||
|
|
||||||
vector<string> ProtoConverter::createVars(unsigned _startIdx, unsigned _endIdx)
|
vector<string> ProtoConverter::createVars(unsigned _startIdx, unsigned _endIdx)
|
||||||
@ -1228,7 +1269,7 @@ void ProtoConverter::registerFunction(FunctionDef const* _x)
|
|||||||
auto ret = m_functionSigMap.emplace(make_pair(funcName, make_pair(numInParams, numOutParams)));
|
auto ret = m_functionSigMap.emplace(make_pair(funcName, make_pair(numInParams, numOutParams)));
|
||||||
yulAssert(ret.second, "Proto fuzzer: Function already exists.");
|
yulAssert(ret.second, "Proto fuzzer: Function already exists.");
|
||||||
m_functions.push_back(funcName);
|
m_functions.push_back(funcName);
|
||||||
m_scopeFuncs.top().push_back(funcName);
|
m_scopeFuncs.back().push_back(funcName);
|
||||||
m_functionDefMap.emplace(make_pair(_x, funcName));
|
m_functionDefMap.emplace(make_pair(_x, funcName));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1367,8 +1408,12 @@ void ProtoConverter::createFunctionDefAndCall(
|
|||||||
bool wasInFunctionDef = m_inFunctionDef;
|
bool wasInFunctionDef = m_inFunctionDef;
|
||||||
m_inFunctionDef = true;
|
m_inFunctionDef = true;
|
||||||
|
|
||||||
// Body
|
// Create new function scope and add function input and return
|
||||||
visit(_x.block(), varsVec);
|
// parameters to it.
|
||||||
|
openFunctionScope(varsVec);
|
||||||
|
// Visit function body
|
||||||
|
visit(_x.block());
|
||||||
|
closeFunctionScope();
|
||||||
|
|
||||||
m_inForBodyScope = wasInForBody;
|
m_inForBodyScope = wasInForBody;
|
||||||
m_inFunctionDef = wasInFunctionDef;
|
m_inFunctionDef = wasInFunctionDef;
|
||||||
|
@ -42,6 +42,8 @@ class ProtoConverter
|
|||||||
public:
|
public:
|
||||||
ProtoConverter()
|
ProtoConverter()
|
||||||
{
|
{
|
||||||
|
m_funcVars = std::vector<std::vector<std::vector<std::string>>>{};
|
||||||
|
m_globalVars = std::vector<std::vector<std::string>>{};
|
||||||
m_inForBodyScope = false;
|
m_inForBodyScope = false;
|
||||||
m_inForInitScope = false;
|
m_inForInitScope = false;
|
||||||
m_numNestedForLoops = 0;
|
m_numNestedForLoops = 0;
|
||||||
@ -62,7 +64,7 @@ private:
|
|||||||
/// @param _block Reference to a basic block of yul statements.
|
/// @param _block Reference to a basic block of yul statements.
|
||||||
/// @param _funcParams List of function parameter names, defaults to
|
/// @param _funcParams List of function parameter names, defaults to
|
||||||
/// an empty vector.
|
/// an empty vector.
|
||||||
void visit(Block const& _block, std::vector<std::string> _funcParams = {});
|
void visit(Block const& _block);
|
||||||
|
|
||||||
std::string visit(Literal const&);
|
std::string visit(Literal const&);
|
||||||
void visit(VarRef const&);
|
void visit(VarRef const&);
|
||||||
@ -99,11 +101,15 @@ private:
|
|||||||
void visit(Code const&);
|
void visit(Code const&);
|
||||||
void visit(Program const&);
|
void visit(Program const&);
|
||||||
|
|
||||||
/// Creates a new scope, and adds @a _funcParams to it if it
|
/// Creates a new block scope.
|
||||||
|
void openBlockScope();
|
||||||
|
/// Creates a new function scope, and adds @a _funcParams to it if it
|
||||||
/// is non-empty.
|
/// is non-empty.
|
||||||
void openScope(std::vector<std::string> const& _funcParams);
|
void openFunctionScope(std::vector<std::string> const& _funcParams);
|
||||||
/// Closes current scope
|
/// Closes current block scope
|
||||||
void closeScope();
|
void closeBlockScope();
|
||||||
|
/// Closes current function scope
|
||||||
|
void closeFunctionScope();
|
||||||
/// Adds @a _vars to current scope
|
/// Adds @a _vars to current scope
|
||||||
void addVarsToScope(std::vector<std::string> const& _vars);
|
void addVarsToScope(std::vector<std::string> const& _vars);
|
||||||
|
|
||||||
@ -139,6 +145,14 @@ private:
|
|||||||
/// Multiple -> "m"
|
/// Multiple -> "m"
|
||||||
std::string functionTypeToString(NumFunctionReturns _type);
|
std::string functionTypeToString(NumFunctionReturns _type);
|
||||||
|
|
||||||
|
/// Builds a single vector containing variables declared in
|
||||||
|
/// function scope.
|
||||||
|
void consolidateVarDeclsInFunctionDef();
|
||||||
|
|
||||||
|
/// Builds a single vector containing variables declared in
|
||||||
|
/// global scope.
|
||||||
|
void consolidateGlobalVarDecls();
|
||||||
|
|
||||||
/// Return true if at least one variable declaration is in scope,
|
/// Return true if at least one variable declaration is in scope,
|
||||||
/// false otherwise.
|
/// false otherwise.
|
||||||
/// @return True in the following cases:
|
/// @return True in the following cases:
|
||||||
@ -296,12 +310,16 @@ private:
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::ostringstream m_output;
|
std::ostringstream m_output;
|
||||||
/// Variables in current scope
|
/// Variables in all function definitions
|
||||||
std::stack<std::vector<std::string>> m_scopeVars;
|
std::vector<std::vector<std::vector<std::string>>> m_funcVars;
|
||||||
|
/// Variables in current function definition
|
||||||
|
std::vector<std::string const*> m_currentFuncVars;
|
||||||
|
/// Variables in global scope
|
||||||
|
std::vector<std::string const*> m_currentGlobalVars;
|
||||||
/// Functions in current scope
|
/// Functions in current scope
|
||||||
std::stack<std::vector<std::string>> m_scopeFuncs;
|
std::vector<std::vector<std::string>> m_scopeFuncs;
|
||||||
/// Variables
|
/// Variables
|
||||||
std::vector<std::string> m_variables;
|
std::vector<std::vector<std::string>> m_globalVars;
|
||||||
/// Functions
|
/// Functions
|
||||||
std::vector<std::string> m_functions;
|
std::vector<std::string> m_functions;
|
||||||
/// Maps FunctionDef object to its name
|
/// Maps FunctionDef object to its name
|
||||||
|
@ -55,8 +55,7 @@ void printErrors(ostream& _stream, ErrorList const& _errors)
|
|||||||
|
|
||||||
DEFINE_PROTO_FUZZER(Program const& _input)
|
DEFINE_PROTO_FUZZER(Program const& _input)
|
||||||
{
|
{
|
||||||
ProtoConverter converter;
|
string yul_source = ProtoConverter().programToString(_input);
|
||||||
string yul_source = converter.programToString(_input);
|
|
||||||
|
|
||||||
if (const char* dump_path = getenv("PROTO_FUZZER_DUMP_PATH"))
|
if (const char* dump_path = getenv("PROTO_FUZZER_DUMP_PATH"))
|
||||||
{
|
{
|
||||||
@ -70,24 +69,17 @@ DEFINE_PROTO_FUZZER(Program const& _input)
|
|||||||
|
|
||||||
// AssemblyStack entry point
|
// AssemblyStack entry point
|
||||||
AssemblyStack stack(
|
AssemblyStack stack(
|
||||||
langutil::EVMVersion(langutil::EVMVersion::istanbul()),
|
langutil::EVMVersion::istanbul(),
|
||||||
AssemblyStack::Language::StrictAssembly,
|
AssemblyStack::Language::StrictAssembly,
|
||||||
dev::solidity::OptimiserSettings::full()
|
dev::solidity::OptimiserSettings::full()
|
||||||
);
|
);
|
||||||
|
|
||||||
try
|
// Parse protobuf mutated YUL code
|
||||||
|
if (!stack.parseAndAnalyze("source", yul_source) || !stack.parserResult()->code ||
|
||||||
|
!stack.parserResult()->analysisInfo)
|
||||||
{
|
{
|
||||||
// Parse protobuf mutated YUL code
|
printErrors(std::cout, stack.errors());
|
||||||
if (!stack.parseAndAnalyze("source", yul_source) || !stack.parserResult()->code ||
|
yulAssert(false, "Proto fuzzer generated malformed program");
|
||||||
!stack.parserResult()->analysisInfo)
|
|
||||||
{
|
|
||||||
printErrors(std::cout, stack.errors());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (Exception const&)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ostringstream os1;
|
ostringstream os1;
|
||||||
@ -95,7 +87,7 @@ DEFINE_PROTO_FUZZER(Program const& _input)
|
|||||||
yulFuzzerUtil::TerminationReason termReason = yulFuzzerUtil::interpret(
|
yulFuzzerUtil::TerminationReason termReason = yulFuzzerUtil::interpret(
|
||||||
os1,
|
os1,
|
||||||
stack.parserResult()->code,
|
stack.parserResult()->code,
|
||||||
EVMDialect::strictAssemblyForEVMObjects(langutil::EVMVersion(langutil::EVMVersion::istanbul()))
|
EVMDialect::strictAssemblyForEVMObjects(langutil::EVMVersion::istanbul())
|
||||||
);
|
);
|
||||||
|
|
||||||
if (termReason == yulFuzzerUtil::TerminationReason::StepLimitReached)
|
if (termReason == yulFuzzerUtil::TerminationReason::StepLimitReached)
|
||||||
@ -105,7 +97,7 @@ DEFINE_PROTO_FUZZER(Program const& _input)
|
|||||||
termReason = yulFuzzerUtil::interpret(
|
termReason = yulFuzzerUtil::interpret(
|
||||||
os2,
|
os2,
|
||||||
stack.parserResult()->code,
|
stack.parserResult()->code,
|
||||||
EVMDialect::strictAssemblyForEVMObjects(langutil::EVMVersion(langutil::EVMVersion::istanbul())),
|
EVMDialect::strictAssemblyForEVMObjects(langutil::EVMVersion::istanbul()),
|
||||||
(yul::test::yul_fuzzer::yulFuzzerUtil::maxSteps * 4)
|
(yul::test::yul_fuzzer::yulFuzzerUtil::maxSteps * 4)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user