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:
|
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.
|
* 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:
|
Language Features:
|
||||||
@ -26,6 +28,8 @@ Language Features:
|
|||||||
|
|
||||||
Compiler Features:
|
Compiler Features:
|
||||||
* Commandline Interface: Don't ignore `--yul-optimizations` in assembly mode.
|
* 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.
|
* 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.
|
* 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.
|
* 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)
|
### 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;
|
pragma solidity ^0.4.25;
|
||||||
// This will report a warning until version 0.4.25 of the compiler
|
// This will report a warning until version 0.4.25 of the compiler
|
||||||
// This will not compile after 0.5.0
|
// 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;
|
pragma solidity >=0.5.0 <0.8.0;
|
||||||
interface OldContract {
|
interface OldContract {
|
||||||
function someOldFunction(uint8 a) external;
|
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;
|
pragma solidity >=0.5.0 <0.8.0;
|
||||||
|
|
||||||
interface OldContract {
|
interface OldContract {
|
||||||
@ -347,6 +350,7 @@ commandline compiler for linking):
|
|||||||
::
|
::
|
||||||
|
|
||||||
// This will not compile after 0.6.0
|
// This will not compile after 0.6.0
|
||||||
|
// SPDX-License-Identifier: GPL-3.0
|
||||||
pragma solidity >=0.5.0 <0.5.99;
|
pragma solidity >=0.5.0 <0.5.99;
|
||||||
|
|
||||||
library OldLibrary {
|
library OldLibrary {
|
||||||
@ -370,6 +374,7 @@ Old version:
|
|||||||
|
|
||||||
::
|
::
|
||||||
|
|
||||||
|
// SPDX-License-Identifier: GPL-3.0
|
||||||
pragma solidity ^0.4.25;
|
pragma solidity ^0.4.25;
|
||||||
// This will not compile after 0.5.0
|
// 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;
|
pragma solidity >=0.5.0 <0.5.99;
|
||||||
// This will not compile after 0.6.0
|
// 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;
|
pragma solidity >=0.4.16 <0.8.0;
|
||||||
|
|
||||||
contract Foo {
|
contract Foo {
|
||||||
@ -535,6 +536,7 @@ For example,
|
|||||||
|
|
||||||
::
|
::
|
||||||
|
|
||||||
|
// SPDX-License-Identifier: GPL-3.0
|
||||||
pragma solidity >=0.5.0 <0.8.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 solidity >=0.4.19 <0.8.0;
|
||||||
pragma experimental ABIEncoderV2;
|
pragma experimental ABIEncoderV2;
|
||||||
|
|
||||||
|
@ -41,6 +41,7 @@ without a compiler change.
|
|||||||
|
|
||||||
.. code::
|
.. code::
|
||||||
|
|
||||||
|
// SPDX-License-Identifier: GPL-3.0
|
||||||
pragma solidity >=0.4.16 <0.8.0;
|
pragma solidity >=0.4.16 <0.8.0;
|
||||||
|
|
||||||
library GetCode {
|
library GetCode {
|
||||||
@ -66,6 +67,7 @@ efficient code, for example:
|
|||||||
|
|
||||||
.. code::
|
.. code::
|
||||||
|
|
||||||
|
// SPDX-License-Identifier: GPL-3.0
|
||||||
pragma solidity >=0.4.16 <0.8.0;
|
pragma solidity >=0.4.16 <0.8.0;
|
||||||
|
|
||||||
|
|
||||||
@ -136,6 +138,7 @@ Local Solidity variables are available for assignments, for example:
|
|||||||
|
|
||||||
.. code::
|
.. code::
|
||||||
|
|
||||||
|
// SPDX-License-Identifier: GPL-3.0
|
||||||
pragma solidity >=0.4.16 <0.8.0;
|
pragma solidity >=0.4.16 <0.8.0;
|
||||||
|
|
||||||
contract C {
|
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",
|
"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.",
|
"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": {
|
"0.5.14": {
|
||||||
"bugs": [
|
"bugs": [
|
||||||
|
"MissingEscapingInFormatting",
|
||||||
"ImplicitConstructorCallvalueCheck",
|
"ImplicitConstructorCallvalueCheck",
|
||||||
"TupleAssignmentMultiStackSlotComponents",
|
"TupleAssignmentMultiStackSlotComponents",
|
||||||
"MemoryArrayCreationOverflow",
|
"MemoryArrayCreationOverflow",
|
||||||
@ -934,6 +935,7 @@
|
|||||||
},
|
},
|
||||||
"0.5.15": {
|
"0.5.15": {
|
||||||
"bugs": [
|
"bugs": [
|
||||||
|
"MissingEscapingInFormatting",
|
||||||
"ImplicitConstructorCallvalueCheck",
|
"ImplicitConstructorCallvalueCheck",
|
||||||
"TupleAssignmentMultiStackSlotComponents",
|
"TupleAssignmentMultiStackSlotComponents",
|
||||||
"MemoryArrayCreationOverflow",
|
"MemoryArrayCreationOverflow",
|
||||||
@ -944,6 +946,7 @@
|
|||||||
},
|
},
|
||||||
"0.5.16": {
|
"0.5.16": {
|
||||||
"bugs": [
|
"bugs": [
|
||||||
|
"MissingEscapingInFormatting",
|
||||||
"ImplicitConstructorCallvalueCheck",
|
"ImplicitConstructorCallvalueCheck",
|
||||||
"TupleAssignmentMultiStackSlotComponents",
|
"TupleAssignmentMultiStackSlotComponents",
|
||||||
"MemoryArrayCreationOverflow",
|
"MemoryArrayCreationOverflow",
|
||||||
@ -953,6 +956,7 @@
|
|||||||
},
|
},
|
||||||
"0.5.17": {
|
"0.5.17": {
|
||||||
"bugs": [
|
"bugs": [
|
||||||
|
"MissingEscapingInFormatting",
|
||||||
"ImplicitConstructorCallvalueCheck",
|
"ImplicitConstructorCallvalueCheck",
|
||||||
"TupleAssignmentMultiStackSlotComponents",
|
"TupleAssignmentMultiStackSlotComponents",
|
||||||
"MemoryArrayCreationOverflow"
|
"MemoryArrayCreationOverflow"
|
||||||
@ -1082,6 +1086,8 @@
|
|||||||
},
|
},
|
||||||
"0.6.0": {
|
"0.6.0": {
|
||||||
"bugs": [
|
"bugs": [
|
||||||
|
"MissingEscapingInFormatting",
|
||||||
|
"ArraySliceDynamicallyEncodedBaseType",
|
||||||
"ImplicitConstructorCallvalueCheck",
|
"ImplicitConstructorCallvalueCheck",
|
||||||
"TupleAssignmentMultiStackSlotComponents",
|
"TupleAssignmentMultiStackSlotComponents",
|
||||||
"MemoryArrayCreationOverflow",
|
"MemoryArrayCreationOverflow",
|
||||||
@ -1091,6 +1097,8 @@
|
|||||||
},
|
},
|
||||||
"0.6.1": {
|
"0.6.1": {
|
||||||
"bugs": [
|
"bugs": [
|
||||||
|
"MissingEscapingInFormatting",
|
||||||
|
"ArraySliceDynamicallyEncodedBaseType",
|
||||||
"ImplicitConstructorCallvalueCheck",
|
"ImplicitConstructorCallvalueCheck",
|
||||||
"TupleAssignmentMultiStackSlotComponents",
|
"TupleAssignmentMultiStackSlotComponents",
|
||||||
"MemoryArrayCreationOverflow"
|
"MemoryArrayCreationOverflow"
|
||||||
@ -1099,6 +1107,8 @@
|
|||||||
},
|
},
|
||||||
"0.6.2": {
|
"0.6.2": {
|
||||||
"bugs": [
|
"bugs": [
|
||||||
|
"MissingEscapingInFormatting",
|
||||||
|
"ArraySliceDynamicallyEncodedBaseType",
|
||||||
"ImplicitConstructorCallvalueCheck",
|
"ImplicitConstructorCallvalueCheck",
|
||||||
"TupleAssignmentMultiStackSlotComponents",
|
"TupleAssignmentMultiStackSlotComponents",
|
||||||
"MemoryArrayCreationOverflow"
|
"MemoryArrayCreationOverflow"
|
||||||
@ -1107,6 +1117,8 @@
|
|||||||
},
|
},
|
||||||
"0.6.3": {
|
"0.6.3": {
|
||||||
"bugs": [
|
"bugs": [
|
||||||
|
"MissingEscapingInFormatting",
|
||||||
|
"ArraySliceDynamicallyEncodedBaseType",
|
||||||
"ImplicitConstructorCallvalueCheck",
|
"ImplicitConstructorCallvalueCheck",
|
||||||
"TupleAssignmentMultiStackSlotComponents",
|
"TupleAssignmentMultiStackSlotComponents",
|
||||||
"MemoryArrayCreationOverflow"
|
"MemoryArrayCreationOverflow"
|
||||||
@ -1115,6 +1127,8 @@
|
|||||||
},
|
},
|
||||||
"0.6.4": {
|
"0.6.4": {
|
||||||
"bugs": [
|
"bugs": [
|
||||||
|
"MissingEscapingInFormatting",
|
||||||
|
"ArraySliceDynamicallyEncodedBaseType",
|
||||||
"ImplicitConstructorCallvalueCheck",
|
"ImplicitConstructorCallvalueCheck",
|
||||||
"TupleAssignmentMultiStackSlotComponents",
|
"TupleAssignmentMultiStackSlotComponents",
|
||||||
"MemoryArrayCreationOverflow"
|
"MemoryArrayCreationOverflow"
|
||||||
@ -1123,6 +1137,8 @@
|
|||||||
},
|
},
|
||||||
"0.6.5": {
|
"0.6.5": {
|
||||||
"bugs": [
|
"bugs": [
|
||||||
|
"MissingEscapingInFormatting",
|
||||||
|
"ArraySliceDynamicallyEncodedBaseType",
|
||||||
"ImplicitConstructorCallvalueCheck",
|
"ImplicitConstructorCallvalueCheck",
|
||||||
"TupleAssignmentMultiStackSlotComponents"
|
"TupleAssignmentMultiStackSlotComponents"
|
||||||
],
|
],
|
||||||
@ -1130,12 +1146,16 @@
|
|||||||
},
|
},
|
||||||
"0.6.6": {
|
"0.6.6": {
|
||||||
"bugs": [
|
"bugs": [
|
||||||
|
"MissingEscapingInFormatting",
|
||||||
|
"ArraySliceDynamicallyEncodedBaseType",
|
||||||
"ImplicitConstructorCallvalueCheck"
|
"ImplicitConstructorCallvalueCheck"
|
||||||
],
|
],
|
||||||
"released": "2020-04-09"
|
"released": "2020-04-09"
|
||||||
},
|
},
|
||||||
"0.6.7": {
|
"0.6.7": {
|
||||||
"bugs": [
|
"bugs": [
|
||||||
|
"MissingEscapingInFormatting",
|
||||||
|
"ArraySliceDynamicallyEncodedBaseType",
|
||||||
"ImplicitConstructorCallvalueCheck"
|
"ImplicitConstructorCallvalueCheck"
|
||||||
],
|
],
|
||||||
"released": "2020-05-04"
|
"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;
|
pragma solidity >=0.5.0 <0.8.0;
|
||||||
|
|
||||||
contract WithdrawalContract {
|
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;
|
pragma solidity >=0.5.0 <0.8.0;
|
||||||
|
|
||||||
contract SendContract {
|
contract SendContract {
|
||||||
@ -121,6 +123,7 @@ restrictions highly readable.
|
|||||||
|
|
||||||
::
|
::
|
||||||
|
|
||||||
|
// SPDX-License-Identifier: GPL-3.0
|
||||||
pragma solidity >=0.4.22 <0.8.0;
|
pragma solidity >=0.4.22 <0.8.0;
|
||||||
|
|
||||||
contract AccessRestriction {
|
contract AccessRestriction {
|
||||||
@ -273,6 +276,7 @@ function finishes.
|
|||||||
|
|
||||||
::
|
::
|
||||||
|
|
||||||
|
// SPDX-License-Identifier: GPL-3.0
|
||||||
pragma solidity >=0.4.22 <0.8.0;
|
pragma solidity >=0.4.22 <0.8.0;
|
||||||
|
|
||||||
contract StateMachine {
|
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
|
defined as abstract, because the function ``utterance()`` was defined, but no implementation was
|
||||||
provided (no implementation body ``{ }`` was given).::
|
provided (no implementation body ``{ }`` was given).::
|
||||||
|
|
||||||
|
// SPDX-License-Identifier: GPL-3.0
|
||||||
pragma solidity >=0.6.0 <0.8.0;
|
pragma solidity >=0.6.0 <0.8.0;
|
||||||
|
|
||||||
abstract contract Feline {
|
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
|
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::
|
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;
|
pragma solidity >=0.6.0 <0.8.0;
|
||||||
|
|
||||||
abstract contract Feline {
|
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;
|
pragma solidity >0.6.4 <0.8.0;
|
||||||
|
|
||||||
contract C {
|
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;
|
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;
|
pragma solidity >=0.4.21 <0.8.0;
|
||||||
|
|
||||||
contract ClientReceipt {
|
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;
|
pragma solidity >=0.4.10 <0.8.0;
|
||||||
|
|
||||||
contract C {
|
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;
|
pragma solidity >=0.5.0 <0.8.0;
|
||||||
|
|
||||||
contract owned {
|
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
|
For example, if you want your contract to accept one kind of external call
|
||||||
with two integers, you would use something like the following::
|
with two integers, you would use something like the following::
|
||||||
|
|
||||||
|
// SPDX-License-Identifier: GPL-3.0
|
||||||
pragma solidity >=0.4.16 <0.8.0;
|
pragma solidity >=0.4.16 <0.8.0;
|
||||||
|
|
||||||
contract Simple {
|
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
|
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::
|
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;
|
pragma solidity >=0.4.16 <0.8.0;
|
||||||
|
|
||||||
contract Simple {
|
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``
|
(either a single or :ref:`multiple ones<multi-return>`) directly with the ``return``
|
||||||
statement::
|
statement::
|
||||||
|
|
||||||
|
// SPDX-License-Identifier: GPL-3.0
|
||||||
pragma solidity >=0.4.16 <0.8.0;
|
pragma solidity >=0.4.16 <0.8.0;
|
||||||
|
|
||||||
contract Simple {
|
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;
|
pragma solidity >=0.5.0 <0.8.0;
|
||||||
|
|
||||||
contract C {
|
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;
|
pragma solidity >=0.5.0 <0.8.0;
|
||||||
|
|
||||||
contract C {
|
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;
|
pragma solidity >=0.6.0 <0.8.0;
|
||||||
|
|
||||||
// This contract keeps all Ether sent to it with no way
|
// 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;
|
pragma solidity >=0.6.2 <0.8.0;
|
||||||
|
|
||||||
contract Test {
|
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;
|
pragma solidity >=0.4.16 <0.8.0;
|
||||||
|
|
||||||
contract A {
|
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;
|
pragma solidity >=0.4.16 <0.8.0;
|
||||||
|
|
||||||
// This will not compile
|
// 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;
|
pragma solidity >=0.4.16 <0.8.0;
|
||||||
|
|
||||||
contract A {
|
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;
|
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
|
destruction request. The way this is done is problematic, as
|
||||||
seen in the following example::
|
seen in the following example::
|
||||||
|
|
||||||
|
// SPDX-License-Identifier: GPL-3.0
|
||||||
pragma solidity >=0.6.0 <0.8.0;
|
pragma solidity >=0.6.0 <0.8.0;
|
||||||
|
|
||||||
contract owned {
|
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
|
explicitly in the final override, but this function will bypass
|
||||||
``Base1.destroy``. The way around this is to use ``super``::
|
``Base1.destroy``. The way around this is to use ``super``::
|
||||||
|
|
||||||
|
// SPDX-License-Identifier: GPL-3.0
|
||||||
pragma solidity >=0.6.0 <0.8.0;
|
pragma solidity >=0.6.0 <0.8.0;
|
||||||
|
|
||||||
contract owned {
|
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;
|
pragma solidity >=0.6.0 <0.8.0;
|
||||||
|
|
||||||
contract Base
|
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;
|
pragma solidity >=0.6.0 <0.8.0;
|
||||||
|
|
||||||
contract Base1
|
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;
|
pragma solidity >=0.6.0 <0.8.0;
|
||||||
|
|
||||||
contract A { function f() public pure{} }
|
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;
|
pragma solidity >=0.6.0 <0.8.0;
|
||||||
|
|
||||||
contract A
|
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;
|
pragma solidity >=0.6.0 <0.8.0;
|
||||||
|
|
||||||
contract Base
|
contract Base
|
||||||
@ -342,6 +350,7 @@ explicitly:
|
|||||||
|
|
||||||
::
|
::
|
||||||
|
|
||||||
|
// SPDX-License-Identifier: GPL-3.0
|
||||||
pragma solidity >=0.6.0 <0.8.0;
|
pragma solidity >=0.6.0 <0.8.0;
|
||||||
|
|
||||||
contract Base1
|
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;
|
pragma solidity >=0.5.0 <0.8.0;
|
||||||
|
|
||||||
contract A {
|
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,
|
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::
|
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;
|
pragma solidity >=0.4.22 <0.8.0;
|
||||||
|
|
||||||
contract Base {
|
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;
|
pragma solidity >=0.4.0 <0.8.0;
|
||||||
|
|
||||||
contract X {}
|
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;
|
pragma solidity >=0.4.22 <0.8.0;
|
||||||
|
|
||||||
contract Base1 {
|
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;
|
pragma solidity >=0.6.2 <0.8.0;
|
||||||
|
|
||||||
interface Token {
|
interface Token {
|
||||||
@ -42,6 +43,7 @@ inheritance.
|
|||||||
|
|
||||||
::
|
::
|
||||||
|
|
||||||
|
// SPDX-License-Identifier: GPL-3.0
|
||||||
pragma solidity >=0.6.2 <0.8.0;
|
pragma solidity >=0.6.2 <0.8.0;
|
||||||
|
|
||||||
interface ParentA {
|
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;
|
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;
|
pragma solidity >=0.6.0 <0.8.0;
|
||||||
|
|
||||||
struct bigint {
|
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;
|
pragma solidity >=0.5.14 <0.8.0;
|
||||||
|
|
||||||
library L {
|
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
|
Let us rewrite the set example from the
|
||||||
:ref:`libraries` in this way::
|
:ref:`libraries` in this way::
|
||||||
|
|
||||||
|
// SPDX-License-Identifier: GPL-3.0
|
||||||
pragma solidity >=0.6.0 <0.8.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::
|
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;
|
pragma solidity >=0.4.16 <0.8.0;
|
||||||
|
|
||||||
library Search {
|
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;
|
pragma solidity >=0.4.16 <0.8.0;
|
||||||
|
|
||||||
contract C {
|
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;
|
pragma solidity >=0.4.16 <0.8.0;
|
||||||
|
|
||||||
contract C {
|
contract C {
|
||||||
@ -112,6 +114,7 @@ when they are declared.
|
|||||||
|
|
||||||
::
|
::
|
||||||
|
|
||||||
|
// SPDX-License-Identifier: GPL-3.0
|
||||||
pragma solidity >=0.4.16 <0.8.0;
|
pragma solidity >=0.4.16 <0.8.0;
|
||||||
|
|
||||||
contract C {
|
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;
|
pragma solidity >=0.4.0 <0.8.0;
|
||||||
|
|
||||||
contract C {
|
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;
|
pragma solidity >=0.4.16 <0.8.0;
|
||||||
|
|
||||||
contract arrayExample {
|
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;
|
pragma solidity >=0.4.0 <0.8.0;
|
||||||
|
|
||||||
contract Complex {
|
contract Complex {
|
||||||
|
@ -41,6 +41,7 @@ Internal Function Calls
|
|||||||
Functions of the current contract can be called directly ("internally"), also recursively, as seen in
|
Functions of the current contract can be called directly ("internally"), also recursively, as seen in
|
||||||
this nonsensical example::
|
this nonsensical example::
|
||||||
|
|
||||||
|
// SPDX-License-Identifier: GPL-3.0
|
||||||
pragma solidity >=0.4.22 <0.8.0;
|
pragma solidity >=0.4.22 <0.8.0;
|
||||||
|
|
||||||
contract C {
|
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;
|
pragma solidity >=0.6.2 <0.8.0;
|
||||||
|
|
||||||
contract InfoFeed {
|
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;
|
pragma solidity >=0.4.0 <0.8.0;
|
||||||
|
|
||||||
contract C {
|
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;
|
pragma solidity >=0.4.22 <0.8.0;
|
||||||
|
|
||||||
contract C {
|
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;
|
pragma solidity >=0.6.2 <0.8.0;
|
||||||
|
|
||||||
contract D {
|
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;
|
pragma solidity >=0.6.2 <0.8.0;
|
||||||
|
|
||||||
contract D {
|
contract D {
|
||||||
@ -307,6 +313,7 @@ groupings of expressions.
|
|||||||
|
|
||||||
::
|
::
|
||||||
|
|
||||||
|
// SPDX-License-Identifier: GPL-3.0
|
||||||
pragma solidity >=0.5.0 <0.8.0;
|
pragma solidity >=0.5.0 <0.8.0;
|
||||||
|
|
||||||
contract C {
|
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;
|
pragma solidity >=0.4.22 <0.8.0;
|
||||||
|
|
||||||
contract C {
|
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;
|
pragma solidity >=0.5.0 <0.8.0;
|
||||||
contract C {
|
contract C {
|
||||||
function minimalScoping() pure public {
|
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;
|
pragma solidity >=0.5.0 <0.8.0;
|
||||||
// This will report a warning
|
// This will report a warning
|
||||||
contract C {
|
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;
|
pragma solidity >=0.5.0 <0.8.0;
|
||||||
// This will not compile
|
// This will not compile
|
||||||
contract C {
|
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;
|
pragma solidity >=0.5.0 <0.8.0;
|
||||||
|
|
||||||
contract Sharer {
|
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;
|
pragma solidity >=0.5.0 <0.8.0;
|
||||||
|
|
||||||
contract VendingMachine {
|
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;
|
pragma solidity >=0.6.0 <0.8.0;
|
||||||
|
|
||||||
interface DataFeed { function getData(address token) external returns (uint value); }
|
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;
|
pragma solidity >=0.5.0 <0.8.0;
|
||||||
|
|
||||||
contract SimpleAuction {
|
contract SimpleAuction {
|
||||||
@ -184,6 +185,7 @@ invalid bids.
|
|||||||
|
|
||||||
::
|
::
|
||||||
|
|
||||||
|
// SPDX-License-Identifier: GPL-3.0
|
||||||
pragma solidity >=0.5.0 <0.8.0;
|
pragma solidity >=0.5.0 <0.8.0;
|
||||||
|
|
||||||
contract BlindAuction {
|
contract BlindAuction {
|
||||||
|
@ -142,6 +142,7 @@ The full contract
|
|||||||
|
|
||||||
::
|
::
|
||||||
|
|
||||||
|
// SPDX-License-Identifier: GPL-3.0
|
||||||
pragma solidity >=0.4.24 <0.8.0;
|
pragma solidity >=0.4.24 <0.8.0;
|
||||||
|
|
||||||
contract ReceiverPays {
|
contract ReceiverPays {
|
||||||
@ -338,6 +339,7 @@ The full contract
|
|||||||
|
|
||||||
::
|
::
|
||||||
|
|
||||||
|
// SPDX-License-Identifier: GPL-3.0
|
||||||
pragma solidity >=0.5.0 <0.8.0;
|
pragma solidity >=0.5.0 <0.8.0;
|
||||||
|
|
||||||
contract SimplePaymentChannel {
|
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;
|
pragma solidity >=0.5.0 <0.8.0;
|
||||||
|
|
||||||
library Balances {
|
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;
|
pragma solidity >=0.5.0 <0.8.0;
|
||||||
|
|
||||||
contract Purchase {
|
contract Purchase {
|
||||||
|
@ -32,6 +32,7 @@ of votes.
|
|||||||
|
|
||||||
::
|
::
|
||||||
|
|
||||||
|
// SPDX-License-Identifier: GPL-3.0
|
||||||
pragma solidity >=0.4.22 <0.8.0;
|
pragma solidity >=0.4.22 <0.8.0;
|
||||||
|
|
||||||
/// @title Voting with delegation.
|
/// @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``::
|
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;
|
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::
|
.. code::
|
||||||
|
|
||||||
|
// SPDX-License-Identifier: GPL-3.0
|
||||||
pragma solidity >=0.4.0 <0.8.0;
|
pragma solidity >=0.4.0 <0.8.0;
|
||||||
contract A {
|
contract A {
|
||||||
struct S {
|
struct S {
|
||||||
|
@ -17,6 +17,7 @@ Storage Example
|
|||||||
|
|
||||||
::
|
::
|
||||||
|
|
||||||
|
// SPDX-License-Identifier: GPL-3.0
|
||||||
pragma solidity >=0.4.16 <0.8.0;
|
pragma solidity >=0.4.16 <0.8.0;
|
||||||
|
|
||||||
contract SimpleStorage {
|
contract SimpleStorage {
|
||||||
@ -31,8 +32,12 @@ Storage Example
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
The first line tells you that the source code is written for
|
The first line tells you that the source code is licensed under the
|
||||||
Solidity version 0.4.0, or a newer version of the language up to, but not including version 0.7.0.
|
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.
|
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
|
: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>`_).
|
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;
|
pragma solidity >=0.5.0 <0.8.0;
|
||||||
|
|
||||||
contract Coin {
|
contract Coin {
|
||||||
|
@ -7,6 +7,38 @@ Source files can contain an arbitrary number of
|
|||||||
:ref:`pragma directives<pragma>` and
|
:ref:`pragma directives<pragma>` and
|
||||||
:ref:`struct<structs>` and :ref:`enum<enums>` definitions.
|
: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
|
.. index:: ! pragma
|
||||||
|
|
||||||
.. _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;
|
pragma solidity >=0.4.21 <0.8.0;
|
||||||
|
|
||||||
/** @title Shape calculator. */
|
/** @title Shape calculator. */
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
.. _metadata:
|
||||||
|
|
||||||
#################
|
#################
|
||||||
Contract Metadata
|
Contract Metadata
|
||||||
#################
|
#################
|
||||||
@ -54,7 +56,9 @@ explanatory purposes.
|
|||||||
// Required (unless "content" is used, see below): Sorted URL(s)
|
// Required (unless "content" is used, see below): Sorted URL(s)
|
||||||
// to the source file, protocol is more or less arbitrary, but a
|
// to the source file, protocol is more or less arbitrary, but a
|
||||||
// Swarm URL is recommended
|
// Swarm URL is recommended
|
||||||
"urls": [ "bzzr://56ab..." ]
|
"urls": [ "bzzr://56ab..." ],
|
||||||
|
// Optional: SPDX license identifier as given in the source file
|
||||||
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"destructible": {
|
"destructible": {
|
||||||
// Required: keccak256 hash of the source file
|
// 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
|
.. code:: solidity
|
||||||
|
|
||||||
|
// SPDX-License-Identifier: GPL-3.0
|
||||||
pragma solidity >=0.5.0 <0.8.0;
|
pragma solidity >=0.5.0 <0.8.0;
|
||||||
|
|
||||||
/// @title A simulator for trees
|
/// @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;
|
pragma solidity >=0.4.0 <0.8.0;
|
||||||
|
|
||||||
// THIS CONTRACT CONTAINS A BUG - DO NOT USE
|
// 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;
|
pragma solidity >=0.6.2 <0.8.0;
|
||||||
|
|
||||||
// THIS CONTRACT CONTAINS A BUG - DO NOT USE
|
// 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;
|
pragma solidity >=0.4.11 <0.8.0;
|
||||||
|
|
||||||
contract Fund {
|
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;
|
pragma solidity >=0.5.0 <0.8.0;
|
||||||
|
|
||||||
// THIS CONTRACT CONTAINS A BUG - DO NOT USE
|
// 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;
|
pragma solidity >=0.6.0 <0.8.0;
|
||||||
|
|
||||||
interface TxUserWallet {
|
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;
|
pragma solidity >=0.6.0 <0.8.0;
|
||||||
|
|
||||||
contract Map {
|
contract Map {
|
||||||
@ -555,6 +561,7 @@ not mean loss of proving power.
|
|||||||
|
|
||||||
::
|
::
|
||||||
|
|
||||||
|
// SPDX-License-Identifier: GPL-3.0
|
||||||
pragma solidity >=0.5.0;
|
pragma solidity >=0.5.0;
|
||||||
pragma experimental SMTChecker;
|
pragma experimental SMTChecker;
|
||||||
// This may report a warning if no SMT solver available.
|
// 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 solidity >=0.5.0;
|
||||||
pragma experimental SMTChecker;
|
pragma experimental SMTChecker;
|
||||||
// This will report a warning
|
// This will report a warning
|
||||||
|
@ -26,6 +26,7 @@ storage.
|
|||||||
|
|
||||||
::
|
::
|
||||||
|
|
||||||
|
// SPDX-License-Identifier: GPL-3.0
|
||||||
pragma solidity >=0.4.0 <0.8.0;
|
pragma solidity >=0.4.0 <0.8.0;
|
||||||
|
|
||||||
contract SimpleStorage {
|
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;
|
pragma solidity >=0.4.0 <0.8.0;
|
||||||
|
|
||||||
contract SimpleAuction {
|
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;
|
pragma solidity >=0.4.22 <0.8.0;
|
||||||
|
|
||||||
contract Purchase {
|
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;
|
pragma solidity >=0.4.21 <0.8.0;
|
||||||
|
|
||||||
contract SimpleAuction {
|
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;
|
pragma solidity >=0.4.0 <0.8.0;
|
||||||
|
|
||||||
contract Ballot {
|
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;
|
pragma solidity >=0.4.0 <0.8.0;
|
||||||
|
|
||||||
contract Purchase {
|
contract Purchase {
|
||||||
|
@ -55,6 +55,7 @@ Surround top level declarations in solidity source with two blank lines.
|
|||||||
|
|
||||||
Yes::
|
Yes::
|
||||||
|
|
||||||
|
// SPDX-License-Identifier: GPL-3.0
|
||||||
pragma solidity >=0.4.0 <0.8.0;
|
pragma solidity >=0.4.0 <0.8.0;
|
||||||
|
|
||||||
contract A {
|
contract A {
|
||||||
@ -73,6 +74,7 @@ Yes::
|
|||||||
|
|
||||||
No::
|
No::
|
||||||
|
|
||||||
|
// SPDX-License-Identifier: GPL-3.0
|
||||||
pragma solidity >=0.4.0 <0.8.0;
|
pragma solidity >=0.4.0 <0.8.0;
|
||||||
|
|
||||||
contract A {
|
contract A {
|
||||||
@ -92,6 +94,7 @@ Blank lines may be omitted between groups of related one-liners (such as stub fu
|
|||||||
|
|
||||||
Yes::
|
Yes::
|
||||||
|
|
||||||
|
// SPDX-License-Identifier: GPL-3.0
|
||||||
pragma solidity >=0.6.0 <0.8.0;
|
pragma solidity >=0.6.0 <0.8.0;
|
||||||
|
|
||||||
abstract contract A {
|
abstract contract A {
|
||||||
@ -112,6 +115,7 @@ Yes::
|
|||||||
|
|
||||||
No::
|
No::
|
||||||
|
|
||||||
|
// SPDX-License-Identifier: GPL-3.0
|
||||||
pragma solidity >=0.6.0 <0.8.0;
|
pragma solidity >=0.6.0 <0.8.0;
|
||||||
|
|
||||||
abstract contract A {
|
abstract contract A {
|
||||||
@ -246,6 +250,7 @@ Import statements should always be placed at the top of the file.
|
|||||||
|
|
||||||
Yes::
|
Yes::
|
||||||
|
|
||||||
|
// SPDX-License-Identifier: GPL-3.0
|
||||||
pragma solidity >=0.4.0 <0.8.0;
|
pragma solidity >=0.4.0 <0.8.0;
|
||||||
|
|
||||||
import "./Owned.sol";
|
import "./Owned.sol";
|
||||||
@ -260,6 +265,7 @@ Yes::
|
|||||||
|
|
||||||
No::
|
No::
|
||||||
|
|
||||||
|
// SPDX-License-Identifier: GPL-3.0
|
||||||
pragma solidity >=0.4.0 <0.8.0;
|
pragma solidity >=0.4.0 <0.8.0;
|
||||||
|
|
||||||
contract A {
|
contract A {
|
||||||
@ -293,6 +299,7 @@ Within a grouping, place the ``view`` and ``pure`` functions last.
|
|||||||
|
|
||||||
Yes::
|
Yes::
|
||||||
|
|
||||||
|
// SPDX-License-Identifier: GPL-3.0
|
||||||
pragma solidity >=0.6.0 <0.8.0;
|
pragma solidity >=0.6.0 <0.8.0;
|
||||||
|
|
||||||
contract A {
|
contract A {
|
||||||
@ -329,6 +336,7 @@ Yes::
|
|||||||
|
|
||||||
No::
|
No::
|
||||||
|
|
||||||
|
// SPDX-License-Identifier: GPL-3.0
|
||||||
pragma solidity >=0.6.0 <0.8.0;
|
pragma solidity >=0.6.0 <0.8.0;
|
||||||
|
|
||||||
contract A {
|
contract A {
|
||||||
@ -436,6 +444,7 @@ should:
|
|||||||
|
|
||||||
Yes::
|
Yes::
|
||||||
|
|
||||||
|
// SPDX-License-Identifier: GPL-3.0
|
||||||
pragma solidity >=0.4.0 <0.8.0;
|
pragma solidity >=0.4.0 <0.8.0;
|
||||||
|
|
||||||
contract Coin {
|
contract Coin {
|
||||||
@ -447,6 +456,7 @@ Yes::
|
|||||||
|
|
||||||
No::
|
No::
|
||||||
|
|
||||||
|
// SPDX-License-Identifier: GPL-3.0
|
||||||
pragma solidity >=0.4.0 <0.8.0;
|
pragma solidity >=0.4.0 <0.8.0;
|
||||||
|
|
||||||
contract Coin
|
contract Coin
|
||||||
@ -747,6 +757,7 @@ manner as modifiers if the function declaration is long or hard to read.
|
|||||||
|
|
||||||
Yes::
|
Yes::
|
||||||
|
|
||||||
|
// SPDX-License-Identifier: GPL-3.0
|
||||||
pragma solidity >=0.4.22 <0.8.0;
|
pragma solidity >=0.4.22 <0.8.0;
|
||||||
|
|
||||||
// Base contracts just to make this compile
|
// Base contracts just to make this compile
|
||||||
@ -779,6 +790,7 @@ Yes::
|
|||||||
|
|
||||||
No::
|
No::
|
||||||
|
|
||||||
|
// SPDX-License-Identifier: GPL-3.0
|
||||||
pragma solidity >=0.4.22 <0.8.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::
|
Yes::
|
||||||
|
|
||||||
|
// SPDX-License-Identifier: GPL-3.0
|
||||||
pragma solidity >=0.4.22 <0.8.0;
|
pragma solidity >=0.4.22 <0.8.0;
|
||||||
|
|
||||||
|
|
||||||
@ -1025,6 +1038,7 @@ Yes::
|
|||||||
|
|
||||||
and in ``Congress.sol``::
|
and in ``Congress.sol``::
|
||||||
|
|
||||||
|
// SPDX-License-Identifier: GPL-3.0
|
||||||
pragma solidity >=0.4.0 <0.8.0;
|
pragma solidity >=0.4.0 <0.8.0;
|
||||||
|
|
||||||
import "./Owned.sol";
|
import "./Owned.sol";
|
||||||
@ -1036,6 +1050,7 @@ and in ``Congress.sol``::
|
|||||||
|
|
||||||
No::
|
No::
|
||||||
|
|
||||||
|
// SPDX-License-Identifier: GPL-3.0
|
||||||
pragma solidity >=0.4.22 <0.8.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
|
For example, the contract from `a simple smart contract <simple-smart-contract>`_ with the comments
|
||||||
added looks like the one below::
|
added looks like the one below::
|
||||||
|
|
||||||
|
// SPDX-License-Identifier: GPL-3.0
|
||||||
pragma solidity >=0.4.16 <0.8.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;
|
pragma solidity >=0.4.0 <0.8.0;
|
||||||
|
|
||||||
contract MappingExample {
|
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;
|
pragma solidity >=0.4.22 <0.8.0;
|
||||||
|
|
||||||
contract MappingExample {
|
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;
|
pragma solidity >=0.6.0 <0.8.0;
|
||||||
|
|
||||||
struct IndexValue { uint keyIndex; uint value; }
|
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;
|
pragma solidity >=0.4.0 <0.8.0;
|
||||||
|
|
||||||
contract DeleteExample {
|
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;
|
pragma solidity >=0.5.0 <0.8.0;
|
||||||
|
|
||||||
contract C {
|
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;
|
pragma solidity >=0.4.16 <0.8.0;
|
||||||
|
|
||||||
contract C {
|
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;
|
pragma solidity >=0.4.16 <0.8.0;
|
||||||
|
|
||||||
contract C {
|
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;
|
pragma solidity >=0.4.0 <0.8.0;
|
||||||
|
|
||||||
// This will not compile.
|
// This will not compile.
|
||||||
@ -274,6 +278,7 @@ Array Members
|
|||||||
|
|
||||||
::
|
::
|
||||||
|
|
||||||
|
// SPDX-License-Identifier: GPL-3.0
|
||||||
pragma solidity >=0.6.0 <0.8.0;
|
pragma solidity >=0.6.0 <0.8.0;
|
||||||
|
|
||||||
contract ArrayContract {
|
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;
|
pragma solidity >=0.6.0 <0.8.0;
|
||||||
|
|
||||||
contract Proxy {
|
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;
|
pragma solidity >=0.6.0 <0.8.0;
|
||||||
|
|
||||||
// Defines a new type with two fields.
|
// 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;
|
pragma solidity >=0.4.16 <0.8.0;
|
||||||
|
|
||||||
contract test {
|
contract test {
|
||||||
@ -655,7 +656,13 @@ External (or public) functions have the following members:
|
|||||||
|
|
||||||
Example that shows how to use the members::
|
Example that shows how to use the members::
|
||||||
|
|
||||||
|
<<<<<<< HEAD
|
||||||
pragma solidity >=0.6.4 <0.8.0;
|
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 {
|
contract Example {
|
||||||
function f() public payable returns (bytes4) {
|
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::
|
Example that shows how to use internal function types::
|
||||||
|
|
||||||
|
// SPDX-License-Identifier: GPL-3.0
|
||||||
pragma solidity >=0.4.16 <0.8.0;
|
pragma solidity >=0.4.16 <0.8.0;
|
||||||
|
|
||||||
library ArrayUtils {
|
library ArrayUtils {
|
||||||
@ -727,6 +735,7 @@ Example that shows how to use internal function types::
|
|||||||
|
|
||||||
Another example that uses external function types::
|
Another example that uses external function types::
|
||||||
|
|
||||||
|
// SPDX-License-Identifier: GPL-3.0
|
||||||
pragma solidity >=0.4.22 <0.8.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
|
.. code-block:: none
|
||||||
|
|
||||||
// This will not compile after 0.5.0
|
// This will not compile after 0.5.0
|
||||||
|
// SPDX-License-Identifier: GPL-3.0
|
||||||
pragma solidity >0.4.23 <0.5.0;
|
pragma solidity >0.4.23 <0.5.0;
|
||||||
|
|
||||||
contract Updateable {
|
contract Updateable {
|
||||||
@ -709,6 +710,7 @@ The command above applies all changes as shown below. Please review them careful
|
|||||||
|
|
||||||
.. code-block:: solidity
|
.. code-block:: solidity
|
||||||
|
|
||||||
|
// SPDX-License-Identifier: GPL-3.0
|
||||||
pragma solidity >=0.6.0 <0.8.0;
|
pragma solidity >=0.6.0 <0.8.0;
|
||||||
|
|
||||||
abstract contract Updateable {
|
abstract contract Updateable {
|
||||||
|
@ -134,6 +134,12 @@ public:
|
|||||||
return m_errorCount > 0;
|
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.
|
// @returns true if the maximum error count has been reached.
|
||||||
bool hasExcessiveErrors() const;
|
bool hasExcessiveErrors() const;
|
||||||
|
|
||||||
|
@ -148,6 +148,11 @@ void ParserBase::parserWarning(ErrorId _error, string const& _description)
|
|||||||
m_errorReporter.warning(_error, currentLocation(), _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)
|
void ParserBase::parserError(ErrorId _error, SourceLocation const& _location, string const& _description)
|
||||||
{
|
{
|
||||||
m_errorReporter.parserError(_error, _location, _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
|
/// Creates a @ref ParserWarning and annotates it with the current position and the
|
||||||
/// given @a _description.
|
/// given @a _description.
|
||||||
void parserWarning(ErrorId _error, std::string const& _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
|
/// Creates a @ref ParserError and annotates it with the current position and the
|
||||||
/// given @a _description. Throws the FatalError.
|
/// 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)
|
void DeclarationTypeChecker::typeError(SourceLocation const& _location, string const& _description)
|
||||||
{
|
{
|
||||||
m_errorOccurred = true;
|
|
||||||
m_errorReporter.typeError(2311_error, _location, _description);
|
m_errorReporter.typeError(2311_error, _location, _description);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DeclarationTypeChecker::fatalTypeError(SourceLocation const& _location, string const& _description)
|
void DeclarationTypeChecker::fatalTypeError(SourceLocation const& _location, string const& _description)
|
||||||
{
|
{
|
||||||
m_errorOccurred = true;
|
|
||||||
m_errorReporter.fatalTypeError(5651_error, _location, _description);
|
m_errorReporter.fatalTypeError(5651_error, _location, _description);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DeclarationTypeChecker::fatalDeclarationError(SourceLocation const& _location, string const& _description)
|
void DeclarationTypeChecker::fatalDeclarationError(SourceLocation const& _location, string const& _description)
|
||||||
{
|
{
|
||||||
m_errorOccurred = true;
|
|
||||||
m_errorReporter.fatalDeclarationError(2046_error, _location, _description);
|
m_errorReporter.fatalDeclarationError(2046_error, _location, _description);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DeclarationTypeChecker::check(ASTNode const& _node)
|
bool DeclarationTypeChecker::check(ASTNode const& _node)
|
||||||
{
|
{
|
||||||
|
unsigned errorCount = m_errorReporter.errorCount();
|
||||||
_node.accept(*this);
|
_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);
|
void fatalDeclarationError(langutil::SourceLocation const& _location, std::string const& _description);
|
||||||
|
|
||||||
langutil::ErrorReporter& m_errorReporter;
|
langutil::ErrorReporter& m_errorReporter;
|
||||||
bool m_errorOccurred = false;
|
|
||||||
langutil::EVMVersion m_evmVersion;
|
langutil::EVMVersion m_evmVersion;
|
||||||
bool m_insideFunctionType = false;
|
bool m_insideFunctionType = false;
|
||||||
bool m_recursiveStructSeen = false;
|
bool m_recursiveStructSeen = false;
|
||||||
|
@ -2866,6 +2866,8 @@ bool TypeChecker::visit(IndexRangeAccess const& _access)
|
|||||||
|
|
||||||
if (arrayType->location() != DataLocation::CallData || !arrayType->isDynamicallySized())
|
if (arrayType->location() != DataLocation::CallData || !arrayType->isDynamicallySized())
|
||||||
m_errorReporter.typeError(1227_error, _access.location(), "Index range access is only supported for dynamic calldata arrays.");
|
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().type = TypeProvider::arraySlice(*arrayType);
|
||||||
_access.annotation().isLValue = isLValue;
|
_access.annotation().isLValue = isLValue;
|
||||||
_access.annotation().isPure = isPure;
|
_access.annotation().isPure = isPure;
|
||||||
|
@ -156,19 +156,26 @@ std::vector<T const*> ASTNode::filteredNodes(std::vector<ASTPointer<ASTNode>> co
|
|||||||
class SourceUnit: public ASTNode
|
class SourceUnit: public ASTNode
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
SourceUnit(int64_t _id, SourceLocation const& _location, std::vector<ASTPointer<ASTNode>> _nodes):
|
SourceUnit(
|
||||||
ASTNode(_id, _location), m_nodes(std::move(_nodes)) {}
|
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(ASTVisitor& _visitor) override;
|
||||||
void accept(ASTConstVisitor& _visitor) const override;
|
void accept(ASTConstVisitor& _visitor) const override;
|
||||||
SourceUnitAnnotation& annotation() 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; }
|
std::vector<ASTPointer<ASTNode>> nodes() const { return m_nodes; }
|
||||||
|
|
||||||
/// @returns a set of referenced SourceUnits. Recursively if @a _recurse is true.
|
/// @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;
|
std::set<SourceUnit const*> referencedSourceUnits(bool _recurse = false, std::set<SourceUnit const*> _skipList = std::set<SourceUnit const*>()) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
std::optional<std::string> m_licenseString;
|
||||||
std::vector<ASTPointer<ASTNode>> m_nodes;
|
std::vector<ASTPointer<ASTNode>> m_nodes;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -225,6 +225,7 @@ bool ASTJsonConverter::visit(SourceUnit const& _node)
|
|||||||
{
|
{
|
||||||
make_pair("absolutePath", _node.annotation().path),
|
make_pair("absolutePath", _node.annotation().path),
|
||||||
make_pair("exportedSymbols", move(exportedSymbols)),
|
make_pair("exportedSymbols", move(exportedSymbols)),
|
||||||
|
make_pair("license", _node.licenseString() ? Json::Value(*_node.licenseString()) : Json::nullValue),
|
||||||
make_pair("nodes", toJson(_node.nodes()))
|
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)
|
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;
|
vector<ASTPointer<ASTNode>> nodes;
|
||||||
for (auto& child: member(_node, "nodes"))
|
for (auto& child: member(_node, "nodes"))
|
||||||
nodes.emplace_back(convertJsonToASTNode(child));
|
nodes.emplace_back(convertJsonToASTNode(child));
|
||||||
ASTPointer<SourceUnit> tmp = createASTNode<SourceUnit>(_node, nodes);
|
|
||||||
|
ASTPointer<SourceUnit> tmp = createASTNode<SourceUnit>(_node, license, nodes);
|
||||||
tmp->annotation().path = _srcName;
|
tmp->annotation().path = _srcName;
|
||||||
return tmp;
|
return tmp;
|
||||||
}
|
}
|
||||||
|
@ -330,7 +330,7 @@ TypePointer Type::fullEncodingType(bool _inLibraryCall, bool _encoderV2, bool) c
|
|||||||
// Structs are fine in the following circumstances:
|
// Structs are fine in the following circumstances:
|
||||||
// - ABIv2 or,
|
// - ABIv2 or,
|
||||||
// - storage struct for a library
|
// - storage struct for a library
|
||||||
if (_inLibraryCall && encodingType->dataStoredIn(DataLocation::Storage))
|
if (_inLibraryCall && encodingType && encodingType->dataStoredIn(DataLocation::Storage))
|
||||||
return encodingType;
|
return encodingType;
|
||||||
TypePointer baseType = encodingType;
|
TypePointer baseType = encodingType;
|
||||||
while (auto const* arrayType = dynamic_cast<ArrayType const*>(baseType))
|
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))
|
else if (dynamic_cast<FixedPointType const*>(_other))
|
||||||
return nullptr;
|
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;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1964,6 +1971,19 @@ string ArraySliceType::toString(bool _short) const
|
|||||||
return m_arrayType.toString(_short) + " slice";
|
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
|
std::vector<std::tuple<std::string, TypePointer>> ArraySliceType::makeStackItems() const
|
||||||
{
|
{
|
||||||
return {{"offset", TypeProvider::uint256()}, {"length", TypeProvider::uint256()}};
|
return {{"offset", TypeProvider::uint256()}, {"length", TypeProvider::uint256()}};
|
||||||
|
@ -831,6 +831,7 @@ public:
|
|||||||
bool isDynamicallyEncoded() const override { return true; }
|
bool isDynamicallyEncoded() const override { return true; }
|
||||||
bool canLiveOutsideStorage() const override { return m_arrayType.canLiveOutsideStorage(); }
|
bool canLiveOutsideStorage() const override { return m_arrayType.canLiveOutsideStorage(); }
|
||||||
std::string toString(bool _short) const override;
|
std::string toString(bool _short) const override;
|
||||||
|
TypePointer mobileType() const override;
|
||||||
|
|
||||||
BoolResult validForLocation(DataLocation _loc) const override { return m_arrayType.validForLocation(_loc); }
|
BoolResult validForLocation(DataLocation _loc) const override { return m_arrayType.validForLocation(_loc); }
|
||||||
|
|
||||||
|
@ -279,31 +279,47 @@ string ABIFunctions::abiEncodingFunction(
|
|||||||
return abiEncodingFunctionStringLiteral(_from, to, _options);
|
return abiEncodingFunctionStringLiteral(_from, to, _options);
|
||||||
else if (auto toArray = dynamic_cast<ArrayType const*>(&to))
|
else if (auto toArray = dynamic_cast<ArrayType const*>(&to))
|
||||||
{
|
{
|
||||||
solAssert(_from.category() == Type::Category::Array, "");
|
ArrayType const* fromArray = nullptr;
|
||||||
solAssert(to.dataStoredIn(DataLocation::Memory), "");
|
switch (_from.category())
|
||||||
ArrayType const& fromArray = dynamic_cast<ArrayType const&>(_from);
|
{
|
||||||
|
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:
|
case DataLocation::CallData:
|
||||||
if (
|
if (
|
||||||
fromArray.isByteArray() ||
|
fromArray->isByteArray() ||
|
||||||
*fromArray.baseType() == *TypeProvider::uint256() ||
|
*fromArray->baseType() == *TypeProvider::uint256() ||
|
||||||
*fromArray.baseType() == FixedBytesType(32)
|
*fromArray->baseType() == FixedBytesType(32)
|
||||||
)
|
)
|
||||||
return abiEncodingFunctionCalldataArrayWithoutCleanup(fromArray, *toArray, _options);
|
return abiEncodingFunctionCalldataArrayWithoutCleanup(*fromArray, *toArray, _options);
|
||||||
else
|
else
|
||||||
return abiEncodingFunctionSimpleArray(fromArray, *toArray, _options);
|
return abiEncodingFunctionSimpleArray(*fromArray, *toArray, _options);
|
||||||
case DataLocation::Memory:
|
case DataLocation::Memory:
|
||||||
if (fromArray.isByteArray())
|
if (fromArray->isByteArray())
|
||||||
return abiEncodingFunctionMemoryByteArray(fromArray, *toArray, _options);
|
return abiEncodingFunctionMemoryByteArray(*fromArray, *toArray, _options);
|
||||||
else
|
else
|
||||||
return abiEncodingFunctionSimpleArray(fromArray, *toArray, _options);
|
return abiEncodingFunctionSimpleArray(*fromArray, *toArray, _options);
|
||||||
case DataLocation::Storage:
|
case DataLocation::Storage:
|
||||||
if (fromArray.baseType()->storageBytes() <= 16)
|
if (fromArray->baseType()->storageBytes() <= 16)
|
||||||
return abiEncodingFunctionCompactStorageArray(fromArray, *toArray, _options);
|
return abiEncodingFunctionCompactStorageArray(*fromArray, *toArray, _options);
|
||||||
else
|
else
|
||||||
return abiEncodingFunctionSimpleArray(fromArray, *toArray, _options);
|
return abiEncodingFunctionSimpleArray(*fromArray, *toArray, _options);
|
||||||
default:
|
default:
|
||||||
solAssert(false, "");
|
solAssert(false, "");
|
||||||
}
|
}
|
||||||
|
@ -480,6 +480,16 @@ void CompilerUtils::encodeToMemory(
|
|||||||
convertType(*_givenTypes[i], *targetType, true);
|
convertType(*_givenTypes[i], *targetType, true);
|
||||||
if (auto arrayType = dynamic_cast<ArrayType const*>(type))
|
if (auto arrayType = dynamic_cast<ArrayType const*>(type))
|
||||||
ArrayUtils(m_context).copyArrayToMemory(*arrayType, _padToWordBoundaries);
|
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
|
else
|
||||||
storeInMemoryDynamic(*type, _padToWordBoundaries);
|
storeInMemoryDynamic(*type, _padToWordBoundaries);
|
||||||
}
|
}
|
||||||
@ -516,22 +526,39 @@ void CompilerUtils::encodeToMemory(
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
solAssert(_givenTypes[i]->category() == Type::Category::Array, "Unknown dynamic type.");
|
ArrayType const* arrayType = nullptr;
|
||||||
auto const& arrayType = dynamic_cast<ArrayType const&>(*_givenTypes[i]);
|
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
|
// now copy the array
|
||||||
copyToStackTop(argSize - stackPos + dynPointers + 2, arrayType.sizeOnStack());
|
copyToStackTop(argSize - stackPos + dynPointers + 2, arrayType->sizeOnStack());
|
||||||
// stack: ... <end_of_mem> <value...>
|
// stack: ... <end_of_mem> <value...>
|
||||||
// copy length to memory
|
// copy length to memory
|
||||||
m_context << dupInstruction(1 + arrayType.sizeOnStack());
|
m_context << dupInstruction(1 + arrayType->sizeOnStack());
|
||||||
ArrayUtils(m_context).retrieveLength(arrayType, 1);
|
ArrayUtils(m_context).retrieveLength(*arrayType, 1);
|
||||||
// stack: ... <end_of_mem> <value...> <end_of_mem'> <length>
|
// stack: ... <end_of_mem> <value...> <end_of_mem'> <length>
|
||||||
storeInMemoryDynamic(*TypeProvider::uint256(), true);
|
storeInMemoryDynamic(*TypeProvider::uint256(), true);
|
||||||
// stack: ... <end_of_mem> <value...> <end_of_mem''>
|
// stack: ... <end_of_mem> <value...> <end_of_mem''>
|
||||||
// copy the new memory pointer
|
// 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...>
|
// stack: ... <end_of_mem''> <value...>
|
||||||
// copy data part
|
// copy data part
|
||||||
ArrayUtils(m_context).copyArrayToMemory(arrayType, _padToWordBoundaries);
|
ArrayUtils(m_context).copyArrayToMemory(*arrayType, _padToWordBoundaries);
|
||||||
// stack: ... <end_of_mem'''>
|
// stack: ... <end_of_mem'''>
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -990,7 +1017,8 @@ void CompilerUtils::convertType(
|
|||||||
solAssert(_targetType == typeOnStack.arrayType(), "");
|
solAssert(_targetType == typeOnStack.arrayType(), "");
|
||||||
solUnimplementedAssert(
|
solUnimplementedAssert(
|
||||||
typeOnStack.arrayType().location() == DataLocation::CallData &&
|
typeOnStack.arrayType().location() == DataLocation::CallData &&
|
||||||
typeOnStack.arrayType().isDynamicallySized(),
|
typeOnStack.arrayType().isDynamicallySized() &&
|
||||||
|
!typeOnStack.arrayType().baseType()->isDynamicallyEncoded(),
|
||||||
""
|
""
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
|
@ -1769,7 +1769,12 @@ bool ExpressionCompiler::visit(IndexAccess const& _indexAccess)
|
|||||||
case Type::Category::ArraySlice:
|
case Type::Category::ArraySlice:
|
||||||
{
|
{
|
||||||
auto const& arrayType = dynamic_cast<ArraySliceType const&>(baseType).arrayType();
|
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.");
|
solAssert(_indexAccess.indexExpression(), "Index expression expected.");
|
||||||
|
|
||||||
acceptAndConvert(*_indexAccess.indexExpression(), *TypeProvider::uint256(), true);
|
acceptAndConvert(*_indexAccess.indexExpression(), *TypeProvider::uint256(), true);
|
||||||
@ -1852,7 +1857,12 @@ bool ExpressionCompiler::visit(IndexRangeAccess const& _indexAccess)
|
|||||||
arrayType = &sliceType->arrayType();
|
arrayType = &sliceType->arrayType();
|
||||||
|
|
||||||
solAssert(arrayType, "");
|
solAssert(arrayType, "");
|
||||||
solUnimplementedAssert(arrayType->location() == DataLocation::CallData && arrayType->isDynamicallySized(), "");
|
solUnimplementedAssert(
|
||||||
|
arrayType->location() == DataLocation::CallData &&
|
||||||
|
arrayType->isDynamicallySized() &&
|
||||||
|
!arrayType->baseType()->isDynamicallyEncoded(),
|
||||||
|
""
|
||||||
|
);
|
||||||
|
|
||||||
if (_indexAccess.startExpression())
|
if (_indexAccess.startExpression())
|
||||||
acceptAndConvert(*_indexAccess.startExpression(), *TypeProvider::uint256());
|
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);
|
ArraySliceType const& fromType = dynamic_cast<ArraySliceType const&>(_from);
|
||||||
ArrayType const& targetType = dynamic_cast<ArrayType const&>(_to);
|
ArrayType const& targetType = dynamic_cast<ArrayType const&>(_to);
|
||||||
|
|
||||||
|
solAssert(!fromType.arrayType().baseType()->isDynamicallyEncoded(), "");
|
||||||
solAssert(
|
solAssert(
|
||||||
*fromType.arrayType().baseType() == *targetType.baseType(),
|
*fromType.arrayType().baseType() == *targetType.baseType(),
|
||||||
"Converting arrays of different type is not possible"
|
"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");
|
solAssert(s.second.scanner, "Scanner not available");
|
||||||
meta["sources"][s.first]["keccak256"] = "0x" + toHex(s.second.keccak256().asBytes());
|
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)
|
if (m_metadataLiteralSources)
|
||||||
meta["sources"][s.first]["content"] = s.second.scanner->source();
|
meta["sources"][s.first]["content"] = s.second.scanner->source();
|
||||||
else
|
else
|
||||||
|
@ -30,8 +30,11 @@
|
|||||||
#include <liblangutil/SemVerHandler.h>
|
#include <liblangutil/SemVerHandler.h>
|
||||||
#include <liblangutil/SourceLocation.h>
|
#include <liblangutil/SourceLocation.h>
|
||||||
#include <libyul/backends/evm/EVMDialect.h>
|
#include <libyul/backends/evm/EVMDialect.h>
|
||||||
|
#include <boost/algorithm/string/trim.hpp>
|
||||||
|
#include <boost/algorithm/string/replace.hpp>
|
||||||
#include <cctype>
|
#include <cctype>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include <regex>
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
using namespace solidity::langutil;
|
using namespace solidity::langutil;
|
||||||
@ -79,6 +82,7 @@ ASTPointer<SourceUnit> Parser::parse(shared_ptr<Scanner> const& _scanner)
|
|||||||
m_recursionDepth = 0;
|
m_recursionDepth = 0;
|
||||||
m_scanner = _scanner;
|
m_scanner = _scanner;
|
||||||
ASTNodeFactory nodeFactory(*this);
|
ASTNodeFactory nodeFactory(*this);
|
||||||
|
|
||||||
vector<ASTPointer<ASTNode>> nodes;
|
vector<ASTPointer<ASTNode>> nodes;
|
||||||
while (m_scanner->currentToken() != Token::EOS)
|
while (m_scanner->currentToken() != Token::EOS)
|
||||||
{
|
{
|
||||||
@ -107,7 +111,7 @@ ASTPointer<SourceUnit> Parser::parse(shared_ptr<Scanner> const& _scanner)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
solAssert(m_recursionDepth == 0, "");
|
solAssert(m_recursionDepth == 0, "");
|
||||||
return nodeFactory.createNode<SourceUnit>(nodes);
|
return nodeFactory.createNode<SourceUnit>(findLicenseString(nodes), nodes);
|
||||||
}
|
}
|
||||||
catch (FatalError const&)
|
catch (FatalError const&)
|
||||||
{
|
{
|
||||||
@ -1981,6 +1985,60 @@ pair<vector<ASTPointer<Expression>>, vector<ASTPointer<ASTString>>> Parser::pars
|
|||||||
return ret;
|
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
|
Parser::LookAheadInfo Parser::peekStatementType() const
|
||||||
{
|
{
|
||||||
// Distinguish between variable declaration (and potentially assignment) and expression statement
|
// Distinguish between variable declaration (and potentially assignment) and expression statement
|
||||||
|
@ -175,6 +175,8 @@ private:
|
|||||||
bool empty() const;
|
bool empty() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
std::optional<std::string> findLicenseString(std::vector<ASTPointer<ASTNode>> const& _nodes);
|
||||||
|
|
||||||
/// Returns the next AST node ID
|
/// Returns the next AST node ID
|
||||||
int64_t nextID() { return ++m_currentNodeID; }
|
int64_t nextID() { return ++m_currentNodeID; }
|
||||||
|
|
||||||
|
@ -188,5 +188,39 @@ string solidity::util::formatAsStringOrNumber(string const& _value)
|
|||||||
if (c <= 0x1f || c >= 0x7f || c == '"')
|
if (c <= 0x1f || c >= 0x7f || c == '"')
|
||||||
return "0x" + h256(_value, h256::AlignLeft).hex();
|
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.
|
/// _value cannot be longer than 32 bytes.
|
||||||
std::string formatAsStringOrNumber(std::string const& _value);
|
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>
|
template<typename Container, typename Compare>
|
||||||
bool containerEqual(Container const& _lhs, Container const& _rhs, Compare&& _compare)
|
bool containerEqual(Container const& _lhs, Container const& _rhs, Compare&& _compare)
|
||||||
{
|
{
|
||||||
|
@ -55,33 +55,7 @@ string AsmPrinter::operator()(Literal const& _literal) const
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
string out;
|
return escapeAndQuoteString(_literal.value.str()) + appendTypeName(_literal.type);
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
string AsmPrinter::operator()(Identifier const& _identifier) const
|
string AsmPrinter::operator()(Identifier const& _identifier) const
|
||||||
|
@ -358,13 +358,13 @@ bytes BinaryTransform::operator()(If const& _if)
|
|||||||
toBytes(Opcode::If) +
|
toBytes(Opcode::If) +
|
||||||
toBytes(ValueType::Void);
|
toBytes(ValueType::Void);
|
||||||
|
|
||||||
m_labels.push({});
|
m_labels.emplace_back();
|
||||||
|
|
||||||
result += visit(_if.statements);
|
result += visit(_if.statements);
|
||||||
if (_if.elseStatements)
|
if (_if.elseStatements)
|
||||||
result += toBytes(Opcode::Else) + visit(*_if.elseStatements);
|
result += toBytes(Opcode::Else) + visit(*_if.elseStatements);
|
||||||
|
|
||||||
m_labels.pop();
|
m_labels.pop_back();
|
||||||
|
|
||||||
result += toBytes(Opcode::End);
|
result += toBytes(Opcode::End);
|
||||||
return result;
|
return result;
|
||||||
@ -374,26 +374,24 @@ bytes BinaryTransform::operator()(Loop const& _loop)
|
|||||||
{
|
{
|
||||||
bytes result = toBytes(Opcode::Loop) + toBytes(ValueType::Void);
|
bytes result = toBytes(Opcode::Loop) + toBytes(ValueType::Void);
|
||||||
|
|
||||||
m_labels.push(_loop.labelName);
|
m_labels.emplace_back(_loop.labelName);
|
||||||
result += visit(_loop.statements);
|
result += visit(_loop.statements);
|
||||||
m_labels.pop();
|
m_labels.pop_back();
|
||||||
|
|
||||||
result += toBytes(Opcode::End);
|
result += toBytes(Opcode::End);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
bytes BinaryTransform::operator()(Break const&)
|
bytes BinaryTransform::operator()(Break const& _break)
|
||||||
{
|
{
|
||||||
yulAssert(false, "br not yet implemented.");
|
return toBytes(Opcode::Br) + encodeLabelIdx(_break.label.name);
|
||||||
// TODO the index is just the nesting depth.
|
|
||||||
return {};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bytes BinaryTransform::operator()(BreakIf const&)
|
bytes BinaryTransform::operator()(BreakIf const& _breakIf)
|
||||||
{
|
{
|
||||||
yulAssert(false, "br_if not yet implemented.");
|
bytes result = std::visit(*this, *_breakIf.condition);
|
||||||
// TODO the index is just the nesting depth.
|
result += toBytes(Opcode::BrIf) + encodeLabelIdx(_breakIf.label.name);
|
||||||
return {};
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
bytes BinaryTransform::operator()(Return const&)
|
bytes BinaryTransform::operator()(Return const&)
|
||||||
@ -403,11 +401,14 @@ bytes BinaryTransform::operator()(Return const&)
|
|||||||
|
|
||||||
bytes BinaryTransform::operator()(Block const& _block)
|
bytes BinaryTransform::operator()(Block const& _block)
|
||||||
{
|
{
|
||||||
return
|
m_labels.emplace_back(_block.labelName);
|
||||||
|
bytes result =
|
||||||
toBytes(Opcode::Block) +
|
toBytes(Opcode::Block) +
|
||||||
toBytes(ValueType::Void) +
|
toBytes(ValueType::Void) +
|
||||||
visit(_block.statements) +
|
visit(_block.statements) +
|
||||||
toBytes(Opcode::End);
|
toBytes(Opcode::End);
|
||||||
|
m_labels.pop_back();
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
bytes BinaryTransform::operator()(FunctionDefinition const& _function)
|
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)
|
for (size_t i = 0; i < _function.locals.size(); ++i)
|
||||||
m_locals[_function.locals[i].variableName] = varIdx++;
|
m_locals[_function.locals[i].variableName] = varIdx++;
|
||||||
|
|
||||||
|
yulAssert(m_labels.empty(), "Stray labels.");
|
||||||
|
|
||||||
ret += visit(_function.body);
|
ret += visit(_function.body);
|
||||||
ret += toBytes(Opcode::End);
|
ret += toBytes(Opcode::End);
|
||||||
|
|
||||||
|
yulAssert(m_labels.empty(), "Stray labels.");
|
||||||
|
|
||||||
return prefixSize(std::move(ret));
|
return prefixSize(std::move(ret));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -581,6 +586,18 @@ bytes BinaryTransform::visitReversed(vector<Expression> const& _expressions)
|
|||||||
return result;
|
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)
|
bytes BinaryTransform::encodeName(std::string const& _name)
|
||||||
{
|
{
|
||||||
// UTF-8 is allowed here by the Wasm spec, but since all names here should stem from
|
// 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 visit(std::vector<wasm::Expression> const& _expressions);
|
||||||
bytes visitReversed(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);
|
static bytes encodeName(std::string const& _name);
|
||||||
|
|
||||||
std::map<std::string, size_t> m_locals;
|
std::map<std::string, size_t> m_locals;
|
||||||
std::map<std::string, size_t> m_globals;
|
std::map<std::string, size_t> m_globals;
|
||||||
std::map<std::string, size_t> m_functions;
|
std::map<std::string, size_t> m_functions;
|
||||||
std::map<std::string, size_t> m_functionTypes;
|
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;
|
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)
|
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)
|
string TextTransform::operator()(wasm::BreakIf const& _break)
|
||||||
|
@ -52,7 +52,7 @@ def extract_docs_cases(path):
|
|||||||
if inside:
|
if inside:
|
||||||
extractedLines[-1] += l + '\n'
|
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.
|
# Filter all tests that do not contain Solidity or are intended incorrectly.
|
||||||
for lines in extractedLines:
|
for lines in extractedLines:
|
||||||
|
@ -81,12 +81,14 @@ EVMHost::EVMHost(langutil::EVMVersion _evmVersion, evmc::VM& _vm):
|
|||||||
m_evmRevision = EVMC_BYZANTIUM;
|
m_evmRevision = EVMC_BYZANTIUM;
|
||||||
else if (_evmVersion == langutil::EVMVersion::constantinople())
|
else if (_evmVersion == langutil::EVMVersion::constantinople())
|
||||||
m_evmRevision = EVMC_CONSTANTINOPLE;
|
m_evmRevision = EVMC_CONSTANTINOPLE;
|
||||||
|
else if (_evmVersion == langutil::EVMVersion::petersburg())
|
||||||
|
m_evmRevision = EVMC_PETERSBURG;
|
||||||
else if (_evmVersion == langutil::EVMVersion::istanbul())
|
else if (_evmVersion == langutil::EVMVersion::istanbul())
|
||||||
m_evmRevision = EVMC_ISTANBUL;
|
m_evmRevision = EVMC_ISTANBUL;
|
||||||
else if (_evmVersion == langutil::EVMVersion::berlin())
|
else if (_evmVersion == langutil::EVMVersion::berlin())
|
||||||
assertThrow(false, Exception, "Berlin is not supported yet.");
|
m_evmRevision = EVMC_BERLIN;
|
||||||
else //if (_evmVersion == langutil::EVMVersion::petersburg())
|
else
|
||||||
m_evmRevision = EVMC_PETERSBURG;
|
assertThrow(false, Exception, "Unsupported EVM version");
|
||||||
|
|
||||||
// Mark all precompiled contracts as existing. Existing here means to have a balance (as per EIP-161).
|
// 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.
|
// NOTE: keep this in sync with `EVMHost::call` below.
|
||||||
@ -99,17 +101,16 @@ EVMHost::EVMHost(langutil::EVMVersion _evmVersion, evmc::VM& _vm):
|
|||||||
evmc::address address{};
|
evmc::address address{};
|
||||||
address.bytes[19] = precompiledAddress;
|
address.bytes[19] = precompiledAddress;
|
||||||
// 1wei
|
// 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 = evmc::uint256be{200000000};
|
||||||
tx_context.block_difficulty = convertToEVMC(u256("200000000"));
|
|
||||||
tx_context.block_gas_limit = 20000000;
|
tx_context.block_gas_limit = 20000000;
|
||||||
tx_context.block_coinbase = 0x7878787878787878787878787878787878787878_address;
|
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;
|
tx_context.tx_origin = 0x9292929292929292929292929292929292929292_address;
|
||||||
// Mainnet according to EIP-155
|
// 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
|
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 solidity >=0.0;
|
||||||
pragma experimental ABIEncoderV2;
|
pragma experimental ABIEncoderV2;
|
||||||
|
|
||||||
contract C {
|
contract C {
|
||||||
struct S { uint x; }
|
struct S { uint x; }
|
||||||
function f(S memory) public pure {
|
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;
|
pragma solidity >=0.6.0;
|
||||||
|
|
||||||
contract C {
|
contract C {
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
Warning: Unused local variable.
|
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;
|
pragma solidity >=0.6.0;
|
||||||
|
|
||||||
contract C {}
|
contract C {}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
// checks that error messages around power-or-10 lines are formatted correctly
|
// 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;
|
pragma solidity >=0.0;
|
||||||
|
|
||||||
contract C
|
contract C
|
||||||
|
@ -1,69 +1,69 @@
|
|||||||
|
|
||||||
======= optimizer_user_yul/input.sol:C =======
|
======= optimizer_user_yul/input.sol:C =======
|
||||||
EVM assembly:
|
EVM assembly:
|
||||||
/* "optimizer_user_yul/input.sol":24:489 contract C... */
|
/* "optimizer_user_yul/input.sol":60:525 contract C... */
|
||||||
mstore(0x40, 0x80)
|
mstore(0x40, 0x80)
|
||||||
/* "optimizer_user_yul/input.sol":72:77 int a */
|
/* "optimizer_user_yul/input.sol":108:113 int a */
|
||||||
0x00
|
0x00
|
||||||
/* "optimizer_user_yul/input.sol":152:161 let x,y,z */
|
/* "optimizer_user_yul/input.sol":188:197 let x,y,z */
|
||||||
dup1
|
dup1
|
||||||
0x00
|
0x00
|
||||||
dup1
|
dup1
|
||||||
/* "optimizer_user_yul/input.sol":176:177 1 */
|
/* "optimizer_user_yul/input.sol":212:213 1 */
|
||||||
0x01
|
0x01
|
||||||
/* "optimizer_user_yul/input.sol":173:174 0 */
|
/* "optimizer_user_yul/input.sol":209:210 0 */
|
||||||
0x00
|
0x00
|
||||||
/* "optimizer_user_yul/input.sol":166:178 sstore(0, 1) */
|
/* "optimizer_user_yul/input.sol":202:214 sstore(0, 1) */
|
||||||
sstore
|
sstore
|
||||||
/* "optimizer_user_yul/input.sol":183:229 for { } sload(4) { } {... */
|
/* "optimizer_user_yul/input.sol":219:265 for { } sload(4) { } {... */
|
||||||
tag_3:
|
tag_3:
|
||||||
/* "optimizer_user_yul/input.sol":197:198 4 */
|
/* "optimizer_user_yul/input.sol":233:234 4 */
|
||||||
0x04
|
0x04
|
||||||
/* "optimizer_user_yul/input.sol":191:199 sload(4) */
|
/* "optimizer_user_yul/input.sol":227:235 sload(4) */
|
||||||
sload
|
sload
|
||||||
/* "optimizer_user_yul/input.sol":183:229 for { } sload(4) { } {... */
|
/* "optimizer_user_yul/input.sol":219:265 for { } sload(4) { } {... */
|
||||||
iszero
|
iszero
|
||||||
tag_5
|
tag_5
|
||||||
jumpi
|
jumpi
|
||||||
pop
|
pop
|
||||||
/* "optimizer_user_yul/input.sol":215:224 exp(x, y) */
|
/* "optimizer_user_yul/input.sol":251:260 exp(x, y) */
|
||||||
dup1
|
dup1
|
||||||
dup3
|
dup3
|
||||||
exp
|
exp
|
||||||
/* "optimizer_user_yul/input.sol":183:229 for { } sload(4) { } {... */
|
/* "optimizer_user_yul/input.sol":219:265 for { } sload(4) { } {... */
|
||||||
jump(tag_3)
|
jump(tag_3)
|
||||||
tag_5:
|
tag_5:
|
||||||
/* "optimizer_user_yul/input.sol":187:190 { } */
|
/* "optimizer_user_yul/input.sol":223:226 { } */
|
||||||
pop
|
pop
|
||||||
pop
|
pop
|
||||||
pop
|
pop
|
||||||
/* "optimizer_user_yul/input.sol":239:240 2 */
|
/* "optimizer_user_yul/input.sol":275:276 2 */
|
||||||
0x02
|
0x02
|
||||||
/* "optimizer_user_yul/input.sol":234:240 a := 2 */
|
/* "optimizer_user_yul/input.sol":270:276 a := 2 */
|
||||||
swap1
|
swap1
|
||||||
pop
|
pop
|
||||||
/* "optimizer_user_yul/input.sol":340:341 3 */
|
/* "optimizer_user_yul/input.sol":376:377 3 */
|
||||||
0x03
|
0x03
|
||||||
/* "optimizer_user_yul/input.sol":337:338 2 */
|
/* "optimizer_user_yul/input.sol":373:374 2 */
|
||||||
0x02
|
0x02
|
||||||
/* "optimizer_user_yul/input.sol":330:342 sstore(2, 3) */
|
/* "optimizer_user_yul/input.sol":366:378 sstore(2, 3) */
|
||||||
sstore
|
sstore
|
||||||
/* "optimizer_user_yul/input.sol":347:480 for { } sload(5) { } {... */
|
/* "optimizer_user_yul/input.sol":383:516 for { } sload(5) { } {... */
|
||||||
tag_6:
|
tag_6:
|
||||||
/* "optimizer_user_yul/input.sol":361:362 5 */
|
/* "optimizer_user_yul/input.sol":397:398 5 */
|
||||||
0x05
|
0x05
|
||||||
/* "optimizer_user_yul/input.sol":355:363 sload(5) */
|
/* "optimizer_user_yul/input.sol":391:399 sload(5) */
|
||||||
sload
|
sload
|
||||||
tag_9
|
tag_9
|
||||||
jumpi
|
jumpi
|
||||||
jump(tag_8)
|
jump(tag_8)
|
||||||
tag_9:
|
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)
|
jump(tag_6)
|
||||||
tag_8:
|
tag_8:
|
||||||
/* "optimizer_user_yul/input.sol":311:484 {... */
|
/* "optimizer_user_yul/input.sol":347:520 {... */
|
||||||
pop
|
pop
|
||||||
/* "optimizer_user_yul/input.sol":24:489 contract C... */
|
/* "optimizer_user_yul/input.sol":60:525 contract C... */
|
||||||
dataSize(sub_0)
|
dataSize(sub_0)
|
||||||
dup1
|
dup1
|
||||||
dataOffset(sub_0)
|
dataOffset(sub_0)
|
||||||
@ -74,7 +74,7 @@ tag_8:
|
|||||||
stop
|
stop
|
||||||
|
|
||||||
sub_0: assembly {
|
sub_0: assembly {
|
||||||
/* "optimizer_user_yul/input.sol":24:489 contract C... */
|
/* "optimizer_user_yul/input.sol":60:525 contract C... */
|
||||||
mstore(0x40, 0x80)
|
mstore(0x40, 0x80)
|
||||||
/* "--CODEGEN--":12:13 */
|
/* "--CODEGEN--":12:13 */
|
||||||
0x00
|
0x00
|
||||||
|
@ -2,10 +2,10 @@
|
|||||||
"language": "Solidity",
|
"language": "Solidity",
|
||||||
"sources": {
|
"sources": {
|
||||||
"a.sol": {
|
"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": {
|
"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": {
|
"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!
|
{"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":"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); } }
|
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",
|
"language": "Solidity",
|
||||||
"sources": {
|
"sources": {
|
||||||
"a.sol": {
|
"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": {
|
"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": {
|
"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!
|
{"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":"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); } }
|
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",
|
"language": "Solidity",
|
||||||
"sources": {
|
"sources": {
|
||||||
"a.sol": {
|
"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": {
|
"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": {
|
"settings": {
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{"errors":[{"component":"general","formattedMessage":"a.sol: Warning: Source file does not specify required compiler version!
|
{"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":"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); } }
|
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",
|
"language": "Solidity",
|
||||||
"sources": {
|
"sources": {
|
||||||
"a.sol": {
|
"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": {
|
"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": {
|
"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!
|
{"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":"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); } }
|
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",
|
"language": "Solidity",
|
||||||
"sources": {
|
"sources": {
|
||||||
"a.sol": {
|
"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": {
|
"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": {
|
"settings": {
|
||||||
|
@ -2,10 +2,10 @@
|
|||||||
"language": "Solidity",
|
"language": "Solidity",
|
||||||
"sources": {
|
"sources": {
|
||||||
"a.sol": {
|
"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": {
|
"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": {
|
"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!
|
{"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); } }
|
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",
|
"language": "Solidity",
|
||||||
"sources": {
|
"sources": {
|
||||||
"a.sol": {
|
"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": {
|
"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": {
|
"settings": {
|
||||||
|
@ -1,13 +1,13 @@
|
|||||||
Error: Expected primary expression.
|
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 ';'.
|
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;
|
pragma solidity >=0.0.0;
|
||||||
|
|
||||||
contract Error1 {
|
contract Error1 {
|
||||||
|
@ -12,7 +12,8 @@ JSON AST:
|
|||||||
[
|
[
|
||||||
18
|
18
|
||||||
]
|
]
|
||||||
}
|
},
|
||||||
|
"license": "GPL-3.0"
|
||||||
},
|
},
|
||||||
"children":
|
"children":
|
||||||
[
|
[
|
||||||
@ -29,7 +30,7 @@ JSON AST:
|
|||||||
},
|
},
|
||||||
"id": 1,
|
"id": 1,
|
||||||
"name": "PragmaDirective",
|
"name": "PragmaDirective",
|
||||||
"src": "0:24:0"
|
"src": "36:24:0"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"attributes":
|
"attributes":
|
||||||
@ -86,7 +87,7 @@ JSON AST:
|
|||||||
"children": [],
|
"children": [],
|
||||||
"id": 2,
|
"id": 2,
|
||||||
"name": "ParameterList",
|
"name": "ParameterList",
|
||||||
"src": "57:2:0"
|
"src": "93:2:0"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"attributes":
|
"attributes":
|
||||||
@ -99,7 +100,7 @@ JSON AST:
|
|||||||
"children": [],
|
"children": [],
|
||||||
"id": 3,
|
"id": 3,
|
||||||
"name": "ParameterList",
|
"name": "ParameterList",
|
||||||
"src": "67:0:0"
|
"src": "103:0:0"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"attributes":
|
"attributes":
|
||||||
@ -112,12 +113,12 @@ JSON AST:
|
|||||||
"children": [],
|
"children": [],
|
||||||
"id": 8,
|
"id": 8,
|
||||||
"name": "Block",
|
"name": "Block",
|
||||||
"src": "67:49:0"
|
"src": "103:49:0"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"id": 9,
|
"id": 9,
|
||||||
"name": "FunctionDefinition",
|
"name": "FunctionDefinition",
|
||||||
"src": "46:70:0"
|
"src": "82:70:0"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"attributes":
|
"attributes":
|
||||||
@ -151,7 +152,7 @@ JSON AST:
|
|||||||
"children": [],
|
"children": [],
|
||||||
"id": 10,
|
"id": 10,
|
||||||
"name": "ParameterList",
|
"name": "ParameterList",
|
||||||
"src": "382:2:0"
|
"src": "418:2:0"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"children":
|
"children":
|
||||||
@ -180,17 +181,17 @@ JSON AST:
|
|||||||
},
|
},
|
||||||
"id": 11,
|
"id": 11,
|
||||||
"name": "ElementaryTypeName",
|
"name": "ElementaryTypeName",
|
||||||
"src": "405:4:0"
|
"src": "441:4:0"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"id": 12,
|
"id": 12,
|
||||||
"name": "VariableDeclaration",
|
"name": "VariableDeclaration",
|
||||||
"src": "405:4:0"
|
"src": "441:4:0"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"id": 13,
|
"id": 13,
|
||||||
"name": "ParameterList",
|
"name": "ParameterList",
|
||||||
"src": "404:6:0"
|
"src": "440:6:0"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"children":
|
"children":
|
||||||
@ -218,30 +219,30 @@ JSON AST:
|
|||||||
},
|
},
|
||||||
"id": 14,
|
"id": 14,
|
||||||
"name": "Literal",
|
"name": "Literal",
|
||||||
"src": "424:1:0"
|
"src": "460:1:0"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"id": 15,
|
"id": 15,
|
||||||
"name": "Return",
|
"name": "Return",
|
||||||
"src": "417:8:0"
|
"src": "453:8:0"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"id": 16,
|
"id": 16,
|
||||||
"name": "Block",
|
"name": "Block",
|
||||||
"src": "411:19:0"
|
"src": "447:19:0"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"id": 17,
|
"id": 17,
|
||||||
"name": "FunctionDefinition",
|
"name": "FunctionDefinition",
|
||||||
"src": "369:61:0"
|
"src": "405:61:0"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"id": 18,
|
"id": 18,
|
||||||
"name": "ContractDefinition",
|
"name": "ContractDefinition",
|
||||||
"src": "26:406:0"
|
"src": "62:406:0"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"id": 19,
|
"id": 19,
|
||||||
"name": "SourceUnit",
|
"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.
|
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;
|
pragma 0.5.11;
|
||||||
c
|
c
|
@ -4,7 +4,7 @@
|
|||||||
{
|
{
|
||||||
"A":
|
"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":
|
"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 */ }
|
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 */ }
|
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.
|
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)
|
||||||
Note: Candidate: function require(bool, string memory)
|
Note: Candidate: function require(bool, string memory)
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
// SPDX-License-Identifier: GPL-3.0
|
||||||
pragma solidity >=0.0;
|
pragma solidity >=0.0;
|
||||||
contract C {
|
contract C {
|
||||||
function f() public pure {
|
function f() public pure {
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
{
|
{
|
||||||
"A":
|
"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":
|
"A":
|
||||||
{
|
{
|
||||||
"content": "pragma solidity >=0.0; contract C { }"
|
"content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0; contract C { }"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"settings":
|
"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 \".\";
|
pragma solidity >=0.0; import {A} from \".\";
|
||||||
^------------------^
|
^------------------^
|
||||||
","message":"Declaration \"A\" not found in \"\" (referenced as \".\").","severity":"error","type":"DeclarationError"}],"sources":{}}
|
","message":"Declaration \"A\" not found in \"\" (referenced as \".\").","severity":"error","type":"DeclarationError"}],"sources":{}}
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
"language": "Solidity",
|
"language": "Solidity",
|
||||||
"sources": {
|
"sources": {
|
||||||
"a.sol": {
|
"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": {
|
"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