diff options
author | Erik Kundt <bitshift@posteo.org> | 2018-09-22 06:18:22 +0800 |
---|---|---|
committer | Erik Kundt <bitshift@posteo.org> | 2018-09-22 06:25:52 +0800 |
commit | d821cbdff5a483b3f7a7bd07758bf5e11a7cd762 (patch) | |
tree | 8e6a7c5c5da3d62c811f432f0c6fb6fa0b5728e9 | |
parent | ff5be1799088ca51fb51e9c86031bd2d88fe3bce (diff) | |
download | dexon-solidity-d821cbdff5a483b3f7a7bd07758bf5e11a7cd762.tar.gz dexon-solidity-d821cbdff5a483b3f7a7bd07758bf5e11a7cd762.tar.zst dexon-solidity-d821cbdff5a483b3f7a7bd07758bf5e11a7cd762.zip |
Moves length check to reference resolver.
7 files changed, 36 insertions, 13 deletions
diff --git a/libsolidity/analysis/ReferencesResolver.cpp b/libsolidity/analysis/ReferencesResolver.cpp index 8a576e2e..30aa3d49 100644 --- a/libsolidity/analysis/ReferencesResolver.cpp +++ b/libsolidity/analysis/ReferencesResolver.cpp @@ -231,6 +231,8 @@ void ReferencesResolver::endVisit(Mapping const& _typeName) void ReferencesResolver::endVisit(ArrayTypeName const& _typeName) { TypePointer baseType = _typeName.baseType().annotation().type; + auto arrayType = dynamic_cast<ArrayType const*>(baseType.get()); + bool isFixedSizeArray = (arrayType && arrayType->isByteArray()) || !baseType->isDynamicallySized(); if (!baseType) { solAssert(!m_errorReporter.errors().empty(), ""); @@ -246,6 +248,8 @@ void ReferencesResolver::endVisit(ArrayTypeName const& _typeName) RationalNumberType const* lengthType = dynamic_cast<RationalNumberType const*>(lengthTypeGeneric.get()); if (!lengthType || !lengthType->mobileType()) fatalTypeError(length->location(), "Invalid array length, expected integer literal or constant expression."); + else if (lengthType->isZero() && isFixedSizeArray) + fatalTypeError(length->location(), "Array with zero length specified."); else if (lengthType->isFractional()) fatalTypeError(length->location(), "Array with fractional length specified."); else if (lengthType->isNegative()) diff --git a/libsolidity/analysis/TypeChecker.cpp b/libsolidity/analysis/TypeChecker.cpp index 3b5e7b11..3056561b 100644 --- a/libsolidity/analysis/TypeChecker.cpp +++ b/libsolidity/analysis/TypeChecker.cpp @@ -822,17 +822,12 @@ bool TypeChecker::visit(VariableDeclaration const& _variable) { case Type::Category::Array: if (auto arrayType = dynamic_cast<ArrayType const*>(varType.get())) - { if ( ((arrayType->location() == DataLocation::Memory) || (arrayType->location() == DataLocation::CallData)) && !arrayType->validForCalldata() ) m_errorReporter.typeError(_variable.location(), "Array is too large to be encoded."); - if (auto baseType = dynamic_cast<ArrayType const*>(arrayType->baseType().get())) - if (!baseType->isDynamicallySized() && baseType->length() == 0) - m_errorReporter.typeError(_variable.location(), "Fixed-size multidimensional arrays are not allowed to have zero length."); - } break; case Type::Category::Mapping: if (auto mappingType = dynamic_cast<MappingType const*>(varType.get())) diff --git a/test/libsolidity/syntaxTests/array/length/fixed_size_multidim_zero_length.sol b/test/libsolidity/syntaxTests/array/length/fixed_size_multidim_zero_length.sol new file mode 100644 index 00000000..fd8f3078 --- /dev/null +++ b/test/libsolidity/syntaxTests/array/length/fixed_size_multidim_zero_length.sol @@ -0,0 +1,15 @@ +contract C { + function a() public pure returns(int[0][500] memory) {} + function b() public pure returns(uint[0][500] memory) {} + function c() public pure returns(byte[0][500] memory) {} + function d() public pure returns(bytes32[0][500] memory) {} + function e() public pure returns(bytes[0][500] memory) {} + function e() public pure returns(string[0][500] memory) {} +} +// ---- +// TypeError: (52-53): Array with zero length specified. +// TypeError: (111-112): Array with zero length specified. +// TypeError: (170-171): Array with zero length specified. +// TypeError: (232-233): Array with zero length specified. +// TypeError: (292-293): Array with zero length specified. +// TypeError: (353-354): Array with zero length specified. diff --git a/test/libsolidity/syntaxTests/array/length/fixed_size_zero_length.sol b/test/libsolidity/syntaxTests/array/length/fixed_size_zero_length.sol new file mode 100644 index 00000000..b38939e3 --- /dev/null +++ b/test/libsolidity/syntaxTests/array/length/fixed_size_zero_length.sol @@ -0,0 +1,15 @@ +contract C { + int[0] a; + uint[0] b; + byte[0] c; + bytes32[0] d; + bytes[0] e; + string[0] f; +} +// ---- +// TypeError: (19-20): Array with zero length specified. +// TypeError: (32-33): Array with zero length specified. +// TypeError: (45-46): Array with zero length specified. +// TypeError: (61-62): Array with zero length specified. +// TypeError: (75-76): Array with zero length specified. +// TypeError: (90-91): Array with zero length specified. diff --git a/test/libsolidity/syntaxTests/array/length/parentheses.sol b/test/libsolidity/syntaxTests/array/length/parentheses.sol index 40f55ad6..8dbcc0a4 100644 --- a/test/libsolidity/syntaxTests/array/length/parentheses.sol +++ b/test/libsolidity/syntaxTests/array/length/parentheses.sol @@ -21,5 +21,5 @@ contract C { uint[((2) + 1) + 1] a12; uint[(2 + 1) + ((1))] a13; uint[(((2) + 1)) + (((1)))] a14; - uint[((((2) + 1)) + (((1))))%1] a15; + uint[((((3) + 1)) + (((1))))%2] a15; } diff --git a/test/libsolidity/syntaxTests/array/multi_dim_zero_length.sol b/test/libsolidity/syntaxTests/array/multi_dim_zero_length.sol deleted file mode 100644 index 2f487cde..00000000 --- a/test/libsolidity/syntaxTests/array/multi_dim_zero_length.sol +++ /dev/null @@ -1,6 +0,0 @@ -contract C { - bytes[0] a; - function f() public pure returns(bytes32[0][500] memory) {} -} -// ---- -// TypeError: (62-84): Fixed-size multidimensional arrays are not allowed to have zero length. diff --git a/test/libsolidity/syntaxTests/parsing/arrays_in_storage.sol b/test/libsolidity/syntaxTests/parsing/arrays_in_storage.sol index 9181222e..9adf6f12 100644 --- a/test/libsolidity/syntaxTests/parsing/arrays_in_storage.sol +++ b/test/libsolidity/syntaxTests/parsing/arrays_in_storage.sol @@ -1,6 +1,6 @@ contract c { uint[10] a; uint[] a2; - struct x { uint[2**20] b; y[0] c; } + struct x { uint[2**20] b; y[1] c; } struct y { uint d; mapping(uint=>x)[] e; } } |