aboutsummaryrefslogtreecommitdiffstats
path: root/libsolidity
diff options
context:
space:
mode:
authorLianaHus <liana@ethdev.com>2015-09-10 23:17:13 +0800
committerLianaHus <liana@ethdev.com>2015-09-10 23:17:13 +0800
commit47e42430f27c579e09157f3373238e3bbe8ab93e (patch)
tree39fdc6752502ecd44d0f92362f053cf1e1295b63 /libsolidity
parent30e89b3d9a85d7dba3e9858a19b3495e9c8f759a (diff)
downloaddexon-solidity-47e42430f27c579e09157f3373238e3bbe8ab93e.tar.gz
dexon-solidity-47e42430f27c579e09157f3373238e3bbe8ab93e.tar.zst
dexon-solidity-47e42430f27c579e09157f3373238e3bbe8ab93e.zip
added type check if the type of the var decl is one of base contract type
Diffstat (limited to 'libsolidity')
-rw-r--r--libsolidity/AST.cpp9
-rw-r--r--libsolidity/AST.h6
2 files changed, 12 insertions, 3 deletions
diff --git a/libsolidity/AST.cpp b/libsolidity/AST.cpp
index 25d2ccd8..1b22c44f 100644
--- a/libsolidity/AST.cpp
+++ b/libsolidity/AST.cpp
@@ -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."));
}
diff --git a/libsolidity/AST.h b/libsolidity/AST.h
index 6068e756..1288b5d3 100644
--- a/libsolidity/AST.h
+++ b/libsolidity/AST.h
@@ -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() { 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;
};