Browse Source

Type checks for array assignment.

cl-refactor
Christian 10 years ago
parent
commit
9252c02a63
  1. 19
      libsolidity/Types.cpp
  2. 55
      test/SolidityNameAndTypeResolution.cpp

19
libsolidity/Types.cpp

@ -537,7 +537,19 @@ TypePointer ContractType::unaryOperatorResult(Token::Value _operator) const
bool ArrayType::isImplicitlyConvertibleTo(const Type& _convertTo) const bool ArrayType::isImplicitlyConvertibleTo(const Type& _convertTo) const
{ {
return _convertTo.getCategory() == getCategory(); if (_convertTo.getCategory() != getCategory())
return false;
auto& convertTo = dynamic_cast<ArrayType const&>(_convertTo);
// let us not allow assignment to memory arrays for now
if (convertTo.getLocation() != Location::Storage)
return false;
if (convertTo.isByteArray() != isByteArray())
return false;
if (!getBaseType()->isImplicitlyConvertibleTo(*convertTo.getBaseType()))
return false;
if (convertTo.isDynamicallySized())
return true;
return !isDynamicallySized() && convertTo.getLength() >= getLength();
} }
TypePointer ArrayType::unaryOperatorResult(Token::Value _operator) const TypePointer ArrayType::unaryOperatorResult(Token::Value _operator) const
@ -552,7 +564,10 @@ bool ArrayType::operator==(Type const& _other) const
if (_other.getCategory() != getCategory()) if (_other.getCategory() != getCategory())
return false; return false;
ArrayType const& other = dynamic_cast<ArrayType const&>(_other); ArrayType const& other = dynamic_cast<ArrayType const&>(_other);
return other.m_location == m_location; if (other.m_location != m_location || other.isByteArray() != isByteArray() ||
other.isDynamicallySized() != isDynamicallySized())
return false;
return isDynamicallySized() || getLength() == other.getLength();
} }
u256 ArrayType::getStorageSize() const u256 ArrayType::getStorageSize() const

55
test/SolidityNameAndTypeResolution.cpp

@ -1185,6 +1185,61 @@ BOOST_AUTO_TEST_CASE(array_with_nonconstant_length)
BOOST_CHECK_THROW(parseTextAndResolveNames(text), TypeError); BOOST_CHECK_THROW(parseTextAndResolveNames(text), TypeError);
} }
BOOST_AUTO_TEST_CASE(array_copy_with_different_types1)
{
char const* text = R"(
contract c {
bytes a;
uint[] b;
function f() { b = a; }
})";
BOOST_CHECK_THROW(parseTextAndResolveNames(text), TypeError);
}
BOOST_AUTO_TEST_CASE(array_copy_with_different_types2)
{
char const* text = R"(
contract c {
uint32[] a;
uint8[] b;
function f() { b = a; }
})";
BOOST_CHECK_THROW(parseTextAndResolveNames(text), TypeError);
}
BOOST_AUTO_TEST_CASE(array_copy_with_different_types_conversion_possible)
{
char const* text = R"(
contract c {
uint32[] a;
uint8[] b;
function f() { a = b; }
})";
BOOST_CHECK_NO_THROW(parseTextAndResolveNames(text));
}
BOOST_AUTO_TEST_CASE(array_copy_with_different_types_static_dynamic)
{
char const* text = R"(
contract c {
uint32[] a;
uint8[80] b;
function f() { a = b; }
})";
BOOST_CHECK_NO_THROW(parseTextAndResolveNames(text));
}
BOOST_AUTO_TEST_CASE(array_copy_with_different_types_dynamic_static)
{
char const* text = R"(
contract c {
uint[] a;
uint[80] b;
function f() { b = a; }
})";
BOOST_CHECK_THROW(parseTextAndResolveNames(text), TypeError);
}
BOOST_AUTO_TEST_SUITE_END() BOOST_AUTO_TEST_SUITE_END()
} }

Loading…
Cancel
Save