diff options
author | chriseth <c@ethdev.com> | 2015-11-17 08:47:47 +0800 |
---|---|---|
committer | chriseth <c@ethdev.com> | 2015-11-26 20:10:12 +0800 |
commit | bf55aa6ae2b9aeec09bb8cf1e3715afd7dd59b7e (patch) | |
tree | e49bc5845496df706ea45de03748c5475611c3b9 /libsolidity/analysis | |
parent | 30b325fdc148d5014f04fd238362e3a1df10310f (diff) | |
download | dexon-solidity-bf55aa6ae2b9aeec09bb8cf1e3715afd7dd59b7e.tar.gz dexon-solidity-bf55aa6ae2b9aeec09bb8cf1e3715afd7dd59b7e.tar.zst dexon-solidity-bf55aa6ae2b9aeec09bb8cf1e3715afd7dd59b7e.zip |
Type checking for creating new arrays.
Diffstat (limited to 'libsolidity/analysis')
-rw-r--r-- | libsolidity/analysis/ReferencesResolver.cpp | 5 | ||||
-rw-r--r-- | libsolidity/analysis/ReferencesResolver.h | 1 | ||||
-rw-r--r-- | libsolidity/analysis/TypeChecker.cpp | 24 |
3 files changed, 28 insertions, 2 deletions
diff --git a/libsolidity/analysis/ReferencesResolver.cpp b/libsolidity/analysis/ReferencesResolver.cpp index 0e153045..408212f1 100644 --- a/libsolidity/analysis/ReferencesResolver.cpp +++ b/libsolidity/analysis/ReferencesResolver.cpp @@ -37,6 +37,11 @@ bool ReferencesResolver::visit(Return const& _return) return true; } +void ReferencesResolver::endVisit(NewExpression const& _new) +{ + typeFor(_new.typeName()); +} + bool ReferencesResolver::visit(UserDefinedTypeName const& _typeName) { Declaration const* declaration = m_resolver.pathFromCurrentScope(_typeName.namePath()); diff --git a/libsolidity/analysis/ReferencesResolver.h b/libsolidity/analysis/ReferencesResolver.h index 21cb1d35..62104611 100644 --- a/libsolidity/analysis/ReferencesResolver.h +++ b/libsolidity/analysis/ReferencesResolver.h @@ -64,6 +64,7 @@ private: virtual bool visit(Identifier const& _identifier) override; virtual bool visit(UserDefinedTypeName const& _typeName) override; virtual bool visit(Return const& _return) override; + virtual void endVisit(NewExpression const& _new) override; virtual void endVisit(VariableDeclaration const& _variable) override; TypePointer typeFor(TypeName const& _typeName); diff --git a/libsolidity/analysis/TypeChecker.cpp b/libsolidity/analysis/TypeChecker.cpp index 13c2235a..5623da37 100644 --- a/libsolidity/analysis/TypeChecker.cpp +++ b/libsolidity/analysis/TypeChecker.cpp @@ -1045,6 +1045,9 @@ bool TypeChecker::visit(FunctionCall const& _functionCall) void TypeChecker::endVisit(NewExpression const& _newExpression) { + TypePointer type = _newExpression.typeName().annotation().type; + solAssert(!!type, "Type name not resolved."); + if (auto contractName = dynamic_cast<UserDefinedTypeName const*>(&_newExpression.typeName())) { auto contract = dynamic_cast<ContractDefinition const*>(&dereference(*contractName)); @@ -1076,9 +1079,26 @@ void TypeChecker::endVisit(NewExpression const& _newExpression) FunctionType::Location::Creation ); } - else if (auto arrayTypeName = dynamic_cast<ArrayTypeName const*>(&_newExpression.typeName())) + else if (type->category() == Type::Category::Array) { - solAssert(false, "Not yet implemented."); + if (!type->canLiveOutsideStorage()) + fatalTypeError( + _newExpression.typeName().location(), + "Type cannot live outside storage." + ); + if (!type->isDynamicallySized()) + typeError( + _newExpression.typeName().location(), + "Length has to be placed in parentheses after the array type for new expression." + ); + type = ReferenceType::copyForLocationIfReference(DataLocation::Memory, type); + _newExpression.annotation().type = make_shared<FunctionType>( + TypePointers{make_shared<IntegerType>(256)}, + TypePointers{type}, + strings(), + strings(), + FunctionType::Location::ObjectCreation + ); } else fatalTypeError(_newExpression.location(), "Contract or array type expected."); |