Do not set to ref for explicit conversion and add assertion for array

type conversion. Also, add some test cases for #4901 and #4948.
This commit is contained in:
liangdzou 2018-09-12 18:01:34 +08:00 committed by Daniel Kirchner
parent 5f4a2d2cad
commit f3cbdadec7
8 changed files with 84 additions and 2 deletions

View File

@ -1733,8 +1733,23 @@ bool TypeChecker::visit(FunctionCall const& _functionCall)
DataLocation dataLoc = DataLocation::Memory; DataLocation dataLoc = DataLocation::Memory;
if (auto argRefType = dynamic_cast<ReferenceType const*>(argType.get())) if (auto argRefType = dynamic_cast<ReferenceType const*>(argType.get()))
dataLoc = argRefType->location(); dataLoc = argRefType->location();
resultType = ReferenceType::copyForLocationIfReference(dataLoc, resultType); if (auto type = dynamic_cast<ReferenceType const*>(resultType.get()))
if (!argType->isExplicitlyConvertibleTo(*resultType)) resultType = type->copyForLocation(dataLoc, type->isPointer());
if (argType->isExplicitlyConvertibleTo(*resultType))
{
if (auto argArrayType = dynamic_cast<ArrayType const*>(argType.get()))
{
auto resultArrayType = dynamic_cast<ArrayType const*>(resultType.get());
solAssert(!!resultArrayType, "");
solAssert(
argArrayType->location() != DataLocation::Storage ||
((resultArrayType->isPointer() || (argArrayType->isByteArray() && resultArrayType->isByteArray())) &&
resultArrayType->location() == DataLocation::Storage),
"Invalid explicit conversion to storage type."
);
}
}
else
{ {
if (resultType->category() == Type::Category::Contract && argType->category() == Type::Category::Address) if (resultType->category() == Type::Category::Contract && argType->category() == Type::Category::Address)
{ {

View File

@ -0,0 +1,9 @@
contract C {
bytes a;
bytes b;
function f() public view {
bytes storage c = a;
bytes memory d = b;
d = bytes(c);
}
}

View File

@ -0,0 +1,9 @@
contract C {
string a;
string b;
function f() public view {
string storage c = a;
string memory d = b;
d = string(c);
}
}

View File

@ -0,0 +1,10 @@
contract C {
int[10] x;
function f() public view {
int[](x);
int(x);
}
}
// ----
// TypeError: (55-63): Explicit type conversion not allowed from "int256[10] storage ref" to "int256[] storage pointer".
// TypeError: (67-73): Explicit type conversion not allowed from "int256[10] storage ref" to "int256".

View File

@ -0,0 +1,7 @@
contract C {
int[10] x;
int[] y;
function f() public {
y = x;
}
}

View File

@ -0,0 +1,10 @@
contract C {
uint[] a;
uint[] b;
function f() public view {
uint[] storage c = a;
uint[] storage d = b;
d = uint[](c);
}
}
// ----

View File

@ -0,0 +1,10 @@
contract C {
uint[] a;
uint[] b;
function f() public view {
uint[] storage c = a;
uint[] memory d = b;
d = uint[](c);
}
}
// ----

View File

@ -0,0 +1,12 @@
contract C {
int[] x;
function f() public {
int[] storage a = x;
int[] memory b;
a = b;
a = int[](b);
}
}
// ----
// TypeError: (93-94): Type int256[] memory is not implicitly convertible to expected type int256[] storage pointer.
// TypeError: (102-110): Type int256[] memory is not implicitly convertible to expected type int256[] storage pointer.