mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Merge remote-tracking branch 'origin/develop' into HEAD
This commit is contained in:
@@ -82,7 +82,7 @@ BOOST_AUTO_TEST_CASE(enums)
|
||||
}
|
||||
}
|
||||
)";
|
||||
bool newDecoder = solidity::test::Options::get().useABIEncoderV2;
|
||||
bool newDecoder = solidity::test::CommonOptions::get().useABIEncoderV2;
|
||||
BOTH_ENCODERS(
|
||||
compileAndRun(sourceCode);
|
||||
ABI_CHECK(callContractFunction("f(uint8)", 0), encodeArgs(u256(0)));
|
||||
@@ -104,7 +104,7 @@ BOOST_AUTO_TEST_CASE(cleanup)
|
||||
}
|
||||
}
|
||||
)";
|
||||
bool newDecoder = solidity::test::Options::get().useABIEncoderV2;
|
||||
bool newDecoder = solidity::test::CommonOptions::get().useABIEncoderV2;
|
||||
BOTH_ENCODERS(
|
||||
compileAndRun(sourceCode);
|
||||
ABI_CHECK(
|
||||
@@ -573,7 +573,7 @@ BOOST_AUTO_TEST_CASE(validation_function_type)
|
||||
function i(function () external[] calldata a) external pure returns (uint r) { a[0]; r = 4; }
|
||||
}
|
||||
)";
|
||||
bool newDecoder = solidity::test::Options::get().useABIEncoderV2;
|
||||
bool newDecoder = solidity::test::CommonOptions::get().useABIEncoderV2;
|
||||
string validFun{"01234567890123456789abcd"};
|
||||
string invalidFun{"01234567890123456789abcdX"};
|
||||
BOTH_ENCODERS(
|
||||
@@ -950,7 +950,7 @@ BOOST_AUTO_TEST_CASE(out_of_bounds_bool_value)
|
||||
function f(bool b) public pure returns (bool) { return b; }
|
||||
}
|
||||
)";
|
||||
bool newDecoder = solidity::test::Options::get().useABIEncoderV2;
|
||||
bool newDecoder = solidity::test::CommonOptions::get().useABIEncoderV2;
|
||||
BOTH_ENCODERS(
|
||||
compileAndRun(sourceCode);
|
||||
ABI_CHECK(callContractFunction("f(bool)", true), encodeArgs(true));
|
||||
|
||||
@@ -165,7 +165,7 @@ BOOST_AUTO_TEST_CASE(memory_array_one_dim)
|
||||
}
|
||||
)";
|
||||
|
||||
if (!solidity::test::Options::get().useABIEncoderV2)
|
||||
if (!solidity::test::CommonOptions::get().useABIEncoderV2)
|
||||
{
|
||||
compileAndRun(sourceCode);
|
||||
callContractFunction("f()");
|
||||
@@ -752,7 +752,7 @@ BOOST_AUTO_TEST_CASE(struct_in_constructor_indirect)
|
||||
}
|
||||
}
|
||||
)";
|
||||
if (solidity::test::Options::get().evmVersion().supportsReturndata())
|
||||
if (solidity::test::CommonOptions::get().evmVersion().supportsReturndata())
|
||||
{
|
||||
NEW_ENCODER(
|
||||
compileAndRun(sourceCode, 0, "D");
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
|
||||
#include <test/libsolidity/ABIJsonTest.h>
|
||||
|
||||
#include <test/Options.h>
|
||||
#include <test/Common.h>
|
||||
|
||||
#include <libsolidity/interface/CompilerStack.h>
|
||||
#include <libsolutil/JSON.h>
|
||||
@@ -52,8 +52,8 @@ TestCase::TestResult ABIJsonTest::run(ostream& _stream, string const& _linePrefi
|
||||
CompilerStack compiler;
|
||||
|
||||
compiler.setSources({{"", "pragma solidity >=0.0;\n" + m_source}});
|
||||
compiler.setEVMVersion(solidity::test::Options::get().evmVersion());
|
||||
compiler.setOptimiserSettings(solidity::test::Options::get().optimize);
|
||||
compiler.setEVMVersion(solidity::test::CommonOptions::get().evmVersion());
|
||||
compiler.setOptimiserSettings(solidity::test::CommonOptions::get().optimize);
|
||||
if (!compiler.parseAndAnalyze())
|
||||
BOOST_THROW_EXCEPTION(runtime_error("Parsing contract failed"));
|
||||
|
||||
|
||||
@@ -282,7 +282,7 @@
|
||||
"name": "this",
|
||||
"nodeType": "Identifier",
|
||||
"overloadedDeclarations": [],
|
||||
"referencedDeclaration": 68,
|
||||
"referencedDeclaration": -28,
|
||||
"src": "217:4:1",
|
||||
"typeDescriptions":
|
||||
{
|
||||
|
||||
@@ -446,7 +446,7 @@
|
||||
[
|
||||
null
|
||||
],
|
||||
"referencedDeclaration": 68,
|
||||
"referencedDeclaration": -28,
|
||||
"type": "contract C",
|
||||
"value": "this"
|
||||
},
|
||||
|
||||
@@ -124,6 +124,7 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
"evmVersion": %EVMVERSION%,
|
||||
"externalReferences": [],
|
||||
"id": 3,
|
||||
"nodeType": "InlineAssembly",
|
||||
|
||||
@@ -89,6 +89,7 @@
|
||||
{
|
||||
"attributes":
|
||||
{
|
||||
"evmVersion": %EVMVERSION%,
|
||||
"externalReferences":
|
||||
[
|
||||
null
|
||||
|
||||
@@ -111,6 +111,7 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
"evmVersion": %EVMVERSION%,
|
||||
"externalReferences": [],
|
||||
"id": 3,
|
||||
"nodeType": "InlineAssembly",
|
||||
|
||||
@@ -89,6 +89,7 @@
|
||||
{
|
||||
"attributes":
|
||||
{
|
||||
"evmVersion": %EVMVERSION%,
|
||||
"externalReferences":
|
||||
[
|
||||
null
|
||||
|
||||
@@ -61,6 +61,7 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
"evmVersion": %EVMVERSION%,
|
||||
"externalReferences": [],
|
||||
"id": 3,
|
||||
"nodeType": "InlineAssembly",
|
||||
|
||||
@@ -89,6 +89,7 @@
|
||||
{
|
||||
"attributes":
|
||||
{
|
||||
"evmVersion": %EVMVERSION%,
|
||||
"externalReferences":
|
||||
[
|
||||
null
|
||||
|
||||
@@ -124,6 +124,7 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
"evmVersion": %EVMVERSION%,
|
||||
"externalReferences": [],
|
||||
"id": 3,
|
||||
"nodeType": "InlineAssembly",
|
||||
|
||||
@@ -89,6 +89,7 @@
|
||||
{
|
||||
"attributes":
|
||||
{
|
||||
"evmVersion": %EVMVERSION%,
|
||||
"externalReferences":
|
||||
[
|
||||
null
|
||||
|
||||
@@ -0,0 +1,166 @@
|
||||
{
|
||||
"absolutePath": "a",
|
||||
"exportedSymbols":
|
||||
{
|
||||
"C":
|
||||
[
|
||||
8
|
||||
]
|
||||
},
|
||||
"id": 9,
|
||||
"nodeType": "SourceUnit",
|
||||
"nodes":
|
||||
[
|
||||
{
|
||||
"abstract": false,
|
||||
"baseContracts": [],
|
||||
"contractDependencies": [],
|
||||
"contractKind": "contract",
|
||||
"documentation": null,
|
||||
"fullyImplemented": true,
|
||||
"id": 8,
|
||||
"linearizedBaseContracts":
|
||||
[
|
||||
8
|
||||
],
|
||||
"name": "C",
|
||||
"nodeType": "ContractDefinition",
|
||||
"nodes":
|
||||
[
|
||||
{
|
||||
"body":
|
||||
{
|
||||
"id": 6,
|
||||
"nodeType": "Block",
|
||||
"src": "57:97:1",
|
||||
"statements":
|
||||
[
|
||||
{
|
||||
"AST":
|
||||
{
|
||||
"nodeType": "YulBlock",
|
||||
"src": "72:78:1",
|
||||
"statements":
|
||||
[
|
||||
{
|
||||
"body":
|
||||
{
|
||||
"nodeType": "YulBlock",
|
||||
"src": "94:50:1",
|
||||
"statements":
|
||||
[
|
||||
{
|
||||
"body":
|
||||
{
|
||||
"nodeType": "YulBlock",
|
||||
"src": "118:3:1",
|
||||
"statements": []
|
||||
},
|
||||
"name": "f2",
|
||||
"nodeType": "YulFunctionDefinition",
|
||||
"src": "104:17:1"
|
||||
},
|
||||
{
|
||||
"nodeType": "YulAssignment",
|
||||
"src": "130:6:1",
|
||||
"value":
|
||||
{
|
||||
"kind": "number",
|
||||
"nodeType": "YulLiteral",
|
||||
"src": "135:1:1",
|
||||
"type": "",
|
||||
"value": "2"
|
||||
},
|
||||
"variableNames":
|
||||
[
|
||||
{
|
||||
"name": "x",
|
||||
"nodeType": "YulIdentifier",
|
||||
"src": "130:1:1"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"name": "f1",
|
||||
"nodeType": "YulFunctionDefinition",
|
||||
"src": "80:64:1"
|
||||
}
|
||||
]
|
||||
},
|
||||
"evmVersion": %EVMVERSION%,
|
||||
"externalReferences": [],
|
||||
"id": 5,
|
||||
"nodeType": "InlineAssembly",
|
||||
"src": "63:87:1"
|
||||
}
|
||||
]
|
||||
},
|
||||
"documentation": null,
|
||||
"functionSelector": "26121ff0",
|
||||
"id": 7,
|
||||
"implemented": true,
|
||||
"kind": "function",
|
||||
"modifiers": [],
|
||||
"name": "f",
|
||||
"nodeType": "FunctionDefinition",
|
||||
"overrides": null,
|
||||
"parameters":
|
||||
{
|
||||
"id": 1,
|
||||
"nodeType": "ParameterList",
|
||||
"parameters": [],
|
||||
"src": "25:2:1"
|
||||
},
|
||||
"returnParameters":
|
||||
{
|
||||
"id": 4,
|
||||
"nodeType": "ParameterList",
|
||||
"parameters":
|
||||
[
|
||||
{
|
||||
"constant": false,
|
||||
"id": 3,
|
||||
"name": "x",
|
||||
"nodeType": "VariableDeclaration",
|
||||
"overrides": null,
|
||||
"scope": 7,
|
||||
"src": "49:6:1",
|
||||
"stateVariable": false,
|
||||
"storageLocation": "default",
|
||||
"typeDescriptions":
|
||||
{
|
||||
"typeIdentifier": "t_uint256",
|
||||
"typeString": "uint256"
|
||||
},
|
||||
"typeName":
|
||||
{
|
||||
"id": 2,
|
||||
"name": "uint",
|
||||
"nodeType": "ElementaryTypeName",
|
||||
"src": "49:4:1",
|
||||
"typeDescriptions":
|
||||
{
|
||||
"typeIdentifier": "t_uint256",
|
||||
"typeString": "uint256"
|
||||
}
|
||||
},
|
||||
"value": null,
|
||||
"visibility": "internal"
|
||||
}
|
||||
],
|
||||
"src": "48:8:1"
|
||||
},
|
||||
"scope": 8,
|
||||
"src": "15:139:1",
|
||||
"stateMutability": "pure",
|
||||
"virtual": false,
|
||||
"visibility": "public"
|
||||
}
|
||||
],
|
||||
"scope": 9,
|
||||
"src": "0:156:1"
|
||||
}
|
||||
],
|
||||
"src": "0:157:1"
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
contract C {
|
||||
function f() public pure returns (uint x) {
|
||||
assembly {
|
||||
function f1() {
|
||||
function f2() { }
|
||||
x := 2
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ----
|
||||
@@ -0,0 +1,148 @@
|
||||
{
|
||||
"attributes":
|
||||
{
|
||||
"absolutePath": "a",
|
||||
"exportedSymbols":
|
||||
{
|
||||
"C":
|
||||
[
|
||||
8
|
||||
]
|
||||
}
|
||||
},
|
||||
"children":
|
||||
[
|
||||
{
|
||||
"attributes":
|
||||
{
|
||||
"abstract": false,
|
||||
"baseContracts":
|
||||
[
|
||||
null
|
||||
],
|
||||
"contractDependencies":
|
||||
[
|
||||
null
|
||||
],
|
||||
"contractKind": "contract",
|
||||
"documentation": null,
|
||||
"fullyImplemented": true,
|
||||
"linearizedBaseContracts":
|
||||
[
|
||||
8
|
||||
],
|
||||
"name": "C",
|
||||
"scope": 9
|
||||
},
|
||||
"children":
|
||||
[
|
||||
{
|
||||
"attributes":
|
||||
{
|
||||
"documentation": null,
|
||||
"functionSelector": "26121ff0",
|
||||
"implemented": true,
|
||||
"isConstructor": false,
|
||||
"kind": "function",
|
||||
"modifiers":
|
||||
[
|
||||
null
|
||||
],
|
||||
"name": "f",
|
||||
"overrides": null,
|
||||
"scope": 8,
|
||||
"stateMutability": "pure",
|
||||
"virtual": false,
|
||||
"visibility": "public"
|
||||
},
|
||||
"children":
|
||||
[
|
||||
{
|
||||
"attributes":
|
||||
{
|
||||
"parameters":
|
||||
[
|
||||
null
|
||||
]
|
||||
},
|
||||
"children": [],
|
||||
"id": 1,
|
||||
"name": "ParameterList",
|
||||
"src": "25:2:1"
|
||||
},
|
||||
{
|
||||
"children":
|
||||
[
|
||||
{
|
||||
"attributes":
|
||||
{
|
||||
"constant": false,
|
||||
"name": "x",
|
||||
"overrides": null,
|
||||
"scope": 7,
|
||||
"stateVariable": false,
|
||||
"storageLocation": "default",
|
||||
"type": "uint256",
|
||||
"value": null,
|
||||
"visibility": "internal"
|
||||
},
|
||||
"children":
|
||||
[
|
||||
{
|
||||
"attributes":
|
||||
{
|
||||
"name": "uint",
|
||||
"type": "uint256"
|
||||
},
|
||||
"id": 2,
|
||||
"name": "ElementaryTypeName",
|
||||
"src": "49:4:1"
|
||||
}
|
||||
],
|
||||
"id": 3,
|
||||
"name": "VariableDeclaration",
|
||||
"src": "49:6:1"
|
||||
}
|
||||
],
|
||||
"id": 4,
|
||||
"name": "ParameterList",
|
||||
"src": "48:8:1"
|
||||
},
|
||||
{
|
||||
"children":
|
||||
[
|
||||
{
|
||||
"attributes":
|
||||
{
|
||||
"evmVersion": %EVMVERSION%,
|
||||
"externalReferences":
|
||||
[
|
||||
null
|
||||
],
|
||||
"operations": "{\n function f1()\n {\n function f2()\n { }\n x := 2\n }\n}"
|
||||
},
|
||||
"children": [],
|
||||
"id": 5,
|
||||
"name": "InlineAssembly",
|
||||
"src": "63:87:1"
|
||||
}
|
||||
],
|
||||
"id": 6,
|
||||
"name": "Block",
|
||||
"src": "57:97:1"
|
||||
}
|
||||
],
|
||||
"id": 7,
|
||||
"name": "FunctionDefinition",
|
||||
"src": "15:139:1"
|
||||
}
|
||||
],
|
||||
"id": 8,
|
||||
"name": "ContractDefinition",
|
||||
"src": "0:156:1"
|
||||
}
|
||||
],
|
||||
"id": 9,
|
||||
"name": "SourceUnit",
|
||||
"src": "0:157:1"
|
||||
}
|
||||
@@ -176,6 +176,7 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
"evmVersion": %EVMVERSION%,
|
||||
"externalReferences":
|
||||
[
|
||||
{
|
||||
|
||||
@@ -166,6 +166,7 @@
|
||||
{
|
||||
"attributes":
|
||||
{
|
||||
"evmVersion": %EVMVERSION%,
|
||||
"externalReferences":
|
||||
[
|
||||
{
|
||||
|
||||
@@ -65,6 +65,7 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
"evmVersion": %EVMVERSION%,
|
||||
"externalReferences": [],
|
||||
"id": 3,
|
||||
"nodeType": "InlineAssembly",
|
||||
|
||||
@@ -89,6 +89,7 @@
|
||||
{
|
||||
"attributes":
|
||||
{
|
||||
"evmVersion": %EVMVERSION%,
|
||||
"externalReferences":
|
||||
[
|
||||
null
|
||||
|
||||
@@ -157,7 +157,24 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
"externalReferences": [],
|
||||
"evmVersion": %EVMVERSION%,
|
||||
"externalReferences":
|
||||
[
|
||||
{
|
||||
"declaration": 5,
|
||||
"isOffset": false,
|
||||
"isSlot": false,
|
||||
"src": "141:1:1",
|
||||
"valueSize": 18446744073709551615
|
||||
},
|
||||
{
|
||||
"declaration": 5,
|
||||
"isOffset": false,
|
||||
"isSlot": false,
|
||||
"src": "172:1:1",
|
||||
"valueSize": 18446744073709551615
|
||||
}
|
||||
],
|
||||
"id": 3,
|
||||
"nodeType": "InlineAssembly",
|
||||
"src": "52:138:1"
|
||||
|
||||
@@ -89,9 +89,23 @@
|
||||
{
|
||||
"attributes":
|
||||
{
|
||||
"evmVersion": %EVMVERSION%,
|
||||
"externalReferences":
|
||||
[
|
||||
null
|
||||
{
|
||||
"declaration": 5,
|
||||
"isOffset": false,
|
||||
"isSlot": false,
|
||||
"src": "141:1:1",
|
||||
"valueSize": 18446744073709551615
|
||||
},
|
||||
{
|
||||
"declaration": 5,
|
||||
"isOffset": false,
|
||||
"isSlot": false,
|
||||
"src": "172:1:1",
|
||||
"valueSize": 18446744073709551615
|
||||
}
|
||||
],
|
||||
"operations": "{\n let f := 0\n switch calldatasize()\n case 0 { f := 1 }\n default { f := 2 }\n}"
|
||||
},
|
||||
|
||||
@@ -107,6 +107,7 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
"evmVersion": %EVMVERSION%,
|
||||
"externalReferences":
|
||||
[
|
||||
{
|
||||
|
||||
@@ -135,6 +135,7 @@
|
||||
{
|
||||
"attributes":
|
||||
{
|
||||
"evmVersion": %EVMVERSION%,
|
||||
"externalReferences":
|
||||
[
|
||||
{
|
||||
|
||||
@@ -4,10 +4,10 @@
|
||||
{
|
||||
"C":
|
||||
[
|
||||
1
|
||||
2
|
||||
]
|
||||
},
|
||||
"id": 2,
|
||||
"id": 3,
|
||||
"nodeType": "SourceUnit",
|
||||
"nodes":
|
||||
[
|
||||
@@ -16,17 +16,23 @@
|
||||
"baseContracts": [],
|
||||
"contractDependencies": [],
|
||||
"contractKind": "contract",
|
||||
"documentation": "This contract is empty",
|
||||
"documentation":
|
||||
{
|
||||
"id": 1,
|
||||
"nodeType": "StructuredDocumentation",
|
||||
"src": "0:27:1",
|
||||
"text": "This contract is empty"
|
||||
},
|
||||
"fullyImplemented": true,
|
||||
"id": 1,
|
||||
"id": 2,
|
||||
"linearizedBaseContracts":
|
||||
[
|
||||
1
|
||||
2
|
||||
],
|
||||
"name": "C",
|
||||
"nodeType": "ContractDefinition",
|
||||
"nodes": [],
|
||||
"scope": 2,
|
||||
"scope": 3,
|
||||
"src": "28:13:1"
|
||||
}
|
||||
],
|
||||
@@ -38,10 +44,10 @@
|
||||
{
|
||||
"C":
|
||||
[
|
||||
3
|
||||
5
|
||||
]
|
||||
},
|
||||
"id": 4,
|
||||
"id": 6,
|
||||
"nodeType": "SourceUnit",
|
||||
"nodes":
|
||||
[
|
||||
@@ -50,17 +56,23 @@
|
||||
"baseContracts": [],
|
||||
"contractDependencies": [],
|
||||
"contractKind": "contract",
|
||||
"documentation": "This contract is empty\nand has a line-breaking comment.",
|
||||
"documentation":
|
||||
{
|
||||
"id": 4,
|
||||
"nodeType": "StructuredDocumentation",
|
||||
"src": "0:61:2",
|
||||
"text": "This contract is empty\nand has a line-breaking comment."
|
||||
},
|
||||
"fullyImplemented": true,
|
||||
"id": 3,
|
||||
"id": 5,
|
||||
"linearizedBaseContracts":
|
||||
[
|
||||
3
|
||||
5
|
||||
],
|
||||
"name": "C",
|
||||
"nodeType": "ContractDefinition",
|
||||
"nodes": [],
|
||||
"scope": 4,
|
||||
"scope": 6,
|
||||
"src": "62:13:2"
|
||||
}
|
||||
],
|
||||
@@ -72,10 +84,10 @@
|
||||
{
|
||||
"C":
|
||||
[
|
||||
15
|
||||
20
|
||||
]
|
||||
},
|
||||
"id": 16,
|
||||
"id": 21,
|
||||
"nodeType": "SourceUnit",
|
||||
"nodes":
|
||||
[
|
||||
@@ -86,10 +98,10 @@
|
||||
"contractKind": "contract",
|
||||
"documentation": null,
|
||||
"fullyImplemented": true,
|
||||
"id": 15,
|
||||
"id": 20,
|
||||
"linearizedBaseContracts":
|
||||
[
|
||||
15
|
||||
20
|
||||
],
|
||||
"name": "C",
|
||||
"nodeType": "ContractDefinition",
|
||||
@@ -97,13 +109,19 @@
|
||||
[
|
||||
{
|
||||
"anonymous": false,
|
||||
"documentation": "Some comment on Evt.",
|
||||
"id": 6,
|
||||
"documentation":
|
||||
{
|
||||
"id": 7,
|
||||
"nodeType": "StructuredDocumentation",
|
||||
"src": "15:26:3",
|
||||
"text": "Some comment on Evt."
|
||||
},
|
||||
"id": 9,
|
||||
"name": "Evt",
|
||||
"nodeType": "EventDefinition",
|
||||
"parameters":
|
||||
{
|
||||
"id": 5,
|
||||
"id": 8,
|
||||
"nodeType": "ParameterList",
|
||||
"parameters": [],
|
||||
"src": "51:2:3"
|
||||
@@ -113,26 +131,32 @@
|
||||
{
|
||||
"body":
|
||||
{
|
||||
"id": 9,
|
||||
"id": 13,
|
||||
"nodeType": "Block",
|
||||
"src": "99:6:3",
|
||||
"statements":
|
||||
[
|
||||
{
|
||||
"id": 8,
|
||||
"id": 12,
|
||||
"nodeType": "PlaceholderStatement",
|
||||
"src": "101:1:3"
|
||||
}
|
||||
]
|
||||
},
|
||||
"documentation": "Some comment on mod.",
|
||||
"id": 10,
|
||||
"documentation":
|
||||
{
|
||||
"id": 10,
|
||||
"nodeType": "StructuredDocumentation",
|
||||
"src": "57:26:3",
|
||||
"text": "Some comment on mod."
|
||||
},
|
||||
"id": 14,
|
||||
"name": "mod",
|
||||
"nodeType": "ModifierDefinition",
|
||||
"overrides": null,
|
||||
"parameters":
|
||||
{
|
||||
"id": 7,
|
||||
"id": 11,
|
||||
"nodeType": "ParameterList",
|
||||
"parameters": [],
|
||||
"src": "96:2:3"
|
||||
@@ -144,14 +168,20 @@
|
||||
{
|
||||
"body":
|
||||
{
|
||||
"id": 13,
|
||||
"id": 18,
|
||||
"nodeType": "Block",
|
||||
"src": "155:2:3",
|
||||
"statements": []
|
||||
},
|
||||
"documentation": "Some comment on fn.",
|
||||
"documentation":
|
||||
{
|
||||
"id": 15,
|
||||
"nodeType": "StructuredDocumentation",
|
||||
"src": "108:25:3",
|
||||
"text": "Some comment on fn."
|
||||
},
|
||||
"functionSelector": "a4a2c40b",
|
||||
"id": 14,
|
||||
"id": 19,
|
||||
"implemented": true,
|
||||
"kind": "function",
|
||||
"modifiers": [],
|
||||
@@ -160,26 +190,26 @@
|
||||
"overrides": null,
|
||||
"parameters":
|
||||
{
|
||||
"id": 11,
|
||||
"id": 16,
|
||||
"nodeType": "ParameterList",
|
||||
"parameters": [],
|
||||
"src": "145:2:3"
|
||||
},
|
||||
"returnParameters":
|
||||
{
|
||||
"id": 12,
|
||||
"id": 17,
|
||||
"nodeType": "ParameterList",
|
||||
"parameters": [],
|
||||
"src": "155:0:3"
|
||||
},
|
||||
"scope": 15,
|
||||
"scope": 20,
|
||||
"src": "134:23:3",
|
||||
"stateMutability": "nonpayable",
|
||||
"virtual": false,
|
||||
"visibility": "public"
|
||||
}
|
||||
],
|
||||
"scope": 16,
|
||||
"scope": 21,
|
||||
"src": "0:159:3"
|
||||
}
|
||||
],
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
{
|
||||
"C":
|
||||
[
|
||||
15
|
||||
20
|
||||
]
|
||||
}
|
||||
},
|
||||
@@ -29,10 +29,10 @@
|
||||
"fullyImplemented": true,
|
||||
"linearizedBaseContracts":
|
||||
[
|
||||
15
|
||||
20
|
||||
],
|
||||
"name": "C",
|
||||
"scope": 16
|
||||
"scope": 21
|
||||
},
|
||||
"children":
|
||||
[
|
||||
@@ -40,11 +40,19 @@
|
||||
"attributes":
|
||||
{
|
||||
"anonymous": false,
|
||||
"documentation": "Some comment on Evt.",
|
||||
"name": "Evt"
|
||||
},
|
||||
"children":
|
||||
[
|
||||
{
|
||||
"attributes":
|
||||
{
|
||||
"text": "Some comment on Evt."
|
||||
},
|
||||
"id": 7,
|
||||
"name": "StructuredDocumentation",
|
||||
"src": "15:26:3"
|
||||
},
|
||||
{
|
||||
"attributes":
|
||||
{
|
||||
@@ -54,19 +62,18 @@
|
||||
]
|
||||
},
|
||||
"children": [],
|
||||
"id": 5,
|
||||
"id": 8,
|
||||
"name": "ParameterList",
|
||||
"src": "51:2:3"
|
||||
}
|
||||
],
|
||||
"id": 6,
|
||||
"id": 9,
|
||||
"name": "EventDefinition",
|
||||
"src": "42:12:3"
|
||||
},
|
||||
{
|
||||
"attributes":
|
||||
{
|
||||
"documentation": "Some comment on mod.",
|
||||
"name": "mod",
|
||||
"overrides": null,
|
||||
"virtual": false,
|
||||
@@ -77,55 +84,12 @@
|
||||
{
|
||||
"attributes":
|
||||
{
|
||||
"parameters":
|
||||
[
|
||||
null
|
||||
]
|
||||
"text": "Some comment on mod."
|
||||
},
|
||||
"children": [],
|
||||
"id": 7,
|
||||
"name": "ParameterList",
|
||||
"src": "96:2:3"
|
||||
"id": 10,
|
||||
"name": "StructuredDocumentation",
|
||||
"src": "57:26:3"
|
||||
},
|
||||
{
|
||||
"children":
|
||||
[
|
||||
{
|
||||
"id": 8,
|
||||
"name": "PlaceholderStatement",
|
||||
"src": "101:1:3"
|
||||
}
|
||||
],
|
||||
"id": 9,
|
||||
"name": "Block",
|
||||
"src": "99:6:3"
|
||||
}
|
||||
],
|
||||
"id": 10,
|
||||
"name": "ModifierDefinition",
|
||||
"src": "84:21:3"
|
||||
},
|
||||
{
|
||||
"attributes":
|
||||
{
|
||||
"documentation": "Some comment on fn.",
|
||||
"functionSelector": "a4a2c40b",
|
||||
"implemented": true,
|
||||
"isConstructor": false,
|
||||
"kind": "function",
|
||||
"modifiers":
|
||||
[
|
||||
null
|
||||
],
|
||||
"name": "fn",
|
||||
"overrides": null,
|
||||
"scope": 15,
|
||||
"stateMutability": "nonpayable",
|
||||
"virtual": false,
|
||||
"visibility": "public"
|
||||
},
|
||||
"children":
|
||||
[
|
||||
{
|
||||
"attributes":
|
||||
{
|
||||
@@ -137,6 +101,66 @@
|
||||
"children": [],
|
||||
"id": 11,
|
||||
"name": "ParameterList",
|
||||
"src": "96:2:3"
|
||||
},
|
||||
{
|
||||
"children":
|
||||
[
|
||||
{
|
||||
"id": 12,
|
||||
"name": "PlaceholderStatement",
|
||||
"src": "101:1:3"
|
||||
}
|
||||
],
|
||||
"id": 13,
|
||||
"name": "Block",
|
||||
"src": "99:6:3"
|
||||
}
|
||||
],
|
||||
"id": 14,
|
||||
"name": "ModifierDefinition",
|
||||
"src": "84:21:3"
|
||||
},
|
||||
{
|
||||
"attributes":
|
||||
{
|
||||
"functionSelector": "a4a2c40b",
|
||||
"implemented": true,
|
||||
"isConstructor": false,
|
||||
"kind": "function",
|
||||
"modifiers":
|
||||
[
|
||||
null
|
||||
],
|
||||
"name": "fn",
|
||||
"overrides": null,
|
||||
"scope": 20,
|
||||
"stateMutability": "nonpayable",
|
||||
"virtual": false,
|
||||
"visibility": "public"
|
||||
},
|
||||
"children":
|
||||
[
|
||||
{
|
||||
"attributes":
|
||||
{
|
||||
"text": "Some comment on fn."
|
||||
},
|
||||
"id": 15,
|
||||
"name": "StructuredDocumentation",
|
||||
"src": "108:25:3"
|
||||
},
|
||||
{
|
||||
"attributes":
|
||||
{
|
||||
"parameters":
|
||||
[
|
||||
null
|
||||
]
|
||||
},
|
||||
"children": [],
|
||||
"id": 16,
|
||||
"name": "ParameterList",
|
||||
"src": "145:2:3"
|
||||
},
|
||||
{
|
||||
@@ -148,7 +172,7 @@
|
||||
]
|
||||
},
|
||||
"children": [],
|
||||
"id": 12,
|
||||
"id": 17,
|
||||
"name": "ParameterList",
|
||||
"src": "155:0:3"
|
||||
},
|
||||
@@ -161,22 +185,22 @@
|
||||
]
|
||||
},
|
||||
"children": [],
|
||||
"id": 13,
|
||||
"id": 18,
|
||||
"name": "Block",
|
||||
"src": "155:2:3"
|
||||
}
|
||||
],
|
||||
"id": 14,
|
||||
"id": 19,
|
||||
"name": "FunctionDefinition",
|
||||
"src": "134:23:3"
|
||||
}
|
||||
],
|
||||
"id": 15,
|
||||
"id": 20,
|
||||
"name": "ContractDefinition",
|
||||
"src": "0:159:3"
|
||||
}
|
||||
],
|
||||
"id": 16,
|
||||
"id": 21,
|
||||
"name": "SourceUnit",
|
||||
"src": "0:160:3"
|
||||
}
|
||||
|
||||
@@ -0,0 +1,227 @@
|
||||
{
|
||||
"absolutePath": "a",
|
||||
"exportedSymbols":
|
||||
{
|
||||
"C":
|
||||
[
|
||||
17
|
||||
]
|
||||
},
|
||||
"id": 18,
|
||||
"nodeType": "SourceUnit",
|
||||
"nodes":
|
||||
[
|
||||
{
|
||||
"abstract": false,
|
||||
"baseContracts": [],
|
||||
"contractDependencies": [],
|
||||
"contractKind": "contract",
|
||||
"documentation": null,
|
||||
"fullyImplemented": true,
|
||||
"id": 17,
|
||||
"linearizedBaseContracts":
|
||||
[
|
||||
17
|
||||
],
|
||||
"name": "C",
|
||||
"nodeType": "ContractDefinition",
|
||||
"nodes":
|
||||
[
|
||||
{
|
||||
"canonicalName": "C.E",
|
||||
"id": 4,
|
||||
"members":
|
||||
[
|
||||
{
|
||||
"id": 1,
|
||||
"name": "A",
|
||||
"nodeType": "EnumValue",
|
||||
"src": "26:1:1"
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"name": "B",
|
||||
"nodeType": "EnumValue",
|
||||
"src": "29:1:1"
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"name": "C",
|
||||
"nodeType": "EnumValue",
|
||||
"src": "32:1:1"
|
||||
}
|
||||
],
|
||||
"name": "E",
|
||||
"nodeType": "EnumDefinition",
|
||||
"src": "17:18:1"
|
||||
},
|
||||
{
|
||||
"constant": false,
|
||||
"id": 8,
|
||||
"name": "a",
|
||||
"nodeType": "VariableDeclaration",
|
||||
"overrides": null,
|
||||
"scope": 17,
|
||||
"src": "40:20:1",
|
||||
"stateVariable": true,
|
||||
"storageLocation": "default",
|
||||
"typeDescriptions":
|
||||
{
|
||||
"typeIdentifier": "t_mapping$_t_contract$_C_$17_$_t_bool_$",
|
||||
"typeString": "mapping(contract C => bool)"
|
||||
},
|
||||
"typeName":
|
||||
{
|
||||
"id": 7,
|
||||
"keyType":
|
||||
{
|
||||
"contractScope": null,
|
||||
"id": 5,
|
||||
"name": "C",
|
||||
"nodeType": "UserDefinedTypeName",
|
||||
"referencedDeclaration": 17,
|
||||
"src": "48:1:1",
|
||||
"typeDescriptions":
|
||||
{
|
||||
"typeIdentifier": "t_contract$_C_$17",
|
||||
"typeString": "contract C"
|
||||
}
|
||||
},
|
||||
"nodeType": "Mapping",
|
||||
"src": "40:18:1",
|
||||
"typeDescriptions":
|
||||
{
|
||||
"typeIdentifier": "t_mapping$_t_contract$_C_$17_$_t_bool_$",
|
||||
"typeString": "mapping(contract C => bool)"
|
||||
},
|
||||
"valueType":
|
||||
{
|
||||
"id": 6,
|
||||
"name": "bool",
|
||||
"nodeType": "ElementaryTypeName",
|
||||
"src": "53:4:1",
|
||||
"typeDescriptions":
|
||||
{
|
||||
"typeIdentifier": "t_bool",
|
||||
"typeString": "bool"
|
||||
}
|
||||
}
|
||||
},
|
||||
"value": null,
|
||||
"visibility": "internal"
|
||||
},
|
||||
{
|
||||
"constant": false,
|
||||
"id": 12,
|
||||
"name": "b",
|
||||
"nodeType": "VariableDeclaration",
|
||||
"overrides": null,
|
||||
"scope": 17,
|
||||
"src": "66:26:1",
|
||||
"stateVariable": true,
|
||||
"storageLocation": "default",
|
||||
"typeDescriptions":
|
||||
{
|
||||
"typeIdentifier": "t_mapping$_t_address_$_t_bool_$",
|
||||
"typeString": "mapping(address => bool)"
|
||||
},
|
||||
"typeName":
|
||||
{
|
||||
"id": 11,
|
||||
"keyType":
|
||||
{
|
||||
"id": 9,
|
||||
"name": "address",
|
||||
"nodeType": "ElementaryTypeName",
|
||||
"src": "74:7:1",
|
||||
"typeDescriptions":
|
||||
{
|
||||
"typeIdentifier": "t_address",
|
||||
"typeString": "address"
|
||||
}
|
||||
},
|
||||
"nodeType": "Mapping",
|
||||
"src": "66:24:1",
|
||||
"typeDescriptions":
|
||||
{
|
||||
"typeIdentifier": "t_mapping$_t_address_$_t_bool_$",
|
||||
"typeString": "mapping(address => bool)"
|
||||
},
|
||||
"valueType":
|
||||
{
|
||||
"id": 10,
|
||||
"name": "bool",
|
||||
"nodeType": "ElementaryTypeName",
|
||||
"src": "85:4:1",
|
||||
"typeDescriptions":
|
||||
{
|
||||
"typeIdentifier": "t_bool",
|
||||
"typeString": "bool"
|
||||
}
|
||||
}
|
||||
},
|
||||
"value": null,
|
||||
"visibility": "internal"
|
||||
},
|
||||
{
|
||||
"constant": false,
|
||||
"id": 16,
|
||||
"name": "c",
|
||||
"nodeType": "VariableDeclaration",
|
||||
"overrides": null,
|
||||
"scope": 17,
|
||||
"src": "98:20:1",
|
||||
"stateVariable": true,
|
||||
"storageLocation": "default",
|
||||
"typeDescriptions":
|
||||
{
|
||||
"typeIdentifier": "t_mapping$_t_enum$_E_$4_$_t_bool_$",
|
||||
"typeString": "mapping(enum C.E => bool)"
|
||||
},
|
||||
"typeName":
|
||||
{
|
||||
"id": 15,
|
||||
"keyType":
|
||||
{
|
||||
"contractScope": null,
|
||||
"id": 13,
|
||||
"name": "E",
|
||||
"nodeType": "UserDefinedTypeName",
|
||||
"referencedDeclaration": 4,
|
||||
"src": "106:1:1",
|
||||
"typeDescriptions":
|
||||
{
|
||||
"typeIdentifier": "t_enum$_E_$4",
|
||||
"typeString": "enum C.E"
|
||||
}
|
||||
},
|
||||
"nodeType": "Mapping",
|
||||
"src": "98:18:1",
|
||||
"typeDescriptions":
|
||||
{
|
||||
"typeIdentifier": "t_mapping$_t_enum$_E_$4_$_t_bool_$",
|
||||
"typeString": "mapping(enum C.E => bool)"
|
||||
},
|
||||
"valueType":
|
||||
{
|
||||
"id": 14,
|
||||
"name": "bool",
|
||||
"nodeType": "ElementaryTypeName",
|
||||
"src": "111:4:1",
|
||||
"typeDescriptions":
|
||||
{
|
||||
"typeIdentifier": "t_bool",
|
||||
"typeString": "bool"
|
||||
}
|
||||
}
|
||||
},
|
||||
"value": null,
|
||||
"visibility": "internal"
|
||||
}
|
||||
],
|
||||
"scope": 18,
|
||||
"src": "0:121:1"
|
||||
}
|
||||
],
|
||||
"src": "0:122:1"
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
contract C {
|
||||
enum E { A, B, C }
|
||||
mapping(C => bool) a;
|
||||
mapping(address => bool) b;
|
||||
mapping(E => bool) c;
|
||||
}
|
||||
|
||||
// ----
|
||||
@@ -0,0 +1,248 @@
|
||||
{
|
||||
"attributes":
|
||||
{
|
||||
"absolutePath": "a",
|
||||
"exportedSymbols":
|
||||
{
|
||||
"C":
|
||||
[
|
||||
17
|
||||
]
|
||||
}
|
||||
},
|
||||
"children":
|
||||
[
|
||||
{
|
||||
"attributes":
|
||||
{
|
||||
"abstract": false,
|
||||
"baseContracts":
|
||||
[
|
||||
null
|
||||
],
|
||||
"contractDependencies":
|
||||
[
|
||||
null
|
||||
],
|
||||
"contractKind": "contract",
|
||||
"documentation": null,
|
||||
"fullyImplemented": true,
|
||||
"linearizedBaseContracts":
|
||||
[
|
||||
17
|
||||
],
|
||||
"name": "C",
|
||||
"scope": 18
|
||||
},
|
||||
"children":
|
||||
[
|
||||
{
|
||||
"attributes":
|
||||
{
|
||||
"canonicalName": "C.E",
|
||||
"name": "E"
|
||||
},
|
||||
"children":
|
||||
[
|
||||
{
|
||||
"attributes":
|
||||
{
|
||||
"name": "A"
|
||||
},
|
||||
"id": 1,
|
||||
"name": "EnumValue",
|
||||
"src": "26:1:1"
|
||||
},
|
||||
{
|
||||
"attributes":
|
||||
{
|
||||
"name": "B"
|
||||
},
|
||||
"id": 2,
|
||||
"name": "EnumValue",
|
||||
"src": "29:1:1"
|
||||
},
|
||||
{
|
||||
"attributes":
|
||||
{
|
||||
"name": "C"
|
||||
},
|
||||
"id": 3,
|
||||
"name": "EnumValue",
|
||||
"src": "32:1:1"
|
||||
}
|
||||
],
|
||||
"id": 4,
|
||||
"name": "EnumDefinition",
|
||||
"src": "17:18:1"
|
||||
},
|
||||
{
|
||||
"attributes":
|
||||
{
|
||||
"constant": false,
|
||||
"name": "a",
|
||||
"overrides": null,
|
||||
"scope": 17,
|
||||
"stateVariable": true,
|
||||
"storageLocation": "default",
|
||||
"type": "mapping(contract C => bool)",
|
||||
"value": null,
|
||||
"visibility": "internal"
|
||||
},
|
||||
"children":
|
||||
[
|
||||
{
|
||||
"attributes":
|
||||
{
|
||||
"type": "mapping(contract C => bool)"
|
||||
},
|
||||
"children":
|
||||
[
|
||||
{
|
||||
"attributes":
|
||||
{
|
||||
"contractScope": null,
|
||||
"name": "C",
|
||||
"referencedDeclaration": 17,
|
||||
"type": "contract C"
|
||||
},
|
||||
"id": 5,
|
||||
"name": "UserDefinedTypeName",
|
||||
"src": "48:1:1"
|
||||
},
|
||||
{
|
||||
"attributes":
|
||||
{
|
||||
"name": "bool",
|
||||
"type": "bool"
|
||||
},
|
||||
"id": 6,
|
||||
"name": "ElementaryTypeName",
|
||||
"src": "53:4:1"
|
||||
}
|
||||
],
|
||||
"id": 7,
|
||||
"name": "Mapping",
|
||||
"src": "40:18:1"
|
||||
}
|
||||
],
|
||||
"id": 8,
|
||||
"name": "VariableDeclaration",
|
||||
"src": "40:20:1"
|
||||
},
|
||||
{
|
||||
"attributes":
|
||||
{
|
||||
"constant": false,
|
||||
"name": "b",
|
||||
"overrides": null,
|
||||
"scope": 17,
|
||||
"stateVariable": true,
|
||||
"storageLocation": "default",
|
||||
"type": "mapping(address => bool)",
|
||||
"value": null,
|
||||
"visibility": "internal"
|
||||
},
|
||||
"children":
|
||||
[
|
||||
{
|
||||
"attributes":
|
||||
{
|
||||
"type": "mapping(address => bool)"
|
||||
},
|
||||
"children":
|
||||
[
|
||||
{
|
||||
"attributes":
|
||||
{
|
||||
"name": "address",
|
||||
"type": "address"
|
||||
},
|
||||
"id": 9,
|
||||
"name": "ElementaryTypeName",
|
||||
"src": "74:7:1"
|
||||
},
|
||||
{
|
||||
"attributes":
|
||||
{
|
||||
"name": "bool",
|
||||
"type": "bool"
|
||||
},
|
||||
"id": 10,
|
||||
"name": "ElementaryTypeName",
|
||||
"src": "85:4:1"
|
||||
}
|
||||
],
|
||||
"id": 11,
|
||||
"name": "Mapping",
|
||||
"src": "66:24:1"
|
||||
}
|
||||
],
|
||||
"id": 12,
|
||||
"name": "VariableDeclaration",
|
||||
"src": "66:26:1"
|
||||
},
|
||||
{
|
||||
"attributes":
|
||||
{
|
||||
"constant": false,
|
||||
"name": "c",
|
||||
"overrides": null,
|
||||
"scope": 17,
|
||||
"stateVariable": true,
|
||||
"storageLocation": "default",
|
||||
"type": "mapping(enum C.E => bool)",
|
||||
"value": null,
|
||||
"visibility": "internal"
|
||||
},
|
||||
"children":
|
||||
[
|
||||
{
|
||||
"attributes":
|
||||
{
|
||||
"type": "mapping(enum C.E => bool)"
|
||||
},
|
||||
"children":
|
||||
[
|
||||
{
|
||||
"attributes":
|
||||
{
|
||||
"contractScope": null,
|
||||
"name": "E",
|
||||
"referencedDeclaration": 4,
|
||||
"type": "enum C.E"
|
||||
},
|
||||
"id": 13,
|
||||
"name": "UserDefinedTypeName",
|
||||
"src": "106:1:1"
|
||||
},
|
||||
{
|
||||
"attributes":
|
||||
{
|
||||
"name": "bool",
|
||||
"type": "bool"
|
||||
},
|
||||
"id": 14,
|
||||
"name": "ElementaryTypeName",
|
||||
"src": "111:4:1"
|
||||
}
|
||||
],
|
||||
"id": 15,
|
||||
"name": "Mapping",
|
||||
"src": "98:18:1"
|
||||
}
|
||||
],
|
||||
"id": 16,
|
||||
"name": "VariableDeclaration",
|
||||
"src": "98:20:1"
|
||||
}
|
||||
],
|
||||
"id": 17,
|
||||
"name": "ContractDefinition",
|
||||
"src": "0:121:1"
|
||||
}
|
||||
],
|
||||
"id": 18,
|
||||
"name": "SourceUnit",
|
||||
"src": "0:122:1"
|
||||
}
|
||||
@@ -15,8 +15,9 @@
|
||||
along with solidity. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <boost/algorithm/string/replace.hpp>
|
||||
#include <test/libsolidity/ASTJSONTest.h>
|
||||
#include <test/Options.h>
|
||||
#include <test/Common.h>
|
||||
#include <libsolutil/AnsiColorized.h>
|
||||
#include <liblangutil/SourceReferenceFormatterHuman.h>
|
||||
#include <libsolidity/ast/ASTJsonConverter.h>
|
||||
@@ -24,6 +25,7 @@
|
||||
#include <boost/algorithm/string.hpp>
|
||||
#include <boost/algorithm/string/predicate.hpp>
|
||||
#include <boost/throw_exception.hpp>
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#include <fstream>
|
||||
#include <memory>
|
||||
#include <stdexcept>
|
||||
@@ -38,6 +40,30 @@ using namespace std;
|
||||
namespace fs = boost::filesystem;
|
||||
using namespace boost::unit_test;
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
void replaceVersionWithTag(string& _input)
|
||||
{
|
||||
boost::algorithm::replace_all(
|
||||
_input,
|
||||
"\"" + solidity::test::CommonOptions::get().evmVersion().name() + "\"",
|
||||
"%EVMVERSION%"
|
||||
);
|
||||
}
|
||||
|
||||
void replaceTagWithVersion(string& _input)
|
||||
{
|
||||
boost::algorithm::replace_all(
|
||||
_input,
|
||||
"%EVMVERSION%",
|
||||
"\"" + solidity::test::CommonOptions::get().evmVersion().name() + "\""
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
ASTJSONTest::ASTJSONTest(string const& _filename)
|
||||
{
|
||||
if (!boost::algorithm::ends_with(_filename, ".sol"))
|
||||
@@ -103,7 +129,7 @@ TestCase::TestResult ASTJSONTest::run(ostream& _stream, string const& _linePrefi
|
||||
sourceIndices[m_sources[i].first] = i + 1;
|
||||
}
|
||||
c.setSources(sources);
|
||||
c.setEVMVersion(solidity::test::Options::get().evmVersion());
|
||||
c.setEVMVersion(solidity::test::CommonOptions::get().evmVersion());
|
||||
if (c.parse())
|
||||
c.analyze();
|
||||
else
|
||||
@@ -126,6 +152,8 @@ TestCase::TestResult ASTJSONTest::run(ostream& _stream, string const& _linePrefi
|
||||
|
||||
bool resultsMatch = true;
|
||||
|
||||
replaceTagWithVersion(m_expectation);
|
||||
|
||||
if (m_expectation != m_result)
|
||||
{
|
||||
string nextIndentLevel = _linePrefix + " ";
|
||||
@@ -158,6 +186,8 @@ TestCase::TestResult ASTJSONTest::run(ostream& _stream, string const& _linePrefi
|
||||
m_resultLegacy += "\n";
|
||||
}
|
||||
|
||||
replaceTagWithVersion(m_expectationLegacy);
|
||||
|
||||
if (m_expectationLegacy != m_resultLegacy)
|
||||
{
|
||||
string nextIndentLevel = _linePrefix + " ";
|
||||
@@ -202,12 +232,21 @@ void ASTJSONTest::printUpdatedExpectations(std::ostream&, std::string const&) co
|
||||
ofstream file(m_astFilename.c_str());
|
||||
if (!file) BOOST_THROW_EXCEPTION(runtime_error("Cannot write AST expectation to \"" + m_astFilename + "\"."));
|
||||
file.exceptions(ios::badbit);
|
||||
file << m_result;
|
||||
|
||||
string replacedResult = m_result;
|
||||
replaceVersionWithTag(replacedResult);
|
||||
|
||||
file << replacedResult;
|
||||
file.flush();
|
||||
file.close();
|
||||
|
||||
file.open(m_legacyAstFilename.c_str());
|
||||
if (!file) BOOST_THROW_EXCEPTION(runtime_error("Cannot write legacy AST expectation to \"" + m_legacyAstFilename + "\"."));
|
||||
file << m_resultLegacy;
|
||||
|
||||
string replacedResultLegacy = m_resultLegacy;
|
||||
replaceVersionWithTag(replacedResultLegacy);
|
||||
|
||||
file << replacedResultLegacy;
|
||||
file.flush();
|
||||
file.close();
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
|
||||
#include <test/libsolidity/AnalysisFramework.h>
|
||||
|
||||
#include <test/Options.h>
|
||||
#include <test/Common.h>
|
||||
|
||||
#include <libsolidity/interface/CompilerStack.h>
|
||||
#include <liblangutil/SourceReferenceFormatter.h>
|
||||
@@ -51,7 +51,7 @@ AnalysisFramework::parseAnalyseAndReturnError(
|
||||
{
|
||||
compiler().reset();
|
||||
compiler().setSources({{"", _insertVersionPragma ? "pragma solidity >=0.0;\n" + _source : _source}});
|
||||
compiler().setEVMVersion(solidity::test::Options::get().evmVersion());
|
||||
compiler().setEVMVersion(solidity::test::CommonOptions::get().evmVersion());
|
||||
compiler().setParserErrorRecovery(_allowRecoveryErrors);
|
||||
_allowMultipleErrors = _allowMultipleErrors || _allowRecoveryErrors;
|
||||
if (!compiler().parse())
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
* Unit tests for Assembly Items from evmasm/Assembly.h
|
||||
*/
|
||||
|
||||
#include <test/Options.h>
|
||||
#include <test/Common.h>
|
||||
|
||||
#include <liblangutil/SourceLocation.h>
|
||||
#include <libevmasm/Assembly.h>
|
||||
@@ -52,14 +52,14 @@ evmasm::AssemblyItems compileContract(std::shared_ptr<CharStream> _sourceCode)
|
||||
{
|
||||
ErrorList errors;
|
||||
ErrorReporter errorReporter(errors);
|
||||
Parser parser(errorReporter, solidity::test::Options::get().evmVersion());
|
||||
Parser parser(errorReporter, solidity::test::CommonOptions::get().evmVersion());
|
||||
ASTPointer<SourceUnit> sourceUnit;
|
||||
BOOST_REQUIRE_NO_THROW(sourceUnit = parser.parse(make_shared<Scanner>(_sourceCode)));
|
||||
BOOST_CHECK(!!sourceUnit);
|
||||
|
||||
map<ASTNode const*, shared_ptr<DeclarationContainer>> scopes;
|
||||
GlobalContext globalContext;
|
||||
NameAndTypeResolver resolver(globalContext, solidity::test::Options::get().evmVersion(), scopes, errorReporter);
|
||||
NameAndTypeResolver resolver(globalContext, solidity::test::CommonOptions::get().evmVersion(), scopes, errorReporter);
|
||||
solAssert(Error::containsOnlyWarnings(errorReporter.errors()), "");
|
||||
resolver.registerDeclarations(*sourceUnit);
|
||||
for (ASTPointer<ASTNode> const& node: sourceUnit->nodes())
|
||||
@@ -72,7 +72,7 @@ evmasm::AssemblyItems compileContract(std::shared_ptr<CharStream> _sourceCode)
|
||||
for (ASTPointer<ASTNode> const& node: sourceUnit->nodes())
|
||||
if (ContractDefinition* contract = dynamic_cast<ContractDefinition*>(node.get()))
|
||||
{
|
||||
TypeChecker checker(solidity::test::Options::get().evmVersion(), errorReporter);
|
||||
TypeChecker checker(solidity::test::CommonOptions::get().evmVersion(), errorReporter);
|
||||
BOOST_REQUIRE_NO_THROW(checker.checkTypeRequirements(*contract));
|
||||
if (!Error::containsOnlyWarnings(errorReporter.errors()))
|
||||
return AssemblyItems();
|
||||
@@ -81,9 +81,9 @@ evmasm::AssemblyItems compileContract(std::shared_ptr<CharStream> _sourceCode)
|
||||
if (ContractDefinition* contract = dynamic_cast<ContractDefinition*>(node.get()))
|
||||
{
|
||||
Compiler compiler(
|
||||
solidity::test::Options::get().evmVersion(),
|
||||
solidity::test::CommonOptions::get().evmVersion(),
|
||||
RevertStrings::Default,
|
||||
solidity::test::Options::get().optimize ? OptimiserSettings::standard() : OptimiserSettings::minimal()
|
||||
solidity::test::CommonOptions::get().optimize ? OptimiserSettings::standard() : OptimiserSettings::minimal()
|
||||
);
|
||||
compiler.compileContract(*contract, map<ContractDefinition const*, shared_ptr<Compiler const>>{}, bytes());
|
||||
|
||||
@@ -161,34 +161,40 @@ BOOST_AUTO_TEST_CASE(location_test)
|
||||
}
|
||||
)", "");
|
||||
AssemblyItems items = compileContract(sourceCode);
|
||||
bool hasShifts = solidity::test::Options::get().evmVersion().hasBitwiseShifting();
|
||||
bool hasShifts = solidity::test::CommonOptions::get().evmVersion().hasBitwiseShifting();
|
||||
|
||||
auto codegenCharStream = make_shared<CharStream>("", "--CODEGEN--");
|
||||
|
||||
vector<SourceLocation> locations;
|
||||
if (solidity::test::Options::get().optimize)
|
||||
if (solidity::test::CommonOptions::get().optimize)
|
||||
locations =
|
||||
vector<SourceLocation>(4, SourceLocation{2, 82, sourceCode}) +
|
||||
vector<SourceLocation>(1, SourceLocation{8, 17, codegenCharStream}) +
|
||||
vector<SourceLocation>(3, SourceLocation{5, 7, codegenCharStream}) +
|
||||
vector<SourceLocation>(1, SourceLocation{30, 31, codegenCharStream}) +
|
||||
vector<SourceLocation>(1, SourceLocation{5, 14, codegenCharStream}) +
|
||||
vector<SourceLocation>(3, SourceLocation{2, 4, codegenCharStream}) +
|
||||
vector<SourceLocation>(1, SourceLocation{27, 28, codegenCharStream}) +
|
||||
vector<SourceLocation>(1, SourceLocation{20, 32, codegenCharStream}) +
|
||||
vector<SourceLocation>(1, SourceLocation{5, 7, codegenCharStream}) +
|
||||
vector<SourceLocation>(19, SourceLocation{2, 82, sourceCode}) +
|
||||
vector<SourceLocation>(1, SourceLocation{24, 25, codegenCharStream}) +
|
||||
vector<SourceLocation>(1, SourceLocation{17, 29, codegenCharStream}) +
|
||||
vector<SourceLocation>(1, SourceLocation{2, 4, codegenCharStream}) +
|
||||
vector<SourceLocation>(16, SourceLocation{2, 82, sourceCode}) +
|
||||
vector<SourceLocation>(1, SourceLocation{12, 13, codegenCharStream}) +
|
||||
vector<SourceLocation>(1, SourceLocation{9, 10, codegenCharStream}) +
|
||||
vector<SourceLocation>(1, SourceLocation{2, 14, codegenCharStream}) +
|
||||
vector<SourceLocation>(21, SourceLocation{20, 79, sourceCode}) +
|
||||
vector<SourceLocation>(1, SourceLocation{72, 74, sourceCode}) +
|
||||
vector<SourceLocation>(2, SourceLocation{20, 79, sourceCode});
|
||||
else
|
||||
locations =
|
||||
vector<SourceLocation>(4, SourceLocation{2, 82, sourceCode}) +
|
||||
vector<SourceLocation>(1, SourceLocation{8, 17, codegenCharStream}) +
|
||||
vector<SourceLocation>(3, SourceLocation{5, 7, codegenCharStream}) +
|
||||
vector<SourceLocation>(1, SourceLocation{30, 31, codegenCharStream}) +
|
||||
vector<SourceLocation>(1, SourceLocation{5, 14, codegenCharStream}) +
|
||||
vector<SourceLocation>(3, SourceLocation{2, 4, codegenCharStream}) +
|
||||
vector<SourceLocation>(1, SourceLocation{27, 28, codegenCharStream}) +
|
||||
vector<SourceLocation>(1, SourceLocation{20, 32, codegenCharStream}) +
|
||||
vector<SourceLocation>(1, SourceLocation{5, 7, codegenCharStream}) +
|
||||
vector<SourceLocation>(hasShifts ? 19 : 20, SourceLocation{2, 82, sourceCode}) +
|
||||
vector<SourceLocation>(1, SourceLocation{24, 25, codegenCharStream}) +
|
||||
vector<SourceLocation>(1, SourceLocation{17, 29, codegenCharStream}) +
|
||||
vector<SourceLocation>(1, SourceLocation{2, 4, codegenCharStream}) +
|
||||
vector<SourceLocation>(hasShifts ? 16 : 17, SourceLocation{2, 82, sourceCode}) +
|
||||
vector<SourceLocation>(1, SourceLocation{12, 13, codegenCharStream}) +
|
||||
vector<SourceLocation>(1, SourceLocation{9, 10, codegenCharStream}) +
|
||||
vector<SourceLocation>(1, SourceLocation{2, 14, codegenCharStream}) +
|
||||
vector<SourceLocation>(24, SourceLocation{20, 79, sourceCode}) +
|
||||
vector<SourceLocation>(1, SourceLocation{49, 58, sourceCode}) +
|
||||
vector<SourceLocation>(1, SourceLocation{72, 74, sourceCode}) +
|
||||
|
||||
@@ -93,14 +93,14 @@ BOOST_AUTO_TEST_CASE(string_storage)
|
||||
m_compiler.overwriteReleaseFlag(true);
|
||||
compileAndRun(sourceCode);
|
||||
|
||||
auto evmVersion = solidity::test::Options::get().evmVersion();
|
||||
auto evmVersion = solidity::test::CommonOptions::get().evmVersion();
|
||||
|
||||
if (evmVersion <= EVMVersion::byzantium())
|
||||
CHECK_DEPLOY_GAS(134145, 130831, evmVersion);
|
||||
// This is only correct on >=Constantinople.
|
||||
else if (Options::get().useABIEncoderV2)
|
||||
else if (CommonOptions::get().useABIEncoderV2)
|
||||
{
|
||||
if (Options::get().optimizeYul)
|
||||
if (CommonOptions::get().optimizeYul)
|
||||
{
|
||||
// Costs with 0 are cases which cannot be triggered in tests.
|
||||
if (evmVersion < EVMVersion::istanbul())
|
||||
@@ -127,9 +127,9 @@ BOOST_AUTO_TEST_CASE(string_storage)
|
||||
if (evmVersion == EVMVersion::byzantium())
|
||||
CHECK_GAS(21545, 21526, 20);
|
||||
// This is only correct on >=Constantinople.
|
||||
else if (Options::get().useABIEncoderV2)
|
||||
else if (CommonOptions::get().useABIEncoderV2)
|
||||
{
|
||||
if (Options::get().optimizeYul)
|
||||
if (CommonOptions::get().optimizeYul)
|
||||
{
|
||||
if (evmVersion < EVMVersion::istanbul())
|
||||
CHECK_GAS(0, 21567, 20);
|
||||
|
||||
@@ -44,7 +44,7 @@ public:
|
||||
{
|
||||
m_compiler.reset();
|
||||
m_compiler.setSources({{"", "pragma solidity >=0.0;\n" + _sourceCode}});
|
||||
m_compiler.setOptimiserSettings(solidity::test::Options::get().optimize);
|
||||
m_compiler.setOptimiserSettings(solidity::test::CommonOptions::get().optimize);
|
||||
m_compiler.setEVMVersion(m_evmVersion);
|
||||
BOOST_REQUIRE_MESSAGE(m_compiler.compile(), "Compiling contract failed");
|
||||
|
||||
@@ -52,7 +52,7 @@ public:
|
||||
ASTNode const& sourceUnit = m_compiler.ast("");
|
||||
BOOST_REQUIRE(items != nullptr);
|
||||
m_gasCosts = GasEstimator::breakToStatementLevel(
|
||||
GasEstimator(solidity::test::Options::get().evmVersion()).structuralEstimation(*items, vector<ASTNode const*>({&sourceUnit})),
|
||||
GasEstimator(solidity::test::CommonOptions::get().evmVersion()).structuralEstimation(*items, vector<ASTNode const*>({&sourceUnit})),
|
||||
{&sourceUnit}
|
||||
);
|
||||
}
|
||||
@@ -61,7 +61,7 @@ public:
|
||||
{
|
||||
compileAndRun(_sourceCode);
|
||||
auto state = make_shared<KnownState>();
|
||||
PathGasMeter meter(*m_compiler.assemblyItems(m_compiler.lastContractName()), solidity::test::Options::get().evmVersion());
|
||||
PathGasMeter meter(*m_compiler.assemblyItems(m_compiler.lastContractName()), solidity::test::CommonOptions::get().evmVersion());
|
||||
GasMeter::GasConsumption gas = meter.estimateMax(0, state);
|
||||
u256 bytecodeSize(m_compiler.runtimeObject(m_compiler.lastContractName()).bytecode.size());
|
||||
// costs for deployment
|
||||
@@ -71,7 +71,7 @@ public:
|
||||
|
||||
// Skip the tests when we force ABIEncoderV2.
|
||||
// TODO: We should enable this again once the yul optimizer is activated.
|
||||
if (!solidity::test::Options::get().useABIEncoderV2)
|
||||
if (!solidity::test::CommonOptions::get().useABIEncoderV2)
|
||||
{
|
||||
BOOST_REQUIRE(!gas.isInfinite);
|
||||
BOOST_CHECK_LE(m_gasUsed, gas.value);
|
||||
@@ -94,13 +94,13 @@ public:
|
||||
gas = max(gas, gasForTransaction(hash.asBytes() + arguments, false));
|
||||
}
|
||||
|
||||
gas += GasEstimator(solidity::test::Options::get().evmVersion()).functionalEstimation(
|
||||
gas += GasEstimator(solidity::test::CommonOptions::get().evmVersion()).functionalEstimation(
|
||||
*m_compiler.runtimeAssemblyItems(m_compiler.lastContractName()),
|
||||
_sig
|
||||
);
|
||||
// Skip the tests when we force ABIEncoderV2.
|
||||
// TODO: We should enable this again once the yul optimizer is activated.
|
||||
if (!solidity::test::Options::get().useABIEncoderV2)
|
||||
if (!solidity::test::CommonOptions::get().useABIEncoderV2)
|
||||
{
|
||||
BOOST_REQUIRE(!gas.isInfinite);
|
||||
BOOST_CHECK_LE(m_gasUsed, gas.value);
|
||||
@@ -110,7 +110,7 @@ public:
|
||||
|
||||
static GasMeter::GasConsumption gasForTransaction(bytes const& _data, bool _isCreation)
|
||||
{
|
||||
auto evmVersion = solidity::test::Options::get().evmVersion();
|
||||
auto evmVersion = solidity::test::CommonOptions::get().evmVersion();
|
||||
GasMeter::GasConsumption gas = _isCreation ? GasCosts::txCreateGas : GasCosts::txGas;
|
||||
for (auto i: _data)
|
||||
gas += i != 0 ? GasCosts::txDataNonZeroGas(evmVersion) : GasCosts::txDataZeroGas;
|
||||
@@ -261,6 +261,9 @@ BOOST_AUTO_TEST_CASE(exponent_size)
|
||||
{
|
||||
char const* sourceCode = R"(
|
||||
contract A {
|
||||
function f(uint x) public returns (uint) {
|
||||
return x ** 0;
|
||||
}
|
||||
function g(uint x) public returns (uint) {
|
||||
return x ** 0x100;
|
||||
}
|
||||
@@ -270,6 +273,7 @@ BOOST_AUTO_TEST_CASE(exponent_size)
|
||||
}
|
||||
)";
|
||||
testCreationTimeGas(sourceCode);
|
||||
testRunTimeGas("f(uint256)", vector<bytes>{encodeArgs(2)});
|
||||
testRunTimeGas("g(uint256)", vector<bytes>{encodeArgs(2)});
|
||||
testRunTimeGas("h(uint256)", vector<bytes>{encodeArgs(2)});
|
||||
}
|
||||
|
||||
@@ -16,12 +16,14 @@
|
||||
*/
|
||||
|
||||
#include <test/libsolidity/GasTest.h>
|
||||
#include <test/Options.h>
|
||||
#include <test/Common.h>
|
||||
#include <libsolutil/CommonIO.h>
|
||||
#include <libsolutil/JSON.h>
|
||||
#include <liblangutil/SourceReferenceFormatterHuman.h>
|
||||
#include <boost/algorithm/string.hpp>
|
||||
#include <boost/algorithm/string/predicate.hpp>
|
||||
#include <boost/filesystem.hpp>
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#include <boost/throw_exception.hpp>
|
||||
#include <fstream>
|
||||
#include <stdexcept>
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
*/
|
||||
|
||||
#include <test/libsolidity/ErrorCheck.h>
|
||||
#include <test/Options.h>
|
||||
#include <test/Common.h>
|
||||
|
||||
#include <liblangutil/Exceptions.h>
|
||||
#include <libsolidity/interface/CompilerStack.h>
|
||||
@@ -47,7 +47,7 @@ BOOST_AUTO_TEST_CASE(remappings)
|
||||
{"s_1.4.6/s.sol", "contract S {} pragma solidity >=0.0;"},
|
||||
{"Tee/tee.sol", "contract Tee {} pragma solidity >=0.0;"}
|
||||
});
|
||||
c.setEVMVersion(solidity::test::Options::get().evmVersion());
|
||||
c.setEVMVersion(solidity::test::CommonOptions::get().evmVersion());
|
||||
BOOST_CHECK(c.compile());
|
||||
}
|
||||
|
||||
@@ -61,7 +61,7 @@ BOOST_AUTO_TEST_CASE(context_dependent_remappings)
|
||||
{"s_1.4.6/s.sol", "contract SSix {} pragma solidity >=0.0;"},
|
||||
{"s_1.4.7/s.sol", "contract SSeven {} pragma solidity >=0.0;"}
|
||||
});
|
||||
c.setEVMVersion(solidity::test::Options::get().evmVersion());
|
||||
c.setEVMVersion(solidity::test::CommonOptions::get().evmVersion());
|
||||
BOOST_CHECK(c.compile());
|
||||
}
|
||||
|
||||
@@ -79,7 +79,7 @@ BOOST_AUTO_TEST_CASE(context_dependent_remappings_ensure_default_and_module_pres
|
||||
{"vendor/foo_1.0.0/foo.sol", "contract Foo1 {} pragma solidity >=0.0;"},
|
||||
{"vendor/foo_2.0.0/foo.sol", "contract Foo2 {} pragma solidity >=0.0;"}
|
||||
});
|
||||
c.setEVMVersion(solidity::test::Options::get().evmVersion());
|
||||
c.setEVMVersion(solidity::test::CommonOptions::get().evmVersion());
|
||||
BOOST_CHECK(c.compile());
|
||||
}
|
||||
|
||||
@@ -93,7 +93,7 @@ BOOST_AUTO_TEST_CASE(context_dependent_remappings_order_independent_1)
|
||||
{"d/z.sol", "contract D {} pragma solidity >=0.0;"},
|
||||
{"e/y/z/z.sol", "contract E {} pragma solidity >=0.0;"}
|
||||
});
|
||||
c.setEVMVersion(solidity::test::Options::get().evmVersion());
|
||||
c.setEVMVersion(solidity::test::CommonOptions::get().evmVersion());
|
||||
BOOST_CHECK(c.compile());
|
||||
}
|
||||
|
||||
@@ -107,7 +107,7 @@ BOOST_AUTO_TEST_CASE(context_dependent_remappings_order_independent_2)
|
||||
{"d/z.sol", "contract D {} pragma solidity >=0.0;"},
|
||||
{"e/y/z/z.sol", "contract E {} pragma solidity >=0.0;"}
|
||||
});
|
||||
c.setEVMVersion(solidity::test::Options::get().evmVersion());
|
||||
c.setEVMVersion(solidity::test::CommonOptions::get().evmVersion());
|
||||
BOOST_CHECK(c.compile());
|
||||
}
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
* Unit tests for inline assembly.
|
||||
*/
|
||||
|
||||
#include <test/Options.h>
|
||||
#include <test/Common.h>
|
||||
|
||||
#include <test/libsolidity/ErrorCheck.h>
|
||||
|
||||
@@ -35,6 +35,7 @@
|
||||
#include <libevmasm/Assembly.h>
|
||||
|
||||
#include <boost/algorithm/string/replace.hpp>
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
@@ -58,7 +59,7 @@ std::optional<Error> parseAndReturnFirstError(
|
||||
AssemblyStack::Machine _machine = AssemblyStack::Machine::EVM
|
||||
)
|
||||
{
|
||||
AssemblyStack stack(solidity::test::Options::get().evmVersion(), _language, solidity::frontend::OptimiserSettings::none());
|
||||
AssemblyStack stack(solidity::test::CommonOptions::get().evmVersion(), _language, solidity::frontend::OptimiserSettings::none());
|
||||
bool success = false;
|
||||
try
|
||||
{
|
||||
@@ -125,7 +126,7 @@ Error expectError(
|
||||
|
||||
void parsePrintCompare(string const& _source, bool _canWarn = false)
|
||||
{
|
||||
AssemblyStack stack(solidity::test::Options::get().evmVersion(), AssemblyStack::Language::Assembly, OptimiserSettings::none());
|
||||
AssemblyStack stack(solidity::test::CommonOptions::get().evmVersion(), AssemblyStack::Language::Assembly, OptimiserSettings::none());
|
||||
BOOST_REQUIRE(stack.parseAndAnalyze("", _source));
|
||||
if (_canWarn)
|
||||
BOOST_REQUIRE(Error::containsOnlyWarnings(stack.errors()));
|
||||
@@ -224,8 +225,8 @@ BOOST_AUTO_TEST_CASE(vardecl_multi_conflict)
|
||||
|
||||
BOOST_AUTO_TEST_CASE(vardecl_bool)
|
||||
{
|
||||
CHECK_PARSE_ERROR("{ let x := true }", ParserError, "True and false are not valid literals.");
|
||||
CHECK_PARSE_ERROR("{ let x := false }", ParserError, "True and false are not valid literals.");
|
||||
successParse("{ let x := true }");
|
||||
successParse("{ let x := false }");
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(vardecl_empty)
|
||||
@@ -286,7 +287,7 @@ BOOST_AUTO_TEST_CASE(if_statement_invalid)
|
||||
{
|
||||
CHECK_PARSE_ERROR("{ if mload {} }", ParserError, "Expected '(' but got '{'");
|
||||
BOOST_CHECK("{ if calldatasize() {}");
|
||||
CHECK_PARSE_ERROR("{ if mstore(1, 1) {} }", TypeError, "Expected expression to return one item to the stack, but did return 0 items");
|
||||
CHECK_PARSE_ERROR("{ if mstore(1, 1) {} }", TypeError, "Expected expression to evaluate to one value, but got 0 values instead.");
|
||||
CHECK_PARSE_ERROR("{ if 32 let x := 3 }", ParserError, "Expected '{' but got reserved keyword 'let'");
|
||||
}
|
||||
|
||||
@@ -313,9 +314,9 @@ BOOST_AUTO_TEST_CASE(switch_duplicate_case)
|
||||
|
||||
BOOST_AUTO_TEST_CASE(switch_invalid_expression)
|
||||
{
|
||||
CHECK_PARSE_ERROR("{ switch {} default {} }", ParserError, "Literal, identifier or instruction expected.");
|
||||
CHECK_PARSE_ERROR("{ switch {} default {} }", ParserError, "Literal or identifier expected.");
|
||||
CHECK_PARSE_ERROR("{ switch mload default {} }", ParserError, "Expected '(' but got reserved keyword 'default'");
|
||||
CHECK_PARSE_ERROR("{ switch mstore(1, 1) default {} }", TypeError, "Expected expression to return one item to the stack, but did return 0 items");
|
||||
CHECK_PARSE_ERROR("{ switch mstore(1, 1) default {} }", TypeError, "Expected expression to evaluate to one value, but got 0 values instead.");
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(switch_default_before_case)
|
||||
@@ -346,12 +347,12 @@ BOOST_AUTO_TEST_CASE(for_statement)
|
||||
|
||||
BOOST_AUTO_TEST_CASE(for_invalid_expression)
|
||||
{
|
||||
CHECK_PARSE_ERROR("{ for {} {} {} {} }", ParserError, "Literal, identifier or instruction expected.");
|
||||
CHECK_PARSE_ERROR("{ for {} {} {} {} }", ParserError, "Literal or identifier expected.");
|
||||
CHECK_PARSE_ERROR("{ for 1 1 {} {} }", ParserError, "Expected '{' but got 'Number'");
|
||||
CHECK_PARSE_ERROR("{ for {} 1 1 {} }", ParserError, "Expected '{' but got 'Number'");
|
||||
CHECK_PARSE_ERROR("{ for {} 1 {} 1 }", ParserError, "Expected '{' but got 'Number'");
|
||||
CHECK_PARSE_ERROR("{ for {} mload {} {} }", ParserError, "Expected '(' but got '{'");
|
||||
CHECK_PARSE_ERROR("{ for {} mstore(1, 1) {} {} }", TypeError, "Expected expression to return one item to the stack, but did return 0 items");
|
||||
CHECK_PARSE_ERROR("{ for {} mstore(1, 1) {} {} }", TypeError, "Expected expression to evaluate to one value, but got 0 values instead.");
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(for_visibility)
|
||||
@@ -538,7 +539,7 @@ BOOST_AUTO_TEST_CASE(print_string_literal_unicode)
|
||||
{
|
||||
string source = "{ let x := \"\\u1bac\" }";
|
||||
string parsed = "object \"object\" {\n code { let x := \"\\xe1\\xae\\xac\" }\n}\n";
|
||||
AssemblyStack stack(solidity::test::Options::get().evmVersion(), AssemblyStack::Language::Assembly, OptimiserSettings::none());
|
||||
AssemblyStack stack(solidity::test::CommonOptions::get().evmVersion(), AssemblyStack::Language::Assembly, OptimiserSettings::none());
|
||||
BOOST_REQUIRE(stack.parseAndAnalyze("", source));
|
||||
BOOST_REQUIRE(stack.errors().empty());
|
||||
BOOST_CHECK_EQUAL(stack.print(), parsed);
|
||||
@@ -685,42 +686,42 @@ BOOST_AUTO_TEST_CASE(keccak256)
|
||||
|
||||
BOOST_AUTO_TEST_CASE(returndatasize)
|
||||
{
|
||||
if (!solidity::test::Options::get().evmVersion().supportsReturndata())
|
||||
if (!solidity::test::CommonOptions::get().evmVersion().supportsReturndata())
|
||||
return;
|
||||
BOOST_CHECK(successAssemble("{ let r := returndatasize() }"));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(returndatacopy)
|
||||
{
|
||||
if (!solidity::test::Options::get().evmVersion().supportsReturndata())
|
||||
if (!solidity::test::CommonOptions::get().evmVersion().supportsReturndata())
|
||||
return;
|
||||
BOOST_CHECK(successAssemble("{ returndatacopy(0, 32, 64) }"));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(returndatacopy_functional)
|
||||
{
|
||||
if (!solidity::test::Options::get().evmVersion().supportsReturndata())
|
||||
if (!solidity::test::CommonOptions::get().evmVersion().supportsReturndata())
|
||||
return;
|
||||
BOOST_CHECK(successAssemble("{ returndatacopy(0, 32, 64) }"));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(staticcall)
|
||||
{
|
||||
if (!solidity::test::Options::get().evmVersion().hasStaticCall())
|
||||
if (!solidity::test::CommonOptions::get().evmVersion().hasStaticCall())
|
||||
return;
|
||||
BOOST_CHECK(successAssemble("{ pop(staticcall(10000, 0x123, 64, 0x10, 128, 0x10)) }"));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(create2)
|
||||
{
|
||||
if (!solidity::test::Options::get().evmVersion().hasCreate2())
|
||||
if (!solidity::test::CommonOptions::get().evmVersion().hasCreate2())
|
||||
return;
|
||||
BOOST_CHECK(successAssemble("{ pop(create2(10, 0x123, 32, 64)) }"));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(shift)
|
||||
{
|
||||
if (!solidity::test::Options::get().evmVersion().hasBitwiseShifting())
|
||||
if (!solidity::test::CommonOptions::get().evmVersion().hasBitwiseShifting())
|
||||
return;
|
||||
BOOST_CHECK(successAssemble("{ pop(shl(10, 32)) }"));
|
||||
BOOST_CHECK(successAssemble("{ pop(shr(10, 32)) }"));
|
||||
@@ -729,11 +730,11 @@ BOOST_AUTO_TEST_CASE(shift)
|
||||
|
||||
BOOST_AUTO_TEST_CASE(shift_constantinople_warning)
|
||||
{
|
||||
if (solidity::test::Options::get().evmVersion().hasBitwiseShifting())
|
||||
if (solidity::test::CommonOptions::get().evmVersion().hasBitwiseShifting())
|
||||
return;
|
||||
CHECK_PARSE_WARNING("{ pop(shl(10, 32)) }", TypeError, "The \"shl\" instruction is only available for Constantinople-compatible VMs");
|
||||
CHECK_PARSE_WARNING("{ pop(shr(10, 32)) }", TypeError, "The \"shr\" instruction is only available for Constantinople-compatible VMs");
|
||||
CHECK_PARSE_WARNING("{ pop(sar(10, 32)) }", TypeError, "The \"sar\" instruction is only available for Constantinople-compatible VMs");
|
||||
CHECK_PARSE_WARNING("{ shl(10, 32) }", TypeError, "The \"shl\" instruction is only available for Constantinople-compatible VMs");
|
||||
CHECK_PARSE_WARNING("{ shr(10, 32) }", TypeError, "The \"shr\" instruction is only available for Constantinople-compatible VMs");
|
||||
CHECK_PARSE_WARNING("{ sar(10, 32) }", TypeError, "The \"sar\" instruction is only available for Constantinople-compatible VMs");
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(jump_error)
|
||||
|
||||
@@ -20,13 +20,15 @@
|
||||
*/
|
||||
|
||||
#include <test/Metadata.h>
|
||||
#include <test/Options.h>
|
||||
#include <test/Common.h>
|
||||
#include <libsolidity/interface/CompilerStack.h>
|
||||
#include <libsolidity/interface/Version.h>
|
||||
#include <libsolutil/SwarmHash.h>
|
||||
#include <libsolutil/IpfsHash.h>
|
||||
#include <libsolutil/JSON.h>
|
||||
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace solidity::frontend::test
|
||||
@@ -66,8 +68,8 @@ BOOST_AUTO_TEST_CASE(metadata_stamp)
|
||||
CompilerStack compilerStack;
|
||||
compilerStack.overwriteReleaseFlag(release);
|
||||
compilerStack.setSources({{"", std::string(sourceCode)}});
|
||||
compilerStack.setEVMVersion(solidity::test::Options::get().evmVersion());
|
||||
compilerStack.setOptimiserSettings(solidity::test::Options::get().optimize);
|
||||
compilerStack.setEVMVersion(solidity::test::CommonOptions::get().evmVersion());
|
||||
compilerStack.setOptimiserSettings(solidity::test::CommonOptions::get().optimize);
|
||||
compilerStack.setMetadataHash(metadataHash);
|
||||
BOOST_REQUIRE_MESSAGE(compilerStack.compile(), "Compiling contract failed");
|
||||
bytes const& bytecode = compilerStack.runtimeObject("test").bytecode;
|
||||
@@ -127,8 +129,8 @@ BOOST_AUTO_TEST_CASE(metadata_stamp_experimental)
|
||||
CompilerStack compilerStack;
|
||||
compilerStack.overwriteReleaseFlag(release);
|
||||
compilerStack.setSources({{"", std::string(sourceCode)}});
|
||||
compilerStack.setEVMVersion(solidity::test::Options::get().evmVersion());
|
||||
compilerStack.setOptimiserSettings(solidity::test::Options::get().optimize);
|
||||
compilerStack.setEVMVersion(solidity::test::CommonOptions::get().evmVersion());
|
||||
compilerStack.setOptimiserSettings(solidity::test::CommonOptions::get().optimize);
|
||||
compilerStack.setMetadataHash(metadataHash);
|
||||
BOOST_REQUIRE_MESSAGE(compilerStack.compile(), "Compiling contract failed");
|
||||
bytes const& bytecode = compilerStack.runtimeObject("test").bytecode;
|
||||
@@ -189,8 +191,8 @@ BOOST_AUTO_TEST_CASE(metadata_relevant_sources)
|
||||
{"A", std::string(sourceCodeA)},
|
||||
{"B", std::string(sourceCodeB)},
|
||||
});
|
||||
compilerStack.setEVMVersion(solidity::test::Options::get().evmVersion());
|
||||
compilerStack.setOptimiserSettings(solidity::test::Options::get().optimize);
|
||||
compilerStack.setEVMVersion(solidity::test::CommonOptions::get().evmVersion());
|
||||
compilerStack.setOptimiserSettings(solidity::test::CommonOptions::get().optimize);
|
||||
BOOST_REQUIRE_MESSAGE(compilerStack.compile(), "Compiling contract failed");
|
||||
|
||||
std::string const& serialisedMetadata = compilerStack.metadata("A");
|
||||
@@ -230,8 +232,8 @@ BOOST_AUTO_TEST_CASE(metadata_relevant_sources_imports)
|
||||
{"B", std::string(sourceCodeB)},
|
||||
{"C", std::string(sourceCodeC)}
|
||||
});
|
||||
compilerStack.setEVMVersion(solidity::test::Options::get().evmVersion());
|
||||
compilerStack.setOptimiserSettings(solidity::test::Options::get().optimize);
|
||||
compilerStack.setEVMVersion(solidity::test::CommonOptions::get().evmVersion());
|
||||
compilerStack.setOptimiserSettings(solidity::test::CommonOptions::get().optimize);
|
||||
BOOST_REQUIRE_MESSAGE(compilerStack.compile(), "Compiling contract failed");
|
||||
|
||||
std::string const& serialisedMetadata = compilerStack.metadata("C");
|
||||
@@ -258,8 +260,8 @@ BOOST_AUTO_TEST_CASE(metadata_useLiteralContent)
|
||||
{
|
||||
CompilerStack compilerStack;
|
||||
compilerStack.setSources({{"", std::string(_src)}});
|
||||
compilerStack.setEVMVersion(solidity::test::Options::get().evmVersion());
|
||||
compilerStack.setOptimiserSettings(solidity::test::Options::get().optimize);
|
||||
compilerStack.setEVMVersion(solidity::test::CommonOptions::get().evmVersion());
|
||||
compilerStack.setOptimiserSettings(solidity::test::CommonOptions::get().optimize);
|
||||
compilerStack.useMetadataLiteralSources(_literal);
|
||||
BOOST_REQUIRE_MESSAGE(compilerStack.compile(), "Compiling contract failed");
|
||||
string metadata_str = compilerStack.metadata("test");
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
*/
|
||||
|
||||
#include <test/libsolidity/AnalysisFramework.h>
|
||||
#include <test/Options.h>
|
||||
#include <test/Common.h>
|
||||
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
@@ -83,7 +83,7 @@ BOOST_AUTO_TEST_CASE(import_base)
|
||||
}
|
||||
)"}
|
||||
});
|
||||
c.setEVMVersion(solidity::test::Options::get().evmVersion());
|
||||
c.setEVMVersion(solidity::test::CommonOptions::get().evmVersion());
|
||||
BOOST_CHECK(c.compile());
|
||||
|
||||
unsigned asserts = 0;
|
||||
@@ -122,7 +122,7 @@ BOOST_AUTO_TEST_CASE(import_library)
|
||||
}
|
||||
)"}
|
||||
});
|
||||
c.setEVMVersion(solidity::test::Options::get().evmVersion());
|
||||
c.setEVMVersion(solidity::test::CommonOptions::get().evmVersion());
|
||||
BOOST_CHECK(c.compile());
|
||||
|
||||
unsigned asserts = 0;
|
||||
|
||||
@@ -16,13 +16,14 @@
|
||||
*/
|
||||
|
||||
#include <test/libsolidity/SMTCheckerJSONTest.h>
|
||||
#include <test/Options.h>
|
||||
#include <test/Common.h>
|
||||
#include <libsolidity/interface/StandardCompiler.h>
|
||||
#include <libsolutil/CommonIO.h>
|
||||
#include <libsolutil/JSON.h>
|
||||
#include <boost/algorithm/string.hpp>
|
||||
#include <boost/algorithm/string/join.hpp>
|
||||
#include <boost/algorithm/string/predicate.hpp>
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#include <boost/throw_exception.hpp>
|
||||
#include <fstream>
|
||||
#include <memory>
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
*/
|
||||
|
||||
#include <test/libsolidity/SMTCheckerTest.h>
|
||||
#include <test/Options.h>
|
||||
#include <test/Common.h>
|
||||
|
||||
#include <libsolidity/formal/ModelChecker.h>
|
||||
|
||||
|
||||
@@ -25,7 +25,9 @@
|
||||
#include <tuple>
|
||||
#include <liblangutil/Scanner.h>
|
||||
#include <liblangutil/SemVerHandler.h>
|
||||
#include <test/Options.h>
|
||||
#include <test/Common.h>
|
||||
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
using namespace std;
|
||||
using namespace solidity::langutil;
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
*/
|
||||
|
||||
#include <test/libsolidity/SemanticTest.h>
|
||||
#include <test/Options.h>
|
||||
#include <test/Common.h>
|
||||
#include <boost/algorithm/string.hpp>
|
||||
#include <boost/algorithm/string/predicate.hpp>
|
||||
#include <boost/algorithm/string/trim.hpp>
|
||||
@@ -61,10 +61,42 @@ SemanticTest::SemanticTest(string const& _filename, langutil::EVMVersion _evmVer
|
||||
}
|
||||
m_settings.erase("compileViaYul");
|
||||
}
|
||||
if (m_settings.count("ABIEncoderV1Only"))
|
||||
{
|
||||
if (m_settings["ABIEncoderV1Only"] == "true")
|
||||
{
|
||||
m_validatedSettings["ABIEncoderV1Only"] = "true";
|
||||
m_runWithABIEncoderV1Only = true;
|
||||
}
|
||||
m_settings.erase("ABIEncoderV1Only");
|
||||
}
|
||||
|
||||
if (m_settings.count("revertStrings"))
|
||||
{
|
||||
auto revertStrings = revertStringsFromString(m_settings["revertStrings"]);
|
||||
if (revertStrings)
|
||||
m_revertStrings = *revertStrings;
|
||||
m_validatedSettings["revertStrings"] = revertStringsToString(m_revertStrings);
|
||||
m_settings.erase("revertStrings");
|
||||
}
|
||||
|
||||
if (m_settings.count("allowNonExistingFunctions"))
|
||||
{
|
||||
m_validatedSettings["allowNonExistingFunctions"] = true;
|
||||
m_settings.erase("allowNonExistingFunctions");
|
||||
}
|
||||
|
||||
parseExpectations(file);
|
||||
soltestAssert(!m_tests.empty(), "No tests specified in " + _filename);
|
||||
}
|
||||
|
||||
bool SemanticTest::validateSettings(langutil::EVMVersion _evmVersion)
|
||||
{
|
||||
if (m_runWithABIEncoderV1Only && solidity::test::CommonOptions::get().useABIEncoderV2)
|
||||
return false;
|
||||
return EVMVersionRestrictedTestCase::validateSettings(_evmVersion);
|
||||
}
|
||||
|
||||
TestCase::TestResult SemanticTest::run(ostream& _stream, string const& _linePrefix, bool _formatted)
|
||||
{
|
||||
for(bool compileViaYul: set<bool>{!m_runWithoutYul, m_runWithYul})
|
||||
@@ -101,7 +133,7 @@ TestCase::TestResult SemanticTest::run(ostream& _stream, string const& _linePref
|
||||
else
|
||||
{
|
||||
if (test.call().isConstructor)
|
||||
deploy("", test.call().value, test.call().arguments.rawBytes(), libraries);
|
||||
deploy("", test.call().value.value, test.call().arguments.rawBytes(), libraries);
|
||||
else
|
||||
soltestAssert(deploy("", 0, bytes(), libraries), "Failed to deploy contract.");
|
||||
constructed = true;
|
||||
@@ -117,13 +149,22 @@ TestCase::TestResult SemanticTest::run(ostream& _stream, string const& _linePref
|
||||
}
|
||||
else
|
||||
{
|
||||
bytes output = test.call().useCallWithoutSignature ?
|
||||
callLowLevel(test.call().arguments.rawBytes(), test.call().value) :
|
||||
callContractFunctionWithValueNoEncoding(
|
||||
bytes output;
|
||||
if (test.call().useCallWithoutSignature)
|
||||
output = callLowLevel(test.call().arguments.rawBytes(), test.call().value.value);
|
||||
else
|
||||
{
|
||||
soltestAssert(
|
||||
m_validatedSettings.count("allowNonExistingFunctions") || m_compiler.methodIdentifiers(m_compiler.lastContractName()).isMember(test.call().signature),
|
||||
"The function " + test.call().signature + " is not known to the compiler"
|
||||
);
|
||||
|
||||
output = callContractFunctionWithValueNoEncoding(
|
||||
test.call().signature,
|
||||
test.call().value,
|
||||
test.call().value.value,
|
||||
test.call().arguments.rawBytes()
|
||||
);
|
||||
}
|
||||
|
||||
if ((m_transactionSuccessful == test.call().expectations.failure) || (output != test.call().expectations.rawBytes()))
|
||||
success = false;
|
||||
|
||||
@@ -44,6 +44,8 @@ public:
|
||||
|
||||
explicit SemanticTest(std::string const& _filename, langutil::EVMVersion _evmVersion);
|
||||
|
||||
bool validateSettings(langutil::EVMVersion _evmVersion) override;
|
||||
|
||||
TestResult run(std::ostream& _stream, std::string const& _linePrefix = "", bool _formatted = false) override;
|
||||
void printSource(std::ostream &_stream, std::string const& _linePrefix = "", bool _formatted = false) const override;
|
||||
void printUpdatedExpectations(std::ostream& _stream, std::string const& _linePrefix = "") const override;
|
||||
@@ -64,6 +66,7 @@ private:
|
||||
std::vector<TestFunctionCall> m_tests;
|
||||
bool m_runWithYul = false;
|
||||
bool m_runWithoutYul = true;
|
||||
bool m_runWithABIEncoderV1Only = false;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -20,7 +20,9 @@
|
||||
|
||||
#include <test/libsolidity/AnalysisFramework.h>
|
||||
#include <test/Metadata.h>
|
||||
#include <test/Options.h>
|
||||
#include <test/Common.h>
|
||||
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
using namespace std;
|
||||
|
||||
@@ -38,7 +40,7 @@ BOOST_AUTO_TEST_CASE(does_not_include_creation_time_only_internal_functions)
|
||||
function f() internal { for (uint i = 0; i < 10; ++i) x += 3 + i; }
|
||||
}
|
||||
)";
|
||||
compiler().setOptimiserSettings(solidity::test::Options::get().optimize);
|
||||
compiler().setOptimiserSettings(solidity::test::CommonOptions::get().optimize);
|
||||
BOOST_REQUIRE(success(sourceCode));
|
||||
BOOST_REQUIRE_MESSAGE(compiler().compile(), "Compiling contract failed");
|
||||
bytes const& creationBytecode = solidity::test::bytecodeSansMetadata(compiler().object("C").bytecode);
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
|
||||
#include <test/libsolidity/SolidityExecutionFramework.h>
|
||||
|
||||
#include <test/Options.h>
|
||||
#include <test/Common.h>
|
||||
#include <test/EVMHost.h>
|
||||
|
||||
#include <liblangutil/Exceptions.h>
|
||||
@@ -784,26 +784,6 @@ BOOST_AUTO_TEST_CASE(small_signed_types)
|
||||
testContractAgainstCpp("run()", small_signed_types_cpp);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(strings)
|
||||
{
|
||||
char const* sourceCode = R"(
|
||||
contract test {
|
||||
function fixedBytes() public returns(bytes32 ret) {
|
||||
return "abc\x00\xff__";
|
||||
}
|
||||
function pipeThrough(bytes2 small, bool one) public returns(bytes16 large, bool oneRet) {
|
||||
oneRet = one;
|
||||
large = small;
|
||||
}
|
||||
}
|
||||
)";
|
||||
ALSO_VIA_YUL(
|
||||
compileAndRun(sourceCode);
|
||||
ABI_CHECK(callContractFunction("fixedBytes()"), encodeArgs(string("abc\0\xff__", 7)));
|
||||
ABI_CHECK(callContractFunction("pipeThrough(bytes2,bool)", string("\0\x02", 2), true), encodeArgs(string("\0\x2", 2), true));
|
||||
)
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(compound_assign)
|
||||
{
|
||||
char const* sourceCode = R"(
|
||||
@@ -843,40 +823,6 @@ BOOST_AUTO_TEST_CASE(compound_assign)
|
||||
)
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(simple_mapping)
|
||||
{
|
||||
char const* sourceCode = R"(
|
||||
contract test {
|
||||
mapping(uint8 => uint8) table;
|
||||
function get(uint8 k) public returns (uint8 v) {
|
||||
return table[k];
|
||||
}
|
||||
function set(uint8 k, uint8 v) public {
|
||||
table[k] = v;
|
||||
}
|
||||
}
|
||||
)";
|
||||
|
||||
ALSO_VIA_YUL(
|
||||
compileAndRun(sourceCode);
|
||||
ABI_CHECK(callContractFunction("get(uint8)", uint8_t(0)), encodeArgs(uint8_t(0x00)));
|
||||
ABI_CHECK(callContractFunction("get(uint8)", uint8_t(0x01)), encodeArgs(uint8_t(0x00)));
|
||||
ABI_CHECK(callContractFunction("get(uint8)", uint8_t(0xa7)), encodeArgs(uint8_t(0x00)));
|
||||
callContractFunction("set(uint8,uint8)", uint8_t(0x01), uint8_t(0xa1));
|
||||
ABI_CHECK(callContractFunction("get(uint8)", uint8_t(0x00)), encodeArgs(uint8_t(0x00)));
|
||||
ABI_CHECK(callContractFunction("get(uint8)", uint8_t(0x01)), encodeArgs(uint8_t(0xa1)));
|
||||
ABI_CHECK(callContractFunction("get(uint8)", uint8_t(0xa7)), encodeArgs(uint8_t(0x00)));
|
||||
callContractFunction("set(uint8,uint8)", uint8_t(0x00), uint8_t(0xef));
|
||||
ABI_CHECK(callContractFunction("get(uint8)", uint8_t(0x00)), encodeArgs(uint8_t(0xef)));
|
||||
ABI_CHECK(callContractFunction("get(uint8)", uint8_t(0x01)), encodeArgs(uint8_t(0xa1)));
|
||||
ABI_CHECK(callContractFunction("get(uint8)", uint8_t(0xa7)), encodeArgs(uint8_t(0x00)));
|
||||
callContractFunction("set(uint8,uint8)", uint8_t(0x01), uint8_t(0x05));
|
||||
ABI_CHECK(callContractFunction("get(uint8)", uint8_t(0x00)), encodeArgs(uint8_t(0xef)));
|
||||
ABI_CHECK(callContractFunction("get(uint8)", uint8_t(0x01)), encodeArgs(uint8_t(0x05)));
|
||||
ABI_CHECK(callContractFunction("get(uint8)", uint8_t(0xa7)), encodeArgs(uint8_t(0x00)));
|
||||
)
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(mapping_state)
|
||||
{
|
||||
char const* sourceCode = R"(
|
||||
@@ -1057,34 +1003,6 @@ BOOST_AUTO_TEST_CASE(constructor)
|
||||
)
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(multiple_elementary_accessors)
|
||||
{
|
||||
char const* sourceCode = R"(
|
||||
contract test {
|
||||
uint256 public data;
|
||||
bytes6 public name;
|
||||
bytes32 public a_hash;
|
||||
address public an_address;
|
||||
constructor() public {
|
||||
data = 8;
|
||||
name = "Celina";
|
||||
a_hash = keccak256("\x7b");
|
||||
an_address = address(0x1337);
|
||||
super_secret_data = 42;
|
||||
}
|
||||
uint256 super_secret_data;
|
||||
}
|
||||
)";
|
||||
ALSO_VIA_YUL(
|
||||
compileAndRun(sourceCode);
|
||||
ABI_CHECK(callContractFunction("data()"), encodeArgs(8));
|
||||
ABI_CHECK(callContractFunction("name()"), encodeArgs("Celina"));
|
||||
ABI_CHECK(callContractFunction("a_hash()"), encodeArgs(util::keccak256(bytes(1, 0x7b))));
|
||||
ABI_CHECK(callContractFunction("an_address()"), encodeArgs(util::toBigEndian(u160(0x1337))));
|
||||
ABI_CHECK(callContractFunction("super_secret_data()"), bytes());
|
||||
);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(balance)
|
||||
{
|
||||
char const* sourceCode = R"(
|
||||
@@ -1929,6 +1847,40 @@ BOOST_AUTO_TEST_CASE(gas_and_value_basic)
|
||||
BOOST_REQUIRE(callContractFunction("checkState()") == encodeArgs(false, 20 - 5));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(gas_and_value_brace_syntax)
|
||||
{
|
||||
char const* sourceCode = R"(
|
||||
contract helper {
|
||||
bool flag;
|
||||
function getBalance() payable public returns (uint256 myBalance) {
|
||||
return address(this).balance;
|
||||
}
|
||||
function setFlag() public { flag = true; }
|
||||
function getFlag() public returns (bool fl) { return flag; }
|
||||
}
|
||||
contract test {
|
||||
helper h;
|
||||
constructor() public payable { h = new helper(); }
|
||||
function sendAmount(uint amount) public payable returns (uint256 bal) {
|
||||
return h.getBalance{value: amount}();
|
||||
}
|
||||
function outOfGas() public returns (bool ret) {
|
||||
h.setFlag{gas: 2}(); // should fail due to OOG
|
||||
return true;
|
||||
}
|
||||
function checkState() public returns (bool flagAfter, uint myBal) {
|
||||
flagAfter = h.getFlag();
|
||||
myBal = address(this).balance;
|
||||
}
|
||||
}
|
||||
)";
|
||||
compileAndRun(sourceCode, 20);
|
||||
BOOST_REQUIRE(callContractFunction("sendAmount(uint256)", 5) == encodeArgs(5));
|
||||
// call to helper should not succeed but amount should be transferred anyway
|
||||
BOOST_REQUIRE(callContractFunction("outOfGas()") == bytes());
|
||||
BOOST_REQUIRE(callContractFunction("checkState()") == encodeArgs(false, 20 - 5));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(gasleft_decrease)
|
||||
{
|
||||
char const* sourceCode = R"(
|
||||
@@ -2506,7 +2458,7 @@ BOOST_AUTO_TEST_CASE(default_fallback_throws)
|
||||
compileAndRun(sourceCode);
|
||||
ABI_CHECK(callContractFunction("f()"), encodeArgs(0));
|
||||
|
||||
if (solidity::test::Options::get().evmVersion().hasStaticCall())
|
||||
if (solidity::test::CommonOptions::get().evmVersion().hasStaticCall())
|
||||
{
|
||||
char const* sourceCode = R"YY(
|
||||
contract A {
|
||||
@@ -3371,7 +3323,7 @@ BOOST_AUTO_TEST_CASE(generic_delegatecall)
|
||||
|
||||
BOOST_AUTO_TEST_CASE(generic_staticcall)
|
||||
{
|
||||
if (solidity::test::Options::get().evmVersion().hasStaticCall())
|
||||
if (solidity::test::CommonOptions::get().evmVersion().hasStaticCall())
|
||||
{
|
||||
char const* sourceCode = R"**(
|
||||
contract A {
|
||||
@@ -5757,7 +5709,7 @@ BOOST_AUTO_TEST_CASE(bool_conversion)
|
||||
}
|
||||
)";
|
||||
compileAndRun(sourceCode, 0, "C");
|
||||
bool v2 = solidity::test::Options::get().useABIEncoderV2;
|
||||
bool v2 = solidity::test::CommonOptions::get().useABIEncoderV2;
|
||||
ABI_CHECK(callContractFunction("f(bool)", 0), encodeArgs(0));
|
||||
ABI_CHECK(callContractFunction("f(bool)", 1), encodeArgs(1));
|
||||
ABI_CHECK(callContractFunction("f(bool)", 2), v2 ? encodeArgs() : encodeArgs(1));
|
||||
@@ -10018,7 +9970,7 @@ BOOST_AUTO_TEST_CASE(cleanup_bytes_types)
|
||||
)";
|
||||
compileAndRun(sourceCode, 0, "C");
|
||||
// We input longer data on purpose.
|
||||
bool v2 = solidity::test::Options::get().useABIEncoderV2;
|
||||
bool v2 = solidity::test::CommonOptions::get().useABIEncoderV2;
|
||||
ABI_CHECK(callContractFunction("f(bytes2,uint16)", string("abc"), u256(0x040102)), v2 ? encodeArgs() : encodeArgs(0));
|
||||
}
|
||||
BOOST_AUTO_TEST_CASE(cleanup_bytes_types_shortening)
|
||||
@@ -10055,7 +10007,7 @@ BOOST_AUTO_TEST_CASE(cleanup_address_types)
|
||||
)";
|
||||
compileAndRun(sourceCode, 0, "C");
|
||||
|
||||
bool v2 = solidity::test::Options::get().useABIEncoderV2;
|
||||
bool v2 = solidity::test::CommonOptions::get().useABIEncoderV2;
|
||||
// We input longer data on purpose.
|
||||
ABI_CHECK(callContractFunction("f(address)", u256("0xFFFF1234567890123456789012345678901234567890")), v2 ? encodeArgs() : encodeArgs(0));
|
||||
ABI_CHECK(callContractFunction("g(address)", u256("0xFFFF1234567890123456789012345678901234567890")), v2 ? encodeArgs() : encodeArgs(0));
|
||||
@@ -10179,7 +10131,7 @@ BOOST_AUTO_TEST_CASE(create_dynamic_array_with_zero_length)
|
||||
|
||||
BOOST_AUTO_TEST_CASE(correctly_initialize_memory_array_in_constructor)
|
||||
{
|
||||
// Memory arrays are initialized using codecopy past the size of the code.
|
||||
// Memory arrays are initialized using calldatacopy past the size of the calldata.
|
||||
// This test checks that it also works in the constructor context.
|
||||
char const* sourceCode = R"(
|
||||
contract C {
|
||||
@@ -11308,7 +11260,7 @@ BOOST_AUTO_TEST_CASE(shift_right_garbled)
|
||||
}
|
||||
)";
|
||||
compileAndRun(sourceCode, 0, "C");
|
||||
bool v2 = solidity::test::Options::get().useABIEncoderV2;
|
||||
bool v2 = solidity::test::CommonOptions::get().useABIEncoderV2;
|
||||
ABI_CHECK(callContractFunction("f(uint8,uint8)", u256(0x0), u256(4)), encodeArgs(u256(0xf)));
|
||||
ABI_CHECK(callContractFunction("f(uint8,uint8)", u256(0x0), u256(0x1004)), v2 ? encodeArgs() : encodeArgs(u256(0xf)));
|
||||
}
|
||||
@@ -11334,7 +11286,7 @@ BOOST_AUTO_TEST_CASE(shift_right_garbled_signed)
|
||||
}
|
||||
)";
|
||||
compileAndRun(sourceCode, 0, "C");
|
||||
bool v2 = solidity::test::Options::get().useABIEncoderV2;
|
||||
bool v2 = solidity::test::CommonOptions::get().useABIEncoderV2;
|
||||
ABI_CHECK(callContractFunction("f(int8,uint8)", u256(0x0), u256(3)), encodeArgs(u256(-2)));
|
||||
ABI_CHECK(callContractFunction("f(int8,uint8)", u256(0x0), u256(4)), encodeArgs(u256(-1)));
|
||||
ABI_CHECK(callContractFunction("f(int8,uint8)", u256(0x0), u256(0xFF)), encodeArgs(u256(-1)));
|
||||
@@ -11528,7 +11480,7 @@ BOOST_AUTO_TEST_CASE(shift_right_negative_lvalue_signextend_int8)
|
||||
}
|
||||
)";
|
||||
compileAndRun(sourceCode, 0, "C");
|
||||
bool v2 = solidity::test::Options::get().useABIEncoderV2;
|
||||
bool v2 = solidity::test::CommonOptions::get().useABIEncoderV2;
|
||||
ABI_CHECK(callContractFunction("f(int8,int8)", u256(0x99u), u256(0)), v2 ? encodeArgs() : encodeArgs(u256(-103)));
|
||||
ABI_CHECK(callContractFunction("f(int8,int8)", u256(0x99u), u256(1)), v2 ? encodeArgs() : encodeArgs(u256(-52)));
|
||||
ABI_CHECK(callContractFunction("f(int8,int8)", u256(0x99u), u256(2)), v2 ? encodeArgs() : encodeArgs(u256(-26)));
|
||||
@@ -11546,7 +11498,7 @@ BOOST_AUTO_TEST_CASE(shift_right_negative_lvalue_signextend_int16)
|
||||
}
|
||||
)";
|
||||
compileAndRun(sourceCode, 0, "C");
|
||||
bool v2 = solidity::test::Options::get().useABIEncoderV2;
|
||||
bool v2 = solidity::test::CommonOptions::get().useABIEncoderV2;
|
||||
ABI_CHECK(callContractFunction("f(int16,int16)", u256(0xFF99u), u256(0)), v2 ? encodeArgs() : encodeArgs(u256(-103)));
|
||||
ABI_CHECK(callContractFunction("f(int16,int16)", u256(0xFF99u), u256(1)), v2 ? encodeArgs() : encodeArgs(u256(-52)));
|
||||
ABI_CHECK(callContractFunction("f(int16,int16)", u256(0xFF99u), u256(2)), v2 ? encodeArgs() : encodeArgs(u256(-26)));
|
||||
@@ -11564,7 +11516,7 @@ BOOST_AUTO_TEST_CASE(shift_right_negative_lvalue_signextend_int32)
|
||||
}
|
||||
)";
|
||||
compileAndRun(sourceCode, 0, "C");
|
||||
bool v2 = solidity::test::Options::get().useABIEncoderV2;
|
||||
bool v2 = solidity::test::CommonOptions::get().useABIEncoderV2;
|
||||
ABI_CHECK(callContractFunction("f(int32,int32)", u256(0xFFFFFF99u), u256(0)), v2 ? encodeArgs() : encodeArgs(u256(-103)));
|
||||
ABI_CHECK(callContractFunction("f(int32,int32)", u256(0xFFFFFF99u), u256(1)), v2 ? encodeArgs() : encodeArgs(u256(-52)));
|
||||
ABI_CHECK(callContractFunction("f(int32,int32)", u256(0xFFFFFF99u), u256(2)), v2 ? encodeArgs() : encodeArgs(u256(-26)));
|
||||
@@ -12092,7 +12044,7 @@ BOOST_AUTO_TEST_CASE(revert_with_cause)
|
||||
}
|
||||
}
|
||||
)";
|
||||
if (solidity::test::Options::get().evmVersion().supportsReturndata())
|
||||
if (solidity::test::CommonOptions::get().evmVersion().supportsReturndata())
|
||||
{
|
||||
compileAndRun(sourceCode, 0, "C");
|
||||
bytes const errorSignature = bytes{0x08, 0xc3, 0x79, 0xa0};
|
||||
@@ -12166,7 +12118,7 @@ BOOST_AUTO_TEST_CASE(require_with_message)
|
||||
}
|
||||
}
|
||||
)";
|
||||
if (solidity::test::Options::get().evmVersion().supportsReturndata())
|
||||
if (solidity::test::CommonOptions::get().evmVersion().supportsReturndata())
|
||||
{
|
||||
compileAndRun(sourceCode, 0, "C");
|
||||
bytes const errorSignature = bytes{0x08, 0xc3, 0x79, 0xa0};
|
||||
@@ -12212,7 +12164,7 @@ BOOST_AUTO_TEST_CASE(bubble_up_error_messages)
|
||||
}
|
||||
}
|
||||
)";
|
||||
if (solidity::test::Options::get().evmVersion().supportsReturndata())
|
||||
if (solidity::test::CommonOptions::get().evmVersion().supportsReturndata())
|
||||
{
|
||||
compileAndRun(sourceCode, 0, "C");
|
||||
bytes const errorSignature = bytes{0x08, 0xc3, 0x79, 0xa0};
|
||||
@@ -12250,7 +12202,7 @@ BOOST_AUTO_TEST_CASE(bubble_up_error_messages_through_transfer)
|
||||
}
|
||||
}
|
||||
)";
|
||||
if (solidity::test::Options::get().evmVersion().supportsReturndata())
|
||||
if (solidity::test::CommonOptions::get().evmVersion().supportsReturndata())
|
||||
{
|
||||
compileAndRun(sourceCode, 0, "C");
|
||||
bytes const errorSignature = bytes{0x08, 0xc3, 0x79, 0xa0};
|
||||
@@ -12289,7 +12241,7 @@ BOOST_AUTO_TEST_CASE(bubble_up_error_messages_through_create)
|
||||
}
|
||||
}
|
||||
)";
|
||||
if (solidity::test::Options::get().evmVersion().supportsReturndata())
|
||||
if (solidity::test::CommonOptions::get().evmVersion().supportsReturndata())
|
||||
{
|
||||
compileAndRun(sourceCode, 0, "C");
|
||||
bytes const errorSignature = bytes{0x08, 0xc3, 0x79, 0xa0};
|
||||
@@ -12494,7 +12446,7 @@ BOOST_AUTO_TEST_CASE(bare_call_invalid_address)
|
||||
ABI_CHECK(callContractFunction("f()"), encodeArgs(u256(1)));
|
||||
ABI_CHECK(callContractFunction("h()"), encodeArgs(u256(1)));
|
||||
|
||||
if (solidity::test::Options::get().evmVersion().hasStaticCall())
|
||||
if (solidity::test::CommonOptions::get().evmVersion().hasStaticCall())
|
||||
{
|
||||
char const* sourceCode = R"YY(
|
||||
contract C {
|
||||
@@ -12510,10 +12462,10 @@ BOOST_AUTO_TEST_CASE(bare_call_invalid_address)
|
||||
|
||||
BOOST_AUTO_TEST_CASE(bare_call_return_data)
|
||||
{
|
||||
if (solidity::test::Options::get().evmVersion().supportsReturndata())
|
||||
if (solidity::test::CommonOptions::get().evmVersion().supportsReturndata())
|
||||
{
|
||||
vector<string> calltypes = {"call", "delegatecall"};
|
||||
if (solidity::test::Options::get().evmVersion().hasStaticCall())
|
||||
if (solidity::test::CommonOptions::get().evmVersion().hasStaticCall())
|
||||
calltypes.emplace_back("staticcall");
|
||||
for (string const& calltype: calltypes)
|
||||
{
|
||||
@@ -12637,7 +12589,7 @@ BOOST_AUTO_TEST_CASE(bare_call_return_data)
|
||||
|
||||
BOOST_AUTO_TEST_CASE(delegatecall_return_value)
|
||||
{
|
||||
if (solidity::test::Options::get().evmVersion().supportsReturndata())
|
||||
if (solidity::test::CommonOptions::get().evmVersion().supportsReturndata())
|
||||
{
|
||||
char const* sourceCode = R"DELIMITER(
|
||||
contract C {
|
||||
@@ -13438,7 +13390,7 @@ BOOST_AUTO_TEST_CASE(abi_encode_empty_string)
|
||||
)";
|
||||
|
||||
compileAndRun(sourceCode, 0, "C");
|
||||
if (!solidity::test::Options::get().useABIEncoderV2)
|
||||
if (!solidity::test::CommonOptions::get().useABIEncoderV2)
|
||||
{
|
||||
// ABI Encoder V2 has slightly different padding, tested below.
|
||||
ABI_CHECK(callContractFunction("f()"), encodeArgs(
|
||||
@@ -13562,7 +13514,7 @@ BOOST_AUTO_TEST_CASE(staticcall_for_view_and_pure)
|
||||
compileAndRun(sourceCode, 0, "D");
|
||||
// This should work (called via CALL)
|
||||
ABI_CHECK(callContractFunction("f()"), encodeArgs(1));
|
||||
if (solidity::test::Options::get().evmVersion().hasStaticCall())
|
||||
if (solidity::test::CommonOptions::get().evmVersion().hasStaticCall())
|
||||
{
|
||||
// These should throw (called via STATICCALL)
|
||||
ABI_CHECK(callContractFunction("fview()"), encodeArgs());
|
||||
@@ -13577,7 +13529,7 @@ BOOST_AUTO_TEST_CASE(staticcall_for_view_and_pure)
|
||||
|
||||
BOOST_AUTO_TEST_CASE(bitwise_shifting_constantinople)
|
||||
{
|
||||
if (!solidity::test::Options::get().evmVersion().hasBitwiseShifting())
|
||||
if (!solidity::test::CommonOptions::get().evmVersion().hasBitwiseShifting())
|
||||
return;
|
||||
char const* sourceCode = R"(
|
||||
contract C {
|
||||
@@ -13616,7 +13568,7 @@ BOOST_AUTO_TEST_CASE(bitwise_shifting_constantinople)
|
||||
|
||||
BOOST_AUTO_TEST_CASE(bitwise_shifting_constants_constantinople)
|
||||
{
|
||||
if (!solidity::test::Options::get().evmVersion().hasBitwiseShifting())
|
||||
if (!solidity::test::CommonOptions::get().evmVersion().hasBitwiseShifting())
|
||||
return;
|
||||
char const* sourceCode = R"(
|
||||
contract C {
|
||||
@@ -13683,7 +13635,7 @@ BOOST_AUTO_TEST_CASE(bitwise_shifting_constants_constantinople)
|
||||
|
||||
BOOST_AUTO_TEST_CASE(bitwise_shifting_constantinople_combined)
|
||||
{
|
||||
if (!solidity::test::Options::get().evmVersion().hasBitwiseShifting())
|
||||
if (!solidity::test::CommonOptions::get().evmVersion().hasBitwiseShifting())
|
||||
return;
|
||||
char const* sourceCode = R"(
|
||||
contract C {
|
||||
@@ -14439,7 +14391,7 @@ BOOST_AUTO_TEST_CASE(try_catch_library_call)
|
||||
}
|
||||
}
|
||||
)";
|
||||
if (solidity::test::Options::get().evmVersion().supportsReturndata())
|
||||
if (solidity::test::CommonOptions::get().evmVersion().supportsReturndata())
|
||||
{
|
||||
compileAndRun(sourceCode, 0, "L", bytes());
|
||||
compileAndRun(sourceCode, 0, "C", bytes(), map<string, Address>{{"L", m_contractAddress}});
|
||||
|
||||
@@ -39,7 +39,7 @@ bytes SolidityExecutionFramework::compileContract(
|
||||
// Silence compiler version warning
|
||||
std::string sourceCode = "pragma solidity >=0.0;\n";
|
||||
if (
|
||||
solidity::test::Options::get().useABIEncoderV2 &&
|
||||
solidity::test::CommonOptions::get().useABIEncoderV2 &&
|
||||
_sourceCode.find("pragma experimental ABIEncoderV2;") == std::string::npos
|
||||
)
|
||||
sourceCode += "pragma experimental ABIEncoderV2;\n";
|
||||
@@ -51,6 +51,7 @@ bytes SolidityExecutionFramework::compileContract(
|
||||
m_compiler.setEVMVersion(m_evmVersion);
|
||||
m_compiler.setOptimiserSettings(m_optimiserSettings);
|
||||
m_compiler.enableIRGeneration(m_compileViaYul);
|
||||
m_compiler.setRevertStringBehaviour(m_revertStrings);
|
||||
if (!m_compiler.compile())
|
||||
{
|
||||
langutil::SourceReferenceFormatter formatter(std::cerr);
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
#include <test/ExecutionFramework.h>
|
||||
|
||||
#include <libsolidity/interface/CompilerStack.h>
|
||||
#include <libsolidity/interface/DebugSettings.h>
|
||||
|
||||
#include <libyul/AssemblyStack.h>
|
||||
|
||||
@@ -67,6 +68,8 @@ public:
|
||||
protected:
|
||||
solidity::frontend::CompilerStack m_compiler;
|
||||
bool m_compileViaYul = false;
|
||||
RevertStrings m_revertStrings = RevertStrings::Default;
|
||||
|
||||
};
|
||||
|
||||
} // end namespaces
|
||||
|
||||
@@ -31,7 +31,9 @@
|
||||
#include <libsolidity/ast/TypeProvider.h>
|
||||
#include <libsolidity/analysis/TypeChecker.h>
|
||||
#include <liblangutil/ErrorReporter.h>
|
||||
#include <test/Options.h>
|
||||
#include <test/Common.h>
|
||||
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
using namespace std;
|
||||
using namespace solidity::evmasm;
|
||||
@@ -98,7 +100,7 @@ bytes compileFirstExpression(
|
||||
{
|
||||
ErrorList errors;
|
||||
ErrorReporter errorReporter(errors);
|
||||
sourceUnit = Parser(errorReporter, solidity::test::Options::get().evmVersion()).parse(
|
||||
sourceUnit = Parser(errorReporter, solidity::test::CommonOptions::get().evmVersion()).parse(
|
||||
make_shared<Scanner>(CharStream(_sourceCode, ""))
|
||||
);
|
||||
if (!sourceUnit)
|
||||
@@ -114,7 +116,7 @@ bytes compileFirstExpression(
|
||||
ErrorReporter errorReporter(errors);
|
||||
GlobalContext globalContext;
|
||||
map<ASTNode const*, shared_ptr<DeclarationContainer>> scopes;
|
||||
NameAndTypeResolver resolver(globalContext, solidity::test::Options::get().evmVersion(), scopes, errorReporter);
|
||||
NameAndTypeResolver resolver(globalContext, solidity::test::CommonOptions::get().evmVersion(), scopes, errorReporter);
|
||||
resolver.registerDeclarations(*sourceUnit);
|
||||
|
||||
vector<ContractDefinition const*> inheritanceHierarchy;
|
||||
@@ -128,7 +130,7 @@ bytes compileFirstExpression(
|
||||
if (ContractDefinition* contract = dynamic_cast<ContractDefinition*>(node.get()))
|
||||
{
|
||||
ErrorReporter errorReporter(errors);
|
||||
TypeChecker typeChecker(solidity::test::Options::get().evmVersion(), errorReporter);
|
||||
TypeChecker typeChecker(solidity::test::CommonOptions::get().evmVersion(), errorReporter);
|
||||
BOOST_REQUIRE(typeChecker.checkTypeRequirements(*contract));
|
||||
}
|
||||
for (ASTPointer<ASTNode> const& node: sourceUnit->nodes())
|
||||
@@ -137,7 +139,10 @@ bytes compileFirstExpression(
|
||||
FirstExpressionExtractor extractor(*contract);
|
||||
BOOST_REQUIRE(extractor.expression() != nullptr);
|
||||
|
||||
CompilerContext context(solidity::test::Options::get().evmVersion());
|
||||
CompilerContext context(
|
||||
solidity::test::CommonOptions::get().evmVersion(),
|
||||
RevertStrings::Default
|
||||
);
|
||||
context.resetVisitedNodes(contract);
|
||||
context.setInheritanceHierarchy(inheritanceHierarchy);
|
||||
unsigned parametersSize = _localVariables.size(); // assume they are all one slot on the stack
|
||||
@@ -150,8 +155,7 @@ bytes compileFirstExpression(
|
||||
|
||||
ExpressionCompiler(
|
||||
context,
|
||||
RevertStrings::Default,
|
||||
solidity::test::Options::get().optimize
|
||||
solidity::test::CommonOptions::get().optimize
|
||||
).compile(*extractor.expression());
|
||||
|
||||
for (vector<string> const& function: _functions)
|
||||
@@ -282,7 +286,7 @@ BOOST_AUTO_TEST_CASE(comparison)
|
||||
bytes code = compileFirstExpression(sourceCode);
|
||||
|
||||
bytes expectation;
|
||||
if (solidity::test::Options::get().optimize)
|
||||
if (solidity::test::CommonOptions::get().optimize)
|
||||
expectation = {
|
||||
uint8_t(Instruction::PUSH2), 0x11, 0xaa,
|
||||
uint8_t(Instruction::PUSH2), 0x10, 0xaa,
|
||||
@@ -345,7 +349,7 @@ BOOST_AUTO_TEST_CASE(arithmetic)
|
||||
bytes code = compileFirstExpression(sourceCode, {}, {{"test", "f", "y"}});
|
||||
|
||||
bytes expectation;
|
||||
if (solidity::test::Options::get().optimize)
|
||||
if (solidity::test::CommonOptions::get().optimize)
|
||||
expectation = {
|
||||
uint8_t(Instruction::PUSH1), 0x2,
|
||||
uint8_t(Instruction::PUSH1), 0x3,
|
||||
@@ -426,7 +430,7 @@ BOOST_AUTO_TEST_CASE(unary_operators)
|
||||
bytes code = compileFirstExpression(sourceCode, {}, {{"test", "f", "y"}});
|
||||
|
||||
bytes expectation;
|
||||
if (solidity::test::Options::get().optimize)
|
||||
if (solidity::test::CommonOptions::get().optimize)
|
||||
expectation = {
|
||||
uint8_t(Instruction::DUP1),
|
||||
uint8_t(Instruction::PUSH1), 0x0,
|
||||
@@ -517,7 +521,7 @@ BOOST_AUTO_TEST_CASE(assignment)
|
||||
|
||||
// Stack: a, b
|
||||
bytes expectation;
|
||||
if (solidity::test::Options::get().optimize)
|
||||
if (solidity::test::CommonOptions::get().optimize)
|
||||
expectation = {
|
||||
uint8_t(Instruction::DUP1),
|
||||
uint8_t(Instruction::DUP3),
|
||||
@@ -629,7 +633,7 @@ BOOST_AUTO_TEST_CASE(selfbalance)
|
||||
|
||||
bytes code = compileFirstExpression(sourceCode, {}, {});
|
||||
|
||||
if (solidity::test::Options::get().evmVersion() == EVMVersion::istanbul())
|
||||
if (solidity::test::CommonOptions::get().evmVersion() == EVMVersion::istanbul())
|
||||
{
|
||||
bytes expectation({uint8_t(Instruction::SELFBALANCE)});
|
||||
BOOST_CHECK_EQUAL_COLLECTIONS(code.begin(), code.end(), expectation.begin(), expectation.end());
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
|
||||
#include <test/libsolidity/AnalysisFramework.h>
|
||||
|
||||
#include <test/Options.h>
|
||||
#include <test/Common.h>
|
||||
|
||||
#include <libsolidity/ast/AST.h>
|
||||
|
||||
@@ -361,7 +361,7 @@ BOOST_AUTO_TEST_CASE(dynamic_return_types_not_possible)
|
||||
}
|
||||
}
|
||||
)";
|
||||
if (solidity::test::Options::get().evmVersion() == EVMVersion::homestead())
|
||||
if (solidity::test::CommonOptions::get().evmVersion() == EVMVersion::homestead())
|
||||
CHECK_ERROR(sourceCode, TypeError, "Type inaccessible dynamic type is not implicitly convertible to expected type string memory.");
|
||||
else
|
||||
CHECK_SUCCESS_NO_WARNINGS(sourceCode);
|
||||
@@ -386,8 +386,11 @@ BOOST_AUTO_TEST_CASE(returndatasize_as_variable)
|
||||
vector<pair<Error::Type, std::string>> expectations(vector<pair<Error::Type, std::string>>{
|
||||
{Error::Type::Warning, "Variable is shadowed in inline assembly by an instruction of the same name"}
|
||||
});
|
||||
if (!solidity::test::Options::get().evmVersion().supportsReturndata())
|
||||
if (!solidity::test::CommonOptions::get().evmVersion().supportsReturndata())
|
||||
{
|
||||
expectations.emplace_back(make_pair(Error::Type::TypeError, std::string("\"returndatasize\" instruction is only available for Byzantium-compatible VMs")));
|
||||
expectations.emplace_back(make_pair(Error::Type::TypeError, std::string("Expected expression to evaluate to one value, but got 0 values instead.")));
|
||||
}
|
||||
CHECK_ALLOW_MULTI(text, expectations);
|
||||
}
|
||||
|
||||
@@ -401,8 +404,11 @@ BOOST_AUTO_TEST_CASE(create2_as_variable)
|
||||
vector<pair<Error::Type, std::string>> expectations(vector<pair<Error::Type, std::string>>{
|
||||
{Error::Type::Warning, "Variable is shadowed in inline assembly by an instruction of the same name"}
|
||||
});
|
||||
if (!solidity::test::Options::get().evmVersion().hasCreate2())
|
||||
if (!solidity::test::CommonOptions::get().evmVersion().hasCreate2())
|
||||
{
|
||||
expectations.emplace_back(make_pair(Error::Type::TypeError, std::string("\"create2\" instruction is only available for Constantinople-compatible VMs")));
|
||||
expectations.emplace_back(make_pair(Error::Type::TypeError, std::string("Expected expression to evaluate to one value, but got 0 values instead.")));
|
||||
}
|
||||
CHECK_ALLOW_MULTI(text, expectations);
|
||||
}
|
||||
|
||||
@@ -416,8 +422,11 @@ BOOST_AUTO_TEST_CASE(extcodehash_as_variable)
|
||||
vector<pair<Error::Type, std::string>> expectations(vector<pair<Error::Type, std::string>>{
|
||||
{Error::Type::Warning, "Variable is shadowed in inline assembly by an instruction of the same name"}
|
||||
});
|
||||
if (!solidity::test::Options::get().evmVersion().hasExtCodeHash())
|
||||
if (!solidity::test::CommonOptions::get().evmVersion().hasExtCodeHash())
|
||||
{
|
||||
expectations.emplace_back(make_pair(Error::Type::TypeError, std::string("\"extcodehash\" instruction is only available for Constantinople-compatible VMs")));
|
||||
expectations.emplace_back(make_pair(Error::Type::TypeError, std::string("Expected expression to evaluate to one value, but got 0 values instead.")));
|
||||
}
|
||||
CHECK_ALLOW_MULTI(text, expectations);
|
||||
}
|
||||
|
||||
@@ -452,7 +461,7 @@ BOOST_AUTO_TEST_CASE(address_staticcall)
|
||||
}
|
||||
)";
|
||||
|
||||
if (solidity::test::Options::get().evmVersion().hasStaticCall())
|
||||
if (solidity::test::CommonOptions::get().evmVersion().hasStaticCall())
|
||||
CHECK_SUCCESS_NO_WARNINGS(sourceCode);
|
||||
else
|
||||
CHECK_ERROR(sourceCode, TypeError, "\"staticcall\" is not supported by the VM version.");
|
||||
@@ -460,7 +469,7 @@ BOOST_AUTO_TEST_CASE(address_staticcall)
|
||||
|
||||
BOOST_AUTO_TEST_CASE(address_staticcall_value)
|
||||
{
|
||||
if (solidity::test::Options::get().evmVersion().hasStaticCall())
|
||||
if (solidity::test::CommonOptions::get().evmVersion().hasStaticCall())
|
||||
{
|
||||
char const* sourceCode = R"(
|
||||
contract C {
|
||||
@@ -484,7 +493,7 @@ BOOST_AUTO_TEST_CASE(address_call_full_return_type)
|
||||
}
|
||||
)";
|
||||
|
||||
if (solidity::test::Options::get().evmVersion().supportsReturndata())
|
||||
if (solidity::test::CommonOptions::get().evmVersion().supportsReturndata())
|
||||
CHECK_SUCCESS_NO_WARNINGS(sourceCode);
|
||||
else
|
||||
CHECK_ERROR(sourceCode, TypeError, "Type inaccessible dynamic type is not implicitly convertible to expected type bytes memory.");
|
||||
@@ -501,7 +510,7 @@ BOOST_AUTO_TEST_CASE(address_delegatecall_full_return_type)
|
||||
}
|
||||
)";
|
||||
|
||||
if (solidity::test::Options::get().evmVersion().supportsReturndata())
|
||||
if (solidity::test::CommonOptions::get().evmVersion().supportsReturndata())
|
||||
CHECK_SUCCESS_NO_WARNINGS(sourceCode);
|
||||
else
|
||||
CHECK_ERROR(sourceCode, TypeError, "Type inaccessible dynamic type is not implicitly convertible to expected type bytes memory.");
|
||||
@@ -510,7 +519,7 @@ BOOST_AUTO_TEST_CASE(address_delegatecall_full_return_type)
|
||||
|
||||
BOOST_AUTO_TEST_CASE(address_staticcall_full_return_type)
|
||||
{
|
||||
if (solidity::test::Options::get().evmVersion().hasStaticCall())
|
||||
if (solidity::test::CommonOptions::get().evmVersion().hasStaticCall())
|
||||
{
|
||||
char const* sourceCode = R"(
|
||||
contract C {
|
||||
|
||||
@@ -20,13 +20,15 @@
|
||||
* Unit tests for the solidity compiler JSON Interface output.
|
||||
*/
|
||||
|
||||
#include <test/Options.h>
|
||||
#include <test/Common.h>
|
||||
#include <string>
|
||||
#include <libsolutil/JSON.h>
|
||||
#include <libsolidity/interface/CompilerStack.h>
|
||||
#include <liblangutil/Exceptions.h>
|
||||
#include <libsolutil/Exceptions.h>
|
||||
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
using namespace solidity::langutil;
|
||||
|
||||
namespace solidity::frontend::test
|
||||
@@ -44,7 +46,7 @@ public:
|
||||
{
|
||||
m_compilerStack.reset();
|
||||
m_compilerStack.setSources({{"", "pragma solidity >=0.0;\n" + _code}});
|
||||
m_compilerStack.setEVMVersion(solidity::test::Options::get().evmVersion());
|
||||
m_compilerStack.setEVMVersion(solidity::test::CommonOptions::get().evmVersion());
|
||||
BOOST_REQUIRE_MESSAGE(m_compilerStack.parseAndAnalyze(), "Parsing contract failed");
|
||||
|
||||
Json::Value generatedDocumentation;
|
||||
@@ -65,7 +67,7 @@ public:
|
||||
{
|
||||
m_compilerStack.reset();
|
||||
m_compilerStack.setSources({{"", "pragma solidity >=0.0;\n" + _code}});
|
||||
m_compilerStack.setEVMVersion(solidity::test::Options::get().evmVersion());
|
||||
m_compilerStack.setEVMVersion(solidity::test::CommonOptions::get().evmVersion());
|
||||
BOOST_CHECK(!m_compilerStack.parseAndAnalyze());
|
||||
BOOST_REQUIRE(Error::containsErrorOfType(m_compilerStack.errors(), Error::Type::DocstringParsingError));
|
||||
}
|
||||
|
||||
@@ -25,10 +25,12 @@
|
||||
#include <liblangutil/Scanner.h>
|
||||
#include <libsolidity/parsing/Parser.h>
|
||||
#include <liblangutil/ErrorReporter.h>
|
||||
#include <test/Options.h>
|
||||
#include <test/Common.h>
|
||||
#include <test/libsolidity/ErrorCheck.h>
|
||||
#include <libsolidity/ast/ASTVisitor.h>
|
||||
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
using namespace std;
|
||||
using namespace solidity::langutil;
|
||||
|
||||
@@ -42,7 +44,7 @@ ASTPointer<ContractDefinition> parseText(std::string const& _source, ErrorList&
|
||||
ErrorReporter errorReporter(_errors);
|
||||
ASTPointer<SourceUnit> sourceUnit = Parser(
|
||||
errorReporter,
|
||||
solidity::test::Options::get().evmVersion(),
|
||||
solidity::test::CommonOptions::get().evmVersion(),
|
||||
errorRecovery
|
||||
).parse(std::make_shared<Scanner>(CharStream(_source, "")));
|
||||
if (!sourceUnit)
|
||||
@@ -96,7 +98,7 @@ void checkFunctionNatspec(
|
||||
std::string const& _expectedDoc
|
||||
)
|
||||
{
|
||||
auto doc = _function->documentation();
|
||||
auto doc = _function->documentation()->text();
|
||||
BOOST_CHECK_MESSAGE(doc != nullptr, "Function does not have Natspec Doc as expected");
|
||||
BOOST_CHECK_EQUAL(*doc, _expectedDoc);
|
||||
}
|
||||
|
||||
@@ -145,7 +145,8 @@ BOOST_AUTO_TEST_CASE(type_identifier_escaping)
|
||||
|
||||
BOOST_AUTO_TEST_CASE(type_identifiers)
|
||||
{
|
||||
ASTNode::resetID();
|
||||
int64_t id = 0;
|
||||
|
||||
BOOST_CHECK_EQUAL(TypeProvider::fromElementaryTypeName("uint128")->identifier(), "t_uint128");
|
||||
BOOST_CHECK_EQUAL(TypeProvider::fromElementaryTypeName("int128")->identifier(), "t_int128");
|
||||
BOOST_CHECK_EQUAL(TypeProvider::fromElementaryTypeName("address")->identifier(), "t_address");
|
||||
@@ -157,7 +158,7 @@ BOOST_AUTO_TEST_CASE(type_identifiers)
|
||||
BOOST_CHECK_EQUAL(RationalNumberType(rational(2 * 200, 2 * 77)).identifier(), "t_rational_200_by_77");
|
||||
BOOST_CHECK_EQUAL(RationalNumberType(rational(-2 * 200, 2 * 77)).identifier(), "t_rational_minus_200_by_77");
|
||||
BOOST_CHECK_EQUAL(
|
||||
StringLiteralType(Literal(SourceLocation{}, Token::StringLiteral, make_shared<string>("abc - def"))).identifier(),
|
||||
StringLiteralType(Literal(++id, SourceLocation{}, Token::StringLiteral, make_shared<string>("abc - def"))).identifier(),
|
||||
"t_stringliteral_196a9142ee0d40e274a6482393c762b16dd8315713207365e1e13d8d85b74fc4"
|
||||
);
|
||||
BOOST_CHECK_EQUAL(TypeProvider::fromElementaryTypeName("byte")->identifier(), "t_bytes1");
|
||||
@@ -178,14 +179,14 @@ BOOST_AUTO_TEST_CASE(type_identifiers)
|
||||
TypePointer multiArray = TypeProvider::array(DataLocation::Storage, stringArray);
|
||||
BOOST_CHECK_EQUAL(multiArray->identifier(), "t_array$_t_array$_t_string_storage_$20_storage_$dyn_storage_ptr");
|
||||
|
||||
ContractDefinition c(SourceLocation{}, make_shared<string>("MyContract$"), {}, {}, {}, ContractKind::Contract);
|
||||
ContractDefinition c(++id, SourceLocation{}, make_shared<string>("MyContract$"), {}, {}, {}, ContractKind::Contract);
|
||||
BOOST_CHECK_EQUAL(c.type()->identifier(), "t_type$_t_contract$_MyContract$$$_$2_$");
|
||||
BOOST_CHECK_EQUAL(ContractType(c, true).identifier(), "t_super$_MyContract$$$_$2");
|
||||
|
||||
StructDefinition s({}, make_shared<string>("Struct"), {});
|
||||
StructDefinition s(++id, {}, make_shared<string>("Struct"), {});
|
||||
BOOST_CHECK_EQUAL(s.type()->identifier(), "t_type$_t_struct$_Struct_$3_storage_ptr_$");
|
||||
|
||||
EnumDefinition e({}, make_shared<string>("Enum"), {});
|
||||
EnumDefinition e(++id, {}, make_shared<string>("Enum"), {});
|
||||
BOOST_CHECK_EQUAL(e.type()->identifier(), "t_type$_t_enum$_Enum_$4_$");
|
||||
|
||||
TupleType t({e.type(), s.type(), stringArray, nullptr});
|
||||
@@ -203,11 +204,11 @@ BOOST_AUTO_TEST_CASE(type_identifiers)
|
||||
|
||||
// TypeType is tested with contract
|
||||
|
||||
auto emptyParams = make_shared<ParameterList>(SourceLocation(), std::vector<ASTPointer<VariableDeclaration>>());
|
||||
ModifierDefinition mod(SourceLocation{}, make_shared<string>("modif"), {}, emptyParams, {}, {}, {});
|
||||
auto emptyParams = make_shared<ParameterList>(++id, SourceLocation(), std::vector<ASTPointer<VariableDeclaration>>());
|
||||
ModifierDefinition mod(++id, SourceLocation{}, make_shared<string>("modif"), {}, emptyParams, {}, {}, {});
|
||||
BOOST_CHECK_EQUAL(ModifierType(mod).identifier(), "t_modifier$__$");
|
||||
|
||||
SourceUnit su({}, {});
|
||||
SourceUnit su(++id, {}, {});
|
||||
BOOST_CHECK_EQUAL(ModuleType(su).identifier(), "t_module_7");
|
||||
BOOST_CHECK_EQUAL(MagicType(MagicType::Kind::Block).identifier(), "t_magic_block");
|
||||
BOOST_CHECK_EQUAL(MagicType(MagicType::Kind::Message).identifier(), "t_magic_message");
|
||||
|
||||
@@ -366,14 +366,15 @@ BOOST_AUTO_TEST_CASE(basic_compilation)
|
||||
BOOST_CHECK(contract["evm"]["assembly"].isString());
|
||||
BOOST_CHECK(contract["evm"]["assembly"].asString().find(
|
||||
" /* \"fileA\":0:14 contract A { } */\n mstore(0x40, 0x80)\n "
|
||||
"callvalue\n /* \"--CODEGEN--\":8:17 */\n dup1\n "
|
||||
"/* \"--CODEGEN--\":5:7 */\n iszero\n tag_1\n jumpi\n "
|
||||
"/* \"--CODEGEN--\":30:31 */\n 0x00\n /* \"--CODEGEN--\":27:28 */\n "
|
||||
"dup1\n /* \"--CODEGEN--\":20:32 */\n revert\n /* \"--CODEGEN--\":5:7 */\n"
|
||||
"callvalue\n /* \"--CODEGEN--\":5:14 */\n dup1\n "
|
||||
"/* \"--CODEGEN--\":2:4 */\n iszero\n tag_1\n jumpi\n "
|
||||
"/* \"--CODEGEN--\":27:28 */\n 0x00\n /* \"--CODEGEN--\":24:25 */\n "
|
||||
"dup1\n /* \"--CODEGEN--\":17:29 */\n revert\n /* \"--CODEGEN--\":2:4 */\n"
|
||||
"tag_1:\n /* \"fileA\":0:14 contract A { } */\n pop\n dataSize(sub_0)\n dup1\n "
|
||||
"dataOffset(sub_0)\n 0x00\n codecopy\n 0x00\n return\nstop\n\nsub_0: assembly {\n "
|
||||
"/* \"fileA\":0:14 contract A { } */\n mstore(0x40, 0x80)\n 0x00\n "
|
||||
"dup1\n revert\n\n auxdata: 0xa26469706673582212"
|
||||
"/* \"fileA\":0:14 contract A { } */\n mstore(0x40, 0x80)\n "
|
||||
"/* \"--CODEGEN--\":12:13 */\n 0x00\n /* \"--CODEGEN--\":9:10 */\n "
|
||||
"dup1\n /* \"--CODEGEN--\":2:14 */\n revert\n\n auxdata: 0xa26469706673582212"
|
||||
) == 0);
|
||||
BOOST_CHECK(contract["evm"]["gasEstimates"].isObject());
|
||||
BOOST_CHECK_EQUAL(contract["evm"]["gasEstimates"].size(), 1);
|
||||
@@ -393,27 +394,27 @@ BOOST_AUTO_TEST_CASE(basic_compilation)
|
||||
BOOST_CHECK(contract["evm"]["legacyAssembly"][".code"].isArray());
|
||||
BOOST_CHECK_EQUAL(
|
||||
util::jsonCompactPrint(contract["evm"]["legacyAssembly"][".code"]),
|
||||
"[{\"begin\":0,\"end\":14,\"name\":\"PUSH\",\"value\":\"80\"},"
|
||||
"{\"begin\":0,\"end\":14,\"name\":\"PUSH\",\"value\":\"40\"},"
|
||||
"{\"begin\":0,\"end\":14,\"name\":\"MSTORE\"},"
|
||||
"{\"begin\":0,\"end\":14,\"name\":\"CALLVALUE\"},"
|
||||
"{\"begin\":8,\"end\":17,\"name\":\"DUP1\"},"
|
||||
"{\"begin\":5,\"end\":7,\"name\":\"ISZERO\"},"
|
||||
"{\"begin\":5,\"end\":7,\"name\":\"PUSH [tag]\",\"value\":\"1\"},"
|
||||
"{\"begin\":5,\"end\":7,\"name\":\"JUMPI\"},"
|
||||
"{\"begin\":30,\"end\":31,\"name\":\"PUSH\",\"value\":\"0\"},"
|
||||
"{\"begin\":27,\"end\":28,\"name\":\"DUP1\"},"
|
||||
"{\"begin\":20,\"end\":32,\"name\":\"REVERT\"},"
|
||||
"{\"begin\":5,\"end\":7,\"name\":\"tag\",\"value\":\"1\"},"
|
||||
"{\"begin\":5,\"end\":7,\"name\":\"JUMPDEST\"},"
|
||||
"{\"begin\":0,\"end\":14,\"name\":\"POP\"},"
|
||||
"{\"begin\":0,\"end\":14,\"name\":\"PUSH #[$]\",\"value\":\"0000000000000000000000000000000000000000000000000000000000000000\"},"
|
||||
"{\"begin\":0,\"end\":14,\"name\":\"DUP1\"},"
|
||||
"{\"begin\":0,\"end\":14,\"name\":\"PUSH [$]\",\"value\":\"0000000000000000000000000000000000000000000000000000000000000000\"},"
|
||||
"{\"begin\":0,\"end\":14,\"name\":\"PUSH\",\"value\":\"0\"},"
|
||||
"{\"begin\":0,\"end\":14,\"name\":\"CODECOPY\"},"
|
||||
"{\"begin\":0,\"end\":14,\"name\":\"PUSH\",\"value\":\"0\"},"
|
||||
"{\"begin\":0,\"end\":14,\"name\":\"RETURN\"}]"
|
||||
"[{\"begin\":0,\"end\":14,\"name\":\"PUSH\",\"source\":0,\"value\":\"80\"},"
|
||||
"{\"begin\":0,\"end\":14,\"name\":\"PUSH\",\"source\":0,\"value\":\"40\"},"
|
||||
"{\"begin\":0,\"end\":14,\"name\":\"MSTORE\",\"source\":0},"
|
||||
"{\"begin\":0,\"end\":14,\"name\":\"CALLVALUE\",\"source\":0},"
|
||||
"{\"begin\":5,\"end\":14,\"name\":\"DUP1\",\"source\":-1},"
|
||||
"{\"begin\":2,\"end\":4,\"name\":\"ISZERO\",\"source\":-1},"
|
||||
"{\"begin\":2,\"end\":4,\"name\":\"PUSH [tag]\",\"source\":-1,\"value\":\"1\"},"
|
||||
"{\"begin\":2,\"end\":4,\"name\":\"JUMPI\",\"source\":-1},"
|
||||
"{\"begin\":27,\"end\":28,\"name\":\"PUSH\",\"source\":-1,\"value\":\"0\"},"
|
||||
"{\"begin\":24,\"end\":25,\"name\":\"DUP1\",\"source\":-1},"
|
||||
"{\"begin\":17,\"end\":29,\"name\":\"REVERT\",\"source\":-1},"
|
||||
"{\"begin\":2,\"end\":4,\"name\":\"tag\",\"source\":-1,\"value\":\"1\"},"
|
||||
"{\"begin\":2,\"end\":4,\"name\":\"JUMPDEST\",\"source\":-1},"
|
||||
"{\"begin\":0,\"end\":14,\"name\":\"POP\",\"source\":0},"
|
||||
"{\"begin\":0,\"end\":14,\"name\":\"PUSH #[$]\",\"source\":0,\"value\":\"0000000000000000000000000000000000000000000000000000000000000000\"},"
|
||||
"{\"begin\":0,\"end\":14,\"name\":\"DUP1\",\"source\":0},"
|
||||
"{\"begin\":0,\"end\":14,\"name\":\"PUSH [$]\",\"source\":0,\"value\":\"0000000000000000000000000000000000000000000000000000000000000000\"},"
|
||||
"{\"begin\":0,\"end\":14,\"name\":\"PUSH\",\"source\":0,\"value\":\"0\"},"
|
||||
"{\"begin\":0,\"end\":14,\"name\":\"CODECOPY\",\"source\":0},"
|
||||
"{\"begin\":0,\"end\":14,\"name\":\"PUSH\",\"source\":0,\"value\":\"0\"},"
|
||||
"{\"begin\":0,\"end\":14,\"name\":\"RETURN\",\"source\":0}]"
|
||||
);
|
||||
BOOST_CHECK(contract["metadata"].isString());
|
||||
BOOST_CHECK(solidity::test::isValidMetadata(contract["metadata"].asString()));
|
||||
|
||||
@@ -16,9 +16,10 @@
|
||||
*/
|
||||
|
||||
#include <test/libsolidity/SyntaxTest.h>
|
||||
#include <test/Options.h>
|
||||
#include <test/Common.h>
|
||||
#include <boost/algorithm/string.hpp>
|
||||
#include <boost/algorithm/string/predicate.hpp>
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#include <boost/throw_exception.hpp>
|
||||
#include <fstream>
|
||||
#include <memory>
|
||||
@@ -34,34 +35,8 @@ using namespace solidity::frontend::test;
|
||||
using namespace boost::unit_test;
|
||||
namespace fs = boost::filesystem;
|
||||
|
||||
namespace
|
||||
SyntaxTest::SyntaxTest(string const& _filename, langutil::EVMVersion _evmVersion, bool _parserErrorRecovery): CommonSyntaxTest(_filename, _evmVersion)
|
||||
{
|
||||
|
||||
int parseUnsignedInteger(string::iterator& _it, string::iterator _end)
|
||||
{
|
||||
if (_it == _end || !isdigit(*_it))
|
||||
throw runtime_error("Invalid test expectation. Source location expected.");
|
||||
int result = 0;
|
||||
while (_it != _end && isdigit(*_it))
|
||||
{
|
||||
result *= 10;
|
||||
result += *_it - '0';
|
||||
++_it;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
SyntaxTest::SyntaxTest(string const& _filename, langutil::EVMVersion _evmVersion, bool _parserErrorRecovery): m_evmVersion(_evmVersion)
|
||||
{
|
||||
ifstream file(_filename);
|
||||
if (!file)
|
||||
BOOST_THROW_EXCEPTION(runtime_error("Cannot open test contract: \"" + _filename + "\"."));
|
||||
file.exceptions(ios::badbit);
|
||||
|
||||
m_sources = parseSourcesAndSettings(file);
|
||||
|
||||
if (m_settings.count("optimize-yul"))
|
||||
{
|
||||
if (m_settings["optimize-yul"] == "true")
|
||||
@@ -76,7 +51,6 @@ SyntaxTest::SyntaxTest(string const& _filename, langutil::EVMVersion _evmVersion
|
||||
m_optimiseYul = false;
|
||||
}
|
||||
}
|
||||
m_expectations = parseExpectations(file);
|
||||
m_parserErrorRecovery = _parserErrorRecovery;
|
||||
}
|
||||
|
||||
@@ -89,83 +63,6 @@ TestCase::TestResult SyntaxTest::run(ostream& _stream, string const& _linePrefix
|
||||
return printExpectationAndError(_stream, _linePrefix, _formatted) ? TestResult::Success : TestResult::Failure;
|
||||
}
|
||||
|
||||
bool SyntaxTest::printExpectationAndError(ostream& _stream, string const& _linePrefix, bool _formatted)
|
||||
{
|
||||
if (m_expectations != m_errorList)
|
||||
{
|
||||
string nextIndentLevel = _linePrefix + " ";
|
||||
AnsiColorized(_stream, _formatted, {BOLD, CYAN}) << _linePrefix << "Expected result:" << endl;
|
||||
printErrorList(_stream, m_expectations, nextIndentLevel, _formatted);
|
||||
AnsiColorized(_stream, _formatted, {BOLD, CYAN}) << _linePrefix << "Obtained result:" << endl;
|
||||
printErrorList(_stream, m_errorList, nextIndentLevel, _formatted);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void SyntaxTest::printSource(ostream& _stream, string const& _linePrefix, bool _formatted) const
|
||||
{
|
||||
|
||||
if (m_sources.empty())
|
||||
return;
|
||||
|
||||
bool outputSourceNames = true;
|
||||
if (m_sources.size() == 1 && m_sources.begin()->first.empty())
|
||||
outputSourceNames = false;
|
||||
|
||||
if (_formatted)
|
||||
{
|
||||
for (auto const& [name, source]: m_sources)
|
||||
{
|
||||
if (outputSourceNames)
|
||||
_stream << _linePrefix << formatting::CYAN << "==== Source: " << name << " ====" << formatting::RESET << endl;
|
||||
vector<char const*> sourceFormatting(source.length(), formatting::RESET);
|
||||
for (auto const& error: m_errorList)
|
||||
if (error.sourceName == name && error.locationStart >= 0 && error.locationEnd >= 0)
|
||||
{
|
||||
assert(static_cast<size_t>(error.locationStart) <= source.length());
|
||||
assert(static_cast<size_t>(error.locationEnd) <= source.length());
|
||||
bool isWarning = error.type == "Warning";
|
||||
for (int i = error.locationStart; i < error.locationEnd; i++)
|
||||
if (isWarning)
|
||||
{
|
||||
if (sourceFormatting[i] == formatting::RESET)
|
||||
sourceFormatting[i] = formatting::ORANGE_BACKGROUND_256;
|
||||
}
|
||||
else
|
||||
sourceFormatting[i] = formatting::RED_BACKGROUND;
|
||||
}
|
||||
|
||||
_stream << _linePrefix << sourceFormatting.front() << source.front();
|
||||
for (size_t i = 1; i < source.length(); i++)
|
||||
{
|
||||
if (sourceFormatting[i] != sourceFormatting[i - 1])
|
||||
_stream << sourceFormatting[i];
|
||||
if (source[i] != '\n')
|
||||
_stream << source[i];
|
||||
else
|
||||
{
|
||||
_stream << formatting::RESET << endl;
|
||||
if (i + 1 < source.length())
|
||||
_stream << _linePrefix << sourceFormatting[i];
|
||||
}
|
||||
}
|
||||
_stream << formatting::RESET;
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
for (auto const& [name, source]: m_sources)
|
||||
{
|
||||
if (outputSourceNames)
|
||||
_stream << _linePrefix << "==== Source: " + name << " ====" << endl;
|
||||
stringstream stream(source);
|
||||
string line;
|
||||
while (getline(stream, line))
|
||||
_stream << _linePrefix << line << endl;
|
||||
}
|
||||
}
|
||||
|
||||
void SyntaxTest::setupCompiler()
|
||||
{
|
||||
string const versionPragma = "pragma solidity >=0.0;\n";
|
||||
@@ -230,102 +127,3 @@ void SyntaxTest::filterObtainedErrors()
|
||||
}
|
||||
}
|
||||
|
||||
void SyntaxTest::printErrorList(
|
||||
ostream& _stream,
|
||||
vector<SyntaxTestError> const& _errorList,
|
||||
string const& _linePrefix,
|
||||
bool _formatted
|
||||
)
|
||||
{
|
||||
if (_errorList.empty())
|
||||
AnsiColorized(_stream, _formatted, {BOLD, GREEN}) << _linePrefix << "Success" << endl;
|
||||
else
|
||||
for (auto const& error: _errorList)
|
||||
{
|
||||
{
|
||||
AnsiColorized scope(_stream, _formatted, {BOLD, (error.type == "Warning") ? YELLOW : RED});
|
||||
_stream << _linePrefix;
|
||||
_stream << error.type << ": ";
|
||||
}
|
||||
if (!error.sourceName.empty() || error.locationStart >= 0 || error.locationEnd >= 0)
|
||||
{
|
||||
_stream << "(";
|
||||
if (!error.sourceName.empty())
|
||||
_stream << error.sourceName << ":";
|
||||
if (error.locationStart >= 0)
|
||||
_stream << error.locationStart;
|
||||
_stream << "-";
|
||||
if (error.locationEnd >= 0)
|
||||
_stream << error.locationEnd;
|
||||
_stream << "): ";
|
||||
}
|
||||
_stream << error.message << endl;
|
||||
}
|
||||
}
|
||||
|
||||
string SyntaxTest::errorMessage(Exception const& _e)
|
||||
{
|
||||
if (_e.comment() && !_e.comment()->empty())
|
||||
return boost::replace_all_copy(*_e.comment(), "\n", "\\n");
|
||||
else
|
||||
return "NONE";
|
||||
}
|
||||
|
||||
vector<SyntaxTestError> SyntaxTest::parseExpectations(istream& _stream)
|
||||
{
|
||||
vector<SyntaxTestError> expectations;
|
||||
string line;
|
||||
while (getline(_stream, line))
|
||||
{
|
||||
auto it = line.begin();
|
||||
|
||||
skipSlashes(it, line.end());
|
||||
skipWhitespace(it, line.end());
|
||||
|
||||
if (it == line.end()) continue;
|
||||
|
||||
auto typeBegin = it;
|
||||
while (it != line.end() && *it != ':')
|
||||
++it;
|
||||
string errorType(typeBegin, it);
|
||||
|
||||
// skip colon
|
||||
if (it != line.end()) it++;
|
||||
|
||||
skipWhitespace(it, line.end());
|
||||
|
||||
int locationStart = -1;
|
||||
int locationEnd = -1;
|
||||
std::string sourceName;
|
||||
|
||||
if (it != line.end() && *it == '(')
|
||||
{
|
||||
++it;
|
||||
if (it != line.end() && !isdigit(*it))
|
||||
{
|
||||
auto sourceNameStart = it;
|
||||
while (it != line.end() && *it != ':')
|
||||
++it;
|
||||
sourceName = std::string(sourceNameStart, it);
|
||||
expect(it, line.end(), ':');
|
||||
}
|
||||
locationStart = parseUnsignedInteger(it, line.end());
|
||||
expect(it, line.end(), '-');
|
||||
locationEnd = parseUnsignedInteger(it, line.end());
|
||||
expect(it, line.end(), ')');
|
||||
expect(it, line.end(), ':');
|
||||
}
|
||||
|
||||
skipWhitespace(it, line.end());
|
||||
|
||||
string errorMessage(it, line.end());
|
||||
expectations.emplace_back(SyntaxTestError{
|
||||
move(errorType),
|
||||
move(errorMessage),
|
||||
move(sourceName),
|
||||
locationStart,
|
||||
locationEnd
|
||||
});
|
||||
}
|
||||
return expectations;
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
|
||||
#include <test/libsolidity/AnalysisFramework.h>
|
||||
#include <test/TestCase.h>
|
||||
#include <test/CommonSyntaxTest.h>
|
||||
#include <liblangutil/Exceptions.h>
|
||||
#include <libsolutil/AnsiColorized.h>
|
||||
|
||||
@@ -30,25 +31,9 @@
|
||||
namespace solidity::frontend::test
|
||||
{
|
||||
|
||||
struct SyntaxTestError
|
||||
{
|
||||
std::string type;
|
||||
std::string message;
|
||||
std::string sourceName;
|
||||
int locationStart;
|
||||
int locationEnd;
|
||||
bool operator==(SyntaxTestError const& _rhs) const
|
||||
{
|
||||
return type == _rhs.type &&
|
||||
message == _rhs.message &&
|
||||
sourceName == _rhs.sourceName &&
|
||||
locationStart == _rhs.locationStart &&
|
||||
locationEnd == _rhs.locationEnd;
|
||||
}
|
||||
};
|
||||
using solidity::test::SyntaxTestError;
|
||||
|
||||
|
||||
class SyntaxTest: public AnalysisFramework, public EVMVersionRestrictedTestCase
|
||||
class SyntaxTest: public AnalysisFramework, public solidity::test::CommonSyntaxTest
|
||||
{
|
||||
public:
|
||||
static std::unique_ptr<TestCase> create(Config const& _config)
|
||||
@@ -63,35 +48,12 @@ public:
|
||||
|
||||
TestResult run(std::ostream& _stream, std::string const& _linePrefix = "", bool _formatted = false) override;
|
||||
|
||||
void printSource(std::ostream &_stream, std::string const &_linePrefix = "", bool _formatted = false) const override;
|
||||
void printUpdatedExpectations(std::ostream& _stream, std::string const& _linePrefix) const override
|
||||
{
|
||||
if (!m_errorList.empty())
|
||||
printErrorList(_stream, m_errorList, _linePrefix, false);
|
||||
}
|
||||
|
||||
static std::string errorMessage(util::Exception const& _e);
|
||||
protected:
|
||||
void setupCompiler();
|
||||
void parseAndAnalyze();
|
||||
void parseAndAnalyze() override;
|
||||
void filterObtainedErrors();
|
||||
|
||||
static void printErrorList(
|
||||
std::ostream& _stream,
|
||||
std::vector<SyntaxTestError> const& _errors,
|
||||
std::string const& _linePrefix,
|
||||
bool _formatted = false
|
||||
);
|
||||
|
||||
virtual bool printExpectationAndError(std::ostream& _stream, std::string const& _linePrefix = "", bool _formatted = false);
|
||||
|
||||
static std::vector<SyntaxTestError> parseExpectations(std::istream& _stream);
|
||||
|
||||
std::map<std::string, std::string> m_sources;
|
||||
std::vector<SyntaxTestError> m_expectations;
|
||||
std::vector<SyntaxTestError> m_errorList;
|
||||
bool m_optimiseYul = true;
|
||||
langutil::EVMVersion const m_evmVersion;
|
||||
bool m_parserErrorRecovery = false;
|
||||
};
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
|
||||
#include <test/libsolidity/AnalysisFramework.h>
|
||||
|
||||
#include <test/Options.h>
|
||||
#include <test/Common.h>
|
||||
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
@@ -52,7 +52,7 @@ BOOST_AUTO_TEST_CASE(environment_access)
|
||||
"this",
|
||||
"address(1).balance",
|
||||
};
|
||||
if (solidity::test::Options::get().evmVersion().hasStaticCall())
|
||||
if (solidity::test::CommonOptions::get().evmVersion().hasStaticCall())
|
||||
view.emplace_back("address(0x4242).staticcall(\"\")");
|
||||
|
||||
// ``block.blockhash`` and ``blockhash`` are tested separately below because their usage will
|
||||
@@ -105,7 +105,7 @@ BOOST_AUTO_TEST_CASE(address_staticcall)
|
||||
}
|
||||
}
|
||||
)";
|
||||
if (!solidity::test::Options::get().evmVersion().hasStaticCall())
|
||||
if (!solidity::test::CommonOptions::get().evmVersion().hasStaticCall())
|
||||
CHECK_ERROR(text, TypeError, "\"staticcall\" is not supported by the VM version.");
|
||||
else
|
||||
CHECK_SUCCESS_NO_WARNINGS(text);
|
||||
@@ -121,9 +121,7 @@ BOOST_AUTO_TEST_CASE(assembly_staticcall)
|
||||
}
|
||||
}
|
||||
)";
|
||||
if (!solidity::test::Options::get().evmVersion().hasStaticCall())
|
||||
CHECK_ERROR(text, TypeError, "\"staticcall\" instruction is only available for Byzantium-compatible");
|
||||
else
|
||||
if (solidity::test::CommonOptions::get().evmVersion().hasStaticCall())
|
||||
CHECK_SUCCESS_NO_WARNINGS(text);
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
pragma solidity >= 0.6.0;
|
||||
|
||||
contract C {
|
||||
function h(uint[4] memory n) public pure returns (uint) {
|
||||
return n[0] + n[1] + n[2] + n[3];
|
||||
}
|
||||
|
||||
function i(uint[4] memory n) public view returns (uint) {
|
||||
return this.h(n) * 2;
|
||||
}
|
||||
}
|
||||
|
||||
// ====
|
||||
// compileViaYul: also
|
||||
// ----
|
||||
// h(uint256[4]): 1, 2, 3, 4 -> 10
|
||||
// i(uint256[4]): 1, 2, 3, 4 -> 20
|
||||
@@ -2,5 +2,6 @@ contract test {
|
||||
}
|
||||
// ====
|
||||
// compileViaYul: also
|
||||
// allowNonExistingFunctions: true
|
||||
// ----
|
||||
// i_am_not_there() -> FAILURE
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
pragma solidity >= 0.6.0;
|
||||
|
||||
contract C {
|
||||
function g(uint n) external pure returns (uint) {
|
||||
return n + 1;
|
||||
}
|
||||
|
||||
function f(uint n) public view returns (uint) {
|
||||
return this.g(2 * n);
|
||||
}
|
||||
}
|
||||
|
||||
// ====
|
||||
// compileViaYul: also
|
||||
// ----
|
||||
// g(uint256): 4 -> 5
|
||||
// f(uint256): 2 -> 5
|
||||
@@ -0,0 +1,24 @@
|
||||
pragma solidity >= 0.6.0;
|
||||
|
||||
contract C {
|
||||
function d(uint n) external pure returns (uint[] memory) {
|
||||
uint[] memory data = new uint[](n);
|
||||
for (uint i = 0; i < data.length; ++i)
|
||||
data[i] = i;
|
||||
return data;
|
||||
}
|
||||
|
||||
function dt(uint n) public view returns (uint) {
|
||||
uint[] memory data = this.d(n);
|
||||
uint sum = 0;
|
||||
for (uint i = 0; i < data.length; ++i)
|
||||
sum += data[i];
|
||||
return sum;
|
||||
}
|
||||
}
|
||||
|
||||
// ====
|
||||
// compileViaYul: also
|
||||
// EVMVersion: >=byzantium
|
||||
// ----
|
||||
// dt(uint256): 4 -> 6
|
||||
@@ -0,0 +1,23 @@
|
||||
contract test {
|
||||
uint256 public data;
|
||||
bytes6 public name;
|
||||
bytes32 public a_hash;
|
||||
address public an_address;
|
||||
constructor() public {
|
||||
data = 8;
|
||||
name = "Celina";
|
||||
a_hash = keccak256("\x7b");
|
||||
an_address = address(0x1337);
|
||||
super_secret_data = 42;
|
||||
}
|
||||
uint256 super_secret_data;
|
||||
}
|
||||
// ====
|
||||
// allowNonExistingFunctions: true
|
||||
// compileViaYul: also
|
||||
// ----
|
||||
// data() -> 8
|
||||
// name() -> "Celina"
|
||||
// a_hash() -> 0xa91eddf639b0b768929589c1a9fd21dcb0107199bdd82e55c5348018a1572f52
|
||||
// an_address() -> 0x1337
|
||||
// super_secret_data() -> FAILURE
|
||||
@@ -4,6 +4,8 @@ contract test {
|
||||
function c() public returns(uint n) { return 2; }
|
||||
function f() public returns(uint n) { return 3; }
|
||||
}
|
||||
// ====
|
||||
// allowNonExistingFunctions: true
|
||||
// ----
|
||||
// a() -> 0
|
||||
// b() -> 1
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
contract C {
|
||||
function f() public payable returns (uint) {
|
||||
return msg.value;
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// f(), 1 ether -> 1000000000000000000
|
||||
// f(), 1 wei -> 1
|
||||
@@ -9,4 +9,4 @@ contract C {
|
||||
// EVMVersion: >=istanbul
|
||||
// compileViaYul: also
|
||||
// ----
|
||||
// f(), 254 ether -> 254
|
||||
// f(), 254 wei -> 254
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
contract C {
|
||||
struct S {
|
||||
uint a;
|
||||
uint b;
|
||||
}
|
||||
|
||||
mapping(uint => S) public mappingAccess;
|
||||
|
||||
function data() internal view returns (S storage _data) {
|
||||
// We need to assign it from somewhere, otherwise we would
|
||||
// get an "uninitialized access" error.
|
||||
_data = mappingAccess[20];
|
||||
|
||||
bytes32 slot = keccak256(abi.encode(uint(1), uint(0)));
|
||||
assembly {
|
||||
_data_slot := slot
|
||||
}
|
||||
}
|
||||
|
||||
function set(uint x) public {
|
||||
data().a = x;
|
||||
}
|
||||
|
||||
function get() public view returns (uint) {
|
||||
return data().a;
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// get() -> 0
|
||||
// mappingAccess(uint256): 1 -> 0, 0
|
||||
// set(uint256): 4
|
||||
// get() -> 4
|
||||
// mappingAccess(uint256): 1 -> 4, 0
|
||||
@@ -0,0 +1,12 @@
|
||||
contract C {
|
||||
function f() public returns (uint x, uint y) {
|
||||
assembly {
|
||||
x := true
|
||||
y := false
|
||||
}
|
||||
}
|
||||
}
|
||||
// ====
|
||||
// compileViaYul: also
|
||||
// ----
|
||||
// f() -> 1, 0
|
||||
@@ -0,0 +1,39 @@
|
||||
interface Parent {
|
||||
function parentFun() external returns (uint256);
|
||||
}
|
||||
|
||||
interface SubA is Parent {
|
||||
function subAFun() external returns (uint256);
|
||||
}
|
||||
|
||||
interface SubB is Parent {
|
||||
function subBFun() external returns (uint256);
|
||||
}
|
||||
|
||||
contract Impl is SubA, SubB {
|
||||
function parentFun() override external returns (uint256) { return 1; }
|
||||
function subAFun() override external returns (uint256) { return 2; }
|
||||
function subBFun() override external returns (uint256) { return 3; }
|
||||
}
|
||||
|
||||
contract C {
|
||||
function convertParent() public returns (uint256) {
|
||||
Parent p = new Impl();
|
||||
return p.parentFun();
|
||||
}
|
||||
|
||||
function convertSubA() public returns (uint256, uint256) {
|
||||
SubA sa = new Impl();
|
||||
return (sa.parentFun(), sa.subAFun());
|
||||
}
|
||||
|
||||
function convertSubB() public returns (uint256, uint256) {
|
||||
SubB sb = new Impl();
|
||||
return (sb.parentFun(), sb.subBFun());
|
||||
}
|
||||
}
|
||||
|
||||
// ----
|
||||
// convertParent() -> 1
|
||||
// convertSubA() -> 1, 2
|
||||
// convertSubB() -> 1, 3
|
||||
@@ -6,7 +6,8 @@ contract A {
|
||||
// x() -> 0
|
||||
// ()
|
||||
// x() -> 1
|
||||
// (), 1 ether
|
||||
// (), 1 wei
|
||||
// x() -> 2
|
||||
// x(), 1 wei -> FAILURE
|
||||
// (): hex"00" -> FAILURE
|
||||
// (), 1 ether: hex"00" -> FAILURE
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
contract C {
|
||||
function f(uint256 start, uint256 end, uint256[] calldata arr) external pure {
|
||||
arr[start:end];
|
||||
}
|
||||
}
|
||||
// ====
|
||||
// EVMVersion: >=byzantium
|
||||
// revertStrings: debug
|
||||
// ----
|
||||
// f(uint256,uint256,uint256[]): 2, 1, 0x80, 3, 1, 2, 3 -> FAILURE, hex"08c379a0", 0x20, 22, "Slice starts after end"
|
||||
// f(uint256,uint256,uint256[]): 1, 5, 0x80, 3, 1, 2, 3 -> FAILURE, hex"08c379a0", 0x20, 28, "Slice is greater than length"
|
||||
@@ -0,0 +1,15 @@
|
||||
contract A {
|
||||
function g() public { revert("fail"); }
|
||||
}
|
||||
|
||||
contract C {
|
||||
A a = new A();
|
||||
function f() public {
|
||||
a.g();
|
||||
}
|
||||
}
|
||||
// ====
|
||||
// EVMVersion: >=byzantium
|
||||
// revertStrings: debug
|
||||
// ----
|
||||
// f() -> FAILURE, hex"08c379a0", 0x20, 4, "fail"
|
||||
@@ -0,0 +1,11 @@
|
||||
pragma experimental ABIEncoderV2;
|
||||
contract C {
|
||||
function f(uint256[][] calldata a) external returns (uint) {
|
||||
return 42;
|
||||
}
|
||||
}
|
||||
// ====
|
||||
// EVMVersion: >=byzantium
|
||||
// revertStrings: debug
|
||||
// ----
|
||||
// f(uint256[][]): 0x20, 1 -> FAILURE, hex"08c379a0", 0x20, 43, "ABI decoding: invalid calldata a", "rray stride"
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
pragma experimental ABIEncoderV2;
|
||||
contract C {
|
||||
function f(uint256[][2][] calldata x) external returns (uint256) {
|
||||
x[0];
|
||||
return 23;
|
||||
}
|
||||
}
|
||||
// ====
|
||||
// EVMVersion: >=byzantium
|
||||
// revertStrings: debug
|
||||
// ----
|
||||
// f(uint256[][2][]): 0x20, 0x01, 0x20, 0x00 -> FAILURE, hex"08c379a0", 0x20, 28, "Invalid calldata tail offset"
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
pragma experimental ABIEncoderV2;
|
||||
contract C {
|
||||
function f(uint256[][2][] calldata x) external returns (uint256) {
|
||||
return 42;
|
||||
}
|
||||
function g(uint256[][2][] calldata x) external returns (uint256) {
|
||||
return this.f(x);
|
||||
}
|
||||
}
|
||||
// ====
|
||||
// EVMVersion: >=byzantium
|
||||
// revertStrings: debug
|
||||
// ----
|
||||
// g(uint256[][2][]): 0x20, 0x01, 0x20, 0x00 -> FAILURE, hex"08c379a0", 0x20, 30, "Invalid calldata access offset"
|
||||
@@ -0,0 +1,11 @@
|
||||
pragma experimental ABIEncoderV2;
|
||||
contract C {
|
||||
function f(uint256[][] calldata x) external returns (uint256) {
|
||||
return x[0].length;
|
||||
}
|
||||
}
|
||||
// ====
|
||||
// EVMVersion: >=byzantium
|
||||
// revertStrings: debug
|
||||
// ----
|
||||
// f(uint256[][]): 0x20, 1, 0x20, 0x0100000000000000000000 -> FAILURE, hex"08c379a0", 0x20, 28, "Invalid calldata tail length"
|
||||
@@ -0,0 +1,11 @@
|
||||
pragma experimental ABIEncoderV2;
|
||||
contract C {
|
||||
function f(uint a, uint[] calldata b, uint c) external pure returns (uint) {
|
||||
return 7;
|
||||
}
|
||||
}
|
||||
// ====
|
||||
// EVMVersion: >=byzantium
|
||||
// revertStrings: debug
|
||||
// ----
|
||||
// f(uint256,uint256[],uint256): 6, 0x60, 9, 0x1000000000000000000000000000000000000000000000000000000000000002, 1, 2 -> FAILURE, hex"08c379a0", 0x20, 43, "ABI decoding: invalid calldata a", "rray length"
|
||||
@@ -0,0 +1,11 @@
|
||||
contract C {
|
||||
function d(bytes memory _data) public pure returns (uint8) {
|
||||
return abi.decode(_data, (uint8));
|
||||
}
|
||||
}
|
||||
// ====
|
||||
// EVMVersion: >=byzantium
|
||||
// revertStrings: debug
|
||||
// ABIEncoderV1Only: true
|
||||
// ----
|
||||
// d(bytes): 0x20, 0x01, 0x0000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex"08c379a0", 0x20, 18, "Calldata too short"
|
||||
@@ -0,0 +1,12 @@
|
||||
contract C {
|
||||
function f() external {}
|
||||
function g() external {
|
||||
C c = C(0x0000000000000000000000000000000000000000000000000000000000000000);
|
||||
c.f();
|
||||
}
|
||||
}
|
||||
// ====
|
||||
// EVMVersion: >=byzantium
|
||||
// revertStrings: debug
|
||||
// ----
|
||||
// g() -> FAILURE, hex"08c379a0", 0x20, 37, "Target contract does not contain", " code"
|
||||
@@ -0,0 +1,12 @@
|
||||
contract C {
|
||||
enum E {X, Y}
|
||||
function f(E[] calldata arr) external {
|
||||
arr[1];
|
||||
}
|
||||
}
|
||||
// ====
|
||||
// EVMVersion: >=byzantium
|
||||
// revertStrings: debug
|
||||
// ABIEncoderV1Only: true
|
||||
// ----
|
||||
// f(uint8[]): 0x20, 2, 3, 3 -> FAILURE, hex"08c379a0", 0x20, 17, "Enum out of range"
|
||||
@@ -0,0 +1,9 @@
|
||||
contract C {
|
||||
function f() public {}
|
||||
}
|
||||
// ====
|
||||
// EVMVersion: >=byzantium
|
||||
// revertStrings: debug
|
||||
// ----
|
||||
// f(), 1 ether -> FAILURE, hex"08c379a0", 0x20, 34, "Ether sent to non-payable functi", "on"
|
||||
// () -> FAILURE, hex"08c379a0", 0x20, 53, "Contract does not have fallback ", "nor receive functions"
|
||||
@@ -0,0 +1,9 @@
|
||||
contract C {
|
||||
function t(uint) public pure {}
|
||||
}
|
||||
// ====
|
||||
// EVMVersion: >=byzantium
|
||||
// compileViaYul: true
|
||||
// revertStrings: debug
|
||||
// ----
|
||||
// t(uint256) -> FAILURE, hex"08c379a0", 0x20, 34, "ABI decoding: tuple data too sho", "rt"
|
||||
@@ -0,0 +1,13 @@
|
||||
contract C {
|
||||
function d(bytes memory _data) public pure returns (uint8) {
|
||||
return abi.decode(_data, (uint8));
|
||||
}
|
||||
}
|
||||
// ====
|
||||
// EVMVersion: >=byzantium
|
||||
// revertStrings: debug
|
||||
// ABIEncoderV1Only: true
|
||||
// ----
|
||||
// d(bytes): 0x20, 0x20, 0x0000000000000000000000000000000000000000000000000000000000000000 -> 0
|
||||
// d(bytes): 0x100, 0x20, 0x0000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex"08c379a0", 0x20, 43, "ABI calldata decoding: invalid h", "ead pointer"
|
||||
// d(bytes): 0x20, 0x100, 0x0000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex"08c379a0", 0x20, 43, "ABI calldata decoding: invalid d", "ata pointer"
|
||||
@@ -0,0 +1,20 @@
|
||||
contract C {
|
||||
function dyn(uint ptr, uint start, uint x) public returns (bytes memory a) {
|
||||
assembly {
|
||||
mstore(0, start)
|
||||
mstore(start, add(start, 1))
|
||||
return(ptr, x)
|
||||
}
|
||||
}
|
||||
function f(uint ptr, uint start, uint x) public returns (bool) {
|
||||
this.dyn(ptr, start, x);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
// ====
|
||||
// EVMVersion: >=byzantium
|
||||
// revertStrings: debug
|
||||
// ABIEncoderV1Only: true
|
||||
// ----
|
||||
// f(uint256,uint256,uint256): 0, 0x200, 0x60 -> FAILURE, hex"08c379a0", 0x20, 39, "ABI memory decoding: invalid dat", "a start"
|
||||
// f(uint256,uint256,uint256): 0, 0x20, 0x60 -> FAILURE, hex"08c379a0", 0x20, 40, "ABI memory decoding: invalid dat", "a length"
|
||||
@@ -0,0 +1,16 @@
|
||||
library L {
|
||||
function g() external {}
|
||||
}
|
||||
contract C {
|
||||
function f() public returns (bytes memory) {
|
||||
(bool success, bytes memory result) = address(L).call(abi.encodeWithSignature("g()"));
|
||||
assert(!success);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
// ====
|
||||
// EVMVersion: >=byzantium
|
||||
// revertStrings: debug
|
||||
// ----
|
||||
// library: L
|
||||
// f() -> 32, 132, 3963877391197344453575983046348115674221700746820753546331534351508065746944, 862718293348820473429344482784628181556388621521298319395315527974912, 1518017211910606845658622928256476421055725129218887721595913401102969, 14649601406562900601407788686537400806574002225747213573947654179243427889152, 0
|
||||
@@ -0,0 +1,9 @@
|
||||
pragma experimental ABIEncoderV2;
|
||||
contract C {
|
||||
function f(uint[] memory a) public pure returns (uint) { return 7; }
|
||||
}
|
||||
// ====
|
||||
// EVMVersion: >=byzantium
|
||||
// revertStrings: debug
|
||||
// ----
|
||||
// f(uint256[]): 0x20, 1 -> FAILURE, hex"08c379a0", 0x20, 43, "ABI decoding: invalid calldata a", "rray stride"
|
||||
@@ -0,0 +1,9 @@
|
||||
pragma experimental ABIEncoderV2;
|
||||
contract C {
|
||||
function e(bytes memory a) public pure returns (uint) { return 7; }
|
||||
}
|
||||
// ====
|
||||
// EVMVersion: >=byzantium
|
||||
// revertStrings: debug
|
||||
// ----
|
||||
// e(bytes): 0x20, 7 -> FAILURE, hex"08c379a0", 0x20, 39, "ABI decoding: invalid byte array", " length"
|
||||
@@ -0,0 +1,27 @@
|
||||
contract A {
|
||||
receive() external payable {
|
||||
revert("no_receive");
|
||||
}
|
||||
}
|
||||
|
||||
contract C {
|
||||
A a = new A();
|
||||
receive() external payable {}
|
||||
function f() public {
|
||||
address(a).transfer(1 wei);
|
||||
}
|
||||
function h() public {
|
||||
address(a).transfer(100 ether);
|
||||
}
|
||||
function g() public view returns (uint) {
|
||||
return address(this).balance;
|
||||
}
|
||||
}
|
||||
// ====
|
||||
// EVMVersion: >=byzantium
|
||||
// revertStrings: debug
|
||||
// ----
|
||||
// (), 10 wei ->
|
||||
// g() -> 10
|
||||
// f() -> FAILURE, hex"08c379a0", 0x20, 10, "no_receive"
|
||||
// h() -> FAILURE
|
||||
@@ -0,0 +1,8 @@
|
||||
contract A {
|
||||
receive () external payable {}
|
||||
}
|
||||
// ====
|
||||
// EVMVersion: >=byzantium
|
||||
// revertStrings: debug
|
||||
// ----
|
||||
// (): hex"00" -> FAILURE, hex"08c379a0", 0x20, 41, "Unknown signature and no fallbac", "k defined"
|
||||
@@ -0,0 +1,23 @@
|
||||
contract B
|
||||
{
|
||||
}
|
||||
|
||||
contract A {
|
||||
function different_salt() public returns (bool) {
|
||||
B x = new B{salt: "abc"}();
|
||||
B y = new B{salt: "abcef"}();
|
||||
return x != y;
|
||||
}
|
||||
function same_salt() public returns (bool) {
|
||||
B x = new B{salt: "xyz"}();
|
||||
try new B{salt: "xyz"}() {} catch {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
// ====
|
||||
// EVMVersion: >=constantinople
|
||||
// ----
|
||||
// different_salt() -> true
|
||||
// same_salt() -> true
|
||||
@@ -0,0 +1,23 @@
|
||||
contract B
|
||||
{
|
||||
uint x;
|
||||
function getBalance() public view returns (uint) {
|
||||
return address(this).balance * 1000 + x;
|
||||
}
|
||||
constructor(uint _x) public payable {
|
||||
x = _x;
|
||||
}
|
||||
}
|
||||
|
||||
contract A {
|
||||
function f() public payable returns (uint, uint, uint) {
|
||||
B x = new B{salt: "abc", value: 3}(7);
|
||||
B y = new B{value: 3}{salt: "abc"}(8);
|
||||
B z = new B{value: 3, salt: "abc"}(9);
|
||||
return (x.getBalance(), y.getBalance(), z.getBalance());
|
||||
}
|
||||
}
|
||||
// ====
|
||||
// EVMVersion: >=constantinople
|
||||
// ----
|
||||
// f(), 10 ether -> 3007, 3008, 3009
|
||||
@@ -30,7 +30,8 @@ contract C {
|
||||
}
|
||||
// ----
|
||||
// d() ->
|
||||
// e(), 1 ether -> 1
|
||||
// e(), 1 wei -> 1
|
||||
// e(), 1 ether -> 1000000000000000000
|
||||
// f(uint256): 3 -> 3, 3
|
||||
// g() -> 2, 3
|
||||
// h(uint256,uint256): 1, -2 -> 3
|
||||
|
||||
@@ -11,7 +11,7 @@ contract C {
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// constructor(), 2 ether: 3 ->
|
||||
// constructor(), 2 wei: 3 ->
|
||||
// state() -> 3
|
||||
// balance() -> 2
|
||||
// update(uint256): 4
|
||||
|
||||
@@ -14,6 +14,7 @@ contract C {
|
||||
}
|
||||
}
|
||||
// ====
|
||||
// allowNonExistingFunctions: true
|
||||
// EVMVersion: >homestead
|
||||
// ----
|
||||
// _() -> FAILURE
|
||||
|
||||
@@ -16,8 +16,8 @@ contract A {
|
||||
// data() -> 2
|
||||
// externalData() -> 0x20, 2, left(0x42ef)
|
||||
// balance() -> 0
|
||||
// (), 1 ether
|
||||
// (), 1 wei
|
||||
// balance() -> 1
|
||||
// (), 2 ether: hex"fefe"
|
||||
// (), 2 wei: hex"fefe"
|
||||
// balance() -> 2
|
||||
// externalData() -> 0x20, 2, left(0xfefe)
|
||||
@@ -4,6 +4,7 @@ contract C {
|
||||
}
|
||||
}
|
||||
// ====
|
||||
// allowNonExistingFunctions: true
|
||||
// compileViaYul: also
|
||||
// ----
|
||||
// f(uint256,uint256,uint256,uint256,uint256): 1, 1, 1, 1, 1
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
interface A {}
|
||||
contract test {
|
||||
mapping(A => uint8) table;
|
||||
function get(A k) public returns (uint8 v) {
|
||||
return table[k];
|
||||
}
|
||||
function set(A k, uint8 v) public {
|
||||
table[k] = v;
|
||||
}
|
||||
}
|
||||
// ====
|
||||
// compileViaYul: also
|
||||
// ----
|
||||
// get(address): 0 -> 0
|
||||
// get(address): 0x01 -> 0
|
||||
// get(address): 0xa7 -> 0
|
||||
// set(address,uint8): 0x01, 0xa1 ->
|
||||
// get(address): 0 -> 0
|
||||
// get(address): 0x01 -> 0xa1
|
||||
// get(address): 0xa7 -> 0
|
||||
// set(address,uint8): 0x00, 0xef ->
|
||||
// get(address): 0 -> 0xef
|
||||
// get(address): 0x01 -> 0xa1
|
||||
// get(address): 0xa7 -> 0
|
||||
// set(address,uint8): 0x01, 0x05 ->
|
||||
// get(address): 0 -> 0xef
|
||||
// get(address): 0x01 -> 0x05
|
||||
// get(address): 0xa7 -> 0
|
||||
@@ -0,0 +1,38 @@
|
||||
interface A {}
|
||||
contract test {
|
||||
mapping(A => uint8) public table;
|
||||
function set(A k, uint8 v) public {
|
||||
table[k] = v;
|
||||
}
|
||||
function get(A k) public returns (uint8) {
|
||||
return this.table(k);
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// table(address): 0 -> 0
|
||||
// table(address): 0x01 -> 0
|
||||
// table(address): 0xa7 -> 0
|
||||
// get(address): 0 -> 0
|
||||
// get(address): 0x01 -> 0
|
||||
// get(address): 0xa7 -> 0
|
||||
// set(address,uint8): 0x01, 0xa1 ->
|
||||
// table(address): 0 -> 0
|
||||
// table(address): 0x01 -> 0xa1
|
||||
// table(address): 0xa7 -> 0
|
||||
// get(address): 0 -> 0
|
||||
// get(address): 0x01 -> 0xa1
|
||||
// get(address): 0xa7 -> 0
|
||||
// set(address,uint8): 0x00, 0xef ->
|
||||
// table(address): 0 -> 0xef
|
||||
// table(address): 0x01 -> 0xa1
|
||||
// table(address): 0xa7 -> 0
|
||||
// get(address): 0 -> 0xef
|
||||
// get(address): 0x01 -> 0xa1
|
||||
// get(address): 0xa7 -> 0
|
||||
// set(address,uint8): 0x01, 0x05 ->
|
||||
// table(address): 0 -> 0xef
|
||||
// table(address): 0x01 -> 0x05
|
||||
// table(address): 0xa7 -> 0
|
||||
// get(address): 0 -> 0xef
|
||||
// get(address): 0x01 -> 0x05
|
||||
// get(address): 0xa7 -> 0
|
||||
@@ -0,0 +1,35 @@
|
||||
interface A {}
|
||||
library L {
|
||||
function get(mapping(A => uint8) storage table, A k) external returns (uint8) {
|
||||
return table[k];
|
||||
}
|
||||
function set(mapping(A => uint8) storage table, A k, uint8 v) external {
|
||||
table[k] = v;
|
||||
}
|
||||
}
|
||||
contract test {
|
||||
mapping(A => uint8) table;
|
||||
function get(A k) public returns (uint8 v) {
|
||||
return L.get(table, k);
|
||||
}
|
||||
function set(A k, uint8 v) public {
|
||||
L.set(table, k, v);
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// library: L
|
||||
// get(address): 0 -> 0
|
||||
// get(address): 0x01 -> 0
|
||||
// get(address): 0xa7 -> 0
|
||||
// set(address,uint8): 0x01, 0xa1 ->
|
||||
// get(address): 0 -> 0
|
||||
// get(address): 0x01 -> 0xa1
|
||||
// get(address): 0xa7 -> 0
|
||||
// set(address,uint8): 0x00, 0xef ->
|
||||
// get(address): 0 -> 0xef
|
||||
// get(address): 0x01 -> 0xa1
|
||||
// get(address): 0xa7 -> 0
|
||||
// set(address,uint8): 0x01, 0x05 ->
|
||||
// get(address): 0 -> 0xef
|
||||
// get(address): 0x01 -> 0x05
|
||||
// get(address): 0xa7 -> 0
|
||||
@@ -0,0 +1,30 @@
|
||||
enum E { A, B, C }
|
||||
contract test {
|
||||
mapping(E => uint8) table;
|
||||
function get(E k) public returns (uint8 v) {
|
||||
return table[k];
|
||||
}
|
||||
function set(E k, uint8 v) public {
|
||||
table[k] = v;
|
||||
}
|
||||
}
|
||||
// ====
|
||||
// compileViaYul: also
|
||||
// ----
|
||||
// get(uint8): 0 -> 0
|
||||
// get(uint8): 0x01 -> 0
|
||||
// get(uint8): 0x02 -> 0
|
||||
// get(uint8): 0x03 -> FAILURE
|
||||
// get(uint8): 0xa7 -> FAILURE
|
||||
// set(uint8,uint8): 0x01, 0xa1 ->
|
||||
// get(uint8): 0 -> 0
|
||||
// get(uint8): 0x01 -> 0xa1
|
||||
// get(uint8): 0xa7 -> FAILURE
|
||||
// set(uint8,uint8): 0x00, 0xef ->
|
||||
// get(uint8): 0 -> 0xef
|
||||
// get(uint8): 0x01 -> 0xa1
|
||||
// get(uint8): 0xa7 -> FAILURE
|
||||
// set(uint8,uint8): 0x01, 0x05 ->
|
||||
// get(uint8): 0 -> 0xef
|
||||
// get(uint8): 0x01 -> 0x05
|
||||
// get(uint8): 0xa7 -> FAILURE
|
||||
@@ -0,0 +1,40 @@
|
||||
contract test {
|
||||
enum E { A, B, C }
|
||||
mapping(E => uint8) public table;
|
||||
function set(E k, uint8 v) public {
|
||||
table[k] = v;
|
||||
}
|
||||
function get(E k) public returns (uint8) {
|
||||
return this.table(k);
|
||||
}
|
||||
}
|
||||
// ====
|
||||
// ABIEncoderV1Only: true
|
||||
// ----
|
||||
// table(uint8): 0 -> 0
|
||||
// table(uint8): 0x01 -> 0
|
||||
// table(uint8): 0xa7 -> 0
|
||||
// get(uint8): 0 -> 0
|
||||
// get(uint8): 0x01 -> 0
|
||||
// get(uint8): 0xa7 -> FAILURE
|
||||
// set(uint8,uint8): 0x01, 0xa1 ->
|
||||
// table(uint8): 0 -> 0
|
||||
// table(uint8): 0x01 -> 0xa1
|
||||
// table(uint8): 0xa7 -> 0
|
||||
// get(uint8): 0 -> 0
|
||||
// get(uint8): 0x01 -> 0xa1
|
||||
// get(uint8): 0xa7 -> FAILURE
|
||||
// set(uint8,uint8): 0x00, 0xef ->
|
||||
// table(uint8): 0 -> 0xef
|
||||
// table(uint8): 0x01 -> 0xa1
|
||||
// table(uint8): 0xa7 -> 0
|
||||
// get(uint8): 0 -> 0xef
|
||||
// get(uint8): 0x01 -> 0xa1
|
||||
// get(uint8): 0xa7 -> FAILURE
|
||||
// set(uint8,uint8): 0x01, 0x05 ->
|
||||
// table(uint8): 0 -> 0xef
|
||||
// table(uint8): 0x01 -> 0x05
|
||||
// table(uint8): 0xa7 -> 0
|
||||
// get(uint8): 0 -> 0xef
|
||||
// get(uint8): 0x01 -> 0x05
|
||||
// get(uint8): 0xa7 -> FAILURE
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user