Merge pull request #65 from LianaHus/sol_Creating_a_contract_from_within_itself

Added error when creating a contract from within itself
This commit is contained in:
chriseth 2015-09-11 15:19:58 +02:00
commit c5b6d9d2a9
3 changed files with 24 additions and 3 deletions

View File

@ -1001,10 +1001,17 @@ void NewExpression::checkTypeRequirements(TypePointers const*)
{
m_contractName->checkTypeRequirements(nullptr);
m_contract = dynamic_cast<ContractDefinition const*>(&m_contractName->referencedDeclaration());
if (!m_contract)
BOOST_THROW_EXCEPTION(createTypeError("Identifier is not a contract."));
if (!m_contract->isFullyImplemented())
BOOST_THROW_EXCEPTION(createTypeError("Trying to create an instance of an abstract contract."));
auto scopeContract = m_contractName->contractScope();
auto bases = m_contract->linearizedBaseContracts();
if (find(bases.begin(), bases.end(), scopeContract) != bases.end())
BOOST_THROW_EXCEPTION(createTypeError("Circular reference for contract creation: cannot create instance of derived or same contract."));
shared_ptr<ContractType const> contractType = make_shared<ContractType>(*m_contract);
TypePointers const& parameterTypes = contractType->constructorType()->parameterTypes();
m_type = make_shared<FunctionType>(
@ -1137,7 +1144,7 @@ void Identifier::checkTypeRequirements(TypePointers const* _argumentTypes)
}
solAssert(!!m_referencedDeclaration, "Referenced declaration is null after overload resolution.");
m_isLValue = m_referencedDeclaration->isLValue();
m_type = m_referencedDeclaration->type(m_currentContract);
m_type = m_referencedDeclaration->type(m_contractScope);
if (!m_type)
BOOST_THROW_EXCEPTION(createTypeError("Declaration referenced before type could be determined."));
}

View File

@ -1257,7 +1257,7 @@ public:
)
{
m_referencedDeclaration = &_referencedDeclaration;
m_currentContract = _currentContract;
m_contractScope = _currentContract;
}
Declaration const& referencedDeclaration() const;
@ -1273,6 +1273,8 @@ public:
/// argument types in a call context.
void overloadResolution(TypePointers const& _argumentTypes);
ContractDefinition const* contractScope() const { return m_contractScope; }
private:
ASTPointer<ASTString> m_name;
@ -1280,7 +1282,7 @@ private:
Declaration const* m_referencedDeclaration = nullptr;
/// Stores a reference to the current contract. This is needed because types of base contracts
/// change depending on the context.
ContractDefinition const* m_currentContract = nullptr;
ContractDefinition const* m_contractScope = nullptr;
/// A vector of overloaded declarations, right now only FunctionDefinition has overloaded declarations.
std::vector<Declaration const*> m_overloadedDeclarations;
};

View File

@ -2194,6 +2194,18 @@ BOOST_AUTO_TEST_CASE(string_bytes_conversion)
BOOST_CHECK_NO_THROW(parseTextAndResolveNames(text));
}
BOOST_AUTO_TEST_CASE(creating_contract_within_the_contract)
{
char const* sourceCode = R"(
contract Test {
function f() { var x = new Test(); }
}
)";
BOOST_CHECK_THROW(parseTextAndResolveNames(sourceCode), TypeError);
}
BOOST_AUTO_TEST_SUITE_END()
}