mirror of
				https://github.com/ethereum/solidity
				synced 2023-10-03 13:03:40 +00:00 
			
		
		
		
	Merge pull request #8942 from ethereum/calldataVariables
Calldata variables.
This commit is contained in:
		
						commit
						e6b399c86e
					
				| @ -1,6 +1,7 @@ | ||||
| ### 0.6.9 (unreleased) | ||||
| 
 | ||||
| Language Features: | ||||
|  * Permit calldata location for all variables. | ||||
| 
 | ||||
| 
 | ||||
| Compiler Features: | ||||
|  | ||||
| @ -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 | ||||
|  | ||||
| @ -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." | ||||
| 			); | ||||
|  | ||||
| @ -338,7 +338,13 @@ TypePointer FunctionDefinition::type() const | ||||
| TypePointer FunctionDefinition::typeViaContractName() const | ||||
| { | ||||
| 	if (annotation().contract->isLibrary()) | ||||
| 	{ | ||||
| 		if (isPublic()) | ||||
| 			return FunctionType(*this).asCallableFunction(true); | ||||
| 		else | ||||
| 			return TypeProvider::function(*this, FunctionType::Kind::Internal); | ||||
| 	} | ||||
| 	else | ||||
| 		return TypeProvider::function(*this, FunctionType::Kind::Declaration); | ||||
| } | ||||
| 
 | ||||
| @ -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); | ||||
|  | ||||
| @ -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()) | ||||
|  | ||||
| @ -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. | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user