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

This commit is contained in:
chriseth
2020-03-24 13:35:41 +01:00
856 changed files with 12967 additions and 8148 deletions
+4 -8
View File
@@ -36,15 +36,11 @@ using namespace solidity::util;
using namespace solidity::frontend;
using namespace solidity::frontend::test;
ABIJsonTest::ABIJsonTest(string const& _filename)
ABIJsonTest::ABIJsonTest(string const& _filename):
TestCase(_filename)
{
ifstream file(_filename);
if (!file)
BOOST_THROW_EXCEPTION(runtime_error("Cannot open test contract: \"" + _filename + "\"."));
file.exceptions(ios::badbit);
m_source = parseSourceAndSettings(file);
m_expectation = parseSimpleExpectations(file);
m_source = m_reader.source();
m_expectation = m_reader.simpleExpectations();
}
TestCase::TestResult ABIJsonTest::run(ostream& _stream, string const& _linePrefix, bool _formatted)
@@ -54,7 +54,7 @@
"storageLocation": "memory",
"typeDescriptions":
{
"typeIdentifier": "t_array$_t_array$_t_uint256_$dyn_memory_$dyn_memory_ptr",
"typeIdentifier": "t_array$_t_array$_t_uint256_$dyn_memory_ptr_$dyn_memory_ptr",
"typeString": "uint256[][]"
},
"typeName":
+7 -28
View File
@@ -36,35 +36,14 @@ using namespace std;
namespace fs = boost::filesystem;
using namespace boost::unit_test;
GasTest::GasTest(string const& _filename)
GasTest::GasTest(string const& _filename):
TestCase(_filename)
{
ifstream file(_filename);
if (!file)
BOOST_THROW_EXCEPTION(runtime_error("Cannot open test contract: \"" + _filename + "\"."));
file.exceptions(ios::badbit);
m_source = parseSourceAndSettings(file);
if (m_settings.count("optimize"))
{
m_optimise = true;
m_validatedSettings["optimize"] = "true";
m_settings.erase("optimize");
}
if (m_settings.count("optimize-yul"))
{
m_optimiseYul = true;
m_validatedSettings["optimize-yul"] = "true";
m_settings.erase("optimize-yul");
}
if (m_settings.count("optimize-runs"))
{
m_optimiseRuns = stoul(m_settings["optimize-runs"]);
m_validatedSettings["optimize-runs"] = m_settings["optimize-runs"];
m_settings.erase("optimize-runs");
}
parseExpectations(file);
m_source = m_reader.source();
m_optimise = m_reader.boolSetting("optimize", false);
m_optimiseYul = m_reader.boolSetting("optimize-yul", false);
m_optimiseRuns = m_reader.sizetSetting("optimize-runs", 200);
parseExpectations(m_reader.stream());
}
void GasTest::parseExpectations(std::istream& _stream)
+1 -1
View File
@@ -135,7 +135,7 @@ TestCase::TestResult SMTCheckerJSONTest::run(ostream& _stream, string const& _li
}
}
return printExpectationAndError(_stream, _linePrefix, _formatted) ? TestResult::Success : TestResult::Failure;
return conclude(_stream, _linePrefix, _formatted);
}
vector<string> SMTCheckerJSONTest::hashesFromJson(Json::Value const& _jsonObj, string const& _auxInput, string const& _smtlib)
+11 -16
View File
@@ -28,22 +28,17 @@ using namespace solidity::frontend::test;
SMTCheckerTest::SMTCheckerTest(string const& _filename, langutil::EVMVersion _evmVersion): SyntaxTest(_filename, _evmVersion)
{
if (m_settings.count("SMTSolvers"))
{
auto const& choice = m_settings.at("SMTSolvers");
if (choice == "any")
m_enabledSolvers = smt::SMTSolverChoice::All();
else if (choice == "z3")
m_enabledSolvers = smt::SMTSolverChoice::Z3();
else if (choice == "cvc4")
m_enabledSolvers = smt::SMTSolverChoice::CVC4();
else if (choice == "none")
m_enabledSolvers = smt::SMTSolverChoice::None();
else
BOOST_THROW_EXCEPTION(runtime_error("Invalid SMT solver choice."));
}
else
auto const& choice = m_reader.stringSetting("SMTSolvers", "any");
if (choice == "any")
m_enabledSolvers = smt::SMTSolverChoice::All();
else if (choice == "z3")
m_enabledSolvers = smt::SMTSolverChoice::Z3();
else if (choice == "cvc4")
m_enabledSolvers = smt::SMTSolverChoice::CVC4();
else if (choice == "none")
m_enabledSolvers = smt::SMTSolverChoice::None();
else
BOOST_THROW_EXCEPTION(runtime_error("Invalid SMT solver choice."));
auto available = ModelChecker::availableSolvers();
if (!available.z3)
@@ -62,5 +57,5 @@ TestCase::TestResult SMTCheckerTest::run(ostream& _stream, string const& _linePr
parseAndAnalyze();
filterObtainedErrors();
return printExpectationAndError(_stream, _linePrefix, _formatted) ? TestResult::Success : TestResult::Failure;
return conclude(_stream, _linePrefix, _formatted);
}
+25 -42
View File
@@ -37,59 +37,42 @@ namespace fs = boost::filesystem;
SemanticTest::SemanticTest(string const& _filename, langutil::EVMVersion _evmVersion):
SolidityExecutionFramework(_evmVersion)
SolidityExecutionFramework(_evmVersion),
EVMVersionRestrictedTestCase(_filename)
{
ifstream file(_filename);
soltestAssert(file, "Cannot open test contract: \"" + _filename + "\".");
file.exceptions(ios::badbit);
m_source = m_reader.source();
m_lineOffset = m_reader.lineNumber();
std::tie(m_source, m_lineOffset) = parseSourceAndSettingsWithLineNumbers(file);
if (m_settings.count("compileViaYul"))
string choice = m_reader.stringSetting("compileViaYul", "false");
if (choice == "also")
{
if (m_settings["compileViaYul"] == "also")
{
m_validatedSettings["compileViaYul"] = m_settings["compileViaYul"];
m_runWithYul = true;
m_runWithoutYul = true;
}
else
{
m_validatedSettings["compileViaYul"] = "only";
m_runWithYul = true;
m_runWithoutYul = false;
}
m_settings.erase("compileViaYul");
m_runWithYul = true;
m_runWithoutYul = true;
}
if (m_settings.count("ABIEncoderV1Only"))
else if (choice == "true")
{
if (m_settings["ABIEncoderV1Only"] == "true")
{
m_validatedSettings["ABIEncoderV1Only"] = "true";
m_runWithABIEncoderV1Only = true;
}
m_settings.erase("ABIEncoderV1Only");
m_runWithYul = true;
m_runWithoutYul = false;
}
else if (choice == "false")
{
m_runWithYul = false;
m_runWithoutYul = true;
}
else
BOOST_THROW_EXCEPTION(runtime_error("Invalid compileViaYul value: " + choice + "."));
m_runWithABIEncoderV1Only = m_reader.boolSetting("ABIEncoderV1Only", false);
if (m_runWithABIEncoderV1Only && solidity::test::CommonOptions::get().useABIEncoderV2)
m_shouldRun = false;
if (m_settings.count("revertStrings"))
{
auto revertStrings = revertStringsFromString(m_settings["revertStrings"]);
if (revertStrings)
m_revertStrings = *revertStrings;
m_validatedSettings["revertStrings"] = revertStringsToString(m_revertStrings);
m_settings.erase("revertStrings");
}
auto revertStrings = revertStringsFromString(m_reader.stringSetting("revertStrings", "default"));
soltestAssert(revertStrings, "Invalid revertStrings setting.");
m_revertStrings = revertStrings.value();
if (m_settings.count("allowNonExistingFunctions"))
{
m_validatedSettings["allowNonExistingFunctions"] = true;
m_settings.erase("allowNonExistingFunctions");
}
m_allowNonExistingFunctions = m_reader.boolSetting("allowNonExistingFunctions", false);
parseExpectations(file);
parseExpectations(m_reader.stream());
soltestAssert(!m_tests.empty(), "No tests specified in " + _filename);
}
@@ -152,7 +135,7 @@ TestCase::TestResult SemanticTest::run(ostream& _stream, string const& _linePref
else
{
soltestAssert(
m_validatedSettings.count("allowNonExistingFunctions") || m_compiler.methodIdentifiers(m_compiler.lastContractName()).isMember(test.call().signature),
m_allowNonExistingFunctions || m_compiler.methodIdentifiers(m_compiler.lastContractName()).isMember(test.call().signature),
"The function " + test.call().signature + " is not known to the compiler"
);
+1
View File
@@ -65,6 +65,7 @@ private:
bool m_runWithYul = false;
bool m_runWithoutYul = true;
bool m_runWithABIEncoderV1Only = false;
bool m_allowNonExistingFunctions = false;
};
}
File diff suppressed because it is too large Load Diff
@@ -21,6 +21,7 @@
*/
#include <cstdlib>
#include <iostream>
#include <boost/test/framework.hpp>
#include <test/libsolidity/SolidityExecutionFramework.h>
@@ -60,6 +61,7 @@ bytes SolidityExecutionFramework::compileContract(
formatter.printErrorInformation(*error);
BOOST_ERROR("Compiling contract failed");
}
std::string contractName(_contractName.empty() ? m_compiler.lastContractName() : _contractName);
evmasm::LinkerObject obj;
if (m_compileViaYul)
{
@@ -70,9 +72,7 @@ bytes SolidityExecutionFramework::compileContract(
// get code that does not exhaust the stack.
OptimiserSettings::full()
);
if (!asmStack.parseAndAnalyze("", m_compiler.yulIROptimized(
_contractName.empty() ? m_compiler.lastContractName() : _contractName
)))
if (!asmStack.parseAndAnalyze("", m_compiler.yulIROptimized(contractName)))
{
langutil::SourceReferenceFormatter formatter(std::cerr);
@@ -84,7 +84,9 @@ bytes SolidityExecutionFramework::compileContract(
obj = std::move(*asmStack.assemble(yul::AssemblyStack::Machine::EVM).bytecode);
}
else
obj = m_compiler.object(_contractName.empty() ? m_compiler.lastContractName() : _contractName);
obj = m_compiler.object(contractName);
BOOST_REQUIRE(obj.linkReferences.empty());
if (m_showMetadata)
cout << "metadata: " << m_compiler.metadata(contractName) << endl;
return obj.bytecode;
}
@@ -41,9 +41,9 @@ class SolidityExecutionFramework: public solidity::test::ExecutionFramework
{
public:
SolidityExecutionFramework() {}
SolidityExecutionFramework(): m_showMetadata(solidity::test::CommonOptions::get().showMetadata) {}
explicit SolidityExecutionFramework(langutil::EVMVersion _evmVersion):
ExecutionFramework(_evmVersion)
ExecutionFramework(_evmVersion), m_showMetadata(solidity::test::CommonOptions::get().showMetadata)
{}
virtual bytes const& compileAndRunWithoutCheck(
@@ -68,6 +68,7 @@ public:
protected:
solidity::frontend::CompilerStack m_compiler;
bool m_compileViaYul = false;
bool m_showMetadata = false;
RevertStrings m_revertStrings = RevertStrings::Default;
};
+2 -15
View File
@@ -37,20 +37,7 @@ namespace fs = boost::filesystem;
SyntaxTest::SyntaxTest(string const& _filename, langutil::EVMVersion _evmVersion, bool _parserErrorRecovery): CommonSyntaxTest(_filename, _evmVersion)
{
if (m_settings.count("optimize-yul"))
{
if (m_settings["optimize-yul"] == "true")
{
m_validatedSettings["optimize-yul"] = "true";
m_settings.erase("optimize-yul");
}
else if (m_settings["optimize-yul"] == "false")
{
m_validatedSettings["optimize-yul"] = "false";
m_settings.erase("optimize-yul");
m_optimiseYul = false;
}
}
m_optimiseYul = m_reader.boolSetting("optimize-yul", true);
m_parserErrorRecovery = _parserErrorRecovery;
}
@@ -60,7 +47,7 @@ TestCase::TestResult SyntaxTest::run(ostream& _stream, string const& _linePrefix
parseAndAnalyze();
filterObtainedErrors();
return printExpectationAndError(_stream, _linePrefix, _formatted) ? TestResult::Success : TestResult::Failure;
return conclude(_stream, _linePrefix, _formatted);
}
void SyntaxTest::setupCompiler()
+3 -3
View File
@@ -14,9 +14,9 @@ contract C {
}
// ----
// creation:
// codeDepositCost: 1120000
// executionCost: 1160
// totalCost: 1121160
// codeDepositCost: 1094400
// executionCost: 1134
// totalCost: 1095534
// external:
// a(): 1130
// b(uint256): infinite
@@ -0,0 +1,8 @@
contract C {
function f(bytes calldata data) external pure returns (uint256[] memory) {
return abi.decode(data, (uint256[]));
}
}
// ----
// f(bytes): 0x20, 0xc0, 0x20, 0x4, 0x3, 0x4, 0x5, 0x6 -> 0x20, 0x4, 0x3, 0x4, 0x5, 0x6
@@ -0,0 +1,12 @@
contract C {
function f(bytes calldata data)
external
pure
returns (uint256[2][3] memory)
{
return abi.decode(data, (uint256[2][3]));
}
}
// ----
// f(bytes): 0x20, 0xc0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6 -> 1, 2, 3, 4, 5, 6
@@ -0,0 +1,15 @@
pragma experimental ABIEncoderV2;
contract C {
function f(bytes calldata data)
external
pure
returns (uint256[2][3] memory)
{
return abi.decode(data, (uint256[2][3]));
}
}
// ----
// f(bytes): 0x20, 0xc0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6 -> 1, 2, 3, 4, 5, 6
@@ -0,0 +1,8 @@
contract C {
function f(bytes memory data) public pure returns (uint256) {
return abi.decode(data, (uint256));
}
}
// ----
// f(bytes): 0x20, 0x20, 0x21 -> 33
@@ -0,0 +1,22 @@
pragma experimental ABIEncoderV2;
contract C {
struct S {
uint256 a;
uint256[] b;
}
function f() public pure returns (S memory) {
S memory s;
s.a = 8;
s.b = new uint256[](3);
s.b[0] = 9;
s.b[1] = 10;
s.b[2] = 11;
return abi.decode(abi.encode(s), (S));
}
}
// ----
// f() -> 0x20, 0x8, 0x40, 0x3, 0x9, 0xa, 0xb
@@ -0,0 +1,16 @@
pragma experimental ABIEncoderV2;
contract C {
struct S {
uint256 a;
uint256[] b;
}
function f(bytes calldata data) external pure returns (S memory) {
return abi.decode(data, (S));
}
}
// ----
// f(bytes): 0x20, 0xe0, 0x20, 0x21, 0x40, 0x3, 0xa, 0xb, 0xc -> 0x20, 0x21, 0x40, 0x3, 0xa, 0xb, 0xc
@@ -0,0 +1,24 @@
pragma experimental ABIEncoderV2;
contract C {
bytes data;
struct S {
uint256 a;
uint256[] b;
}
function f() public returns (S memory) {
S memory s;
s.a = 8;
s.b = new uint256[](3);
s.b[0] = 9;
s.b[1] = 10;
s.b[2] = 11;
data = abi.encode(s);
return abi.decode(data, (S));
}
}
// ----
// f() -> 0x20, 0x8, 0x40, 0x3, 0x9, 0xa, 0xb
@@ -0,0 +1,36 @@
contract C {
function f0() public returns (bytes memory) {
return abi.encode();
}
function f1() public returns (bytes memory) {
return abi.encode(1, 2);
}
function f2() public returns (bytes memory) {
string memory x = "abc";
return abi.encode(1, x, 2);
}
function f3() public returns (bytes memory r) {
// test that memory is properly allocated
string memory x = "abc";
r = abi.encode(1, x, 2);
bytes memory y = "def";
require(y[0] == "d");
y[0] = "e";
require(y[0] == "e");
}
function f4() public returns (bytes memory) {
bytes4 x = "abcd";
return abi.encode(bytes2(x));
}
}
// ----
// f0() -> 0x20, 0x0
// f1() -> 0x20, 0x40, 0x1, 0x2
// f2() -> 0x20, 0xa0, 0x1, 0x60, 0x2, 0x3, "abc"
// f3() -> 0x20, 0xa0, 0x1, 0x60, 0x2, 0x3, "abc"
// f4() -> 0x20, 0x20, "ab"
@@ -0,0 +1,26 @@
contract C {
bool x;
function c(uint256 a, uint256[] memory b) public {
require(a == 5);
require(b.length == 2);
require(b[0] == 6);
require(b[1] == 7);
x = true;
}
function f() public returns (bool) {
uint256 a = 5;
uint256[] memory b = new uint256[](2);
b[0] = 6;
b[1] = 7;
(bool success, ) = address(this).call(
abi.encodeWithSignature("c(uint256,uint256[])", a, b)
);
require(success);
return x;
}
}
// ----
// f() -> true
@@ -0,0 +1,9 @@
contract C {
function f() public pure returns (uint256, bytes memory) {
bytes memory arg = "abcdefg";
return abi.decode(abi.encode(uint256(33), arg), (uint256, bytes));
}
}
// ----
// f() -> 0x21, 0x40, 0x7, "abcdefg"
@@ -0,0 +1,9 @@
// Tests that rational numbers (even negative ones) are encoded properly.
contract C {
function f() public pure returns (bytes memory) {
return abi.encode(1, -2);
}
}
// ----
// f() -> 0x20, 0x40, 0x1, -2
@@ -0,0 +1,13 @@
// Tests that this will not end up using a "bytes0" type
// (which would assert)
pragma experimental ABIEncoderV2;
contract C {
function f() public pure returns (bytes memory, bytes memory) {
return (abi.encode(""), abi.encodePacked(""));
}
}
// ----
// f() -> 0x40, 0xa0, 0x40, 0x20, 0x0, 0x0
@@ -0,0 +1,12 @@
// Tests that rational numbers (even negative ones) are encoded properly.
pragma experimental ABIEncoderV2;
contract C {
function f() public pure returns (bytes memory) {
return abi.encode(1, -2);
}
}
// ----
// f() -> 0x20, 0x40, 0x1, -2
@@ -0,0 +1,53 @@
pragma experimental ABIEncoderV2;
contract C {
struct S {
uint256 a;
uint256[] b;
}
function f0() public pure returns (bytes memory) {
return abi.encode();
}
function f1() public pure returns (bytes memory) {
return abi.encode(1, 2);
}
function f2() public pure returns (bytes memory) {
string memory x = "abc";
return abi.encode(1, x, 2);
}
function f3() public pure returns (bytes memory r) {
// test that memory is properly allocated
string memory x = "abc";
r = abi.encode(1, x, 2);
bytes memory y = "def";
require(y[0] == "d");
y[0] = "e";
require(y[0] == "e");
}
S s;
function f4() public returns (bytes memory r) {
string memory x = "abc";
s.a = 7;
s.b.push(2);
s.b.push(3);
r = abi.encode(1, x, s, 2);
bytes memory y = "def";
require(y[0] == "d");
y[0] = "e";
require(y[0] == "e");
}
}
// ----
// f0() -> 0x20, 0x0
// f1() -> 0x20, 0x40, 0x1, 0x2
// f2() -> 0x20, 0xa0, 0x1, 0x60, 0x2, 0x3, "abc"
// f3() -> 0x20, 0xa0, 0x1, 0x60, 0x2, 0x3, "abc"
// f4() -> 0x20, 0x160, 0x1, 0x80, 0xc0, 0x2, 0x3, "abc", 0x7, 0x40, 0x2, 0x2, 0x3
@@ -0,0 +1,6 @@
contract Lotto {
uint256 public constant ticketPrice = 555;
}
// ----
// ticketPrice() -> 555
@@ -0,0 +1,8 @@
contract Lotto {
uint256 public ticketPrice = 500;
}
// ====
// compileViaYul: also
// ----
// ticketPrice() -> 500
@@ -0,0 +1,12 @@
contract C {
function test() public returns (uint256) {
// Note that this only works because computation on literals is done using
// unbounded integers.
if ((2**255 + 2**255) % 7 != addmod(2**255, 2**255, 7)) return 1;
if ((2**255 + 2**255) % 7 != addmod(2**255, 2**255, 7)) return 2;
return 0;
}
}
// ----
// test() -> 0
@@ -0,0 +1,24 @@
contract C {
function f(uint256 d) public pure returns (uint256) {
addmod(1, 2, d);
return 2;
}
function g(uint256 d) public pure returns (uint256) {
mulmod(1, 2, d);
return 2;
}
function h() public pure returns (uint256) {
mulmod(0, 1, 2);
mulmod(1, 0, 2);
addmod(0, 1, 2);
addmod(1, 0, 2);
return 2;
}
}
// ----
// f(uint256): 0 -> FAILURE
// g(uint256): 0 -> FAILURE
// h() -> 2
@@ -0,0 +1,15 @@
contract C {
function div(uint256 a, uint256 b) public returns (uint256) {
return a / b;
}
function mod(uint256 a, uint256 b) public returns (uint256) {
return a % b;
}
}
// ----
// div(uint256,uint256): 7, 2 -> 3
// div(uint256,uint256): 7, 0 -> FAILURE # throws #
// mod(uint256,uint256): 7, 2 -> 1
// mod(uint256,uint256): 7, 0 -> FAILURE # throws #
@@ -0,0 +1,21 @@
contract c {
bytes8[] data1; // 4 per slot
bytes10[] data2; // 3 per slot
function test()
public
returns (bytes10 a, bytes10 b, bytes10 c, bytes10 d, bytes10 e)
{
data1 = new bytes8[](9);
for (uint256 i = 0; i < data1.length; ++i) data1[i] = bytes8(uint64(i));
data2 = data1;
a = data2[1];
b = data2[2];
c = data2[3];
d = data2[4];
e = data2[5];
}
}
// ----
// test() -> 0x01000000000000000000000000000000000000000000000000, 0x02000000000000000000000000000000000000000000000000, 0x03000000000000000000000000000000000000000000000000, 0x04000000000000000000000000000000000000000000000000, 0x05000000000000000000000000000000000000000000000000
@@ -0,0 +1,15 @@
contract c {
uint256[4][] a;
uint256[10][] b;
uint256[][] c;
function test(uint256[2][] calldata d) external returns (uint256) {
a = d;
b = a;
c = b;
return c[1][1] | c[1][2] | c[1][3] | c[1][4];
}
}
// ----
// test(uint256[2][]): 32, 3, 7, 8, 9, 10, 11, 12 -> 10
@@ -0,0 +1,20 @@
// NOTE: This does not really test copying from storage to ABI directly,
// because it will always copy to memory first.
contract c {
int16[] x;
function test() public returns (int16[] memory) {
x.push(int16(-1));
x.push(int16(-1));
x.push(int16(8));
x.push(int16(-16));
x.push(int16(-2));
x.push(int16(6));
x.push(int16(8));
x.push(int16(-1));
return x;
}
}
// ----
// test() -> 0x20, 0x8, -1, -1, 8, -16, -2, 6, 8, -1
@@ -0,0 +1,14 @@
contract c {
uint256[9] data1;
uint256[] data2;
function test() public returns (uint256 x, uint256 y) {
data1[8] = 4;
data2 = data1;
x = data2.length;
y = data2[8];
}
}
// ----
// test() -> 9, 4
@@ -0,0 +1,17 @@
contract c {
uint256[40] data1;
uint256[20] data2;
function test() public returns (uint256 x, uint256 y) {
data1[30] = 4;
data1[2] = 7;
data1[3] = 9;
data2[3] = 8;
data1 = data2;
x = data1[3];
y = data1[30]; // should be cleared
}
}
// ----
// test() -> 8, 0
@@ -0,0 +1,22 @@
// since the copy always copies whole slots, we have to make sure that the source size maxes
// out a whole slot and at the same time there are still elements left in the target at that point
contract c {
bytes8[4] data1; // fits into one slot
bytes10[6] data2; // 4 elements need two slots
function test() public returns (bytes10 r1, bytes10 r2, bytes10 r3) {
data1[0] = bytes8(uint64(1));
data1[1] = bytes8(uint64(2));
data1[2] = bytes8(uint64(3));
data1[3] = bytes8(uint64(4));
for (uint256 i = 0; i < data2.length; ++i)
data2[i] = bytes10(uint80(0xffff00 | (1 + i)));
data2 = data1;
r1 = data2[3];
r2 = data2[4];
r3 = data2[5];
}
}
// ----
// test() -> 0x04000000000000000000000000000000000000000000000000, 0x0, 0x0
@@ -0,0 +1,21 @@
contract c {
bytes8[9] data1; // 4 per slot
bytes17[10] data2; // 1 per slot, no offset counter
function test()
public
returns (bytes17 a, bytes17 b, bytes17 c, bytes17 d, bytes17 e)
{
for (uint256 i = 0; i < data1.length; ++i) data1[i] = bytes8(uint64(i));
data2[8] = data2[9] = bytes8(uint64(2));
data2 = data1;
a = data2[1];
b = data2[2];
c = data2[3];
d = data2[4];
e = data2[9];
}
}
// ----
// test() -> 0x01000000000000000000000000000000000000000000000000, 0x02000000000000000000000000000000000000000000000000, 0x03000000000000000000000000000000000000000000000000, 0x04000000000000000000000000000000000000000000000000, 0x0
@@ -0,0 +1,16 @@
contract c {
uint256[] data;
function test() public returns (uint256 x, uint256 l) {
data.push(7);
data.push(3);
x = data.length;
data.pop();
x = data.length;
data.pop();
l = data.length;
}
}
// ----
// test() -> 1, 0
@@ -0,0 +1,11 @@
contract c {
uint256[] data;
function test() public returns (bool) {
data.pop();
return true;
}
}
// ----
// test() -> FAILURE
@@ -0,0 +1,13 @@
// This tests that the compiler knows the correct size of the function on the stack.
contract c {
uint256[] data;
function test() public returns (uint256 x) {
x = 2;
data.pop;
x = 3;
}
}
// ----
// test() -> 3
@@ -0,0 +1,19 @@
contract c {
uint256[] data;
function test()
public
returns (uint256 x, uint256 y, uint256 z, uint256 l)
{
data.push(5);
x = data[0];
data.push(4);
y = data[1];
data.push(3);
l = data.length;
z = data[2];
}
}
// ----
// test() -> 5, 4, 3, 3
@@ -0,0 +1,16 @@
contract c {
uint80[] x;
function test() public returns (uint80, uint80, uint80, uint80) {
x.push(1);
x.push(2);
x.push(3);
x.push(4);
x.push(5);
x.pop();
return (x[0], x[1], x[2], x[3]);
}
}
// ----
// test() -> 1, 2, 3, 4
@@ -0,0 +1,23 @@
contract c {
struct S {
uint16 a;
uint16 b;
uint16[3] c;
uint16[] d;
}
S[] data;
function test() public returns (uint16, uint16, uint16, uint16) {
S memory s;
s.a = 2;
s.b = 3;
s.c[2] = 4;
s.d = new uint16[](4);
s.d[2] = 5;
data.push(s);
return (data[0].a, data[0].b, data[0].c[2], data[0].d[2]);
}
}
// ----
// test() -> 2, 3, 4, 5
@@ -0,0 +1,17 @@
contract c {
bytes data;
function test() public returns (uint256 x, uint256 y, uint256 l) {
data.push(0x07);
data.push(0x03);
x = data.length;
data.pop();
data.pop();
data.push(0x02);
y = data.length;
l = data.length;
}
}
// ----
// test() -> 2, 1, 1
@@ -0,0 +1,12 @@
contract c {
bytes data;
function test() public returns (bytes memory) {
for (uint256 i = 0; i < 33; i++) data.push(0x03);
for (uint256 j = 0; j < 4; j++) data.pop();
return data;
}
}
// ----
// test() -> 0x20, 29, 0x0303030303030303030303030303030303030303030303030303030303000000
@@ -0,0 +1,14 @@
contract c {
uint256 a;
uint256 b;
uint256 c;
bytes data;
function test() public returns (bool) {
data.pop();
return true;
}
}
// ----
// test() -> FAILURE
@@ -0,0 +1,13 @@
// This tests that the compiler knows the correct size of the function on the stack.
contract c {
bytes data;
function test() public returns (uint256 x) {
x = 2;
data.pop;
x = 3;
}
}
// ----
// test() -> 3
@@ -0,0 +1,12 @@
contract c {
bytes data;
function test() public returns (bytes memory) {
for (uint256 i = 0; i < 34; i++) data.push(0x03);
data.pop();
return data;
}
}
// ----
// test() -> 0x20, 33, 0x303030303030303030303030303030303030303030303030303030303030303, 0x0300000000000000000000000000000000000000000000000000000000000000
@@ -0,0 +1,18 @@
contract c {
bytes data;
function test() public returns (bool x) {
data.push(0x05);
if (data.length != 1) return true;
if (data[0] != 0x05) return true;
data.push(0x04);
if (data[1] != 0x04) return true;
data.push(0x03);
uint256 l = data.length;
if (data[2] != 0x03) return true;
if (l != 0x03) return true;
}
}
// ----
// test() -> false
@@ -0,0 +1,18 @@
// Tests transition between short and long encoding
contract c {
bytes data;
function test() public returns (uint256) {
for (uint8 i = 1; i < 40; i++) {
data.push(bytes1(i));
if (data.length != i) return 0x1000 + i;
if (data[data.length - 1] != bytes1(i)) return i;
}
for (uint8 i = 1; i < 40; i++)
if (data[i - 1] != bytes1(i)) return 0x1000000 + i;
return 0;
}
}
// ----
// test() -> 0
@@ -0,0 +1,19 @@
contract c {
bytes data;
function test1() external returns (bool) {
data = new bytes(100);
for (uint256 i = 0; i < data.length; i++) data[i] = bytes1(uint8(i));
delete data[94];
delete data[96];
delete data[98];
return
data[94] == 0 &&
uint8(data[95]) == 95 &&
data[96] == 0 &&
uint8(data[97]) == 97;
}
}
// ----
// test1() -> true
@@ -0,0 +1,17 @@
contract c {
function set() public returns (bool) {
data = msg.data;
return true;
}
function getLength() public returns (uint256) {
return data.length;
}
bytes data;
}
// ----
// getLength() -> 0
// set(): 1, 2 -> true
// getLength() -> 68
@@ -0,0 +1,16 @@
pragma experimental ABIEncoderV2;
contract C {
function f(uint256[2] calldata s)
external
pure
returns (uint256 a, uint256 b)
{
a = s[0];
b = s[1];
}
}
// ----
// f(uint256[2]): 42, 23 -> 42, 23
@@ -0,0 +1,21 @@
pragma experimental ABIEncoderV2;
contract C {
function f(uint256[][] calldata a) external returns (uint256) {
return 42;
}
function g(uint256[][] calldata a) external returns (uint256) {
a[0];
return 42;
}
}
// ----
// f(uint256[][]): 0x20, 0x0 -> 42 # valid access stub #
// f(uint256[][]): 0x20, 0x1 -> FAILURE # invalid on argument decoding #
// f(uint256[][]): 0x20, 0x1, 0x20 -> 42 # invalid on outer access #
// g(uint256[][]): 0x20, 0x1, 0x20 -> FAILURE
// f(uint256[][]): 0x20, 0x1, 0x20, 0x2, 0x42 -> 42 # invalid on inner access #
// g(uint256[][]): 0x20, 0x1, 0x20, 0x2, 0x42 -> FAILURE
@@ -0,0 +1,30 @@
pragma experimental ABIEncoderV2;
contract C {
function f(uint256[][1][] calldata a) external returns (uint256) {
return 42;
}
function g(uint256[][1][] calldata a) external returns (uint256) {
a[0];
return 42;
}
function h(uint256[][1][] calldata a) external returns (uint256) {
a[0][0];
return 42;
}
}
// ----
// f(uint256[][1][]): 0x20, 0x0 -> 42 # valid access stub #
// f(uint256[][1][]): 0x20, 0x1 -> FAILURE # invalid on argument decoding #
// f(uint256[][1][]): 0x20, 0x1, 0x20 -> 42 # invalid on outer access #
// g(uint256[][1][]): 0x20, 0x1, 0x20 -> FAILURE
// f(uint256[][1][]): 0x20, 0x1, 0x20, 0x20 -> 42 # invalid on inner access #
// g(uint256[][1][]): 0x20, 0x1, 0x20, 0x20 -> 42
// h(uint256[][1][]): 0x20, 0x1, 0x20, 0x20 -> FAILURE
// f(uint256[][1][]): 0x20, 0x1, 0x20, 0x20, 0x1 -> 42
// g(uint256[][1][]): 0x20, 0x1, 0x20, 0x20, 0x1 -> 42
// h(uint256[][1][]): 0x20, 0x1, 0x20, 0x20, 0x1 -> FAILURE
@@ -0,0 +1,24 @@
pragma experimental ABIEncoderV2;
contract C {
struct S {
uint256 a;
uint256 b;
}
function f(S[] calldata s)
external
pure
returns (uint256 l, uint256 a, uint256 b, uint256 c, uint256 d)
{
l = s.length;
a = s[0].a;
b = s[0].b;
c = s[1].a;
d = s[1].b;
}
}
// ----
// f((uint256,uint256)[]): 0x20, 0x2, 0x1, 0x2, 0x3, 0x4 -> 2, 1, 2, 3, 4
@@ -0,0 +1,25 @@
pragma experimental ABIEncoderV2;
contract C {
struct S {
uint256 a;
uint256 b;
}
function f(S[] calldata s)
external
pure
returns (uint256 l, uint256 a, uint256 b, uint256 c, uint256 d)
{
S[] memory m = s;
l = m.length;
a = m[0].a;
b = m[0].b;
c = m[1].a;
d = m[1].b;
}
}
// ----
// f((uint256,uint256)[]): 0x20, 0x2, 0x1, 0x2, 0x3, 0x4 -> 2, 1, 2, 3, 4
@@ -0,0 +1,15 @@
pragma experimental ABIEncoderV2;
contract C {
function f(uint256[][] calldata a)
external
returns (uint256, uint256[] memory)
{
uint256[] memory m = a[0];
return (a.length, m);
}
}
// ----
// f(uint256[][]): 0x20, 0x1, 0x20, 0x2, 0x17, 0x2a -> 0x1, 0x40, 0x2, 0x17, 0x2a
@@ -6,6 +6,8 @@ contract C {
return (x[start:end][index], x[start:][0:end-start][index], x[:end][start:][index]);
}
}
// ====
// compileViaYul: also
// ----
// f(uint256[],uint256,uint256): 0x80, 0, 0, 0, 1, 42 ->
// f(uint256[],uint256,uint256): 0x80, 0, 1, 0, 1, 42 ->
@@ -0,0 +1,14 @@
contract C {
uint256 constant LEN = 3;
uint256[LEN] public a;
constructor(uint256[LEN] memory _a) public {
a = _a;
}
}
// ----
// constructor(): 1, 2, 3 ->
// a(uint256): 0 -> 1
// a(uint256): 1 -> 2
// a(uint256): 2 -> 3
@@ -0,0 +1,18 @@
contract C {
function() internal returns (uint)[] x;
function() internal returns (uint)[] y;
function test() public returns (uint256) {
x = new function() internal returns (uint)[](10);
x[9] = a;
y = x;
return y[9]();
}
function a() public returns (uint256) {
return 7;
}
}
// ----
// test() -> 7
@@ -0,0 +1,22 @@
contract C {
function() internal returns (uint)[20] x;
int256 mutex;
function one() public returns (uint256) {
function() internal returns (uint)[20] memory xmem;
x = xmem;
return 3;
}
function two() public returns (uint256) {
if (mutex > 0) return 7;
mutex = 1;
// If this test fails, it might re-execute this function.
x[0]();
return 2;
}
}
// ----
// one() -> 3
// two() -> FAILURE
@@ -0,0 +1,9 @@
contract C {
function f() public returns (uint256) {
uint256[][] memory a = new uint256[][](0);
return 7;
}
}
// ----
// f() -> 7
@@ -0,0 +1,21 @@
contract C {
struct S {
uint256[2] a;
bytes b;
}
function f() public returns (bytes1, uint256, uint256, bytes1) {
bytes memory x = new bytes(200);
x[199] = "A";
uint256[2][] memory y = new uint256[2][](300);
y[203][1] = 8;
S[] memory z = new S[](180);
z[170].a[1] = 4;
z[170].b = new bytes(102);
z[170].b[99] = "B";
return (x[199], y[203][1], z[170].a[1], z[170].b[99]);
}
}
// ----
// f() -> "A", 8, 4, "B"
@@ -0,0 +1,34 @@
contract C {
function f() public returns (uint256) {
uint256[][] memory x = new uint256[][](42);
assert(x[0].length == 0);
x[0] = new uint256[](1);
x[0][0] = 1;
assert(x[4].length == 0);
x[4] = new uint256[](1);
x[4][0] = 2;
assert(x[10].length == 0);
x[10] = new uint256[](1);
x[10][0] = 44;
uint256[][] memory y = new uint256[][](24);
assert(y[0].length == 0);
y[0] = new uint256[](1);
y[0][0] = 1;
assert(y[4].length == 0);
y[4] = new uint256[](1);
y[4][0] = 2;
assert(y[10].length == 0);
y[10] = new uint256[](1);
y[10][0] = 88;
if (
(x[0][0] == y[0][0]) &&
(x[4][0] == y[4][0]) &&
(x[10][0] == 44) &&
(y[10][0] == 88)
) return 7;
return 0;
}
}
// ----
// f() -> 7
@@ -0,0 +1,20 @@
// Test for a bug where we did not increment the counter properly while deleting a dynamic array.
contract C {
struct S {
uint256 x;
uint256[] y;
}
S[] data;
function f() public returns (bool) {
S storage s1 = data.push();
s1.x = 2**200;
S storage s2 = data.push();
s2.x = 2**200;
delete data;
return true;
}
}
// ----
// f() -> true # This code interprets x as an array length and thus will go out of gas. neither of the two should throw due to out-of-bounds access #
@@ -0,0 +1,53 @@
contract c {
struct Data {
uint256 x;
uint256 y;
}
Data[] data;
uint256[] 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;
}
function setLengths(uint256 l1, uint256 l2) public {
while (data.length < l1) data.push();
while (ids.length < l2) ids.push();
}
}
// ----
// getLengths() -> 0, 0
// setLengths(uint256,uint256): 48, 49 ->
// getLengths() -> 48, 49
// setIDStatic(uint256): 11 ->
// getID(uint256): 2 -> 11
// setID(uint256,uint256): 7, 8 ->
// getID(uint256): 7 -> 8
// setData(uint256,uint256,uint256): 7, 8, 9 ->
// setData(uint256,uint256,uint256): 8, 10, 11 ->
// getData(uint256): 7 -> 8, 9
// getData(uint256): 8 -> 10, 11
@@ -0,0 +1,34 @@
contract c {
uint256[] data;
function enlarge(uint256 amount) public returns (uint256) {
while (data.length < amount) data.push();
return data.length;
}
function set(uint256 index, uint256 value) public returns (bool) {
data[index] = value;
return true;
}
function get(uint256 index) public returns (uint256) {
return data[index];
}
function length() public returns (uint256) {
return data.length;
}
}
// ====
// compileViaYul: also
// ----
// length() -> 0
// get(uint256): 3 -> FAILURE
// enlarge(uint256): 4 -> 4
// length() -> 4
// set(uint256,uint256): 3, 4 -> true
// get(uint256): 3 -> 4
// length() -> 4
// set(uint256,uint256): 4, 8 -> FAILURE
// length() -> 4
@@ -0,0 +1,19 @@
contract A {
uint256[3] arr;
bool public test = false;
function getElement(uint256 i) public returns (uint256) {
return arr[i];
}
function testIt() public returns (bool) {
uint256 i = this.getElement(5);
test = true;
return true;
}
}
// ----
// test() -> false
// testIt() -> FAILURE
// test() -> false
@@ -0,0 +1,21 @@
contract A {
function f(uint16 input) public pure returns (uint16[5] memory arr) {
arr[0] = input;
arr[1] = ++input;
arr[2] = ++input;
arr[3] = ++input;
arr[4] = ++input;
}
}
contract B {
function f() public returns (uint16[5] memory res, uint16[5] memory res2) {
A a = new A();
res = a.f(2);
res2 = a.f(1000);
}
}
// ----
// f() -> 2, 3, 4, 5, 6, 1000, 1001, 1002, 1003, 1004
@@ -0,0 +1,14 @@
contract Creator {
uint256 public r;
address public ch;
constructor(address[3] memory s, uint256 x) public {
r = x;
ch = s[2];
}
}
// ----
// constructor(): 1, 2, 3, 4 ->
// r() -> 4
// ch() -> 3
@@ -0,0 +1,10 @@
contract C {
bytes1 a;
function f(bytes32 x) public returns (uint256, uint256, uint256) {
return (x.length, bytes16(uint128(2)).length, a.length + 7);
}
}
// ----
// f(bytes32): "789" -> 32, 16, 8
@@ -0,0 +1,28 @@
contract c {
uint256[4] data;
function set(uint256 index, uint256 value) public returns (bool) {
data[index] = value;
return true;
}
function get(uint256 index) public returns (uint256) {
return data[index];
}
function length() public returns (uint256) {
return data.length;
}
}
// ====
// compileViaYul: also
// ----
// length() -> 4
// set(uint256,uint256): 3, 4 -> true
// set(uint256,uint256): 4, 5 -> FAILURE
// set(uint256,uint256): 400, 5 -> FAILURE
// get(uint256): 3 -> 4
// get(uint256): 4 -> FAILURE
// get(uint256): 400 -> FAILURE
// length() -> 4
@@ -0,0 +1,45 @@
contract D {
function f(function() external returns (function() external returns (uint))[] memory x)
public returns (function() external returns (uint)[3] memory r) {
r[0] = x[0]();
r[1] = x[1]();
r[2] = x[2]();
}
}
contract C {
function test() public returns (uint256, uint256, uint256) {
function() external returns (function() external returns (uint))[] memory x =
new function() external returns (function() external returns (uint))[](10);
for (uint256 i = 0; i < x.length; i++) x[i] = this.h;
x[0] = this.htwo;
function() external returns (uint)[3] memory y = (new D()).f(x);
return (y[0](), y[1](), y[2]());
}
function e() public returns (uint256) {
return 5;
}
function f() public returns (uint256) {
return 6;
}
function g() public returns (uint256) {
return 7;
}
uint256 counter;
function h() public returns (function() external returns (uint)) {
return counter++ == 0 ? this.f : this.g;
}
function htwo() public returns (function() external returns (uint)) {
return this.e;
}
}
// ----
// test() -> 5, 6, 7
@@ -0,0 +1,40 @@
contract C {
function a(uint256 x) public returns (uint256) {
return x + 1;
}
function b(uint256 x) public returns (uint256) {
return x + 2;
}
function c(uint256 x) public returns (uint256) {
return x + 3;
}
function d(uint256 x) public returns (uint256) {
return x + 5;
}
function e(uint256 x) public returns (uint256) {
return x + 8;
}
function test(uint256 x, uint256 i) public returns (uint256) {
function(uint) internal returns (uint)[] memory arr =
new function(uint) internal returns (uint)[](10);
arr[0] = a;
arr[1] = b;
arr[2] = c;
arr[3] = d;
arr[4] = e;
return arr[i](x);
}
}
// ----
// test(uint256,uint256): 10, 0 -> 11
// test(uint256,uint256): 10, 1 -> 12
// test(uint256,uint256): 10, 2 -> 13
// test(uint256,uint256): 10, 3 -> 15
// test(uint256,uint256): 10, 4 -> 18
// test(uint256,uint256): 10, 5 -> FAILURE
@@ -0,0 +1,8 @@
contract C {
function f() public returns (uint256) {
return ([1, 2, 3, 4][2]);
}
}
// ----
// f() -> 3
@@ -0,0 +1,15 @@
contract C {
string public tester;
function f() public returns (string memory) {
return (["abc", "def", "g"][0]);
}
function test() public {
tester = f();
}
}
// ----
// test() ->
// tester() -> 0x20, 0x3, "abc"
@@ -0,0 +1,15 @@
contract C {
uint8[] tester;
function f() public returns (uint8[5] memory) {
return ([1, 2, 3, 4, 5]);
}
function test() public returns (uint8, uint8, uint8, uint8, uint8) {
tester = f();
return (tester[0], tester[1], tester[2], tester[3], tester[4]);
}
}
// ----
// f() -> 1, 2, 3, 4, 5
@@ -0,0 +1,9 @@
// This caused a failure since the type was not converted to its mobile type.
contract C {
function f() public returns (uint256) {
return [4][0];
}
}
// ----
// f() -> 4
@@ -0,0 +1,11 @@
contract C {
function f() public returns (uint256 x, uint256 y) {
x = 3;
y = 6;
uint256[2] memory z = [x, y];
return (z[0], z[1]);
}
}
// ----
// f() -> 3, 6
@@ -0,0 +1,12 @@
contract C {
string s = "doh";
function f() public returns (string memory, string memory) {
string memory t = "ray";
string[3] memory x = [s, t, "mi"];
return (x[1], x[2]);
}
}
// ----
// f() -> 0x40, 0x80, 0x3, "ray", 0x2, "mi"
@@ -0,0 +1,12 @@
contract C {
function f(uint256 i) public returns (string memory) {
string[4] memory x = ["This", "is", "an", "array"];
return (x[i]);
}
}
// ----
// f(uint256): 0 -> 0x20, 0x4, "This"
// f(uint256): 1 -> 0x20, 0x2, "is"
// f(uint256): 2 -> 0x20, 0x2, "an"
// f(uint256): 3 -> 0x20, 0x5, "array"
@@ -0,0 +1,17 @@
// Computes binomial coefficients the chinese way
contract C {
function f(uint256 n, uint256 k) public returns (uint256) {
uint256[][] memory rows = new uint256[][](n + 1);
for (uint256 i = 1; i <= n; i++) {
rows[i] = new uint256[](i);
rows[i][0] = rows[i][rows[i].length - 1] = 1;
for (uint256 j = 1; j < i - 1; j++)
rows[i][j] = rows[i - 1][j - 1] + rows[i - 1][j];
}
return rows[n][k - 1];
}
}
// ----
// f(uint256,uint256): 3, 1 -> 1
// f(uint256,uint256): 9, 5 -> 70
@@ -0,0 +1,60 @@
contract BinarySearch {
/// Finds the position of _value in the sorted list _data.
/// Note that "internal" is important here, because storage references only work for internal or private functions
function find(uint256[] storage _data, uint256 _value)
internal
returns (uint256 o_position)
{
return find(_data, 0, _data.length, _value);
}
function find(
uint256[] storage _data,
uint256 _begin,
uint256 _len,
uint256 _value
) private returns (uint256 o_position) {
if (_len == 0 || (_len == 1 && _data[_begin] != _value))
return uint256(-1); // failure
uint256 halfLen = _len / 2;
uint256 v = _data[_begin + halfLen];
if (_value < v) return find(_data, _begin, halfLen, _value);
else if (_value > v)
return find(_data, _begin + halfLen + 1, halfLen - 1, _value);
else return _begin + halfLen;
}
}
contract Store is BinarySearch {
uint256[] data;
function add(uint256 v) public {
data.push(0);
data[data.length - 1] = v;
}
function find(uint256 v) public returns (uint256) {
return find(data, v);
}
}
// ====
// compileViaYul: also
// ----
// find(uint256): 7 -> -1
// add(uint256): 7 ->
// find(uint256): 7 -> 0
// add(uint256): 11 ->
// add(uint256): 17 ->
// add(uint256): 27 ->
// add(uint256): 31 ->
// add(uint256): 32 ->
// add(uint256): 66 ->
// add(uint256): 177 ->
// find(uint256): 7 -> 0
// find(uint256): 27 -> 3
// find(uint256): 32 -> 5
// find(uint256): 176 -> -1
// find(uint256): 0 -> -1
// find(uint256): 400 -> -1
@@ -0,0 +1,10 @@
contract C {
function f() public returns (bytes32) {
return keccak256("");
}
}
// ====
// compileViaYul: also
// ----
// f() -> 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470
@@ -0,0 +1,13 @@
contract c {
bytes data;
function foo() public returns (bool) {
data.push("f");
data.push("o");
data.push("o");
return keccak256(data) == keccak256("foo");
}
}
// ----
// foo() -> true
@@ -0,0 +1,8 @@
contract C {
function f() public returns (bytes20) {
return ripemd160("");
}
}
// ----
// f() -> 0x9c1185a5c5e9fc54612808977ee8f548b2258d31000000000000000000000000
@@ -0,0 +1,8 @@
contract C {
function f() public returns (bytes32) {
return sha256("");
}
}
// ----
// f() -> 0xe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
@@ -0,0 +1,33 @@
contract C {
function f() public pure returns (address r) {
bytes21 x = 0x1122334455667788990011223344556677889900ff;
bytes20 y;
assembly {
y := x
}
address z = address(y);
assembly {
r := z
}
require(z == 0x1122334455667788990011223344556677889900);
}
function g() public pure returns (address payable r) {
bytes21 x = 0x1122334455667788990011223344556677889900ff;
bytes20 y;
assembly {
y := x
}
address payable z = address(y);
assembly {
r := z
}
require(z == 0x1122334455667788990011223344556677889900);
}
}
// ====
// compileViaYul: also
// ----
// f() -> 0x1122334455667788990011223344556677889900
// g() -> 0x1122334455667788990011223344556677889900
@@ -0,0 +1,15 @@
contract C {
function f() public pure returns (bytes32 r) {
bytes4 x = 0xffffffff;
bytes2 y = bytes2(x);
assembly {
r := y
}
// At this point, r and y both store four bytes, but
// y is properly cleaned before the equality check
require(y == bytes2(0xffff));
}
}
// ----
// f() -> "\xff\xff\xff\xff"
@@ -0,0 +1,13 @@
contract C {
function test() public returns (uint256, uint256) {
uint32 a = 0xffffffff;
uint16 x = uint16(a);
uint16 y = x;
x /= 0x100;
y = y / 0x100;
return (x, y);
}
}
// ----
// test() -> 0xff, 0xff
@@ -0,0 +1,9 @@
contract C {
function f() public pure returns (uint8 x) {
uint8 y = uint8(2)**uint8(8);
return 0**y;
}
}
// ----
// f() -> 0x1
@@ -0,0 +1,8 @@
contract C {
function f() public pure returns (uint8 x) {
return uint8(0)**uint8(uint8(2)**uint8(8));
}
}
// ----
// f() -> 0x1
@@ -0,0 +1,8 @@
contract C {
function f() public pure returns (uint8 x) {
return uint8(0x166)**uint8(uint8(2)**uint8(8));
}
}
// ----
// f() -> 0x1
@@ -0,0 +1,22 @@
contract C {
bytes constant a = "\x03\x01\x02";
bytes constant b = hex"030102";
string constant c = "hello";
function f() public returns (bytes memory) {
return a;
}
function g() public returns (bytes memory) {
return b;
}
function h() public returns (bytes memory) {
return bytes(c);
}
}
// ----
// f() -> 0x20, 3, "\x03\x01\x02"
// g() -> 0x20, 3, "\x03\x01\x02"
// h() -> 0x20, 5, "hello"
@@ -0,0 +1,11 @@
contract Foo {
uint256 constant x = 56;
enum ActionChoices {GoLeft, GoRight, GoStraight, Sit}
ActionChoices constant choices = ActionChoices.GoLeft;
bytes32 constant st = "abc\x00\xff__";
}
// ====
// compileViaYul: also
// ----
// constructor() ->
@@ -0,0 +1,10 @@
contract Foo {
function getX() public returns (uint256 r) {
return x;
}
uint256 constant x = 56;
}
// ----
// getX() -> 56

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