diff options
15 files changed, 172 insertions, 54 deletions
diff --git a/docs/control-structures.rst b/docs/control-structures.rst index 7c91cab7..ae0abc49 100644 --- a/docs/control-structures.rst +++ b/docs/control-structures.rst @@ -14,8 +14,8 @@ parameters as output. Input Parameters ---------------- -The input parameters are declared the same way as variables are. As an -exception, unused parameters can omit the variable name. +The input parameters are declared the same way as variables are. +The name of unused parameters can be omitted. For example, suppose we want our contract to accept one kind of external calls with two integers, we would write something like:: @@ -29,6 +29,9 @@ something like:: } } +Input parameters can be used just as any other local variable +can be used, they can also be assigned to. + Output Parameters ----------------- @@ -51,24 +54,20 @@ write:: } The names of output parameters can be omitted. -The output values can also be specified using ``return`` statements. -The ``return`` statements are also capable of returning multiple -values, see :ref:`multi-return`. -Return parameters are initialized to zero; if they are not explicitly -set, they stay to be zero. - -Input parameters and output parameters can be used as expressions in -the function body. There, they are also usable in the left-hand side -of assignment. +The output values can also be specified using ``return`` statements, +which are also capable of :ref:`returning multiple values<multi-return>`. +Return parameters can be used as any other local variable and they +are zero-initialized; if they are not explicitly +set, they stay zero. .. index:: if, else, while, do/while, for, break, continue, return, switch, goto Control Structures =================== -Most of the control structures from JavaScript are available in Solidity -except for ``switch`` and ``goto``. So -there is: ``if``, ``else``, ``while``, ``do``, ``for``, ``break``, ``continue``, ``return``, ``? :``, with +Most of the control structures known from curly-braces languages are available in Solidity: + +There is: ``if``, ``else``, ``while``, ``do``, ``for``, ``break``, ``continue``, ``return``, with the usual semantics known from C or JavaScript. Parentheses can *not* be omitted for conditionals, but curly brances can be omitted @@ -112,6 +111,9 @@ the effect that the current memory is not cleared, i.e. passing memory reference to internally-called functions is very efficient. Only functions of the same contract can be called internally. +You should still avoid excessive recursion, as every internal function call +uses up at least one stack slot and there are at most 1024 slots available. + External Function Calls ----------------------- @@ -143,7 +145,7 @@ You need to use the modifier ``payable`` with the ``info`` function because otherwise, the ``.value()`` option would not be available. .. warning:: - Be careful that ``feed.info.value(10).gas(800)`` only locally sets the ``value`` and amount of ``gas`` sent with the function call, and the parentheses at the end perform the actual call. + Be careful that ``feed.info.value(10).gas(800)`` only locally sets the ``value`` and amount of ``gas`` sent with the function call, and the parentheses at the end perform the actual call. So in this case, the function is not called. Function calls cause exceptions if the called contract does not exist (in the sense that the account does not contain code) or if the called contract itself @@ -167,7 +169,7 @@ throws an exception or goes out of gas. Named Calls and Anonymous Function Parameters --------------------------------------------- -Function call arguments can also be given by name, in any order, +Function call arguments can be given by name, in any order, if they are enclosed in ``{ }`` as can be seen in the following example. The argument list has to coincide by name with the list of parameters from the function declaration, but can be in arbitrary order. @@ -214,9 +216,9 @@ Those parameters will still be present on the stack, but they are inaccessible. Creating Contracts via ``new`` ============================== -A contract can create a new contract using the ``new`` keyword. The full -code of the contract being created has to be known in advance, so recursive -creation-dependencies are not possible. +A contract can create other contracts using the ``new`` keyword. The full +code of the contract being created has to be known when the creating contract +is compiled so recursive creation-dependencies are not possible. :: @@ -244,7 +246,7 @@ creation-dependencies are not possible. } } -As seen in the example, it is possible to forward Ether while creating +As seen in the example, it is possible to send Ether while creating an instance of ``D`` using the ``.value()`` option, but it is not possible to limit the amount of gas. If the creation fails (due to out-of-stack, not enough balance or other problems), @@ -269,8 +271,11 @@ Assignment Destructuring Assignments and Returning Multiple Values ------------------------------------------------------- -Solidity internally allows tuple types, i.e. a list of objects of potentially different types whose size is a constant at compile-time. Those tuples can be used to return multiple values at the same time. -These can then either be assigned to newly declared variables or to pre-existing variables (or LValues in general): +Solidity internally allows tuple types, i.e. a list of objects of potentially different types whose number is a constant at compile-time. Those tuples can be used to return multiple values at the same time. +These can then either be assigned to newly declared variables or to pre-existing variables (or LValues in general). + +Tuples are not proper types in Solidity, they can only be used to form syntactic +groupings of expressions. :: @@ -294,15 +299,23 @@ These can then either be assigned to newly declared variables or to pre-existing } } +It is not possible to mix variable declarations and non-declaration assignments, +i.e. the following is not valid: ``(x, uint y) = (1, 2);`` + .. note:: 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 disallowed, so both sides have to have the same number of components. +.. warning:: + Be careful when assigning to multiple variables at the same time when + reference types are involved, because it could lead to unexpected + copying behaviour. + Complications for Arrays and Structs ------------------------------------ -The semantics of assignment are a bit more complicated for non-value types like arrays and structs. +The semantics of assignments are a bit more complicated for non-value types like arrays and structs. Assigning *to* a state variable always creates an independent copy. On the other hand, assigning to a local variable creates an independent copy only for elementary types, i.e. static types that fit into 32 bytes. If structs or arrays (including ``bytes`` and ``string``) are assigned from a state variable to a local variable, the local variable holds a reference to the original state variable. A second assignment to the local variable does not modify the state but only changes the reference. Assignments to members (or elements) of the local variable *do* change the state. .. index:: ! scoping, declarations, default value @@ -320,11 +333,11 @@ and ``string``, the default value is an empty array or string. Scoping in Solidity follows the widespread scoping rules of C99 (and many other languages): Variables are visible from the point right after their declaration -until the end of a ``{ }``-block. As an exception to this rule, variables declared in the +until the end of the smallest ``{ }``-block that contains the declaration. As an exception to this rule, variables declared in the initialization part of a for-loop are only visible until the end of the for-loop. Variables and other items declared outside of a code block, for example functions, contracts, -user-defined types, etc., do not change their scoping behaviour. This means you can +user-defined types, etc., are visible even before they were declared. This means you can use state variables before they are declared and call functions recursively. As a consequence, the following examples will compile without warnings, since @@ -368,7 +381,7 @@ In any case, you will get a warning about the outer variable being shadowed. .. warning:: Before version 0.5.0 Solidity followed the same scoping rules as JavaScript, that is, a variable declared anywhere within a function would be in scope - for the entire function, regardless where it was declared. Note that this is a breaking change. The following example shows a code snippet that used + for the entire function, regardless where it was declared. The following example shows a code snippet that used to compile but leads to an error starting from version 0.5.0. :: @@ -400,17 +413,17 @@ If used properly, analysis tools can evaluate your contract to identify the cond There are two other ways to trigger exceptions: The ``revert`` function can be used to flag an error and revert the current call. It is possible to provide a string message containing details about the error that will be passed back to the caller. -The deprecated keyword ``throw`` can also be used as an alternative to ``revert()`` (but only without error message). .. note:: - From version 0.4.13 the ``throw`` keyword is deprecated and will be phased out in the future. + There used to be a keyword called ``throw`` with the same semantics as ``revert()`` which + whas deprecated in version 0.4.13 and removed in version 0.5.0. When exceptions happen in a sub-call, they "bubble up" (i.e. exceptions are rethrown) automatically. Exceptions to this rule are ``send`` -and the low-level functions ``call``, ``delegatecall``, ``callcode`` and ``staticcall`` -- those return ``false`` in case +and the low-level functions ``call``, ``delegatecall`` and ``staticcall`` -- those return ``false`` as their first return value in case of an exception instead of "bubbling up". .. warning:: - The low-level ``call``, ``delegatecall``, ``callcode`` and ``staticcall`` will return success if the called account is non-existent, as part of the design of EVM. Existence must be checked prior to calling if desired. + The low-level functions ``call``, ``delegatecall`` and ``staticcall`` return ``true`` as their first return value if the called account is non-existent, as part of the design of EVM. Existence must be checked prior to calling if desired. Catching exceptions is not yet possible. @@ -447,7 +460,6 @@ An ``assert``-style exception is generated in the following situations: A ``require``-style exception is generated in the following situations: -#. Calling ``throw``. #. Calling ``require`` with an argument that evaluates to ``false``. #. If you call a function via a message call but it does not finish properly (i.e. it runs out of gas, has no matching function, or throws an exception itself), except when a low level operation ``call``, ``send``, ``delegatecall``, ``callcode`` or ``staticcall`` is used. The low level operations never throw exceptions but indicate failures by returning ``false``. #. If you create a contract using the ``new`` keyword but the contract creation does not finish properly (see above for the definition of "not finish properly"). diff --git a/docs/miscellaneous.rst b/docs/miscellaneous.rst index d96ff166..de3ab962 100644 --- a/docs/miscellaneous.rst +++ b/docs/miscellaneous.rst @@ -66,18 +66,18 @@ Layout in Memory Solidity reserves four 32 byte slots: -- ``0x00`` - ``0x3f``: scratch space for hashing methods -- ``0x40`` - ``0x5f``: currently allocated memory size (aka. free memory pointer) -- ``0x60`` - ``0x7f``: zero slot +- ``0x00`` - ``0x3f`` (64 bytes): scratch space for hashing methods +- ``0x40`` - ``0x5f`` (32 bytes): currently allocated memory size (aka. free memory pointer) +- ``0x60`` - ``0x7f`` (32 bytes): zero slot -Scratch space can be used between statements (ie. within inline assembly). The zero slot +Scratch space can be used between statements (i.e. within inline assembly). The zero slot is used as initial value for dynamic memory arrays and should never be written to (the free memory pointer points to ``0x80`` initially). Solidity always places new objects at the free memory pointer and memory is never freed (this might change in the future). .. warning:: - There are some operations in Solidity that need a temporary memory area larger than 64 bytes and therefore will not fit into the scratch space. They will be placed where the free memory points to, but given their short lifecycle, the pointer is not updated. The memory may or may not be zeroed out. Because of this, one shouldn't expect the free memory to be zeroed out. + There are some operations in Solidity that need a temporary memory area larger than 64 bytes and therefore will not fit into the scratch space. They will be placed where the free memory points to, but given their short lifetime, the pointer is not updated. The memory may or may not be zeroed out. Because of this, one shouldn't expect the free memory to point to zeroed out memory. While it may seem like a good idea to use ``msize`` to arrive at a definitely zeroed out memory area, using such a pointer non-temporarily without updating the free memory pointer can have adverse results. @@ -242,7 +242,6 @@ Tips and Tricks * Use shorter types for struct elements and sort them such that short types are grouped together. This can lower the gas costs as multiple ``SSTORE`` operations might be combined into a single (``SSTORE`` costs 5000 or 20000 gas, so this is what you want to optimise). Use the gas price estimator (with optimiser enabled) to check! * Make your state variables public - the compiler will create :ref:`getters <visibility-and-getters>` for you automatically. * If you end up checking conditions on input or state a lot at the beginning of your functions, try using :ref:`modifiers`. -* If your contract has a function called ``send`` but you want to use the built-in send-function, use ``address(contractVariable).send(amount)``. * Initialize storage structs with a single assignment: ``x = MyStruct({a: 1, b: 2});`` .. note:: @@ -278,7 +277,7 @@ The following is the order of precedence for operators, listed in order of evalu +------------+-------------------------------------+--------------------------------------------+ | *2* | Prefix increment and decrement | ``++``, ``--`` | + +-------------------------------------+--------------------------------------------+ -| | Unary plus and minus | ``+``, ``-`` | +| | Unary minus | ``-`` | + +-------------------------------------+--------------------------------------------+ | | Unary operations | ``delete`` | + +-------------------------------------+--------------------------------------------+ @@ -322,13 +321,12 @@ The following is the order of precedence for operators, listed in order of evalu Global Variables ================ -- ``abi.decode(bytes encodedData, (...)) returns (...)``: :ref:`ABI <ABI>`-decodes the provided data. The types are given in parentheses as second argument. Example: ``(uint a, uint[2] memory b, bytes memory c) = abi.decode(data, (uint, uint[2], bytes))`` -- ``abi.encode(...) returns (bytes)``: :ref:`ABI <ABI>`-encodes 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 +- ``abi.decode(bytes memory encodedData, (...)) returns (...)``: :ref:`ABI <ABI>`-decodes the provided data. The types are given in parentheses as second argument. Example: ``(uint a, uint[2] memory b, bytes memory c) = abi.decode(data, (uint, uint[2], bytes))`` +- ``abi.encode(...) returns (bytes memory)``: :ref:`ABI <ABI>`-encodes the given arguments +- ``abi.encodePacked(...) returns (bytes memory)``: Performs :ref:`packed encoding <abi_packed_mode>` of the given arguments +- ``abi.encodeWithSelector(bytes4 selector, ...) returns (bytes memory)``: :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)), ...)``` -- ``block.blockhash(uint blockNumber) returns (bytes32)``: hash of the given block - only works for 256 most recent, excluding current, blocks - deprecated in version 0.4.22 and replaced by ``blockhash(uint blockNumber)``. +- ``abi.encodeWithSignature(string memory signature, ...) returns (bytes memory)``: Equivalent to ``abi.encodeWithSelector(bytes4(keccak256(bytes(signature)), ...)``` - ``block.coinbase`` (``address payable``): current block miner's address - ``block.difficulty`` (``uint``): current block difficulty - ``block.gaslimit`` (``uint``): current block gaslimit @@ -336,7 +334,6 @@ Global Variables - ``block.timestamp`` (``uint``): current block timestamp - ``gasleft() returns (uint256)``: remaining gas - ``msg.data`` (``bytes``): complete calldata -- ``msg.gas`` (``uint``): remaining gas - deprecated in version 0.4.21 and to be replaced by ``gasleft()`` - ``msg.sender`` (``address payable``): sender of the message (current call) - ``msg.value`` (``uint``): number of wei sent with the message - ``now`` (``uint``): current block timestamp (alias for ``block.timestamp``) @@ -344,21 +341,19 @@ Global Variables - ``tx.origin`` (``address payable``): sender of the transaction (full call chain) - ``assert(bool condition)``: abort execution and revert state changes if condition is ``false`` (use for internal error) - ``require(bool condition)``: abort execution and revert state changes if condition is ``false`` (use for malformed input or error in external component) -- ``require(bool condition, string message)``: abort execution and revert state changes if condition is ``false`` (use for malformed input or error in external component). Also provide error message. +- ``require(bool condition, string memory message)``: abort execution and revert state changes if condition is ``false`` (use for malformed input or error in external component). Also provide error message. - ``revert()``: abort execution and revert state changes -- ``revert(string message)``: abort execution and revert state changes providing an explanatory string +- ``revert(string memory message)``: abort execution and revert state changes providing an explanatory string - ``blockhash(uint blockNumber) returns (bytes32)``: hash of the given block - only works for 256 most recent blocks -- ``keccak256(bytes memory) returns (bytes32)``: compute the Ethereum-SHA-3 (Keccak-256) hash of the input -- ``sha3(bytes memory) returns (bytes32)``: an alias to ``keccak256`` +- ``keccak256(bytes memory) returns (bytes32)``: compute the Keccak-256 hash of the input - ``sha256(bytes memory) returns (bytes32)``: compute the SHA-256 hash of the input - ``ripemd160(bytes memory) returns (bytes20)``: compute the RIPEMD-160 hash of the input - ``ecrecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) returns (address)``: recover address associated with the public key from elliptic curve signature, return zero on error - ``addmod(uint x, uint y, uint k) returns (uint)``: compute ``(x + y) % k`` where the addition is performed with arbitrary precision and does not wrap around at ``2**256``. Assert that ``k != 0`` starting from version 0.5.0. - ``mulmod(uint x, uint y, uint k) returns (uint)``: compute ``(x * y) % k`` where the multiplication is performed with arbitrary precision and does not wrap around at ``2**256``. Assert that ``k != 0`` starting from version 0.5.0. -- ``this`` (current contract's type): the current contract, explicitly convertible to ``address`` +- ``this`` (current contract's type): the current contract, explicitly convertible to ``address`` or ``address payable`` - ``super``: the contract one level higher in the inheritance hierarchy -- ``selfdestruct(address recipient)``: destroy the current contract, sending its funds to the given address -- ``suicide(address recipient)``: a deprecated alias to ``selfdestruct`` +- ``selfdestruct(address payable recipient)``: destroy the current contract, sending its funds to the given address - ``<address>.balance`` (``uint256``): balance of the :ref:`address` in Wei - ``<address payable>.send(uint256 amount) returns (bool)``: send given amount of Wei to :ref:`address`, returns ``false`` on failure - ``<address payable>.transfer(uint256 amount)``: send given amount of Wei to :ref:`address`, throws on failure @@ -380,6 +375,11 @@ Global Variables You can only access the hashes of the most recent 256 blocks, all other values will be zero. +.. note:: + In version 0.5.0, the following aliases were removed: ``suicide`` as alias for ``selfdestruct``, + ``msg.gas`` as alias for ``gasleft``, ``block.blockhash`` as alias for ``blockhash`` and + ``sha3`` as alias for ``keccak256``. + .. index:: visibility, public, private, external, internal Function Visibility Specifiers diff --git a/libsolidity/interface/StandardCompiler.cpp b/libsolidity/interface/StandardCompiler.cpp index b53c5a5e..e7b1553f 100644 --- a/libsolidity/interface/StandardCompiler.cpp +++ b/libsolidity/interface/StandardCompiler.cpp @@ -615,7 +615,7 @@ string StandardCompiler::compile(string const& _input) noexcept } catch (...) { - return "{\"errors\":\"[{\"type\":\"JSONError\",\"component\":\"general\",\"severity\":\"error\",\"message\":\"Error parsing input JSON.\"}]}"; + return "{\"errors\":[{\"type\":\"JSONError\",\"component\":\"general\",\"severity\":\"error\",\"message\":\"Error parsing input JSON.\"}]}"; } // cout << "Input: " << input.toStyledString() << endl; @@ -628,6 +628,6 @@ string StandardCompiler::compile(string const& _input) noexcept } catch (...) { - return "{\"errors\":\"[{\"type\":\"JSONError\",\"component\":\"general\",\"severity\":\"error\",\"message\":\"Error writing output JSON.\"}]}"; + return "{\"errors\":[{\"type\":\"JSONError\",\"component\":\"general\",\"severity\":\"error\",\"message\":\"Error writing output JSON.\"}]}"; } } diff --git a/test/libsolidity/syntaxTests/multiline_comments.sol b/test/libsolidity/syntaxTests/multiline_comments.sol new file mode 100644 index 00000000..480fde6c --- /dev/null +++ b/test/libsolidity/syntaxTests/multiline_comments.sol @@ -0,0 +1,13 @@ +/* + * This is a multi-line comment + * it should create no problems + * +*/ + +contract test { + /* + * this is another multi-line comment + * + */ +} +// ---- diff --git a/test/libsolidity/syntaxTests/string/string_escapes.sol b/test/libsolidity/syntaxTests/string/string_escapes.sol new file mode 100644 index 00000000..51b90d73 --- /dev/null +++ b/test/libsolidity/syntaxTests/string/string_escapes.sol @@ -0,0 +1,7 @@ +contract test { + function f() public pure returns (bytes32) { + bytes32 escapeCharacters = "\t\b\n\r\f\'\"\\\b"; + return escapeCharacters; + } +} +// ---- diff --git a/test/libsolidity/syntaxTests/string/string_new_line.sol b/test/libsolidity/syntaxTests/string/string_new_line.sol new file mode 100644 index 00000000..da2240f7 --- /dev/null +++ b/test/libsolidity/syntaxTests/string/string_new_line.sol @@ -0,0 +1,9 @@ +contract test { + function f() public pure returns (bytes32) { + bytes32 escapeCharacters = "This a test + "; + return escapeCharacters; + } +} +// ---- +// ParserError: (100-112): Expected primary expression. diff --git a/test/libsolidity/syntaxTests/string/string_terminated_by_backslash.sol b/test/libsolidity/syntaxTests/string/string_terminated_by_backslash.sol new file mode 100644 index 00000000..3eaba6af --- /dev/null +++ b/test/libsolidity/syntaxTests/string/string_terminated_by_backslash.sol @@ -0,0 +1,8 @@ +contract test { + function f() public pure returns (bytes32) { + bytes32 escapeCharacters = "text \"; + return escapeCharacters; + } +} +// ---- +// ParserError: (100-109): Expected primary expression.
\ No newline at end of file diff --git a/test/libsolidity/syntaxTests/string/string_unterminated.sol b/test/libsolidity/syntaxTests/string/string_unterminated.sol new file mode 100644 index 00000000..3291781e --- /dev/null +++ b/test/libsolidity/syntaxTests/string/string_unterminated.sol @@ -0,0 +1,7 @@ +contract test { + function f() public pure returns (bytes32) { + bytes32 escapeCharacters = "This a test + } +} +// ---- +// ParserError: (100-112): Expected primary expression.
\ No newline at end of file diff --git a/test/libsolidity/syntaxTests/string/string_unterminated_no_new_line.sol b/test/libsolidity/syntaxTests/string/string_unterminated_no_new_line.sol new file mode 100644 index 00000000..e7be50d2 --- /dev/null +++ b/test/libsolidity/syntaxTests/string/string_unterminated_no_new_line.sol @@ -0,0 +1,4 @@ +contract test { + function f() pure public { "abc\ +// ---- +// ParserError: (47-53): Expected primary expression.
\ No newline at end of file diff --git a/test/libsolidity/syntaxTests/unicode_escape_literals.sol b/test/libsolidity/syntaxTests/unicode_escape_literals.sol new file mode 100644 index 00000000..a340487b --- /dev/null +++ b/test/libsolidity/syntaxTests/unicode_escape_literals.sol @@ -0,0 +1,31 @@ +contract test { + + function oneByteUTF8() public pure returns (bytes32) { + bytes32 usdollar = "aaa\u0024aaa"; + return usdollar; + } + + function twoBytesUTF8() public pure returns (bytes32) { + bytes32 cent = "aaa\u00A2aaa"; + return cent; + } + + function threeBytesUTF8() public pure returns (bytes32) { + bytes32 eur = "aaa\u20ACaaa"; + return eur; + } + + function together() public pure returns (bytes32) { + bytes32 res = "\u0024\u00A2\u20AC"; + return res; + } + + // this function returns an invalid unicode character + function invalidLiteral() public pure returns(bytes32) { + bytes32 invalid = "\u00xx"; + return invalid; + } + +} +// ---- +// ParserError: (678-681): Expected primary expression. diff --git a/test/libsolidity/syntaxTests/unterminatedBlocks/one_dot.sol b/test/libsolidity/syntaxTests/unterminatedBlocks/one_dot.sol new file mode 100644 index 00000000..a678f004 --- /dev/null +++ b/test/libsolidity/syntaxTests/unterminatedBlocks/one_dot.sol @@ -0,0 +1,4 @@ +contract c { + function f() pure public { 1. +// ---- +// ParserError: (47-47): Expected identifier but got end of source
\ No newline at end of file diff --git a/test/libsolidity/syntaxTests/unterminatedBlocks/one_dot_x.sol b/test/libsolidity/syntaxTests/unterminatedBlocks/one_dot_x.sol new file mode 100644 index 00000000..3cc59374 --- /dev/null +++ b/test/libsolidity/syntaxTests/unterminatedBlocks/one_dot_x.sol @@ -0,0 +1,5 @@ +contract test { + function f() pure public { 1.x; } +} +// ---- +// TypeError: (47-50): Member "x" not found or not visible after argument-dependent lookup in int_const 1.
\ No newline at end of file diff --git a/test/libsolidity/syntaxTests/unterminatedBlocks/zero_dot.sol b/test/libsolidity/syntaxTests/unterminatedBlocks/zero_dot.sol new file mode 100644 index 00000000..6ba2b4c2 --- /dev/null +++ b/test/libsolidity/syntaxTests/unterminatedBlocks/zero_dot.sol @@ -0,0 +1,4 @@ +contract c { + function f() pure public { 0. +// ---- +// ParserError: (47-47): Expected identifier but got end of source
\ No newline at end of file diff --git a/test/libsolidity/syntaxTests/unterminatedBlocks/zero_dot_x.sol b/test/libsolidity/syntaxTests/unterminatedBlocks/zero_dot_x.sol new file mode 100644 index 00000000..8648bce2 --- /dev/null +++ b/test/libsolidity/syntaxTests/unterminatedBlocks/zero_dot_x.sol @@ -0,0 +1,5 @@ +contract test { + function f() pure public { 0.x; } +} +// ---- +// TypeError: (47-50): Member "x" not found or not visible after argument-dependent lookup in int_const 0.
\ No newline at end of file diff --git a/test/libsolidity/syntaxTests/upper_case_hex_literals.sol b/test/libsolidity/syntaxTests/upper_case_hex_literals.sol new file mode 100644 index 00000000..0842c2ec --- /dev/null +++ b/test/libsolidity/syntaxTests/upper_case_hex_literals.sol @@ -0,0 +1,9 @@ +contract test { + + function f() public pure returns (uint256) { + uint256 a = 0x1234aAbcC; + uint256 b = 0x1234ABCDEF; + return a + b; + } +} +// ---- |