diff --git a/libsolidity/Types.cpp b/libsolidity/Types.cpp index 14ea4c73c..a718ee4f9 100644 --- a/libsolidity/Types.cpp +++ b/libsolidity/Types.cpp @@ -184,6 +184,8 @@ TypePointer Type::fromArrayTypeName(TypeName& _baseTypeName, Expression* _length TypePointer baseType = _baseTypeName.toType(); if (!baseType) BOOST_THROW_EXCEPTION(_baseTypeName.createTypeError("Invalid type name.")); + if (baseType->getStorageBytes() == 0) + BOOST_THROW_EXCEPTION(_baseTypeName.createTypeError("Illegal base type of storage size zero for array.")); if (_length) { if (!_length->getType()) diff --git a/test/SolidityEndToEndTest.cpp b/test/SolidityEndToEndTest.cpp index 48ad183ae..cbcff405b 100644 --- a/test/SolidityEndToEndTest.cpp +++ b/test/SolidityEndToEndTest.cpp @@ -3549,6 +3549,30 @@ BOOST_AUTO_TEST_CASE(packed_storage_structs_delete) BOOST_CHECK(m_state.storage(m_contractAddress).empty()); } +BOOST_AUTO_TEST_CASE(packed_storage_structs_with_bytes0) +{ + char const* sourceCode = R"( + contract C { + struct str { uint8 a; bytes0 b; uint8 c; } + uint8 a; + bytes0 x; + uint8 b; + str data; + function test() returns (bool) { + a = 2; + b = 3; + data.a = 4; + data.c = 5; + delete x; + delete data.b; + return a == 2 && b == 3 && data.a == 4 && data.c == 5; + } + } + )"; + compileAndRun(sourceCode); + BOOST_CHECK(callContractFunction("test()") == encodeArgs(true)); +} + BOOST_AUTO_TEST_SUITE_END() } diff --git a/test/SolidityNameAndTypeResolution.cpp b/test/SolidityNameAndTypeResolution.cpp index b83709d83..591cf053a 100644 --- a/test/SolidityNameAndTypeResolution.cpp +++ b/test/SolidityNameAndTypeResolution.cpp @@ -1446,6 +1446,16 @@ BOOST_AUTO_TEST_CASE(local_const_variable) BOOST_CHECK_THROW(parseTextAndResolveNames(text), ParserError); } +BOOST_AUTO_TEST_CASE(bytes0_array) +{ + char const* text = R"( + contract Foo { + bytes0[] illegalArray; + } + )"; + BOOST_CHECK_THROW(parseTextAndResolveNames(text), TypeError); +} + BOOST_AUTO_TEST_SUITE_END() }