mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
added type check if the type of the var decl is one of base contract type
This commit is contained in:
parent
30e89b3d9a
commit
47e42430f2
@ -1001,10 +1001,17 @@ void NewExpression::checkTypeRequirements(TypePointers const*)
|
|||||||
{
|
{
|
||||||
m_contractName->checkTypeRequirements(nullptr);
|
m_contractName->checkTypeRequirements(nullptr);
|
||||||
m_contract = dynamic_cast<ContractDefinition const*>(&m_contractName->referencedDeclaration());
|
m_contract = dynamic_cast<ContractDefinition const*>(&m_contractName->referencedDeclaration());
|
||||||
|
|
||||||
if (!m_contract)
|
if (!m_contract)
|
||||||
BOOST_THROW_EXCEPTION(createTypeError("Identifier is not a contract."));
|
BOOST_THROW_EXCEPTION(createTypeError("Identifier is not a contract."));
|
||||||
if (!m_contract->isFullyImplemented())
|
if (!m_contract->isFullyImplemented())
|
||||||
BOOST_THROW_EXCEPTION(createTypeError("Trying to create an instance of an abstract contract."));
|
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);
|
shared_ptr<ContractType const> contractType = make_shared<ContractType>(*m_contract);
|
||||||
TypePointers const& parameterTypes = contractType->constructorType()->parameterTypes();
|
TypePointers const& parameterTypes = contractType->constructorType()->parameterTypes();
|
||||||
m_type = make_shared<FunctionType>(
|
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.");
|
solAssert(!!m_referencedDeclaration, "Referenced declaration is null after overload resolution.");
|
||||||
m_isLValue = m_referencedDeclaration->isLValue();
|
m_isLValue = m_referencedDeclaration->isLValue();
|
||||||
m_type = m_referencedDeclaration->type(m_currentContract);
|
m_type = m_referencedDeclaration->type(m_contractScope);
|
||||||
if (!m_type)
|
if (!m_type)
|
||||||
BOOST_THROW_EXCEPTION(createTypeError("Declaration referenced before type could be determined."));
|
BOOST_THROW_EXCEPTION(createTypeError("Declaration referenced before type could be determined."));
|
||||||
}
|
}
|
||||||
|
@ -1257,7 +1257,7 @@ public:
|
|||||||
)
|
)
|
||||||
{
|
{
|
||||||
m_referencedDeclaration = &_referencedDeclaration;
|
m_referencedDeclaration = &_referencedDeclaration;
|
||||||
m_currentContract = _currentContract;
|
m_contractScope = _currentContract;
|
||||||
}
|
}
|
||||||
Declaration const& referencedDeclaration() const;
|
Declaration const& referencedDeclaration() const;
|
||||||
|
|
||||||
@ -1273,6 +1273,8 @@ public:
|
|||||||
/// argument types in a call context.
|
/// argument types in a call context.
|
||||||
void overloadResolution(TypePointers const& _argumentTypes);
|
void overloadResolution(TypePointers const& _argumentTypes);
|
||||||
|
|
||||||
|
ContractDefinition const* contractScope() { return m_contractScope; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ASTPointer<ASTString> m_name;
|
ASTPointer<ASTString> m_name;
|
||||||
|
|
||||||
@ -1280,7 +1282,7 @@ private:
|
|||||||
Declaration const* m_referencedDeclaration = nullptr;
|
Declaration const* m_referencedDeclaration = nullptr;
|
||||||
/// Stores a reference to the current contract. This is needed because types of base contracts
|
/// Stores a reference to the current contract. This is needed because types of base contracts
|
||||||
/// change depending on the context.
|
/// 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.
|
/// A vector of overloaded declarations, right now only FunctionDefinition has overloaded declarations.
|
||||||
std::vector<Declaration const*> m_overloadedDeclarations;
|
std::vector<Declaration const*> m_overloadedDeclarations;
|
||||||
};
|
};
|
||||||
|
@ -5230,17 +5230,6 @@ BOOST_AUTO_TEST_CASE(storage_string_as_mapping_key_without_variable)
|
|||||||
BOOST_CHECK(callContractFunction("f()") == encodeArgs(u256(2)));
|
BOOST_CHECK(callContractFunction("f()") == encodeArgs(u256(2)));
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(string_as_mapping_key)
|
|
||||||
{
|
|
||||||
char const* sourceCode = R"(
|
|
||||||
contract Test {
|
|
||||||
function f() { var x = new Test(); }
|
|
||||||
}
|
|
||||||
)";
|
|
||||||
|
|
||||||
compileAndRun(sourceCode, 0, "Test");
|
|
||||||
}
|
|
||||||
|
|
||||||
BOOST_AUTO_TEST_SUITE_END()
|
BOOST_AUTO_TEST_SUITE_END()
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -2194,6 +2194,18 @@ BOOST_AUTO_TEST_CASE(string_bytes_conversion)
|
|||||||
BOOST_CHECK_NO_THROW(parseTextAndResolveNames(text));
|
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()
|
BOOST_AUTO_TEST_SUITE_END()
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user