Merge pull request #4777 from ethereum/typeConversionMemory

Defaul data location for type conversions is memory.
This commit is contained in:
chriseth 2018-08-14 11:36:19 +02:00 committed by GitHub
commit 6ca3973944
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 14 additions and 5 deletions

View File

@ -95,6 +95,7 @@ Bugfixes:
* References Resolver: Enforce ``storage`` as data location for mappings. * References Resolver: Enforce ``storage`` as data location for mappings.
* References Resolver: Properly handle invalid references used together with ``_slot`` and ``_offset``. * References Resolver: Properly handle invalid references used together with ``_slot`` and ``_offset``.
* References Resolver: Report error instead of assertion fail when FunctionType has an undeclared type as parameter. * References Resolver: Report error instead of assertion fail when FunctionType has an undeclared type as parameter.
* Type Checker: Default data location for type conversions (e.g. from literals) is memory and not storage.
* Type Checker: Disallow assignments to mappings within tuple assignments as well. * Type Checker: Disallow assignments to mappings within tuple assignments as well.
* Type Checker: Allow assignments to local variables of mapping types. * Type Checker: Allow assignments to local variables of mapping types.
* Type Checker: Consider fixed size arrays when checking for recursive structs. * Type Checker: Consider fixed size arrays when checking for recursive structs.

View File

@ -1629,10 +1629,13 @@ bool TypeChecker::visit(FunctionCall const& _functionCall)
else else
{ {
TypePointer const& argType = type(*arguments.front()); TypePointer const& argType = type(*arguments.front());
// Resulting data location is memory unless we are converting from a reference
// type with a different data location.
// (data location cannot yet be specified for type conversions)
DataLocation dataLoc = DataLocation::Memory;
if (auto argRefType = dynamic_cast<ReferenceType const*>(argType.get())) if (auto argRefType = dynamic_cast<ReferenceType const*>(argType.get()))
// do not change the data location when converting dataLoc = argRefType->location();
// (data location cannot yet be specified for type conversions) resultType = ReferenceType::copyForLocationIfReference(dataLoc, resultType);
resultType = ReferenceType::copyForLocationIfReference(argRefType->location(), resultType);
if (!argType->isExplicitlyConvertibleTo(*resultType)) if (!argType->isExplicitlyConvertibleTo(*resultType))
m_errorReporter.typeError( m_errorReporter.typeError(
_functionCall.location(), _functionCall.location(),

View File

@ -0,0 +1,5 @@
contract test {
function f() public pure returns (bytes) {
return bytes("abc");
}
}

View File

@ -2,4 +2,4 @@ contract C {
string s = string("\xa0\x00"); string s = string("\xa0\x00");
} }
// ---- // ----
// TypeError: (28-46): Explicit type conversion not allowed from "literal_string (contains invalid UTF-8 sequence at position 0)" to "string storage pointer". // TypeError: (28-46): Explicit type conversion not allowed from "literal_string (contains invalid UTF-8 sequence at position 0)" to "string memory".

View File

@ -4,4 +4,4 @@ contract C {
} }
} }
// ---- // ----
// TypeError: (52-65): Explicit type conversion not allowed from "literal_string "abc"" to "string storage pointer". // Warning: (52-65): Statement has no effect.