mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Merge remote-tracking branch 'origin/develop' into breaking
This commit is contained in:
commit
257bc6a416
@ -18,6 +18,8 @@ Bugfixes:
|
||||
|
||||
Important Bugfixes:
|
||||
* Add missing callvalue check to the creation code of a contract that does not define a constructor but has a base that does define a constructor.
|
||||
* Disallow index range accesses for arrays with dynamically encoded base types.
|
||||
* Code Generator: Fixed that string literals containing backslash characters could cause incorrect code to be generated when passed directly to function calls or encoding functions when ABIEncoderV2 is active.
|
||||
|
||||
|
||||
Language Features:
|
||||
@ -26,6 +28,8 @@ Language Features:
|
||||
|
||||
Compiler Features:
|
||||
* Commandline Interface: Don't ignore `--yul-optimizations` in assembly mode.
|
||||
* Allow using abi encoding functions for calldata array slices without explicit casts.
|
||||
* Wasm binary output: Implement ``br`` and ``br_if``.
|
||||
|
||||
|
||||
|
||||
@ -35,6 +39,7 @@ Bugfixes:
|
||||
* Fixed an "Assembly Exception in Bytecode" error where requested functions were generated twice.
|
||||
* Natspec: Fixed a bug that ignored ``@return`` tag when no other developer-documentation tags were present.
|
||||
* Yul assembler: Fix source location of variable declarations without value.
|
||||
* Type checker: Checks if a literal exponent in the ``**`` operation is too large or fractional.
|
||||
|
||||
|
||||
### 0.6.7 (2020-05-04)
|
||||
|
@ -292,6 +292,7 @@ Consider you have the following pre-0.5.0 contract already deployed:
|
||||
|
||||
::
|
||||
|
||||
// SPDX-License-Identifier: GPL-3.0
|
||||
pragma solidity ^0.4.25;
|
||||
// This will report a warning until version 0.4.25 of the compiler
|
||||
// This will not compile after 0.5.0
|
||||
@ -309,6 +310,7 @@ This will no longer compile with Solidity v0.5.0. However, you can define a comp
|
||||
|
||||
::
|
||||
|
||||
// SPDX-License-Identifier: GPL-3.0
|
||||
pragma solidity >=0.5.0 <0.8.0;
|
||||
interface OldContract {
|
||||
function someOldFunction(uint8 a) external;
|
||||
@ -326,6 +328,7 @@ Given the interface defined above, you can now easily use the already deployed p
|
||||
|
||||
::
|
||||
|
||||
// SPDX-License-Identifier: GPL-3.0
|
||||
pragma solidity >=0.5.0 <0.8.0;
|
||||
|
||||
interface OldContract {
|
||||
@ -347,6 +350,7 @@ commandline compiler for linking):
|
||||
::
|
||||
|
||||
// This will not compile after 0.6.0
|
||||
// SPDX-License-Identifier: GPL-3.0
|
||||
pragma solidity >=0.5.0 <0.5.99;
|
||||
|
||||
library OldLibrary {
|
||||
@ -370,6 +374,7 @@ Old version:
|
||||
|
||||
::
|
||||
|
||||
// SPDX-License-Identifier: GPL-3.0
|
||||
pragma solidity ^0.4.25;
|
||||
// This will not compile after 0.5.0
|
||||
|
||||
@ -432,6 +437,7 @@ New version:
|
||||
|
||||
::
|
||||
|
||||
// SPDX-License-Identifier: GPL-3.0
|
||||
pragma solidity >=0.5.0 <0.5.99;
|
||||
// This will not compile after 0.6.0
|
||||
|
||||
|
@ -232,6 +232,7 @@ Given the contract:
|
||||
|
||||
::
|
||||
|
||||
// SPDX-License-Identifier: GPL-3.0
|
||||
pragma solidity >=0.4.16 <0.8.0;
|
||||
|
||||
contract Foo {
|
||||
@ -535,6 +536,7 @@ For example,
|
||||
|
||||
::
|
||||
|
||||
// SPDX-License-Identifier: GPL-3.0
|
||||
pragma solidity >=0.5.0 <0.8.0;
|
||||
|
||||
|
||||
@ -583,6 +585,7 @@ As an example, the code
|
||||
|
||||
::
|
||||
|
||||
// SPDX-License-Identifier: GPL-3.0
|
||||
pragma solidity >=0.4.19 <0.8.0;
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
|
@ -41,6 +41,7 @@ without a compiler change.
|
||||
|
||||
.. code::
|
||||
|
||||
// SPDX-License-Identifier: GPL-3.0
|
||||
pragma solidity >=0.4.16 <0.8.0;
|
||||
|
||||
library GetCode {
|
||||
@ -66,6 +67,7 @@ efficient code, for example:
|
||||
|
||||
.. code::
|
||||
|
||||
// SPDX-License-Identifier: GPL-3.0
|
||||
pragma solidity >=0.4.16 <0.8.0;
|
||||
|
||||
|
||||
@ -136,6 +138,7 @@ Local Solidity variables are available for assignments, for example:
|
||||
|
||||
.. code::
|
||||
|
||||
// SPDX-License-Identifier: GPL-3.0
|
||||
pragma solidity >=0.4.16 <0.8.0;
|
||||
|
||||
contract C {
|
||||
|
@ -1,4 +1,26 @@
|
||||
[
|
||||
{
|
||||
"name": "MissingEscapingInFormatting",
|
||||
"summary": "String literals containing double backslash characters passed directly to external or encoding function calls can lead to a different string being used when ABIEncoderV2 is enabled.",
|
||||
"description": "When ABIEncoderV2 is enabled, string literals passed directly to encoding functions or external function calls are stored as strings in the intemediate code. Characters outside the printable range are handled correctly, but backslashes are not escaped in this procedure. This leads to double backslashes being reduced to single backslashes and consequently re-interpreted as escapes potentially resulting in a different string being encoded.",
|
||||
"introduced": "0.5.14",
|
||||
"fixed": "0.6.8",
|
||||
"severity": "very low",
|
||||
"conditions": {
|
||||
"ABIEncoderV2": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "ArraySliceDynamicallyEncodedBaseType",
|
||||
"summary": "Accessing array slices of arrays with dynamically encoded base types (e.g. multi-dimensional arrays) can result in invalid data being read.",
|
||||
"description": "For arrays with dynamically sized base types, index range accesses that use a start expression that is non-zero will result in invalid array slices. Any index access to such array slices will result in data being read from incorrect calldata offsets. Array slices are only supported for dynamic calldata types and all problematic type require ABIEncoderV2 to be enabled.",
|
||||
"introduced": "0.6.0",
|
||||
"fixed": "0.6.8",
|
||||
"severity": "very low",
|
||||
"conditions": {
|
||||
"ABIEncoderV2": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "ImplicitConstructorCallvalueCheck",
|
||||
"summary": "The creation code of a contract that does not define a constructor but has a base that does define a constructor did not revert for calls with non-zero value.",
|
||||
|
@ -923,6 +923,7 @@
|
||||
},
|
||||
"0.5.14": {
|
||||
"bugs": [
|
||||
"MissingEscapingInFormatting",
|
||||
"ImplicitConstructorCallvalueCheck",
|
||||
"TupleAssignmentMultiStackSlotComponents",
|
||||
"MemoryArrayCreationOverflow",
|
||||
@ -934,6 +935,7 @@
|
||||
},
|
||||
"0.5.15": {
|
||||
"bugs": [
|
||||
"MissingEscapingInFormatting",
|
||||
"ImplicitConstructorCallvalueCheck",
|
||||
"TupleAssignmentMultiStackSlotComponents",
|
||||
"MemoryArrayCreationOverflow",
|
||||
@ -944,6 +946,7 @@
|
||||
},
|
||||
"0.5.16": {
|
||||
"bugs": [
|
||||
"MissingEscapingInFormatting",
|
||||
"ImplicitConstructorCallvalueCheck",
|
||||
"TupleAssignmentMultiStackSlotComponents",
|
||||
"MemoryArrayCreationOverflow",
|
||||
@ -953,6 +956,7 @@
|
||||
},
|
||||
"0.5.17": {
|
||||
"bugs": [
|
||||
"MissingEscapingInFormatting",
|
||||
"ImplicitConstructorCallvalueCheck",
|
||||
"TupleAssignmentMultiStackSlotComponents",
|
||||
"MemoryArrayCreationOverflow"
|
||||
@ -1082,6 +1086,8 @@
|
||||
},
|
||||
"0.6.0": {
|
||||
"bugs": [
|
||||
"MissingEscapingInFormatting",
|
||||
"ArraySliceDynamicallyEncodedBaseType",
|
||||
"ImplicitConstructorCallvalueCheck",
|
||||
"TupleAssignmentMultiStackSlotComponents",
|
||||
"MemoryArrayCreationOverflow",
|
||||
@ -1091,6 +1097,8 @@
|
||||
},
|
||||
"0.6.1": {
|
||||
"bugs": [
|
||||
"MissingEscapingInFormatting",
|
||||
"ArraySliceDynamicallyEncodedBaseType",
|
||||
"ImplicitConstructorCallvalueCheck",
|
||||
"TupleAssignmentMultiStackSlotComponents",
|
||||
"MemoryArrayCreationOverflow"
|
||||
@ -1099,6 +1107,8 @@
|
||||
},
|
||||
"0.6.2": {
|
||||
"bugs": [
|
||||
"MissingEscapingInFormatting",
|
||||
"ArraySliceDynamicallyEncodedBaseType",
|
||||
"ImplicitConstructorCallvalueCheck",
|
||||
"TupleAssignmentMultiStackSlotComponents",
|
||||
"MemoryArrayCreationOverflow"
|
||||
@ -1107,6 +1117,8 @@
|
||||
},
|
||||
"0.6.3": {
|
||||
"bugs": [
|
||||
"MissingEscapingInFormatting",
|
||||
"ArraySliceDynamicallyEncodedBaseType",
|
||||
"ImplicitConstructorCallvalueCheck",
|
||||
"TupleAssignmentMultiStackSlotComponents",
|
||||
"MemoryArrayCreationOverflow"
|
||||
@ -1115,6 +1127,8 @@
|
||||
},
|
||||
"0.6.4": {
|
||||
"bugs": [
|
||||
"MissingEscapingInFormatting",
|
||||
"ArraySliceDynamicallyEncodedBaseType",
|
||||
"ImplicitConstructorCallvalueCheck",
|
||||
"TupleAssignmentMultiStackSlotComponents",
|
||||
"MemoryArrayCreationOverflow"
|
||||
@ -1123,6 +1137,8 @@
|
||||
},
|
||||
"0.6.5": {
|
||||
"bugs": [
|
||||
"MissingEscapingInFormatting",
|
||||
"ArraySliceDynamicallyEncodedBaseType",
|
||||
"ImplicitConstructorCallvalueCheck",
|
||||
"TupleAssignmentMultiStackSlotComponents"
|
||||
],
|
||||
@ -1130,12 +1146,16 @@
|
||||
},
|
||||
"0.6.6": {
|
||||
"bugs": [
|
||||
"MissingEscapingInFormatting",
|
||||
"ArraySliceDynamicallyEncodedBaseType",
|
||||
"ImplicitConstructorCallvalueCheck"
|
||||
],
|
||||
"released": "2020-04-09"
|
||||
},
|
||||
"0.6.7": {
|
||||
"bugs": [
|
||||
"MissingEscapingInFormatting",
|
||||
"ArraySliceDynamicallyEncodedBaseType",
|
||||
"ImplicitConstructorCallvalueCheck"
|
||||
],
|
||||
"released": "2020-05-04"
|
||||
|
@ -27,6 +27,7 @@ you receive the funds of the person who is now the richest.
|
||||
|
||||
::
|
||||
|
||||
// SPDX-License-Identifier: GPL-3.0
|
||||
pragma solidity >=0.5.0 <0.8.0;
|
||||
|
||||
contract WithdrawalContract {
|
||||
@ -60,6 +61,7 @@ This is as opposed to the more intuitive sending pattern:
|
||||
|
||||
::
|
||||
|
||||
// SPDX-License-Identifier: GPL-3.0
|
||||
pragma solidity >=0.5.0 <0.8.0;
|
||||
|
||||
contract SendContract {
|
||||
@ -121,6 +123,7 @@ restrictions highly readable.
|
||||
|
||||
::
|
||||
|
||||
// SPDX-License-Identifier: GPL-3.0
|
||||
pragma solidity >=0.4.22 <0.8.0;
|
||||
|
||||
contract AccessRestriction {
|
||||
@ -273,6 +276,7 @@ function finishes.
|
||||
|
||||
::
|
||||
|
||||
// SPDX-License-Identifier: GPL-3.0
|
||||
pragma solidity >=0.4.22 <0.8.0;
|
||||
|
||||
contract StateMachine {
|
||||
|
@ -13,6 +13,7 @@ This can be done by using the ``abstract`` keyword as shown in the following exa
|
||||
defined as abstract, because the function ``utterance()`` was defined, but no implementation was
|
||||
provided (no implementation body ``{ }`` was given).::
|
||||
|
||||
// SPDX-License-Identifier: GPL-3.0
|
||||
pragma solidity >=0.6.0 <0.8.0;
|
||||
|
||||
abstract contract Feline {
|
||||
@ -22,6 +23,7 @@ provided (no implementation body ``{ }`` was given).::
|
||||
Such abstract contracts can not be instantiated directly. This is also true, if an abstract contract itself does implement
|
||||
all defined functions. The usage of an abstract contract as a base class is shown in the following example::
|
||||
|
||||
// SPDX-License-Identifier: GPL-3.0
|
||||
pragma solidity >=0.6.0 <0.8.0;
|
||||
|
||||
abstract contract Feline {
|
||||
|
@ -17,6 +17,7 @@ Not all types for constants and immutables are implemented at this time. The onl
|
||||
|
||||
::
|
||||
|
||||
// SPDX-License-Identifier: GPL-3.0
|
||||
pragma solidity >0.6.4 <0.8.0;
|
||||
|
||||
contract C {
|
||||
|
@ -34,6 +34,7 @@ This means that cyclic creation dependencies are impossible.
|
||||
|
||||
::
|
||||
|
||||
// SPDX-License-Identifier: GPL-3.0
|
||||
pragma solidity >=0.4.22 <0.8.0;
|
||||
|
||||
|
||||
|
@ -65,6 +65,7 @@ is that they are cheaper to deploy and call.
|
||||
|
||||
::
|
||||
|
||||
// SPDX-License-Identifier: GPL-3.0
|
||||
pragma solidity >=0.4.21 <0.8.0;
|
||||
|
||||
contract ClientReceipt {
|
||||
@ -138,6 +139,7 @@ as topics. The event call above can be performed in the same way as
|
||||
|
||||
::
|
||||
|
||||
// SPDX-License-Identifier: GPL-3.0
|
||||
pragma solidity >=0.4.10 <0.8.0;
|
||||
|
||||
contract C {
|
||||
|
@ -17,6 +17,7 @@ if they are marked ``virtual``. For details, please see
|
||||
|
||||
::
|
||||
|
||||
// SPDX-License-Identifier: GPL-3.0
|
||||
pragma solidity >=0.5.0 <0.8.0;
|
||||
|
||||
contract owned {
|
||||
|
@ -23,6 +23,7 @@ unused parameters can be omitted.
|
||||
For example, if you want your contract to accept one kind of external call
|
||||
with two integers, you would use something like the following::
|
||||
|
||||
// SPDX-License-Identifier: GPL-3.0
|
||||
pragma solidity >=0.4.16 <0.8.0;
|
||||
|
||||
contract Simple {
|
||||
@ -55,6 +56,7 @@ Function return variables are declared with the same syntax after the
|
||||
For example, suppose you want to return two results: the sum and the product of
|
||||
two integers passed as function parameters, then you use something like::
|
||||
|
||||
// SPDX-License-Identifier: GPL-3.0
|
||||
pragma solidity >=0.4.16 <0.8.0;
|
||||
|
||||
contract Simple {
|
||||
@ -79,6 +81,7 @@ or you can provide return values
|
||||
(either a single or :ref:`multiple ones<multi-return>`) directly with the ``return``
|
||||
statement::
|
||||
|
||||
// SPDX-License-Identifier: GPL-3.0
|
||||
pragma solidity >=0.4.16 <0.8.0;
|
||||
|
||||
contract Simple {
|
||||
@ -142,6 +145,7 @@ The following statements are considered modifying the state:
|
||||
|
||||
::
|
||||
|
||||
// SPDX-License-Identifier: GPL-3.0
|
||||
pragma solidity >=0.5.0 <0.8.0;
|
||||
|
||||
contract C {
|
||||
@ -187,6 +191,7 @@ In addition to the list of state modifying statements explained above, the follo
|
||||
|
||||
::
|
||||
|
||||
// SPDX-License-Identifier: GPL-3.0
|
||||
pragma solidity >=0.5.0 <0.8.0;
|
||||
|
||||
contract C {
|
||||
@ -280,6 +285,7 @@ Below you can see an example of a Sink contract that uses function ``receive``.
|
||||
|
||||
::
|
||||
|
||||
// SPDX-License-Identifier: GPL-3.0
|
||||
pragma solidity >=0.6.0 <0.8.0;
|
||||
|
||||
// This contract keeps all Ether sent to it with no way
|
||||
@ -335,6 +341,7 @@ operations as long as there is enough gas passed on to it.
|
||||
|
||||
::
|
||||
|
||||
// SPDX-License-Identifier: GPL-3.0
|
||||
pragma solidity >=0.6.2 <0.8.0;
|
||||
|
||||
contract Test {
|
||||
@ -407,6 +414,7 @@ The following example shows overloading of the function
|
||||
|
||||
::
|
||||
|
||||
// SPDX-License-Identifier: GPL-3.0
|
||||
pragma solidity >=0.4.16 <0.8.0;
|
||||
|
||||
contract A {
|
||||
@ -425,6 +433,7 @@ externally visible functions differ by their Solidity types but not by their ext
|
||||
|
||||
::
|
||||
|
||||
// SPDX-License-Identifier: GPL-3.0
|
||||
pragma solidity >=0.4.16 <0.8.0;
|
||||
|
||||
// This will not compile
|
||||
@ -458,6 +467,7 @@ candidate, resolution fails.
|
||||
|
||||
::
|
||||
|
||||
// SPDX-License-Identifier: GPL-3.0
|
||||
pragma solidity >=0.4.16 <0.8.0;
|
||||
|
||||
contract A {
|
||||
|
@ -38,6 +38,7 @@ Details are given in the following example.
|
||||
|
||||
::
|
||||
|
||||
// SPDX-License-Identifier: GPL-3.0
|
||||
pragma solidity >=0.6.0 <0.8.0;
|
||||
|
||||
|
||||
@ -125,6 +126,7 @@ Note that above, we call ``Destructible.destroy()`` to "forward" the
|
||||
destruction request. The way this is done is problematic, as
|
||||
seen in the following example::
|
||||
|
||||
// SPDX-License-Identifier: GPL-3.0
|
||||
pragma solidity >=0.6.0 <0.8.0;
|
||||
|
||||
contract owned {
|
||||
@ -154,6 +156,7 @@ A call to ``Final.destroy()`` will call ``Base2.destroy`` because we specify it
|
||||
explicitly in the final override, but this function will bypass
|
||||
``Base1.destroy``. The way around this is to use ``super``::
|
||||
|
||||
// SPDX-License-Identifier: GPL-3.0
|
||||
pragma solidity >=0.6.0 <0.8.0;
|
||||
|
||||
contract owned {
|
||||
@ -204,6 +207,7 @@ use the ``override`` keyword in the function header as shown in this example:
|
||||
|
||||
::
|
||||
|
||||
// SPDX-License-Identifier: GPL-3.0
|
||||
pragma solidity >=0.6.0 <0.8.0;
|
||||
|
||||
contract Base
|
||||
@ -227,6 +231,7 @@ bases, it has to explicitly override it:
|
||||
|
||||
::
|
||||
|
||||
// SPDX-License-Identifier: GPL-3.0
|
||||
pragma solidity >=0.6.0 <0.8.0;
|
||||
|
||||
contract Base1
|
||||
@ -253,6 +258,7 @@ that already overrides all other functions.
|
||||
|
||||
::
|
||||
|
||||
// SPDX-License-Identifier: GPL-3.0
|
||||
pragma solidity >=0.6.0 <0.8.0;
|
||||
|
||||
contract A { function f() public pure{} }
|
||||
@ -293,6 +299,7 @@ of the variable:
|
||||
|
||||
::
|
||||
|
||||
// SPDX-License-Identifier: GPL-3.0
|
||||
pragma solidity >=0.6.0 <0.8.0;
|
||||
|
||||
contract A
|
||||
@ -324,6 +331,7 @@ and the ``override`` keyword must be used in the overriding modifier:
|
||||
|
||||
::
|
||||
|
||||
// SPDX-License-Identifier: GPL-3.0
|
||||
pragma solidity >=0.6.0 <0.8.0;
|
||||
|
||||
contract Base
|
||||
@ -342,6 +350,7 @@ explicitly:
|
||||
|
||||
::
|
||||
|
||||
// SPDX-License-Identifier: GPL-3.0
|
||||
pragma solidity >=0.6.0 <0.8.0;
|
||||
|
||||
contract Base1
|
||||
@ -389,6 +398,7 @@ equivalent to ``constructor() public {}``. For example:
|
||||
|
||||
::
|
||||
|
||||
// SPDX-License-Identifier: GPL-3.0
|
||||
pragma solidity >=0.5.0 <0.8.0;
|
||||
|
||||
contract A {
|
||||
@ -419,6 +429,7 @@ The constructors of all the base contracts will be called following the
|
||||
linearization rules explained below. If the base constructors have arguments,
|
||||
derived contracts need to specify all of them. This can be done in two ways::
|
||||
|
||||
// SPDX-License-Identifier: GPL-3.0
|
||||
pragma solidity >=0.4.22 <0.8.0;
|
||||
|
||||
contract Base {
|
||||
@ -478,6 +489,7 @@ error "Linearization of inheritance graph impossible".
|
||||
|
||||
::
|
||||
|
||||
// SPDX-License-Identifier: GPL-3.0
|
||||
pragma solidity >=0.4.0 <0.8.0;
|
||||
|
||||
contract X {}
|
||||
@ -498,6 +510,7 @@ One area where inheritance linearization is especially important and perhaps not
|
||||
|
||||
::
|
||||
|
||||
// SPDX-License-Identifier: GPL-3.0
|
||||
pragma solidity >=0.4.22 <0.8.0;
|
||||
|
||||
contract Base1 {
|
||||
|
@ -22,6 +22,7 @@ Interfaces are denoted by their own keyword:
|
||||
|
||||
::
|
||||
|
||||
// SPDX-License-Identifier: GPL-3.0
|
||||
pragma solidity >=0.6.2 <0.8.0;
|
||||
|
||||
interface Token {
|
||||
@ -42,6 +43,7 @@ inheritance.
|
||||
|
||||
::
|
||||
|
||||
// SPDX-License-Identifier: GPL-3.0
|
||||
pragma solidity >=0.6.2 <0.8.0;
|
||||
|
||||
interface ParentA {
|
||||
|
@ -47,6 +47,7 @@ more advanced example to implement a set).
|
||||
|
||||
::
|
||||
|
||||
// SPDX-License-Identifier: GPL-3.0
|
||||
pragma solidity >=0.6.0 <0.8.0;
|
||||
|
||||
|
||||
@ -125,6 +126,7 @@ custom types without the overhead of external function calls:
|
||||
|
||||
::
|
||||
|
||||
// SPDX-License-Identifier: GPL-3.0
|
||||
pragma solidity >=0.6.0 <0.8.0;
|
||||
|
||||
struct bigint {
|
||||
@ -239,6 +241,7 @@ Its value can be obtained from Solidity using the ``.selector`` member as follow
|
||||
|
||||
::
|
||||
|
||||
// SPDX-License-Identifier: GPL-3.0
|
||||
pragma solidity >=0.5.14 <0.8.0;
|
||||
|
||||
library L {
|
||||
|
@ -29,6 +29,7 @@ may only be used inside a contract, not inside any of its functions.
|
||||
Let us rewrite the set example from the
|
||||
:ref:`libraries` in this way::
|
||||
|
||||
// SPDX-License-Identifier: GPL-3.0
|
||||
pragma solidity >=0.6.0 <0.8.0;
|
||||
|
||||
|
||||
@ -81,6 +82,7 @@ Let us rewrite the set example from the
|
||||
|
||||
It is also possible to extend elementary types in that way::
|
||||
|
||||
// SPDX-License-Identifier: GPL-3.0
|
||||
pragma solidity >=0.4.16 <0.8.0;
|
||||
|
||||
library Search {
|
||||
|
@ -54,6 +54,7 @@ return parameter list for functions.
|
||||
|
||||
::
|
||||
|
||||
// SPDX-License-Identifier: GPL-3.0
|
||||
pragma solidity >=0.4.16 <0.8.0;
|
||||
|
||||
contract C {
|
||||
@ -68,6 +69,7 @@ In the following example, ``D``, can call ``c.getData()`` to retrieve the value
|
||||
|
||||
::
|
||||
|
||||
// SPDX-License-Identifier: GPL-3.0
|
||||
pragma solidity >=0.4.16 <0.8.0;
|
||||
|
||||
contract C {
|
||||
@ -112,6 +114,7 @@ when they are declared.
|
||||
|
||||
::
|
||||
|
||||
// SPDX-License-Identifier: GPL-3.0
|
||||
pragma solidity >=0.4.16 <0.8.0;
|
||||
|
||||
contract C {
|
||||
@ -132,6 +135,7 @@ it evaluates to a state variable. If it is accessed externally
|
||||
|
||||
::
|
||||
|
||||
// SPDX-License-Identifier: GPL-3.0
|
||||
pragma solidity >=0.4.0 <0.8.0;
|
||||
|
||||
contract C {
|
||||
@ -151,6 +155,7 @@ to write a function, for example:
|
||||
|
||||
::
|
||||
|
||||
// SPDX-License-Identifier: GPL-3.0
|
||||
pragma solidity >=0.4.16 <0.8.0;
|
||||
|
||||
contract arrayExample {
|
||||
@ -177,6 +182,7 @@ The next example is more complex:
|
||||
|
||||
::
|
||||
|
||||
// SPDX-License-Identifier: GPL-3.0
|
||||
pragma solidity >=0.4.0 <0.8.0;
|
||||
|
||||
contract Complex {
|
||||
|
@ -41,6 +41,7 @@ Internal Function Calls
|
||||
Functions of the current contract can be called directly ("internally"), also recursively, as seen in
|
||||
this nonsensical example::
|
||||
|
||||
// SPDX-License-Identifier: GPL-3.0
|
||||
pragma solidity >=0.4.22 <0.8.0;
|
||||
|
||||
contract C {
|
||||
@ -82,6 +83,7 @@ to the total balance of that contract:
|
||||
|
||||
::
|
||||
|
||||
// SPDX-License-Identifier: GPL-3.0
|
||||
pragma solidity >=0.6.2 <0.8.0;
|
||||
|
||||
contract InfoFeed {
|
||||
@ -137,6 +139,7 @@ parameters from the function declaration, but can be in arbitrary order.
|
||||
|
||||
::
|
||||
|
||||
// SPDX-License-Identifier: GPL-3.0
|
||||
pragma solidity >=0.4.0 <0.8.0;
|
||||
|
||||
contract C {
|
||||
@ -160,6 +163,7 @@ Those parameters will still be present on the stack, but they are inaccessible.
|
||||
|
||||
::
|
||||
|
||||
// SPDX-License-Identifier: GPL-3.0
|
||||
pragma solidity >=0.4.22 <0.8.0;
|
||||
|
||||
contract C {
|
||||
@ -183,6 +187,7 @@ is compiled so recursive creation-dependencies are not possible.
|
||||
|
||||
::
|
||||
|
||||
// SPDX-License-Identifier: GPL-3.0
|
||||
pragma solidity >=0.6.2 <0.8.0;
|
||||
|
||||
contract D {
|
||||
@ -238,6 +243,7 @@ which only need to be created if there is a dispute.
|
||||
|
||||
::
|
||||
|
||||
// SPDX-License-Identifier: GPL-3.0
|
||||
pragma solidity >=0.6.2 <0.8.0;
|
||||
|
||||
contract D {
|
||||
@ -307,6 +313,7 @@ groupings of expressions.
|
||||
|
||||
::
|
||||
|
||||
// SPDX-License-Identifier: GPL-3.0
|
||||
pragma solidity >=0.5.0 <0.8.0;
|
||||
|
||||
contract C {
|
||||
@ -352,6 +359,7 @@ because only a reference and not a copy is passed.
|
||||
|
||||
::
|
||||
|
||||
// SPDX-License-Identifier: GPL-3.0
|
||||
pragma solidity >=0.4.22 <0.8.0;
|
||||
|
||||
contract C {
|
||||
@ -410,6 +418,7 @@ the two variables have the same name but disjoint scopes.
|
||||
|
||||
::
|
||||
|
||||
// SPDX-License-Identifier: GPL-3.0
|
||||
pragma solidity >=0.5.0 <0.8.0;
|
||||
contract C {
|
||||
function minimalScoping() pure public {
|
||||
@ -431,6 +440,7 @@ In any case, you will get a warning about the outer variable being shadowed.
|
||||
|
||||
::
|
||||
|
||||
// SPDX-License-Identifier: GPL-3.0
|
||||
pragma solidity >=0.5.0 <0.8.0;
|
||||
// This will report a warning
|
||||
contract C {
|
||||
@ -452,6 +462,7 @@ In any case, you will get a warning about the outer variable being shadowed.
|
||||
|
||||
::
|
||||
|
||||
// SPDX-License-Identifier: GPL-3.0
|
||||
pragma solidity >=0.5.0 <0.8.0;
|
||||
// This will not compile
|
||||
contract C {
|
||||
@ -540,6 +551,7 @@ and ``assert`` for internal error checking.
|
||||
|
||||
::
|
||||
|
||||
// SPDX-License-Identifier: GPL-3.0
|
||||
pragma solidity >=0.5.0 <0.8.0;
|
||||
|
||||
contract Sharer {
|
||||
@ -584,6 +596,7 @@ The following example shows how to use an error string together with ``revert``
|
||||
|
||||
::
|
||||
|
||||
// SPDX-License-Identifier: GPL-3.0
|
||||
pragma solidity >=0.5.0 <0.8.0;
|
||||
|
||||
contract VendingMachine {
|
||||
@ -627,6 +640,7 @@ A failure in an external call can be caught using a try/catch statement, as foll
|
||||
|
||||
::
|
||||
|
||||
// SPDX-License-Identifier: GPL-3.0
|
||||
pragma solidity >=0.6.0 <0.8.0;
|
||||
|
||||
interface DataFeed { function getData(address token) external returns (uint value); }
|
||||
|
@ -24,6 +24,7 @@ to receive their money - contracts cannot activate themselves.
|
||||
|
||||
::
|
||||
|
||||
// SPDX-License-Identifier: GPL-3.0
|
||||
pragma solidity >=0.5.0 <0.8.0;
|
||||
|
||||
contract SimpleAuction {
|
||||
@ -184,6 +185,7 @@ invalid bids.
|
||||
|
||||
::
|
||||
|
||||
// SPDX-License-Identifier: GPL-3.0
|
||||
pragma solidity >=0.5.0 <0.8.0;
|
||||
|
||||
contract BlindAuction {
|
||||
|
@ -142,6 +142,7 @@ The full contract
|
||||
|
||||
::
|
||||
|
||||
// SPDX-License-Identifier: GPL-3.0
|
||||
pragma solidity >=0.4.24 <0.8.0;
|
||||
|
||||
contract ReceiverPays {
|
||||
@ -338,6 +339,7 @@ The full contract
|
||||
|
||||
::
|
||||
|
||||
// SPDX-License-Identifier: GPL-3.0
|
||||
pragma solidity >=0.5.0 <0.8.0;
|
||||
|
||||
contract SimplePaymentChannel {
|
||||
|
@ -19,6 +19,7 @@ and the sum of all balances is an invariant across the lifetime of the contract.
|
||||
|
||||
::
|
||||
|
||||
// SPDX-License-Identifier: GPL-3.0
|
||||
pragma solidity >=0.5.0 <0.8.0;
|
||||
|
||||
library Balances {
|
||||
|
@ -25,6 +25,7 @@ you can use state machine-like constructs inside a contract.
|
||||
|
||||
::
|
||||
|
||||
// SPDX-License-Identifier: GPL-3.0
|
||||
pragma solidity >=0.5.0 <0.8.0;
|
||||
|
||||
contract Purchase {
|
||||
|
@ -32,6 +32,7 @@ of votes.
|
||||
|
||||
::
|
||||
|
||||
// SPDX-License-Identifier: GPL-3.0
|
||||
pragma solidity >=0.4.22 <0.8.0;
|
||||
|
||||
/// @title Voting with delegation.
|
||||
|
@ -71,6 +71,7 @@ So for the following contract snippet
|
||||
the position of ``data[4][9].b`` is at ``keccak256(uint256(9) . keccak256(uint256(4) . uint256(1))) + 1``::
|
||||
|
||||
|
||||
// SPDX-License-Identifier: GPL-3.0
|
||||
pragma solidity >=0.4.0 <0.8.0;
|
||||
|
||||
|
||||
@ -171,6 +172,7 @@ value and reference types, types that are encoded packed, and nested types.
|
||||
|
||||
.. code::
|
||||
|
||||
// SPDX-License-Identifier: GPL-3.0
|
||||
pragma solidity >=0.4.0 <0.8.0;
|
||||
contract A {
|
||||
struct S {
|
||||
|
@ -17,6 +17,7 @@ Storage Example
|
||||
|
||||
::
|
||||
|
||||
// SPDX-License-Identifier: GPL-3.0
|
||||
pragma solidity >=0.4.16 <0.8.0;
|
||||
|
||||
contract SimpleStorage {
|
||||
@ -31,8 +32,12 @@ Storage Example
|
||||
}
|
||||
}
|
||||
|
||||
The first line tells you that the source code is written for
|
||||
Solidity version 0.4.0, or a newer version of the language up to, but not including version 0.7.0.
|
||||
The first line tells you that the source code is licensed under the
|
||||
GPL version 3.0. Machine-readable license specifiers are important
|
||||
in a setting where publishing the source code is the default.
|
||||
|
||||
The next line specifies that the source code is written for
|
||||
Solidity version 0.4.16, or a newer version of the language up to, but not including version 0.7.0.
|
||||
This is to ensure that the contract is not compilable with a new (breaking) compiler version, where it could behave differently.
|
||||
:ref:`Pragmas<pragma>` are common instructions for compilers about how to treat the
|
||||
source code (e.g. `pragma once <https://en.wikipedia.org/wiki/Pragma_once>`_).
|
||||
@ -77,6 +82,7 @@ registering with a username and password, all you need is an Ethereum keypair.
|
||||
|
||||
::
|
||||
|
||||
// SPDX-License-Identifier: GPL-3.0
|
||||
pragma solidity >=0.5.0 <0.8.0;
|
||||
|
||||
contract Coin {
|
||||
|
@ -7,6 +7,38 @@ Source files can contain an arbitrary number of
|
||||
:ref:`pragma directives<pragma>` and
|
||||
:ref:`struct<structs>` and :ref:`enum<enums>` definitions.
|
||||
|
||||
.. index:: ! license, spdx
|
||||
|
||||
SPDX License Identifier
|
||||
=======================
|
||||
|
||||
Trust in smart contract can be better established if their source code
|
||||
is available. Since making source code available always touches on legal problems
|
||||
with regards to copyright, the Solidity compiler encouranges the use
|
||||
of machine-readable `SPDX license identifiers <https://spdx.org>`_.
|
||||
Every source file should start with a comment indicating its license:
|
||||
|
||||
``// SPDX-License-Identifier: MIT``
|
||||
|
||||
The compiler does not validate that the license is part of the
|
||||
`list allowed by SPDX <https://spdx.org/licenses/>`_, but
|
||||
it does include the supplied string in the `bytecode metadata <metadata>`_.
|
||||
|
||||
If you do not want to specify a license or if the source code is
|
||||
not open-source, please use the special value ``UNLICENSED``.
|
||||
|
||||
Supplying this comment of course does not free you from other
|
||||
obligations related to licensing like having to mention
|
||||
a specific license header in each source file or the
|
||||
original copyright holder.
|
||||
|
||||
The comment is recognized by the compiler anywhere in the file at the
|
||||
file level, but it is recommended to put it at the top of the file.
|
||||
|
||||
More information about how to use SPDX license identifiers
|
||||
can be found at the `SPDX website <https://spdx.org/ids-how>`_.
|
||||
|
||||
|
||||
.. index:: ! pragma
|
||||
|
||||
.. _pragma:
|
||||
@ -284,6 +316,7 @@ for the two function parameters and two return variables.
|
||||
|
||||
::
|
||||
|
||||
// SPDX-License-Identifier: GPL-3.0
|
||||
pragma solidity >=0.4.21 <0.8.0;
|
||||
|
||||
/** @title Shape calculator. */
|
||||
|
@ -1,3 +1,5 @@
|
||||
.. _metadata:
|
||||
|
||||
#################
|
||||
Contract Metadata
|
||||
#################
|
||||
@ -54,7 +56,9 @@ explanatory purposes.
|
||||
// Required (unless "content" is used, see below): Sorted URL(s)
|
||||
// to the source file, protocol is more or less arbitrary, but a
|
||||
// Swarm URL is recommended
|
||||
"urls": [ "bzzr://56ab..." ]
|
||||
"urls": [ "bzzr://56ab..." ],
|
||||
// Optional: SPDX license identifier as given in the source file
|
||||
"license": "MIT"
|
||||
},
|
||||
"destructible": {
|
||||
// Required: keccak256 hash of the source file
|
||||
|
@ -49,6 +49,7 @@ The following example shows a contract and a function using all available tags.
|
||||
|
||||
.. code:: solidity
|
||||
|
||||
// SPDX-License-Identifier: GPL-3.0
|
||||
pragma solidity >=0.5.0 <0.8.0;
|
||||
|
||||
/// @title A simulator for trees
|
||||
|
@ -58,6 +58,7 @@ complete contract):
|
||||
|
||||
::
|
||||
|
||||
// SPDX-License-Identifier: GPL-3.0
|
||||
pragma solidity >=0.4.0 <0.8.0;
|
||||
|
||||
// THIS CONTRACT CONTAINS A BUG - DO NOT USE
|
||||
@ -81,6 +82,7 @@ as it uses ``call`` which forwards all remaining gas by default:
|
||||
|
||||
::
|
||||
|
||||
// SPDX-License-Identifier: GPL-3.0
|
||||
pragma solidity >=0.6.2 <0.8.0;
|
||||
|
||||
// THIS CONTRACT CONTAINS A BUG - DO NOT USE
|
||||
@ -100,6 +102,7 @@ outlined further below:
|
||||
|
||||
::
|
||||
|
||||
// SPDX-License-Identifier: GPL-3.0
|
||||
pragma solidity >=0.4.11 <0.8.0;
|
||||
|
||||
contract Fund {
|
||||
@ -197,6 +200,7 @@ Never use tx.origin for authorization. Let's say you have a wallet contract like
|
||||
|
||||
::
|
||||
|
||||
// SPDX-License-Identifier: GPL-3.0
|
||||
pragma solidity >=0.5.0 <0.8.0;
|
||||
|
||||
// THIS CONTRACT CONTAINS A BUG - DO NOT USE
|
||||
@ -217,6 +221,7 @@ Now someone tricks you into sending Ether to the address of this attack wallet:
|
||||
|
||||
::
|
||||
|
||||
// SPDX-License-Identifier: GPL-3.0
|
||||
pragma solidity >=0.6.0 <0.8.0;
|
||||
|
||||
interface TxUserWallet {
|
||||
@ -277,6 +282,7 @@ field of a ``struct`` that is the base type of a dynamic storage array. The
|
||||
|
||||
::
|
||||
|
||||
// SPDX-License-Identifier: GPL-3.0
|
||||
pragma solidity >=0.6.0 <0.8.0;
|
||||
|
||||
contract Map {
|
||||
@ -555,6 +561,7 @@ not mean loss of proving power.
|
||||
|
||||
::
|
||||
|
||||
// SPDX-License-Identifier: GPL-3.0
|
||||
pragma solidity >=0.5.0;
|
||||
pragma experimental SMTChecker;
|
||||
// This may report a warning if no SMT solver available.
|
||||
@ -609,6 +616,7 @@ types.
|
||||
|
||||
::
|
||||
|
||||
// SPDX-License-Identifier: GPL-3.0
|
||||
pragma solidity >=0.5.0;
|
||||
pragma experimental SMTChecker;
|
||||
// This will report a warning
|
||||
|
@ -26,6 +26,7 @@ storage.
|
||||
|
||||
::
|
||||
|
||||
// SPDX-License-Identifier: GPL-3.0
|
||||
pragma solidity >=0.4.0 <0.8.0;
|
||||
|
||||
contract SimpleStorage {
|
||||
@ -46,6 +47,7 @@ Functions are the executable units of code within a contract.
|
||||
|
||||
::
|
||||
|
||||
// SPDX-License-Identifier: GPL-3.0
|
||||
pragma solidity >=0.4.0 <0.8.0;
|
||||
|
||||
contract SimpleAuction {
|
||||
@ -74,6 +76,7 @@ Like functions, modifiers can be :ref:`overridden <modifier-overriding>`.
|
||||
|
||||
::
|
||||
|
||||
// SPDX-License-Identifier: GPL-3.0
|
||||
pragma solidity >=0.4.22 <0.8.0;
|
||||
|
||||
contract Purchase {
|
||||
@ -101,6 +104,7 @@ Events are convenience interfaces with the EVM logging facilities.
|
||||
|
||||
::
|
||||
|
||||
// SPDX-License-Identifier: GPL-3.0
|
||||
pragma solidity >=0.4.21 <0.8.0;
|
||||
|
||||
contract SimpleAuction {
|
||||
@ -125,6 +129,7 @@ Structs are custom defined types that can group several variables (see
|
||||
|
||||
::
|
||||
|
||||
// SPDX-License-Identifier: GPL-3.0
|
||||
pragma solidity >=0.4.0 <0.8.0;
|
||||
|
||||
contract Ballot {
|
||||
@ -146,6 +151,7 @@ Enums can be used to create custom types with a finite set of 'constant values'
|
||||
|
||||
::
|
||||
|
||||
// SPDX-License-Identifier: GPL-3.0
|
||||
pragma solidity >=0.4.0 <0.8.0;
|
||||
|
||||
contract Purchase {
|
||||
|
@ -55,6 +55,7 @@ Surround top level declarations in solidity source with two blank lines.
|
||||
|
||||
Yes::
|
||||
|
||||
// SPDX-License-Identifier: GPL-3.0
|
||||
pragma solidity >=0.4.0 <0.8.0;
|
||||
|
||||
contract A {
|
||||
@ -73,6 +74,7 @@ Yes::
|
||||
|
||||
No::
|
||||
|
||||
// SPDX-License-Identifier: GPL-3.0
|
||||
pragma solidity >=0.4.0 <0.8.0;
|
||||
|
||||
contract A {
|
||||
@ -92,6 +94,7 @@ Blank lines may be omitted between groups of related one-liners (such as stub fu
|
||||
|
||||
Yes::
|
||||
|
||||
// SPDX-License-Identifier: GPL-3.0
|
||||
pragma solidity >=0.6.0 <0.8.0;
|
||||
|
||||
abstract contract A {
|
||||
@ -112,6 +115,7 @@ Yes::
|
||||
|
||||
No::
|
||||
|
||||
// SPDX-License-Identifier: GPL-3.0
|
||||
pragma solidity >=0.6.0 <0.8.0;
|
||||
|
||||
abstract contract A {
|
||||
@ -246,6 +250,7 @@ Import statements should always be placed at the top of the file.
|
||||
|
||||
Yes::
|
||||
|
||||
// SPDX-License-Identifier: GPL-3.0
|
||||
pragma solidity >=0.4.0 <0.8.0;
|
||||
|
||||
import "./Owned.sol";
|
||||
@ -260,6 +265,7 @@ Yes::
|
||||
|
||||
No::
|
||||
|
||||
// SPDX-License-Identifier: GPL-3.0
|
||||
pragma solidity >=0.4.0 <0.8.0;
|
||||
|
||||
contract A {
|
||||
@ -293,6 +299,7 @@ Within a grouping, place the ``view`` and ``pure`` functions last.
|
||||
|
||||
Yes::
|
||||
|
||||
// SPDX-License-Identifier: GPL-3.0
|
||||
pragma solidity >=0.6.0 <0.8.0;
|
||||
|
||||
contract A {
|
||||
@ -329,6 +336,7 @@ Yes::
|
||||
|
||||
No::
|
||||
|
||||
// SPDX-License-Identifier: GPL-3.0
|
||||
pragma solidity >=0.6.0 <0.8.0;
|
||||
|
||||
contract A {
|
||||
@ -436,6 +444,7 @@ should:
|
||||
|
||||
Yes::
|
||||
|
||||
// SPDX-License-Identifier: GPL-3.0
|
||||
pragma solidity >=0.4.0 <0.8.0;
|
||||
|
||||
contract Coin {
|
||||
@ -447,6 +456,7 @@ Yes::
|
||||
|
||||
No::
|
||||
|
||||
// SPDX-License-Identifier: GPL-3.0
|
||||
pragma solidity >=0.4.0 <0.8.0;
|
||||
|
||||
contract Coin
|
||||
@ -747,6 +757,7 @@ manner as modifiers if the function declaration is long or hard to read.
|
||||
|
||||
Yes::
|
||||
|
||||
// SPDX-License-Identifier: GPL-3.0
|
||||
pragma solidity >=0.4.22 <0.8.0;
|
||||
|
||||
// Base contracts just to make this compile
|
||||
@ -779,6 +790,7 @@ Yes::
|
||||
|
||||
No::
|
||||
|
||||
// SPDX-License-Identifier: GPL-3.0
|
||||
pragma solidity >=0.4.22 <0.8.0;
|
||||
|
||||
|
||||
@ -1002,6 +1014,7 @@ As shown in the example below, if the contract name is ``Congress`` and the libr
|
||||
|
||||
Yes::
|
||||
|
||||
// SPDX-License-Identifier: GPL-3.0
|
||||
pragma solidity >=0.4.22 <0.8.0;
|
||||
|
||||
|
||||
@ -1025,6 +1038,7 @@ Yes::
|
||||
|
||||
and in ``Congress.sol``::
|
||||
|
||||
// SPDX-License-Identifier: GPL-3.0
|
||||
pragma solidity >=0.4.0 <0.8.0;
|
||||
|
||||
import "./Owned.sol";
|
||||
@ -1036,6 +1050,7 @@ and in ``Congress.sol``::
|
||||
|
||||
No::
|
||||
|
||||
// SPDX-License-Identifier: GPL-3.0
|
||||
pragma solidity >=0.4.22 <0.8.0;
|
||||
|
||||
|
||||
@ -1140,6 +1155,7 @@ multiline comment starting with ``/**`` and ending with ``*/``.
|
||||
For example, the contract from `a simple smart contract <simple-smart-contract>`_ with the comments
|
||||
added looks like the one below::
|
||||
|
||||
// SPDX-License-Identifier: GPL-3.0
|
||||
pragma solidity >=0.4.16 <0.8.0;
|
||||
|
||||
|
||||
|
@ -41,6 +41,7 @@ contract that returns the value at the specified address.
|
||||
|
||||
::
|
||||
|
||||
// SPDX-License-Identifier: GPL-3.0
|
||||
pragma solidity >=0.4.0 <0.8.0;
|
||||
|
||||
contract MappingExample {
|
||||
@ -66,6 +67,7 @@ The example below uses ``_allowances`` to record the amount someone else is allo
|
||||
|
||||
::
|
||||
|
||||
// SPDX-License-Identifier: GPL-3.0
|
||||
pragma solidity >=0.4.22 <0.8.0;
|
||||
|
||||
contract MappingExample {
|
||||
@ -120,6 +122,7 @@ the ``sum`` function iterates over to sum all the values.
|
||||
|
||||
::
|
||||
|
||||
// SPDX-License-Identifier: GPL-3.0
|
||||
pragma solidity >=0.6.0 <0.8.0;
|
||||
|
||||
struct IndexValue { uint keyIndex; uint value; }
|
||||
|
@ -42,6 +42,7 @@ value it referred to previously.
|
||||
|
||||
::
|
||||
|
||||
// SPDX-License-Identifier: GPL-3.0
|
||||
pragma solidity >=0.4.0 <0.8.0;
|
||||
|
||||
contract DeleteExample {
|
||||
|
@ -57,6 +57,7 @@ Data locations are not only relevant for persistency of data, but also for the s
|
||||
|
||||
::
|
||||
|
||||
// SPDX-License-Identifier: GPL-3.0
|
||||
pragma solidity >=0.5.0 <0.8.0;
|
||||
|
||||
contract C {
|
||||
@ -167,6 +168,7 @@ or create a new memory array and copy every element.
|
||||
|
||||
::
|
||||
|
||||
// SPDX-License-Identifier: GPL-3.0
|
||||
pragma solidity >=0.4.16 <0.8.0;
|
||||
|
||||
contract C {
|
||||
@ -198,6 +200,7 @@ the first element to ``uint``.
|
||||
|
||||
::
|
||||
|
||||
// SPDX-License-Identifier: GPL-3.0
|
||||
pragma solidity >=0.4.16 <0.8.0;
|
||||
|
||||
contract C {
|
||||
@ -214,6 +217,7 @@ memory arrays, i.e. the following is not possible:
|
||||
|
||||
::
|
||||
|
||||
// SPDX-License-Identifier: GPL-3.0
|
||||
pragma solidity >=0.4.0 <0.8.0;
|
||||
|
||||
// This will not compile.
|
||||
@ -274,6 +278,7 @@ Array Members
|
||||
|
||||
::
|
||||
|
||||
// SPDX-License-Identifier: GPL-3.0
|
||||
pragma solidity >=0.6.0 <0.8.0;
|
||||
|
||||
contract ArrayContract {
|
||||
@ -406,6 +411,7 @@ Array slices are useful to ABI-decode secondary data passed in function paramete
|
||||
|
||||
::
|
||||
|
||||
// SPDX-License-Identifier: GPL-3.0
|
||||
pragma solidity >=0.6.0 <0.8.0;
|
||||
|
||||
contract Proxy {
|
||||
@ -443,6 +449,7 @@ shown in the following example:
|
||||
|
||||
::
|
||||
|
||||
// SPDX-License-Identifier: GPL-3.0
|
||||
pragma solidity >=0.6.0 <0.8.0;
|
||||
|
||||
// Defines a new type with two fields.
|
||||
|
@ -543,6 +543,7 @@ subsequent unsigned integer values starting from ``0``.
|
||||
|
||||
::
|
||||
|
||||
// SPDX-License-Identifier: GPL-3.0
|
||||
pragma solidity >=0.4.16 <0.8.0;
|
||||
|
||||
contract test {
|
||||
@ -655,7 +656,13 @@ External (or public) functions have the following members:
|
||||
|
||||
Example that shows how to use the members::
|
||||
|
||||
<<<<<<< HEAD
|
||||
pragma solidity >=0.6.4 <0.8.0;
|
||||
=======
|
||||
// SPDX-License-Identifier: GPL-3.0
|
||||
pragma solidity >=0.6.0 <0.7.0;
|
||||
// This will report a warning
|
||||
>>>>>>> origin/develop
|
||||
|
||||
contract Example {
|
||||
function f() public payable returns (bytes4) {
|
||||
@ -670,6 +677,7 @@ Example that shows how to use the members::
|
||||
|
||||
Example that shows how to use internal function types::
|
||||
|
||||
// SPDX-License-Identifier: GPL-3.0
|
||||
pragma solidity >=0.4.16 <0.8.0;
|
||||
|
||||
library ArrayUtils {
|
||||
@ -727,6 +735,7 @@ Example that shows how to use internal function types::
|
||||
|
||||
Another example that uses external function types::
|
||||
|
||||
// SPDX-License-Identifier: GPL-3.0
|
||||
pragma solidity >=0.4.22 <0.8.0;
|
||||
|
||||
|
||||
|
@ -627,6 +627,7 @@ Assume you have the following contracts you want to update declared in ``Source.
|
||||
.. code-block:: none
|
||||
|
||||
// This will not compile after 0.5.0
|
||||
// SPDX-License-Identifier: GPL-3.0
|
||||
pragma solidity >0.4.23 <0.5.0;
|
||||
|
||||
contract Updateable {
|
||||
@ -709,6 +710,7 @@ The command above applies all changes as shown below. Please review them careful
|
||||
|
||||
.. code-block:: solidity
|
||||
|
||||
// SPDX-License-Identifier: GPL-3.0
|
||||
pragma solidity >=0.6.0 <0.8.0;
|
||||
|
||||
abstract contract Updateable {
|
||||
|
@ -134,6 +134,12 @@ public:
|
||||
return m_errorCount > 0;
|
||||
}
|
||||
|
||||
/// @returns the number of errors (ignores warnings).
|
||||
unsigned errorCount() const
|
||||
{
|
||||
return m_errorCount;
|
||||
}
|
||||
|
||||
// @returns true if the maximum error count has been reached.
|
||||
bool hasExcessiveErrors() const;
|
||||
|
||||
|
@ -148,6 +148,11 @@ void ParserBase::parserWarning(ErrorId _error, string const& _description)
|
||||
m_errorReporter.warning(_error, currentLocation(), _description);
|
||||
}
|
||||
|
||||
void ParserBase::parserWarning(ErrorId _error, SourceLocation const& _location, string const& _description)
|
||||
{
|
||||
m_errorReporter.warning(_error, _location, _description);
|
||||
}
|
||||
|
||||
void ParserBase::parserError(ErrorId _error, SourceLocation const& _location, string const& _description)
|
||||
{
|
||||
m_errorReporter.parserError(_error, _location, _description);
|
||||
|
@ -95,6 +95,7 @@ protected:
|
||||
/// Creates a @ref ParserWarning and annotates it with the current position and the
|
||||
/// given @a _description.
|
||||
void parserWarning(ErrorId _error, std::string const& _description);
|
||||
void parserWarning(ErrorId _error, SourceLocation const& _location, std::string const& _description);
|
||||
|
||||
/// Creates a @ref ParserError and annotates it with the current position and the
|
||||
/// given @a _description. Throws the FatalError.
|
||||
|
@ -361,24 +361,22 @@ void DeclarationTypeChecker::endVisit(VariableDeclaration const& _variable)
|
||||
|
||||
void DeclarationTypeChecker::typeError(SourceLocation const& _location, string const& _description)
|
||||
{
|
||||
m_errorOccurred = true;
|
||||
m_errorReporter.typeError(2311_error, _location, _description);
|
||||
}
|
||||
|
||||
void DeclarationTypeChecker::fatalTypeError(SourceLocation const& _location, string const& _description)
|
||||
{
|
||||
m_errorOccurred = true;
|
||||
m_errorReporter.fatalTypeError(5651_error, _location, _description);
|
||||
}
|
||||
|
||||
void DeclarationTypeChecker::fatalDeclarationError(SourceLocation const& _location, string const& _description)
|
||||
{
|
||||
m_errorOccurred = true;
|
||||
m_errorReporter.fatalDeclarationError(2046_error, _location, _description);
|
||||
}
|
||||
|
||||
bool DeclarationTypeChecker::check(ASTNode const& _node)
|
||||
{
|
||||
unsigned errorCount = m_errorReporter.errorCount();
|
||||
_node.accept(*this);
|
||||
return !m_errorOccurred;
|
||||
return m_errorReporter.errorCount() == errorCount;
|
||||
}
|
||||
|
@ -69,7 +69,6 @@ private:
|
||||
void fatalDeclarationError(langutil::SourceLocation const& _location, std::string const& _description);
|
||||
|
||||
langutil::ErrorReporter& m_errorReporter;
|
||||
bool m_errorOccurred = false;
|
||||
langutil::EVMVersion m_evmVersion;
|
||||
bool m_insideFunctionType = false;
|
||||
bool m_recursiveStructSeen = false;
|
||||
|
@ -2866,6 +2866,8 @@ bool TypeChecker::visit(IndexRangeAccess const& _access)
|
||||
|
||||
if (arrayType->location() != DataLocation::CallData || !arrayType->isDynamicallySized())
|
||||
m_errorReporter.typeError(1227_error, _access.location(), "Index range access is only supported for dynamic calldata arrays.");
|
||||
else if (arrayType->baseType()->isDynamicallyEncoded())
|
||||
m_errorReporter.typeError(1878_error, _access.location(), "Index range access is not supported for arrays with dynamically encoded base types.");
|
||||
_access.annotation().type = TypeProvider::arraySlice(*arrayType);
|
||||
_access.annotation().isLValue = isLValue;
|
||||
_access.annotation().isPure = isPure;
|
||||
|
@ -156,19 +156,26 @@ std::vector<T const*> ASTNode::filteredNodes(std::vector<ASTPointer<ASTNode>> co
|
||||
class SourceUnit: public ASTNode
|
||||
{
|
||||
public:
|
||||
SourceUnit(int64_t _id, SourceLocation const& _location, std::vector<ASTPointer<ASTNode>> _nodes):
|
||||
ASTNode(_id, _location), m_nodes(std::move(_nodes)) {}
|
||||
SourceUnit(
|
||||
int64_t _id,
|
||||
SourceLocation const& _location,
|
||||
std::optional<std::string> _licenseString,
|
||||
std::vector<ASTPointer<ASTNode>> _nodes
|
||||
):
|
||||
ASTNode(_id, _location), m_licenseString(std::move(_licenseString)), m_nodes(std::move(_nodes)) {}
|
||||
|
||||
void accept(ASTVisitor& _visitor) override;
|
||||
void accept(ASTConstVisitor& _visitor) const override;
|
||||
SourceUnitAnnotation& annotation() const override;
|
||||
|
||||
std::optional<std::string> const& licenseString() const { return m_licenseString; }
|
||||
std::vector<ASTPointer<ASTNode>> nodes() const { return m_nodes; }
|
||||
|
||||
/// @returns a set of referenced SourceUnits. Recursively if @a _recurse is true.
|
||||
std::set<SourceUnit const*> referencedSourceUnits(bool _recurse = false, std::set<SourceUnit const*> _skipList = std::set<SourceUnit const*>()) const;
|
||||
|
||||
private:
|
||||
std::optional<std::string> m_licenseString;
|
||||
std::vector<ASTPointer<ASTNode>> m_nodes;
|
||||
};
|
||||
|
||||
|
@ -225,6 +225,7 @@ bool ASTJsonConverter::visit(SourceUnit const& _node)
|
||||
{
|
||||
make_pair("absolutePath", _node.annotation().path),
|
||||
make_pair("exportedSymbols", move(exportedSymbols)),
|
||||
make_pair("license", _node.licenseString() ? Json::Value(*_node.licenseString()) : Json::nullValue),
|
||||
make_pair("nodes", toJson(_node.nodes()))
|
||||
}
|
||||
);
|
||||
|
@ -218,10 +218,15 @@ ASTPointer<ASTNode> ASTJsonImporter::convertJsonToASTNode(Json::Value const& _js
|
||||
|
||||
ASTPointer<SourceUnit> ASTJsonImporter::createSourceUnit(Json::Value const& _node, string const& _srcName)
|
||||
{
|
||||
optional<string> license;
|
||||
if (_node.isMember("license") && !_node["license"].isNull())
|
||||
license = _node["license"].asString();
|
||||
|
||||
vector<ASTPointer<ASTNode>> nodes;
|
||||
for (auto& child: member(_node, "nodes"))
|
||||
nodes.emplace_back(convertJsonToASTNode(child));
|
||||
ASTPointer<SourceUnit> tmp = createASTNode<SourceUnit>(_node, nodes);
|
||||
|
||||
ASTPointer<SourceUnit> tmp = createASTNode<SourceUnit>(_node, license, nodes);
|
||||
tmp->annotation().path = _srcName;
|
||||
return tmp;
|
||||
}
|
||||
|
@ -330,7 +330,7 @@ TypePointer Type::fullEncodingType(bool _inLibraryCall, bool _encoderV2, bool) c
|
||||
// Structs are fine in the following circumstances:
|
||||
// - ABIv2 or,
|
||||
// - storage struct for a library
|
||||
if (_inLibraryCall && encodingType->dataStoredIn(DataLocation::Storage))
|
||||
if (_inLibraryCall && encodingType && encodingType->dataStoredIn(DataLocation::Storage))
|
||||
return encodingType;
|
||||
TypePointer baseType = encodingType;
|
||||
while (auto const* arrayType = dynamic_cast<ArrayType const*>(baseType))
|
||||
@ -613,6 +613,13 @@ TypeResult IntegerType::binaryOperatorResult(Token _operator, Type const* _other
|
||||
}
|
||||
else if (dynamic_cast<FixedPointType const*>(_other))
|
||||
return nullptr;
|
||||
else if (auto rationalNumberType = dynamic_cast<RationalNumberType const*>(_other))
|
||||
{
|
||||
if (rationalNumberType->isFractional())
|
||||
return TypeResult::err("Exponent is fractional.");
|
||||
if (!rationalNumberType->integerType())
|
||||
return TypeResult::err("Exponent too large.");
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
@ -1964,6 +1971,19 @@ string ArraySliceType::toString(bool _short) const
|
||||
return m_arrayType.toString(_short) + " slice";
|
||||
}
|
||||
|
||||
TypePointer ArraySliceType::mobileType() const
|
||||
{
|
||||
if (
|
||||
m_arrayType.dataStoredIn(DataLocation::CallData) &&
|
||||
m_arrayType.isDynamicallySized() &&
|
||||
!m_arrayType.baseType()->isDynamicallyEncoded()
|
||||
)
|
||||
return &m_arrayType;
|
||||
else
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
std::vector<std::tuple<std::string, TypePointer>> ArraySliceType::makeStackItems() const
|
||||
{
|
||||
return {{"offset", TypeProvider::uint256()}, {"length", TypeProvider::uint256()}};
|
||||
|
@ -831,6 +831,7 @@ public:
|
||||
bool isDynamicallyEncoded() const override { return true; }
|
||||
bool canLiveOutsideStorage() const override { return m_arrayType.canLiveOutsideStorage(); }
|
||||
std::string toString(bool _short) const override;
|
||||
TypePointer mobileType() const override;
|
||||
|
||||
BoolResult validForLocation(DataLocation _loc) const override { return m_arrayType.validForLocation(_loc); }
|
||||
|
||||
|
@ -279,31 +279,47 @@ string ABIFunctions::abiEncodingFunction(
|
||||
return abiEncodingFunctionStringLiteral(_from, to, _options);
|
||||
else if (auto toArray = dynamic_cast<ArrayType const*>(&to))
|
||||
{
|
||||
solAssert(_from.category() == Type::Category::Array, "");
|
||||
solAssert(to.dataStoredIn(DataLocation::Memory), "");
|
||||
ArrayType const& fromArray = dynamic_cast<ArrayType const&>(_from);
|
||||
ArrayType const* fromArray = nullptr;
|
||||
switch (_from.category())
|
||||
{
|
||||
case Type::Category::Array:
|
||||
fromArray = dynamic_cast<ArrayType const*>(&_from);
|
||||
break;
|
||||
case Type::Category::ArraySlice:
|
||||
fromArray = &dynamic_cast<ArraySliceType const*>(&_from)->arrayType();
|
||||
solAssert(
|
||||
fromArray->dataStoredIn(DataLocation::CallData) &&
|
||||
fromArray->isDynamicallySized() &&
|
||||
!fromArray->baseType()->isDynamicallyEncoded(),
|
||||
""
|
||||
);
|
||||
break;
|
||||
default:
|
||||
solAssert(false, "");
|
||||
break;
|
||||
}
|
||||
|
||||
switch (fromArray.location())
|
||||
switch (fromArray->location())
|
||||
{
|
||||
case DataLocation::CallData:
|
||||
if (
|
||||
fromArray.isByteArray() ||
|
||||
*fromArray.baseType() == *TypeProvider::uint256() ||
|
||||
*fromArray.baseType() == FixedBytesType(32)
|
||||
fromArray->isByteArray() ||
|
||||
*fromArray->baseType() == *TypeProvider::uint256() ||
|
||||
*fromArray->baseType() == FixedBytesType(32)
|
||||
)
|
||||
return abiEncodingFunctionCalldataArrayWithoutCleanup(fromArray, *toArray, _options);
|
||||
return abiEncodingFunctionCalldataArrayWithoutCleanup(*fromArray, *toArray, _options);
|
||||
else
|
||||
return abiEncodingFunctionSimpleArray(fromArray, *toArray, _options);
|
||||
return abiEncodingFunctionSimpleArray(*fromArray, *toArray, _options);
|
||||
case DataLocation::Memory:
|
||||
if (fromArray.isByteArray())
|
||||
return abiEncodingFunctionMemoryByteArray(fromArray, *toArray, _options);
|
||||
if (fromArray->isByteArray())
|
||||
return abiEncodingFunctionMemoryByteArray(*fromArray, *toArray, _options);
|
||||
else
|
||||
return abiEncodingFunctionSimpleArray(fromArray, *toArray, _options);
|
||||
return abiEncodingFunctionSimpleArray(*fromArray, *toArray, _options);
|
||||
case DataLocation::Storage:
|
||||
if (fromArray.baseType()->storageBytes() <= 16)
|
||||
return abiEncodingFunctionCompactStorageArray(fromArray, *toArray, _options);
|
||||
if (fromArray->baseType()->storageBytes() <= 16)
|
||||
return abiEncodingFunctionCompactStorageArray(*fromArray, *toArray, _options);
|
||||
else
|
||||
return abiEncodingFunctionSimpleArray(fromArray, *toArray, _options);
|
||||
return abiEncodingFunctionSimpleArray(*fromArray, *toArray, _options);
|
||||
default:
|
||||
solAssert(false, "");
|
||||
}
|
||||
|
@ -480,6 +480,16 @@ void CompilerUtils::encodeToMemory(
|
||||
convertType(*_givenTypes[i], *targetType, true);
|
||||
if (auto arrayType = dynamic_cast<ArrayType const*>(type))
|
||||
ArrayUtils(m_context).copyArrayToMemory(*arrayType, _padToWordBoundaries);
|
||||
else if (auto arraySliceType = dynamic_cast<ArraySliceType const*>(type))
|
||||
{
|
||||
solAssert(
|
||||
arraySliceType->dataStoredIn(DataLocation::CallData) &&
|
||||
arraySliceType->isDynamicallySized() &&
|
||||
!arraySliceType->arrayType().baseType()->isDynamicallyEncoded(),
|
||||
""
|
||||
);
|
||||
ArrayUtils(m_context).copyArrayToMemory(arraySliceType->arrayType(), _padToWordBoundaries);
|
||||
}
|
||||
else
|
||||
storeInMemoryDynamic(*type, _padToWordBoundaries);
|
||||
}
|
||||
@ -516,22 +526,39 @@ void CompilerUtils::encodeToMemory(
|
||||
}
|
||||
else
|
||||
{
|
||||
solAssert(_givenTypes[i]->category() == Type::Category::Array, "Unknown dynamic type.");
|
||||
auto const& arrayType = dynamic_cast<ArrayType const&>(*_givenTypes[i]);
|
||||
ArrayType const* arrayType = nullptr;
|
||||
switch (_givenTypes[i]->category())
|
||||
{
|
||||
case Type::Category::Array:
|
||||
arrayType = dynamic_cast<ArrayType const*>(_givenTypes[i]);
|
||||
break;
|
||||
case Type::Category::ArraySlice:
|
||||
arrayType = &dynamic_cast<ArraySliceType const*>(_givenTypes[i])->arrayType();
|
||||
solAssert(
|
||||
arrayType->isDynamicallySized() &&
|
||||
arrayType->dataStoredIn(DataLocation::CallData) &&
|
||||
!arrayType->baseType()->isDynamicallyEncoded(),
|
||||
""
|
||||
);
|
||||
break;
|
||||
default:
|
||||
solAssert(false, "Unknown dynamic type.");
|
||||
break;
|
||||
}
|
||||
// now copy the array
|
||||
copyToStackTop(argSize - stackPos + dynPointers + 2, arrayType.sizeOnStack());
|
||||
copyToStackTop(argSize - stackPos + dynPointers + 2, arrayType->sizeOnStack());
|
||||
// stack: ... <end_of_mem> <value...>
|
||||
// copy length to memory
|
||||
m_context << dupInstruction(1 + arrayType.sizeOnStack());
|
||||
ArrayUtils(m_context).retrieveLength(arrayType, 1);
|
||||
m_context << dupInstruction(1 + arrayType->sizeOnStack());
|
||||
ArrayUtils(m_context).retrieveLength(*arrayType, 1);
|
||||
// stack: ... <end_of_mem> <value...> <end_of_mem'> <length>
|
||||
storeInMemoryDynamic(*TypeProvider::uint256(), true);
|
||||
// stack: ... <end_of_mem> <value...> <end_of_mem''>
|
||||
// copy the new memory pointer
|
||||
m_context << swapInstruction(arrayType.sizeOnStack() + 1) << Instruction::POP;
|
||||
m_context << swapInstruction(arrayType->sizeOnStack() + 1) << Instruction::POP;
|
||||
// stack: ... <end_of_mem''> <value...>
|
||||
// copy data part
|
||||
ArrayUtils(m_context).copyArrayToMemory(arrayType, _padToWordBoundaries);
|
||||
ArrayUtils(m_context).copyArrayToMemory(*arrayType, _padToWordBoundaries);
|
||||
// stack: ... <end_of_mem'''>
|
||||
}
|
||||
|
||||
@ -990,7 +1017,8 @@ void CompilerUtils::convertType(
|
||||
solAssert(_targetType == typeOnStack.arrayType(), "");
|
||||
solUnimplementedAssert(
|
||||
typeOnStack.arrayType().location() == DataLocation::CallData &&
|
||||
typeOnStack.arrayType().isDynamicallySized(),
|
||||
typeOnStack.arrayType().isDynamicallySized() &&
|
||||
!typeOnStack.arrayType().baseType()->isDynamicallyEncoded(),
|
||||
""
|
||||
);
|
||||
break;
|
||||
|
@ -1769,7 +1769,12 @@ bool ExpressionCompiler::visit(IndexAccess const& _indexAccess)
|
||||
case Type::Category::ArraySlice:
|
||||
{
|
||||
auto const& arrayType = dynamic_cast<ArraySliceType const&>(baseType).arrayType();
|
||||
solAssert(arrayType.location() == DataLocation::CallData && arrayType.isDynamicallySized(), "");
|
||||
solAssert(
|
||||
arrayType.location() == DataLocation::CallData &&
|
||||
arrayType.isDynamicallySized() &&
|
||||
!arrayType.baseType()->isDynamicallyEncoded(),
|
||||
""
|
||||
);
|
||||
solAssert(_indexAccess.indexExpression(), "Index expression expected.");
|
||||
|
||||
acceptAndConvert(*_indexAccess.indexExpression(), *TypeProvider::uint256(), true);
|
||||
@ -1852,7 +1857,12 @@ bool ExpressionCompiler::visit(IndexRangeAccess const& _indexAccess)
|
||||
arrayType = &sliceType->arrayType();
|
||||
|
||||
solAssert(arrayType, "");
|
||||
solUnimplementedAssert(arrayType->location() == DataLocation::CallData && arrayType->isDynamicallySized(), "");
|
||||
solUnimplementedAssert(
|
||||
arrayType->location() == DataLocation::CallData &&
|
||||
arrayType->isDynamicallySized() &&
|
||||
!arrayType->baseType()->isDynamicallyEncoded(),
|
||||
""
|
||||
);
|
||||
|
||||
if (_indexAccess.startExpression())
|
||||
acceptAndConvert(*_indexAccess.startExpression(), *TypeProvider::uint256());
|
||||
|
@ -1599,6 +1599,7 @@ string YulUtilFunctions::conversionFunction(Type const& _from, Type const& _to)
|
||||
ArraySliceType const& fromType = dynamic_cast<ArraySliceType const&>(_from);
|
||||
ArrayType const& targetType = dynamic_cast<ArrayType const&>(_to);
|
||||
|
||||
solAssert(!fromType.arrayType().baseType()->isDynamicallyEncoded(), "");
|
||||
solAssert(
|
||||
*fromType.arrayType().baseType() == *targetType.baseType(),
|
||||
"Converting arrays of different type is not possible"
|
||||
|
@ -1236,6 +1236,8 @@ string CompilerStack::createMetadata(Contract const& _contract) const
|
||||
|
||||
solAssert(s.second.scanner, "Scanner not available");
|
||||
meta["sources"][s.first]["keccak256"] = "0x" + toHex(s.second.keccak256().asBytes());
|
||||
if (optional<string> licenseString = s.second.ast->licenseString())
|
||||
meta["sources"][s.first]["license"] = *licenseString;
|
||||
if (m_metadataLiteralSources)
|
||||
meta["sources"][s.first]["content"] = s.second.scanner->source();
|
||||
else
|
||||
|
@ -30,8 +30,11 @@
|
||||
#include <liblangutil/SemVerHandler.h>
|
||||
#include <liblangutil/SourceLocation.h>
|
||||
#include <libyul/backends/evm/EVMDialect.h>
|
||||
#include <boost/algorithm/string/trim.hpp>
|
||||
#include <boost/algorithm/string/replace.hpp>
|
||||
#include <cctype>
|
||||
#include <vector>
|
||||
#include <regex>
|
||||
|
||||
using namespace std;
|
||||
using namespace solidity::langutil;
|
||||
@ -79,6 +82,7 @@ ASTPointer<SourceUnit> Parser::parse(shared_ptr<Scanner> const& _scanner)
|
||||
m_recursionDepth = 0;
|
||||
m_scanner = _scanner;
|
||||
ASTNodeFactory nodeFactory(*this);
|
||||
|
||||
vector<ASTPointer<ASTNode>> nodes;
|
||||
while (m_scanner->currentToken() != Token::EOS)
|
||||
{
|
||||
@ -107,7 +111,7 @@ ASTPointer<SourceUnit> Parser::parse(shared_ptr<Scanner> const& _scanner)
|
||||
}
|
||||
}
|
||||
solAssert(m_recursionDepth == 0, "");
|
||||
return nodeFactory.createNode<SourceUnit>(nodes);
|
||||
return nodeFactory.createNode<SourceUnit>(findLicenseString(nodes), nodes);
|
||||
}
|
||||
catch (FatalError const&)
|
||||
{
|
||||
@ -1981,6 +1985,60 @@ pair<vector<ASTPointer<Expression>>, vector<ASTPointer<ASTString>>> Parser::pars
|
||||
return ret;
|
||||
}
|
||||
|
||||
optional<string> Parser::findLicenseString(std::vector<ASTPointer<ASTNode>> const& _nodes)
|
||||
{
|
||||
// We circumvent the scanner here, because it skips non-docstring comments.
|
||||
static regex const licenseRegex("SPDX-License-Identifier:\\s*([a-zA-Z0-9 ()+.-]+)");
|
||||
|
||||
// Search inside all parts of the source not covered by parsed nodes.
|
||||
// This will leave e.g. "global comments".
|
||||
string const& source = m_scanner->source();
|
||||
using iter = decltype(source.begin());
|
||||
vector<pair<iter, iter>> sequencesToSearch;
|
||||
sequencesToSearch.emplace_back(source.begin(), source.end());
|
||||
for (ASTPointer<ASTNode> const& node: _nodes)
|
||||
if (node->location().hasText())
|
||||
{
|
||||
sequencesToSearch.back().second = source.begin() + node->location().start;
|
||||
sequencesToSearch.emplace_back(source.begin() + node->location().end, source.end());
|
||||
}
|
||||
|
||||
vector<string> matches;
|
||||
for (auto const& [start, end]: sequencesToSearch)
|
||||
{
|
||||
smatch match;
|
||||
if (regex_search(start, end, match, licenseRegex))
|
||||
{
|
||||
string license{boost::trim_copy(string(match[1]))};
|
||||
if (!license.empty())
|
||||
matches.emplace_back(std::move(license));
|
||||
}
|
||||
}
|
||||
|
||||
if (matches.size() == 1)
|
||||
return matches.front();
|
||||
else if (matches.empty())
|
||||
parserWarning(
|
||||
1878_error,
|
||||
{-1, -1, m_scanner->charStream()},
|
||||
"SPDX license identifier not provided in source file. "
|
||||
"Before publishing, consider adding a comment containing "
|
||||
"\"SPDX-License-Identifier: <SPDX-License>\" to each source file. "
|
||||
"Use \"SPDX-License-Identifier: UNLICENSED\" for non-open-source code. "
|
||||
"Please see https://spdx.org for more information."
|
||||
);
|
||||
else
|
||||
parserError(
|
||||
3716_error,
|
||||
{-1, -1, m_scanner->charStream()},
|
||||
"Multiple SPDX license identifiers found in source file. "
|
||||
"Use \"AND\" or \"OR\" to combine multiple licenses. "
|
||||
"Please see https://spdx.org for more information."
|
||||
);
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
Parser::LookAheadInfo Parser::peekStatementType() const
|
||||
{
|
||||
// Distinguish between variable declaration (and potentially assignment) and expression statement
|
||||
|
@ -175,6 +175,8 @@ private:
|
||||
bool empty() const;
|
||||
};
|
||||
|
||||
std::optional<std::string> findLicenseString(std::vector<ASTPointer<ASTNode>> const& _nodes);
|
||||
|
||||
/// Returns the next AST node ID
|
||||
int64_t nextID() { return ++m_currentNodeID; }
|
||||
|
||||
|
@ -188,5 +188,39 @@ string solidity::util::formatAsStringOrNumber(string const& _value)
|
||||
if (c <= 0x1f || c >= 0x7f || c == '"')
|
||||
return "0x" + h256(_value, h256::AlignLeft).hex();
|
||||
|
||||
return "\"" + _value + "\"";
|
||||
return escapeAndQuoteString(_value);
|
||||
}
|
||||
|
||||
|
||||
string solidity::util::escapeAndQuoteString(string const& _input)
|
||||
{
|
||||
string out;
|
||||
|
||||
for (char c: _input)
|
||||
if (c == '\\')
|
||||
out += "\\\\";
|
||||
else if (c == '"')
|
||||
out += "\\\"";
|
||||
else if (c == '\b')
|
||||
out += "\\b";
|
||||
else if (c == '\f')
|
||||
out += "\\f";
|
||||
else if (c == '\n')
|
||||
out += "\\n";
|
||||
else if (c == '\r')
|
||||
out += "\\r";
|
||||
else if (c == '\t')
|
||||
out += "\\t";
|
||||
else if (c == '\v')
|
||||
out += "\\v";
|
||||
else if (!isprint(c, locale::classic()))
|
||||
{
|
||||
ostringstream o;
|
||||
o << "\\x" << std::hex << setfill('0') << setw(2) << (unsigned)(unsigned char)(c);
|
||||
out += o.str();
|
||||
}
|
||||
else
|
||||
out += c;
|
||||
|
||||
return "\"" + std::move(out) + "\"";
|
||||
}
|
||||
|
@ -460,6 +460,10 @@ bool isValidDecimal(std::string const& _string);
|
||||
/// _value cannot be longer than 32 bytes.
|
||||
std::string formatAsStringOrNumber(std::string const& _value);
|
||||
|
||||
/// @returns a string with the usual backslash-escapes for non-ASCII
|
||||
/// characters and surrounded by '"'-characters.
|
||||
std::string escapeAndQuoteString(std::string const& _input);
|
||||
|
||||
template<typename Container, typename Compare>
|
||||
bool containerEqual(Container const& _lhs, Container const& _rhs, Compare&& _compare)
|
||||
{
|
||||
|
@ -55,33 +55,7 @@ string AsmPrinter::operator()(Literal const& _literal) const
|
||||
break;
|
||||
}
|
||||
|
||||
string out;
|
||||
for (char c: _literal.value.str())
|
||||
if (c == '\\')
|
||||
out += "\\\\";
|
||||
else if (c == '"')
|
||||
out += "\\\"";
|
||||
else if (c == '\b')
|
||||
out += "\\b";
|
||||
else if (c == '\f')
|
||||
out += "\\f";
|
||||
else if (c == '\n')
|
||||
out += "\\n";
|
||||
else if (c == '\r')
|
||||
out += "\\r";
|
||||
else if (c == '\t')
|
||||
out += "\\t";
|
||||
else if (c == '\v')
|
||||
out += "\\v";
|
||||
else if (!isprint(c, locale::classic()))
|
||||
{
|
||||
ostringstream o;
|
||||
o << std::hex << setfill('0') << setw(2) << (unsigned)(unsigned char)(c);
|
||||
out += "\\x" + o.str();
|
||||
}
|
||||
else
|
||||
out += c;
|
||||
return "\"" + out + "\"" + appendTypeName(_literal.type);
|
||||
return escapeAndQuoteString(_literal.value.str()) + appendTypeName(_literal.type);
|
||||
}
|
||||
|
||||
string AsmPrinter::operator()(Identifier const& _identifier) const
|
||||
|
@ -358,13 +358,13 @@ bytes BinaryTransform::operator()(If const& _if)
|
||||
toBytes(Opcode::If) +
|
||||
toBytes(ValueType::Void);
|
||||
|
||||
m_labels.push({});
|
||||
m_labels.emplace_back();
|
||||
|
||||
result += visit(_if.statements);
|
||||
if (_if.elseStatements)
|
||||
result += toBytes(Opcode::Else) + visit(*_if.elseStatements);
|
||||
|
||||
m_labels.pop();
|
||||
m_labels.pop_back();
|
||||
|
||||
result += toBytes(Opcode::End);
|
||||
return result;
|
||||
@ -374,26 +374,24 @@ bytes BinaryTransform::operator()(Loop const& _loop)
|
||||
{
|
||||
bytes result = toBytes(Opcode::Loop) + toBytes(ValueType::Void);
|
||||
|
||||
m_labels.push(_loop.labelName);
|
||||
m_labels.emplace_back(_loop.labelName);
|
||||
result += visit(_loop.statements);
|
||||
m_labels.pop();
|
||||
m_labels.pop_back();
|
||||
|
||||
result += toBytes(Opcode::End);
|
||||
return result;
|
||||
}
|
||||
|
||||
bytes BinaryTransform::operator()(Break const&)
|
||||
bytes BinaryTransform::operator()(Break const& _break)
|
||||
{
|
||||
yulAssert(false, "br not yet implemented.");
|
||||
// TODO the index is just the nesting depth.
|
||||
return {};
|
||||
return toBytes(Opcode::Br) + encodeLabelIdx(_break.label.name);
|
||||
}
|
||||
|
||||
bytes BinaryTransform::operator()(BreakIf const&)
|
||||
bytes BinaryTransform::operator()(BreakIf const& _breakIf)
|
||||
{
|
||||
yulAssert(false, "br_if not yet implemented.");
|
||||
// TODO the index is just the nesting depth.
|
||||
return {};
|
||||
bytes result = std::visit(*this, *_breakIf.condition);
|
||||
result += toBytes(Opcode::BrIf) + encodeLabelIdx(_breakIf.label.name);
|
||||
return result;
|
||||
}
|
||||
|
||||
bytes BinaryTransform::operator()(Return const&)
|
||||
@ -403,11 +401,14 @@ bytes BinaryTransform::operator()(Return const&)
|
||||
|
||||
bytes BinaryTransform::operator()(Block const& _block)
|
||||
{
|
||||
return
|
||||
m_labels.emplace_back(_block.labelName);
|
||||
bytes result =
|
||||
toBytes(Opcode::Block) +
|
||||
toBytes(ValueType::Void) +
|
||||
visit(_block.statements) +
|
||||
toBytes(Opcode::End);
|
||||
m_labels.pop_back();
|
||||
return result;
|
||||
}
|
||||
|
||||
bytes BinaryTransform::operator()(FunctionDefinition const& _function)
|
||||
@ -427,9 +428,13 @@ bytes BinaryTransform::operator()(FunctionDefinition const& _function)
|
||||
for (size_t i = 0; i < _function.locals.size(); ++i)
|
||||
m_locals[_function.locals[i].variableName] = varIdx++;
|
||||
|
||||
yulAssert(m_labels.empty(), "Stray labels.");
|
||||
|
||||
ret += visit(_function.body);
|
||||
ret += toBytes(Opcode::End);
|
||||
|
||||
yulAssert(m_labels.empty(), "Stray labels.");
|
||||
|
||||
return prefixSize(std::move(ret));
|
||||
}
|
||||
|
||||
@ -581,6 +586,18 @@ bytes BinaryTransform::visitReversed(vector<Expression> const& _expressions)
|
||||
return result;
|
||||
}
|
||||
|
||||
bytes BinaryTransform::encodeLabelIdx(string const& _label) const
|
||||
{
|
||||
yulAssert(!_label.empty(), "Empty label.");
|
||||
size_t depth = 0;
|
||||
for (string const& label: m_labels | boost::adaptors::reversed)
|
||||
if (label == _label)
|
||||
return lebEncode(depth);
|
||||
else
|
||||
++depth;
|
||||
yulAssert(false, "Label not found.");
|
||||
}
|
||||
|
||||
bytes BinaryTransform::encodeName(std::string const& _name)
|
||||
{
|
||||
// UTF-8 is allowed here by the Wasm spec, but since all names here should stem from
|
||||
|
@ -77,13 +77,15 @@ private:
|
||||
bytes visit(std::vector<wasm::Expression> const& _expressions);
|
||||
bytes visitReversed(std::vector<wasm::Expression> const& _expressions);
|
||||
|
||||
bytes encodeLabelIdx(std::string const& _label) const;
|
||||
|
||||
static bytes encodeName(std::string const& _name);
|
||||
|
||||
std::map<std::string, size_t> m_locals;
|
||||
std::map<std::string, size_t> m_globals;
|
||||
std::map<std::string, size_t> m_functions;
|
||||
std::map<std::string, size_t> m_functionTypes;
|
||||
std::stack<std::string> m_labels;
|
||||
std::vector<std::string> m_labels;
|
||||
std::map<std::string, std::pair<size_t, size_t>> m_subModulePosAndSize;
|
||||
};
|
||||
|
||||
|
@ -123,7 +123,7 @@ string TextTransform::operator()(wasm::Loop const& _loop)
|
||||
|
||||
string TextTransform::operator()(wasm::Break const& _break)
|
||||
{
|
||||
return "(break $" + _break.label.name + ")\n";
|
||||
return "(br $" + _break.label.name + ")\n";
|
||||
}
|
||||
|
||||
string TextTransform::operator()(wasm::BreakIf const& _break)
|
||||
|
@ -52,7 +52,7 @@ def extract_docs_cases(path):
|
||||
if inside:
|
||||
extractedLines[-1] += l + '\n'
|
||||
|
||||
codeStart = "(pragma solidity|contract.*{|library.*{|interface.*{)"
|
||||
codeStart = "(// SPDX-License-Identifier:|pragma solidity|contract.*{|library.*{|interface.*{)"
|
||||
|
||||
# Filter all tests that do not contain Solidity or are intended incorrectly.
|
||||
for lines in extractedLines:
|
||||
|
@ -81,12 +81,14 @@ EVMHost::EVMHost(langutil::EVMVersion _evmVersion, evmc::VM& _vm):
|
||||
m_evmRevision = EVMC_BYZANTIUM;
|
||||
else if (_evmVersion == langutil::EVMVersion::constantinople())
|
||||
m_evmRevision = EVMC_CONSTANTINOPLE;
|
||||
else if (_evmVersion == langutil::EVMVersion::petersburg())
|
||||
m_evmRevision = EVMC_PETERSBURG;
|
||||
else if (_evmVersion == langutil::EVMVersion::istanbul())
|
||||
m_evmRevision = EVMC_ISTANBUL;
|
||||
else if (_evmVersion == langutil::EVMVersion::berlin())
|
||||
assertThrow(false, Exception, "Berlin is not supported yet.");
|
||||
else //if (_evmVersion == langutil::EVMVersion::petersburg())
|
||||
m_evmRevision = EVMC_PETERSBURG;
|
||||
m_evmRevision = EVMC_BERLIN;
|
||||
else
|
||||
assertThrow(false, Exception, "Unsupported EVM version");
|
||||
|
||||
// Mark all precompiled contracts as existing. Existing here means to have a balance (as per EIP-161).
|
||||
// NOTE: keep this in sync with `EVMHost::call` below.
|
||||
@ -99,17 +101,16 @@ EVMHost::EVMHost(langutil::EVMVersion _evmVersion, evmc::VM& _vm):
|
||||
evmc::address address{};
|
||||
address.bytes[19] = precompiledAddress;
|
||||
// 1wei
|
||||
accounts[address].balance.bytes[31] = 1;
|
||||
accounts[address].balance = evmc::uint256be{1};
|
||||
}
|
||||
|
||||
// TODO: support short literals in EVMC and use them here
|
||||
tx_context.block_difficulty = convertToEVMC(u256("200000000"));
|
||||
tx_context.block_difficulty = evmc::uint256be{200000000};
|
||||
tx_context.block_gas_limit = 20000000;
|
||||
tx_context.block_coinbase = 0x7878787878787878787878787878787878787878_address;
|
||||
tx_context.tx_gas_price = convertToEVMC(u256("3000000000"));
|
||||
tx_context.tx_gas_price = evmc::uint256be{3000000000};
|
||||
tx_context.tx_origin = 0x9292929292929292929292929292929292929292_address;
|
||||
// Mainnet according to EIP-155
|
||||
tx_context.chain_id = convertToEVMC(u256(1));
|
||||
tx_context.chain_id = evmc::uint256be{1};
|
||||
}
|
||||
|
||||
void EVMHost::selfdestruct(const evmc::address& _addr, const evmc::address& _beneficiary) noexcept
|
||||
|
@ -1,5 +1,7 @@
|
||||
// SPDX-License-Identifier: GPL-3.0
|
||||
pragma solidity >=0.0;
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
contract C {
|
||||
struct S { uint x; }
|
||||
function f(S memory) public pure {
|
||||
|
1
test/cmdlineTests/evm_to_wasm_break/args
Normal file
1
test/cmdlineTests/evm_to_wasm_break/args
Normal file
@ -0,0 +1 @@
|
||||
--assemble --optimize --yul-dialect evm --machine ewasm
|
1
test/cmdlineTests/evm_to_wasm_break/err
Normal file
1
test/cmdlineTests/evm_to_wasm_break/err
Normal file
@ -0,0 +1 @@
|
||||
Warning: Yul is still experimental. Please use the output with care.
|
8
test/cmdlineTests/evm_to_wasm_break/input.sol
Normal file
8
test/cmdlineTests/evm_to_wasm_break/input.sol
Normal file
@ -0,0 +1,8 @@
|
||||
{
|
||||
let x := calldataload(0)
|
||||
for { } lt(x, 10) { x := add(x, 1) } {
|
||||
if eq(x, 2) { break }
|
||||
if eq(x, 4) { continue }
|
||||
}
|
||||
sstore(0, x)
|
||||
}
|
551
test/cmdlineTests/evm_to_wasm_break/output
Normal file
551
test/cmdlineTests/evm_to_wasm_break/output
Normal file
@ -0,0 +1,551 @@
|
||||
|
||||
======= evm_to_wasm_break/input.sol (Ewasm) =======
|
||||
|
||||
Pretty printed source:
|
||||
object "object" {
|
||||
code {
|
||||
{
|
||||
let x := calldataload(0)
|
||||
for { } lt(x, 10) { x := add(x, 1) }
|
||||
{
|
||||
if eq(x, 2) { break }
|
||||
if eq(x, 4) { continue }
|
||||
}
|
||||
sstore(0, x)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
==========================
|
||||
|
||||
Translated source:
|
||||
object "object" {
|
||||
code {
|
||||
function main()
|
||||
{
|
||||
let _1 := 0
|
||||
let x, x_1, x_2, x_3 := calldataload(_1, _1, _1, _1)
|
||||
let x_4 := x
|
||||
let x_5 := x_1
|
||||
let x_6 := x_2
|
||||
let x_7 := x_3
|
||||
let _2 := 1
|
||||
let _3:i32 := i32.eqz(i32.eqz(i64.eqz(i64.or(i64.or(_1, _1), i64.or(_1, _2)))))
|
||||
for { }
|
||||
i32.eqz(_3)
|
||||
{
|
||||
let x_8, x_9, x_10, x_11 := add(x_4, x_5, x_6, x_7, _1, _1, _1, _2)
|
||||
x_4 := x_8
|
||||
x_5 := x_9
|
||||
x_6 := x_10
|
||||
x_7 := x_11
|
||||
}
|
||||
{
|
||||
let _4, _5, _6, _7 := lt(x_4, x_5, x_6, x_7, _1, _1, _1, 10)
|
||||
let _8, _9, _10, _11 := iszero(_4, _5, _6, _7)
|
||||
if i32.eqz(i64.eqz(i64.or(i64.or(_8, _9), i64.or(_10, _11)))) { break }
|
||||
let _12, _13, _14, _15 := eq(x_4, x_5, x_6, x_7, _1, _1, _1, 2)
|
||||
if i32.eqz(i64.eqz(i64.or(i64.or(_12, _13), i64.or(_14, _15)))) { break }
|
||||
let _16, _17, _18, _19 := eq(x_4, x_5, x_6, x_7, _1, _1, _1, 4)
|
||||
if i32.eqz(i64.eqz(i64.or(i64.or(_16, _17), i64.or(_18, _19)))) { continue }
|
||||
}
|
||||
sstore(_1, _1, _1, _1, x_4, x_5, x_6, x_7)
|
||||
}
|
||||
function add_carry(x, y, c) -> r, r_c
|
||||
{
|
||||
let t := i64.add(x, y)
|
||||
r := i64.add(t, c)
|
||||
r_c := i64.extend_i32_u(i32.or(i64.lt_u(t, x), i64.lt_u(r, t)))
|
||||
}
|
||||
function add(x1, x2, x3, x4, y1, y2, y3, y4) -> r1, r2, r3, r4
|
||||
{
|
||||
let t := i64.add(x4, y4)
|
||||
r4 := i64.add(t, 0)
|
||||
let r3_1, carry := add_carry(x3, y3, i64.extend_i32_u(i32.or(i64.lt_u(t, x4), i64.lt_u(r4, t))))
|
||||
r3 := r3_1
|
||||
let r2_1, carry_1 := add_carry(x2, y2, carry)
|
||||
r2 := r2_1
|
||||
let r1_1, carry_2 := add_carry(x1, y1, carry_1)
|
||||
r1 := r1_1
|
||||
}
|
||||
function iszero(x1, x2, x3, x4) -> r1, r2, r3, r4
|
||||
{
|
||||
r4 := i64.extend_i32_u(i64.eqz(i64.or(i64.or(x1, x2), i64.or(x3, x4))))
|
||||
}
|
||||
function eq(x1, x2, x3, x4, y1, y2, y3, y4) -> r1, r2, r3, r4
|
||||
{
|
||||
if i64.eq(x1, y1)
|
||||
{
|
||||
if i64.eq(x2, y2)
|
||||
{
|
||||
if i64.eq(x3, y3) { if i64.eq(x4, y4) { r4 := 1 } }
|
||||
}
|
||||
}
|
||||
}
|
||||
function cmp(a, b) -> r:i32
|
||||
{
|
||||
switch i64.lt_u(a, b)
|
||||
case 1:i32 { r := 0xffffffff:i32 }
|
||||
default { r := i64.ne(a, b) }
|
||||
}
|
||||
function lt(x1, x2, x3, x4, y1, y2, y3, y4) -> z1, z2, z3, z4
|
||||
{
|
||||
let z:i32 := false
|
||||
switch cmp(x1, y1)
|
||||
case 0:i32 {
|
||||
switch cmp(x2, y2)
|
||||
case 0:i32 {
|
||||
switch cmp(x3, y3)
|
||||
case 0:i32 { z := i64.lt_u(x4, y4) }
|
||||
case 1:i32 { z := 0:i32 }
|
||||
default { z := 1:i32 }
|
||||
}
|
||||
case 1:i32 { z := 0:i32 }
|
||||
default { z := 1:i32 }
|
||||
}
|
||||
case 1:i32 { z := 0:i32 }
|
||||
default { z := 1:i32 }
|
||||
z4 := i64.extend_i32_u(z)
|
||||
}
|
||||
function calldataload(x1, x2, x3, x4) -> z1, z2, z3, z4
|
||||
{
|
||||
if i64.ne(0, i64.or(i64.or(x1, x2), x3)) { unreachable() }
|
||||
if i64.ne(0, i64.shr_u(x4, 32)) { unreachable() }
|
||||
eth.callDataCopy(0:i32, i32.wrap_i64(x4), 32:i32)
|
||||
let z1_1 := endian_swap(i64.load(0:i32))
|
||||
let z2_1 := endian_swap(i64.load(i32.add(0:i32, 8:i32)))
|
||||
let z3_1 := endian_swap(i64.load(i32.add(0:i32, 16:i32)))
|
||||
let z4_1 := endian_swap(i64.load(i32.add(0:i32, 24:i32)))
|
||||
z1 := z1_1
|
||||
z2 := z2_1
|
||||
z3 := z3_1
|
||||
z4 := z4_1
|
||||
}
|
||||
function endian_swap_16(x) -> y
|
||||
{
|
||||
y := i64.or(i64.and(i64.shl(x, 8), 0xff00), i64.and(i64.shr_u(x, 8), 0xff))
|
||||
}
|
||||
function endian_swap_32(x) -> y
|
||||
{
|
||||
let hi := i64.shl(endian_swap_16(x), 16)
|
||||
y := i64.or(hi, endian_swap_16(i64.shr_u(x, 16)))
|
||||
}
|
||||
function endian_swap(x) -> y
|
||||
{
|
||||
let hi := i64.shl(endian_swap_32(x), 32)
|
||||
y := i64.or(hi, endian_swap_32(i64.shr_u(x, 32)))
|
||||
}
|
||||
function mstore_internal(pos:i32, y1, y2, y3, y4)
|
||||
{
|
||||
i64.store(pos, endian_swap(y1))
|
||||
i64.store(i32.add(pos, 8:i32), endian_swap(y2))
|
||||
i64.store(i32.add(pos, 16:i32), endian_swap(y3))
|
||||
i64.store(i32.add(pos, 24:i32), endian_swap(y4))
|
||||
}
|
||||
function sstore(x1, x2, x3, x4, y1, y2, y3, y4)
|
||||
{
|
||||
mstore_internal(0:i32, x1, x2, x3, x4)
|
||||
mstore_internal(32:i32, y1, y2, y3, y4)
|
||||
eth.storageStore(0:i32, 32:i32)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Binary representation:
|
||||
0061736d0100000001480a60000060017e017e60027e7e017e60037e7e7e017e60047e7e7e7e017e60057e7e7e7e7e0060087e7e7e7e7e7e7e7e0060087e7e7e7e7e7e7e7e017e60027f7f0060037f7f7f0002310208657468657265756d0c73746f7261676553746f7265000808657468657265756d0c63616c6c44617461436f70790009030e0d0003070407020704010101050605030100010610037e0142000b7e0142000b7e0142000b071102066d656d6f72790200046d61696e00020a80090dee02011f7e4200210002402000200020002000100921012300210223012103230221040b2001210520022106200321072004210842012109200020008420002009848450ada745ada745ad210a02400340200aa745ad500d01024002402005200620072008200020002000420a1008210b2300210c2301210d2302210e0b0240200b200c200d200e1005210f2300211023012111230221120b200f20108420112012848450ada745ad42005204400c030b024020052006200720082000200020004202100621132300211423012115230221160b201320148420152016848450ada745ad42005204400c030b0240200520062007200820002000200042041006211723002118230121192302211a0b20172018842019201a848450ada745ad42005204400c010b0b0240200520062007200820002000200020091004211b2300211c2301211d2302211e0b201b2105201c2106201d2107201e21080b0b20002000200020002005200620072008100e0b2c01037e200020017c2105200520027c21032005200054ada72003200554ada772ada7ad21042004240020030b6f010b7e200320077c210c200c42007c210b024020022006200c200354ada7200b200c54ada772ada7ad1003210d2300210e0b200d210a024020012005200e1003210f230021100b200f2109024020002004201010032111230021120b2011210820092400200a2401200b240220080b2301047e200020018420022003848450ada7ad210720052400200624012007240220040b4601047e2000200451ad42005204402001200551ad42005204402002200651ad42005204402003200751ad42005204404201210b0b0b0b0b20092400200a2401200b240220080b2a01027e02402000200154ad21032003420151044042ffffffff0f2102052000200152ad21020b0b20020b930101087e4200210c0240200020041007210d200d42005104400240200120051007210e200e42005104400240200220061007210f200f42005104402003200754ad210c05200f42015104404200210c054201210c0b0b0b05200e42015104404200210c054201210c0b0b0b05200d42015104404200210c054201210c0b0b0b200ca7ad210b20092400200a2401200b240220080b8c0101087e4200200020018420028452ad4200520440000b4200200342208852ad4200520440000b4200a72003a7ada74220a710014200a7290300100c21084200a74208a76aada7290300100c21094200a74210a76aada7290300100c210a4200a74218a76aada7290300100c210b2008210420092105200a2106200b210720052400200624012007240220040b1c01017e20004208864280fe0383200042088842ff018384210120010b1b01027e2000100a421086210220022000421088100a84210120010b1b01027e2000100b422086210220022000422088100b84210120010b3e01007e2000a72001100c3703002000a74208a76aada72002100c3703002000a74210a76aada72003100c3703002000a74218a76aada72004100c3703000b2401007e42002000200120022003100d42202004200520062007100d4200a74220a710000b
|
||||
|
||||
Text representation:
|
||||
(module
|
||||
(import "ethereum" "storageStore" (func $eth.storageStore (param i32 i32)))
|
||||
(import "ethereum" "callDataCopy" (func $eth.callDataCopy (param i32 i32 i32)))
|
||||
(memory $memory (export "memory") 1)
|
||||
(export "main" (func $main))
|
||||
(global $global_ (mut i64) (i64.const 0))
|
||||
(global $global__1 (mut i64) (i64.const 0))
|
||||
(global $global__2 (mut i64) (i64.const 0))
|
||||
|
||||
(func $main
|
||||
(local $_1 i64)
|
||||
(local $x i64)
|
||||
(local $x_1 i64)
|
||||
(local $x_2 i64)
|
||||
(local $x_3 i64)
|
||||
(local $x_4 i64)
|
||||
(local $x_5 i64)
|
||||
(local $x_6 i64)
|
||||
(local $x_7 i64)
|
||||
(local $_2 i64)
|
||||
(local $_3 i64)
|
||||
(local $_4 i64)
|
||||
(local $_5 i64)
|
||||
(local $_6 i64)
|
||||
(local $_7 i64)
|
||||
(local $_8 i64)
|
||||
(local $_9 i64)
|
||||
(local $_10 i64)
|
||||
(local $_11 i64)
|
||||
(local $_12 i64)
|
||||
(local $_13 i64)
|
||||
(local $_14 i64)
|
||||
(local $_15 i64)
|
||||
(local $_16 i64)
|
||||
(local $_17 i64)
|
||||
(local $_18 i64)
|
||||
(local $_19 i64)
|
||||
(local $x_8 i64)
|
||||
(local $x_9 i64)
|
||||
(local $x_10 i64)
|
||||
(local $x_11 i64)
|
||||
(local.set $_1 (i64.const 0))
|
||||
(block
|
||||
(local.set $x (call $calldataload (local.get $_1) (local.get $_1) (local.get $_1) (local.get $_1)))
|
||||
(local.set $x_1 (global.get $global_))
|
||||
(local.set $x_2 (global.get $global__1))
|
||||
(local.set $x_3 (global.get $global__2))
|
||||
|
||||
)
|
||||
(local.set $x_4 (local.get $x))
|
||||
(local.set $x_5 (local.get $x_1))
|
||||
(local.set $x_6 (local.get $x_2))
|
||||
(local.set $x_7 (local.get $x_3))
|
||||
(local.set $_2 (i64.const 1))
|
||||
(local.set $_3 (i64.extend_i32_u (i32.eqz (i32.wrap_i64 (i64.extend_i32_u (i32.eqz (i32.wrap_i64 (i64.extend_i32_u (i64.eqz (i64.or (i64.or (local.get $_1) (local.get $_1)) (i64.or (local.get $_1) (local.get $_2))))))))))))
|
||||
(block $label_
|
||||
(loop
|
||||
(br_if $label_ (i64.eqz (i64.extend_i32_u (i32.eqz (i32.wrap_i64 (local.get $_3))))))
|
||||
(block $label__3
|
||||
(block
|
||||
(local.set $_4 (call $lt (local.get $x_4) (local.get $x_5) (local.get $x_6) (local.get $x_7) (local.get $_1) (local.get $_1) (local.get $_1) (i64.const 10)))
|
||||
(local.set $_5 (global.get $global_))
|
||||
(local.set $_6 (global.get $global__1))
|
||||
(local.set $_7 (global.get $global__2))
|
||||
|
||||
)
|
||||
(block
|
||||
(local.set $_8 (call $iszero (local.get $_4) (local.get $_5) (local.get $_6) (local.get $_7)))
|
||||
(local.set $_9 (global.get $global_))
|
||||
(local.set $_10 (global.get $global__1))
|
||||
(local.set $_11 (global.get $global__2))
|
||||
|
||||
)
|
||||
(if (i64.ne (i64.extend_i32_u (i32.eqz (i32.wrap_i64 (i64.extend_i32_u (i64.eqz (i64.or (i64.or (local.get $_8) (local.get $_9)) (i64.or (local.get $_10) (local.get $_11)))))))) (i64.const 0)) (then
|
||||
(br $label_)
|
||||
))
|
||||
(block
|
||||
(local.set $_12 (call $eq (local.get $x_4) (local.get $x_5) (local.get $x_6) (local.get $x_7) (local.get $_1) (local.get $_1) (local.get $_1) (i64.const 2)))
|
||||
(local.set $_13 (global.get $global_))
|
||||
(local.set $_14 (global.get $global__1))
|
||||
(local.set $_15 (global.get $global__2))
|
||||
|
||||
)
|
||||
(if (i64.ne (i64.extend_i32_u (i32.eqz (i32.wrap_i64 (i64.extend_i32_u (i64.eqz (i64.or (i64.or (local.get $_12) (local.get $_13)) (i64.or (local.get $_14) (local.get $_15)))))))) (i64.const 0)) (then
|
||||
(br $label_)
|
||||
))
|
||||
(block
|
||||
(local.set $_16 (call $eq (local.get $x_4) (local.get $x_5) (local.get $x_6) (local.get $x_7) (local.get $_1) (local.get $_1) (local.get $_1) (i64.const 4)))
|
||||
(local.set $_17 (global.get $global_))
|
||||
(local.set $_18 (global.get $global__1))
|
||||
(local.set $_19 (global.get $global__2))
|
||||
|
||||
)
|
||||
(if (i64.ne (i64.extend_i32_u (i32.eqz (i32.wrap_i64 (i64.extend_i32_u (i64.eqz (i64.or (i64.or (local.get $_16) (local.get $_17)) (i64.or (local.get $_18) (local.get $_19)))))))) (i64.const 0)) (then
|
||||
(br $label__3)
|
||||
))
|
||||
|
||||
)
|
||||
(block
|
||||
(local.set $x_8 (call $add (local.get $x_4) (local.get $x_5) (local.get $x_6) (local.get $x_7) (local.get $_1) (local.get $_1) (local.get $_1) (local.get $_2)))
|
||||
(local.set $x_9 (global.get $global_))
|
||||
(local.set $x_10 (global.get $global__1))
|
||||
(local.set $x_11 (global.get $global__2))
|
||||
|
||||
)
|
||||
(local.set $x_4 (local.get $x_8))
|
||||
(local.set $x_5 (local.get $x_9))
|
||||
(local.set $x_6 (local.get $x_10))
|
||||
(local.set $x_7 (local.get $x_11))
|
||||
)
|
||||
|
||||
)
|
||||
(call $sstore (local.get $_1) (local.get $_1) (local.get $_1) (local.get $_1) (local.get $x_4) (local.get $x_5) (local.get $x_6) (local.get $x_7))
|
||||
)
|
||||
|
||||
(func $add_carry
|
||||
(param $x i64)
|
||||
(param $y i64)
|
||||
(param $c i64)
|
||||
(result i64)
|
||||
(local $r i64)
|
||||
(local $r_c i64)
|
||||
(local $t i64)
|
||||
(local.set $t (i64.add (local.get $x) (local.get $y)))
|
||||
(local.set $r (i64.add (local.get $t) (local.get $c)))
|
||||
(local.set $r_c (i64.extend_i32_u (i32.wrap_i64 (i64.extend_i32_u (i32.or (i32.wrap_i64 (i64.extend_i32_u (i64.lt_u (local.get $t) (local.get $x)))) (i32.wrap_i64 (i64.extend_i32_u (i64.lt_u (local.get $r) (local.get $t)))))))))
|
||||
(global.set $global_ (local.get $r_c))
|
||||
(local.get $r)
|
||||
)
|
||||
|
||||
(func $add
|
||||
(param $x1 i64)
|
||||
(param $x2 i64)
|
||||
(param $x3 i64)
|
||||
(param $x4 i64)
|
||||
(param $y1 i64)
|
||||
(param $y2 i64)
|
||||
(param $y3 i64)
|
||||
(param $y4 i64)
|
||||
(result i64)
|
||||
(local $r1 i64)
|
||||
(local $r2 i64)
|
||||
(local $r3 i64)
|
||||
(local $r4 i64)
|
||||
(local $t i64)
|
||||
(local $r3_1 i64)
|
||||
(local $carry i64)
|
||||
(local $r2_1 i64)
|
||||
(local $carry_1 i64)
|
||||
(local $r1_1 i64)
|
||||
(local $carry_2 i64)
|
||||
(local.set $t (i64.add (local.get $x4) (local.get $y4)))
|
||||
(local.set $r4 (i64.add (local.get $t) (i64.const 0)))
|
||||
(block
|
||||
(local.set $r3_1 (call $add_carry (local.get $x3) (local.get $y3) (i64.extend_i32_u (i32.wrap_i64 (i64.extend_i32_u (i32.or (i32.wrap_i64 (i64.extend_i32_u (i64.lt_u (local.get $t) (local.get $x4)))) (i32.wrap_i64 (i64.extend_i32_u (i64.lt_u (local.get $r4) (local.get $t))))))))))
|
||||
(local.set $carry (global.get $global_))
|
||||
|
||||
)
|
||||
(local.set $r3 (local.get $r3_1))
|
||||
(block
|
||||
(local.set $r2_1 (call $add_carry (local.get $x2) (local.get $y2) (local.get $carry)))
|
||||
(local.set $carry_1 (global.get $global_))
|
||||
|
||||
)
|
||||
(local.set $r2 (local.get $r2_1))
|
||||
(block
|
||||
(local.set $r1_1 (call $add_carry (local.get $x1) (local.get $y1) (local.get $carry_1)))
|
||||
(local.set $carry_2 (global.get $global_))
|
||||
|
||||
)
|
||||
(local.set $r1 (local.get $r1_1))
|
||||
(global.set $global_ (local.get $r2))
|
||||
(global.set $global__1 (local.get $r3))
|
||||
(global.set $global__2 (local.get $r4))
|
||||
(local.get $r1)
|
||||
)
|
||||
|
||||
(func $iszero
|
||||
(param $x1 i64)
|
||||
(param $x2 i64)
|
||||
(param $x3 i64)
|
||||
(param $x4 i64)
|
||||
(result i64)
|
||||
(local $r1 i64)
|
||||
(local $r2 i64)
|
||||
(local $r3 i64)
|
||||
(local $r4 i64)
|
||||
(local.set $r4 (i64.extend_i32_u (i32.wrap_i64 (i64.extend_i32_u (i64.eqz (i64.or (i64.or (local.get $x1) (local.get $x2)) (i64.or (local.get $x3) (local.get $x4))))))))
|
||||
(global.set $global_ (local.get $r2))
|
||||
(global.set $global__1 (local.get $r3))
|
||||
(global.set $global__2 (local.get $r4))
|
||||
(local.get $r1)
|
||||
)
|
||||
|
||||
(func $eq
|
||||
(param $x1 i64)
|
||||
(param $x2 i64)
|
||||
(param $x3 i64)
|
||||
(param $x4 i64)
|
||||
(param $y1 i64)
|
||||
(param $y2 i64)
|
||||
(param $y3 i64)
|
||||
(param $y4 i64)
|
||||
(result i64)
|
||||
(local $r1 i64)
|
||||
(local $r2 i64)
|
||||
(local $r3 i64)
|
||||
(local $r4 i64)
|
||||
(if (i64.ne (i64.extend_i32_u (i64.eq (local.get $x1) (local.get $y1))) (i64.const 0)) (then
|
||||
(if (i64.ne (i64.extend_i32_u (i64.eq (local.get $x2) (local.get $y2))) (i64.const 0)) (then
|
||||
(if (i64.ne (i64.extend_i32_u (i64.eq (local.get $x3) (local.get $y3))) (i64.const 0)) (then
|
||||
(if (i64.ne (i64.extend_i32_u (i64.eq (local.get $x4) (local.get $y4))) (i64.const 0)) (then
|
||||
(local.set $r4 (i64.const 1))
|
||||
))
|
||||
))
|
||||
))
|
||||
))
|
||||
(global.set $global_ (local.get $r2))
|
||||
(global.set $global__1 (local.get $r3))
|
||||
(global.set $global__2 (local.get $r4))
|
||||
(local.get $r1)
|
||||
)
|
||||
|
||||
(func $cmp
|
||||
(param $a i64)
|
||||
(param $b i64)
|
||||
(result i64)
|
||||
(local $r i64)
|
||||
(local $condition i64)
|
||||
(block
|
||||
(local.set $condition (i64.extend_i32_u (i64.lt_u (local.get $a) (local.get $b))))
|
||||
(if (i64.eq (local.get $condition) (i64.const 1)) (then
|
||||
(local.set $r (i64.const 4294967295))
|
||||
)(else
|
||||
(local.set $r (i64.extend_i32_u (i64.ne (local.get $a) (local.get $b))))
|
||||
))
|
||||
|
||||
)
|
||||
(local.get $r)
|
||||
)
|
||||
|
||||
(func $lt
|
||||
(param $x1 i64)
|
||||
(param $x2 i64)
|
||||
(param $x3 i64)
|
||||
(param $x4 i64)
|
||||
(param $y1 i64)
|
||||
(param $y2 i64)
|
||||
(param $y3 i64)
|
||||
(param $y4 i64)
|
||||
(result i64)
|
||||
(local $z1 i64)
|
||||
(local $z2 i64)
|
||||
(local $z3 i64)
|
||||
(local $z4 i64)
|
||||
(local $z i64)
|
||||
(local $condition_4 i64)
|
||||
(local $condition_5 i64)
|
||||
(local $condition_6 i64)
|
||||
(local.set $z (i64.const 0))
|
||||
(block
|
||||
(local.set $condition_4 (call $cmp (local.get $x1) (local.get $y1)))
|
||||
(if (i64.eq (local.get $condition_4) (i64.const 0)) (then
|
||||
(block
|
||||
(local.set $condition_5 (call $cmp (local.get $x2) (local.get $y2)))
|
||||
(if (i64.eq (local.get $condition_5) (i64.const 0)) (then
|
||||
(block
|
||||
(local.set $condition_6 (call $cmp (local.get $x3) (local.get $y3)))
|
||||
(if (i64.eq (local.get $condition_6) (i64.const 0)) (then
|
||||
(local.set $z (i64.extend_i32_u (i64.lt_u (local.get $x4) (local.get $y4))))
|
||||
)(else
|
||||
(if (i64.eq (local.get $condition_6) (i64.const 1)) (then
|
||||
(local.set $z (i64.const 0))
|
||||
)(else
|
||||
(local.set $z (i64.const 1))
|
||||
))
|
||||
))
|
||||
|
||||
)
|
||||
)(else
|
||||
(if (i64.eq (local.get $condition_5) (i64.const 1)) (then
|
||||
(local.set $z (i64.const 0))
|
||||
)(else
|
||||
(local.set $z (i64.const 1))
|
||||
))
|
||||
))
|
||||
|
||||
)
|
||||
)(else
|
||||
(if (i64.eq (local.get $condition_4) (i64.const 1)) (then
|
||||
(local.set $z (i64.const 0))
|
||||
)(else
|
||||
(local.set $z (i64.const 1))
|
||||
))
|
||||
))
|
||||
|
||||
)
|
||||
(local.set $z4 (i64.extend_i32_u (i32.wrap_i64 (local.get $z))))
|
||||
(global.set $global_ (local.get $z2))
|
||||
(global.set $global__1 (local.get $z3))
|
||||
(global.set $global__2 (local.get $z4))
|
||||
(local.get $z1)
|
||||
)
|
||||
|
||||
(func $calldataload
|
||||
(param $x1 i64)
|
||||
(param $x2 i64)
|
||||
(param $x3 i64)
|
||||
(param $x4 i64)
|
||||
(result i64)
|
||||
(local $z1 i64)
|
||||
(local $z2 i64)
|
||||
(local $z3 i64)
|
||||
(local $z4 i64)
|
||||
(local $z1_1 i64)
|
||||
(local $z2_1 i64)
|
||||
(local $z3_1 i64)
|
||||
(local $z4_1 i64)
|
||||
(if (i64.ne (i64.extend_i32_u (i64.ne (i64.const 0) (i64.or (i64.or (local.get $x1) (local.get $x2)) (local.get $x3)))) (i64.const 0)) (then
|
||||
(unreachable)))
|
||||
(if (i64.ne (i64.extend_i32_u (i64.ne (i64.const 0) (i64.shr_u (local.get $x4) (i64.const 32)))) (i64.const 0)) (then
|
||||
(unreachable)))
|
||||
(call $eth.callDataCopy (i32.wrap_i64 (i64.const 0)) (i32.wrap_i64 (i64.extend_i32_u (i32.wrap_i64 (local.get $x4)))) (i32.wrap_i64 (i64.const 32)))
|
||||
(local.set $z1_1 (call $endian_swap (i64.load (i32.wrap_i64 (i64.const 0)))))
|
||||
(local.set $z2_1 (call $endian_swap (i64.load (i32.wrap_i64 (i64.extend_i32_u (i32.add (i32.wrap_i64 (i64.const 0)) (i32.wrap_i64 (i64.const 8))))))))
|
||||
(local.set $z3_1 (call $endian_swap (i64.load (i32.wrap_i64 (i64.extend_i32_u (i32.add (i32.wrap_i64 (i64.const 0)) (i32.wrap_i64 (i64.const 16))))))))
|
||||
(local.set $z4_1 (call $endian_swap (i64.load (i32.wrap_i64 (i64.extend_i32_u (i32.add (i32.wrap_i64 (i64.const 0)) (i32.wrap_i64 (i64.const 24))))))))
|
||||
(local.set $z1 (local.get $z1_1))
|
||||
(local.set $z2 (local.get $z2_1))
|
||||
(local.set $z3 (local.get $z3_1))
|
||||
(local.set $z4 (local.get $z4_1))
|
||||
(global.set $global_ (local.get $z2))
|
||||
(global.set $global__1 (local.get $z3))
|
||||
(global.set $global__2 (local.get $z4))
|
||||
(local.get $z1)
|
||||
)
|
||||
|
||||
(func $endian_swap_16
|
||||
(param $x i64)
|
||||
(result i64)
|
||||
(local $y i64)
|
||||
(local.set $y (i64.or (i64.and (i64.shl (local.get $x) (i64.const 8)) (i64.const 65280)) (i64.and (i64.shr_u (local.get $x) (i64.const 8)) (i64.const 255))))
|
||||
(local.get $y)
|
||||
)
|
||||
|
||||
(func $endian_swap_32
|
||||
(param $x i64)
|
||||
(result i64)
|
||||
(local $y i64)
|
||||
(local $hi i64)
|
||||
(local.set $hi (i64.shl (call $endian_swap_16 (local.get $x)) (i64.const 16)))
|
||||
(local.set $y (i64.or (local.get $hi) (call $endian_swap_16 (i64.shr_u (local.get $x) (i64.const 16)))))
|
||||
(local.get $y)
|
||||
)
|
||||
|
||||
(func $endian_swap
|
||||
(param $x i64)
|
||||
(result i64)
|
||||
(local $y i64)
|
||||
(local $hi i64)
|
||||
(local.set $hi (i64.shl (call $endian_swap_32 (local.get $x)) (i64.const 32)))
|
||||
(local.set $y (i64.or (local.get $hi) (call $endian_swap_32 (i64.shr_u (local.get $x) (i64.const 32)))))
|
||||
(local.get $y)
|
||||
)
|
||||
|
||||
(func $mstore_internal
|
||||
(param $pos i64)
|
||||
(param $y1 i64)
|
||||
(param $y2 i64)
|
||||
(param $y3 i64)
|
||||
(param $y4 i64)
|
||||
(i64.store (i32.wrap_i64 (local.get $pos)) (call $endian_swap (local.get $y1)))
|
||||
(i64.store (i32.wrap_i64 (i64.extend_i32_u (i32.add (i32.wrap_i64 (local.get $pos)) (i32.wrap_i64 (i64.const 8))))) (call $endian_swap (local.get $y2)))
|
||||
(i64.store (i32.wrap_i64 (i64.extend_i32_u (i32.add (i32.wrap_i64 (local.get $pos)) (i32.wrap_i64 (i64.const 16))))) (call $endian_swap (local.get $y3)))
|
||||
(i64.store (i32.wrap_i64 (i64.extend_i32_u (i32.add (i32.wrap_i64 (local.get $pos)) (i32.wrap_i64 (i64.const 24))))) (call $endian_swap (local.get $y4)))
|
||||
)
|
||||
|
||||
(func $sstore
|
||||
(param $x1 i64)
|
||||
(param $x2 i64)
|
||||
(param $x3 i64)
|
||||
(param $x4 i64)
|
||||
(param $y1 i64)
|
||||
(param $y2 i64)
|
||||
(param $y3 i64)
|
||||
(param $y4 i64)
|
||||
(call $mstore_internal (i64.const 0) (local.get $x1) (local.get $x2) (local.get $x3) (local.get $x4))
|
||||
(call $mstore_internal (i64.const 32) (local.get $y1) (local.get $y2) (local.get $y3) (local.get $y4))
|
||||
(call $eth.storageStore (i32.wrap_i64 (i64.const 0)) (i32.wrap_i64 (i64.const 32)))
|
||||
)
|
||||
|
||||
)
|
@ -1,3 +1,4 @@
|
||||
// SPDX-License-Identifier: GPL-3.0
|
||||
pragma solidity >=0.6.0;
|
||||
|
||||
contract C {
|
||||
|
@ -1,5 +1,5 @@
|
||||
Warning: Unused local variable.
|
||||
--> ir_compiler_subobjects/input.sol:6:9:
|
||||
--> ir_compiler_subobjects/input.sol:7:9:
|
||||
|
|
||||
6 | C c = new C();
|
||||
7 | C c = new C();
|
||||
| ^^^
|
||||
|
@ -1,3 +1,4 @@
|
||||
// SPDX-License-Identifier: GPL-3.0
|
||||
pragma solidity >=0.6.0;
|
||||
|
||||
contract C {}
|
||||
|
@ -1,5 +1,5 @@
|
||||
// checks that error messages around power-or-10 lines are formatted correctly
|
||||
|
||||
// SPDX-License-Identifier: GPL-3.0
|
||||
|
||||
|
||||
|
||||
|
@ -1,3 +1,4 @@
|
||||
// SPDX-License-Identifier: GPL-3.0
|
||||
pragma solidity >=0.0;
|
||||
|
||||
contract C
|
||||
|
@ -1,69 +1,69 @@
|
||||
|
||||
======= optimizer_user_yul/input.sol:C =======
|
||||
EVM assembly:
|
||||
/* "optimizer_user_yul/input.sol":24:489 contract C... */
|
||||
/* "optimizer_user_yul/input.sol":60:525 contract C... */
|
||||
mstore(0x40, 0x80)
|
||||
/* "optimizer_user_yul/input.sol":72:77 int a */
|
||||
/* "optimizer_user_yul/input.sol":108:113 int a */
|
||||
0x00
|
||||
/* "optimizer_user_yul/input.sol":152:161 let x,y,z */
|
||||
/* "optimizer_user_yul/input.sol":188:197 let x,y,z */
|
||||
dup1
|
||||
0x00
|
||||
dup1
|
||||
/* "optimizer_user_yul/input.sol":176:177 1 */
|
||||
/* "optimizer_user_yul/input.sol":212:213 1 */
|
||||
0x01
|
||||
/* "optimizer_user_yul/input.sol":173:174 0 */
|
||||
/* "optimizer_user_yul/input.sol":209:210 0 */
|
||||
0x00
|
||||
/* "optimizer_user_yul/input.sol":166:178 sstore(0, 1) */
|
||||
/* "optimizer_user_yul/input.sol":202:214 sstore(0, 1) */
|
||||
sstore
|
||||
/* "optimizer_user_yul/input.sol":183:229 for { } sload(4) { } {... */
|
||||
/* "optimizer_user_yul/input.sol":219:265 for { } sload(4) { } {... */
|
||||
tag_3:
|
||||
/* "optimizer_user_yul/input.sol":197:198 4 */
|
||||
/* "optimizer_user_yul/input.sol":233:234 4 */
|
||||
0x04
|
||||
/* "optimizer_user_yul/input.sol":191:199 sload(4) */
|
||||
/* "optimizer_user_yul/input.sol":227:235 sload(4) */
|
||||
sload
|
||||
/* "optimizer_user_yul/input.sol":183:229 for { } sload(4) { } {... */
|
||||
/* "optimizer_user_yul/input.sol":219:265 for { } sload(4) { } {... */
|
||||
iszero
|
||||
tag_5
|
||||
jumpi
|
||||
pop
|
||||
/* "optimizer_user_yul/input.sol":215:224 exp(x, y) */
|
||||
/* "optimizer_user_yul/input.sol":251:260 exp(x, y) */
|
||||
dup1
|
||||
dup3
|
||||
exp
|
||||
/* "optimizer_user_yul/input.sol":183:229 for { } sload(4) { } {... */
|
||||
/* "optimizer_user_yul/input.sol":219:265 for { } sload(4) { } {... */
|
||||
jump(tag_3)
|
||||
tag_5:
|
||||
/* "optimizer_user_yul/input.sol":187:190 { } */
|
||||
/* "optimizer_user_yul/input.sol":223:226 { } */
|
||||
pop
|
||||
pop
|
||||
pop
|
||||
/* "optimizer_user_yul/input.sol":239:240 2 */
|
||||
/* "optimizer_user_yul/input.sol":275:276 2 */
|
||||
0x02
|
||||
/* "optimizer_user_yul/input.sol":234:240 a := 2 */
|
||||
/* "optimizer_user_yul/input.sol":270:276 a := 2 */
|
||||
swap1
|
||||
pop
|
||||
/* "optimizer_user_yul/input.sol":340:341 3 */
|
||||
/* "optimizer_user_yul/input.sol":376:377 3 */
|
||||
0x03
|
||||
/* "optimizer_user_yul/input.sol":337:338 2 */
|
||||
/* "optimizer_user_yul/input.sol":373:374 2 */
|
||||
0x02
|
||||
/* "optimizer_user_yul/input.sol":330:342 sstore(2, 3) */
|
||||
/* "optimizer_user_yul/input.sol":366:378 sstore(2, 3) */
|
||||
sstore
|
||||
/* "optimizer_user_yul/input.sol":347:480 for { } sload(5) { } {... */
|
||||
/* "optimizer_user_yul/input.sol":383:516 for { } sload(5) { } {... */
|
||||
tag_6:
|
||||
/* "optimizer_user_yul/input.sol":361:362 5 */
|
||||
/* "optimizer_user_yul/input.sol":397:398 5 */
|
||||
0x05
|
||||
/* "optimizer_user_yul/input.sol":355:363 sload(5) */
|
||||
/* "optimizer_user_yul/input.sol":391:399 sload(5) */
|
||||
sload
|
||||
tag_9
|
||||
jumpi
|
||||
jump(tag_8)
|
||||
tag_9:
|
||||
/* "optimizer_user_yul/input.sol":347:480 for { } sload(5) { } {... */
|
||||
/* "optimizer_user_yul/input.sol":383:516 for { } sload(5) { } {... */
|
||||
jump(tag_6)
|
||||
tag_8:
|
||||
/* "optimizer_user_yul/input.sol":311:484 {... */
|
||||
/* "optimizer_user_yul/input.sol":347:520 {... */
|
||||
pop
|
||||
/* "optimizer_user_yul/input.sol":24:489 contract C... */
|
||||
/* "optimizer_user_yul/input.sol":60:525 contract C... */
|
||||
dataSize(sub_0)
|
||||
dup1
|
||||
dataOffset(sub_0)
|
||||
@ -74,7 +74,7 @@ tag_8:
|
||||
stop
|
||||
|
||||
sub_0: assembly {
|
||||
/* "optimizer_user_yul/input.sol":24:489 contract C... */
|
||||
/* "optimizer_user_yul/input.sol":60:525 contract C... */
|
||||
mstore(0x40, 0x80)
|
||||
/* "--CODEGEN--":12:13 */
|
||||
0x00
|
||||
|
@ -2,10 +2,10 @@
|
||||
"language": "Solidity",
|
||||
"sources": {
|
||||
"a.sol": {
|
||||
"content": "contract A1 { function a(uint x) public pure { assert(x > 0); } } contract A2 { function a(uint x) public pure { assert(x > 0); } }"
|
||||
"content": "//SPDX-License-Identifier: GPL-3.0\ncontract A1 { function a(uint x) public pure { assert(x > 0); } } contract A2 { function a(uint x) public pure { assert(x > 0); } }"
|
||||
},
|
||||
"b.sol": {
|
||||
"content": "contract A1 { function b(uint x) public { assert(x > 0); } } contract B2 { function b(uint x) public pure { assert(x > 0); } }"
|
||||
"content": "//SPDX-License-Identifier: GPL-3.0\ncontract A1 { function b(uint x) public { assert(x > 0); } } contract B2 { function b(uint x) public pure { assert(x > 0); } }"
|
||||
}
|
||||
},
|
||||
"settings": {
|
||||
|
@ -1,6 +1,6 @@
|
||||
{"contracts":{"a.sol":{"A1":{"evm":{"bytecode":{"linkReferences":{},"object":"bytecode removed","opcodes":"opcodes removed","sourceMap":"sourceMap removed"}}}},"b.sol":{"A1":{"evm":{"bytecode":{"linkReferences":{},"object":"bytecode removed","opcodes":"opcodes removed","sourceMap":"sourceMap removed"}}}}},"errors":[{"component":"general","formattedMessage":"a.sol: Warning: Source file does not specify required compiler version!
|
||||
","message":"Source file does not specify required compiler version!","severity":"warning","sourceLocation":{"end":-1,"file":"a.sol","start":-1},"type":"Warning"},{"component":"general","formattedMessage":"b.sol: Warning: Source file does not specify required compiler version!
|
||||
","message":"Source file does not specify required compiler version!","severity":"warning","sourceLocation":{"end":-1,"file":"b.sol","start":-1},"type":"Warning"},{"component":"general","formattedMessage":"b.sol:1:15: Warning: Function state mutability can be restricted to pure
|
||||
","message":"Source file does not specify required compiler version!","severity":"warning","sourceLocation":{"end":-1,"file":"b.sol","start":-1},"type":"Warning"},{"component":"general","formattedMessage":"b.sol:2:15: Warning: Function state mutability can be restricted to pure
|
||||
contract A1 { function b(uint x) public { assert(x > 0); } } contract B2 { function b(uint x) public pure { assert(x > 0); } }
|
||||
^------------------------------------------^
|
||||
","message":"Function state mutability can be restricted to pure","severity":"warning","sourceLocation":{"end":58,"file":"b.sol","start":14},"type":"Warning"}],"sources":{"a.sol":{"id":0},"b.sol":{"id":1}}}
|
||||
","message":"Function state mutability can be restricted to pure","severity":"warning","sourceLocation":{"end":93,"file":"b.sol","start":49},"type":"Warning"}],"sources":{"a.sol":{"id":0},"b.sol":{"id":1}}}
|
||||
|
@ -2,10 +2,10 @@
|
||||
"language": "Solidity",
|
||||
"sources": {
|
||||
"a.sol": {
|
||||
"content": "contract A1 { function a(uint x) public pure { assert(x > 0); } } contract A2 { function a(uint x) public pure { assert(x > 0); } }"
|
||||
"content": "//SPDX-License-Identifier: GPL-3.0\ncontract A1 { function a(uint x) public pure { assert(x > 0); } } contract A2 { function a(uint x) public pure { assert(x > 0); } }"
|
||||
},
|
||||
"b.sol": {
|
||||
"content": "contract A1 { function b(uint x) public { assert(x > 0); } } contract B2 { function b(uint x) public pure { assert(x > 0); } }"
|
||||
"content": "//SPDX-License-Identifier: GPL-3.0\ncontract A1 { function b(uint x) public { assert(x > 0); } } contract B2 { function b(uint x) public pure { assert(x > 0); } }"
|
||||
}
|
||||
},
|
||||
"settings": {
|
||||
|
@ -1,6 +1,6 @@
|
||||
{"contracts":{"a.sol":{"A2":{"evm":{"bytecode":{"linkReferences":{},"object":"bytecode removed","opcodes":"opcodes removed","sourceMap":"sourceMap removed"}}}}},"errors":[{"component":"general","formattedMessage":"a.sol: Warning: Source file does not specify required compiler version!
|
||||
","message":"Source file does not specify required compiler version!","severity":"warning","sourceLocation":{"end":-1,"file":"a.sol","start":-1},"type":"Warning"},{"component":"general","formattedMessage":"b.sol: Warning: Source file does not specify required compiler version!
|
||||
","message":"Source file does not specify required compiler version!","severity":"warning","sourceLocation":{"end":-1,"file":"b.sol","start":-1},"type":"Warning"},{"component":"general","formattedMessage":"b.sol:1:15: Warning: Function state mutability can be restricted to pure
|
||||
","message":"Source file does not specify required compiler version!","severity":"warning","sourceLocation":{"end":-1,"file":"b.sol","start":-1},"type":"Warning"},{"component":"general","formattedMessage":"b.sol:2:15: Warning: Function state mutability can be restricted to pure
|
||||
contract A1 { function b(uint x) public { assert(x > 0); } } contract B2 { function b(uint x) public pure { assert(x > 0); } }
|
||||
^------------------------------------------^
|
||||
","message":"Function state mutability can be restricted to pure","severity":"warning","sourceLocation":{"end":58,"file":"b.sol","start":14},"type":"Warning"}],"sources":{"a.sol":{"id":0},"b.sol":{"id":1}}}
|
||||
","message":"Function state mutability can be restricted to pure","severity":"warning","sourceLocation":{"end":93,"file":"b.sol","start":49},"type":"Warning"}],"sources":{"a.sol":{"id":0},"b.sol":{"id":1}}}
|
||||
|
@ -2,10 +2,10 @@
|
||||
"language": "Solidity",
|
||||
"sources": {
|
||||
"a.sol": {
|
||||
"content": "contract A1 { function a(uint x) public pure { assert(x > 0); } } contract A2 { function a(uint x) public pure { assert(x > 0); } }"
|
||||
"content": "//SPDX-License-Identifier: GPL-3.0\ncontract A1 { function a(uint x) public pure { assert(x > 0); } } contract A2 { function a(uint x) public pure { assert(x > 0); } }"
|
||||
},
|
||||
"b.sol": {
|
||||
"content": "contract A1 { function b(uint x) public { assert(x > 0); } } contract B2 { function b(uint x) public pure { assert(x > 0); } }"
|
||||
"content": "//SPDX-License-Identifier: GPL-3.0\ncontract A1 { function b(uint x) public { assert(x > 0); } } contract B2 { function b(uint x) public pure { assert(x > 0); } }"
|
||||
}
|
||||
},
|
||||
"settings": {
|
||||
|
@ -1,6 +1,6 @@
|
||||
{"errors":[{"component":"general","formattedMessage":"a.sol: Warning: Source file does not specify required compiler version!
|
||||
","message":"Source file does not specify required compiler version!","severity":"warning","sourceLocation":{"end":-1,"file":"a.sol","start":-1},"type":"Warning"},{"component":"general","formattedMessage":"b.sol: Warning: Source file does not specify required compiler version!
|
||||
","message":"Source file does not specify required compiler version!","severity":"warning","sourceLocation":{"end":-1,"file":"b.sol","start":-1},"type":"Warning"},{"component":"general","formattedMessage":"b.sol:1:15: Warning: Function state mutability can be restricted to pure
|
||||
","message":"Source file does not specify required compiler version!","severity":"warning","sourceLocation":{"end":-1,"file":"b.sol","start":-1},"type":"Warning"},{"component":"general","formattedMessage":"b.sol:2:15: Warning: Function state mutability can be restricted to pure
|
||||
contract A1 { function b(uint x) public { assert(x > 0); } } contract B2 { function b(uint x) public pure { assert(x > 0); } }
|
||||
^------------------------------------------^
|
||||
","message":"Function state mutability can be restricted to pure","severity":"warning","sourceLocation":{"end":58,"file":"b.sol","start":14},"type":"Warning"}],"sources":{"a.sol":{"id":0},"b.sol":{"id":1}}}
|
||||
","message":"Function state mutability can be restricted to pure","severity":"warning","sourceLocation":{"end":93,"file":"b.sol","start":49},"type":"Warning"}],"sources":{"a.sol":{"id":0},"b.sol":{"id":1}}}
|
||||
|
@ -2,10 +2,10 @@
|
||||
"language": "Solidity",
|
||||
"sources": {
|
||||
"a.sol": {
|
||||
"content": "contract A1 { function a(uint x) public pure { assert(x > 0); } } contract A2 { function a(uint x) public pure { assert(x > 0); } }"
|
||||
"content": "//SPDX-License-Identifier: GPL-3.0\ncontract A1 { function a(uint x) public pure { assert(x > 0); } } contract A2 { function a(uint x) public pure { assert(x > 0); } }"
|
||||
},
|
||||
"b.sol": {
|
||||
"content": "contract A1 { function b(uint x) public { assert(x > 0); } } contract B2 { function b(uint x) public pure { assert(x > 0); } }"
|
||||
"content": "//SPDX-License-Identifier: GPL-3.0\ncontract A1 { function b(uint x) public { assert(x > 0); } } contract B2 { function b(uint x) public pure { assert(x > 0); } }"
|
||||
}
|
||||
},
|
||||
"settings": {
|
||||
|
@ -1,6 +1,6 @@
|
||||
{"contracts":{"a.sol":{"A1":{"evm":{"bytecode":{"linkReferences":{},"object":"bytecode removed","opcodes":"opcodes removed","sourceMap":"sourceMap removed"}}},"A2":{"evm":{"bytecode":{"linkReferences":{},"object":"bytecode removed","opcodes":"opcodes removed","sourceMap":"sourceMap removed"}}}},"b.sol":{"A1":{"evm":{"bytecode":{"linkReferences":{},"object":"bytecode removed","opcodes":"opcodes removed","sourceMap":"sourceMap removed"}}},"B2":{"evm":{"bytecode":{"linkReferences":{},"object":"bytecode removed","opcodes":"opcodes removed","sourceMap":"sourceMap removed"}}}}},"errors":[{"component":"general","formattedMessage":"a.sol: Warning: Source file does not specify required compiler version!
|
||||
","message":"Source file does not specify required compiler version!","severity":"warning","sourceLocation":{"end":-1,"file":"a.sol","start":-1},"type":"Warning"},{"component":"general","formattedMessage":"b.sol: Warning: Source file does not specify required compiler version!
|
||||
","message":"Source file does not specify required compiler version!","severity":"warning","sourceLocation":{"end":-1,"file":"b.sol","start":-1},"type":"Warning"},{"component":"general","formattedMessage":"b.sol:1:15: Warning: Function state mutability can be restricted to pure
|
||||
","message":"Source file does not specify required compiler version!","severity":"warning","sourceLocation":{"end":-1,"file":"b.sol","start":-1},"type":"Warning"},{"component":"general","formattedMessage":"b.sol:2:15: Warning: Function state mutability can be restricted to pure
|
||||
contract A1 { function b(uint x) public { assert(x > 0); } } contract B2 { function b(uint x) public pure { assert(x > 0); } }
|
||||
^------------------------------------------^
|
||||
","message":"Function state mutability can be restricted to pure","severity":"warning","sourceLocation":{"end":58,"file":"b.sol","start":14},"type":"Warning"}],"sources":{"a.sol":{"id":0},"b.sol":{"id":1}}}
|
||||
","message":"Function state mutability can be restricted to pure","severity":"warning","sourceLocation":{"end":93,"file":"b.sol","start":49},"type":"Warning"}],"sources":{"a.sol":{"id":0},"b.sol":{"id":1}}}
|
||||
|
@ -2,10 +2,10 @@
|
||||
"language": "Solidity",
|
||||
"sources": {
|
||||
"a.sol": {
|
||||
"content": "contract A1 { function a(uint x) public pure { assert(x > 0); } } contract A2 { function a(uint x) public pure { assert(x > 0); } }"
|
||||
"content": "//SPDX-License-Identifier: GPL-3.0\ncontract A1 { function a(uint x) public pure { assert(x > 0); } } contract A2 { function a(uint x) public pure { assert(x > 0); } }"
|
||||
},
|
||||
"b.sol": {
|
||||
"content": "contract A1 { function b(uint x) public { assert(x > 0); } } contract B2 { function b(uint x) public pure { assert(x > 0); } }"
|
||||
"content": "//SPDX-License-Identifier: GPL-3.0\ncontract A1 { function b(uint x) public { assert(x > 0); } } contract B2 { function b(uint x) public pure { assert(x > 0); } }"
|
||||
}
|
||||
},
|
||||
"settings": {
|
||||
|
@ -2,10 +2,10 @@
|
||||
"language": "Solidity",
|
||||
"sources": {
|
||||
"a.sol": {
|
||||
"content": "contract A1 { function a(uint x) public pure { assert(x > 0); } } contract A2 { function a(uint x) public pure { assert(x > 0); } }"
|
||||
"content": "//SPDX-License-Identifier: GPL-3.0\ncontract A1 { function a(uint x) public pure { assert(x > 0); } } contract A2 { function a(uint x) public pure { assert(x > 0); } }"
|
||||
},
|
||||
"b.sol": {
|
||||
"content": "contract A1 { function b(uint x) public { assert(x > 0); } } contract B2 { function b(uint x) public pure { assert(x > 0); } }"
|
||||
"content": "//SPDX-License-Identifier: GPL-3.0\ncontract A1 { function b(uint x) public { assert(x > 0); } } contract B2 { function b(uint x) public pure { assert(x > 0); } }"
|
||||
}
|
||||
},
|
||||
"settings": {
|
||||
|
@ -1,5 +1,5 @@
|
||||
{"contracts":{"b.sol":{"B2":{"evm":{"bytecode":{"linkReferences":{},"object":"bytecode removed","opcodes":"opcodes removed","sourceMap":"sourceMap removed"}}}}},"errors":[{"component":"general","formattedMessage":"b.sol: Warning: Source file does not specify required compiler version!
|
||||
","message":"Source file does not specify required compiler version!","severity":"warning","sourceLocation":{"end":-1,"file":"b.sol","start":-1},"type":"Warning"},{"component":"general","formattedMessage":"b.sol:1:15: Warning: Function state mutability can be restricted to pure
|
||||
","message":"Source file does not specify required compiler version!","severity":"warning","sourceLocation":{"end":-1,"file":"b.sol","start":-1},"type":"Warning"},{"component":"general","formattedMessage":"b.sol:2:15: Warning: Function state mutability can be restricted to pure
|
||||
contract A1 { function b(uint x) public { assert(x > 0); } } contract B2 { function b(uint x) public pure { assert(x > 0); } }
|
||||
^------------------------------------------^
|
||||
","message":"Function state mutability can be restricted to pure","severity":"warning","sourceLocation":{"end":58,"file":"b.sol","start":14},"type":"Warning"}],"sources":{"a.sol":{"id":0},"b.sol":{"id":1}}}
|
||||
","message":"Function state mutability can be restricted to pure","severity":"warning","sourceLocation":{"end":93,"file":"b.sol","start":49},"type":"Warning"}],"sources":{"a.sol":{"id":0},"b.sol":{"id":1}}}
|
||||
|
@ -2,10 +2,10 @@
|
||||
"language": "Solidity",
|
||||
"sources": {
|
||||
"a.sol": {
|
||||
"content": "contract A1 { function a(uint x) public pure { assert(x > 0); } } contract A2 { function a(uint x) public pure { assert(x > 0); } }"
|
||||
"content": "//SPDX-License-Identifier: GPL-3.0\ncontract A1 { function a(uint x) public pure { assert(x > 0); } } contract A2 { function a(uint x) public pure { assert(x > 0); } }"
|
||||
},
|
||||
"b.sol": {
|
||||
"content": "contract A1 { function b(uint x) public { assert(x > 0); } } contract B2 { function b(uint x) public pure { assert(x > 0); } }"
|
||||
"content": "//SPDX-License-Identifier: GPL-3.0\ncontract A1 { function b(uint x) public { assert(x > 0); } } contract B2 { function b(uint x) public pure { assert(x > 0); } }"
|
||||
}
|
||||
},
|
||||
"settings": {
|
||||
|
@ -1,13 +1,13 @@
|
||||
Error: Expected primary expression.
|
||||
--> recovery_ast_constructor/input.sol:5:27:
|
||||
--> recovery_ast_constructor/input.sol:6:27:
|
||||
|
|
||||
5 | balances[tx.origin] = ; // missing RHS.
|
||||
6 | balances[tx.origin] = ; // missing RHS.
|
||||
| ^
|
||||
|
||||
Warning: Recovered in Statement at ';'.
|
||||
--> recovery_ast_constructor/input.sol:5:27:
|
||||
--> recovery_ast_constructor/input.sol:6:27:
|
||||
|
|
||||
5 | balances[tx.origin] = ; // missing RHS.
|
||||
6 | balances[tx.origin] = ; // missing RHS.
|
||||
| ^
|
||||
|
||||
|
||||
|
@ -1,3 +1,4 @@
|
||||
// SPDX-License-Identifier: GPL-3.0
|
||||
pragma solidity >=0.0.0;
|
||||
|
||||
contract Error1 {
|
||||
|
@ -12,7 +12,8 @@ JSON AST:
|
||||
[
|
||||
18
|
||||
]
|
||||
}
|
||||
},
|
||||
"license": "GPL-3.0"
|
||||
},
|
||||
"children":
|
||||
[
|
||||
@ -29,7 +30,7 @@ JSON AST:
|
||||
},
|
||||
"id": 1,
|
||||
"name": "PragmaDirective",
|
||||
"src": "0:24:0"
|
||||
"src": "36:24:0"
|
||||
},
|
||||
{
|
||||
"attributes":
|
||||
@ -86,7 +87,7 @@ JSON AST:
|
||||
"children": [],
|
||||
"id": 2,
|
||||
"name": "ParameterList",
|
||||
"src": "57:2:0"
|
||||
"src": "93:2:0"
|
||||
},
|
||||
{
|
||||
"attributes":
|
||||
@ -99,7 +100,7 @@ JSON AST:
|
||||
"children": [],
|
||||
"id": 3,
|
||||
"name": "ParameterList",
|
||||
"src": "67:0:0"
|
||||
"src": "103:0:0"
|
||||
},
|
||||
{
|
||||
"attributes":
|
||||
@ -112,12 +113,12 @@ JSON AST:
|
||||
"children": [],
|
||||
"id": 8,
|
||||
"name": "Block",
|
||||
"src": "67:49:0"
|
||||
"src": "103:49:0"
|
||||
}
|
||||
],
|
||||
"id": 9,
|
||||
"name": "FunctionDefinition",
|
||||
"src": "46:70:0"
|
||||
"src": "82:70:0"
|
||||
},
|
||||
{
|
||||
"attributes":
|
||||
@ -151,7 +152,7 @@ JSON AST:
|
||||
"children": [],
|
||||
"id": 10,
|
||||
"name": "ParameterList",
|
||||
"src": "382:2:0"
|
||||
"src": "418:2:0"
|
||||
},
|
||||
{
|
||||
"children":
|
||||
@ -180,17 +181,17 @@ JSON AST:
|
||||
},
|
||||
"id": 11,
|
||||
"name": "ElementaryTypeName",
|
||||
"src": "405:4:0"
|
||||
"src": "441:4:0"
|
||||
}
|
||||
],
|
||||
"id": 12,
|
||||
"name": "VariableDeclaration",
|
||||
"src": "405:4:0"
|
||||
"src": "441:4:0"
|
||||
}
|
||||
],
|
||||
"id": 13,
|
||||
"name": "ParameterList",
|
||||
"src": "404:6:0"
|
||||
"src": "440:6:0"
|
||||
},
|
||||
{
|
||||
"children":
|
||||
@ -218,30 +219,30 @@ JSON AST:
|
||||
},
|
||||
"id": 14,
|
||||
"name": "Literal",
|
||||
"src": "424:1:0"
|
||||
"src": "460:1:0"
|
||||
}
|
||||
],
|
||||
"id": 15,
|
||||
"name": "Return",
|
||||
"src": "417:8:0"
|
||||
"src": "453:8:0"
|
||||
}
|
||||
],
|
||||
"id": 16,
|
||||
"name": "Block",
|
||||
"src": "411:19:0"
|
||||
"src": "447:19:0"
|
||||
}
|
||||
],
|
||||
"id": 17,
|
||||
"name": "FunctionDefinition",
|
||||
"src": "369:61:0"
|
||||
"src": "405:61:0"
|
||||
}
|
||||
],
|
||||
"id": 18,
|
||||
"name": "ContractDefinition",
|
||||
"src": "26:406:0"
|
||||
"src": "62:406:0"
|
||||
}
|
||||
],
|
||||
"id": 19,
|
||||
"name": "SourceUnit",
|
||||
"src": "0:433:0"
|
||||
"src": "36:433:0"
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
Error: Expected pragma, import directive or contract/interface/library/struct/enum definition.
|
||||
--> recovery_ast_empty_contract/input.sol:2:1:
|
||||
--> recovery_ast_empty_contract/input.sol:3:1:
|
||||
|
|
||||
2 | c
|
||||
3 | c
|
||||
| ^
|
||||
|
||||
|
||||
|
@ -1,2 +1,3 @@
|
||||
// SPDX-License-Identifier: GPL-3.0
|
||||
pragma 0.5.11;
|
||||
c
|
@ -4,7 +4,7 @@
|
||||
{
|
||||
"A":
|
||||
{
|
||||
"content": "pragma solidity >=0.0; contract Errort6 { using foo for ; /* missing type name */ }"
|
||||
"content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0; contract Errort6 { using foo for ; /* missing type name */ }"
|
||||
}
|
||||
},
|
||||
"settings":
|
||||
|
@ -1,7 +1,7 @@
|
||||
{"errors":[{"component":"general","formattedMessage":"A:1:58: ParserError: Expected type name
|
||||
{"errors":[{"component":"general","formattedMessage":"A:2:58: ParserError: Expected type name
|
||||
pragma solidity >=0.0; contract Errort6 { using foo for ; /* missing type name */ }
|
||||
^
|
||||
","message":"Expected type name","severity":"error","sourceLocation":{"end":58,"file":"A","start":57},"type":"ParserError"},{"component":"general","formattedMessage":"A:1:84: Warning: Recovered in ContractDefinition at '}'.
|
||||
","message":"Expected type name","severity":"error","sourceLocation":{"end":94,"file":"A","start":93},"type":"ParserError"},{"component":"general","formattedMessage":"A:2:84: Warning: Recovered in ContractDefinition at '}'.
|
||||
pragma solidity >=0.0; contract Errort6 { using foo for ; /* missing type name */ }
|
||||
^
|
||||
","message":"Recovered in ContractDefinition at '}'.","severity":"warning","sourceLocation":{"end":84,"file":"A","start":83},"type":"Warning"}],"sources":{"A":{"ast":{"absolutePath":"A","exportedSymbols":{"Errort6":[3]},"id":4,"nodeType":"SourceUnit","nodes":[{"id":1,"literals":["solidity",">=","0.0"],"nodeType":"PragmaDirective","src":"0:22:0"},{"abstract":false,"baseContracts":[],"contractDependencies":[],"contractKind":"contract","documentation":null,"fullyImplemented":true,"id":3,"linearizedBaseContracts":[3],"name":"Errort6","nodeType":"ContractDefinition","nodes":[],"scope":4,"src":"23:35:0"}],"src":"0:84:0"},"id":0}}}
|
||||
","message":"Recovered in ContractDefinition at '}'.","severity":"warning","sourceLocation":{"end":120,"file":"A","start":119},"type":"Warning"}],"sources":{"A":{"ast":{"absolutePath":"A","exportedSymbols":{"Errort6":[3]},"id":4,"license":"GPL-3.0","nodeType":"SourceUnit","nodes":[{"id":1,"literals":["solidity",">=","0.0"],"nodeType":"PragmaDirective","src":"36:22:0"},{"abstract":false,"baseContracts":[],"contractDependencies":[],"contractKind":"contract","documentation":null,"fullyImplemented":true,"id":3,"linearizedBaseContracts":[3],"name":"Errort6","nodeType":"ContractDefinition","nodes":[],"scope":4,"src":"59:35:0"}],"src":"36:84:0"},"id":0}}}
|
||||
|
@ -1,7 +1,7 @@
|
||||
Error: No matching declaration found after argument-dependent lookup.
|
||||
--> require_overload/input.sol:4:9:
|
||||
--> require_overload/input.sol:5:9:
|
||||
|
|
||||
4 | require(this);
|
||||
5 | require(this);
|
||||
| ^^^^^^^
|
||||
Note: Candidate: function require(bool)
|
||||
Note: Candidate: function require(bool, string memory)
|
||||
|
@ -1,3 +1,4 @@
|
||||
// SPDX-License-Identifier: GPL-3.0
|
||||
pragma solidity >=0.0;
|
||||
contract C {
|
||||
function f() public pure {
|
||||
|
@ -4,7 +4,7 @@
|
||||
{
|
||||
"A":
|
||||
{
|
||||
"content": "pragma solidity >=0.0; contract C { function f() public pure {} }"
|
||||
"content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0; contract C { function f() public pure {} }"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -4,7 +4,7 @@
|
||||
{
|
||||
"A":
|
||||
{
|
||||
"content": "pragma solidity >=0.0; contract C { }"
|
||||
"content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0; contract C { }"
|
||||
}
|
||||
},
|
||||
"settings":
|
||||
|
@ -4,7 +4,7 @@
|
||||
{
|
||||
"":
|
||||
{
|
||||
"content": "pragma solidity >=0.0; import {A} from \".\";"
|
||||
"content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0; import {A} from \".\";"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
{"errors":[{"component":"general","formattedMessage":":1:24: DeclarationError: Declaration \"A\" not found in \"\" (referenced as \".\").
|
||||
{"errors":[{"component":"general","formattedMessage":":2:24: DeclarationError: Declaration \"A\" not found in \"\" (referenced as \".\").
|
||||
pragma solidity >=0.0; import {A} from \".\";
|
||||
^------------------^
|
||||
","message":"Declaration \"A\" not found in \"\" (referenced as \".\").","severity":"error","type":"DeclarationError"}],"sources":{}}
|
||||
|
@ -2,7 +2,7 @@
|
||||
"language": "Solidity",
|
||||
"sources": {
|
||||
"a.sol": {
|
||||
"content": "contract A { uint256 immutable x = 1; function f() public view returns (uint256) { return x; } }"
|
||||
"content": "// SPDX-License-Identifier: GPL-3.0\ncontract A { uint256 immutable x = 1; function f() public view returns (uint256) { return x; } }"
|
||||
}
|
||||
},
|
||||
"settings": {
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user