aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Changelog.md5
-rw-r--r--docs/solidity-by-example.rst46
-rw-r--r--docs/types.rst22
-rw-r--r--libdevcore/StringUtils.h28
-rw-r--r--libsolidity/analysis/NameAndTypeResolver.cpp11
-rw-r--r--libsolidity/analysis/NameAndTypeResolver.h2
-rw-r--r--libsolidity/analysis/ReferencesResolver.cpp192
-rw-r--r--libsolidity/analysis/TypeChecker.cpp9
-rw-r--r--libsolidity/ast/AST.cpp121
-rw-r--r--libsolidity/ast/AST.h16
-rw-r--r--test/compilationTests/corion/moduleHandler.sol12
-rw-r--r--test/compilationTests/corion/premium.sol8
-rw-r--r--test/compilationTests/corion/provider.sol8
-rw-r--r--test/compilationTests/corion/publisher.sol2
-rw-r--r--test/compilationTests/corion/schelling.sol2
-rw-r--r--test/compilationTests/corion/token.sol8
-rw-r--r--test/compilationTests/zeppelin/MultisigWallet.sol2
-rw-r--r--test/compilationTests/zeppelin/ownership/HasNoTokens.sol2
-rw-r--r--test/compilationTests/zeppelin/ownership/Multisig.sol2
-rw-r--r--test/contracts/AuctionRegistrar.cpp2
-rw-r--r--test/contracts/Wallet.cpp4
-rw-r--r--test/libsolidity/ABIDecoderTests.cpp4
-rw-r--r--test/libsolidity/ABIEncoderTests.cpp2
-rw-r--r--test/libsolidity/ASTJSON/function_type.json4
-rw-r--r--test/libsolidity/ASTJSON/function_type.sol2
-rw-r--r--test/libsolidity/ASTJSON/function_type_legacy.json4
-rw-r--r--test/libsolidity/SolidityABIJSON.cpp2
-rw-r--r--test/libsolidity/SolidityEndToEndTest.cpp42
-rw-r--r--test/libsolidity/SolidityNameAndTypeResolution.cpp20
-rw-r--r--test/libsolidity/syntaxTests/array/length/array_length_cannot_be_constant_function_parameter.sol1
-rw-r--r--test/libsolidity/syntaxTests/conversion/conversion_to_bytes.sol2
-rw-r--r--test/libsolidity/syntaxTests/dataLocations/data_location_in_function_type.sol4
-rw-r--r--test/libsolidity/syntaxTests/dataLocations/data_location_in_function_type_fail.sol9
-rw-r--r--test/libsolidity/syntaxTests/dataLocations/externalFunction/external_function_return_parameters_no_data_location.sol5
-rw-r--r--test/libsolidity/syntaxTests/dataLocations/externalFunction/function_argument_location_specifier_test_external_memory.sol2
-rw-r--r--test/libsolidity/syntaxTests/dataLocations/externalFunction/function_argument_location_specifier_test_external_storage.sol2
-rw-r--r--test/libsolidity/syntaxTests/dataLocations/function_argument_location_specifier_test_library.sol5
-rw-r--r--test/libsolidity/syntaxTests/dataLocations/function_argument_location_specifier_test_non_reference_type.sol2
-rw-r--r--test/libsolidity/syntaxTests/dataLocations/function_parameters_with_data_location_fine.sol8
-rw-r--r--test/libsolidity/syntaxTests/dataLocations/function_return_parameters_with_data_location_fine.sol6
-rw-r--r--test/libsolidity/syntaxTests/dataLocations/function_type_array_as_reference_type.sol8
-rw-r--r--test/libsolidity/syntaxTests/dataLocations/internalFunction/function_argument_location_specifier_test_internal_calldata.sol2
-rw-r--r--test/libsolidity/syntaxTests/dataLocations/internalFunction/internal_function_parameters_no_data_location.sol5
-rw-r--r--test/libsolidity/syntaxTests/dataLocations/internalFunction/internal_function_return_parameters_no_data_location.sol5
-rw-r--r--test/libsolidity/syntaxTests/dataLocations/libraries/library_external_function_params_no_data_location.sol12
-rw-r--r--test/libsolidity/syntaxTests/dataLocations/libraries/library_external_function_return_no_data_location.sol12
-rw-r--r--test/libsolidity/syntaxTests/dataLocations/libraries/library_function_with_data_location_fine.sol10
-rw-r--r--test/libsolidity/syntaxTests/dataLocations/libraries/library_internal_function_no_data_location.sol20
-rw-r--r--test/libsolidity/syntaxTests/dataLocations/libraries/library_private_function_no_data_location.sol20
-rw-r--r--test/libsolidity/syntaxTests/dataLocations/libraries/library_public_function_no_data_location.sol19
-rw-r--r--test/libsolidity/syntaxTests/dataLocations/libraryExternalFunction/function_argument_location_specifier_test_external_memory.sol2
-rw-r--r--test/libsolidity/syntaxTests/dataLocations/libraryInternalFunction/function_argument_location_specifier_test_internal_calldata.sol2
-rw-r--r--test/libsolidity/syntaxTests/dataLocations/privateFunction/private_function_parameters_no_data_location.sol5
-rw-r--r--test/libsolidity/syntaxTests/dataLocations/privateFunction/private_function_return_parameters_no_data_location.sol5
-rw-r--r--test/libsolidity/syntaxTests/dataLocations/publicFunction/function_argument_location_specifier_test_public_calldata.sol2
-rw-r--r--test/libsolidity/syntaxTests/dataLocations/publicFunction/function_argument_location_specifier_test_public_storage.sol2
-rw-r--r--test/libsolidity/syntaxTests/dataLocations/publicFunction/public_function_parameters_no_data_location.sol5
-rw-r--r--test/libsolidity/syntaxTests/dataLocations/publicFunction/public_function_return_parameters_no_data_location.sol5
-rw-r--r--test/libsolidity/syntaxTests/dataLocations/variable_declaration_location_specifier_test_non_reference_type.sol8
-rw-r--r--test/libsolidity/syntaxTests/functionTypes/external_function_to_function_type_calldata_parameter.sol2
-rw-r--r--test/libsolidity/syntaxTests/nameAndTypeResolution/105_constant_input_parameter.sol2
-rw-r--r--test/libsolidity/syntaxTests/nameAndTypeResolution/149_test_for_bug_override_function_with_bytearray_type.sol6
-rw-r--r--test/libsolidity/syntaxTests/nameAndTypeResolution/204_overwrite_memory_location_external.sol2
-rw-r--r--test/libsolidity/syntaxTests/nameAndTypeResolution/205_overwrite_storage_location_external.sol2
-rw-r--r--test/libsolidity/syntaxTests/nameAndTypeResolution/224_string_bytes_conversion.sol18
-rw-r--r--test/libsolidity/syntaxTests/nameAndTypeResolution/385_inline_assembly_calldata_variables.sol4
-rw-r--r--test/libsolidity/syntaxTests/nameAndTypeResolution/471_unspecified_storage_fail.sol4
-rw-r--r--test/libsolidity/syntaxTests/nameAndTypeResolution/473_storage_location_non_array_or_struct_disallowed.sol2
-rw-r--r--test/libsolidity/syntaxTests/nameAndTypeResolution/474_storage_location_non_array_or_struct_disallowed_is_not_fatal.sol2
-rw-r--r--test/libsolidity/syntaxTests/nameAndTypeResolution/476_too_large_arrays_for_calldata_external.sol4
-rw-r--r--test/libsolidity/syntaxTests/nameAndTypeResolution/constant_mapping.sol8
-rw-r--r--test/libsolidity/syntaxTests/parsing/location_specifiers_for_params.sol4
-rw-r--r--test/libsolidity/syntaxTests/types/mapping/argument_external.sol3
-rw-r--r--test/libsolidity/syntaxTests/types/mapping/argument_public.sol3
-rw-r--r--test/libsolidity/syntaxTests/types/mapping/array_argument_external.sol2
-rw-r--r--test/libsolidity/syntaxTests/types/mapping/array_argument_public.sol2
-rw-r--r--test/libsolidity/syntaxTests/types/mapping/function_type_argument_external.sol1
-rw-r--r--test/libsolidity/syntaxTests/types/mapping/function_type_return_external.sol1
-rw-r--r--test/libsolidity/syntaxTests/types/mapping/mapping_array_data_location_function_param_external.sol6
-rw-r--r--test/libsolidity/syntaxTests/types/mapping/mapping_array_return_external.sol2
-rw-r--r--test/libsolidity/syntaxTests/types/mapping/mapping_array_return_public.sol2
-rw-r--r--test/libsolidity/syntaxTests/types/mapping/mapping_data_location_calldata.sol2
-rw-r--r--test/libsolidity/syntaxTests/types/mapping/mapping_data_location_default.sol2
-rw-r--r--test/libsolidity/syntaxTests/types/mapping/mapping_data_location_function_param_external.sol6
-rw-r--r--test/libsolidity/syntaxTests/types/mapping/mapping_data_location_function_param_internal.sol4
-rw-r--r--test/libsolidity/syntaxTests/types/mapping/mapping_data_location_function_param_public.sol6
-rw-r--r--test/libsolidity/syntaxTests/types/mapping/mapping_data_location_memory.sol2
-rw-r--r--test/libsolidity/syntaxTests/types/mapping/mapping_return_external.sol3
-rw-r--r--test/libsolidity/syntaxTests/types/mapping/mapping_return_public.sol3
-rw-r--r--test/libsolidity/syntaxTests/types/mapping/mapping_return_public_memory.sol7
90 files changed, 586 insertions, 310 deletions
diff --git a/Changelog.md b/Changelog.md
index ea4504ac..8a16d900 100644
--- a/Changelog.md
+++ b/Changelog.md
@@ -5,7 +5,7 @@ How to update your code:
* Change every ``keccak256(a, b, c)`` to ``keccak256(abi.encodePacked(a, b, c))``.
* Add ``public`` to every function and ``external`` to every fallback or interface function that does not specify its visibility already.
* Make your fallback functions ``external``.
- * Explicitly state the storage location for local variables of struct and array types, e.g. change ``uint[] x = m_x`` to ``uint[] storage x = m_x``.
+ * Explicitly state the data location for all variables of struct, array or mapping types (including function parameters), e.g. change ``uint[] x = m_x`` to ``uint[] storage x = m_x``. Note that ``external`` functions require parameters with a data location of ``calldata``.
* Explicitly convert values of contract type to addresses before using an ``address`` member. Example: if ``c`` is a contract, change ``c.transfer(...)`` to ``address(c).transfer(...)``.
Breaking Changes:
@@ -54,6 +54,7 @@ Breaking Changes:
* Type Checker: Disallow calling constructor with wrong argument count. This was already the case in the experimental 0.5.0 mode.
* Type Checker: Disallow uninitialized storage variables. This was already the case in the experimental 0.5.0 mode.
* Type Checker: Detecting cyclic dependencies in variables and structs is limited in recursion to 256.
+ * Type Checker: Require explicit data location for all variables, including function parameters. This was partly already the case in the experimental 0.5.0 mode.
* Type Checker: Only accept a single ``bytes`` type for ``.call()`` (and family), ``keccak256()``, ``sha256()`` and ``ripemd160()``.
* Type Checker: Fallback function must be external. This was already the case in the experimental 0.5.0 mode.
* Type Checker: Interface functions must be declared external. This was already the case in the experimental 0.5.0 mode.
@@ -61,7 +62,7 @@ Breaking Changes:
* Type Checker: Disallow "loose assembly" syntax entirely. This means that jump labels, jumps and non-functional instructions cannot be used anymore.
* Type System: Disallow explicit and implicit conversions from decimal literals to ``bytesXX`` types.
* Type System: Disallow explicit and implicit conversions from hex literals to ``bytesXX`` types of different size.
- * Remove obsolete ``std`` directory from the Solidity repository. This means accessing ``https://github.com/ethereum/soldity/blob/develop/std/*.sol`` (or ``https://github.com/ethereum/solidity/std/*.sol`` in Remix) will not be possible.
+ * Remove obsolete ``std`` directory from the Solidity repository. This means accessing ``https://github.com/ethereum/solidity/blob/develop/std/*.sol`` (or ``https://github.com/ethereum/solidity/std/*.sol`` in Remix) will not be possible.
* References Resolver: Turn missing storage locations into an error. This was already the case in the experimental 0.5.0 mode.
* Syntax Checker: Disallow functions without implementation to use modifiers. This was already the case in the experimental 0.5.0 mode.
* Syntax Checker: Named return values in function types are an error.
diff --git a/docs/solidity-by-example.rst b/docs/solidity-by-example.rst
index 7d325746..adf00546 100644
--- a/docs/solidity-by-example.rst
+++ b/docs/solidity-by-example.rst
@@ -90,7 +90,7 @@ of votes.
// If the first argument of `require` evaluates
// to `false`, execution terminates and all
// changes to the state and to Ether balances
- // are reverted.
+ // are reverted.
// This used to consume all gas in old EVM versions, but
// not anymore.
// It is often a good idea to use `require` to check if
@@ -708,7 +708,7 @@ For a contract that fulfills payments, the signed message must include:
A replay attack is when a signed message is reused to claim authorization for
a second action.
To avoid replay attacks we will use the same as in Ethereum transactions
-themselves, a so-called nonce, which is the number of transactions sent by an
+themselves, a so-called nonce, which is the number of transactions sent by an
account.
The smart contract will check if a nonce is used multiple times.
@@ -731,7 +731,7 @@ Packing arguments
Now that we have identified what information to include in the
signed message, we are ready to put the message together, hash it,
and sign it. For simplicity, we just concatenate the data.
-The
+The
`ethereumjs-abi <https://github.com/ethereumjs/ethereumjs-abi>`_ library provides
a function called ``soliditySHA3`` that mimics the behavior
of Solidity's ``keccak256`` function applied to arguments encoded
@@ -750,7 +750,7 @@ creates the proper signature for the ``ReceiverPays`` example:
["address", "uint256", "uint256", "address"],
[recipient, amount, nonce, contractAddress]
).toString("hex");
-
+
web3.personal.sign(hash, web3.eth.defaultAccount, callback);
}
@@ -779,7 +779,7 @@ at the end of this chapter).
Computing the Message Hash
--------------------------
-
+
The smart contract needs to know exactly what parameters were signed,
and so it must recreate the message from the parameters and use that
for signature verification. The functions ``prefixed`` and
@@ -801,7 +801,7 @@ The full contract
constructor() public payable {}
- function claimPayment(uint256 amount, uint256 nonce, bytes signature) public {
+ function claimPayment(uint256 amount, uint256 nonce, bytes memory signature) public {
require(!usedNonces[nonce]);
usedNonces[nonce] = true;
@@ -820,7 +820,7 @@ The full contract
}
/// signature methods.
- function splitSignature(bytes sig)
+ function splitSignature(bytes memory sig)
internal
pure
returns (uint8 v, bytes32 r, bytes32 s)
@@ -839,7 +839,7 @@ The full contract
return (v, r, s);
}
- function recoverSigner(bytes32 message, bytes sig)
+ function recoverSigner(bytes32 message, bytes memory sig)
internal
pure
returns (address)
@@ -874,7 +874,7 @@ two parties (Alice and Bob). Using it involves three steps:
1. Alice funds a smart contract with Ether. This "opens" the payment channel.
2. Alice signs messages that specify how much of that Ether is owed to the recipient. This step is repeated for each payment.
3. Bob "closes" the payment channel, withdrawing their portion of the Ether and sending the remainder back to the sender.
-
+
Not ethat only steps 1 and 3 require Ethereum transactions, step 2 means that
the sender transmits a cryptographically signed message to the recipient via off chain ways (e.g. email).
This means only two transactions are required to support any number of transfers.
@@ -906,7 +906,7 @@ Each message includes the following information:
* The smart contract's address, used to prevent cross-contract replay attacks.
* The total amount of Ether that is owed the recipient so far.
-
+
A payment channel is closed just once, at the of a series of transfers.
Because of this, only one of the messages sent will be redeemed. This is why
each message specifies a cumulative total amount of Ether owed, rather than the
@@ -926,7 +926,7 @@ Here is the modified javascript code to cryptographically sign a message from th
[contractAddress, amount]
);
}
-
+
function signMessage(message, callback) {
web3.personal.sign(
"0x" + message.toString("hex"),
@@ -934,10 +934,10 @@ Here is the modified javascript code to cryptographically sign a message from th
callback
);
}
-
+
// contractAddress is used to prevent cross-contract replay attacks.
// amount, in wei, specifies how much Ether should be sent.
-
+
function signPayment(contractAddress, amount, callback) {
var message = constructPaymentMessage(contractAddress, amount);
signMessage(message, callback);
@@ -1003,7 +1003,7 @@ The full contract
expiration = now + duration;
}
- function isValidSignature(uint256 amount, bytes signature)
+ function isValidSignature(uint256 amount, bytes memory signature)
internal
view
returns (bool)
@@ -1017,7 +1017,7 @@ The full contract
/// the recipient can close the channel at any time by presenting a
/// signed amount from the sender. the recipient will be sent that amount,
/// and the remainder will go back to the sender
- function close(uint256 amount, bytes signature) public {
+ function close(uint256 amount, bytes memory signature) public {
require(msg.sender == recipient);
require(isValidSignature(amount, signature));
@@ -1043,7 +1043,7 @@ The full contract
/// All functions below this are just taken from the chapter
/// 'creating and verifying signatures' chapter.
- function splitSignature(bytes sig)
+ function splitSignature(bytes memory sig)
internal
pure
returns (uint8 v, bytes32 r, bytes32 s)
@@ -1058,11 +1058,11 @@ The full contract
// final byte (first byte of the next 32 bytes)
v := byte(0, mload(add(sig, 96)))
}
-
+
return (v, r, s);
}
-
- function recoverSigner(bytes32 message, bytes sig)
+
+ function recoverSigner(bytes32 message, bytes memory sig)
internal
pure
returns (address)
@@ -1083,7 +1083,7 @@ Note: The function ``splitSignature`` is very simple and does not use all securi
A real implementation should use a more rigorously tested library, such as
openzepplin's `version <https://github.com/OpenZeppelin/openzeppelin-solidity/blob/master/contracts/ECRecovery.sol>`_ of this code.
-
+
Verifying Payments
------------------
@@ -1101,7 +1101,7 @@ The recipient should verify each message using the following process:
2. Verify that the new total is the expected amount.
3. Verify that the new total does not exceed the amount of Ether escrowed.
4. Verify that the signature is valid and comes from the payment channel sender.
-
+
We'll use the `ethereumjs-util <https://github.com/ethereumjs/ethereumjs-util>`_
library to write this verifications. The final step can be done a number of ways,
but if it's being done in **JavaScript**.
@@ -1117,14 +1117,14 @@ above:
["\x19Ethereum Signed Message:\n32", hash]
);
}
-
+
function recoverSigner(message, signature) {
var split = ethereumjs.Util.fromRpcSig(signature);
var publicKey = ethereumjs.Util.ecrecover(message, split.v, split.r, split.s);
var signer = ethereumjs.Util.pubToAddress(publicKey).toString("hex");
return signer;
}
-
+
function isValidSignature(contractAddress, amount, signature, expectedSigner) {
var message = prefixed(constructPaymentMessage(contractAddress, amount));
var signer = recoverSigner(message, signature);
diff --git a/docs/types.rst b/docs/types.rst
index 18400dee..0e0f4b13 100644
--- a/docs/types.rst
+++ b/docs/types.rst
@@ -580,16 +580,18 @@ variables are held).
Data location
-------------
+
Every complex type, i.e. *arrays* and *structs*, has an additional
-annotation, the "data location", about whether it is stored in memory or in storage. Depending on the
-context, there is always a default, but it can be overridden by appending
-either ``storage`` or ``memory`` to the type. The default for function parameters (including return parameters) is ``memory``, the default for local variables is ``storage`` and the location is forced
-to ``storage`` for state variables (obviously).
+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,
+non-persistent area where function arguments are stored, and behaves mostly like memory.
+
-There is also a third data location, ``calldata``, which is a non-modifiable,
-non-persistent area where function arguments are stored. Function parameters
-(not return parameters) of external functions are forced to ``calldata`` and
-behave mostly like ``memory``.
+.. note::
+ Prior to version 0.5.0 the data location could be omitted, and would default to different locations
+ depending on the kind of variable, function type, etc., but all complex types must now give an explicit
+ data location.
Data locations are important because they change how assignments behave:
assignments between storage and memory and also to a state variable (even from other state variables)
@@ -635,10 +637,6 @@ Forced data location:
- parameters (not return) of external functions: calldata
- state variables: storage
-Default data location:
- - parameters (also return) of functions: memory
- - all other local variables: storage
-
.. index:: ! array
.. _arrays:
diff --git a/libdevcore/StringUtils.h b/libdevcore/StringUtils.h
index 94c6e3c5..f05a426b 100644
--- a/libdevcore/StringUtils.h
+++ b/libdevcore/StringUtils.h
@@ -49,27 +49,23 @@ std::string joinHumanReadable
std::string const& _lastSeparator = ""
)
{
- auto it = begin(_list);
- auto itEnd = end(_list);
+ auto const itEnd = end(_list);
std::string result;
- // append first string
- if (it != itEnd)
+ for (auto it = begin(_list); it != itEnd; )
{
- result += *it;
+ std::string element = *it;
+ bool first = (it == begin(_list));
++it;
- }
-
- for (;it != itEnd; ++it)
- {
- if ((std::next(it) == itEnd) && !_lastSeparator.empty())
- result += _lastSeparator; // last iteration
- else
- result += _separator;
-
- // append string
- result += *it;
+ if (!first)
+ {
+ if (it == itEnd && !_lastSeparator.empty())
+ result += _lastSeparator; // last iteration
+ else
+ result += _separator;
+ }
+ result += std::move(element);
}
return result;
diff --git a/libsolidity/analysis/NameAndTypeResolver.cpp b/libsolidity/analysis/NameAndTypeResolver.cpp
index c5c429ce..b452a49a 100644
--- a/libsolidity/analysis/NameAndTypeResolver.cpp
+++ b/libsolidity/analysis/NameAndTypeResolver.cpp
@@ -626,6 +626,17 @@ void DeclarationRegistrationHelper::endVisit(ModifierDefinition&)
closeCurrentScope();
}
+bool DeclarationRegistrationHelper::visit(FunctionTypeName& _funTypeName)
+{
+ enterNewSubScope(_funTypeName);
+ return true;
+}
+
+void DeclarationRegistrationHelper::endVisit(FunctionTypeName&)
+{
+ closeCurrentScope();
+}
+
bool DeclarationRegistrationHelper::visit(Block& _block)
{
_block.setScope(m_currentScope);
diff --git a/libsolidity/analysis/NameAndTypeResolver.h b/libsolidity/analysis/NameAndTypeResolver.h
index 8178ee17..a72c21e3 100644
--- a/libsolidity/analysis/NameAndTypeResolver.h
+++ b/libsolidity/analysis/NameAndTypeResolver.h
@@ -171,6 +171,8 @@ private:
void endVisit(FunctionDefinition& _function) override;
bool visit(ModifierDefinition& _modifier) override;
void endVisit(ModifierDefinition& _modifier) override;
+ bool visit(FunctionTypeName& _funTypeName) override;
+ void endVisit(FunctionTypeName& _funTypeName) override;
bool visit(Block& _block) override;
void endVisit(Block& _block) override;
bool visit(ForStatement& _forLoop) override;
diff --git a/libsolidity/analysis/ReferencesResolver.cpp b/libsolidity/analysis/ReferencesResolver.cpp
index fa0888dd..f33de7b7 100644
--- a/libsolidity/analysis/ReferencesResolver.cpp
+++ b/libsolidity/analysis/ReferencesResolver.cpp
@@ -30,7 +30,10 @@
#include <libsolidity/inlineasm/AsmData.h>
#include <libsolidity/interface/ErrorReporter.h>
+#include <libdevcore/StringUtils.h>
+
#include <boost/algorithm/string.hpp>
+#include <boost/range/adaptor/transformed.hpp>
using namespace std;
using namespace dev;
@@ -155,7 +158,10 @@ void ReferencesResolver::endVisit(UserDefinedTypeName const& _typeName)
else if (ContractDefinition const* contract = dynamic_cast<ContractDefinition const*>(declaration))
_typeName.annotation().type = make_shared<ContractType>(*contract);
else
+ {
+ _typeName.annotation().type = make_shared<TupleType>();
typeError(_typeName.location(), "Name has to refer to a struct, enum or contract.");
+ }
}
void ReferencesResolver::endVisit(FunctionTypeName const& _typeName)
@@ -166,13 +172,13 @@ void ReferencesResolver::endVisit(FunctionTypeName const& _typeName)
case VariableDeclaration::Visibility::External:
break;
default:
- typeError(_typeName.location(), "Invalid visibility, can only be \"external\" or \"internal\".");
+ fatalTypeError(_typeName.location(), "Invalid visibility, can only be \"external\" or \"internal\".");
return;
}
if (_typeName.isPayable() && _typeName.visibility() != VariableDeclaration::Visibility::External)
{
- typeError(_typeName.location(), "Only external function types can be payable.");
+ fatalTypeError(_typeName.location(), "Only external function types can be payable.");
return;
}
@@ -182,7 +188,7 @@ void ReferencesResolver::endVisit(FunctionTypeName const& _typeName)
solAssert(t->annotation().type, "Type not set for parameter.");
if (!t->annotation().type->canBeUsedExternally(false))
{
- typeError(t->location(), "Internal type cannot be used for external function type.");
+ fatalTypeError(t->location(), "Internal type cannot be used for external function type.");
return;
}
}
@@ -300,6 +306,9 @@ void ReferencesResolver::endVisit(VariableDeclaration const& _variable)
if (_variable.annotation().type)
return;
+ if (_variable.isConstant() && !_variable.isStateVariable())
+ m_errorReporter.declarationError(_variable.location(), "The \"constant\" keyword can only be used for state variables.");
+
if (!_variable.typeName())
{
// This can still happen in very unusual cases where a developer uses constructs, such as
@@ -309,127 +318,92 @@ void ReferencesResolver::endVisit(VariableDeclaration const& _variable)
// after this step.
return;
}
-
- TypePointer type;
- type = _variable.typeName()->annotation().type;
using Location = VariableDeclaration::Location;
Location varLoc = _variable.referenceLocation();
DataLocation typeLoc = DataLocation::Memory;
- // References are forced to calldata for external function parameters (not return)
- // and memory for parameters (also return) of publicly visible functions.
- // They default to memory for function parameters and storage for local variables.
- // As an exception, "storage" is allowed for library functions.
- if (auto ref = dynamic_cast<ReferenceType const*>(type.get()))
+
+ set<Location> allowedDataLocations = _variable.allowedDataLocations();
+ if (!allowedDataLocations.count(varLoc))
{
- bool isPointer = true;
- if (_variable.isExternalCallableParameter())
+ auto locationToString = [](VariableDeclaration::Location _location) -> string
{
- auto const& contract = dynamic_cast<ContractDefinition const&>(
- *dynamic_cast<Declaration const&>(*_variable.scope()).scope()
- );
- if (contract.isLibrary())
- {
- if (varLoc == Location::Memory)
- fatalTypeError(_variable.location(),
- "Location has to be calldata or storage for external "
- "library functions (remove the \"memory\" keyword)."
- );
- }
- else
+ switch (_location)
{
- // force location of external function parameters (not return) to calldata
- if (varLoc != Location::CallData && varLoc != Location::Default)
- fatalTypeError(_variable.location(),
- "Location has to be calldata for external functions "
- "(remove the \"memory\" or \"storage\" keyword)."
- );
+ case Location::Memory: return "\"memory\"";
+ case Location::Storage: return "\"storage\"";
+ case Location::CallData: return "\"calldata\"";
+ case Location::Default: return "none";
}
- if (varLoc == Location::Default || varLoc == Location::CallData)
- typeLoc = DataLocation::CallData;
- else
- typeLoc = varLoc == Location::Memory ? DataLocation::Memory : DataLocation::Storage;
- }
- else if (_variable.isCallableParameter() && dynamic_cast<Declaration const&>(*_variable.scope()).isPublic())
+ return {};
+ };
+
+ string errorString;
+ if (!_variable.hasReferenceOrMappingType())
+ errorString = "Data location can only be specified for array, struct or mapping types";
+ else
{
- auto const& contract = dynamic_cast<ContractDefinition const&>(
- *dynamic_cast<Declaration const&>(*_variable.scope()).scope()
+ errorString = "Data location must be " +
+ joinHumanReadable(
+ allowedDataLocations | boost::adaptors::transformed(locationToString),
+ ", ",
+ " or "
);
- // force locations of public or external function (return) parameters to memory
- if (varLoc != Location::Memory && varLoc != Location::Default && !contract.isLibrary())
- fatalTypeError(_variable.location(),
- "Location has to be memory for publicly visible functions "
- "(remove the \"storage\" or \"calldata\" keyword)."
- );
- if (varLoc == Location::Default || !contract.isLibrary())
- typeLoc = DataLocation::Memory;
+ if (_variable.isCallableParameter())
+ errorString +=
+ " for " +
+ string(_variable.isReturnParameter() ? "return " : "") +
+ "parameter in" +
+ string(_variable.isExternalCallableParameter() ? " external" : "") +
+ " function";
else
- {
- if (varLoc == Location::CallData)
- fatalTypeError(_variable.location(),
- "Location cannot be calldata for non-external functions "
- "(remove the \"calldata\" keyword)."
- );
- typeLoc = varLoc == Location::Memory ? DataLocation::Memory : DataLocation::Storage;
- }
+ errorString += " for variable";
}
- else
+ errorString += ", but " + locationToString(varLoc) + " was given.";
+ typeError(_variable.location(), errorString);
+
+ solAssert(!allowedDataLocations.empty(), "");
+ varLoc = *allowedDataLocations.begin();
+ }
+
+ // Find correct data location.
+ if (_variable.isEventParameter())
+ {
+ solAssert(varLoc == Location::Default, "");
+ typeLoc = DataLocation::Memory;
+ }
+ else if (_variable.isStateVariable())
+ {
+ solAssert(varLoc == Location::Default, "");
+ typeLoc = _variable.isConstant() ? DataLocation::Memory : DataLocation::Storage;
+ }
+ else if (
+ dynamic_cast<StructDefinition const*>(_variable.scope()) ||
+ dynamic_cast<EnumDefinition const*>(_variable.scope())
+ )
+ // The actual location will later be changed depending on how the type is used.
+ typeLoc = DataLocation::Storage;
+ else
+ switch (varLoc)
{
- if (_variable.isConstant())
- {
- if (varLoc != Location::Default && varLoc != Location::Memory)
- fatalTypeError(
- _variable.location(),
- "Data location has to be \"memory\" (or unspecified) for constants."
- );
- typeLoc = DataLocation::Memory;
- }
- else if (varLoc == Location::Default)
- {
- if (_variable.isCallableParameter())
- typeLoc = DataLocation::Memory;
- else
- {
- typeLoc = DataLocation::Storage;
- if (_variable.isLocalVariable())
- typeError(
- _variable.location(),
- "Data location must be specified as either \"memory\" or \"storage\"."
- );
- }
- }
- else
- {
- switch (varLoc)
- {
- case Location::Memory:
- typeLoc = DataLocation::Memory;
- break;
- case Location::Storage:
- typeLoc = DataLocation::Storage;
- break;
- case Location::CallData:
- fatalTypeError(_variable.location(),
- "Variable cannot be declared as \"calldata\" (remove the \"calldata\" keyword)."
- );
- break;
- default:
- solAssert(false, "Unknown data location");
- }
- }
- isPointer = !_variable.isStateVariable();
+ case Location::Memory:
+ typeLoc = DataLocation::Memory;
+ break;
+ case Location::Storage:
+ typeLoc = DataLocation::Storage;
+ break;
+ case Location::CallData:
+ typeLoc = DataLocation::CallData;
+ break;
+ case Location::Default:
+ solAssert(!_variable.hasReferenceOrMappingType(), "Data location not properly set.");
}
- type = ref->copyForLocation(typeLoc, isPointer);
- }
- else if (dynamic_cast<MappingType const*>(type.get()))
+
+ TypePointer type = _variable.typeName()->annotation().type;
+ if (auto ref = dynamic_cast<ReferenceType const*>(type.get()))
{
- if (_variable.isLocalVariable() && varLoc != Location::Storage)
- typeError(
- _variable.location(),
- "Data location for mappings must be specified as \"storage\"."
- );
+ bool isPointer = !_variable.isStateVariable();
+ type = ref->copyForLocation(typeLoc, isPointer);
}
- else if (varLoc != Location::Default && !ref)
- typeError(_variable.location(), "Data location can only be given for array or struct types.");
_variable.annotation().type = type;
}
diff --git a/libsolidity/analysis/TypeChecker.cpp b/libsolidity/analysis/TypeChecker.cpp
index 601a5e7c..8b609a31 100644
--- a/libsolidity/analysis/TypeChecker.cpp
+++ b/libsolidity/analysis/TypeChecker.cpp
@@ -630,8 +630,13 @@ bool TypeChecker::visit(FunctionDefinition const& _function)
for (ASTPointer<VariableDeclaration> const& var: _function.parameters() + _function.returnParameters())
{
if (
+ type(*var)->category() == Type::Category::Mapping &&
+ !type(*var)->dataStoredIn(DataLocation::Storage)
+ )
+ m_errorReporter.typeError(var->location(), "Mapping types can only have a data location of \"storage\".");
+ else if (
!type(*var)->canLiveOutsideStorage() &&
- !(_function.visibility() <= FunctionDefinition::Visibility::Internal)
+ _function.visibility() > FunctionDefinition::Visibility::Internal
)
m_errorReporter.typeError(var->location(), "Type is required to live outside storage.");
if (_function.visibility() >= FunctionDefinition::Visibility::Public && !(type(*var)->interfaceType(isLibraryFunction)))
@@ -716,8 +721,6 @@ bool TypeChecker::visit(VariableDeclaration const& _variable)
expectType(*_variable.value(), *varType);
if (_variable.isConstant())
{
- if (!_variable.isStateVariable())
- m_errorReporter.typeError(_variable.location(), "Illegal use of \"constant\" specifier.");
if (!_variable.type()->isValueType())
{
bool allowed = false;
diff --git a/libsolidity/ast/AST.cpp b/libsolidity/ast/AST.cpp
index 23797d52..a376e55d 100644
--- a/libsolidity/ast/AST.cpp
+++ b/libsolidity/ast/AST.cpp
@@ -418,6 +418,7 @@ bool VariableDeclaration::isLocalVariable() const
{
auto s = scope();
return
+ dynamic_cast<FunctionTypeName const*>(s) ||
dynamic_cast<CallableDeclaration const*>(s) ||
dynamic_cast<Block const*>(s) ||
dynamic_cast<ForStatement const*>(s);
@@ -425,14 +426,18 @@ bool VariableDeclaration::isLocalVariable() const
bool VariableDeclaration::isCallableParameter() const
{
- auto const* callable = dynamic_cast<CallableDeclaration const*>(scope());
- if (!callable)
- return false;
- for (auto const& variable: callable->parameters())
- if (variable.get() == this)
- return true;
- if (callable->returnParameterList())
- for (auto const& variable: callable->returnParameterList()->parameters())
+ if (isReturnParameter())
+ return true;
+
+ vector<ASTPointer<VariableDeclaration>> const* parameters = nullptr;
+
+ if (auto const* funTypeName = dynamic_cast<FunctionTypeName const*>(scope()))
+ parameters = &funTypeName->parameterTypes();
+ else if (auto const* callable = dynamic_cast<CallableDeclaration const*>(scope()))
+ parameters = &callable->parameters();
+
+ if (parameters)
+ for (auto const& variable: *parameters)
if (variable.get() == this)
return true;
return false;
@@ -445,11 +450,16 @@ bool VariableDeclaration::isLocalOrReturn() const
bool VariableDeclaration::isReturnParameter() const
{
- auto const* callable = dynamic_cast<CallableDeclaration const*>(scope());
- if (!callable)
- return false;
- if (callable->returnParameterList())
- for (auto const& variable: callable->returnParameterList()->parameters())
+ vector<ASTPointer<VariableDeclaration>> const* returnParameters = nullptr;
+
+ if (auto const* funTypeName = dynamic_cast<FunctionTypeName const*>(scope()))
+ returnParameters = &funTypeName->returnParameterTypes();
+ else if (auto const* callable = dynamic_cast<CallableDeclaration const*>(scope()))
+ if (callable->returnParameterList())
+ returnParameters = &callable->returnParameterList()->parameters();
+
+ if (returnParameters)
+ for (auto const& variable: *returnParameters)
if (variable.get() == this)
return true;
return false;
@@ -457,15 +467,88 @@ bool VariableDeclaration::isReturnParameter() const
bool VariableDeclaration::isExternalCallableParameter() const
{
- auto const* callable = dynamic_cast<CallableDeclaration const*>(scope());
- if (!callable || callable->visibility() != Declaration::Visibility::External)
+ if (!isCallableParameter())
return false;
- for (auto const& variable: callable->parameters())
- if (variable.get() == this)
- return true;
+
+ if (auto const* callable = dynamic_cast<CallableDeclaration const*>(scope()))
+ if (callable->visibility() == Declaration::Visibility::External)
+ return !isReturnParameter();
+
return false;
}
+bool VariableDeclaration::isInternalCallableParameter() const
+{
+ if (!isCallableParameter())
+ return false;
+
+ if (auto const* funTypeName = dynamic_cast<FunctionTypeName const*>(scope()))
+ return funTypeName->visibility() == Declaration::Visibility::Internal;
+ else if (auto const* callable = dynamic_cast<CallableDeclaration const*>(scope()))
+ return callable->visibility() <= Declaration::Visibility::Internal;
+ return false;
+}
+
+bool VariableDeclaration::isLibraryFunctionParameter() const
+{
+ if (!isCallableParameter())
+ return false;
+ if (auto const* funDef = dynamic_cast<FunctionDefinition const*>(scope()))
+ return dynamic_cast<ContractDefinition const&>(*funDef->scope()).isLibrary();
+ else
+ return false;
+}
+
+bool VariableDeclaration::isEventParameter() const
+{
+ return dynamic_cast<EventDefinition const*>(scope()) != nullptr;
+}
+
+bool VariableDeclaration::hasReferenceOrMappingType() const
+{
+ solAssert(typeName(), "");
+ solAssert(typeName()->annotation().type, "Can only be called after reference resolution");
+ TypePointer const& type = typeName()->annotation().type;
+ return type->category() == Type::Category::Mapping || dynamic_cast<ReferenceType const*>(type.get());
+}
+
+set<VariableDeclaration::Location> VariableDeclaration::allowedDataLocations() const
+{
+ using Location = VariableDeclaration::Location;
+
+ if (!hasReferenceOrMappingType() || isStateVariable() || isEventParameter())
+ return set<Location>{ Location::Default };
+ else if (isStateVariable() && isConstant())
+ return set<Location>{ Location::Memory };
+ else if (isExternalCallableParameter())
+ {
+ set<Location> locations{ Location::CallData };
+ if (isLibraryFunctionParameter())
+ locations.insert(Location::Storage);
+ return locations;
+ }
+ else if (isCallableParameter())
+ {
+ set<Location> locations{ Location::Memory };
+ if (isInternalCallableParameter() || isLibraryFunctionParameter())
+ locations.insert(Location::Storage);
+ return locations;
+ }
+ else if (isLocalVariable())
+ {
+ solAssert(typeName(), "");
+ solAssert(typeName()->annotation().type, "Can only be called after reference resolution");
+ if (typeName()->annotation().type->category() == Type::Category::Mapping)
+ return set<Location>{ Location::Storage };
+ else
+ // TODO: add Location::Calldata once implemented for local variables.
+ return set<Location>{ Location::Memory, Location::Storage };
+ }
+ else
+ // Struct members etc.
+ return set<Location>{ Location::Default };
+}
+
TypePointer VariableDeclaration::type() const
{
return annotation().type;
@@ -580,7 +663,7 @@ bool Literal::passesAddressChecksum() const
return dev::passesAddressChecksum(value(), true);
}
-std::string Literal::getChecksummedAddress() const
+string Literal::getChecksummedAddress() const
{
solAssert(isHexNumber(), "Expected hex number");
/// Pad literal to be a proper hex address.
diff --git a/libsolidity/ast/AST.h b/libsolidity/ast/AST.h
index 69c6fa05..b953211d 100644
--- a/libsolidity/ast/AST.h
+++ b/libsolidity/ast/AST.h
@@ -685,6 +685,8 @@ public:
virtual bool isLValue() const override;
virtual bool isPartOfExternalInterface() const override { return isPublic(); }
+ /// @returns true iff this variable is the parameter (or return parameter) of a function
+ /// (or function type name or event) or declared inside a function body.
bool isLocalVariable() const;
/// @returns true if this variable is a parameter or return parameter of a function.
bool isCallableParameter() const;
@@ -693,13 +695,27 @@ public:
/// @returns true if this variable is a local variable or return parameter.
bool isLocalOrReturn() const;
/// @returns true if this variable is a parameter (not return parameter) of an external function.
+ /// This excludes parameters of external function type names.
bool isExternalCallableParameter() const;
+ /// @returns true if this variable is a parameter or return parameter of an internal function
+ /// or a function type of internal visibility.
+ bool isInternalCallableParameter() const;
+ /// @returns true iff this variable is a parameter(or return parameter of a library function
+ bool isLibraryFunctionParameter() const;
/// @returns true if the type of the variable does not need to be specified, i.e. it is declared
/// in the body of a function or modifier.
+ /// @returns true if this variable is a parameter of an event.
+ bool isEventParameter() const;
+ /// @returns true if the type of the variable is a reference or mapping type, i.e.
+ /// array, struct or mapping. These types can take a data location (and often require it).
+ /// Can only be called after reference resolution.
+ bool hasReferenceOrMappingType() const;
bool isStateVariable() const { return m_isStateVariable; }
bool isIndexed() const { return m_isIndexed; }
bool isConstant() const { return m_isConstant; }
Location referenceLocation() const { return m_location; }
+ /// @returns a set of allowed storage locations for the variable.
+ std::set<Location> allowedDataLocations() const;
virtual TypePointer type() const override;
diff --git a/test/compilationTests/corion/moduleHandler.sol b/test/compilationTests/corion/moduleHandler.sol
index 5628f657..2b513eb1 100644
--- a/test/compilationTests/corion/moduleHandler.sol
+++ b/test/compilationTests/corion/moduleHandler.sol
@@ -140,7 +140,7 @@ contract moduleHandler is multiOwner, announcementTypes {
}
return (true, false, 0);
}
- function replaceModule(string name, address addr, bool callCallback) external returns (bool success) {
+ function replaceModule(string calldata name, address addr, bool callCallback) external returns (bool success) {
/*
Module replace, can be called only by the Publisher contract.
@@ -167,7 +167,7 @@ contract moduleHandler is multiOwner, announcementTypes {
return true;
}
- function callReplaceCallback(string moduleName, address newModule) external returns (bool success) {
+ function callReplaceCallback(string calldata moduleName, address newModule) external returns (bool success) {
require( block.number < debugModeUntil );
if ( ! insertAndCheckDo(calcDoHash("callReplaceCallback", keccak256(abi.encodePacked(moduleName, newModule)))) ) {
return true;
@@ -178,7 +178,7 @@ contract moduleHandler is multiOwner, announcementTypes {
return true;
}
- function newModule(string name, address addr, bool schellingEvent, bool transferEvent) external returns (bool success) {
+ function newModule(string calldata name, address addr, bool schellingEvent, bool transferEvent) external returns (bool success) {
/*
Adding new module to the database. Can be called only by the Publisher contract.
@@ -199,7 +199,7 @@ contract moduleHandler is multiOwner, announcementTypes {
addModule( modules_s(addr, keccak256(bytes(name)), schellingEvent, transferEvent), true);
return true;
}
- function dropModule(string name, bool callCallback) external returns (bool success) {
+ function dropModule(string calldata name, bool callCallback) external returns (bool success) {
/*
Deleting module from the database. Can be called only by the Publisher contract.
@@ -224,7 +224,7 @@ contract moduleHandler is multiOwner, announcementTypes {
return true;
}
- function callDisableCallback(string moduleName) external returns (bool success) {
+ function callDisableCallback(string calldata moduleName) external returns (bool success) {
require( block.number < debugModeUntil );
if ( ! insertAndCheckDo(calcDoHash("callDisableCallback", keccak256(bytes(moduleName)))) ) {
return true;
@@ -406,7 +406,7 @@ contract moduleHandler is multiOwner, announcementTypes {
require( token(modules[_id].addr).burn(from, value) );
return true;
}
- function configureModule(string moduleName, announcementType aType, uint256 value) external returns (bool success) {
+ function configureModule(string calldata moduleName, announcementType aType, uint256 value) external returns (bool success) {
/*
Changing configuration of a module. Can be called only by Publisher or while debug mode by owners.
diff --git a/test/compilationTests/corion/premium.sol b/test/compilationTests/corion/premium.sol
index 65895f33..84277a99 100644
--- a/test/compilationTests/corion/premium.sol
+++ b/test/compilationTests/corion/premium.sol
@@ -5,8 +5,8 @@ import "./tokenDB.sol";
import "./module.sol";
contract thirdPartyPContractAbstract {
- function receiveCorionPremiumToken(address, uint256, bytes) external returns (bool, uint256) {}
- function approvedCorionPremiumToken(address, uint256, bytes) external returns (bool) {}
+ function receiveCorionPremiumToken(address, uint256, bytes calldata) external returns (bool, uint256) {}
+ function approvedCorionPremiumToken(address, uint256, bytes calldata) external returns (bool) {}
}
contract ptokenDB is tokenDB {}
@@ -108,7 +108,7 @@ contract premium is module, safeMath {
* @param extraData Data to give forward to the receiver
* @return True if the approval was successful
*/
- function approveAndCall(address spender, uint256 amount, uint256 nonce, bytes extraData) isReady external returns (bool success) {
+ function approveAndCall(address spender, uint256 amount, uint256 nonce, bytes calldata extraData) isReady external returns (bool success) {
/*
Authorize another address to use an exact amount of the principal’s balance.
After the transaction the approvedCorionPremiumToken function of the address will be called with the given data.
@@ -226,7 +226,7 @@ contract premium is module, safeMath {
* @param extraData Data to give forward to the receiver
* @return Whether the transfer was successful or not
*/
- function transfer(address to, uint256 amount, bytes extraData) isReady external returns (bool success) {
+ function transfer(address to, uint256 amount, bytes calldata extraData) isReady external returns (bool success) {
/*
Launch a transaction where we transfer from a given address to another one.
After thetransaction the approvedCorionPremiumToken function of the receiver’s address is going to be called with the given data.
diff --git a/test/compilationTests/corion/provider.sol b/test/compilationTests/corion/provider.sol
index a4ee4a48..41857e54 100644
--- a/test/compilationTests/corion/provider.sol
+++ b/test/compilationTests/corion/provider.sol
@@ -213,7 +213,7 @@ contract provider is module, safeMath, announcementTypes {
return ( ! priv && ( rate >= publicMinRate && rate <= publicMaxRate ) ) ||
( priv && ( rate >= privateMinRate && rate <= privateMaxRate ) );
}
- function createProvider(bool priv, string name, string website, string country, string info, uint8 rate, bool isForRent, address admin) isReady external {
+ function createProvider(bool priv, string calldata name, string calldata website, string calldata country, string calldata info, uint8 rate, bool isForRent, address admin) isReady external {
/*
Creating a provider.
During the ICO its not allowed to create provider.
@@ -270,7 +270,7 @@ contract provider is module, safeMath, announcementTypes {
}
emit EProviderOpen(msg.sender, currHeight);
}
- function setProviderDetails(address addr, string website, string country, string info, uint8 rate, address admin) isReady external {
+ function setProviderDetails(address addr, string calldata website, string calldata country, string calldata info, uint8 rate, address admin) isReady external {
/*
Modifying the datas of the provider.
This can only be invited by the provider’s admin.
@@ -369,7 +369,7 @@ contract provider is module, safeMath, announcementTypes {
setRightForInterest(getProviderCurrentSupply(msg.sender), 0, providers[msg.sender].data[currHeight].priv);
emit EProviderClose(msg.sender, currHeight);
}
- function allowUsers(address provider, address[] addr) isReady external {
+ function allowUsers(address provider, address[] calldata addr) isReady external {
/*
Permition of the user to be able to connect to the provider.
This can only be invited by the provider’s admin.
@@ -387,7 +387,7 @@ contract provider is module, safeMath, announcementTypes {
providers[provider].data[currHeight].allowedUsers[addr[a]] = true;
}
}
- function disallowUsers(address provider, address[] addr) isReady external {
+ function disallowUsers(address provider, address[] calldata addr) isReady external {
/*
Disable of the user not to be able to connect to the provider.
It is can called only for the admin of the provider.
diff --git a/test/compilationTests/corion/publisher.sol b/test/compilationTests/corion/publisher.sol
index fcba13ad..6a77bc9e 100644
--- a/test/compilationTests/corion/publisher.sol
+++ b/test/compilationTests/corion/publisher.sol
@@ -116,7 +116,7 @@ contract publisher is announcementTypes, module, safeMath {
return _amount * oppositeRate / 100 > weight;
}
- function newAnnouncement(announcementType Type, string Announcement, string Link, bool Oppositable, string _str, uint256 _uint, address _addr) onlyOwner external {
+ function newAnnouncement(announcementType Type, string calldata Announcement, string calldata Link, bool Oppositable, string calldata _str, uint256 _uint, address _addr) onlyOwner external {
/*
New announcement. Can be called only by those in the admin list
diff --git a/test/compilationTests/corion/schelling.sol b/test/compilationTests/corion/schelling.sol
index c4f3c02c..e9288332 100644
--- a/test/compilationTests/corion/schelling.sol
+++ b/test/compilationTests/corion/schelling.sol
@@ -310,7 +310,7 @@ contract schelling is module, announcementTypes, schellingVars {
setRound(currentRound, round);
}
- function sendVote(string vote) isReady noContract external {
+ function sendVote(string calldata vote) isReady noContract external {
/*
Check vote (Envelope opening)
Only the sent “envelopes” can be opened.
diff --git a/test/compilationTests/corion/token.sol b/test/compilationTests/corion/token.sol
index 87ec64d6..6d3f1a1e 100644
--- a/test/compilationTests/corion/token.sol
+++ b/test/compilationTests/corion/token.sol
@@ -7,8 +7,8 @@ import "./moduleHandler.sol";
import "./tokenDB.sol";
contract thirdPartyContractAbstract {
- function receiveCorionToken(address, uint256, bytes) external returns (bool, uint256) {}
- function approvedCorionToken(address, uint256, bytes) external returns (bool) {}
+ function receiveCorionToken(address, uint256, bytes calldata) external returns (bool, uint256) {}
+ function approvedCorionToken(address, uint256, bytes calldata) external returns (bool) {}
}
contract token is safeMath, module, announcementTypes {
@@ -123,7 +123,7 @@ contract token is safeMath, module, announcementTypes {
* @param extraData Data to give forward to the receiver
* @return True if the approval was successful
*/
- function approveAndCall(address spender, uint256 amount, uint256 nonce, bytes extraData) isReady external returns (bool success) {
+ function approveAndCall(address spender, uint256 amount, uint256 nonce, bytes calldata extraData) isReady external returns (bool success) {
/*
Authorise another address to use a certain quantity of the authorising owner’s balance
Following the transaction the receiver address `approvedCorionToken` function is called by the given data
@@ -267,7 +267,7 @@ contract token is safeMath, module, announcementTypes {
* @param extraData Data to give forward to the receiver
* @return Whether the transfer was successful or not
*/
- function transfer(address to, uint256 amount, bytes extraData) isReady external returns (bool success) {
+ function transfer(address to, uint256 amount, bytes calldata extraData) isReady external returns (bool success) {
/*
Start transaction to send a quantity from a given address to another address
After transaction the function `receiveCorionToken`of the receiver is called by the given data
diff --git a/test/compilationTests/zeppelin/MultisigWallet.sol b/test/compilationTests/zeppelin/MultisigWallet.sol
index 3793428d..9aac5c53 100644
--- a/test/compilationTests/zeppelin/MultisigWallet.sol
+++ b/test/compilationTests/zeppelin/MultisigWallet.sol
@@ -55,7 +55,7 @@ contract MultisigWallet is Multisig, Shareable, DayLimit {
* @param _value The value to send
* @param _data The data part of the transaction
*/
- function execute(address _to, uint256 _value, bytes _data) external onlyOwner returns (bytes32 _r) {
+ function execute(address _to, uint256 _value, bytes calldata _data) external onlyOwner returns (bytes32 _r) {
// first, take the opportunity to check that we're under the daily limit.
if (underLimit(_value)) {
emit SingleTransact(msg.sender, _value, _to, _data);
diff --git a/test/compilationTests/zeppelin/ownership/HasNoTokens.sol b/test/compilationTests/zeppelin/ownership/HasNoTokens.sol
index e14d8da7..079cef7c 100644
--- a/test/compilationTests/zeppelin/ownership/HasNoTokens.sol
+++ b/test/compilationTests/zeppelin/ownership/HasNoTokens.sol
@@ -18,7 +18,7 @@ contract HasNoTokens is Ownable {
* @param value_ uint256 the amount of the specified token
* @param data_ Bytes The data passed from the caller.
*/
- function tokenFallback(address from_, uint256 value_, bytes data_) external {
+ function tokenFallback(address from_, uint256 value_, bytes calldata data_) external {
revert();
}
diff --git a/test/compilationTests/zeppelin/ownership/Multisig.sol b/test/compilationTests/zeppelin/ownership/Multisig.sol
index 25531d8d..2eb0f4bc 100644
--- a/test/compilationTests/zeppelin/ownership/Multisig.sol
+++ b/test/compilationTests/zeppelin/ownership/Multisig.sol
@@ -23,6 +23,6 @@ contract Multisig {
// TODO: document
function changeOwner(address _from, address _to) external;
- function execute(address _to, uint256 _value, bytes _data) external returns (bytes32);
+ function execute(address _to, uint256 _value, bytes calldata _data) external returns (bytes32);
function confirm(bytes32 _h) public returns (bool);
}
diff --git a/test/contracts/AuctionRegistrar.cpp b/test/contracts/AuctionRegistrar.cpp
index 4ff55b75..e178748f 100644
--- a/test/contracts/AuctionRegistrar.cpp
+++ b/test/contracts/AuctionRegistrar.cpp
@@ -132,7 +132,7 @@ contract GlobalRegistrar is Registrar, AuctionSystem {
}
}
- function reserve(string _name) external payable {
+ function reserve(string calldata _name) external payable {
if (bytes(_name).length == 0)
revert();
bool needAuction = requiresAuction(_name);
diff --git a/test/contracts/Wallet.cpp b/test/contracts/Wallet.cpp
index ce50fe59..a2e764fb 100644
--- a/test/contracts/Wallet.cpp
+++ b/test/contracts/Wallet.cpp
@@ -348,7 +348,7 @@ contract multisig {
// TODO: document
function changeOwner(address _from, address _to) external;
- function execute(address _to, uint _value, bytes _data) external returns (bytes32);
+ function execute(address _to, uint _value, bytes calldata _data) external returns (bytes32);
function confirm(bytes32 _h) public returns (bool);
}
@@ -390,7 +390,7 @@ contract Wallet is multisig, multiowned, daylimit {
// If not, goes into multisig process. We provide a hash on return to allow the sender to provide
// shortcuts for the other confirmations (allowing them to avoid replicating the _to, _value
// and _data arguments). They still get the option of using them if they want, anyways.
- function execute(address _to, uint _value, bytes _data) external onlyowner returns (bytes32 _r) {
+ function execute(address _to, uint _value, bytes calldata _data) external onlyowner returns (bytes32 _r) {
// first, take the opportunity to check that we're under the daily limit.
if (underLimit(_value)) {
emit SingleTransact(msg.sender, _value, _to, _data);
diff --git a/test/libsolidity/ABIDecoderTests.cpp b/test/libsolidity/ABIDecoderTests.cpp
index f91a4f85..94319985 100644
--- a/test/libsolidity/ABIDecoderTests.cpp
+++ b/test/libsolidity/ABIDecoderTests.cpp
@@ -234,7 +234,7 @@ BOOST_AUTO_TEST_CASE(byte_arrays)
return (a, b.length, b[3], c);
}
- function f_external(uint a, bytes b, uint c)
+ function f_external(uint a, bytes calldata b, uint c)
external pure returns (uint, uint, byte, uint) {
return (a, b.length, b[3], c);
}
@@ -261,7 +261,7 @@ BOOST_AUTO_TEST_CASE(calldata_arrays_too_large)
{
string sourceCode = R"(
contract C {
- function f(uint a, uint[] b, uint c) external pure returns (uint) {
+ function f(uint a, uint[] calldata b, uint c) external pure returns (uint) {
return 7;
}
}
diff --git a/test/libsolidity/ABIEncoderTests.cpp b/test/libsolidity/ABIEncoderTests.cpp
index 06cfb4ec..d2125cc7 100644
--- a/test/libsolidity/ABIEncoderTests.cpp
+++ b/test/libsolidity/ABIEncoderTests.cpp
@@ -367,7 +367,7 @@ BOOST_AUTO_TEST_CASE(calldata)
string sourceCode = R"(
contract C {
event E(bytes);
- function f(bytes a) external {
+ function f(bytes calldata a) external {
emit E(a);
}
}
diff --git a/test/libsolidity/ASTJSON/function_type.json b/test/libsolidity/ASTJSON/function_type.json
index 7b10f0dc..5dbc5b80 100644
--- a/test/libsolidity/ASTJSON/function_type.json
+++ b/test/libsolidity/ASTJSON/function_type.json
@@ -83,7 +83,7 @@
"id" : 3,
"name" : "",
"nodeType" : "VariableDeclaration",
- "scope" : 16,
+ "scope" : 5,
"src" : "61:4:1",
"stateVariable" : false,
"storageLocation" : "default",
@@ -167,7 +167,7 @@
"id" : 10,
"name" : "",
"nodeType" : "VariableDeclaration",
- "scope" : 16,
+ "scope" : 12,
"src" : "113:4:1",
"stateVariable" : false,
"storageLocation" : "default",
diff --git a/test/libsolidity/ASTJSON/function_type.sol b/test/libsolidity/ASTJSON/function_type.sol
index b63bcbf0..bed2742b 100644
--- a/test/libsolidity/ASTJSON/function_type.sol
+++ b/test/libsolidity/ASTJSON/function_type.sol
@@ -1 +1,3 @@
contract C { function f(function() external payable returns (uint) x) returns (function() external view returns (uint)) {} }
+
+// ----
diff --git a/test/libsolidity/ASTJSON/function_type_legacy.json b/test/libsolidity/ASTJSON/function_type_legacy.json
index 952fd865..af0c42dd 100644
--- a/test/libsolidity/ASTJSON/function_type_legacy.json
+++ b/test/libsolidity/ASTJSON/function_type_legacy.json
@@ -100,7 +100,7 @@
{
"constant" : false,
"name" : "",
- "scope" : 16,
+ "scope" : 5,
"stateVariable" : false,
"storageLocation" : "default",
"type" : "uint256",
@@ -191,7 +191,7 @@
{
"constant" : false,
"name" : "",
- "scope" : 16,
+ "scope" : 12,
"stateVariable" : false,
"storageLocation" : "default",
"type" : "uint256",
diff --git a/test/libsolidity/SolidityABIJSON.cpp b/test/libsolidity/SolidityABIJSON.cpp
index fdb11504..a8a67bca 100644
--- a/test/libsolidity/SolidityABIJSON.cpp
+++ b/test/libsolidity/SolidityABIJSON.cpp
@@ -727,7 +727,7 @@ BOOST_AUTO_TEST_CASE(strings_and_arrays)
// bug #1801
char const* sourceCode = R"(
contract test {
- function f(string a, bytes b, uint[] c) external {}
+ function f(string calldata a, bytes calldata b, uint[] calldata c) external {}
}
)";
diff --git a/test/libsolidity/SolidityEndToEndTest.cpp b/test/libsolidity/SolidityEndToEndTest.cpp
index 7b56fa9d..af2b3485 100644
--- a/test/libsolidity/SolidityEndToEndTest.cpp
+++ b/test/libsolidity/SolidityEndToEndTest.cpp
@@ -526,7 +526,7 @@ BOOST_AUTO_TEST_CASE(array_multiple_local_vars)
{
char const* sourceCode = R"(
contract test {
- function f(uint256[] seq) external pure returns (uint256) {
+ function f(uint256[] calldata seq) external pure returns (uint256) {
uint i = 0;
uint sum = 0;
while (i < seq.length)
@@ -4540,7 +4540,7 @@ BOOST_AUTO_TEST_CASE(struct_containing_bytes_copy_and_delete)
struct Struct { uint a; bytes data; uint b; }
Struct data1;
Struct data2;
- function set(uint _a, bytes _data, uint _b) external returns (bool) {
+ function set(uint _a, bytes calldata _data, uint _b) external returns (bool) {
data1.a = _a;
data1.b = _b;
data1.data = _data;
@@ -4764,12 +4764,12 @@ BOOST_AUTO_TEST_CASE(struct_referencing)
}
library L {
struct S { uint b; uint a; }
- function f() public pure returns (S) {
+ function f() public pure returns (S memory) {
S memory s;
s.a = 3;
return s;
}
- function g() public pure returns (I.S) {
+ function g() public pure returns (I.S memory) {
I.S memory s;
s.a = 4;
return s;
@@ -4779,25 +4779,25 @@ BOOST_AUTO_TEST_CASE(struct_referencing)
function a(S memory) public pure returns (uint) { return 2; }
}
contract C is I {
- function f() public pure returns (S) {
+ function f() public pure returns (S memory) {
S memory s;
s.a = 1;
return s;
}
- function g() public pure returns (I.S) {
+ function g() public pure returns (I.S memory) {
I.S memory s;
s.a = 2;
return s;
}
- function h() public pure returns (L.S) {
+ function h() public pure returns (L.S memory) {
L.S memory s;
s.a = 5;
return s;
}
- function x() public pure returns (L.S) {
+ function x() public pure returns (L.S memory) {
return L.f();
}
- function y() public pure returns (I.S) {
+ function y() public pure returns (I.S memory) {
return L.g();
}
function a1() public pure returns (uint) { S memory s; return L.a(s); }
@@ -4941,7 +4941,7 @@ BOOST_AUTO_TEST_CASE(bytes_in_arguments)
uint result;
function f(uint a, uint b) public { result += a + b; }
function g(uint a) public { result *= a; }
- function test(uint a, bytes data1, bytes data2, uint b) external returns (uint r_a, uint r, uint r_b, uint l) {
+ function test(uint a, bytes calldata data1, bytes calldata data2, uint b) external returns (uint r_a, uint r, uint r_b, uint l) {
r_a = a;
address(this).call(data1);
address(this).call(data2);
@@ -5876,7 +5876,7 @@ BOOST_AUTO_TEST_CASE(external_array_args)
{
char const* sourceCode = R"(
contract c {
- function test(uint[8] a, uint[] b, uint[5] c, uint a_index, uint b_index, uint c_index)
+ function test(uint[8] calldata a, uint[] calldata b, uint[5] calldata c, uint a_index, uint b_index, uint c_index)
external returns (uint av, uint bv, uint cv) {
av = a[a_index];
bv = b[b_index];
@@ -5901,10 +5901,10 @@ BOOST_AUTO_TEST_CASE(bytes_index_access)
char const* sourceCode = R"(
contract c {
bytes data;
- function direct(bytes arg, uint index) external returns (uint) {
+ function direct(bytes calldata arg, uint index) external returns (uint) {
return uint(uint8(arg[index]));
}
- function storageCopyRead(bytes arg, uint index) external returns (uint) {
+ function storageCopyRead(bytes calldata arg, uint index) external returns (uint) {
data = arg;
return uint(uint8(data[index]));
}
@@ -5959,7 +5959,7 @@ BOOST_AUTO_TEST_CASE(array_copy_calldata_storage)
uint[9] m_data;
uint[] m_data_dyn;
uint8[][] m_byte_data;
- function store(uint[9] a, uint8[3][] b) external returns (uint8) {
+ function store(uint[9] calldata a, uint8[3][] calldata b) external returns (uint8) {
m_data = a;
m_data_dyn = a;
m_byte_data = b;
@@ -5998,7 +5998,7 @@ BOOST_AUTO_TEST_CASE(array_copy_nested_array)
uint[4][] a;
uint[10][] b;
uint[][] c;
- function test(uint[2][] d) external returns (uint) {
+ function test(uint[2][] calldata d) external returns (uint) {
a = d;
b = a;
c = b;
@@ -6949,7 +6949,7 @@ BOOST_AUTO_TEST_CASE(return_string)
char const* sourceCode = R"(
contract Main {
string public s;
- function set(string _s) external {
+ function set(string calldata _s) external {
s = _s;
}
function get1() public returns (string memory r) {
@@ -6975,7 +6975,7 @@ BOOST_AUTO_TEST_CASE(return_multiple_strings_of_various_sizes)
contract Main {
string public s1;
string public s2;
- function set(string _s1, uint x, string _s2) external returns (uint) {
+ function set(string calldata _s1, uint x, string calldata _s2) external returns (uint) {
s1 = _s1;
s2 = _s2;
return x;
@@ -7024,7 +7024,7 @@ BOOST_AUTO_TEST_CASE(accessor_involving_strings)
contract Main {
struct stringData { string a; uint b; string c; }
mapping(uint => stringData[]) public data;
- function set(uint x, uint y, string a, uint b, string c) external returns (bool) {
+ function set(uint x, uint y, string calldata a, uint b, string calldata c) external returns (bool) {
data[x].length = y + 1;
data[x][y].a = a;
data[x][y].b = b;
@@ -7061,7 +7061,7 @@ BOOST_AUTO_TEST_CASE(bytes_in_function_calls)
function setIndirectFromMemory(string memory _s1, uint x, string memory _s2) public returns (uint) {
return this.set(_s1, x, _s2);
}
- function setIndirectFromCalldata(string _s1, uint x, string _s2) external returns (uint) {
+ function setIndirectFromCalldata(string calldata _s1, uint x, string calldata _s2) external returns (uint) {
return this.set(_s1, x, _s2);
}
}
@@ -7102,7 +7102,7 @@ BOOST_AUTO_TEST_CASE(return_bytes_internal)
s1 = _s1;
_r1 = s1;
}
- function set(bytes _s1) external returns (uint _r, bytes memory _r1) {
+ function set(bytes calldata _s1) external returns (uint _r, bytes memory _r1) {
_r1 = doSet(_s1);
_r = _r1.length;
}
@@ -8040,7 +8040,7 @@ BOOST_AUTO_TEST_CASE(library_call)
BOOST_AUTO_TEST_CASE(library_function_external)
{
char const* sourceCode = R"(
- library Lib { function m(bytes b) external pure returns (byte) { return b[2]; } }
+ library Lib { function m(bytes calldata b) external pure returns (byte) { return b[2]; } }
contract Test {
function f(bytes memory b) public pure returns (byte) {
return Lib.m(b);
diff --git a/test/libsolidity/SolidityNameAndTypeResolution.cpp b/test/libsolidity/SolidityNameAndTypeResolution.cpp
index 41814888..55e81867 100644
--- a/test/libsolidity/SolidityNameAndTypeResolution.cpp
+++ b/test/libsolidity/SolidityNameAndTypeResolution.cpp
@@ -158,7 +158,7 @@ BOOST_AUTO_TEST_CASE(function_external_types)
uint a;
}
contract Test {
- function boo(uint, bool, bytes8, bool[2], uint[], C, address[]) external returns (uint ret) {
+ function boo(uint, bool, bytes8, bool[2] calldata, uint[] calldata, C, address[] calldata) external returns (uint ret) {
ret = 5;
}
}
@@ -206,10 +206,10 @@ BOOST_AUTO_TEST_CASE(external_structs)
struct Simple { uint i; }
struct Nested { X[2][] a; uint y; }
struct X { bytes32 x; Test t; Simple[] s; }
- function f(ActionChoices, uint, Simple) external {}
- function g(Test, Nested) external {}
- function h(function(Nested memory) external returns (uint)[]) external {}
- function i(Nested[]) external {}
+ function f(ActionChoices, uint, Simple calldata) external {}
+ function g(Test, Nested calldata) external {}
+ function h(function(Nested memory) external returns (uint)[] calldata) external {}
+ function i(Nested[] calldata) external {}
}
)";
SourceUnit const* sourceUnit = parseAndAnalyse(text);
@@ -234,10 +234,10 @@ BOOST_AUTO_TEST_CASE(external_structs_in_libraries)
struct Simple { uint i; }
struct Nested { X[2][] a; uint y; }
struct X { bytes32 x; Test t; Simple[] s; }
- function f(ActionChoices, uint, Simple) external {}
- function g(Test, Nested) external {}
- function h(function(Nested memory) external returns (uint)[]) external {}
- function i(Nested[]) external {}
+ function f(ActionChoices, uint, Simple calldata) external {}
+ function g(Test, Nested calldata) external {}
+ function h(function(Nested memory) external returns (uint)[] calldata) external {}
+ function i(Nested[] calldata) external {}
}
)";
SourceUnit const* sourceUnit = parseAndAnalyse(text);
@@ -340,7 +340,7 @@ BOOST_AUTO_TEST_CASE(string)
char const* sourceCode = R"(
contract C {
string s;
- function f(string x) external { s = x; }
+ function f(string calldata x) external { s = x; }
}
)";
BOOST_CHECK_NO_THROW(parseAndAnalyse(sourceCode));
diff --git a/test/libsolidity/syntaxTests/array/length/array_length_cannot_be_constant_function_parameter.sol b/test/libsolidity/syntaxTests/array/length/array_length_cannot_be_constant_function_parameter.sol
index 5add9106..59328140 100644
--- a/test/libsolidity/syntaxTests/array/length/array_length_cannot_be_constant_function_parameter.sol
+++ b/test/libsolidity/syntaxTests/array/length/array_length_cannot_be_constant_function_parameter.sol
@@ -4,4 +4,5 @@ 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.
diff --git a/test/libsolidity/syntaxTests/conversion/conversion_to_bytes.sol b/test/libsolidity/syntaxTests/conversion/conversion_to_bytes.sol
index 5946e921..3a6deff1 100644
--- a/test/libsolidity/syntaxTests/conversion/conversion_to_bytes.sol
+++ b/test/libsolidity/syntaxTests/conversion/conversion_to_bytes.sol
@@ -1,5 +1,5 @@
contract test {
- function f() public pure returns (bytes) {
+ function f() public pure returns (bytes memory) {
return bytes("abc");
}
}
diff --git a/test/libsolidity/syntaxTests/dataLocations/data_location_in_function_type.sol b/test/libsolidity/syntaxTests/dataLocations/data_location_in_function_type.sol
new file mode 100644
index 00000000..b23fbb89
--- /dev/null
+++ b/test/libsolidity/syntaxTests/dataLocations/data_location_in_function_type.sol
@@ -0,0 +1,4 @@
+library L {
+ struct Nested { uint y; }
+ function c(function(Nested memory) external returns (uint)[] storage) external pure {}
+}
diff --git a/test/libsolidity/syntaxTests/dataLocations/data_location_in_function_type_fail.sol b/test/libsolidity/syntaxTests/dataLocations/data_location_in_function_type_fail.sol
new file mode 100644
index 00000000..e1ea6989
--- /dev/null
+++ b/test/libsolidity/syntaxTests/dataLocations/data_location_in_function_type_fail.sol
@@ -0,0 +1,9 @@
+library L {
+ struct Nested { uint y; }
+ function b(function(Nested calldata) external returns (uint)[] storage) external pure {}
+ function d(function(Nested storage) external returns (uint)[] storage) external pure {}
+}
+
+// ----
+// TypeError: (66-72): Data location must be "memory" for parameter in function, but "calldata" was given.
+// TypeError: (159-165): Data location must be "memory" for parameter in function, but "storage" was given.
diff --git a/test/libsolidity/syntaxTests/dataLocations/externalFunction/external_function_return_parameters_no_data_location.sol b/test/libsolidity/syntaxTests/dataLocations/externalFunction/external_function_return_parameters_no_data_location.sol
new file mode 100644
index 00000000..cbcf2a6e
--- /dev/null
+++ b/test/libsolidity/syntaxTests/dataLocations/externalFunction/external_function_return_parameters_no_data_location.sol
@@ -0,0 +1,5 @@
+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.
diff --git a/test/libsolidity/syntaxTests/dataLocations/externalFunction/function_argument_location_specifier_test_external_memory.sol b/test/libsolidity/syntaxTests/dataLocations/externalFunction/function_argument_location_specifier_test_external_memory.sol
index 807cc064..d914fa5b 100644
--- a/test/libsolidity/syntaxTests/dataLocations/externalFunction/function_argument_location_specifier_test_external_memory.sol
+++ b/test/libsolidity/syntaxTests/dataLocations/externalFunction/function_argument_location_specifier_test_external_memory.sol
@@ -2,4 +2,4 @@ contract test {
function f(bytes memory) external;
}
// ----
-// TypeError: (31-36): Location has to be calldata for external functions (remove the "memory" or "storage" keyword).
+// TypeError: (31-36): Data location must be "calldata" for parameter in external function, but "memory" was given.
diff --git a/test/libsolidity/syntaxTests/dataLocations/externalFunction/function_argument_location_specifier_test_external_storage.sol b/test/libsolidity/syntaxTests/dataLocations/externalFunction/function_argument_location_specifier_test_external_storage.sol
index 2664dbab..adb7e52e 100644
--- a/test/libsolidity/syntaxTests/dataLocations/externalFunction/function_argument_location_specifier_test_external_storage.sol
+++ b/test/libsolidity/syntaxTests/dataLocations/externalFunction/function_argument_location_specifier_test_external_storage.sol
@@ -2,4 +2,4 @@ contract test {
function f(bytes storage) external;
}
// ----
-// TypeError: (31-36): Location has to be calldata for external functions (remove the "memory" or "storage" keyword).
+// TypeError: (31-36): Data location must be "calldata" for parameter in external function, but "storage" was given.
diff --git a/test/libsolidity/syntaxTests/dataLocations/function_argument_location_specifier_test_library.sol b/test/libsolidity/syntaxTests/dataLocations/function_argument_location_specifier_test_library.sol
deleted file mode 100644
index 4348482a..00000000
--- a/test/libsolidity/syntaxTests/dataLocations/function_argument_location_specifier_test_library.sol
+++ /dev/null
@@ -1,5 +0,0 @@
-library test {
- function f(bytes calldata) public;
-}
-// ----
-// TypeError: (30-35): Location cannot be calldata for non-external functions (remove the "calldata" keyword).
diff --git a/test/libsolidity/syntaxTests/dataLocations/function_argument_location_specifier_test_non_reference_type.sol b/test/libsolidity/syntaxTests/dataLocations/function_argument_location_specifier_test_non_reference_type.sol
index 70f6c5eb..71756ebb 100644
--- a/test/libsolidity/syntaxTests/dataLocations/function_argument_location_specifier_test_non_reference_type.sol
+++ b/test/libsolidity/syntaxTests/dataLocations/function_argument_location_specifier_test_non_reference_type.sol
@@ -2,4 +2,4 @@ contract test {
function f(bytes4 memory) public;
}
// ----
-// TypeError: (31-37): Data location can only be given for array or struct types.
+// TypeError: (31-37): Data location can only be specified for array, struct or mapping types, but "memory" was given.
diff --git a/test/libsolidity/syntaxTests/dataLocations/function_parameters_with_data_location_fine.sol b/test/libsolidity/syntaxTests/dataLocations/function_parameters_with_data_location_fine.sol
new file mode 100644
index 00000000..2bc7b393
--- /dev/null
+++ b/test/libsolidity/syntaxTests/dataLocations/function_parameters_with_data_location_fine.sol
@@ -0,0 +1,8 @@
+contract C {
+ function f(uint[] memory, uint[] storage) private pure {}
+ function g(uint[] memory, uint[] storage) internal pure {}
+ function h(uint[] memory) public pure {}
+ function i(uint[] calldata) external pure {}
+ // No data location for events.
+ event e(uint[]);
+}
diff --git a/test/libsolidity/syntaxTests/dataLocations/function_return_parameters_with_data_location_fine.sol b/test/libsolidity/syntaxTests/dataLocations/function_return_parameters_with_data_location_fine.sol
new file mode 100644
index 00000000..ea019198
--- /dev/null
+++ b/test/libsolidity/syntaxTests/dataLocations/function_return_parameters_with_data_location_fine.sol
@@ -0,0 +1,6 @@
+contract C {
+ function f() private pure returns(uint[] memory, uint[] storage b) { b = b; }
+ function g() internal pure returns(uint[] memory, uint[] storage b) { b = b; }
+ function h() public pure returns(uint[] memory) {}
+ function i() external pure returns(uint[] memory) {}
+}
diff --git a/test/libsolidity/syntaxTests/dataLocations/function_type_array_as_reference_type.sol b/test/libsolidity/syntaxTests/dataLocations/function_type_array_as_reference_type.sol
new file mode 100644
index 00000000..b3856f58
--- /dev/null
+++ b/test/libsolidity/syntaxTests/dataLocations/function_type_array_as_reference_type.sol
@@ -0,0 +1,8 @@
+contract C {
+ struct Nested { uint y; }
+ // ensure that we consider array of function pointers as reference type
+ function b(function(Nested memory) external returns (uint)[] storage) internal pure {}
+ function c(function(Nested memory) external returns (uint)[] memory) public pure {}
+ function d(function(Nested memory) external returns (uint)[] calldata) external pure {}
+}
+// ----
diff --git a/test/libsolidity/syntaxTests/dataLocations/internalFunction/function_argument_location_specifier_test_internal_calldata.sol b/test/libsolidity/syntaxTests/dataLocations/internalFunction/function_argument_location_specifier_test_internal_calldata.sol
index f2740946..771f1525 100644
--- a/test/libsolidity/syntaxTests/dataLocations/internalFunction/function_argument_location_specifier_test_internal_calldata.sol
+++ b/test/libsolidity/syntaxTests/dataLocations/internalFunction/function_argument_location_specifier_test_internal_calldata.sol
@@ -2,4 +2,4 @@ contract test {
function f(bytes calldata) internal;
}
// ----
-// TypeError: (31-36): Variable cannot be declared as "calldata" (remove the "calldata" keyword).
+// TypeError: (31-36): Data location must be "storage" or "memory" for parameter in function, but "calldata" was given.
diff --git a/test/libsolidity/syntaxTests/dataLocations/internalFunction/internal_function_parameters_no_data_location.sol b/test/libsolidity/syntaxTests/dataLocations/internalFunction/internal_function_parameters_no_data_location.sol
new file mode 100644
index 00000000..f1c4a550
--- /dev/null
+++ b/test/libsolidity/syntaxTests/dataLocations/internalFunction/internal_function_parameters_no_data_location.sol
@@ -0,0 +1,5 @@
+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.
diff --git a/test/libsolidity/syntaxTests/dataLocations/internalFunction/internal_function_return_parameters_no_data_location.sol b/test/libsolidity/syntaxTests/dataLocations/internalFunction/internal_function_return_parameters_no_data_location.sol
new file mode 100644
index 00000000..a32995e7
--- /dev/null
+++ b/test/libsolidity/syntaxTests/dataLocations/internalFunction/internal_function_return_parameters_no_data_location.sol
@@ -0,0 +1,5 @@
+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.
diff --git a/test/libsolidity/syntaxTests/dataLocations/libraries/library_external_function_params_no_data_location.sol b/test/libsolidity/syntaxTests/dataLocations/libraries/library_external_function_params_no_data_location.sol
new file mode 100644
index 00000000..c20088b7
--- /dev/null
+++ b/test/libsolidity/syntaxTests/dataLocations/libraries/library_external_function_params_no_data_location.sol
@@ -0,0 +1,12 @@
+library L {
+ struct S { uint x; }
+ function g(uint[2]) external pure {}
+ function h(uint[]) external pure {}
+ function i(S) external pure {}
+ 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.
diff --git a/test/libsolidity/syntaxTests/dataLocations/libraries/library_external_function_return_no_data_location.sol b/test/libsolidity/syntaxTests/dataLocations/libraries/library_external_function_return_no_data_location.sol
new file mode 100644
index 00000000..fa3a7821
--- /dev/null
+++ b/test/libsolidity/syntaxTests/dataLocations/libraries/library_external_function_return_no_data_location.sol
@@ -0,0 +1,12 @@
+library L {
+ struct S { uint x; }
+ function g() external pure returns (uint[2]) {}
+ function h() external pure returns (uint[]) {}
+ function i() external pure returns (S) {}
+ 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.
diff --git a/test/libsolidity/syntaxTests/dataLocations/libraries/library_function_with_data_location_fine.sol b/test/libsolidity/syntaxTests/dataLocations/libraries/library_function_with_data_location_fine.sol
new file mode 100644
index 00000000..7a276f95
--- /dev/null
+++ b/test/libsolidity/syntaxTests/dataLocations/libraries/library_function_with_data_location_fine.sol
@@ -0,0 +1,10 @@
+library L {
+ struct S { uint x; }
+ function f(uint[] memory, uint[] storage, S storage) private pure
+ returns (mapping(uint => uint) storage a, S memory b, uint[] storage c) { return (a, b, c); }
+ function g(uint[] memory, uint[] storage) internal pure
+ returns (mapping(uint => uint) storage a, S memory b, uint[] storage c) { return (a, b, c); }
+ function h(uint[] memory, uint[] storage) public pure returns (S storage x) { return x; }
+ function i(uint[] calldata, uint[] storage) external pure returns (S storage x) {return x; }
+}
+// ----
diff --git a/test/libsolidity/syntaxTests/dataLocations/libraries/library_internal_function_no_data_location.sol b/test/libsolidity/syntaxTests/dataLocations/libraries/library_internal_function_no_data_location.sol
new file mode 100644
index 00000000..68c177a8
--- /dev/null
+++ b/test/libsolidity/syntaxTests/dataLocations/libraries/library_internal_function_no_data_location.sol
@@ -0,0 +1,20 @@
+library L {
+ struct S { uint x; }
+ function g() internal pure returns (uint[2]) {}
+ function h() internal pure returns (uint[]) {}
+ function i() internal pure returns (S) {}
+ function j() internal pure returns (mapping(uint => uint)) {}
+ function gp(uint[2]) internal pure {}
+ function hp(uint[]) internal pure {}
+ function ip(S) internal pure {}
+ 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.
diff --git a/test/libsolidity/syntaxTests/dataLocations/libraries/library_private_function_no_data_location.sol b/test/libsolidity/syntaxTests/dataLocations/libraries/library_private_function_no_data_location.sol
new file mode 100644
index 00000000..35256eae
--- /dev/null
+++ b/test/libsolidity/syntaxTests/dataLocations/libraries/library_private_function_no_data_location.sol
@@ -0,0 +1,20 @@
+library L {
+ struct S { uint x; }
+ function g() private pure returns (uint[2]) {}
+ function h() private pure returns (uint[]) {}
+ function i() private pure returns (S) {}
+ function j() private pure returns (mapping(uint => uint)) {}
+ function gp(uint[2]) private pure {}
+ function hp(uint[]) private pure {}
+ 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.
diff --git a/test/libsolidity/syntaxTests/dataLocations/libraries/library_public_function_no_data_location.sol b/test/libsolidity/syntaxTests/dataLocations/libraries/library_public_function_no_data_location.sol
new file mode 100644
index 00000000..f8f8dcb2
--- /dev/null
+++ b/test/libsolidity/syntaxTests/dataLocations/libraries/library_public_function_no_data_location.sol
@@ -0,0 +1,19 @@
+library L {
+ struct S { uint x; }
+ function g() private pure returns (uint[2]) {}
+ function h() private pure returns (uint[]) {}
+ function i() private pure returns (S) {}
+ function j() private pure returns (mapping(uint => uint)) {}
+ function gp(uint[2]) private pure {}
+ function hp(uint[]) private pure {}
+ 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.
diff --git a/test/libsolidity/syntaxTests/dataLocations/libraryExternalFunction/function_argument_location_specifier_test_external_memory.sol b/test/libsolidity/syntaxTests/dataLocations/libraryExternalFunction/function_argument_location_specifier_test_external_memory.sol
index 6fa0a152..9a6b8b7c 100644
--- a/test/libsolidity/syntaxTests/dataLocations/libraryExternalFunction/function_argument_location_specifier_test_external_memory.sol
+++ b/test/libsolidity/syntaxTests/dataLocations/libraryExternalFunction/function_argument_location_specifier_test_external_memory.sol
@@ -2,4 +2,4 @@ library test {
function f(bytes memory) external;
}
// ----
-// TypeError: (30-35): Location has to be calldata or storage for external library functions (remove the "memory" keyword).
+// TypeError: (30-35): Data location must be "storage" or "calldata" for parameter in external function, but "memory" was given.
diff --git a/test/libsolidity/syntaxTests/dataLocations/libraryInternalFunction/function_argument_location_specifier_test_internal_calldata.sol b/test/libsolidity/syntaxTests/dataLocations/libraryInternalFunction/function_argument_location_specifier_test_internal_calldata.sol
index 868c5c30..99b89dfc 100644
--- a/test/libsolidity/syntaxTests/dataLocations/libraryInternalFunction/function_argument_location_specifier_test_internal_calldata.sol
+++ b/test/libsolidity/syntaxTests/dataLocations/libraryInternalFunction/function_argument_location_specifier_test_internal_calldata.sol
@@ -2,4 +2,4 @@ library test {
function f(bytes calldata) internal pure {}
}
// ----
-// TypeError: (30-35): Variable cannot be declared as "calldata" (remove the "calldata" keyword).
+// TypeError: (30-35): Data location must be "storage" or "memory" for parameter in function, but "calldata" was given.
diff --git a/test/libsolidity/syntaxTests/dataLocations/privateFunction/private_function_parameters_no_data_location.sol b/test/libsolidity/syntaxTests/dataLocations/privateFunction/private_function_parameters_no_data_location.sol
new file mode 100644
index 00000000..fdd5cbaf
--- /dev/null
+++ b/test/libsolidity/syntaxTests/dataLocations/privateFunction/private_function_parameters_no_data_location.sol
@@ -0,0 +1,5 @@
+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.
diff --git a/test/libsolidity/syntaxTests/dataLocations/privateFunction/private_function_return_parameters_no_data_location.sol b/test/libsolidity/syntaxTests/dataLocations/privateFunction/private_function_return_parameters_no_data_location.sol
new file mode 100644
index 00000000..65ec1bce
--- /dev/null
+++ b/test/libsolidity/syntaxTests/dataLocations/privateFunction/private_function_return_parameters_no_data_location.sol
@@ -0,0 +1,5 @@
+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.
diff --git a/test/libsolidity/syntaxTests/dataLocations/publicFunction/function_argument_location_specifier_test_public_calldata.sol b/test/libsolidity/syntaxTests/dataLocations/publicFunction/function_argument_location_specifier_test_public_calldata.sol
index cb00199f..efc92cf3 100644
--- a/test/libsolidity/syntaxTests/dataLocations/publicFunction/function_argument_location_specifier_test_public_calldata.sol
+++ b/test/libsolidity/syntaxTests/dataLocations/publicFunction/function_argument_location_specifier_test_public_calldata.sol
@@ -2,4 +2,4 @@ contract test {
function f(bytes calldata) public;
}
// ----
-// TypeError: (31-36): Location has to be memory for publicly visible functions (remove the "storage" or "calldata" keyword).
+// TypeError: (31-36): Data location must be "memory" for parameter in function, but "calldata" was given.
diff --git a/test/libsolidity/syntaxTests/dataLocations/publicFunction/function_argument_location_specifier_test_public_storage.sol b/test/libsolidity/syntaxTests/dataLocations/publicFunction/function_argument_location_specifier_test_public_storage.sol
index 9380d9df..b954ea78 100644
--- a/test/libsolidity/syntaxTests/dataLocations/publicFunction/function_argument_location_specifier_test_public_storage.sol
+++ b/test/libsolidity/syntaxTests/dataLocations/publicFunction/function_argument_location_specifier_test_public_storage.sol
@@ -2,4 +2,4 @@ contract test {
function f(bytes storage) public;
}
// ----
-// TypeError: (31-36): Location has to be memory for publicly visible functions (remove the "storage" or "calldata" keyword).
+// TypeError: (31-36): Data location must be "memory" for parameter in function, but "storage" was given.
diff --git a/test/libsolidity/syntaxTests/dataLocations/publicFunction/public_function_parameters_no_data_location.sol b/test/libsolidity/syntaxTests/dataLocations/publicFunction/public_function_parameters_no_data_location.sol
new file mode 100644
index 00000000..f76bd631
--- /dev/null
+++ b/test/libsolidity/syntaxTests/dataLocations/publicFunction/public_function_parameters_no_data_location.sol
@@ -0,0 +1,5 @@
+contract C {
+ function h(uint[]) public pure {}
+}
+// ----
+// TypeError: (28-34): Data location must be "memory" for parameter in function, but none was given.
diff --git a/test/libsolidity/syntaxTests/dataLocations/publicFunction/public_function_return_parameters_no_data_location.sol b/test/libsolidity/syntaxTests/dataLocations/publicFunction/public_function_return_parameters_no_data_location.sol
new file mode 100644
index 00000000..6b087c34
--- /dev/null
+++ b/test/libsolidity/syntaxTests/dataLocations/publicFunction/public_function_return_parameters_no_data_location.sol
@@ -0,0 +1,5 @@
+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.
diff --git a/test/libsolidity/syntaxTests/dataLocations/variable_declaration_location_specifier_test_non_reference_type.sol b/test/libsolidity/syntaxTests/dataLocations/variable_declaration_location_specifier_test_non_reference_type.sol
index ac312685..5f6daf68 100644
--- a/test/libsolidity/syntaxTests/dataLocations/variable_declaration_location_specifier_test_non_reference_type.sol
+++ b/test/libsolidity/syntaxTests/dataLocations/variable_declaration_location_specifier_test_non_reference_type.sol
@@ -7,7 +7,7 @@ contract test {
}
}
// ----
-// TypeError: (48-63): Data location can only be given for array or struct types.
-// TypeError: (71-89): Data location can only be given for array or struct types.
-// TypeError: (97-111): Data location can only be given for array or struct types.
-// TypeError: (119-136): Data location can only be given for array or struct types.
+// TypeError: (48-63): Data location can only be specified for array, struct or mapping types, but "storage" was given.
+// TypeError: (71-89): Data location can only be specified for array, struct or mapping types, but "storage" was given.
+// TypeError: (97-111): Data location can only be specified for array, struct or mapping types, but "memory" was given.
+// TypeError: (119-136): Data location can only be specified for array, struct or mapping types, but "memory" was given.
diff --git a/test/libsolidity/syntaxTests/functionTypes/external_function_to_function_type_calldata_parameter.sol b/test/libsolidity/syntaxTests/functionTypes/external_function_to_function_type_calldata_parameter.sol
index eb4f0693..f22afe5e 100644
--- a/test/libsolidity/syntaxTests/functionTypes/external_function_to_function_type_calldata_parameter.sol
+++ b/test/libsolidity/syntaxTests/functionTypes/external_function_to_function_type_calldata_parameter.sol
@@ -3,7 +3,7 @@
// when converting to a function type.
contract C {
function f(function(bytes memory) pure external /*g*/) pure public { }
- function callback(bytes) pure external {}
+ function callback(bytes calldata) pure external {}
function g() view public {
f(this.callback);
}
diff --git a/test/libsolidity/syntaxTests/nameAndTypeResolution/105_constant_input_parameter.sol b/test/libsolidity/syntaxTests/nameAndTypeResolution/105_constant_input_parameter.sol
index df47aa6b..ba05fcb3 100644
--- a/test/libsolidity/syntaxTests/nameAndTypeResolution/105_constant_input_parameter.sol
+++ b/test/libsolidity/syntaxTests/nameAndTypeResolution/105_constant_input_parameter.sol
@@ -2,6 +2,6 @@ contract test {
function f(uint[] memory constant a) public { }
}
// ----
-// TypeError: (31-55): Illegal use of "constant" specifier.
+// DeclarationError: (31-55): The "constant" keyword can only be used for state variables.
// TypeError: (31-55): Constants of non-value type not yet implemented.
// TypeError: (31-55): Uninitialized "constant" variable.
diff --git a/test/libsolidity/syntaxTests/nameAndTypeResolution/149_test_for_bug_override_function_with_bytearray_type.sol b/test/libsolidity/syntaxTests/nameAndTypeResolution/149_test_for_bug_override_function_with_bytearray_type.sol
index 871af310..bc1c4267 100644
--- a/test/libsolidity/syntaxTests/nameAndTypeResolution/149_test_for_bug_override_function_with_bytearray_type.sol
+++ b/test/libsolidity/syntaxTests/nameAndTypeResolution/149_test_for_bug_override_function_with_bytearray_type.sol
@@ -1,8 +1,8 @@
contract Vehicle {
- function f(bytes) external returns (uint256 r) {r = 1;}
+ function f(bytes calldata) external returns (uint256 r) {r = 1;}
}
contract Bike is Vehicle {
- function f(bytes) external returns (uint256 r) {r = 42;}
+ function f(bytes calldata) external returns (uint256 r) {r = 42;}
}
// ----
-// Warning: (23-78): Function state mutability can be restricted to pure
+// Warning: (23-87): Function state mutability can be restricted to pure
diff --git a/test/libsolidity/syntaxTests/nameAndTypeResolution/204_overwrite_memory_location_external.sol b/test/libsolidity/syntaxTests/nameAndTypeResolution/204_overwrite_memory_location_external.sol
index 16d71ca4..22d515ea 100644
--- a/test/libsolidity/syntaxTests/nameAndTypeResolution/204_overwrite_memory_location_external.sol
+++ b/test/libsolidity/syntaxTests/nameAndTypeResolution/204_overwrite_memory_location_external.sol
@@ -2,4 +2,4 @@ contract C {
function f(uint[] memory a) external {}
}
// ----
-// TypeError: (28-43): Location has to be calldata for external functions (remove the "memory" or "storage" keyword).
+// TypeError: (28-43): Data location must be "calldata" for parameter in external function, but "memory" was given.
diff --git a/test/libsolidity/syntaxTests/nameAndTypeResolution/205_overwrite_storage_location_external.sol b/test/libsolidity/syntaxTests/nameAndTypeResolution/205_overwrite_storage_location_external.sol
index 99c9827d..3825809c 100644
--- a/test/libsolidity/syntaxTests/nameAndTypeResolution/205_overwrite_storage_location_external.sol
+++ b/test/libsolidity/syntaxTests/nameAndTypeResolution/205_overwrite_storage_location_external.sol
@@ -2,4 +2,4 @@ contract C {
function f(uint[] storage a) external {}
}
// ----
-// TypeError: (28-44): Location has to be calldata for external functions (remove the "memory" or "storage" keyword).
+// TypeError: (28-44): Data location must be "calldata" for parameter in external function, but "storage" was given.
diff --git a/test/libsolidity/syntaxTests/nameAndTypeResolution/224_string_bytes_conversion.sol b/test/libsolidity/syntaxTests/nameAndTypeResolution/224_string_bytes_conversion.sol
index 7b953abb..ed6a9b37 100644
--- a/test/libsolidity/syntaxTests/nameAndTypeResolution/224_string_bytes_conversion.sol
+++ b/test/libsolidity/syntaxTests/nameAndTypeResolution/224_string_bytes_conversion.sol
@@ -1,17 +1,11 @@
contract Test {
string s;
bytes b;
- function h(string _s) external { bytes(_s).length; }
- function i(string memory _s) internal { bytes(_s).length; }
- function j() internal { bytes(s).length; }
- function k(bytes _b) external { string(_b); }
- function l(bytes memory _b) internal { string(_b); }
- function m() internal { string(b); }
+ function h(string calldata _s) pure external { bytes(_s).length; }
+ function i(string memory _s) pure internal { bytes(_s).length; }
+ function j() view internal { bytes(s).length; }
+ function k(bytes calldata _b) pure external { string(_b); }
+ function l(bytes memory _b) pure internal { string(_b); }
+ function m() view internal { string(b); }
}
// ----
-// Warning: (47-99): Function state mutability can be restricted to pure
-// Warning: (104-163): Function state mutability can be restricted to pure
-// Warning: (168-210): Function state mutability can be restricted to view
-// Warning: (215-260): Function state mutability can be restricted to pure
-// Warning: (265-317): Function state mutability can be restricted to pure
-// Warning: (322-358): Function state mutability can be restricted to view
diff --git a/test/libsolidity/syntaxTests/nameAndTypeResolution/385_inline_assembly_calldata_variables.sol b/test/libsolidity/syntaxTests/nameAndTypeResolution/385_inline_assembly_calldata_variables.sol
index 9e324ce1..952b9af6 100644
--- a/test/libsolidity/syntaxTests/nameAndTypeResolution/385_inline_assembly_calldata_variables.sol
+++ b/test/libsolidity/syntaxTests/nameAndTypeResolution/385_inline_assembly_calldata_variables.sol
@@ -1,9 +1,9 @@
contract C {
- function f(bytes bytesAsCalldata) external {
+ function f(bytes calldata bytesAsCalldata) external {
assembly {
let x := bytesAsCalldata
}
}
}
// ----
-// TypeError: (102-117): Call data elements cannot be accessed directly. Copy to a local variable first or use "calldataload" or "calldatacopy" with manually determined offsets and sizes.
+// TypeError: (111-126): Call data elements cannot be accessed directly. Copy to a local variable first or use "calldataload" or "calldatacopy" with manually determined offsets and sizes.
diff --git a/test/libsolidity/syntaxTests/nameAndTypeResolution/471_unspecified_storage_fail.sol b/test/libsolidity/syntaxTests/nameAndTypeResolution/471_unspecified_storage_fail.sol
index 6e401920..de42ebd7 100644
--- a/test/libsolidity/syntaxTests/nameAndTypeResolution/471_unspecified_storage_fail.sol
+++ b/test/libsolidity/syntaxTests/nameAndTypeResolution/471_unspecified_storage_fail.sol
@@ -9,5 +9,5 @@ contract C {
}
}
// ----
-// TypeError: (104-107): Data location must be specified as either "memory" or "storage".
-// TypeError: (123-131): Data location must be specified as either "memory" or "storage".
+// 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.
diff --git a/test/libsolidity/syntaxTests/nameAndTypeResolution/473_storage_location_non_array_or_struct_disallowed.sol b/test/libsolidity/syntaxTests/nameAndTypeResolution/473_storage_location_non_array_or_struct_disallowed.sol
index 6c9f50af..fe846aa0 100644
--- a/test/libsolidity/syntaxTests/nameAndTypeResolution/473_storage_location_non_array_or_struct_disallowed.sol
+++ b/test/libsolidity/syntaxTests/nameAndTypeResolution/473_storage_location_non_array_or_struct_disallowed.sol
@@ -2,4 +2,4 @@ contract C {
function f(uint storage a) public { }
}
// ----
-// TypeError: (28-42): Data location can only be given for array or struct types.
+// TypeError: (28-42): Data location can only be specified for array, struct or mapping types, but "storage" was given.
diff --git a/test/libsolidity/syntaxTests/nameAndTypeResolution/474_storage_location_non_array_or_struct_disallowed_is_not_fatal.sol b/test/libsolidity/syntaxTests/nameAndTypeResolution/474_storage_location_non_array_or_struct_disallowed_is_not_fatal.sol
index a2f47407..e74db375 100644
--- a/test/libsolidity/syntaxTests/nameAndTypeResolution/474_storage_location_non_array_or_struct_disallowed_is_not_fatal.sol
+++ b/test/libsolidity/syntaxTests/nameAndTypeResolution/474_storage_location_non_array_or_struct_disallowed_is_not_fatal.sol
@@ -4,4 +4,4 @@ contract C {
}
}
// ----
-// TypeError: (28-42): Data location can only be given for array or struct types.
+// TypeError: (28-42): Data location can only be specified for array, struct or mapping types, but "storage" was given.
diff --git a/test/libsolidity/syntaxTests/nameAndTypeResolution/476_too_large_arrays_for_calldata_external.sol b/test/libsolidity/syntaxTests/nameAndTypeResolution/476_too_large_arrays_for_calldata_external.sol
index de8b7501..78c38aaf 100644
--- a/test/libsolidity/syntaxTests/nameAndTypeResolution/476_too_large_arrays_for_calldata_external.sol
+++ b/test/libsolidity/syntaxTests/nameAndTypeResolution/476_too_large_arrays_for_calldata_external.sol
@@ -1,6 +1,6 @@
contract C {
- function f(uint[85678901234] a) pure external {
+ function f(uint[85678901234] calldata a) pure external {
}
}
// ----
-// TypeError: (28-47): Array is too large to be encoded.
+// TypeError: (28-56): Array is too large to be encoded.
diff --git a/test/libsolidity/syntaxTests/nameAndTypeResolution/constant_mapping.sol b/test/libsolidity/syntaxTests/nameAndTypeResolution/constant_mapping.sol
new file mode 100644
index 00000000..61c0cc17
--- /dev/null
+++ b/test/libsolidity/syntaxTests/nameAndTypeResolution/constant_mapping.sol
@@ -0,0 +1,8 @@
+contract C {
+ // This should probably have a better error message at some point.
+ // Constant mappings should not be possible in general.
+ mapping(uint => uint) constant x;
+}
+// ----
+// TypeError: (148-180): Constants of non-value type not yet implemented.
+// TypeError: (148-180): Uninitialized "constant" variable.
diff --git a/test/libsolidity/syntaxTests/parsing/location_specifiers_for_params.sol b/test/libsolidity/syntaxTests/parsing/location_specifiers_for_params.sol
index 72b6ce84..bf78e59c 100644
--- a/test/libsolidity/syntaxTests/parsing/location_specifiers_for_params.sol
+++ b/test/libsolidity/syntaxTests/parsing/location_specifiers_for_params.sol
@@ -2,4 +2,6 @@ contract Foo {
function f(uint[] storage constant x, uint[] memory y) internal { }
}
// ----
-// TypeError: (30-55): Data location has to be "memory" (or unspecified) for constants.
+// DeclarationError: (30-55): The "constant" keyword can only be used for state variables.
+// TypeError: (30-55): Constants of non-value type not yet implemented.
+// TypeError: (30-55): Uninitialized "constant" variable.
diff --git a/test/libsolidity/syntaxTests/types/mapping/argument_external.sol b/test/libsolidity/syntaxTests/types/mapping/argument_external.sol
index 0354893f..02beefec 100644
--- a/test/libsolidity/syntaxTests/types/mapping/argument_external.sol
+++ b/test/libsolidity/syntaxTests/types/mapping/argument_external.sol
@@ -3,5 +3,4 @@ contract C {
}
}
// ----
-// TypeError: (28-49): Type is required to live outside storage.
-// TypeError: (28-49): Internal or recursive type is not allowed for public or external functions.
+// TypeError: (28-49): Data location must be "calldata" for parameter in external function, but "storage" was given.
diff --git a/test/libsolidity/syntaxTests/types/mapping/argument_public.sol b/test/libsolidity/syntaxTests/types/mapping/argument_public.sol
index e4121c7f..3939cf26 100644
--- a/test/libsolidity/syntaxTests/types/mapping/argument_public.sol
+++ b/test/libsolidity/syntaxTests/types/mapping/argument_public.sol
@@ -3,5 +3,4 @@ contract C {
}
}
// ----
-// TypeError: (28-49): Type is required to live outside storage.
-// TypeError: (28-49): Internal or recursive type is not allowed for public or external functions.
+// TypeError: (28-49): Data location must be "memory" for parameter in function, but "storage" was given.
diff --git a/test/libsolidity/syntaxTests/types/mapping/array_argument_external.sol b/test/libsolidity/syntaxTests/types/mapping/array_argument_external.sol
index 8dea6907..ef0046d4 100644
--- a/test/libsolidity/syntaxTests/types/mapping/array_argument_external.sol
+++ b/test/libsolidity/syntaxTests/types/mapping/array_argument_external.sol
@@ -3,4 +3,4 @@ contract C {
}
}
// ----
-// TypeError: (28-51): Location has to be calldata for external functions (remove the "memory" or "storage" keyword).
+// TypeError: (28-51): Data location must be "calldata" for parameter in external function, but "storage" was given.
diff --git a/test/libsolidity/syntaxTests/types/mapping/array_argument_public.sol b/test/libsolidity/syntaxTests/types/mapping/array_argument_public.sol
index 69dcec01..fb3f25a4 100644
--- a/test/libsolidity/syntaxTests/types/mapping/array_argument_public.sol
+++ b/test/libsolidity/syntaxTests/types/mapping/array_argument_public.sol
@@ -3,4 +3,4 @@ contract C {
}
}
// ----
-// TypeError: (28-51): Location has to be memory for publicly visible functions (remove the "storage" or "calldata" keyword).
+// TypeError: (28-51): Data location must be "memory" for parameter in function, but "storage" was given.
diff --git a/test/libsolidity/syntaxTests/types/mapping/function_type_argument_external.sol b/test/libsolidity/syntaxTests/types/mapping/function_type_argument_external.sol
index 7fe74fb6..349a4f97 100644
--- a/test/libsolidity/syntaxTests/types/mapping/function_type_argument_external.sol
+++ b/test/libsolidity/syntaxTests/types/mapping/function_type_argument_external.sol
@@ -3,4 +3,5 @@ contract C {
}
}
// ----
+// TypeError: (37-56): Data location must be "memory" for parameter in function, but "storage" was given.
// TypeError: (37-56): Internal type cannot be used for external function type.
diff --git a/test/libsolidity/syntaxTests/types/mapping/function_type_return_external.sol b/test/libsolidity/syntaxTests/types/mapping/function_type_return_external.sol
index f0f8dea6..108d9861 100644
--- a/test/libsolidity/syntaxTests/types/mapping/function_type_return_external.sol
+++ b/test/libsolidity/syntaxTests/types/mapping/function_type_return_external.sol
@@ -3,4 +3,5 @@ contract C {
}
}
// ----
+// TypeError: (57-76): Data location must be "memory" for return parameter in function, but "storage" was given.
// TypeError: (57-76): Internal type cannot be used for external function type.
diff --git a/test/libsolidity/syntaxTests/types/mapping/mapping_array_data_location_function_param_external.sol b/test/libsolidity/syntaxTests/types/mapping/mapping_array_data_location_function_param_external.sol
new file mode 100644
index 00000000..9b96fd3a
--- /dev/null
+++ b/test/libsolidity/syntaxTests/types/mapping/mapping_array_data_location_function_param_external.sol
@@ -0,0 +1,6 @@
+contract c {
+ function f1(mapping(uint => uint)[] calldata) pure external {}
+}
+// ----
+// TypeError: (29-52): Type is required to live outside storage.
+// TypeError: (29-52): Internal or recursive type is not allowed for public or external functions.
diff --git a/test/libsolidity/syntaxTests/types/mapping/mapping_array_return_external.sol b/test/libsolidity/syntaxTests/types/mapping/mapping_array_return_external.sol
index dbe030fb..fe021bd0 100644
--- a/test/libsolidity/syntaxTests/types/mapping/mapping_array_return_external.sol
+++ b/test/libsolidity/syntaxTests/types/mapping/mapping_array_return_external.sol
@@ -3,4 +3,4 @@ contract C {
}
}
// ----
-// TypeError: (53-84): Location has to be memory for publicly visible functions (remove the "storage" or "calldata" keyword).
+// TypeError: (53-84): Data location must be "memory" for return parameter in function, but "storage" was given.
diff --git a/test/libsolidity/syntaxTests/types/mapping/mapping_array_return_public.sol b/test/libsolidity/syntaxTests/types/mapping/mapping_array_return_public.sol
index 7dfecf19..1eb9d03b 100644
--- a/test/libsolidity/syntaxTests/types/mapping/mapping_array_return_public.sol
+++ b/test/libsolidity/syntaxTests/types/mapping/mapping_array_return_public.sol
@@ -3,4 +3,4 @@ contract C {
}
}
// ----
-// TypeError: (51-82): Location has to be memory for publicly visible functions (remove the "storage" or "calldata" keyword).
+// TypeError: (51-82): Data location must be "memory" for return parameter in function, but "storage" was given.
diff --git a/test/libsolidity/syntaxTests/types/mapping/mapping_data_location_calldata.sol b/test/libsolidity/syntaxTests/types/mapping/mapping_data_location_calldata.sol
index c73c7f32..deff7c14 100644
--- a/test/libsolidity/syntaxTests/types/mapping/mapping_data_location_calldata.sol
+++ b/test/libsolidity/syntaxTests/types/mapping/mapping_data_location_calldata.sol
@@ -6,4 +6,4 @@ contract c {
}
}
// ----
-// TypeError: (81-113): Data location for mappings must be specified as "storage".
+// TypeError: (81-113): Data location must be "storage" for variable, but "calldata" was given.
diff --git a/test/libsolidity/syntaxTests/types/mapping/mapping_data_location_default.sol b/test/libsolidity/syntaxTests/types/mapping/mapping_data_location_default.sol
index 85531ae1..e5253f00 100644
--- a/test/libsolidity/syntaxTests/types/mapping/mapping_data_location_default.sol
+++ b/test/libsolidity/syntaxTests/types/mapping/mapping_data_location_default.sol
@@ -6,4 +6,4 @@ contract c {
}
}
// ----
-// TypeError: (81-104): Data location for mappings must be specified as "storage".
+// TypeError: (81-104): Data location must be "storage" for variable, but none was given.
diff --git a/test/libsolidity/syntaxTests/types/mapping/mapping_data_location_function_param_external.sol b/test/libsolidity/syntaxTests/types/mapping/mapping_data_location_function_param_external.sol
new file mode 100644
index 00000000..adcfee2a
--- /dev/null
+++ b/test/libsolidity/syntaxTests/types/mapping/mapping_data_location_function_param_external.sol
@@ -0,0 +1,6 @@
+contract c {
+ function f1(mapping(uint => uint) calldata) pure external returns (mapping(uint => uint) memory) {}
+}
+// ----
+// TypeError: (29-50): Type is required to live outside storage.
+// TypeError: (29-50): Internal or recursive type is not allowed for public or external functions.
diff --git a/test/libsolidity/syntaxTests/types/mapping/mapping_data_location_function_param_internal.sol b/test/libsolidity/syntaxTests/types/mapping/mapping_data_location_function_param_internal.sol
new file mode 100644
index 00000000..17f2f712
--- /dev/null
+++ b/test/libsolidity/syntaxTests/types/mapping/mapping_data_location_function_param_internal.sol
@@ -0,0 +1,4 @@
+contract c {
+ function f4(mapping(uint => uint) memory) pure internal {}
+}
+// ----
diff --git a/test/libsolidity/syntaxTests/types/mapping/mapping_data_location_function_param_public.sol b/test/libsolidity/syntaxTests/types/mapping/mapping_data_location_function_param_public.sol
new file mode 100644
index 00000000..e98c1fe8
--- /dev/null
+++ b/test/libsolidity/syntaxTests/types/mapping/mapping_data_location_function_param_public.sol
@@ -0,0 +1,6 @@
+contract c {
+ function f3(mapping(uint => uint) memory) view public {}
+}
+// ----
+// TypeError: (29-50): Type is required to live outside storage.
+// TypeError: (29-50): Internal or recursive type is not allowed for public or external functions.
diff --git a/test/libsolidity/syntaxTests/types/mapping/mapping_data_location_memory.sol b/test/libsolidity/syntaxTests/types/mapping/mapping_data_location_memory.sol
index 7151e887..600ae669 100644
--- a/test/libsolidity/syntaxTests/types/mapping/mapping_data_location_memory.sol
+++ b/test/libsolidity/syntaxTests/types/mapping/mapping_data_location_memory.sol
@@ -6,4 +6,4 @@ contract c {
}
}
// ----
-// TypeError: (81-111): Data location for mappings must be specified as "storage".
+// TypeError: (81-111): Data location must be "storage" for variable, but "memory" was given.
diff --git a/test/libsolidity/syntaxTests/types/mapping/mapping_return_external.sol b/test/libsolidity/syntaxTests/types/mapping/mapping_return_external.sol
index 85121241..17e646ce 100644
--- a/test/libsolidity/syntaxTests/types/mapping/mapping_return_external.sol
+++ b/test/libsolidity/syntaxTests/types/mapping/mapping_return_external.sol
@@ -3,5 +3,4 @@ contract C {
}
}
// ----
-// TypeError: (53-82): Type is required to live outside storage.
-// TypeError: (53-82): Internal or recursive type is not allowed for public or external functions.
+// TypeError: (53-82): Data location must be "memory" for return parameter in function, but "storage" was given.
diff --git a/test/libsolidity/syntaxTests/types/mapping/mapping_return_public.sol b/test/libsolidity/syntaxTests/types/mapping/mapping_return_public.sol
index 383fa797..cf5ec4ff 100644
--- a/test/libsolidity/syntaxTests/types/mapping/mapping_return_public.sol
+++ b/test/libsolidity/syntaxTests/types/mapping/mapping_return_public.sol
@@ -3,5 +3,4 @@ contract C {
}
}
// ----
-// TypeError: (51-80): Type is required to live outside storage.
-// TypeError: (51-80): Internal or recursive type is not allowed for public or external functions.
+// TypeError: (51-80): Data location must be "memory" for return parameter in function, but "storage" was given.
diff --git a/test/libsolidity/syntaxTests/types/mapping/mapping_return_public_memory.sol b/test/libsolidity/syntaxTests/types/mapping/mapping_return_public_memory.sol
new file mode 100644
index 00000000..35c3abc9
--- /dev/null
+++ b/test/libsolidity/syntaxTests/types/mapping/mapping_return_public_memory.sol
@@ -0,0 +1,7 @@
+contract C {
+ function f() public pure returns (mapping(uint=>uint) memory m) {
+ }
+}
+// ----
+// TypeError: (51-79): Type is required to live outside storage.
+// TypeError: (51-79): Internal or recursive type is not allowed for public or external functions.