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

This commit is contained in:
chriseth
2020-04-07 11:14:28 +02:00
288 changed files with 6927 additions and 2129 deletions
+2 -2
View File
@@ -34,14 +34,14 @@ namespace solidity::frontend::test
class SMTCheckerFramework: public AnalysisFramework
{
protected:
virtual std::pair<SourceUnit const*, ErrorList>
std::pair<SourceUnit const*, ErrorList>
parseAnalyseAndReturnError(
std::string const& _source,
bool _reportWarnings = false,
bool _insertVersionPragma = true,
bool _allowMultipleErrors = false,
bool _allowRecoveryErrors = false
)
) override
{
return AnalysisFramework::parseAnalyseAndReturnError(
"pragma experimental SMTChecker;\n" + _source,
File diff suppressed because it is too large Load Diff
@@ -46,7 +46,7 @@ public:
ExecutionFramework(_evmVersion), m_showMetadata(solidity::test::CommonOptions::get().showMetadata)
{}
virtual bytes const& compileAndRunWithoutCheck(
bytes const& compileAndRunWithoutCheck(
std::string const& _sourceCode,
u256 const& _value = 0,
std::string const& _contractName = "",
+10 -14
View File
@@ -52,15 +52,15 @@ public:
FirstExpressionExtractor(ASTNode& _node): m_expression(nullptr) { _node.accept(*this); }
Expression* expression() const { return m_expression; }
private:
virtual bool visit(Assignment& _expression) override { return checkExpression(_expression); }
virtual bool visit(UnaryOperation& _expression) override { return checkExpression(_expression); }
virtual bool visit(BinaryOperation& _expression) override { return checkExpression(_expression); }
virtual bool visit(FunctionCall& _expression) override { return checkExpression(_expression); }
virtual bool visit(MemberAccess& _expression) override { return checkExpression(_expression); }
virtual bool visit(IndexAccess& _expression) override { return checkExpression(_expression); }
virtual bool visit(Identifier& _expression) override { return checkExpression(_expression); }
virtual bool visit(ElementaryTypeNameExpression& _expression) override { return checkExpression(_expression); }
virtual bool visit(Literal& _expression) override { return checkExpression(_expression); }
bool visit(Assignment& _expression) override { return checkExpression(_expression); }
bool visit(UnaryOperation& _expression) override { return checkExpression(_expression); }
bool visit(BinaryOperation& _expression) override { return checkExpression(_expression); }
bool visit(FunctionCall& _expression) override { return checkExpression(_expression); }
bool visit(MemberAccess& _expression) override { return checkExpression(_expression); }
bool visit(IndexAccess& _expression) override { return checkExpression(_expression); }
bool visit(Identifier& _expression) override { return checkExpression(_expression); }
bool visit(ElementaryTypeNameExpression& _expression) override { return checkExpression(_expression); }
bool visit(Literal& _expression) override { return checkExpression(_expression); }
bool checkExpression(Expression& _expression)
{
if (m_expression == nullptr)
@@ -119,13 +119,9 @@ bytes compileFirstExpression(
NameAndTypeResolver resolver(globalContext, solidity::test::CommonOptions::get().evmVersion(), scopes, errorReporter);
resolver.registerDeclarations(*sourceUnit);
vector<ContractDefinition const*> inheritanceHierarchy;
for (ASTPointer<ASTNode> const& node: sourceUnit->nodes())
if (ContractDefinition* contract = dynamic_cast<ContractDefinition*>(node.get()))
{
BOOST_REQUIRE_MESSAGE(resolver.resolveNamesAndTypes(*contract), "Resolving names failed");
inheritanceHierarchy = vector<ContractDefinition const*>(1, contract);
}
for (ASTPointer<ASTNode> const& node: sourceUnit->nodes())
if (ContractDefinition* contract = dynamic_cast<ContractDefinition*>(node.get()))
{
@@ -144,7 +140,7 @@ bytes compileFirstExpression(
RevertStrings::Default
);
context.resetVisitedNodes(contract);
context.setInheritanceHierarchy(inheritanceHierarchy);
context.setMostDerivedContract(*contract);
unsigned parametersSize = _localVariables.size(); // assume they are all one slot on the stack
context.adjustStackOffset(parametersSize);
for (vector<string> const& variable: _localVariables)
+1 -1
View File
@@ -672,7 +672,7 @@ BOOST_AUTO_TEST_CASE(inline_asm_end_location)
{
public:
bool visited = false;
virtual bool visit(InlineAssembly const& _inlineAsm)
bool visit(InlineAssembly const& _inlineAsm) override
{
auto loc = _inlineAsm.location();
auto asmStr = loc.source->source().substr(loc.start, loc.end - loc.start);
@@ -0,0 +1,11 @@
contract C {
function f(bytes calldata data)
external
pure
returns (uint256, bytes memory r)
{
return abi.decode(data, (uint256, bytes));
}
}
// ----
// f(bytes): 0x20, 0x80, 0x21, 0x40, 0x7, "abcdefg" -> 0x21, 0x40, 0x7, "abcdefg"
@@ -0,0 +1,7 @@
contract C {
function f(bytes memory data) public pure returns (uint256, bytes memory) {
return abi.decode(data, (uint256, bytes));
}
}
// ----
// f(bytes): 0x20, 0x80, 0x21, 0x40, 0x7, "abcdefg" -> 0x21, 0x40, 0x7, "abcdefg"
@@ -0,0 +1,10 @@
contract C {
bytes data;
function f(bytes memory _data) public returns (uint256, bytes memory) {
data = _data;
return abi.decode(data, (uint256, bytes));
}
}
// ----
// f(bytes): 0x20, 0x80, 0x21, 0x40, 0x7, "abcdefg" -> 0x21, 0x40, 0x7, "abcdefg"
@@ -0,0 +1,11 @@
// Tests that this will not end up using a "bytes0" type
// (which would assert)
contract C {
function f() public pure returns (bytes memory, bytes memory) {
return (abi.encode(""), abi.encodePacked(""));
}
}
// ====
// ABIEncoderV1Only: true
// ----
// f() -> 0x40, 0xc0, 0x60, 0x20, 0x0, 0x0, 0x0
@@ -0,0 +1,18 @@
contract Test {
uint24[3][] public data;
function set(uint24[3][] memory _data) public returns (uint256) {
data = _data;
return data.length;
}
function get() public returns (uint24[3][] memory) {
return data;
}
}
// ----
// set(uint24[3][]): 0x20, 0x06, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12 -> 0x06
// data(uint256,uint256): 0x02, 0x02 -> 0x09
// data(uint256,uint256): 0x05, 0x01 -> 0x11
// data(uint256,uint256): 0x06, 0x00 -> FAILURE
// get() -> 0x20, 0x06, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12
@@ -0,0 +1,13 @@
contract Test {
function set(uint24[3][] memory _data, uint256 a, uint256 b)
public
returns (uint256 l, uint256 e)
{
l = _data.length;
e = _data[a][b];
}
}
// ====
// compileViaYul: also
// ----
// set(uint24[3][],uint256,uint256): 0x60, 0x03, 0x02, 0x06, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12 -> 0x06, 0x0c
@@ -0,0 +1,13 @@
contract Test {
function set(bytes memory _data, uint256 i)
public
returns (uint256 l, bytes1 c)
{
l = _data.length;
c = _data[i];
}
}
// ====
// compileViaYul: also
// ----
// set(bytes,uint256): 0x40, 0x03, 0x08, "abcdefgh" -> 0x08, "d"
@@ -0,0 +1,24 @@
contract C {
function f() public returns (uint256) {
uint256 l = 2**256 / 32;
// This used to work without causing an error.
uint256[] memory x = new uint256[](l);
uint256[] memory y = new uint256[](1);
x[1] = 42;
// This used to overwrite the value written above.
y[0] = 23;
return x[1];
}
function g() public returns (uint256) {
uint256 l = 2**256 / 2 + 1;
// This used to work without causing an error.
uint16[] memory x = new uint16[](l);
uint16[] memory y = new uint16[](1);
x[2] = 42;
// This used to overwrite the value written above.
y[0] = 23;
return x[2];
}}
// ----
// f() -> FAILURE
// g() -> FAILURE
@@ -0,0 +1,45 @@
contract c {
struct Data {
uint256 x;
uint256 y;
}
Data[2**10] data;
uint256[2**10 + 3] ids;
function setIDStatic(uint256 id) public {
ids[2] = id;
}
function setID(uint256 index, uint256 id) public {
ids[index] = id;
}
function setData(uint256 index, uint256 x, uint256 y) public {
data[index].x = x;
data[index].y = y;
}
function getID(uint256 index) public returns (uint256) {
return ids[index];
}
function getData(uint256 index) public returns (uint256 x, uint256 y) {
x = data[index].x;
y = data[index].y;
}
function getLengths() public returns (uint256 l1, uint256 l2) {
l1 = data.length;
l2 = ids.length;
}
}
// ----
// setIDStatic(uint256): 0xb ->
// getID(uint256): 0x2 -> 0xb
// setID(uint256,uint256): 0x7, 0x8 ->
// getID(uint256): 0x7 -> 0x8
// setData(uint256,uint256,uint256): 0x7, 0x8, 0x9 ->
// setData(uint256,uint256,uint256): 0x8, 0xa, 0xb ->
// getData(uint256): 0x7 -> 0x8, 0x9
// getData(uint256): 0x8 -> 0xa, 0xb
// getLengths() -> 0x400, 0x403
@@ -0,0 +1,17 @@
contract C {
bytes16[] public data;
function f(bytes32 x) public returns (bytes1) {
return x[2];
}
function g(bytes32 x) public returns (uint256) {
data = [x[0], x[1], x[2]];
data[0] = "12345";
return uint256(uint8(data[0][4]));
}
}
// ----
// f(bytes32): "789" -> "9"
// g(bytes32): "789" -> 0x35
// data(uint256): 0x01 -> "8"
@@ -0,0 +1,19 @@
contract Test {
uint24[3][][4] data;
function set(uint24[3][][4] memory x)
internal
returns (uint24[3][][4] memory)
{
x[1][2][2] = 1;
x[1][3][2] = 7;
return x;
}
function f() public returns (uint24[3][] memory) {
while (data[1].length < 4) data[1].push();
return set(data)[1];
}
}
// ----
// f() -> 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x07
@@ -0,0 +1,14 @@
contract Test {
function set(uint24[3][4] memory x) public {
x[2][2] = 1;
x[3][2] = 7;
}
function f() public returns (uint24[3][4] memory) {
uint24[3][4] memory data;
set(data);
return data;
}
}
// ----
// f() -> 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x07
@@ -0,0 +1,26 @@
// Invoke some features that use memory and test that they do not interfere with each other.
contract Helper {
uint256 public flag;
constructor(uint256 x) public {
flag = x;
}
}
contract Main {
mapping(uint256 => uint256) map;
function f(uint256 x) public returns (uint256) {
map[x] = x;
return
(new Helper(uint256(keccak256(abi.encodePacked(this.g(map[x]))))))
.flag();
}
function g(uint256 a) public returns (uint256) {
return map[a];
}
}
// ----
// f(uint256): 0x34 -> 0x46bddb1178e94d7f2892ff5f366840eb658911794f2c3a44c450aa2c505186c1
@@ -0,0 +1,20 @@
contract Sample {
struct s {
uint16 x;
uint16 y;
string a;
string b;
}
s[2] public p;
constructor() public {
s memory m;
m.x = 0xbbbb;
m.y = 0xcccc;
m.a = "hello";
m.b = "world";
p[0] = m;
}
}
// ----
// p(uint256): 0x0 -> 0xbbbb, 0xcccc, 0x80, 0xc0, 0x05, "hello", 0x05, "world"
@@ -0,0 +1,17 @@
contract Test {
string s;
bytes b;
function f(string memory _s, uint256 n) public returns (bytes1) {
b = bytes(_s);
s = string(b);
return bytes(s)[n];
}
function l() public returns (uint256) {
return bytes(s).length;
}
}
// ----
// f(string,uint256): 0x40, 0x02, 0x06, "abcdef" -> "c"
// l() -> 0x06
@@ -0,0 +1,35 @@
contract buggystruct {
Buggy public bug;
struct Buggy {
uint256 first;
uint256 second;
uint256 third;
string last;
}
constructor() public {
bug = Buggy(10, 20, 30, "asdfghjkl");
}
function getFirst() public returns (uint256) {
return bug.first;
}
function getSecond() public returns (uint256) {
return bug.second;
}
function getThird() public returns (uint256) {
return bug.third;
}
function getLast() public returns (string memory) {
return bug.last;
}
}
// ----
// getFirst() -> 0x0a
// getSecond() -> 0x14
// getThird() -> 0x1e
// getLast() -> 0x20, 0x09, "asdfghjkl"
@@ -0,0 +1,9 @@
contract C {
bytes32 constant x = keccak256("abc");
function f() public returns (bytes32) {
return x;
}
}
// ----
// f() -> 0x4e03657aea45a94fc7d47ba826c8d667c0d1e6e33a64a036ec44f58fa12d6c45
@@ -0,0 +1,26 @@
contract C {
uint256 public x;
function f() public pure returns (bytes4) {
return this.f.selector;
}
function g() public returns (bytes4) {
function () pure external returns (bytes4) fun = this.f;
return fun.selector;
}
function h() public returns (bytes4) {
function () pure external returns (bytes4) fun = this.f;
return fun.selector;
}
function i() public pure returns (bytes4) {
return this.x.selector;
}
}
// ----
// f() -> 0x26121ff000000000000000000000000000000000000000000000000000000000
// g() -> 0x26121ff000000000000000000000000000000000000000000000000000000000
// h() -> 0x26121ff000000000000000000000000000000000000000000000000000000000
// i() -> 0x0c55699c00000000000000000000000000000000000000000000000000000000
@@ -0,0 +1,12 @@
contract c {
bytes data;
function foo() public returns (bytes32) {
data.push("x");
data.push("y");
data.push("z");
return keccak256(abi.encodePacked("b", keccak256(data), "a"));
}
}
// ----
// foo() -> 0xb338eefce206f9f57b83aa738deecd5326dc4b72dd81ee6a7c621a6facb7acdc
@@ -0,0 +1,7 @@
contract c {
function foo(uint256 a, uint256 b, uint256 c) public returns (bytes32 d) {
d = keccak256(abi.encodePacked(a, b, c));
}
}
// ----
// foo(uint256,uint256,uint256): 0xa, 0xc, 0xd -> 0xbc740a98aae5923e8f04c9aa798c9ee82f69e319997699f2782c40828db9fd81
@@ -0,0 +1,7 @@
contract c {
function foo(uint256 a, uint16 b) public returns (bytes32 d) {
d = keccak256(abi.encodePacked(a, b, uint8(145)));
}
}
// ----
// foo(uint256,uint16): 0xa, 0xc -> 0x88acd45f75907e7c560318bc1a5249850a0999c4896717b1167d05d116e6dbad
@@ -0,0 +1,12 @@
contract c {
function foo() public returns (bytes32 d) {
d = keccak256("foo");
}
function bar(uint256 a, uint16 b) public returns (bytes32 d) {
d = keccak256(abi.encodePacked(a, b, uint8(145), "foo"));
}
}
// ----
// foo() -> 0x41b1a0649752af1b28b3dc29a1556eee781e4a4c3a1f7f53f90fa834de098c4d
// bar(uint256,uint16): 0xa, 0xc -> 0x6990f36476dc412b1c4baa48e2d9f4aa4bb313f61fda367c8fdbbb2232dc6146
@@ -0,0 +1,9 @@
contract test {
function foo(uint256 a) public returns (bytes4 value) {
return msg.sig;
}
}
// ====
// compileViaYul: also
// ----
// foo(uint256): 0x0 -> 0x2fbebd3800000000000000000000000000000000000000000000000000000000
@@ -0,0 +1,13 @@
contract test {
function boo() public returns (bytes4 value) {
return msg.sig;
}
function foo(uint256 a) public returns (bytes4 value) {
return boo();
}
}
// ====
// compileViaYul: also
// ----
// foo(uint256): 0x0 -> 0x2fbebd3800000000000000000000000000000000000000000000000000000000
@@ -0,0 +1,74 @@
pragma experimental ABIEncoderV2;
contract C {
function f1(bytes[1] calldata a)
external
returns (uint256, uint256, uint256, uint256)
{
return (a[0].length, uint8(a[0][0]), uint8(a[0][1]), uint8(a[0][2]));
}
function f2(bytes[1] calldata a, bytes[1] calldata b)
external
returns (uint256, uint256, uint256, uint256, uint256, uint256, uint256)
{
return (
a[0].length,
uint8(a[0][0]),
uint8(a[0][1]),
uint8(a[0][2]),
b[0].length,
uint8(b[0][0]),
uint8(b[0][1])
);
}
function g1(bytes[2] calldata a)
external
returns (
uint256,
uint256,
uint256,
uint256,
uint256,
uint256,
uint256,
uint256
)
{
return (
a[0].length,
uint8(a[0][0]),
uint8(a[0][1]),
uint8(a[0][2]),
a[1].length,
uint8(a[1][0]),
uint8(a[1][1]),
uint8(a[1][2])
);
}
function g2(bytes[] calldata a) external returns (uint256[8] memory) {
return [
a.length,
a[0].length,
uint8(a[0][0]),
uint8(a[0][1]),
a[1].length,
uint8(a[1][0]),
uint8(a[1][1]),
uint8(a[1][2])
];
}
}
// found expectation comments:
// same offset for both arrays @ ABI_CHECK(
// ----
// f1(bytes[1]): 0x20, 0x20, 0x3, hex"0102030000000000000000000000000000000000000000000000000000000000" -> 0x3, 0x1, 0x2, 0x3
// f2(bytes[1],bytes[1]): 0x40, 0xa0, 0x20, 0x3, hex"0102030000000000000000000000000000000000000000000000000000000000", 0x20, 0x2, hex"0102000000000000000000000000000000000000000000000000000000000000" -> 0x3, 0x1, 0x2, 0x3, 0x2, 0x1, 0x2
// g1(bytes[2]): 0x20, 0x40, 0x80, 0x3, hex"0102030000000000000000000000000000000000000000000000000000000000", 0x3, hex"0405060000000000000000000000000000000000000000000000000000000000" -> 0x3, 0x1, 0x2, 0x3, 0x3, 0x4, 0x5, 0x6
// g1(bytes[2]): 0x20, 0x40, 0x40, 0x3, hex"0102030000000000000000000000000000000000000000000000000000000000" -> 0x3, 0x1, 0x2, 0x3, 0x3, 0x1, 0x2, 0x3
// g2(bytes[]): 0x20, 0x2, 0x40, 0x80, 0x2, hex"0102000000000000000000000000000000000000000000000000000000000000", 0x3, hex"0405060000000000000000000000000000000000000000000000000000000000" -> 0x2, 0x2, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6
@@ -0,0 +1,18 @@
pragma experimental ABIEncoderV2;
contract C {
function f(bytes[] calldata a)
external
returns (uint256, uint256, bytes memory)
{
bytes memory m = a[0];
return (a.length, m.length, m);
}
}
// ----
// f(bytes[]): 0x20, 0x1, 0x20, 0x2, hex"6162000000000000000000000000000000000000000000000000000000000000" -> 0x1, 0x2, 0x60, 0x2, hex"6162000000000000000000000000000000000000000000000000000000000000"
// f(bytes[]): 0x20, 0x1, 0x20, 0x20, hex"7878787878787878787878787878787878787878787878787878787878787878" -> 0x1, 0x20, 0x60, 0x20, hex"7878787878787878787878787878787878787878787878787878787878787878"
// f(bytes[]): 0x20, 0x1, 0x20, 0x20, hex"7800000000000000000000000000000000000000000000000000000000000061" -> 0x1, 0x20, 0x60, 0x20, hex"7800000000000000000000000000000000000000000000000000000000000061"
// f(bytes[]): 0x20, 0x1, 0x20, 0x20, hex"6100000000000000000000000000000000000000000000000000000000000078" -> 0x1, 0x20, 0x60, 0x20, hex"6100000000000000000000000000000000000000000000000000000000000078"
// f(bytes[]): 0x20, 0x1, 0x20, 0x20, hex"616d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d78" -> 0x1, 0x20, 0x60, 0x20, hex"616d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d78"
@@ -0,0 +1,15 @@
pragma experimental ABIEncoderV2;
contract C {
function f(string[] calldata a)
external
returns (uint256, uint256, uint256, string memory)
{
string memory s1 = a[0];
bytes memory m1 = bytes(s1);
return (a.length, m1.length, uint8(m1[0]), s1);
}
}
// ----
// f(string[]): 0x20, 0x1, 0x20, 0x2, hex"6162000000000000000000000000000000000000000000000000000000000000" -> 1, 2, 97, 0x80, 2, "ab"
@@ -0,0 +1,22 @@
pragma experimental ABIEncoderV2;
contract C {
struct S {
uint8 a;
bytes1 b;
}
function f(S calldata s) external pure returns (uint256 a, bytes32 b) {
uint8 tmp1 = s.a;
bytes1 tmp2 = s.b;
assembly {
a := tmp1
b := tmp2
}
}
}
// ----
// f((uint8,bytes1)): 0x12, hex"3400000000000000000000000000000000000000000000000000000000000000" -> 0x12, hex"3400000000000000000000000000000000000000000000000000000000000000" # double check that the valid case goes through #
// f((uint8,bytes1)): 0x1234, hex"5678000000000000000000000000000000000000000000000000000000000000" -> FAILURE
// f((uint8,bytes1)): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> FAILURE
@@ -0,0 +1,23 @@
contract C {
function f(bool _b) public returns (uint256) {
if (_b) return 1;
else return 0;
}
function g(bool _in) public returns (bool _out) {
_out = _in;
}
}
// ====
// ABIEncoderV1Only: true
// ----
// f(bool): 0x0 -> 0x0
// f(bool): 0x1 -> 0x1
// f(bool): 0x2 -> 0x1
// f(bool): 0x3 -> 0x1
// f(bool): 0xff -> 0x1
// g(bool): 0x0 -> 0x0
// g(bool): 0x1 -> 0x1
// g(bool): 0x2 -> 0x1
// g(bool): 0x3 -> 0x1
// g(bool): 0xff -> 0x1
@@ -0,0 +1,24 @@
pragma experimental ABIEncoderV2;
contract C {
function f(bool _b) public returns (uint256) {
if (_b) return 1;
else return 0;
}
function g(bool _in) public returns (bool _out) {
_out = _in;
}
}
// ----
// f(bool): 0x0 -> 0x0
// f(bool): 0x1 -> 0x1
// f(bool): 0x2 -> FAILURE
// f(bool): 0x3 -> FAILURE
// f(bool): 0xff -> FAILURE
// g(bool): 0x0 -> 0x0
// g(bool): 0x1 -> 0x1
// g(bool): 0x2 -> FAILURE
// g(bool): 0x3 -> FAILURE
// g(bool): 0xff -> FAILURE
@@ -0,0 +1,17 @@
// Checks that address types are properly cleaned before they are compared.
contract C {
function f(address a) public returns (uint256) {
if (a != 0x1234567890123456789012345678901234567890) return 1;
return 0;
}
function g(address payable a) public returns (uint256) {
if (a != 0x1234567890123456789012345678901234567890) return 1;
return 0;
}
}
// ====
// ABIEncoderV1Only: true
// ----
// f(address): 0xffff1234567890123456789012345678901234567890 -> 0x0 # We input longer data on purpose.#
// g(address): 0xffff1234567890123456789012345678901234567890 -> 0x0
@@ -0,0 +1,18 @@
pragma experimental ABIEncoderV2;
// Checks that address types are properly cleaned before they are compared.
contract C {
function f(address a) public returns (uint256) {
if (a != 0x1234567890123456789012345678901234567890) return 1;
return 0;
}
function g(address payable a) public returns (uint256) {
if (a != 0x1234567890123456789012345678901234567890) return 1;
return 0;
}
}
// ----
// f(address): 0xffff1234567890123456789012345678901234567890 -> FAILURE # We input longer data on purpose.#
// g(address): 0xffff1234567890123456789012345678901234567890 -> FAILURE
@@ -0,0 +1,13 @@
// Checks that bytesXX types are properly cleaned before they are compared.
contract C {
function f(bytes2 a, uint16 x) public returns (uint256) {
if (a != "ab") return 1;
if (x != 0x0102) return 2;
if (bytes3(uint24(x)) != 0x000102) return 3;
return 0;
}
}
// ====
// ABIEncoderV1Only: true
// ----
// f(bytes2,uint16): "abc", 0x40102 -> 0x0 # We input longer data on purpose. #
@@ -0,0 +1,14 @@
pragma experimental ABIEncoderV2;
// Checks that bytesXX types are properly cleaned before they are compared.
contract C {
function f(bytes2 a, uint16 x) public returns (uint256) {
if (a != "ab") return 1;
if (x != 0x0102) return 2;
if (bytes3(uint24(x)) != 0x000102) return 3;
return 0;
}
}
// ----
// f(bytes2,uint16): "abc", 0x40102 -> FAILURE # We input longer data on purpose. #
@@ -0,0 +1,15 @@
contract C {
uint public i;
uint public k;
constructor(uint newI, uint newK) public {
i = newI;
k = newK;
}
}
// ====
// compileViaYul: also
// ----
// constructor(): 2, 0 ->
// i() -> 2
// k() -> 0
@@ -0,0 +1,37 @@
contract C {
uint256 value;
function set(uint256 _value) external {
value = _value;
}
function get() external view returns (uint256) {
return value;
}
function get_delegated() external returns (bool, bytes memory) {
return address(this).delegatecall(abi.encodeWithSignature("get()"));
}
function assert0() external view {
assert(value == 0);
}
function assert0_delegated() external returns (bool, bytes memory) {
return address(this).delegatecall(abi.encodeWithSignature("assert0()"));
}
}
// ====
// EVMVersion: >=byzantium
// ----
// get() -> 0x00
// assert0_delegated() -> 0x01, 0x40, 0x0
// get_delegated() -> 0x01, 0x40, 0x20, 0x0
// set(uint256): 0x01 ->
// get() -> 0x01
// assert0_delegated() -> 0x00, 0x40, 0x0
// get_delegated() -> 0x01, 0x40, 0x20, 0x1
// set(uint256): 0x2a ->
// get() -> 0x2a
// assert0_delegated() -> 0x00, 0x40, 0x0
// get_delegated() -> 0x01, 0x40, 0x20, 0x2a
@@ -0,0 +1,39 @@
contract C {
uint256 value;
function set(uint256 _value) external {
value = _value;
}
function get() external view returns (uint256) {
return value;
}
function get_delegated() external returns (bool) {
(bool success,) = address(this).delegatecall(abi.encodeWithSignature("get()"));
return success;
}
function assert0() external view {
assert(value == 0);
}
function assert0_delegated() external returns (bool) {
(bool success,) = address(this).delegatecall(abi.encodeWithSignature("assert0()"));
return success;
}
}
// ====
// EVMVersion: <byzantium
// ----
// get() -> 0x00
// assert0_delegated() -> true
// get_delegated() -> true
// set(uint256): 0x01 ->
// get() -> 0x01
// assert0_delegated() -> false
// get_delegated() -> true
// set(uint256): 0x2a ->
// get() -> 0x2a
// assert0_delegated() -> false
// get_delegated() -> true
@@ -0,0 +1,8 @@
contract A {
uint8 immutable a = 2;
function f() public view returns (uint) {
return a;
}
}
// ----
// f() -> 2
@@ -0,0 +1,5 @@
contract C {
uint immutable public x = 1;
}
// ----
// x() -> 1
@@ -0,0 +1,17 @@
contract A {
uint immutable public x = 1;
uint public y;
constructor() public {
y = this.x();
}
}
contract C {
function f() public returns (bool) {
try new A() { return false; }
catch { return true; }
}
}
// ====
// EVMVersion: >=tangerineWhistle
// ----
// f() -> true
@@ -0,0 +1,30 @@
contract A {
uint8 immutable a;
constructor() public {
a = 4;
}
}
contract B is A {
uint8 immutable b;
constructor() public {
b = 3;
}
}
contract C is A {
uint8 immutable c;
constructor() public {
c = 2;
}
}
contract D is B, C {
uint8 immutable d;
constructor() public {
d = 1;
}
function f() public view returns (uint256, uint256, uint, uint) {
return (a, b, c, d);
}
}
// ----
// f() -> 4, 3, 2, 1
@@ -0,0 +1,15 @@
contract C {
function() internal view returns(uint256) immutable z;
constructor() public {
z = f;
}
function f() public view returns (uint256) {
return 7;
}
function callZ() public view returns (uint) {
return z();
}
}
// ----
// f() -> 7
// callZ() -> 7
@@ -0,0 +1,31 @@
contract A {
uint immutable a;
constructor() public {
a = 7;
}
function f() public view returns (uint) { return a; }
}
contract B {
uint immutable a;
constructor() public {
a = 5;
}
function f() public view returns (uint) { return a; }
}
contract C {
uint immutable a;
uint public x;
uint public y;
constructor() public {
a = 3;
x = (new A()).f();
y = (new B()).f();
}
function f() public returns (uint256, uint, uint) {
return (a, (new A()).f(), (new B()).f());
}
}
// ----
// f() -> 3, 7, 5
// x() -> 7
// y() -> 5
@@ -0,0 +1,13 @@
contract C {
uint256 immutable x;
uint256 immutable y;
constructor() public {
x = 42;
y = 23;
}
function f() public view returns (uint256, uint256) {
return (x+x,y);
}
}
// ----
// f() -> 84, 23
@@ -0,0 +1,19 @@
contract C {
uint256 immutable x;
uint256 immutable y;
mapping(uint => uint) public m;
constructor(uint _a) public {
x = 42;
y = 23;
m[_a] = 7;
new uint[](4);
}
function f() public view returns (uint256, uint256) {
return (x+x,y);
}
}
// ----
// constructor(): 3 ->
// f() -> 84, 23
// m(uint256): 3 -> 7
@@ -0,0 +1,34 @@
contract C {
function shl(uint256 a, uint256 b) public returns (uint256 c) {
assembly {
c := shl(b, a)
}
}
function shr(uint256 a, uint256 b) public returns (uint256 c) {
assembly {
c := shr(b, a)
}
}
function sar(uint256 a, uint256 b) public returns (uint256 c) {
assembly {
c := sar(b, a)
}
}
}
// ====
// EVMVersion: >=constantinople
// compileViaYul: also
// ----
// shl(uint256,uint256): 0x01, 0x02 -> 0x04
// shl(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x01 -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe
// shl(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x100 -> 0x00
// shr(uint256,uint256): 0x03, 0x01 -> 0x01
// shr(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x01 -> 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
// shr(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xff -> 0x01
// shr(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x100 -> 0x00
// sar(uint256,uint256): 0x03, 0x01 -> 0x01
// sar(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x01 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
// sar(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
// sar(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x100 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
@@ -0,0 +1,122 @@
contract C {
function shl_zero(uint256 a) public returns (uint256 c) {
assembly {
c := shl(0, a)
}
}
function shr_zero(uint256 a) public returns (uint256 c) {
assembly {
c := shr(0, a)
}
}
function sar_zero(uint256 a) public returns (uint256 c) {
assembly {
c := sar(0, a)
}
}
function shl_large(uint256 a) public returns (uint256 c) {
assembly {
c := shl(0x110, a)
}
}
function shr_large(uint256 a) public returns (uint256 c) {
assembly {
c := shr(0x110, a)
}
}
function sar_large(uint256 a) public returns (uint256 c) {
assembly {
c := sar(0x110, a)
}
}
function shl_combined(uint256 a) public returns (uint256 c) {
assembly {
c := shl(4, shl(12, a))
}
}
function shr_combined(uint256 a) public returns (uint256 c) {
assembly {
c := shr(4, shr(12, a))
}
}
function sar_combined(uint256 a) public returns (uint256 c) {
assembly {
c := sar(4, sar(12, a))
}
}
function shl_combined_large(uint256 a) public returns (uint256 c) {
assembly {
c := shl(0xd0, shl(0x40, a))
}
}
function shl_combined_overflow(uint256 a) public returns (uint256 c) {
assembly {
c := shl(0x01, shl(not(0x00), a))
}
}
function shr_combined_large(uint256 a) public returns (uint256 c) {
assembly {
c := shr(0xd0, shr(0x40, a))
}
}
function shr_combined_overflow(uint256 a) public returns (uint256 c) {
assembly {
c := shr(0x01, shr(not(0x00), a))
}
}
function sar_combined_large(uint256 a) public returns (uint256 c) {
assembly {
c := sar(0xd0, sar(0x40, a))
}
}
}
// ====
// EVMVersion: >=constantinople
// compileViaYul: also
// ----
// shl_zero(uint256): 0x00 -> 0x00
// shl_zero(uint256): 0xffff -> 0xffff
// shl_zero(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
// shr_zero(uint256): 0x00 -> 0x00
// shr_zero(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
// sar_zero(uint256): 0x00 -> 0x00
// sar_zero(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
// shl_large(uint256): 0x00 -> 0x00
// shl_large(uint256): 0xffff -> 0x00
// shl_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00
// shr_large(uint256): 0x00 -> 0x00
// shr_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00
// sar_large(uint256): 0x00 -> 0x00
// sar_large(uint256): 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00
// sar_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
// shl_combined(uint256): 0x00 -> 0x00
// shl_combined(uint256): 0xffff -> 0xffff0000
// shl_combined(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000
// shr_combined(uint256): 0x00 -> 0x00
// shr_combined(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
// sar_combined(uint256): 0x00 -> 0x00
// sar_combined(uint256): 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
// sar_combined(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
// shl_combined_large(uint256): 0x00 -> 0x00
// shl_combined_large(uint256): 0xffff -> 0x00
// shl_combined_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00
// shl_combined_overflow(uint256): 0x02 -> 0x00
// shr_combined_large(uint256): 0x00 -> 0x00
// shr_combined_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00
// shr_combined_overflow(uint256): 0x02 -> 0x00
// sar_combined_large(uint256): 0x00 -> 0x00
// sar_combined_large(uint256): 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00
// sar_combined_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
@@ -0,0 +1,83 @@
contract C {
function shl_1() public returns (bool) {
uint256 c;
assembly {
c := shl(2, 1)
}
assert(c == 4);
return true;
}
function shl_2() public returns (bool) {
uint256 c;
assembly {
c := shl(
1,
0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
)
}
assert(
c ==
0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe
);
return true;
}
function shl_3() public returns (bool) {
uint256 c;
assembly {
c := shl(
256,
0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
)
}
assert(c == 0);
return true;
}
function shr_1() public returns (bool) {
uint256 c;
assembly {
c := shr(1, 3)
}
assert(c == 1);
return true;
}
function shr_2() public returns (bool) {
uint256 c;
assembly {
c := shr(
1,
0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
)
}
assert(
c ==
0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
);
return true;
}
function shr_3() public returns (bool) {
uint256 c;
assembly {
c := shr(
256,
0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
)
}
assert(c == 0);
return true;
}
}
// ====
// EVMVersion: >=constantinople
// compileViaYul: also
// ----
// shl_1() -> 0x01
// shl_2() -> 0x01
// shl_3() -> 0x01
// shr_1() -> 0x01
// shr_2() -> 0x01
// shr_3() -> 0x01
@@ -0,0 +1,14 @@
contract C {
function f(uint8 a, uint8 b) public returns (uint256) {
assembly {
a := 0xffffffff
}
// Higher bits should be cleared before the shift
return a >> b;
}
}
// ====
// ABIEncoderV1Only: true
// ----
// f(uint8,uint8): 0x00, 0x04 -> 0x0f
// f(uint8,uint8): 0x00, 0x1004 -> 0x0f
@@ -0,0 +1,30 @@
contract C {
function f(int8 a, uint8 b) public returns (int256) {
assembly {
a := 0xfffffff0
}
// Higher bits should be signextended before the shift
return a >> b;
}
function g(int8 a, uint8 b) public returns (int256) {
assembly {
a := 0xf0
}
// Higher bits should be signextended before the shift
return a >> b;
}
}
// ====
// ABIEncoderV1Only: true
// ----
// f(int8,uint8): 0x00, 0x03 -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe
// f(int8,uint8): 0x00, 0x04 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
// f(int8,uint8): 0x00, 0xff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
// f(int8,uint8): 0x00, 0x1003 -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe
// f(int8,uint8): 0x00, 0x1004 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
// g(int8,uint8): 0x00, 0x03 -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe
// g(int8,uint8): 0x00, 0x04 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
// g(int8,uint8): 0x00, 0xff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
// g(int8,uint8): 0x00, 0x1003 -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe
// g(int8,uint8): 0x00, 0x1004 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
@@ -0,0 +1,31 @@
pragma experimental ABIEncoderV2;
contract C {
function f(int8 a, uint8 b) public returns (int256) {
assembly {
a := 0xfffffff0
}
// Higher bits should be signextended before the shift
return a >> b;
}
function g(int8 a, uint8 b) public returns (int256) {
assembly {
a := 0xf0
}
// Higher bits should be signextended before the shift
return a >> b;
}
}
// ----
// f(int8,uint8): 0x00, 0x03 -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe
// f(int8,uint8): 0x00, 0x04 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
// f(int8,uint8): 0x00, 0xff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
// f(int8,uint8): 0x00, 0x1003 -> FAILURE
// f(int8,uint8): 0x00, 0x1004 -> FAILURE
// g(int8,uint8): 0x00, 0x03 -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe
// g(int8,uint8): 0x00, 0x04 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
// g(int8,uint8): 0x00, 0xff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
// g(int8,uint8): 0x00, 0x1003 -> FAILURE
// g(int8,uint8): 0x00, 0x1004 -> FAILURE
@@ -0,0 +1,15 @@
pragma experimental ABIEncoderV2;
contract C {
function f(uint8 a, uint8 b) public returns (uint256) {
assembly {
a := 0xffffffff
}
// Higher bits should be cleared before the shift
return a >> b;
}
}
// ----
// f(uint8,uint8): 0x00, 0x04 -> 0x0f
// f(uint8,uint8): 0x00, 0x1004 -> FAILURE
@@ -0,0 +1,13 @@
contract C {
function f(int16 a, int16 b) public returns (int16) {
return a >> b;
}
}
// ====
// ABIEncoderV1Only: true
// ----
// f(int16,int16): 0xff99, 0x00 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff99
// f(int16,int16): 0xff99, 0x01 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffcc
// f(int16,int16): 0xff99, 0x02 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe6
// f(int16,int16): 0xff99, 0x04 -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9
// f(int16,int16): 0xff99, 0x08 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
@@ -0,0 +1,14 @@
pragma experimental ABIEncoderV2;
contract C {
function f(int16 a, int16 b) public returns (int16) {
return a >> b;
}
}
// ----
// f(int16,int16): 0xff99, 0x00 -> FAILURE
// f(int16,int16): 0xff99, 0x01 -> FAILURE
// f(int16,int16): 0xff99, 0x02 -> FAILURE
// f(int16,int16): 0xff99, 0x04 -> FAILURE
// f(int16,int16): 0xff99, 0x08 -> FAILURE
@@ -0,0 +1,13 @@
contract C {
function f(int32 a, int32 b) public returns (int32) {
return a >> b;
}
}
// ====
// ABIEncoderV1Only: true
// ----
// f(int32,int32): 0xffffff99, 0x00 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff99
// f(int32,int32): 0xffffff99, 0x01 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffcc
// f(int32,int32): 0xffffff99, 0x02 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe6
// f(int32,int32): 0xffffff99, 0x04 -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9
// f(int32,int32): 0xffffff99, 0x08 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
@@ -0,0 +1,14 @@
pragma experimental ABIEncoderV2;
contract C {
function f(int32 a, int32 b) public returns (int32) {
return a >> b;
}
}
// ----
// f(int32,int32): 0xffffff99, 0x00 -> FAILURE
// f(int32,int32): 0xffffff99, 0x01 -> FAILURE
// f(int32,int32): 0xffffff99, 0x02 -> FAILURE
// f(int32,int32): 0xffffff99, 0x04 -> FAILURE
// f(int32,int32): 0xffffff99, 0x08 -> FAILURE
@@ -0,0 +1,13 @@
contract C {
function f(int8 a, int8 b) public returns (int8) {
return a >> b;
}
}
// ====
// ABIEncoderV1Only: true
// ----
// f(int8,int8): 0x99, 0x00 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff99
// f(int8,int8): 0x99, 0x01 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffcc
// f(int8,int8): 0x99, 0x02 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe6
// f(int8,int8): 0x99, 0x04 -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9
// f(int8,int8): 0x99, 0x08 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
@@ -0,0 +1,14 @@
pragma experimental ABIEncoderV2;
contract C {
function f(int8 a, int8 b) public returns (int8) {
return a >> b;
}
}
// ----
// f(int8,int8): 0x99, 0x00 -> FAILURE
// f(int8,int8): 0x99, 0x01 -> FAILURE
// f(int8,int8): 0x99, 0x02 -> FAILURE
// f(int8,int8): 0x99, 0x04 -> FAILURE
// f(int8,int8): 0x99, 0x08 -> FAILURE
@@ -0,0 +1,69 @@
contract Test {
struct S {
uint8 x;
uint16 y;
uint256 z;
}
struct X {
uint8 x;
S s;
uint8[2] a;
}
X m_x;
function load()
public
returns (
uint256 a,
uint256 x,
uint256 y,
uint256 z,
uint256 a1,
uint256 a2
)
{
m_x.x = 1;
m_x.s.x = 2;
m_x.s.y = 3;
m_x.s.z = 4;
m_x.a[0] = 5;
m_x.a[1] = 6;
X memory d = m_x;
a = d.x;
x = d.s.x;
y = d.s.y;
z = d.s.z;
a1 = d.a[0];
a2 = d.a[1];
}
function store()
public
returns (
uint256 a,
uint256 x,
uint256 y,
uint256 z,
uint256 a1,
uint256 a2
)
{
X memory d;
d.x = 1;
d.s.x = 2;
d.s.y = 3;
d.s.z = 4;
d.a[0] = 5;
d.a[1] = 6;
m_x = d;
a = m_x.x;
x = m_x.s.x;
y = m_x.s.y;
z = m_x.s.z;
a1 = m_x.a[0];
a2 = m_x.a[1];
}
}
// ----
// load() -> 0x01, 0x02, 0x03, 0x04, 0x05, 0x06
// store() -> 0x01, 0x02, 0x03, 0x04, 0x05, 0x06
@@ -0,0 +1,30 @@
contract C {
struct X {
uint256 x1;
uint256 x2;
}
struct S {
uint256 s1;
uint256[3] s2;
X s3;
}
S s;
constructor() public {
uint256[3] memory s2;
s2[1] = 9;
s = S(1, s2, X(4, 5));
}
function get()
public
returns (uint256 s1, uint256[3] memory s2, uint256 x1, uint256 x2)
{
s1 = s.s1;
s2 = s.s2;
x1 = s.s3.x1;
x2 = s.s3.x2;
}
}
// ----
// get() -> 0x01, 0x00, 0x09, 0x00, 0x04, 0x05
@@ -0,0 +1,24 @@
contract test {
function f0() public returns(int, bool) {
int a;
bool b;
((a, b)) = (2, true);
return (a, b);
}
function f1() public returns(int) {
int a;
(((a, ), )) = ((1, 2) ,3);
return a;
}
function f2() public returns(int) {
int a;
(((, a),)) = ((1, 2), 3);
return a;
}
}
// ====
// compileViaYul: also
// ----
// f0() -> 2, true
// f1() -> 1
// f2() -> 2
@@ -0,0 +1,23 @@
// This triggered a bug in some version because the variable in the modifier was not
// unregistered correctly.
contract C {
uint256 public x;
modifier m1 {
address a1 = msg.sender;
x++;
_;
}
function f1() public m1() {
x += 7;
}
function f2() public m1() {
x += 3;
}
}
// ----
// f1() ->
// x() -> 0x08
// f2() ->
// x() -> 0x0c
@@ -0,0 +1,39 @@
contract C {
uint256 x;
function f() public returns (uint256) {
x = 3;
return 1;
}
}
interface CView {
function f() external view returns (uint256);
}
interface CPure {
function f() external pure returns (uint256);
}
contract D {
function f() public returns (uint256) {
return (new C()).f();
}
function fview() public returns (uint256) {
return (CView(address(new C()))).f();
}
function fpure() public returns (uint256) {
return (CPure(address(new C()))).f();
}
}
// ====
// EVMVersion: >=byzantium
// ----
// f() -> 0x1 # This should work, next should throw #
// fview() -> FAILURE
// fpure() -> FAILURE
@@ -0,0 +1,39 @@
contract C {
uint256 x;
function f() public returns (uint256) {
x = 3;
return 1;
}
}
interface CView {
function f() external view returns (uint256);
}
interface CPure {
function f() external pure returns (uint256);
}
contract D {
function f() public returns (uint256) {
return (new C()).f();
}
function fview() public returns (uint256) {
return (CView(address(new C()))).f();
}
function fpure() public returns (uint256) {
return (CPure(address(new C()))).f();
}
}
// ====
// EVMVersion: <byzantium
// ----
// f() -> 0x1
// fview() -> 1
// fpure() -> 1
@@ -0,0 +1,29 @@
contract C {
function f(uint n, uint m) public {
function() internal returns (uint)[] memory arr = new function() internal returns (uint)[](n);
arr[m]();
}
function f2(uint n, uint m, uint a, uint b) public {
function() internal returns (uint)[][] memory arr = new function() internal returns (uint)[][](n);
for (uint i = 0; i < n; ++i)
arr[i] = new function() internal returns (uint)[](m);
arr[a][b]();
}
function g(uint n, uint m) public {
function() external returns (uint)[] memory arr = new function() external returns (uint)[](n);
arr[m]();
}
function g2(uint n, uint m, uint a, uint b) public {
function() external returns (uint)[][] memory arr = new function() external returns (uint)[][](n);
for (uint i = 0; i < n; ++i)
arr[i] = new function() external returns (uint)[](m);
arr[a][b]();
}
}
// ====
// compileViaYul: also
// ----
// f(uint256,uint256): 1823621, 12323 -> FAILURE
// f2(uint256,uint256,uint256,uint256): 18723921, 1823621, 123, 12323 -> FAILURE
// g(uint256,uint256): 1823621, 12323 -> FAILURE
// g2(uint256,uint256,uint256,uint256): 18723921, 1823621, 123, 12323 -> FAILURE
@@ -0,0 +1,24 @@
contract C {
uint test1;
uint test2;
uint test3;
uint test4;
uint test5;
uint test6;
uint test7;
mapping (string => uint) map;
function set(string memory s, uint n, uint m, uint a, uint b) public returns (uint) {
map[s] = 0;
uint[][] memory x = new uint[][](n);
for (uint i = 0; i < n; ++i)
x[i] = new uint[](m);
return x[a][b];
}
}
// ====
// compileViaYul: also
// ----
// set(string,uint256,uint256,uint256,uint256): 0xa0, 2, 4, 0, 0, 32, "01234567890123456789012345678901" -> 0
// set(string,uint256,uint256,uint256,uint256): 0xa0, 2, 4, 1, 3, 32, "01234567890123456789012345678901" -> 0
// set(string,uint256,uint256,uint256,uint256): 0xa0, 2, 4, 3, 3, 32, "01234567890123456789012345678901" -> FAILURE
// set(string,uint256,uint256,uint256,uint256): 0xa0, 2, 4, 1, 5, 32, "01234567890123456789012345678901" -> FAILURE
@@ -0,0 +1,22 @@
contract C {
uint test1;
uint test2;
uint test3;
uint test4;
uint test5;
uint test6;
uint test7;
mapping (string => uint) map;
function set(string memory s, uint n, uint m) public returns (uint) {
map[s] = 0;
uint[4][] memory x = new uint[4][](n);
return x[m][0];
}
}
// ====
// compileViaYul: also
// ----
// set(string,uint256,uint256): 0x60, 2, 0, 32, "01234567890123456789012345678901" -> 0
// set(string,uint256,uint256): 0x60, 2, 1, 32, "01234567890123456789012345678901" -> 0
// set(string,uint256,uint256): 0x60, 2, 2, 32, "01234567890123456789012345678901" -> FAILURE
// set(string,uint256,uint256): 0x60, 200, 199, 32, "01234567890123456789012345678901" -> 0
@@ -0,0 +1,17 @@
contract C {
uint test1;
uint test2;
uint test3;
uint test4;
uint test5;
uint test6;
uint test7;
mapping (string => uint) map;
function set(string memory s) public returns (uint[3] memory x, uint[2] memory y, uint[] memory z, uint t) {
map[s] = 0;
}
}
// ====
// compileViaYul: also
// ----
// set(string): 0x20, 32, "01234567890123456789012345678901" -> 0, 0, 0, 0, 0, 0xe0, 0, 0
@@ -0,0 +1,19 @@
contract C {
uint test1;
uint test2;
uint test3;
uint test4;
uint test5;
uint test6;
uint test7;
mapping (string => uint) map;
function set(string memory s) public returns (uint) {
map[s] = 0;
uint[3] memory x;
return x[2];
}
}
// ====
// compileViaYul: also
// ----
// set(string): 0x20, 32, "01234567890123456789012345678901" -> 0
@@ -0,0 +1,22 @@
contract C {
uint test1;
uint test2;
uint test3;
uint test4;
uint test5;
uint test6;
uint test7;
mapping (string => uint) map;
function set(string memory s, uint n, uint a) public returns (uint) {
map[s] = 0;
uint[] memory x = new uint[](n);
return x[a];
}
}
// ====
// compileViaYul: also
// ----
// set(string,uint256,uint256): 0x60, 5, 0, 32, "01234567890123456789012345678901" -> 0
// set(string,uint256,uint256): 0x60, 5, 1, 32, "01234567890123456789012345678901" -> 0
// set(string,uint256,uint256): 0x60, 5, 4, 32, "01234567890123456789012345678901" -> 0
// set(string,uint256,uint256): 0x60, 5, 5, 32, "01234567890123456789012345678901" -> FAILURE
@@ -0,0 +1,25 @@
contract C {
function f() public {
function() internal returns (uint) _f;
_f();
}
function g() public {
function() external returns (uint) _g;
_g();
}
function h1() internal returns (function() internal returns (uint) _h) {}
function h2() public {
h1()();
}
function k1() internal returns (function() external returns (uint) _k) {}
function k2() public {
k1()();
}
}
// ====
// compileViaYul: also
// ----
// f() -> FAILURE
// g() -> FAILURE
// h2() -> FAILURE
// k2() -> FAILURE
@@ -0,0 +1,16 @@
contract C {
uint[] arr1;
uint[][] arr2;
function f() internal returns (uint[] storage ptr1, uint[][] storage ptr2) {
ptr1 = arr1;
ptr2 = arr2;
}
function g() public returns (uint, uint) {
return (arr1.length, arr2.length);
}
}
// ====
// compileViaYul: also
// ----
// g() -> 0, 0
@@ -0,0 +1,20 @@
pragma experimental SMTChecker;
contract C {
function c() public pure returns (uint) { return 42; }
}
contract B is C {
function b() public pure returns (uint) { return c(); }
}
contract A is B {
uint public x;
function a() public {
x = b();
assert(x < 40);
}
}
// ----
// Warning: (254-268): Assertion violation happens here
@@ -0,0 +1,24 @@
pragma experimental SMTChecker;
contract C {
uint y;
function c(uint _y) public returns (uint) {
y = _y;
return y;
}
}
contract B is C {
function b() public returns (uint) { return c(42); }
}
contract A is B {
uint public x;
function a() public {
x = b();
assert(x < 40);
}
}
// ----
// Warning: (274-288): Assertion violation happens here
@@ -2,8 +2,10 @@ contract C {
function f() public {
uint[] storage x;
uint[10] storage y;
x;
y;
}
}
// ----
// DeclarationError: (38-54): Uninitialized storage pointer.
// DeclarationError: (58-76): Uninitialized storage pointer.
// TypeError: (80-81): This variable is of storage pointer type and can be accessed without prior assignment, which would lead to undefined behaviour.
// TypeError: (85-86): This variable is of storage pointer type and can be accessed without prior assignment, which would lead to undefined behaviour.
@@ -0,0 +1,38 @@
contract C {
struct S { bool f; }
S s;
function f() internal pure {
S storage c;
assembly {
for {} eq(0,0) { c_slot := s_slot } {}
}
c;
}
function g() internal pure {
S storage c;
assembly {
for {} eq(0,1) { c_slot := s_slot } {}
}
c;
}
function h() internal pure {
S storage c;
assembly {
for {} eq(0,0) {} { c_slot := s_slot }
}
c;
}
function i() internal pure {
S storage c;
assembly {
for {} eq(0,1) {} { c_slot := s_slot }
}
c;
}
}
// ----
// TypeError: (189-190): This variable is of storage pointer type and can be accessed without prior assignment, which would lead to undefined behaviour.
// TypeError: (340-341): This variable is of storage pointer type and can be accessed without prior assignment, which would lead to undefined behaviour.
// TypeError: (491-492): This variable is of storage pointer type and can be accessed without prior assignment, which would lead to undefined behaviour.
// TypeError: (642-643): This variable is of storage pointer type and can be accessed without prior assignment, which would lead to undefined behaviour.
@@ -0,0 +1,19 @@
contract C {
struct S { bool f; }
S s;
function f() internal pure {
S storage c;
assembly {
for { c_slot := s_slot } iszero(0) {} {}
}
c;
}
function g() internal pure {
S storage c;
assembly {
for { c_slot := s_slot } iszero(1) {} {}
}
c;
}
}
// ----
@@ -0,0 +1,13 @@
contract C {
struct S { bool f; }
S s;
function f(bool flag) internal pure {
S storage c;
assembly {
if flag { c_slot := s_slot }
}
c;
}
}
// ----
// TypeError: (188-189): This variable is of storage pointer type and can be accessed without prior assignment, which would lead to undefined behaviour.
@@ -0,0 +1,15 @@
contract C {
struct S { bool f; }
S s;
function f() internal pure {
S storage c;
// this should warn about unreachable code, but currently function flow is ignored
assembly {
function f() { return(0, 0) }
f()
c_slot := s_slot
}
c;
}
}
// ----
@@ -0,0 +1,15 @@
contract C {
struct S { bool f; }
S s;
function f() internal pure {
S storage c;
// this could be allowed, but currently control flow for functions is not analysed
assembly {
function f() { revert(0, 0) }
f()
}
c;
}
}
// ----
// TypeError: (287-288): This variable is of storage pointer type and can be accessed without prior assignment, which would lead to undefined behaviour.
@@ -0,0 +1,12 @@
contract C {
struct S { bool f; }
S s;
function f() internal pure {
S storage c;
assembly {
c_slot := s_slot
}
c;
}
}
// ----
@@ -0,0 +1,33 @@
contract C {
struct S { bool f; }
S s;
function f(uint256 a) internal pure {
S storage c;
assembly {
switch a
case 0 { c_slot := s_slot }
}
c;
}
function g(bool flag) internal pure {
S storage c;
assembly {
switch flag
case 0 { c_slot := s_slot }
case 1 { c_slot := s_slot }
}
c;
}
function h(uint256 a) internal pure {
S storage c;
assembly {
switch a
case 0 { c_slot := s_slot }
default { return(0,0) }
}
c;
}
}
// ----
// TypeError: (208-209): This variable is of storage pointer type and can be accessed without prior assignment, which would lead to undefined behaviour.
// TypeError: (421-422): This variable is of storage pointer type and can be accessed without prior assignment, which would lead to undefined behaviour.
@@ -0,0 +1,31 @@
contract C {
struct S { bool f; }
S s;
function f(uint256 a) internal pure {
S storage c;
assembly {
switch a
default { c_slot := s_slot }
}
c;
}
function g(bool flag) internal pure {
S storage c;
assembly {
switch flag
case 0 { c_slot := s_slot }
default { c_slot := s_slot }
}
c;
}
function h(uint256 a) internal pure {
S storage c;
assembly {
switch a
case 0 { revert(0, 0) }
default { c_slot := s_slot }
}
c;
}
}
// ----
@@ -0,0 +1,66 @@
contract C {
struct S { bool f; }
S s;
function f() internal view {
S storage c;
do {
break;
c = s;
} while(false);
c;
}
function g() internal view {
S storage c;
do {
if (s.f) {
continue;
c = s;
}
else {
}
} while(false);
c;
}
function h() internal view {
S storage c;
do {
if (s.f) {
break;
}
else {
c = s;
}
} while(false);
c;
}
function i() internal view {
S storage c;
do {
if (s.f) {
continue;
}
else {
c = s;
}
} while(false);
c;
}
function j() internal view {
S storage c;
do {
continue;
c = s;
} while(false);
c;
}
}
// ----
// TypeError: (184-185): This variable is of storage pointer type and can be accessed without prior assignment, which would lead to undefined behaviour.
// Warning: (145-150): Unreachable code.
// Warning: (168-173): Unreachable code.
// TypeError: (411-412): This variable is of storage pointer type and can be accessed without prior assignment, which would lead to undefined behaviour.
// Warning: (325-330): Unreachable code.
// TypeError: (635-636): This variable is of storage pointer type and can be accessed without prior assignment, which would lead to undefined behaviour.
// TypeError: (862-863): This variable is of storage pointer type and can be accessed without prior assignment, which would lead to undefined behaviour.
// TypeError: (1011-1012): This variable is of storage pointer type and can be accessed without prior assignment, which would lead to undefined behaviour.
// Warning: (972-977): Unreachable code.
@@ -0,0 +1,44 @@
contract C {
struct S { bool f; }
S s;
function f() internal view {
S storage c;
do {} while((c = s).f);
c;
}
function g() internal view {
S storage c;
do { c = s; } while(false);
c;
}
function h() internal view {
S storage c;
c = s;
do {} while(false);
c;
}
function i() internal view {
S storage c;
do {} while(false);
c = s;
c;
}
function j() internal view {
S storage c;
do {
c = s;
break;
} while(false);
c;
}
function k() internal view {
S storage c;
do {
c = s;
continue;
} while(false);
c;
}
}
// ----
// Warning: (606-611): Unreachable code.
@@ -0,0 +1,20 @@
contract C {
struct S { bool f; }
S s;
function f() internal view {
S storage c;
for(;; c = s) {
}
c;
}
function g() internal view {
S storage c;
for(;;) {
c = s;
}
c;
}
}
// ----
//TypeError: (143-144): This variable is of storage pointer type and can be accessed without prior assignment, which would lead to undefined behaviour.
// TypeError: (261-262): This variable is of storage pointer type and can be accessed without prior assignment, which would lead to undefined behaviour.
@@ -0,0 +1,17 @@
contract C {
struct S { bool f; }
S s;
function f() internal view {
S storage c;
for(c = s;;) {
}
c;
}
function g() internal view {
S storage c;
for(; (c = s).f;) {
}
c;
}
}
// ----
@@ -0,0 +1,22 @@
contract C {
struct S { bool f; }
S s;
function f(bool flag) internal {
S storage c;
if (flag) c = s;
c;
}
function g(bool flag) internal {
S storage c;
if (flag) c = s;
else
{
if (!flag) c = s;
else s.f = true;
}
c;
}
}
// ----
// TypeError: (138-139): This variable is of storage pointer type and can be accessed without prior assignment, which would lead to undefined behaviour.
// TypeError: (330-331): This variable is of storage pointer type and can be accessed without prior assignment, which would lead to undefined behaviour.
@@ -0,0 +1,39 @@
contract C {
struct S { bool f; }
S s;
function f(bool flag) internal view {
S storage c;
if (flag) c = s;
else c = s;
c;
}
function g(bool flag) internal view {
S storage c;
if (flag) c = s;
else { c = s; }
c;
}
function h(bool flag) internal view {
S storage c;
if (flag) c = s;
else
{
if (!flag) c = s;
else c = s;
}
c;
}
function i() internal view {
S storage c;
if ((c = s).f) {
}
c;
}
function j() internal view {
S storage c;
if ((c = s).f && !(c = s).f) {
}
c;
}
}
// ----
@@ -0,0 +1,20 @@
contract C {
modifier revertIfNoReturn() {
_;
revert();
}
modifier ifFlag(bool flag) {
if (flag)
_;
}
struct S { uint a; }
S s;
function f(bool flag) revertIfNoReturn() internal view {
if (flag) s;
}
function g(bool flag) revertIfNoReturn() ifFlag(flag) internal view {
s;
}
}
// ----
@@ -0,0 +1,11 @@
contract C {
struct S { bool f; }
S s;
function g(bool flag) internal view {
S storage c;
if (flag) c = s;
else revert();
s;
}
}
// ----
@@ -0,0 +1,24 @@
contract C {
struct S { bool f; }
S s;
function f() internal view {
S storage c;
false && (c = s).f;
c;
}
function g() internal view {
S storage c;
true || (c = s).f;
c;
}
function h() internal view {
S storage c;
// expect error, although this is always fine
true && (false || (c = s).f);
c;
}
}
// ----
// TypeError: (137-138): This variable is of storage pointer type and can be accessed without prior assignment, which would lead to undefined behaviour.
// TypeError: (235-236): This variable is of storage pointer type and can be accessed without prior assignment, which would lead to undefined behaviour.
// TypeError: (398-399): This variable is of storage pointer type and can be accessed without prior assignment, which would lead to undefined behaviour.
@@ -0,0 +1,15 @@
contract C {
struct S { bool f; }
S s;
function f() internal view {
S storage c;
(c = s).f && false;
c;
}
function g() internal view {
S storage c;
(c = s).f || true;
c;
}
}
// ----
@@ -0,0 +1,17 @@
contract C {
struct S { bool f; }
S s;
function f() internal pure {}
function g() internal view { s; }
function h() internal view {
S storage c;
c = s;
c;
}
function i() internal view {
S storage c;
(c) = s;
c;
}
}
// ----
@@ -0,0 +1,11 @@
contract C {
uint256[] s;
function f() public {
bool d;
uint256[] storage x;
uint256[] storage y = d ? (x = s) : x;
y;
}
}
// ----
// TypeError: (145-146): This variable is of storage pointer type and can be accessed without prior assignment, which would lead to undefined behaviour.

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