diff options
402 files changed, 3732 insertions, 2958 deletions
diff --git a/.circleci/config.yml b/.circleci/config.yml index 30dccead..c577be7b 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -158,6 +158,23 @@ jobs: - store_artifacts: *solc_artifact - persist_to_workspace: *all_artifacts + test_check_spelling: + docker: + - image: circleci/python:3.6 + environment: + TERM: xterm + steps: + - checkout + - attach_workspace: + at: build + - run: + name: Install dependencies + command: | + pip install --user codespell + - run: + name: Check spelling + command: ~/.local/bin/codespell -S "*.enc,.git" -I ./scripts/codespell_whitelist.txt + test_x86_linux: docker: - image: buildpack-deps:artful @@ -220,6 +237,7 @@ workflows: version: 2 build_all: jobs: + - test_check_spelling: *build_on_tags - build_emscripten: *build_on_tags - test_emscripten_solcjs: <<: *build_on_tags @@ -35,6 +35,7 @@ build/ docs/_build docs/utils/__pycache__ docs/utils/*.pyc +/deps/downloads/ # vim stuff *.swp @@ -43,3 +44,5 @@ docs/utils/*.pyc .idea browse.VC.db CMakeLists.txt.user +/CMakeSettings.json +/.vs diff --git a/Changelog.md b/Changelog.md index 34343a8b..c2aa3f17 100644 --- a/Changelog.md +++ b/Changelog.md @@ -3,12 +3,17 @@ How to update your code: * Change every ``.call()`` to a ``.call("")`` and every ``.call(signature, a, b, c)`` to use ``.call(abi.encodeWithSignature(signature, a, b, c))`` (the last one only works for value types). * 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 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: * ABI Encoder: Properly pad data from calldata (``msg.data`` and external function parameters). Use ``abi.encodePacked`` for unpadded encoding. * Code Generator: Signed right shift uses proper arithmetic shift, i.e. rounding towards negative infinity. Warning: this may silently change the semantics of existing code! * Code Generator: Revert at runtime if calldata is too short or points out of bounds. This is done inside the ``ABI decoder`` and therefore also applies to ``abi.decode()``. + * Code Generator: Use ``STATICCALL`` for ``pure`` and ``view`` functions. This was already the case in the experimental 0.5.0 mode. * Commandline interface: Remove obsolete ``--formal`` option. * Commandline interface: Rename the ``--julia`` option to ``--yul``. * Commandline interface: Require ``-`` if standard input is used as source. @@ -17,24 +22,38 @@ Breaking Changes: * General: Disallow raw ``callcode`` (was already deprecated in 0.4.12). It is still possible to use it via inline assembly. * General: Disallow ``var`` keyword. * General: Disallow ``sha3`` and ``suicide`` aliases. + * General: Disallow the ``throw`` statement. This was already the case in the experimental 0.5.0 mode. * General: Disallow the ``years`` unit denomination (was already deprecated in 0.4.24) * General: Introduce ``emit`` as a keyword instead of parsing it as identifier. - * General: New keywords: ``calldata`` + * General: New keywords: ``calldata`` and ``constructor`` * General: New reserved keywords: ``alias``, ``apply``, ``auto``, ``copyof``, ``define``, ``immutable``, ``implements``, ``macro``, ``mutable``, ``override``, ``partial``, ``promise``, ``reference``, ``sealed``, ``sizeof``, ``supports``, ``typedef`` and ``unchecked``. * General: Remove assembly instruction aliases ``sha3`` and ``suicide`` * General: C99-style scoping rules are enforced now. This was already the case in the experimental 0.5.0 mode. + * General: Disallow combining hex numbers with unit denominations (e.g. ``0x1e wei``). This was already the case in the experimental 0.5.0 mode. * Optimizer: Remove the no-op ``PUSH1 0 NOT AND`` sequence. * Parser: Disallow trailing dots that are not followed by a number. * Parser: Remove ``constant`` as function state mutability modifer. + * Type Checker: Disallow assignments between tuples with different numbers of components. This was already the case in the experimental 0.5.0 mode. * Type Checker: Disallow values for constants that are not compile-time constants. This was already the case in the experimental 0.5.0 mode. * Type Checker: Disallow arithmetic operations for boolean variables. + * Type Checker: Disallow tight packing of literals. This was already the case in the experimental 0.5.0 mode. * Type Checker: Disallow conversions between ``bytesX`` and ``uintY`` of different size. + * Type Checker: Disallow empty tuple components. This was partly already the case in the experimental 0.5.0 mode. + * Type Checker: Disallow multi-variable declarations with mismatching number of values. This was already the case in the experimental 0.5.0 mode. * Type Checker: Disallow specifying base constructor arguments multiple times in the same inheritance hierarchy. This was already the case in the experimental 0.5.0 mode. + * 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: 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. + * Type Checker: Address members are not included in contract types anymore. An explicit conversion is now required before invoking an ``address`` member from a contract. * 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. + * References Resolver: Turn missing storage locations into an error. This was already the case in the experimental 0.5.0 mode. * Syntax Checker: Named return values in function types are an error. + * Syntax Checker: Strictly require visibility specifier for functions. This was already the case in the experimental 0.5.0 mode. + * Syntax Checker: Disallow unary ``+``. This was already the case in the experimental 0.5.0 mode. * View Pure Checker: Strictly enfore state mutability. This was already the case in the experimental 0.5.0 mode. Language Features: @@ -43,12 +62,17 @@ Language Features: * General: Scoping rules now follow the C99-style. Compiler Features: + * C API (``libsolc``): Export the ``solidity_license``, ``solidity_version`` and ``solidity_compile`` methods. * Type Checker: Show named argument in case of error. * Tests: Determine transaction status during IPC calls. + * Code Generator: Allocate and free local variables according to their scope. Bugfixes: * Tests: Fix chain parameters to make ipc tests work with newer versions of cpp-ethereum. * Code Generator: Fix allocation of byte arrays (zeroed out too much memory). + * Fix NatSpec json output for `@notice` and `@dev` tags on contract definitions. + * Type Checker: Consider fixed size arrays when checking for recursive structs. + * Type System: Allow arbitrary exponents for literals with a mantissa of zero. ### 0.4.24 (2018-05-16) @@ -700,7 +724,7 @@ Bugfixes: * Conditional: `x ? y : z` * Bugfix: Fixed several bugs where the optimizer generated invalid code. * Bugfix: Enums and structs were not accessible to other contracts. - * Bugfix: Fixed segfault connected to function paramater types, appeared during gas estimation. + * Bugfix: Fixed segfault connected to function parameter types, appeared during gas estimation. * Bugfix: Type checker crash for wrong number of base constructor parameters. * Bugfix: Allow function overloads with different array types. * Bugfix: Allow assignments of type `(x) = 7`. diff --git a/ReleaseChecklist.md b/ReleaseChecklist.md index ebdb7539..b84ae4c4 100644 --- a/ReleaseChecklist.md +++ b/ReleaseChecklist.md @@ -8,7 +8,7 @@ Checklist for making a release: - [ ] Make a final check that there are no platform-dependency issues in the ``solc-test-bytecode`` repository. - [ ] Wait for the tests for the commit on ``release``, create a release in Github, creating the tag. - [ ] Thank voluntary contributors in the Github release page (use ``git shortlog -s -n -e origin/release..origin/develop``). - - [ ] Wait for the CI runs on the tag itself (they should push artefacts onto the Github release page). + - [ ] Wait for the CI runs on the tag itself (they should push artifacts onto the Github release page). - [ ] Run ``scripts/release_ppa.sh release`` to create the PPA release (you need the relevant openssl key). - [ ] Check that the Docker release was pushed to Docker Hub (this still seems to have problems, run ``./scripts/docker_deploy_manual.sh release``). - [ ] Update the homebrew realease in https://github.com/ethereum/homebrew-ethereum/blob/master/solidity.rb (version and hash) diff --git a/cmake/EthCompilerSettings.cmake b/cmake/EthCompilerSettings.cmake index 683d1d2e..ff3a5edb 100644 --- a/cmake/EthCompilerSettings.cmake +++ b/cmake/EthCompilerSettings.cmake @@ -26,7 +26,7 @@ eth_add_cxx_compiler_flag_if_supported(-Wimplicit-fallthrough) if (("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU") OR ("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang")) # Use ISO C++11 standard language. - set(CMAKE_CXX_FLAGS -std=c++11) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") # Enables all the warnings about constructions that some users consider questionable, # and that are easy to avoid. Also enable some extra warning flags that are not @@ -90,7 +90,7 @@ if (("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU") OR ("${CMAKE_CXX_COMPILER_ID}" MA if (EMSCRIPTEN) # Do not emit a separate memory initialiser file set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} --memory-init-file 0") - # Leave only exported symbols as public and agressively remove others + # Leave only exported symbols as public and aggressively remove others set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fdata-sections -ffunction-sections -Wl,--gc-sections -fvisibility=hidden") # Optimisation level set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O3") @@ -132,17 +132,6 @@ elseif (DEFINED MSVC) add_compile_options(-D_WIN32_WINNT=0x0600) # declare Windows Vista API requirement add_compile_options(-DNOMINMAX) # undefine windows.h MAX && MIN macros cause it cause conflicts with std::min && std::max functions - # Always use Release variant of C++ runtime. - # We don't want to provide Debug variants of all dependencies. Some default - # flags set by CMake must be tweaked. - string(REPLACE "/MDd" "/MD" CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG}") - string(REPLACE "/D_DEBUG" "" CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG}") - string(REPLACE "/RTC1" "" CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG}") - string(REPLACE "/MDd" "/MD" CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG}") - string(REPLACE "/D_DEBUG" "" CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG}") - string(REPLACE "/RTC1" "" CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG}") - set_property(GLOBAL PROPERTY DEBUG_CONFIGURATIONS OFF) - # disable empty object file warning set(CMAKE_STATIC_LINKER_FLAGS "${CMAKE_STATIC_LINKER_FLAGS} /ignore:4221") # warning LNK4075: ignoring '/EDITANDCONTINUE' due to '/SAFESEH' specification diff --git a/cmake/jsoncpp.cmake b/cmake/jsoncpp.cmake index 0c110b53..e886c609 100644 --- a/cmake/jsoncpp.cmake +++ b/cmake/jsoncpp.cmake @@ -35,9 +35,7 @@ ExternalProject_Add(jsoncpp-project -DJSONCPP_WITH_TESTS=OFF -DJSONCPP_WITH_PKGCONFIG_SUPPORT=OFF -DCMAKE_CXX_FLAGS=${JSONCPP_EXTRA_FLAGS} - # Overwrite build and install commands to force Release build on MSVC. - BUILD_COMMAND cmake --build <BINARY_DIR> --config Release - INSTALL_COMMAND cmake --build <BINARY_DIR> --config Release --target install + -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} ${byproducts} ) diff --git a/docs/abi-spec.rst b/docs/abi-spec.rst index 366ca951..5f6d7d50 100644 --- a/docs/abi-spec.rst +++ b/docs/abi-spec.rst @@ -2,14 +2,14 @@ .. _ABI: -****************************************** -Application Binary Interface Specification -****************************************** +************************** +Contract ABI Specification +************************** Basic Design ============ -The Application Binary Interface is the standard way to interact with contracts in the Ethereum ecosystem, both +The Contract Application Binary Interface (ABI) is the standard way to interact with contracts in the Ethereum ecosystem, both from outside the blockchain and for contract-to-contract interaction. Data is encoded according to its type, as described in this specification. The encoding is not self describing and thus requires a schema in order to decode. @@ -193,9 +193,9 @@ Given the contract: pragma solidity ^0.4.16; contract Foo { - function bar(bytes3[2]) public pure {} + function bar(bytes3[2] memory) public pure {} function baz(uint32 x, bool y) public pure returns (bool r) { r = x > 32 || y; } - function sam(bytes, bool, uint[]) public pure {} + function sam(bytes memory, bool, uint[] memory) public pure {} } @@ -279,13 +279,13 @@ All together, the encoding is (newline after function selector and each 32-bytes Let us apply the same principle to encode the data for a function with a signature ``g(uint[][],string[])`` with values ``([[1, 2], [3]], ["one", "two", "three"])`` but start from the most atomic parts of the encoding: -First we encode the length and data of the first embeded dynamic array ``[1, 2]`` of the first root array ``[[1, 2], [3]]``: +First we encode the length and data of the first embedded dynamic array ``[1, 2]`` of the first root array ``[[1, 2], [3]]``: - ``0x0000000000000000000000000000000000000000000000000000000000000002`` (number of elements in the first array, 2; the elements themselves are ``1`` and ``2``) - ``0x0000000000000000000000000000000000000000000000000000000000000001`` (first element) - ``0x0000000000000000000000000000000000000000000000000000000000000002`` (second element) -Then we encode the length and data of the second embeded dynamic array ``[3]`` of the first root array ``[[1, 2], [3]]``: +Then we encode the length and data of the second embedded dynamic array ``[3]`` of the first root array ``[[1, 2], [3]]``: - ``0x0000000000000000000000000000000000000000000000000000000000000001`` (number of elements in the second array, 1; the element is ``3``) - ``0x0000000000000000000000000000000000000000000000000000000000000003`` (first element) @@ -307,7 +307,7 @@ Offset ``a`` points to the start of the content of the array ``[1, 2]`` which is Offset ``b`` points to the start of the content of the array ``[3]`` which is line 5 (160 bytes); thus ``b = 0x00000000000000000000000000000000000000000000000000000000000000a0``. -Then we encode the embeded strings of the second root array: +Then we encode the embedded strings of the second root array: - ``0x0000000000000000000000000000000000000000000000000000000000000003`` (number of characters in word ``"one"``) - ``0x6f6e650000000000000000000000000000000000000000000000000000000000`` (utf8 representation of word ``"one"``) @@ -337,7 +337,7 @@ Offset ``d`` points to the start of the content of the string ``"two"`` which is Offset ``e`` points to the start of the content of the string ``"three"`` which is line 7 (224 bytes); thus ``e = 0x00000000000000000000000000000000000000000000000000000000000000e0``. -Note that the encodings of the embeded elements of the root arrays are not dependent on each other and have the same encodings for a fuction with a signature ``g(string[],uint[][])``. +Note that the encodings of the embedded elements of the root arrays are not dependent on each other and have the same encodings for a function with a signature ``g(string[],uint[][])``. Then we encode the length of the first root array: @@ -490,8 +490,8 @@ As an example, the code contract Test { struct S { uint a; uint[] b; T[] c; } struct T { uint x; uint y; } - function f(S s, T t, uint a) public { } - function g() public returns (S s, T t, uint a) {} + function f(S memory s, T memory t, uint a) public { } + function g() public returns (S memory s, T memory t, uint a) {} } would result in the JSON: diff --git a/docs/assembly.rst b/docs/assembly.rst index edc826ac..ec6ac876 100644 --- a/docs/assembly.rst +++ b/docs/assembly.rst @@ -54,7 +54,7 @@ idea is that assembly libraries will be used to enhance the language in such way pragma solidity ^0.4.0; library GetCode { - function at(address _addr) public view returns (bytes o_code) { + function at(address _addr) public view returns (bytes memory o_code) { assembly { // retrieve the size of the code, this needs assembly let size := extcodesize(_addr) @@ -83,7 +83,7 @@ you really know what you are doing. library VectorSum { // This function is less efficient because the optimizer currently fails to // remove the bounds checks in array access. - function sumSolidity(uint[] _data) public view returns (uint o_sum) { + function sumSolidity(uint[] memory _data) public view returns (uint o_sum) { for (uint i = 0; i < _data.length; ++i) o_sum += _data[i]; } @@ -91,7 +91,7 @@ you really know what you are doing. // We know that we only access the array in bounds, so we can avoid the check. // 0x20 needs to be added to an array because the first slot contains the // array length. - function sumAsm(uint[] _data) public view returns (uint o_sum) { + function sumAsm(uint[] memory _data) public view returns (uint o_sum) { for (uint i = 0; i < _data.length; ++i) { assembly { o_sum := add(o_sum, mload(add(add(_data, 0x20), mul(i, 0x20)))) @@ -100,7 +100,7 @@ you really know what you are doing. } // Same as above, but accomplish the entire code within inline assembly. - function sumPureAsm(uint[] _data) public view returns (uint o_sum) { + function sumPureAsm(uint[] memory _data) public view returns (uint o_sum) { assembly { // Load the length (first 32 bytes) let len := mload(_data) @@ -212,9 +212,9 @@ In the grammar, opcodes are represented as pre-defined identifiers. +-------------------------+-----+---+-----------------------------------------------------------------+ | sar(x, y) | | C | arithmetic shift right y by x bits | +-------------------------+-----+---+-----------------------------------------------------------------+ -| addmod(x, y, m) | | F | (x + y) % m with arbitrary precision arithmetics | +| addmod(x, y, m) | | F | (x + y) % m with arbitrary precision arithmetic | +-------------------------+-----+---+-----------------------------------------------------------------+ -| mulmod(x, y, m) | | F | (x * y) % m with arbitrary precision arithmetics | +| mulmod(x, y, m) | | F | (x * y) % m with arbitrary precision arithmetic | +-------------------------+-----+---+-----------------------------------------------------------------+ | signextend(i, x) | | F | sign extend from (i*8+7)th bit counting from least significant | +-------------------------+-----+---+-----------------------------------------------------------------+ @@ -228,13 +228,13 @@ In the grammar, opcodes are represented as pre-defined identifiers. +-------------------------+-----+---+-----------------------------------------------------------------+ | pop(x) | `-` | F | remove the element pushed by x | +-------------------------+-----+---+-----------------------------------------------------------------+ -| dup1 ... dup16 | | F | copy ith stack slot to the top (counting from top) | +| dup1 ... dup16 | | F | copy nth stack slot to the top (counting from top) | +-------------------------+-----+---+-----------------------------------------------------------------+ -| swap1 ... swap16 | `*` | F | swap topmost and ith stack slot below it | +| swap1 ... swap16 | `*` | F | swap topmost and nth stack slot below it | +-------------------------+-----+---+-----------------------------------------------------------------+ -| mload(p) | | F | mem[p..(p+32)) | +| mload(p) | | F | mem[p...(p+32)) | +-------------------------+-----+---+-----------------------------------------------------------------+ -| mstore(p, v) | `-` | F | mem[p..(p+32)) := v | +| mstore(p, v) | `-` | F | mem[p...(p+32)) := v | +-------------------------+-----+---+-----------------------------------------------------------------+ | mstore8(p, v) | `-` | F | mem[p] := v & 0xff (only modifies a single byte) | +-------------------------+-----+---+-----------------------------------------------------------------+ @@ -272,16 +272,16 @@ In the grammar, opcodes are represented as pre-defined identifiers. +-------------------------+-----+---+-----------------------------------------------------------------+ | returndatacopy(t, f, s) | `-` | B | copy s bytes from returndata at position f to mem at position t | +-------------------------+-----+---+-----------------------------------------------------------------+ -| create(v, p, s) | | F | create new contract with code mem[p..(p+s)) and send v wei | +| create(v, p, s) | | F | create new contract with code mem[p...(p+s)) and send v wei | | | | | and return the new address | +-------------------------+-----+---+-----------------------------------------------------------------+ -| create2(v, n, p, s) | | C | create new contract with code mem[p..(p+s)) at address | -| | | | keccak256(<address> . n . keccak256(mem[p..(p+s))) and send v | +| create2(v, n, p, s) | | C | create new contract with code mem[p...(p+s)) at address | +| | | | keccak256(<address> . n . keccak256(mem[p...(p+s))) and send v | | | | | wei and return the new address | +-------------------------+-----+---+-----------------------------------------------------------------+ -| call(g, a, v, in, | | F | call contract at address a with input mem[in..(in+insize)) | +| call(g, a, v, in, | | F | call contract at address a with input mem[in...(in+insize)) | | insize, out, outsize) | | | providing g gas and v wei and output area | -| | | | mem[out..(out+outsize)) returning 0 on error (eg. out of gas) | +| | | | mem[out...(out+outsize)) returning 0 on error (eg. out of gas) | | | | | and 1 on success | +-------------------------+-----+---+-----------------------------------------------------------------+ | callcode(g, a, v, in, | | F | identical to ``call`` but only use the code from a and stay | @@ -293,23 +293,23 @@ In the grammar, opcodes are represented as pre-defined identifiers. | staticcall(g, a, in, | | B | identical to ``call(g, a, 0, in, insize, out, outsize)`` but do | | insize, out, outsize) | | | not allow state modifications | +-------------------------+-----+---+-----------------------------------------------------------------+ -| return(p, s) | `-` | F | end execution, return data mem[p..(p+s)) | +| return(p, s) | `-` | F | end execution, return data mem[p...(p+s)) | +-------------------------+-----+---+-----------------------------------------------------------------+ -| revert(p, s) | `-` | B | end execution, revert state changes, return data mem[p..(p+s)) | +| revert(p, s) | `-` | B | end execution, revert state changes, return data mem[p...(p+s)) | +-------------------------+-----+---+-----------------------------------------------------------------+ | selfdestruct(a) | `-` | F | end execution, destroy current contract and send funds to a | +-------------------------+-----+---+-----------------------------------------------------------------+ | invalid | `-` | F | end execution with invalid instruction | +-------------------------+-----+---+-----------------------------------------------------------------+ -| log0(p, s) | `-` | F | log without topics and data mem[p..(p+s)) | +| log0(p, s) | `-` | F | log without topics and data mem[p...(p+s)) | +-------------------------+-----+---+-----------------------------------------------------------------+ -| log1(p, s, t1) | `-` | F | log with topic t1 and data mem[p..(p+s)) | +| log1(p, s, t1) | `-` | F | log with topic t1 and data mem[p...(p+s)) | +-------------------------+-----+---+-----------------------------------------------------------------+ -| log2(p, s, t1, t2) | `-` | F | log with topics t1, t2 and data mem[p..(p+s)) | +| log2(p, s, t1, t2) | `-` | F | log with topics t1, t2 and data mem[p...(p+s)) | +-------------------------+-----+---+-----------------------------------------------------------------+ -| log3(p, s, t1, t2, t3) | `-` | F | log with topics t1, t2, t3 and data mem[p..(p+s)) | +| log3(p, s, t1, t2, t3) | `-` | F | log with topics t1, t2, t3 and data mem[p...(p+s)) | +-------------------------+-----+---+-----------------------------------------------------------------+ -| log4(p, s, t1, t2, t3, | `-` | F | log with topics t1, t2, t3, t4 and data mem[p..(p+s)) | +| log4(p, s, t1, t2, t3, | `-` | F | log with topics t1, t2, t3, t4 and data mem[p...(p+s)) | | t4) | | | | +-------------------------+-----+---+-----------------------------------------------------------------+ | origin | | F | transaction sender | diff --git a/docs/contracts.rst b/docs/contracts.rst index 53e50656..51d7923d 100644 --- a/docs/contracts.rst +++ b/docs/contracts.rst @@ -20,7 +20,7 @@ Contracts can be created "from outside" via Ethereum transactions or from within IDEs, such as `Remix <https://remix.ethereum.org/>`_, make the creation process seamless using UI elements. -Creating contracts programatically on Ethereum is best done via using the JavaScript API `web3.js <https://github.com/ethereum/web3.js>`_. +Creating contracts programmatically on Ethereum is best done via using the JavaScript API `web3.js <https://github.com/ethereum/web3.js>`_. As of today it has a method called `web3.eth.Contract <https://web3js.readthedocs.io/en/1.0/web3-eth-contract.html#new-contract>`_ to facilitate contract creation. @@ -131,10 +131,9 @@ a "message call") and external ones that do), there are four types of visibilities for functions and state variables. -Functions can be specified as being ``external``, -``public``, ``internal`` or ``private``, where the default is -``public``. For state variables, ``external`` is not possible -and the default is ``internal``. +Functions have to be specified as being ``external``, +``public``, ``internal`` or ``private``. +For state variables, ``external`` is not possible. ``external``: External functions are part of the contract @@ -406,7 +405,7 @@ Constant State Variables State variables can be declared as ``constant``. In this case, they have to be assigned from an expression which is a constant at compile time. Any expression -that accesses storage, blockchain data (e.g. ``now``, ``this.balance`` or +that accesses storage, blockchain data (e.g. ``now``, ``address(this).balance`` or ``block.number``) or execution data (``msg.value`` or ``gasleft()``) or make calls to external contracts are disallowed. Expressions that might have a side-effect on memory allocation are allowed, but those that @@ -451,6 +450,10 @@ View Functions Functions can be declared ``view`` in which case they promise not to modify the state. +.. note:: + If the compiler's EVM target is Byzantium or newer (default) the opcode + ``STATICCALL`` is used. + The following statements are considered modifying the state: #. Writing to state variables. @@ -464,7 +467,7 @@ The following statements are considered modifying the state: :: - pragma solidity ^0.4.16; + pragma solidity >0.4.24; contract C { function f(uint a, uint b) public view returns (uint) { @@ -479,11 +482,12 @@ The following statements are considered modifying the state: Getter methods are marked ``view``. .. note:: - If invalid explicit type conversions are used, state modifications are possible - even though a ``view`` function was called. - You can switch the compiler to use ``STATICCALL`` when calling such functions and thus - prevent modifications to the state on the level of the EVM by adding - ``pragma experimental "v0.5.0";`` + Prior to version 0.5.0, the compiler did not use the ``STATICCALL`` opcode + for ``view`` functions. + This enabled state modifications in ``view`` functions through the use of + invalid explicit type conversions. + By using ``STATICCALL`` for ``view`` functions, modifications to the + state are prevented on the level of the EVM. .. index:: ! pure function, function;pure @@ -494,17 +498,20 @@ Pure Functions Functions can be declared ``pure`` in which case they promise not to read from or modify the state. +.. note:: + If the compiler's EVM target is Byzantium or newer (default) the opcode ``STATICCALL`` is used. + In addition to the list of state modifying statements explained above, the following are considered reading from the state: #. Reading from state variables. -#. Accessing ``this.balance`` or ``<address>.balance``. +#. Accessing ``address(this).balance`` or ``<address>.balance``. #. Accessing any of the members of ``block``, ``tx``, ``msg`` (with the exception of ``msg.sig`` and ``msg.data``). #. Calling any function not marked ``pure``. #. Using inline assembly that contains certain opcodes. :: - pragma solidity ^0.4.16; + pragma solidity >0.4.24; contract C { function f(uint a, uint b) public pure returns (uint) { @@ -513,11 +520,12 @@ In addition to the list of state modifying statements explained above, the follo } .. note:: - If invalid explicit type conversions are used, state modifications are possible - even though a ``pure`` function was called. - You can switch the compiler to use ``STATICCALL`` when calling such functions and thus - prevent modifications to the state on the level of the EVM by adding - ``pragma experimental "v0.5.0";`` + Prior to version 0.5.0, the compiler did not use the ``STATICCALL`` opcode + for ``pure`` functions. + This enabled state modifications in ``pure`` functions through the use of + invalid explicit type conversions. + By using ``STATICCALL`` for ``pure`` functions, modifications to the + state are prevented on the level of the EVM. .. warning:: It is not possible to prevent functions from reading the state at the level @@ -571,7 +579,7 @@ Like any function, the fallback function can execute complex operations as long but do not define a fallback function throw an exception, sending back the Ether (this was different before Solidity v0.4.0). So if you want your contract to receive Ether, - you have to implement a fallback function. + you have to implement a payable fallback function. .. warning:: A contract without a payable fallback function can receive Ether as a recipient of a `coinbase transaction` (aka `miner block reward`) @@ -579,11 +587,11 @@ Like any function, the fallback function can execute complex operations as long A contract cannot react to such Ether transfers and thus also cannot reject them. This is a design choice of the EVM and Solidity cannot work around it. - It also means that ``this.balance`` can be higher than the sum of some manual accounting implemented in a contract (i.e. having a counter updated in the fallback function). + It also means that ``address(this).balance`` can be higher than the sum of some manual accounting implemented in a contract (i.e. having a counter updated in the fallback function). :: - pragma solidity ^0.4.0; + pragma solidity >0.4.24; contract Test { // This function is called for all messages sent to @@ -604,14 +612,13 @@ Like any function, the fallback function can execute complex operations as long contract Caller { function callTest(Test test) public { - test.call(abi.encodeWithSignature("nonExistingFunction()")); + address(test).call(abi.encodeWithSignature("nonExistingFunction()")); // results in test.x becoming == 1. - // The following will not compile, but even - // if someone sends ether to that contract, + // If someone sends ether to that contract, // the transaction will fail and reject the // Ether. - //test.send(2 ether); + address(test).send(2 ether); } } @@ -842,10 +849,10 @@ Details are given in the following example. :: - pragma solidity ^0.4.22; + pragma solidity >0.4.24; contract owned { - constructor() { owner = msg.sender; } + constructor() public { owner = msg.sender; } address owner; } @@ -854,7 +861,7 @@ Details are given in the following example. // internal functions and state variables. These cannot be // accessed externally via `this`, though. contract mortal is owned { - function kill() { + function kill() public { if (msg.sender == owner) selfdestruct(owner); } } @@ -876,7 +883,7 @@ Details are given in the following example. // also a base class of `mortal`, yet there is only a single // instance of `owned` (as for virtual inheritance in C++). contract named is owned, mortal { - constructor(bytes32 name) { + constructor(bytes32 name) public { Config config = Config(0xD5f9D8D94886E70b06E474c3fB14Fd43E2f23970); NameReg(config.lookup(1)).register(name); } @@ -1042,7 +1049,7 @@ constant and defines the behaviour of the contract or describes it. The second way has to be used if the constructor arguments of the base depend on those of the derived contract. Arguments have to be given either in the -inheritance list or in modifier-style in the derived constuctor. +inheritance list or in modifier-style in the derived constructor. Specifying arguments in both places is an error. If a derived contract doesn't specify the arguments to all of its base @@ -1142,6 +1149,7 @@ Interfaces Interfaces are similar to abstract contracts, but they cannot have any functions implemented. There are further restrictions: - Cannot inherit other contracts or interfaces. +- All declared functions must be external. - Cannot define constructor. - Cannot define variables. - Cannot define structs. @@ -1159,7 +1167,7 @@ Interfaces are denoted by their own keyword: pragma solidity ^0.4.11; interface Token { - function transfer(address recipient, uint amount) public; + function transfer(address recipient, uint amount) external; } Contracts can inherit interfaces as they would inherit other contracts. @@ -1287,12 +1295,12 @@ custom types without the overhead of external function calls: uint[] limbs; } - function fromUint(uint x) internal pure returns (bigint r) { + function fromUint(uint x) internal pure returns (bigint memory r) { r.limbs = new uint[](1); r.limbs[0] = x; } - function add(bigint _a, bigint _b) internal pure returns (bigint r) { + function add(bigint memory _a, bigint memory _b) internal pure returns (bigint memory r) { r.limbs = new uint[](max(_a.limbs.length, _b.limbs.length)); uint carry = 0; for (uint i = 0; i < r.limbs.length; ++i) { @@ -1315,7 +1323,7 @@ custom types without the overhead of external function calls: } } - function limb(bigint _a, uint _limb) internal pure returns (uint) { + function limb(bigint memory _a, uint _limb) internal pure returns (uint) { return _limb < _a.limbs.length ? _a.limbs[_limb] : 0; } diff --git a/docs/contributing.rst b/docs/contributing.rst index f1dae192..155b4e65 100644 --- a/docs/contributing.rst +++ b/docs/contributing.rst @@ -97,6 +97,11 @@ Alternatively, there is a testing script at ``scripts/test.sh`` which executes a Travis CI even runs some additional tests (including ``solc-js`` and testing third party Solidity frameworks) that require compiling the Emscripten target. +.. note :: + + While any version of ``cpp-ethereum`` should be usable, this cannot be guaranteed, and it is suggested to use the same version that is used by the Solidity continuous integration tests. + Currently the CI uses ``d661ac4fec0aeffbedcdc195f67f5ded0c798278`` of ``cpp-ethereum``. + Writing and running syntax tests -------------------------------- @@ -114,13 +119,13 @@ Example: ``./test/libsolidity/syntaxTests/double_stateVariable_declaration.sol`` // ---- // DeclarationError: Identifier already declared. -A syntax test must contain at least the contract under test itself, followed by the seperator ``----``. The additional comments above are used to describe the +A syntax test must contain at least the contract under test itself, followed by the separator ``----``. The additional comments above are used to describe the expected compiler errors or warnings. This section can be empty in case that the contract should compile without any errors or warnings. In the above example, the state variable ``variable`` was declared twice, which is not allowed. This will result in a ``DeclarationError`` stating that the identifier was already declared. The tool that is being used for those tests is called ``isoltest`` and can be found under ``./test/tools/``. It is an interactive tool which allows -editing of failing contracts using your prefered text editor. Let's try to break this test by removing the second declaration of ``variable``: +editing of failing contracts using your preferred text editor. Let's try to break this test by removing the second declaration of ``variable``: :: @@ -213,6 +218,7 @@ At this stage you should be able to see a message similar to the following: If the instrumentation messages did not appear, try switching the cmake flags pointing to AFL's clang binaries: :: + # if previously failed make clean cmake .. -DCMAKE_C_COMPILER=path/to/afl-clang -DCMAKE_CXX_COMPILER=path/to/afl-clang++ @@ -240,7 +246,7 @@ Othwerise, upon execution the fuzzer will halt with an error saying binary is no Location : check_binary(), afl-fuzz.c:6920 -Next, you need some example source files. This will make it much easer for the fuzzer +Next, you need some example source files. This will make it much easier for the fuzzer to find errors. You can either copy some files from the syntax tests or extract test files from the documentation or the other tests: diff --git a/docs/control-structures.rst b/docs/control-structures.rst index 8ced0fbc..9fd017db 100644 --- a/docs/control-structures.rst +++ b/docs/control-structures.rst @@ -39,7 +39,7 @@ write:: pragma solidity ^0.4.16; contract Simple { - function arithmetics(uint _a, uint _b) + function arithmetic(uint _a, uint _b) public pure returns (uint o_sum, uint o_product) @@ -293,18 +293,13 @@ These can then either be assigned to newly declared variables or to pre-existing (x, y) = (y, x); // Components can be left out (also for variable declarations). (data.length,,) = f(); // Sets the length to 7 - // Components can only be left out at the left-hand-side of assignments, with - // one exception: - (x,) = (1,); - // (1,) is the only way to specify a 1-component tuple, because (1) is - // equivalent to 1. } } .. note:: - Prior to version 0.4.24 it was possible to assign to tuples of smaller size, either + Prior to version 0.5.0 it was possible to assign to tuples of smaller size, either filling up on the left or on the right side (which ever was empty). This is - now deprecated, both sides have to have the same number of components. + now disallowed, so both sides have to have the same number of components. Complications for Arrays and Structs ------------------------------------ @@ -423,18 +418,18 @@ a message string for ``require``, but not for ``assert``. :: - pragma solidity ^0.4.22; + pragma solidity >0.4.24; contract Sharer { function sendHalf(address addr) public payable returns (uint balance) { require(msg.value % 2 == 0, "Even value required."); - uint balanceBeforeTransfer = this.balance; + uint balanceBeforeTransfer = address(this).balance; addr.transfer(msg.value / 2); // Since transfer throws an exception on failure and // cannot call back here, there should be no way for us to // still have half of the money. - assert(this.balance == balanceBeforeTransfer - msg.value / 2); - return this.balance; + assert(address(this).balance == balanceBeforeTransfer - msg.value / 2); + return address(this).balance; } } @@ -470,10 +465,10 @@ The following example shows how an error string can be used together with revert :: - pragma solidity ^0.4.22; + pragma solidity >0.4.24; contract VendingMachine { - function buy(uint amount) payable { + function buy(uint amount) public payable { if (amount > msg.value / 2 ether) revert("Not enough Ether provided."); // Alternative way to do it: diff --git a/docs/frequently-asked-questions.rst b/docs/frequently-asked-questions.rst index 0d6fa033..cb46dea6 100644 --- a/docs/frequently-asked-questions.rst +++ b/docs/frequently-asked-questions.rst @@ -25,21 +25,6 @@ What is the transaction "payload"? This is just the bytecode "data" sent along with the request. -Is there a decompiler available? -================================ - -There is no exact decompiler to Solidity, but -`Porosity <https://github.com/comaeio/porosity>`_ is close. -Because some information like variable names, comments, and -source code formatting is lost in the compilation process, -it is not possible to completely recover the original source code. - -Bytecode can be disassembled to opcodes, a service that is provided by -several blockchain explorers. - -Contracts on the blockchain should have their original source -code published if they are to be used by third parties. - Create a contract that can be killed and return funds ===================================================== @@ -69,7 +54,7 @@ Can you return an array or a ``string`` from a solidity function call? Yes. See `array_receiver_and_returner.sol <https://github.com/fivedogit/solidity-baby-steps/blob/master/contracts/60_array_receiver_and_returner.sol>`_. What is problematic, though, is returning any variably-sized data (e.g. a -variably-sized array like ``uint[]``) from a fuction **called from within Solidity**. +variably-sized array like ``uint[]``) from a function **called from within Solidity**. This is a limitation of the EVM and will be solved with the next protocol update. Returning variably-sized data as part of an external transaction or call is fine. @@ -85,7 +70,7 @@ Example:: pragma solidity ^0.4.16; contract C { - function f() public pure returns (uint8[5]) { + function f() public pure returns (uint8[5] memory) { string[4] memory adaArr = ["This", "is", "an", "array"]; return ([1, 2, 3, 4, 5]); } @@ -260,7 +245,7 @@ The third one is the stack, which is used to hold small local variables. It is almost free to use, but can only hold a limited amount of values. For almost all types, you cannot specify where they should be stored, because -they are copied everytime they are used. +they are copied every time they are used. The types where the so-called storage location is important are structs and arrays. If you e.g. pass such variables in function calls, their @@ -273,9 +258,11 @@ of variable it concerns: * state variables are always in storage * function arguments are in memory by default -* local variables of struct, array or mapping type reference storage by default +* local variables of mapping type reference storage by default * local variables of value type (i.e. neither array, nor struct nor mapping) are stored in the stack +For local variables of struct or array type the storage location has to be stated explicitly. + Example:: pragma solidity ^0.4.0; @@ -306,48 +293,12 @@ independent copy of the state variable is created in memory and is another issue). The modifications to this independent copy do not carry back to ``data1`` or ``data2``. -A common mistake is to declare a local variable and assume that it will -be created in memory, although it will be created in storage:: - - /// THIS CONTRACT CONTAINS AN ERROR - - pragma solidity ^0.4.0; - - contract C { - uint someVariable; - uint[] data; - - function f() public { - uint[] x; - x.push(2); - data = x; - } - } - -The type of the local variable ``x`` is ``uint[] storage``, but since -storage is not dynamically allocated, it has to be assigned from -a state variable before it can be used. So no space in storage will be -allocated for ``x``, but instead it functions only as an alias for -a pre-existing variable in storage. - -What will happen is that the compiler interprets ``x`` as a storage -pointer and will make it point to the storage slot ``0`` by default. -This has the effect that ``someVariable`` (which resides at storage -slot ``0``) is modified by ``x.push(2)``. - -The correct way to do this is the following:: - - pragma solidity ^0.4.0; - - contract C { - uint someVariable; - uint[] data; - - function f() public { - uint[] x = data; - x.push(2); - } - } +.. warning:: + Prior to version 0.5.0, a common mistake was to declare a local variable and assume that it will + be created in memory, although it will be created in storage. Using such a variable without initializing + could lead to unexpected behavior. Starting from 0.5.0, however, the storage location for local variables + has to be specified explicitly and local storage variables have to be initialized, which should prevent + these kinds of mistakes. ****************** Advanced Questions @@ -409,7 +360,7 @@ This is a very interesting question. Suppose that we have a contract field set u User user2 = user1; } -In this case, the mapping of the struct being copied over into the userList is ignored as there is no "list of mapped keys". +In this case, the mapping of the struct being copied over into ``user2`` is ignored as there is no "list of mapped keys". Therefore it is not possible to find out which values should be copied over. How do I initialize a contract with only a specific amount of wei? @@ -479,7 +430,7 @@ independent copies will be created:: h(x); } - function g(uint[20] y) internal pure { + function g(uint[20] memory y) internal pure { y[2] = 3; } @@ -489,10 +440,9 @@ independent copies will be created:: } The call to ``g(x)`` will not have an effect on ``x`` because it needs -to create an independent copy of the storage value in memory -(the default storage location is memory). On the other hand, -``h(x)`` successfully modifies ``x`` because only a reference -and not a copy is passed. +to create an independent copy of the storage value in memory. +On the other hand, ``h(x)`` successfully modifies ``x`` because only +a reference and not a copy is passed. Sometimes, when I try to change the length of an array with ex: ``arrayname.length = 7;`` I get a compiler error ``Value must be an lvalue``. Why? ================================================================================================================================================== diff --git a/docs/index.rst b/docs/index.rst index a57b93e4..75af4827 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -20,8 +20,8 @@ crowdfunding, blind auctions, multi-signature wallets and more. The best way to try out Solidity right now is using `Remix <https://remix.ethereum.org/>`_ (it can take a while to load, please be patient). Remix is a web browser - based IDE that allows you to write Solidity smart contracts, then deploy - and run the smart contracts. + based IDE that allows you to write Solidity smart contracts, then deploy + and run the smart contracts. .. warning:: Since software is written by humans, it can have bugs. Thus, also @@ -83,7 +83,7 @@ Available Solidity Integrations * `Solium <https://github.com/duaraghav8/Solium/>`_ Linter to identify and fix style and security issues in Solidity. - + * `Solhint <https://github.com/protofire/solhint>`_ Solidity linter that provides security, style guide and best practice rules for smart contract validation. @@ -104,7 +104,7 @@ Discontinued: * `Mix IDE <https://github.com/ethereum/mix/>`_ Qt based IDE for designing, debugging and testing solidity smart contracts. -* `Ethereum Studio <https://live.ether.camp/>`_ +* `Ethereum Studio <https://live.ether.camp/>`_ Specialized web IDE that also provides shell access to a complete Ethereum environment. Solidity Tools @@ -119,11 +119,14 @@ Solidity Tools * `solgraph <https://github.com/raineorshine/solgraph>`_ Visualize Solidity control flow and highlight potential security vulnerabilities. +* `Doxity <https://github.com/DigixGlobal/doxity>`_ + Documentation Generator for Solidity. + * `evmdis <https://github.com/Arachnid/evmdis>`_ EVM Disassembler that performs static analysis on the bytecode to provide a higher level of abstraction than raw EVM operations. -* `Doxity <https://github.com/DigixGlobal/doxity>`_ - Documentation Generator for Solidity. +.. note:: + Information like variable names, comments, and source code formatting is lost in the compilation process and it is not possible to completely recover the original source code. Decompiling smart contracts to view the original source code might not be possible, or the end result that useful. Third-Party Solidity Parsers and Grammars ----------------------------------------- diff --git a/docs/installing-solidity.rst b/docs/installing-solidity.rst index 05ee0748..5b3fdf87 100644 --- a/docs/installing-solidity.rst +++ b/docs/installing-solidity.rst @@ -64,7 +64,7 @@ repository contains potentially unstable changes in the develop branch. .. code:: bash - docker run ethereum/solc:stable solc --version + docker run ethereum/solc:stable --version Currently, the docker image only contains the compiler executable, so you have to do some additional work to link in the source and diff --git a/docs/layout-of-source-files.rst b/docs/layout-of-source-files.rst index 81faf816..46ef3d57 100644 --- a/docs/layout-of-source-files.rst +++ b/docs/layout-of-source-files.rst @@ -205,7 +205,7 @@ for the two input parameters and two returned values. * @return s The calculated surface. * @return p The calculated perimeter. */ - function rectangle(uint w, uint h) returns (uint s, uint p) { + function rectangle(uint w, uint h) public returns (uint s, uint p) { s = w * h; p = 2 * (w + h); } diff --git a/docs/miscellaneous.rst b/docs/miscellaneous.rst index 1d5add9a..c0c7cb1b 100644 --- a/docs/miscellaneous.rst +++ b/docs/miscellaneous.rst @@ -319,7 +319,7 @@ Global Variables ================ - ``abi.encode(...) returns (bytes)``: :ref:`ABI <ABI>`-encodes the given arguments -- ``abi.encodePacked(...) returns (bytes)``: Performes :ref:`packed encoding <abi_packed_mode>` of the given arguments +- ``abi.encodePacked(...) returns (bytes)``: Performs :ref:`packed encoding <abi_packed_mode>` of the given arguments - ``abi.encodeWithSelector(bytes4 selector, ...) returns (bytes)``: :ref:`ABI <ABI>`-encodes the given arguments starting from the second and prepends the given four-byte selector - ``abi.encodeWithSignature(string signature, ...) returns (bytes)``: Equivalent to ``abi.encodeWithSelector(bytes4(keccak256(bytes(signature)), ...)``` diff --git a/docs/security-considerations.rst b/docs/security-considerations.rst index afdecb98..b997466b 100644 --- a/docs/security-considerations.rst +++ b/docs/security-considerations.rst @@ -203,7 +203,7 @@ Now someone tricks you into sending ether to the address of this attack wallet: pragma solidity >0.4.24; interface TxUserWallet { - function transferTo(address dest, uint amount) public; + function transferTo(address dest, uint amount) external; } contract TxAttackWallet { diff --git a/docs/solidity-by-example.rst b/docs/solidity-by-example.rst index fcdd1862..3934d29d 100644 --- a/docs/solidity-by-example.rst +++ b/docs/solidity-by-example.rst @@ -66,7 +66,7 @@ of votes. Proposal[] public proposals; /// Create a new ballot to choose one of `proposalNames`. - constructor(bytes32[] proposalNames) public { + constructor(bytes32[] memory proposalNames) public { chairperson = msg.sender; voters[chairperson].weight = 1; @@ -452,9 +452,9 @@ high or low invalid bids. /// correctly blinded invalid bids and for all bids except for /// the totally highest. function reveal( - uint[] _values, - bool[] _fake, - bytes32[] _secret + uint[] memory _values, + bool[] memory _fake, + bytes32[] memory _secret ) public onlyAfter(biddingEnd) @@ -645,4 +645,489 @@ Safe Remote Purchase Micropayment Channel ******************** -To be written. +In this section we will learn how to build a simple implementation +of a payment channel. It use cryptographics signatures to make +repeated transfers of Ether between the same parties secure, instantaneous, and +without transaction fees. To do it we need to understand how to +sign and verify signatures, and setup the payment channel. + +Creating and verifying signatures +================================= + +Imagine Alice wants to send a quantity of Ether to Bob, i.e. +Alice is the sender and the Bob is the recipient. +Alice only needs to send cryptographically signed messages off-chain +(e.g. via email) to Bob and it will be very similar to writing checks. + +Signatures are used to authorize transactions, +and they are a general tool that is available to +smart contracts. Alice will build a simple +smart contract that lets her transmit Ether, but +in a unusual way, instead of calling a function herself +to initiate a payment, she will let Bob +do that, and therefore pay the transaction fee. +The contract will work as follows: + + 1. Alice deploys the ``ReceiverPays`` contract, attaching enough Ether to cover the payments that will be made. + 2. Alice authorizes a payment by signing a message with their private key. + 3. Alice sends the cryptographically signed message to Bob. The message does not need to be kept secret + (you will understand it later), and the mechanism for sending it does not matter. + 4. Bob claims their payment by presenting the signed message to the smart contract, it verifies the + authenticity of the message and then releases the funds. + +Creating the signature +---------------------- + +Alice does not need to interact with Ethereum network to +sign the transaction, the process is completely offline. +In this tutorial, we will sign messages in the browser +using ``web3.js`` and ``MetaMask``. +In particular, we will use the standard way described in `EIP-762 <https://github.com/ethereum/EIPs/pull/712>`_, +as it provides a number of other security benefits. + +:: + + /// Hashing first makes a few things easier + var hash = web3.sha3("message to sign"); + web3.personal.sign(hash, web3.eth.defaultAccount, function () {...}); + + +Note that the ``web3.personal.sign`` prepends the length of the message to the signed data. +Since we hash first, the message will always be exactly 32 bytes long, +and thus this length prefix is always the same, making everything easier. + +What to Sign +------------ + +For a contract that fulfills payments, the signed message must include: + + 1. The recipient's address + 2. The amount to be transferred + 3. Protection against replay attacks + +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 +account. +The smart contract will check if a nonce is used multiple times. + +There is another type of replay attacks, it occurs when the +owner deploys a ``ReceiverPays`` smart contract, performs some payments, +and then destroy the contract. Later, she decides to deploy the +``RecipientPays`` smart contract again, but the new contract does not +know the nonces used in the previous deployment, so the attacker +can use the old messages again. + +Alice can protect against it including +the contract's address in the message, and only +messages containing contract's address itself will be accepted. +This functionality can be found in the first two lines of the ``claimPayment()`` function in the full contract +at the end of this chapter. + +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 +`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 +using ``abi.encodePacked``. +Putting it all together, here is a JavaScript function that +creates the proper signature for the ``ReceiverPays`` example: + +:: + + // recipient is the address that should be paid. + // amount, in wei, specifies how much ether should be sent. + // nonce can be any unique number to prevent replay attacks + // contractAddress is used to prevent cross-contract replay attacks + function signPayment(recipient, amount, nonce, contractAddress, callback) { + var hash = "0x" + ethereumjs.ABI.soliditySHA3( + ["address", "uint256", "uint256", "address"], + [recipient, amount, nonce, contractAddress] + ).toString("hex"); + + web3.personal.sign(hash, web3.eth.defaultAccount, callback); + } + +Recovering the Message Signer in Solidity +----------------------------------------- + +In general, ECDSA signatures consist of two parameters, ``r`` and ``s``. +Signatures in Ethereum include a third parameter called ``v``, that can be used +to recover which account's private key was used to sign in the message, +the transaction's sender. Solidity provides a built-in function +`ecrecover <mathematical-and-cryptographic-functions>`_ +that accepts a message along with the ``r``, ``s`` and ``v`` parameters and +returns the address that was used to sign the message. + +Extracting the Signature Parameters +----------------------------------- + +Signatures produced by web3.js are the concatenation of ``r``, ``s`` and ``v``, +so the first step is splitting those parameters back out. It can be done on the client, +but doing it inside the smart contract means only one signature parameter +needs to be sent rather than three. +Splitting apart a byte array into component parts is a little messy. +We will use `inline assembly <assembly>`_ to do the job +in the ``splitSignature`` function (the third function in the full contract +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 +``recoverSigner`` do this and their use can be found in the +``claimPayment`` function. + + +The full contract +----------------- + +:: + + pragma solidity ^0.4.24; + + contract ReceiverPays { + address owner = msg.sender; + + mapping(uint256 => bool) usedNonces; + + constructor() public payable {} + + function claimPayment(uint256 amount, uint256 nonce, bytes signature) public { + require(!usedNonces[nonce]); + usedNonces[nonce] = true; + + // this recreates the message that was signed on the client + bytes32 message = prefixed(keccak256(abi.encodePacked(msg.sender, amount, nonce, this))); + + require(recoverSigner(message, signature) == owner); + + msg.sender.transfer(amount); + } + + /// destroy the contract and reclaim the leftover funds. + function kill() public { + require(msg.sender == owner); + selfdestruct(msg.sender); + } + + /// signature methods. + function splitSignature(bytes sig) + internal + pure + returns (uint8 v, bytes32 r, bytes32 s) + { + require(sig.length == 65); + + assembly { + // first 32 bytes, after the length prefix. + r := mload(add(sig, 32)) + // second 32 bytes. + s := mload(add(sig, 64)) + // 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) + internal + pure + returns (address) + { + (uint8 v, bytes32 r, bytes32 s) = splitSignature(sig); + + return ecrecover(message, v, r, s); + } + + /// builds a prefixed hash to mimic the behavior of eth_sign. + function prefixed(bytes32 hash) internal pure returns (bytes32) { + return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", hash)); + } + } + + +Writing a Simple Payment Channel +================================ + +Alice will now build a simple but complete implementation of a payment channel. +Payment channels use cryptographic signatures to make repeated transfers +of Ether securely, instantaneously, and without transaction fees. + +What is a Payment Channel? +-------------------------- + +Payment channels allow participants to make repeated transfers of Ether without +using transactions. This means that the delays and fees associated with transactions +can be avoided. We are going to explore a simple unidirectional payment channel between +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. + +Bob is guaranteed to receive their funds because the smart contract escrows +the Ether and honors a valid signed message. The smart contract also enforces a timeout, +so Alice is guaranteed to eventually recover their funds even if the recipient refuses +to close the channel. +It is up to the participants in a payment channel to decide how long to keep it open. +For a short-lived transaction, such as paying an internet cafe for each minute of network access, +or for a longer relationship, such as paying an employee an hourly wage, a payment could last for months or years. + +Opening the Payment Channel +--------------------------- + +To open the payment channel, Alice deploys the smart contract, +attaching the Ether to be escrowed and specifying the intendend recipient +and a maximum duration for the channel to exist. It is the function +``SimplePaymentChannel`` in the contract, that is at the end of this chapter. + +Making Payments +--------------- + +Alice makes payments by sending signed messages to Bob. +This step is performed entirely outside of the Ethereum network. +Messages are cryptographically signed by the sender and then transmitted directly to the recipient. + +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 +amount of the individual micropayment. The recipient will naturally choose to +redeem the most recent message because that is the one with the highest total. +The nonce per-message is not needed anymore, because the smart contract will +only honor a single message. The address of the smart contract is still used +to prevent a message intended for one payment channel from being used for a different channel. + +Here is the modified javascript code to cryptographically sign a message from the previous chapter: + +:: + + function constructPaymentMessage(contractAddress, amount) { + return ethereumjs.ABI.soliditySHA3( + ["address", "uint256"], + [contractAddress, amount] + ); + } + + function signMessage(message, callback) { + web3.personal.sign( + "0x" + message.toString("hex"), + web3.eth.defaultAccount, + 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); + } + + +Closing the Payment Channel +--------------------------- + +When Bob is ready to receive their funds, it is time to +close the payment channel by calling a ``close`` function on the smart contract. +Closing the channel pays the recipient the Ether they are owed and destroys the contract, +sending any remaining Ether back to Alice. +To close the channel, Bob needs to provide a message signed by Alice. + +The smart contract must verify that the message contains a valid signature from the sender. +The process for doing this verification is the same as the process the recipient uses. +The Solidity functions ``isValidSignature`` and ``recoverSigner`` work just like their +JavaScript counterparts in the previous section. The latter is borrowed from the +``ReceiverPays`` contract in the previous chapter. + +The ``close`` function can only be called by the payment channel recipient, +who will naturally pass the most recent payment message because that message +carries the highest total owed. If the sender were allowed to call this function, +they could provide a message with a lower amount and cheat the recipient out of what they are owed. + +The function verifies the signed message matches the given parameters. +If everything checks out, the recipient is sent their portion of the Ether, +and the sender is sent the rest via a ``selfdestruct``. +You can see the ``close`` function in the full contract. + +Channel Expiration +------------------- + +Bob can close the payment channel at any time, but if they fail to do so, +Alice needs a way to recover their escrowed funds. An *expiration* time was set +at the time of contract deployment. Once that time is reached, Alice can call +``claimTimeout`` to recover their funds. You can see the ``claimTimeout`` function in the +full contract. + +After this function is called, Bob can no longer receive any Ether, +so it is important that Bob closes the channel before the expiration is reached. + + +The full contract +----------------- + +:: + + pragma solidity ^0.4.24; + + contract SimplePaymentChannel { + address public sender; // The account sending payments. + address public recipient; // The account receiving the payments. + uint256 public expiration; // Timeout in case the recipient never closes. + + constructor (address _recipient, uint256 duration) + public + payable + { + sender = msg.sender; + recipient = _recipient; + expiration = now + duration; + } + + function isValidSignature(uint256 amount, bytes signature) + internal + view + returns (bool) + { + bytes32 message = prefixed(keccak256(abi.encodePacked(this, amount))); + + // check that the signature is from the payment sender + return recoverSigner(message, signature) == sender; + } + + /// 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 { + require(msg.sender == recipient); + require(isValidSignature(amount, signature)); + + recipient.transfer(amount); + selfdestruct(sender); + } + + /// the sender can extend the expiration at any time + function extend(uint256 newExpiration) public { + require(msg.sender == sender); + require(newExpiration > expiration); + + expiration = newExpiration; + } + + /// if the timeout is reached without the recipient closing the channel, + /// then the Ether is released back to the sender. + function claimTimeout() public { + require(now >= expiration); + selfdestruct(sender); + } + + /// All functions below this are just taken from the chapter + /// 'creating and verifying signatures' chapter. + + function splitSignature(bytes sig) + internal + pure + returns (uint8 v, bytes32 r, bytes32 s) + { + require(sig.length == 65); + + assembly { + // first 32 bytes, after the length prefix + r := mload(add(sig, 32)) + // second 32 bytes + s := mload(add(sig, 64)) + // 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) + internal + pure + returns (address) + { + (uint8 v, bytes32 r, bytes32 s) = splitSignature(sig); + + return ecrecover(message, v, r, s); + } + + /// builds a prefixed hash to mimic the behavior of eth_sign. + function prefixed(bytes32 hash) internal pure returns (bytes32) { + return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", hash)); + } + } + + +Note: The function ``splitSignature`` is very simple and does not use all security checks. +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 +------------------ + +Unlike in our previous chapter, messages in a payment channel aren't +redeemed right away. The recipient keeps track of the latest message and +redeems it when it's time to close the payment channel. This means it's +critical that the recipient perform their own verification of each message. +Otherwise there is no guarantee that the recipient will be able to get paid +in the end. + +The recipient should verify each message using the following process: + + 1. Verify that the contact address in the message matches the payment channel. + 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**. +The following code borrows the `constructMessage` function from the signing **JavaScript code** +above: + +:: + + // this mimics the prefixing behavior of the eth_sign JSON-RPC method. + function prefixed(hash) { + return ethereumjs.ABI.soliditySHA3( + ["string", "bytes32"], + ["\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); + return signer.toLowerCase() == + ethereumjs.Util.stripHexPrefix(expectedSigner).toLowerCase(); + } diff --git a/docs/style-guide.rst b/docs/style-guide.rst index 8311e925..19e3aae5 100644 --- a/docs/style-guide.rst +++ b/docs/style-guide.rst @@ -188,8 +188,8 @@ Event Definitions and Event Emitters Yes:: event LongAndLotsOfArgs( - adress sender, - adress recipient, + address sender, + address recipient, uint256 publicKey, uint256 amount, bytes32[] options @@ -205,8 +205,8 @@ Yes:: No:: - event LongAndLotsOfArgs(adress sender, - adress recipient, + event LongAndLotsOfArgs(address sender, + address recipient, uint256 publicKey, uint256 amount, bytes32[] options); @@ -830,7 +830,7 @@ The naming recommendations given here are intended to improve the readability, and thus they are not rules, but rather guidelines to try and help convey the most information through the names of things. -Lastly, consistency within a codebase should always supercede any conventions +Lastly, consistency within a codebase should always supersede any conventions outlined in this document. diff --git a/docs/types.rst b/docs/types.rst index 217a2273..c81dee33 100644 --- a/docs/types.rst +++ b/docs/types.rst @@ -386,10 +386,6 @@ By default, function types are internal, so the ``internal`` keyword can be omitted. In contrast, contract functions themselves are public by default, only when used as the name of a type, the default is internal. -There are two ways to access a function in the current contract: Either directly -by its name, ``f``, or using ``this.f``. The former will result in an internal -function, the latter in an external function. - If a function type variable is not initialized, calling it will result in an exception. The same happens if you call a function after using ``delete`` on it. @@ -475,11 +471,11 @@ Another example that uses external function types:: } Request[] requests; event NewRequest(uint); - function query(bytes data, function(bytes memory) external callback) public { + function query(bytes memory data, function(bytes memory) external callback) public { requests.push(Request(data, callback)); emit NewRequest(requests.length - 1); } - function reply(uint requestID, bytes response) public { + function reply(uint requestID, bytes memory response) public { // Here goes the check that the reply comes from a trusted source requests[requestID].callback(response); } @@ -487,10 +483,10 @@ Another example that uses external function types:: contract OracleUser { Oracle constant oracle = Oracle(0x1234567); // known contract - function buySomething() { + function buySomething() public { oracle.query("USD", this.oracleResponse); } - function oracleResponse(bytes response) public { + function oracleResponse(bytes memory response) public { require( msg.sender == address(oracle), "Only oracle can call this." @@ -544,7 +540,7 @@ memory-stored reference type do not create a copy. uint[] x; // the data location of x is storage // the data location of memoryArray is memory - function f(uint[] memoryArray) public { + function f(uint[] memory memoryArray) public { x = memoryArray; // works, copies the whole array to storage uint[] storage y = x; // works, assigns a pointer, data location of y is storage y[7]; // fine, returns the 8th element @@ -561,7 +557,7 @@ memory-stored reference type do not create a copy. } function g(uint[] storage storageArray) internal {} - function h(uint[] memoryArray) public {} + function h(uint[] memory memoryArray) public {} } Summary @@ -650,7 +646,7 @@ assigned to a variable right away. function f() public pure { g([uint(1), 2, 3]); } - function g(uint[3] _data) public pure { + function g(uint[3] memory _data) public pure { // ... } } @@ -717,7 +713,7 @@ Members bool[2][] m_pairsOfFlags; // newPairs is stored in memory - the default for function arguments - function setAllFlagPairs(bool[2][] newPairs) public { + function setAllFlagPairs(bool[2][] memory newPairs) public { // assignment to a storage array replaces the complete array m_pairsOfFlags = newPairs; } @@ -743,7 +739,7 @@ Members bytes m_byteData; - function byteArrays(bytes data) public { + function byteArrays(bytes memory data) public { // byte arrays ("bytes") are different as they are stored without padding, // but can be treated identical to "uint8[]" m_byteData = data; @@ -752,11 +748,11 @@ Members delete m_byteData[2]; } - function addFlag(bool[2] flag) public returns (uint) { + function addFlag(bool[2] memory flag) public returns (uint) { return m_pairsOfFlags.push(flag); } - function createMemoryArray(uint size) public pure returns (bytes) { + function createMemoryArray(uint size) public pure returns (bytes memory) { // Dynamic memory arrays are created using `new`: uint[2][] memory arrayOfPairs = new uint[2][](size); // Create a dynamic byte array: @@ -850,7 +846,7 @@ Mappings ======== Mapping types are declared as ``mapping(_KeyType => _ValueType)``. -Here ``_KeyType`` can be almost any type except for a mapping, a dynamically sized array, a contract, an enum and a struct. +Here ``_KeyType`` can be almost any type except for a mapping, a dynamically sized array, a contract, a function, an enum and a struct. ``_ValueType`` can actually be any type, including mappings. Mappings can be seen as `hash tables <https://en.wikipedia.org/wiki/Hash_table>`_ which are virtually initialized such that @@ -983,4 +979,3 @@ converted to a matching size. This makes alignment and padding explicit:: uint16 x = 0xffff; bytes32(uint256(x)); // pad on the left bytes32(bytes2(x)); // pad on the right - diff --git a/docs/units-and-global-variables.rst b/docs/units-and-global-variables.rst index 455231cd..6eae2804 100644 --- a/docs/units-and-global-variables.rst +++ b/docs/units-and-global-variables.rst @@ -100,9 +100,8 @@ ABI Encoding Functions ---------------------- - ``abi.encode(...) returns (bytes)``: ABI-encodes the given arguments -- ``abi.encodePacked(...) returns (bytes)``: Performes :ref:`packed encoding <abi_packed_mode>` of the given arguments -- ``abi.encodeWithSelector(bytes4 selector, ...) returns (bytes)``: ABI-encodes the given arguments - starting from the second and prepends the given four-byte selector +- ``abi.encodePacked(...) returns (bytes)``: Performs :ref:`packed encoding <abi_packed_mode>` of the given arguments +- ``abi.encodeWithSelector(bytes4 selector, ...) returns (bytes)``: ABI-encodes the given arguments starting from the second and prepends the given four-byte selector - ``abi.encodeWithSignature(string signature, ...) returns (bytes)``: Equivalent to ``abi.encodeWithSelector(bytes4(keccak256(bytes(signature)), ...)``` .. note:: @@ -181,6 +180,10 @@ For more information, see the section on :ref:`address`. Use a pattern where the recipient withdraws the money. .. note:: + Prior to version 0.5.0, Solidity allowed address members to be accessed by a contract instance, for example ``this.balance``. + This is now forbidden and an explicit conversion to address must be done: ``address(this).balance``. + +.. note:: If storage variables are accessed via a low-level delegatecall, the storage layout of the two contracts must align in order for the called contract to correctly access the storage variables of the calling contract by name. This is of course not the case if storage pointers are passed as function arguments as in the case for diff --git a/docs/yul.rst b/docs/yul.rst index 4f5ef98f..87ec0c03 100644 --- a/docs/yul.rst +++ b/docs/yul.rst @@ -338,7 +338,7 @@ The following functions must be available: +---------------------------------------------+-----------------------------------------------------------------+ | xor(x:bool, y:bool) -> z:bool | xor | +---------------------------------------------+-----------------------------------------------------------------+ -| *Arithmetics* | +| *Arithmetic* | +---------------------------------------------+-----------------------------------------------------------------+ | addu256(x:u256, y:u256) -> z:u256 | x + y | +---------------------------------------------+-----------------------------------------------------------------+ @@ -358,9 +358,9 @@ The following functions must be available: +---------------------------------------------+-----------------------------------------------------------------+ | expu256(x:u256, y:u256) -> z:u256 | x to the power of y | +---------------------------------------------+-----------------------------------------------------------------+ -| addmodu256(x:u256, y:u256, m:u256) -> z:u256| (x + y) % m with arbitrary precision arithmetics | +| addmodu256(x:u256, y:u256, m:u256) -> z:u256| (x + y) % m with arbitrary precision arithmetic | +---------------------------------------------+-----------------------------------------------------------------+ -| mulmodu256(x:u256, y:u256, m:u256) -> z:u256| (x * y) % m with arbitrary precision arithmetics | +| mulmodu256(x:u256, y:u256, m:u256) -> z:u256| (x * y) % m with arbitrary precision arithmetic | +---------------------------------------------+-----------------------------------------------------------------+ | ltu256(x:u256, y:u256) -> z:bool | true if x < y, false otherwise | +---------------------------------------------+-----------------------------------------------------------------+ diff --git a/libevmasm/ControlFlowGraph.h b/libevmasm/ControlFlowGraph.h index ebef543f..f0c9356c 100644 --- a/libevmasm/ControlFlowGraph.h +++ b/libevmasm/ControlFlowGraph.h @@ -39,7 +39,7 @@ using KnownStatePointer = std::shared_ptr<KnownState>; /** * Identifier for a block, coincides with the tag number of an AssemblyItem but adds a special - * ID for the inital block. + * ID for the initial block. */ class BlockId { diff --git a/libevmasm/GasMeter.h b/libevmasm/GasMeter.h index b131802f..fc3740d2 100644 --- a/libevmasm/GasMeter.h +++ b/libevmasm/GasMeter.h @@ -112,9 +112,10 @@ public: static GasConsumption infinite() { return GasConsumption(0, true); } GasConsumption& operator+=(GasConsumption const& _other); - bool operator<(GasConsumption const& _other) const { return this->tuple() < _other.tuple(); } - - std::tuple<bool const&, u256 const&> tuple() const { return std::tie(isInfinite, value); } + bool operator<(GasConsumption const& _other) const + { + return std::make_pair(isInfinite, value) < std::make_pair(_other.isInfinite, _other.value); + } u256 value; bool isInfinite; diff --git a/libevmasm/LinkerObject.cpp b/libevmasm/LinkerObject.cpp index 8b7d9e06..1d5efecb 100644 --- a/libevmasm/LinkerObject.cpp +++ b/libevmasm/LinkerObject.cpp @@ -68,7 +68,7 @@ LinkerObject::matchLibrary( if (it != _libraryAddresses.end()) return &it->second; // If the user did not supply a fully qualified library name, - // try to match only the simple libary name + // try to match only the simple library name size_t colon = _linkRefName.find(':'); if (colon == string::npos) return nullptr; diff --git a/libevmasm/RuleList.h b/libevmasm/RuleList.h index 2b7da01b..7a2bc484 100644 --- a/libevmasm/RuleList.h +++ b/libevmasm/RuleList.h @@ -59,7 +59,7 @@ std::vector<SimplificationRule<Pattern>> simplificationRuleList( { std::vector<SimplificationRule<Pattern>> rules; rules += std::vector<SimplificationRule<Pattern>>{ - // arithmetics on constants + // arithmetic on constants {{Instruction::ADD, {A, B}}, [=]{ return A.d() + B.d(); }, false}, {{Instruction::MUL, {A, B}}, [=]{ return A.d() * B.d(); }, false}, {{Instruction::SUB, {A, B}}, [=]{ return A.d() - B.d(); }, false}, diff --git a/libevmasm/SimplificationRules.cpp b/libevmasm/SimplificationRules.cpp index 53a5f9fc..504dbc24 100644 --- a/libevmasm/SimplificationRules.cpp +++ b/libevmasm/SimplificationRules.cpp @@ -67,7 +67,7 @@ void Rules::addRule(SimplificationRule<Pattern> const& _rule) Rules::Rules() { - // Multiple occurences of one of these inside one rule must match the same equivalence class. + // Multiple occurrences of one of these inside one rule must match the same equivalence class. // Constants. Pattern A(Push); Pattern B(Push); diff --git a/libjulia/backends/evm/AbstractAssembly.h b/libjulia/backends/evm/AbstractAssembly.h index 46fa7796..6b1b5c23 100644 --- a/libjulia/backends/evm/AbstractAssembly.h +++ b/libjulia/backends/evm/AbstractAssembly.h @@ -68,7 +68,7 @@ public: virtual LabelID newLabelId() = 0; /// Returns a label identified by the given name. Creates it if it does not yet exist. virtual LabelID namedLabel(std::string const& _name) = 0; - /// Append a reference to a to-be-linked symobl. + /// Append a reference to a to-be-linked symbol. /// Currently, we assume that the value is always a 20 byte number. virtual void appendLinkerSymbol(std::string const& _name) = 0; diff --git a/libjulia/backends/evm/EVMAssembly.h b/libjulia/backends/evm/EVMAssembly.h index 593cee6a..56ae7655 100644 --- a/libjulia/backends/evm/EVMAssembly.h +++ b/libjulia/backends/evm/EVMAssembly.h @@ -54,7 +54,7 @@ public: virtual LabelID newLabelId() override; /// Returns a label identified by the given name. Creates it if it does not yet exist. virtual LabelID namedLabel(std::string const& _name) override; - /// Append a reference to a to-be-linked symobl. + /// Append a reference to a to-be-linked symbol. /// Currently, we assume that the value is always a 20 byte number. virtual void appendLinkerSymbol(std::string const& _name) override; diff --git a/libjulia/optimiser/DataFlowAnalyzer.h b/libjulia/optimiser/DataFlowAnalyzer.h index 4cb3d4cd..66df2f48 100644 --- a/libjulia/optimiser/DataFlowAnalyzer.h +++ b/libjulia/optimiser/DataFlowAnalyzer.h @@ -56,7 +56,7 @@ protected: /// Registers the assignment. void handleAssignment(std::set<std::string> const& _names, Expression* _value); - /// Clears information about the valuse assigned to the given variables, + /// Clears information about the values assigned to the given variables, /// for example at points where control flow is merged. void clearValues(std::set<std::string> const& _names); diff --git a/libjulia/optimiser/README.md b/libjulia/optimiser/README.md index b1ce8931..b26da0c7 100644 --- a/libjulia/optimiser/README.md +++ b/libjulia/optimiser/README.md @@ -1,3 +1,7 @@ +Note that the Yul optimiser is still in research phase. Because of that, +the following description might not fully reflect the current or even +planned state of the optimiser. + ## Yul Optimiser The Yul optimiser consists of several stages and components that all transform diff --git a/libjulia/optimiser/SimplificationRules.cpp b/libjulia/optimiser/SimplificationRules.cpp index 070d5484..a5e296c3 100644 --- a/libjulia/optimiser/SimplificationRules.cpp +++ b/libjulia/optimiser/SimplificationRules.cpp @@ -64,7 +64,7 @@ void SimplificationRules::addRule(SimplificationRule<Pattern> const& _rule) SimplificationRules::SimplificationRules() { - // Multiple occurences of one of these inside one rule must match the same equivalence class. + // Multiple occurrences of one of these inside one rule must match the same equivalence class. // Constants. Pattern A(PatternKind::Constant); Pattern B(PatternKind::Constant); diff --git a/libsolc/CMakeLists.txt b/libsolc/CMakeLists.txt index e67583dd..63fc1a83 100644 --- a/libsolc/CMakeLists.txt +++ b/libsolc/CMakeLists.txt @@ -1,5 +1,5 @@ if (EMSCRIPTEN) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -s EXPORTED_FUNCTIONS='[\"_compileJSON\",\"_license\",\"_version\",\"_compileJSONMulti\",\"_compileJSONCallback\",\"_compileStandard\"]' -s RESERVED_FUNCTION_POINTERS=20") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -s EXPORTED_FUNCTIONS='[\"_solidity_license\",\"_solidity_version\",\"_solidity_compile\",\"_license\",\"_version\",\"_compileJSON\",\"_compileJSONMulti\",\"_compileJSONCallback\",\"_compileStandard\"]' -s RESERVED_FUNCTION_POINTERS=20") add_executable(soljson libsolc.cpp) target_link_libraries(soljson PRIVATE solidity) else() diff --git a/libsolc/libsolc.cpp b/libsolc/libsolc.cpp index 6c587e23..26ce98ce 100644 --- a/libsolc/libsolc.cpp +++ b/libsolc/libsolc.cpp @@ -299,4 +299,19 @@ extern char const* compileStandard(char const* _input, CStyleReadFileCallback _r s_outputBuffer = compileStandardInternal(_input, _readCallback); return s_outputBuffer.c_str(); } +extern char const* solidity_license() +{ + /// todo: make this the default or an alias + return license(); +} +extern char const* solidity_version() +{ + /// todo: make this the default or an alias + return version(); +} +extern char const* solidity_compile(char const* _input, CStyleReadFileCallback _readCallback) +{ + /// todo: make this the default or an alias + return compileStandard(_input, _readCallback); +} } diff --git a/libsolc/libsolc.h b/libsolc/libsolc.h index c392ce93..2cc004d4 100644 --- a/libsolc/libsolc.h +++ b/libsolc/libsolc.h @@ -37,6 +37,10 @@ char const* compileJSONMulti(char const* _input, bool _optimize); char const* compileJSONCallback(char const* _input, bool _optimize, CStyleReadFileCallback _readCallback); char const* compileStandard(char const* _input, CStyleReadFileCallback _readCallback); +char const* solidity_license(); +char const* solidity_version(); +char const* solidity_compile(char const* _input, CStyleReadFileCallback _readCallback); + #ifdef __cplusplus } #endif diff --git a/libsolidity/analysis/DeclarationContainer.cpp b/libsolidity/analysis/DeclarationContainer.cpp index 786272e4..9e2bf6d3 100644 --- a/libsolidity/analysis/DeclarationContainer.cpp +++ b/libsolidity/analysis/DeclarationContainer.cpp @@ -96,6 +96,11 @@ void DeclarationContainer::activateVariable(ASTString const& _name) m_invisibleDeclarations.erase(_name); } +bool DeclarationContainer::isInvisible(ASTString const& _name) const +{ + return m_invisibleDeclarations.count(_name); +} + bool DeclarationContainer::registerDeclaration( Declaration const& _declaration, ASTString const* _name, diff --git a/libsolidity/analysis/DeclarationContainer.h b/libsolidity/analysis/DeclarationContainer.h index a3e0bd0a..9d7a17a3 100644 --- a/libsolidity/analysis/DeclarationContainer.h +++ b/libsolidity/analysis/DeclarationContainer.h @@ -62,6 +62,9 @@ public: /// VariableDeclarationStatements. void activateVariable(ASTString const& _name); + /// @returns true if declaration is currently invisible. + bool isInvisible(ASTString const& _name) const; + /// @returns existing declaration names similar to @a _name. /// Searches this and all parent containers. std::vector<ASTString> similarNames(ASTString const& _name) const; diff --git a/libsolidity/analysis/NameAndTypeResolver.cpp b/libsolidity/analysis/NameAndTypeResolver.cpp index b856544a..823378c7 100644 --- a/libsolidity/analysis/NameAndTypeResolver.cpp +++ b/libsolidity/analysis/NameAndTypeResolver.cpp @@ -156,7 +156,13 @@ bool NameAndTypeResolver::updateDeclaration(Declaration const& _declaration) void NameAndTypeResolver::activateVariable(string const& _name) { solAssert(m_currentScope, ""); - m_currentScope->activateVariable(_name); + // Scoped local variables are invisible before activation. + // When a local variable is activated, its name is removed + // from a scope's invisible variables. + // This is used to avoid activation of variables of same name + // in the same scope (an error is returned). + if (m_currentScope->isInvisible(_name)) + m_currentScope->activateVariable(_name); } vector<Declaration const*> NameAndTypeResolver::resolveName(ASTString const& _name, ASTNode const* _scope) const @@ -704,10 +710,6 @@ void DeclarationRegistrationHelper::registerDeclaration(Declaration& _declaratio dynamic_cast<EventDefinition const*>(m_currentScope) ) warnAboutShadowing = false; - // Do not warn about the constructor shadowing the contract. - if (auto fun = dynamic_cast<FunctionDefinition const*>(&_declaration)) - if (fun->isConstructor()) - warnAboutShadowing = false; // Register declaration as inactive if we are in block scope. bool inactive = diff --git a/libsolidity/analysis/ReferencesResolver.cpp b/libsolidity/analysis/ReferencesResolver.cpp index 58b659f7..dfcbf888 100644 --- a/libsolidity/analysis/ReferencesResolver.cpp +++ b/libsolidity/analysis/ReferencesResolver.cpp @@ -377,19 +377,10 @@ void ReferencesResolver::endVisit(VariableDeclaration const& _variable) { typeLoc = DataLocation::Storage; if (_variable.isLocalVariable()) - { - if (_variable.sourceUnit().annotation().experimentalFeatures.count(ExperimentalFeature::V050)) - typeError( - _variable.location(), - "Data location must be specified as either \"memory\" or \"storage\"." - ); - else - m_errorReporter.warning( - _variable.location(), - "Variable is declared as a storage pointer. " - "Use an explicit \"storage\" keyword to silence this warning." - ); - } + typeError( + _variable.location(), + "Data location must be specified as either \"memory\" or \"storage\"." + ); } } else diff --git a/libsolidity/analysis/StaticAnalyzer.cpp b/libsolidity/analysis/StaticAnalyzer.cpp index 323282ca..60a58665 100644 --- a/libsolidity/analysis/StaticAnalyzer.cpp +++ b/libsolidity/analysis/StaticAnalyzer.cpp @@ -51,16 +51,6 @@ void StaticAnalyzer::endVisit(ContractDefinition const&) bool StaticAnalyzer::visit(FunctionDefinition const& _function) { - const bool isInterface = m_currentContract->contractKind() == ContractDefinition::ContractKind::Interface; - - if (_function.noVisibilitySpecified()) - m_errorReporter.warning( - _function.location(), - "No visibility specified. Defaulting to \"" + - Declaration::visibilityToString(_function.visibility()) + - "\"." + - (isInterface ? " In interfaces it defaults to external." : "") - ); if (_function.isImplemented()) m_currentFunction = &_function; else diff --git a/libsolidity/analysis/SyntaxChecker.cpp b/libsolidity/analysis/SyntaxChecker.cpp index cd0dc2a4..5d16a33f 100644 --- a/libsolidity/analysis/SyntaxChecker.cpp +++ b/libsolidity/analysis/SyntaxChecker.cpp @@ -22,6 +22,7 @@ #include <libsolidity/analysis/SemVerHandler.h> #include <libsolidity/interface/ErrorReporter.h> #include <libsolidity/interface/Version.h> +#include <boost/algorithm/cxx11/all_of.hpp> using namespace std; using namespace dev; @@ -174,33 +175,19 @@ bool SyntaxChecker::visit(Break const& _breakStatement) bool SyntaxChecker::visit(Throw const& _throwStatement) { - bool const v050 = m_sourceUnit->annotation().experimentalFeatures.count(ExperimentalFeature::V050); - - if (v050) - m_errorReporter.syntaxError( - _throwStatement.location(), - "\"throw\" is deprecated in favour of \"revert()\", \"require()\" and \"assert()\"." - ); - else - m_errorReporter.warning( - _throwStatement.location(), - "\"throw\" is deprecated in favour of \"revert()\", \"require()\" and \"assert()\"." - ); + m_errorReporter.syntaxError( + _throwStatement.location(), + "\"throw\" is deprecated in favour of \"revert()\", \"require()\" and \"assert()\"." + ); return true; } bool SyntaxChecker::visit(UnaryOperation const& _operation) { - bool const v050 = m_sourceUnit->annotation().experimentalFeatures.count(ExperimentalFeature::V050); - if (_operation.getOperator() == Token::Add) - { - if (v050) - m_errorReporter.syntaxError(_operation.location(), "Use of unary + is deprecated."); - else - m_errorReporter.warning(_operation.location(), "Use of unary + is deprecated."); - } + m_errorReporter.syntaxError(_operation.location(), "Use of unary + is disallowed."); + return true; } @@ -210,28 +197,33 @@ bool SyntaxChecker::visit(PlaceholderStatement const&) return true; } -bool SyntaxChecker::visit(FunctionDefinition const& _function) +bool SyntaxChecker::visit(ContractDefinition const& _contract) { - bool const v050 = m_sourceUnit->annotation().experimentalFeatures.count(ExperimentalFeature::V050); + m_isInterface = _contract.contractKind() == ContractDefinition::ContractKind::Interface; - if (v050 && _function.noVisibilitySpecified()) - m_errorReporter.syntaxError(_function.location(), "No visibility specified."); - - if (_function.isOldStyleConstructor()) - { - if (v050) - m_errorReporter.syntaxError( - _function.location(), + ASTString const& contractName = _contract.name(); + for (FunctionDefinition const* function: _contract.definedFunctions()) + if (function->name() == contractName) + m_errorReporter.syntaxError(function->location(), "Functions are not allowed to have the same name as the contract. " "If you intend this to be a constructor, use \"constructor(...) { ... }\" to define it." ); - else - m_errorReporter.warning( - _function.location(), - "Defining constructors as functions with the same name as the contract is deprecated. " - "Use \"constructor(...) { ... }\" instead." - ); + return true; +} + +bool SyntaxChecker::visit(FunctionDefinition const& _function) +{ + bool const v050 = m_sourceUnit->annotation().experimentalFeatures.count(ExperimentalFeature::V050); + + if (_function.noVisibilitySpecified()) + { + string suggestedVisibility = _function.isFallback() || m_isInterface ? "external" : "public"; + m_errorReporter.syntaxError( + _function.location(), + "No visibility specified. Did you intend to add \"" + suggestedVisibility + "\"?" + ); } + if (!_function.isImplemented() && !_function.modifiers().empty()) { if (v050) @@ -239,11 +231,6 @@ bool SyntaxChecker::visit(FunctionDefinition const& _function) else m_errorReporter.warning(_function.location(), "Modifiers of functions without implementation are ignored." ); } - if (_function.name() == "constructor") - m_errorReporter.warning(_function.location(), - "This function is named \"constructor\" but is not the constructor of the contract. " - "If you intend this to be a constructor, use \"constructor(...) { ... }\" without the \"function\" keyword to define it." - ); return true; } @@ -260,12 +247,15 @@ bool SyntaxChecker::visit(FunctionTypeName const& _node) return true; } -bool SyntaxChecker::visit(VariableDeclaration const& _declaration) +bool SyntaxChecker::visit(VariableDeclarationStatement const& _statement) { - if (!_declaration.typeName()) - { - m_errorReporter.syntaxError(_declaration.location(), "Use of the \"var\" keyword is disallowed."); - } + // Report if none of the variable components in the tuple have a name (only possible via deprecated "var") + if (boost::algorithm::all_of_equal(_statement.declarations(), nullptr)) + m_errorReporter.syntaxError( + _statement.location(), + "The use of the \"var\" keyword is disallowed. The declaration part of the statement can be removed, since it is empty." + ); + return true; } diff --git a/libsolidity/analysis/SyntaxChecker.h b/libsolidity/analysis/SyntaxChecker.h index 1579df57..28a0f66e 100644 --- a/libsolidity/analysis/SyntaxChecker.h +++ b/libsolidity/analysis/SyntaxChecker.h @@ -66,10 +66,11 @@ private: virtual bool visit(PlaceholderStatement const& _placeholderStatement) override; + virtual bool visit(ContractDefinition const& _contract) override; virtual bool visit(FunctionDefinition const& _function) override; virtual bool visit(FunctionTypeName const& _node) override; - virtual bool visit(VariableDeclaration const& _declaration) override; + virtual bool visit(VariableDeclarationStatement const& _statement) override; virtual bool visit(StructDefinition const& _struct) override; @@ -82,6 +83,7 @@ private: bool m_versionPragmaFound = false; int m_inLoopDepth = 0; + bool m_isInterface = false; SourceUnit const* m_sourceUnit = nullptr; }; diff --git a/libsolidity/analysis/TypeChecker.cpp b/libsolidity/analysis/TypeChecker.cpp index 676b3cd6..8536e934 100644 --- a/libsolidity/analysis/TypeChecker.cpp +++ b/libsolidity/analysis/TypeChecker.cpp @@ -23,12 +23,14 @@ #include <libsolidity/analysis/TypeChecker.h> #include <memory> #include <boost/algorithm/string/predicate.hpp> +#include <boost/algorithm/string/join.hpp> #include <boost/range/adaptor/reversed.hpp> #include <libsolidity/ast/AST.h> #include <libsolidity/inlineasm/AsmAnalysis.h> #include <libsolidity/inlineasm/AsmAnalysisInfo.h> #include <libsolidity/inlineasm/AsmData.h> #include <libsolidity/interface/ErrorReporter.h> +#include <libdevcore/Algorithms.h> using namespace std; using namespace dev; @@ -123,10 +125,7 @@ bool TypeChecker::visit(ContractDefinition const& _contract) m_errorReporter.typeError(function->parameterList().location(), "Fallback function cannot take parameters."); if (!function->returnParameters().empty()) m_errorReporter.typeError(function->returnParameterList()->location(), "Fallback function cannot return values."); - if ( - _contract.sourceUnit().annotation().experimentalFeatures.count(ExperimentalFeature::V050) && - function->visibility() != FunctionDefinition::Visibility::External - ) + if (function->visibility() != FunctionDefinition::Visibility::External) m_errorReporter.typeError(function->location(), "Fallback function must be defined as \"external\"."); } @@ -451,7 +450,7 @@ void TypeChecker::overrideError(FunctionDefinition const& function, FunctionDefi { m_errorReporter.typeError( function.location(), - SecondarySourceLocation().append("Overriden function is here:", super.location()), + SecondarySourceLocation().append("Overridden function is here:", super.location()), message ); } @@ -551,33 +550,18 @@ void TypeChecker::endVisit(InheritanceSpecifier const& _inheritance) if (arguments) { - bool v050 = m_scope->sourceUnit().annotation().experimentalFeatures.count(ExperimentalFeature::V050); - if (parameterTypes.size() != arguments->size()) { - if (arguments->size() == 0 && !v050) - m_errorReporter.warning( - _inheritance.location(), - "Wrong argument count for constructor call: " + - toString(arguments->size()) + - " arguments given but expected " + - toString(parameterTypes.size()) + - "." - ); - else - { - m_errorReporter.typeError( - _inheritance.location(), - "Wrong argument count for constructor call: " + - toString(arguments->size()) + - " arguments given but expected " + - toString(parameterTypes.size()) + - "." - ); - return; - } + m_errorReporter.typeError( + _inheritance.location(), + "Wrong argument count for constructor call: " + + toString(arguments->size()) + + " arguments given but expected " + + toString(parameterTypes.size()) + + ". Remove parentheses if you do not want to provide arguments here." + ); } - for (size_t i = 0; i < arguments->size(); ++i) + for (size_t i = 0; i < std::min(arguments->size(), parameterTypes.size()); ++i) if (!type(*(*arguments)[i])->isImplicitlyConvertibleTo(*parameterTypes[i])) m_errorReporter.typeError( (*arguments)[i]->location(), @@ -610,22 +594,24 @@ bool TypeChecker::visit(StructDefinition const& _struct) m_errorReporter.typeError(member->location(), "Type cannot be used in struct."); // Check recursion, fatal error if detected. - using StructPointer = StructDefinition const*; - using StructPointersSet = set<StructPointer>; - function<void(StructPointer,StructPointersSet const&)> check = [&](StructPointer _struct, StructPointersSet const& _parents) - { - if (_parents.count(_struct)) - m_errorReporter.fatalTypeError(_struct->location(), "Recursive struct definition."); - StructPointersSet parents = _parents; - parents.insert(_struct); - for (ASTPointer<VariableDeclaration> const& member: _struct->members()) - if (type(*member)->category() == Type::Category::Struct) + auto visitor = [&](StructDefinition const& _struct, CycleDetector<StructDefinition>& _cycleDetector) + { + for (ASTPointer<VariableDeclaration> const& member: _struct.members()) + { + Type const* memberType = type(*member).get(); + while (auto arrayType = dynamic_cast<ArrayType const*>(memberType)) { - auto const& typeName = dynamic_cast<UserDefinedTypeName const&>(*member->typeName()); - check(&dynamic_cast<StructDefinition const&>(*typeName.annotation().referencedDeclaration), parents); + if (arrayType->isDynamicallySized()) + break; + memberType = arrayType->baseType().get(); } + if (auto structType = dynamic_cast<StructType const*>(memberType)) + if (_cycleDetector.run(structType->structDefinition())) + return; + } }; - check(&_struct, StructPointersSet{}); + if (CycleDetector<StructDefinition>(visitor).run(_struct) != nullptr) + m_errorReporter.fatalTypeError(_struct.location(), "Recursive struct definition."); ASTNode::listAccept(_struct.members(), *this); @@ -685,18 +671,10 @@ bool TypeChecker::visit(FunctionDefinition const& _function) { if (_function.isImplemented()) m_errorReporter.typeError(_function.location(), "Functions in interfaces cannot have an implementation."); - if (_function.sourceUnit().annotation().experimentalFeatures.count(ExperimentalFeature::V050)) - { - if (_function.visibility() != FunctionDefinition::Visibility::External) - m_errorReporter.typeError(_function.location(), "Functions in interfaces must be declared external."); - } - else - { - if (_function.visibility() < FunctionDefinition::Visibility::Public) - m_errorReporter.typeError(_function.location(), "Functions in interfaces cannot be internal or private."); - else if (_function.visibility() != FunctionDefinition::Visibility::External) - m_errorReporter.warning(_function.location(), "Functions in interfaces should be declared external."); - } + + if (_function.visibility() != FunctionDefinition::Visibility::External) + m_errorReporter.typeError(_function.location(), "Functions in interfaces must be declared external."); + if (_function.isConstructor()) m_errorReporter.typeError(_function.location(), "Constructor cannot be defined in interfaces."); } @@ -1054,9 +1032,49 @@ void TypeChecker::endVisit(EmitStatement const& _emit) m_insideEmitStatement = false; } +namespace +{ +/** + * @returns a suggested left-hand-side of a multi-variable declaration contairing + * the variable declarations given in @a _decls. + */ +string createTupleDecl(vector<ASTPointer<VariableDeclaration>> const& _decls) +{ + vector<string> components; + for (ASTPointer<VariableDeclaration> const& decl: _decls) + if (decl) + components.emplace_back(decl->annotation().type->toString(false) + " " + decl->name()); + else + components.emplace_back(); + + if (_decls.size() == 1) + return components.front(); + else + return "(" + boost::algorithm::join(components, ", ") + ")"; +} + +bool typeCanBeExpressed(vector<ASTPointer<VariableDeclaration>> const& decls) +{ + for (ASTPointer<VariableDeclaration> const& decl: decls) + { + // skip empty tuples (they can be expressed of course) + if (!decl) + continue; + + if (auto functionType = dynamic_cast<FunctionType const*>(decl->annotation().type.get())) + if ( + functionType->kind() != FunctionType::Kind::Internal && + functionType->kind() != FunctionType::Kind::External + ) + return false; + } + + return true; +} +} + bool TypeChecker::visit(VariableDeclarationStatement const& _statement) { - bool const v050 = m_scope->sourceUnit().annotation().experimentalFeatures.count(ExperimentalFeature::V050); if (!_statement.initialValue()) { // No initial value is only permitted for single variables with specified type. @@ -1073,10 +1091,7 @@ bool TypeChecker::visit(VariableDeclarationStatement const& _statement) if (varDecl.referenceLocation() == VariableDeclaration::Location::Default) errorText += " Did you mean '<type> memory " + varDecl.name() + "'?"; solAssert(m_scope, ""); - if (v050) - m_errorReporter.declarationError(varDecl.location(), errorText); - else - m_errorReporter.warning(varDecl.location(), errorText); + m_errorReporter.declarationError(varDecl.location(), errorText); } } else if (dynamic_cast<MappingType const*>(type(varDecl).get())) @@ -1098,85 +1113,34 @@ bool TypeChecker::visit(VariableDeclarationStatement const& _statement) else valueTypes = TypePointers{type(*_statement.initialValue())}; - // Determine which component is assigned to which variable. - // If numbers do not match, fill up if variables begin or end empty (not both). - vector<VariableDeclaration const*>& assignments = _statement.annotation().assignments; - assignments.resize(valueTypes.size(), nullptr); vector<ASTPointer<VariableDeclaration>> const& variables = _statement.declarations(); if (variables.empty()) - { - if (!valueTypes.empty()) - m_errorReporter.fatalTypeError( - _statement.location(), - "Too many components (" + - toString(valueTypes.size()) + - ") in value for variable assignment (0) needed" - ); - } + // We already have an error for this in the SyntaxChecker. + solAssert(m_errorReporter.hasErrors(), ""); else if (valueTypes.size() != variables.size()) - { - if (v050) - m_errorReporter.fatalTypeError( - _statement.location(), - "Different number of components on the left hand side (" + - toString(variables.size()) + - ") than on the right hand side (" + - toString(valueTypes.size()) + - ")." - ); - else if (!variables.front() && !variables.back()) - m_errorReporter.fatalTypeError( - _statement.location(), - "Wildcard both at beginning and end of variable declaration list is only allowed " - "if the number of components is equal." - ); - else - m_errorReporter.warning( - _statement.location(), - "Different number of components on the left hand side (" + - toString(variables.size()) + - ") than on the right hand side (" + - toString(valueTypes.size()) + - ")." - ); - } - size_t minNumValues = variables.size(); - if (!variables.empty() && (!variables.back() || !variables.front())) - --minNumValues; - if (valueTypes.size() < minNumValues) - m_errorReporter.fatalTypeError( - _statement.location(), - "Not enough components (" + - toString(valueTypes.size()) + - ") in value to assign all variables (" + - toString(minNumValues) + ")." - ); - if (valueTypes.size() > variables.size() && variables.front() && variables.back()) - m_errorReporter.fatalTypeError( + m_errorReporter.typeError( _statement.location(), - "Too many components (" + + "Different number of components on the left hand side (" + + toString(variables.size()) + + ") than on the right hand side (" + toString(valueTypes.size()) + - ") in value for variable assignment (" + - toString(minNumValues) + - " needed)." + ")." ); - bool fillRight = !variables.empty() && (!variables.back() || variables.front()); - for (size_t i = 0; i < min(variables.size(), valueTypes.size()); ++i) - if (fillRight) - assignments[i] = variables[i].get(); - else - assignments[assignments.size() - i - 1] = variables[variables.size() - i - 1].get(); - for (size_t i = 0; i < assignments.size(); ++i) + bool autoTypeDeductionNeeded = false; + + for (size_t i = 0; i < min(variables.size(), valueTypes.size()); ++i) { - if (!assignments[i]) + if (!variables[i]) continue; - VariableDeclaration const& var = *assignments[i]; + VariableDeclaration const& var = *variables[i]; solAssert(!var.value(), "Value has to be tied to statement."); TypePointer const& valueComponentType = valueTypes[i]; solAssert(!!valueComponentType, ""); if (!var.annotation().type) { + autoTypeDeductionNeeded = true; + // Infer type from value. solAssert(!var.typeName(), ""); var.annotation().type = valueComponentType->mobileType(); @@ -1220,14 +1184,6 @@ bool TypeChecker::visit(VariableDeclarationStatement const& _statement) } else solAssert(dynamic_cast<FixedPointType const*>(var.annotation().type.get()), "Unknown type."); - - m_errorReporter.warning( - _statement.location(), - "The type of this variable was inferred as " + - typeName + - extension + - ". This is probably not desired. Use an explicit type to silence this warning." - ); } var.accept(*this); @@ -1264,6 +1220,23 @@ bool TypeChecker::visit(VariableDeclarationStatement const& _statement) } } } + + if (autoTypeDeductionNeeded) + { + if (!typeCanBeExpressed(variables)) + m_errorReporter.syntaxError( + _statement.location(), + "Use of the \"var\" keyword is disallowed. " + "Type cannot be expressed in syntax." + ); + else + m_errorReporter.syntaxError( + _statement.location(), + "Use of the \"var\" keyword is disallowed. " + "Use explicit declaration `" + createTupleDecl(variables) + " = ...´ instead." + ); + } + return false; } @@ -1337,7 +1310,6 @@ bool TypeChecker::visit(Conditional const& _conditional) bool TypeChecker::visit(Assignment const& _assignment) { - bool const v050 = m_scope->sourceUnit().annotation().experimentalFeatures.count(ExperimentalFeature::V050); requireLValue(_assignment.leftHandSide()); TypePointer t = type(_assignment.leftHandSide()); _assignment.annotation().type = t; @@ -1354,25 +1326,8 @@ bool TypeChecker::visit(Assignment const& _assignment) expectType(_assignment.rightHandSide(), *tupleType); // expectType does not cause fatal errors, so we have to check again here. - if (TupleType const* rhsType = dynamic_cast<TupleType const*>(type(_assignment.rightHandSide()).get())) - { + if (dynamic_cast<TupleType const*>(type(_assignment.rightHandSide()).get())) checkDoubleStorageAssignment(_assignment); - // @todo For 0.5.0, this code shoud move to TupleType::isImplicitlyConvertibleTo, - // but we cannot do it right now. - if (rhsType->components().size() != tupleType->components().size()) - { - string message = - "Different number of components on the left hand side (" + - toString(tupleType->components().size()) + - ") than on the right hand side (" + - toString(rhsType->components().size()) + - ")."; - if (v050) - m_errorReporter.typeError(_assignment.location(), message); - else - m_errorReporter.warning(_assignment.location(), message); - } - } } else if (t->category() == Type::Category::Mapping) { @@ -1429,14 +1384,12 @@ bool TypeChecker::visit(TupleExpression const& _tuple) } else { - bool const v050 = m_scope->sourceUnit().annotation().experimentalFeatures.count(ExperimentalFeature::V050); bool isPure = true; TypePointer inlineArrayType; for (size_t i = 0; i < components.size(); ++i) { - // Outside of an lvalue-context, the only situation where a component can be empty is (x,). - if (!components[i] && !(i == 1 && components.size() == 2)) + if (!components[i]) m_errorReporter.fatalTypeError(_tuple.location(), "Tuple component cannot be empty."); else if (components[i]) { @@ -1448,10 +1401,7 @@ bool TypeChecker::visit(TupleExpression const& _tuple) { if (_tuple.isInlineArray()) m_errorReporter.fatalTypeError(components[i]->location(), "Array component cannot be empty."); - if (v050) - m_errorReporter.fatalTypeError(components[i]->location(), "Tuple component cannot be empty."); - else - m_errorReporter.warning(components[i]->location(), "Tuple component cannot be empty."); + m_errorReporter.typeError(components[i]->location(), "Tuple component cannot be empty."); } // Note: code generation will visit each of the expression even if they are not assigned from. @@ -1489,11 +1439,7 @@ bool TypeChecker::visit(TupleExpression const& _tuple) if (components.size() == 1) _tuple.annotation().type = type(*components[0]); else - { - if (components.size() == 2 && !components[1]) - types.pop_back(); _tuple.annotation().type = make_shared<TupleType>(types); - } } } @@ -1684,8 +1630,6 @@ bool TypeChecker::visit(FunctionCall const& _functionCall) else _functionCall.annotation().type = make_shared<TupleType>(returnTypes); - bool const v050 = m_scope->sourceUnit().annotation().experimentalFeatures.count(ExperimentalFeature::V050); - if (auto functionName = dynamic_cast<Identifier const*>(&_functionCall.expression())) { if (functionName->name() == "sha3" && functionType->kind() == FunctionType::Kind::SHA3) @@ -1705,23 +1649,15 @@ bool TypeChecker::visit(FunctionCall const& _functionCall) auto const& argType = type(*arguments[i]); if (auto literal = dynamic_cast<RationalNumberType const*>(argType.get())) { - /* If no mobile type is available an error will be raised elsewhere. */ if (literal->mobileType()) + m_errorReporter.typeError( + arguments[i]->location(), + "Cannot perform packed encoding for a literal. Please convert it to an explicit type first." + ); + else { - if (v050) - m_errorReporter.typeError( - arguments[i]->location(), - "Cannot perform packed encoding for a literal. Please convert it to an explicit type first." - ); - else - m_errorReporter.warning( - arguments[i]->location(), - "The type of \"" + - argType->toString() + - "\" was inferred as " + - literal->mobileType()->toString() + - ". This is probably not desired. Use an explicit type to silence this warning." - ); + /* If no mobile type is available an error will be raised elsewhere. */ + solAssert(m_errorReporter.hasErrors(), ""); } } } @@ -1848,7 +1784,7 @@ bool TypeChecker::visit(FunctionCall const& _functionCall) if (functionType->takesArbitraryParameters()) m_errorReporter.typeError( _functionCall.location(), - "Named arguments cannnot be used for functions that take arbitrary parameters." + "Named arguments cannot be used for functions that take arbitrary parameters." ); else if (parameterNames.size() > argumentNames.size()) m_errorReporter.typeError(_functionCall.location(), "Some argument names are missing."); @@ -1994,6 +1930,9 @@ bool TypeChecker::visit(MemberAccess const& _memberAccess) else ++it; } + + auto& annotation = _memberAccess.annotation(); + if (possibleMembers.size() == 0) { if (initialMemberCount == 0) @@ -2011,11 +1950,21 @@ bool TypeChecker::visit(MemberAccess const& _memberAccess) " outside of storage." ); } + string errorMsg = "Member \"" + memberName + "\" not found or not visible " + "after argument-dependent lookup in " + exprType->toString() + + (memberName == "value" ? " - did you forget the \"payable\" modifier?" : "."); + if (exprType->category() == Type::Category::Contract) + for (auto const& addressMember: IntegerType(160, IntegerType::Modifier::Address).nativeMembers(nullptr)) + if (addressMember.name == memberName) + { + Identifier const* var = dynamic_cast<Identifier const*>(&_memberAccess.expression()); + string varName = var ? var->name() : "..."; + errorMsg += " Use \"address(" + varName + ")." + memberName + "\" to access this address member."; + break; + } m_errorReporter.fatalTypeError( _memberAccess.location(), - "Member \"" + memberName + "\" not found or not visible " - "after argument-dependent lookup in " + exprType->toString() + - (memberName == "value" ? " - did you forget the \"payable\" modifier?" : "") + errorMsg ); } else if (possibleMembers.size() > 1) @@ -2023,10 +1972,9 @@ bool TypeChecker::visit(MemberAccess const& _memberAccess) _memberAccess.location(), "Member \"" + memberName + "\" not unique " "after argument-dependent lookup in " + exprType->toString() + - (memberName == "value" ? " - did you forget the \"payable\" modifier?" : "") + (memberName == "value" ? " - did you forget the \"payable\" modifier?" : ".") ); - auto& annotation = _memberAccess.annotation(); annotation.referencedDeclaration = possibleMembers.front().declaration; annotation.type = possibleMembers.front().type; @@ -2035,7 +1983,7 @@ bool TypeChecker::visit(MemberAccess const& _memberAccess) m_errorReporter.typeError( _memberAccess.location(), "Function \"" + memberName + "\" cannot be called on an object of type " + - exprType->toString() + " (expected " + funType->selfType()->toString() + ")" + exprType->toString() + " (expected " + funType->selfType()->toString() + ")." ); if (exprType->category() == Type::Category::Struct) @@ -2059,20 +2007,6 @@ bool TypeChecker::visit(MemberAccess const& _memberAccess) if (exprType->category() == Type::Category::Contract) { - // Warn about using address members on contracts - bool v050 = m_scope->sourceUnit().annotation().experimentalFeatures.count(ExperimentalFeature::V050); - for (auto const& addressMember: IntegerType(160, IntegerType::Modifier::Address).nativeMembers(nullptr)) - if (addressMember.name == memberName && *annotation.type == *addressMember.type) - { - solAssert(!v050, "Address member still present on contract in v0.5.0."); - m_errorReporter.warning( - _memberAccess.location(), - "Using contract member \"" + memberName +"\" inherited from the address type is deprecated." + - " Convert the contract to \"address\" type to access the member," - " for example use \"address(contract)." + memberName + "\" instead." - ); - } - // Warn about using send or transfer with a non-payable fallback function. if (auto callType = dynamic_cast<FunctionType const*>(type(_memberAccess).get())) { @@ -2267,11 +2201,9 @@ void TypeChecker::endVisit(ElementaryTypeNameExpression const& _expr) void TypeChecker::endVisit(Literal const& _literal) { - bool const v050 = m_scope->sourceUnit().annotation().experimentalFeatures.count(ExperimentalFeature::V050); - if (_literal.looksLikeAddress()) { - // Assign type here if it even looks like an address. This prevents double error in 050 mode for invalid address + // Assign type here if it even looks like an address. This prevents double errors for invalid addresses _literal.annotation().type = make_shared<IntegerType>(160, IntegerType::Modifier::Address); string msg; @@ -2298,20 +2230,11 @@ void TypeChecker::endVisit(Literal const& _literal) } if (_literal.isHexNumber() && _literal.subDenomination() != Literal::SubDenomination::None) - { - if (v050) - m_errorReporter.fatalTypeError( - _literal.location(), - "Hexadecimal numbers cannot be used with unit denominations. " - "You can use an expression of the form \"0x1234 * 1 day\" instead." - ); - else - m_errorReporter.warning( - _literal.location(), - "Hexadecimal numbers with unit denominations are deprecated. " - "You can use an expression of the form \"0x1234 * 1 day\" instead." - ); - } + m_errorReporter.fatalTypeError( + _literal.location(), + "Hexadecimal numbers cannot be used with unit denominations. " + "You can use an expression of the form \"0x1234 * 1 day\" instead." + ); if (_literal.subDenomination() == Literal::SubDenomination::Year) m_errorReporter.typeError( diff --git a/libsolidity/analysis/TypeChecker.h b/libsolidity/analysis/TypeChecker.h index 2245abd6..8dc6b376 100644 --- a/libsolidity/analysis/TypeChecker.h +++ b/libsolidity/analysis/TypeChecker.h @@ -68,7 +68,7 @@ private: void checkContractDuplicateFunctions(ContractDefinition const& _contract); void checkContractDuplicateEvents(ContractDefinition const& _contract); void checkContractIllegalOverrides(ContractDefinition const& _contract); - /// Reports a type error with an appropiate message if overriden function signature differs. + /// Reports a type error with an appropriate message if overridden function signature differs. /// Also stores the direct super function in the AST annotations. void checkFunctionOverride(FunctionDefinition const& function, FunctionDefinition const& super); void overrideError(FunctionDefinition const& function, FunctionDefinition const& super, std::string message); diff --git a/libsolidity/analysis/ViewPureChecker.cpp b/libsolidity/analysis/ViewPureChecker.cpp index 18c642c3..d936ada0 100644 --- a/libsolidity/analysis/ViewPureChecker.cpp +++ b/libsolidity/analysis/ViewPureChecker.cpp @@ -287,9 +287,8 @@ void ViewPureChecker::endVisit(MemberAccess const& _memberAccess) ASTString const& member = _memberAccess.memberName(); switch (_memberAccess.expression().annotation().type->category()) { - case Type::Category::Contract: case Type::Category::Integer: - if (member == "balance" && !_memberAccess.annotation().referencedDeclaration) + if (member == "balance") mutability = StateMutability::View; break; case Type::Category::Magic: diff --git a/libsolidity/ast/AST.cpp b/libsolidity/ast/AST.cpp index 16c9b2d2..7719d080 100644 --- a/libsolidity/ast/AST.cpp +++ b/libsolidity/ast/AST.cpp @@ -535,13 +535,6 @@ ReturnAnnotation& Return::annotation() const return dynamic_cast<ReturnAnnotation&>(*m_annotation); } -VariableDeclarationStatementAnnotation& VariableDeclarationStatement::annotation() const -{ - if (!m_annotation) - m_annotation = new VariableDeclarationStatementAnnotation(); - return dynamic_cast<VariableDeclarationStatementAnnotation&>(*m_annotation); -} - ExpressionAnnotation& Expression::annotation() const { if (!m_annotation) diff --git a/libsolidity/ast/AST.h b/libsolidity/ast/AST.h index d703ae53..9ed3b9aa 100644 --- a/libsolidity/ast/AST.h +++ b/libsolidity/ast/AST.h @@ -614,7 +614,6 @@ public: StateMutability stateMutability() const { return m_stateMutability; } bool isConstructor() const { return m_isConstructor; } - bool isOldStyleConstructor() const { return m_isConstructor && !name().empty(); } bool isFallback() const { return !m_isConstructor && name().empty(); } bool isPayable() const { return m_stateMutability == StateMutability::Payable; } std::vector<ASTPointer<ModifierInvocation>> const& modifiers() const { return m_functionModifiers; } @@ -1169,11 +1168,11 @@ public: Statement const& body() const { return *m_body; } private: - /// For statement's initialization expresion. for(XXX; ; ). Can be empty + /// For statement's initialization expression. for(XXX; ; ). Can be empty ASTPointer<Statement> m_initExpression; - /// For statement's condition expresion. for(; XXX ; ). Can be empty + /// For statement's condition expression. for(; XXX ; ). Can be empty ASTPointer<Expression> m_condExpression; - /// For statement's loop expresion. for(;;XXX). Can be empty + /// For statement's loop expression. for(;;XXX). Can be empty ASTPointer<ExpressionStatement> m_loopExpression; /// The body of the loop ASTPointer<Statement> m_body; @@ -1250,13 +1249,12 @@ private: }; /** - * Definition of a variable as a statement inside a function. It requires a type name (which can - * also be "var") but the actual assignment can be missing. - * Examples: var a = 2; uint256 a; - * As a second form, multiple variables can be declared, cannot have a type and must be assigned - * right away. If the first or last component is unnamed, it can "consume" an arbitrary number - * of components. - * Examples: var (a, b) = f(); var (a,,,c) = g(); var (a,) = d(); + * Definition of one or more variables as a statement inside a function. + * If multiple variables are declared, a value has to be assigned directly. + * If only a single variable is declared, the value can be missing. + * Examples: + * uint[] memory a; uint a = 2; + * (uint a, bytes32 b, ) = f(); (, uint a, , StructName storage x) = g(); */ class VariableDeclarationStatement: public Statement { @@ -1271,13 +1269,14 @@ public: virtual void accept(ASTVisitor& _visitor) override; virtual void accept(ASTConstVisitor& _visitor) const override; - VariableDeclarationStatementAnnotation& annotation() const override; - std::vector<ASTPointer<VariableDeclaration>> const& declarations() const { return m_variables; } Expression const* initialValue() const { return m_initialValue.get(); } private: /// List of variables, some of which can be empty pointers (unnamed components). + /// Note that the ``m_value`` member of these is unused. Instead, ``m_initialValue`` + /// below is used, because the initial value can be a single expression assigned + /// to all variables. std::vector<ASTPointer<VariableDeclaration>> m_variables; /// The assigned expression / initial value. ASTPointer<Expression> m_initialValue; diff --git a/libsolidity/ast/ASTAnnotations.h b/libsolidity/ast/ASTAnnotations.h index 5cbe42bd..e0b3f492 100644 --- a/libsolidity/ast/ASTAnnotations.h +++ b/libsolidity/ast/ASTAnnotations.h @@ -164,13 +164,6 @@ struct UserDefinedTypeNameAnnotation: TypeNameAnnotation ContractDefinition const* contractScope = nullptr; }; -struct VariableDeclarationStatementAnnotation: StatementAnnotation -{ - /// Information about which component of the value is assigned to which variable. - /// The pointer can be null to signify that the component is discarded. - std::vector<VariableDeclaration const*> assignments; -}; - struct ExpressionAnnotation: ASTAnnotation { /// Inferred type of the expression. diff --git a/libsolidity/ast/ASTJsonConverter.cpp b/libsolidity/ast/ASTJsonConverter.cpp index b7855668..a26828a6 100644 --- a/libsolidity/ast/ASTJsonConverter.cpp +++ b/libsolidity/ast/ASTJsonConverter.cpp @@ -555,8 +555,8 @@ bool ASTJsonConverter::visit(EmitStatement const& _node) bool ASTJsonConverter::visit(VariableDeclarationStatement const& _node) { Json::Value varDecs(Json::arrayValue); - for (auto const& v: _node.annotation().assignments) - appendMove(varDecs, idOrNull(v)); + for (auto const& v: _node.declarations()) + appendMove(varDecs, idOrNull(v.get())); setJsonNode(_node, "VariableDeclarationStatement", { make_pair("assignments", std::move(varDecs)), make_pair("declarations", toJson(_node.declarations())), diff --git a/libsolidity/ast/Types.cpp b/libsolidity/ast/Types.cpp index 1c4eb76e..2c2d3b68 100644 --- a/libsolidity/ast/Types.cpp +++ b/libsolidity/ast/Types.cpp @@ -771,20 +771,23 @@ tuple<bool, rational> RationalNumberType::isValidLiteral(Literal const& _literal } else if (expPoint != _literal.value().end()) { - // Parse base and exponent. Checks numeric limit. - bigint exp = bigint(string(expPoint + 1, _literal.value().end())); + // Parse mantissa and exponent. Checks numeric limit. + tuple<bool, rational> mantissa = parseRational(string(_literal.value().begin(), expPoint)); - if (exp > numeric_limits<int32_t>::max() || exp < numeric_limits<int32_t>::min()) + if (!get<0>(mantissa)) return make_tuple(false, rational(0)); + value = get<1>(mantissa); - uint32_t expAbs = bigint(abs(exp)).convert_to<uint32_t>(); - + // 0E... is always zero. + if (value == 0) + return make_tuple(true, rational(0)); - tuple<bool, rational> base = parseRational(string(_literal.value().begin(), expPoint)); + bigint exp = bigint(string(expPoint + 1, _literal.value().end())); - if (!get<0>(base)) + if (exp > numeric_limits<int32_t>::max() || exp < numeric_limits<int32_t>::min()) return make_tuple(false, rational(0)); - value = get<1>(base); + + uint32_t expAbs = bigint(abs(exp)).convert_to<uint32_t>(); if (exp < 0) { @@ -949,7 +952,7 @@ TypePointer RationalNumberType::binaryOperatorResult(Token::Value _operator, Typ RationalNumberType const& other = dynamic_cast<RationalNumberType const&>(*_other); if (Token::isCompareOp(_operator)) { - // Since we do not have a "BoolConstantType", we have to do the acutal comparison + // Since we do not have a "BoolConstantType", we have to do the actual comparison // at runtime and convert to mobile typse first. Such a comparison is not a very common // use-case and will be optimized away. TypePointer thisMobile = mobileType(); @@ -1870,47 +1873,9 @@ MemberList::MemberMap ContractType::nativeMembers(ContractDefinition const* _con &it.second->declaration() )); } - // In 0.5.0 address members are not populated into the contract. - if (!_contract->sourceUnit().annotation().experimentalFeatures.count(ExperimentalFeature::V050)) - addNonConflictingAddressMembers(members); return members; } -void ContractType::addNonConflictingAddressMembers(MemberList::MemberMap& _members) -{ - MemberList::MemberMap addressMembers = IntegerType(160, IntegerType::Modifier::Address).nativeMembers(nullptr); - for (auto const& addressMember: addressMembers) - { - bool clash = false; - for (auto const& member: _members) - { - if ( - member.name == addressMember.name && - ( - // Members with different types are not allowed - member.type->category() != addressMember.type->category() || - // Members must overload functions without clash - ( - member.type->category() == Type::Category::Function && - dynamic_cast<FunctionType const&>(*member.type).hasEqualArgumentTypes(dynamic_cast<FunctionType const&>(*addressMember.type)) - ) - ) - ) - { - clash = true; - break; - } - } - - if (!clash) - _members.push_back(MemberList::Member( - addressMember.name, - addressMember.type, - addressMember.declaration - )); - } -} - shared_ptr<FunctionType const> const& ContractType::newExpressionType() const { if (!m_constructorType) @@ -2238,25 +2203,13 @@ bool TupleType::isImplicitlyConvertibleTo(Type const& _other) const TypePointers const& targets = tupleType->components(); if (targets.empty()) return components().empty(); - if (components().size() != targets.size() && !targets.front() && !targets.back()) - return false; // (,a,) = (1,2,3,4) - unable to position `a` in the tuple. - size_t minNumValues = targets.size(); - if (!targets.back() || !targets.front()) - --minNumValues; // wildcards can also match 0 components - if (components().size() < minNumValues) + if (components().size() != targets.size()) return false; - if (components().size() > targets.size() && targets.front() && targets.back()) - return false; // larger source and no wildcard - bool fillRight = !targets.back() || targets.front(); - for (size_t i = 0; i < min(targets.size(), components().size()); ++i) - { - auto const& s = components()[fillRight ? i : components().size() - i - 1]; - auto const& t = targets[fillRight ? i : targets.size() - i - 1]; - if (!s && t) + for (size_t i = 0; i < targets.size(); ++i) + if (!components()[i] && targets[i]) return false; - else if (s && t && !s->isImplicitlyConvertibleTo(*t)) + else if (components()[i] && targets[i] && !components()[i]->isImplicitlyConvertibleTo(*targets[i])) return false; - } return true; } else diff --git a/libsolidity/ast/Types.h b/libsolidity/ast/Types.h index 4415fb4b..1a676b42 100644 --- a/libsolidity/ast/Types.h +++ b/libsolidity/ast/Types.h @@ -740,8 +740,6 @@ public: std::vector<std::tuple<VariableDeclaration const*, u256, unsigned>> stateVariables() const; private: - static void addNonConflictingAddressMembers(MemberList::MemberMap& _members); - ContractDefinition const& m_contract; /// If true, it is the "super" type of the current contract, i.e. it contains only inherited /// members. @@ -1031,7 +1029,7 @@ public: /// @param _selfType if the function is bound, this has to be supplied and is the type of the /// expression the function is called on. bool canTakeArguments(TypePointers const& _arguments, TypePointer const& _selfType = TypePointer()) const; - /// @returns true if the types of parameters are equal (does't check return parameter types) + /// @returns true if the types of parameters are equal (doesn't check return parameter types) bool hasEqualArgumentTypes(FunctionType const& _other) const; /// @returns true if the ABI is used for this call (only meaningful for external calls) diff --git a/libsolidity/codegen/ABIFunctions.cpp b/libsolidity/codegen/ABIFunctions.cpp index 4818e111..b3f1bc7e 100644 --- a/libsolidity/codegen/ABIFunctions.cpp +++ b/libsolidity/codegen/ABIFunctions.cpp @@ -1188,7 +1188,8 @@ string ABIFunctions::abiDecodingFunctionCalldataArray(ArrayType const& _type) solAssert(_type.dataStoredIn(DataLocation::CallData), ""); if (!_type.isDynamicallySized()) solAssert(_type.length() < u256("0xffffffffffffffff"), ""); - solAssert(!_type.baseType()->isDynamicallyEncoded(), ""); + if (_type.baseType()->isDynamicallyEncoded()) + solUnimplemented("Calldata arrays with non-value base types are not yet supported by Solidity."); solAssert(_type.baseType()->calldataEncodedSize() < u256("0xffffffffffffffff"), ""); string functionName = diff --git a/libsolidity/codegen/ABIFunctions.h b/libsolidity/codegen/ABIFunctions.h index 6bfb3f15..3caaa1d9 100644 --- a/libsolidity/codegen/ABIFunctions.h +++ b/libsolidity/codegen/ABIFunctions.h @@ -203,7 +203,7 @@ private: std::string arrayLengthFunction(ArrayType const& _type); /// @returns the name of a function that computes the number of bytes required /// to store an array in memory given its length (internally encoded, not ABI encoded). - /// The function reverts for too large lengthes. + /// The function reverts for too large lengths. std::string arrayAllocationSizeFunction(ArrayType const& _type); /// @returns the name of a function that converts a storage slot number /// or a memory pointer to the slot number / memory pointer for the data position of an array diff --git a/libsolidity/codegen/CompilerContext.cpp b/libsolidity/codegen/CompilerContext.cpp index a35eea73..3b1b4ec0 100644 --- a/libsolidity/codegen/CompilerContext.cpp +++ b/libsolidity/codegen/CompilerContext.cpp @@ -127,10 +127,14 @@ void CompilerContext::addVariable(VariableDeclaration const& _declaration, unsigned _offsetToCurrent) { solAssert(m_asm->deposit() >= 0 && unsigned(m_asm->deposit()) >= _offsetToCurrent, ""); + unsigned sizeOnStack = _declaration.annotation().type->sizeOnStack(); + // Variables should not have stack size other than [1, 2], + // but that might change when new types are introduced. + solAssert(sizeOnStack == 1 || sizeOnStack == 2, ""); m_localVariables[&_declaration].push_back(unsigned(m_asm->deposit()) - _offsetToCurrent); } -void CompilerContext::removeVariable(VariableDeclaration const& _declaration) +void CompilerContext::removeVariable(Declaration const& _declaration) { solAssert(m_localVariables.count(&_declaration) && !m_localVariables[&_declaration].empty(), ""); m_localVariables[&_declaration].pop_back(); @@ -138,6 +142,25 @@ void CompilerContext::removeVariable(VariableDeclaration const& _declaration) m_localVariables.erase(&_declaration); } +void CompilerContext::removeVariablesAboveStackHeight(unsigned _stackHeight) +{ + vector<Declaration const*> toRemove; + for (auto _var: m_localVariables) + { + solAssert(!_var.second.empty(), ""); + solAssert(_var.second.back() <= stackHeight(), ""); + if (_var.second.back() >= _stackHeight) + toRemove.push_back(_var.first); + } + for (auto _var: toRemove) + removeVariable(*_var); +} + +unsigned CompilerContext::numberOfLocalVariables() const +{ + return m_localVariables.size(); +} + eth::Assembly const& CompilerContext::compiledContract(const ContractDefinition& _contract) const { auto ret = m_compiledContracts.find(&_contract); diff --git a/libsolidity/codegen/CompilerContext.h b/libsolidity/codegen/CompilerContext.h index 5776b5d1..3f357821 100644 --- a/libsolidity/codegen/CompilerContext.h +++ b/libsolidity/codegen/CompilerContext.h @@ -71,7 +71,11 @@ public: void addStateVariable(VariableDeclaration const& _declaration, u256 const& _storageOffset, unsigned _byteOffset); void addVariable(VariableDeclaration const& _declaration, unsigned _offsetToCurrent = 0); - void removeVariable(VariableDeclaration const& _declaration); + void removeVariable(Declaration const& _declaration); + /// Removes all local variables currently allocated above _stackHeight. + void removeVariablesAboveStackHeight(unsigned _stackHeight); + /// Returns the number of currently allocated local variables. + unsigned numberOfLocalVariables() const; void setCompiledContracts(std::map<ContractDefinition const*, eth::Assembly const*> const& _contracts) { m_compiledContracts = _contracts; } eth::Assembly const& compiledContract(ContractDefinition const& _contract) const; diff --git a/libsolidity/codegen/CompilerUtils.cpp b/libsolidity/codegen/CompilerUtils.cpp index 2f45765a..2d81a106 100644 --- a/libsolidity/codegen/CompilerUtils.cpp +++ b/libsolidity/codegen/CompilerUtils.cpp @@ -363,8 +363,8 @@ void CompilerUtils::encodeToMemory( // Stack during operation: // <v1> <v2> ... <vn> <mem_start> <dyn_head_1> ... <dyn_head_r> <end_of_mem> - // The values dyn_head_i are added during the first loop and they point to the head part - // of the ith dynamic parameter, which is filled once the dynamic parts are processed. + // The values dyn_head_n are added during the first loop and they point to the head part + // of the nth dynamic parameter, which is filled once the dynamic parts are processed. // store memory start pointer m_context << Instruction::DUP1; @@ -1170,6 +1170,15 @@ void CompilerUtils::popStackSlots(size_t _amount) m_context << Instruction::POP; } +void CompilerUtils::popAndJump(unsigned _toHeight, eth::AssemblyItem const& _jumpTo) +{ + solAssert(m_context.stackHeight() >= _toHeight, ""); + unsigned amount = m_context.stackHeight() - _toHeight; + popStackSlots(amount); + m_context.appendJumpTo(_jumpTo); + m_context.adjustStackOffset(amount); +} + unsigned CompilerUtils::sizeOnStack(vector<shared_ptr<Type const>> const& _variableTypes) { unsigned size = 0; diff --git a/libsolidity/codegen/CompilerUtils.h b/libsolidity/codegen/CompilerUtils.h index 0ff3ad7c..26df4765 100644 --- a/libsolidity/codegen/CompilerUtils.h +++ b/libsolidity/codegen/CompilerUtils.h @@ -241,6 +241,10 @@ public: void popStackElement(Type const& _type); /// Removes element from the top of the stack _amount times. void popStackSlots(size_t _amount); + /// Pops slots from the stack such that its height is _toHeight. + /// Adds jump to _jumpTo. + /// Readjusts the stack offset to the original value. + void popAndJump(unsigned _toHeight, eth::AssemblyItem const& _jumpTo); template <class T> static unsigned sizeOnStack(std::vector<T> const& _variables); diff --git a/libsolidity/codegen/ContractCompiler.cpp b/libsolidity/codegen/ContractCompiler.cpp index 81aba21e..bbb3db3d 100644 --- a/libsolidity/codegen/ContractCompiler.cpp +++ b/libsolidity/codegen/ContractCompiler.cpp @@ -427,7 +427,7 @@ bool ContractCompiler::visit(FunctionDefinition const& _function) m_context.startFunction(_function); // stack upon entry: [return address] [arg0] [arg1] ... [argn] - // reserve additional slots: [retarg0] ... [retargm] [localvar0] ... [localvarp] + // reserve additional slots: [retarg0] ... [retargm] unsigned parametersSize = CompilerUtils::sizeOnStack(_function.parameters()); if (!_function.isConstructor()) @@ -441,8 +441,6 @@ bool ContractCompiler::visit(FunctionDefinition const& _function) for (ASTPointer<VariableDeclaration const> const& variable: _function.returnParameters()) appendStackVariableInitialisation(*variable); - for (VariableDeclaration const* localVariable: _function.localVariables()) - appendStackVariableInitialisation(*localVariable); if (_function.isConstructor()) if (auto c = m_context.nextConstructor(dynamic_cast<ContractDefinition const&>(*_function.scope()))) @@ -451,12 +449,11 @@ bool ContractCompiler::visit(FunctionDefinition const& _function) solAssert(m_returnTags.empty(), ""); m_breakTags.clear(); m_continueTags.clear(); - m_stackCleanupForReturn = 0; m_currentFunction = &_function; m_modifierDepth = -1; + m_scopeStackHeight.clear(); appendModifierOrFunctionCode(); - solAssert(m_returnTags.empty(), ""); // Now we need to re-shuffle the stack. For this we keep a record of the stack layout @@ -467,14 +464,12 @@ bool ContractCompiler::visit(FunctionDefinition const& _function) unsigned const c_argumentsSize = CompilerUtils::sizeOnStack(_function.parameters()); unsigned const c_returnValuesSize = CompilerUtils::sizeOnStack(_function.returnParameters()); - unsigned const c_localVariablesSize = CompilerUtils::sizeOnStack(_function.localVariables()); vector<int> stackLayout; stackLayout.push_back(c_returnValuesSize); // target of return address stackLayout += vector<int>(c_argumentsSize, -1); // discard all arguments for (unsigned i = 0; i < c_returnValuesSize; ++i) stackLayout.push_back(i); - stackLayout += vector<int>(c_localVariablesSize, -1); if (stackLayout.size() > 17) BOOST_THROW_EXCEPTION( @@ -493,18 +488,23 @@ bool ContractCompiler::visit(FunctionDefinition const& _function) m_context << swapInstruction(stackLayout.size() - stackLayout.back() - 1); swap(stackLayout[stackLayout.back()], stackLayout.back()); } - //@todo assert that everything is in place now + for (int i = 0; i < int(stackLayout.size()); ++i) + if (stackLayout[i] != i) + solAssert(false, "Invalid stack layout on cleanup."); for (ASTPointer<VariableDeclaration const> const& variable: _function.parameters() + _function.returnParameters()) m_context.removeVariable(*variable); - for (VariableDeclaration const* localVariable: _function.localVariables()) - m_context.removeVariable(*localVariable); m_context.adjustStackOffset(-(int)c_returnValuesSize); /// The constructor and the fallback function doesn't to jump out. - if (!_function.isConstructor() && !_function.isFallback()) - m_context.appendJump(eth::AssemblyItem::JumpType::OutOfFunction); + if (!_function.isConstructor()) + { + solAssert(m_context.numberOfLocalVariables() == 0, ""); + if (!_function.isFallback()) + m_context.appendJump(eth::AssemblyItem::JumpType::OutOfFunction); + } + return false; } @@ -669,14 +669,14 @@ bool ContractCompiler::visit(WhileStatement const& _whileStatement) eth::AssemblyItem loopStart = m_context.newTag(); eth::AssemblyItem loopEnd = m_context.newTag(); - m_breakTags.push_back(loopEnd); + m_breakTags.push_back({loopEnd, m_context.stackHeight()}); m_context << loopStart; if (_whileStatement.isDoWhile()) { eth::AssemblyItem condition = m_context.newTag(); - m_continueTags.push_back(condition); + m_continueTags.push_back({condition, m_context.stackHeight()}); _whileStatement.body().accept(*this); @@ -687,7 +687,7 @@ bool ContractCompiler::visit(WhileStatement const& _whileStatement) } else { - m_continueTags.push_back(loopStart); + m_continueTags.push_back({loopStart, m_context.stackHeight()}); compileExpression(_whileStatement.condition()); m_context << Instruction::ISZERO; m_context.appendConditionalJumpTo(loopEnd); @@ -712,12 +712,14 @@ bool ContractCompiler::visit(ForStatement const& _forStatement) eth::AssemblyItem loopStart = m_context.newTag(); eth::AssemblyItem loopEnd = m_context.newTag(); eth::AssemblyItem loopNext = m_context.newTag(); - m_continueTags.push_back(loopNext); - m_breakTags.push_back(loopEnd); + + storeStackHeight(&_forStatement); if (_forStatement.initializationExpression()) _forStatement.initializationExpression()->accept(*this); + m_breakTags.push_back({loopEnd, m_context.stackHeight()}); + m_continueTags.push_back({loopNext, m_context.stackHeight()}); m_context << loopStart; // if there is no terminating condition in for, default is to always be true @@ -737,11 +739,16 @@ bool ContractCompiler::visit(ForStatement const& _forStatement) _forStatement.loopExpression()->accept(*this); m_context.appendJumpTo(loopStart); + m_context << loopEnd; m_continueTags.pop_back(); m_breakTags.pop_back(); + // For the case where no break/return is executed: + // loop initialization variables have to be freed + popScopedVariables(&_forStatement); + checker.check(); return false; } @@ -750,7 +757,7 @@ bool ContractCompiler::visit(Continue const& _continueStatement) { CompilerContext::LocationSetter locationSetter(m_context, _continueStatement); solAssert(!m_continueTags.empty(), ""); - m_context.appendJumpTo(m_continueTags.back()); + CompilerUtils(m_context).popAndJump(m_continueTags.back().second, m_continueTags.back().first); return false; } @@ -758,7 +765,7 @@ bool ContractCompiler::visit(Break const& _breakStatement) { CompilerContext::LocationSetter locationSetter(m_context, _breakStatement); solAssert(!m_breakTags.empty(), ""); - m_context.appendJumpTo(m_breakTags.back()); + CompilerUtils(m_context).popAndJump(m_breakTags.back().second, m_breakTags.back().first); return false; } @@ -784,10 +791,8 @@ bool ContractCompiler::visit(Return const& _return) for (auto const& retVariable: boost::adaptors::reverse(returnParameters)) CompilerUtils(m_context).moveToStackVariable(*retVariable); } - for (unsigned i = 0; i < m_stackCleanupForReturn; ++i) - m_context << Instruction::POP; - m_context.appendJumpTo(m_returnTags.back()); - m_context.adjustStackOffset(m_stackCleanupForReturn); + + CompilerUtils(m_context).popAndJump(m_returnTags.back().second, m_returnTags.back().first); return false; } @@ -810,8 +815,15 @@ bool ContractCompiler::visit(EmitStatement const& _emit) bool ContractCompiler::visit(VariableDeclarationStatement const& _variableDeclarationStatement) { - StackHeightChecker checker(m_context); CompilerContext::LocationSetter locationSetter(m_context, _variableDeclarationStatement); + + // Local variable slots are reserved when their declaration is visited, + // and freed in the end of their scope. + for (auto _decl: _variableDeclarationStatement.declarations()) + if (_decl) + appendStackVariableInitialisation(*_decl); + + StackHeightChecker checker(m_context); if (Expression const* expression = _variableDeclarationStatement.initialValue()) { CompilerUtils utils(m_context); @@ -821,20 +833,19 @@ bool ContractCompiler::visit(VariableDeclarationStatement const& _variableDeclar valueTypes = tupleType->components(); else valueTypes = TypePointers{expression->annotation().type}; - auto const& assignments = _variableDeclarationStatement.annotation().assignments; - solAssert(assignments.size() == valueTypes.size(), ""); - for (size_t i = 0; i < assignments.size(); ++i) + auto const& declarations = _variableDeclarationStatement.declarations(); + solAssert(declarations.size() == valueTypes.size(), ""); + for (size_t i = 0; i < declarations.size(); ++i) { - size_t j = assignments.size() - i - 1; + size_t j = declarations.size() - i - 1; solAssert(!!valueTypes[j], ""); - VariableDeclaration const* varDecl = assignments[j]; - if (!varDecl) - utils.popStackElement(*valueTypes[j]); - else + if (VariableDeclaration const* varDecl = declarations[j].get()) { utils.convertType(*valueTypes[j], *varDecl->annotation().type); utils.moveToStackVariable(*varDecl); } + else + utils.popStackElement(*valueTypes[j]); } } checker.check(); @@ -861,6 +872,18 @@ bool ContractCompiler::visit(PlaceholderStatement const& _placeholderStatement) return true; } +bool ContractCompiler::visit(Block const& _block) +{ + storeStackHeight(&_block); + return true; +} + +void ContractCompiler::endVisit(Block const& _block) +{ + // Frees local variables declared in the scope of this block. + popScopedVariables(&_block); +} + void ContractCompiler::appendMissingFunctions() { while (Declaration const* function = m_context.nextFunctionToCompile()) @@ -916,27 +939,19 @@ void ContractCompiler::appendModifierOrFunctionCode() modifier.parameters()[i]->annotation().type ); } - for (VariableDeclaration const* localVariable: modifier.localVariables()) - { - addedVariables.push_back(localVariable); - appendStackVariableInitialisation(*localVariable); - } - stackSurplus = - CompilerUtils::sizeOnStack(modifier.parameters()) + - CompilerUtils::sizeOnStack(modifier.localVariables()); + stackSurplus = CompilerUtils::sizeOnStack(modifier.parameters()); codeBlock = &modifier.body(); } } if (codeBlock) { - m_returnTags.push_back(m_context.newTag()); - + m_returnTags.push_back({m_context.newTag(), m_context.stackHeight()}); codeBlock->accept(*this); solAssert(!m_returnTags.empty(), ""); - m_context << m_returnTags.back(); + m_context << m_returnTags.back().first; m_returnTags.pop_back(); CompilerUtils(m_context).popStackSlots(stackSurplus); @@ -983,3 +998,20 @@ eth::AssemblyPointer ContractCompiler::cloneRuntime() const a << u256(0x20) << u256(0) << Instruction::RETURN; return make_shared<eth::Assembly>(a); } + +void ContractCompiler::popScopedVariables(ASTNode const* _node) +{ + unsigned blockHeight = m_scopeStackHeight.at(m_modifierDepth).at(_node); + m_context.removeVariablesAboveStackHeight(blockHeight); + solAssert(m_context.stackHeight() >= blockHeight, ""); + unsigned stackDiff = m_context.stackHeight() - blockHeight; + CompilerUtils(m_context).popStackSlots(stackDiff); + m_scopeStackHeight[m_modifierDepth].erase(_node); + if (m_scopeStackHeight[m_modifierDepth].size() == 0) + m_scopeStackHeight.erase(m_modifierDepth); +} + +void ContractCompiler::storeStackHeight(ASTNode const* _node) +{ + m_scopeStackHeight[m_modifierDepth][_node] = m_context.stackHeight(); +} diff --git a/libsolidity/codegen/ContractCompiler.h b/libsolidity/codegen/ContractCompiler.h index 02a3452f..8516ec2c 100644 --- a/libsolidity/codegen/ContractCompiler.h +++ b/libsolidity/codegen/ContractCompiler.h @@ -109,6 +109,8 @@ private: virtual bool visit(VariableDeclarationStatement const& _variableDeclarationStatement) override; virtual bool visit(ExpressionStatement const& _expressionStatement) override; virtual bool visit(PlaceholderStatement const&) override; + virtual bool visit(Block const& _block) override; + virtual void endVisit(Block const& _block) override; /// Repeatedly visits all function which are referenced but which are not compiled yet. void appendMissingFunctions(); @@ -123,19 +125,31 @@ private: /// @returns the runtime assembly for clone contracts. eth::AssemblyPointer cloneRuntime() const; + /// Frees the variables of a certain scope (to be used when leaving). + void popScopedVariables(ASTNode const* _node); + + /// Sets the stack height for the visited loop. + void storeStackHeight(ASTNode const* _node); + bool const m_optimise; /// Pointer to the runtime compiler in case this is a creation compiler. ContractCompiler* m_runtimeCompiler = nullptr; CompilerContext& m_context; - std::vector<eth::AssemblyItem> m_breakTags; ///< tag to jump to for a "break" statement - std::vector<eth::AssemblyItem> m_continueTags; ///< tag to jump to for a "continue" statement - /// Tag to jump to for a "return" statement, needs to be stacked because of modifiers. - std::vector<eth::AssemblyItem> m_returnTags; + /// Tag to jump to for a "break" statement and the stack height after freeing the local loop variables. + std::vector<std::pair<eth::AssemblyItem, unsigned>> m_breakTags; + /// Tag to jump to for a "continue" statement and the stack height after freeing the local loop variables. + std::vector<std::pair<eth::AssemblyItem, unsigned>> m_continueTags; + /// Tag to jump to for a "return" statement and the stack height after freeing the local function or modifier variables. + /// Needs to be stacked because of modifiers. + std::vector<std::pair<eth::AssemblyItem, unsigned>> m_returnTags; unsigned m_modifierDepth = 0; FunctionDefinition const* m_currentFunction = nullptr; - unsigned m_stackCleanupForReturn = 0; ///< this number of stack elements need to be removed before jump to m_returnTag + // arguments for base constructors, filled in derived-to-base order std::map<FunctionDefinition const*, ASTNode const*> const* m_baseArguments; + + /// Stores the variables that were declared inside a specific scope, for each modifier depth. + std::map<unsigned, std::map<ASTNode const*, unsigned>> m_scopeStackHeight; }; } diff --git a/libsolidity/codegen/ExpressionCompiler.cpp b/libsolidity/codegen/ExpressionCompiler.cpp index 2e548e32..54518906 100644 --- a/libsolidity/codegen/ExpressionCompiler.cpp +++ b/libsolidity/codegen/ExpressionCompiler.cpp @@ -349,6 +349,10 @@ bool ExpressionCompiler::visit(UnaryOperation const& _unaryOperation) case Token::Inc: // ++ (pre- or postfix) case Token::Dec: // -- (pre- or postfix) solAssert(!!m_currentLValue, "LValue not retrieved."); + solUnimplementedAssert( + _unaryOperation.annotation().type->category() != Type::Category::FixedPoint, + "Not yet implemented - FixedPointType." + ); m_currentLValue->retrieveValue(_unaryOperation.location()); if (!_unaryOperation.isPrefixOperation()) { @@ -1210,63 +1214,52 @@ bool ExpressionCompiler::visit(MemberAccess const& _memberAccess) switch (_memberAccess.expression().annotation().type->category()) { case Type::Category::Contract: - case Type::Category::Integer: { - bool alsoSearchInteger = false; - if (_memberAccess.expression().annotation().type->category() == Type::Category::Contract) + ContractType const& type = dynamic_cast<ContractType const&>(*_memberAccess.expression().annotation().type); + if (type.isSuper()) { - ContractType const& type = dynamic_cast<ContractType const&>(*_memberAccess.expression().annotation().type); - if (type.isSuper()) - { - solAssert(!!_memberAccess.annotation().referencedDeclaration, "Referenced declaration not resolved."); - utils().pushCombinedFunctionEntryLabel(m_context.superFunction( - dynamic_cast<FunctionDefinition const&>(*_memberAccess.annotation().referencedDeclaration), - type.contractDefinition() - )); - } + solAssert(!!_memberAccess.annotation().referencedDeclaration, "Referenced declaration not resolved."); + utils().pushCombinedFunctionEntryLabel(m_context.superFunction( + dynamic_cast<FunctionDefinition const&>(*_memberAccess.annotation().referencedDeclaration), + type.contractDefinition() + )); + } + // ordinary contract type + else if (Declaration const* declaration = _memberAccess.annotation().referencedDeclaration) + { + u256 identifier; + if (auto const* variable = dynamic_cast<VariableDeclaration const*>(declaration)) + identifier = FunctionType(*variable).externalIdentifier(); + else if (auto const* function = dynamic_cast<FunctionDefinition const*>(declaration)) + identifier = FunctionType(*function).externalIdentifier(); else - { - // ordinary contract type - if (Declaration const* declaration = _memberAccess.annotation().referencedDeclaration) - { - u256 identifier; - if (auto const* variable = dynamic_cast<VariableDeclaration const*>(declaration)) - identifier = FunctionType(*variable).externalIdentifier(); - else if (auto const* function = dynamic_cast<FunctionDefinition const*>(declaration)) - identifier = FunctionType(*function).externalIdentifier(); - else - solAssert(false, "Contract member is neither variable nor function."); - utils().convertType(type, IntegerType(160, IntegerType::Modifier::Address), true); - m_context << identifier; - } - else - // not found in contract, search in members inherited from address - alsoSearchInteger = true; - } + solAssert(false, "Contract member is neither variable nor function."); + utils().convertType(type, IntegerType(160, IntegerType::Modifier::Address), true); + m_context << identifier; } else - alsoSearchInteger = true; - - if (alsoSearchInteger) + solAssert(false, "Invalid member access in contract"); + break; + } + case Type::Category::Integer: + { + if (member == "balance") { - if (member == "balance") - { - utils().convertType( - *_memberAccess.expression().annotation().type, - IntegerType(160, IntegerType::Modifier::Address), - true - ); - m_context << Instruction::BALANCE; - } - else if ((set<string>{"send", "transfer", "call", "callcode", "delegatecall"}).count(member)) - utils().convertType( - *_memberAccess.expression().annotation().type, - IntegerType(160, IntegerType::Modifier::Address), - true - ); - else - solAssert(false, "Invalid member access to integer"); + utils().convertType( + *_memberAccess.expression().annotation().type, + IntegerType(160, IntegerType::Modifier::Address), + true + ); + m_context << Instruction::BALANCE; } + else if ((set<string>{"send", "transfer", "call", "callcode", "delegatecall"}).count(member)) + utils().convertType( + *_memberAccess.expression().annotation().type, + IntegerType(160, IntegerType::Modifier::Address), + true + ); + else + solAssert(false, "Invalid member access to integer"); break; } case Type::Category::Function: @@ -1647,12 +1640,12 @@ void ExpressionCompiler::appendOrdinaryBinaryOperatorCode(Token::Value _operator void ExpressionCompiler::appendArithmeticOperatorCode(Token::Value _operator, Type const& _type) { - IntegerType const& type = dynamic_cast<IntegerType const&>(_type); - bool const c_isSigned = type.isSigned(); - if (_type.category() == Type::Category::FixedPoint) solUnimplemented("Not yet implemented - FixedPointType."); + IntegerType const& type = dynamic_cast<IntegerType const&>(_type); + bool const c_isSigned = type.isSigned(); + switch (_operator) { case Token::Add: @@ -1751,7 +1744,7 @@ void ExpressionCompiler::appendShiftOperatorCode(Token::Value _operator, Type co { if (c_valueSigned) // In the following assembly snippet, xor_mask will be zero, if value_to_shift is positive. - // Therefor xor'ing with xor_mask is the identity and the computation reduces to + // Therefore xor'ing with xor_mask is the identity and the computation reduces to // div(value_to_shift, exp(2, shift_amount)), which is correct, since for positive values // arithmetic right shift is dividing by a power of two (which, as a bitwise operation, results // in discarding bits on the right and filling with zeros from the left). @@ -1810,15 +1803,11 @@ void ExpressionCompiler::appendExternalFunctionCall( if (_functionType.bound()) utils().moveToStackTop(gasValueSize, _functionType.selfType()->sizeOnStack()); - bool const v050 = m_context.experimentalFeatureActive(ExperimentalFeature::V050); auto funKind = _functionType.kind(); bool returnSuccessCondition = funKind == FunctionType::Kind::BareCall || funKind == FunctionType::Kind::BareCallCode || funKind == FunctionType::Kind::BareDelegateCall; bool isCallCode = funKind == FunctionType::Kind::BareCallCode || funKind == FunctionType::Kind::CallCode; bool isDelegateCall = funKind == FunctionType::Kind::BareDelegateCall || funKind == FunctionType::Kind::DelegateCall; - bool useStaticCall = - _functionType.stateMutability() <= StateMutability::View && - v050 && - m_context.evmVersion().hasStaticCall(); + bool useStaticCall = _functionType.stateMutability() <= StateMutability::View && m_context.evmVersion().hasStaticCall(); bool haveReturndatacopy = m_context.evmVersion().supportsReturndata(); unsigned retSize = 0; @@ -1879,7 +1868,7 @@ void ExpressionCompiler::appendExternalFunctionCall( { m_context << u256(0); utils().fetchFreeMemoryPointer(); - // This touches too much, but that way we save some rounding arithmetics + // This touches too much, but that way we save some rounding arithmetic m_context << u256(retSize) << Instruction::ADD << Instruction::MSTORE; } } diff --git a/libsolidity/formal/SMTChecker.cpp b/libsolidity/formal/SMTChecker.cpp index a4d9500b..e2a51267 100644 --- a/libsolidity/formal/SMTChecker.cpp +++ b/libsolidity/formal/SMTChecker.cpp @@ -95,7 +95,7 @@ bool SMTChecker::visit(FunctionDefinition const& _function) void SMTChecker::endVisit(FunctionDefinition const&) { - // TOOD we could check for "reachability", i.e. satisfiability here. + // TODO we could check for "reachability", i.e. satisfiability here. // We only handle local variables, so we clear at the beginning of the function. // If we add storage variables, those should be cleared differently. removeLocalVariables(); diff --git a/libsolidity/inlineasm/AsmParser.cpp b/libsolidity/inlineasm/AsmParser.cpp index 7df9ab88..cd429a98 100644 --- a/libsolidity/inlineasm/AsmParser.cpp +++ b/libsolidity/inlineasm/AsmParser.cpp @@ -150,7 +150,7 @@ assembly::Statement Parser::parseStatement() expectToken(Token::Comma); elementary = parseElementaryOperation(); if (elementary.type() != typeid(assembly::Identifier)) - fatalParserError("Variable name expected in multiple assignemnt."); + fatalParserError("Variable name expected in multiple assignment."); assignment.variableNames.emplace_back(boost::get<assembly::Identifier>(elementary)); } while (currentToken() == Token::Comma); diff --git a/libsolidity/interface/AssemblyStack.cpp b/libsolidity/interface/AssemblyStack.cpp index a4b0265e..46fa1d6b 100644 --- a/libsolidity/interface/AssemblyStack.cpp +++ b/libsolidity/interface/AssemblyStack.cpp @@ -119,7 +119,7 @@ MachineAssemblyObject AssemblyStack::assemble(Machine _machine) const julia::EVMAssembly assembly(true); julia::CodeTransform(assembly, *m_analysisInfo, m_language == Language::Yul, true)(*m_parserResult); object.bytecode = make_shared<eth::LinkerObject>(assembly.finalize()); - /// TOOD: fill out text representation + /// TODO: fill out text representation return object; } case Machine::eWasm: diff --git a/libsolidity/interface/CompilerStack.h b/libsolidity/interface/CompilerStack.h index 4359c3fa..0578ac86 100644 --- a/libsolidity/interface/CompilerStack.h +++ b/libsolidity/interface/CompilerStack.h @@ -93,7 +93,7 @@ public: m_errorList(), m_errorReporter(m_errorList) {} - /// @returns the list of errors that occured during parsing and type checking. + /// @returns the list of errors that occurred during parsing and type checking. ErrorList const& errors() const { return m_errorReporter.errors(); } /// @returns the current state. diff --git a/libsolidity/interface/ErrorReporter.h b/libsolidity/interface/ErrorReporter.h index d1a0030f..fd53587a 100644 --- a/libsolidity/interface/ErrorReporter.h +++ b/libsolidity/interface/ErrorReporter.h @@ -92,6 +92,12 @@ public: void clear(); + /// @returns true iff there is any error (ignores warnings). + bool hasErrors() const + { + return m_errorCount > 0; + } + private: void error(Error::Type _type, SourceLocation const& _location, diff --git a/libsolidity/interface/Natspec.cpp b/libsolidity/interface/Natspec.cpp index 7f7084ef..29a5b798 100644 --- a/libsolidity/interface/Natspec.cpp +++ b/libsolidity/interface/Natspec.cpp @@ -36,6 +36,10 @@ Json::Value Natspec::userDocumentation(ContractDefinition const& _contractDef) Json::Value doc; Json::Value methods(Json::objectValue); + string notice = extractDoc(_contractDef.annotation().docTags, "notice"); + if (!notice.empty()) + doc["notice"] = Json::Value(notice); + for (auto const& it: _contractDef.interfaceFunctions()) if (it.second->hasDeclaration()) if (auto const* f = dynamic_cast<FunctionDefinition const*>(&it.second->declaration())) @@ -65,6 +69,9 @@ Json::Value Natspec::devDocumentation(ContractDefinition const& _contractDef) auto title = extractDoc(_contractDef.annotation().docTags, "title"); if (!title.empty()) doc["title"] = title; + auto dev = extractDoc(_contractDef.annotation().docTags, "dev"); + if (!dev.empty()) + doc["details"] = Json::Value(dev); for (auto const& it: _contractDef.interfaceFunctions()) { diff --git a/libsolidity/interface/Natspec.h b/libsolidity/interface/Natspec.h index 0701f821..6a827d3b 100644 --- a/libsolidity/interface/Natspec.h +++ b/libsolidity/interface/Natspec.h @@ -45,7 +45,7 @@ public: /// @param _contractDef The contract definition /// @return A JSON representation of the contract's user documentation static Json::Value userDocumentation(ContractDefinition const& _contractDef); - /// Genereates the Developer's documentation of the contract + /// Generates the Developer's documentation of the contract /// @param _contractDef The contract definition /// @return A JSON representation /// of the contract's developer documentation diff --git a/libsolidity/interface/StandardCompiler.h b/libsolidity/interface/StandardCompiler.h index 11a0b4c2..2772394a 100644 --- a/libsolidity/interface/StandardCompiler.h +++ b/libsolidity/interface/StandardCompiler.h @@ -31,7 +31,7 @@ namespace solidity { /** - * Standard JSON compiler interface, which expects a JSON input and returns a JSON ouput. + * Standard JSON compiler interface, which expects a JSON input and returns a JSON output. * See docs/using-the-compiler#compiler-input-and-output-json-description. */ class StandardCompiler: boost::noncopyable diff --git a/libsolidity/parsing/Parser.cpp b/libsolidity/parsing/Parser.cpp index e2bd6fb4..0bee2a91 100644 --- a/libsolidity/parsing/Parser.cpp +++ b/libsolidity/parsing/Parser.cpp @@ -239,13 +239,10 @@ ASTPointer<ContractDefinition> Parser::parseContractDefinition(Token::Value _exp Token::Value currentTokenValue = m_scanner->currentToken(); if (currentTokenValue == Token::RBrace) break; - else if ( - currentTokenValue == Token::Function || - (currentTokenValue == Token::Identifier && m_scanner->currentLiteral() == "constructor") - ) + else if (currentTokenValue == Token::Function || currentTokenValue == Token::Constructor) // This can be a function or a state variable of function type (especially // complicated to distinguish fallback function from function type state variable) - subNodes.push_back(parseFunctionDefinitionOrFunctionTypeStateVariable(name.get())); + subNodes.push_back(parseFunctionDefinitionOrFunctionTypeStateVariable()); else if (currentTokenValue == Token::Struct) subNodes.push_back(parseStructDefinition()); else if (currentTokenValue == Token::Enum) @@ -340,30 +337,31 @@ StateMutability Parser::parseStateMutability(Token::Value _token) return stateMutability; } -Parser::FunctionHeaderParserResult Parser::parseFunctionHeader( - bool _forceEmptyName, - bool _allowModifiers, - ASTString const* _contractName -) +Parser::FunctionHeaderParserResult Parser::parseFunctionHeader(bool _forceEmptyName, bool _allowModifiers) { RecursionGuard recursionGuard(*this); FunctionHeaderParserResult result; result.isConstructor = false; - if (m_scanner->currentToken() == Token::Identifier && m_scanner->currentLiteral() == "constructor") + if (m_scanner->currentToken() == Token::Constructor) result.isConstructor = true; else if (m_scanner->currentToken() != Token::Function) solAssert(false, "Function or constructor expected."); m_scanner->next(); - if (result.isConstructor || _forceEmptyName || m_scanner->currentToken() == Token::LParen) + if (result.isConstructor) result.name = make_shared<ASTString>(); + else if (_forceEmptyName || m_scanner->currentToken() == Token::LParen) + result.name = make_shared<ASTString>(); + else if (m_scanner->currentToken() == Token::Constructor) + fatalParserError(string( + "This function is named \"constructor\" but is not the constructor of the contract. " + "If you intend this to be a constructor, use \"constructor(...) { ... }\" without the \"function\" keyword to define it." + )); else result.name = expectIdentifierToken(); - if (!result.name->empty() && _contractName && *result.name == *_contractName) - result.isConstructor = true; VarDeclParserOptions options; options.allowLocationSpecifier = true; @@ -435,7 +433,7 @@ Parser::FunctionHeaderParserResult Parser::parseFunctionHeader( return result; } -ASTPointer<ASTNode> Parser::parseFunctionDefinitionOrFunctionTypeStateVariable(ASTString const* _contractName) +ASTPointer<ASTNode> Parser::parseFunctionDefinitionOrFunctionTypeStateVariable() { RecursionGuard recursionGuard(*this); ASTNodeFactory nodeFactory(*this); @@ -443,7 +441,7 @@ ASTPointer<ASTNode> Parser::parseFunctionDefinitionOrFunctionTypeStateVariable(A if (m_scanner->currentCommentLiteral() != "") docstring = make_shared<ASTString>(m_scanner->currentCommentLiteral()); - FunctionHeaderParserResult header = parseFunctionHeader(false, true, _contractName); + FunctionHeaderParserResult header = parseFunctionHeader(false, true); if ( header.isConstructor || diff --git a/libsolidity/parsing/Parser.h b/libsolidity/parsing/Parser.h index 08653364..c906771a 100644 --- a/libsolidity/parsing/Parser.h +++ b/libsolidity/parsing/Parser.h @@ -74,12 +74,8 @@ private: ASTPointer<InheritanceSpecifier> parseInheritanceSpecifier(); Declaration::Visibility parseVisibilitySpecifier(Token::Value _token); StateMutability parseStateMutability(Token::Value _token); - FunctionHeaderParserResult parseFunctionHeader( - bool _forceEmptyName, - bool _allowModifiers, - ASTString const* _contractName = nullptr - ); - ASTPointer<ASTNode> parseFunctionDefinitionOrFunctionTypeStateVariable(ASTString const* _contractName); + FunctionHeaderParserResult parseFunctionHeader(bool _forceEmptyName, bool _allowModifiers); + ASTPointer<ASTNode> parseFunctionDefinitionOrFunctionTypeStateVariable(); ASTPointer<FunctionDefinition> parseFunctionDefinition(ASTString const* _contractName); ASTPointer<StructDefinition> parseStructDefinition(); ASTPointer<EnumDefinition> parseEnumDefinition(); diff --git a/libsolidity/parsing/Scanner.h b/libsolidity/parsing/Scanner.h index 0adaa6fd..8a3011eb 100644 --- a/libsolidity/parsing/Scanner.h +++ b/libsolidity/parsing/Scanner.h @@ -223,7 +223,7 @@ private: bool isSourcePastEndOfInput() const { return m_source.isPastEndOfInput(); } TokenDesc m_skippedComment; // desc for current skipped comment - TokenDesc m_nextSkippedComment; // desc for next skiped comment + TokenDesc m_nextSkippedComment; // desc for next skipped comment TokenDesc m_currentToken; // desc for current token (as returned by Next()) TokenDesc m_nextToken; // desc for next token (one token look-ahead) diff --git a/libsolidity/parsing/Token.h b/libsolidity/parsing/Token.h index cb855cbe..7ce24e69 100644 --- a/libsolidity/parsing/Token.h +++ b/libsolidity/parsing/Token.h @@ -144,6 +144,7 @@ namespace solidity K(Assembly, "assembly", 0) \ K(Break, "break", 0) \ K(Constant, "constant", 0) \ + K(Constructor, "constructor", 0) \ K(Continue, "continue", 0) \ K(Contract, "contract", 0) \ K(Do, "do", 0) \ diff --git a/scripts/codespell_whitelist.txt b/scripts/codespell_whitelist.txt new file mode 100644 index 00000000..31f03981 --- /dev/null +++ b/scripts/codespell_whitelist.txt @@ -0,0 +1,3 @@ +iff +nd +assignend diff --git a/scripts/isolate_tests.py b/scripts/isolate_tests.py index 82dff1e0..1f913504 100755 --- a/scripts/isolate_tests.py +++ b/scripts/isolate_tests.py @@ -10,7 +10,7 @@ import sys import re import os import hashlib -from os.path import join +from os.path import join, isfile def extract_test_cases(path): lines = open(path, 'rb').read().splitlines() @@ -77,24 +77,31 @@ def write_cases(tests): for test in tests: open('test_%s.sol' % hashlib.sha256(test).hexdigest(), 'wb').write(test) + +def extract_and_write(f, path): + if docs: + cases = extract_docs_cases(path) + else: + if f.endswith('.sol'): + cases = [open(path, 'r').read()] + else: + cases = extract_test_cases(path) + write_cases(cases) + if __name__ == '__main__': path = sys.argv[1] docs = False if len(sys.argv) > 2 and sys.argv[2] == 'docs': docs = True - for root, subdirs, files in os.walk(path): - if '_build' in subdirs: - subdirs.remove('_build') - if 'compilationTests' in subdirs: - subdirs.remove('compilationTests') - for f in files: - path = join(root, f) - if docs: - cases = extract_docs_cases(path) - else: - if f.endswith(".sol"): - cases = [open(path, "r").read()] - else: - cases = extract_test_cases(path) - write_cases(cases) + if isfile(path): + extract_and_write(path, path) + else: + for root, subdirs, files in os.walk(path): + if '_build' in subdirs: + subdirs.remove('_build') + if 'compilationTests' in subdirs: + subdirs.remove('compilationTests') + for f in files: + path = join(root, f) + extract_and_write(f, path) diff --git a/scripts/tests.sh b/scripts/tests.sh index 7fb260bc..0a1fcdac 100755 --- a/scripts/tests.sh +++ b/scripts/tests.sh @@ -56,7 +56,6 @@ fi function printError() { echo "$(tput setaf 1)$1$(tput sgr0)"; } function printTask() { echo "$(tput bold)$(tput setaf 2)$1$(tput sgr0)"; } - printTask "Running commandline tests..." "$REPO_ROOT/test/cmdlineTests.sh" & CMDLINE_PID=$! @@ -70,58 +69,59 @@ then fi fi -function download_eth() +function download_aleth() { if [[ "$OSTYPE" == "darwin"* ]]; then - ETH_PATH="$REPO_ROOT/eth" + ALETH_PATH="$REPO_ROOT/aleth" elif [ -z $CI ]; then - ETH_PATH="eth" + ALETH_PATH="aleth" else + # Any time the hash is updated here, the "Running compiler tests" section should also be updated. mkdir -p /tmp/test if grep -i trusty /etc/lsb-release >/dev/null 2>&1 then # built from d661ac4fec0aeffbedcdc195f67f5ded0c798278 at 2018-06-20 - ETH_BINARY=aleth_2018-06-20_trusty - ETH_HASH="54b8a5455e45b295e3a962f353ff8f1580ed106c" + ALETH_BINARY=aleth_2018-06-20_trusty + ALETH_HASH="54b8a5455e45b295e3a962f353ff8f1580ed106c" else # built from d661ac4fec0aeffbedcdc195f67f5ded0c798278 at 2018-06-20 - ETH_BINARY=aleth_2018-06-20_artful - ETH_HASH="02e6c4b3d98299885e73f7db6c9e3fbe3d66d444" + ALETH_BINARY=aleth_2018-06-20_artful + ALETH_HASH="02e6c4b3d98299885e73f7db6c9e3fbe3d66d444" fi - wget -q -O /tmp/test/eth https://github.com/ethereum/cpp-ethereum/releases/download/solidityTester/$ETH_BINARY - test "$(shasum /tmp/test/eth)" = "$ETH_HASH /tmp/test/eth" + ALETH_PATH="/tmp/test/aleth" + wget -q -O $ALETH_PATH https://github.com/ethereum/cpp-ethereum/releases/download/solidityTester/$ALETH_BINARY + test "$(shasum $ALETH_PATH)" = "$ALETH_HASH $ALETH_PATH" sync - chmod +x /tmp/test/eth + chmod +x $ALETH_PATH sync # Otherwise we might get a "text file busy" error - ETH_PATH="/tmp/test/eth" fi } # $1: data directory # echos the PID -function run_eth() +function run_aleth() { - $ETH_PATH --test -d "$1" >/dev/null 2>&1 & + $ALETH_PATH --test -d "$1" >/dev/null 2>&1 & echo $! # Wait until the IPC endpoint is available. while [ ! -S "$1"/geth.ipc ] ; do sleep 1; done sleep 2 } -function check_eth() { - printTask "Running IPC tests with $ETH_PATH..." - if ! hash $ETH_PATH 2>/dev/null; then - printError "$ETH_PATH not found" +function check_aleth() { + printTask "Running IPC tests with $ALETH_PATH..." + if ! hash $ALETH_PATH 2>/dev/null; then + printError "$ALETH_PATH not found" exit 1 fi } if [ "$IPC_ENABLED" = true ]; then - download_eth - check_eth - ETH_PID=$(run_eth /tmp/test) + download_aleth + check_aleth + ALETH_PID=$(run_aleth /tmp/test) fi progress="--show-progress" @@ -166,7 +166,7 @@ fi if [ "$IPC_ENABLED" = true ] then - pkill "$ETH_PID" || true + pkill "$ALETH_PID" || true sleep 4 - pgrep "$ETH_PID" && pkill -9 "$ETH_PID" || true + pgrep "$ALETH_PID" && pkill -9 "$ALETH_PID" || true fi diff --git a/solc/CommandLineInterface.cpp b/solc/CommandLineInterface.cpp index 8b331c75..6a768a00 100644 --- a/solc/CommandLineInterface.cpp +++ b/solc/CommandLineInterface.cpp @@ -447,7 +447,7 @@ bool CommandLineInterface::readInputFilesAndConfigureRemappings() m_sourceCodes[g_stdinFileName] = dev::readStandardInput(); if (m_sourceCodes.size() == 0) { - cerr << "No input files given. If you wish to use the standard input please specify \"-\" explicity." << endl; + cerr << "No input files given. If you wish to use the standard input please specify \"-\" explicitly." << endl; return false; } @@ -986,10 +986,15 @@ void CommandLineInterface::handleAst(string const& _argStr) map<ASTNode const*, eth::GasMeter::GasConsumption> gasCosts; // FIXME: shouldn't this be done for every contract? if (m_compiler->runtimeAssemblyItems(m_compiler->lastContractName())) - gasCosts = GasEstimator::breakToStatementLevel( + { + //NOTE: keep the local variable `ret` to prevent a Heisenbug that could happen on certain mac os platform. + //See: https://github.com/ethereum/solidity/issues/3718 for details. + auto ret = GasEstimator::breakToStatementLevel( GasEstimator(m_evmVersion).structuralEstimation(*m_compiler->runtimeAssemblyItems(m_compiler->lastContractName()), asts), asts ); + gasCosts = ret; + } bool legacyFormat = !m_args.count(g_argAstCompactJson); if (m_args.count(g_argOutputDir)) diff --git a/test/compilationTests/MultiSigWallet/MultiSigWallet.sol b/test/compilationTests/MultiSigWallet/MultiSigWallet.sol index 6b10f17e..35f6208b 100644 --- a/test/compilationTests/MultiSigWallet/MultiSigWallet.sol +++ b/test/compilationTests/MultiSigWallet/MultiSigWallet.sol @@ -33,49 +33,49 @@ contract MultiSigWallet { modifier onlyWallet() { if (msg.sender != address(this)) - throw; + revert(); _; } modifier ownerDoesNotExist(address owner) { if (isOwner[owner]) - throw; + revert(); _; } modifier ownerExists(address owner) { if (!isOwner[owner]) - throw; + revert(); _; } modifier transactionExists(uint transactionId) { if (transactions[transactionId].destination == address(0)) - throw; + revert(); _; } modifier confirmed(uint transactionId, address owner) { if (!confirmations[transactionId][owner]) - throw; + revert(); _; } modifier notConfirmed(uint transactionId, address owner) { if (confirmations[transactionId][owner]) - throw; + revert(); _; } modifier notExecuted(uint transactionId) { if (transactions[transactionId].executed) - throw; + revert(); _; } modifier notNull(address _address) { if (_address == address(0)) - throw; + revert(); _; } @@ -84,7 +84,7 @@ contract MultiSigWallet { || _required > ownerCount || _required == 0 || ownerCount == 0) - throw; + revert(); _; } @@ -103,13 +103,13 @@ contract MultiSigWallet { /// @dev Contract constructor sets initial owners and required number of confirmations. /// @param _owners List of initial owners. /// @param _required Number of required confirmations. - constructor(address[] _owners, uint _required) + constructor(address[] memory _owners, uint _required) public validRequirement(_owners.length, _required) { for (uint i=0; i<_owners.length; i++) { if (isOwner[_owners[i]] || _owners[i] == address(0)) - throw; + revert(); isOwner[_owners[i]] = true; } owners = _owners; @@ -185,7 +185,7 @@ contract MultiSigWallet { /// @param value Transaction ether value. /// @param data Transaction data payload. /// @return Returns transaction ID. - function submitTransaction(address destination, uint value, bytes data) + function submitTransaction(address destination, uint value, bytes memory data) public returns (uint transactionId) { @@ -225,7 +225,7 @@ contract MultiSigWallet { notExecuted(transactionId) { if (isConfirmed(transactionId)) { - Transaction tx = transactions[transactionId]; + Transaction storage tx = transactions[transactionId]; tx.executed = true; if (tx.destination.call.value(tx.value)(tx.data)) emit Execution(transactionId); @@ -261,7 +261,7 @@ contract MultiSigWallet { /// @param value Transaction ether value. /// @param data Transaction data payload. /// @return Returns transaction ID. - function addTransaction(address destination, uint value, bytes data) + function addTransaction(address destination, uint value, bytes memory data) internal notNull(destination) returns (uint transactionId) @@ -313,7 +313,7 @@ contract MultiSigWallet { function getOwners() public view - returns (address[]) + returns (address[] memory) { return owners; } @@ -324,7 +324,7 @@ contract MultiSigWallet { function getConfirmations(uint transactionId) public view - returns (address[] _confirmations) + returns (address[] memory _confirmations) { address[] memory confirmationsTemp = new address[](owners.length); uint count = 0; @@ -348,7 +348,7 @@ contract MultiSigWallet { function getTransactionIds(uint from, uint to, bool pending, bool executed) public view - returns (uint[] _transactionIds) + returns (uint[] memory _transactionIds) { uint[] memory transactionIdsTemp = new uint[](transactionCount); uint count = 0; diff --git a/test/compilationTests/MultiSigWallet/MultiSigWalletFactory.sol b/test/compilationTests/MultiSigWallet/MultiSigWalletFactory.sol index cb58ab1c..16219aa2 100644 --- a/test/compilationTests/MultiSigWallet/MultiSigWalletFactory.sol +++ b/test/compilationTests/MultiSigWallet/MultiSigWalletFactory.sol @@ -11,7 +11,7 @@ contract MultiSigWalletFactory is Factory { /// @param _owners List of initial owners. /// @param _required Number of required confirmations. /// @return Returns wallet address. - function create(address[] _owners, uint _required) + function create(address[] memory _owners, uint _required) public returns (address wallet) { diff --git a/test/compilationTests/MultiSigWallet/MultiSigWalletWithDailyLimit.sol b/test/compilationTests/MultiSigWallet/MultiSigWalletWithDailyLimit.sol index 3a68f662..69e94fd5 100644 --- a/test/compilationTests/MultiSigWallet/MultiSigWalletWithDailyLimit.sol +++ b/test/compilationTests/MultiSigWallet/MultiSigWalletWithDailyLimit.sol @@ -19,7 +19,7 @@ contract MultiSigWalletWithDailyLimit is MultiSigWallet { /// @param _owners List of initial owners. /// @param _required Number of required confirmations. /// @param _dailyLimit Amount in wei, which can be withdrawn without confirmations on a daily basis. - constructor(address[] _owners, uint _required, uint _dailyLimit) + constructor(address[] memory _owners, uint _required, uint _dailyLimit) public MultiSigWallet(_owners, _required) { @@ -42,7 +42,7 @@ contract MultiSigWalletWithDailyLimit is MultiSigWallet { public notExecuted(transactionId) { - Transaction tx = transactions[transactionId]; + Transaction storage tx = transactions[transactionId]; bool confirmed = isConfirmed(transactionId); if (confirmed || tx.data.length == 0 && isUnderLimit(tx.value)) { tx.executed = true; diff --git a/test/compilationTests/MultiSigWallet/MultiSigWalletWithDailyLimitFactory.sol b/test/compilationTests/MultiSigWallet/MultiSigWalletWithDailyLimitFactory.sol index 8a2efa32..e4cfc031 100644 --- a/test/compilationTests/MultiSigWallet/MultiSigWalletWithDailyLimitFactory.sol +++ b/test/compilationTests/MultiSigWallet/MultiSigWalletWithDailyLimitFactory.sol @@ -12,7 +12,7 @@ contract MultiSigWalletWithDailyLimitFactory is Factory { /// @param _required Number of required confirmations. /// @param _dailyLimit Amount in wei, which can be withdrawn without confirmations on a daily basis. /// @return Returns wallet address. - function create(address[] _owners, uint _required, uint _dailyLimit) + function create(address[] memory _owners, uint _required, uint _dailyLimit) public returns (address wallet) { diff --git a/test/compilationTests/MultiSigWallet/TestToken.sol b/test/compilationTests/MultiSigWallet/TestToken.sol index df195c58..a100b449 100644 --- a/test/compilationTests/MultiSigWallet/TestToken.sol +++ b/test/compilationTests/MultiSigWallet/TestToken.sol @@ -27,7 +27,7 @@ contract TestToken { returns (bool success) { if (balances[msg.sender] < _value) { - throw; + revert(); } balances[msg.sender] -= _value; balances[_to] += _value; @@ -40,7 +40,7 @@ contract TestToken { returns (bool success) { if (balances[_from] < _value || allowed[_from][msg.sender] < _value) { - throw; + revert(); } balances[_to] += _value; balances[_from] -= _value; diff --git a/test/compilationTests/corion/ico.sol b/test/compilationTests/corion/ico.sol index b6d8e035..2f60e0fe 100644 --- a/test/compilationTests/corion/ico.sol +++ b/test/compilationTests/corion/ico.sol @@ -49,8 +49,8 @@ contract ico is safeMath { mapping (address => mapping(uint256 => interest_s)) public interestDB; uint256 public totalMint; uint256 public totalPremiumMint; - - constructor(address foundation, address priceSet, uint256 exchangeRate, uint256 startBlockNum, address[] genesisAddr, uint256[] genesisValue) { + + constructor(address foundation, address priceSet, uint256 exchangeRate, uint256 startBlockNum, address[] memory genesisAddr, uint256[] memory genesisValue) public { /* Installation function. @@ -231,7 +231,7 @@ contract ico is safeMath { require( ! aborted ); require( token(tokenAddr).mint(foundationAddress, token(tokenAddr).totalSupply() * 96 / 100) ); require( premium(premiumAddr).mint(foundationAddress, totalMint / 5000 - totalPremiumMint) ); - require( foundationAddress.send(this.balance) ); + require( foundationAddress.send(address(this).balance) ); require( token(tokenAddr).closeIco() ); require( premium(premiumAddr).closeIco() ); } @@ -277,22 +277,22 @@ contract ico is safeMath { function () external payable { /* - Callback function. Simply calls the buy function as a beneficiary and there is no affilate address. + Callback function. Simply calls the buy function as a beneficiary and there is no affiliate address. If they call the contract without any function then this process will be taken place. */ require( isICO() ); require( buy(msg.sender, address(0x00)) ); } - - function buy(address beneficiaryAddress, address affilateAddress) payable returns (bool success) { + + function buy(address beneficiaryAddress, address affilateAddress) public payable returns (bool success) { /* Buying a token If there is not at least 0.2 ether balance on the beneficiaryAddress then the amount of the ether which was intended for the purchase will be reduced by 0.2 and that will be sent to the address of the beneficiary. From the remaining amount calculate the reward with the help of the getIcoReward function. - Only that affilate address is valid which has some token on it’s account. - If there is a valid affilate address then calculate and credit the reward as well in the following way: - With more than 1e12 token contract credit 5% reward based on the calculation that how many tokens did they buy when he was added as an affilate. + Only that affiliate address is valid which has some token on it’s account. + If there is a valid affiliate address then calculate and credit the reward as well in the following way: + With more than 1e12 token contract credit 5% reward based on the calculation that how many tokens did they buy when he was added as an affiliate. More than 1e11 token: 4% More than 1e10 token: 3% More than 1e9 token: 2% below 1% @@ -345,7 +345,7 @@ contract ico is safeMath { /* Crediting the premium token - @owner The corion token balance of this address will be set based on the calculation which shows that how many times can be the amount of the purchased tokens devided by 5000. So after each 5000 token we give 1 premium token. + @owner The corion token balance of this address will be set based on the calculation which shows that how many times can be the amount of the purchased tokens divided by 5000. So after each 5000 token we give 1 premium token. */ uint256 _reward = (brought[owner].cor / 5e9) - brought[owner].corp; if ( _reward > 0 ) { @@ -372,5 +372,5 @@ contract ico is safeMath { return startBlock <= block.number && block.number <= icoDelay && ( ! aborted ) && ( ! closed ); } - event EICO(address indexed Address, uint256 indexed value, address Affilate, uint256 AffilateValue); + event EICO(address indexed Address, uint256 indexed value, address Affiliate, uint256 AffilateValue); } diff --git a/test/compilationTests/corion/module.sol b/test/compilationTests/corion/module.sol index 362283ef..e0084ea5 100644 --- a/test/compilationTests/corion/module.sol +++ b/test/compilationTests/corion/module.sol @@ -95,8 +95,8 @@ contract module { if ( _balance > 0 ) { require( abstractModuleHandler(moduleHandlerAddress).transfer(address(this), newModuleAddress, _balance, false) ); } - if ( this.balance > 0 ) { - require( newModuleAddress.send(this.balance) ); + if ( address(this).balance > 0 ) { + require( newModuleAddress.send(address(this).balance) ); } moduleStatus = status.Disconnected; } @@ -131,7 +131,7 @@ contract module { /* Check self for ready for functions or not. - @success Function call was successfull or not + @success Function call was successful or not @active Ready for functions or not */ return (true, moduleStatus == status.Connected && block.number >= disabledUntil); diff --git a/test/compilationTests/corion/moduleHandler.sol b/test/compilationTests/corion/moduleHandler.sol index b3d03c2a..ce53114b 100644 --- a/test/compilationTests/corion/moduleHandler.sol +++ b/test/compilationTests/corion/moduleHandler.sol @@ -34,10 +34,10 @@ contract moduleHandler is multiOwner, announcementTypes { modules_s[] public modules; address public foundationAddress; uint256 debugModeUntil = block.number + 1000000; - - - constructor(address[] newOwners) multiOwner(newOwners) {} - function load(address foundation, bool forReplace, address Token, address Premium, address Publisher, address Schelling, address Provider) { + + + constructor(address[] memory newOwners) multiOwner(newOwners) public {} + function load(address foundation, bool forReplace, address Token, address Premium, address Publisher, address Schelling, address Provider) public { /* Loading modulest to ModuleHandler. @@ -60,10 +60,10 @@ contract moduleHandler is multiOwner, announcementTypes { addModule( modules_s(Schelling, keccak256('Schelling'), false, true), ! forReplace); addModule( modules_s(Provider, keccak256('Provider'), true, true), ! forReplace); } - function addModule(modules_s input, bool call) internal { + function addModule(modules_s memory input, bool call) internal { /* Inside function for registration of the modules in the database. - If the call is false, wont happen any direct call. + If the call is false, won't happen any direct call. @input _Structure of module. @call Is connect to the module or not. @@ -81,14 +81,14 @@ contract moduleHandler is multiOwner, announcementTypes { } modules[id] = input; } - function getModuleAddressByName(string name) public view returns( bool success, bool found, address addr ) { + function getModuleAddressByName(string memory name) public view returns( bool success, bool found, address addr ) { /* Search by name for module. The result is an Ethereum address. @name Name of module. @addr Address of module. @found Is there any result. - @success Was the transaction succesfull or not. + @success Was the transaction successful or not. */ (bool _success, bool _found, uint256 _id) = getModuleIDByName(name); if ( _success && _found ) { return (true, true, modules[_id].addr); } @@ -109,7 +109,7 @@ contract moduleHandler is multiOwner, announcementTypes { } return (true, false, 0); } - function getModuleIDByName(string name) public view returns( bool success, bool found, uint256 id ) { + function getModuleIDByName(string memory name) public view returns( bool success, bool found, uint256 id ) { /* Search by name for module. The result is an index array. @@ -177,7 +177,7 @@ contract moduleHandler is multiOwner, announcementTypes { require( abstractModule(modules[_id].addr).replaceModule(newModule) ); return true; } - + function newModule(string 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. @@ -204,7 +204,7 @@ contract moduleHandler is multiOwner, announcementTypes { Deleting module from the database. Can be called only by the Publisher contract. @name Name of module to delete. - @bool Was the function successfull? + @bool Was the function successful? @callCallback Call the replaceable module to confirm replacement or not. */ (bool _success, bool _found, uint256 _id) = getModuleIDByAddress(msg.sender); @@ -245,7 +245,7 @@ contract moduleHandler is multiOwner, announcementTypes { @from from who. @to to who. @value amount. - @bool Was the function successfull? + @bool Was the function successful? */ (bool _success, bool _found, uint256 _id) = getModuleIDByAddress(msg.sender); require( _success && _found && modules[_id].name == keccak256('Token') ); @@ -264,7 +264,7 @@ contract moduleHandler is multiOwner, announcementTypes { @roundID Number of Schelling round. @reward Coin emission in this Schelling round. - @bool Was the function successfull? + @bool Was the function successful? */ (bool _success, bool _found, uint256 _id) = getModuleIDByAddress(msg.sender); require( _success && _found && modules[_id].name == keccak256('Schelling') ); @@ -283,7 +283,7 @@ contract moduleHandler is multiOwner, announcementTypes { Every module will be informed about the ModuleHandler replacement. @newHandler Address of the new ModuleHandler. - @bool Was the function successfull? + @bool Was the function successful? */ (bool _success, bool _found, uint256 _id) = getModuleIDByAddress(msg.sender); require( _success ); @@ -304,7 +304,7 @@ contract moduleHandler is multiOwner, announcementTypes { @owner address @value balance. - @success was the function successfull? + @success was the function successful? */ (bool _success, bool _found, uint256 _id) = getModuleIDByName('Token'); require( _success && _found ); @@ -315,7 +315,7 @@ contract moduleHandler is multiOwner, announcementTypes { Query of the whole token amount. @value amount. - @success was the function successfull? + @success was the function successful? */ (bool _success, bool _found, uint256 _id) = getModuleIDByName('Token'); require( _success && _found ); @@ -326,7 +326,7 @@ contract moduleHandler is multiOwner, announcementTypes { Query of ICO state @ico Is ICO in progress?. - @success was the function successfull? + @success was the function successful? */ (bool _success, bool _found, uint256 _id) = getModuleIDByName('Token'); require( _success && _found ); @@ -337,7 +337,7 @@ contract moduleHandler is multiOwner, announcementTypes { Query of number of the actual Schelling round. @round Schelling round. - @success was the function successfull? + @success was the function successful? */ (bool _success, bool _found, uint256 _id) = getModuleIDByName('Schelling'); require( _success && _found ); @@ -350,7 +350,7 @@ contract moduleHandler is multiOwner, announcementTypes { @to Place of new token @value Token amount - @success Was the function successfull? + @success Was the function successful? */ (bool _success, bool _found, uint256 _id) = getModuleIDByAddress(msg.sender); require( _success && _found && modules[_id].name == keccak256('Provider') ); @@ -367,7 +367,7 @@ contract moduleHandler is multiOwner, announcementTypes { @to To who. @value Token amount. @fee Transaction fee will be charged or not? - @success Was the function successfull? + @success Was the function successful? */ (bool _success, bool _found, uint256 _id) = getModuleIDByAddress(msg.sender); require( _success && _found ); @@ -382,7 +382,7 @@ contract moduleHandler is multiOwner, announcementTypes { @from From who. @value Token amount. - @success Was the function successfull? + @success Was the function successful? */ (bool _success, bool _found, uint256 _id) = getModuleIDByAddress(msg.sender); require( _success && _found && modules[_id].name == keccak256('Provider') ); @@ -397,7 +397,7 @@ contract moduleHandler is multiOwner, announcementTypes { @from From who. @value Token amount. - @success Was the function successfull? + @success Was the function successful? */ (bool _success, bool _found, uint256 _id) = getModuleIDByAddress(msg.sender); require( _success && _found && modules[_id].name == keccak256('Schelling') ); @@ -413,7 +413,7 @@ contract moduleHandler is multiOwner, announcementTypes { @moduleName Module name which will be configured @aType Type of variable (announcementType). @value New value - @success Was the function successfull? + @success Was the function successful? */ (bool _success, bool _found, uint256 _id) = getModuleIDByAddress(msg.sender); require( _success ); @@ -431,7 +431,7 @@ contract moduleHandler is multiOwner, announcementTypes { function freezing(bool forever) external { /* Freezing CORION Platform. Can be called only by the owner. - Freez can not be recalled! + Freeze can not be recalled! @forever Is it forever or not? */ diff --git a/test/compilationTests/corion/multiOwner.sol b/test/compilationTests/corion/multiOwner.sol index 78f7109c..ecc51ac3 100644 --- a/test/compilationTests/corion/multiOwner.sol +++ b/test/compilationTests/corion/multiOwner.sol @@ -12,7 +12,7 @@ contract multiOwner is safeMath { /* Constructor */ - constructor(address[] newOwners) { + constructor(address[] memory newOwners) public { for ( uint256 a=0 ; a<newOwners.length ; a++ ) { _addOwner(newOwners[a]); } @@ -41,7 +41,7 @@ contract multiOwner is safeMath { function ownersForChange() public view returns (uint256 owners) { return ownerCount * 75 / 100; } - function calcDoHash(string job, bytes32 data) public pure returns (bytes32 hash) { + function calcDoHash(string memory job, bytes32 data) public pure returns (bytes32 hash) { return keccak256(abi.encodePacked(job, data)); } function validDoHash(bytes32 doHash) public view returns (bool valid) { diff --git a/test/compilationTests/corion/premium.sol b/test/compilationTests/corion/premium.sol index 695dd344..45fe7666 100644 --- a/test/compilationTests/corion/premium.sol +++ b/test/compilationTests/corion/premium.sol @@ -39,8 +39,8 @@ contract premium is module, safeMath { bool public isICO; mapping(address => bool) public genesis; - - constructor(bool forReplace, address moduleHandler, address dbAddress, address icoContractAddr, address[] genesisAddr, uint256[] genesisValue) { + + constructor(bool forReplace, address moduleHandler, address dbAddress, address icoContractAddr, address[] memory genesisAddr, uint256[] memory genesisValue) public { /* Setup function. If an ICOaddress is defined then the balance of the genesis addresses will be set as well. @@ -118,7 +118,7 @@ contract premium is module, safeMath { @extraData Extra data to be received by the receiver @nonce Transaction count - @sucess Was the Function successful? + @success Was the Function successful? */ _approve(spender, amount, nonce); require( thirdPartyPContractAbstract(spender).approvedCorionPremiumToken(msg.sender, amount, extraData) ); @@ -139,8 +139,8 @@ contract premium is module, safeMath { require( db.setAllowance(msg.sender, spender, amount, nonce) ); emit Approval(msg.sender, spender, amount); } - - function allowance(address owner, address spender) view returns (uint256 remaining, uint256 nonce) { + + function allowance(address owner, address spender) public view returns (uint256 remaining, uint256 nonce) { /* Get the quantity of tokens given to be used @@ -246,7 +246,7 @@ contract premium is module, safeMath { return true; } - function transferToContract(address from, address to, uint256 amount, bytes extraData) internal { + function transferToContract(address from, address to, uint256 amount, bytes memory extraData) internal { /* Inner function in order to transact a contract. @@ -318,8 +318,8 @@ contract premium is module, safeMath { } return _codeLength > 0; } - - function balanceOf(address owner) view returns (uint256 value) { + + function balanceOf(address owner) public view returns (uint256 value) { /* Token balance query @@ -328,8 +328,8 @@ contract premium is module, safeMath { */ return db.balanceOf(owner); } - - function totalSupply() view returns (uint256 value) { + + function totalSupply() public view returns (uint256 value) { /* Total token quantity query diff --git a/test/compilationTests/corion/provider.sol b/test/compilationTests/corion/provider.sol index 16546809..7d1e04e3 100644 --- a/test/compilationTests/corion/provider.sol +++ b/test/compilationTests/corion/provider.sol @@ -18,7 +18,7 @@ contract provider is module, safeMath, announcementTypes { } function transferEvent(address from, address to, uint256 value) external returns (bool success) { /* - Transaction completed. This function is ony available for the modulehandler. + Transaction completed. This function is only available for the modulehandler. It should be checked if the sender or the acceptor does not connect to the provider or it is not a provider itself if so than the change should be recorded. @from From whom? @@ -35,7 +35,7 @@ contract provider is module, safeMath, announcementTypes { /* New schelling round. This function is only available for the moduleHandler. We are recording the new schelling round and we are storing the whole current quantity of the tokens. - We generate a reward quantity of tokens directed to the providers address. The collected interest will be tranfered from this contract. + We generate a reward quantity of tokens directed to the providers address. The collected interest will be transferred from this contract. @roundID Number of the schelling round. @reward token emission @@ -118,7 +118,7 @@ contract provider is module, safeMath, announcementTypes { uint256 private currentSchellingRound = 1; - constructor(address _moduleHandler) { + constructor(address _moduleHandler) public { /* Install function. @@ -228,7 +228,7 @@ contract provider is module, safeMath, announcementTypes { @website Provider’s website @country Provider’s country @info Provider’s short introduction. - @rate Rate of the emission what is going to be transfered to the client by the provider. + @rate Rate of the emission what is going to be transferred to the client by the provider. @isForRent is for Rent or not? @admin The admin’s address */ @@ -299,7 +299,7 @@ contract provider is module, safeMath, announcementTypes { providers[addr].data[currHeight].currentRate = rate; emit EProviderDetailsChanged(addr, currHeight, website, country, info, rate, admin); } - function getProviderInfo(address addr, uint256 height) public view returns (string name, string website, string country, string info, uint256 create) { + function getProviderInfo(address addr, uint256 height) public view returns (string memory name, string memory website, string memory country, string memory info, uint256 create) { /* for the infos of the provider. In case the height is unknown then the system will use the last known height. @@ -328,7 +328,7 @@ contract provider is module, safeMath, announcementTypes { @addr Address of the provider @height Height - @rate The rate of the emission which will be transfered to the client. + @rate The rate of the emission which will be transferred to the client. @isForRent Rent or not. @clientsCount Number of the clients. @priv Private or not? @@ -356,7 +356,7 @@ contract provider is module, safeMath, announcementTypes { } function closeProvider() isReady external { /* - Closing and inactivate the provider. + Closing and deactivating the provider. It is only possible to close that active provider which is owned by the sender itself after calling the whole share of the emission. Whom were connected to the provider those clients will have to disconnect after they’ve called their share of emission which was not called before. */ @@ -373,7 +373,7 @@ contract provider is module, safeMath, announcementTypes { /* Permition of the user to be able to connect to the provider. This can only be invited by the provider’s admin. - With this kind of call only 100 address can be permited. + With this kind of call only 100 address can be permitted. @addr Array of the addresses for whom the connection is allowed. */ @@ -391,7 +391,7 @@ contract provider is module, safeMath, announcementTypes { /* Disable of the user not to be able to connect to the provider. It is can called only for the admin of the provider. - With this kind of call only 100 address can be permited. + With this kind of call only 100 address can be permitted. @addr Array of the addresses for whom the connection is allowed. */ @@ -411,7 +411,7 @@ contract provider is module, safeMath, announcementTypes { Providers can not connect to other providers. If is a client at any provider, then it is not possible to connect to other provider one. It is only possible to connect to valid and active providers. - If is an active provider then the client can only connect, if address is permited at the provider (Whitelist). + If is an active provider then the client can only connect, if address is permitted at the provider (Whitelist). At private providers, the number of the client is restricted. If it reaches the limit no further clients are allowed to connect. This process has a transaction fee based on the senders whole token quantity. @@ -487,12 +487,12 @@ contract provider is module, safeMath, announcementTypes { /* Polling the share from the token emission token emission for clients and for providers. - It is optionaly possible to give an address of a beneficiary for whom we can transfer the accumulated amount. In case we don’t enter any address then the amount will be transfered to the caller’s address. + It is optionally possible to give an address of a beneficiary for whom we can transfer the accumulated amount. In case we don’t enter any address then the amount will be transferred to the caller’s address. As the interest should be checked at each schelling round in order to get the share from that so to avoid the overflow of the gas the number of the check-rounds should be limited. - Opcionalisan megadhato az ellenorzes koreinek szama. It is possible to enter optionaly the number of the check-rounds. If it is 0 then it is automatic. + Opcionalisan megadhato az ellenorzes koreinek szama. It is possible to enter optionally the number of the check-rounds. If it is 0 then it is automatic. Provider variable should only be entered if the real owner of the provider is not the caller’s address. In case the client/provider was far behind then it is possible that this function should be called several times to check the total generated schelling rounds and to collect the share. - If is neighter a client nor a provider then the function is not available. + If is neither a client nor a provider then the function is not available. The tokens will be sent to the beneficiary from the address of the provider without any transaction fees. @beneficiary Address of the beneficiary @@ -514,7 +514,7 @@ contract provider is module, safeMath, announcementTypes { } else if ( clients[msg.sender].providerAddress != address(0x00) ) { clientReward = getClientReward(_limit); } else { - throw; + revert(); } if ( clientReward > 0 ) { require( moduleHandler(moduleHandlerAddress).transfer(address(this), _beneficiary, clientReward, false) ); @@ -784,7 +784,7 @@ contract provider is module, safeMath, announcementTypes { /* Inner function to check the ICO status. - @isICO Is the ICO in proccess or not? + @isICO Is the ICO in process or not? */ (bool _success, bool _isICO) = moduleHandler(moduleHandlerAddress).isICO(); require( _success ); diff --git a/test/compilationTests/corion/publisher.sol b/test/compilationTests/corion/publisher.sol index f7d8fdea..575b99a8 100644 --- a/test/compilationTests/corion/publisher.sol +++ b/test/compilationTests/corion/publisher.sol @@ -60,8 +60,8 @@ contract publisher is announcementTypes, module, safeMath { uint256 announcementsLength = 1;
mapping (address => uint256[]) public opponents;
-
- constructor(address moduleHandler) {
+
+ constructor(address moduleHandler) public {
/*
Installation function. The installer will be registered in the admin list automatically
@@ -70,7 +70,7 @@ contract publisher is announcementTypes, module, safeMath { super.registerModuleHandler(moduleHandler);
}
- function Announcements(uint256 id) public view returns (uint256 Type, uint256 Start, uint256 End, bool Closed, string Announcement, string Link, bool Opposited, string _str, uint256 _uint, address _addr) {
+ function Announcements(uint256 id) public view returns (uint256 Type, uint256 Start, uint256 End, bool Closed, string memory Announcement, string memory Link, bool Opposited, string memory _str, uint256 _uint, address _addr) {
/*
Announcement data query
@@ -264,7 +264,7 @@ contract publisher is announcementTypes, module, safeMath { function checkICO() internal returns (bool isICO) {
/*
Inner function to check the ICO status.
- @bool Is the ICO in proccess or not?
+ @bool Is the ICO in process or not?
*/
(bool _success, bool _isICO) = moduleHandler(moduleHandlerAddress).isICO();
require( _success );
diff --git a/test/compilationTests/corion/schelling.sol b/test/compilationTests/corion/schelling.sol index 74f8af9d..3905e300 100644 --- a/test/compilationTests/corion/schelling.sol +++ b/test/compilationTests/corion/schelling.sol @@ -45,7 +45,7 @@ contract schellingDB is safeMath, schellingVars { /* Constructor */ - constructor() { + constructor() public { rounds.length = 2; rounds[0].blockHeight = block.number; currentSchellingRound = 1; @@ -54,7 +54,7 @@ contract schellingDB is safeMath, schellingVars { Funds */ mapping(address => uint256) private funds; - function getFunds(address _owner) view returns(bool, uint256) { + function getFunds(address _owner) public view returns(bool, uint256) { return (true, funds[_owner]); } function setFunds(address _owner, uint256 _amount) isOwner external returns(bool) { @@ -65,7 +65,7 @@ contract schellingDB is safeMath, schellingVars { Rounds */ _rounds[] private rounds; - function getRound(uint256 _id) view returns(bool, uint256, uint256, uint256, uint256, bool) { + function getRound(uint256 _id) public view returns(bool, uint256, uint256, uint256, uint256, bool) { if ( rounds.length <= _id ) { return (false, 0, 0, 0, 0, false); } else { return (true, rounds[_id].totalAboveWeight, rounds[_id].totalBelowWeight, rounds[_id].reward, rounds[_id].blockHeight, rounds[_id].voted); } } @@ -76,14 +76,14 @@ contract schellingDB is safeMath, schellingVars { rounds[_id] = _rounds(_totalAboveWeight, _totalBelowWeight, _reward, _blockHeight, _voted); return true; } - function getCurrentRound() view returns(bool, uint256) { + function getCurrentRound() public view returns(bool, uint256) { return (true, rounds.length-1); } /* Voter */ mapping(address => _voter) private voter; - function getVoter(address _owner) view returns(bool success, uint256 roundID, + function getVoter(address _owner) public view returns(bool success, uint256 roundID, bytes32 hash, voterStatus status, bool voteResult, uint256 rewards) { roundID = voter[_owner].roundID; hash = voter[_owner].hash; @@ -106,7 +106,7 @@ contract schellingDB is safeMath, schellingVars { Schelling Token emission */ mapping(uint256 => uint256) private schellingExpansion; - function getSchellingExpansion(uint256 _id) view returns(bool, uint256) { + function getSchellingExpansion(uint256 _id) public view returns(bool, uint256) { return (true, schellingExpansion[_id]); } function setSchellingExpansion(uint256 _id, uint256 _expansion) isOwner external returns(bool) { @@ -121,7 +121,7 @@ contract schellingDB is safeMath, schellingVars { currentSchellingRound = _id; return true; } - function getCurrentSchellingRound() view returns(bool, uint256) { + function getCurrentSchellingRound() public view returns(bool, uint256) { return (true, currentSchellingRound); } } @@ -147,7 +147,7 @@ contract schelling is module, announcementTypes, schellingVars { @from From who @to To who @value Amount - @bool Was the transaction succesfull? + @bool Was the transaction successful? */ require( super.isModuleHandler(msg.sender) ); if ( to == address(this) ) { @@ -174,7 +174,7 @@ contract schelling is module, announcementTypes, schellingVars { function setFunds(address addr, uint256 amount) internal { require( db.setFunds(addr, amount) ); } - function setVoter(address owner, _voter voter) internal { + function setVoter(address owner, _voter memory voter) internal { require( db.setVoter(owner, voter.roundID, voter.hash, @@ -182,13 +182,13 @@ contract schelling is module, announcementTypes, schellingVars { voter.voteResult, voter.rewards ) ); - } - function getVoter(address addr) internal view returns (_voter) { + } + function getVoter(address addr) internal view returns (_voter memory) { (bool a, uint256 b, bytes32 c, schellingVars.voterStatus d, bool e, uint256 f) = db.getVoter(addr); require( a ); return _voter(b, c, d, e, f); } - function setRound(uint256 id, _rounds round) internal { + function setRound(uint256 id, _rounds memory round) internal { require( db.setRound(id, round.totalAboveWeight, round.totalBelowWeight, @@ -197,8 +197,8 @@ contract schelling is module, announcementTypes, schellingVars { round.voted ) ); } - function pushRound(_rounds round) internal returns (uint256) { - (bool a, uint256 b) = db.pushRound( + function pushRound(_rounds memory round) internal returns (uint256) { + (bool a, uint256 b) = db.pushRound( round.totalAboveWeight, round.totalBelowWeight, round.reward, @@ -208,7 +208,7 @@ contract schelling is module, announcementTypes, schellingVars { require( a ); return b; } - function getRound(uint256 id) internal returns (_rounds) { + function getRound(uint256 id) internal returns (_rounds memory) { (bool a, uint256 b, uint256 c, uint256 d, uint256 e, bool f) = db.getRound(id); require( a ); return _rounds(b, c, d, e, f); @@ -246,8 +246,8 @@ contract schelling is module, announcementTypes, schellingVars { bytes1 public aboveChar = 0x31; bytes1 public belowChar = 0x30; schellingDB private db; - - constructor(address _moduleHandler, address _db, bool _forReplace) { + + constructor(address _moduleHandler, address _db, bool _forReplace) public { /* Installation function. @@ -389,7 +389,7 @@ contract schelling is module, announcementTypes, schellingVars { } delete voter.status; delete voter.roundID; - } else { throw; } + } else { revert(); } setVoter(msg.sender, voter); setFunds(msg.sender, funds); @@ -442,14 +442,14 @@ contract schelling is module, announcementTypes, schellingVars { if ( ! round.voted ) { newRound.reward = round.reward; } - uint256 aboves; + uint256 above; for ( uint256 a=currentRound ; a>=currentRound-interestCheckRounds ; a-- ) { if (a == 0) { break; } prevRound = getRound(a); - if ( prevRound.totalAboveWeight > prevRound.totalBelowWeight ) { aboves++; } + if ( prevRound.totalAboveWeight > prevRound.totalBelowWeight ) { above++; } } uint256 expansion; - if ( aboves >= interestCheckAboves ) { + if ( above >= interestCheckAboves ) { expansion = getTotalSupply() * interestRate / interestRateM / 100; } @@ -529,7 +529,7 @@ contract schelling is module, announcementTypes, schellingVars { return belowW; } } - function isWinner(_rounds round, bool aboveVote) internal returns (bool) { + function isWinner(_rounds memory round, bool aboveVote) internal returns (bool) { /* Inside function for calculating the result of the game. diff --git a/test/compilationTests/corion/token.sol b/test/compilationTests/corion/token.sol index fecbce3d..6c8f6f24 100644 --- a/test/compilationTests/corion/token.sol +++ b/test/compilationTests/corion/token.sol @@ -47,8 +47,8 @@ contract token is safeMath, module, announcementTypes { bool public isICO = true; mapping(address => bool) public genesis; - - constructor(bool forReplace, address moduleHandler, address dbAddr, address icoContractAddr, address exchangeContractAddress, address[] genesisAddr, uint256[] genesisValue) payable { + + constructor(bool forReplace, address moduleHandler, address dbAddr, address icoContractAddr, address exchangeContractAddress, address[] memory genesisAddr, uint256[] memory genesisValue) public payable { /* Installation function @@ -73,7 +73,7 @@ contract token is safeMath, module, announcementTypes { if ( ! forReplace ) { require( db.replaceOwner(this) ); assert( genesisAddr.length == genesisValue.length ); - require( this.balance >= genesisAddr.length * 0.2 ether ); + require( address(this).balance >= genesisAddr.length * 0.2 ether ); for ( uint256 a=0 ; a<genesisAddr.length ; a++ ) { genesis[genesisAddr[a]] = true; require( db.increase(genesisAddr[a], genesisValue[a]) ); @@ -154,8 +154,8 @@ contract token is safeMath, module, announcementTypes { require( db.setAllowance(msg.sender, spender, amount, nonce) ); emit Approval(msg.sender, spender, amount); } - - function allowance(address owner, address spender) view returns (uint256 remaining, uint256 nonce) { + + function allowance(address owner, address spender) public view returns (uint256 remaining, uint256 nonce) { /* Get the quantity of tokens given to be used @@ -288,7 +288,7 @@ contract token is safeMath, module, announcementTypes { return true; } - function _transferToContract(address from, address to, uint256 amount, bytes extraData) internal { + function _transferToContract(address from, address to, uint256 amount, bytes memory extraData) internal { /* Internal function to start transactions to a contract @@ -471,8 +471,8 @@ contract token is safeMath, module, announcementTypes { } return _codeLength > 0; } - - function balanceOf(address owner) view returns (uint256 value) { + + function balanceOf(address owner) public view returns (uint256 value) { /* Token balance query @@ -482,8 +482,8 @@ contract token is safeMath, module, announcementTypes { */ return db.balanceOf(owner); } - - function totalSupply() view returns (uint256 value) { + + function totalSupply() public view returns (uint256 value) { /* Total token quantity query diff --git a/test/compilationTests/corion/tokenDB.sol b/test/compilationTests/corion/tokenDB.sol index 40304a54..484135ca 100644 --- a/test/compilationTests/corion/tokenDB.sol +++ b/test/compilationTests/corion/tokenDB.sol @@ -60,8 +60,8 @@ contract tokenDB is safeMath, ownedDB { allowance[owner][spender].nonce = nonce;
return true;
}
-
- function getAllowance(address owner, address spender) view returns(bool success, uint256 remaining, uint256 nonce) {
+
+ function getAllowance(address owner, address spender) public view returns(bool success, uint256 remaining, uint256 nonce) {
/*
Get allowance from the database.
diff --git a/test/compilationTests/gnosis/Events/Event.sol b/test/compilationTests/gnosis/Events/Event.sol index 177f61df..5b1a550c 100644 --- a/test/compilationTests/gnosis/Events/Event.sol +++ b/test/compilationTests/gnosis/Events/Event.sol @@ -101,7 +101,7 @@ contract Event { function getOutcomeTokens() public view - returns (OutcomeToken[]) + returns (OutcomeToken[] memory) { return outcomeTokens; } @@ -111,7 +111,7 @@ contract Event { function getOutcomeTokenDistribution(address owner) public view - returns (uint[] outcomeTokenDistribution) + returns (uint[] memory outcomeTokenDistribution) { outcomeTokenDistribution = new uint[](outcomeTokens.length); for (uint8 i = 0; i < outcomeTokenDistribution.length; i++) diff --git a/test/compilationTests/gnosis/MarketMakers/LMSRMarketMaker.sol b/test/compilationTests/gnosis/MarketMakers/LMSRMarketMaker.sol index cf4fcd7d..4ad285eb 100644 --- a/test/compilationTests/gnosis/MarketMakers/LMSRMarketMaker.sol +++ b/test/compilationTests/gnosis/MarketMakers/LMSRMarketMaker.sol @@ -108,7 +108,7 @@ contract LMSRMarketMaker is MarketMaker { /// @param netOutcomeTokensSold Net outcome tokens sold by market /// @param funding Initial funding for market /// @return Cost level - function calcCostLevel(int logN, int[] netOutcomeTokensSold, uint funding) + function calcCostLevel(int logN, int[] memory netOutcomeTokensSold, uint funding) private view returns(int costLevel) @@ -129,7 +129,7 @@ contract LMSRMarketMaker is MarketMaker { /// @param funding Initial funding for market /// @param outcomeIndex Index of exponential term to extract (for use by marginal price function) /// @return A result structure composed of the sum, the offset used, and the summand associated with the supplied index - function sumExpOffset(int logN, int[] netOutcomeTokensSold, uint funding, uint8 outcomeIndex) + function sumExpOffset(int logN, int[] memory netOutcomeTokensSold, uint funding, uint8 outcomeIndex) private view returns (uint sum, int offset, uint outcomeExpTerm) @@ -171,7 +171,7 @@ contract LMSRMarketMaker is MarketMaker { function getNetOutcomeTokensSold(Market market) private view - returns (int[] quantities) + returns (int[] memory quantities) { quantities = new int[](market.eventContract().getOutcomeCount()); for (uint8 i = 0; i < quantities.length; i++) diff --git a/test/compilationTests/gnosis/Migrations.sol b/test/compilationTests/gnosis/Migrations.sol index c7d09bd2..f1a3ea9d 100644 --- a/test/compilationTests/gnosis/Migrations.sol +++ b/test/compilationTests/gnosis/Migrations.sol @@ -8,15 +8,15 @@ contract Migrations { if (msg.sender == owner) _; } - constructor() { + constructor() public { owner = msg.sender; } - function setCompleted(uint completed) restricted { + function setCompleted(uint completed) public restricted { last_completed_migration = completed; } - function upgrade(address new_address) restricted { + function upgrade(address new_address) public restricted { Migrations upgraded = Migrations(new_address); upgraded.setCompleted(last_completed_migration); } diff --git a/test/compilationTests/gnosis/Oracles/CentralizedOracle.sol b/test/compilationTests/gnosis/Oracles/CentralizedOracle.sol index de182a61..e175dfdb 100644 --- a/test/compilationTests/gnosis/Oracles/CentralizedOracle.sol +++ b/test/compilationTests/gnosis/Oracles/CentralizedOracle.sol @@ -34,7 +34,7 @@ contract CentralizedOracle is Oracle { */ /// @dev Constructor sets owner address and IPFS hash /// @param _ipfsHash Hash identifying off chain event description - constructor(address _owner, bytes _ipfsHash) + constructor(address _owner, bytes memory _ipfsHash) public { // Description hash cannot be null diff --git a/test/compilationTests/gnosis/Oracles/CentralizedOracleFactory.sol b/test/compilationTests/gnosis/Oracles/CentralizedOracleFactory.sol index ca4e37d2..be632070 100644 --- a/test/compilationTests/gnosis/Oracles/CentralizedOracleFactory.sol +++ b/test/compilationTests/gnosis/Oracles/CentralizedOracleFactory.sol @@ -17,7 +17,7 @@ contract CentralizedOracleFactory { /// @dev Creates a new centralized oracle contract /// @param ipfsHash Hash identifying off chain event description /// @return Oracle contract - function createCentralizedOracle(bytes ipfsHash) + function createCentralizedOracle(bytes memory ipfsHash) public returns (CentralizedOracle centralizedOracle) { diff --git a/test/compilationTests/gnosis/Oracles/MajorityOracle.sol b/test/compilationTests/gnosis/Oracles/MajorityOracle.sol index d8097370..4dc1760d 100644 --- a/test/compilationTests/gnosis/Oracles/MajorityOracle.sol +++ b/test/compilationTests/gnosis/Oracles/MajorityOracle.sol @@ -16,7 +16,7 @@ contract MajorityOracle is Oracle { */ /// @dev Allows to create an oracle for a majority vote based on other oracles /// @param _oracles List of oracles taking part in the majority vote - constructor(Oracle[] _oracles) + constructor(Oracle[] memory _oracles) public { // At least 2 oracles should be defined diff --git a/test/compilationTests/gnosis/Oracles/MajorityOracleFactory.sol b/test/compilationTests/gnosis/Oracles/MajorityOracleFactory.sol index 3c02fef4..dbbccc4c 100644 --- a/test/compilationTests/gnosis/Oracles/MajorityOracleFactory.sol +++ b/test/compilationTests/gnosis/Oracles/MajorityOracleFactory.sol @@ -17,7 +17,7 @@ contract MajorityOracleFactory { /// @dev Creates a new majority oracle contract /// @param oracles List of oracles taking part in the majority vote /// @return Oracle contract - function createMajorityOracle(Oracle[] oracles) + function createMajorityOracle(Oracle[] memory oracles) public returns (MajorityOracle majorityOracle) { diff --git a/test/compilationTests/gnosis/Utils/Math.sol b/test/compilationTests/gnosis/Utils/Math.sol index 93456c33..47edcba4 100644 --- a/test/compilationTests/gnosis/Utils/Math.sol +++ b/test/compilationTests/gnosis/Utils/Math.sol @@ -176,7 +176,7 @@ library Math { /// @dev Returns maximum of an array /// @param nums Numbers to look through /// @return Maximum number - function max(int[] nums) + function max(int[] memory nums) public pure returns (int max) diff --git a/test/compilationTests/milestonetracker/MilestoneTracker.sol b/test/compilationTests/milestonetracker/MilestoneTracker.sol index 378f7b73..856fb1a5 100644 --- a/test/compilationTests/milestonetracker/MilestoneTracker.sol +++ b/test/compilationTests/milestonetracker/MilestoneTracker.sol @@ -22,7 +22,7 @@ pragma solidity ^0.4.6; /// @dev This contract tracks the -/// is rules the relation betwen a donor and a recipient +/// is rules the relation between a donor and a recipient /// in order to guaranty to the donor that the job will be done and to guaranty /// to the recipient that he will be paid @@ -83,14 +83,14 @@ contract MilestoneTracker { /// @dev The following modifiers only allow specific roles to call functions /// with these modifiers - modifier onlyRecipient { if (msg.sender != recipient) throw; _; } - modifier onlyArbitrator { if (msg.sender != arbitrator) throw; _; } - modifier onlyDonor { if (msg.sender != donor) throw; _; } + modifier onlyRecipient { if (msg.sender != recipient) revert(); _; } + modifier onlyArbitrator { if (msg.sender != arbitrator) revert(); _; } + modifier onlyDonor { if (msg.sender != donor) revert(); _; } /// @dev The following modifiers prevent functions from being called if the /// campaign has been canceled or if new milestones are being proposed - modifier campaignNotCanceled { if (campaignCanceled) throw; _; } - modifier notChanging { if (changingMilestones) throw; _; } + modifier campaignNotCanceled { if (campaignCanceled) revert(); _; } + modifier notChanging { if (changingMilestones) revert(); _; } // @dev Events to make the payment movements easy to find on the blockchain event NewMilestoneListProposed(); @@ -112,7 +112,7 @@ contract MilestoneTracker { address _arbitrator, address _donor, address _recipient - ) { + ) public { arbitrator = _arbitrator; donor = _donor; recipient = _recipient; @@ -124,7 +124,7 @@ contract MilestoneTracker { ///////// /// @return The number of milestones ever created even if they were canceled - function numberOfMilestones() view returns (uint) { + function numberOfMilestones() public view returns (uint) { return milestones.length; } @@ -135,19 +135,19 @@ contract MilestoneTracker { /// @notice `onlyArbitrator` Reassigns the arbitrator to a new address /// @param _newArbitrator The new arbitrator - function changeArbitrator(address _newArbitrator) onlyArbitrator { + function changeArbitrator(address _newArbitrator) public onlyArbitrator { arbitrator = _newArbitrator; } /// @notice `onlyDonor` Reassigns the `donor` to a new address /// @param _newDonor The new donor - function changeDonor(address _newDonor) onlyDonor { + function changeDonor(address _newDonor) public onlyDonor { donor = _newDonor; } /// @notice `onlyRecipient` Reassigns the `recipient` to a new address /// @param _newRecipient The new recipient - function changeRecipient(address _newRecipient) onlyRecipient { + function changeRecipient(address _newRecipient) public onlyRecipient { recipient = _newRecipient; } @@ -175,8 +175,8 @@ contract MilestoneTracker { /// uint reviewTime /// address paymentSource, /// bytes payData, - function proposeMilestones(bytes _newMilestones - ) onlyRecipient campaignNotCanceled { + function proposeMilestones(bytes memory _newMilestones + ) public onlyRecipient campaignNotCanceled { proposedMilestones = _newMilestones; changingMilestones = true; emit NewMilestoneListProposed(); @@ -189,7 +189,7 @@ contract MilestoneTracker { /// @notice `onlyRecipient` Cancels the proposed milestones and reactivates /// the previous set of milestones - function unproposeMilestones() onlyRecipient campaignNotCanceled { + function unproposeMilestones() public onlyRecipient campaignNotCanceled { delete proposedMilestones; changingMilestones = false; emit NewMilestoneListUnproposed(); @@ -200,12 +200,12 @@ contract MilestoneTracker { /// bytecode; this confirms that the `donor` knows the set of milestones /// they are approving function acceptProposedMilestones(bytes32 _hashProposals - ) onlyDonor campaignNotCanceled { + ) public onlyDonor campaignNotCanceled { uint i; - if (!changingMilestones) throw; - if (keccak256(proposedMilestones) != _hashProposals) throw; + if (!changingMilestones) revert(); + if (keccak256(proposedMilestones) != _hashProposals) revert(); // Cancel all the unfinished milestones for (i=0; i<milestones.length; i++) { @@ -218,7 +218,7 @@ contract MilestoneTracker { RLP.RLPItem memory itmProposals = mProposedMilestones.toRLPItem(true); - if (!itmProposals.isList()) throw; + if (!itmProposals.isList()) revert(); RLP.Iterator memory itrProposals = itmProposals.iterator(); @@ -227,9 +227,9 @@ contract MilestoneTracker { RLP.RLPItem memory itmProposal = itrProposals.next(); - Milestone milestone = milestones[milestones.length ++]; + Milestone storage milestone = milestones[milestones.length ++]; - if (!itmProposal.isList()) throw; + if (!itmProposal.isList()) revert(); RLP.Iterator memory itrProposal = itmProposal.iterator(); @@ -256,16 +256,16 @@ contract MilestoneTracker { /// ready for review /// @param _idMilestone ID of the milestone that has been completed function markMilestoneComplete(uint _idMilestone) - campaignNotCanceled notChanging + public campaignNotCanceled notChanging { - if (_idMilestone >= milestones.length) throw; - Milestone milestone = milestones[_idMilestone]; + if (_idMilestone >= milestones.length) revert(); + Milestone storage milestone = milestones[_idMilestone]; if ( (msg.sender != milestone.milestoneLeadLink) &&(msg.sender != recipient)) - throw; - if (milestone.status != MilestoneStatus.AcceptedAndInProgress) throw; - if (now < milestone.minCompletionDate) throw; - if (now > milestone.maxCompletionDate) throw; + revert(); + if (milestone.status != MilestoneStatus.AcceptedAndInProgress) revert(); + if (now < milestone.minCompletionDate) revert(); + if (now > milestone.maxCompletionDate) revert(); milestone.status = MilestoneStatus.Completed; milestone.doneTime = now; emit ProposalStatusChanged(_idMilestone, milestone.status); @@ -274,12 +274,12 @@ contract MilestoneTracker { /// @notice `onlyReviewer` Approves a specific milestone /// @param _idMilestone ID of the milestone that is approved function approveCompletedMilestone(uint _idMilestone) - campaignNotCanceled notChanging + public campaignNotCanceled notChanging { - if (_idMilestone >= milestones.length) throw; - Milestone milestone = milestones[_idMilestone]; + if (_idMilestone >= milestones.length) revert(); + Milestone storage milestone = milestones[_idMilestone]; if ((msg.sender != milestone.reviewer) || - (milestone.status != MilestoneStatus.Completed)) throw; + (milestone.status != MilestoneStatus.Completed)) revert(); authorizePayment(_idMilestone); } @@ -289,12 +289,12 @@ contract MilestoneTracker { /// state /// @param _idMilestone ID of the milestone that is being rejected function rejectMilestone(uint _idMilestone) - campaignNotCanceled notChanging + public campaignNotCanceled notChanging { - if (_idMilestone >= milestones.length) throw; - Milestone milestone = milestones[_idMilestone]; + if (_idMilestone >= milestones.length) revert(); + Milestone storage milestone = milestones[_idMilestone]; if ((msg.sender != milestone.reviewer) || - (milestone.status != MilestoneStatus.Completed)) throw; + (milestone.status != MilestoneStatus.Completed)) revert(); milestone.status = MilestoneStatus.AcceptedAndInProgress; emit ProposalStatusChanged(_idMilestone, milestone.status); @@ -305,15 +305,15 @@ contract MilestoneTracker { /// `reviewTime` has elapsed /// @param _idMilestone ID of the milestone to be paid out function requestMilestonePayment(uint _idMilestone - ) campaignNotCanceled notChanging { - if (_idMilestone >= milestones.length) throw; - Milestone milestone = milestones[_idMilestone]; + ) public campaignNotCanceled notChanging { + if (_idMilestone >= milestones.length) revert(); + Milestone storage milestone = milestones[_idMilestone]; if ( (msg.sender != milestone.milestoneLeadLink) &&(msg.sender != recipient)) - throw; + revert(); if ((milestone.status != MilestoneStatus.Completed) || (now < milestone.doneTime + milestone.reviewTime)) - throw; + revert(); authorizePayment(_idMilestone); } @@ -321,13 +321,13 @@ contract MilestoneTracker { /// @notice `onlyRecipient` Cancels a previously accepted milestone /// @param _idMilestone ID of the milestone to be canceled function cancelMilestone(uint _idMilestone) - onlyRecipient campaignNotCanceled notChanging + public onlyRecipient campaignNotCanceled notChanging { - if (_idMilestone >= milestones.length) throw; - Milestone milestone = milestones[_idMilestone]; + if (_idMilestone >= milestones.length) revert(); + Milestone storage milestone = milestones[_idMilestone]; if ((milestone.status != MilestoneStatus.AcceptedAndInProgress) && (milestone.status != MilestoneStatus.Completed)) - throw; + revert(); milestone.status = MilestoneStatus.Canceled; emit ProposalStatusChanged(_idMilestone, milestone.status); @@ -337,31 +337,31 @@ contract MilestoneTracker { /// has not been paid or canceled /// @param _idMilestone ID of the milestone to be paid out function arbitrateApproveMilestone(uint _idMilestone - ) onlyArbitrator campaignNotCanceled notChanging { - if (_idMilestone >= milestones.length) throw; - Milestone milestone = milestones[_idMilestone]; + ) public onlyArbitrator campaignNotCanceled notChanging { + if (_idMilestone >= milestones.length) revert(); + Milestone storage milestone = milestones[_idMilestone]; if ((milestone.status != MilestoneStatus.AcceptedAndInProgress) && (milestone.status != MilestoneStatus.Completed)) - throw; + revert(); authorizePayment(_idMilestone); } /// @notice `onlyArbitrator` Cancels the entire campaign voiding all /// milestones. - function arbitrateCancelCampaign() onlyArbitrator campaignNotCanceled { + function arbitrateCancelCampaign() public onlyArbitrator campaignNotCanceled { campaignCanceled = true; emit CampaignCanceled(); } // @dev This internal function is executed when the milestone is paid out function authorizePayment(uint _idMilestone) internal { - if (_idMilestone >= milestones.length) throw; - Milestone milestone = milestones[_idMilestone]; + if (_idMilestone >= milestones.length) revert(); + Milestone storage milestone = milestones[_idMilestone]; // Recheck again to not pay twice - if (milestone.status == MilestoneStatus.AuthorizedForPayment) throw; + if (milestone.status == MilestoneStatus.AuthorizedForPayment) revert(); milestone.status = MilestoneStatus.AuthorizedForPayment; if (!milestone.paymentSource.call.value(0)(milestone.payData)) - throw; + revert(); emit ProposalStatusChanged(_idMilestone, milestone.status); } } diff --git a/test/compilationTests/milestonetracker/RLP.sol b/test/compilationTests/milestonetracker/RLP.sol index e96bb332..e261bf23 100644 --- a/test/compilationTests/milestonetracker/RLP.sol +++ b/test/compilationTests/milestonetracker/RLP.sol @@ -39,13 +39,13 @@ library RLP { self._unsafe_nextPtr = ptr + itemLength; } else - throw; + revert(); } function next(Iterator memory self, bool strict) internal view returns (RLPItem memory subItem) { subItem = next(self); if(strict && !_validate(subItem)) - throw; + revert(); return; } @@ -80,11 +80,11 @@ library RLP { if(strict) { uint len = self.length; if(_payloadOffset(item) > len) - throw; + revert(); if(_itemLength(item._unsafe_memPtr) != len) - throw; + revert(); if(!_validate(item)) - throw; + revert(); } return item; } @@ -160,7 +160,7 @@ library RLP { /// @return An 'Iterator' over the item. function iterator(RLPItem memory self) internal view returns (Iterator memory it) { if (!isList(self)) - throw; + revert(); uint ptr = self._unsafe_memPtr + _payloadOffset(self); it._unsafe_item = self; it._unsafe_nextPtr = ptr; @@ -183,7 +183,7 @@ library RLP { /// @return The decoded string. function toData(RLPItem memory self) internal returns (bytes memory bts) { if(!isData(self)) - throw; + revert(); (uint rStartPos, uint len) = _decode(self); bts = new bytes(len); _copyToBytes(rStartPos, bts, len); @@ -195,7 +195,7 @@ library RLP { /// @return Array of RLPItems. function toList(RLPItem memory self) internal view returns (RLPItem[] memory list) { if(!isList(self)) - throw; + revert(); uint numItems = items(self); list = new RLPItem[](numItems); Iterator memory it = iterator(self); @@ -212,7 +212,7 @@ library RLP { /// @return The decoded string. function toAscii(RLPItem memory self) internal returns (string memory str) { if(!isData(self)) - throw; + revert(); (uint rStartPos, uint len) = _decode(self); bytes memory bts = new bytes(len); _copyToBytes(rStartPos, bts, len); @@ -225,10 +225,10 @@ library RLP { /// @return The decoded string. function toUint(RLPItem memory self) internal view returns (uint data) { if(!isData(self)) - throw; + revert(); (uint rStartPos, uint len) = _decode(self); if (len > 32 || len == 0) - throw; + revert(); assembly { data := div(mload(rStartPos), exp(256, sub(32, len))) } @@ -240,16 +240,16 @@ library RLP { /// @return The decoded string. function toBool(RLPItem memory self) internal view returns (bool data) { if(!isData(self)) - throw; + revert(); (uint rStartPos, uint len) = _decode(self); if (len != 1) - throw; + revert(); uint temp; assembly { temp := byte(0, mload(rStartPos)) } if (temp > 1) - throw; + revert(); return temp == 1 ? true : false; } @@ -259,10 +259,10 @@ library RLP { /// @return The decoded string. function toByte(RLPItem memory self) internal view returns (byte data) { if(!isData(self)) - throw; + revert(); (uint rStartPos, uint len) = _decode(self); if (len != 1) - throw; + revert(); uint8 temp; assembly { temp := byte(0, mload(rStartPos)) @@ -292,10 +292,10 @@ library RLP { /// @return The decoded string. function toAddress(RLPItem memory self) internal view returns (address data) { if(!isData(self)) - throw; + revert(); (uint rStartPos, uint len) = _decode(self); if (len != 20) - throw; + revert(); assembly { data := div(mload(rStartPos), exp(256, 12)) } @@ -350,7 +350,7 @@ library RLP { // Get start position and length of the data. function _decode(RLPItem memory self) private view returns (uint memPtr, uint len) { if(!isData(self)) - throw; + revert(); uint b0; uint start = self._unsafe_memPtr; assembly { diff --git a/test/compilationTests/stringutils/strings.sol b/test/compilationTests/stringutils/strings.sol index fc46ec5a..390fb5d9 100644 --- a/test/compilationTests/stringutils/strings.sol +++ b/test/compilationTests/stringutils/strings.sol @@ -63,7 +63,7 @@ library strings { * @param self The string to make a slice from. * @return A newly allocated slice containing the entire string. */ - function toSlice(string self) internal returns (slice) { + function toSlice(string memory self) internal returns (slice memory) { uint ptr; assembly { ptr := add(self, 0x20) @@ -109,7 +109,7 @@ library strings { * @return A new slice containing the value of the input argument up to the * first null. */ - function toSliceB32(bytes32 self) internal returns (slice ret) { + function toSliceB32(bytes32 self) internal returns (slice memory ret) { // Allocate space for `self` in memory, copy it there, and point ret at it assembly { let ptr := mload(0x40) @@ -125,7 +125,7 @@ library strings { * @param self The slice to copy. * @return A new slice containing the same data as `self`. */ - function copy(slice self) internal returns (slice) { + function copy(slice memory self) internal returns (slice memory) { return slice(self._len, self._ptr); } @@ -134,7 +134,7 @@ library strings { * @param self The slice to copy. * @return A newly allocated string containing the slice's text. */ - function toString(slice self) internal returns (string) { + function toString(slice memory self) internal returns (string memory) { string memory ret = new string(self._len); uint retptr; assembly { retptr := add(ret, 32) } @@ -151,7 +151,7 @@ library strings { * @param self The slice to operate on. * @return The length of the slice in runes. */ - function len(slice self) internal returns (uint) { + function len(slice memory self) internal returns (uint) { // Starting at ptr-31 means the LSB will be the byte we care about uint ptr = self._ptr - 31; uint end = ptr + self._len; @@ -181,7 +181,7 @@ library strings { * @param self The slice to operate on. * @return True if the slice is empty, False otherwise. */ - function empty(slice self) internal returns (bool) { + function empty(slice memory self) internal returns (bool) { return self._len == 0; } @@ -194,7 +194,7 @@ library strings { * @param other The second slice to compare. * @return The result of the comparison. */ - function compare(slice self, slice other) internal returns (int) { + function compare(slice memory self, slice memory other) internal returns (int) { uint shortest = self._len; if (other._len < self._len) shortest = other._len; @@ -227,7 +227,7 @@ library strings { * @param self The second slice to compare. * @return True if the slices are equal, false otherwise. */ - function equals(slice self, slice other) internal returns (bool) { + function equals(slice memory self, slice memory other) internal returns (bool) { return compare(self, other) == 0; } @@ -238,7 +238,7 @@ library strings { * @param rune The slice that will contain the first rune. * @return `rune`. */ - function nextRune(slice self, slice rune) internal returns (slice) { + function nextRune(slice memory self, slice memory rune) internal returns (slice memory) { rune._ptr = self._ptr; if (self._len == 0) { @@ -280,7 +280,7 @@ library strings { * @param self The slice to operate on. * @return A slice containing only the first rune from `self`. */ - function nextRune(slice self) internal returns (slice ret) { + function nextRune(slice memory self) internal returns (slice memory ret) { nextRune(self, ret); } @@ -289,7 +289,7 @@ library strings { * @param self The slice to operate on. * @return The number of the first codepoint in the slice. */ - function ord(slice self) internal returns (uint ret) { + function ord(slice memory self) internal returns (uint ret) { if (self._len == 0) { return 0; } @@ -338,7 +338,7 @@ library strings { * @param self The slice to hash. * @return The hash of the slice. */ - function keccak(slice self) internal returns (bytes32 ret) { + function keccak(slice memory self) internal returns (bytes32 ret) { assembly { ret := keccak256(mload(add(self, 32)), mload(self)) } @@ -350,7 +350,7 @@ library strings { * @param needle The slice to search for. * @return True if the slice starts with the provided text, false otherwise. */ - function startsWith(slice self, slice needle) internal returns (bool) { + function startsWith(slice memory self, slice memory needle) internal returns (bool) { if (self._len < needle._len) { return false; } @@ -376,7 +376,7 @@ library strings { * @param needle The slice to search for. * @return `self` */ - function beyond(slice self, slice needle) internal returns (slice) { + function beyond(slice memory self, slice memory needle) internal returns (slice memory) { if (self._len < needle._len) { return self; } @@ -405,7 +405,7 @@ library strings { * @param needle The slice to search for. * @return True if the slice starts with the provided text, false otherwise. */ - function endsWith(slice self, slice needle) internal returns (bool) { + function endsWith(slice memory self, slice memory needle) internal returns (bool) { if (self._len < needle._len) { return false; } @@ -433,7 +433,7 @@ library strings { * @param needle The slice to search for. * @return `self` */ - function until(slice self, slice needle) internal returns (slice) { + function until(slice memory self, slice memory needle) internal returns (slice memory) { if (self._len < needle._len) { return self; } @@ -542,7 +542,7 @@ library strings { * @param needle The text to search for. * @return `self`. */ - function find(slice self, slice needle) internal returns (slice) { + function find(slice memory self, slice memory needle) internal returns (slice memory) { uint ptr = findPtr(self._len, self._ptr, needle._len, needle._ptr); self._len -= ptr - self._ptr; self._ptr = ptr; @@ -557,7 +557,7 @@ library strings { * @param needle The text to search for. * @return `self`. */ - function rfind(slice self, slice needle) internal returns (slice) { + function rfind(slice memory self, slice memory needle) internal returns (slice memory) { uint ptr = rfindPtr(self._len, self._ptr, needle._len, needle._ptr); self._len = ptr - self._ptr; return self; @@ -573,7 +573,7 @@ library strings { * @param token An output parameter to which the first token is written. * @return `token`. */ - function split(slice self, slice needle, slice token) internal returns (slice) { + function split(slice memory self, slice memory needle, slice memory token) internal returns (slice memory) { uint ptr = findPtr(self._len, self._ptr, needle._len, needle._ptr); token._ptr = self._ptr; token._len = ptr - self._ptr; @@ -596,7 +596,7 @@ library strings { * @param needle The text to search for in `self`. * @return The part of `self` up to the first occurrence of `delim`. */ - function split(slice self, slice needle) internal returns (slice token) { + function split(slice memory self, slice memory needle) internal returns (slice memory token) { split(self, needle, token); } @@ -610,7 +610,7 @@ library strings { * @param token An output parameter to which the first token is written. * @return `token`. */ - function rsplit(slice self, slice needle, slice token) internal returns (slice) { + function rsplit(slice memory self, slice memory needle, slice memory token) internal returns (slice memory) { uint ptr = rfindPtr(self._len, self._ptr, needle._len, needle._ptr); token._ptr = ptr; token._len = self._len - (ptr - self._ptr); @@ -632,7 +632,7 @@ library strings { * @param needle The text to search for in `self`. * @return The part of `self` after the last occurrence of `delim`. */ - function rsplit(slice self, slice needle) internal returns (slice token) { + function rsplit(slice memory self, slice memory needle) internal returns (slice memory token) { rsplit(self, needle, token); } @@ -642,7 +642,7 @@ library strings { * @param needle The text to search for in `self`. * @return The number of occurrences of `needle` found in `self`. */ - function count(slice self, slice needle) internal returns (uint count) { + function count(slice memory self, slice memory needle) internal returns (uint count) { uint ptr = findPtr(self._len, self._ptr, needle._len, needle._ptr) + needle._len; while (ptr <= self._ptr + self._len) { count++; @@ -656,7 +656,7 @@ library strings { * @param needle The text to search for in `self`. * @return True if `needle` is found in `self`, false otherwise. */ - function contains(slice self, slice needle) internal returns (bool) { + function contains(slice memory self, slice memory needle) internal returns (bool) { return rfindPtr(self._len, self._ptr, needle._len, needle._ptr) != self._ptr; } @@ -667,7 +667,7 @@ library strings { * @param other The second slice to concatenate. * @return The concatenation of the two strings. */ - function concat(slice self, slice other) internal returns (string) { + function concat(slice memory self, slice memory other) internal returns (string memory) { string memory ret = new string(self._len + other._len); uint retptr; assembly { retptr := add(ret, 32) } @@ -684,7 +684,7 @@ library strings { * @return A newly allocated string containing all the slices in `parts`, * joined with `self`. */ - function join(slice self, slice[] parts) internal returns (string) { + function join(slice memory self, slice[] memory parts) internal returns (string memory) { if (parts.length == 0) return ""; diff --git a/test/compilationTests/zeppelin/Bounty.sol b/test/compilationTests/zeppelin/Bounty.sol index 8be16a54..55e64071 100644 --- a/test/compilationTests/zeppelin/Bounty.sol +++ b/test/compilationTests/zeppelin/Bounty.sol @@ -16,11 +16,11 @@ contract Bounty is PullPayment, Destructible { event TargetCreated(address createdAddress); /** - * @dev Fallback function allowing the contract to recieve funds, if they haven't already been claimed. + * @dev Fallback function allowing the contract to receive funds, if they haven't already been claimed. */ function() external payable { if (claimed) { - throw; + revert(); } } @@ -29,7 +29,7 @@ contract Bounty is PullPayment, Destructible { * msg.sender as a researcher * @return A target contract */ - function createTarget() returns(Target) { + function createTarget() public returns(Target) { Target target = Target(deployContract()); researchers[target] = msg.sender; emit TargetCreated(target); @@ -46,16 +46,16 @@ contract Bounty is PullPayment, Destructible { * @dev Sends the contract funds to the researcher that proved the contract is broken. * @param target contract */ - function claim(Target target) { + function claim(Target target) public { address researcher = researchers[target]; if (researcher == address(0)) { - throw; + revert(); } // Check Target contract invariants if (target.checkInvariant()) { - throw; + revert(); } - asyncSend(researcher, this.balance); + asyncSend(researcher, address(this).balance); claimed = true; } @@ -74,5 +74,5 @@ contract Target { * In order to win the bounty, security researchers will try to cause this broken state. * @return True if all invariant values are correct, false otherwise. */ - function checkInvariant() returns(bool); + function checkInvariant() public returns(bool); } diff --git a/test/compilationTests/zeppelin/DayLimit.sol b/test/compilationTests/zeppelin/DayLimit.sol index e55076b7..bc576c89 100644 --- a/test/compilationTests/zeppelin/DayLimit.sol +++ b/test/compilationTests/zeppelin/DayLimit.sol @@ -15,7 +15,7 @@ contract DayLimit { * @dev Constructor that sets the passed value as a dailyLimit. * @param _limit uint256 to represent the daily limit. */ - constructor(uint256 _limit) { + constructor(uint256 _limit) public { dailyLimit = _limit; lastDay = today(); } @@ -68,7 +68,7 @@ contract DayLimit { */ modifier limitedDaily(uint256 _value) { if (!underLimit(_value)) { - throw; + revert(); } _; } diff --git a/test/compilationTests/zeppelin/LimitBalance.sol b/test/compilationTests/zeppelin/LimitBalance.sol index 40edd014..8bf4b253 100644 --- a/test/compilationTests/zeppelin/LimitBalance.sol +++ b/test/compilationTests/zeppelin/LimitBalance.sol @@ -15,7 +15,7 @@ contract LimitBalance { * @dev Constructor that sets the passed value as a limit. * @param _limit uint256 to represent the limit. */ - constructor(uint256 _limit) { + constructor(uint256 _limit) public { limit = _limit; } @@ -23,8 +23,8 @@ contract LimitBalance { * @dev Checks if limit was reached. Case true, it throws. */ modifier limitedPayable() { - if (this.balance > limit) { - throw; + if (address(this).balance > limit) { + revert(); } _; diff --git a/test/compilationTests/zeppelin/MultisigWallet.sol b/test/compilationTests/zeppelin/MultisigWallet.sol index 96624d3a..3793428d 100644 --- a/test/compilationTests/zeppelin/MultisigWallet.sol +++ b/test/compilationTests/zeppelin/MultisigWallet.sol @@ -25,19 +25,19 @@ contract MultisigWallet is Multisig, Shareable, DayLimit { * @param _owners A list of owners. * @param _required The amount required for a transaction to be approved. */ - constructor(address[] _owners, uint256 _required, uint256 _daylimit) + constructor(address[] memory _owners, uint256 _required, uint256 _daylimit) Shareable(_owners, _required) - DayLimit(_daylimit) { } + DayLimit(_daylimit) public { } - /** - * @dev destroys the contract sending everything to `_to`. + /** + * @dev destroys the contract sending everything to `_to`. */ function destroy(address _to) onlymanyowners(keccak256(msg.data)) external { selfdestruct(_to); } - /** - * @dev Fallback function, receives value and emits a deposit event. + /** + * @dev Fallback function, receives value and emits a deposit event. */ function() external payable { // just being sent some cash? @@ -46,10 +46,10 @@ contract MultisigWallet is Multisig, Shareable, DayLimit { } /** - * @dev Outside-visible transaction entry point. Executes transaction immediately if below daily - * spending limit. 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, + * @dev Outside-visible transaction entry point. Executes transaction immediately if below daily + * spending limit. 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. * @param _to The receiver address * @param _value The value to send @@ -61,7 +61,7 @@ contract MultisigWallet is Multisig, Shareable, DayLimit { emit SingleTransact(msg.sender, _value, _to, _data); // yes - just execute the call. if (!_to.call.value(_value)(_data)) { - throw; + revert(); } return 0; } @@ -76,14 +76,14 @@ contract MultisigWallet is Multisig, Shareable, DayLimit { } /** - * @dev Confirm a transaction by providing just the hash. We use the previous transactions map, + * @dev Confirm a transaction by providing just the hash. We use the previous transactions map, * txs, in order to determine the body of the transaction from the hash provided. * @param _h The transaction hash to approve. */ - function confirm(bytes32 _h) onlymanyowners(_h) returns (bool) { + function confirm(bytes32 _h) onlymanyowners(_h) public returns (bool) { if (txs[_h].to != address(0)) { if (!txs[_h].to.call.value(txs[_h].value)(txs[_h].data)) { - throw; + revert(); } emit MultiTransact(msg.sender, _h, txs[_h].value, txs[_h].to, txs[_h].data); delete txs[_h]; @@ -91,15 +91,15 @@ contract MultisigWallet is Multisig, Shareable, DayLimit { } } - /** - * @dev Updates the daily limit value. + /** + * @dev Updates the daily limit value. * @param _newLimit uint256 to represent the new limit. */ function setDailyLimit(uint256 _newLimit) onlymanyowners(keccak256(msg.data)) external { _setDailyLimit(_newLimit); } - /** + /** * @dev Resets the value spent to enable more spending */ function resetSpentToday() onlymanyowners(keccak256(msg.data)) external { @@ -108,7 +108,7 @@ contract MultisigWallet is Multisig, Shareable, DayLimit { // INTERNAL METHODS - /** + /** * @dev Clears the list of transactions pending approval. */ function clearPending() internal { diff --git a/test/compilationTests/zeppelin/ReentrancyGuard.sol b/test/compilationTests/zeppelin/ReentrancyGuard.sol index ca8b643b..7805ec07 100644 --- a/test/compilationTests/zeppelin/ReentrancyGuard.sol +++ b/test/compilationTests/zeppelin/ReentrancyGuard.sol @@ -1,7 +1,7 @@ pragma solidity ^0.4.11; /** - * @title Helps contracts guard agains rentrancy attacks. + * @title Helps contracts guard against rentrancy attacks. * @author Remco Bloemen <remco@2π.com> * @notice If you mark a function `nonReentrant`, you should also * mark it `external`. @@ -27,7 +27,7 @@ contract ReentrancyGuard { _; rentrancy_lock = false; } else { - throw; + revert(); } } diff --git a/test/compilationTests/zeppelin/crowdsale/CappedCrowdsale.sol b/test/compilationTests/zeppelin/crowdsale/CappedCrowdsale.sol index d4066812..98c8c3d4 100644 --- a/test/compilationTests/zeppelin/crowdsale/CappedCrowdsale.sol +++ b/test/compilationTests/zeppelin/crowdsale/CappedCrowdsale.sol @@ -12,7 +12,7 @@ contract CappedCrowdsale is Crowdsale { uint256 public cap; - constructor(uint256 _cap) { + constructor(uint256 _cap) public { cap = _cap; } diff --git a/test/compilationTests/zeppelin/crowdsale/Crowdsale.sol b/test/compilationTests/zeppelin/crowdsale/Crowdsale.sol index 1f148a74..51eeb7b8 100644 --- a/test/compilationTests/zeppelin/crowdsale/Crowdsale.sol +++ b/test/compilationTests/zeppelin/crowdsale/Crowdsale.sol @@ -4,11 +4,11 @@ import '../token/MintableToken.sol'; import '../math/SafeMath.sol'; /** - * @title Crowdsale + * @title Crowdsale * @dev Crowdsale is a base contract for managing a token crowdsale. * Crowdsales have a start and end block, where investors can make * token purchases and the crowdsale will assign them tokens based - * on a token per ETH rate. Funds collected are forwarded to a wallet + * on a token per ETH rate. Funds collected are forwarded to a wallet * as they arrive. */ contract Crowdsale { @@ -36,11 +36,11 @@ contract Crowdsale { * @param beneficiary who got the tokens * @param value weis paid for purchase * @param amount amount of tokens purchased - */ + */ event TokenPurchase(address indexed purchaser, address indexed beneficiary, uint256 value, uint256 amount); - constructor(uint256 _startBlock, uint256 _endBlock, uint256 _rate, address _wallet) { + constructor(uint256 _startBlock, uint256 _endBlock, uint256 _rate, address _wallet) public { require(_startBlock >= block.number); require(_endBlock >= _startBlock); require(_rate > 0); @@ -53,7 +53,7 @@ contract Crowdsale { wallet = _wallet; } - // creates the token to be sold. + // creates the token to be sold. // override this method to have crowdsale of a specific mintable token. function createTokenContract() internal returns (MintableToken) { return new MintableToken(); @@ -66,7 +66,7 @@ contract Crowdsale { } // low level token purchase function - function buyTokens(address beneficiary) payable { + function buyTokens(address beneficiary) public payable { require(beneficiary != address(0x0)); require(validPurchase()); diff --git a/test/compilationTests/zeppelin/crowdsale/FinalizableCrowdsale.sol b/test/compilationTests/zeppelin/crowdsale/FinalizableCrowdsale.sol index 7965a66d..da4e3b7f 100644 --- a/test/compilationTests/zeppelin/crowdsale/FinalizableCrowdsale.sol +++ b/test/compilationTests/zeppelin/crowdsale/FinalizableCrowdsale.sol @@ -18,7 +18,7 @@ contract FinalizableCrowdsale is Crowdsale, Ownable { // should be called after crowdsale ends, to do // some extra finalization work - function finalize() onlyOwner { + function finalize() public onlyOwner { require(!isFinalized); require(hasEnded()); diff --git a/test/compilationTests/zeppelin/crowdsale/RefundVault.sol b/test/compilationTests/zeppelin/crowdsale/RefundVault.sol index 0be45ec4..b7db8ef2 100644 --- a/test/compilationTests/zeppelin/crowdsale/RefundVault.sol +++ b/test/compilationTests/zeppelin/crowdsale/RefundVault.sol @@ -22,31 +22,31 @@ contract RefundVault is Ownable { event RefundsEnabled(); event Refunded(address indexed beneficiary, uint256 weiAmount); - constructor(address _wallet) { + constructor(address _wallet) public { require(_wallet != address(0x0)); wallet = _wallet; state = State.Active; } - function deposit(address investor) onlyOwner payable { + function deposit(address investor) public onlyOwner payable { require(state == State.Active); deposited[investor] = deposited[investor].add(msg.value); } - function close() onlyOwner { + function close() public onlyOwner { require(state == State.Active); state = State.Closed; emit Closed(); - wallet.transfer(this.balance); + wallet.transfer(address(this).balance); } - function enableRefunds() onlyOwner { + function enableRefunds() public onlyOwner { require(state == State.Active); state = State.Refunding; emit RefundsEnabled(); } - function refund(address investor) { + function refund(address investor) public { require(state == State.Refunding); uint256 depositedValue = deposited[investor]; deposited[investor] = 0; diff --git a/test/compilationTests/zeppelin/crowdsale/RefundableCrowdsale.sol b/test/compilationTests/zeppelin/crowdsale/RefundableCrowdsale.sol index bb6b5e17..94e3af99 100644 --- a/test/compilationTests/zeppelin/crowdsale/RefundableCrowdsale.sol +++ b/test/compilationTests/zeppelin/crowdsale/RefundableCrowdsale.sol @@ -21,7 +21,7 @@ contract RefundableCrowdsale is FinalizableCrowdsale { // refund vault used to hold funds while crowdsale is running RefundVault public vault; - constructor(uint256 _goal) { + constructor(uint256 _goal) public { vault = new RefundVault(wallet); goal = _goal; } @@ -34,7 +34,7 @@ contract RefundableCrowdsale is FinalizableCrowdsale { } // if crowdsale is unsuccessful, investors can claim refunds here - function claimRefund() { + function claimRefund() public { require(isFinalized); require(!goalReached()); diff --git a/test/compilationTests/zeppelin/lifecycle/Destructible.sol b/test/compilationTests/zeppelin/lifecycle/Destructible.sol index 00492590..5b0e9f58 100644 --- a/test/compilationTests/zeppelin/lifecycle/Destructible.sol +++ b/test/compilationTests/zeppelin/lifecycle/Destructible.sol @@ -10,16 +10,16 @@ import "../ownership/Ownable.sol"; */ contract Destructible is Ownable { - constructor() payable { } + constructor() public payable { } /** * @dev Transfers the current balance to the owner and terminates the contract. */ - function destroy() onlyOwner { + function destroy() public onlyOwner { selfdestruct(owner); } - function destroyAndSend(address _recipient) onlyOwner { + function destroyAndSend(address _recipient) public onlyOwner { selfdestruct(_recipient); } } diff --git a/test/compilationTests/zeppelin/lifecycle/Migrations.sol b/test/compilationTests/zeppelin/lifecycle/Migrations.sol index d5b05308..4ca95d36 100644 --- a/test/compilationTests/zeppelin/lifecycle/Migrations.sol +++ b/test/compilationTests/zeppelin/lifecycle/Migrations.sol @@ -10,11 +10,11 @@ import '../ownership/Ownable.sol'; contract Migrations is Ownable { uint256 public lastCompletedMigration; - function setCompleted(uint256 completed) onlyOwner { + function setCompleted(uint256 completed) public onlyOwner { lastCompletedMigration = completed; } - function upgrade(address newAddress) onlyOwner { + function upgrade(address newAddress) public onlyOwner { Migrations upgraded = Migrations(newAddress); upgraded.setCompleted(lastCompletedMigration); } diff --git a/test/compilationTests/zeppelin/lifecycle/Pausable.sol b/test/compilationTests/zeppelin/lifecycle/Pausable.sol index 10b0fcd8..0c48f2f6 100644 --- a/test/compilationTests/zeppelin/lifecycle/Pausable.sol +++ b/test/compilationTests/zeppelin/lifecycle/Pausable.sol @@ -19,7 +19,7 @@ contract Pausable is Ownable { * @dev modifier to allow actions only when the contract IS paused */ modifier whenNotPaused() { - if (paused) throw; + if (paused) revert(); _; } @@ -27,14 +27,14 @@ contract Pausable is Ownable { * @dev modifier to allow actions only when the contract IS NOT paused */ modifier whenPaused { - if (!paused) throw; + if (!paused) revert(); _; } /** * @dev called by the owner to pause, triggers stopped state */ - function pause() onlyOwner whenNotPaused returns (bool) { + function pause() public onlyOwner whenNotPaused returns (bool) { paused = true; emit Pause(); return true; @@ -43,7 +43,7 @@ contract Pausable is Ownable { /** * @dev called by the owner to unpause, returns to normal state */ - function unpause() onlyOwner whenPaused returns (bool) { + function unpause() public onlyOwner whenPaused returns (bool) { paused = false; emit Unpause(); return true; diff --git a/test/compilationTests/zeppelin/lifecycle/TokenDestructible.sol b/test/compilationTests/zeppelin/lifecycle/TokenDestructible.sol index f88a55aa..51f6b68e 100644 --- a/test/compilationTests/zeppelin/lifecycle/TokenDestructible.sol +++ b/test/compilationTests/zeppelin/lifecycle/TokenDestructible.sol @@ -12,7 +12,7 @@ import "../token/ERC20Basic.sol"; */ contract TokenDestructible is Ownable { - constructor() payable { } + constructor() public payable { } /** * @notice Terminate contract and refund to owner @@ -21,7 +21,7 @@ contract TokenDestructible is Ownable { * @notice The called token contracts could try to re-enter this contract. Only supply token contracts you trust. */ - function destroy(address[] tokens) onlyOwner { + function destroy(address[] memory tokens) public onlyOwner { // Transfer tokens to owner for(uint256 i = 0; i < tokens.length; i++) { diff --git a/test/compilationTests/zeppelin/ownership/Claimable.sol b/test/compilationTests/zeppelin/ownership/Claimable.sol index 14d0ac6a..d7b48a29 100644 --- a/test/compilationTests/zeppelin/ownership/Claimable.sol +++ b/test/compilationTests/zeppelin/ownership/Claimable.sol @@ -17,7 +17,7 @@ contract Claimable is Ownable { */ modifier onlyPendingOwner() { if (msg.sender != pendingOwner) { - throw; + revert(); } _; } @@ -26,14 +26,14 @@ contract Claimable is Ownable { * @dev Allows the current owner to set the pendingOwner address. * @param newOwner The address to transfer ownership to. */ - function transferOwnership(address newOwner) onlyOwner { + function transferOwnership(address newOwner) public onlyOwner { pendingOwner = newOwner; } /** * @dev Allows the pendingOwner address to finalize the transfer. */ - function claimOwnership() onlyPendingOwner { + function claimOwnership() public onlyPendingOwner { owner = pendingOwner; pendingOwner = address(0x0); } diff --git a/test/compilationTests/zeppelin/ownership/Contactable.sol b/test/compilationTests/zeppelin/ownership/Contactable.sol index 0db3ee07..5f781e13 100644 --- a/test/compilationTests/zeppelin/ownership/Contactable.sol +++ b/test/compilationTests/zeppelin/ownership/Contactable.sol @@ -15,7 +15,7 @@ contract Contactable is Ownable{ * @dev Allows the owner to set a string with their contact information. * @param info The contact information to attach to the contract. */ - function setContactInformation(string info) onlyOwner{ + function setContactInformation(string memory info) public onlyOwner{ contactInformation = info; } } diff --git a/test/compilationTests/zeppelin/ownership/DelayedClaimable.sol b/test/compilationTests/zeppelin/ownership/DelayedClaimable.sol index 93177dc6..540a2ce0 100644 --- a/test/compilationTests/zeppelin/ownership/DelayedClaimable.sol +++ b/test/compilationTests/zeppelin/ownership/DelayedClaimable.sol @@ -20,9 +20,9 @@ contract DelayedClaimable is Claimable { * @param _start The earliest time ownership can be claimed. * @param _end The latest time ownership can be claimed. */ - function setLimits(uint256 _start, uint256 _end) onlyOwner { + function setLimits(uint256 _start, uint256 _end) public onlyOwner { if (_start > _end) - throw; + revert(); end = _end; start = _start; } @@ -32,9 +32,9 @@ contract DelayedClaimable is Claimable { * @dev Allows the pendingOwner address to finalize the transfer, as long as it is called within * the specified start and end time. */ - function claimOwnership() onlyPendingOwner { + function claimOwnership() public onlyPendingOwner { if ((block.number > end) || (block.number < start)) - throw; + revert(); owner = pendingOwner; pendingOwner = address(0x0); end = 0; diff --git a/test/compilationTests/zeppelin/ownership/HasNoEther.sol b/test/compilationTests/zeppelin/ownership/HasNoEther.sol index 8f9edc03..75d90841 100644 --- a/test/compilationTests/zeppelin/ownership/HasNoEther.sol +++ b/test/compilationTests/zeppelin/ownership/HasNoEther.sol @@ -21,9 +21,9 @@ contract HasNoEther is Ownable { * constructor. By doing it this way we prevent a payable constructor from working. Alternatively * we could use assembly to access msg.value. */ - constructor() payable { + constructor() public payable { if(msg.value > 0) { - throw; + revert(); } } @@ -37,8 +37,8 @@ contract HasNoEther is Ownable { * @dev Transfer all Ether held by the contract to the owner. */ function reclaimEther() external onlyOwner { - if(!owner.send(this.balance)) { - throw; + if(!owner.send(address(this).balance)) { + revert(); } } } diff --git a/test/compilationTests/zeppelin/ownership/HasNoTokens.sol b/test/compilationTests/zeppelin/ownership/HasNoTokens.sol index d1dc4b3e..df4284f1 100644 --- a/test/compilationTests/zeppelin/ownership/HasNoTokens.sol +++ b/test/compilationTests/zeppelin/ownership/HasNoTokens.sol @@ -19,7 +19,7 @@ contract HasNoTokens is Ownable { * @param data_ Bytes The data passed from the caller. */ function tokenFallback(address from_, uint256 value_, bytes data_) external { - throw; + revert(); } /** diff --git a/test/compilationTests/zeppelin/ownership/Multisig.sol b/test/compilationTests/zeppelin/ownership/Multisig.sol index 76c78411..25531d8d 100644 --- a/test/compilationTests/zeppelin/ownership/Multisig.sol +++ b/test/compilationTests/zeppelin/ownership/Multisig.sol @@ -24,5 +24,5 @@ contract Multisig { // TODO: document function changeOwner(address _from, address _to) external; function execute(address _to, uint256 _value, bytes _data) external returns (bytes32); - function confirm(bytes32 _h) returns (bool); + function confirm(bytes32 _h) public returns (bool); } diff --git a/test/compilationTests/zeppelin/ownership/Ownable.sol b/test/compilationTests/zeppelin/ownership/Ownable.sol index 0a2257d6..a862cb74 100644 --- a/test/compilationTests/zeppelin/ownership/Ownable.sol +++ b/test/compilationTests/zeppelin/ownership/Ownable.sol @@ -14,7 +14,7 @@ contract Ownable { * @dev The Ownable constructor sets the original `owner` of the contract to the sender * account. */ - constructor() { + constructor() public { owner = msg.sender; } @@ -24,7 +24,7 @@ contract Ownable { */ modifier onlyOwner() { if (msg.sender != owner) { - throw; + revert(); } _; } @@ -34,7 +34,7 @@ contract Ownable { * @dev Allows the current owner to transfer control of the contract to a newOwner. * @param newOwner The address to transfer ownership to. */ - function transferOwnership(address newOwner) onlyOwner { + function transferOwnership(address newOwner) public onlyOwner { if (newOwner != address(0)) { owner = newOwner; } diff --git a/test/compilationTests/zeppelin/ownership/Shareable.sol b/test/compilationTests/zeppelin/ownership/Shareable.sol index c954052b..0c8d16a5 100644 --- a/test/compilationTests/zeppelin/ownership/Shareable.sol +++ b/test/compilationTests/zeppelin/ownership/Shareable.sol @@ -37,7 +37,7 @@ contract Shareable { // simple single-sig function modifier. modifier onlyOwner { if (!isOwner(msg.sender)) { - throw; + revert(); } _; } @@ -59,7 +59,7 @@ contract Shareable { * @param _owners A list of owners. * @param _required The amount required for a transaction to be approved. */ - constructor(address[] _owners, uint256 _required) { + constructor(address[] memory _owners, uint256 _required) public { owners[1] = msg.sender; ownerIndex[msg.sender] = 1; for (uint256 i = 0; i < _owners.length; ++i) { @@ -68,7 +68,7 @@ contract Shareable { } required = _required; if (required > owners.length) { - throw; + revert(); } } @@ -105,7 +105,7 @@ contract Shareable { * @param _addr address The address which you want to check. * @return True if the address is an owner and fase otherwise. */ - function isOwner(address _addr) view returns (bool) { + function isOwner(address _addr) public view returns (bool) { return ownerIndex[_addr] > 0; } @@ -115,7 +115,7 @@ contract Shareable { * @param _owner The owner address. * @return True if the owner has confirmed and false otherwise. */ - function hasConfirmed(bytes32 _operation, address _owner) view returns (bool) { + function hasConfirmed(bytes32 _operation, address _owner) public view returns (bool) { PendingState memory pending = pendings[_operation]; uint256 index = ownerIndex[_owner]; @@ -139,7 +139,7 @@ contract Shareable { uint256 index = ownerIndex[msg.sender]; // make sure they're an owner if (index == 0) { - throw; + revert(); } PendingState memory pending = pendings[_operation]; diff --git a/test/compilationTests/zeppelin/payment/PullPayment.sol b/test/compilationTests/zeppelin/payment/PullPayment.sol index ba710b53..bac1d019 100644 --- a/test/compilationTests/zeppelin/payment/PullPayment.sol +++ b/test/compilationTests/zeppelin/payment/PullPayment.sol @@ -28,23 +28,23 @@ contract PullPayment { /** * @dev withdraw accumulated balance, called by payee. */ - function withdrawPayments() { + function withdrawPayments() public { address payee = msg.sender; uint256 payment = payments[payee]; if (payment == 0) { - throw; + revert(); } - if (this.balance < payment) { - throw; + if (address(this).balance < payment) { + revert(); } totalPayments = totalPayments.sub(payment); payments[payee] = 0; if (!payee.send(payment)) { - throw; + revert(); } } } diff --git a/test/compilationTests/zeppelin/token/BasicToken.sol b/test/compilationTests/zeppelin/token/BasicToken.sol index 8a3d8ead..bc085f85 100644 --- a/test/compilationTests/zeppelin/token/BasicToken.sol +++ b/test/compilationTests/zeppelin/token/BasicToken.sol @@ -19,7 +19,7 @@ contract BasicToken is ERC20Basic { * @param _to The address to transfer to. * @param _value The amount to be transferred. */ - function transfer(address _to, uint256 _value) { + function transfer(address _to, uint256 _value) public { balances[msg.sender] = balances[msg.sender].sub(_value); balances[_to] = balances[_to].add(_value); emit Transfer(msg.sender, _to, _value); @@ -30,7 +30,7 @@ contract BasicToken is ERC20Basic { * @param _owner The address to query the the balance of. * @return An uint256 representing the amount owned by the passed address. */ - function balanceOf(address _owner) view returns (uint256 balance) { + function balanceOf(address _owner) public view returns (uint256 balance) { return balances[_owner]; } diff --git a/test/compilationTests/zeppelin/token/ERC20.sol b/test/compilationTests/zeppelin/token/ERC20.sol index ae5aa624..5b5dc748 100644 --- a/test/compilationTests/zeppelin/token/ERC20.sol +++ b/test/compilationTests/zeppelin/token/ERC20.sol @@ -9,8 +9,8 @@ import './ERC20Basic.sol'; * @dev see https://github.com/ethereum/EIPs/issues/20 */ contract ERC20 is ERC20Basic { - function allowance(address owner, address spender) view returns (uint256); - function transferFrom(address from, address to, uint256 value); - function approve(address spender, uint256 value); + function allowance(address owner, address spender) public view returns (uint256); + function transferFrom(address from, address to, uint256 value) public; + function approve(address spender, uint256 value) public; event Approval(address indexed owner, address indexed spender, uint256 value); } diff --git a/test/compilationTests/zeppelin/token/ERC20Basic.sol b/test/compilationTests/zeppelin/token/ERC20Basic.sol index 94fb7bcf..fbe33134 100644 --- a/test/compilationTests/zeppelin/token/ERC20Basic.sol +++ b/test/compilationTests/zeppelin/token/ERC20Basic.sol @@ -8,7 +8,7 @@ pragma solidity ^0.4.11; */ contract ERC20Basic { uint256 public totalSupply; - function balanceOf(address who) view returns (uint256); - function transfer(address to, uint256 value); + function balanceOf(address who) public view returns (uint256); + function transfer(address to, uint256 value) public; event Transfer(address indexed from, address indexed to, uint256 value); } diff --git a/test/compilationTests/zeppelin/token/LimitedTransferToken.sol b/test/compilationTests/zeppelin/token/LimitedTransferToken.sol index 0ccd60b2..3ce928f6 100644 --- a/test/compilationTests/zeppelin/token/LimitedTransferToken.sol +++ b/test/compilationTests/zeppelin/token/LimitedTransferToken.sol @@ -23,26 +23,26 @@ contract LimitedTransferToken is ERC20 { * @dev Checks whether it can transfer or otherwise throws. */ modifier canTransfer(address _sender, uint256 _value) { - if (_value > transferableTokens(_sender, uint64(now))) throw; + if (_value > transferableTokens(_sender, uint64(now))) revert(); _; } /** * @dev Checks modifier and allows transfer if tokens are not locked. - * @param _to The address that will recieve the tokens. + * @param _to The address that will receive the tokens. * @param _value The amount of tokens to be transferred. */ - function transfer(address _to, uint256 _value) canTransfer(msg.sender, _value) { + function transfer(address _to, uint256 _value) canTransfer(msg.sender, _value) public { super.transfer(_to, _value); } /** * @dev Checks modifier and allows transfer if tokens are not locked. * @param _from The address that will send the tokens. - * @param _to The address that will recieve the tokens. + * @param _to The address that will receive the tokens. * @param _value The amount of tokens to be transferred. */ - function transferFrom(address _from, address _to, uint256 _value) canTransfer(_from, _value) { + function transferFrom(address _from, address _to, uint256 _value) public canTransfer(_from, _value) { super.transferFrom(_from, _to, _value); } diff --git a/test/compilationTests/zeppelin/token/MintableToken.sol b/test/compilationTests/zeppelin/token/MintableToken.sol index 45926afb..24b8c807 100644 --- a/test/compilationTests/zeppelin/token/MintableToken.sol +++ b/test/compilationTests/zeppelin/token/MintableToken.sol @@ -21,17 +21,17 @@ contract MintableToken is StandardToken, Ownable { modifier canMint() { - if(mintingFinished) throw; + if(mintingFinished) revert(); _; } /** * @dev Function to mint tokens - * @param _to The address that will recieve the minted tokens. + * @param _to The address that will receive the minted tokens. * @param _amount The amount of tokens to mint. * @return A boolean that indicates if the operation was successful. */ - function mint(address _to, uint256 _amount) onlyOwner canMint returns (bool) { + function mint(address _to, uint256 _amount) public onlyOwner canMint returns (bool) { totalSupply = totalSupply.add(_amount); balances[_to] = balances[_to].add(_amount); emit Mint(_to, _amount); @@ -42,7 +42,7 @@ contract MintableToken is StandardToken, Ownable { * @dev Function to stop minting new tokens. * @return True if the operation was successful. */ - function finishMinting() onlyOwner returns (bool) { + function finishMinting() public onlyOwner returns (bool) { mintingFinished = true; emit MintFinished(); return true; diff --git a/test/compilationTests/zeppelin/token/PausableToken.sol b/test/compilationTests/zeppelin/token/PausableToken.sol index 8ee114e1..66f80b80 100644 --- a/test/compilationTests/zeppelin/token/PausableToken.sol +++ b/test/compilationTests/zeppelin/token/PausableToken.sol @@ -11,11 +11,11 @@ import '../lifecycle/Pausable.sol'; contract PausableToken is StandardToken, Pausable { - function transfer(address _to, uint _value) whenNotPaused { + function transfer(address _to, uint _value) public whenNotPaused { super.transfer(_to, _value); } - function transferFrom(address _from, address _to, uint _value) whenNotPaused { + function transferFrom(address _from, address _to, uint _value) public whenNotPaused { super.transferFrom(_from, _to, _value); } } diff --git a/test/compilationTests/zeppelin/token/SimpleToken.sol b/test/compilationTests/zeppelin/token/SimpleToken.sol index a4ba9eb3..6c3f5740 100644 --- a/test/compilationTests/zeppelin/token/SimpleToken.sol +++ b/test/compilationTests/zeppelin/token/SimpleToken.sol @@ -18,9 +18,9 @@ contract SimpleToken is StandardToken { uint256 public INITIAL_SUPPLY = 10000; /** - * @dev Contructor that gives msg.sender all of existing tokens. + * @dev Constructor that gives msg.sender all of existing tokens. */ - constructor() { + constructor() public { totalSupply = INITIAL_SUPPLY; balances[msg.sender] = INITIAL_SUPPLY; } diff --git a/test/compilationTests/zeppelin/token/StandardToken.sol b/test/compilationTests/zeppelin/token/StandardToken.sol index 900a9102..56f4a5f3 100644 --- a/test/compilationTests/zeppelin/token/StandardToken.sol +++ b/test/compilationTests/zeppelin/token/StandardToken.sol @@ -21,13 +21,13 @@ contract StandardToken is ERC20, BasicToken { * @dev Transfer tokens from one address to another * @param _from address The address which you want to send tokens from * @param _to address The address which you want to transfer to - * @param _value uint256 the amout of tokens to be transfered + * @param _value uint256 the amount of tokens to be transferred */ - function transferFrom(address _from, address _to, uint256 _value) { + function transferFrom(address _from, address _to, uint256 _value) public { uint256 _allowance = allowed[_from][msg.sender]; // Check is not needed because sub(_allowance, _value) will already throw if this condition is not met - // if (_value > _allowance) throw; + // if (_value > _allowance) revert(); balances[_to] = balances[_to].add(_value); balances[_from] = balances[_from].sub(_value); @@ -40,13 +40,13 @@ contract StandardToken is ERC20, BasicToken { * @param _spender The address which will spend the funds. * @param _value The amount of tokens to be spent. */ - function approve(address _spender, uint256 _value) { + function approve(address _spender, uint256 _value) public { // To change the approve amount you first have to reduce the addresses` // allowance to zero by calling `approve(_spender, 0)` if it is not // already 0 to mitigate the race condition described here: // https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 - if ((_value != 0) && (allowed[msg.sender][_spender] != 0)) throw; + if ((_value != 0) && (allowed[msg.sender][_spender] != 0)) revert(); allowed[msg.sender][_spender] = _value; emit Approval(msg.sender, _spender, _value); @@ -56,9 +56,9 @@ contract StandardToken is ERC20, BasicToken { * @dev Function to check the amount of tokens that an owner allowed to a spender. * @param _owner address The address which owns the funds. * @param _spender address The address which will spend the funds. - * @return A uint256 specifing the amount of tokens still avaible for the spender. + * @return A uint256 specifying the amount of tokens still available for the spender. */ - function allowance(address _owner, address _spender) view returns (uint256 remaining) { + function allowance(address _owner, address _spender) public view returns (uint256 remaining) { return allowed[_owner][_spender]; } diff --git a/test/compilationTests/zeppelin/token/TokenTimelock.sol b/test/compilationTests/zeppelin/token/TokenTimelock.sol index e9f998ba..fa1af025 100644 --- a/test/compilationTests/zeppelin/token/TokenTimelock.sol +++ b/test/compilationTests/zeppelin/token/TokenTimelock.sol @@ -19,7 +19,7 @@ contract TokenTimelock { // timestamp when token release is enabled uint releaseTime; - constructor(ERC20Basic _token, address _beneficiary, uint _releaseTime) { + constructor(ERC20Basic _token, address _beneficiary, uint _releaseTime) public { require(_releaseTime > now); token = _token; beneficiary = _beneficiary; @@ -29,7 +29,7 @@ contract TokenTimelock { /** * @dev beneficiary claims tokens held by time lock */ - function claim() { + function claim() public { require(msg.sender == beneficiary); require(now >= releaseTime); diff --git a/test/compilationTests/zeppelin/token/VestedToken.sol b/test/compilationTests/zeppelin/token/VestedToken.sol index 3953612d..ca13b638 100644 --- a/test/compilationTests/zeppelin/token/VestedToken.sol +++ b/test/compilationTests/zeppelin/token/VestedToken.sol @@ -46,10 +46,10 @@ contract VestedToken is StandardToken, LimitedTransferToken { // Check for date inconsistencies that may cause unexpected behavior if (_cliff < _start || _vesting < _cliff) { - throw; + revert(); } - if (tokenGrantsCount(_to) > MAX_GRANTS_PER_ADDRESS) throw; // To prevent a user being spammed and have his balance locked (out of gas attack when calculating vesting). + if (tokenGrantsCount(_to) > MAX_GRANTS_PER_ADDRESS) revert(); // To prevent a user being spammed and have his balance locked (out of gas attack when calculating vesting). uint256 count = grants[_to].push( TokenGrant( @@ -69,19 +69,19 @@ contract VestedToken is StandardToken, LimitedTransferToken { } /** - * @dev Revoke the grant of tokens of a specifed address. + * @dev Revoke the grant of tokens of a specified address. * @param _holder The address which will have its tokens revoked. * @param _grantId The id of the token grant. */ function revokeTokenGrant(address _holder, uint256 _grantId) public { - TokenGrant grant = grants[_holder][_grantId]; + TokenGrant storage grant = grants[_holder][_grantId]; if (!grant.revokable) { // Check if grant was revokable - throw; + revert(); } if (grant.granter != msg.sender) { // Only granter can revoke it - throw; + revert(); } address receiver = grant.burnsOnRevoke ? 0xdead : msg.sender; @@ -130,18 +130,18 @@ contract VestedToken is StandardToken, LimitedTransferToken { * @param _holder The holder of the grants. * @return A uint256 representing the total amount of grants. */ - function tokenGrantsCount(address _holder) view returns (uint256 index) { + function tokenGrantsCount(address _holder) public view returns (uint256 index) { return grants[_holder].length; } /** - * @dev Calculate amount of vested tokens at a specifc time. - * @param tokens uint256 The amount of tokens grantted. + * @dev Calculate amount of vested tokens at a specific time. + * @param tokens uint256 The amount of tokens granted. * @param time uint64 The time to be checked - * @param start uint64 A time representing the begining of the grant + * @param start uint64 A time representing the beginning of the grant * @param cliff uint64 The cliff period. * @param vesting uint64 The vesting period. - * @return An uint256 representing the amount of vested tokensof a specif grant. + * @return An uint256 representing the amount of vested tokens of a specific grant. * transferableTokens * | _/-------- vestedTokens rect * | _/ @@ -163,7 +163,7 @@ contract VestedToken is StandardToken, LimitedTransferToken { uint256 time, uint256 start, uint256 cliff, - uint256 vesting) view returns (uint256) + uint256 vesting) public view returns (uint256) { // Shortcuts for before cliff and after vesting cases. if (time < cliff) return 0; @@ -186,14 +186,14 @@ contract VestedToken is StandardToken, LimitedTransferToken { } /** - * @dev Get all information about a specifc grant. + * @dev Get all information about a specific grant. * @param _holder The address which will have its tokens revoked. * @param _grantId The id of the token grant. * @return Returns all the values that represent a TokenGrant(address, value, start, cliff, * revokability, burnsOnRevoke, and vesting) plus the vested value at the current time. */ - function tokenGrant(address _holder, uint256 _grantId) view returns (address granter, uint256 value, uint256 vested, uint64 start, uint64 cliff, uint64 vesting, bool revokable, bool burnsOnRevoke) { - TokenGrant grant = grants[_holder][_grantId]; + function tokenGrant(address _holder, uint256 _grantId) public view returns (address granter, uint256 value, uint256 vested, uint64 start, uint64 cliff, uint64 vesting, bool revokable, bool burnsOnRevoke) { + TokenGrant storage grant = grants[_holder][_grantId]; granter = grant.granter; value = grant.value; @@ -212,7 +212,7 @@ contract VestedToken is StandardToken, LimitedTransferToken { * @param time The time to be checked * @return An uint256 representing the amount of vested tokens of a specific grant at a specific time. */ - function vestedTokens(TokenGrant grant, uint64 time) private view returns (uint256) { + function vestedTokens(TokenGrant memory grant, uint64 time) private view returns (uint256) { return calculateVestedTokens( grant.value, uint256(time), @@ -226,10 +226,10 @@ contract VestedToken is StandardToken, LimitedTransferToken { * @dev Calculate the amount of non vested tokens at a specific time. * @param grant TokenGrant The grant to be checked. * @param time uint64 The time to be checked - * @return An uint256 representing the amount of non vested tokens of a specifc grant on the + * @return An uint256 representing the amount of non vested tokens of a specific grant on the * passed time frame. */ - function nonVestedTokens(TokenGrant grant, uint64 time) private view returns (uint256) { + function nonVestedTokens(TokenGrant memory grant, uint64 time) private view returns (uint256) { return grant.value.sub(vestedTokens(grant, time)); } diff --git a/test/contracts/AuctionRegistrar.cpp b/test/contracts/AuctionRegistrar.cpp index 3d759aa0..4ff55b75 100644 --- a/test/contracts/AuctionRegistrar.cpp +++ b/test/contracts/AuctionRegistrar.cpp @@ -43,20 +43,20 @@ static char const* registrarCode = R"DELIMITER( pragma solidity ^0.4.0; contract NameRegister { - function addr(string _name) view returns (address o_owner); - function name(address _owner) view returns (string o_name); + function addr(string memory _name) public view returns (address o_owner); + function name(address _owner) public view returns (string memory o_name); } contract Registrar is NameRegister { event Changed(string indexed name); event PrimaryChanged(string indexed name, address indexed addr); - function owner(string _name) view returns (address o_owner); - function addr(string _name) view returns (address o_address); - function subRegistrar(string _name) view returns (address o_subRegistrar); - function content(string _name) view returns (bytes32 o_content); + function owner(string memory _name) public view returns (address o_owner); + function addr(string memory _name) public view returns (address o_address); + function subRegistrar(string memory _name) public view returns (address o_subRegistrar); + function content(string memory _name) public view returns (bytes32 o_content); - function name(address _owner) view returns (string o_name); + function name(address _owner) public view returns (string memory o_name); } contract AuctionSystem { @@ -64,9 +64,9 @@ contract AuctionSystem { event NewBid(string indexed _name, address _bidder, uint _value); /// Function that is called once an auction ends. - function onAuctionEnd(string _name) internal; + function onAuctionEnd(string memory _name) internal; - function bid(string _name, address _bidder, uint _value) internal { + function bid(string memory _name, address _bidder, uint _value) internal { Auction storage auction = m_auctions[_name]; if (auction.endDate > 0 && now > auction.endDate) { @@ -112,11 +112,11 @@ contract GlobalRegistrar is Registrar, AuctionSystem { uint constant c_renewalInterval = 365 days; uint constant c_freeBytes = 12; - function Registrar() { + function Registrar() public { // TODO: Populate with hall-of-fame. } - function onAuctionEnd(string _name) internal { + function onAuctionEnd(string memory _name) internal { Auction storage auction = m_auctions[_name]; Record storage record = m_toRecord[_name]; address previousOwner = record.owner; @@ -125,43 +125,43 @@ contract GlobalRegistrar is Registrar, AuctionSystem { emit Changed(_name); if (previousOwner != 0x0000000000000000000000000000000000000000) { if (!record.owner.send(auction.sumOfBids - auction.highestBid / 100)) - throw; + revert(); } else { if (!auction.highestBidder.send(auction.highestBid - auction.secondHighestBid)) - throw; + revert(); } } function reserve(string _name) external payable { if (bytes(_name).length == 0) - throw; + revert(); bool needAuction = requiresAuction(_name); if (needAuction) { if (now < m_toRecord[_name].renewalDate) - throw; + revert(); bid(_name, msg.sender, msg.value); } else { - Record record = m_toRecord[_name]; + Record storage record = m_toRecord[_name]; if (record.owner != 0x0000000000000000000000000000000000000000) - throw; + revert(); m_toRecord[_name].owner = msg.sender; emit Changed(_name); } } - function requiresAuction(string _name) internal returns (bool) { + function requiresAuction(string memory _name) internal returns (bool) { return bytes(_name).length < c_freeBytes; } - modifier onlyrecordowner(string _name) { if (m_toRecord[_name].owner == msg.sender) _; } + modifier onlyrecordowner(string memory _name) { if (m_toRecord[_name].owner == msg.sender) _; } - function transfer(string _name, address _newOwner) onlyrecordowner(_name) { + function transfer(string memory _name, address _newOwner) onlyrecordowner(_name) public { m_toRecord[_name].owner = _newOwner; emit Changed(_name); } - function disown(string _name) onlyrecordowner(_name) { + function disown(string memory _name) onlyrecordowner(_name) public { if (stringsEqual(m_toName[m_toRecord[_name].primary], _name)) { emit PrimaryChanged(_name, m_toRecord[_name].primary); @@ -171,7 +171,7 @@ contract GlobalRegistrar is Registrar, AuctionSystem { emit Changed(_name); } - function setAddress(string _name, address _a, bool _primary) onlyrecordowner(_name) { + function setAddress(string memory _name, address _a, bool _primary) onlyrecordowner(_name) public { m_toRecord[_name].primary = _a; if (_primary) { @@ -180,11 +180,11 @@ contract GlobalRegistrar is Registrar, AuctionSystem { } emit Changed(_name); } - function setSubRegistrar(string _name, address _registrar) onlyrecordowner(_name) { + function setSubRegistrar(string memory _name, address _registrar) onlyrecordowner(_name) public { m_toRecord[_name].subRegistrar = _registrar; emit Changed(_name); } - function setContent(string _name, bytes32 _content) onlyrecordowner(_name) { + function setContent(string memory _name, bytes32 _content) onlyrecordowner(_name) public { m_toRecord[_name].content = _content; emit Changed(_name); } @@ -201,11 +201,11 @@ contract GlobalRegistrar is Registrar, AuctionSystem { return true; } - function owner(string _name) view returns (address) { return m_toRecord[_name].owner; } - function addr(string _name) view returns (address) { return m_toRecord[_name].primary; } - function subRegistrar(string _name) view returns (address) { return m_toRecord[_name].subRegistrar; } - function content(string _name) view returns (bytes32) { return m_toRecord[_name].content; } - function name(address _addr) view returns (string o_name) { return m_toName[_addr]; } + function owner(string memory _name) public view returns (address) { return m_toRecord[_name].owner; } + function addr(string memory _name) public view returns (address) { return m_toRecord[_name].primary; } + function subRegistrar(string memory _name) public view returns (address) { return m_toRecord[_name].subRegistrar; } + function content(string memory _name) public view returns (bytes32) { return m_toRecord[_name].content; } + function name(address _addr) public view returns (string memory o_name) { return m_toName[_addr]; } mapping (address => string) m_toName; mapping (string => Record) m_toRecord; diff --git a/test/contracts/FixedFeeRegistrar.cpp b/test/contracts/FixedFeeRegistrar.cpp index 87f801b0..78db4761 100644 --- a/test/contracts/FixedFeeRegistrar.cpp +++ b/test/contracts/FixedFeeRegistrar.cpp @@ -58,10 +58,10 @@ pragma solidity ^0.4.0; contract Registrar { event Changed(string indexed name); - function owner(string _name) view returns (address o_owner); - function addr(string _name) view returns (address o_address); - function subRegistrar(string _name) view returns (address o_subRegistrar); - function content(string _name) view returns (bytes32 o_content); + function owner(string memory _name) public view returns (address o_owner); + function addr(string memory _name) public view returns (address o_address); + function subRegistrar(string memory _name) public view returns (address o_subRegistrar); + function content(string memory _name) public view returns (bytes32 o_content); } contract FixedFeeRegistrar is Registrar { @@ -72,52 +72,52 @@ contract FixedFeeRegistrar is Registrar { address owner; } - modifier onlyrecordowner(string _name) { if (m_record(_name).owner == msg.sender) _; } + modifier onlyrecordowner(string memory _name) { if (m_record(_name).owner == msg.sender) _; } - function reserve(string _name) payable { - Record rec = m_record(_name); + function reserve(string memory _name) public payable { + Record storage rec = m_record(_name); if (rec.owner == 0x0000000000000000000000000000000000000000 && msg.value >= c_fee) { rec.owner = msg.sender; emit Changed(_name); } } - function disown(string _name, address _refund) onlyrecordowner(_name) { + function disown(string memory _name, address _refund) onlyrecordowner(_name) public { delete m_recordData[uint(keccak256(bytes(_name))) / 8]; if (!_refund.send(c_fee)) - throw; + revert(); emit Changed(_name); } - function transfer(string _name, address _newOwner) onlyrecordowner(_name) { + function transfer(string memory _name, address _newOwner) onlyrecordowner(_name) public { m_record(_name).owner = _newOwner; emit Changed(_name); } - function setAddr(string _name, address _a) onlyrecordowner(_name) { + function setAddr(string memory _name, address _a) onlyrecordowner(_name) public { m_record(_name).addr = _a; emit Changed(_name); } - function setSubRegistrar(string _name, address _registrar) onlyrecordowner(_name) { + function setSubRegistrar(string memory _name, address _registrar) onlyrecordowner(_name) public { m_record(_name).subRegistrar = _registrar; emit Changed(_name); } - function setContent(string _name, bytes32 _content) onlyrecordowner(_name) { + function setContent(string memory _name, bytes32 _content) onlyrecordowner(_name) public { m_record(_name).content = _content; emit Changed(_name); } - function record(string _name) view returns (address o_addr, address o_subRegistrar, bytes32 o_content, address o_owner) { - Record rec = m_record(_name); + function record(string memory _name) public view returns (address o_addr, address o_subRegistrar, bytes32 o_content, address o_owner) { + Record storage rec = m_record(_name); o_addr = rec.addr; o_subRegistrar = rec.subRegistrar; o_content = rec.content; o_owner = rec.owner; } - function addr(string _name) view returns (address) { return m_record(_name).addr; } - function subRegistrar(string _name) view returns (address) { return m_record(_name).subRegistrar; } - function content(string _name) view returns (bytes32) { return m_record(_name).content; } - function owner(string _name) view returns (address) { return m_record(_name).owner; } + function addr(string memory _name) public view returns (address) { return m_record(_name).addr; } + function subRegistrar(string memory _name) public view returns (address) { return m_record(_name).subRegistrar; } + function content(string memory _name) public view returns (bytes32) { return m_record(_name).content; } + function owner(string memory _name) public view returns (address) { return m_record(_name).owner; } Record[2**253] m_recordData; - function m_record(string _name) view internal returns (Record storage o_record) { + function m_record(string memory _name) view internal returns (Record storage o_record) { return m_recordData[uint(keccak256(bytes(_name))) / 8]; } uint constant c_fee = 69 ether; diff --git a/test/contracts/Wallet.cpp b/test/contracts/Wallet.cpp index fb104300..dc949063 100644 --- a/test/contracts/Wallet.cpp +++ b/test/contracts/Wallet.cpp @@ -101,7 +101,7 @@ contract multiowned { // constructor is given number of sigs required to do protected "onlymanyowners" transactions // as well as the selection of addresses capable of confirming them. - constructor(address[] _owners, uint _required) { + constructor(address[] memory _owners, uint _required) public { m_numOwners = _owners.length + 1; m_owners[1] = uint(msg.sender); m_ownerIndex[uint(msg.sender)] = 1; @@ -119,7 +119,7 @@ contract multiowned { // make sure they're an owner if (ownerIndex == 0) return; uint ownerIndexBit = 2**ownerIndex; - PendingState pending = m_pending[_operation]; + PendingState storage pending = m_pending[_operation]; if (pending.ownersDone & ownerIndexBit > 0) { pending.yetNeeded++; pending.ownersDone -= ownerIndexBit; @@ -173,12 +173,12 @@ contract multiowned { emit RequirementChanged(_newRequired); } - function isOwner(address _addr) returns (bool) { + function isOwner(address _addr) public returns (bool) { return m_ownerIndex[uint(_addr)] > 0; } - function hasConfirmed(bytes32 _operation, address _owner) view returns (bool) { - PendingState pending = m_pending[_operation]; + function hasConfirmed(bytes32 _operation, address _owner) public view returns (bool) { + PendingState storage pending = m_pending[_operation]; uint ownerIndex = m_ownerIndex[uint(_owner)]; // make sure they're an owner @@ -201,7 +201,7 @@ contract multiowned { // make sure they're an owner if (ownerIndex == 0) return; - PendingState pending = m_pending[_operation]; + PendingState storage pending = m_pending[_operation]; // if we're not yet working on this operation, switch over and reset the confirmation status. if (pending.yetNeeded == 0) { // reset count of confirmations needed. @@ -288,7 +288,7 @@ contract daylimit is multiowned { // METHODS // constructor - stores initial daily limit and records the present day's index. - constructor(uint _limit) { + constructor(uint _limit) public { m_dailyLimit = _limit; m_lastDay = today(); } @@ -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 confirm(bytes32 _h) returns (bool); + function confirm(bytes32 _h) public returns (bool); } // usage: @@ -369,7 +369,7 @@ contract Wallet is multisig, multiowned, daylimit { // constructor - just pass on the owner array to the multiowned and // the limit to daylimit - constructor(address[] _owners, uint _required, uint _daylimit) payable + constructor(address[] memory _owners, uint _required, uint _daylimit) public payable multiowned(_owners, _required) daylimit(_daylimit) { } @@ -385,7 +385,7 @@ contract Wallet is multisig, multiowned, daylimit { emit Deposit(msg.sender, msg.value); } - // Outside-visible transact entry point. Executes transacion immediately if below daily spend limit. + // Outside-visible transact entry point. Executes transaction immediately if below daily spend limit. // 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. @@ -409,7 +409,7 @@ contract Wallet is multisig, multiowned, daylimit { // confirm a transaction through just the hash. we use the previous transactions map, m_txs, in order // to determine the body of the transaction from the hash provided. - function confirm(bytes32 _h) onlymanyowners(_h) returns (bool) { + function confirm(bytes32 _h) onlymanyowners(_h) public returns (bool) { if (m_txs[_h].to != 0x0000000000000000000000000000000000000000) { m_txs[_h].to.call.value(m_txs[_h].value)(m_txs[_h].data); emit MultiTransact(msg.sender, _h, m_txs[_h].value, m_txs[_h].to, m_txs[_h].data); diff --git a/test/libjulia/Parser.cpp b/test/libjulia/Parser.cpp index 07154718..3f329d28 100644 --- a/test/libjulia/Parser.cpp +++ b/test/libjulia/Parser.cpp @@ -267,7 +267,7 @@ BOOST_AUTO_TEST_CASE(recursion_depth) BOOST_AUTO_TEST_CASE(multiple_assignment) { CHECK_ERROR("{ let x:u256 function f() -> a:u256, b:u256 {} 123:u256, x := f() }", ParserError, "Label name / variable name must precede \",\" (multiple assignment)."); - CHECK_ERROR("{ let x:u256 function f() -> a:u256, b:u256 {} x, 123:u256 := f() }", ParserError, "Variable name expected in multiple assignemnt."); + CHECK_ERROR("{ let x:u256 function f() -> a:u256, b:u256 {} x, 123:u256 := f() }", ParserError, "Variable name expected in multiple assignment."); /// NOTE: Travis hiccups if not having a variable char const* text = R"( diff --git a/test/libsolidity/ABIDecoderTests.cpp b/test/libsolidity/ABIDecoderTests.cpp index 6504f6bc..28f982c4 100644 --- a/test/libsolidity/ABIDecoderTests.cpp +++ b/test/libsolidity/ABIDecoderTests.cpp @@ -128,7 +128,7 @@ BOOST_AUTO_TEST_CASE(fixed_arrays) { string sourceCode = R"( contract C { - function f(uint16[3] a, uint16[2][3] b, uint i, uint j, uint k) + function f(uint16[3] memory a, uint16[2][3] memory b, uint i, uint j, uint k) public pure returns (uint, uint) { return (a[i], b[j][k]); } @@ -154,7 +154,7 @@ BOOST_AUTO_TEST_CASE(dynamic_arrays) { string sourceCode = R"( contract C { - function f(uint a, uint16[] b, uint c) + function f(uint a, uint16[] memory b, uint c) public pure returns (uint, uint, uint) { return (b.length, b[a], c); } @@ -178,11 +178,11 @@ BOOST_AUTO_TEST_CASE(dynamic_nested_arrays) { string sourceCode = R"( contract C { - function f(uint a, uint16[][] b, uint[2][][3] c, uint d) + function f(uint a, uint16[][] memory b, uint[2][][3] memory c, uint d) public pure returns (uint, uint, uint, uint, uint, uint, uint) { return (a, b.length, b[1].length, b[1][1], c[1].length, c[1][1][1], d); } - function test() view returns (uint, uint, uint, uint, uint, uint, uint) { + function test() public view returns (uint, uint, uint, uint, uint, uint, uint) { uint16[][] memory b = new uint16[][](3); b[0] = new uint16[](2); b[0][0] = 0x55; @@ -229,7 +229,7 @@ BOOST_AUTO_TEST_CASE(byte_arrays) { string sourceCode = R"( contract C { - function f(uint a, bytes b, uint c) + function f(uint a, bytes memory b, uint c) public pure returns (uint, uint, byte, uint) { return (a, b.length, b[3], c); } @@ -285,7 +285,7 @@ BOOST_AUTO_TEST_CASE(decode_from_memory_simple) contract C { uint public _a; uint[] public _b; - constructor(uint a, uint[] b) public { + constructor(uint a, uint[] memory b) public { _a = a; _b = b; } @@ -344,13 +344,13 @@ BOOST_AUTO_TEST_CASE(decode_function_type_array) string sourceCode = R"( contract D { function () external returns (uint)[] public _a; - constructor(function () external returns (uint)[] a) public { + constructor(function () external returns (uint)[] memory a) public { _a = a; } } contract E { function () external returns (uint)[3] public _a; - constructor(function () external returns (uint)[3] a) public { + constructor(function () external returns (uint)[3] memory a) public { _a = a; } } @@ -364,10 +364,10 @@ BOOST_AUTO_TEST_CASE(decode_function_type_array) function f3() public returns (uint) { return 3; } - function g(function () external returns (uint)[] _f, uint i) public returns (uint) { + function g(function () external returns (uint)[] memory _f, uint i) public returns (uint) { return _f[i](); } - function h(function () external returns (uint)[3] _f, uint i) public returns (uint) { + function h(function () external returns (uint)[3] memory _f, uint i) public returns (uint) { return _f[i](); } // uses "decode from memory" @@ -412,7 +412,7 @@ BOOST_AUTO_TEST_CASE(decode_from_memory_complex) uint public _a; uint[] public _b; bytes[2] public _c; - constructor(uint a, uint[] b, bytes[2] c) public { + constructor(uint a, uint[] memory b, bytes[2] memory c) public { _a = a; _b = b; _c = c; @@ -459,7 +459,7 @@ BOOST_AUTO_TEST_CASE(short_input_array) { string sourceCode = R"( contract C { - function f(uint[] a) public pure returns (uint) { return 7; } + function f(uint[] memory a) public pure returns (uint) { return 7; } } )"; BOTH_ENCODERS( @@ -476,7 +476,7 @@ BOOST_AUTO_TEST_CASE(short_dynamic_input_array) { string sourceCode = R"( contract C { - function f(bytes[1] a) public pure returns (uint) { return 7; } + function f(bytes[1] memory a) public pure returns (uint) { return 7; } } )"; NEW_ENCODER( @@ -489,8 +489,8 @@ BOOST_AUTO_TEST_CASE(short_input_bytes) { string sourceCode = R"( contract C { - function e(bytes a) public pure returns (uint) { return 7; } - function f(bytes[] a) public pure returns (uint) { return 7; } + function e(bytes memory a) public pure returns (uint) { return 7; } + function f(bytes[] memory a) public pure returns (uint) { return 7; } } )"; NEW_ENCODER( @@ -511,9 +511,9 @@ BOOST_AUTO_TEST_CASE(cleanup_int_inside_arrays) string sourceCode = R"( contract C { enum E { A, B } - function f(uint16[] a) public pure returns (uint r) { assembly { r := mload(add(a, 0x20)) } } - function g(int16[] a) public pure returns (uint r) { assembly { r := mload(add(a, 0x20)) } } - function h(E[] a) public pure returns (uint r) { assembly { r := mload(add(a, 0x20)) } } + function f(uint16[] memory a) public pure returns (uint r) { assembly { r := mload(add(a, 0x20)) } } + function g(int16[] memory a) public pure returns (uint r) { assembly { r := mload(add(a, 0x20)) } } + function h(E[] memory a) public pure returns (uint r) { assembly { r := mload(add(a, 0x20)) } } } )"; NEW_ENCODER( @@ -569,7 +569,7 @@ BOOST_AUTO_TEST_CASE(struct_simple) string sourceCode = R"( contract C { struct S { uint a; uint8 b; uint8 c; bytes2 d; } - function f(S s) public pure returns (uint a, uint b, uint c, uint d) { + function f(S memory s) public pure returns (uint a, uint b, uint c, uint d) { a = s.a; b = s.b; c = s.c; @@ -588,7 +588,7 @@ BOOST_AUTO_TEST_CASE(struct_cleanup) string sourceCode = R"( contract C { struct S { int16 a; uint8 b; bytes2 c; } - function f(S s) public pure returns (uint a, uint b, uint c) { + function f(S memory s) public pure returns (uint a, uint b, uint c) { assembly { a := mload(s) b := mload(add(s, 0x20)) @@ -611,7 +611,7 @@ BOOST_AUTO_TEST_CASE(struct_short) string sourceCode = R"( contract C { struct S { int a; uint b; bytes16 c; } - function f(S s) public pure returns (S q) { + function f(S memory s) public pure returns (S memory q) { q = s; } } @@ -638,7 +638,7 @@ BOOST_AUTO_TEST_CASE(struct_function) string sourceCode = R"( contract C { struct S { function () external returns (uint) f; uint b; } - function f(S s) public returns (uint, uint) { + function f(S memory s) public returns (uint, uint) { return (s.f(), s.b); } function test() public returns (uint, uint) { @@ -658,7 +658,7 @@ BOOST_AUTO_TEST_CASE(mediocre_struct) string sourceCode = R"( contract C { struct S { C c; } - function f(uint a, S[2] s1, uint b) public returns (uint r1, C r2, uint r3) { + function f(uint a, S[2] memory s1, uint b) public returns (uint r1, C r2, uint r3) { r1 = a; r2 = s1[0].c; r3 = b; @@ -679,7 +679,7 @@ BOOST_AUTO_TEST_CASE(mediocre2_struct) string sourceCode = R"( contract C { struct S { C c; uint[] x; } - function f(uint a, S[2] s1, uint b) public returns (uint r1, C r2, uint r3) { + function f(uint a, S[2] memory s1, uint b) public returns (uint r1, C r2, uint r3) { r1 = a; r2 = s1[0].c; r3 = b; @@ -707,7 +707,7 @@ BOOST_AUTO_TEST_CASE(complex_struct) enum E {A, B, C} struct T { uint x; E e; uint8 y; } struct S { C c; T[] t;} - function f(uint a, S[2] s1, S[] s2, uint b) public returns + function f(uint a, S[2] memory s1, S[] memory s2, uint b) public returns (uint r1, C r2, uint r3, uint r4, C r5, uint r6, E r7, uint8 r8) { r1 = a; r2 = s1[0].c; @@ -767,10 +767,10 @@ BOOST_AUTO_TEST_CASE(return_dynamic_types_cross_call_simple) string sourceCode = R"( contract C { - function dyn() public returns (bytes) { + function dyn() public returns (bytes memory) { return "1234567890123456789012345678901234567890"; } - function f() public returns (bytes) { + function f() public returns (bytes memory) { return this.dyn(); } } @@ -788,7 +788,7 @@ BOOST_AUTO_TEST_CASE(return_dynamic_types_cross_call_advanced) string sourceCode = R"( contract C { - function dyn() public returns (bytes a, uint b, bytes20[] c, uint d) { + function dyn() public returns (bytes memory a, uint b, bytes20[] memory c, uint d) { a = "1234567890123456789012345678901234567890"; b = uint(-1); c = new bytes20[](4); @@ -796,7 +796,7 @@ BOOST_AUTO_TEST_CASE(return_dynamic_types_cross_call_advanced) c[3] = bytes20(6789); d = 0x1234; } - function f() public returns (bytes, uint, bytes20[], uint) { + function f() public returns (bytes memory, uint, bytes20[] memory, uint) { return this.dyn(); } } @@ -815,7 +815,7 @@ BOOST_AUTO_TEST_CASE(return_dynamic_types_cross_call_out_of_range) { string sourceCode = R"( contract C { - function dyn(uint x) public returns (bytes a) { + function dyn(uint x) public returns (bytes memory a) { assembly { mstore(0, 0x20) mstore(0x20, 0x21) diff --git a/test/libsolidity/ABIEncoderTests.cpp b/test/libsolidity/ABIEncoderTests.cpp index 9b6250d8..b1eda425 100644 --- a/test/libsolidity/ABIEncoderTests.cpp +++ b/test/libsolidity/ABIEncoderTests.cpp @@ -417,7 +417,7 @@ BOOST_AUTO_TEST_CASE(structs) struct T { uint64[2] x; } S s; event e(uint16, S); - function f() public returns (uint, S) { + function f() public returns (uint, S memory) { uint16 x = 7; s.a = 8; s.b = 9; @@ -454,7 +454,7 @@ BOOST_AUTO_TEST_CASE(structs2) enum E {A, B, C} struct T { uint x; E e; uint8 y; } struct S { C c; T[] t;} - function f() public returns (uint a, S[2] s1, S[] s2, uint b) { + function f() public returns (uint a, S[2] memory s1, S[] memory s2, uint b) { a = 7; b = 8; s1[0].c = this; diff --git a/test/libsolidity/ASTJSON.cpp b/test/libsolidity/ASTJSON.cpp index 03e74097..482b05e6 100644 --- a/test/libsolidity/ASTJSON.cpp +++ b/test/libsolidity/ASTJSON.cpp @@ -88,7 +88,7 @@ BOOST_AUTO_TEST_CASE(long_type_name_binary_operation) BOOST_AUTO_TEST_CASE(long_type_name_identifier) { CompilerStack c; - c.addSource("a", "contract c { uint[] a; function f() public { uint[] b = a; } }"); + c.addSource("a", "contract c { uint[] a; function f() public { uint[] storage b = a; } }"); c.setEVMVersion(dev::test::Options::get().evmVersion()); c.parseAndAnalyze(); map<string, unsigned> sourceIndices; diff --git a/test/libsolidity/GasMeter.cpp b/test/libsolidity/GasMeter.cpp index a404c072..84e30033 100644 --- a/test/libsolidity/GasMeter.cpp +++ b/test/libsolidity/GasMeter.cpp @@ -119,7 +119,7 @@ BOOST_AUTO_TEST_CASE(non_overlapping_filtered_costs) char const* sourceCode = R"( contract test { bytes x; - function f(uint a) returns (uint b) { + function f(uint a) public returns (uint b) { x.length = a; for (; a < 200; ++a) { x[a] = 9; @@ -152,7 +152,7 @@ BOOST_AUTO_TEST_CASE(simple_contract) char const* sourceCode = R"( contract test { bytes32 public shaValue; - function f(uint a) { + function f(uint a) public { shaValue = keccak256(abi.encodePacked(a)); } } @@ -165,7 +165,7 @@ BOOST_AUTO_TEST_CASE(store_keccak256) char const* sourceCode = R"( contract test { bytes32 public shaValue; - constructor(uint a) { + constructor(uint a) public { shaValue = keccak256(abi.encodePacked(a)); } } @@ -179,7 +179,7 @@ BOOST_AUTO_TEST_CASE(updating_store) contract test { uint data; uint data2; - constructor() { + constructor() public { data = 1; data = 2; data2 = 0; @@ -195,7 +195,7 @@ BOOST_AUTO_TEST_CASE(branches) contract test { uint data; uint data2; - function f(uint x) { + function f(uint x) public { if (x > 7) data2 = 1; else @@ -213,7 +213,7 @@ BOOST_AUTO_TEST_CASE(function_calls) contract test { uint data; uint data2; - function f(uint x) { + function f(uint x) public { if (x > 7) data2 = g(x**8) + 1; else @@ -234,13 +234,13 @@ BOOST_AUTO_TEST_CASE(multiple_external_functions) contract test { uint data; uint data2; - function f(uint x) { + function f(uint x) public { if (x > 7) data2 = g(x**8) + 1; else data = 1; } - function g(uint x) returns (uint) { + function g(uint x) public returns (uint) { return data2; } } @@ -254,10 +254,10 @@ BOOST_AUTO_TEST_CASE(exponent_size) { char const* sourceCode = R"( contract A { - function g(uint x) returns (uint) { + function g(uint x) public returns (uint) { return x ** 0x100; } - function h(uint x) returns (uint) { + function h(uint x) public returns (uint) { return x ** 0x10000; } } @@ -271,7 +271,7 @@ BOOST_AUTO_TEST_CASE(balance_gas) { char const* sourceCode = R"( contract A { - function lookup_balance(address a) returns (uint) { + function lookup_balance(address a) public returns (uint) { return a.balance; } } @@ -284,7 +284,7 @@ BOOST_AUTO_TEST_CASE(extcodesize_gas) { char const* sourceCode = R"( contract A { - function f() returns (uint _s) { + function f() public returns (uint _s) { assembly { _s := extcodesize(0x30) } @@ -316,7 +316,7 @@ BOOST_AUTO_TEST_CASE(complex_control_flow) // we previously considered. This of course reduces accuracy. char const* sourceCode = R"( contract log { - function ln(int128 x) pure returns (int128 result) { + function ln(int128 x) public pure returns (int128 result) { int128 t = x / 256; int128 y = 5545177; x = t; diff --git a/test/libsolidity/Imports.cpp b/test/libsolidity/Imports.cpp index 4b700ceb..df31ac40 100644 --- a/test/libsolidity/Imports.cpp +++ b/test/libsolidity/Imports.cpp @@ -138,7 +138,7 @@ BOOST_AUTO_TEST_CASE(complex_import) CompilerStack c; c.addSource("a", "contract A {} contract B {} contract C { struct S { uint a; } } pragma solidity >=0.0;"); c.addSource("b", "import \"a\" as x; import {B as b, C as c, C} from \"a\"; " - "contract D is b { function f(c.S var1, x.C.S var2, C.S var3) internal {} } pragma solidity >=0.0;"); + "contract D is b { function f(c.S memory var1, x.C.S memory var2, C.S memory var3) internal {} } pragma solidity >=0.0;"); c.setEVMVersion(dev::test::Options::get().evmVersion()); BOOST_CHECK(c.compile()); } diff --git a/test/libsolidity/InlineAssembly.cpp b/test/libsolidity/InlineAssembly.cpp index 3046372f..a9ce6e49 100644 --- a/test/libsolidity/InlineAssembly.cpp +++ b/test/libsolidity/InlineAssembly.cpp @@ -461,7 +461,7 @@ BOOST_AUTO_TEST_CASE(recursion_depth) BOOST_AUTO_TEST_CASE(multiple_assignment) { CHECK_PARSE_ERROR("{ let x function f() -> a, b {} 123, x := f() }", ParserError, "Label name / variable name must precede \",\" (multiple assignment)."); - CHECK_PARSE_ERROR("{ let x function f() -> a, b {} x, 123 := f() }", ParserError, "Variable name expected in multiple assignemnt."); + CHECK_PARSE_ERROR("{ let x function f() -> a, b {} x, 123 := f() }", ParserError, "Variable name expected in multiple assignment."); /// NOTE: Travis hiccups if not having a variable char const* text = R"( diff --git a/test/libsolidity/JSONCompiler.cpp b/test/libsolidity/LibSolc.cpp index 2b3df3a7..9d5ffa27 100644 --- a/test/libsolidity/JSONCompiler.cpp +++ b/test/libsolidity/LibSolc.cpp @@ -16,7 +16,7 @@ */ /** * @date 2017 - * Unit tests for solc/jsonCompiler.cpp. + * Unit tests for libsolc/libsolc.cpp. */ #include <string> @@ -70,7 +70,7 @@ Json::Value compile(string const& _input) } // end anonymous namespace -BOOST_AUTO_TEST_SUITE(JSONCompiler) +BOOST_AUTO_TEST_SUITE(LibSolc) BOOST_AUTO_TEST_CASE(read_version) { @@ -201,6 +201,26 @@ BOOST_AUTO_TEST_CASE(standard_compilation) BOOST_CHECK(result.isMember("contracts")); } +BOOST_AUTO_TEST_CASE(new_api) +{ + char const* input = R"( + { + "language": "Solidity", + "sources": { + "fileA": { + "content": "contract A { }" + } + } + } + )"; + BOOST_CHECK_EQUAL(string(version()), string(solidity_version())); + BOOST_CHECK_EQUAL(string(license()), string(solidity_license())); + BOOST_CHECK_EQUAL( + string(compileStandard(input, nullptr)), + string(solidity_compile(input, nullptr)) + ); +} + BOOST_AUTO_TEST_SUITE_END() } diff --git a/test/libsolidity/Metadata.cpp b/test/libsolidity/Metadata.cpp index 808bd1e1..007ee2b6 100644 --- a/test/libsolidity/Metadata.cpp +++ b/test/libsolidity/Metadata.cpp @@ -41,7 +41,7 @@ BOOST_AUTO_TEST_CASE(metadata_stamp) pragma solidity >=0.0; pragma experimental __testOnlyAnalysis; contract test { - function g(function(uint) external returns (uint) x) {} + function g(function(uint) external returns (uint) x) public {} } )"; CompilerStack compilerStack; @@ -68,7 +68,7 @@ BOOST_AUTO_TEST_CASE(metadata_stamp_experimental) pragma solidity >=0.0; pragma experimental __test; contract test { - function g(function(uint) external returns (uint) x) {} + function g(function(uint) external returns (uint) x) public {} } )"; CompilerStack compilerStack; @@ -97,14 +97,14 @@ BOOST_AUTO_TEST_CASE(metadata_relevant_sources) char const* sourceCode = R"( pragma solidity >=0.0; contract A { - function g(function(uint) external returns (uint) x) {} + function g(function(uint) external returns (uint) x) public {} } )"; compilerStack.addSource("A", std::string(sourceCode)); sourceCode = R"( pragma solidity >=0.0; contract B { - function g(function(uint) external returns (uint) x) {} + function g(function(uint) external returns (uint) x) public {} } )"; compilerStack.addSource("B", std::string(sourceCode)); @@ -127,7 +127,7 @@ BOOST_AUTO_TEST_CASE(metadata_relevant_sources_imports) char const* sourceCode = R"( pragma solidity >=0.0; contract A { - function g(function(uint) external returns (uint) x) {} + function g(function(uint) external returns (uint) x) public {} } )"; compilerStack.addSource("A", std::string(sourceCode)); @@ -135,7 +135,7 @@ BOOST_AUTO_TEST_CASE(metadata_relevant_sources_imports) pragma solidity >=0.0; import "./A"; contract B is A { - function g(function(uint) external returns (uint) x) {} + function g(function(uint) external returns (uint) x) public {} } )"; compilerStack.addSource("B", std::string(sourceCode)); @@ -143,7 +143,7 @@ BOOST_AUTO_TEST_CASE(metadata_relevant_sources_imports) pragma solidity >=0.0; import "./B"; contract C is B { - function g(function(uint) external returns (uint) x) {} + function g(function(uint) external returns (uint) x) public {} } )"; compilerStack.addSource("C", std::string(sourceCode)); diff --git a/test/libsolidity/SMTChecker.cpp b/test/libsolidity/SMTChecker.cpp index 57f414db..497ee867 100644 --- a/test/libsolidity/SMTChecker.cpp +++ b/test/libsolidity/SMTChecker.cpp @@ -91,7 +91,7 @@ BOOST_AUTO_TEST_CASE(warn_on_struct) pragma experimental ABIEncoderV2; contract C { struct A { uint a; uint b; } - function f() public pure returns (A) { + function f() public pure returns (A memory) { return A({ a: 1, b: 2 }); } } diff --git a/test/libsolidity/SolidityABIJSON.cpp b/test/libsolidity/SolidityABIJSON.cpp index c366e866..14413ca0 100644 --- a/test/libsolidity/SolidityABIJSON.cpp +++ b/test/libsolidity/SolidityABIJSON.cpp @@ -199,7 +199,7 @@ BOOST_AUTO_TEST_CASE(multiple_params) BOOST_AUTO_TEST_CASE(multiple_methods_order) { - // methods are expected to be in alpabetical order + // methods are expected to be in alphabetical order char const* sourceCode = R"( contract test { function f(uint a) public returns (uint d) { return a * 7; } @@ -256,7 +256,7 @@ BOOST_AUTO_TEST_CASE(view_function) char const* sourceCode = R"( contract test { function foo(uint a, uint b) public returns (uint d) { return a + b; } - function boo(uint32 a) view returns(uint b) { return a * 4; } + function boo(uint32 a) public view returns(uint b) { return a * 4; } } )"; @@ -311,7 +311,7 @@ BOOST_AUTO_TEST_CASE(pure_function) char const* sourceCode = R"( contract test { function foo(uint a, uint b) public returns (uint d) { return a + b; } - function boo(uint32 a) pure returns(uint b) { return a * 4; } + function boo(uint32 a) public pure returns (uint b) { return a * 4; } } )"; @@ -616,7 +616,7 @@ BOOST_AUTO_TEST_CASE(constructor_abi) { char const* sourceCode = R"( contract test { - constructor(uint param1, test param2, bool param3) {} + constructor(uint param1, test param2, bool param3) public {} } )"; @@ -648,7 +648,7 @@ BOOST_AUTO_TEST_CASE(payable_constructor_abi) { char const* sourceCode = R"( contract test { - constructor(uint param1, test param2, bool param3) payable {} + constructor(uint param1, test param2, bool param3) public payable {} } )"; @@ -682,7 +682,7 @@ BOOST_AUTO_TEST_CASE(return_param_in_abi) char const* sourceCode = R"( contract test { enum ActionChoices { GoLeft, GoRight, GoStraight, Sit } - constructor(ActionChoices param) {} + constructor(ActionChoices param) public {} function ret() public returns (ActionChoices) { ActionChoices action = ActionChoices.GoLeft; return action; @@ -756,7 +756,7 @@ BOOST_AUTO_TEST_CASE(library_function) char const* sourceCode = R"( library test { struct StructType { uint a; } - function f(StructType storage b, uint[] storage c, test d) public returns (uint[] e, StructType storage f) {} + function f(StructType storage b, uint[] storage c, test d) public returns (uint[] memory e, StructType storage f) {} } )"; @@ -807,8 +807,8 @@ BOOST_AUTO_TEST_CASE(payable_function) { char const* sourceCode = R"( contract test { - function f() {} - function g() payable {} + function f() public {} + function g() public payable {} } )"; @@ -861,7 +861,7 @@ BOOST_AUTO_TEST_CASE(function_type) { char const* sourceCode = R"( contract test { - function g(function(uint) external returns (uint) x) {} + function g(function(uint) external returns (uint) x) public {} } )"; @@ -891,7 +891,7 @@ BOOST_AUTO_TEST_CASE(return_structs) contract C { struct S { uint a; T[] sub; } struct T { uint[2] x; } - function f() public returns (uint x, S s) { + function f() public returns (uint x, S memory s) { } } )"; @@ -940,7 +940,7 @@ BOOST_AUTO_TEST_CASE(return_structs_with_contracts) pragma experimental ABIEncoderV2; contract C { struct S { C[] x; C y; } - function f() public returns (S s, C c) { + function f() public returns (S memory s, C c) { } } )"; @@ -1041,8 +1041,8 @@ BOOST_AUTO_TEST_CASE(structs_in_libraries) library L { struct S { uint a; T[] sub; bytes b; } struct T { uint[2] x; } - function f(L.S storage s) {} - function g(L.S s) {} + function f(L.S storage s) public {} + function g(L.S memory s) public {} } )"; char const* interface = R"( diff --git a/test/libsolidity/SolidityEndToEndTest.cpp b/test/libsolidity/SolidityEndToEndTest.cpp index bc613868..be590557 100644 --- a/test/libsolidity/SolidityEndToEndTest.cpp +++ b/test/libsolidity/SolidityEndToEndTest.cpp @@ -53,9 +53,9 @@ BOOST_AUTO_TEST_CASE(transaction_status) { char const* sourceCode = R"( contract test { - function f() { } - function g() { revert(); } - function h() { assert(false); } + function f() public { } + function g() public { revert(); } + function h() public { assert(false); } } )"; compileAndRun(sourceCode); @@ -523,6 +523,96 @@ BOOST_AUTO_TEST_CASE(do_while_loop_continue) ABI_CHECK(callContractFunction("f()"), encodeArgs(42)); } +BOOST_AUTO_TEST_CASE(array_multiple_local_vars) +{ + char const* sourceCode = R"( + contract test { + function f(uint256[] seq) external pure returns (uint256) { + uint i = 0; + uint sum = 0; + while (i < seq.length) + { + uint idx = i; + if (idx >= 10) break; + uint x = seq[idx]; + if (x >= 1000) { + uint n = i + 1; + i = n; + continue; + } + else { + uint y = sum + x; + sum = y; + } + if (sum >= 500) return sum; + i++; + } + return sum; + } + } + )"; + compileAndRun(sourceCode); + + ABI_CHECK(callContractFunction("f(uint256[])", 32, 3, u256(1000), u256(1), u256(2)), encodeArgs(3)); + ABI_CHECK(callContractFunction("f(uint256[])", 32, 3, u256(100), u256(500), u256(300)), encodeArgs(600)); + ABI_CHECK(callContractFunction( + "f(uint256[])", 32, 11, + u256(1), u256(2), u256(3), u256(4), u256(5), u256(6), u256(7), u256(8), u256(9), u256(10), u256(111) + ), encodeArgs(55)); +} + + +BOOST_AUTO_TEST_CASE(do_while_loop_multiple_local_vars) +{ + char const* sourceCode = R"( + contract test { + function f(uint x) public pure returns(uint r) { + uint i = 0; + do + { + uint z = x * 2; + if (z < 4) break; + else { + uint k = z + 1; + if (k < 8) { + x++; + continue; + } + } + if (z > 12) return 0; + x++; + i++; + } while (true); + return 42; + } + } + )"; + compileAndRun(sourceCode); + + auto do_while = [](u256 n) -> u256 + { + u256 i = 0; + do + { + u256 z = n * 2; + if (z < 4) break; + else { + u256 k = z + 1; + if (k < 8) { + n++; + continue; + } + } + if (z > 12) return 0; + n++; + i++; + } while (true); + return 42; + }; + + testContractAgainstCppOnRange("f(uint256)", do_while, 0, 12); +} + BOOST_AUTO_TEST_CASE(nested_loops) { // tests that break and continue statements in nested loops jump to the correct place @@ -574,6 +664,178 @@ BOOST_AUTO_TEST_CASE(nested_loops) testContractAgainstCppOnRange("f(uint256)", nested_loops_cpp, 0, 12); } +BOOST_AUTO_TEST_CASE(nested_loops_multiple_local_vars) +{ + // tests that break and continue statements in nested loops jump to the correct place + // and free local variables properly + char const* sourceCode = R"( + contract test { + function f(uint x) public returns(uint y) { + while (x > 0) { + uint z = x + 10; + uint k = z + 1; + if (k > 20) { + break; + uint p = 100; + k += p; + } + if (k > 15) { + x--; + continue; + uint t = 1000; + x += t; + } + while (k > 10) { + uint m = k - 1; + if (m == 10) return x; + return k; + uint h = 10000; + z += h; + } + x--; + break; + } + return x; + } + } + )"; + compileAndRun(sourceCode); + + auto nested_loops_cpp = [](u256 n) -> u256 + { + while (n > 0) + { + u256 z = n + 10; + u256 k = z + 1; + if (k > 20) break; + if (k > 15) { + n--; + continue; + } + while (k > 10) + { + u256 m = k - 1; + if (m == 10) return n; + return k; + } + n--; + break; + } + + return n; + }; + + testContractAgainstCppOnRange("f(uint256)", nested_loops_cpp, 0, 12); +} + +BOOST_AUTO_TEST_CASE(for_loop_multiple_local_vars) +{ + char const* sourceCode = R"( + contract test { + function f(uint x) public pure returns(uint r) { + for (uint i = 0; i < 12; i++) + { + uint z = x + 1; + if (z < 4) break; + else { + uint k = z * 2; + if (i + k < 10) { + x++; + continue; + } + } + if (z > 8) return 0; + x++; + } + return 42; + } + } + )"; + compileAndRun(sourceCode); + + auto for_loop = [](u256 n) -> u256 + { + for (u256 i = 0; i < 12; i++) + { + u256 z = n + 1; + if (z < 4) break; + else { + u256 k = z * 2; + if (i + k < 10) { + n++; + continue; + } + } + if (z > 8) return 0; + n++; + } + return 42; + }; + + testContractAgainstCppOnRange("f(uint256)", for_loop, 0, 12); +} + +BOOST_AUTO_TEST_CASE(nested_for_loop_multiple_local_vars) +{ + char const* sourceCode = R"( + contract test { + function f(uint x) public pure returns(uint r) { + for (uint i = 0; i < 5; i++) + { + uint z = x + 1; + if (z < 3) { + break; + uint p = z + 2; + } + for (uint j = 0; j < 5; j++) + { + uint k = z * 2; + if (j + k < 8) { + x++; + continue; + uint t = z * 3; + } + x++; + if (x > 20) { + return 84; + uint h = x + 42; + } + } + if (x > 30) { + return 42; + uint b = 0xcafe; + } + } + return 42; + } + } + )"; + compileAndRun(sourceCode); + + auto for_loop = [](u256 n) -> u256 + { + for (u256 i = 0; i < 5; i++) + { + u256 z = n + 1; + if (z < 3) break; + for (u256 j = 0; j < 5; j++) + { + u256 k = z * 2; + if (j + k < 8) { + n++; + continue; + } + n++; + if (n > 20) return 84; + } + if (n > 30) return 42; + } + return 42; + }; + + testContractAgainstCppOnRange("f(uint256)", for_loop, 0, 12); +} + BOOST_AUTO_TEST_CASE(for_loop) { char const* sourceCode = R"( @@ -991,7 +1253,7 @@ BOOST_AUTO_TEST_CASE(state_smoke_test) if (which == 0) return value1; else return value2; } - function set(uint8 which, uint256 value) { + function set(uint8 which, uint256 value) public { if (which == 0) value1 = value; else value2 = value; } @@ -1053,7 +1315,7 @@ BOOST_AUTO_TEST_CASE(simple_mapping) function get(uint8 k) public returns (uint8 v) { return table[k]; } - function set(uint8 k, uint8 v) { + function set(uint8 k, uint8 v) public { table[k] = v; } } @@ -1087,7 +1349,7 @@ BOOST_AUTO_TEST_CASE(mapping_state) function getVoteCount(address addr) public returns (uint retVoteCount) { return voteCount[addr]; } - function grantVoteRight(address addr) { + function grantVoteRight(address addr) public { canVote[addr] = true; } function vote(address voter, address vote) public returns (bool success) { @@ -1273,7 +1535,7 @@ BOOST_AUTO_TEST_CASE(struct_reference) function set() public { data.z = 2; mapping(uint8 => s2) map = data.recursive; - s2 inner = map[0]; + s2 storage inner = map[0]; inner.z = 3; inner.recursive[0].z = inner.recursive[1].z + 1; } @@ -1300,7 +1562,7 @@ BOOST_AUTO_TEST_CASE(deleteStruct) uint nestedValue; mapping (uint => bool) nestedMapping; } - constructor(){ + constructor() public { toDelete = 5; str.topValue = 1; str.topMapping[0] = 1; @@ -1821,9 +2083,9 @@ BOOST_AUTO_TEST_CASE(transfer_ether) constructor() public payable {} function a(address addr, uint amount) public returns (uint) { addr.transfer(amount); - return this.balance; + return address(this).balance; } - function b(address addr, uint amount) { + function b(address addr, uint amount) public { addr.transfer(amount); } } @@ -1833,7 +2095,7 @@ BOOST_AUTO_TEST_CASE(transfer_ether) contract C { function () external payable { - throw; + revert(); } } )"; @@ -2082,7 +2344,7 @@ BOOST_AUTO_TEST_CASE(packed_keccak256) function a(bytes32 input) public returns (bytes32 hash) { uint24 b = 65536; uint c = 256; - return keccak256(abi.encodePacked(8, input, b, input, c)); + return keccak256(abi.encodePacked(uint8(8), input, b, input, c)); } } )"; @@ -2134,7 +2396,7 @@ BOOST_AUTO_TEST_CASE(packed_sha256) function a(bytes32 input) public returns (bytes32 hash) { uint24 b = 65536; uint c = 256; - return sha256(abi.encodePacked(8, input, b, input, c)); + return sha256(abi.encodePacked(uint8(8), input, b, input, c)); } } )"; @@ -2161,7 +2423,7 @@ BOOST_AUTO_TEST_CASE(packed_ripemd160) function a(bytes32 input) public returns (bytes32 hash) { uint24 b = 65536; uint c = 256; - return ripemd160(abi.encodePacked(8, input, b, input, c)); + return ripemd160(abi.encodePacked(uint8(8), input, b, input, c)); } } )"; @@ -2215,7 +2477,7 @@ BOOST_AUTO_TEST_CASE(inter_contract_calls) function getHelper() public returns (address haddress) { return address(h); } - function setHelper(address haddress) { + function setHelper(address haddress) public { h = Helper(haddress); } } @@ -2246,7 +2508,7 @@ BOOST_AUTO_TEST_CASE(inter_contract_calls_with_complex_parameters) function getHelper() public returns (address haddress) { return address(h); } - function setHelper(address haddress) { + function setHelper(address haddress) public { h = Helper(haddress); } } @@ -2278,7 +2540,7 @@ BOOST_AUTO_TEST_CASE(inter_contract_calls_accessing_this) function getHelper() public returns (address addr) { return address(h); } - function setHelper(address addr) { + function setHelper(address addr) public { h = Helper(addr); } } @@ -2310,7 +2572,7 @@ BOOST_AUTO_TEST_CASE(calls_to_this) function getHelper() public returns (address addr) { return address(h); } - function setHelper(address addr) { + function setHelper(address addr) public { h = Helper(addr); } } @@ -2345,7 +2607,7 @@ BOOST_AUTO_TEST_CASE(inter_contract_calls_with_local_vars) function getHelper() public returns (address haddress) { return address(h); } - function setHelper(address haddress) { + function setHelper(address haddress) public { h = Helper(haddress); } } @@ -2376,7 +2638,7 @@ BOOST_AUTO_TEST_CASE(fixed_bytes_in_calls) function getHelper() public returns (address addr) { return address(h); } - function setHelper(address addr) { + function setHelper(address addr) public { h = Helper(addr); } } @@ -2444,7 +2706,7 @@ BOOST_AUTO_TEST_CASE(constructor_with_long_arguments) string public a; string public b; - constructor(string _a, string _b) public { + constructor(string memory _a, string memory _b) public { a = _a; b = _b; } @@ -2472,7 +2734,7 @@ BOOST_AUTO_TEST_CASE(constructor_static_array_argument) uint public a; uint[3] public b; - constructor(uint _a, uint[3] _b) public { + constructor(uint _a, uint[3] memory _b) public { a = _a; b = _b; } @@ -2492,7 +2754,7 @@ BOOST_AUTO_TEST_CASE(constant_var_as_array_length) uint constant LEN = 3; uint[LEN] public a; - constructor(uint[LEN] _a) public { + constructor(uint[LEN] memory _a) public { a = _a; } } @@ -2528,10 +2790,10 @@ BOOST_AUTO_TEST_CASE(contracts_as_addresses) } contract test { helper h; - constructor() public payable { h = new helper(); h.send(5); } + constructor() public payable { h = new helper(); address(h).send(5); } function getBalance() public returns (uint256 myBalance, uint256 helperBalance) { - myBalance = this.balance; - helperBalance = h.balance; + myBalance = address(this).balance; + helperBalance = address(h).balance; } } )"; @@ -2546,7 +2808,7 @@ BOOST_AUTO_TEST_CASE(gas_and_value_basic) contract helper { bool flag; function getBalance() payable public returns (uint256 myBalance) { - return this.balance; + return address(this).balance; } function setFlag() public { flag = true; } function getFlag() public returns (bool fl) { return flag; } @@ -2563,7 +2825,7 @@ BOOST_AUTO_TEST_CASE(gas_and_value_basic) } function checkState() public returns (bool flagAfter, uint myBal) { flagAfter = h.getFlag(); - myBal = this.balance; + myBal = address(this).balance; } } )"; @@ -2579,13 +2841,13 @@ BOOST_AUTO_TEST_CASE(value_complex) char const* sourceCode = R"( contract helper { function getBalance() payable public returns (uint256 myBalance) { - return this.balance; + return address(this).balance; } } contract test { helper h; constructor() public payable { h = new helper(); } - function sendAmount(uint amount) payable returns (uint256 bal) { + function sendAmount(uint amount) public payable returns (uint256 bal) { uint someStackElement = 20; return h.getBalance.value(amount).gas(1000).value(amount + 3)(); } @@ -2600,7 +2862,7 @@ BOOST_AUTO_TEST_CASE(value_insane) char const* sourceCode = R"( contract helper { function getBalance() payable public returns (uint256 myBalance) { - return this.balance; + return address(this).balance; } } contract test { @@ -2621,7 +2883,7 @@ BOOST_AUTO_TEST_CASE(value_for_constructor) contract Helper { bytes3 name; bool flag; - constructor(bytes3 x, bool f) payable { + constructor(bytes3 x, bool f) public payable { name = x; flag = f; } @@ -2630,12 +2892,12 @@ BOOST_AUTO_TEST_CASE(value_for_constructor) } contract Main { Helper h; - constructor() payable { + constructor() public payable { h = (new Helper).value(10)("abc", true); } function getFlag() public returns (bool ret) { return h.getFlag(); } function getName() public returns (bytes3 ret) { return h.getName(); } - function getBalances() public returns (uint me, uint them) { me = this.balance; them = h.balance;} + function getBalances() public returns (uint me, uint them) { me = address(this).balance; them = address(h).balance;} } )"; compileAndRun(sourceCode, 22, "Main"); @@ -2691,10 +2953,10 @@ BOOST_AUTO_TEST_CASE(single_copy_with_multiple_inheritance) char const* sourceCode = R"( contract Base { uint data; - function setData(uint i) { data = i; } + function setData(uint i) public { data = i; } function getViaBase() public returns (uint i) { return data; } } - contract A is Base { function setViaA(uint i) { setData(i); } } + contract A is Base { function setViaA(uint i) public { setData(i); } } contract B is Base { function getViaB() public returns (uint i) { return getViaBase(); } } contract Derived is Base, B, A { } )"; @@ -2903,7 +3165,7 @@ BOOST_AUTO_TEST_CASE(function_modifier_for_constructor) char const* sourceCode = R"( contract A { uint data; - constructor() mod1 { data |= 2; } + constructor() mod1 public { data |= 2; } modifier mod1 { data |= 1; _; } function getData() public returns (uint r) { return data; } } @@ -3079,7 +3341,7 @@ BOOST_AUTO_TEST_CASE(default_fallback_throws) char const* sourceCode = R"YY( contract A { function f() public returns (bool) { - return this.call(""); + return address(this).call(""); } } )YY"; @@ -3113,7 +3375,7 @@ BOOST_AUTO_TEST_CASE(event) char const* sourceCode = R"( contract ClientReceipt { event Deposit(address indexed _from, bytes32 indexed _id, uint _value); - function deposit(bytes32 _id, bool _manually) payable { + function deposit(bytes32 _id, bool _manually) public payable { if (_manually) { bytes32 s = 0x19dacbf83c5de6658e14cbf7bcae5c15eca2eedecf1c66fbca928e4d351bea0f; log3(bytes32(msg.value), s, bytes32(uint256(msg.sender)), _id); @@ -3144,7 +3406,7 @@ BOOST_AUTO_TEST_CASE(event_emit) char const* sourceCode = R"( contract ClientReceipt { event Deposit(address indexed _from, bytes32 indexed _id, uint _value); - function deposit(bytes32 _id) payable { + function deposit(bytes32 _id) public payable { emit Deposit(msg.sender, _id, msg.value); } } @@ -3322,7 +3584,7 @@ BOOST_AUTO_TEST_CASE(event_anonymous_with_topics) char const* sourceCode = R"( contract ClientReceipt { event Deposit(address indexed _from, bytes32 indexed _id, uint indexed _value, uint indexed _value2, bytes32 data) anonymous; - function deposit(bytes32 _id) payable { + function deposit(bytes32 _id) public payable { emit Deposit(msg.sender, _id, msg.value, 2, "abc"); } } @@ -3346,7 +3608,7 @@ BOOST_AUTO_TEST_CASE(event_lots_of_data) char const* sourceCode = R"( contract ClientReceipt { event Deposit(address _from, bytes32 _id, uint _value, bool _flag); - function deposit(bytes32 _id) payable { + function deposit(bytes32 _id) public payable { emit Deposit(msg.sender, _id, msg.value, true); } } @@ -3560,7 +3822,7 @@ BOOST_AUTO_TEST_CASE(keccak256_multiple_arguments_with_numeric_literals) contract c { function foo(uint a, uint16 b) public returns (bytes32 d) { - d = keccak256(abi.encodePacked(a, b, 145)); + d = keccak256(abi.encodePacked(a, b, uint8(145))); } } )"; @@ -3585,7 +3847,7 @@ BOOST_AUTO_TEST_CASE(keccak256_multiple_arguments_with_string_literals) } function bar(uint a, uint16 b) public returns (bytes32 d) { - d = keccak256(abi.encodePacked(a, b, 145, "foo")); + d = keccak256(abi.encodePacked(a, b, uint8(145), "foo")); } } )"; @@ -3648,7 +3910,7 @@ BOOST_AUTO_TEST_CASE(generic_call) char const* sourceCode = R"**( contract receiver { uint public received; - function receive(uint256 x) payable { received = x; } + function receive(uint256 x) public payable { received = x; } } contract sender { constructor() public payable {} @@ -3674,15 +3936,15 @@ BOOST_AUTO_TEST_CASE(generic_delegatecall) uint public received; address public sender; uint public value; - constructor() payable {} - function receive(uint256 x) payable { received = x; sender = msg.sender; value = msg.value; } + constructor() public payable {} + function receive(uint256 x) public payable { received = x; sender = msg.sender; value = msg.value; } } contract Sender { uint public received; address public sender; uint public value; - constructor() payable {} - function doSend(address rec) payable + constructor() public payable {} + function doSend(address rec) public payable { bytes4 signature = bytes4(bytes32(keccak256("receive(uint256)"))); if (rec.delegatecall(abi.encodeWithSelector(signature, 23))) {} @@ -3804,7 +4066,7 @@ BOOST_AUTO_TEST_CASE(call_forward_bytes) contract sender { constructor() public { rec = new receiver(); } function() external { savedData = msg.data; } - function forward() public returns (bool) { !rec.call(savedData); return true; } + function forward() public returns (bool) { !address(rec).call(savedData); return true; } function clear() public returns (bool) { delete savedData; return true; } function val() public returns (uint) { return rec.received(); } receiver rec; @@ -3833,18 +4095,18 @@ BOOST_AUTO_TEST_CASE(call_forward_bytes_length) receiver rec; constructor() public { rec = new receiver(); } function viaCalldata() public returns (uint) { - require(rec.call(msg.data)); + require(address(rec).call(msg.data)); return rec.calledLength(); } function viaMemory() public returns (uint) { bytes memory x = msg.data; - require(rec.call(x)); + require(address(rec).call(x)); return rec.calledLength(); } bytes s; function viaStorage() public returns (uint) { s = msg.data; - require(rec.call(s)); + require(address(rec).call(s)); return rec.calledLength(); } } @@ -3868,15 +4130,15 @@ BOOST_AUTO_TEST_CASE(copying_bytes_multiassign) char const* sourceCode = R"( contract receiver { uint public received; - function receive(uint x) { received += x + 1; } + function receive(uint x) public { received += x + 1; } function() external { received = 0x80; } } contract sender { constructor() public { rec = new receiver(); } function() external { savedData1 = savedData2 = msg.data; } function forward(bool selector) public returns (bool) { - if (selector) { rec.call(savedData1); delete savedData1; } - else { rec.call(savedData2); delete savedData2; } + if (selector) { address(rec).call(savedData1); delete savedData1; } + else { address(rec).call(savedData2); delete savedData2; } return true; } function val() public returns (uint) { return rec.received(); } @@ -4087,7 +4349,7 @@ BOOST_AUTO_TEST_CASE(using_enums) char const* sourceCode = R"( contract test { enum ActionChoices { GoLeft, GoRight, GoStraight, Sit } - constructor() + constructor() public { choices = ActionChoices.GoStraight; } @@ -4107,7 +4369,7 @@ BOOST_AUTO_TEST_CASE(enum_explicit_overflow) char const* sourceCode = R"( contract test { enum ActionChoices { GoLeft, GoRight, GoStraight } - constructor() + constructor() public { } function getChoiceExp(uint x) public returns (uint d) @@ -4252,7 +4514,7 @@ BOOST_AUTO_TEST_CASE(inline_member_init) { char const* sourceCode = R"( contract test { - constructor(){ + constructor() public { m_b = 6; m_c = 8; } @@ -4274,12 +4536,12 @@ BOOST_AUTO_TEST_CASE(inline_member_init_inheritence) { char const* sourceCode = R"( contract Base { - constructor(){} + constructor() public {} uint m_base = 5; function getBMember() public returns (uint i) { return m_base; } } contract Derived is Base { - constructor(){} + constructor() public {} uint m_derived = 6; function getDMember() public returns (uint i) { return m_derived; } } @@ -4326,12 +4588,12 @@ BOOST_AUTO_TEST_CASE(bytes_in_arguments) char const* sourceCode = R"( contract c { uint result; - function f(uint a, uint b) { result += a + b; } - function g(uint a) { result *= a; } + 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) { r_a = a; - this.call(data1); - this.call(data2); + address(this).call(data1); + address(this).call(data2); r = result; r_b = b; l = data1.length; @@ -4359,9 +4621,9 @@ BOOST_AUTO_TEST_CASE(fixed_arrays_in_storage) struct Data { uint x; uint y; } Data[2**10] data; uint[2**10 + 3] ids; - function setIDStatic(uint id) { ids[2] = id; } - function setID(uint index, uint id) { ids[index] = id; } - function setData(uint index, uint x, uint y) { data[index].x = x; data[index].y = y; } + function setIDStatic(uint id) public { ids[2] = id; } + function setID(uint index, uint id) public { ids[index] = id; } + function setData(uint index, uint x, uint y) public { data[index].x = x; data[index].y = y; } function getID(uint index) public returns (uint) { return ids[index]; } function getData(uint index) public returns (uint x, uint y) { x = data[index].x; y = data[index].y; } function getLengths() public returns (uint l1, uint l2) { l1 = data.length; l2 = ids.length; } @@ -4386,13 +4648,13 @@ BOOST_AUTO_TEST_CASE(dynamic_arrays_in_storage) struct Data { uint x; uint y; } Data[] data; uint[] ids; - function setIDStatic(uint id) { ids[2] = id; } - function setID(uint index, uint id) { ids[index] = id; } - function setData(uint index, uint x, uint y) { data[index].x = x; data[index].y = y; } + function setIDStatic(uint id) public { ids[2] = id; } + function setID(uint index, uint id) public { ids[index] = id; } + function setData(uint index, uint x, uint y) public { data[index].x = x; data[index].y = y; } function getID(uint index) public returns (uint) { return ids[index]; } function getData(uint index) public returns (uint x, uint y) { x = data[index].x; y = data[index].y; } function getLengths() public returns (uint l1, uint l2) { l1 = data.length; l2 = ids.length; } - function setLengths(uint l1, uint l2) { data.length = l1; ids.length = l2; } + function setLengths(uint l1, uint l2) public { data.length = l1; ids.length = l2; } } )"; compileAndRun(sourceCode); @@ -4549,7 +4811,7 @@ BOOST_AUTO_TEST_CASE(array_copy_storage_storage_dyn_dyn) contract c { uint[] data1; uint[] data2; - function setData1(uint length, uint index, uint value) { + function setData1(uint length, uint index, uint value) public { data1.length = length; if (index < length) data1[index] = value; } function copyStorageStorage() public { data2 = data1; } @@ -4760,22 +5022,22 @@ BOOST_AUTO_TEST_CASE(array_copy_storage_abi) uint16[] y; uint24[] z; uint24[][] w; - function test1() public returns (uint8[]) { + function test1() public returns (uint8[] memory) { for (uint i = 0; i < 101; ++i) x.push(uint8(i)); return x; } - function test2() public returns (uint16[]) { + function test2() public returns (uint16[] memory) { for (uint i = 0; i < 101; ++i) y.push(uint16(i)); return y; } - function test3() public returns (uint24[]) { + function test3() public returns (uint24[] memory) { for (uint i = 0; i < 101; ++i) z.push(uint24(i)); return z; } - function test4() public returns (uint24[][]) { + function test4() public returns (uint24[][] memory) { w.length = 5; for (uint i = 0; i < 5; ++i) for (uint j = 0; j < 101; ++j) @@ -4808,7 +5070,7 @@ BOOST_AUTO_TEST_CASE(array_copy_storage_abi_signed) char const* sourceCode = R"( contract c { int16[] x; - function test() public returns (int16[]) { + function test() public returns (int16[] memory) { x.push(int16(-1)); x.push(int16(-1)); x.push(int16(8)); @@ -5186,7 +5448,7 @@ BOOST_AUTO_TEST_CASE(byte_array_pop_masking_long) char const* sourceCode = R"( contract c { bytes data; - function test() public returns (bytes) { + function test() public returns (bytes memory) { for (uint i = 0; i < 34; i++) data.push(3); data.pop(); @@ -5208,7 +5470,7 @@ BOOST_AUTO_TEST_CASE(byte_array_pop_copy_long) char const* sourceCode = R"( contract c { bytes data; - function test() public returns (bytes) { + function test() public returns (bytes memory) { for (uint i = 0; i < 33; i++) data.push(3); for (uint j = 0; j < 4; j++) @@ -5475,14 +5737,14 @@ BOOST_AUTO_TEST_CASE(pass_dynamic_arguments_to_the_base) { char const* sourceCode = R"( contract Base { - constructor(uint i) + constructor(uint i) public { m_i = i; } uint public m_i; } contract Derived is Base { - constructor(uint i) Base(i) + constructor(uint i) Base(i) public {} } contract Final is Derived(4) { @@ -5520,14 +5782,14 @@ BOOST_AUTO_TEST_CASE(pass_dynamic_arguments_to_the_base_base_with_gap) { char const* sourceCode = R"( contract Base { - constructor(uint i) + constructor(uint i) public { m_i = i; } uint public m_i; } contract Base1 is Base { - constructor(uint k) {} + constructor(uint k) public {} } contract Derived is Base, Base1 { constructor(uint i) Base(i) Base1(7) public {} @@ -6106,13 +6368,13 @@ BOOST_AUTO_TEST_CASE(struct_assign_reference_to_struct) testStruct data1; testStruct data2; testStruct data3; - constructor() + constructor() public { data1.m_value = 2; } function assign() public returns (uint ret_local, uint ret_global, uint ret_global3, uint ret_global1) { - testStruct x = data1; //x is a reference data1.m_value == 2 as well as x.m_value = 2 + testStruct storage x = data1; //x is a reference data1.m_value == 2 as well as x.m_value = 2 data2 = data1; // should copy data. data2.m_value == 2 ret_local = x.m_value; // = 2 @@ -6138,13 +6400,13 @@ BOOST_AUTO_TEST_CASE(struct_delete_member) uint m_value; } testStruct data1; - constructor() + constructor() public { data1.m_value = 2; } function deleteMember() public returns (uint ret_value) { - testStruct x = data1; //should not copy the data. data1.m_value == 2 but x.m_value = 0 + testStruct storage x = data1; //should not copy the data. data1.m_value == 2 but x.m_value = 0 x.m_value = 4; delete x.m_value; ret_value = data1.m_value; @@ -6165,7 +6427,7 @@ BOOST_AUTO_TEST_CASE(struct_delete_struct_in_mapping) } mapping (uint => testStruct) campaigns; - constructor() + constructor() public { campaigns[0].m_value = 2; } @@ -6208,14 +6470,14 @@ BOOST_AUTO_TEST_CASE(evm_exceptions_in_constructor_call_fail) { char const* sourceCode = R"( contract A { - constructor() + constructor() public { - this.call("123"); + address(this).call("123"); } } contract B { uint public test = 1; - function testIt() + function testIt() public { A a = new A(); ++test; @@ -6234,7 +6496,7 @@ BOOST_AUTO_TEST_CASE(evm_exceptions_in_constructor_out_of_baund) contract A { uint public test = 1; uint[3] arr; - constructor() + constructor() public { uint index = 5; test = arr[index]; @@ -6274,7 +6536,7 @@ BOOST_AUTO_TEST_CASE(failing_send) constructor() public payable {} function callHelper(address _a) public returns (bool r, uint bal) { r = !_a.send(5); - bal = this.balance; + bal = address(this).balance; } } )"; @@ -6297,7 +6559,7 @@ BOOST_AUTO_TEST_CASE(send_zero_ether) constructor() public payable {} function s() public returns (bool) { Receiver r = new Receiver(); - return r.send(0); + return address(r).send(0); } } )"; @@ -6339,10 +6601,10 @@ BOOST_AUTO_TEST_CASE(return_string) function set(string _s) external { s = _s; } - function get1() public returns (string r) { + function get1() public returns (string memory r) { return s; } - function get2() public returns (string r) { + function get2() public returns (string memory r) { r = s; } } @@ -6367,7 +6629,7 @@ BOOST_AUTO_TEST_CASE(return_multiple_strings_of_various_sizes) s2 = _s2; return x; } - function get() public returns (string r1, string r2) { + function get() public returns (string memory r1, string memory r2) { r1 = s1; r2 = s2; } @@ -6387,9 +6649,9 @@ BOOST_AUTO_TEST_CASE(return_multiple_strings_of_various_sizes) "ABCDEFGHIJKLMNOPQRSTUVXYZABCDEFGHIJKLMNOPQRSTUVXYZABCDEFGHIJKLMNOPQRSTUVXYZ" "ABCDEFGHIJKLMNOPQRSTUVXYZABCDEFGHIJKLMNOPQRSTUVXYZABCDEFGHIJKLMNOPQRSTUVXYZ" ); - vector<size_t> lengthes{0, 30, 32, 63, 64, 65, 210, 300}; - for (auto l1: lengthes) - for (auto l2: lengthes) + vector<size_t> lengths{0, 30, 32, 63, 64, 65, 210, 300}; + for (auto l1: lengths) + for (auto l2: lengths) { bytes dyn1 = encodeArgs(u256(l1), s1.substr(0, l1)); bytes dyn2 = encodeArgs(u256(l2), s2.substr(0, l2)); @@ -6440,12 +6702,12 @@ BOOST_AUTO_TEST_CASE(bytes_in_function_calls) contract Main { string public s1; string public s2; - function set(string _s1, uint x, string _s2) public returns (uint) { + function set(string memory _s1, uint x, string memory _s2) public returns (uint) { s1 = _s1; s2 = _s2; return x; } - function setIndirectFromMemory(string _s1, uint x, string _s2) public returns (uint) { + 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) { @@ -6456,9 +6718,9 @@ BOOST_AUTO_TEST_CASE(bytes_in_function_calls) compileAndRun(sourceCode, 0, "Main"); string s1("abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz"); string s2("ABCDEFGHIJKLMNOPQRSTUVXYZABCDEFGHIJKLMNOPQRSTUVXYZABCDEFGHIJKLMNOPQRSTUVXYZ"); - vector<size_t> lengthes{0, 31, 64, 65}; - for (auto l1: lengthes) - for (auto l2: lengthes) + vector<size_t> lengths{0, 31, 64, 65}; + for (auto l1: lengths) + for (auto l2: lengths) { bytes dyn1 = encodeArgs(u256(l1), s1.substr(0, l1)); bytes dyn2 = encodeArgs(u256(l2), s2.substr(0, l2)); @@ -6485,11 +6747,11 @@ BOOST_AUTO_TEST_CASE(return_bytes_internal) char const* sourceCode = R"( contract Main { bytes s1; - function doSet(bytes _s1) public returns (bytes _r1) { + function doSet(bytes memory _s1) public returns (bytes memory _r1) { s1 = _s1; _r1 = s1; } - function set(bytes _s1) external returns (uint _r, bytes _r1) { + function set(bytes _s1) external returns (uint _r, bytes memory _r1) { _r1 = doSet(_s1); _r = _r1.length; } @@ -6497,8 +6759,8 @@ BOOST_AUTO_TEST_CASE(return_bytes_internal) )"; compileAndRun(sourceCode, 0, "Main"); string s1("abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz"); - vector<size_t> lengthes{0, 31, 64, 65}; - for (auto l1: lengthes) + vector<size_t> lengths{0, 31, 64, 65}; + for (auto l1: lengths) { bytes dyn1 = encodeArgs(u256(l1), s1.substr(0, l1)); bytes args1 = encodeArgs(u256(0x20)) + dyn1; @@ -6513,15 +6775,15 @@ BOOST_AUTO_TEST_CASE(bytes_index_access_memory) { char const* sourceCode = R"( contract Main { - function f(bytes _s1, uint i1, uint i2, uint i3) public returns (byte c1, byte c2, byte c3) { + function f(bytes memory _s1, uint i1, uint i2, uint i3) public returns (byte c1, byte c2, byte c3) { c1 = _s1[i1]; c2 = intern(_s1, i2); c3 = internIndirect(_s1)[i3]; } - function intern(bytes _s1, uint i) public returns (byte c) { + function intern(bytes memory _s1, uint i) public returns (byte c) { return _s1[i]; } - function internIndirect(bytes _s1) public returns (bytes) { + function internIndirect(bytes memory _s1) public returns (bytes memory) { return _s1; } } @@ -6542,7 +6804,7 @@ BOOST_AUTO_TEST_CASE(bytes_in_constructors_unpacker) contract Test { uint public m_x; bytes public m_s; - constructor(uint x, bytes s) public { + constructor(uint x, bytes memory s) public { m_x = x; m_s = s; } @@ -6563,7 +6825,7 @@ BOOST_AUTO_TEST_CASE(bytes_in_constructors_packer) contract Base { uint public m_x; bytes m_s; - constructor(uint x, bytes s) public { + constructor(uint x, bytes memory s) public { m_x = x; m_s = s; } @@ -6572,13 +6834,13 @@ BOOST_AUTO_TEST_CASE(bytes_in_constructors_packer) } } contract Main is Base { - constructor(bytes s, uint x) Base(x, f(s)) public {} - function f(bytes s) public returns (bytes) { + constructor(bytes memory s, uint x) Base(x, f(s)) public {} + function f(bytes memory s) public returns (bytes memory) { return s; } } contract Creator { - function f(uint x, bytes s) public returns (uint r, byte ch) { + function f(uint x, bytes memory s) public returns (uint r, byte ch) { Main c = new Main(s, x); r = c.m_x(); ch = c.part(x); @@ -6602,7 +6864,7 @@ BOOST_AUTO_TEST_CASE(arrays_in_constructors) contract Base { uint public m_x; address[] m_s; - constructor(uint x, address[] s) public { + constructor(uint x, address[] memory s) public { m_x = x; m_s = s; } @@ -6611,13 +6873,13 @@ BOOST_AUTO_TEST_CASE(arrays_in_constructors) } } contract Main is Base { - constructor(address[] s, uint x) Base(x, f(s)) public {} - function f(address[] s) public returns (address[]) { + constructor(address[] memory s, uint x) Base(x, f(s)) public {} + function f(address[] memory s) public returns (address[] memory) { return s; } } contract Creator { - function f(uint x, address[] s) public returns (uint r, address ch) { + function f(uint x, address[] memory s) public returns (uint r, address ch) { Main c = new Main(s, x); r = c.m_x(); ch = c.part(x); @@ -6641,7 +6903,7 @@ BOOST_AUTO_TEST_CASE(fixed_arrays_in_constructors) contract Creator { uint public r; address public ch; - constructor(address[3] s, uint x) public { + constructor(address[3] memory s, uint x) public { r = x; ch = s[2]; } @@ -6657,11 +6919,11 @@ BOOST_AUTO_TEST_CASE(arrays_from_and_to_storage) char const* sourceCode = R"( contract Test { uint24[] public data; - function set(uint24[] _data) public returns (uint) { + function set(uint24[] memory _data) public returns (uint) { data = _data; return data.length; } - function get() public returns (uint24[]) { + function get() public returns (uint24[] memory) { return data; } } @@ -6684,11 +6946,11 @@ BOOST_AUTO_TEST_CASE(arrays_complex_from_and_to_storage) char const* sourceCode = R"( contract Test { uint24[3][] public data; - function set(uint24[3][] _data) public returns (uint) { + function set(uint24[3][] memory _data) public returns (uint) { data = _data; return data.length; } - function get() public returns (uint24[3][]) { + function get() public returns (uint24[3][] memory) { return data; } } @@ -6710,7 +6972,7 @@ BOOST_AUTO_TEST_CASE(arrays_complex_memory_index_access) { char const* sourceCode = R"( contract Test { - function set(uint24[3][] _data, uint a, uint b) public returns (uint l, uint e) { + function set(uint24[3][] memory _data, uint a, uint b) public returns (uint l, uint e) { l = _data.length; e = _data[a][b]; } @@ -6733,7 +6995,7 @@ BOOST_AUTO_TEST_CASE(bytes_memory_index_access) { char const* sourceCode = R"( contract Test { - function set(bytes _data, uint i) public returns (uint l, byte c) { + function set(bytes memory _data, uint i) public returns (uint l, byte c) { l = _data.length; c = _data[i]; } @@ -6776,7 +7038,7 @@ BOOST_AUTO_TEST_CASE(storage_array_ref) contract Store is BinarySearch { uint[] data; - function add(uint v) { + function add(uint v) public { data.length++; data[data.length - 1] = v; } @@ -6809,13 +7071,13 @@ BOOST_AUTO_TEST_CASE(memory_types_initialisation) char const* sourceCode = R"( contract Test { mapping(uint=>uint) data; - function stat() public returns (uint[5]) + function stat() public returns (uint[5] memory) { data[2] = 3; // make sure to use some memory } - function dyn() public returns (uint[]) { stat(); } - function nested() public returns (uint[3][]) { stat(); } - function nestedStat() public returns (uint[3][7]) { stat(); } + function dyn() public returns (uint[] memory) { stat(); } + function nested() public returns (uint[3][] memory) { stat(); } + function nestedStat() public returns (uint[3][7] memory) { stat(); } } )"; compileAndRun(sourceCode, 0, "Test"); @@ -6830,7 +7092,7 @@ BOOST_AUTO_TEST_CASE(memory_arrays_delete) { char const* sourceCode = R"( contract Test { - function del() public returns (uint24[3][4]) { + function del() public returns (uint24[3][4] memory) { uint24[3][4] memory x; for (uint24 i = 0; i < x.length; i ++) for (uint24 j = 0; j < x[i].length; j ++) @@ -6859,11 +7121,11 @@ BOOST_AUTO_TEST_CASE(memory_arrays_index_access_write) { char const* sourceCode = R"( contract Test { - function set(uint24[3][4] x) { + function set(uint24[3][4] memory x) public { x[2][2] = 1; x[3][2] = 7; } - function f() public returns (uint24[3][4]){ + function f() public returns (uint24[3][4] memory){ uint24[3][4] memory data; set(data); return data; @@ -6883,12 +7145,12 @@ BOOST_AUTO_TEST_CASE(memory_arrays_dynamic_index_access_write) char const* sourceCode = R"( contract Test { uint24[3][][4] data; - function set(uint24[3][][4] x) internal returns (uint24[3][][4]) { + function set(uint24[3][][4] memory x) internal returns (uint24[3][][4] memory) { x[1][2][2] = 1; x[1][3][2] = 7; return x; } - function f() public returns (uint24[3][]) { + function f() public returns (uint24[3][] memory) { data[1].length = 4; return set(data)[1]; } @@ -6958,12 +7220,12 @@ BOOST_AUTO_TEST_CASE(memory_structs_as_function_args) y = extract(data, 1); z = extract(data, 2); } - function extract(S s, uint which) internal returns (uint x) { + function extract(S memory s, uint which) internal returns (uint x) { if (which == 0) return s.x; else if (which == 1) return s.y; else return s.z; } - function combine(uint8 x, uint16 y, uint z) internal returns (S s) { + function combine(uint8 x, uint16 y, uint z) internal returns (S memory s) { s.x = x; s.y = y; s.z = z; @@ -6988,13 +7250,13 @@ BOOST_AUTO_TEST_CASE(memory_structs_nested) y = extract(d, 2); z = extract(d, 3); } - function extract(X s, uint which) internal returns (uint x) { + function extract(X memory s, uint which) internal returns (uint x) { if (which == 0) return s.x; else if (which == 1) return s.s.x; else if (which == 2) return s.s.y; else return s.s.z; } - function combine(uint8 a, uint8 x, uint16 y, uint z) internal returns (X s) { + function combine(uint8 a, uint8 x, uint16 y, uint z) internal returns (X memory s) { s.x = a; s.s.x = x; s.s.y = y; @@ -7066,7 +7328,7 @@ BOOST_AUTO_TEST_CASE(struct_constructor_nested) s2[1] = 9; s = S(1, s2, X(4, 5)); } - function get() public returns (uint s1, uint[3] s2, uint x1, uint x2) + function get() public returns (uint s1, uint[3] memory s2, uint x1, uint x2) { s1 = s.s1; s2 = s.s2; @@ -7105,7 +7367,7 @@ BOOST_AUTO_TEST_CASE(literal_strings) string public medium; string public short; string public empty; - function f() public returns (string) { + function f() public returns (string memory) { long = "0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789001234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678900123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789001234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890"; medium = "01234567890123456789012345678901234567890123456789012345678901234567890123456789"; short = "123"; @@ -7172,7 +7434,7 @@ BOOST_AUTO_TEST_CASE(string_bytes_conversion) contract Test { string s; bytes b; - function f(string _s, uint n) public returns (byte) { + function f(string memory _s, uint n) public returns (byte) { b = bytes(_s); s = string(b); return bytes(s)[n]; @@ -7196,8 +7458,8 @@ BOOST_AUTO_TEST_CASE(string_as_mapping_key) char const* sourceCode = R"( contract Test { mapping(string => uint) data; - function set(string _s, uint _v) { data[_s] = _v; } - function get(string _s) public returns (uint) { return data[_s]; } + function set(string memory _s, uint _v) public { data[_s] = _v; } + function get(string memory _s) public returns (uint) { return data[_s]; } } )"; compileAndRun(sourceCode, 0, "Test"); @@ -7374,8 +7636,8 @@ BOOST_AUTO_TEST_CASE(constant_string_literal) bytes32 bb = b; } function getB() public returns (bytes32) { return b; } - function getX() public returns (string) { return x; } - function getX2() public returns (string r) { r = x; } + function getX() public returns (string memory) { return x; } + function getX2() public returns (string memory r) { r = x; } function unused() public returns (uint) { "unusedunusedunusedunusedunusedunusedunusedunusedunusedunusedunusedunused"; return 2; @@ -7429,7 +7691,7 @@ BOOST_AUTO_TEST_CASE(library_function_external) char const* sourceCode = R"( library Lib { function m(bytes b) external pure returns (byte) { return b[2]; } } contract Test { - function f(bytes b) public pure returns (byte) { + function f(bytes memory b) public pure returns (byte) { return Lib.m(b); } } @@ -7479,7 +7741,7 @@ BOOST_AUTO_TEST_CASE(simple_throw) if (x > 10) return x + 10; else - throw; + revert(); return 2; } } @@ -7502,7 +7764,7 @@ BOOST_AUTO_TEST_CASE(strings_in_struct) string last; } - constructor(){ + constructor() public { bug = Buggy(10, 20, 30, "asdfghjkl"); } function getFirst() public returns (uint) @@ -7517,7 +7779,7 @@ BOOST_AUTO_TEST_CASE(strings_in_struct) { return bug.third; } - function getLast() public returns (string) + function getLast() public returns (string memory) { return bug.last; } @@ -7535,7 +7797,7 @@ BOOST_AUTO_TEST_CASE(fixed_arrays_as_return_type) { char const* sourceCode = R"( contract A { - function f(uint16 input) public pure returns (uint16[5] arr) + function f(uint16 input) public pure returns (uint16[5] memory arr) { arr[0] = input; arr[1] = ++input; @@ -7545,7 +7807,7 @@ BOOST_AUTO_TEST_CASE(fixed_arrays_as_return_type) } } contract B { - function f() public returns (uint16[5] res, uint16[5] res2) + function f() public returns (uint16[5] memory res, uint16[5] memory res2) { A a = new A(); res = a.f(2); @@ -7594,7 +7856,7 @@ BOOST_AUTO_TEST_CASE(using_library_structs) char const* sourceCode = R"( library Lib { struct Data { uint a; uint[] b; } - function set(Data storage _s) + function set(Data storage _s) public { _s.a = 7; _s.b.length = 20; @@ -7777,7 +8039,7 @@ BOOST_AUTO_TEST_CASE(calldata_offset) { address[] _arr; string public last = "nd"; - constructor(address[] guardians) + constructor(address[] memory guardians) public { _arr = guardians; } @@ -7829,17 +8091,36 @@ BOOST_AUTO_TEST_CASE(multi_variable_declaration) function g() public returns (uint a, uint b, uint c) { a = 1; b = 2; c = 3; } - function f() public returns (bool) { + function h() public returns (uint a, uint b, uint c, uint d) { + a = 1; b = 2; c = 3; d = 4; + } + function f1() public returns (bool) { (uint x, uint y, uint z) = g(); if (x != 1 || y != 2 || z != 3) return false; (, uint a,) = g(); if (a != 2) return false; - (uint b,) = g(); + (uint b, , ) = g(); if (b != 1) return false; - (, uint c) = g(); + (, , uint c) = g(); if (c != 3) return false; return true; } + function f2() public returns (bool) { + (uint a1, , uint a3, ) = h(); + if (a1 != 1 || a3 != 3) return false; + (uint b1, uint b2, , ) = h(); + if (b1 != 1 || b2 != 2) return false; + (, uint c2, uint c3, ) = h(); + if (c2 != 2 || c3 != 3) return false; + (, , uint d3, uint d4) = h(); + if (d3 != 3 || d4 != 4) return false; + (uint e1, , uint e3, uint e4) = h(); + if (e1 != 1 || e3 != 3 || e4 != 4) return false; + return true; + } + function f() public returns (bool) { + return f1() && f2(); + } } )"; compileAndRun(sourceCode); @@ -7878,6 +8159,7 @@ BOOST_AUTO_TEST_CASE(tuples) char const* sourceCode = R"( contract C { uint[] data; + uint[] m_c; function g() internal returns (uint a, uint b, uint[] storage c) { return (1, 2, data); } @@ -7890,12 +8172,12 @@ BOOST_AUTO_TEST_CASE(tuples) uint a; uint b; (a, b) = this.h(); if (a != 5 || b != 6) return 1; - uint[] storage c; + uint[] storage c = m_c; (a, b, c) = g(); if (a != 1 || b != 2 || c[0] != 3) return 2; (a, b) = (b, a); if (a != 2 || b != 1) return 3; - (a, , b, ) = (8, 9, 10, 11, 12); + (a, , b, , ) = (8, 9, 10, 11, 12); if (a != 8 || b != 10) return 4; } } @@ -7908,14 +8190,14 @@ BOOST_AUTO_TEST_CASE(string_tuples) { char const* sourceCode = R"( contract C { - function f() public returns (string, uint) { + function f() public returns (string memory, uint) { return ("abc", 8); } - function g() public returns (string, string) { + function g() public returns (string memory, string memory) { return (h(), "def"); } - function h() public returns (string) { - return ("abc",); + function h() public returns (string memory) { + return ("abc"); } } )"; @@ -7961,13 +8243,13 @@ BOOST_AUTO_TEST_CASE(destructuring_assignment) bytes data; uint[] y; uint[] arrayData; - function returnsArray() public returns (uint[]) { + function returnsArray() public returns (uint[] memory) { arrayData.length = 9; arrayData[2] = 5; arrayData[7] = 4; return arrayData; } - function f(bytes s) public returns (uint) { + function f(bytes memory s) public returns (uint) { uint loc; uint[] memory memArray; (loc, x, y, data, arrayData[3]) = (8, 4, returnsArray(), s, 2); @@ -7983,7 +8265,7 @@ BOOST_AUTO_TEST_CASE(destructuring_assignment) if (loc != 3) return 9; if (memArray.length != arrayData.length) return 10; bytes memory memBytes; - (x, memBytes, y[2], ) = (456, s, 789, 101112, 131415); + (x, memBytes, y[2], , ) = (456, s, 789, 101112, 131415); if (x != 456 || memBytes.length != s.length || y[2] != 789) return 11; } } @@ -7992,31 +8274,6 @@ BOOST_AUTO_TEST_CASE(destructuring_assignment) ABI_CHECK(callContractFunction("f(bytes)", u256(0x20), u256(5), string("abcde")), encodeArgs(u256(0))); } -BOOST_AUTO_TEST_CASE(destructuring_assignment_wildcard) -{ - char const* sourceCode = R"( - contract C { - function f() public returns (uint) { - uint a; - uint b; - uint c; - (a,) = (1,); - if (a != 1) return 1; - (,b) = (2,3,4); - if (b != 4) return 2; - (, c,) = (5,6,7); - if (c != 6) return 3; - (a, b,) = (11, 12, 13); - if (a != 11 || b != 12) return 4; - (, a, b) = (11, 12, 13); - if (a != 12 || b != 13) return 5; - } - } - )"; - compileAndRun(sourceCode); - ABI_CHECK(callContractFunction("f()"), encodeArgs(u256(0))); -} - BOOST_AUTO_TEST_CASE(lone_struct_array_type) { char const* sourceCode = R"( @@ -8139,7 +8396,7 @@ BOOST_AUTO_TEST_CASE(memory_overwrite) { char const* sourceCode = R"( contract C { - function f() public returns (bytes x) { + function f() public returns (bytes memory x) { x = "12345"; x[3] = 0x61; x[0] = 0x62; @@ -8371,7 +8628,7 @@ BOOST_AUTO_TEST_CASE(inline_array_storage_to_memory_conversion_strings) char const* sourceCode = R"( contract C { string s = "doh"; - function f() public returns (string, string) { + function f() public returns (string memory, string memory) { string memory t = "ray"; string[3] memory x = [s, t, "mi"]; return (x[1], x[2]); @@ -8386,7 +8643,7 @@ BOOST_AUTO_TEST_CASE(inline_array_strings_from_document) { char const* sourceCode = R"( contract C { - function f(uint i) public returns (string) { + function f(uint i) public returns (string memory) { string[4] memory x = ["This", "is", "an", "array"]; return (x[i]); } @@ -8433,7 +8690,7 @@ BOOST_AUTO_TEST_CASE(inline_array_index_access_strings) char const* sourceCode = R"( contract C { string public tester; - function f() public returns (string) { + function f() public returns (string memory) { return (["abc", "def", "g"][0]); } function test() public { @@ -8451,7 +8708,7 @@ BOOST_AUTO_TEST_CASE(inline_array_return) char const* sourceCode = R"( contract C { uint8[] tester; - function f() public returns (uint8[5]) { + function f() public returns (uint8[5] memory) { return ([1,2,3,4,5]); } function test() public returns (uint8, uint8, uint8, uint8, uint8) { @@ -8483,7 +8740,7 @@ BOOST_AUTO_TEST_CASE(inline_long_string_return) { char const* sourceCode = R"( contract C { - function f() public returns (string) { + function f() public returns (string memory) { return (["somethingShort", "0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789001234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678900123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789001234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890"][1]); } } @@ -8560,7 +8817,7 @@ BOOST_AUTO_TEST_CASE(inline_assembly_memory_access) { char const* sourceCode = R"( contract C { - function test() public returns (bytes) { + function test() public returns (bytes memory) { bytes memory x = new bytes(5); for (uint i = 0; i < x.length; ++i) x[i] = byte(uint8(i + 1)); @@ -8635,7 +8892,7 @@ BOOST_AUTO_TEST_CASE(inline_assembly_storage_access_via_pointer) Data public a; uint public separator2; function f() public returns (bool) { - Data x = a; + Data storage x = a; uint off; assembly { sstore(x_slot, 7) @@ -8684,8 +8941,8 @@ BOOST_AUTO_TEST_CASE(inline_assembly_function_access) char const* sourceCode = R"( contract C { uint public x; - function g(uint y) { x = 2 * y; assembly { stop } } - function f(uint _x) { + function g(uint y) public { x = 2 * y; assembly { stop } } + function f(uint _x) public { assembly { _x jump(g) @@ -8919,7 +9176,7 @@ BOOST_AUTO_TEST_CASE(index_access_with_type_conversion) // Test for a bug where higher order bits cleanup was not done for array index access. char const* sourceCode = R"( contract C { - function f(uint x) public returns (uint[256] r){ + function f(uint x) public returns (uint[256] memory r){ r[uint8(x)] = 2; } } @@ -8959,7 +9216,7 @@ BOOST_AUTO_TEST_CASE(internal_library_function) // and retain the same memory context (i.e. are pulled into the caller's code) char const* sourceCode = R"( library L { - function f(uint[] _data) internal { + function f(uint[] memory _data) internal { _data[3] = 2; } } @@ -8984,10 +9241,10 @@ BOOST_AUTO_TEST_CASE(internal_library_function_calling_private) // also has to be pulled into the caller's code) char const* sourceCode = R"( library L { - function g(uint[] _data) private { + function g(uint[] memory _data) private { _data[3] = 2; } - function f(uint[] _data) internal { + function f(uint[] memory _data) internal { g(_data); } } @@ -9010,7 +9267,7 @@ BOOST_AUTO_TEST_CASE(internal_library_function_bound) char const* sourceCode = R"( library L { struct S { uint[] data; } - function f(S _s) internal { + function f(S memory _s) internal { _s.data[3] = 2; } } @@ -9035,7 +9292,7 @@ BOOST_AUTO_TEST_CASE(internal_library_function_return_var_size) char const* sourceCode = R"( library L { struct S { uint[] data; } - function f(S _s) internal returns (uint[]) { + function f(S memory _s) internal returns (uint[] memory) { _s.data[3] = 2; return _s.data; } @@ -9116,7 +9373,7 @@ BOOST_AUTO_TEST_CASE(skip_dynamic_types) // The EVM cannot provide access to dynamically-sized return values, so we have to skip them. char const* sourceCode = R"( contract C { - function f() public returns (uint, uint[], uint) { + function f() public returns (uint, uint[] memory, uint) { return (7, new uint[](2), 8); } function g() public returns (uint, uint) { @@ -9159,7 +9416,7 @@ BOOST_AUTO_TEST_CASE(skip_dynamic_types_for_structs) BOOST_AUTO_TEST_CASE(failed_create) { char const* sourceCode = R"( - contract D { constructor() payable {} } + contract D { constructor() public payable {} } contract C { uint public x; constructor() public payable {} @@ -9255,8 +9512,10 @@ BOOST_AUTO_TEST_CASE(break_in_modifier) break; } } - function f() run { - x++; + function f() run public { + uint k = x; + uint t = k + 1; + x = t; } } )"; @@ -9266,6 +9525,54 @@ BOOST_AUTO_TEST_CASE(break_in_modifier) ABI_CHECK(callContractFunction("x()"), encodeArgs(u256(1))); } +BOOST_AUTO_TEST_CASE(continue_in_modifier) +{ + char const* sourceCode = R"( + contract C { + uint public x; + modifier run() { + for (uint i = 0; i < 10; i++) { + if (i % 2 == 1) continue; + _; + } + } + function f() run public { + uint k = x; + uint t = k + 1; + x = t; + } + } + )"; + compileAndRun(sourceCode, 0, "C"); + ABI_CHECK(callContractFunction("x()"), encodeArgs(u256(0))); + ABI_CHECK(callContractFunction("f()"), encodeArgs()); + ABI_CHECK(callContractFunction("x()"), encodeArgs(u256(5))); +} + +BOOST_AUTO_TEST_CASE(return_in_modifier) +{ + char const* sourceCode = R"( + contract C { + uint public x; + modifier run() { + for (uint i = 1; i < 10; i++) { + if (i == 5) return; + _; + } + } + function f() run public { + uint k = x; + uint t = k + 1; + x = t; + } + } + )"; + compileAndRun(sourceCode, 0, "C"); + ABI_CHECK(callContractFunction("x()"), encodeArgs(u256(0))); + ABI_CHECK(callContractFunction("f()"), encodeArgs()); + ABI_CHECK(callContractFunction("x()"), encodeArgs(u256(4))); +} + BOOST_AUTO_TEST_CASE(stacked_return_with_modifiers) { char const* sourceCode = R"( @@ -9277,8 +9584,10 @@ BOOST_AUTO_TEST_CASE(stacked_return_with_modifiers) break; } } - function f() run { - x++; + function f() run public { + uint k = x; + uint t = k + 1; + x = t; } } )"; @@ -9294,7 +9603,7 @@ BOOST_AUTO_TEST_CASE(mutex) contract mutexed { bool locked; modifier protected { - if (locked) throw; + if (locked) revert(); locked = true; _; locked = false; @@ -9302,20 +9611,20 @@ BOOST_AUTO_TEST_CASE(mutex) } contract Fund is mutexed { uint shares; - constructor() payable { shares = msg.value; } - function withdraw(uint amount) protected returns (uint) { + constructor() public payable { shares = msg.value; } + function withdraw(uint amount) public protected returns (uint) { // NOTE: It is very bad practice to write this function this way. // Please refer to the documentation of how to do this properly. - if (amount > shares) throw; - if (!msg.sender.call.value(amount)("")) throw; + if (amount > shares) revert(); + if (!msg.sender.call.value(amount)("")) revert(); shares -= amount; return shares; } function withdrawUnprotected(uint amount) public returns (uint) { // NOTE: It is very bad practice to write this function this way. // Please refer to the documentation of how to do this properly. - if (amount > shares) throw; - if (!msg.sender.call.value(amount)("")) throw; + if (amount > shares) revert(); + if (!msg.sender.call.value(amount)("")) revert(); shares -= amount; return shares; } @@ -9324,7 +9633,7 @@ BOOST_AUTO_TEST_CASE(mutex) Fund public fund; uint callDepth; bool protected; - function setProtected(bool _protected) { protected = _protected; } + function setProtected(bool _protected) public { protected = _protected; } constructor(Fund _fund) public { fund = _fund; } function attack() public returns (uint) { callDepth = 0; @@ -9421,7 +9730,7 @@ BOOST_AUTO_TEST_CASE(failing_ecrecover_invalid_input_asm) BOOST_AUTO_TEST_CASE(calling_nonexisting_contract_throws) { char const* sourceCode = R"YY( - contract D { function g(); } + contract D { function g() public; } contract C { D d = D(0x1212); function f() public returns (uint) { @@ -9433,7 +9742,7 @@ BOOST_AUTO_TEST_CASE(calling_nonexisting_contract_throws) return 7; } function h() public returns (uint) { - d.call(""); // this does not throw (low-level) + address(d).call(""); // this does not throw (low-level) return 7; } } @@ -9448,7 +9757,7 @@ BOOST_AUTO_TEST_CASE(payable_constructor) { char const* sourceCode = R"( contract C { - constructor() payable { } + constructor() public payable { } } )"; compileAndRun(sourceCode, 27, "C"); @@ -9483,7 +9792,7 @@ BOOST_AUTO_TEST_CASE(payable_function_calls_library) function f() public returns (uint) { return 7; } } contract C { - function f() payable public returns (uint) { + function f() public payable returns (uint) { return L.f(); } } @@ -9543,7 +9852,7 @@ BOOST_AUTO_TEST_CASE(mem_resize_is_not_paid_at_call) // Tests that this also survives the optimizer. char const* sourceCode = R"( contract C { - function f() public returns (uint[200]) {} + function f() public returns (uint[200] memory) {} } contract D { function f(C c) public returns (uint) { c.f(); return 7; } @@ -9610,7 +9919,7 @@ BOOST_AUTO_TEST_CASE(calling_uninitialized_function_through_array) { assembly { mstore(0, 7) return(0, 0x20) } } mutex = 1; // Avoid re-executing this function if we jump somewhere. - function() internal returns (uint)[200] x; + function() internal returns (uint)[200] memory x; x[0](); return 2; } @@ -9706,7 +10015,7 @@ BOOST_AUTO_TEST_CASE(store_function) contract C { function (function (uint) external returns (uint)) internal returns (uint) ev; function (uint) external returns (uint) x; - function store(function(uint) external returns (uint) y) { + function store(function(uint) external returns (uint) y) public { x = y; } function eval(function(uint) external returns (uint) y) public returns (uint) { @@ -9848,7 +10157,7 @@ BOOST_AUTO_TEST_CASE(function_type_library_internal) } } contract C { - function f(uint[] x) public returns (uint) { + function f(uint[] memory x) public returns (uint) { return Utils.reduce(x, Utils.sum, 0); } } @@ -10077,8 +10386,8 @@ BOOST_AUTO_TEST_CASE(function_array_cross_calls) { char const* sourceCode = R"( contract D { - function f(function() external returns (function() external returns (uint))[] x) - public returns (function() external returns (uint)[3] r) + function f(function() external returns (function() external returns (uint))[] memory x) + public returns (function() external returns (uint)[3] memory r) { r[0] = x[0](); r[1] = x[1](); @@ -10138,7 +10447,7 @@ BOOST_AUTO_TEST_CASE(copy_internal_function_array_to_storage) function() internal returns (uint)[20] x; int mutex; function one() public returns (uint) { - function() internal returns (uint)[20] xmem; + function() internal returns (uint)[20] memory xmem; x = xmem; return 3; } @@ -10850,7 +11159,7 @@ BOOST_AUTO_TEST_CASE(inline_assembly_in_modifiers) a := 2 } if (a != 2) - throw; + revert(); _; } function f() m public returns (bool) { @@ -11035,7 +11344,7 @@ BOOST_AUTO_TEST_CASE(revert_with_cause) } contract C { D d = new D(); - function forward(address target, bytes data) internal returns (bool success, bytes retval) { + function forward(address target, bytes memory data) internal returns (bool success, bytes memory retval) { uint retsize; assembly { success := call(not(0), target, 0, add(data, 0x20), mload(data), 0, 0) @@ -11046,19 +11355,19 @@ BOOST_AUTO_TEST_CASE(revert_with_cause) returndatacopy(add(retval, 0x20), 0, returndatasize()) } } - function f() public returns (bool, bytes) { + function f() public returns (bool, bytes memory) { return forward(address(d), msg.data); } - function g() public returns (bool, bytes) { + function g() public returns (bool, bytes memory) { return forward(address(d), msg.data); } - function h() public returns (bool, bytes) { + function h() public returns (bool, bytes memory) { return forward(address(d), msg.data); } - function i() public returns (bool, bytes) { + function i() public returns (bool, bytes memory) { return forward(address(d), msg.data); } - function j() public returns (bool, bytes) { + function j() public returns (bool, bytes memory) { return forward(address(d), msg.data); } } @@ -11090,7 +11399,7 @@ BOOST_AUTO_TEST_CASE(require_with_message) bool flagCopy = flag; require(flagCopy == false, internalFun()); } - function internalFun() public returns (string) { + function internalFun() public returns (string memory) { flag = true; return "only on second run"; } @@ -11107,7 +11416,7 @@ BOOST_AUTO_TEST_CASE(require_with_message) } contract C { D d = new D(); - function forward(address target, bytes data) internal returns (bool success, bytes retval) { + function forward(address target, bytes memory data) internal returns (bool success, bytes memory retval) { uint retsize; assembly { success := call(not(0), target, 0, add(data, 0x20), mload(data), 0, 0) @@ -11118,19 +11427,19 @@ BOOST_AUTO_TEST_CASE(require_with_message) returndatacopy(add(retval, 0x20), 0, returndatasize()) } } - function f(uint x) public returns (bool, bytes) { + function f(uint x) public returns (bool, bytes memory) { return forward(address(d), msg.data); } - function g() public returns (bool, bytes) { + function g() public returns (bool, bytes memory) { return forward(address(d), msg.data); } - function h() public returns (bool, bytes) { + function h() public returns (bool, bytes memory) { return forward(address(d), msg.data); } - function i() public returns (bool, bytes) { + function i() public returns (bool, bytes memory) { return forward(address(d), msg.data); } - function j() public returns (bool, bytes) { + function j() public returns (bool, bytes memory) { return forward(address(d), msg.data); } } @@ -11160,7 +11469,7 @@ BOOST_AUTO_TEST_CASE(bubble_up_error_messages) } contract C { D d = new D(); - function forward(address target, bytes data) internal returns (bool success, bytes retval) { + function forward(address target, bytes memory data) internal returns (bool success, bytes memory retval) { uint retsize; assembly { success := call(not(0), target, 0, add(data, 0x20), mload(data), 0, 0) @@ -11171,10 +11480,10 @@ BOOST_AUTO_TEST_CASE(bubble_up_error_messages) returndatacopy(add(retval, 0x20), 0, returndatasize()) } } - function f() public returns (bool, bytes) { + function f() public returns (bool, bytes memory) { return forward(address(d), msg.data); } - function g() public returns (bool, bytes) { + function g() public returns (bool, bytes memory) { return forward(address(d), msg.data); } } @@ -11194,12 +11503,12 @@ BOOST_AUTO_TEST_CASE(bubble_up_error_messages_through_transfer) revert("message"); } function f() public { - this.transfer(0); + address(this).transfer(0); } } contract C { D d = new D(); - function forward(address target, bytes data) internal returns (bool success, bytes retval) { + function forward(address target, bytes memory data) internal returns (bool success, bytes memory retval) { uint retsize; assembly { success := call(not(0), target, 0, add(data, 0x20), mload(data), 0, 0) @@ -11210,7 +11519,7 @@ BOOST_AUTO_TEST_CASE(bubble_up_error_messages_through_transfer) returndatacopy(add(retval, 0x20), 0, returndatasize()) } } - function f() public returns (bool, bytes) { + function f() public returns (bool, bytes memory) { return forward(address(d), msg.data); } } @@ -11236,7 +11545,7 @@ BOOST_AUTO_TEST_CASE(bubble_up_error_messages_through_create) } contract C { D d = new D(); - function forward(address target, bytes data) internal returns (bool success, bytes retval) { + function forward(address target, bytes memory data) internal returns (bool success, bytes memory retval) { uint retsize; assembly { success := call(not(0), target, 0, add(data, 0x20), mload(data), 0, 0) @@ -11247,7 +11556,7 @@ BOOST_AUTO_TEST_CASE(bubble_up_error_messages_through_create) returndatacopy(add(retval, 0x20), 0, returndatasize()) } } - function f() public returns (bool, bytes) { + function f() public returns (bool, bytes memory) { return forward(address(d), msg.data); } } @@ -11271,9 +11580,9 @@ BOOST_AUTO_TEST_CASE(negative_stack_height) bool Aboolc; bool exists; } - function nredit(uint startindex) public pure returns(uint[500] CIDs, uint[500] dates, uint[500] RIDs, bool[500] Cboolas, uint[500] amounts){} - function return500InvoicesByDates(uint begindate, uint enddate, uint startindex) public view returns(uint[500] AIDs, bool[500] Aboolas, uint[500] dates, bytes32[3][500] Abytesas, bytes32[3][500] bytesbs, bytes32[2][500] bytescs, uint[500] amounts, bool[500] Aboolbs, bool[500] Aboolcs){} - function return500PaymentsByDates(uint begindate, uint enddate, uint startindex) public view returns(uint[500] BIDs, uint[500] dates, uint[500] RIDs, bool[500] Bboolas, bytes32[3][500] bytesbs,bytes32[2][500] bytescs, uint[500] amounts, bool[500] Bboolbs){} + function nredit(uint startindex) public pure returns(uint[500] memory CIDs, uint[500] memory dates, uint[500] memory RIDs, bool[500] memory Cboolas, uint[500] memory amounts){} + function return500InvoicesByDates(uint begindate, uint enddate, uint startindex) public view returns(uint[500] memory AIDs, bool[500] memory Aboolas, uint[500] memory dates, bytes32[3][500] memory Abytesas, bytes32[3][500] memory bytesbs, bytes32[2][500] memory bytescs, uint[500] memory amounts, bool[500] memory Aboolbs, bool[500] memory Aboolcs){} + function return500PaymentsByDates(uint begindate, uint enddate, uint startindex) public view returns(uint[500] memory BIDs, uint[500] memory dates, uint[500] memory RIDs, bool[500] memory Bboolas, bytes32[3][500] memory bytesbs,bytes32[2][500] memory bytescs, uint[500] memory amounts, bool[500] memory Bboolbs){} } )"; compileAndRun(sourceCode, 0, "C"); @@ -11285,7 +11594,7 @@ BOOST_AUTO_TEST_CASE(literal_empty_string) contract C { bytes32 public x; uint public a; - function f(bytes32 _x, uint _a) { + function f(bytes32 _x, uint _a) public { x = _x; a = _a; } @@ -11340,7 +11649,7 @@ BOOST_AUTO_TEST_CASE(interface_contract) char const* sourceCode = R"( interface I { event A(); - function f() public returns (bool); + function f() external returns (bool); function() external payable; } @@ -11469,13 +11778,13 @@ BOOST_AUTO_TEST_CASE(delegatecall_return_value) return value; } function get_delegated() external returns (bool) { - return this.delegatecall(abi.encodeWithSignature("get()")); + return address(this).delegatecall(abi.encodeWithSignature("get()")); } function assert0() external view { assert(value == 0); } function assert0_delegated() external returns (bool) { - return this.delegatecall(abi.encodeWithSignature("assert0()")); + return address(this).delegatecall(abi.encodeWithSignature("assert0()")); } } )DELIMITER"; @@ -11528,13 +11837,13 @@ BOOST_AUTO_TEST_CASE(constant_string) bytes constant a = "\x03\x01\x02"; bytes constant b = hex"030102"; string constant c = "hello"; - function f() public returns (bytes) { + function f() public returns (bytes memory) { return a; } - function g() public returns (bytes) { + function g() public returns (bytes memory) { return b; } - function h() public returns (bytes) { + function h() public returns (bytes memory) { return bytes(c); } } @@ -11585,12 +11894,12 @@ BOOST_AUTO_TEST_CASE(snark) } /// @return the generator of G1 - function P1() internal returns (G1Point) { + function P1() internal returns (G1Point memory) { return G1Point(1, 2); } /// @return the generator of G2 - function P2() internal returns (G2Point) { + function P2() internal returns (G2Point memory) { return G2Point( [11559732032986387107991004021392285783925812861821192530917403151452391805634, 10857046999023057135944570762232829481370756359578518086990519993285655852781], @@ -11600,7 +11909,7 @@ BOOST_AUTO_TEST_CASE(snark) } /// @return the negation of p, i.e. p.add(p.negate()) should be zero. - function negate(G1Point p) internal returns (G1Point) { + function negate(G1Point memory p) internal returns (G1Point memory) { // The prime q in the base field F_q for G1 uint q = 21888242871839275222246405745257275088696311157297823662689037894645226208583; if (p.X == 0 && p.Y == 0) @@ -11609,7 +11918,7 @@ BOOST_AUTO_TEST_CASE(snark) } /// @return the sum of two points of G1 - function add(G1Point p1, G1Point p2) internal returns (G1Point r) { + function add(G1Point memory p1, G1Point memory p2) internal returns (G1Point memory r) { uint[4] memory input; input[0] = p1.X; input[1] = p1.Y; @@ -11626,7 +11935,7 @@ BOOST_AUTO_TEST_CASE(snark) /// @return the product of a point on G1 and a scalar, i.e. /// p == p.mul(1) and p.add(p) == p.mul(2) for all points p. - function mul(G1Point p, uint s) internal returns (G1Point r) { + function mul(G1Point memory p, uint s) internal returns (G1Point memory r) { uint[3] memory input; input[0] = p.X; input[1] = p.Y; @@ -11644,7 +11953,7 @@ BOOST_AUTO_TEST_CASE(snark) /// e(p1[0], p2[0]) * .... * e(p1[n], p2[n]) == 1 /// For example pairing([P1(), P1().negate()], [P2(), P2()]) should /// return true. - function pairing(G1Point[] p1, G2Point[] p2) internal returns (bool) { + function pairing(G1Point[] memory p1, G2Point[] memory p2) internal returns (bool) { require(p1.length == p2.length); uint elements = p1.length; uint inputSize = p1.length * 6; @@ -11668,7 +11977,7 @@ BOOST_AUTO_TEST_CASE(snark) require(success); return out[0] != 0; } - function pairingProd2(G1Point a1, G2Point a2, G1Point b1, G2Point b2) internal returns (bool) { + function pairingProd2(G1Point memory a1, G2Point memory a2, G1Point memory b1, G2Point memory b2) internal returns (bool) { G1Point[] memory p1 = new G1Point[](2); G2Point[] memory p2 = new G2Point[](2); p1[0] = a1; @@ -11678,9 +11987,9 @@ BOOST_AUTO_TEST_CASE(snark) return pairing(p1, p2); } function pairingProd3( - G1Point a1, G2Point a2, - G1Point b1, G2Point b2, - G1Point c1, G2Point c2 + G1Point memory a1, G2Point memory a2, + G1Point memory b1, G2Point memory b2, + G1Point memory c1, G2Point memory c2 ) internal returns (bool) { G1Point[] memory p1 = new G1Point[](3); G2Point[] memory p2 = new G2Point[](3); @@ -11693,10 +12002,10 @@ BOOST_AUTO_TEST_CASE(snark) return pairing(p1, p2); } function pairingProd4( - G1Point a1, G2Point a2, - G1Point b1, G2Point b2, - G1Point c1, G2Point c2, - G1Point d1, G2Point d2 + G1Point memory a1, G2Point memory a2, + G1Point memory b1, G2Point memory b2, + G1Point memory c1, G2Point memory c2, + G1Point memory d1, G2Point memory d2 ) internal returns (bool) { G1Point[] memory p1 = new G1Point[](4); G2Point[] memory p2 = new G2Point[](4); @@ -11785,7 +12094,7 @@ BOOST_AUTO_TEST_CASE(snark) return false; return true; } - function verifyingKey() internal returns (VerifyingKey vk) { + function verifyingKey() internal returns (VerifyingKey memory vk) { vk.A = Pairing.G2Point([0x209dd15ebff5d46c4bd888e51a93cf99a7329636c63514396b4a452003a35bf7, 0x04bf11ca01483bfa8b34b43561848d28905960114c8ac04049af4b6315a41678], [0x2bb8324af6cfc93537a2ad1a445cfd0ca2a71acd7ac41fadbf933c2a51be344d, 0x120a2a4cf30c1bf9845f20c6fe39e07ea2cce61f0c9bb048165fe5e4de877550]); vk.B = Pairing.G1Point(0x2eca0c7238bf16e83e7a1e6c5d49540685ff51380f309842a98561558019fc02, 0x03d3260361bb8451de5ff5ecd17f010ff22f5c31cdf184e9020b06fa5997db84); vk.C = Pairing.G2Point([0x2e89718ad33c8bed92e210e81d1853435399a271913a6520736a4729cf0d51eb, 0x01a9e2ffa2e92599b68e44de5bcf354fa2642bd4f26b259daa6f7ce3ed57aeb3], [0x14a9a87b789a58af499b314e13c3d65bede56c07ea2d418d6874857b70763713, 0x178fb49a2d6cd347dc58973ff49613a20757d0fcc22079f9abd10c3baee24590]); @@ -11805,7 +12114,7 @@ BOOST_AUTO_TEST_CASE(snark) vk.IC[8] = Pairing.G1Point(0x0a6de0e2240aa253f46ce0da883b61976e3588146e01c9d8976548c145fe6e4a, 0x04fbaa3a4aed4bb77f30ebb07a3ec1c7d77a7f2edd75636babfeff97b1ea686e); vk.IC[9] = Pairing.G1Point(0x111e2e2a5f8828f80ddad08f9f74db56dac1cc16c1cb278036f79a84cf7a116f, 0x1d7d62e192b219b9808faa906c5ced871788f6339e8d91b83ac1343e20a16b30); } - function verify(uint[] input, Proof proof) internal returns (uint) { + function verify(uint[] memory input, Proof memory proof) internal returns (uint) { VerifyingKey memory vk = verifyingKey(); require(input.length + 1 == vk.IC.length); // Compute the linear combination vk_x @@ -11875,17 +12184,17 @@ BOOST_AUTO_TEST_CASE(abi_encode) { char const* sourceCode = R"( contract C { - function f0() public returns (bytes) { + function f0() public returns (bytes memory) { return abi.encode(); } - function f1() public returns (bytes) { + function f1() public returns (bytes memory) { return abi.encode(1, 2); } - function f2() public returns (bytes) { + function f2() public returns (bytes memory) { string memory x = "abc"; return abi.encode(1, x, 2); } - function f3() public returns (bytes r) { + function f3() public returns (bytes memory r) { // test that memory is properly allocated string memory x = "abc"; r = abi.encode(1, x, 2); @@ -11894,7 +12203,7 @@ BOOST_AUTO_TEST_CASE(abi_encode) y[0] = "e"; require(y[0] == "e"); } - function f4() public returns (bytes) { + function f4() public returns (bytes memory) { bytes4 x = "abcd"; return abi.encode(bytes2(x)); } @@ -11914,17 +12223,17 @@ BOOST_AUTO_TEST_CASE(abi_encode_v2) pragma experimental ABIEncoderV2; contract C { struct S { uint a; uint[] b; } - function f0() public pure returns (bytes) { + function f0() public pure returns (bytes memory) { return abi.encode(); } - function f1() public pure returns (bytes) { + function f1() public pure returns (bytes memory) { return abi.encode(1, 2); } - function f2() public pure returns (bytes) { + function f2() public pure returns (bytes memory) { string memory x = "abc"; return abi.encode(1, x, 2); } - function f3() public pure returns (bytes r) { + function f3() public pure returns (bytes memory r) { // test that memory is properly allocated string memory x = "abc"; r = abi.encode(1, x, 2); @@ -11934,7 +12243,7 @@ BOOST_AUTO_TEST_CASE(abi_encode_v2) require(y[0] == "e"); } S s; - function f4() public returns (bytes r) { + function f4() public returns (bytes memory r) { string memory x = "abc"; s.a = 7; s.b.push(2); @@ -11960,17 +12269,17 @@ BOOST_AUTO_TEST_CASE(abi_encodePacked) { char const* sourceCode = R"( contract C { - function f0() public pure returns (bytes) { + function f0() public pure returns (bytes memory) { return abi.encodePacked(); } - function f1() public pure returns (bytes) { + function f1() public pure returns (bytes memory) { return abi.encodePacked(uint8(1), uint8(2)); } - function f2() public pure returns (bytes) { + function f2() public pure returns (bytes memory) { string memory x = "abc"; return abi.encodePacked(uint8(1), x, uint8(2)); } - function f3() public pure returns (bytes r) { + function f3() public pure returns (bytes memory r) { // test that memory is properly allocated string memory x = "abc"; r = abi.encodePacked(uint8(1), x, uint8(2)); @@ -11992,17 +12301,17 @@ BOOST_AUTO_TEST_CASE(abi_encode_with_selector) { char const* sourceCode = R"( contract C { - function f0() public pure returns (bytes) { + function f0() public pure returns (bytes memory) { return abi.encodeWithSelector(0x12345678); } - function f1() public pure returns (bytes) { + function f1() public pure returns (bytes memory) { return abi.encodeWithSelector(0x12345678, "abc"); } - function f2() public pure returns (bytes) { + function f2() public pure returns (bytes memory) { bytes4 x = 0x12345678; return abi.encodeWithSelector(x, "abc"); } - function f3() public pure returns (bytes) { + function f3() public pure returns (bytes memory) { bytes4 x = 0x12345678; return abi.encodeWithSelector(x, uint(-1)); } @@ -12024,22 +12333,22 @@ BOOST_AUTO_TEST_CASE(abi_encode_with_selectorv2) char const* sourceCode = R"( pragma experimental ABIEncoderV2; contract C { - function f0() public pure returns (bytes) { + function f0() public pure returns (bytes memory) { return abi.encodeWithSelector(0x12345678); } - function f1() public pure returns (bytes) { + function f1() public pure returns (bytes memory) { return abi.encodeWithSelector(0x12345678, "abc"); } - function f2() public pure returns (bytes) { + function f2() public pure returns (bytes memory) { bytes4 x = 0x12345678; return abi.encodeWithSelector(x, "abc"); } - function f3() public pure returns (bytes) { + function f3() public pure returns (bytes memory) { bytes4 x = 0x12345678; return abi.encodeWithSelector(x, uint(-1)); } struct S { uint a; string b; uint16 c; } - function f4() public pure returns (bytes) { + function f4() public pure returns (bytes memory) { bytes4 x = 0x12345678; S memory s; s.a = 0x1234567; @@ -12070,19 +12379,19 @@ BOOST_AUTO_TEST_CASE(abi_encode_with_signature) { char const* sourceCode = R"T( contract C { - function f0() public pure returns (bytes) { + function f0() public pure returns (bytes memory) { return abi.encodeWithSignature("f(uint256)"); } - function f1() public pure returns (bytes) { + function f1() public pure returns (bytes memory) { string memory x = "f(uint256)"; return abi.encodeWithSignature(x, "abc"); } string xstor; - function f1s() public returns (bytes) { + function f1s() public returns (bytes memory) { xstor = "f(uint256)"; return abi.encodeWithSignature(xstor, "abc"); } - function f2() public pure returns (bytes r, uint[] ar) { + function f2() public pure returns (bytes memory r, uint[] memory ar) { string memory x = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua."; uint[] memory y = new uint[](4); y[0] = uint(-1); @@ -12114,19 +12423,19 @@ BOOST_AUTO_TEST_CASE(abi_encode_with_signaturev2) char const* sourceCode = R"T( pragma experimental ABIEncoderV2; contract C { - function f0() public pure returns (bytes) { + function f0() public pure returns (bytes memory) { return abi.encodeWithSignature("f(uint256)"); } - function f1() public pure returns (bytes) { + function f1() public pure returns (bytes memory) { string memory x = "f(uint256)"; return abi.encodeWithSignature(x, "abc"); } string xstor; - function f1s() public returns (bytes) { + function f1s() public returns (bytes memory) { xstor = "f(uint256)"; return abi.encodeWithSignature(xstor, "abc"); } - function f2() public pure returns (bytes r, uint[] ar) { + function f2() public pure returns (bytes memory r, uint[] memory ar) { string memory x = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua."; uint[] memory y = new uint[](4); y[0] = uint(-1); @@ -12139,7 +12448,7 @@ BOOST_AUTO_TEST_CASE(abi_encode_with_signaturev2) ar = new uint[](2); } struct S { uint a; string b; uint16 c; } - function f4() public pure returns (bytes) { + function f4() public pure returns (bytes memory) { bytes4 x = 0x12345678; S memory s; s.a = 0x1234567; @@ -12173,7 +12482,7 @@ BOOST_AUTO_TEST_CASE(abi_encode_call) char const* sourceCode = R"T( contract C { bool x; - function c(uint a, uint[] b) public { + function c(uint a, uint[] memory b) public { require(a == 5); require(b.length == 2); require(b[0] == 6); @@ -12185,7 +12494,7 @@ BOOST_AUTO_TEST_CASE(abi_encode_call) uint[] memory b = new uint[](2); b[0] = 6; b[1] = 7; - require(this.call(abi.encodeWithSignature("c(uint256,uint256[])", a, b))); + require(address(this).call(abi.encodeWithSignature("c(uint256,uint256[])", a, b))); return x; } } @@ -12197,7 +12506,6 @@ BOOST_AUTO_TEST_CASE(abi_encode_call) BOOST_AUTO_TEST_CASE(staticcall_for_view_and_pure) { char const* sourceCode = R"( - pragma experimental "v0.5.0"; contract C { uint x; function f() public returns (uint) { @@ -12422,7 +12730,7 @@ BOOST_AUTO_TEST_CASE(senders_balance) } contract D { C c = new C(); - constructor() payable { } + constructor() public payable { } function f() public view returns (uint) { return c.f(); } @@ -12432,6 +12740,43 @@ BOOST_AUTO_TEST_CASE(senders_balance) BOOST_CHECK(callContractFunction("f()") == encodeArgs(u256(27))); } +BOOST_AUTO_TEST_CASE(write_storage_external) +{ + char const* sourceCode = R"( + contract C { + uint public x; + function f(uint y) public payable { + x = y; + } + function g(uint y) external { + x = y; + } + function h() public { + this.g(12); + } + } + contract D { + C c = new C(); + function f() public payable returns (uint) { + c.g(3); + return c.x(); + } + function g() public returns (uint) { + c.g(8); + return c.x(); + } + function h() public returns (uint) { + c.h(); + return c.x(); + } + } + )"; + compileAndRun(sourceCode, 0, "D"); + ABI_CHECK(callContractFunction("f()"), encodeArgs(3)); + ABI_CHECK(callContractFunction("g()"), encodeArgs(8)); + ABI_CHECK(callContractFunction("h()"), encodeArgs(12)); +} + BOOST_AUTO_TEST_SUITE_END() } diff --git a/test/libsolidity/SolidityExpressionCompiler.cpp b/test/libsolidity/SolidityExpressionCompiler.cpp index 949045ea..26b7914f 100644 --- a/test/libsolidity/SolidityExpressionCompiler.cpp +++ b/test/libsolidity/SolidityExpressionCompiler.cpp @@ -77,7 +77,7 @@ Declaration const& resolveDeclaration( ) { ASTNode const* scope = &_sourceUnit; - // bracers are required, cause msvc couldnt handle this macro in for statement + // bracers are required, cause msvc couldn't handle this macro in for statement for (string const& namePart: _namespacedName) { auto declarations = _resolver.resolveName(namePart, scope); @@ -319,7 +319,7 @@ BOOST_AUTO_TEST_CASE(short_circuiting) BOOST_CHECK_EQUAL_COLLECTIONS(code.begin(), code.end(), expectation.begin(), expectation.end()); } -BOOST_AUTO_TEST_CASE(arithmetics) +BOOST_AUTO_TEST_CASE(arithmetic) { char const* sourceCode = R"( contract test { diff --git a/test/libsolidity/SolidityNameAndTypeResolution.cpp b/test/libsolidity/SolidityNameAndTypeResolution.cpp index e6d93b36..d025e65a 100644 --- a/test/libsolidity/SolidityNameAndTypeResolution.cpp +++ b/test/libsolidity/SolidityNameAndTypeResolution.cpp @@ -208,7 +208,7 @@ BOOST_AUTO_TEST_CASE(external_structs) struct X { bytes32 x; Test t; Simple[] s; } function f(ActionChoices, uint, Simple) external {} function g(Test, Nested) external {} - function h(function(Nested) external returns (uint)[]) external {} + function h(function(Nested memory) external returns (uint)[]) external {} function i(Nested[]) external {} } )"; @@ -236,7 +236,7 @@ BOOST_AUTO_TEST_CASE(external_structs_in_libraries) struct X { bytes32 x; Test t; Simple[] s; } function f(ActionChoices, uint, Simple) external {} function g(Test, Nested) external {} - function h(function(Nested) external returns (uint)[]) external {} + function h(function(Nested memory) external returns (uint)[]) external {} function i(Nested[]) external {} } )"; @@ -350,7 +350,7 @@ BOOST_AUTO_TEST_CASE(dynamic_return_types_not_possible) { char const* sourceCode = R"( contract C { - function f(uint) public returns (string); + function f(uint) public returns (string memory); function g() public { string memory x = this.f(2); // we can assign to x but it is not usable. diff --git a/test/libsolidity/SolidityOptimizer.cpp b/test/libsolidity/SolidityOptimizer.cpp index d375beff..3e2dce26 100644 --- a/test/libsolidity/SolidityOptimizer.cpp +++ b/test/libsolidity/SolidityOptimizer.cpp @@ -104,7 +104,7 @@ public: "\nOptimized: " + toHex(optimizedOutput)); } - /// @returns the number of intructions in the given bytecode, not taking the metadata hash + /// @returns the number of instructions in the given bytecode, not taking the metadata hash /// into account. size_t numInstructions(bytes const& _bytecode, boost::optional<Instruction> _which = boost::optional<Instruction>{}) { @@ -370,7 +370,7 @@ BOOST_AUTO_TEST_CASE(sequence_number_for_calls) // to storage), so the sequence number should be incremented. char const* sourceCode = R"( contract test { - function f(string a, string b) public returns (bool) { return sha256(bytes(a)) == sha256(bytes(b)); } + function f(string memory a, string memory b) public returns (bool) { return sha256(bytes(a)) == sha256(bytes(b)); } } )"; compileBothVersions(sourceCode); @@ -394,12 +394,12 @@ BOOST_AUTO_TEST_CASE(computing_constants) g(); return 1; } - function g() { + function g() public { m_b = 0x817416927846239487123469187231298734162934871263941234127518276; m_c = 0x817416927846239487123469187231298734162934871263941234127518276; h(); } - function h() { + function h() public { m_d = 0xff05694900000000000000000000000000000000000000000000000000000000; } function get() public returns (uint ra, uint rb, uint rc, uint rd) { @@ -518,8 +518,8 @@ BOOST_AUTO_TEST_CASE(inconsistency) // Called with params: containerIndex=0, valueIndex=0 function levelIII(uint containerIndex, uint valueIndex) private { - Container container = containers[containerIndex]; - Value value = container.values[valueIndex]; + Container storage container = containers[containerIndex]; + Value storage value = container.values[valueIndex]; debug = container.valueIndices[value.number]; } function levelII() private { @@ -530,7 +530,7 @@ BOOST_AUTO_TEST_CASE(inconsistency) function trigger() public returns (uint) { containers.length++; - Container container = containers[0]; + Container storage container = containers[0]; container.values.push(Value({ badnum: 9000, @@ -600,7 +600,7 @@ BOOST_AUTO_TEST_CASE(init_empty_dynamic_arrays) // not use any memory. char const* sourceCode = R"( contract Test { - function f() pure returns (uint r) { + function f() public pure returns (uint r) { uint[][] memory x = new uint[][](20000); return x.length; } @@ -619,7 +619,7 @@ BOOST_AUTO_TEST_CASE(optimise_multi_stores) struct S { uint16 a; uint16 b; uint16[3] c; uint[] dyn; } uint padding; S[] s; - function f() public returns (uint16, uint16, uint16[3], uint) { + function f() public returns (uint16, uint16, uint16[3] memory, uint) { uint16[3] memory c; c[0] = 7; c[1] = 8; diff --git a/test/libsolidity/StandardCompiler.cpp b/test/libsolidity/StandardCompiler.cpp index bfb0d739..16921a24 100644 --- a/test/libsolidity/StandardCompiler.cpp +++ b/test/libsolidity/StandardCompiler.cpp @@ -466,7 +466,7 @@ BOOST_AUTO_TEST_CASE(output_selection_dependent_contract) }, "sources": { "fileA": { - "content": "contract B { } contract A { function f() { new B(); } }" + "content": "contract B { } contract A { function f() public { new B(); } }" } } } @@ -495,7 +495,7 @@ BOOST_AUTO_TEST_CASE(output_selection_dependent_contract_with_import) }, "sources": { "fileA": { - "content": "import \"fileB\"; contract A { function f() { new B(); } }" + "content": "import \"fileB\"; contract A { function f() public { new B(); } }" }, "fileB": { "content": "contract B { }" @@ -712,7 +712,7 @@ BOOST_AUTO_TEST_CASE(library_linking) "content": "library L { function g() public returns (uint) { return 1; } }" }, "library2.sol": { - "content": "library L2 { function g() { } }" + "content": "library L2 { function g() public { } }" } } } diff --git a/test/libsolidity/ViewPureChecker.cpp b/test/libsolidity/ViewPureChecker.cpp index bb5480b2..299cd084 100644 --- a/test/libsolidity/ViewPureChecker.cpp +++ b/test/libsolidity/ViewPureChecker.cpp @@ -55,7 +55,7 @@ BOOST_AUTO_TEST_CASE(environment_access) "this", "address(1).balance" }; - // ``block.blockhash`` and ``blockhash`` are tested seperately below because their usage will + // ``block.blockhash`` and ``blockhash`` are tested separately below because their usage will // produce warnings that can't be handled in a generic way. vector<string> pure{ "msg.data", 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 11d40f26..5add9106 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 @@ -1,7 +1,7 @@ contract C { - function f(uint constant LEN) { + function f(uint constant LEN) public { uint[LEN] a; } } // ---- -// TypeError: (62-65): Invalid array length, expected integer literal or constant expression. +// TypeError: (69-72): Invalid array length, expected integer literal or constant expression. diff --git a/test/libsolidity/syntaxTests/array/length/cannot_be_function.sol b/test/libsolidity/syntaxTests/array/length/cannot_be_function.sol index ac3abc4c..2ad97d27 100644 --- a/test/libsolidity/syntaxTests/array/length/cannot_be_function.sol +++ b/test/libsolidity/syntaxTests/array/length/cannot_be_function.sol @@ -1,6 +1,6 @@ contract C { - function f() {} + function f() public {} uint[f] ids; } // ---- -// TypeError: (42-43): Invalid array length, expected integer literal or constant expression. +// TypeError: (49-50): Invalid array length, expected integer literal or constant expression. diff --git a/test/libsolidity/syntaxTests/array/length/cannot_be_function_call.sol b/test/libsolidity/syntaxTests/array/length/cannot_be_function_call.sol index a6863955..bb8cc599 100644 --- a/test/libsolidity/syntaxTests/array/length/cannot_be_function_call.sol +++ b/test/libsolidity/syntaxTests/array/length/cannot_be_function_call.sol @@ -1,7 +1,7 @@ contract C { - function f(uint x) {} + function f(uint x) public {} uint constant LEN = f(); uint[LEN] ids; } // ---- -// TypeError: (77-80): Invalid array length, expected integer literal or constant expression. +// TypeError: (84-87): Invalid array length, expected integer literal or constant expression. diff --git a/test/libsolidity/syntaxTests/array/length/complex_cyclic_constant.sol b/test/libsolidity/syntaxTests/array/length/complex_cyclic_constant.sol index 254f9f02..ee107078 100644 --- a/test/libsolidity/syntaxTests/array/length/complex_cyclic_constant.sol +++ b/test/libsolidity/syntaxTests/array/length/complex_cyclic_constant.sol @@ -2,7 +2,7 @@ contract C { uint constant L2 = LEN - 10; uint constant L1 = L2 / 10; uint constant LEN = 10 + L1 * 5; - function f() { + function f() public { uint[LEN] a; } } diff --git a/test/libsolidity/syntaxTests/array/length/cyclic_constant.sol b/test/libsolidity/syntaxTests/array/length/cyclic_constant.sol index 91ba9045..3adc0e9b 100644 --- a/test/libsolidity/syntaxTests/array/length/cyclic_constant.sol +++ b/test/libsolidity/syntaxTests/array/length/cyclic_constant.sol @@ -1,6 +1,6 @@ contract C { uint constant LEN = LEN; - function f() { + function f() public { uint[LEN] a; } } diff --git a/test/libsolidity/syntaxTests/array/no_array_pop.sol b/test/libsolidity/syntaxTests/array/no_array_pop.sol index 44e54ad2..79a68ef1 100644 --- a/test/libsolidity/syntaxTests/array/no_array_pop.sol +++ b/test/libsolidity/syntaxTests/array/no_array_pop.sol @@ -5,4 +5,4 @@ contract C { } } // ---- -// TypeError: (63-71): Member "pop" not found or not visible after argument-dependent lookup in uint256 +// TypeError: (63-71): Member "pop" not found or not visible after argument-dependent lookup in uint256. diff --git a/test/libsolidity/syntaxTests/array/static_storage_array_pop.sol b/test/libsolidity/syntaxTests/array/static_storage_array_pop.sol index 0af171ad..8414f43d 100644 --- a/test/libsolidity/syntaxTests/array/static_storage_array_pop.sol +++ b/test/libsolidity/syntaxTests/array/static_storage_array_pop.sol @@ -5,4 +5,4 @@ contract C { } } // ---- -// TypeError: (66-74): Member "pop" not found or not visible after argument-dependent lookup in uint256[3] storage ref +// TypeError: (66-74): Member "pop" not found or not visible after argument-dependent lookup in uint256[3] storage ref. diff --git a/test/libsolidity/syntaxTests/array/string_pop.sol b/test/libsolidity/syntaxTests/array/string_pop.sol index 2a46d0c3..700fda16 100644 --- a/test/libsolidity/syntaxTests/array/string_pop.sol +++ b/test/libsolidity/syntaxTests/array/string_pop.sol @@ -5,4 +5,4 @@ contract C { } } // ---- -// TypeError: (65-73): Member "pop" not found or not visible after argument-dependent lookup in string storage ref +// TypeError: (65-73): Member "pop" not found or not visible after argument-dependent lookup in string storage ref. diff --git a/test/libsolidity/syntaxTests/array/uninitialized_storage_var.sol b/test/libsolidity/syntaxTests/array/uninitialized_storage_var.sol new file mode 100644 index 00000000..f3be9071 --- /dev/null +++ b/test/libsolidity/syntaxTests/array/uninitialized_storage_var.sol @@ -0,0 +1,9 @@ +contract C { + function f() public { + uint[] storage x; + uint[10] storage y; + } +} +// ---- +// DeclarationError: (38-54): Uninitialized storage pointer. +// DeclarationError: (58-76): Uninitialized storage pointer. diff --git a/test/libsolidity/syntaxTests/constructor/constructible_internal_constructor_new.sol b/test/libsolidity/syntaxTests/constructor/constructible_internal_constructor.sol index 8dee4c71..8dee4c71 100644 --- a/test/libsolidity/syntaxTests/constructor/constructible_internal_constructor_new.sol +++ b/test/libsolidity/syntaxTests/constructor/constructible_internal_constructor.sol diff --git a/test/libsolidity/syntaxTests/constructor/constructible_internal_constructor_old.sol b/test/libsolidity/syntaxTests/constructor/constructible_internal_constructor_old.sol deleted file mode 100644 index 144743e3..00000000 --- a/test/libsolidity/syntaxTests/constructor/constructible_internal_constructor_old.sol +++ /dev/null @@ -1,9 +0,0 @@ -contract C { - function C() internal {} -} -contract D is C { - function D() public {} -} -// ---- -// Warning: (14-38): Defining constructors as functions with the same name as the contract is deprecated. Use "constructor(...) { ... }" instead. -// Warning: (60-82): Defining constructors as functions with the same name as the contract is deprecated. Use "constructor(...) { ... }" instead. diff --git a/test/libsolidity/syntaxTests/constructor/constructor_new.sol b/test/libsolidity/syntaxTests/constructor/constructor.sol index aa3422cc..aa3422cc 100644 --- a/test/libsolidity/syntaxTests/constructor/constructor_new.sol +++ b/test/libsolidity/syntaxTests/constructor/constructor.sol diff --git a/test/libsolidity/syntaxTests/constructor/constructor_no_visibility.sol b/test/libsolidity/syntaxTests/constructor/constructor_no_visibility.sol index 88553084..586329b1 100644 --- a/test/libsolidity/syntaxTests/constructor/constructor_no_visibility.sol +++ b/test/libsolidity/syntaxTests/constructor/constructor_no_visibility.sol @@ -1,3 +1,3 @@ contract A { constructor() {} } // ---- -// Warning: (13-29): No visibility specified. Defaulting to "public". +// SyntaxError: (13-29): No visibility specified. Did you intend to add "public"? diff --git a/test/libsolidity/syntaxTests/constructor/constructor_no_visibility_050.sol b/test/libsolidity/syntaxTests/constructor/constructor_no_visibility_050.sol deleted file mode 100644 index 0f57a41f..00000000 --- a/test/libsolidity/syntaxTests/constructor/constructor_no_visibility_050.sol +++ /dev/null @@ -1,4 +0,0 @@ -pragma experimental "v0.5.0"; -contract A { constructor() {} } -// ---- -// SyntaxError: (43-59): No visibility specified. diff --git a/test/libsolidity/syntaxTests/constructor/constructor_old.sol b/test/libsolidity/syntaxTests/constructor/constructor_old.sol index 9ec6257d..9ead6858 100644 --- a/test/libsolidity/syntaxTests/constructor/constructor_old.sol +++ b/test/libsolidity/syntaxTests/constructor/constructor_old.sol @@ -1,3 +1,4 @@ contract A { function A() public {} } // ---- -// Warning: (13-35): Defining constructors as functions with the same name as the contract is deprecated. Use "constructor(...) { ... }" instead. +// SyntaxError: (13-35): Functions are not allowed to have the same name as the contract. If you intend this to be a constructor, use "constructor(...) { ... }" to define it. +// Warning: (13-35): This declaration shadows an existing declaration. diff --git a/test/libsolidity/syntaxTests/constructor/constructor_old_050.sol b/test/libsolidity/syntaxTests/constructor/constructor_old_050.sol deleted file mode 100644 index 19e46e79..00000000 --- a/test/libsolidity/syntaxTests/constructor/constructor_old_050.sol +++ /dev/null @@ -1,4 +0,0 @@ -pragma experimental "v0.5.0"; -contract A { function A() public {} } -// ---- -// SyntaxError: (43-65): Functions are not allowed to have the same name as the contract. If you intend this to be a constructor, use "constructor(...) { ... }" to define it. diff --git a/test/libsolidity/syntaxTests/constructor/constructor_state_mutability.sol b/test/libsolidity/syntaxTests/constructor/constructor_state_mutability.sol new file mode 100644 index 00000000..39bf6384 --- /dev/null +++ b/test/libsolidity/syntaxTests/constructor/constructor_state_mutability.sol @@ -0,0 +1,9 @@ +contract test1 { + constructor() public view {} +} +contract test2 { + constructor() public pure {} +} +// ---- +// TypeError: (19-47): Constructor must be payable or non-payable, but is "view". +// TypeError: (69-97): Constructor must be payable or non-payable, but is "pure". diff --git a/test/libsolidity/syntaxTests/constructor/constructor_state_mutability_new.sol b/test/libsolidity/syntaxTests/constructor/constructor_state_mutability_new.sol deleted file mode 100644 index 78272c98..00000000 --- a/test/libsolidity/syntaxTests/constructor/constructor_state_mutability_new.sol +++ /dev/null @@ -1,9 +0,0 @@ -contract test1 { - constructor() view {} -} -contract test2 { - constructor() pure {} -} -// ---- -// TypeError: (19-40): Constructor must be payable or non-payable, but is "view". -// TypeError: (62-83): Constructor must be payable or non-payable, but is "pure". diff --git a/test/libsolidity/syntaxTests/constructor/constructor_state_mutability_old.sol b/test/libsolidity/syntaxTests/constructor/constructor_state_mutability_old.sol deleted file mode 100644 index 1ceaffee..00000000 --- a/test/libsolidity/syntaxTests/constructor/constructor_state_mutability_old.sol +++ /dev/null @@ -1,11 +0,0 @@ -contract test1 { - function test1() view {} -} -contract test2 { - function test2() pure {} -} -// ---- -// Warning: (21-45): Defining constructors as functions with the same name as the contract is deprecated. Use "constructor(...) { ... }" instead. -// Warning: (69-93): Defining constructors as functions with the same name as the contract is deprecated. Use "constructor(...) { ... }" instead. -// TypeError: (21-45): Constructor must be payable or non-payable, but is "view". -// TypeError: (69-93): Constructor must be payable or non-payable, but is "pure". diff --git a/test/libsolidity/syntaxTests/constructor/constructor_visibility_new.sol b/test/libsolidity/syntaxTests/constructor/constructor_visibility.sol index 502dc029..f9c4b9b9 100644 --- a/test/libsolidity/syntaxTests/constructor/constructor_visibility_new.sol +++ b/test/libsolidity/syntaxTests/constructor/constructor_visibility.sol @@ -1,5 +1,5 @@ // The constructor of a base class should not be visible in the derived class -contract A { constructor(string) public { } } +contract A { constructor(string memory) public { } } contract B is A { function f() pure public { A x = A(0); // convert from address @@ -9,4 +9,4 @@ contract B is A { } } // ---- -// TypeError: (243-247): Explicit type conversion not allowed from "string memory" to "contract A". +// TypeError: (250-254): Explicit type conversion not allowed from "string memory" to "contract A". diff --git a/test/libsolidity/syntaxTests/constructor/constructor_visibility_old.sol b/test/libsolidity/syntaxTests/constructor/constructor_visibility_old.sol deleted file mode 100644 index 847ea27b..00000000 --- a/test/libsolidity/syntaxTests/constructor/constructor_visibility_old.sol +++ /dev/null @@ -1,13 +0,0 @@ -// The constructor of a base class should not be visible in the derived class -contract A { function A(string s) public { } } -contract B is A { - function f() pure public { - A x = A(0); // convert from address - string memory y = "ab"; - A(y); // call as a function is invalid - x; - } -} -// ---- -// Warning: (91-122): Defining constructors as functions with the same name as the contract is deprecated. Use "constructor(...) { ... }" instead. -// TypeError: (244-248): Explicit type conversion not allowed from "string memory" to "contract A". diff --git a/test/libsolidity/syntaxTests/constructor/constructor_without_implementation.sol b/test/libsolidity/syntaxTests/constructor/constructor_without_implementation.sol new file mode 100644 index 00000000..6bbb83ce --- /dev/null +++ b/test/libsolidity/syntaxTests/constructor/constructor_without_implementation.sol @@ -0,0 +1,5 @@ +contract C { + constructor() public; +} +// ---- +// TypeError: (14-35): Constructor must be implemented if declared. diff --git a/test/libsolidity/syntaxTests/constructor/constructor_without_implementation_new.sol b/test/libsolidity/syntaxTests/constructor/constructor_without_implementation_new.sol deleted file mode 100644 index 5e619143..00000000 --- a/test/libsolidity/syntaxTests/constructor/constructor_without_implementation_new.sol +++ /dev/null @@ -1,5 +0,0 @@ -contract C { - constructor(); -} -// ---- -// TypeError: (14-28): Constructor must be implemented if declared. diff --git a/test/libsolidity/syntaxTests/constructor/constructor_without_implementation_old.sol b/test/libsolidity/syntaxTests/constructor/constructor_without_implementation_old.sol deleted file mode 100644 index 72458703..00000000 --- a/test/libsolidity/syntaxTests/constructor/constructor_without_implementation_old.sol +++ /dev/null @@ -1,6 +0,0 @@ -contract C { - function C(); -} -// ---- -// Warning: (14-27): Defining constructors as functions with the same name as the contract is deprecated. Use "constructor(...) { ... }" instead. -// TypeError: (14-27): Constructor must be implemented if declared. diff --git a/test/libsolidity/syntaxTests/constructor/external_constructor_new.sol b/test/libsolidity/syntaxTests/constructor/external_constructor.sol index 30cf0668..30cf0668 100644 --- a/test/libsolidity/syntaxTests/constructor/external_constructor_new.sol +++ b/test/libsolidity/syntaxTests/constructor/external_constructor.sol diff --git a/test/libsolidity/syntaxTests/constructor/external_constructor_old.sol b/test/libsolidity/syntaxTests/constructor/external_constructor_old.sol deleted file mode 100644 index 27869361..00000000 --- a/test/libsolidity/syntaxTests/constructor/external_constructor_old.sol +++ /dev/null @@ -1,6 +0,0 @@ -contract test { - function test() external {} -} -// ---- -// Warning: (17-44): Defining constructors as functions with the same name as the contract is deprecated. Use "constructor(...) { ... }" instead. -// TypeError: (17-44): Constructor must be public or internal. diff --git a/test/libsolidity/syntaxTests/constructor/function_named_constructor.sol b/test/libsolidity/syntaxTests/constructor/function_named_constructor.sol index 29784033..68273c0a 100644 --- a/test/libsolidity/syntaxTests/constructor/function_named_constructor.sol +++ b/test/libsolidity/syntaxTests/constructor/function_named_constructor.sol @@ -2,4 +2,4 @@ contract C { function constructor() public; } // ---- -// Warning: (17-47): This function is named "constructor" but is not the constructor of the contract. If you intend this to be a constructor, use "constructor(...) { ... }" without the "function" keyword to define it. +// ParserError: (26-37): This function is named "constructor" but is not the constructor of the contract. If you intend this to be a constructor, use "constructor(...) { ... }" without the "function" keyword to define it. diff --git a/test/libsolidity/syntaxTests/constructor/inconstructible_internal_constructor_new.sol b/test/libsolidity/syntaxTests/constructor/inconstructible_internal_constructor.sol index 2511c751..2511c751 100644 --- a/test/libsolidity/syntaxTests/constructor/inconstructible_internal_constructor_new.sol +++ b/test/libsolidity/syntaxTests/constructor/inconstructible_internal_constructor.sol diff --git a/test/libsolidity/syntaxTests/constructor/inconstructible_internal_constructor_inverted_new.sol b/test/libsolidity/syntaxTests/constructor/inconstructible_internal_constructor_inverted.sol index 2a199b3a..2a199b3a 100644 --- a/test/libsolidity/syntaxTests/constructor/inconstructible_internal_constructor_inverted_new.sol +++ b/test/libsolidity/syntaxTests/constructor/inconstructible_internal_constructor_inverted.sol diff --git a/test/libsolidity/syntaxTests/constructor/inconstructible_internal_constructor_inverted_old.sol b/test/libsolidity/syntaxTests/constructor/inconstructible_internal_constructor_inverted_old.sol deleted file mode 100644 index 0a27e9f8..00000000 --- a/test/libsolidity/syntaxTests/constructor/inconstructible_internal_constructor_inverted_old.sol +++ /dev/null @@ -1,15 +0,0 @@ -// Previously, the type information for A was not yet available at the point of -// "new A". -contract B { - A a; - function B() public { - a = new A(this); - } -} -contract A { - function A(address a) internal {} -} -// ---- -// Warning: (112-155): Defining constructors as functions with the same name as the contract is deprecated. Use "constructor(...) { ... }" instead. -// Warning: (172-205): Defining constructors as functions with the same name as the contract is deprecated. Use "constructor(...) { ... }" instead. -// TypeError: (140-145): Contract with internal constructor cannot be created directly. diff --git a/test/libsolidity/syntaxTests/constructor/inconstructible_internal_constructor_old.sol b/test/libsolidity/syntaxTests/constructor/inconstructible_internal_constructor_old.sol deleted file mode 100644 index 2897e6f3..00000000 --- a/test/libsolidity/syntaxTests/constructor/inconstructible_internal_constructor_old.sol +++ /dev/null @@ -1,9 +0,0 @@ -contract C { - function C() internal {} -} -contract D { - function f() public { C x = new C(); x; } -} -// ---- -// Warning: (14-38): Defining constructors as functions with the same name as the contract is deprecated. Use "constructor(...) { ... }" instead. -// TypeError: (83-88): Contract with internal constructor cannot be created directly. diff --git a/test/libsolidity/syntaxTests/constructor/interface_constructor.sol b/test/libsolidity/syntaxTests/constructor/interface_constructor.sol new file mode 100644 index 00000000..87585a62 --- /dev/null +++ b/test/libsolidity/syntaxTests/constructor/interface_constructor.sol @@ -0,0 +1,7 @@ +interface I { + constructor() public; +} +// ---- +// TypeError: (15-36): Functions in interfaces must be declared external. +// TypeError: (15-36): Constructor cannot be defined in interfaces. +// TypeError: (15-36): Constructor must be implemented if declared. diff --git a/test/libsolidity/syntaxTests/constructor/interface_constructor_new.sol b/test/libsolidity/syntaxTests/constructor/interface_constructor_new.sol deleted file mode 100644 index fa5d54c4..00000000 --- a/test/libsolidity/syntaxTests/constructor/interface_constructor_new.sol +++ /dev/null @@ -1,7 +0,0 @@ -interface I { - constructor(); -} -// ---- -// Warning: (15-29): Functions in interfaces should be declared external. -// TypeError: (15-29): Constructor cannot be defined in interfaces. -// TypeError: (15-29): Constructor must be implemented if declared. diff --git a/test/libsolidity/syntaxTests/constructor/interface_constructor_old.sol b/test/libsolidity/syntaxTests/constructor/interface_constructor_old.sol deleted file mode 100644 index ddf54977..00000000 --- a/test/libsolidity/syntaxTests/constructor/interface_constructor_old.sol +++ /dev/null @@ -1,8 +0,0 @@ -interface I { - function I(); -} -// ---- -// Warning: (15-28): Defining constructors as functions with the same name as the contract is deprecated. Use "constructor(...) { ... }" instead. -// Warning: (15-28): Functions in interfaces should be declared external. -// TypeError: (15-28): Constructor cannot be defined in interfaces. -// TypeError: (15-28): Constructor must be implemented if declared. diff --git a/test/libsolidity/syntaxTests/constructor/library_constructor.sol b/test/libsolidity/syntaxTests/constructor/library_constructor.sol new file mode 100644 index 00000000..38934f8d --- /dev/null +++ b/test/libsolidity/syntaxTests/constructor/library_constructor.sol @@ -0,0 +1,6 @@ +library Lib { + constructor() public; +} +// ---- +// TypeError: (15-36): Constructor cannot be defined in libraries. +// TypeError: (15-36): Constructor must be implemented if declared. diff --git a/test/libsolidity/syntaxTests/constructor/library_constructor_new.sol b/test/libsolidity/syntaxTests/constructor/library_constructor_new.sol deleted file mode 100644 index 8db7e62a..00000000 --- a/test/libsolidity/syntaxTests/constructor/library_constructor_new.sol +++ /dev/null @@ -1,6 +0,0 @@ -library Lib { - constructor(); -} -// ---- -// TypeError: (15-29): Constructor cannot be defined in libraries. -// TypeError: (15-29): Constructor must be implemented if declared. diff --git a/test/libsolidity/syntaxTests/constructor/library_constructor_old.sol b/test/libsolidity/syntaxTests/constructor/library_constructor_old.sol deleted file mode 100644 index d4499049..00000000 --- a/test/libsolidity/syntaxTests/constructor/library_constructor_old.sol +++ /dev/null @@ -1,7 +0,0 @@ -library Lib { - function Lib(); -} -// ---- -// Warning: (15-30): Defining constructors as functions with the same name as the contract is deprecated. Use "constructor(...) { ... }" instead. -// TypeError: (15-30): Constructor cannot be defined in libraries. -// TypeError: (15-30): Constructor must be implemented if declared. diff --git a/test/libsolidity/syntaxTests/constructor/overriding_constructor.sol b/test/libsolidity/syntaxTests/constructor/overriding_constructor.sol index 5fb3a189..30cf3bce 100644 --- a/test/libsolidity/syntaxTests/constructor/overriding_constructor.sol +++ b/test/libsolidity/syntaxTests/constructor/overriding_constructor.sol @@ -1,10 +1,10 @@ -contract A { constructor() public {} } -contract B is A { function A() public pure returns (uint8) {} } -contract C is A { function A() public pure returns (uint8) {} } -contract D is B { function B() public pure returns (uint8) {} } -contract E is D { function B() public pure returns (uint8) {} } +contract A { function f() public {} } +contract B is A { + function A() public pure returns (uint8) {} + function g() public { + A.f(); + } +} // ---- -// Warning: (57-100): This declaration shadows an existing declaration. -// Warning: (121-164): This declaration shadows an existing declaration. -// Warning: (185-228): This declaration shadows an existing declaration. -// Warning: (249-292): This declaration shadows an existing declaration. +// Warning: (58-101): This declaration shadows an existing declaration. +// TypeError: (130-133): Member "f" not found or not visible after argument-dependent lookup in function () pure returns (uint8). diff --git a/test/libsolidity/syntaxTests/constructor/returns_in_constructor_new.sol b/test/libsolidity/syntaxTests/constructor/returns_in_constructor.sol index e6a03014..e6a03014 100644 --- a/test/libsolidity/syntaxTests/constructor/returns_in_constructor_new.sol +++ b/test/libsolidity/syntaxTests/constructor/returns_in_constructor.sol diff --git a/test/libsolidity/syntaxTests/constructor/returns_in_constructor_old.sol b/test/libsolidity/syntaxTests/constructor/returns_in_constructor_old.sol deleted file mode 100644 index 00b3974c..00000000 --- a/test/libsolidity/syntaxTests/constructor/returns_in_constructor_old.sol +++ /dev/null @@ -1,6 +0,0 @@ -contract test { - function test() public returns (uint a) { } -} -// ---- -// Warning: (17-60): Defining constructors as functions with the same name as the contract is deprecated. Use "constructor(...) { ... }" instead. -// TypeError: (48-56): Non-empty "returns" directive for constructor. diff --git a/test/libsolidity/syntaxTests/constructor/two_constructors_new.sol b/test/libsolidity/syntaxTests/constructor/two_constructors.sol index 42c0de28..42c0de28 100644 --- a/test/libsolidity/syntaxTests/constructor/two_constructors_new.sol +++ b/test/libsolidity/syntaxTests/constructor/two_constructors.sol diff --git a/test/libsolidity/syntaxTests/constructor/two_constructors_mixed.sol b/test/libsolidity/syntaxTests/constructor/two_constructors_mixed.sol deleted file mode 100644 index c757354e..00000000 --- a/test/libsolidity/syntaxTests/constructor/two_constructors_mixed.sol +++ /dev/null @@ -1,7 +0,0 @@ -contract test { - function test(uint) public { } - constructor() public {} -} -// ---- -// Warning: (17-47): Defining constructors as functions with the same name as the contract is deprecated. Use "constructor(...) { ... }" instead. -// DeclarationError: (49-72): More than one constructor defined. diff --git a/test/libsolidity/syntaxTests/constructor/two_constructors_old.sol b/test/libsolidity/syntaxTests/constructor/two_constructors_old.sol deleted file mode 100644 index db632ced..00000000 --- a/test/libsolidity/syntaxTests/constructor/two_constructors_old.sol +++ /dev/null @@ -1,8 +0,0 @@ -contract test { - function test(uint a) public { } - function test() public {} -} -// ---- -// Warning: (17-49): Defining constructors as functions with the same name as the contract is deprecated. Use "constructor(...) { ... }" instead. -// Warning: (51-76): Defining constructors as functions with the same name as the contract is deprecated. Use "constructor(...) { ... }" instead. -// DeclarationError: (51-76): More than one constructor defined. diff --git a/test/libsolidity/syntaxTests/controlFlow/storageReturn/default_location.sol b/test/libsolidity/syntaxTests/controlFlow/storageReturn/default_location.sol index 9a42192d..ec83c596 100644 --- a/test/libsolidity/syntaxTests/controlFlow/storageReturn/default_location.sol +++ b/test/libsolidity/syntaxTests/controlFlow/storageReturn/default_location.sol @@ -1,18 +1,18 @@ contract C { struct S { bool f; } S s; - function f() internal view returns (S c) { + function f() internal view returns (S memory c) { c = s; } - function g() internal view returns (S) { + function g() internal view returns (S memory) { return s; } - function h() internal pure returns (S) { + function h() internal pure returns (S memory) { } - function i(bool flag) internal view returns (S c) { + function i(bool flag) internal view returns (S memory c) { if (flag) c = s; } - function j(bool flag) internal view returns (S) { + function j(bool flag) internal view returns (S memory) { if (flag) return s; } } diff --git a/test/libsolidity/syntaxTests/controlFlow/storageReturn/throw_fine.sol b/test/libsolidity/syntaxTests/controlFlow/storageReturn/throw_fine.sol deleted file mode 100644 index 4cecc27c..00000000 --- a/test/libsolidity/syntaxTests/controlFlow/storageReturn/throw_fine.sol +++ /dev/null @@ -1,9 +0,0 @@ -contract C { - struct S { bool f; } - S s; - function f() internal pure returns (S storage) { - throw; - } -} -// ---- -// Warning: (108-113): "throw" is deprecated in favour of "revert()", "require()" and "assert()". 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 876d6fd6..ac312685 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 @@ -1,5 +1,5 @@ contract test { - function f() { + function f() public { uint storage a1; bytes16 storage b1; uint memory a2; @@ -7,7 +7,7 @@ contract test { } } // ---- -// TypeError: (41-56): Data location can only be given for array or struct types. -// TypeError: (64-82): Data location can only be given for array or struct types. -// TypeError: (90-104): Data location can only be given for array or struct types. -// TypeError: (112-129): Data location can only be given for array or struct types. +// 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. diff --git a/test/libsolidity/syntaxTests/dataLocations/variable_declaration_location_specifier_test_reference_type.sol b/test/libsolidity/syntaxTests/dataLocations/variable_declaration_location_specifier_test_reference_type.sol index bd011f2d..0fbad155 100644 --- a/test/libsolidity/syntaxTests/dataLocations/variable_declaration_location_specifier_test_reference_type.sol +++ b/test/libsolidity/syntaxTests/dataLocations/variable_declaration_location_specifier_test_reference_type.sol @@ -4,11 +4,10 @@ contract test { function f() public { uint[] storage s1 = a; uint[] memory s2 = new uint[](42); - uint[] s3 = b; + uint[] storage s3 = b; s1.push(42); s2[3] = 12; s3.push(42); } } // ---- -// Warning: (147-156): Variable is declared as a storage pointer. Use an explicit "storage" keyword to silence this warning. diff --git a/test/libsolidity/syntaxTests/denominations/combining_hex_and_denomination.sol b/test/libsolidity/syntaxTests/denominations/combining_hex_and_denomination.sol index 3571e8a9..f115ac60 100644 --- a/test/libsolidity/syntaxTests/denominations/combining_hex_and_denomination.sol +++ b/test/libsolidity/syntaxTests/denominations/combining_hex_and_denomination.sol @@ -2,4 +2,4 @@ contract C { uint constant x = 0x01 wei; } // ---- -// Warning: (32-40): Hexadecimal numbers with unit denominations are deprecated. You can use an expression of the form "0x1234 * 1 day" instead. +// TypeError: (32-40): Hexadecimal numbers cannot be used with unit denominations. You can use an expression of the form "0x1234 * 1 day" instead. diff --git a/test/libsolidity/syntaxTests/denominations/combining_hex_and_denomination_050.sol b/test/libsolidity/syntaxTests/denominations/combining_hex_and_denomination_050.sol deleted file mode 100644 index 98865999..00000000 --- a/test/libsolidity/syntaxTests/denominations/combining_hex_and_denomination_050.sol +++ /dev/null @@ -1,6 +0,0 @@ -pragma experimental "v0.5.0"; -contract C { - uint constant x = 0x01 wei; -} -// ---- -// TypeError: (62-70): Hexadecimal numbers cannot be used with unit denominations. You can use an expression of the form "0x1234 * 1 day" instead. diff --git a/test/libsolidity/syntaxTests/emit_non_event.sol b/test/libsolidity/syntaxTests/emit_non_event.sol index 1df6990d..d5045ddf 100644 --- a/test/libsolidity/syntaxTests/emit_non_event.sol +++ b/test/libsolidity/syntaxTests/emit_non_event.sol @@ -1,10 +1,10 @@ contract C { uint256 Test; - function f() { + function f() public { emit Test(); } } // ---- -// TypeError: (56-62): Type is not callable -// TypeError: (56-60): Expression has to be an event invocation. +// TypeError: (63-69): Type is not callable +// TypeError: (63-67): Expression has to be an event invocation. diff --git a/test/libsolidity/syntaxTests/fallback/default_visibility.sol b/test/libsolidity/syntaxTests/fallback/default_visibility.sol index f45bbd3c..6fbb15a5 100644 --- a/test/libsolidity/syntaxTests/fallback/default_visibility.sol +++ b/test/libsolidity/syntaxTests/fallback/default_visibility.sol @@ -3,4 +3,5 @@ contract C { function() {} } // ---- -// Warning: (90-103): No visibility specified. Defaulting to "public". +// SyntaxError: (90-103): No visibility specified. Did you intend to add "external"? +// TypeError: (90-103): Fallback function must be defined as "external". diff --git a/test/libsolidity/syntaxTests/functionCalls/named_arguments_for_functions_that_take_arbitrary_parameters.sol b/test/libsolidity/syntaxTests/functionCalls/named_arguments_for_functions_that_take_arbitrary_parameters.sol new file mode 100644 index 00000000..089e1dbf --- /dev/null +++ b/test/libsolidity/syntaxTests/functionCalls/named_arguments_for_functions_that_take_arbitrary_parameters.sol @@ -0,0 +1,7 @@ +contract C { + function f() pure public { + abi.encodeWithSelector({selector:"abc"}); + } +} +// ---- +// TypeError: (52-92): Named arguments cannot be used for functions that take arbitrary parameters. diff --git a/test/libsolidity/syntaxTests/functionTypes/function_type_constructor.sol b/test/libsolidity/syntaxTests/functionTypes/function_type_constructor.sol index 95ebc179..6549eb48 100644 --- a/test/libsolidity/syntaxTests/functionTypes/function_type_constructor.sol +++ b/test/libsolidity/syntaxTests/functionTypes/function_type_constructor.sol @@ -1,7 +1,7 @@ contract C { // Fool parser into parsing a constructor as a function type. - constructor() x; + constructor() public x; } // ---- -// Warning: (83-99): Modifiers of functions without implementation are ignored. -// DeclarationError: (97-98): Undeclared identifier. +// Warning: (83-106): Modifiers of functions without implementation are ignored. +// DeclarationError: (104-105): Undeclared identifier. diff --git a/test/libsolidity/syntaxTests/functionTypes/function_type_constructor_local.sol b/test/libsolidity/syntaxTests/functionTypes/function_type_constructor_local.sol index b89a3bb4..42697b73 100644 --- a/test/libsolidity/syntaxTests/functionTypes/function_type_constructor_local.sol +++ b/test/libsolidity/syntaxTests/functionTypes/function_type_constructor_local.sol @@ -5,4 +5,4 @@ contract C { } } // ---- -// ParserError: (118-119): Expected ';' but got identifier +// ParserError: (104-115): Expected primary expression. diff --git a/test/libsolidity/syntaxTests/functionTypes/valid_function_type_variables.sol b/test/libsolidity/syntaxTests/functionTypes/valid_function_type_variables.sol index 10c6767c..e7d2c9a9 100644 --- a/test/libsolidity/syntaxTests/functionTypes/valid_function_type_variables.sol +++ b/test/libsolidity/syntaxTests/functionTypes/valid_function_type_variables.sol @@ -1,5 +1,5 @@ contract test { - function fa(uint) {} + function fa(uint) public {} function fb(uint) internal {} function fc(uint) internal {} function fd(uint) external {} @@ -13,11 +13,14 @@ contract test { function(uint) internal internal c = fc; function(uint) external d = this.fd; function(uint) external internal e = this.fe; - function(uint) internal public f = ff; - function(uint) internal pure public g = fg; - function(uint) pure internal public h = fh; + function(uint) internal f = ff; + function(uint) internal pure g = fg; + function(uint) pure internal h = fh; } // ---- -// TypeError: (545-582): Internal or recursive type is not allowed for public state variables. -// TypeError: (588-630): Internal or recursive type is not allowed for public state variables. -// TypeError: (636-678): Internal or recursive type is not allowed for public state variables. +// Warning: (20-47): Function state mutability can be restricted to pure +// Warning: (52-81): Function state mutability can be restricted to pure +// Warning: (86-115): Function state mutability can be restricted to pure +// Warning: (120-149): Function state mutability can be restricted to pure +// Warning: (154-183): Function state mutability can be restricted to pure +// Warning: (188-217): Function state mutability can be restricted to pure diff --git a/test/libsolidity/syntaxTests/inheritance/base_arguments_empty_parentheses.sol b/test/libsolidity/syntaxTests/inheritance/base_arguments_empty_parentheses.sol index 0b18b995..692b1827 100644 --- a/test/libsolidity/syntaxTests/inheritance/base_arguments_empty_parentheses.sol +++ b/test/libsolidity/syntaxTests/inheritance/base_arguments_empty_parentheses.sol @@ -4,4 +4,4 @@ contract Base { contract Derived is Base(2) { } contract Derived2 is Base(), Derived() { } // ---- -// Warning: (101-107): Wrong argument count for constructor call: 0 arguments given but expected 1. +// TypeError: (101-107): Wrong argument count for constructor call: 0 arguments given but expected 1. Remove parentheses if you do not want to provide arguments here. diff --git a/test/libsolidity/syntaxTests/inheritance/base_arguments_empty_parentheses_V050.sol b/test/libsolidity/syntaxTests/inheritance/base_arguments_empty_parentheses_V050.sol deleted file mode 100644 index db04ab8c..00000000 --- a/test/libsolidity/syntaxTests/inheritance/base_arguments_empty_parentheses_V050.sol +++ /dev/null @@ -1,9 +0,0 @@ -pragma experimental "v0.5.0"; - -contract Base { - constructor(uint) public {} -} -contract Derived is Base(2) { } -contract Derived2 is Base(), Derived() { } -// ---- -// TypeError: (132-138): Wrong argument count for constructor call: 0 arguments given but expected 1. diff --git a/test/libsolidity/syntaxTests/inheritance/override/add_view.sol b/test/libsolidity/syntaxTests/inheritance/override/add_view.sol index 9973b23e..21e43792 100644 --- a/test/libsolidity/syntaxTests/inheritance/override/add_view.sol +++ b/test/libsolidity/syntaxTests/inheritance/override/add_view.sol @@ -1,4 +1,4 @@ contract B { function f() public {} } -contract C is B { function f() view {} } +contract C is B { function f() public view {} } // ---- -// TypeError: (56-76): Overriding function changes state mutability from "nonpayable" to "view". +// TypeError: (56-83): Overriding function changes state mutability from "nonpayable" to "view". diff --git a/test/libsolidity/syntaxTests/inheritance/override/remove_view.sol b/test/libsolidity/syntaxTests/inheritance/override/remove_view.sol index e58f6b20..cc785858 100644 --- a/test/libsolidity/syntaxTests/inheritance/override/remove_view.sol +++ b/test/libsolidity/syntaxTests/inheritance/override/remove_view.sol @@ -1,4 +1,4 @@ -contract B { function f() view {} } +contract B { function f() public view {} } contract C is B { function f() public {} } // ---- -// TypeError: (54-76): Overriding function changes state mutability from "view" to "nonpayable". +// TypeError: (61-83): Overriding function changes state mutability from "view" to "nonpayable". diff --git a/test/libsolidity/syntaxTests/inheritance/too_few_base_arguments.sol b/test/libsolidity/syntaxTests/inheritance/too_few_base_arguments.sol index c55c41f2..1ce48200 100644 --- a/test/libsolidity/syntaxTests/inheritance/too_few_base_arguments.sol +++ b/test/libsolidity/syntaxTests/inheritance/too_few_base_arguments.sol @@ -6,5 +6,5 @@ contract Derived2 is Base { constructor() Base(2) public { } } // ---- -// TypeError: (74-81): Wrong argument count for constructor call: 1 arguments given but expected 2. +// TypeError: (74-81): Wrong argument count for constructor call: 1 arguments given but expected 2. Remove parentheses if you do not want to provide arguments here. // TypeError: (130-137): Wrong argument count for modifier invocation: 1 arguments given but expected 2. diff --git a/test/libsolidity/syntaxTests/inlineAssembly/storage_reference.sol b/test/libsolidity/syntaxTests/inlineAssembly/storage_reference.sol index 55c83674..b6dd12b8 100644 --- a/test/libsolidity/syntaxTests/inlineAssembly/storage_reference.sol +++ b/test/libsolidity/syntaxTests/inlineAssembly/storage_reference.sol @@ -1,6 +1,6 @@ contract C { uint[] x; - function() public { + function() external { uint[] storage y = x; assembly { pop(y) @@ -8,4 +8,4 @@ contract C { } } // ---- -// TypeError: (117-118): You have to use the _slot or _offset suffix to access storage reference variables. +// TypeError: (119-120): You have to use the _slot or _offset suffix to access storage reference variables. diff --git a/test/libsolidity/syntaxTests/inlineAssembly/storage_reference_fine.sol b/test/libsolidity/syntaxTests/inlineAssembly/storage_reference_fine.sol index 3ae24b34..84f98ed9 100644 --- a/test/libsolidity/syntaxTests/inlineAssembly/storage_reference_fine.sol +++ b/test/libsolidity/syntaxTests/inlineAssembly/storage_reference_fine.sol @@ -1,6 +1,6 @@ contract C { uint[] x; - function() public { + function() external { uint[] storage y = x; assembly { pop(y_slot) diff --git a/test/libsolidity/syntaxTests/memberLookup/failed_function_lookup.sol b/test/libsolidity/syntaxTests/memberLookup/failed_function_lookup.sol index c23992e9..119df5d3 100644 --- a/test/libsolidity/syntaxTests/memberLookup/failed_function_lookup.sol +++ b/test/libsolidity/syntaxTests/memberLookup/failed_function_lookup.sol @@ -1,7 +1,7 @@ contract C { - function f(uint, uint) {} - function f(uint) {} - function g() { f(1, 2, 3); } + function f(uint, uint) public {} + function f(uint) public {} + function g() public { f(1, 2, 3); } } // ---- -// TypeError: (80-81): No matching declaration found after argument-dependent lookup. +// TypeError: (101-102): No matching declaration found after argument-dependent lookup. diff --git a/test/libsolidity/syntaxTests/memberLookup/failed_function_lookup_in_library.sol b/test/libsolidity/syntaxTests/memberLookup/failed_function_lookup_in_library.sol index 310c4a10..d8f2eadd 100644 --- a/test/libsolidity/syntaxTests/memberLookup/failed_function_lookup_in_library.sol +++ b/test/libsolidity/syntaxTests/memberLookup/failed_function_lookup_in_library.sol @@ -1,9 +1,9 @@ library L { - function f(uint, uint) {} - function f(uint) {} + function f(uint, uint) public {} + function f(uint) public {} } contract C { - function g() { L.f(1, 2, 3); } + function g() public { L.f(1, 2, 3); } } // ---- -// TypeError: (94-97): Member "f" not found or not visible after argument-dependent lookup in type(library L) +// TypeError: (115-118): Member "f" not found or not visible after argument-dependent lookup in type(library L). diff --git a/test/libsolidity/syntaxTests/missing_state_variable.sol b/test/libsolidity/syntaxTests/missing_state_variable.sol index 02082a45..8b97220c 100644 --- a/test/libsolidity/syntaxTests/missing_state_variable.sol +++ b/test/libsolidity/syntaxTests/missing_state_variable.sol @@ -4,4 +4,4 @@ contract Scope { } } // ---- -// TypeError: (101-115): Member "stateVar" not found or not visible after argument-dependent lookup in type(contract Scope) +// TypeError: (101-115): Member "stateVar" not found or not visible after argument-dependent lookup in type(contract Scope). diff --git a/test/libsolidity/syntaxTests/more_than_256_declarationerrors.sol b/test/libsolidity/syntaxTests/more_than_256_declarationerrors.sol index 2d75f29b..307b728d 100644 --- a/test/libsolidity/syntaxTests/more_than_256_declarationerrors.sol +++ b/test/libsolidity/syntaxTests/more_than_256_declarationerrors.sol @@ -1,5 +1,5 @@ contract C { - function f() { + function f() public { b = 5; b = 5; b = 5; @@ -265,260 +265,260 @@ contract C { } } // ---- -// DeclarationError: (34-35): Undeclared identifier. -// DeclarationError: (45-46): Undeclared identifier. -// DeclarationError: (56-57): Undeclared identifier. -// DeclarationError: (67-68): Undeclared identifier. -// DeclarationError: (78-79): Undeclared identifier. -// DeclarationError: (89-90): Undeclared identifier. -// DeclarationError: (100-101): Undeclared identifier. -// DeclarationError: (111-112): Undeclared identifier. -// DeclarationError: (122-123): Undeclared identifier. -// DeclarationError: (133-134): Undeclared identifier. -// DeclarationError: (144-145): Undeclared identifier. -// DeclarationError: (155-156): Undeclared identifier. -// DeclarationError: (166-167): Undeclared identifier. -// DeclarationError: (177-178): Undeclared identifier. -// DeclarationError: (188-189): Undeclared identifier. -// DeclarationError: (199-200): Undeclared identifier. -// DeclarationError: (210-211): Undeclared identifier. -// DeclarationError: (221-222): Undeclared identifier. -// DeclarationError: (232-233): Undeclared identifier. -// DeclarationError: (243-244): Undeclared identifier. -// DeclarationError: (254-255): Undeclared identifier. -// DeclarationError: (265-266): Undeclared identifier. -// DeclarationError: (276-277): Undeclared identifier. -// DeclarationError: (287-288): Undeclared identifier. -// DeclarationError: (298-299): Undeclared identifier. -// DeclarationError: (309-310): Undeclared identifier. -// DeclarationError: (320-321): Undeclared identifier. -// DeclarationError: (331-332): Undeclared identifier. -// DeclarationError: (342-343): Undeclared identifier. -// DeclarationError: (353-354): Undeclared identifier. -// DeclarationError: (364-365): Undeclared identifier. -// DeclarationError: (375-376): Undeclared identifier. -// DeclarationError: (386-387): Undeclared identifier. -// DeclarationError: (397-398): Undeclared identifier. -// DeclarationError: (408-409): Undeclared identifier. -// DeclarationError: (419-420): Undeclared identifier. -// DeclarationError: (430-431): Undeclared identifier. -// DeclarationError: (441-442): Undeclared identifier. -// DeclarationError: (452-453): Undeclared identifier. -// DeclarationError: (463-464): Undeclared identifier. -// DeclarationError: (474-475): Undeclared identifier. -// DeclarationError: (485-486): Undeclared identifier. -// DeclarationError: (496-497): Undeclared identifier. -// DeclarationError: (507-508): Undeclared identifier. -// DeclarationError: (518-519): Undeclared identifier. -// DeclarationError: (529-530): Undeclared identifier. -// DeclarationError: (540-541): Undeclared identifier. -// DeclarationError: (551-552): Undeclared identifier. -// DeclarationError: (562-563): Undeclared identifier. -// DeclarationError: (573-574): Undeclared identifier. -// DeclarationError: (584-585): Undeclared identifier. -// DeclarationError: (595-596): Undeclared identifier. -// DeclarationError: (606-607): Undeclared identifier. -// DeclarationError: (617-618): Undeclared identifier. -// DeclarationError: (628-629): Undeclared identifier. -// DeclarationError: (639-640): Undeclared identifier. -// DeclarationError: (650-651): Undeclared identifier. -// DeclarationError: (661-662): Undeclared identifier. -// DeclarationError: (672-673): Undeclared identifier. -// DeclarationError: (683-684): Undeclared identifier. -// DeclarationError: (694-695): Undeclared identifier. -// DeclarationError: (705-706): Undeclared identifier. -// DeclarationError: (716-717): Undeclared identifier. -// DeclarationError: (727-728): Undeclared identifier. -// DeclarationError: (738-739): Undeclared identifier. -// DeclarationError: (749-750): Undeclared identifier. -// DeclarationError: (760-761): Undeclared identifier. -// DeclarationError: (771-772): Undeclared identifier. -// DeclarationError: (782-783): Undeclared identifier. -// DeclarationError: (793-794): Undeclared identifier. -// DeclarationError: (804-805): Undeclared identifier. -// DeclarationError: (815-816): Undeclared identifier. -// DeclarationError: (826-827): Undeclared identifier. -// DeclarationError: (837-838): Undeclared identifier. -// DeclarationError: (848-849): Undeclared identifier. -// DeclarationError: (859-860): Undeclared identifier. -// DeclarationError: (870-871): Undeclared identifier. -// DeclarationError: (881-882): Undeclared identifier. -// DeclarationError: (892-893): Undeclared identifier. -// DeclarationError: (903-904): Undeclared identifier. -// DeclarationError: (914-915): Undeclared identifier. -// DeclarationError: (925-926): Undeclared identifier. -// DeclarationError: (936-937): Undeclared identifier. -// DeclarationError: (947-948): Undeclared identifier. -// DeclarationError: (958-959): Undeclared identifier. -// DeclarationError: (969-970): Undeclared identifier. -// DeclarationError: (980-981): Undeclared identifier. -// DeclarationError: (991-992): Undeclared identifier. -// DeclarationError: (1002-1003): Undeclared identifier. -// DeclarationError: (1013-1014): Undeclared identifier. -// DeclarationError: (1024-1025): Undeclared identifier. -// DeclarationError: (1035-1036): Undeclared identifier. -// DeclarationError: (1046-1047): Undeclared identifier. -// DeclarationError: (1057-1058): Undeclared identifier. -// DeclarationError: (1068-1069): Undeclared identifier. -// DeclarationError: (1079-1080): Undeclared identifier. -// DeclarationError: (1090-1091): Undeclared identifier. -// DeclarationError: (1101-1102): Undeclared identifier. -// DeclarationError: (1112-1113): Undeclared identifier. -// DeclarationError: (1123-1124): Undeclared identifier. -// DeclarationError: (1134-1135): Undeclared identifier. -// DeclarationError: (1145-1146): Undeclared identifier. -// DeclarationError: (1156-1157): Undeclared identifier. -// DeclarationError: (1167-1168): Undeclared identifier. -// DeclarationError: (1178-1179): Undeclared identifier. -// DeclarationError: (1189-1190): Undeclared identifier. -// DeclarationError: (1200-1201): Undeclared identifier. -// DeclarationError: (1211-1212): Undeclared identifier. -// DeclarationError: (1222-1223): Undeclared identifier. -// DeclarationError: (1233-1234): Undeclared identifier. -// DeclarationError: (1244-1245): Undeclared identifier. -// DeclarationError: (1255-1256): Undeclared identifier. -// DeclarationError: (1266-1267): Undeclared identifier. -// DeclarationError: (1277-1278): Undeclared identifier. -// DeclarationError: (1288-1289): Undeclared identifier. -// DeclarationError: (1299-1300): Undeclared identifier. -// DeclarationError: (1310-1311): Undeclared identifier. -// DeclarationError: (1321-1322): Undeclared identifier. -// DeclarationError: (1332-1333): Undeclared identifier. -// DeclarationError: (1343-1344): Undeclared identifier. -// DeclarationError: (1354-1355): Undeclared identifier. -// DeclarationError: (1365-1366): Undeclared identifier. -// DeclarationError: (1376-1377): Undeclared identifier. -// DeclarationError: (1387-1388): Undeclared identifier. -// DeclarationError: (1398-1399): Undeclared identifier. -// DeclarationError: (1409-1410): Undeclared identifier. -// DeclarationError: (1420-1421): Undeclared identifier. -// DeclarationError: (1431-1432): Undeclared identifier. -// DeclarationError: (1442-1443): Undeclared identifier. -// DeclarationError: (1453-1454): Undeclared identifier. -// DeclarationError: (1464-1465): Undeclared identifier. -// DeclarationError: (1475-1476): Undeclared identifier. -// DeclarationError: (1486-1487): Undeclared identifier. -// DeclarationError: (1497-1498): Undeclared identifier. -// DeclarationError: (1508-1509): Undeclared identifier. -// DeclarationError: (1519-1520): Undeclared identifier. -// DeclarationError: (1530-1531): Undeclared identifier. -// DeclarationError: (1541-1542): Undeclared identifier. -// DeclarationError: (1552-1553): Undeclared identifier. -// DeclarationError: (1563-1564): Undeclared identifier. -// DeclarationError: (1574-1575): Undeclared identifier. -// DeclarationError: (1585-1586): Undeclared identifier. -// DeclarationError: (1596-1597): Undeclared identifier. -// DeclarationError: (1607-1608): Undeclared identifier. -// DeclarationError: (1618-1619): Undeclared identifier. -// DeclarationError: (1629-1630): Undeclared identifier. -// DeclarationError: (1640-1641): Undeclared identifier. -// DeclarationError: (1651-1652): Undeclared identifier. -// DeclarationError: (1662-1663): Undeclared identifier. -// DeclarationError: (1673-1674): Undeclared identifier. -// DeclarationError: (1684-1685): Undeclared identifier. -// DeclarationError: (1695-1696): Undeclared identifier. -// DeclarationError: (1706-1707): Undeclared identifier. -// DeclarationError: (1717-1718): Undeclared identifier. -// DeclarationError: (1728-1729): Undeclared identifier. -// DeclarationError: (1739-1740): Undeclared identifier. -// DeclarationError: (1750-1751): Undeclared identifier. -// DeclarationError: (1761-1762): Undeclared identifier. -// DeclarationError: (1772-1773): Undeclared identifier. -// DeclarationError: (1783-1784): Undeclared identifier. -// DeclarationError: (1794-1795): Undeclared identifier. -// DeclarationError: (1805-1806): Undeclared identifier. -// DeclarationError: (1816-1817): Undeclared identifier. -// DeclarationError: (1827-1828): Undeclared identifier. -// DeclarationError: (1838-1839): Undeclared identifier. -// DeclarationError: (1849-1850): Undeclared identifier. -// DeclarationError: (1860-1861): Undeclared identifier. -// DeclarationError: (1871-1872): Undeclared identifier. -// DeclarationError: (1882-1883): Undeclared identifier. -// DeclarationError: (1893-1894): Undeclared identifier. -// DeclarationError: (1904-1905): Undeclared identifier. -// DeclarationError: (1915-1916): Undeclared identifier. -// DeclarationError: (1926-1927): Undeclared identifier. -// DeclarationError: (1937-1938): Undeclared identifier. -// DeclarationError: (1948-1949): Undeclared identifier. -// DeclarationError: (1959-1960): Undeclared identifier. -// DeclarationError: (1970-1971): Undeclared identifier. -// DeclarationError: (1981-1982): Undeclared identifier. -// DeclarationError: (1992-1993): Undeclared identifier. -// DeclarationError: (2003-2004): Undeclared identifier. -// DeclarationError: (2014-2015): Undeclared identifier. -// DeclarationError: (2025-2026): Undeclared identifier. -// DeclarationError: (2036-2037): Undeclared identifier. -// DeclarationError: (2047-2048): Undeclared identifier. -// DeclarationError: (2058-2059): Undeclared identifier. -// DeclarationError: (2069-2070): Undeclared identifier. -// DeclarationError: (2080-2081): Undeclared identifier. -// DeclarationError: (2091-2092): Undeclared identifier. -// DeclarationError: (2102-2103): Undeclared identifier. -// DeclarationError: (2113-2114): Undeclared identifier. -// DeclarationError: (2124-2125): Undeclared identifier. -// DeclarationError: (2135-2136): Undeclared identifier. -// DeclarationError: (2146-2147): Undeclared identifier. -// DeclarationError: (2157-2158): Undeclared identifier. -// DeclarationError: (2168-2169): Undeclared identifier. -// DeclarationError: (2179-2180): Undeclared identifier. -// DeclarationError: (2190-2191): Undeclared identifier. -// DeclarationError: (2201-2202): Undeclared identifier. -// DeclarationError: (2212-2213): Undeclared identifier. -// DeclarationError: (2223-2224): Undeclared identifier. -// DeclarationError: (2234-2235): Undeclared identifier. -// DeclarationError: (2245-2246): Undeclared identifier. -// DeclarationError: (2256-2257): Undeclared identifier. -// DeclarationError: (2267-2268): Undeclared identifier. -// DeclarationError: (2278-2279): Undeclared identifier. -// DeclarationError: (2289-2290): Undeclared identifier. -// DeclarationError: (2300-2301): Undeclared identifier. -// DeclarationError: (2311-2312): Undeclared identifier. -// DeclarationError: (2322-2323): Undeclared identifier. -// DeclarationError: (2333-2334): Undeclared identifier. -// DeclarationError: (2344-2345): Undeclared identifier. -// DeclarationError: (2355-2356): Undeclared identifier. -// DeclarationError: (2366-2367): Undeclared identifier. -// DeclarationError: (2377-2378): Undeclared identifier. -// DeclarationError: (2388-2389): Undeclared identifier. -// DeclarationError: (2399-2400): Undeclared identifier. -// DeclarationError: (2410-2411): Undeclared identifier. -// DeclarationError: (2421-2422): Undeclared identifier. -// DeclarationError: (2432-2433): Undeclared identifier. -// DeclarationError: (2443-2444): Undeclared identifier. -// DeclarationError: (2454-2455): Undeclared identifier. -// DeclarationError: (2465-2466): Undeclared identifier. -// DeclarationError: (2476-2477): Undeclared identifier. -// DeclarationError: (2487-2488): Undeclared identifier. -// DeclarationError: (2498-2499): Undeclared identifier. -// DeclarationError: (2509-2510): Undeclared identifier. -// DeclarationError: (2520-2521): Undeclared identifier. -// DeclarationError: (2531-2532): Undeclared identifier. -// DeclarationError: (2542-2543): Undeclared identifier. -// DeclarationError: (2553-2554): Undeclared identifier. -// DeclarationError: (2564-2565): Undeclared identifier. -// DeclarationError: (2575-2576): Undeclared identifier. -// DeclarationError: (2586-2587): Undeclared identifier. -// DeclarationError: (2597-2598): Undeclared identifier. -// DeclarationError: (2608-2609): Undeclared identifier. -// DeclarationError: (2619-2620): Undeclared identifier. -// DeclarationError: (2630-2631): Undeclared identifier. -// DeclarationError: (2641-2642): Undeclared identifier. -// DeclarationError: (2652-2653): Undeclared identifier. -// DeclarationError: (2663-2664): Undeclared identifier. -// DeclarationError: (2674-2675): Undeclared identifier. -// DeclarationError: (2685-2686): Undeclared identifier. -// DeclarationError: (2696-2697): Undeclared identifier. -// DeclarationError: (2707-2708): Undeclared identifier. -// DeclarationError: (2718-2719): Undeclared identifier. -// DeclarationError: (2729-2730): Undeclared identifier. -// DeclarationError: (2740-2741): Undeclared identifier. -// DeclarationError: (2751-2752): Undeclared identifier. -// DeclarationError: (2762-2763): Undeclared identifier. -// DeclarationError: (2773-2774): Undeclared identifier. -// DeclarationError: (2784-2785): Undeclared identifier. -// DeclarationError: (2795-2796): Undeclared identifier. -// DeclarationError: (2806-2807): Undeclared identifier. -// DeclarationError: (2817-2818): Undeclared identifier. -// DeclarationError: (2828-2829): Undeclared identifier. -// DeclarationError: (2839-2840): Undeclared identifier. +// DeclarationError: (41-42): Undeclared identifier. +// DeclarationError: (52-53): Undeclared identifier. +// DeclarationError: (63-64): Undeclared identifier. +// DeclarationError: (74-75): Undeclared identifier. +// DeclarationError: (85-86): Undeclared identifier. +// DeclarationError: (96-97): Undeclared identifier. +// DeclarationError: (107-108): Undeclared identifier. +// DeclarationError: (118-119): Undeclared identifier. +// DeclarationError: (129-130): Undeclared identifier. +// DeclarationError: (140-141): Undeclared identifier. +// DeclarationError: (151-152): Undeclared identifier. +// DeclarationError: (162-163): Undeclared identifier. +// DeclarationError: (173-174): Undeclared identifier. +// DeclarationError: (184-185): Undeclared identifier. +// DeclarationError: (195-196): Undeclared identifier. +// DeclarationError: (206-207): Undeclared identifier. +// DeclarationError: (217-218): Undeclared identifier. +// DeclarationError: (228-229): Undeclared identifier. +// DeclarationError: (239-240): Undeclared identifier. +// DeclarationError: (250-251): Undeclared identifier. +// DeclarationError: (261-262): Undeclared identifier. +// DeclarationError: (272-273): Undeclared identifier. +// DeclarationError: (283-284): Undeclared identifier. +// DeclarationError: (294-295): Undeclared identifier. +// DeclarationError: (305-306): Undeclared identifier. +// DeclarationError: (316-317): Undeclared identifier. +// DeclarationError: (327-328): Undeclared identifier. +// DeclarationError: (338-339): Undeclared identifier. +// DeclarationError: (349-350): Undeclared identifier. +// DeclarationError: (360-361): Undeclared identifier. +// DeclarationError: (371-372): Undeclared identifier. +// DeclarationError: (382-383): Undeclared identifier. +// DeclarationError: (393-394): Undeclared identifier. +// DeclarationError: (404-405): Undeclared identifier. +// DeclarationError: (415-416): Undeclared identifier. +// DeclarationError: (426-427): Undeclared identifier. +// DeclarationError: (437-438): Undeclared identifier. +// DeclarationError: (448-449): Undeclared identifier. +// DeclarationError: (459-460): Undeclared identifier. +// DeclarationError: (470-471): Undeclared identifier. +// DeclarationError: (481-482): Undeclared identifier. +// DeclarationError: (492-493): Undeclared identifier. +// DeclarationError: (503-504): Undeclared identifier. +// DeclarationError: (514-515): Undeclared identifier. +// DeclarationError: (525-526): Undeclared identifier. +// DeclarationError: (536-537): Undeclared identifier. +// DeclarationError: (547-548): Undeclared identifier. +// DeclarationError: (558-559): Undeclared identifier. +// DeclarationError: (569-570): Undeclared identifier. +// DeclarationError: (580-581): Undeclared identifier. +// DeclarationError: (591-592): Undeclared identifier. +// DeclarationError: (602-603): Undeclared identifier. +// DeclarationError: (613-614): Undeclared identifier. +// DeclarationError: (624-625): Undeclared identifier. +// DeclarationError: (635-636): Undeclared identifier. +// DeclarationError: (646-647): Undeclared identifier. +// DeclarationError: (657-658): Undeclared identifier. +// DeclarationError: (668-669): Undeclared identifier. +// DeclarationError: (679-680): Undeclared identifier. +// DeclarationError: (690-691): Undeclared identifier. +// DeclarationError: (701-702): Undeclared identifier. +// DeclarationError: (712-713): Undeclared identifier. +// DeclarationError: (723-724): Undeclared identifier. +// DeclarationError: (734-735): Undeclared identifier. +// DeclarationError: (745-746): Undeclared identifier. +// DeclarationError: (756-757): Undeclared identifier. +// DeclarationError: (767-768): Undeclared identifier. +// DeclarationError: (778-779): Undeclared identifier. +// DeclarationError: (789-790): Undeclared identifier. +// DeclarationError: (800-801): Undeclared identifier. +// DeclarationError: (811-812): Undeclared identifier. +// DeclarationError: (822-823): Undeclared identifier. +// DeclarationError: (833-834): Undeclared identifier. +// DeclarationError: (844-845): Undeclared identifier. +// DeclarationError: (855-856): Undeclared identifier. +// DeclarationError: (866-867): Undeclared identifier. +// DeclarationError: (877-878): Undeclared identifier. +// DeclarationError: (888-889): Undeclared identifier. +// DeclarationError: (899-900): Undeclared identifier. +// DeclarationError: (910-911): Undeclared identifier. +// DeclarationError: (921-922): Undeclared identifier. +// DeclarationError: (932-933): Undeclared identifier. +// DeclarationError: (943-944): Undeclared identifier. +// DeclarationError: (954-955): Undeclared identifier. +// DeclarationError: (965-966): Undeclared identifier. +// DeclarationError: (976-977): Undeclared identifier. +// DeclarationError: (987-988): Undeclared identifier. +// DeclarationError: (998-999): Undeclared identifier. +// DeclarationError: (1009-1010): Undeclared identifier. +// DeclarationError: (1020-1021): Undeclared identifier. +// DeclarationError: (1031-1032): Undeclared identifier. +// DeclarationError: (1042-1043): Undeclared identifier. +// DeclarationError: (1053-1054): Undeclared identifier. +// DeclarationError: (1064-1065): Undeclared identifier. +// DeclarationError: (1075-1076): Undeclared identifier. +// DeclarationError: (1086-1087): Undeclared identifier. +// DeclarationError: (1097-1098): Undeclared identifier. +// DeclarationError: (1108-1109): Undeclared identifier. +// DeclarationError: (1119-1120): Undeclared identifier. +// DeclarationError: (1130-1131): Undeclared identifier. +// DeclarationError: (1141-1142): Undeclared identifier. +// DeclarationError: (1152-1153): Undeclared identifier. +// DeclarationError: (1163-1164): Undeclared identifier. +// DeclarationError: (1174-1175): Undeclared identifier. +// DeclarationError: (1185-1186): Undeclared identifier. +// DeclarationError: (1196-1197): Undeclared identifier. +// DeclarationError: (1207-1208): Undeclared identifier. +// DeclarationError: (1218-1219): Undeclared identifier. +// DeclarationError: (1229-1230): Undeclared identifier. +// DeclarationError: (1240-1241): Undeclared identifier. +// DeclarationError: (1251-1252): Undeclared identifier. +// DeclarationError: (1262-1263): Undeclared identifier. +// DeclarationError: (1273-1274): Undeclared identifier. +// DeclarationError: (1284-1285): Undeclared identifier. +// DeclarationError: (1295-1296): Undeclared identifier. +// DeclarationError: (1306-1307): Undeclared identifier. +// DeclarationError: (1317-1318): Undeclared identifier. +// DeclarationError: (1328-1329): Undeclared identifier. +// DeclarationError: (1339-1340): Undeclared identifier. +// DeclarationError: (1350-1351): Undeclared identifier. +// DeclarationError: (1361-1362): Undeclared identifier. +// DeclarationError: (1372-1373): Undeclared identifier. +// DeclarationError: (1383-1384): Undeclared identifier. +// DeclarationError: (1394-1395): Undeclared identifier. +// DeclarationError: (1405-1406): Undeclared identifier. +// DeclarationError: (1416-1417): Undeclared identifier. +// DeclarationError: (1427-1428): Undeclared identifier. +// DeclarationError: (1438-1439): Undeclared identifier. +// DeclarationError: (1449-1450): Undeclared identifier. +// DeclarationError: (1460-1461): Undeclared identifier. +// DeclarationError: (1471-1472): Undeclared identifier. +// DeclarationError: (1482-1483): Undeclared identifier. +// DeclarationError: (1493-1494): Undeclared identifier. +// DeclarationError: (1504-1505): Undeclared identifier. +// DeclarationError: (1515-1516): Undeclared identifier. +// DeclarationError: (1526-1527): Undeclared identifier. +// DeclarationError: (1537-1538): Undeclared identifier. +// DeclarationError: (1548-1549): Undeclared identifier. +// DeclarationError: (1559-1560): Undeclared identifier. +// DeclarationError: (1570-1571): Undeclared identifier. +// DeclarationError: (1581-1582): Undeclared identifier. +// DeclarationError: (1592-1593): Undeclared identifier. +// DeclarationError: (1603-1604): Undeclared identifier. +// DeclarationError: (1614-1615): Undeclared identifier. +// DeclarationError: (1625-1626): Undeclared identifier. +// DeclarationError: (1636-1637): Undeclared identifier. +// DeclarationError: (1647-1648): Undeclared identifier. +// DeclarationError: (1658-1659): Undeclared identifier. +// DeclarationError: (1669-1670): Undeclared identifier. +// DeclarationError: (1680-1681): Undeclared identifier. +// DeclarationError: (1691-1692): Undeclared identifier. +// DeclarationError: (1702-1703): Undeclared identifier. +// DeclarationError: (1713-1714): Undeclared identifier. +// DeclarationError: (1724-1725): Undeclared identifier. +// DeclarationError: (1735-1736): Undeclared identifier. +// DeclarationError: (1746-1747): Undeclared identifier. +// DeclarationError: (1757-1758): Undeclared identifier. +// DeclarationError: (1768-1769): Undeclared identifier. +// DeclarationError: (1779-1780): Undeclared identifier. +// DeclarationError: (1790-1791): Undeclared identifier. +// DeclarationError: (1801-1802): Undeclared identifier. +// DeclarationError: (1812-1813): Undeclared identifier. +// DeclarationError: (1823-1824): Undeclared identifier. +// DeclarationError: (1834-1835): Undeclared identifier. +// DeclarationError: (1845-1846): Undeclared identifier. +// DeclarationError: (1856-1857): Undeclared identifier. +// DeclarationError: (1867-1868): Undeclared identifier. +// DeclarationError: (1878-1879): Undeclared identifier. +// DeclarationError: (1889-1890): Undeclared identifier. +// DeclarationError: (1900-1901): Undeclared identifier. +// DeclarationError: (1911-1912): Undeclared identifier. +// DeclarationError: (1922-1923): Undeclared identifier. +// DeclarationError: (1933-1934): Undeclared identifier. +// DeclarationError: (1944-1945): Undeclared identifier. +// DeclarationError: (1955-1956): Undeclared identifier. +// DeclarationError: (1966-1967): Undeclared identifier. +// DeclarationError: (1977-1978): Undeclared identifier. +// DeclarationError: (1988-1989): Undeclared identifier. +// DeclarationError: (1999-2000): Undeclared identifier. +// DeclarationError: (2010-2011): Undeclared identifier. +// DeclarationError: (2021-2022): Undeclared identifier. +// DeclarationError: (2032-2033): Undeclared identifier. +// DeclarationError: (2043-2044): Undeclared identifier. +// DeclarationError: (2054-2055): Undeclared identifier. +// DeclarationError: (2065-2066): Undeclared identifier. +// DeclarationError: (2076-2077): Undeclared identifier. +// DeclarationError: (2087-2088): Undeclared identifier. +// DeclarationError: (2098-2099): Undeclared identifier. +// DeclarationError: (2109-2110): Undeclared identifier. +// DeclarationError: (2120-2121): Undeclared identifier. +// DeclarationError: (2131-2132): Undeclared identifier. +// DeclarationError: (2142-2143): Undeclared identifier. +// DeclarationError: (2153-2154): Undeclared identifier. +// DeclarationError: (2164-2165): Undeclared identifier. +// DeclarationError: (2175-2176): Undeclared identifier. +// DeclarationError: (2186-2187): Undeclared identifier. +// DeclarationError: (2197-2198): Undeclared identifier. +// DeclarationError: (2208-2209): Undeclared identifier. +// DeclarationError: (2219-2220): Undeclared identifier. +// DeclarationError: (2230-2231): Undeclared identifier. +// DeclarationError: (2241-2242): Undeclared identifier. +// DeclarationError: (2252-2253): Undeclared identifier. +// DeclarationError: (2263-2264): Undeclared identifier. +// DeclarationError: (2274-2275): Undeclared identifier. +// DeclarationError: (2285-2286): Undeclared identifier. +// DeclarationError: (2296-2297): Undeclared identifier. +// DeclarationError: (2307-2308): Undeclared identifier. +// DeclarationError: (2318-2319): Undeclared identifier. +// DeclarationError: (2329-2330): Undeclared identifier. +// DeclarationError: (2340-2341): Undeclared identifier. +// DeclarationError: (2351-2352): Undeclared identifier. +// DeclarationError: (2362-2363): Undeclared identifier. +// DeclarationError: (2373-2374): Undeclared identifier. +// DeclarationError: (2384-2385): Undeclared identifier. +// DeclarationError: (2395-2396): Undeclared identifier. +// DeclarationError: (2406-2407): Undeclared identifier. +// DeclarationError: (2417-2418): Undeclared identifier. +// DeclarationError: (2428-2429): Undeclared identifier. +// DeclarationError: (2439-2440): Undeclared identifier. +// DeclarationError: (2450-2451): Undeclared identifier. +// DeclarationError: (2461-2462): Undeclared identifier. +// DeclarationError: (2472-2473): Undeclared identifier. +// DeclarationError: (2483-2484): Undeclared identifier. +// DeclarationError: (2494-2495): Undeclared identifier. +// DeclarationError: (2505-2506): Undeclared identifier. +// DeclarationError: (2516-2517): Undeclared identifier. +// DeclarationError: (2527-2528): Undeclared identifier. +// DeclarationError: (2538-2539): Undeclared identifier. +// DeclarationError: (2549-2550): Undeclared identifier. +// DeclarationError: (2560-2561): Undeclared identifier. +// DeclarationError: (2571-2572): Undeclared identifier. +// DeclarationError: (2582-2583): Undeclared identifier. +// DeclarationError: (2593-2594): Undeclared identifier. +// DeclarationError: (2604-2605): Undeclared identifier. +// DeclarationError: (2615-2616): Undeclared identifier. +// DeclarationError: (2626-2627): Undeclared identifier. +// DeclarationError: (2637-2638): Undeclared identifier. +// DeclarationError: (2648-2649): Undeclared identifier. +// DeclarationError: (2659-2660): Undeclared identifier. +// DeclarationError: (2670-2671): Undeclared identifier. +// DeclarationError: (2681-2682): Undeclared identifier. +// DeclarationError: (2692-2693): Undeclared identifier. +// DeclarationError: (2703-2704): Undeclared identifier. +// DeclarationError: (2714-2715): Undeclared identifier. +// DeclarationError: (2725-2726): Undeclared identifier. +// DeclarationError: (2736-2737): Undeclared identifier. +// DeclarationError: (2747-2748): Undeclared identifier. +// DeclarationError: (2758-2759): Undeclared identifier. +// DeclarationError: (2769-2770): Undeclared identifier. +// DeclarationError: (2780-2781): Undeclared identifier. +// DeclarationError: (2791-2792): Undeclared identifier. +// DeclarationError: (2802-2803): Undeclared identifier. +// DeclarationError: (2813-2814): Undeclared identifier. +// DeclarationError: (2824-2825): Undeclared identifier. +// DeclarationError: (2835-2836): Undeclared identifier. +// DeclarationError: (2846-2847): Undeclared identifier. // Warning: There are more than 256 errors. Aborting. diff --git a/test/libsolidity/syntaxTests/more_than_256_syntaxerrors.sol b/test/libsolidity/syntaxTests/more_than_256_syntaxerrors.sol index 2c9b8a42..fe877396 100644 --- a/test/libsolidity/syntaxTests/more_than_256_syntaxerrors.sol +++ b/test/libsolidity/syntaxTests/more_than_256_syntaxerrors.sol @@ -1,5 +1,5 @@ contract C { - function f() { + function f() public { continue; continue; continue; @@ -265,260 +265,260 @@ contract C { } } // ---- -// SyntaxError: (34-42): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (48-56): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (62-70): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (76-84): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (90-98): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (104-112): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (118-126): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (132-140): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (146-154): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (160-168): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (174-182): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (188-196): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (202-210): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (216-224): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (230-238): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (244-252): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (258-266): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (272-280): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (286-294): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (300-308): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (314-322): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (328-336): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (342-350): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (356-364): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (370-378): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (384-392): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (398-406): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (412-420): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (426-434): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (440-448): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (454-462): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (468-476): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (482-490): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (496-504): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (510-518): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (524-532): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (538-546): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (552-560): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (566-574): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (580-588): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (594-602): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (608-616): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (622-630): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (636-644): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (650-658): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (664-672): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (678-686): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (692-700): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (706-714): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (720-728): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (734-742): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (748-756): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (762-770): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (776-784): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (790-798): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (804-812): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (818-826): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (832-840): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (846-854): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (860-868): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (874-882): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (888-896): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (902-910): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (916-924): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (930-938): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (944-952): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (958-966): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (972-980): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (986-994): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (1000-1008): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (1014-1022): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (1028-1036): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (1042-1050): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (1056-1064): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (1070-1078): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (1084-1092): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (1098-1106): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (1112-1120): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (1126-1134): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (1140-1148): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (1154-1162): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (1168-1176): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (1182-1190): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (1196-1204): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (1210-1218): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (1224-1232): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (1238-1246): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (1252-1260): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (1266-1274): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (1280-1288): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (1294-1302): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (1308-1316): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (1322-1330): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (1336-1344): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (1350-1358): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (1364-1372): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (1378-1386): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (1392-1400): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (1406-1414): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (1420-1428): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (1434-1442): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (1448-1456): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (1462-1470): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (1476-1484): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (1490-1498): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (1504-1512): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (1518-1526): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (1532-1540): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (1546-1554): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (1560-1568): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (1574-1582): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (1588-1596): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (1602-1610): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (1616-1624): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (1630-1638): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (1644-1652): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (1658-1666): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (1672-1680): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (1686-1694): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (1700-1708): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (1714-1722): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (1728-1736): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (1742-1750): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (1756-1764): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (1770-1778): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (1784-1792): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (1798-1806): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (1812-1820): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (1826-1834): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (1840-1848): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (1854-1862): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (1868-1876): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (1882-1890): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (1896-1904): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (1910-1918): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (1924-1932): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (1938-1946): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (1952-1960): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (1966-1974): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (1980-1988): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (1994-2002): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (2008-2016): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (2022-2030): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (2036-2044): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (2050-2058): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (2064-2072): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (2078-2086): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (2092-2100): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (2106-2114): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (2120-2128): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (2134-2142): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (2148-2156): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (2162-2170): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (2176-2184): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (2190-2198): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (2204-2212): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (2218-2226): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (2232-2240): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (2246-2254): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (2260-2268): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (2274-2282): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (2288-2296): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (2302-2310): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (2316-2324): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (2330-2338): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (2344-2352): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (2358-2366): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (2372-2380): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (2386-2394): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (2400-2408): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (2414-2422): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (2428-2436): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (2442-2450): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (2456-2464): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (2470-2478): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (2484-2492): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (2498-2506): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (2512-2520): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (2526-2534): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (2540-2548): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (2554-2562): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (2568-2576): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (2582-2590): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (2596-2604): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (2610-2618): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (2624-2632): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (2638-2646): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (2652-2660): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (2666-2674): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (2680-2688): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (2694-2702): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (2708-2716): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (2722-2730): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (2736-2744): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (2750-2758): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (2764-2772): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (2778-2786): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (2792-2800): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (2806-2814): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (2820-2828): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (2834-2842): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (2848-2856): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (2862-2870): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (2876-2884): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (2890-2898): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (2904-2912): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (2918-2926): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (2932-2940): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (2946-2954): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (2960-2968): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (2974-2982): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (2988-2996): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (3002-3010): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (3016-3024): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (3030-3038): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (3044-3052): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (3058-3066): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (3072-3080): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (3086-3094): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (3100-3108): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (3114-3122): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (3128-3136): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (3142-3150): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (3156-3164): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (3170-3178): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (3184-3192): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (3198-3206): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (3212-3220): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (3226-3234): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (3240-3248): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (3254-3262): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (3268-3276): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (3282-3290): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (3296-3304): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (3310-3318): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (3324-3332): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (3338-3346): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (3352-3360): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (3366-3374): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (3380-3388): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (3394-3402): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (3408-3416): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (3422-3430): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (3436-3444): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (3450-3458): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (3464-3472): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (3478-3486): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (3492-3500): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (3506-3514): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (3520-3528): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (3534-3542): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (3548-3556): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (3562-3570): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (3576-3584): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (3590-3598): "continue" has to be in a "for" or "while" loop. -// SyntaxError: (3604-3612): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (41-49): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (55-63): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (69-77): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (83-91): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (97-105): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (111-119): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (125-133): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (139-147): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (153-161): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (167-175): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (181-189): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (195-203): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (209-217): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (223-231): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (237-245): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (251-259): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (265-273): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (279-287): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (293-301): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (307-315): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (321-329): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (335-343): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (349-357): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (363-371): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (377-385): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (391-399): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (405-413): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (419-427): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (433-441): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (447-455): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (461-469): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (475-483): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (489-497): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (503-511): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (517-525): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (531-539): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (545-553): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (559-567): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (573-581): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (587-595): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (601-609): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (615-623): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (629-637): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (643-651): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (657-665): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (671-679): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (685-693): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (699-707): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (713-721): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (727-735): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (741-749): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (755-763): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (769-777): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (783-791): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (797-805): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (811-819): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (825-833): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (839-847): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (853-861): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (867-875): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (881-889): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (895-903): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (909-917): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (923-931): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (937-945): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (951-959): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (965-973): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (979-987): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (993-1001): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (1007-1015): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (1021-1029): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (1035-1043): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (1049-1057): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (1063-1071): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (1077-1085): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (1091-1099): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (1105-1113): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (1119-1127): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (1133-1141): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (1147-1155): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (1161-1169): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (1175-1183): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (1189-1197): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (1203-1211): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (1217-1225): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (1231-1239): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (1245-1253): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (1259-1267): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (1273-1281): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (1287-1295): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (1301-1309): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (1315-1323): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (1329-1337): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (1343-1351): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (1357-1365): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (1371-1379): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (1385-1393): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (1399-1407): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (1413-1421): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (1427-1435): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (1441-1449): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (1455-1463): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (1469-1477): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (1483-1491): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (1497-1505): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (1511-1519): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (1525-1533): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (1539-1547): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (1553-1561): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (1567-1575): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (1581-1589): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (1595-1603): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (1609-1617): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (1623-1631): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (1637-1645): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (1651-1659): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (1665-1673): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (1679-1687): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (1693-1701): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (1707-1715): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (1721-1729): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (1735-1743): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (1749-1757): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (1763-1771): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (1777-1785): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (1791-1799): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (1805-1813): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (1819-1827): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (1833-1841): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (1847-1855): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (1861-1869): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (1875-1883): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (1889-1897): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (1903-1911): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (1917-1925): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (1931-1939): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (1945-1953): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (1959-1967): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (1973-1981): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (1987-1995): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (2001-2009): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (2015-2023): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (2029-2037): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (2043-2051): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (2057-2065): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (2071-2079): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (2085-2093): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (2099-2107): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (2113-2121): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (2127-2135): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (2141-2149): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (2155-2163): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (2169-2177): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (2183-2191): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (2197-2205): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (2211-2219): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (2225-2233): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (2239-2247): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (2253-2261): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (2267-2275): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (2281-2289): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (2295-2303): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (2309-2317): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (2323-2331): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (2337-2345): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (2351-2359): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (2365-2373): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (2379-2387): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (2393-2401): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (2407-2415): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (2421-2429): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (2435-2443): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (2449-2457): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (2463-2471): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (2477-2485): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (2491-2499): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (2505-2513): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (2519-2527): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (2533-2541): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (2547-2555): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (2561-2569): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (2575-2583): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (2589-2597): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (2603-2611): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (2617-2625): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (2631-2639): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (2645-2653): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (2659-2667): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (2673-2681): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (2687-2695): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (2701-2709): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (2715-2723): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (2729-2737): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (2743-2751): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (2757-2765): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (2771-2779): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (2785-2793): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (2799-2807): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (2813-2821): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (2827-2835): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (2841-2849): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (2855-2863): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (2869-2877): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (2883-2891): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (2897-2905): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (2911-2919): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (2925-2933): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (2939-2947): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (2953-2961): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (2967-2975): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (2981-2989): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (2995-3003): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (3009-3017): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (3023-3031): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (3037-3045): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (3051-3059): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (3065-3073): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (3079-3087): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (3093-3101): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (3107-3115): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (3121-3129): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (3135-3143): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (3149-3157): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (3163-3171): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (3177-3185): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (3191-3199): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (3205-3213): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (3219-3227): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (3233-3241): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (3247-3255): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (3261-3269): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (3275-3283): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (3289-3297): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (3303-3311): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (3317-3325): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (3331-3339): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (3345-3353): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (3359-3367): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (3373-3381): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (3387-3395): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (3401-3409): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (3415-3423): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (3429-3437): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (3443-3451): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (3457-3465): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (3471-3479): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (3485-3493): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (3499-3507): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (3513-3521): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (3527-3535): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (3541-3549): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (3555-3563): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (3569-3577): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (3583-3591): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (3597-3605): "continue" has to be in a "for" or "while" loop. +// SyntaxError: (3611-3619): "continue" has to be in a "for" or "while" loop. // Warning: There are more than 256 errors. Aborting. diff --git a/test/libsolidity/syntaxTests/multiVariableDeclaration/differentNumberOfComponents.sol b/test/libsolidity/syntaxTests/multiVariableDeclaration/differentNumberOfComponents.sol new file mode 100644 index 00000000..3b05a54c --- /dev/null +++ b/test/libsolidity/syntaxTests/multiVariableDeclaration/differentNumberOfComponents.sol @@ -0,0 +1,25 @@ +contract C { + function f() public { + uint a = (1,2); + uint b = (1,2,3); + uint c = (1,2,3,4); + } + function g() public { + (uint a1, uint b1, uint c1, uint d1) = 1; + (uint a2, uint b2, uint c2) = 1; + (uint a3, uint b3) = 1; + } + function h() public { + (uint a1, uint b1, uint c1, uint d1) = (1,2,3); + (uint a2, uint b2, uint c2) = (1,2,3,4); + } +} +// ---- +// TypeError: (47-61): Different number of components on the left hand side (1) than on the right hand side (2). +// TypeError: (71-87): Different number of components on the left hand side (1) than on the right hand side (3). +// TypeError: (97-115): Different number of components on the left hand side (1) than on the right hand side (4). +// TypeError: (157-197): Different number of components on the left hand side (4) than on the right hand side (1). +// TypeError: (207-238): Different number of components on the left hand side (3) than on the right hand side (1). +// TypeError: (248-270): Different number of components on the left hand side (2) than on the right hand side (1). +// TypeError: (312-358): Different number of components on the left hand side (4) than on the right hand side (3). +// TypeError: (368-407): Different number of components on the left hand side (3) than on the right hand side (4). diff --git a/test/libsolidity/syntaxTests/multiVariableDeclaration/differentNumberOfComponentsFromReturn.sol b/test/libsolidity/syntaxTests/multiVariableDeclaration/differentNumberOfComponentsFromReturn.sol new file mode 100644 index 00000000..7b556350 --- /dev/null +++ b/test/libsolidity/syntaxTests/multiVariableDeclaration/differentNumberOfComponentsFromReturn.sol @@ -0,0 +1,29 @@ +contract C { + function f() public { + uint a = two(); + uint b = three(); + uint c = four(); + } + function g() public { + (uint a1, uint b1, uint c1, uint d1) = one(); + (uint a2, uint b2, uint c2) = one(); + (uint a3, uint b3) = one(); + } + function h() public { + (uint a1, uint b1, uint c1, uint d1) = three(); + (uint a2, uint b2, uint c2) = four(); + } + function one() public pure returns (uint); + function two() public pure returns (uint, uint); + function three() public pure returns (uint, uint, uint); + function four() public pure returns (uint, uint, uint, uint); +} +// ---- +// TypeError: (47-61): Different number of components on the left hand side (1) than on the right hand side (2). +// TypeError: (71-87): Different number of components on the left hand side (1) than on the right hand side (3). +// TypeError: (97-112): Different number of components on the left hand side (1) than on the right hand side (4). +// TypeError: (154-198): Different number of components on the left hand side (4) than on the right hand side (1). +// TypeError: (208-243): Different number of components on the left hand side (3) than on the right hand side (1). +// TypeError: (253-279): Different number of components on the left hand side (2) than on the right hand side (1). +// TypeError: (321-367): Different number of components on the left hand side (4) than on the right hand side (3). +// TypeError: (377-413): Different number of components on the left hand side (3) than on the right hand side (4). diff --git a/test/libsolidity/syntaxTests/multiVariableDeclaration/disallowWildcards.sol b/test/libsolidity/syntaxTests/multiVariableDeclaration/disallowWildcards.sol new file mode 100644 index 00000000..b500823d --- /dev/null +++ b/test/libsolidity/syntaxTests/multiVariableDeclaration/disallowWildcards.sol @@ -0,0 +1,24 @@ +contract C { + function fn() public pure { + (uint a,) = (1,2,3); + (,uint b) = (1,2,3); + (,uint c,) = (1,2,3,4,5); + (uint d, uint e,) = (1,2,3,4); + (,uint f, uint g) = (1,2,3,4); + (,uint h, uint i,) = (1,2,3); + (uint j,) = 1; + (,uint k) = 1; + (,uint l,) = 1; + a;b;c;d;e;f;g;h;i;j;k;l; + } +} +// ---- +// TypeError: (53-72): Different number of components on the left hand side (2) than on the right hand side (3). +// TypeError: (82-101): Different number of components on the left hand side (2) than on the right hand side (3). +// TypeError: (111-135): Different number of components on the left hand side (3) than on the right hand side (5). +// TypeError: (145-174): Different number of components on the left hand side (3) than on the right hand side (4). +// TypeError: (184-213): Different number of components on the left hand side (3) than on the right hand side (4). +// TypeError: (223-251): Different number of components on the left hand side (4) than on the right hand side (3). +// TypeError: (261-274): Different number of components on the left hand side (2) than on the right hand side (1). +// TypeError: (284-297): Different number of components on the left hand side (2) than on the right hand side (1). +// TypeError: (307-321): Different number of components on the left hand side (3) than on the right hand side (1). diff --git a/test/libsolidity/syntaxTests/multiVariableDeclaration/disallowWildcardsFromReturn.sol b/test/libsolidity/syntaxTests/multiVariableDeclaration/disallowWildcardsFromReturn.sol new file mode 100644 index 00000000..3224a182 --- /dev/null +++ b/test/libsolidity/syntaxTests/multiVariableDeclaration/disallowWildcardsFromReturn.sol @@ -0,0 +1,31 @@ +contract C { + function fn() public pure { + (uint a,) = three(); + (,uint b) = three(); + (,uint c,) = five(); + (uint d, uint e,) = four(); + (,uint f, uint g) = four(); + (,uint h, uint i,) = three(); + (uint j,) = one(); + (,uint k) = one(); + (,uint l,) = one(); + (,uint m, uint n,) = five(); + a;b;c;d;e;f;g;h;i;j;k;l;m;n; + } + function one() public pure returns (uint); + function two() public pure returns (uint, uint); + function three() public pure returns (uint, uint, uint); + function four() public pure returns (uint, uint, uint, uint); + function five() public pure returns (uint, uint, uint, uint, uint); +} +// ---- +// TypeError: (53-72): Different number of components on the left hand side (2) than on the right hand side (3). +// TypeError: (82-101): Different number of components on the left hand side (2) than on the right hand side (3). +// TypeError: (111-130): Different number of components on the left hand side (3) than on the right hand side (5). +// TypeError: (140-166): Different number of components on the left hand side (3) than on the right hand side (4). +// TypeError: (176-202): Different number of components on the left hand side (3) than on the right hand side (4). +// TypeError: (212-240): Different number of components on the left hand side (4) than on the right hand side (3). +// TypeError: (250-267): Different number of components on the left hand side (2) than on the right hand side (1). +// TypeError: (277-294): Different number of components on the left hand side (2) than on the right hand side (1). +// TypeError: (304-322): Different number of components on the left hand side (3) than on the right hand side (1). +// TypeError: (332-359): Different number of components on the left hand side (4) than on the right hand side (5). diff --git a/test/libsolidity/syntaxTests/multiVariableDeclaration/multiVariableDeclarationComplex.sol b/test/libsolidity/syntaxTests/multiVariableDeclaration/multiVariableDeclarationComplex.sol index a3ce6a74..ba6e9916 100644 --- a/test/libsolidity/syntaxTests/multiVariableDeclaration/multiVariableDeclarationComplex.sol +++ b/test/libsolidity/syntaxTests/multiVariableDeclaration/multiVariableDeclarationComplex.sol @@ -2,10 +2,10 @@ contract D { struct S { uint a; uint b; } } contract C { - function f() internal returns (uint, uint, uint, D.S[20] storage, uint) { - (,,,D.S[10*2] storage x,) = f(); + function f() internal pure { + (,,,D.S[10*2] storage x,) = g(); x; } -} + function g() internal pure returns (uint, uint, uint, D.S[20] storage x, uint) { x = x; } +} // ---- -// Warning: (110-117): This variable is of storage pointer type and might be returned without assignment. This can cause storage corruption. Assign the variable (potentially from itself) to remove this warning. diff --git a/test/libsolidity/syntaxTests/multiVariableDeclaration/multiVariableDeclarationEmpty.sol b/test/libsolidity/syntaxTests/multiVariableDeclaration/multiVariableDeclarationEmpty.sol new file mode 100644 index 00000000..9618958e --- /dev/null +++ b/test/libsolidity/syntaxTests/multiVariableDeclaration/multiVariableDeclarationEmpty.sol @@ -0,0 +1,11 @@ +contract C { + function f() public pure { + (uint a, uint b) = f(); + (uint c) = f(); + uint d = f(); + } +} +// ---- +// TypeError: (52-74): Different number of components on the left hand side (2) than on the right hand side (0). +// TypeError: (84-98): Different number of components on the left hand side (1) than on the right hand side (0). +// TypeError: (108-120): Different number of components on the left hand side (1) than on the right hand side (0). diff --git a/test/libsolidity/syntaxTests/multiVariableDeclaration/multiVariableDeclarationSimple.sol b/test/libsolidity/syntaxTests/multiVariableDeclaration/multiVariableDeclarationSimple.sol index 8e06322c..a2fcce18 100644 --- a/test/libsolidity/syntaxTests/multiVariableDeclaration/multiVariableDeclarationSimple.sol +++ b/test/libsolidity/syntaxTests/multiVariableDeclaration/multiVariableDeclarationSimple.sol @@ -1,12 +1,12 @@ contract C { - function f() internal returns (uint, uint, uint, uint) { + function f() internal pure returns (uint, uint, uint, uint) { (uint a, uint b,,) = f(); a; b; } - function g() internal returns (bytes memory, string storage) { - (bytes memory a, string storage b) = g(); + function g() internal pure { + (bytes memory a, string storage b) = h(); a; b; } -} + function h() internal pure returns (bytes memory, string storage s) { s = s; } +} // ---- -// Warning: (163-169): This variable is of storage pointer type and might be returned without assignment. This can cause storage corruption. Assign the variable (potentially from itself) to remove this warning. diff --git a/test/libsolidity/syntaxTests/multiVariableDeclaration/oneElementTuple.sol b/test/libsolidity/syntaxTests/multiVariableDeclaration/oneElementTuple.sol new file mode 100644 index 00000000..562c7c0b --- /dev/null +++ b/test/libsolidity/syntaxTests/multiVariableDeclaration/oneElementTuple.sol @@ -0,0 +1,8 @@ +contract C { + function f() public { + (uint a,) = (1,); + a; + } +} +// ---- +// TypeError: (59-63): Tuple component cannot be empty. diff --git a/test/libsolidity/syntaxTests/multiVariableDeclaration/sameNumberOfComponents.sol b/test/libsolidity/syntaxTests/multiVariableDeclaration/sameNumberOfComponents.sol new file mode 100644 index 00000000..59eb34af --- /dev/null +++ b/test/libsolidity/syntaxTests/multiVariableDeclaration/sameNumberOfComponents.sol @@ -0,0 +1,9 @@ +contract C { + function f() public pure { + (uint a1, uint b1, uint c1, uint d1) = (1,2,3,4); + (uint a2, uint b2, uint c2) = (1,2,3); + (uint a3, uint b3) = (1,2); + a1; b1; c1; d1; a2; b2; c2; a3; b3; + } +} +// ---- diff --git a/test/libsolidity/syntaxTests/nameAndTypeResolution/029_create_abstract_contract.sol b/test/libsolidity/syntaxTests/nameAndTypeResolution/029_create_abstract_contract.sol index 3a2bf56d..455f4189 100644 --- a/test/libsolidity/syntaxTests/nameAndTypeResolution/029_create_abstract_contract.sol +++ b/test/libsolidity/syntaxTests/nameAndTypeResolution/029_create_abstract_contract.sol @@ -1,7 +1,7 @@ -contract base { function foo(); } +contract base { function foo() public; } contract derived { base b; function foo() public { b = new base(); } } // ---- -// TypeError: (97-105): Trying to create an instance of an abstract contract. +// TypeError: (104-112): Trying to create an instance of an abstract contract. diff --git a/test/libsolidity/syntaxTests/nameAndTypeResolution/030_redeclare_implemented_abstract_function_as_abstract.sol b/test/libsolidity/syntaxTests/nameAndTypeResolution/030_redeclare_implemented_abstract_function_as_abstract.sol index 05bc4bc7..55bdea89 100644 --- a/test/libsolidity/syntaxTests/nameAndTypeResolution/030_redeclare_implemented_abstract_function_as_abstract.sol +++ b/test/libsolidity/syntaxTests/nameAndTypeResolution/030_redeclare_implemented_abstract_function_as_abstract.sol @@ -1,5 +1,5 @@ -contract base { function foo(); } +contract base { function foo() public; } contract derived is base { function foo() public {} } -contract wrong is derived { function foo(); } +contract wrong is derived { function foo() public; } // ---- -// TypeError: (116-131): Redeclaring an already implemented function as abstract +// TypeError: (123-145): Redeclaring an already implemented function as abstract diff --git a/test/libsolidity/syntaxTests/nameAndTypeResolution/039_functions_with_identical_structs_in_interface.sol b/test/libsolidity/syntaxTests/nameAndTypeResolution/039_functions_with_identical_structs_in_interface.sol index 0be0bb2b..3389ffe4 100644 --- a/test/libsolidity/syntaxTests/nameAndTypeResolution/039_functions_with_identical_structs_in_interface.sol +++ b/test/libsolidity/syntaxTests/nameAndTypeResolution/039_functions_with_identical_structs_in_interface.sol @@ -3,9 +3,9 @@ pragma experimental ABIEncoderV2; contract C { struct S1 { int i; } struct S2 { int i; } - function f(S1) pure {} - function f(S2) pure {} + function f(S1 memory) public pure {} + function f(S2 memory) public pure {} } // ---- // Warning: (0-33): Experimental features are turned on. Do not use experimental features on live deployments. -// TypeError: (129-151): Function overload clash during conversion to external types for arguments. +// TypeError: (143-179): Function overload clash during conversion to external types for arguments. diff --git a/test/libsolidity/syntaxTests/nameAndTypeResolution/040_functions_with_different_structs_in_interface.sol b/test/libsolidity/syntaxTests/nameAndTypeResolution/040_functions_with_different_structs_in_interface.sol index 1689e6f5..6ff8fd6e 100644 --- a/test/libsolidity/syntaxTests/nameAndTypeResolution/040_functions_with_different_structs_in_interface.sol +++ b/test/libsolidity/syntaxTests/nameAndTypeResolution/040_functions_with_different_structs_in_interface.sol @@ -3,8 +3,8 @@ pragma experimental ABIEncoderV2; contract C { struct S1 { function() external a; } struct S2 { bytes24 a; } - function f(S1) public pure {} - function f(S2) public pure {} + function f(S1 memory) public pure {} + function f(S2 memory) public pure {} } // ---- -// Warning: (0-33): Experimental features are turned on. Do not use experimental features on live deployments. +// Warning: (0-33): Experimental features are turned on. Do not use experimental features on live deployments.
\ No newline at end of file diff --git a/test/libsolidity/syntaxTests/nameAndTypeResolution/041_functions_with_stucts_of_non_external_types_in_interface.sol b/test/libsolidity/syntaxTests/nameAndTypeResolution/041_functions_with_stucts_of_non_external_types_in_interface.sol index f9937fb9..9fd09dd7 100644 --- a/test/libsolidity/syntaxTests/nameAndTypeResolution/041_functions_with_stucts_of_non_external_types_in_interface.sol +++ b/test/libsolidity/syntaxTests/nameAndTypeResolution/041_functions_with_stucts_of_non_external_types_in_interface.sol @@ -2,7 +2,7 @@ pragma experimental ABIEncoderV2; contract C { struct S { function() internal a; } - function f(S) {} + function f(S memory) public {} } // ---- // Warning: (0-33): Experimental features are turned on. Do not use experimental features on live deployments. diff --git a/test/libsolidity/syntaxTests/nameAndTypeResolution/042_functions_with_stucts_of_non_external_types_in_interface_2.sol b/test/libsolidity/syntaxTests/nameAndTypeResolution/042_functions_with_stucts_of_non_external_types_in_interface_2.sol index d9c3bfc4..435a02ef 100644 --- a/test/libsolidity/syntaxTests/nameAndTypeResolution/042_functions_with_stucts_of_non_external_types_in_interface_2.sol +++ b/test/libsolidity/syntaxTests/nameAndTypeResolution/042_functions_with_stucts_of_non_external_types_in_interface_2.sol @@ -2,7 +2,7 @@ pragma experimental ABIEncoderV2; contract C { struct S { mapping(uint => uint) a; } - function f(S) {} + function f(S memory) public {} } // ---- // Warning: (0-33): Experimental features are turned on. Do not use experimental features on live deployments. diff --git a/test/libsolidity/syntaxTests/nameAndTypeResolution/043_functions_with_stucts_of_non_external_types_in_interface_nested.sol b/test/libsolidity/syntaxTests/nameAndTypeResolution/043_functions_with_stucts_of_non_external_types_in_interface_nested.sol index f223cf53..b9dc7c2e 100644 --- a/test/libsolidity/syntaxTests/nameAndTypeResolution/043_functions_with_stucts_of_non_external_types_in_interface_nested.sol +++ b/test/libsolidity/syntaxTests/nameAndTypeResolution/043_functions_with_stucts_of_non_external_types_in_interface_nested.sol @@ -3,7 +3,7 @@ pragma experimental ABIEncoderV2; contract C { struct T { mapping(uint => uint) a; } struct S { T[][2] b; } - function f(S) {} + function f(S memory) public {} } // ---- // Warning: (0-33): Experimental features are turned on. Do not use experimental features on live deployments. diff --git a/test/libsolidity/syntaxTests/nameAndTypeResolution/044_returning_multi_dimensional_arrays_new_abi.sol b/test/libsolidity/syntaxTests/nameAndTypeResolution/044_returning_multi_dimensional_arrays_new_abi.sol index e54e27e9..ae9416e5 100644 --- a/test/libsolidity/syntaxTests/nameAndTypeResolution/044_returning_multi_dimensional_arrays_new_abi.sol +++ b/test/libsolidity/syntaxTests/nameAndTypeResolution/044_returning_multi_dimensional_arrays_new_abi.sol @@ -1,7 +1,7 @@ pragma experimental ABIEncoderV2; contract C { - function f() public pure returns (string[][]) {} + function f() public pure returns (string[][] memory) {} } // ---- // Warning: (0-33): Experimental features are turned on. Do not use experimental features on live deployments. diff --git a/test/libsolidity/syntaxTests/nameAndTypeResolution/045_returning_multi_dimensional_arrays.sol b/test/libsolidity/syntaxTests/nameAndTypeResolution/045_returning_multi_dimensional_arrays.sol index daa67836..221e5fa4 100644 --- a/test/libsolidity/syntaxTests/nameAndTypeResolution/045_returning_multi_dimensional_arrays.sol +++ b/test/libsolidity/syntaxTests/nameAndTypeResolution/045_returning_multi_dimensional_arrays.sol @@ -1,5 +1,5 @@ contract C { - function f() public pure returns (string[][]) {} + function f() public pure returns (string[][] memory) {} } // ---- // TypeError: (51-61): This type is only supported in the new experimental ABI encoder. Use "pragma experimental ABIEncoderV2;" to enable the feature. diff --git a/test/libsolidity/syntaxTests/nameAndTypeResolution/046_returning_multi_dimensional_static_arrays.sol b/test/libsolidity/syntaxTests/nameAndTypeResolution/046_returning_multi_dimensional_static_arrays.sol index 26af7436..75423bc9 100644 --- a/test/libsolidity/syntaxTests/nameAndTypeResolution/046_returning_multi_dimensional_static_arrays.sol +++ b/test/libsolidity/syntaxTests/nameAndTypeResolution/046_returning_multi_dimensional_static_arrays.sol @@ -1,5 +1,5 @@ contract C { - function f() public pure returns (uint[][2]) {} + function f() public pure returns (uint[][2] memory) {} } // ---- // TypeError: (51-60): This type is only supported in the new experimental ABI encoder. Use "pragma experimental ABIEncoderV2;" to enable the feature. diff --git a/test/libsolidity/syntaxTests/nameAndTypeResolution/047_returning_arrays_in_structs_new_abi.sol b/test/libsolidity/syntaxTests/nameAndTypeResolution/047_returning_arrays_in_structs_new_abi.sol index 81628a12..8ca3a53d 100644 --- a/test/libsolidity/syntaxTests/nameAndTypeResolution/047_returning_arrays_in_structs_new_abi.sol +++ b/test/libsolidity/syntaxTests/nameAndTypeResolution/047_returning_arrays_in_structs_new_abi.sol @@ -2,7 +2,7 @@ pragma experimental ABIEncoderV2; contract C { struct S { string[] s; } - function f() public pure returns (S) {} + function f() public pure returns (S memory) {} } // ---- // Warning: (0-33): Experimental features are turned on. Do not use experimental features on live deployments. diff --git a/test/libsolidity/syntaxTests/nameAndTypeResolution/048_returning_arrays_in_structs_arrays.sol b/test/libsolidity/syntaxTests/nameAndTypeResolution/048_returning_arrays_in_structs_arrays.sol index 2f1e5a15..48e80fcf 100644 --- a/test/libsolidity/syntaxTests/nameAndTypeResolution/048_returning_arrays_in_structs_arrays.sol +++ b/test/libsolidity/syntaxTests/nameAndTypeResolution/048_returning_arrays_in_structs_arrays.sol @@ -1,6 +1,6 @@ contract C { struct S { string[] s; } - function f() public pure returns (S x) {} + function f() public pure returns (S memory x) {} } // ---- -// TypeError: (80-83): This type is only supported in the new experimental ABI encoder. Use "pragma experimental ABIEncoderV2;" to enable the feature. +// TypeError: (80-90): This type is only supported in the new experimental ABI encoder. Use "pragma experimental ABIEncoderV2;" to enable the feature. diff --git a/test/libsolidity/syntaxTests/nameAndTypeResolution/065_super_excludes_current_contract.sol b/test/libsolidity/syntaxTests/nameAndTypeResolution/065_super_excludes_current_contract.sol index 6fa92a6a..544df1a5 100644 --- a/test/libsolidity/syntaxTests/nameAndTypeResolution/065_super_excludes_current_contract.sol +++ b/test/libsolidity/syntaxTests/nameAndTypeResolution/065_super_excludes_current_contract.sol @@ -8,4 +8,4 @@ contract B is A { } } // ---- -// TypeError: (95-102): Member "f" not found or not visible after argument-dependent lookup in contract super B +// TypeError: (95-102): Member "f" not found or not visible after argument-dependent lookup in contract super B. diff --git a/test/libsolidity/syntaxTests/nameAndTypeResolution/072_state_variable_member_of_wrong_class1.sol b/test/libsolidity/syntaxTests/nameAndTypeResolution/072_state_variable_member_of_wrong_class1.sol index 949761b6..dd73ac47 100644 --- a/test/libsolidity/syntaxTests/nameAndTypeResolution/072_state_variable_member_of_wrong_class1.sol +++ b/test/libsolidity/syntaxTests/nameAndTypeResolution/072_state_variable_member_of_wrong_class1.sol @@ -8,4 +8,4 @@ contract Child is Parent2 { function foo() public returns (uint256) { return Parent2.m_aMember1; } } // ---- -// TypeError: (200-218): Member "m_aMember1" not found or not visible after argument-dependent lookup in type(contract Parent2) +// TypeError: (200-218): Member "m_aMember1" not found or not visible after argument-dependent lookup in type(contract Parent2). diff --git a/test/libsolidity/syntaxTests/nameAndTypeResolution/073_state_variable_member_of_wrong_class2.sol b/test/libsolidity/syntaxTests/nameAndTypeResolution/073_state_variable_member_of_wrong_class2.sol index 9a0ee8a3..f2de6e72 100644 --- a/test/libsolidity/syntaxTests/nameAndTypeResolution/073_state_variable_member_of_wrong_class2.sol +++ b/test/libsolidity/syntaxTests/nameAndTypeResolution/073_state_variable_member_of_wrong_class2.sol @@ -9,4 +9,4 @@ contract Child is Parent2 { uint256 public m_aMember3; } // ---- -// TypeError: (200-216): Member "m_aMember2" not found or not visible after argument-dependent lookup in type(contract Child) +// TypeError: (200-216): Member "m_aMember2" not found or not visible after argument-dependent lookup in type(contract Child). diff --git a/test/libsolidity/syntaxTests/nameAndTypeResolution/097_access_to_internal_function.sol b/test/libsolidity/syntaxTests/nameAndTypeResolution/097_access_to_internal_function.sol index e13e1531..60d7b758 100644 --- a/test/libsolidity/syntaxTests/nameAndTypeResolution/097_access_to_internal_function.sol +++ b/test/libsolidity/syntaxTests/nameAndTypeResolution/097_access_to_internal_function.sol @@ -5,4 +5,4 @@ contract d { function g() public { c(0).f(); } } // ---- -// TypeError: (83-89): Member "f" not found or not visible after argument-dependent lookup in contract c +// TypeError: (83-89): Member "f" not found or not visible after argument-dependent lookup in contract c. diff --git a/test/libsolidity/syntaxTests/nameAndTypeResolution/098_access_to_default_state_variable_visibility.sol b/test/libsolidity/syntaxTests/nameAndTypeResolution/098_access_to_default_state_variable_visibility.sol index ab7546c6..8c9d0c0f 100644 --- a/test/libsolidity/syntaxTests/nameAndTypeResolution/098_access_to_default_state_variable_visibility.sol +++ b/test/libsolidity/syntaxTests/nameAndTypeResolution/098_access_to_default_state_variable_visibility.sol @@ -5,4 +5,4 @@ contract d { function g() public { c(0).a(); } } // ---- -// TypeError: (66-72): Member "a" not found or not visible after argument-dependent lookup in contract c +// TypeError: (66-72): Member "a" not found or not visible after argument-dependent lookup in contract c. diff --git a/test/libsolidity/syntaxTests/nameAndTypeResolution/105_constant_input_parameter.sol b/test/libsolidity/syntaxTests/nameAndTypeResolution/105_constant_input_parameter.sol index 636d325f..df47aa6b 100644 --- a/test/libsolidity/syntaxTests/nameAndTypeResolution/105_constant_input_parameter.sol +++ b/test/libsolidity/syntaxTests/nameAndTypeResolution/105_constant_input_parameter.sol @@ -1,7 +1,7 @@ contract test { - function f(uint[] constant a) public { } + function f(uint[] memory constant a) public { } } // ---- -// TypeError: (31-48): Illegal use of "constant" specifier. -// TypeError: (31-48): Constants of non-value type not yet implemented. -// TypeError: (31-48): Uninitialized "constant" variable. +// TypeError: (31-55): Illegal use of "constant" specifier. +// TypeError: (31-55): Constants of non-value type not yet implemented. +// TypeError: (31-55): Uninitialized "constant" variable. diff --git a/test/libsolidity/syntaxTests/nameAndTypeResolution/126_enum_invalid_member_access.sol b/test/libsolidity/syntaxTests/nameAndTypeResolution/126_enum_invalid_member_access.sol index 079bf0c8..e58ed160 100644 --- a/test/libsolidity/syntaxTests/nameAndTypeResolution/126_enum_invalid_member_access.sol +++ b/test/libsolidity/syntaxTests/nameAndTypeResolution/126_enum_invalid_member_access.sol @@ -6,4 +6,4 @@ contract test { ActionChoices choices; } // ---- -// TypeError: (121-159): Member "RunAroundWavingYourHands" not found or not visible after argument-dependent lookup in type(enum test.ActionChoices) +// TypeError: (121-159): Member "RunAroundWavingYourHands" not found or not visible after argument-dependent lookup in type(enum test.ActionChoices). diff --git a/test/libsolidity/syntaxTests/nameAndTypeResolution/136_private_visibility_via_explicit_base_access.sol b/test/libsolidity/syntaxTests/nameAndTypeResolution/136_private_visibility_via_explicit_base_access.sol index fc89c033..2f94ef92 100644 --- a/test/libsolidity/syntaxTests/nameAndTypeResolution/136_private_visibility_via_explicit_base_access.sol +++ b/test/libsolidity/syntaxTests/nameAndTypeResolution/136_private_visibility_via_explicit_base_access.sol @@ -5,4 +5,4 @@ contract derived is base { function g() public { base.f(); } } // ---- -// TypeError: (99-105): Member "f" not found or not visible after argument-dependent lookup in type(contract base) +// TypeError: (99-105): Member "f" not found or not visible after argument-dependent lookup in type(contract base). diff --git a/test/libsolidity/syntaxTests/nameAndTypeResolution/138_similar_name_suggestions_expected.sol b/test/libsolidity/syntaxTests/nameAndTypeResolution/138_similar_name_suggestions_expected.sol index 8f11f003..ef6e933a 100644 --- a/test/libsolidity/syntaxTests/nameAndTypeResolution/138_similar_name_suggestions_expected.sol +++ b/test/libsolidity/syntaxTests/nameAndTypeResolution/138_similar_name_suggestions_expected.sol @@ -1,6 +1,6 @@ contract c { - function func() {} + function func() public {} function g() public { fun(); } } // ---- -// DeclarationError: (62-65): Undeclared identifier. Did you mean "func"? +// DeclarationError: (69-72): Undeclared identifier. Did you mean "func"? diff --git a/test/libsolidity/syntaxTests/nameAndTypeResolution/145_external_base_visibility.sol b/test/libsolidity/syntaxTests/nameAndTypeResolution/145_external_base_visibility.sol index 2d1baa20..cf680462 100644 --- a/test/libsolidity/syntaxTests/nameAndTypeResolution/145_external_base_visibility.sol +++ b/test/libsolidity/syntaxTests/nameAndTypeResolution/145_external_base_visibility.sol @@ -5,4 +5,4 @@ contract derived is base { function g() public { base.f(); } } // ---- -// TypeError: (100-106): Member "f" not found or not visible after argument-dependent lookup in type(contract base) +// TypeError: (100-106): Member "f" not found or not visible after argument-dependent lookup in type(contract base). diff --git a/test/libsolidity/syntaxTests/nameAndTypeResolution/189_string_length.sol b/test/libsolidity/syntaxTests/nameAndTypeResolution/189_string_length.sol index 9e714d68..845b9156 100644 --- a/test/libsolidity/syntaxTests/nameAndTypeResolution/189_string_length.sol +++ b/test/libsolidity/syntaxTests/nameAndTypeResolution/189_string_length.sol @@ -3,4 +3,4 @@ contract C { function f() public { uint a = s.length; } } // ---- -// TypeError: (62-70): Member "length" not found or not visible after argument-dependent lookup in string storage ref +// TypeError: (62-70): Member "length" not found or not visible after argument-dependent lookup in string storage ref. diff --git a/test/libsolidity/syntaxTests/nameAndTypeResolution/206_storage_location_local_variables.sol b/test/libsolidity/syntaxTests/nameAndTypeResolution/206_storage_location_local_variables.sol index 5199e5d7..868d7bc8 100644 --- a/test/libsolidity/syntaxTests/nameAndTypeResolution/206_storage_location_local_variables.sol +++ b/test/libsolidity/syntaxTests/nameAndTypeResolution/206_storage_location_local_variables.sol @@ -1,11 +1,9 @@ contract C { - function f() public { - uint[] storage x; + uint[] m_x; + function f() public view { + uint[] storage x = m_x; uint[] memory y; - uint[] memory z; - x;y;z; + x;y; } } // ---- -// Warning: (47-63): Uninitialized storage pointer. -// Warning: (17-135): Function state mutability can be restricted to pure diff --git a/test/libsolidity/syntaxTests/nameAndTypeResolution/208_assignment_mem_to_local_storage_variable.sol b/test/libsolidity/syntaxTests/nameAndTypeResolution/208_assignment_mem_to_local_storage_variable.sol index febe39e6..cf303772 100644 --- a/test/libsolidity/syntaxTests/nameAndTypeResolution/208_assignment_mem_to_local_storage_variable.sol +++ b/test/libsolidity/syntaxTests/nameAndTypeResolution/208_assignment_mem_to_local_storage_variable.sol @@ -1,9 +1,9 @@ contract C { uint[] data; - function f(uint[] x) public { + function f(uint[] memory x) public { uint[] storage dataRef = data; dataRef = x; } } // ---- -// TypeError: (121-122): Type uint256[] memory is not implicitly convertible to expected type uint256[] storage pointer. +// TypeError: (128-129): Type uint256[] memory is not implicitly convertible to expected type uint256[] storage pointer. diff --git a/test/libsolidity/syntaxTests/nameAndTypeResolution/211_uninitialized_mapping_array_variable.sol b/test/libsolidity/syntaxTests/nameAndTypeResolution/211_uninitialized_mapping_array_variable.sol index 80467491..edae7549 100644 --- a/test/libsolidity/syntaxTests/nameAndTypeResolution/211_uninitialized_mapping_array_variable.sol +++ b/test/libsolidity/syntaxTests/nameAndTypeResolution/211_uninitialized_mapping_array_variable.sol @@ -5,4 +5,4 @@ contract C { } } // ---- -// Warning: (52-85): Uninitialized storage pointer. +// DeclarationError: (52-85): Uninitialized storage pointer. diff --git a/test/libsolidity/syntaxTests/nameAndTypeResolution/212_uninitialized_mapping_array_variable_050.sol b/test/libsolidity/syntaxTests/nameAndTypeResolution/212_uninitialized_mapping_array_variable_050.sol deleted file mode 100644 index f2028690..00000000 --- a/test/libsolidity/syntaxTests/nameAndTypeResolution/212_uninitialized_mapping_array_variable_050.sol +++ /dev/null @@ -1,9 +0,0 @@ -pragma experimental "v0.5.0"; -contract C { - function f() pure public { - mapping(uint => uint)[] storage x; - x; - } -} -// ---- -// DeclarationError: (82-115): Uninitialized storage pointer. diff --git a/test/libsolidity/syntaxTests/nameAndTypeResolution/214_assignment_mem_storage_variable_directly.sol b/test/libsolidity/syntaxTests/nameAndTypeResolution/214_assignment_mem_storage_variable_directly.sol index 08737f2d..801eb275 100644 --- a/test/libsolidity/syntaxTests/nameAndTypeResolution/214_assignment_mem_storage_variable_directly.sol +++ b/test/libsolidity/syntaxTests/nameAndTypeResolution/214_assignment_mem_storage_variable_directly.sol @@ -1,6 +1,6 @@ contract C { uint[] data; - function f(uint[] x) public { + function f(uint[] memory x) public { data = x; } } diff --git a/test/libsolidity/syntaxTests/nameAndTypeResolution/215_function_argument_mem_to_storage.sol b/test/libsolidity/syntaxTests/nameAndTypeResolution/215_function_argument_mem_to_storage.sol index 4d75732a..984b81b1 100644 --- a/test/libsolidity/syntaxTests/nameAndTypeResolution/215_function_argument_mem_to_storage.sol +++ b/test/libsolidity/syntaxTests/nameAndTypeResolution/215_function_argument_mem_to_storage.sol @@ -1,9 +1,9 @@ contract C { function f(uint[] storage x) private { } - function g(uint[] x) public { + function g(uint[] memory x) public { f(x); } } // ---- -// TypeError: (106-107): Invalid type for argument in function call. Invalid implicit conversion from uint256[] memory to uint256[] storage pointer requested. +// TypeError: (113-114): Invalid type for argument in function call. Invalid implicit conversion from uint256[] memory to uint256[] storage pointer requested. diff --git a/test/libsolidity/syntaxTests/nameAndTypeResolution/216_function_argument_storage_to_mem.sol b/test/libsolidity/syntaxTests/nameAndTypeResolution/216_function_argument_storage_to_mem.sol index 157ef4dd..c5175a41 100644 --- a/test/libsolidity/syntaxTests/nameAndTypeResolution/216_function_argument_storage_to_mem.sol +++ b/test/libsolidity/syntaxTests/nameAndTypeResolution/216_function_argument_storage_to_mem.sol @@ -2,9 +2,9 @@ contract C { function f(uint[] storage x) private { g(x); } - function g(uint[] x) public { + function g(uint[] memory x) public { } } // ---- -// Warning: (91-99): Unused function parameter. Remove or comment out the variable name to silence this warning. -// Warning: (80-115): Function state mutability can be restricted to pure +// Warning: (91-106): Unused function parameter. Remove or comment out the variable name to silence this warning. +// Warning: (80-122): Function state mutability can be restricted to pure diff --git a/test/libsolidity/syntaxTests/nameAndTypeResolution/224_string_bytes_conversion.sol b/test/libsolidity/syntaxTests/nameAndTypeResolution/224_string_bytes_conversion.sol index 137aa893..7b953abb 100644 --- a/test/libsolidity/syntaxTests/nameAndTypeResolution/224_string_bytes_conversion.sol +++ b/test/libsolidity/syntaxTests/nameAndTypeResolution/224_string_bytes_conversion.sol @@ -2,16 +2,16 @@ contract Test { string s; bytes b; function h(string _s) external { bytes(_s).length; } - function i(string _s) internal { 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 _b) internal { string(_b); } + function l(bytes memory _b) internal { string(_b); } function m() internal { string(b); } } // ---- // Warning: (47-99): Function state mutability can be restricted to pure -// Warning: (104-156): Function state mutability can be restricted to pure -// Warning: (161-203): Function state mutability can be restricted to view -// Warning: (208-253): Function state mutability can be restricted to pure -// Warning: (258-303): Function state mutability can be restricted to pure -// Warning: (308-344): Function state mutability can be restricted to view +// 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/232_literal_string_to_storage_pointer.sol b/test/libsolidity/syntaxTests/nameAndTypeResolution/232_literal_string_to_storage_pointer.sol index a586dc80..be57144e 100644 --- a/test/libsolidity/syntaxTests/nameAndTypeResolution/232_literal_string_to_storage_pointer.sol +++ b/test/libsolidity/syntaxTests/nameAndTypeResolution/232_literal_string_to_storage_pointer.sol @@ -1,6 +1,5 @@ contract C { - function f() public { string x = "abc"; } + function f() public { string storage x = "abc"; } } // ---- -// Warning: (39-47): Variable is declared as a storage pointer. Use an explicit "storage" keyword to silence this warning. -// TypeError: (39-55): Type literal_string "abc" is not implicitly convertible to expected type string storage pointer. +// TypeError: (39-63): Type literal_string "abc" is not implicitly convertible to expected type string storage pointer. diff --git a/test/libsolidity/syntaxTests/nameAndTypeResolution/233_non_initialized_references.sol b/test/libsolidity/syntaxTests/nameAndTypeResolution/233_non_initialized_references.sol index 9d8d4834..a0b6f71e 100644 --- a/test/libsolidity/syntaxTests/nameAndTypeResolution/233_non_initialized_references.sol +++ b/test/libsolidity/syntaxTests/nameAndTypeResolution/233_non_initialized_references.sol @@ -8,4 +8,4 @@ contract C { } } // ---- -// Warning: (84-95): Uninitialized storage pointer. +// DeclarationError: (84-95): Uninitialized storage pointer. diff --git a/test/libsolidity/syntaxTests/nameAndTypeResolution/234_non_initialized_references_050.sol b/test/libsolidity/syntaxTests/nameAndTypeResolution/234_non_initialized_references_050.sol deleted file mode 100644 index c221b73c..00000000 --- a/test/libsolidity/syntaxTests/nameAndTypeResolution/234_non_initialized_references_050.sol +++ /dev/null @@ -1,11 +0,0 @@ -pragma experimental "v0.5.0"; -contract C { - struct s { - uint a; - } - function f() public { - s storage x; - } -} -// ---- -// DeclarationError: (114-125): Uninitialized storage pointer. diff --git a/test/libsolidity/syntaxTests/nameAndTypeResolution/239_multi_variable_declaration_wildcards_fine.sol b/test/libsolidity/syntaxTests/nameAndTypeResolution/239_multi_variable_declaration_wildcards_fine.sol deleted file mode 100644 index 0da5c7ee..00000000 --- a/test/libsolidity/syntaxTests/nameAndTypeResolution/239_multi_variable_declaration_wildcards_fine.sol +++ /dev/null @@ -1,19 +0,0 @@ -contract C { - function three() public returns (uint, uint, uint); - function two() public returns (uint, uint); - function none() public; - function f() public { - (uint a,) = three(); - (uint b, uint c,) = two(); - (,uint d) = three(); - (,uint e, uint g) = two(); - var (,,) = three(); - var () = none(); - a;b;c;d;e;g; - } -} -// ---- -// Warning: (179-198): Different number of components on the left hand side (2) than on the right hand side (3). -// Warning: (208-233): Different number of components on the left hand side (3) than on the right hand side (2). -// Warning: (243-262): Different number of components on the left hand side (2) than on the right hand side (3). -// Warning: (272-297): Different number of components on the left hand side (3) than on the right hand side (2). diff --git a/test/libsolidity/syntaxTests/nameAndTypeResolution/240_multi_variable_declaration_wildcards_fail_1.sol b/test/libsolidity/syntaxTests/nameAndTypeResolution/240_multi_variable_declaration_wildcards_fail_1.sol deleted file mode 100644 index 0ccbb327..00000000 --- a/test/libsolidity/syntaxTests/nameAndTypeResolution/240_multi_variable_declaration_wildcards_fail_1.sol +++ /dev/null @@ -1,7 +0,0 @@ -contract C { - function one() public returns (uint); - function f() public { (uint a, uint b, ) = one(); } -} -// ---- -// Warning: (81-107): Different number of components on the left hand side (3) than on the right hand side (1). -// TypeError: (81-107): Not enough components (1) in value to assign all variables (2). diff --git a/test/libsolidity/syntaxTests/nameAndTypeResolution/241_multi_variable_declaration_wildcards_fail_2.sol b/test/libsolidity/syntaxTests/nameAndTypeResolution/241_multi_variable_declaration_wildcards_fail_2.sol deleted file mode 100644 index 8d5de125..00000000 --- a/test/libsolidity/syntaxTests/nameAndTypeResolution/241_multi_variable_declaration_wildcards_fail_2.sol +++ /dev/null @@ -1,7 +0,0 @@ -contract C { - function one() public returns (uint); - function f() public { (uint a, , ) = one(); } -} -// ---- -// Warning: (81-101): Different number of components on the left hand side (3) than on the right hand side (1). -// TypeError: (81-101): Not enough components (1) in value to assign all variables (2). diff --git a/test/libsolidity/syntaxTests/nameAndTypeResolution/242_multi_variable_declaration_wildcards_fail_3.sol b/test/libsolidity/syntaxTests/nameAndTypeResolution/242_multi_variable_declaration_wildcards_fail_3.sol deleted file mode 100644 index 993df9b9..00000000 --- a/test/libsolidity/syntaxTests/nameAndTypeResolution/242_multi_variable_declaration_wildcards_fail_3.sol +++ /dev/null @@ -1,7 +0,0 @@ -contract C { - function one() public returns (uint); - function f() public { (, , uint a) = one(); } -} -// ---- -// Warning: (81-101): Different number of components on the left hand side (3) than on the right hand side (1). -// TypeError: (81-101): Not enough components (1) in value to assign all variables (2). diff --git a/test/libsolidity/syntaxTests/nameAndTypeResolution/243_multi_variable_declaration_wildcards_fail_4.sol b/test/libsolidity/syntaxTests/nameAndTypeResolution/243_multi_variable_declaration_wildcards_fail_4.sol deleted file mode 100644 index 0697b789..00000000 --- a/test/libsolidity/syntaxTests/nameAndTypeResolution/243_multi_variable_declaration_wildcards_fail_4.sol +++ /dev/null @@ -1,7 +0,0 @@ -contract C { - function one() public returns (uint); - function f() public { (, uint a, uint b) = one(); } -} -// ---- -// Warning: (81-107): Different number of components on the left hand side (3) than on the right hand side (1). -// TypeError: (81-107): Not enough components (1) in value to assign all variables (2). diff --git a/test/libsolidity/syntaxTests/nameAndTypeResolution/244_tuples.sol b/test/libsolidity/syntaxTests/nameAndTypeResolution/244_tuples.sol index 3112f67a..d18c115d 100644 --- a/test/libsolidity/syntaxTests/nameAndTypeResolution/244_tuples.sol +++ b/test/libsolidity/syntaxTests/nameAndTypeResolution/244_tuples.sol @@ -1,13 +1,10 @@ contract C { - function f() public { + function f() public pure { uint a = (1); - (uint b,) = (uint8(1),); + (uint b,) = (uint8(1),2); (uint c, uint d) = (uint32(1), 2 + a); - (uint e,) = (uint64(1), 2, b); + (uint e, ,) = (uint64(1), 2, b); a;b;c;d;e; } } // ---- -// Warning: (69-92): Different number of components on the left hand side (2) than on the right hand side (1). -// Warning: (149-178): Different number of components on the left hand side (2) than on the right hand side (3). -// Warning: (17-204): Function state mutability can be restricted to pure diff --git a/test/libsolidity/syntaxTests/nameAndTypeResolution/246_multi_variable_declaration_wildcards_fail_5.sol b/test/libsolidity/syntaxTests/nameAndTypeResolution/246_multi_variable_declaration_wildcards_fail_5.sol deleted file mode 100644 index 3d2d0705..00000000 --- a/test/libsolidity/syntaxTests/nameAndTypeResolution/246_multi_variable_declaration_wildcards_fail_5.sol +++ /dev/null @@ -1,6 +0,0 @@ -contract C { - function one() public returns (uint); - function f() public { var (,) = one(); } -} -// ---- -// TypeError: (81-96): Wildcard both at beginning and end of variable declaration list is only allowed if the number of components is equal. diff --git a/test/libsolidity/syntaxTests/nameAndTypeResolution/247_multi_variable_declaration_wildcards_fail_6.sol b/test/libsolidity/syntaxTests/nameAndTypeResolution/247_multi_variable_declaration_wildcards_fail_6.sol deleted file mode 100644 index cc5953db..00000000 --- a/test/libsolidity/syntaxTests/nameAndTypeResolution/247_multi_variable_declaration_wildcards_fail_6.sol +++ /dev/null @@ -1,7 +0,0 @@ -contract C { - function two() public returns (uint, uint); - function f() public { (uint a, uint b, uint c) = two(); } -} -// ---- -// Warning: (87-119): Different number of components on the left hand side (3) than on the right hand side (2). -// TypeError: (87-119): Not enough components (2) in value to assign all variables (3). diff --git a/test/libsolidity/syntaxTests/nameAndTypeResolution/250_member_access_parser_ambiguity.sol b/test/libsolidity/syntaxTests/nameAndTypeResolution/250_member_access_parser_ambiguity.sol index f5252180..0ab3c198 100644 --- a/test/libsolidity/syntaxTests/nameAndTypeResolution/250_member_access_parser_ambiguity.sol +++ b/test/libsolidity/syntaxTests/nameAndTypeResolution/250_member_access_parser_ambiguity.sol @@ -3,15 +3,14 @@ contract C { struct S { uint a; uint b; uint[20][20][20] c; R d; } S data; function f() public { - C.S x = data; + C.S storage x = data; C.S memory y; C.S[10] memory z; C.S[10]; y.a = 2; x.c[1][2][3] = 9; x.d.y[2][2] = 3; + z; } } // ---- -// Warning: (150-155): Variable is declared as a storage pointer. Use an explicit "storage" keyword to silence this warning. -// Warning: (194-210): Unused local variable. diff --git a/test/libsolidity/syntaxTests/nameAndTypeResolution/258_using_for_mismatch.sol b/test/libsolidity/syntaxTests/nameAndTypeResolution/258_using_for_mismatch.sol index 84e42072..c60ee651 100644 --- a/test/libsolidity/syntaxTests/nameAndTypeResolution/258_using_for_mismatch.sol +++ b/test/libsolidity/syntaxTests/nameAndTypeResolution/258_using_for_mismatch.sol @@ -6,4 +6,4 @@ contract C { } } // ---- -// TypeError: (177-185): Member "double" not found or not visible after argument-dependent lookup in uint256 +// TypeError: (177-185): Member "double" not found or not visible after argument-dependent lookup in uint256. diff --git a/test/libsolidity/syntaxTests/nameAndTypeResolution/259_using_for_not_used.sol b/test/libsolidity/syntaxTests/nameAndTypeResolution/259_using_for_not_used.sol index fae918b7..b11cefba 100644 --- a/test/libsolidity/syntaxTests/nameAndTypeResolution/259_using_for_not_used.sol +++ b/test/libsolidity/syntaxTests/nameAndTypeResolution/259_using_for_not_used.sol @@ -8,4 +8,4 @@ contract C { } } // ---- -// TypeError: (305-313): Member "double" not found or not visible after argument-dependent lookup in uint16 +// TypeError: (305-313): Member "double" not found or not visible after argument-dependent lookup in uint16. diff --git a/test/libsolidity/syntaxTests/nameAndTypeResolution/260_library_memory_struct.sol b/test/libsolidity/syntaxTests/nameAndTypeResolution/260_library_memory_struct.sol index e06ba2d1..20d8afa5 100644 --- a/test/libsolidity/syntaxTests/nameAndTypeResolution/260_library_memory_struct.sol +++ b/test/libsolidity/syntaxTests/nameAndTypeResolution/260_library_memory_struct.sol @@ -1,8 +1,8 @@ pragma experimental ABIEncoderV2; library c { struct S { uint x; } - function f() public returns (S ) {} + function f() public returns (S memory) {} } // ---- // Warning: (0-33): Experimental features are turned on. Do not use experimental features on live deployments. -// Warning: (75-110): Function state mutability can be restricted to pure +// Warning: (75-116): Function state mutability can be restricted to pure diff --git a/test/libsolidity/syntaxTests/nameAndTypeResolution/261_using_for_arbitrary_mismatch.sol b/test/libsolidity/syntaxTests/nameAndTypeResolution/261_using_for_arbitrary_mismatch.sol index ced4705f..b2b55350 100644 --- a/test/libsolidity/syntaxTests/nameAndTypeResolution/261_using_for_arbitrary_mismatch.sol +++ b/test/libsolidity/syntaxTests/nameAndTypeResolution/261_using_for_arbitrary_mismatch.sol @@ -7,4 +7,4 @@ contract C { } } // ---- -// TypeError: (227-235): Member "double" not found or not visible after argument-dependent lookup in uint256 +// TypeError: (227-235): Member "double" not found or not visible after argument-dependent lookup in uint256. diff --git a/test/libsolidity/syntaxTests/nameAndTypeResolution/268_function_overload_array_type.sol b/test/libsolidity/syntaxTests/nameAndTypeResolution/268_function_overload_array_type.sol index 97e68aa3..4fc9d46e 100644 --- a/test/libsolidity/syntaxTests/nameAndTypeResolution/268_function_overload_array_type.sol +++ b/test/libsolidity/syntaxTests/nameAndTypeResolution/268_function_overload_array_type.sol @@ -1,4 +1,4 @@ contract M { - function f(uint[]) public; - function f(int[]) public; + function f(uint[] memory) public; + function f(int[] memory) public; } diff --git a/test/libsolidity/syntaxTests/nameAndTypeResolution/270_inline_array_declaration_and_passing_implicit_conversion_strings.sol b/test/libsolidity/syntaxTests/nameAndTypeResolution/270_inline_array_declaration_and_passing_implicit_conversion_strings.sol index d7765d7b..025244d3 100644 --- a/test/libsolidity/syntaxTests/nameAndTypeResolution/270_inline_array_declaration_and_passing_implicit_conversion_strings.sol +++ b/test/libsolidity/syntaxTests/nameAndTypeResolution/270_inline_array_declaration_and_passing_implicit_conversion_strings.sol @@ -1,5 +1,5 @@ contract C { - function f() public returns (string) { + function f() public returns (string memory) { string memory x = "Hello"; string memory y = "World"; string[2] memory z = [x, y]; @@ -7,4 +7,4 @@ contract C { } } // ---- -// Warning: (17-191): Function state mutability can be restricted to pure +// Warning: (17-198): Function state mutability can be restricted to pure diff --git a/test/libsolidity/syntaxTests/nameAndTypeResolution/272_inline_array_declaration_const_string_conversion.sol b/test/libsolidity/syntaxTests/nameAndTypeResolution/272_inline_array_declaration_const_string_conversion.sol index dd39af85..4e92f6e1 100644 --- a/test/libsolidity/syntaxTests/nameAndTypeResolution/272_inline_array_declaration_const_string_conversion.sol +++ b/test/libsolidity/syntaxTests/nameAndTypeResolution/272_inline_array_declaration_const_string_conversion.sol @@ -1,8 +1,8 @@ contract C { - function f() public returns (string) { + function f() public returns (string memory) { string[2] memory z = ["Hello", "World"]; return (z[0]); } } // ---- -// Warning: (17-133): Function state mutability can be restricted to pure +// Warning: (17-140): Function state mutability can be restricted to pure diff --git a/test/libsolidity/syntaxTests/nameAndTypeResolution/274_inline_array_declaration_no_type_strings.sol b/test/libsolidity/syntaxTests/nameAndTypeResolution/274_inline_array_declaration_no_type_strings.sol index fbc028c5..6d36942d 100644 --- a/test/libsolidity/syntaxTests/nameAndTypeResolution/274_inline_array_declaration_no_type_strings.sol +++ b/test/libsolidity/syntaxTests/nameAndTypeResolution/274_inline_array_declaration_no_type_strings.sol @@ -1,7 +1,7 @@ contract C { - function f() public returns (string) { + function f() public returns (string memory) { return (["foo", "man", "choo"][1]); } } // ---- -// Warning: (17-105): Function state mutability can be restricted to pure +// Warning: (17-112): Function state mutability can be restricted to pure diff --git a/test/libsolidity/syntaxTests/nameAndTypeResolution/276_invalid_types_in_inline_array.sol b/test/libsolidity/syntaxTests/nameAndTypeResolution/276_invalid_types_in_inline_array.sol index 6c8aabd5..03d7266a 100644 --- a/test/libsolidity/syntaxTests/nameAndTypeResolution/276_invalid_types_in_inline_array.sol +++ b/test/libsolidity/syntaxTests/nameAndTypeResolution/276_invalid_types_in_inline_array.sol @@ -1,8 +1,7 @@ contract C { function f() public { - uint[3] x = [45, 'foo', true]; + uint[3] memory x = [45, 'foo', true]; } } // ---- -// Warning: (47-56): Variable is declared as a storage pointer. Use an explicit "storage" keyword to silence this warning. -// TypeError: (59-76): Unable to deduce common type for array elements. +// TypeError: (66-83): Unable to deduce common type for array elements. diff --git a/test/libsolidity/syntaxTests/nameAndTypeResolution/301_library_instances_cannot_be_used.sol b/test/libsolidity/syntaxTests/nameAndTypeResolution/301_library_instances_cannot_be_used.sol index 82e4a0d1..dcf11a6e 100644 --- a/test/libsolidity/syntaxTests/nameAndTypeResolution/301_library_instances_cannot_be_used.sol +++ b/test/libsolidity/syntaxTests/nameAndTypeResolution/301_library_instances_cannot_be_used.sol @@ -6,4 +6,4 @@ contract test { } } // ---- -// TypeError: (100-103): Member "l" not found or not visible after argument-dependent lookup in library L +// TypeError: (100-103): Member "l" not found or not visible after argument-dependent lookup in library L. diff --git a/test/libsolidity/syntaxTests/nameAndTypeResolution/308_rational_unary_plus_operation.sol b/test/libsolidity/syntaxTests/nameAndTypeResolution/308_rational_unary_plus_operation.sol index eb7c6ea9..f635a214 100644 --- a/test/libsolidity/syntaxTests/nameAndTypeResolution/308_rational_unary_plus_operation.sol +++ b/test/libsolidity/syntaxTests/nameAndTypeResolution/308_rational_unary_plus_operation.sol @@ -6,4 +6,4 @@ contract test { } } // ---- -// Warning: (70-75): Use of unary + is deprecated. +// SyntaxError: (70-75): Use of unary + is disallowed. diff --git a/test/libsolidity/syntaxTests/nameAndTypeResolution/310_rational_unary_plus_operation_v050.sol b/test/libsolidity/syntaxTests/nameAndTypeResolution/310_rational_unary_plus_operation_v050.sol deleted file mode 100644 index 140655af..00000000 --- a/test/libsolidity/syntaxTests/nameAndTypeResolution/310_rational_unary_plus_operation_v050.sol +++ /dev/null @@ -1,10 +0,0 @@ -pragma experimental "v0.5.0"; -contract test { - function f() pure public { - ufixed16x2 a = +3.25; - fixed16x2 b = -3.25; - a; b; - } -} -// ---- -// SyntaxError: (100-105): Use of unary + is deprecated. diff --git a/test/libsolidity/syntaxTests/nameAndTypeResolution/311_rational_unary_plus_assignment_v050.sol b/test/libsolidity/syntaxTests/nameAndTypeResolution/311_rational_unary_plus_assignment_v050.sol deleted file mode 100644 index 7e5c0feb..00000000 --- a/test/libsolidity/syntaxTests/nameAndTypeResolution/311_rational_unary_plus_assignment_v050.sol +++ /dev/null @@ -1,9 +0,0 @@ -pragma experimental "v0.5.0"; -contract test { - function f(uint x) pure public { - uint y = +x; - y; - } -} -// ---- -// SyntaxError: (100-102): Use of unary + is deprecated. diff --git a/test/libsolidity/syntaxTests/nameAndTypeResolution/363_non_payable_constructor.sol b/test/libsolidity/syntaxTests/nameAndTypeResolution/363_non_payable_constructor.sol index 4cd1fcae..27381904 100644 --- a/test/libsolidity/syntaxTests/nameAndTypeResolution/363_non_payable_constructor.sol +++ b/test/libsolidity/syntaxTests/nameAndTypeResolution/363_non_payable_constructor.sol @@ -1,5 +1,5 @@ contract C { - constructor() { } + constructor() public { } } contract D { function f() public returns (uint) { @@ -8,4 +8,4 @@ contract D { } } // ---- -// TypeError: (99-112): Member "value" not found or not visible after argument-dependent lookup in function () returns (contract C) - did you forget the "payable" modifier? +// TypeError: (106-119): Member "value" not found or not visible after argument-dependent lookup in function () returns (contract C) - did you forget the "payable" modifier? diff --git a/test/libsolidity/syntaxTests/nameAndTypeResolution/367_using_directive_for_missing_selftype.sol b/test/libsolidity/syntaxTests/nameAndTypeResolution/367_using_directive_for_missing_selftype.sol index 415acb3c..3d9bc3fc 100644 --- a/test/libsolidity/syntaxTests/nameAndTypeResolution/367_using_directive_for_missing_selftype.sol +++ b/test/libsolidity/syntaxTests/nameAndTypeResolution/367_using_directive_for_missing_selftype.sol @@ -11,4 +11,4 @@ contract A { } } // ---- -// TypeError: (137-140): Member "b" not found or not visible after argument-dependent lookup in bytes memory +// TypeError: (137-140): Member "b" not found or not visible after argument-dependent lookup in bytes memory. diff --git a/test/libsolidity/syntaxTests/nameAndTypeResolution/403_return_structs.sol b/test/libsolidity/syntaxTests/nameAndTypeResolution/403_return_structs.sol index 8af8098c..2575954e 100644 --- a/test/libsolidity/syntaxTests/nameAndTypeResolution/403_return_structs.sol +++ b/test/libsolidity/syntaxTests/nameAndTypeResolution/403_return_structs.sol @@ -2,9 +2,9 @@ pragma experimental ABIEncoderV2; contract C { struct S { uint a; T[] sub; } struct T { uint[] x; } - function f() public returns (uint, S) { + function f() public returns (uint, S memory) { } } // ---- // Warning: (0-33): Experimental features are turned on. Do not use experimental features on live deployments. -// Warning: (112-157): Function state mutability can be restricted to pure +// Warning: (112-164): Function state mutability can be restricted to pure diff --git a/test/libsolidity/syntaxTests/nameAndTypeResolution/404_read_returned_struct.sol b/test/libsolidity/syntaxTests/nameAndTypeResolution/404_read_returned_struct.sol index dd16eae4..52d1bd13 100644 --- a/test/libsolidity/syntaxTests/nameAndTypeResolution/404_read_returned_struct.sol +++ b/test/libsolidity/syntaxTests/nameAndTypeResolution/404_read_returned_struct.sol @@ -4,7 +4,7 @@ contract A { int x; int y; } - function g() public returns (T) { + function g() public returns (T memory) { return this.g(); } } diff --git a/test/libsolidity/syntaxTests/nameAndTypeResolution/412_early_exit_on_fatal_errors.sol b/test/libsolidity/syntaxTests/nameAndTypeResolution/412_early_exit_on_fatal_errors.sol index 979f0eb6..56fc4051 100644 --- a/test/libsolidity/syntaxTests/nameAndTypeResolution/412_early_exit_on_fatal_errors.sol +++ b/test/libsolidity/syntaxTests/nameAndTypeResolution/412_early_exit_on_fatal_errors.sol @@ -1,11 +1,11 @@ -// This tests a crash that occured because we did not stop for fatal errors. +// This tests a crash that occurred because we did not stop for fatal errors. contract C { struct S { ftring a; } S public s; - function s() s { + function s() public s { } } // ---- -// DeclarationError: (113-119): Identifier not found or not unique. +// DeclarationError: (114-120): Identifier not found or not unique. diff --git a/test/libsolidity/syntaxTests/nameAndTypeResolution/416_interface_function_bodies.sol b/test/libsolidity/syntaxTests/nameAndTypeResolution/416_interface_function_bodies.sol index 24b26c04..fee2525e 100644 --- a/test/libsolidity/syntaxTests/nameAndTypeResolution/416_interface_function_bodies.sol +++ b/test/libsolidity/syntaxTests/nameAndTypeResolution/416_interface_function_bodies.sol @@ -1,7 +1,6 @@ interface I { - function f() public { + function f() external pure { } } // ---- -// TypeError: (18-45): Functions in interfaces cannot have an implementation. -// Warning: (18-45): Functions in interfaces should be declared external. +// TypeError: (18-52): Functions in interfaces cannot have an implementation. diff --git a/test/libsolidity/syntaxTests/nameAndTypeResolution/421_interface_function_parameters.sol b/test/libsolidity/syntaxTests/nameAndTypeResolution/421_interface_function_parameters.sol index 05e2dcfd..9722e936 100644 --- a/test/libsolidity/syntaxTests/nameAndTypeResolution/421_interface_function_parameters.sol +++ b/test/libsolidity/syntaxTests/nameAndTypeResolution/421_interface_function_parameters.sol @@ -1,5 +1,4 @@ interface I { - function f(uint a) public returns (bool); + function f(uint a) external returns (bool); } // ---- -// Warning: (18-59): Functions in interfaces should be declared external. diff --git a/test/libsolidity/syntaxTests/nameAndTypeResolution/426_throw_is_deprecated.sol b/test/libsolidity/syntaxTests/nameAndTypeResolution/426_throw_is_deprecated.sol index 510c0d01..24f36c5b 100644 --- a/test/libsolidity/syntaxTests/nameAndTypeResolution/426_throw_is_deprecated.sol +++ b/test/libsolidity/syntaxTests/nameAndTypeResolution/426_throw_is_deprecated.sol @@ -4,4 +4,4 @@ contract C { } } // ---- -// Warning: (52-57): "throw" is deprecated in favour of "revert()", "require()" and "assert()". +// SyntaxError: (52-57): "throw" is deprecated in favour of "revert()", "require()" and "assert()". diff --git a/test/libsolidity/syntaxTests/nameAndTypeResolution/427_throw_is_deprecated_v050.sol b/test/libsolidity/syntaxTests/nameAndTypeResolution/427_throw_is_deprecated_v050.sol deleted file mode 100644 index 170d47d9..00000000 --- a/test/libsolidity/syntaxTests/nameAndTypeResolution/427_throw_is_deprecated_v050.sol +++ /dev/null @@ -1,8 +0,0 @@ -pragma experimental "v0.5.0"; -contract C { - function f() pure public { - throw; - } -} -// ---- -// SyntaxError: (82-87): "throw" is deprecated in favour of "revert()", "require()" and "assert()". diff --git a/test/libsolidity/syntaxTests/nameAndTypeResolution/463_error_transfer_non_payable_fallback.sol b/test/libsolidity/syntaxTests/nameAndTypeResolution/463_error_transfer_non_payable_fallback.sol deleted file mode 100644 index 2b2ef39e..00000000 --- a/test/libsolidity/syntaxTests/nameAndTypeResolution/463_error_transfer_non_payable_fallback.sol +++ /dev/null @@ -1,17 +0,0 @@ -// This used to be a test for a.transfer to generate a warning -// because A's fallback function is not payable. - -contract A { - function() external {} -} - -contract B { - A a; - - function() external { - a.transfer(100); - } -} -// ---- -// Warning: (213-223): Using contract member "transfer" inherited from the address type is deprecated. Convert the contract to "address" type to access the member, for example use "address(contract).transfer" instead. -// TypeError: (213-223): Value transfer to a contract without a payable fallback function. diff --git a/test/libsolidity/syntaxTests/nameAndTypeResolution/464_error_transfer_no_fallback.sol b/test/libsolidity/syntaxTests/nameAndTypeResolution/464_error_transfer_no_fallback.sol deleted file mode 100644 index 67398de7..00000000 --- a/test/libsolidity/syntaxTests/nameAndTypeResolution/464_error_transfer_no_fallback.sol +++ /dev/null @@ -1,15 +0,0 @@ -// This used to be a test for a.transfer to generate a warning -// because A does not have a payable fallback function. - -contract A {} - -contract B { - A a; - - function() external { - a.transfer(100); - } -} -// ---- -// Warning: (192-202): Using contract member "transfer" inherited from the address type is deprecated. Convert the contract to "address" type to access the member, for example use "address(contract).transfer" instead. -// TypeError: (192-202): Value transfer to a contract without a payable fallback function. diff --git a/test/libsolidity/syntaxTests/nameAndTypeResolution/465_error_send_non_payable_fallback.sol b/test/libsolidity/syntaxTests/nameAndTypeResolution/465_error_send_non_payable_fallback.sol deleted file mode 100644 index 1a4b2e81..00000000 --- a/test/libsolidity/syntaxTests/nameAndTypeResolution/465_error_send_non_payable_fallback.sol +++ /dev/null @@ -1,17 +0,0 @@ -// This used to be a test for a.send to generate a warning -// because A does not have a payable fallback function. - -contract A { - function() external {} -} - -contract B { - A a; - - function() external { - require(a.send(100)); - } -} -// ---- -// Warning: (224-230): Using contract member "send" inherited from the address type is deprecated. Convert the contract to "address" type to access the member, for example use "address(contract).send" instead. -// TypeError: (224-230): Value transfer to a contract without a payable fallback function. diff --git a/test/libsolidity/syntaxTests/nameAndTypeResolution/466_does_not_error_transfer_payable_fallback.sol b/test/libsolidity/syntaxTests/nameAndTypeResolution/466_does_not_error_transfer_payable_fallback.sol index 2b7f8dae..c343995f 100644 --- a/test/libsolidity/syntaxTests/nameAndTypeResolution/466_does_not_error_transfer_payable_fallback.sol +++ b/test/libsolidity/syntaxTests/nameAndTypeResolution/466_does_not_error_transfer_payable_fallback.sol @@ -9,8 +9,7 @@ contract B { A a; function() external { - a.transfer(100); + address(a).transfer(100); } } // ---- -// Warning: (228-238): Using contract member "transfer" inherited from the address type is deprecated. Convert the contract to "address" type to access the member, for example use "address(contract).transfer" instead. diff --git a/test/libsolidity/syntaxTests/nameAndTypeResolution/471_unspecified_storage_fail.sol b/test/libsolidity/syntaxTests/nameAndTypeResolution/471_unspecified_storage_fail.sol new file mode 100644 index 00000000..6e401920 --- /dev/null +++ b/test/libsolidity/syntaxTests/nameAndTypeResolution/471_unspecified_storage_fail.sol @@ -0,0 +1,13 @@ +contract C { + struct S { uint a; } + S m_x; + uint[] m_y; + function f() view public { + S x = m_x; + uint[] y = m_y; + x; y; + } +} +// ---- +// 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". diff --git a/test/libsolidity/syntaxTests/nameAndTypeResolution/471_unspecified_storage_warn.sol b/test/libsolidity/syntaxTests/nameAndTypeResolution/471_unspecified_storage_warn.sol deleted file mode 100644 index aa16a6b4..00000000 --- a/test/libsolidity/syntaxTests/nameAndTypeResolution/471_unspecified_storage_warn.sol +++ /dev/null @@ -1,10 +0,0 @@ -contract C { - struct S { uint a; } - S x; - function f() view public { - S y = x; - y; - } -} -// ---- -// Warning: (86-89): Variable is declared as a storage pointer. Use an explicit "storage" keyword to silence this warning. diff --git a/test/libsolidity/syntaxTests/nameAndTypeResolution/472_unspecified_storage_v050.sol b/test/libsolidity/syntaxTests/nameAndTypeResolution/472_unspecified_storage_v050.sol deleted file mode 100644 index 179c9931..00000000 --- a/test/libsolidity/syntaxTests/nameAndTypeResolution/472_unspecified_storage_v050.sol +++ /dev/null @@ -1,11 +0,0 @@ -pragma experimental "v0.5.0"; -contract C { - struct S { uint a; } - S x; - function f() view public { - S y = x; - y; - } -} -// ---- -// TypeError: (116-119): Data location must be specified as either "memory" or "storage". diff --git a/test/libsolidity/syntaxTests/nameAndTypeResolution/477_too_large_arrays_for_calldata_internal.sol b/test/libsolidity/syntaxTests/nameAndTypeResolution/477_too_large_arrays_for_calldata_internal.sol index ab57f489..7578246e 100644 --- a/test/libsolidity/syntaxTests/nameAndTypeResolution/477_too_large_arrays_for_calldata_internal.sol +++ b/test/libsolidity/syntaxTests/nameAndTypeResolution/477_too_large_arrays_for_calldata_internal.sol @@ -1,6 +1,6 @@ contract C { - function f(uint[85678901234] a) pure internal { + function f(uint[85678901234] memory a) pure internal { } } // ---- -// TypeError: (28-47): Array is too large to be encoded. +// TypeError: (28-54): Array is too large to be encoded. diff --git a/test/libsolidity/syntaxTests/nameAndTypeResolution/478_too_large_arrays_for_calldata_public.sol b/test/libsolidity/syntaxTests/nameAndTypeResolution/478_too_large_arrays_for_calldata_public.sol index 1493f3ca..2831b6fb 100644 --- a/test/libsolidity/syntaxTests/nameAndTypeResolution/478_too_large_arrays_for_calldata_public.sol +++ b/test/libsolidity/syntaxTests/nameAndTypeResolution/478_too_large_arrays_for_calldata_public.sol @@ -1,6 +1,6 @@ contract C { - function f(uint[85678901234] a) pure public { + function f(uint[85678901234] memory a) pure public { } } // ---- -// TypeError: (28-47): Array is too large to be encoded. +// TypeError: (28-54): Array is too large to be encoded. diff --git a/test/libsolidity/syntaxTests/nameAndTypeResolution/481_explicit_literal_to_unspecified_string_assignment.sol b/test/libsolidity/syntaxTests/nameAndTypeResolution/481_explicit_literal_to_unspecified_string_assignment.sol index 9801b831..ee56204a 100644 --- a/test/libsolidity/syntaxTests/nameAndTypeResolution/481_explicit_literal_to_unspecified_string_assignment.sol +++ b/test/libsolidity/syntaxTests/nameAndTypeResolution/481_explicit_literal_to_unspecified_string_assignment.sol @@ -1,8 +1,7 @@ contract C { function f() pure public { - string x = "abc"; + string storage x = "abc"; } } // ---- -// Warning: (52-60): Variable is declared as a storage pointer. Use an explicit "storage" keyword to silence this warning. -// TypeError: (52-68): Type literal_string "abc" is not implicitly convertible to expected type string storage pointer. +// TypeError: (52-76): Type literal_string "abc" is not implicitly convertible to expected type string storage pointer. diff --git a/test/libsolidity/syntaxTests/nameAndTypeResolution/484_function_types_selector_1.sol b/test/libsolidity/syntaxTests/nameAndTypeResolution/484_function_types_selector_1.sol index 76c3fcd6..41ef95c5 100644 --- a/test/libsolidity/syntaxTests/nameAndTypeResolution/484_function_types_selector_1.sol +++ b/test/libsolidity/syntaxTests/nameAndTypeResolution/484_function_types_selector_1.sol @@ -1,7 +1,7 @@ contract C { - function f() view returns (bytes4) { + function f() public view returns (bytes4) { return f.selector; } } // ---- -// TypeError: (69-79): Member "selector" not found or not visible after argument-dependent lookup in function () view returns (bytes4) +// TypeError: (76-86): Member "selector" not found or not visible after argument-dependent lookup in function () view returns (bytes4). diff --git a/test/libsolidity/syntaxTests/nameAndTypeResolution/485_function_types_selector_2.sol b/test/libsolidity/syntaxTests/nameAndTypeResolution/485_function_types_selector_2.sol index b21a5d3d..d02b098d 100644 --- a/test/libsolidity/syntaxTests/nameAndTypeResolution/485_function_types_selector_2.sol +++ b/test/libsolidity/syntaxTests/nameAndTypeResolution/485_function_types_selector_2.sol @@ -1,9 +1,9 @@ contract C { function g() pure internal { } - function f() view returns (bytes4) { + function f() public view returns (bytes4) { return g.selector; } } // ---- -// TypeError: (108-118): Member "selector" not found or not visible after argument-dependent lookup in function () pure +// TypeError: (115-125): Member "selector" not found or not visible after argument-dependent lookup in function () pure. diff --git a/test/libsolidity/syntaxTests/nameAndTypeResolution/486_function_types_selector_3.sol b/test/libsolidity/syntaxTests/nameAndTypeResolution/486_function_types_selector_3.sol index 3567c44f..d39fcc28 100644 --- a/test/libsolidity/syntaxTests/nameAndTypeResolution/486_function_types_selector_3.sol +++ b/test/libsolidity/syntaxTests/nameAndTypeResolution/486_function_types_selector_3.sol @@ -1,8 +1,8 @@ contract C { - function f() view returns (bytes4) { + function f() public view returns (bytes4) { function () g; return g.selector; } } // ---- -// TypeError: (92-102): Member "selector" not found or not visible after argument-dependent lookup in function () +// TypeError: (99-109): Member "selector" not found or not visible after argument-dependent lookup in function (). diff --git a/test/libsolidity/syntaxTests/nameAndTypeResolution/493_builtin_keccak256_reject_gas.sol b/test/libsolidity/syntaxTests/nameAndTypeResolution/493_builtin_keccak256_reject_gas.sol index b99431f9..e4113906 100644 --- a/test/libsolidity/syntaxTests/nameAndTypeResolution/493_builtin_keccak256_reject_gas.sol +++ b/test/libsolidity/syntaxTests/nameAndTypeResolution/493_builtin_keccak256_reject_gas.sol @@ -4,4 +4,4 @@ contract C { } } // ---- -// TypeError: (47-60): Member "gas" not found or not visible after argument-dependent lookup in function (bytes memory) pure returns (bytes32) +// TypeError: (47-60): Member "gas" not found or not visible after argument-dependent lookup in function (bytes memory) pure returns (bytes32). diff --git a/test/libsolidity/syntaxTests/nameAndTypeResolution/494_builtin_sha256_reject_gas.sol b/test/libsolidity/syntaxTests/nameAndTypeResolution/494_builtin_sha256_reject_gas.sol index 23c90acb..20031ea9 100644 --- a/test/libsolidity/syntaxTests/nameAndTypeResolution/494_builtin_sha256_reject_gas.sol +++ b/test/libsolidity/syntaxTests/nameAndTypeResolution/494_builtin_sha256_reject_gas.sol @@ -4,4 +4,4 @@ contract C { } } // ---- -// TypeError: (47-57): Member "gas" not found or not visible after argument-dependent lookup in function (bytes memory) pure returns (bytes32) +// TypeError: (47-57): Member "gas" not found or not visible after argument-dependent lookup in function (bytes memory) pure returns (bytes32). diff --git a/test/libsolidity/syntaxTests/nameAndTypeResolution/495_builtin_ripemd160_reject_gas.sol b/test/libsolidity/syntaxTests/nameAndTypeResolution/495_builtin_ripemd160_reject_gas.sol index 5884e212..3d37e988 100644 --- a/test/libsolidity/syntaxTests/nameAndTypeResolution/495_builtin_ripemd160_reject_gas.sol +++ b/test/libsolidity/syntaxTests/nameAndTypeResolution/495_builtin_ripemd160_reject_gas.sol @@ -4,4 +4,4 @@ contract C { } } // ---- -// TypeError: (47-60): Member "gas" not found or not visible after argument-dependent lookup in function (bytes memory) pure returns (bytes20) +// TypeError: (47-60): Member "gas" not found or not visible after argument-dependent lookup in function (bytes memory) pure returns (bytes20). diff --git a/test/libsolidity/syntaxTests/nameAndTypeResolution/496_builtin_ecrecover_reject_gas.sol b/test/libsolidity/syntaxTests/nameAndTypeResolution/496_builtin_ecrecover_reject_gas.sol index 0a874f5d..82b6c89d 100644 --- a/test/libsolidity/syntaxTests/nameAndTypeResolution/496_builtin_ecrecover_reject_gas.sol +++ b/test/libsolidity/syntaxTests/nameAndTypeResolution/496_builtin_ecrecover_reject_gas.sol @@ -4,4 +4,4 @@ contract C { } } // ---- -// TypeError: (47-60): Member "gas" not found or not visible after argument-dependent lookup in function (bytes32,uint8,bytes32,bytes32) pure returns (address) +// TypeError: (47-60): Member "gas" not found or not visible after argument-dependent lookup in function (bytes32,uint8,bytes32,bytes32) pure returns (address). diff --git a/test/libsolidity/syntaxTests/nameAndTypeResolution/514_using_for_with_non_library.sol b/test/libsolidity/syntaxTests/nameAndTypeResolution/514_using_for_with_non_library.sol index ab139dd5..7e9612d0 100644 --- a/test/libsolidity/syntaxTests/nameAndTypeResolution/514_using_for_with_non_library.sol +++ b/test/libsolidity/syntaxTests/nameAndTypeResolution/514_using_for_with_non_library.sol @@ -2,7 +2,7 @@ library L { struct S { uint d; } using S for S; - function f(S _s) internal { + function f(S memory _s) internal { _s.d = 1; } } diff --git a/test/libsolidity/syntaxTests/nameAndTypeResolution/525_reject_interface_constructors.sol b/test/libsolidity/syntaxTests/nameAndTypeResolution/525_reject_interface_constructors.sol index d65c639f..ad08eca6 100644 --- a/test/libsolidity/syntaxTests/nameAndTypeResolution/525_reject_interface_constructors.sol +++ b/test/libsolidity/syntaxTests/nameAndTypeResolution/525_reject_interface_constructors.sol @@ -1,4 +1,4 @@ interface I {} contract C is I(2) {} // ---- -// TypeError: (29-33): Wrong argument count for constructor call: 1 arguments given but expected 0. +// TypeError: (29-33): Wrong argument count for constructor call: 1 arguments given but expected 0. Remove parentheses if you do not want to provide arguments here. diff --git a/test/libsolidity/syntaxTests/nameAndTypeResolution/526_fallback_marked_external_v050.sol b/test/libsolidity/syntaxTests/nameAndTypeResolution/526_fallback_marked_external_v050.sol deleted file mode 100644 index f13a87ec..00000000 --- a/test/libsolidity/syntaxTests/nameAndTypeResolution/526_fallback_marked_external_v050.sol +++ /dev/null @@ -1,4 +0,0 @@ -pragma experimental "v0.5.0"; -contract C { - function () external { } -} diff --git a/test/libsolidity/syntaxTests/nameAndTypeResolution/527_fallback_marked_internal.sol b/test/libsolidity/syntaxTests/nameAndTypeResolution/527_fallback_marked_internal.sol index 2d425037..b8e1c654 100644 --- a/test/libsolidity/syntaxTests/nameAndTypeResolution/527_fallback_marked_internal.sol +++ b/test/libsolidity/syntaxTests/nameAndTypeResolution/527_fallback_marked_internal.sol @@ -2,3 +2,4 @@ contract C { function () internal { } } // ---- +// TypeError: (17-41): Fallback function must be defined as "external". diff --git a/test/libsolidity/syntaxTests/nameAndTypeResolution/527_fallback_marked_internal_v050.sol b/test/libsolidity/syntaxTests/nameAndTypeResolution/527_fallback_marked_internal_v050.sol deleted file mode 100644 index 6c8b23c8..00000000 --- a/test/libsolidity/syntaxTests/nameAndTypeResolution/527_fallback_marked_internal_v050.sol +++ /dev/null @@ -1,6 +0,0 @@ -pragma experimental "v0.5.0"; -contract C { - function () internal { } -} -// ---- -// TypeError: (47-71): Fallback function must be defined as "external". diff --git a/test/libsolidity/syntaxTests/nameAndTypeResolution/528_fallback_marked_private.sol b/test/libsolidity/syntaxTests/nameAndTypeResolution/528_fallback_marked_private.sol index 2105c815..6038a99f 100644 --- a/test/libsolidity/syntaxTests/nameAndTypeResolution/528_fallback_marked_private.sol +++ b/test/libsolidity/syntaxTests/nameAndTypeResolution/528_fallback_marked_private.sol @@ -2,3 +2,4 @@ contract C { function () private { } } // ---- +// TypeError: (17-40): Fallback function must be defined as "external". diff --git a/test/libsolidity/syntaxTests/nameAndTypeResolution/528_fallback_marked_private_v050.sol b/test/libsolidity/syntaxTests/nameAndTypeResolution/528_fallback_marked_private_v050.sol deleted file mode 100644 index be381909..00000000 --- a/test/libsolidity/syntaxTests/nameAndTypeResolution/528_fallback_marked_private_v050.sol +++ /dev/null @@ -1,6 +0,0 @@ -pragma experimental "v0.5.0"; -contract C { - function () private { } -} -// ---- -// TypeError: (47-70): Fallback function must be defined as "external". diff --git a/test/libsolidity/syntaxTests/nameAndTypeResolution/529_fallback_marked_public.sol b/test/libsolidity/syntaxTests/nameAndTypeResolution/529_fallback_marked_public.sol index 42585137..d9c1580f 100644 --- a/test/libsolidity/syntaxTests/nameAndTypeResolution/529_fallback_marked_public.sol +++ b/test/libsolidity/syntaxTests/nameAndTypeResolution/529_fallback_marked_public.sol @@ -2,3 +2,4 @@ contract C { function () public { } } // ---- +// TypeError: (17-39): Fallback function must be defined as "external". diff --git a/test/libsolidity/syntaxTests/nameAndTypeResolution/529_fallback_marked_public_v050.sol b/test/libsolidity/syntaxTests/nameAndTypeResolution/529_fallback_marked_public_v050.sol deleted file mode 100644 index d0beffda..00000000 --- a/test/libsolidity/syntaxTests/nameAndTypeResolution/529_fallback_marked_public_v050.sol +++ /dev/null @@ -1,6 +0,0 @@ -pragma experimental "v0.5.0"; -contract C { - function () public { } -} -// ---- -// TypeError: (47-69): Fallback function must be defined as "external". diff --git a/test/libsolidity/syntaxTests/nameAndTypeResolution/541_warn_about_address_members_on_contract_balance.sol b/test/libsolidity/syntaxTests/nameAndTypeResolution/541_warn_about_address_members_on_contract_balance.sol index 4acb0dc2..39edaa2d 100644 --- a/test/libsolidity/syntaxTests/nameAndTypeResolution/541_warn_about_address_members_on_contract_balance.sol +++ b/test/libsolidity/syntaxTests/nameAndTypeResolution/541_warn_about_address_members_on_contract_balance.sol @@ -4,4 +4,4 @@ contract C { } } // ---- -// Warning: (52-64): Using contract member "balance" inherited from the address type is deprecated. Convert the contract to "address" type to access the member, for example use "address(contract).balance" instead. +// TypeError: (52-64): Member "balance" not found or not visible after argument-dependent lookup in contract C. Use "address(this).balance" to access this address member. diff --git a/test/libsolidity/syntaxTests/nameAndTypeResolution/542_warn_about_address_members_on_contract_transfer.sol b/test/libsolidity/syntaxTests/nameAndTypeResolution/542_warn_about_address_members_on_contract_transfer.sol index 45ee1f5b..a44cc6d2 100644 --- a/test/libsolidity/syntaxTests/nameAndTypeResolution/542_warn_about_address_members_on_contract_transfer.sol +++ b/test/libsolidity/syntaxTests/nameAndTypeResolution/542_warn_about_address_members_on_contract_transfer.sol @@ -4,5 +4,4 @@ contract C { } } // ---- -// Warning: (52-65): Using contract member "transfer" inherited from the address type is deprecated. Convert the contract to "address" type to access the member, for example use "address(contract).transfer" instead. -// TypeError: (52-65): Value transfer to a contract without a payable fallback function. +// TypeError: (52-65): Member "transfer" not found or not visible after argument-dependent lookup in contract C. Use "address(this).transfer" to access this address member. diff --git a/test/libsolidity/syntaxTests/nameAndTypeResolution/543_warn_about_address_members_on_contract_send.sol b/test/libsolidity/syntaxTests/nameAndTypeResolution/543_warn_about_address_members_on_contract_send.sol index 99b7b8b2..e9e26a00 100644 --- a/test/libsolidity/syntaxTests/nameAndTypeResolution/543_warn_about_address_members_on_contract_send.sol +++ b/test/libsolidity/syntaxTests/nameAndTypeResolution/543_warn_about_address_members_on_contract_send.sol @@ -4,5 +4,4 @@ contract C { } } // ---- -// Warning: (52-61): Using contract member "send" inherited from the address type is deprecated. Convert the contract to "address" type to access the member, for example use "address(contract).send" instead. -// TypeError: (52-61): Value transfer to a contract without a payable fallback function. +// TypeError: (52-61): Member "send" not found or not visible after argument-dependent lookup in contract C. Use "address(this).send" to access this address member. diff --git a/test/libsolidity/syntaxTests/nameAndTypeResolution/544_warn_about_address_members_on_contract_call.sol b/test/libsolidity/syntaxTests/nameAndTypeResolution/544_warn_about_address_members_on_contract_call.sol index 446410ba..16da7578 100644 --- a/test/libsolidity/syntaxTests/nameAndTypeResolution/544_warn_about_address_members_on_contract_call.sol +++ b/test/libsolidity/syntaxTests/nameAndTypeResolution/544_warn_about_address_members_on_contract_call.sol @@ -4,4 +4,4 @@ contract C { } } // ---- -// Warning: (52-61): Using contract member "call" inherited from the address type is deprecated. Convert the contract to "address" type to access the member, for example use "address(contract).call" instead. +// TypeError: (52-61): Member "call" not found or not visible after argument-dependent lookup in contract C. Use "address(this).call" to access this address member. diff --git a/test/libsolidity/syntaxTests/nameAndTypeResolution/545_warn_about_address_members_on_contract_callcode.sol b/test/libsolidity/syntaxTests/nameAndTypeResolution/545_warn_about_address_members_on_contract_callcode.sol index 43ee4d88..9292f9c0 100644 --- a/test/libsolidity/syntaxTests/nameAndTypeResolution/545_warn_about_address_members_on_contract_callcode.sol +++ b/test/libsolidity/syntaxTests/nameAndTypeResolution/545_warn_about_address_members_on_contract_callcode.sol @@ -4,5 +4,4 @@ contract C { } } // ---- -// Warning: (52-65): Using contract member "callcode" inherited from the address type is deprecated. Convert the contract to "address" type to access the member, for example use "address(contract).callcode" instead. -// TypeError: (52-65): "callcode" has been deprecated in favour of "delegatecall". +// TypeError: (52-65): Member "callcode" not found or not visible after argument-dependent lookup in contract C. Use "address(this).callcode" to access this address member. diff --git a/test/libsolidity/syntaxTests/nameAndTypeResolution/546_warn_about_address_members_on_contract_delegatecall.sol b/test/libsolidity/syntaxTests/nameAndTypeResolution/546_warn_about_address_members_on_contract_delegatecall.sol index 7cbd832a..20354991 100644 --- a/test/libsolidity/syntaxTests/nameAndTypeResolution/546_warn_about_address_members_on_contract_delegatecall.sol +++ b/test/libsolidity/syntaxTests/nameAndTypeResolution/546_warn_about_address_members_on_contract_delegatecall.sol @@ -4,4 +4,4 @@ contract C { } } // ---- -// Warning: (52-69): Using contract member "delegatecall" inherited from the address type is deprecated. Convert the contract to "address" type to access the member, for example use "address(contract).delegatecall" instead. +// TypeError: (52-69): Member "delegatecall" not found or not visible after argument-dependent lookup in contract C. Use "address(this).delegatecall" to access this address member. diff --git a/test/libsolidity/syntaxTests/nameAndTypeResolution/547_warn_about_address_members_on_non_this_contract_balance.sol b/test/libsolidity/syntaxTests/nameAndTypeResolution/547_warn_about_address_members_on_non_this_contract_balance.sol index 3ba59a9f..8a4734e6 100644 --- a/test/libsolidity/syntaxTests/nameAndTypeResolution/547_warn_about_address_members_on_non_this_contract_balance.sol +++ b/test/libsolidity/syntaxTests/nameAndTypeResolution/547_warn_about_address_members_on_non_this_contract_balance.sol @@ -5,4 +5,4 @@ contract C { } } // ---- -// Warning: (65-74): Using contract member "balance" inherited from the address type is deprecated. Convert the contract to "address" type to access the member, for example use "address(contract).balance" instead. +// TypeError: (65-74): Member "balance" not found or not visible after argument-dependent lookup in contract C. Use "address(c).balance" to access this address member. diff --git a/test/libsolidity/syntaxTests/nameAndTypeResolution/548_warn_about_address_members_on_non_this_contract_transfer.sol b/test/libsolidity/syntaxTests/nameAndTypeResolution/548_warn_about_address_members_on_non_this_contract_transfer.sol index 17455124..e617f540 100644 --- a/test/libsolidity/syntaxTests/nameAndTypeResolution/548_warn_about_address_members_on_non_this_contract_transfer.sol +++ b/test/libsolidity/syntaxTests/nameAndTypeResolution/548_warn_about_address_members_on_non_this_contract_transfer.sol @@ -5,5 +5,4 @@ contract C { } } // ---- -// Warning: (65-75): Using contract member "transfer" inherited from the address type is deprecated. Convert the contract to "address" type to access the member, for example use "address(contract).transfer" instead. -// TypeError: (65-75): Value transfer to a contract without a payable fallback function. +// TypeError: (65-75): Member "transfer" not found or not visible after argument-dependent lookup in contract C. Use "address(c).transfer" to access this address member. diff --git a/test/libsolidity/syntaxTests/nameAndTypeResolution/549_warn_about_address_members_on_non_this_contract_send.sol b/test/libsolidity/syntaxTests/nameAndTypeResolution/549_warn_about_address_members_on_non_this_contract_send.sol index ca0630c4..54965d4b 100644 --- a/test/libsolidity/syntaxTests/nameAndTypeResolution/549_warn_about_address_members_on_non_this_contract_send.sol +++ b/test/libsolidity/syntaxTests/nameAndTypeResolution/549_warn_about_address_members_on_non_this_contract_send.sol @@ -5,5 +5,4 @@ contract C { } } // ---- -// Warning: (65-71): Using contract member "send" inherited from the address type is deprecated. Convert the contract to "address" type to access the member, for example use "address(contract).send" instead. -// TypeError: (65-71): Value transfer to a contract without a payable fallback function. +// TypeError: (65-71): Member "send" not found or not visible after argument-dependent lookup in contract C. Use "address(c).send" to access this address member. diff --git a/test/libsolidity/syntaxTests/nameAndTypeResolution/550_warn_about_address_members_on_non_this_contract_call.sol b/test/libsolidity/syntaxTests/nameAndTypeResolution/550_warn_about_address_members_on_non_this_contract_call.sol index c06e0f61..940f383c 100644 --- a/test/libsolidity/syntaxTests/nameAndTypeResolution/550_warn_about_address_members_on_non_this_contract_call.sol +++ b/test/libsolidity/syntaxTests/nameAndTypeResolution/550_warn_about_address_members_on_non_this_contract_call.sol @@ -5,4 +5,4 @@ contract C { } } // ---- -// Warning: (65-71): Using contract member "call" inherited from the address type is deprecated. Convert the contract to "address" type to access the member, for example use "address(contract).call" instead. +// TypeError: (65-71): Member "call" not found or not visible after argument-dependent lookup in contract C. Use "address(c).call" to access this address member. diff --git a/test/libsolidity/syntaxTests/nameAndTypeResolution/551_warn_about_address_members_on_non_this_contract_callcode.sol b/test/libsolidity/syntaxTests/nameAndTypeResolution/551_warn_about_address_members_on_non_this_contract_callcode.sol index 3c1e0280..9d4725bd 100644 --- a/test/libsolidity/syntaxTests/nameAndTypeResolution/551_warn_about_address_members_on_non_this_contract_callcode.sol +++ b/test/libsolidity/syntaxTests/nameAndTypeResolution/551_warn_about_address_members_on_non_this_contract_callcode.sol @@ -5,5 +5,4 @@ contract C { } } // ---- -// Warning: (65-75): Using contract member "callcode" inherited from the address type is deprecated. Convert the contract to "address" type to access the member, for example use "address(contract).callcode" instead. -// TypeError: (65-75): "callcode" has been deprecated in favour of "delegatecall". +// TypeError: (65-75): Member "callcode" not found or not visible after argument-dependent lookup in contract C. Use "address(c).callcode" to access this address member. diff --git a/test/libsolidity/syntaxTests/nameAndTypeResolution/552_warn_about_address_members_on_non_this_contract_delegatecall.sol b/test/libsolidity/syntaxTests/nameAndTypeResolution/552_warn_about_address_members_on_non_this_contract_delegatecall.sol index 8e286945..9941ce1f 100644 --- a/test/libsolidity/syntaxTests/nameAndTypeResolution/552_warn_about_address_members_on_non_this_contract_delegatecall.sol +++ b/test/libsolidity/syntaxTests/nameAndTypeResolution/552_warn_about_address_members_on_non_this_contract_delegatecall.sol @@ -5,4 +5,4 @@ contract C { } } // ---- -// Warning: (65-79): Using contract member "delegatecall" inherited from the address type is deprecated. Convert the contract to "address" type to access the member, for example use "address(contract).delegatecall" instead. +// TypeError: (65-79): Member "delegatecall" not found or not visible after argument-dependent lookup in contract C. Use "address(c).delegatecall" to access this address member. diff --git a/test/libsolidity/syntaxTests/nameAndTypeResolution/553_no_address_members_on_contract_balance_v050.sol b/test/libsolidity/syntaxTests/nameAndTypeResolution/553_no_address_members_on_contract_balance_v050.sol deleted file mode 100644 index 7c4ad16a..00000000 --- a/test/libsolidity/syntaxTests/nameAndTypeResolution/553_no_address_members_on_contract_balance_v050.sol +++ /dev/null @@ -1,8 +0,0 @@ -pragma experimental "v0.5.0"; -contract C { - function f() public { - this.balance; - } -} -// ---- -// TypeError: (77-89): Member "balance" not found or not visible after argument-dependent lookup in contract C diff --git a/test/libsolidity/syntaxTests/nameAndTypeResolution/554_no_address_members_on_contract_transfer_v050.sol b/test/libsolidity/syntaxTests/nameAndTypeResolution/554_no_address_members_on_contract_transfer_v050.sol deleted file mode 100644 index 74bdabd2..00000000 --- a/test/libsolidity/syntaxTests/nameAndTypeResolution/554_no_address_members_on_contract_transfer_v050.sol +++ /dev/null @@ -1,8 +0,0 @@ -pragma experimental "v0.5.0"; -contract C { - function f() public { - this.transfer; - } -} -// ---- -// TypeError: (77-90): Member "transfer" not found or not visible after argument-dependent lookup in contract C diff --git a/test/libsolidity/syntaxTests/nameAndTypeResolution/555_no_address_members_on_contract_send_v050.sol b/test/libsolidity/syntaxTests/nameAndTypeResolution/555_no_address_members_on_contract_send_v050.sol deleted file mode 100644 index 0852e47e..00000000 --- a/test/libsolidity/syntaxTests/nameAndTypeResolution/555_no_address_members_on_contract_send_v050.sol +++ /dev/null @@ -1,8 +0,0 @@ -pragma experimental "v0.5.0"; -contract C { - function f() public { - this.send; - } -} -// ---- -// TypeError: (77-86): Member "send" not found or not visible after argument-dependent lookup in contract C diff --git a/test/libsolidity/syntaxTests/nameAndTypeResolution/556_no_address_members_on_contract_call_v050.sol b/test/libsolidity/syntaxTests/nameAndTypeResolution/556_no_address_members_on_contract_call_v050.sol deleted file mode 100644 index b9a226ad..00000000 --- a/test/libsolidity/syntaxTests/nameAndTypeResolution/556_no_address_members_on_contract_call_v050.sol +++ /dev/null @@ -1,8 +0,0 @@ -pragma experimental "v0.5.0"; -contract C { - function f() public { - this.call; - } -} -// ---- -// TypeError: (77-86): Member "call" not found or not visible after argument-dependent lookup in contract C diff --git a/test/libsolidity/syntaxTests/nameAndTypeResolution/557_no_address_members_on_contract_callcode_v050.sol b/test/libsolidity/syntaxTests/nameAndTypeResolution/557_no_address_members_on_contract_callcode_v050.sol deleted file mode 100644 index 95198a94..00000000 --- a/test/libsolidity/syntaxTests/nameAndTypeResolution/557_no_address_members_on_contract_callcode_v050.sol +++ /dev/null @@ -1,8 +0,0 @@ -pragma experimental "v0.5.0"; -contract C { - function f() public { - this.callcode; - } -} -// ---- -// TypeError: (77-90): Member "callcode" not found or not visible after argument-dependent lookup in contract C diff --git a/test/libsolidity/syntaxTests/nameAndTypeResolution/558_no_address_members_on_contract_delegatecall_v050.sol b/test/libsolidity/syntaxTests/nameAndTypeResolution/558_no_address_members_on_contract_delegatecall_v050.sol deleted file mode 100644 index b7a7053e..00000000 --- a/test/libsolidity/syntaxTests/nameAndTypeResolution/558_no_address_members_on_contract_delegatecall_v050.sol +++ /dev/null @@ -1,8 +0,0 @@ -pragma experimental "v0.5.0"; -contract C { - function f() public { - this.delegatecall; - } -} -// ---- -// TypeError: (77-94): Member "delegatecall" not found or not visible after argument-dependent lookup in contract C diff --git a/test/libsolidity/syntaxTests/nameAndTypeResolution/559_no_warning_for_using_members_that_look_like_address_members.sol b/test/libsolidity/syntaxTests/nameAndTypeResolution/559_no_warning_for_using_members_that_look_like_address_members.sol index 9355853a..4c1870f1 100644 --- a/test/libsolidity/syntaxTests/nameAndTypeResolution/559_no_warning_for_using_members_that_look_like_address_members.sol +++ b/test/libsolidity/syntaxTests/nameAndTypeResolution/559_no_warning_for_using_members_that_look_like_address_members.sol @@ -1,4 +1,3 @@ -pragma experimental "v0.5.0"; contract C { function transfer(uint) public; function f() public { diff --git a/test/libsolidity/syntaxTests/nameAndTypeResolution/567_require_visibility_specifiers_v050.sol b/test/libsolidity/syntaxTests/nameAndTypeResolution/567_require_visibility_specifiers_v050.sol deleted file mode 100644 index ec7c0937..00000000 --- a/test/libsolidity/syntaxTests/nameAndTypeResolution/567_require_visibility_specifiers_v050.sol +++ /dev/null @@ -1,6 +0,0 @@ -pragma experimental "v0.5.0"; -contract C { - function f() pure { } -} -// ---- -// SyntaxError: (47-68): No visibility specified. diff --git a/test/libsolidity/syntaxTests/parsing/arrays_in_expressions.sol b/test/libsolidity/syntaxTests/parsing/arrays_in_expressions.sol index 626e865e..4c1f96e6 100644 --- a/test/libsolidity/syntaxTests/parsing/arrays_in_expressions.sol +++ b/test/libsolidity/syntaxTests/parsing/arrays_in_expressions.sol @@ -1,8 +1,6 @@ contract c { - function f() { c[10] a = 7; uint8[10 * 2] x; } + function f() public { c[10] storage a = 7; uint8[10 * 2] storage x; } } // ---- -// Warning: (32-39): Variable is declared as a storage pointer. Use an explicit "storage" keyword to silence this warning. -// Warning: (45-60): Variable is declared as a storage pointer. Use an explicit "storage" keyword to silence this warning. -// TypeError: (32-43): Type int_const 7 is not implicitly convertible to expected type contract c[10] storage pointer. -// Warning: (45-60): Uninitialized storage pointer. Did you mean '<type> memory x'? +// TypeError: (39-58): Type int_const 7 is not implicitly convertible to expected type contract c[10] storage pointer. +// DeclarationError: (60-83): Uninitialized storage pointer. diff --git a/test/libsolidity/syntaxTests/parsing/interface_basic.sol b/test/libsolidity/syntaxTests/parsing/interface_basic.sol index 2363eaa8..0742c24f 100644 --- a/test/libsolidity/syntaxTests/parsing/interface_basic.sol +++ b/test/libsolidity/syntaxTests/parsing/interface_basic.sol @@ -1,5 +1,4 @@ interface Interface { - function f() public; + function f() external; } // ---- -// Warning: (23-43): Functions in interfaces should be declared external. diff --git a/test/libsolidity/syntaxTests/parsing/location_specifiers_for_locals.sol b/test/libsolidity/syntaxTests/parsing/location_specifiers_for_locals.sol index e311dd96..38de7b1c 100644 --- a/test/libsolidity/syntaxTests/parsing/location_specifiers_for_locals.sol +++ b/test/libsolidity/syntaxTests/parsing/location_specifiers_for_locals.sol @@ -1,11 +1,9 @@ contract Foo { - function f() public { - uint[] storage x; + uint[] m_x; + function f() public view { + uint[] storage x = m_x; uint[] memory y; + x; y; } } // ---- -// Warning: (49-65): Uninitialized storage pointer. -// Warning: (49-65): Unused local variable. -// Warning: (75-90): Unused local variable. -// Warning: (19-97): Function state mutability can be restricted to pure diff --git a/test/libsolidity/syntaxTests/parsing/multi_variable_declarations.sol b/test/libsolidity/syntaxTests/parsing/multi_variable_declarations.sol index 1984ed36..56c2e280 100644 --- a/test/libsolidity/syntaxTests/parsing/multi_variable_declarations.sol +++ b/test/libsolidity/syntaxTests/parsing/multi_variable_declarations.sol @@ -2,8 +2,8 @@ contract C { function f() pure public { (uint a, uint b, uint c) = g(); (uint d) = 2; - (, uint e) = 3; - (uint h,) = 4; + (, uint e) = (3,4); + (uint h,) = (4,5); (uint x,,) = g(); (, uint y,) = g(); a; b; c; d; e; h; x; y; @@ -11,5 +11,3 @@ contract C { function g() pure public returns (uint, uint, uint) {} } // ---- -// Warning: (93-107): Different number of components on the left hand side (2) than on the right hand side (1). -// Warning: (111-124): Different number of components on the left hand side (2) than on the right hand side (1). diff --git a/test/libsolidity/syntaxTests/parsing/trailing_dot1.sol b/test/libsolidity/syntaxTests/parsing/trailing_dot1.sol index 7f26242c..d91c385a 100644 --- a/test/libsolidity/syntaxTests/parsing/trailing_dot1.sol +++ b/test/libsolidity/syntaxTests/parsing/trailing_dot1.sol @@ -4,4 +4,4 @@ contract test { uint256 c = 4.e-2; } // ---- -// TypeError: (70-73): Member "e" not found or not visible after argument-dependent lookup in int_const 4 +// TypeError: (70-73): Member "e" not found or not visible after argument-dependent lookup in int_const 4. diff --git a/test/libsolidity/syntaxTests/parsing/tuples.sol b/test/libsolidity/syntaxTests/parsing/tuples.sol index 8266c94f..875556e9 100644 --- a/test/libsolidity/syntaxTests/parsing/tuples.sol +++ b/test/libsolidity/syntaxTests/parsing/tuples.sol @@ -1,16 +1,11 @@ contract C { - function f() public { + function f() public pure { uint a = (1); - (uint b,) = (1,); + (uint b,) = (1,2); (uint c, uint d) = (1, 2 + a); - (uint e,) = (1, 2, b); + (uint e,) = (1, b); (a) = 3; + a;b;c;d;e; } } // ---- -// Warning: (54-70): Different number of components on the left hand side (2) than on the right hand side (1). -// Warning: (107-128): Different number of components on the left hand side (2) than on the right hand side (3). -// Warning: (75-81): Unused local variable. -// Warning: (83-89): Unused local variable. -// Warning: (108-114): Unused local variable. -// Warning: (14-143): Function state mutability can be restricted to pure diff --git a/test/libsolidity/syntaxTests/parsing/two_exact_functions.sol b/test/libsolidity/syntaxTests/parsing/two_exact_functions.sol index 0b3dda56..957740d0 100644 --- a/test/libsolidity/syntaxTests/parsing/two_exact_functions.sol +++ b/test/libsolidity/syntaxTests/parsing/two_exact_functions.sol @@ -2,8 +2,8 @@ // we can't determine whether they match exactly, however // it will throw DeclarationError in following stage. contract test { - function fun(uint a) returns(uint r) { return a; } - function fun(uint a) returns(uint r) { return a; } + function fun(uint a) public returns(uint r) { return a; } + function fun(uint a) public returns(uint r) { return a; } } // ---- -// DeclarationError: (189-239): Function with same name and arguments defined twice. +// DeclarationError: (189-246): Function with same name and arguments defined twice. diff --git a/test/libsolidity/syntaxTests/nameAndTypeResolution/309_rational_unary_plus_assignment.sol b/test/libsolidity/syntaxTests/parsing/unary_plus_expression.sol index a5bdd6c8..5646c43b 100644 --- a/test/libsolidity/syntaxTests/nameAndTypeResolution/309_rational_unary_plus_assignment.sol +++ b/test/libsolidity/syntaxTests/parsing/unary_plus_expression.sol @@ -5,4 +5,4 @@ contract test { } } // ---- -// Warning: (70-72): Use of unary + is deprecated. +// SyntaxError: (70-72): Use of unary + is disallowed. diff --git a/test/libsolidity/syntaxTests/scoping/double_variable_declaration_same_and_disjoint_scope.sol b/test/libsolidity/syntaxTests/scoping/double_variable_declaration_same_and_disjoint_scope.sol new file mode 100644 index 00000000..45c5ff2d --- /dev/null +++ b/test/libsolidity/syntaxTests/scoping/double_variable_declaration_same_and_disjoint_scope.sol @@ -0,0 +1,10 @@ +contract test { + function f() pure public { + uint x; + { uint x; } + uint x; + } +} +// ---- +// Warning: (73-79): This declaration shadows an existing declaration. +// DeclarationError: (91-97): Identifier already declared. diff --git a/test/libsolidity/syntaxTests/scoping/double_variable_declaration_same_scope.sol b/test/libsolidity/syntaxTests/scoping/double_variable_declaration_same_scope.sol new file mode 100644 index 00000000..72c31f73 --- /dev/null +++ b/test/libsolidity/syntaxTests/scoping/double_variable_declaration_same_scope.sol @@ -0,0 +1,8 @@ +contract test { + function f() pure public { + uint x; + uint x; + } +} +// ---- +// DeclarationError: (71-77): Identifier already declared. diff --git a/test/libsolidity/syntaxTests/scoping/poly_variable_declaration_same_scope.sol b/test/libsolidity/syntaxTests/scoping/poly_variable_declaration_same_scope.sol new file mode 100644 index 00000000..e414f611 --- /dev/null +++ b/test/libsolidity/syntaxTests/scoping/poly_variable_declaration_same_scope.sol @@ -0,0 +1,16 @@ +contract test { + function f() pure public { + uint x; + uint x; + uint x; + uint x; + uint x; + uint x; + } +} +// ---- +// DeclarationError: (71-77): Identifier already declared. +// DeclarationError: (87-93): Identifier already declared. +// DeclarationError: (103-109): Identifier already declared. +// DeclarationError: (119-125): Identifier already declared. +// DeclarationError: (135-141): Identifier already declared. diff --git a/test/libsolidity/syntaxTests/structs/recursion/multi_struct_composition.sol b/test/libsolidity/syntaxTests/structs/recursion/multi_struct_composition.sol index 895bb6c5..e8ece3bc 100644 --- a/test/libsolidity/syntaxTests/structs/recursion/multi_struct_composition.sol +++ b/test/libsolidity/syntaxTests/structs/recursion/multi_struct_composition.sol @@ -9,7 +9,7 @@ contract C { struct W { uint x; } - function f(T) public pure { } + function f(T memory) public pure { } } // ---- // Warning: (0-33): Experimental features are turned on. Do not use experimental features on live deployments. diff --git a/test/libsolidity/syntaxTests/structs/recursion/parallel_structs.sol b/test/libsolidity/syntaxTests/structs/recursion/parallel_structs.sol index 96362ef0..e9b25453 100644 --- a/test/libsolidity/syntaxTests/structs/recursion/parallel_structs.sol +++ b/test/libsolidity/syntaxTests/structs/recursion/parallel_structs.sol @@ -9,7 +9,7 @@ contract TestContract SubStruct subStruct1; SubStruct subStruct2; } - function addTestStruct(TestStruct) public pure {} + function addTestStruct(TestStruct memory) public pure {} } // ---- // Warning: (0-33): Experimental features are turned on. Do not use experimental features on live deployments. diff --git a/test/libsolidity/syntaxTests/structs/recursion/return_recursive_structs.sol b/test/libsolidity/syntaxTests/structs/recursion/return_recursive_structs.sol index 4966a731..89d1ddd9 100644 --- a/test/libsolidity/syntaxTests/structs/recursion/return_recursive_structs.sol +++ b/test/libsolidity/syntaxTests/structs/recursion/return_recursive_structs.sol @@ -1,6 +1,6 @@ contract C { struct S { uint a; S[] sub; } - function f() public pure returns (uint, S) { + function f() public pure returns (uint, S memory) { } } // ---- diff --git a/test/libsolidity/syntaxTests/structs/recursion/return_recursive_structs2.sol b/test/libsolidity/syntaxTests/structs/recursion/return_recursive_structs2.sol index 68113924..1c31e180 100644 --- a/test/libsolidity/syntaxTests/structs/recursion/return_recursive_structs2.sol +++ b/test/libsolidity/syntaxTests/structs/recursion/return_recursive_structs2.sol @@ -1,6 +1,6 @@ contract C { struct S { uint a; S[2][] sub; } - function f() public pure returns (uint, S) { + function f() public pure returns (uint, S memory) { } } // ---- diff --git a/test/libsolidity/syntaxTests/structs/recursion/return_recursive_structs3.sol b/test/libsolidity/syntaxTests/structs/recursion/return_recursive_structs3.sol index 47690d9b..0a5b1bc8 100644 --- a/test/libsolidity/syntaxTests/structs/recursion/return_recursive_structs3.sol +++ b/test/libsolidity/syntaxTests/structs/recursion/return_recursive_structs3.sol @@ -1,8 +1,8 @@ contract C { struct S { uint a; S[][][] sub; } struct T { S s; } - function f() public pure returns (uint x, T t) { + function f() public pure returns (uint x, T memory t) { } } // ---- -// TypeError: (119-122): Internal or recursive type is not allowed for public or external functions. +// TypeError: (119-129): Internal or recursive type is not allowed for public or external functions. diff --git a/test/libsolidity/syntaxTests/structs/recursion/struct_definition_directly_recursive_dynamic_array.sol b/test/libsolidity/syntaxTests/structs/recursion/struct_definition_directly_recursive_dynamic_array.sol new file mode 100644 index 00000000..d847f17c --- /dev/null +++ b/test/libsolidity/syntaxTests/structs/recursion/struct_definition_directly_recursive_dynamic_array.sol @@ -0,0 +1,7 @@ +contract Test { + struct MyStructName { + address addr; + MyStructName[] x; + } +} +// ---- diff --git a/test/libsolidity/syntaxTests/structs/recursion/struct_definition_directly_recursive_fixed_array.sol b/test/libsolidity/syntaxTests/structs/recursion/struct_definition_directly_recursive_fixed_array.sol new file mode 100644 index 00000000..126dda4f --- /dev/null +++ b/test/libsolidity/syntaxTests/structs/recursion/struct_definition_directly_recursive_fixed_array.sol @@ -0,0 +1,8 @@ +contract Test { + struct MyStructName { + address addr; + MyStructName[1] x; + } +} +// ---- +// TypeError: (20-96): Recursive struct definition. diff --git a/test/libsolidity/syntaxTests/structs/recursion/struct_definition_indirectly_recursive_complex.sol b/test/libsolidity/syntaxTests/structs/recursion/struct_definition_indirectly_recursive_complex.sol new file mode 100644 index 00000000..6d35a5d3 --- /dev/null +++ b/test/libsolidity/syntaxTests/structs/recursion/struct_definition_indirectly_recursive_complex.sol @@ -0,0 +1,18 @@ +contract Test { + struct MyStructName1 { + address addr; + uint256 count; + MyStructName4[1] x; + } + struct MyStructName2 { + MyStructName1 x; + } + struct MyStructName3 { + MyStructName2[1] x; + } + struct MyStructName4 { + MyStructName3 x; + } +} +// ---- +// TypeError: (20-121): Recursive struct definition. diff --git a/test/libsolidity/syntaxTests/structs/recursion/struct_definition_indirectly_recursive_dynamic_array1.sol b/test/libsolidity/syntaxTests/structs/recursion/struct_definition_indirectly_recursive_dynamic_array1.sol new file mode 100644 index 00000000..10d7de2c --- /dev/null +++ b/test/libsolidity/syntaxTests/structs/recursion/struct_definition_indirectly_recursive_dynamic_array1.sol @@ -0,0 +1,11 @@ +contract Test { + struct MyStructName1 { + address addr; + uint256 count; + MyStructName2[] x; + } + struct MyStructName2 { + MyStructName1 x; + } +} +// ---- diff --git a/test/libsolidity/syntaxTests/structs/recursion/struct_definition_indirectly_recursive_dynamic_array2.sol b/test/libsolidity/syntaxTests/structs/recursion/struct_definition_indirectly_recursive_dynamic_array2.sol new file mode 100644 index 00000000..f20510ca --- /dev/null +++ b/test/libsolidity/syntaxTests/structs/recursion/struct_definition_indirectly_recursive_dynamic_array2.sol @@ -0,0 +1,11 @@ +contract Test { + struct MyStructName1 { + address addr; + uint256 count; + MyStructName2 x; + } + struct MyStructName2 { + MyStructName1[] x; + } +} +// ---- diff --git a/test/libsolidity/syntaxTests/structs/recursion/struct_definition_indirectly_recursive_dynamic_array3.sol b/test/libsolidity/syntaxTests/structs/recursion/struct_definition_indirectly_recursive_dynamic_array3.sol new file mode 100644 index 00000000..69747e71 --- /dev/null +++ b/test/libsolidity/syntaxTests/structs/recursion/struct_definition_indirectly_recursive_dynamic_array3.sol @@ -0,0 +1,11 @@ +contract Test { + struct MyStructName1 { + address addr; + uint256 count; + MyStructName2[] x; + } + struct MyStructName2 { + MyStructName1[] x; + } +} +// ---- diff --git a/test/libsolidity/syntaxTests/structs/recursion/struct_definition_indirectly_recursive_dynamic_multi_array.sol b/test/libsolidity/syntaxTests/structs/recursion/struct_definition_indirectly_recursive_dynamic_multi_array.sol new file mode 100644 index 00000000..b3507828 --- /dev/null +++ b/test/libsolidity/syntaxTests/structs/recursion/struct_definition_indirectly_recursive_dynamic_multi_array.sol @@ -0,0 +1,21 @@ +contract Test { + struct S1 { + S2[1][] x; + } + struct S2 { + S1 x; + } + struct T1 { + T2[][1] x; + } + struct T2 { + T1 x; + } + struct R1 { + R2[][] x; + } + struct R2 { + R1 x; + } +} +// ---- diff --git a/test/libsolidity/syntaxTests/structs/recursion/struct_definition_indirectly_recursive_fixed_array1.sol b/test/libsolidity/syntaxTests/structs/recursion/struct_definition_indirectly_recursive_fixed_array1.sol new file mode 100644 index 00000000..2c0b90ec --- /dev/null +++ b/test/libsolidity/syntaxTests/structs/recursion/struct_definition_indirectly_recursive_fixed_array1.sol @@ -0,0 +1,12 @@ +contract Test { + struct MyStructName1 { + address addr; + uint256 count; + MyStructName2[1] x; + } + struct MyStructName2 { + MyStructName1 x; + } +} +// ---- +// TypeError: (20-121): Recursive struct definition. diff --git a/test/libsolidity/syntaxTests/structs/recursion/struct_definition_indirectly_recursive_fixed_array2.sol b/test/libsolidity/syntaxTests/structs/recursion/struct_definition_indirectly_recursive_fixed_array2.sol new file mode 100644 index 00000000..3178e569 --- /dev/null +++ b/test/libsolidity/syntaxTests/structs/recursion/struct_definition_indirectly_recursive_fixed_array2.sol @@ -0,0 +1,12 @@ +contract Test { + struct MyStructName1 { + address addr; + uint256 count; + MyStructName2 x; + } + struct MyStructName2 { + MyStructName1[1] x; + } +} +// ---- +// TypeError: (20-118): Recursive struct definition. diff --git a/test/libsolidity/syntaxTests/structs/recursion/struct_definition_indirectly_recursive_fixed_array3.sol b/test/libsolidity/syntaxTests/structs/recursion/struct_definition_indirectly_recursive_fixed_array3.sol new file mode 100644 index 00000000..e34cf9bc --- /dev/null +++ b/test/libsolidity/syntaxTests/structs/recursion/struct_definition_indirectly_recursive_fixed_array3.sol @@ -0,0 +1,12 @@ +contract Test { + struct MyStructName1 { + address addr; + uint256 count; + MyStructName2[1] x; + } + struct MyStructName2 { + MyStructName1[1] x; + } +} +// ---- +// TypeError: (20-121): Recursive struct definition. diff --git a/test/libsolidity/syntaxTests/structs/recursion/struct_definition_indirectly_recursive_fixed_multi_array.sol b/test/libsolidity/syntaxTests/structs/recursion/struct_definition_indirectly_recursive_fixed_multi_array.sol new file mode 100644 index 00000000..ed659b6e --- /dev/null +++ b/test/libsolidity/syntaxTests/structs/recursion/struct_definition_indirectly_recursive_fixed_multi_array.sol @@ -0,0 +1,12 @@ +contract Test { + struct MyStructName1 { + address addr; + uint256 count; + MyStructName2[1][1] x; + } + struct MyStructName2 { + MyStructName1 x; + } +} +// ---- +// TypeError: (20-124): Recursive struct definition. diff --git a/test/libsolidity/syntaxTests/structs/recursion/struct_definition_not_really_recursive_array.sol b/test/libsolidity/syntaxTests/structs/recursion/struct_definition_not_really_recursive_array.sol new file mode 100644 index 00000000..b2053b8a --- /dev/null +++ b/test/libsolidity/syntaxTests/structs/recursion/struct_definition_not_really_recursive_array.sol @@ -0,0 +1,4 @@ +contract Test { + struct S1 { uint a; } + struct S2 { S1[1] x; S1[1] y; } +} diff --git a/test/libsolidity/syntaxTests/tight_packing_literals.sol b/test/libsolidity/syntaxTests/tight_packing_literals.sol index be8482ff..0fc1fc08 100644 --- a/test/libsolidity/syntaxTests/tight_packing_literals.sol +++ b/test/libsolidity/syntaxTests/tight_packing_literals.sol @@ -1,8 +1,8 @@ contract C { - function k() pure public returns (bytes) { + function k() pure public returns (bytes memory) { return abi.encodePacked(1); } } // ---- -// Warning: (92-93): The type of "int_const 1" was inferred as uint8. This is probably not desired. Use an explicit type to silence this warning. +// TypeError: (99-100): Cannot perform packed encoding for a literal. Please convert it to an explicit type first. diff --git a/test/libsolidity/syntaxTests/tight_packing_literals_050.sol b/test/libsolidity/syntaxTests/tight_packing_literals_050.sol deleted file mode 100644 index 4e6210c6..00000000 --- a/test/libsolidity/syntaxTests/tight_packing_literals_050.sol +++ /dev/null @@ -1,9 +0,0 @@ -pragma experimental "v0.5.0"; -contract C { - function k() pure public returns (bytes) { - return abi.encodePacked(1); - } -} - -// ---- -// TypeError: (122-123): Cannot perform packed encoding for a literal. Please convert it to an explicit type first. diff --git a/test/libsolidity/syntaxTests/tight_packing_literals_fine.sol b/test/libsolidity/syntaxTests/tight_packing_literals_fine.sol index 7bbc36d0..45fc1f72 100644 --- a/test/libsolidity/syntaxTests/tight_packing_literals_fine.sol +++ b/test/libsolidity/syntaxTests/tight_packing_literals_fine.sol @@ -1,8 +1,8 @@ contract C { - function k() pure public returns (bytes) { + function k() pure public returns (bytes memory) { return abi.encodePacked(uint8(1)); } - function l() pure public returns (bytes) { + function l() pure public returns (bytes memory) { return abi.encode(1); } } diff --git a/test/libsolidity/syntaxTests/tupleAssignments/err_fill_assignment.sol b/test/libsolidity/syntaxTests/tupleAssignments/err_fill_assignment.sol new file mode 100644 index 00000000..32b381bb --- /dev/null +++ b/test/libsolidity/syntaxTests/tupleAssignments/err_fill_assignment.sol @@ -0,0 +1,11 @@ +contract C { + function f() public pure returns (uint, uint, bytes32) { + uint a; + bytes32 b; + (a,) = f(); + (,b) = f(); + } +} +// ---- +// TypeError: (103-106): Type tuple(uint256,uint256,bytes32) is not implicitly convertible to expected type tuple(uint256,). +// TypeError: (117-120): Type tuple(uint256,uint256,bytes32) is not implicitly convertible to expected type tuple(,bytes32). diff --git a/test/libsolidity/syntaxTests/tupleAssignments/warn_multiple_storage_storage_copies_fill_left.sol b/test/libsolidity/syntaxTests/tupleAssignments/err_multiple_storage_storage_copies_fill_left.sol index b2979804..902d8b98 100644 --- a/test/libsolidity/syntaxTests/tupleAssignments/warn_multiple_storage_storage_copies_fill_left.sol +++ b/test/libsolidity/syntaxTests/tupleAssignments/err_multiple_storage_storage_copies_fill_left.sol @@ -6,5 +6,5 @@ contract C { } } // ---- +// TypeError: (89-101): Type tuple(int_const 1,int_const 2,struct C.S storage ref,struct C.S storage ref) is not implicitly convertible to expected type tuple(,struct C.S storage ref,struct C.S storage ref). // Warning: (79-101): This assignment performs two copies to storage. Since storage copies do not first copy to a temporary location, one of them might be overwritten before the second is executed and thus may have unexpected effects. It is safer to perform the copies separately or assign to storage pointers first. -// Warning: (79-101): Different number of components on the left hand side (3) than on the right hand side (4). diff --git a/test/libsolidity/syntaxTests/tupleAssignments/warn_multiple_storage_storage_copies_fill_right.sol b/test/libsolidity/syntaxTests/tupleAssignments/err_multiple_storage_storage_copies_fill_right.sol index aa35d7d4..51556aab 100644 --- a/test/libsolidity/syntaxTests/tupleAssignments/warn_multiple_storage_storage_copies_fill_right.sol +++ b/test/libsolidity/syntaxTests/tupleAssignments/err_multiple_storage_storage_copies_fill_right.sol @@ -6,5 +6,5 @@ contract C { } } // ---- +// TypeError: (90-102): Type tuple(struct C.S storage ref,struct C.S storage ref,int_const 1,int_const 2) is not implicitly convertible to expected type tuple(struct C.S storage ref,struct C.S storage ref,). // Warning: (79-102): This assignment performs two copies to storage. Since storage copies do not first copy to a temporary location, one of them might be overwritten before the second is executed and thus may have unexpected effects. It is safer to perform the copies separately or assign to storage pointers first. -// Warning: (79-102): Different number of components on the left hand side (3) than on the right hand side (4). diff --git a/test/libsolidity/syntaxTests/tupleAssignments/error_fill.sol b/test/libsolidity/syntaxTests/tupleAssignments/error_fill.sol index 5b7f870b..ae722391 100644 --- a/test/libsolidity/syntaxTests/tupleAssignments/error_fill.sol +++ b/test/libsolidity/syntaxTests/tupleAssignments/error_fill.sol @@ -8,5 +8,5 @@ contract C { } } // ---- -// TypeError: (126-136): Different number of components on the left hand side (2) than on the right hand side (3). -// TypeError: (140-150): Different number of components on the left hand side (2) than on the right hand side (3). +// TypeError: (133-136): Type tuple(uint256,uint256,bytes32) is not implicitly convertible to expected type tuple(uint256,). +// TypeError: (147-150): Type tuple(uint256,uint256,bytes32) is not implicitly convertible to expected type tuple(,bytes32). diff --git a/test/libsolidity/syntaxTests/tupleAssignments/nowarn_explicit_singleton_token_expression.sol b/test/libsolidity/syntaxTests/tupleAssignments/nowarn_explicit_singleton_token_expression.sol deleted file mode 100644 index 3262781b..00000000 --- a/test/libsolidity/syntaxTests/tupleAssignments/nowarn_explicit_singleton_token_expression.sol +++ /dev/null @@ -1,8 +0,0 @@ -contract C { - function f() public pure { - uint a; - (a,) = (uint(1),); - } -} -// ---- -// Warning: (53-70): Different number of components on the left hand side (2) than on the right hand side (1). diff --git a/test/libsolidity/syntaxTests/tupleAssignments/warn_fill_assignment.sol b/test/libsolidity/syntaxTests/tupleAssignments/warn_fill_assignment.sol deleted file mode 100644 index a079a509..00000000 --- a/test/libsolidity/syntaxTests/tupleAssignments/warn_fill_assignment.sol +++ /dev/null @@ -1,11 +0,0 @@ -contract C { - function f() public pure returns (uint, uint, bytes32) { - uint a; - bytes32 b; - (a,) = f(); - (,b) = f(); - } -} -// ---- -// Warning: (96-106): Different number of components on the left hand side (2) than on the right hand side (3). -// Warning: (110-120): Different number of components on the left hand side (2) than on the right hand side (3). diff --git a/test/libsolidity/syntaxTests/tupleAssignments/warn_fill_vardecl.sol b/test/libsolidity/syntaxTests/tupleAssignments/warn_fill_vardecl.sol deleted file mode 100644 index 23484567..00000000 --- a/test/libsolidity/syntaxTests/tupleAssignments/warn_fill_vardecl.sol +++ /dev/null @@ -1,8 +0,0 @@ -contract C { - function f() public pure returns (uint, uint, uint, uint) { - (uint a, uint b,) = f(); - a; b; - } -} -// ---- -// Warning: (76-99): Different number of components on the left hand side (3) than on the right hand side (4). diff --git a/test/libsolidity/syntaxTests/types/address_members_in_contract.sol b/test/libsolidity/syntaxTests/types/address_members_in_contract.sol new file mode 100644 index 00000000..eafc8268 --- /dev/null +++ b/test/libsolidity/syntaxTests/types/address_members_in_contract.sol @@ -0,0 +1,6 @@ +contract C { + function f() public returns (C) { return this; } + function g() public returns (uint) { return f().balance(); } +} +// ---- +// TypeError: (114-125): Member "balance" not found or not visible after argument-dependent lookup in contract C. Use "address(...).balance" to access this address member. diff --git a/test/libsolidity/syntaxTests/types/empty_tuple_function.sol b/test/libsolidity/syntaxTests/types/empty_tuple_function.sol index 05b54442..ff31d440 100644 --- a/test/libsolidity/syntaxTests/types/empty_tuple_function.sol +++ b/test/libsolidity/syntaxTests/types/empty_tuple_function.sol @@ -8,5 +8,5 @@ contract C { } } // ---- -// Warning: (162-165): Tuple component cannot be empty. -// Warning: (181-184): Tuple component cannot be empty. +// TypeError: (162-165): Tuple component cannot be empty. +// TypeError: (181-184): Tuple component cannot be empty. diff --git a/test/libsolidity/syntaxTests/types/empty_tuple_function_050.sol b/test/libsolidity/syntaxTests/types/empty_tuple_function_050.sol deleted file mode 100644 index c4b9e03f..00000000 --- a/test/libsolidity/syntaxTests/types/empty_tuple_function_050.sol +++ /dev/null @@ -1,11 +0,0 @@ -pragma experimental "v0.5.0"; -contract C { - function f() private pure {} - function a() public pure { - bool x = true; - bool y = true; - (x) ? (f(), y = false) : (f(), y = false); - } -} -// ---- -// TypeError: (168-171): Tuple component cannot be empty. diff --git a/test/libsolidity/syntaxTests/types/empty_tuple_lvalue.sol b/test/libsolidity/syntaxTests/types/empty_tuple_lvalue.sol index cba30c1b..3d252f0b 100644 --- a/test/libsolidity/syntaxTests/types/empty_tuple_lvalue.sol +++ b/test/libsolidity/syntaxTests/types/empty_tuple_lvalue.sol @@ -8,6 +8,6 @@ contract C { } } // ---- -// Warning: (146-149): Tuple component cannot be empty. -// Warning: (151-154): Tuple component cannot be empty. +// TypeError: (146-149): Tuple component cannot be empty. +// TypeError: (151-154): Tuple component cannot be empty. // TypeError: (145-155): Type tuple(tuple(),tuple()) is not implicitly convertible to expected type tuple(uint256,uint256). diff --git a/test/libsolidity/syntaxTests/types/empty_tuple_lvalue_050.sol b/test/libsolidity/syntaxTests/types/empty_tuple_lvalue_050.sol deleted file mode 100644 index b0691778..00000000 --- a/test/libsolidity/syntaxTests/types/empty_tuple_lvalue_050.sol +++ /dev/null @@ -1,11 +0,0 @@ -pragma experimental "v0.5.0"; -contract C { - function f() private pure {} - function a() public { - uint x; - uint y; - (x, y) = (f(), f()); - } -} -// ---- -// TypeError: (152-155): Tuple component cannot be empty. diff --git a/test/libsolidity/syntaxTests/types/no_singleton_tuple.sol b/test/libsolidity/syntaxTests/types/no_singleton_tuple.sol new file mode 100644 index 00000000..62a58f83 --- /dev/null +++ b/test/libsolidity/syntaxTests/types/no_singleton_tuple.sol @@ -0,0 +1,8 @@ +contract C { + function f() public pure { + uint a; + (a,) = (uint(1),); + } +} +// ---- +// TypeError: (60-70): Tuple component cannot be empty. diff --git a/test/libsolidity/syntaxTests/types/rational_number_exp_limit.sol b/test/libsolidity/syntaxTests/types/rational_number_exp_limit_fail.sol index 6785f580..058db2e9 100644 --- a/test/libsolidity/syntaxTests/types/rational_number_exp_limit.sol +++ b/test/libsolidity/syntaxTests/types/rational_number_exp_limit_fail.sol @@ -4,9 +4,6 @@ contract c { a = 4 ** 4 ** 2 ** 4 ** 4 ** 4 ** 4; a = -4 ** 4 ** 2 ** 4 ** 4 ** 4 ** 4 ** 4; a = 4 ** (-(2 ** 4 ** 4 ** 4 ** 4 ** 4)); - a = 0 ** 1E1233; // fine - a = 1 ** 1E1233; // fine - a = -1 ** 1E1233; // fine a = 2 ** 1E1233; a = -2 ** 1E1233; a = 2 ** -1E1233; @@ -28,23 +25,23 @@ contract c { // TypeError: (116-153): Operator ** not compatible with types int_const 1797...(301 digits omitted)...7216 and int_const 4 // TypeError: (116-153): Type int_const 1797...(301 digits omitted)...7216 is not implicitly convertible to expected type int256. // TypeError: (167-203): Operator ** not compatible with types int_const 4 and int_const -179...(302 digits omitted)...7216 -// TypeError: (317-328): Operator ** not compatible with types int_const 2 and int_const 1000...(1226 digits omitted)...0000 -// TypeError: (342-354): Operator ** not compatible with types int_const -2 and int_const 1000...(1226 digits omitted)...0000 -// TypeError: (368-380): Operator ** not compatible with types int_const 2 and int_const -100...(1227 digits omitted)...0000 -// TypeError: (394-407): Operator ** not compatible with types int_const -2 and int_const -100...(1227 digits omitted)...0000 -// TypeError: (421-432): Operator ** not compatible with types int_const 1000...(1226 digits omitted)...0000 and int_const 2 -// TypeError: (421-432): Type int_const 1000...(1226 digits omitted)...0000 is not implicitly convertible to expected type int256. -// TypeError: (446-458): Operator ** not compatible with types int_const -100...(1227 digits omitted)...0000 and int_const 2 -// TypeError: (446-458): Type int_const -100...(1227 digits omitted)...0000 is not implicitly convertible to expected type int256. -// TypeError: (472-484): Operator ** not compatible with types int_const 1000...(1226 digits omitted)...0000 and int_const -2 -// TypeError: (472-484): Type int_const 1000...(1226 digits omitted)...0000 is not implicitly convertible to expected type int256. -// TypeError: (498-511): Operator ** not compatible with types int_const -100...(1227 digits omitted)...0000 and int_const -2 -// TypeError: (498-511): Type int_const -100...(1227 digits omitted)...0000 is not implicitly convertible to expected type int256. -// TypeError: (525-541): Operator ** not compatible with types int_const 1000...(1226 digits omitted)...0000 and int_const 1000...(1226 digits omitted)...0000 -// TypeError: (525-541): Type int_const 1000...(1226 digits omitted)...0000 is not implicitly convertible to expected type int256. -// TypeError: (555-572): Operator ** not compatible with types int_const 1000...(1226 digits omitted)...0000 and int_const -100...(1227 digits omitted)...0000 -// TypeError: (555-572): Type int_const 1000...(1226 digits omitted)...0000 is not implicitly convertible to expected type int256. -// TypeError: (586-603): Operator ** not compatible with types int_const -100...(1227 digits omitted)...0000 and int_const 1000...(1226 digits omitted)...0000 -// TypeError: (586-603): Type int_const -100...(1227 digits omitted)...0000 is not implicitly convertible to expected type int256. -// TypeError: (617-635): Operator ** not compatible with types int_const -100...(1227 digits omitted)...0000 and int_const -100...(1227 digits omitted)...0000 -// TypeError: (617-635): Type int_const -100...(1227 digits omitted)...0000 is not implicitly convertible to expected type int256. +// TypeError: (217-228): Operator ** not compatible with types int_const 2 and int_const 1000...(1226 digits omitted)...0000 +// TypeError: (242-254): Operator ** not compatible with types int_const -2 and int_const 1000...(1226 digits omitted)...0000 +// TypeError: (268-280): Operator ** not compatible with types int_const 2 and int_const -100...(1227 digits omitted)...0000 +// TypeError: (294-307): Operator ** not compatible with types int_const -2 and int_const -100...(1227 digits omitted)...0000 +// TypeError: (321-332): Operator ** not compatible with types int_const 1000...(1226 digits omitted)...0000 and int_const 2 +// TypeError: (321-332): Type int_const 1000...(1226 digits omitted)...0000 is not implicitly convertible to expected type int256. +// TypeError: (346-358): Operator ** not compatible with types int_const -100...(1227 digits omitted)...0000 and int_const 2 +// TypeError: (346-358): Type int_const -100...(1227 digits omitted)...0000 is not implicitly convertible to expected type int256. +// TypeError: (372-384): Operator ** not compatible with types int_const 1000...(1226 digits omitted)...0000 and int_const -2 +// TypeError: (372-384): Type int_const 1000...(1226 digits omitted)...0000 is not implicitly convertible to expected type int256. +// TypeError: (398-411): Operator ** not compatible with types int_const -100...(1227 digits omitted)...0000 and int_const -2 +// TypeError: (398-411): Type int_const -100...(1227 digits omitted)...0000 is not implicitly convertible to expected type int256. +// TypeError: (425-441): Operator ** not compatible with types int_const 1000...(1226 digits omitted)...0000 and int_const 1000...(1226 digits omitted)...0000 +// TypeError: (425-441): Type int_const 1000...(1226 digits omitted)...0000 is not implicitly convertible to expected type int256. +// TypeError: (455-472): Operator ** not compatible with types int_const 1000...(1226 digits omitted)...0000 and int_const -100...(1227 digits omitted)...0000 +// TypeError: (455-472): Type int_const 1000...(1226 digits omitted)...0000 is not implicitly convertible to expected type int256. +// TypeError: (486-503): Operator ** not compatible with types int_const -100...(1227 digits omitted)...0000 and int_const 1000...(1226 digits omitted)...0000 +// TypeError: (486-503): Type int_const -100...(1227 digits omitted)...0000 is not implicitly convertible to expected type int256. +// TypeError: (517-535): Operator ** not compatible with types int_const -100...(1227 digits omitted)...0000 and int_const -100...(1227 digits omitted)...0000 +// TypeError: (517-535): Type int_const -100...(1227 digits omitted)...0000 is not implicitly convertible to expected type int256. diff --git a/test/libsolidity/syntaxTests/types/rational_number_exp_limit_fine.sol b/test/libsolidity/syntaxTests/types/rational_number_exp_limit_fine.sol new file mode 100644 index 00000000..66d02eb9 --- /dev/null +++ b/test/libsolidity/syntaxTests/types/rational_number_exp_limit_fine.sol @@ -0,0 +1,9 @@ +contract c { + function f() public pure { + int a; + a = 0 ** 1E1233; + a = 1 ** 1E1233; + a = -1 ** 1E1233; + a = 0E123456789; + } +} diff --git a/test/libsolidity/syntaxTests/types/unnamed_tuple_decl.sol b/test/libsolidity/syntaxTests/types/unnamed_tuple_decl.sol new file mode 100644 index 00000000..7ed92b58 --- /dev/null +++ b/test/libsolidity/syntaxTests/types/unnamed_tuple_decl.sol @@ -0,0 +1,18 @@ +pragma solidity ^0.4.20; + +contract C { + function f() internal pure {} + function g() internal pure returns (uint) { return 1; } + function h() internal pure returns (uint, uint) { return (1, 2); } + + function test() internal pure { + var () = f(); + var () = g(); + var (,) = h(); + } +} + +// ---- +// SyntaxError: (249-261): The use of the "var" keyword is disallowed. The declaration part of the statement can be removed, since it is empty. +// SyntaxError: (271-283): The use of the "var" keyword is disallowed. The declaration part of the statement can be removed, since it is empty. +// SyntaxError: (293-306): The use of the "var" keyword is disallowed. The declaration part of the statement can be removed, since it is empty. diff --git a/test/libsolidity/syntaxTests/types/var_type_suggest.sol b/test/libsolidity/syntaxTests/types/var_type_suggest.sol new file mode 100644 index 00000000..176fab96 --- /dev/null +++ b/test/libsolidity/syntaxTests/types/var_type_suggest.sol @@ -0,0 +1,23 @@ +contract C { + function h() internal pure returns (uint, uint, uint) { + return (1, 2, 4); + } + function g(uint x) internal pure returns (uint) { + return x; + } + function f() internal pure { + var i = 31415; + var t = "string"; + var g2 = g; + var myblockhash = block.blockhash; + var (a, b) = (2, "troi"); + var (x,, z) = h(); + } +} +// ---- +// SyntaxError: (224-237): Use of the "var" keyword is disallowed. Use explicit declaration `uint16 i = ...´ instead. +// SyntaxError: (247-263): Use of the "var" keyword is disallowed. Use explicit declaration `string memory t = ...´ instead. +// SyntaxError: (273-283): Use of the "var" keyword is disallowed. Use explicit declaration `function (uint256) pure returns (uint256) g2 = ...´ instead. +// SyntaxError: (293-326): Use of the "var" keyword is disallowed. Type cannot be expressed in syntax. +// SyntaxError: (336-360): Use of the "var" keyword is disallowed. Use explicit declaration `(uint8 a, string memory b) = ...´ instead. +// SyntaxError: (370-387): Use of the "var" keyword is disallowed. Use explicit declaration `(uint256 x, , uint256 z) = ...´ instead. diff --git a/test/libsolidity/syntaxTests/viewPure/view_pure_abi_encode.sol b/test/libsolidity/syntaxTests/viewPure/view_pure_abi_encode.sol index ca7db42e..e0e031c2 100644 --- a/test/libsolidity/syntaxTests/viewPure/view_pure_abi_encode.sol +++ b/test/libsolidity/syntaxTests/viewPure/view_pure_abi_encode.sol @@ -1,5 +1,5 @@ contract C { - function f() pure public returns (bytes r) { + function f() pure public returns (bytes memory r) { r = abi.encode(1, 2); r = abi.encodePacked(f()); r = abi.encodeWithSelector(0x12345678, 1); diff --git a/test/libsolidity/syntaxTests/viewPure/view_pure_abi_encode_arguments.sol b/test/libsolidity/syntaxTests/viewPure/view_pure_abi_encode_arguments.sol index 547362c3..cc845d51 100644 --- a/test/libsolidity/syntaxTests/viewPure/view_pure_abi_encode_arguments.sol +++ b/test/libsolidity/syntaxTests/viewPure/view_pure_abi_encode_arguments.sol @@ -3,34 +3,34 @@ contract C { function gView() public view returns (uint) { return x; } function gNonPayable() public returns (uint) { x = 4; return 0; } - function f1() view public returns (bytes) { + function f1() view public returns (bytes memory) { return abi.encode(gView()); } - function f2() view public returns (bytes) { + function f2() view public returns (bytes memory) { return abi.encodePacked(gView()); } - function f3() view public returns (bytes) { + function f3() view public returns (bytes memory) { return abi.encodeWithSelector(0x12345678, gView()); } - function f4() view public returns (bytes) { + function f4() view public returns (bytes memory) { return abi.encodeWithSignature("f(uint256)", gView()); } - function g1() public returns (bytes) { + function g1() public returns (bytes memory) { return abi.encode(gNonPayable()); } - function g2() public returns (bytes) { + function g2() public returns (bytes memory) { return abi.encodePacked(gNonPayable()); } - function g3() public returns (bytes) { + function g3() public returns (bytes memory) { return abi.encodeWithSelector(0x12345678, gNonPayable()); } - function g4() public returns (bytes) { + function g4() public returns (bytes memory) { return abi.encodeWithSignature("f(uint256)", gNonPayable()); } // This will generate the only warning. - function check() public returns (bytes) { + function check() public returns (bytes memory) { return abi.encode(2); } } // ---- -// Warning: (1044-1121): Function state mutability can be restricted to pure +// Warning: (1100-1184): Function state mutability can be restricted to pure diff --git a/test/libsolidity/syntaxTests/visibility/function_no_visibility.sol b/test/libsolidity/syntaxTests/visibility/function_no_visibility.sol index ecc36f04..4fc7900f 100644 --- a/test/libsolidity/syntaxTests/visibility/function_no_visibility.sol +++ b/test/libsolidity/syntaxTests/visibility/function_no_visibility.sol @@ -2,4 +2,4 @@ contract C { function f() pure { } } // ---- -// Warning: (17-38): No visibility specified. Defaulting to "public". +// SyntaxError: (17-38): No visibility specified. Did you intend to add "public"? diff --git a/test/libsolidity/syntaxTests/visibility/function_no_visibility_050.sol b/test/libsolidity/syntaxTests/visibility/function_no_visibility_050.sol deleted file mode 100644 index ec7c0937..00000000 --- a/test/libsolidity/syntaxTests/visibility/function_no_visibility_050.sol +++ /dev/null @@ -1,6 +0,0 @@ -pragma experimental "v0.5.0"; -contract C { - function f() pure { } -} -// ---- -// SyntaxError: (47-68): No visibility specified. diff --git a/test/libsolidity/syntaxTests/visibility/interface/function_default.sol b/test/libsolidity/syntaxTests/visibility/interface/function_default.sol index 72ce3b40..b7e96e5e 100644 --- a/test/libsolidity/syntaxTests/visibility/interface/function_default.sol +++ b/test/libsolidity/syntaxTests/visibility/interface/function_default.sol @@ -2,5 +2,5 @@ interface I { function f(); } // ---- -// Warning: (15-28): Functions in interfaces should be declared external. -// Warning: (15-28): No visibility specified. Defaulting to "public". In interfaces it defaults to external. +// SyntaxError: (15-28): No visibility specified. Did you intend to add "external"? +// TypeError: (15-28): Functions in interfaces must be declared external. diff --git a/test/libsolidity/syntaxTests/visibility/interface/function_default050.sol b/test/libsolidity/syntaxTests/visibility/interface/function_default050.sol deleted file mode 100644 index 513df26b..00000000 --- a/test/libsolidity/syntaxTests/visibility/interface/function_default050.sol +++ /dev/null @@ -1,7 +0,0 @@ -pragma experimental "v0.5.0"; -interface I { - function f(); -} -// ---- -// SyntaxError: (45-58): No visibility specified. -// TypeError: (45-58): Functions in interfaces must be declared external. diff --git a/test/libsolidity/syntaxTests/visibility/interface/function_internal.sol b/test/libsolidity/syntaxTests/visibility/interface/function_internal.sol index ac62e69b..06c1547a 100644 --- a/test/libsolidity/syntaxTests/visibility/interface/function_internal.sol +++ b/test/libsolidity/syntaxTests/visibility/interface/function_internal.sol @@ -2,4 +2,4 @@ interface I { function f() internal; } // ---- -// TypeError: (15-37): Functions in interfaces cannot be internal or private. +// TypeError: (15-37): Functions in interfaces must be declared external. diff --git a/test/libsolidity/syntaxTests/visibility/interface/function_private.sol b/test/libsolidity/syntaxTests/visibility/interface/function_private.sol index 881e647e..98198c3d 100644 --- a/test/libsolidity/syntaxTests/visibility/interface/function_private.sol +++ b/test/libsolidity/syntaxTests/visibility/interface/function_private.sol @@ -2,4 +2,4 @@ interface I { function f() private; } // ---- -// TypeError: (15-36): Functions in interfaces cannot be internal or private. +// TypeError: (15-36): Functions in interfaces must be declared external. diff --git a/test/libsolidity/syntaxTests/visibility/interface/function_public.sol b/test/libsolidity/syntaxTests/visibility/interface/function_public.sol index 891d9fdf..a8cea199 100644 --- a/test/libsolidity/syntaxTests/visibility/interface/function_public.sol +++ b/test/libsolidity/syntaxTests/visibility/interface/function_public.sol @@ -2,4 +2,4 @@ interface I { function f() public; } // ---- -// Warning: (15-35): Functions in interfaces should be declared external. +// TypeError: (15-35): Functions in interfaces must be declared external. diff --git a/test/libsolidity/syntaxTests/visibility/interface/interface_contract_function_default.sol b/test/libsolidity/syntaxTests/visibility/interface/interface_contract_function_default.sol new file mode 100644 index 00000000..b1a820ed --- /dev/null +++ b/test/libsolidity/syntaxTests/visibility/interface/interface_contract_function_default.sol @@ -0,0 +1,12 @@ +// State of the syntax checker has to be reset after the interface +// was visited. The suggested visibility for g() should not be external. +interface I { + function f(); +} +contract C { + function g(); +} +// ---- +// SyntaxError: (158-171): No visibility specified. Did you intend to add "external"? +// SyntaxError: (191-204): No visibility specified. Did you intend to add "public"? +// TypeError: (158-171): Functions in interfaces must be declared external. diff --git a/test/tools/fuzzer.cpp b/test/tools/fuzzer.cpp index 71f38b67..a5a63854 100644 --- a/test/tools/fuzzer.cpp +++ b/test/tools/fuzzer.cpp @@ -135,6 +135,10 @@ void testCompiler(bool optimize) for (Json::Value const& error: outputJson["errors"]) { string invalid = contains(error.asString(), vector<string>{ + // StandardJSON error types + "Exception", + "InternalCompilerError", + // Old-school error messages "Internal compiler error", "Exception during compilation", "Unknown exception during compilation", diff --git a/test/tools/isoltest.cpp b/test/tools/isoltest.cpp index 41dff148..ed4f148e 100644 --- a/test/tools/isoltest.cpp +++ b/test/tools/isoltest.cpp @@ -29,6 +29,10 @@ #include <fstream> #include <queue> +#if defined(_WIN32) +#include <windows.h> +#endif + using namespace dev; using namespace dev::solidity; using namespace dev::solidity::test; @@ -242,8 +246,30 @@ TestStats TestTool::processPath( } +void setupTerminal() +{ +#if defined(_WIN32) && defined(ENABLE_VIRTUAL_TERMINAL_PROCESSING) + // Set output mode to handle virtual terminal (ANSI escape sequences) + // ignore any error, as this is just a "nice-to-have" + // only windows needs to be taken care of, as other platforms (Linux/OSX) support them natively. + HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE); + if (hOut == INVALID_HANDLE_VALUE) + return; + + DWORD dwMode = 0; + if (!GetConsoleMode(hOut, &dwMode)) + return; + + dwMode |= ENABLE_VIRTUAL_TERMINAL_PROCESSING; + if (!SetConsoleMode(hOut, dwMode)) + return; +#endif +} + int main(int argc, char *argv[]) { + setupTerminal(); + if (getenv("EDITOR")) TestTool::editor = getenv("EDITOR"); else if (fs::exists("/usr/bin/editor")) |