mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Merge remote-tracking branch 'origin/develop' into breaking
This commit is contained in:
@@ -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":
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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"
|
||||
);
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
};
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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
|
||||
+11
@@ -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
|
||||
+12
@@ -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
Reference in New Issue
Block a user