Merge remote-tracking branch 'origin/develop' into HEAD

This commit is contained in:
chriseth
2020-02-27 15:06:36 +01:00
671 changed files with 19686 additions and 9996 deletions
+4 -4
View File
@@ -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));
+2 -2
View File
@@ -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");
+3 -3
View File
@@ -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
+18 -1
View File
@@ -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":
[
{
+61 -31
View File
@@ -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"
}
+227
View File
@@ -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"
}
+8
View File
@@ -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"
}
+43 -4
View File
@@ -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();
}
+2 -2
View File
@@ -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())
+26 -20
View File
@@ -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}) +
+5 -5
View File
@@ -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);
+11 -7
View File
@@ -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)});
}
+3 -1
View File
@@ -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>
+6 -6
View File
@@ -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());
}
+22 -21
View File
@@ -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)
+13 -11
View File
@@ -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");
+3 -3
View File
@@ -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;
+2 -1
View File
@@ -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>
+1 -1
View File
@@ -16,7 +16,7 @@
*/
#include <test/libsolidity/SMTCheckerTest.h>
#include <test/Options.h>
#include <test/Common.h>
#include <libsolidity/formal/ModelChecker.h>
+3 -1
View File
@@ -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;
+47 -6
View File
@@ -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;
+3
View File
@@ -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;
};
}
+4 -2
View File
@@ -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);
+61 -109
View File
@@ -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
+16 -12
View File
@@ -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 {
+5 -3
View File
@@ -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));
}
+5 -3
View File
@@ -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);
}
+9 -8
View File
@@ -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");
+28 -27
View File
@@ -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()));
+3 -205
View File
@@ -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;
}
+4 -42
View File
@@ -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;
};
+4 -6
View File
@@ -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"
@@ -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"
@@ -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