mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Merge remote-tracking branch 'origin/develop' into HEAD
This commit is contained in:
@@ -49,14 +49,6 @@ public:
|
||||
m_compiler.setOptimiserSettings(solidity::test::CommonOptions::get().optimize);
|
||||
m_compiler.setEVMVersion(m_evmVersion);
|
||||
BOOST_REQUIRE_MESSAGE(m_compiler.compile(), "Compiling contract failed");
|
||||
|
||||
AssemblyItems const* items = m_compiler.runtimeAssemblyItems(m_compiler.lastContractName());
|
||||
ASTNode const& sourceUnit = m_compiler.ast("");
|
||||
BOOST_REQUIRE(items != nullptr);
|
||||
m_gasCosts = GasEstimator::breakToStatementLevel(
|
||||
GasEstimator(solidity::test::CommonOptions::get().evmVersion()).structuralEstimation(*items, vector<ASTNode const*>({&sourceUnit})),
|
||||
{&sourceUnit}
|
||||
);
|
||||
}
|
||||
|
||||
void testCreationTimeGas(string const& _sourceCode, u256 const& _tolerance = u256(0))
|
||||
@@ -118,43 +110,10 @@ public:
|
||||
gas += i != 0 ? GasCosts::txDataNonZeroGas(evmVersion) : GasCosts::txDataZeroGas;
|
||||
return gas;
|
||||
}
|
||||
|
||||
protected:
|
||||
map<ASTNode const*, evmasm::GasMeter::GasConsumption> m_gasCosts;
|
||||
};
|
||||
|
||||
BOOST_FIXTURE_TEST_SUITE(GasMeterTests, GasMeterTestFramework)
|
||||
|
||||
BOOST_AUTO_TEST_CASE(non_overlapping_filtered_costs)
|
||||
{
|
||||
char const* sourceCode = R"(
|
||||
contract test {
|
||||
bytes x;
|
||||
function f(uint a) public returns (uint b) {
|
||||
for (; a < 200; ++a) {
|
||||
x.push(0x09);
|
||||
b = a * a;
|
||||
}
|
||||
return f(a - 1);
|
||||
}
|
||||
}
|
||||
)";
|
||||
compile(sourceCode);
|
||||
for (auto first = m_gasCosts.cbegin(); first != m_gasCosts.cend(); ++first)
|
||||
{
|
||||
auto second = first;
|
||||
for (++second; second != m_gasCosts.cend(); ++second)
|
||||
if (first->first->location().intersects(second->first->location()))
|
||||
{
|
||||
BOOST_CHECK_MESSAGE(false, "Source locations should not overlap!");
|
||||
langutil::SourceReferenceFormatter formatter(cout);
|
||||
|
||||
formatter.printSourceLocation(&first->first->location());
|
||||
formatter.printSourceLocation(&second->first->location());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(simple_contract)
|
||||
{
|
||||
// Tests a simple "deploy contract" code without constructor. The actual contract is not relevant.
|
||||
|
||||
@@ -633,8 +633,8 @@ BOOST_AUTO_TEST_CASE(optimise_multi_stores)
|
||||
)";
|
||||
compileBothVersions(sourceCode);
|
||||
compareVersions("f()");
|
||||
BOOST_CHECK_EQUAL(numInstructions(m_nonOptimizedBytecode, Instruction::SSTORE), 9);
|
||||
BOOST_CHECK_EQUAL(numInstructions(m_optimizedBytecode, Instruction::SSTORE), 8);
|
||||
BOOST_CHECK_EQUAL(numInstructions(m_nonOptimizedBytecode, Instruction::SSTORE), 8);
|
||||
BOOST_CHECK_EQUAL(numInstructions(m_optimizedBytecode, Instruction::SSTORE), 7);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(optimise_constant_to_codecopy)
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
// Test to see if cleanup is performed properly during array copying
|
||||
contract C {
|
||||
uint128[] x;
|
||||
function f() public returns(bool) {
|
||||
x.push(42); x.push(42); x.push(42); x.push(42);
|
||||
uint128[] memory y = new uint128[](1);
|
||||
y[0] = 23;
|
||||
x = y;
|
||||
assembly { sstore(x.slot, 4) }
|
||||
|
||||
assert(x[0] == 23);
|
||||
assert(x[1] == 0);
|
||||
|
||||
assert(x[2] == 0);
|
||||
// Issue 9832: the cleanup was only performed for the first packed type leaving the rest of
|
||||
// the slot dirty.
|
||||
assert(x[3] == 0);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// f() -> true
|
||||
@@ -0,0 +1,48 @@
|
||||
// Issue 9832: Test to see if cleanup is performed properly after array copying
|
||||
contract C {
|
||||
uint40[] x;
|
||||
function f() public returns(bool) {
|
||||
|
||||
x.push(42); x.push(42); x.push(42); x.push(42);
|
||||
x.push(42); x.push(42); x.push(42); x.push(42);
|
||||
x.push(42); x.push(42); x.push(42); x.push(42);
|
||||
x.push(42); x.push(42); x.push(42); x.push(42);
|
||||
x.push(42); x.push(42); x.push(42); x.push(42);
|
||||
|
||||
uint40[] memory y = new uint40[](1);
|
||||
y[0] = 23;
|
||||
x = y;
|
||||
|
||||
assembly { sstore(x.slot, 20) }
|
||||
|
||||
assert(x[0] == 23);
|
||||
assert(x[1] == 0);
|
||||
assert(x[2] == 0);
|
||||
assert(x[3] == 0);
|
||||
|
||||
assert(x[4] == 0);
|
||||
assert(x[5] == 0);
|
||||
assert(x[6] == 0);
|
||||
assert(x[7] == 0);
|
||||
|
||||
assert(x[8] == 0);
|
||||
assert(x[9] == 0);
|
||||
assert(x[10] == 0);
|
||||
assert(x[11] == 0);
|
||||
|
||||
assert(x[12] == 0);
|
||||
assert(x[13] == 0);
|
||||
assert(x[14] == 0);
|
||||
assert(x[15] == 0);
|
||||
|
||||
assert(x[16] == 0);
|
||||
assert(x[17] == 0);
|
||||
assert(x[18] == 0);
|
||||
assert(x[19] == 0);
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// f() -> true
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
==== Source: A ====
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
library L {
|
||||
struct Item {
|
||||
uint x;
|
||||
}
|
||||
|
||||
function set(Item storage _item) external view {}
|
||||
}
|
||||
==== Source: B ====
|
||||
import "A";
|
||||
|
||||
contract Test {
|
||||
L.Item item;
|
||||
|
||||
function foo() public view {
|
||||
L.set(item);
|
||||
}
|
||||
}
|
||||
// ----
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
==== Source: A ====
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
contract C {
|
||||
struct Item {
|
||||
uint x;
|
||||
}
|
||||
|
||||
constructor(Item memory _item) {}
|
||||
}
|
||||
==== Source: B ====
|
||||
import "A";
|
||||
|
||||
contract Test {
|
||||
function foo() public {
|
||||
new C(C.Item(5));
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// TypeError 2443: (B:71-80): The type of this parameter, struct C.Item, is only supported in ABIEncoderV2. Use "pragma experimental ABIEncoderV2;" to enable the feature.
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
==== Source: A ====
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
contract C {
|
||||
struct Item {
|
||||
uint x;
|
||||
}
|
||||
|
||||
function set(uint _x, string memory _y, Item memory _item, bool _z) external view {}
|
||||
}
|
||||
==== Source: B ====
|
||||
import "A";
|
||||
|
||||
contract Test {
|
||||
function foo() public view {
|
||||
C(0x00).set({_item: C.Item(50), _z: false, _y: "abc", _x: 30});
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// TypeError 2443: (B:90-100): The type of this parameter, struct C.Item, is only supported in ABIEncoderV2. Use "pragma experimental ABIEncoderV2;" to enable the feature.
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
==== Source: A ====
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
contract C {
|
||||
struct Item {
|
||||
uint x;
|
||||
}
|
||||
|
||||
function get(Item memory _item) external {}
|
||||
}
|
||||
==== Source: B ====
|
||||
import "A";
|
||||
|
||||
contract Test {
|
||||
function foo() public {
|
||||
C c = new C();
|
||||
function(C.Item memory) external ptr = c.get;
|
||||
ptr(C.Item(5));
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// TypeError 2443: (B:146-155): The type of this parameter, struct C.Item, is only supported in ABIEncoderV2. Use "pragma experimental ABIEncoderV2;" to enable the feature.
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
==== Source: A ====
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
contract C {
|
||||
function f() external view returns (string[] memory) {}
|
||||
}
|
||||
==== Source: B ====
|
||||
import "A";
|
||||
|
||||
contract D {
|
||||
function g() public view {
|
||||
C(0x00).f();
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// TypeError 2428: (B:65-76): The type of return parameter 1, string[], is only supported in ABIEncoderV2. Use "pragma experimental ABIEncoderV2;" to enable the feature.
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
==== Source: A ====
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
contract C {
|
||||
struct Item {
|
||||
uint x;
|
||||
}
|
||||
|
||||
function get() external view returns(Item memory) {}
|
||||
}
|
||||
==== Source: B ====
|
||||
import "A";
|
||||
|
||||
contract Test {
|
||||
function foo() public view {
|
||||
C(0x00).get();
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// TypeError 2428: (B:70-83): The type of return parameter 1, struct C.Item, is only supported in ABIEncoderV2. Use "pragma experimental ABIEncoderV2;" to enable the feature.
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
==== Source: A ====
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
contract C {
|
||||
struct Item {
|
||||
uint[] y;
|
||||
}
|
||||
|
||||
function get() external view returns(Item memory) {}
|
||||
}
|
||||
==== Source: B ====
|
||||
import "A";
|
||||
|
||||
contract Test {
|
||||
function foo() public view {
|
||||
C(0x00).get();
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// TypeError 2428: (B:70-83): The type of return parameter 1, struct C.Item, is only supported in ABIEncoderV2. Use "pragma experimental ABIEncoderV2;" to enable the feature.
|
||||
@@ -0,0 +1,19 @@
|
||||
==== Source: A ====
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
library L {
|
||||
struct Item {
|
||||
uint x;
|
||||
}
|
||||
event E(Item _value);
|
||||
}
|
||||
==== Source: B ====
|
||||
import "A";
|
||||
|
||||
contract Test {
|
||||
function foo() public {
|
||||
emit L.E(L.Item(42));
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// TypeError 2443: (B:74-84): The type of this parameter, struct L.Item, is only supported in ABIEncoderV2. Use "pragma experimental ABIEncoderV2;" to enable the feature.
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
==== Source: A ====
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
library L {
|
||||
struct Item {
|
||||
uint x;
|
||||
}
|
||||
|
||||
function get(Item storage _item) external view {}
|
||||
}
|
||||
==== Source: B ====
|
||||
import "A";
|
||||
|
||||
contract Test {
|
||||
L.Item item;
|
||||
|
||||
function foo() public view {
|
||||
L.get(item);
|
||||
}
|
||||
}
|
||||
// ----
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
==== Source: A ====
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
library L {
|
||||
struct Item {
|
||||
uint x;
|
||||
}
|
||||
|
||||
function get() external view returns(Item memory) {}
|
||||
}
|
||||
==== Source: B ====
|
||||
import "A";
|
||||
|
||||
contract Test {
|
||||
function foo() public view {
|
||||
L.get();
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// TypeError 2428: (B:70-77): The type of return parameter 1, struct L.Item, is only supported in ABIEncoderV2. Use "pragma experimental ABIEncoderV2;" to enable the feature.
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
contract C {
|
||||
function get() public view returns (uint[][] memory) {}
|
||||
|
||||
function test() public view returns (bool) {
|
||||
uint[][] memory x = this.get();
|
||||
}
|
||||
}
|
||||
// ====
|
||||
// EVMVersion: >=byzantium
|
||||
// ----
|
||||
// Warning 2072: (166-183): Unused local variable.
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
contract C {
|
||||
function get() public view returns (uint[][] memory) {}
|
||||
|
||||
function test() public view returns (bool) {
|
||||
uint[][] memory x = this.get();
|
||||
}
|
||||
}
|
||||
// ====
|
||||
// EVMVersion: <byzantium
|
||||
// ----
|
||||
// TypeError 9574: (166-196): Type inaccessible dynamic type is not implicitly convertible to expected type uint256[] memory[] memory.
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
==== Source: A ====
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
contract C {
|
||||
struct Item {
|
||||
uint x;
|
||||
}
|
||||
|
||||
constructor(Item memory _item) {}
|
||||
}
|
||||
==== Source: B ====
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
import "A";
|
||||
|
||||
contract Test {
|
||||
function foo() public {
|
||||
new C(C.Item(5));
|
||||
}
|
||||
}
|
||||
// ----
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
==== Source: A ====
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
contract C {
|
||||
struct Item {
|
||||
uint x;
|
||||
}
|
||||
|
||||
function get(Item memory _item) external {}
|
||||
}
|
||||
==== Source: B ====
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
import "A";
|
||||
|
||||
contract Test {
|
||||
function foo() public {
|
||||
C c = new C();
|
||||
function(C.Item memory) external ptr = c.get;
|
||||
ptr(C.Item(5));
|
||||
}
|
||||
}
|
||||
// ----
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
==== Source: A ====
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
contract C {
|
||||
function f() external view returns (string[] memory) {}
|
||||
}
|
||||
==== Source: B ====
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
import "A";
|
||||
|
||||
contract D {
|
||||
function g() public view {
|
||||
C(0x00).f();
|
||||
}
|
||||
}
|
||||
// ----
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
==== Source: A ====
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
contract C {
|
||||
struct Item {
|
||||
uint x;
|
||||
}
|
||||
|
||||
function get() external view returns(Item memory) {}
|
||||
}
|
||||
==== Source: B ====
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
import "A";
|
||||
|
||||
contract Test {
|
||||
function foo() public view {
|
||||
C(0x00).get();
|
||||
}
|
||||
}
|
||||
// ----
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
==== Source: A ====
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
contract C {
|
||||
struct Item {
|
||||
uint[] y;
|
||||
}
|
||||
|
||||
function get() external view returns(Item memory) {}
|
||||
}
|
||||
==== Source: B ====
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
import "A";
|
||||
|
||||
contract Test {
|
||||
function foo() public view {
|
||||
C(0x00).get();
|
||||
}
|
||||
}
|
||||
// ----
|
||||
@@ -0,0 +1,20 @@
|
||||
==== Source: A ====
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
library L {
|
||||
struct Item {
|
||||
uint x;
|
||||
}
|
||||
event E(Item _value);
|
||||
}
|
||||
==== Source: B ====
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
import "A";
|
||||
|
||||
contract Test {
|
||||
function foo() public {
|
||||
emit L.E(L.Item(42));
|
||||
}
|
||||
}
|
||||
// ----
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
==== Source: A ====
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
library L {
|
||||
struct Item {
|
||||
uint x;
|
||||
}
|
||||
|
||||
function get(Item memory _item) external {}
|
||||
}
|
||||
==== Source: B ====
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
import "A";
|
||||
|
||||
contract Test {
|
||||
function foo() public {
|
||||
// NOTE: This test checks a case that is currently not possible (pointer to an external
|
||||
// library function) but it might become possible in the future.
|
||||
function(L.Item memory) external ptr = L.get;
|
||||
ptr(L.Item(5));
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// TypeError 9574: (B:269-313): Type function (struct L.Item memory) is not implicitly convertible to expected type function (struct L.Item memory) external.
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
==== Source: A ====
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
library L {
|
||||
struct Item {
|
||||
uint x;
|
||||
}
|
||||
|
||||
function get() external view returns(Item memory) {}
|
||||
}
|
||||
==== Source: B ====
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
import "A";
|
||||
|
||||
contract Test {
|
||||
function foo() public view {
|
||||
L.get();
|
||||
}
|
||||
}
|
||||
// ----
|
||||
@@ -0,0 +1,30 @@
|
||||
==== Source: A ====
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
struct Data {
|
||||
bool flag;
|
||||
}
|
||||
|
||||
contract A {
|
||||
function get() public view returns (Data memory) {}
|
||||
}
|
||||
==== Source: B ====
|
||||
import "A";
|
||||
|
||||
contract B {
|
||||
modifier validate() {
|
||||
A(0x00).get();
|
||||
_;
|
||||
}
|
||||
}
|
||||
==== Source: C ====
|
||||
import "B";
|
||||
|
||||
contract C is B {
|
||||
function foo()
|
||||
public
|
||||
validate()
|
||||
{}
|
||||
}
|
||||
// ----
|
||||
// TypeError 2428: (B:60-73): The type of return parameter 1, struct Data, is only supported in ABIEncoderV2. Use "pragma experimental ABIEncoderV2;" to enable the feature.
|
||||
@@ -0,0 +1,32 @@
|
||||
==== Source: A ====
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
struct Data {
|
||||
bool flag;
|
||||
}
|
||||
|
||||
contract A {
|
||||
function get() public view returns (Data memory) {}
|
||||
}
|
||||
==== Source: B ====
|
||||
import "A";
|
||||
|
||||
contract B {
|
||||
modifier validate() {
|
||||
A(0x00).get();
|
||||
_;
|
||||
}
|
||||
}
|
||||
==== Source: C ====
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
import "B";
|
||||
|
||||
contract C is B {
|
||||
function foo()
|
||||
public
|
||||
validate()
|
||||
{}
|
||||
}
|
||||
// ----
|
||||
// TypeError 2428: (B:60-73): The type of return parameter 1, struct Data, is only supported in ABIEncoderV2. Use "pragma experimental ABIEncoderV2;" to enable the feature.
|
||||
@@ -0,0 +1,11 @@
|
||||
contract C {
|
||||
function foo(uint x) public
|
||||
{
|
||||
// Used to cause an ICE
|
||||
uint p = new uint[] = x;
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// TypeError 4247: (100-110): Expression has to be an lvalue.
|
||||
// TypeError 7407: (113-114): Type uint256 is not implicitly convertible to expected type function (uint256) pure returns (uint256[] memory).
|
||||
// TypeError 9574: (91-114): Type function (uint256) pure returns (uint256[] memory) is not implicitly convertible to expected type uint256.
|
||||
Reference in New Issue
Block a user