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

This commit is contained in:
chriseth
2020-04-28 13:02:06 +02:00
195 changed files with 3903 additions and 1336 deletions
+13
View File
@@ -19,6 +19,7 @@
#include <test/TestCase.h>
#include <boost/algorithm/string/predicate.hpp>
#include <boost/algorithm/string.hpp>
#include <stdexcept>
#include <iostream>
@@ -60,6 +61,18 @@ void TestCase::expect(string::iterator& _it, string::iterator _end, string::valu
++_it;
}
void TestCase::printIndented(ostream& _stream, string const& _output, string const& _linePrefix) const
{
stringstream output(_output);
string line;
while (getline(output, line))
if (line.empty())
// Avoid trailing spaces.
_stream << boost::trim_right_copy(_linePrefix) << endl;
else
_stream << _linePrefix << line << endl;
}
EVMVersionRestrictedTestCase::EVMVersionRestrictedTestCase(string const& _filename):
TestCase(_filename)
{
+2
View File
@@ -93,6 +93,8 @@ protected:
++_it;
}
void printIndented(std::ostream& _stream, std::string const& _output, std::string const& _linePrefix = "") const;
TestCaseReader m_reader;
bool m_shouldRun = true;
};
+3 -1
View File
@@ -126,7 +126,7 @@ function test_solc_behaviour()
# Remove trailing empty lines. Needs a line break to make OSX sed happy.
sed -i.bak -e '1{/^$/d
}' "$stderr_path"
rm "$stderr_path.bak"
rm "$stderr_path.bak" "$stdout_path.bak"
fi
# Remove path to cpp file
sed -i.bak -e 's/^\(Exception while assembling:\).*/\1/' "$stderr_path"
@@ -175,6 +175,8 @@ function test_solc_behaviour()
exit 1
fi
fi
rm -f "$stdout_path" "$stderr_path"
}
@@ -0,0 +1 @@
--ir-optimized --optimize
@@ -0,0 +1,7 @@
pragma solidity >=0.6.0;
contract C {
constructor() public {}
}
contract D is C {
}
@@ -0,0 +1,55 @@
Optimized IR:
/*******************************************************
* WARNING *
* Solidity to Yul compilation is still EXPERIMENTAL *
* It can result in LOSS OF FUNDS or worse *
* !USE AT YOUR OWN RISK! *
*******************************************************/
object "C_6" {
code {
{
mstore(64, 128)
if callvalue() { revert(0, 0) }
let _1 := datasize("C_6_deployed")
codecopy(0, dataoffset("C_6_deployed"), _1)
return(0, _1)
}
}
object "C_6_deployed" {
code {
{
mstore(64, 128)
revert(0, 0)
}
}
}
}
Optimized IR:
/*******************************************************
* WARNING *
* Solidity to Yul compilation is still EXPERIMENTAL *
* It can result in LOSS OF FUNDS or worse *
* !USE AT YOUR OWN RISK! *
*******************************************************/
object "D_9" {
code {
{
mstore(64, 128)
if callvalue() { revert(0, 0) }
let _1 := datasize("D_9_deployed")
codecopy(0, dataoffset("D_9_deployed"), _1)
return(0, _1)
}
}
object "D_9_deployed" {
code {
{
mstore(64, 128)
revert(0, 0)
}
}
}
}
@@ -0,0 +1 @@
--ir-optimized --optimize
@@ -0,0 +1,5 @@
Warning: Unused local variable.
--> ir_compiler_subobjects/input.sol:6:9:
|
6 | C c = new C();
| ^^^
@@ -0,0 +1,8 @@
pragma solidity >=0.6.0;
contract C {}
contract D {
function f() public {
C c = new C();
}
}
@@ -0,0 +1,96 @@
Optimized IR:
/*******************************************************
* WARNING *
* Solidity to Yul compilation is still EXPERIMENTAL *
* It can result in LOSS OF FUNDS or worse *
* !USE AT YOUR OWN RISK! *
*******************************************************/
object "C_2" {
code {
{
mstore(64, 128)
if callvalue() { revert(0, 0) }
let _1 := datasize("C_2_deployed")
codecopy(0, dataoffset("C_2_deployed"), _1)
return(0, _1)
}
}
object "C_2_deployed" {
code {
{
mstore(64, 128)
revert(0, 0)
}
}
}
}
Optimized IR:
/*******************************************************
* WARNING *
* Solidity to Yul compilation is still EXPERIMENTAL *
* It can result in LOSS OF FUNDS or worse *
* !USE AT YOUR OWN RISK! *
*******************************************************/
object "D_13" {
code {
{
mstore(64, 128)
if callvalue() { revert(0, 0) }
let _1 := datasize("D_13_deployed")
codecopy(0, dataoffset("D_13_deployed"), _1)
return(0, _1)
}
}
object "D_13_deployed" {
code {
{
mstore(64, 128)
if iszero(lt(calldatasize(), 4))
{
let _1 := 0
if eq(0x26121ff0, shr(224, calldataload(_1)))
{
if callvalue() { revert(_1, _1) }
if slt(add(calldatasize(), not(3)), _1) { revert(_1, _1) }
let _2 := datasize("C_2")
let _3 := add(128, _2)
if or(gt(_3, 0xffffffffffffffff), lt(_3, 128)) { revert(_1, _1) }
datacopy(128, dataoffset("C_2"), _2)
pop(create(_1, 128, _2))
return(allocateMemory(_1), _1)
}
}
revert(0, 0)
}
function allocateMemory(size) -> memPtr
{
memPtr := mload(64)
let newFreePtr := add(memPtr, size)
if or(gt(newFreePtr, 0xffffffffffffffff), lt(newFreePtr, memPtr)) { revert(0, 0) }
mstore(64, newFreePtr)
}
}
object "C_2" {
code {
{
mstore(64, 128)
if callvalue() { revert(0, 0) }
let _1 := datasize("C_2_deployed")
codecopy(0, dataoffset("C_2_deployed"), _1)
return(0, _1)
}
}
object "C_2_deployed" {
code {
{
mstore(64, 128)
revert(0, 0)
}
}
}
}
}
}
+50
View File
@@ -0,0 +1,50 @@
Warning: Source file does not specify required compiler version!
--> message_format/input.sol
Warning: Unused local variable.
--> message_format/input.sol:9:27:
|
9 | function f() public { int x; }
| ^^^^^
Warning: Unused local variable.
--> message_format/input.sol:10:27:
|
10 | function g() public { int x; }
| ^^^^^
Warning: Unused local variable.
--> message_format/input.sol:99:14:
|
99 | /**/ int a; /**/
| ^^^^^
Warning: Unused local variable.
--> message_format/input.sol:100:14:
|
100 | /**/ int b; /**/
| ^^^^^
Warning: Unused local variable.
--> message_format/input.sol:101:14:
|
101 | /**/ int c; /**/
| ^^^^^
Warning: Function state mutability can be restricted to pure
--> message_format/input.sol:9:5:
|
9 | function f() public { int x; }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Warning: Function state mutability can be restricted to pure
--> message_format/input.sol:10:5:
|
10 | function g() public { int x; }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Warning: Function state mutability can be restricted to pure
--> message_format/input.sol:11:5:
|
11 | function h() public {
| ^ (Relevant source part starts here and spans across multiple lines).
+103
View File
@@ -0,0 +1,103 @@
// checks that error messages around power-or-10 lines are formatted correctly
contract C {
function f() public { int x; }
function g() public { int x; }
function h() public {
/**/ int a; /**/
/**/ int b; /**/
/**/ int c; /**/
}
}
@@ -1,6 +1,8 @@
{"contracts":{"A":{"C":{"ewasm":{"wast":"(module
;; sub-module \"C_2_deployed\" will be encoded as custom section in binary here, but is skipped in text mode.
(import \"ethereum\" \"codeCopy\" (func $eth.codeCopy (param i32 i32 i32)))
(import \"ethereum\" \"revert\" (func $eth.revert (param i32 i32)))
(import \"ethereum\" \"getCallValue\" (func $eth.getCallValue (param i32)))
(import \"ethereum\" \"finish\" (func $eth.finish (param i32 i32)))
(memory $memory (export \"memory\") 1)
(export \"main\" (func $main))
@@ -9,27 +11,30 @@
(local $_1 i64)
(local $p i64)
(local $r i64)
(local $hi i64)
(local $hi_1 i64)
(local $y i64)
(local $hi_2 i64)
(local $_2 i64)
(local $z1 i64)
(local $z2 i64)
(local $z3 i64)
(local $_3 i64)
(local.set $_1 (i64.const 0))
(local.set $p (call $u256_to_i32 (local.get $_1) (local.get $_1) (local.get $_1) (i64.const 64)))
(local.set $r (i64.extend_i32_u (i32.add (i32.wrap_i64 (local.get $p)) (i32.wrap_i64 (i64.const 64)))))
(if (i64.ne (i64.extend_i32_u (i32.lt_u (i32.wrap_i64 (local.get $r)) (i32.wrap_i64 (local.get $p)))) (i64.const 0)) (then
(unreachable)))
(local.set $hi (i64.shl (call $endian_swap_16 (local.get $_1)) (i64.const 16)))
(local.set $hi_1 (i64.shl (i64.or (local.get $hi) (call $endian_swap_16 (i64.shr_u (local.get $_1) (i64.const 16)))) (i64.const 32)))
(local.set $y (i64.or (local.get $hi_1) (call $endian_swap_32 (i64.shr_u (local.get $_1) (i64.const 32)))))
(i64.store (i32.wrap_i64 (local.get $r)) (local.get $y))
(i64.store (i32.wrap_i64 (i64.extend_i32_u (i32.add (i32.wrap_i64 (local.get $r)) (i32.wrap_i64 (i64.const 8))))) (local.get $y))
(i64.store (i32.wrap_i64 (i64.extend_i32_u (i32.add (i32.wrap_i64 (local.get $r)) (i32.wrap_i64 (i64.const 16))))) (local.get $y))
(local.set $hi_2 (i64.shl (call $endian_swap_32 (i64.const 128)) (i64.const 32)))
(i64.store (i32.wrap_i64 (i64.extend_i32_u (i32.add (i32.wrap_i64 (local.get $r)) (i32.wrap_i64 (i64.const 24))))) (i64.or (local.get $hi_2) (call $endian_swap_32 (i64.shr_u (i64.const 128) (i64.const 32)))))
(local.set $_2 (datasize \"C_2_deployed\"))
(call $eth.codeCopy (i32.wrap_i64 (call $to_internal_i32ptr (local.get $_1) (local.get $_1) (local.get $_1) (local.get $_1))) (i32.wrap_i64 (call $u256_to_i32 (local.get $_1) (local.get $_1) (local.get $_1) (dataoffset \"C_2_deployed\"))) (i32.wrap_i64 (call $u256_to_i32 (local.get $_1) (local.get $_1) (local.get $_1) (local.get $_2))))
(call $eth.finish (i32.wrap_i64 (call $to_internal_i32ptr (local.get $_1) (local.get $_1) (local.get $_1) (local.get $_1))) (i32.wrap_i64 (call $u256_to_i32 (local.get $_1) (local.get $_1) (local.get $_1) (local.get $_2))))
(local.set $_2 (call $endian_swap (local.get $_1)))
(i64.store (i32.wrap_i64 (local.get $r)) (local.get $_2))
(i64.store (i32.wrap_i64 (i64.extend_i32_u (i32.add (i32.wrap_i64 (local.get $r)) (i32.wrap_i64 (i64.const 8))))) (local.get $_2))
(i64.store (i32.wrap_i64 (i64.extend_i32_u (i32.add (i32.wrap_i64 (local.get $r)) (i32.wrap_i64 (i64.const 16))))) (local.get $_2))
(i64.store (i32.wrap_i64 (i64.extend_i32_u (i32.add (i32.wrap_i64 (local.get $r)) (i32.wrap_i64 (i64.const 24))))) (call $endian_swap (i64.const 128)))
(call $eth.getCallValue (i32.wrap_i64 (i64.const 0)))
(local.set $z1 (call $endian_swap (i64.load (i32.wrap_i64 (i64.const 0)))))
(local.set $z2 (call $endian_swap (i64.load (i32.wrap_i64 (i64.extend_i32_u (i32.add (i32.wrap_i64 (i64.const 0)) (i32.wrap_i64 (i64.const 8))))))))
(local.set $z3 (call $endian_swap (i64.load (i32.wrap_i64 (i64.extend_i32_u (i32.add (i32.wrap_i64 (i64.const 0)) (i32.wrap_i64 (i64.const 16))))))))
(if (i64.ne (i64.extend_i32_u (i32.eqz (i32.wrap_i64 (i64.extend_i32_u (i64.eqz (i64.or (i64.or (local.get $z1) (local.get $z2)) (i64.or (local.get $z3) (call $endian_swap (i64.load (i32.wrap_i64 (i64.extend_i32_u (i32.add (i32.wrap_i64 (i64.const 0)) (i32.wrap_i64 (i64.const 24)))))))))))))) (i64.const 0)) (then
(call $revert (local.get $_1) (local.get $_1) (local.get $_1) (local.get $_1) (local.get $_1) (local.get $_1) (local.get $_1) (local.get $_1))))
(local.set $_3 (datasize \"C_2_deployed\"))
(call $codecopy (local.get $_1) (local.get $_1) (local.get $_1) (local.get $_1) (local.get $_1) (local.get $_1) (local.get $_1) (dataoffset \"C_2_deployed\") (local.get $_1) (local.get $_1) (local.get $_1) (local.get $_3))
(call $return (local.get $_1) (local.get $_1) (local.get $_1) (local.get $_1) (local.get $_1) (local.get $_1) (local.get $_1) (local.get $_3))
)
(func $u256_to_i32
@@ -62,6 +67,22 @@
(local.get $r)
)
(func $codecopy
(param $x1 i64)
(param $x2 i64)
(param $x3 i64)
(param $x4 i64)
(param $y1 i64)
(param $y2 i64)
(param $y3 i64)
(param $y4 i64)
(param $z1 i64)
(param $z2 i64)
(param $z3 i64)
(param $z4 i64)
(call $eth.codeCopy (i32.wrap_i64 (call $to_internal_i32ptr (local.get $x1) (local.get $x2) (local.get $x3) (local.get $x4))) (i32.wrap_i64 (call $u256_to_i32 (local.get $y1) (local.get $y2) (local.get $y3) (local.get $y4))) (i32.wrap_i64 (call $u256_to_i32 (local.get $z1) (local.get $z2) (local.get $z3) (local.get $z4))))
)
(func $endian_swap_16
(param $x i64)
(result i64)
@@ -80,5 +101,39 @@
(local.get $y)
)
(func $endian_swap
(param $x i64)
(result i64)
(local $y i64)
(local $hi i64)
(local.set $hi (i64.shl (call $endian_swap_32 (local.get $x)) (i64.const 32)))
(local.set $y (i64.or (local.get $hi) (call $endian_swap_32 (i64.shr_u (local.get $x) (i64.const 32)))))
(local.get $y)
)
(func $return
(param $x1 i64)
(param $x2 i64)
(param $x3 i64)
(param $x4 i64)
(param $y1 i64)
(param $y2 i64)
(param $y3 i64)
(param $y4 i64)
(call $eth.finish (i32.wrap_i64 (call $to_internal_i32ptr (local.get $x1) (local.get $x2) (local.get $x3) (local.get $x4))) (i32.wrap_i64 (call $u256_to_i32 (local.get $y1) (local.get $y2) (local.get $y3) (local.get $y4))))
)
(func $revert
(param $x1 i64)
(param $x2 i64)
(param $x3 i64)
(param $x4 i64)
(param $y1 i64)
(param $y2 i64)
(param $y3 i64)
(param $y4 i64)
(call $eth.revert (i32.wrap_i64 (call $to_internal_i32ptr (local.get $x1) (local.get $x2) (local.get $x3) (local.get $x4))) (i32.wrap_i64 (call $u256_to_i32 (local.get $y1) (local.get $y2) (local.get $y3) (local.get $y4))))
)
)
"}}}},"sources":{"A":{"id":0}}}
@@ -8,8 +8,12 @@
object \"C_6\" {
code {
mstore(64, 128)
if callvalue() { revert(0, 0) }
constructor_C_6()
codecopy(0, dataoffset(\"C_6_deployed\"), datasize(\"C_6_deployed\"))
return(0, datasize(\"C_6_deployed\"))
function constructor_C_6()
{ }
}
object \"C_6_deployed\" {
code {
@@ -9,14 +9,16 @@
object \"C_6\" {
code {
mstore(64, 128)
if callvalue() { revert(0, 0) }
// Begin state variable initialization for contract \"C\" (0 variables)
// End state variable initialization for contract \"C\".
constructor_C_6()
codecopy(0, dataoffset(\"C_6_deployed\"), datasize(\"C_6_deployed\"))
return(0, datasize(\"C_6_deployed\"))
function constructor_C_6() {
}
}
object \"C_6_deployed\" {
@@ -44,7 +46,6 @@ object \"C_6\" {
if iszero(calldatasize()) { }
revert(0, 0)
function abi_decode_tuple_(headStart, dataEnd) {
if slt(sub(dataEnd, headStart), 0) { revert(0, 0) }
@@ -65,7 +66,6 @@ object \"C_6\" {
function fun_f_5() {
}
function shift_right_224_unsigned(value) -> newValue {
@@ -76,7 +76,9 @@ object \"C_6\" {
}
}
}
}
"}}},"sources":{"A":{"id":0}}}
@@ -0,0 +1,21 @@
{
"language": "Solidity",
"sources":
{
"A":
{
"content": "pragma solidity >=0.0; contract C { function f() public pure {} }"
}
},
"settings":
{
"optimizer": {
"details": {
"yul": true,
"yulDetails": {
"optimizerSteps": "dhfoDgvulfnTUtnIf\n[ xarrscLM\n]\njmuljuljul VcTOcul jmul"
}
}
}
}
}
@@ -0,0 +1 @@
{"sources":{"A":{"id":0}}}
@@ -0,0 +1,21 @@
{
"language": "Solidity",
"sources":
{
"A":
{
"content": "pragma solidity >=0.0; contract C { function f() public pure {} }"
}
},
"settings":
{
"optimizer": {
"details": {
"yul": true,
"yulDetails": {
"optimizerSteps": "abcdefg{hijklmno}pqr[st]uvwxyz"
}
}
}
}
}
@@ -0,0 +1 @@
{"errors":[{"component":"general","formattedMessage":"Invalid optimizer step sequence in \"settings.optimizer.details.optimizerSteps\": 'b' is not a valid step abbreviation","message":"Invalid optimizer step sequence in \"settings.optimizer.details.optimizerSteps\": 'b' is not a valid step abbreviation","severity":"error","type":"JSONError"}]}
@@ -0,0 +1,21 @@
{
"language": "Solidity",
"sources":
{
"A":
{
"content": "pragma solidity >=0.0; contract C { function f() public pure {} }"
}
},
"settings":
{
"optimizer": {
"details": {
"yul": true,
"yulDetails": {
"optimizerSteps": "a[a][aa[aa]]a"
}
}
}
}
}
@@ -0,0 +1 @@
{"errors":[{"component":"general","formattedMessage":"Invalid optimizer step sequence in \"settings.optimizer.details.optimizerSteps\": Nested brackets are not supported","message":"Invalid optimizer step sequence in \"settings.optimizer.details.optimizerSteps\": Nested brackets are not supported","severity":"error","type":"JSONError"}]}
@@ -0,0 +1,21 @@
{
"language": "Solidity",
"sources":
{
"A":
{
"content": "pragma solidity >=0.0; contract C { function f() public pure {} }"
}
},
"settings":
{
"optimizer": {
"details": {
"yul": true,
"yulDetails": {
"optimizerSteps": 42
}
}
}
}
}
@@ -0,0 +1 @@
{"errors":[{"component":"general","formattedMessage":"\"settings.optimizer.details.optimizerSteps\" must be a string","message":"\"settings.optimizer.details.optimizerSteps\" must be a string","severity":"error","type":"JSONError"}]}
@@ -0,0 +1,21 @@
{
"language": "Solidity",
"sources":
{
"A":
{
"content": "pragma solidity >=0.0; contract C { function f() public pure {} }"
}
},
"settings":
{
"optimizer": {
"details": {
"yul": true,
"yulDetails": {
"optimizerSteps": "a[a]["
}
}
}
}
}
@@ -0,0 +1 @@
{"errors":[{"component":"general","formattedMessage":"Invalid optimizer step sequence in \"settings.optimizer.details.optimizerSteps\": Unbalanced brackets","message":"Invalid optimizer step sequence in \"settings.optimizer.details.optimizerSteps\": Unbalanced brackets","severity":"error","type":"JSONError"}]}
+1 -1
View File
@@ -1,5 +1,5 @@
Warning: Source file does not specify required compiler version!
--> too_long_line/input.sol
--> too_long_line/input.sol
Error: Identifier not found or not unique.
--> too_long_line/input.sol:2:164:
@@ -1,5 +1,5 @@
Warning: Source file does not specify required compiler version!
--> too_long_line_both_sides_short/input.sol
--> too_long_line_both_sides_short/input.sol
Error: Identifier not found or not unique.
--> too_long_line_both_sides_short/input.sol:2:15:
+1 -1
View File
@@ -1,5 +1,5 @@
Warning: Source file does not specify required compiler version!
--> too_long_line_edge_in/input.sol
--> too_long_line_edge_in/input.sol
Error: Identifier not found or not unique.
--> too_long_line_edge_in/input.sol:2:36:
+1 -1
View File
@@ -1,5 +1,5 @@
Warning: Source file does not specify required compiler version!
--> too_long_line_edge_out/input.sol
--> too_long_line_edge_out/input.sol
Error: Identifier not found or not unique.
--> too_long_line_edge_out/input.sol:2:37:
@@ -1,5 +1,5 @@
Warning: Source file does not specify required compiler version!
--> too_long_line_left_short/input.sol
--> too_long_line_left_short/input.sol
Error: Identifier not found or not unique.
--> too_long_line_left_short/input.sol:2:15:
@@ -5,4 +5,4 @@ Error: No visibility specified. Did you intend to add "public"?
| ^ (Relevant source part starts here and spans across multiple lines).
Warning: Source file does not specify required compiler version!
--> too_long_line_multiline/input.sol
--> too_long_line_multiline/input.sol
@@ -1,5 +1,5 @@
Warning: Source file does not specify required compiler version!
--> too_long_line_right_short/input.sol
--> too_long_line_right_short/input.sol
Error: Identifier not found or not unique.
--> too_long_line_right_short/input.sol:2:164:
@@ -0,0 +1 @@
--ir-optimized --optimize --yul-optimizations dhfoDgvulfnTUtnIf
@@ -0,0 +1,6 @@
pragma solidity >=0.0;
contract C
{
constructor() public {}
}
@@ -0,0 +1,34 @@
Optimized IR:
/*******************************************************
* WARNING *
* Solidity to Yul compilation is still EXPERIMENTAL *
* It can result in LOSS OF FUNDS or worse *
* !USE AT YOUR OWN RISK! *
*******************************************************/
object "C_6" {
code {
{
mstore(64, 128)
if callvalue() { revert(0, 0) }
codecopy(0, dataoffset("C_6_deployed"), datasize("C_6_deployed"))
return(0, datasize("C_6_deployed"))
}
}
object "C_6_deployed" {
code {
{
mstore(64, 128)
if iszero(lt(calldatasize(), 4))
{
let selector := shift_right_224_unsigned(calldataload(0))
pop(selector)
}
pop(iszero(calldatasize()))
revert(0, 0)
}
function shift_right_224_unsigned(value) -> newValue
{ newValue := shr(224, value) }
}
}
}
@@ -0,0 +1 @@
--ir-optimized --yul-optimizations dhfoDgvulfnTUtnIf
@@ -0,0 +1 @@
--yul-optimizations is invalid if Yul optimizer is disabled
@@ -0,0 +1 @@
1
@@ -0,0 +1,6 @@
pragma solidity >=0.0;
contract C
{
function f() public pure {}
}
@@ -0,0 +1 @@
--ir-optimized --optimize --yul-optimizations abcdefg{hijklmno}pqr[st]uvwxyz
@@ -0,0 +1 @@
Invalid optimizer step sequence in --yul-optimizations: 'b' is not a valid step abbreviation
@@ -0,0 +1 @@
1
@@ -0,0 +1,6 @@
pragma solidity >=0.0;
contract C
{
function f() public pure {}
}
@@ -0,0 +1 @@
--ir-optimized --optimize --yul-optimizations a[a][aa[aa]]a
@@ -0,0 +1 @@
Invalid optimizer step sequence in --yul-optimizations: Nested brackets are not supported
@@ -0,0 +1 @@
1
@@ -0,0 +1,6 @@
pragma solidity >=0.0;
contract C
{
function f() public pure {}
}
@@ -0,0 +1 @@
--ir-optimized --optimize --yul-optimizations a[a][
@@ -0,0 +1 @@
Invalid optimizer step sequence in --yul-optimizations: Unbalanced brackets
@@ -0,0 +1 @@
1
@@ -0,0 +1,6 @@
pragma solidity >=0.0;
contract C
{
function f() public pure {}
}
@@ -9,14 +9,16 @@
object \"C_10\" {
code {
mstore(64, 128)
if callvalue() { revert(0, 0) }
// Begin state variable initialization for contract \"C\" (0 variables)
// End state variable initialization for contract \"C\".
constructor_C_10()
codecopy(0, dataoffset(\"C_10_deployed\"), datasize(\"C_10_deployed\"))
return(0, datasize(\"C_10_deployed\"))
function constructor_C_10() {
}
}
object \"C_10_deployed\" {
@@ -44,7 +46,6 @@ object \"C_10\" {
if iszero(calldatasize()) { }
revert(0, 0)
function abi_decode_tuple_(headStart, dataEnd) {
if slt(sub(dataEnd, headStart), 0) { revert(0, 0) }
@@ -75,11 +76,8 @@ object \"C_10\" {
function array_length_t_string_memory_ptr(value) -> length {
length := mload(value)
}
function array_storeLengthForEncoding_t_string_memory_ptr_fromStack(pos, length) -> updated_pos {
@@ -133,7 +131,9 @@ object \"C_10\" {
}
}
}
}
"}}},"sources":{"A":{"id":0}}}
@@ -9,14 +9,16 @@
object \"C_10\" {
code {
mstore(64, 128)
if callvalue() { revert(0, 0) }
// Begin state variable initialization for contract \"C\" (0 variables)
// End state variable initialization for contract \"C\".
constructor_C_10()
codecopy(0, dataoffset(\"C_10_deployed\"), datasize(\"C_10_deployed\"))
return(0, datasize(\"C_10_deployed\"))
function constructor_C_10() {
}
}
object \"C_10_deployed\" {
@@ -44,7 +46,6 @@ object \"C_10\" {
if iszero(calldatasize()) { }
revert(0, 0)
function abi_decode_tuple_(headStart, dataEnd) {
if slt(sub(dataEnd, headStart), 0) { revert(0, 0) }
@@ -98,7 +99,9 @@ object \"C_10\" {
}
}
}
}
"}}},"sources":{"A":{"id":0}}}
@@ -9,14 +9,16 @@
object \"C_10\" {
code {
mstore(64, 128)
if callvalue() { revert(0, 0) }
// Begin state variable initialization for contract \"C\" (0 variables)
// End state variable initialization for contract \"C\".
constructor_C_10()
codecopy(0, dataoffset(\"C_10_deployed\"), datasize(\"C_10_deployed\"))
return(0, datasize(\"C_10_deployed\"))
function constructor_C_10() {
}
}
object \"C_10_deployed\" {
@@ -44,7 +46,6 @@ object \"C_10\" {
if iszero(calldatasize()) { }
revert(0, 0)
function abi_decode_tuple_(headStart, dataEnd) {
if slt(sub(dataEnd, headStart), 0) { revert(0, 0) }
@@ -110,7 +111,9 @@ object \"C_10\" {
}
}
}
}
"}}},"sources":{"A":{"id":0}}}
@@ -9,14 +9,16 @@
object \"C_10\" {
code {
mstore(64, 128)
if callvalue() { revert(0, 0) }
// Begin state variable initialization for contract \"C\" (0 variables)
// End state variable initialization for contract \"C\".
constructor_C_10()
codecopy(0, dataoffset(\"C_10_deployed\"), datasize(\"C_10_deployed\"))
return(0, datasize(\"C_10_deployed\"))
function constructor_C_10() {
}
}
object \"C_10_deployed\" {
@@ -44,7 +46,6 @@ object \"C_10\" {
if iszero(calldatasize()) { }
revert(0, 0)
function abi_decode_tuple_(headStart, dataEnd) {
if slt(sub(dataEnd, headStart), 0) { revert(0, 0) }
@@ -75,11 +76,8 @@ object \"C_10\" {
function array_length_t_string_memory_ptr(value) -> length {
length := mload(value)
}
function array_storeLengthForEncoding_t_string_memory_ptr_fromStack(pos, length) -> updated_pos {
@@ -137,7 +135,9 @@ object \"C_10\" {
}
}
}
}
"}}},"sources":{"A":{"id":0}}}
@@ -9,14 +9,16 @@
object \"C_10\" {
code {
mstore(64, 128)
if callvalue() { revert(0, 0) }
// Begin state variable initialization for contract \"C\" (0 variables)
// End state variable initialization for contract \"C\".
constructor_C_10()
codecopy(0, dataoffset(\"C_10_deployed\"), datasize(\"C_10_deployed\"))
return(0, datasize(\"C_10_deployed\"))
function constructor_C_10() {
}
}
object \"C_10_deployed\" {
@@ -44,7 +46,6 @@ object \"C_10\" {
if iszero(calldatasize()) { }
revert(0, 0)
function abi_decode_tuple_(headStart, dataEnd) {
if slt(sub(dataEnd, headStart), 0) { revert(0, 0) }
@@ -110,7 +111,9 @@ object \"C_10\" {
}
}
}
}
"}}},"sources":{"A":{"id":0}}}
-15
View File
@@ -26,8 +26,6 @@
#include <libsolutil/JSON.h>
#include <libsolutil/AnsiColorized.h>
#include <boost/algorithm/string.hpp>
#include <fstream>
using namespace std;
@@ -85,16 +83,3 @@ void ABIJsonTest::printUpdatedExpectations(ostream& _stream, string const& _line
{
printIndented(_stream, m_obtainedResult, _linePrefix);
}
void ABIJsonTest::printIndented(ostream& _stream, string const& _output, string const& _linePrefix) const
{
stringstream output(_output);
string line;
while (getline(output, line))
if (line.empty())
// Avoid trailing spaces.
_stream << boost::trim_right_copy(_linePrefix) << endl;
else
_stream << _linePrefix << line << endl;
}
-2
View File
@@ -41,8 +41,6 @@ public:
void printUpdatedExpectations(std::ostream& _stream, std::string const& _linePrefix) const override;
private:
void printIndented(std::ostream& _stream, std::string const& _output, std::string const& _linePrefix = "") const;
std::string m_source;
std::string m_expectation;
std::string m_obtainedResult;
+87 -69
View File
@@ -1126,12 +1126,14 @@ BOOST_AUTO_TEST_CASE(log0)
}
}
)";
compileAndRun(sourceCode);
callContractFunction("a()");
BOOST_REQUIRE_EQUAL(numLogs(), 1);
BOOST_CHECK_EQUAL(logAddress(0), m_contractAddress);
BOOST_CHECK_EQUAL(h256(logData(0)), h256(u256(1)));
BOOST_CHECK_EQUAL(numLogTopics(0), 0);
ALSO_VIA_YUL(
compileAndRun(sourceCode);
callContractFunction("a()");
BOOST_REQUIRE_EQUAL(numLogs(), 1);
BOOST_CHECK_EQUAL(logAddress(0), m_contractAddress);
BOOST_CHECK_EQUAL(h256(logData(0)), h256(u256(1)));
BOOST_CHECK_EQUAL(numLogTopics(0), 0);
)
}
BOOST_AUTO_TEST_CASE(log1)
@@ -1143,13 +1145,15 @@ BOOST_AUTO_TEST_CASE(log1)
}
}
)";
compileAndRun(sourceCode);
callContractFunction("a()");
BOOST_REQUIRE_EQUAL(numLogs(), 1);
BOOST_CHECK_EQUAL(logAddress(0), m_contractAddress);
BOOST_CHECK_EQUAL(h256(logData(0)), h256(u256(1)));
BOOST_REQUIRE_EQUAL(numLogTopics(0), 1);
BOOST_CHECK_EQUAL(logTopic(0, 0), h256(u256(2)));
ALSO_VIA_YUL(
compileAndRun(sourceCode);
callContractFunction("a()");
BOOST_REQUIRE_EQUAL(numLogs(), 1);
BOOST_CHECK_EQUAL(logAddress(0), m_contractAddress);
BOOST_CHECK_EQUAL(h256(logData(0)), h256(u256(1)));
BOOST_REQUIRE_EQUAL(numLogTopics(0), 1);
BOOST_CHECK_EQUAL(logTopic(0, 0), h256(u256(2)));
)
}
BOOST_AUTO_TEST_CASE(log2)
@@ -1161,14 +1165,16 @@ BOOST_AUTO_TEST_CASE(log2)
}
}
)";
compileAndRun(sourceCode);
callContractFunction("a()");
BOOST_REQUIRE_EQUAL(numLogs(), 1);
BOOST_CHECK_EQUAL(logAddress(0), m_contractAddress);
BOOST_CHECK_EQUAL(h256(logData(0)), h256(u256(1)));
BOOST_REQUIRE_EQUAL(numLogTopics(0), 2);
for (unsigned i = 0; i < 2; ++i)
BOOST_CHECK_EQUAL(logTopic(0, i), h256(u256(i + 2)));
ALSO_VIA_YUL(
compileAndRun(sourceCode);
callContractFunction("a()");
BOOST_REQUIRE_EQUAL(numLogs(), 1);
BOOST_CHECK_EQUAL(logAddress(0), m_contractAddress);
BOOST_CHECK_EQUAL(h256(logData(0)), h256(u256(1)));
BOOST_REQUIRE_EQUAL(numLogTopics(0), 2);
for (unsigned i = 0; i < 2; ++i)
BOOST_CHECK_EQUAL(logTopic(0, i), h256(u256(i + 2)));
)
}
BOOST_AUTO_TEST_CASE(log3)
@@ -1180,14 +1186,16 @@ BOOST_AUTO_TEST_CASE(log3)
}
}
)";
compileAndRun(sourceCode);
callContractFunction("a()");
BOOST_REQUIRE_EQUAL(numLogs(), 1);
BOOST_CHECK_EQUAL(logAddress(0), m_contractAddress);
BOOST_CHECK_EQUAL(h256(logData(0)), h256(u256(1)));
BOOST_REQUIRE_EQUAL(numLogTopics(0), 3);
for (unsigned i = 0; i < 3; ++i)
BOOST_CHECK_EQUAL(logTopic(0, i), h256(u256(i + 2)));
ALSO_VIA_YUL(
compileAndRun(sourceCode);
callContractFunction("a()");
BOOST_REQUIRE_EQUAL(numLogs(), 1);
BOOST_CHECK_EQUAL(logAddress(0), m_contractAddress);
BOOST_CHECK_EQUAL(h256(logData(0)), h256(u256(1)));
BOOST_REQUIRE_EQUAL(numLogTopics(0), 3);
for (unsigned i = 0; i < 3; ++i)
BOOST_CHECK_EQUAL(logTopic(0, i), h256(u256(i + 2)));
)
}
BOOST_AUTO_TEST_CASE(log4)
@@ -1199,14 +1207,16 @@ BOOST_AUTO_TEST_CASE(log4)
}
}
)";
compileAndRun(sourceCode);
callContractFunction("a()");
BOOST_REQUIRE_EQUAL(numLogs(), 1);
BOOST_CHECK_EQUAL(logAddress(0), m_contractAddress);
BOOST_CHECK_EQUAL(h256(logData(0)), h256(u256(1)));
BOOST_REQUIRE_EQUAL(numLogTopics(0), 4);
for (unsigned i = 0; i < 4; ++i)
BOOST_CHECK_EQUAL(logTopic(0, i), h256(u256(i + 2)));
ALSO_VIA_YUL(
compileAndRun(sourceCode);
callContractFunction("a()");
BOOST_REQUIRE_EQUAL(numLogs(), 1);
BOOST_CHECK_EQUAL(logAddress(0), m_contractAddress);
BOOST_CHECK_EQUAL(h256(logData(0)), h256(u256(1)));
BOOST_REQUIRE_EQUAL(numLogTopics(0), 4);
for (unsigned i = 0; i < 4; ++i)
BOOST_CHECK_EQUAL(logTopic(0, i), h256(u256(i + 2)));
)
}
BOOST_AUTO_TEST_CASE(log_in_constructor)
@@ -1218,12 +1228,14 @@ BOOST_AUTO_TEST_CASE(log_in_constructor)
}
}
)";
compileAndRun(sourceCode);
BOOST_REQUIRE_EQUAL(numLogs(), 1);
BOOST_CHECK_EQUAL(logAddress(0), m_contractAddress);
BOOST_CHECK_EQUAL(h256(logData(0)), h256(u256(1)));
BOOST_REQUIRE_EQUAL(numLogTopics(0), 1);
BOOST_CHECK_EQUAL(logTopic(0, 0), h256(u256(2)));
ALSO_VIA_YUL(
compileAndRun(sourceCode);
BOOST_REQUIRE_EQUAL(numLogs(), 1);
BOOST_CHECK_EQUAL(logAddress(0), m_contractAddress);
BOOST_CHECK_EQUAL(h256(logData(0)), h256(u256(1)));
BOOST_REQUIRE_EQUAL(numLogTopics(0), 1);
BOOST_CHECK_EQUAL(logTopic(0, 0), h256(u256(2)));
)
}
BOOST_AUTO_TEST_CASE(selfdestruct)
@@ -1238,11 +1250,13 @@ BOOST_AUTO_TEST_CASE(selfdestruct)
}
)";
u256 amount(130);
compileAndRun(sourceCode, amount);
u160 address(23);
ABI_CHECK(callContractFunction("a(address)", address), bytes());
BOOST_CHECK(!addressHasCode(m_contractAddress));
BOOST_CHECK_EQUAL(balanceAt(address), amount);
ALSO_VIA_YUL(
compileAndRun(sourceCode, amount);
ABI_CHECK(callContractFunction("a(address)", address), bytes());
BOOST_CHECK(!addressHasCode(m_contractAddress));
BOOST_CHECK_EQUAL(balanceAt(address), amount);
)
}
BOOST_AUTO_TEST_CASE(keccak256)
@@ -1774,20 +1788,22 @@ BOOST_AUTO_TEST_CASE(event)
}
}
)";
compileAndRun(sourceCode);
u256 value(18);
u256 id(0x1234);
for (bool manually: {true, false})
{
callContractFunctionWithValue("deposit(bytes32,bool)", value, id, manually);
BOOST_REQUIRE_EQUAL(numLogs(), 1);
BOOST_CHECK_EQUAL(logAddress(0), m_contractAddress);
BOOST_CHECK_EQUAL(h256(logData(0)), h256(u256(value)));
BOOST_REQUIRE_EQUAL(numLogTopics(0), 3);
BOOST_CHECK_EQUAL(logTopic(0, 0), util::keccak256(string("Deposit(address,bytes32,uint256)")));
BOOST_CHECK_EQUAL(logTopic(0, 1), h256(m_sender, h256::AlignRight));
BOOST_CHECK_EQUAL(logTopic(0, 2), h256(id));
}
ALSO_VIA_YUL(
compileAndRun(sourceCode);
u256 value(18);
u256 id(0x1234);
for (bool manually: {true, false})
{
callContractFunctionWithValue("deposit(bytes32,bool)", value, id, manually);
BOOST_REQUIRE_EQUAL(numLogs(), 1);
BOOST_CHECK_EQUAL(logAddress(0), m_contractAddress);
BOOST_CHECK_EQUAL(h256(logData(0)), h256(u256(value)));
BOOST_REQUIRE_EQUAL(numLogTopics(0), 3);
BOOST_CHECK_EQUAL(logTopic(0, 0), util::keccak256(string("Deposit(address,bytes32,uint256)")));
BOOST_CHECK_EQUAL(logTopic(0, 1), h256(m_sender, h256::AlignRight));
BOOST_CHECK_EQUAL(logTopic(0, 2), h256(id));
}
)
}
BOOST_AUTO_TEST_CASE(event_emit)
@@ -1801,7 +1817,7 @@ BOOST_AUTO_TEST_CASE(event_emit)
}
)";
ALSO_VIA_YUL(
compileAndRun(sourceCode);
compileAndRun(sourceCode);
u256 value(18);
u256 id(0x1234);
callContractFunctionWithValue("deposit(bytes32)", value, id);
@@ -1850,13 +1866,15 @@ BOOST_AUTO_TEST_CASE(event_access_through_base_name_emit)
}
}
)";
compileAndRun(sourceCode);
callContractFunction("f()");
BOOST_REQUIRE_EQUAL(numLogs(), 1);
BOOST_CHECK_EQUAL(logAddress(0), m_contractAddress);
BOOST_CHECK(logData(0).empty());
BOOST_REQUIRE_EQUAL(numLogTopics(0), 1);
BOOST_CHECK_EQUAL(logTopic(0, 0), util::keccak256(string("x()")));
ALSO_VIA_YUL(
compileAndRun(sourceCode);
callContractFunction("f()");
BOOST_REQUIRE_EQUAL(numLogs(), 1);
BOOST_CHECK_EQUAL(logAddress(0), m_contractAddress);
BOOST_CHECK(logData(0).empty());
BOOST_REQUIRE_EQUAL(numLogTopics(0), 1);
BOOST_CHECK_EQUAL(logTopic(0, 0), util::keccak256(string("x()")));
);
}
BOOST_AUTO_TEST_CASE(events_with_same_name)
@@ -52,7 +52,7 @@ BOOST_AUTO_TEST_CASE(function_no_implementation)
std::vector<ASTPointer<ASTNode>> nodes = sourceUnit->nodes();
ContractDefinition* contract = dynamic_cast<ContractDefinition*>(nodes[1].get());
BOOST_REQUIRE(contract);
BOOST_CHECK(!contract->annotation().unimplementedFunctions.empty());
BOOST_CHECK(!contract->annotation().unimplementedDeclarations.empty());
BOOST_CHECK(!contract->definedFunctions()[0]->isImplemented());
}
@@ -68,10 +68,10 @@ BOOST_AUTO_TEST_CASE(abstract_contract)
ContractDefinition* base = dynamic_cast<ContractDefinition*>(nodes[1].get());
ContractDefinition* derived = dynamic_cast<ContractDefinition*>(nodes[2].get());
BOOST_REQUIRE(base);
BOOST_CHECK(!base->annotation().unimplementedFunctions.empty());
BOOST_CHECK(!base->annotation().unimplementedDeclarations.empty());
BOOST_CHECK(!base->definedFunctions()[0]->isImplemented());
BOOST_REQUIRE(derived);
BOOST_CHECK(derived->annotation().unimplementedFunctions.empty());
BOOST_CHECK(derived->annotation().unimplementedDeclarations.empty());
BOOST_CHECK(derived->definedFunctions()[0]->isImplemented());
}
@@ -87,9 +87,9 @@ BOOST_AUTO_TEST_CASE(abstract_contract_with_overload)
ContractDefinition* base = dynamic_cast<ContractDefinition*>(nodes[1].get());
ContractDefinition* derived = dynamic_cast<ContractDefinition*>(nodes[2].get());
BOOST_REQUIRE(base);
BOOST_CHECK(!base->annotation().unimplementedFunctions.empty());
BOOST_CHECK(!base->annotation().unimplementedDeclarations.empty());
BOOST_REQUIRE(derived);
BOOST_CHECK(!derived->annotation().unimplementedFunctions.empty());
BOOST_CHECK(!derived->annotation().unimplementedDeclarations.empty());
}
BOOST_AUTO_TEST_CASE(implement_abstract_via_constructor)
@@ -104,7 +104,7 @@ BOOST_AUTO_TEST_CASE(implement_abstract_via_constructor)
BOOST_CHECK_EQUAL(nodes.size(), 3);
ContractDefinition* derived = dynamic_cast<ContractDefinition*>(nodes[2].get());
BOOST_REQUIRE(derived);
BOOST_CHECK(!derived->annotation().unimplementedFunctions.empty());
BOOST_CHECK(!derived->annotation().unimplementedDeclarations.empty());
}
BOOST_AUTO_TEST_CASE(function_canonical_signature)
+9 -1
View File
@@ -21,11 +21,15 @@
#include <string>
#include <boost/test/unit_test.hpp>
#include <libsolidity/interface/OptimiserSettings.h>
#include <libsolidity/interface/StandardCompiler.h>
#include <libsolidity/interface/Version.h>
#include <libsolutil/JSON.h>
#include <libsolutil/CommonData.h>
#include <test/Metadata.h>
#include <set>
using namespace std;
using namespace solidity::evmasm;
@@ -1058,8 +1062,12 @@ BOOST_AUTO_TEST_CASE(optimizer_settings_details_different)
BOOST_CHECK(optimizer["details"]["peephole"].asBool() == true);
BOOST_CHECK(optimizer["details"]["yul"].asBool() == true);
BOOST_CHECK(optimizer["details"]["yulDetails"].isObject());
BOOST_CHECK(optimizer["details"]["yulDetails"].getMemberNames() == vector<string>{"stackAllocation"});
BOOST_CHECK(
util::convertContainer<set<string>>(optimizer["details"]["yulDetails"].getMemberNames()) ==
(set<string>{"stackAllocation", "optimizerSteps"})
);
BOOST_CHECK(optimizer["details"]["yulDetails"]["stackAllocation"].asBool() == true);
BOOST_CHECK(optimizer["details"]["yulDetails"]["optimizerSteps"].asString() == OptimiserSettings::DefaultYulOptimiserSteps);
BOOST_CHECK_EQUAL(optimizer["details"].getMemberNames().size(), 8);
BOOST_CHECK(optimizer["runs"].asUInt() == 600);
}
@@ -17,5 +17,7 @@ contract B {
}
}
// ====
// compileViaYul: also
// ----
// f() -> 2, 3, 4, 5, 6, 1000, 1001, 1002, 1003, 1004
@@ -41,5 +41,7 @@ contract C {
}
}
// ====
// compileViaYul: also
// ----
// test() -> 5, 6, 7
@@ -3,6 +3,7 @@ contract C {
return sha256("");
}
}
// ====
// compileViaYul: also
// ----
// f() -> 0xe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
@@ -0,0 +1,14 @@
contract A {
uint x = 42;
function f() public returns(uint256) {
return x;
}
}
contract B is A {
uint public y = f();
}
// ====
// compileViaYul: true
// ----
// constructor() ->
// y() -> 42
@@ -0,0 +1,17 @@
contract A {
uint x;
constructor() public {
x = 42;
}
function f() public returns(uint256) {
return x;
}
}
contract B is A {
uint public y = f();
}
// ====
// compileViaYul: true
// ----
// constructor() ->
// y() -> 42
@@ -0,0 +1,28 @@
contract A {
uint public i;
uint public k;
constructor(uint newI, uint newK) public {
i = newI;
k = newK;
}
}
abstract contract B is A {
uint public j;
constructor(uint newJ) public {
j = newJ;
}
}
contract C is A {
constructor(uint newI, uint newK) A(newI, newK) public {}
}
contract D is B, C {
constructor(uint newI, uint newK) B(newI) C(newI, newK + 1) public {}
}
// ====
// compileViaYul: also
// ----
// constructor(): 2, 0 ->
// i() -> 2
// j() -> 2
// k() -> 1
@@ -0,0 +1,18 @@
contract C {
uint public i;
uint public k;
constructor(uint newI, uint newK) public {
i = newI;
k = newK;
}
}
contract D is C {
constructor(uint newI, uint newK) C(newI, newK + 1) public {}
}
// ====
// compileViaYul: also
// ----
// constructor(): 2, 0 ->
// i() -> 2
// k() -> 1
@@ -0,0 +1,15 @@
contract C {
uint public i;
uint public k;
constructor(uint newI, uint newK) public {
i = newI;
k = newK;
}
}
contract D is C(2, 1) {}
// ====
// compileViaYul: also
// ----
// i() -> 2
// k() -> 1
@@ -34,6 +34,8 @@ contract Child is Base {
BaseBase.init(c, d);
}
}
// ====
// compileViaYul: also
// ----
// x() -> 0
// y() -> 0
@@ -18,6 +18,8 @@ contract Child is Base {
Base.init(c, d);
}
}
// ====
// compileViaYul: also
// ----
// x() -> 0
// y() -> 0
@@ -0,0 +1,19 @@
contract test {
bool public flag = false;
function f0() public {
flag = true;
}
function f() public returns (bool) {
function() internal x = f0;
x();
return flag;
}
}
// ====
// compileViaYul: also
// ----
// f() -> true
// flag() -> true
@@ -0,0 +1,15 @@
contract C {
uint public i;
constructor() public {
i = 2;
}
}
contract D {
function f() public returns (uint r) {
return new C().i();
}
}
// ====
// compileViaYul: also
// ----
// f() -> 2
@@ -0,0 +1,20 @@
contract C {
uint public i;
constructor(uint newI) public {
i = newI;
}
}
contract D {
C c;
constructor(uint v) public {
c = new C(v);
}
function f() public returns (uint r) {
return c.i();
}
}
// ====
// compileViaYul: also
// ----
// constructor(): 2 ->
// f() -> 2
@@ -0,0 +1,21 @@
contract C {
uint public i;
constructor(uint newI) public {
i = newI;
}
}
contract D {
C c;
constructor(uint v) public {
c = new C{salt: "abc"}(v);
}
function f() public returns (uint r) {
return c.i();
}
}
// ====
// EVMVersion: >=constantinople
// compileViaYul: also
// ----
// constructor(): 2 ->
// f() -> 2
@@ -36,8 +36,10 @@ contract test {
}
}
// ====
// compileViaYul: also
// ----
// constructor(), 20 wei ->
// sendAmount(uint256): 5 -> 5
// outOfGas() -> FAILURE # call to helper should not succeed but amount should be transferred anyway #
// checkState() -> false, 15
// checkState() -> false, 15
@@ -0,0 +1,36 @@
interface ERC165 {
/// @notice Query if a contract implements an interface
/// @param interfaceID The interface identifier, as specified in ERC-165
/// @dev Interface identification is specified in ERC-165. This function
/// uses less than 30,000 gas.
/// @return `true` if the contract implements `interfaceID` and
/// `interfaceID` is not 0xffffffff, `false` otherwise
function supportsInterface(bytes4 interfaceID) external view returns (bool);
}
interface Simpson {
function is2D() external returns (bool);
function skinColor() external returns (string memory);
}
contract Homer is ERC165, Simpson {
function supportsInterface(bytes4 interfaceID) external view override returns (bool) {
return
interfaceID == this.supportsInterface.selector || // ERC165
interfaceID == this.is2D.selector ^ this.skinColor.selector; // Simpson
}
function is2D() external override returns (bool) {
return true;
}
function skinColor() external override returns (string memory) {
return "yellow";
}
}
// ----
// supportsInterface(bytes4): left(0x01ffc9a0) -> false
// supportsInterface(bytes4): left(0x01ffc9a7) -> true
// supportsInterface(bytes4): left(0x73b6b492) -> true
// supportsInterface(bytes4): left(0x70b6b492) -> false
@@ -0,0 +1,36 @@
interface ERC165 {
/// @notice Query if a contract implements an interface
/// @param interfaceID The interface identifier, as specified in ERC-165
/// @dev Interface identification is specified in ERC-165. This function
/// uses less than 30,000 gas.
/// @return `true` if the contract implements `interfaceID` and
/// `interfaceID` is not 0xffffffff, `false` otherwise
function supportsInterface(bytes4 interfaceID) external view returns (bool);
}
interface Simpson {
function is2D() external returns (bool);
function skinColor() external returns (string memory);
}
contract Homer is ERC165, Simpson {
function supportsInterface(bytes4 interfaceID) external view override returns (bool) {
return
interfaceID == type(ERC165).interfaceId ||
interfaceID == type(Simpson).interfaceId;
}
function is2D() external override returns (bool) {
return true;
}
function skinColor() external override returns (string memory) {
return "yellow";
}
}
// ----
// supportsInterface(bytes4): left(0x01ffc9a0) -> false
// supportsInterface(bytes4): left(0x01ffc9a7) -> true
// supportsInterface(bytes4): left(0x73b6b492) -> true
// supportsInterface(bytes4): left(0x70b6b492) -> false
@@ -0,0 +1,21 @@
interface HelloWorld {
function hello() external pure;
function world(int) external pure;
}
interface HelloWorldWithEvent {
event Event();
function hello() external pure;
function world(int) external pure;
}
contract Test {
bytes4 public hello_world = type(HelloWorld).interfaceId;
bytes4 public hello_world_with_event = type(HelloWorldWithEvent).interfaceId;
}
// ====
// compileViaYul: also
// ----
// hello_world() -> left(0xc6be8b58)
// hello_world_with_event() -> left(0xc6be8b58)
@@ -0,0 +1,67 @@
interface HelloWorld {
function hello() external pure;
function world(int) external pure;
}
interface HelloWorldDerived is HelloWorld {
function other() external pure;
}
interface ERC165 {
/// @notice Query if a contract implements an interface
/// @param interfaceID The interface identifier, as specified in ERC-165
/// @dev Interface identification is specified in ERC-165. This function
/// uses less than 30,000 gas.
/// @return `true` if the contract implements `interfaceID` and
/// `interfaceID` is not 0xffffffff, `false` otherwise
function supportsInterface(bytes4 interfaceID) external view returns (bool);
}
contract Test {
bytes4 public ghello_world_interfaceId = type(HelloWorld).interfaceId;
bytes4 public ERC165_interfaceId = type(ERC165).interfaceId;
function hello() public pure returns (bytes4 data){
HelloWorld i;
return i.hello.selector;
}
function world() public pure returns (bytes4 data){
HelloWorld i;
return i.world.selector;
}
function hello_world() public pure returns (bytes4 data){
// HelloWorld i;
// return i.hello.selector ^ i.world.selector; // = 0xc6be8b58
return 0xc6be8b58;
}
function hello_world_interfaceId() public pure returns (bytes4 data){
return type(HelloWorld).interfaceId;
}
function other() public pure returns (bytes4 data){
HelloWorldDerived i;
return i.other.selector;
}
function hello_world_derived_interfaceId() public pure returns (bytes4 data){
return type(HelloWorldDerived).interfaceId;
}
}
// ====
// compileViaYul: also
// ----
// hello() -> left(0x19ff1d21)
// world() -> left(0xdf419679)
//
// ERC165_interfaceId() -> left(0x01ffc9a7)
//
// hello_world() -> left(0xc6be8b58)
// hello_world_interfaceId() -> left(0xc6be8b58)
// ghello_world_interfaceId() -> left(0xc6be8b58)
//
// other() -> left(0x85295877)
// hello_world_derived_interfaceId() -> left(0x85295877)
@@ -0,0 +1,47 @@
interface ERC165 {
/// @notice Query if a contract implements an interface
/// @param interfaceID The interface identifier, as specified in ERC-165
/// @dev Interface identification is specified in ERC-165. This function
/// uses less than 30,000 gas.
/// @return `true` if the contract implements `interfaceID` and
/// `interfaceID` is not 0xffffffff, `false` otherwise
function supportsInterface(bytes4 interfaceID) external view returns (bool);
}
contract ERC165MappingImplementation is ERC165 {
/// @dev You must not set element 0xffffffff to true
mapping(bytes4 => bool) internal supportedInterfaces;
constructor() internal {
supportedInterfaces[this.supportsInterface.selector] = true;
}
function supportsInterface(bytes4 interfaceID) external view override returns (bool) {
return supportedInterfaces[interfaceID];
}
}
interface Simpson {
function is2D() external returns (bool);
function skinColor() external returns (string memory);
}
contract Lisa is ERC165MappingImplementation, Simpson {
constructor() public {
supportedInterfaces[this.is2D.selector ^ this.skinColor.selector] = true;
}
function is2D() external override returns (bool) {
return true;
}
function skinColor() external override returns (string memory) {
return "yellow";
}
}
// ----
// supportsInterface(bytes4): left(0x01ffc9a0) -> false
// supportsInterface(bytes4): left(0x01ffc9a7) -> true
// supportsInterface(bytes4): left(0x73b6b492) -> true
// supportsInterface(bytes4): left(0x70b6b492) -> false
@@ -0,0 +1,47 @@
interface ERC165 {
/// @notice Query if a contract implements an interface
/// @param interfaceID The interface identifier, as specified in ERC-165
/// @dev Interface identification is specified in ERC-165. This function
/// uses less than 30,000 gas.
/// @return `true` if the contract implements `interfaceID` and
/// `interfaceID` is not 0xffffffff, `false` otherwise
function supportsInterface(bytes4 interfaceID) external view returns (bool);
}
contract ERC165MappingImplementation is ERC165 {
/// @dev You must not set element 0xffffffff to true
mapping(bytes4 => bool) internal supportedInterfaces;
constructor() internal {
supportedInterfaces[this.supportsInterface.selector] = true;
}
function supportsInterface(bytes4 interfaceID) external view override returns (bool) {
return supportedInterfaces[interfaceID];
}
}
interface Simpson {
function is2D() external returns (bool);
function skinColor() external returns (string memory);
}
contract Lisa is ERC165MappingImplementation, Simpson {
constructor() public {
supportedInterfaces[type(Simpson).interfaceId] = true;
}
function is2D() external override returns (bool) {
return true;
}
function skinColor() external override returns (string memory) {
return "yellow";
}
}
// ----
// supportsInterface(bytes4): left(0x01ffc9a0) -> false
// supportsInterface(bytes4): left(0x01ffc9a7) -> true
// supportsInterface(bytes4): left(0x73b6b492) -> true
// supportsInterface(bytes4): left(0x70b6b492) -> false
@@ -33,6 +33,8 @@ contract C {
}
}
// ====
// compileViaYul: also
// ----
// convertParent() -> 1
// convertSubA() -> 1, 2
@@ -19,6 +19,8 @@ contract D {
}
}
// ====
// compileViaYul: also
// ----
// f() -> 1
// g() -> 5
@@ -21,5 +21,7 @@ contract B {
}
}
// ====
// compileViaYul: also
// ----
// g() -> 42
@@ -21,5 +21,7 @@ contract B {
}
}
// ====
// compileViaYul: also
// ----
// g() -> 42
@@ -15,5 +15,7 @@ contract B {
}
}
// ====
// compileViaYul: also
// ----
// g() -> 1
@@ -17,5 +17,7 @@ contract C {
}
}
// ====
// compileViaYul: also
// ----
// f() -> 2
@@ -22,5 +22,7 @@ contract C {
}
}
// ====
// compileViaYul: also
// ----
// f() -> 2
@@ -6,6 +6,8 @@ contract C {
return L.f(v);
}
}
// ====
// compileViaYul: also
// ----
// g(uint256): 1 -> 1
// g(uint256): 2 -> 4
@@ -0,0 +1,17 @@
abstract contract A {
function f() public mod returns (bool r) {
return true;
}
modifier mod virtual;
}
contract C is A {
modifier mod override {
if (false) _;
}
}
// ----
// f() -> false
@@ -0,0 +1,14 @@
contract A {
uint public x = 0;
uint y = f();
function f() public returns (uint256) {
++x;
return 42;
}
}
contract B is A {
}
// ====
// compileViaYul: also
// ----
// x() -> 1
@@ -0,0 +1,18 @@
contract A {
uint public x = 0;
uint y = f();
function f() public returns (uint256) {
++x;
return 42;
}
}
contract B is A {
uint public z;
constructor() public {
z = x;
}
}
// ====
// compileViaYul: also
// ----
// z() -> 1
@@ -0,0 +1,29 @@
contract A {
uint public a = 42;
uint public b;
uint public c;
constructor(uint x) public {
b = a;
a = x;
}
function f(uint x) public returns (uint256) { c = x * 3; return 23; }
}
contract B is A {
uint public d = f(a);
uint public e = b;
uint public b_a;
uint public b_b;
uint public b_c;
constructor() public A(17) { b_a = a; b_b = b; b_c = c; }
}
// ====
// compileViaYul: true
// ----
// a() -> 17
// b() -> 42
// c() -> 51
// b_a() -> 17
// b_b() -> 42
// b_c() -> 51
// d() -> 23
// e() -> 42
@@ -16,5 +16,7 @@ contract C {
}
}
// ====
// compileViaYul: also
// ----
// constructor() ->
@@ -23,6 +23,8 @@ contract C {
}
}
// ====
// compileViaYul: also
// ----
// test() -> 9, 7
// t2() -> 9
@@ -15,6 +15,8 @@ contract C {
}
}
// ====
// compileViaYul: also
// ----
// f() -> true
// g() -> true
@@ -15,6 +15,8 @@ contract D {
}
}
// ====
// compileViaYul: also
// ----
// constructor(), 27 wei ->
// f() -> 27
@@ -32,6 +32,7 @@ contract D {
}
}
// ====
// compileViaYul: also
// EVMVersion: >=byzantium
// ----
// f() -> 0x1 # This should work, next should throw #
@@ -34,6 +34,8 @@ contract D {
}
}
// ====
// compileViaYul: also
// ----
// f() -> 3
// g() -> 8

Some files were not shown because too many files have changed in this diff Show More