Merge pull request #8942 from ethereum/calldataVariables

Calldata variables.
This commit is contained in:
chriseth
2020-05-26 11:34:40 +02:00
committed by GitHub
55 changed files with 295 additions and 86 deletions
+1
View File
@@ -1,6 +1,7 @@
### 0.6.9 (unreleased)
Language Features:
* Permit calldata location for all variables.
Compiler Features:
+9 -4
View File
@@ -13,8 +13,7 @@ arrays and mappings. If you use a reference type, you always have to explicitly
provide the data area where the type is stored: ``memory`` (whose lifetime is limited
to an external function call), ``storage`` (the location where the state variables
are stored, where the lifetime is limited to the lifetime of a contract)
or ``calldata`` (special data location that contains the function arguments,
only available for external function call parameters).
or ``calldata`` (special data location that contains the function arguments).
An assignment or type conversion that changes the data location will always incur an automatic copy operation,
while assignments inside the same data location only copy in some cases for storage types.
@@ -26,9 +25,9 @@ Data location
Every reference type has an additional
annotation, the "data location", about where it is stored. There are three data locations:
``memory``, ``storage`` and ``calldata``. Calldata is only valid for parameters of external contract
functions and is required for this type of parameter. Calldata is a non-modifiable,
``memory``, ``storage`` and ``calldata``. Calldata is a non-modifiable,
non-persistent area where function arguments are stored, and behaves mostly like memory.
It is required for parameters of external functions but can also be used for other variables.
.. note::
@@ -36,6 +35,12 @@ non-persistent area where function arguments are stored, and behaves mostly like
depending on the kind of variable, function type, etc., but all complex types must now give an explicit
data location.
.. note::
If you can, try to use ``calldata`` as data location because it will avoid copies and
also makes sure that the data cannot be modified. Arrays and structs with ``calldata``
data location can also be returned from functions, but it is not possible to
allocate such types.
.. _data-location-assignment:
Data location and assignment behaviour
+8 -2
View File
@@ -94,7 +94,10 @@ void ControlFlowAnalyzer::checkUninitializedAccess(CFGNode const* _entry, CFGNod
case VariableOccurrence::Kind::Return:
if (unassignedVariables.count(&variableOccurrence.declaration()))
{
if (variableOccurrence.declaration().type()->dataStoredIn(DataLocation::Storage))
if (
variableOccurrence.declaration().type()->dataStoredIn(DataLocation::Storage) ||
variableOccurrence.declaration().type()->dataStoredIn(DataLocation::CallData)
)
// Merely store the unassigned access. We do not generate an error right away, since this
// path might still always revert. It is only an error if this is propagated to the exit
// node of the function (i.e. there is a path with an uninitialized access).
@@ -135,13 +138,16 @@ void ControlFlowAnalyzer::checkUninitializedAccess(CFGNode const* _entry, CFGNod
if (variableOccurrence->occurrence())
ssl.append("The variable was declared here.", variableOccurrence->declaration().location());
bool isStorage = variableOccurrence->declaration().type()->dataStoredIn(DataLocation::Storage);
m_errorReporter.typeError(
3464_error,
variableOccurrence->occurrence() ?
*variableOccurrence->occurrence() :
variableOccurrence->declaration().location(),
ssl,
string("This variable is of storage pointer type and can be ") +
"This variable is of " +
string(isStorage ? "storage" : "calldata") +
" pointer type and can be " +
(variableOccurrence->kind() == VariableOccurrence::Kind::Return ? "returned" : "accessed") +
" without prior assignment, which would lead to undefined behaviour."
);
+12 -11
View File
@@ -338,8 +338,14 @@ TypePointer FunctionDefinition::type() const
TypePointer FunctionDefinition::typeViaContractName() const
{
if (annotation().contract->isLibrary())
return FunctionType(*this).asCallableFunction(true);
return TypeProvider::function(*this, FunctionType::Kind::Declaration);
{
if (isPublic())
return FunctionType(*this).asCallableFunction(true);
else
return TypeProvider::function(*this, FunctionType::Kind::Internal);
}
else
return TypeProvider::function(*this, FunctionType::Kind::Declaration);
}
string FunctionDefinition::externalSignature() const
@@ -616,18 +622,14 @@ set<VariableDeclaration::Location> VariableDeclaration::allowedDataLocations() c
if (!hasReferenceOrMappingType() || isStateVariable() || isEventParameter())
return set<Location>{ Location::Unspecified };
else if (isExternalCallableParameter())
{
set<Location> locations{ Location::CallData };
if (isLibraryFunctionParameter())
locations.insert(Location::Storage);
return locations;
}
else if (isCallableOrCatchParameter())
{
set<Location> locations{ Location::Memory };
if (isInternalCallableParameter() || isLibraryFunctionParameter() || isTryCatchParameter())
locations.insert(Location::Storage);
if (!isTryCatchParameter())
locations.insert(Location::CallData);
return locations;
}
else if (isLocalVariable())
@@ -642,8 +644,7 @@ set<VariableDeclaration::Location> VariableDeclaration::allowedDataLocations() c
case Type::Category::Mapping:
return set<Location>{ Location::Storage };
default:
// TODO: add Location::Calldata once implemented for local variables.
return set<Location>{ Location::Memory, Location::Storage };
return set<Location>{ Location::Memory, Location::Storage, Location::CallData };
}
};
return dataLocations(typeName()->annotation().type, dataLocations);
+9
View File
@@ -1218,6 +1218,15 @@ void CompilerUtils::pushZeroValue(Type const& _type)
m_context << u256(0);
return;
}
if (referenceType->location() == DataLocation::CallData)
{
solAssert(referenceType->sizeOnStack() == 1 || referenceType->sizeOnStack() == 2, "");
m_context << Instruction::CALLDATASIZE;
if (referenceType->sizeOnStack() == 2)
m_context << 0;
return;
}
solAssert(referenceType->location() == DataLocation::Memory, "");
if (auto arrayType = dynamic_cast<ArrayType const*>(&_type))
if (arrayType->isDynamicallySized())
+21 -1
View File
@@ -2240,6 +2240,27 @@ string YulUtilFunctions::zeroValueFunction(Type const& _type, bool _splitFunctio
("functionName", functionName)
.render();
if (_type.dataStoredIn(DataLocation::CallData))
{
solAssert(
_type.category() == Type::Category::Struct ||
_type.category() == Type::Category::Array,
"");
Whiskers templ(R"(
function <functionName>() -> offset<?hasLength>, length</hasLength> {
offset := calldatasize()
<?hasLength> length := 0 </hasLength>
}
)");
templ("functionName", functionName);
templ("hasLength",
_type.category() == Type::Category::Array &&
dynamic_cast<ArrayType const&>(_type).isDynamicallySized()
);
return templ.render();
}
Whiskers templ(R"(
function <functionName>() -> ret {
ret := <zeroValue>
@@ -2624,4 +2645,3 @@ string YulUtilFunctions::copyConstructorArgumentsToMemoryFunction(
.render();
});
}
@@ -0,0 +1,12 @@
contract C {
function f(bytes calldata b, uint i) internal pure returns (byte) {
return b[i];
}
function f(uint, bytes calldata b, uint) external pure returns (byte) {
return f(b, 2);
}
}
// ====
// compileViaYul: also
// ----
// f(uint256,bytes,uint256): 7, 0x60, 7, 4, "abcd" -> "c"
@@ -0,0 +1,17 @@
contract C {
function(bytes calldata) returns (byte) x;
constructor() public { x = f; }
function f(bytes calldata b) internal pure returns (byte) {
return b[2];
}
function h(bytes calldata b) external returns (byte) {
return x(b);
}
function g() external returns (byte) {
bytes memory a = new bytes(34);
a[2] = byte(uint8(7));
return this.h(a);
}
}
// ----
// g() -> 0x0700000000000000000000000000000000000000000000000000000000000000
@@ -0,0 +1,22 @@
library L {
function f(uint, bytes calldata _x, uint) internal returns (byte) {
return _x[2];
}
}
contract C {
function f(bytes calldata a)
external
returns (byte)
{
return L.f(3, a, 9);
}
function g() public returns (byte) {
bytes memory x = new bytes(4);
x[2] = 0x08;
return this.f(x);
}
}
// ====
// compileViaYul: also
// ----
// g() -> 0x0800000000000000000000000000000000000000000000000000000000000000
@@ -0,0 +1,23 @@
pragma experimental ABIEncoderV2;
contract C {
function g(uint[][2] calldata s) internal pure returns (uint, uint[] calldata) {
return (s[0][1], s[1]);
}
function f(uint, uint[][2] calldata s, uint) external pure returns (uint, uint) {
(uint x, uint[] calldata y) = g(s);
return (x, y[0]);
}
function g() public returns (uint, uint) {
uint[][2] memory x;
x[0] = new uint[](2);
x[1] = new uint[](2);
x[0][1] = 7;
x[1][0] = 8;
return this.f(4, x, 5);
}
}
// ====
// compileViaYul: also
// ----
// g() -> 7, 8
@@ -0,0 +1,19 @@
contract C {
function g(uint[3][2] calldata s) internal pure returns (uint, uint[3] calldata) {
return (s[0][1], s[1]);
}
function f(uint, uint[3][2] calldata s, uint) external pure returns (uint, uint) {
(uint x, uint[3] calldata y) = g(s);
return (x, y[0]);
}
function g() public returns (uint, uint) {
uint[3][2] memory x;
x[0][1] = 7;
x[1][0] = 8;
return this.f(4, x, 5);
}
}
// ====
// compileViaYul: also
// ----
// g() -> 7, 8
@@ -0,0 +1,21 @@
contract C {
function f(bytes memory _a, bytes calldata _b, bytes memory _c)
public
returns (uint, byte, byte, byte)
{
return (_a.length + _b.length + _c.length, _a[1], _b[1], _c[1]);
}
function g() public returns (uint, byte, byte, byte) {
bytes memory x = new bytes(3);
bytes memory y = new bytes(4);
bytes memory z = new bytes(7);
x[1] = 0x08;
y[1] = 0x09;
z[1] = 0x0a;
return this.f(x, y, z);
}
}
// ====
// compileViaYul: also
// ----
// g() -> 0x0e, 0x0800000000000000000000000000000000000000000000000000000000000000, 0x0900000000000000000000000000000000000000000000000000000000000000, 0x0a00000000000000000000000000000000000000000000000000000000000000
@@ -0,0 +1,17 @@
pragma experimental ABIEncoderV2;
struct S {
uint x;
uint y;
}
contract C {
function f(S calldata s) internal pure returns (uint, uint) {
return (s.x, s.y);
}
function f(uint, S calldata s, uint) external pure returns (uint, uint) {
return f(s);
}
}
// ----
// f(uint256,(uint256,uint256),uint256): 7, 1, 2, 4 -> 1, 2
@@ -6,4 +6,4 @@ contract C {
// ----
// DeclarationError: (28-45): The "constant" keyword can only be used for state variables.
// TypeError: (69-72): Invalid array length, expected integer literal or constant expression.
// TypeError: (64-75): Data location must be "storage" or "memory" for variable, but none was given.
// TypeError: (64-75): Data location must be "storage", "memory" or "calldata" for variable, but none was given.
@@ -0,0 +1,10 @@
contract C {
function f(uint[] calldata _c) public pure {
uint[] calldata c;
if (_c[2] > 10)
c = _c;
c[2];
}
}
// ----
// TypeError: (141-142): This variable is of calldata pointer type and can be accessed without prior assignment, which would lead to undefined behaviour.
@@ -0,0 +1,11 @@
contract C {
function f(uint[] calldata _c) public pure {
uint[] calldata c;
if (_c[2] > 10)
c = _c;
else
c = _c;
c[2];
}
}
// ----
@@ -0,0 +1,16 @@
contract C {
function g() internal pure returns (bytes calldata) {
return msg.data;
}
function h(uint[] calldata _c) internal pure {
uint[] calldata c;
c = _c;
c[2];
}
function i(uint[] calldata _c) internal pure {
uint[] calldata c;
(c) = _c;
c[2];
}
}
// ----
@@ -5,5 +5,4 @@ library L {
}
// ----
// TypeError: (66-81): Data location must be "memory" for parameter in function, but "calldata" was given.
// TypeError: (159-173): Data location must be "memory" for parameter in function, but "storage" was given.
// TypeError: (159-173): Data location must be "memory" or "calldata" for parameter in function, but "storage" was given.
@@ -2,4 +2,4 @@ contract C {
function i() external pure returns(uint[]) {}
}
// ----
// TypeError: (52-58): Data location must be "memory" for return parameter in function, but none was given.
// TypeError: (52-58): Data location must be "memory" or "calldata" for return parameter in function, but none was given.
@@ -2,4 +2,5 @@ contract test {
function f(bytes memory) external;
}
// ----
// TypeError: (31-43): Data location must be "calldata" for parameter in external function, but "memory" was given.
// TypeError: (0-56): Contract "test" should be marked as abstract.
// TypeError: (20-54): Functions without implementation must be marked virtual.
@@ -2,4 +2,4 @@ contract test {
function f(bytes storage) external;
}
// ----
// TypeError: (31-44): Data location must be "calldata" for parameter in external function, but "storage" was given.
// TypeError: (31-44): Data location must be "memory" or "calldata" for parameter in external function, but "storage" was given.
@@ -2,4 +2,5 @@ contract test {
function f(bytes calldata) internal;
}
// ----
// TypeError: (31-45): Data location must be "storage" or "memory" for parameter in function, but "calldata" was given.
// TypeError: (0-58): Contract "test" should be marked as abstract.
// TypeError: (20-56): Functions without implementation must be marked virtual.
@@ -2,4 +2,4 @@ contract C {
function g(uint[]) internal pure {}
}
// ----
// TypeError: (28-34): Data location must be "storage" or "memory" for parameter in function, but none was given.
// TypeError: (28-34): Data location must be "storage", "memory" or "calldata" for parameter in function, but none was given.
@@ -2,4 +2,4 @@ contract C {
function g() internal pure returns(uint[]) {}
}
// ----
// TypeError: (52-58): Data location must be "storage" or "memory" for return parameter in function, but none was given.
// TypeError: (52-58): Data location must be "storage", "memory" or "calldata" for return parameter in function, but none was given.
@@ -6,7 +6,7 @@ library L {
function j(mapping(uint => uint)) external pure {}
}
// ----
// TypeError: (52-59): Data location must be "storage" or "calldata" for parameter in external function, but none was given.
// TypeError: (93-99): Data location must be "storage" or "calldata" for parameter in external function, but none was given.
// TypeError: (133-134): Data location must be "storage" or "calldata" for parameter in external function, but none was given.
// TypeError: (168-189): Data location must be "storage" or "calldata" for parameter in external function, but none was given.
// TypeError: (52-59): Data location must be "storage", "memory" or "calldata" for parameter in external function, but none was given.
// TypeError: (93-99): Data location must be "storage", "memory" or "calldata" for parameter in external function, but none was given.
// TypeError: (133-134): Data location must be "storage", "memory" or "calldata" for parameter in external function, but none was given.
// TypeError: (168-189): Data location must be "storage", "memory" or "calldata" for parameter in external function, but none was given.
@@ -6,7 +6,7 @@ library L {
function j() external pure returns (mapping(uint => uint)) {}
}
// ----
// TypeError: (77-84): Data location must be "storage" or "memory" for return parameter in function, but none was given.
// TypeError: (129-135): Data location must be "storage" or "memory" for return parameter in function, but none was given.
// TypeError: (180-181): Data location must be "storage" or "memory" for return parameter in function, but none was given.
// TypeError: (226-247): Data location must be "storage" or "memory" for return parameter in function, but none was given.
// TypeError: (77-84): Data location must be "storage", "memory" or "calldata" for return parameter in function, but none was given.
// TypeError: (129-135): Data location must be "storage", "memory" or "calldata" for return parameter in function, but none was given.
// TypeError: (180-181): Data location must be "storage", "memory" or "calldata" for return parameter in function, but none was given.
// TypeError: (226-247): Data location must be "storage", "memory" or "calldata" for return parameter in function, but none was given.
@@ -10,11 +10,11 @@ library L {
function jp(mapping(uint => uint)) internal pure {}
}
// ----
// TypeError: (77-84): Data location must be "storage" or "memory" for return parameter in function, but none was given.
// TypeError: (129-135): Data location must be "storage" or "memory" for return parameter in function, but none was given.
// TypeError: (180-181): Data location must be "storage" or "memory" for return parameter in function, but none was given.
// TypeError: (226-247): Data location must be "storage" or "memory" for return parameter in function, but none was given.
// TypeError: (268-275): Data location must be "storage" or "memory" for parameter in function, but none was given.
// TypeError: (310-316): Data location must be "storage" or "memory" for parameter in function, but none was given.
// TypeError: (351-352): Data location must be "storage" or "memory" for parameter in function, but none was given.
// TypeError: (387-408): Data location must be "storage" or "memory" for parameter in function, but none was given.
// TypeError: (77-84): Data location must be "storage", "memory" or "calldata" for return parameter in function, but none was given.
// TypeError: (129-135): Data location must be "storage", "memory" or "calldata" for return parameter in function, but none was given.
// TypeError: (180-181): Data location must be "storage", "memory" or "calldata" for return parameter in function, but none was given.
// TypeError: (226-247): Data location must be "storage", "memory" or "calldata" for return parameter in function, but none was given.
// TypeError: (268-275): Data location must be "storage", "memory" or "calldata" for parameter in function, but none was given.
// TypeError: (310-316): Data location must be "storage", "memory" or "calldata" for parameter in function, but none was given.
// TypeError: (351-352): Data location must be "storage", "memory" or "calldata" for parameter in function, but none was given.
// TypeError: (387-408): Data location must be "storage", "memory" or "calldata" for parameter in function, but none was given.
@@ -10,11 +10,11 @@ library L {
function jp(mapping(uint => uint)) private pure {}
}
// ----
// TypeError: (76-83): Data location must be "storage" or "memory" for return parameter in function, but none was given.
// TypeError: (127-133): Data location must be "storage" or "memory" for return parameter in function, but none was given.
// TypeError: (177-178): Data location must be "storage" or "memory" for return parameter in function, but none was given.
// TypeError: (222-243): Data location must be "storage" or "memory" for return parameter in function, but none was given.
// TypeError: (264-271): Data location must be "storage" or "memory" for parameter in function, but none was given.
// TypeError: (305-311): Data location must be "storage" or "memory" for parameter in function, but none was given.
// TypeError: (345-346): Data location must be "storage" or "memory" for parameter in function, but none was given.
// TypeError: (380-401): Data location must be "storage" or "memory" for parameter in function, but none was given.
// TypeError: (76-83): Data location must be "storage", "memory" or "calldata" for return parameter in function, but none was given.
// TypeError: (127-133): Data location must be "storage", "memory" or "calldata" for return parameter in function, but none was given.
// TypeError: (177-178): Data location must be "storage", "memory" or "calldata" for return parameter in function, but none was given.
// TypeError: (222-243): Data location must be "storage", "memory" or "calldata" for return parameter in function, but none was given.
// TypeError: (264-271): Data location must be "storage", "memory" or "calldata" for parameter in function, but none was given.
// TypeError: (305-311): Data location must be "storage", "memory" or "calldata" for parameter in function, but none was given.
// TypeError: (345-346): Data location must be "storage", "memory" or "calldata" for parameter in function, but none was given.
// TypeError: (380-401): Data location must be "storage", "memory" or "calldata" for parameter in function, but none was given.
@@ -9,11 +9,11 @@ library L {
function ip(S) private pure {}
function jp(mapping(uint => uint)) private pure {}}
// ----
// TypeError: (76-83): Data location must be "storage" or "memory" for return parameter in function, but none was given.
// TypeError: (127-133): Data location must be "storage" or "memory" for return parameter in function, but none was given.
// TypeError: (177-178): Data location must be "storage" or "memory" for return parameter in function, but none was given.
// TypeError: (222-243): Data location must be "storage" or "memory" for return parameter in function, but none was given.
// TypeError: (264-271): Data location must be "storage" or "memory" for parameter in function, but none was given.
// TypeError: (305-311): Data location must be "storage" or "memory" for parameter in function, but none was given.
// TypeError: (345-346): Data location must be "storage" or "memory" for parameter in function, but none was given.
// TypeError: (380-401): Data location must be "storage" or "memory" for parameter in function, but none was given.
// TypeError: (76-83): Data location must be "storage", "memory" or "calldata" for return parameter in function, but none was given.
// TypeError: (127-133): Data location must be "storage", "memory" or "calldata" for return parameter in function, but none was given.
// TypeError: (177-178): Data location must be "storage", "memory" or "calldata" for return parameter in function, but none was given.
// TypeError: (222-243): Data location must be "storage", "memory" or "calldata" for return parameter in function, but none was given.
// TypeError: (264-271): Data location must be "storage", "memory" or "calldata" for parameter in function, but none was given.
// TypeError: (305-311): Data location must be "storage", "memory" or "calldata" for parameter in function, but none was given.
// TypeError: (345-346): Data location must be "storage", "memory" or "calldata" for parameter in function, but none was given.
// TypeError: (380-401): Data location must be "storage", "memory" or "calldata" for parameter in function, but none was given.
@@ -2,4 +2,3 @@ library test {
function f(bytes memory) external {}
}
// ----
// TypeError: (30-42): Data location must be "storage" or "calldata" for parameter in external function, but "memory" was given.
@@ -2,4 +2,3 @@ library test {
function f(bytes calldata) internal pure {}
}
// ----
// TypeError: (30-44): Data location must be "storage" or "memory" for parameter in function, but "calldata" was given.
@@ -2,4 +2,4 @@ contract C {
function f(uint[]) private pure {}
}
// ----
// TypeError: (28-34): Data location must be "storage" or "memory" for parameter in function, but none was given.
// TypeError: (28-34): Data location must be "storage", "memory" or "calldata" for parameter in function, but none was given.
@@ -2,4 +2,4 @@ contract C {
function f() private pure returns(uint[]) {}
}
// ----
// TypeError: (51-57): Data location must be "storage" or "memory" for return parameter in function, but none was given.
// TypeError: (51-57): Data location must be "storage", "memory" or "calldata" for return parameter in function, but none was given.
@@ -2,4 +2,5 @@ contract test {
function f(bytes calldata) public;
}
// ----
// TypeError: (31-45): Data location must be "memory" for parameter in function, but "calldata" was given.
// TypeError: (0-56): Contract "test" should be marked as abstract.
// TypeError: (20-54): Functions without implementation must be marked virtual.
@@ -2,4 +2,4 @@ contract test {
function f(bytes storage) public;
}
// ----
// TypeError: (31-44): Data location must be "memory" for parameter in function, but "storage" was given.
// TypeError: (31-44): Data location must be "memory" or "calldata" for parameter in function, but "storage" was given.
@@ -2,4 +2,4 @@ contract C {
function h(uint[]) public pure {}
}
// ----
// TypeError: (28-34): Data location must be "memory" for parameter in function, but none was given.
// TypeError: (28-34): Data location must be "memory" or "calldata" for parameter in function, but none was given.
@@ -2,4 +2,4 @@ contract C {
function h() public pure returns(uint[]) {}
}
// ----
// TypeError: (50-56): Data location must be "memory" for return parameter in function, but none was given.
// TypeError: (50-56): Data location must be "memory" or "calldata" for return parameter in function, but none was given.
@@ -3,4 +3,4 @@ contract c {
}
// ----
// TypeError: (51-52): Invalid array length, expected integer literal or constant expression.
// TypeError: (45-55): Data location must be "storage" or "memory" for variable, but none was given.
// TypeError: (45-55): Data location must be "storage", "memory" or "calldata" for variable, but none was given.
@@ -3,4 +3,4 @@ contract c {
}
// ----
// TypeError: (51-53): Array with negative length specified.
// TypeError: (45-56): Data location must be "storage" or "memory" for variable, but none was given.
// TypeError: (45-56): Data location must be "storage", "memory" or "calldata" for variable, but none was given.
@@ -2,4 +2,3 @@ contract C {
function f(uint[] memory a) external {}
}
// ----
// TypeError: (28-43): Data location must be "calldata" for parameter in external function, but "memory" was given.
@@ -2,4 +2,4 @@ contract C {
function f(uint[] storage a) external {}
}
// ----
// TypeError: (28-44): Data location must be "calldata" for parameter in external function, but "storage" was given.
// TypeError: (28-44): Data location must be "memory" or "calldata" for parameter in external function, but "storage" was given.
@@ -5,4 +5,4 @@ contract test {
}
// ----
// TypeError: (55-58): Array with fractional length specified.
// TypeError: (50-61): Data location must be "storage" or "memory" for variable, but none was given.
// TypeError: (50-61): Data location must be "storage", "memory" or "calldata" for variable, but none was given.
@@ -5,4 +5,4 @@ contract test {
}
// ----
// TypeError: (55-65): Invalid array length, expected integer literal or constant expression.
// TypeError: (50-68): Data location must be "storage" or "memory" for variable, but none was given.
// TypeError: (50-68): Data location must be "storage", "memory" or "calldata" for variable, but none was given.
@@ -5,4 +5,4 @@ contract test {
}
// ----
// TypeError: (55-66): Invalid array length, expected integer literal or constant expression.
// TypeError: (50-69): Data location must be "storage" or "memory" for variable, but none was given.
// TypeError: (50-69): Data location must be "storage", "memory" or "calldata" for variable, but none was given.
@@ -9,5 +9,5 @@ contract C {
}
}
// ----
// TypeError: (104-107): Data location must be "storage" or "memory" for variable, but none was given.
// TypeError: (123-131): Data location must be "storage" or "memory" for variable, but none was given.
// TypeError: (104-107): Data location must be "storage", "memory" or "calldata" for variable, but none was given.
// TypeError: (123-131): Data location must be "storage", "memory" or "calldata" for variable, but none was given.
@@ -3,4 +3,4 @@ contract C {
}
}
// ----
// TypeError: (28-57): Data location must be "calldata" for parameter in external function, but "storage" was given.
// TypeError: (28-57): Data location must be "memory" or "calldata" for parameter in external function, but "storage" was given.
@@ -3,4 +3,4 @@ contract C {
}
}
// ----
// TypeError: (28-57): Data location must be "memory" for parameter in function, but "storage" was given.
// TypeError: (28-57): Data location must be "memory" or "calldata" for parameter in function, but "storage" was given.
@@ -3,4 +3,4 @@ contract C {
}
}
// ----
// TypeError: (28-59): Data location must be "calldata" for parameter in external function, but "storage" was given.
// TypeError: (28-59): Data location must be "memory" or "calldata" for parameter in external function, but "storage" was given.
@@ -3,4 +3,4 @@ contract C {
}
}
// ----
// TypeError: (28-59): Data location must be "memory" for parameter in function, but "storage" was given.
// TypeError: (28-59): Data location must be "memory" or "calldata" for parameter in function, but "storage" was given.
@@ -3,4 +3,4 @@ contract C {
}
}
// ----
// TypeError: (37-64): Data location must be "memory" for parameter in function, but "storage" was given.
// TypeError: (37-64): Data location must be "memory" or "calldata" for parameter in function, but "storage" was given.
@@ -3,4 +3,4 @@ contract C {
}
}
// ----
// TypeError: (57-84): Data location must be "memory" for return parameter in function, but "storage" was given.
// TypeError: (57-84): Data location must be "memory" or "calldata" for return parameter in function, but "storage" was given.
@@ -3,4 +3,4 @@ contract C {
}
}
// ----
// TypeError: (53-84): Data location must be "memory" for return parameter in function, but "storage" was given.
// TypeError: (53-84): Data location must be "memory" or "calldata" for return parameter in function, but "storage" was given.
@@ -3,4 +3,4 @@ contract C {
}
}
// ----
// TypeError: (51-82): Data location must be "memory" for return parameter in function, but "storage" was given.
// TypeError: (51-82): Data location must be "memory" or "calldata" for return parameter in function, but "storage" was given.
@@ -3,4 +3,4 @@ contract C {
}
}
// ----
// TypeError: (53-82): Data location must be "memory" for return parameter in function, but "storage" was given.
// TypeError: (53-82): Data location must be "memory" or "calldata" for return parameter in function, but "storage" was given.
@@ -3,4 +3,4 @@ contract C {
}
}
// ----
// TypeError: (51-80): Data location must be "memory" for return parameter in function, but "storage" was given.
// TypeError: (51-80): Data location must be "memory" or "calldata" for return parameter in function, but "storage" was given.