mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Merge pull request #9805 from ethereum/develop
Merge develop into breaking.
This commit is contained in:
+33
-4
@@ -17,6 +17,7 @@
|
||||
// SPDX-License-Identifier: GPL-3.0
|
||||
|
||||
#include <stdexcept>
|
||||
#include <iostream>
|
||||
#include <test/Common.h>
|
||||
|
||||
#include <libsolutil/Assertions.h>
|
||||
@@ -57,9 +58,9 @@ boost::filesystem::path testPath()
|
||||
return {};
|
||||
}
|
||||
|
||||
std::string EVMOneEnvOrDefaultPath()
|
||||
std::string envOrDefaultPath(std::string const& env_name, std::string const& lib_name)
|
||||
{
|
||||
if (auto path = getenv("ETH_EVMONE"))
|
||||
if (auto path = getenv(env_name.c_str()))
|
||||
return path;
|
||||
|
||||
auto const searchPath =
|
||||
@@ -76,7 +77,7 @@ std::string EVMOneEnvOrDefaultPath()
|
||||
};
|
||||
for (auto const& basePath: searchPath)
|
||||
{
|
||||
fs::path p = basePath / evmoneFilename;
|
||||
fs::path p = basePath / lib_name;
|
||||
if (fs::exists(p))
|
||||
return p.string();
|
||||
}
|
||||
@@ -92,7 +93,8 @@ CommonOptions::CommonOptions(std::string _caption):
|
||||
options.add_options()
|
||||
("evm-version", po::value(&evmVersionString), "which evm version to use")
|
||||
("testpath", po::value<fs::path>(&this->testPath)->default_value(solidity::test::testPath()), "path to test files")
|
||||
("evmonepath", po::value<fs::path>(&evmonePath)->default_value(EVMOneEnvOrDefaultPath()), "path to evmone library")
|
||||
("vm", po::value<std::vector<fs::path>>(&vmPaths), "path to evmc library, can be supplied multiple times.")
|
||||
("ewasm", po::bool_switch(&ewasm), "tries to automatically find an ewasm vm and enable ewasm test-execution.")
|
||||
("no-smt", po::bool_switch(&disableSMT), "disable SMT checker")
|
||||
("optimize", po::bool_switch(&optimize), "enables optimization")
|
||||
("enforce-via-yul", po::bool_switch(&enforceViaYul), "Enforce compiling all tests via yul to see if additional tests can be activated.")
|
||||
@@ -141,6 +143,33 @@ bool CommonOptions::parse(int argc, char const* const* argv)
|
||||
throw std::runtime_error(errorMessage.str());
|
||||
}
|
||||
|
||||
if (vmPaths.empty())
|
||||
{
|
||||
std::string evmone = envOrDefaultPath("ETH_EVMONE", evmoneFilename);
|
||||
if (!evmone.empty())
|
||||
vmPaths.emplace_back(evmone);
|
||||
else
|
||||
{
|
||||
std::cout << "Unable to find " << solidity::test::evmoneFilename
|
||||
<< ". Please provide the path using --vm <path>." << std::endl;
|
||||
std::cout << "You can download it at" << std::endl;
|
||||
std::cout << solidity::test::evmoneDownloadLink << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
if (ewasm) {
|
||||
std::string hera = envOrDefaultPath("ETH_HERA", heraFilename);
|
||||
if (!hera.empty())
|
||||
vmPaths.emplace_back(hera);
|
||||
else {
|
||||
std::cout << "Unable to find " << solidity::test::heraFilename
|
||||
<< ". Please provide the path using --vm <path>." << std::endl;
|
||||
std::cout << "You can download it at" << std::endl;
|
||||
std::cout << solidity::test::heraDownloadLink << std::endl;
|
||||
std::cout << "Ewasm tests disabled." << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
+11
-3
@@ -21,6 +21,8 @@
|
||||
#include <libsolutil/Exceptions.h>
|
||||
#include <liblangutil/EVMVersion.h>
|
||||
|
||||
#include <test/evmc/evmc.h>
|
||||
|
||||
#include <boost/filesystem/path.hpp>
|
||||
#include <boost/noncopyable.hpp>
|
||||
#include <boost/program_options.hpp>
|
||||
@@ -31,21 +33,27 @@ namespace solidity::test
|
||||
#ifdef _WIN32
|
||||
static constexpr auto evmoneFilename = "evmone.dll";
|
||||
static constexpr auto evmoneDownloadLink = "https://github.com/ethereum/evmone/releases/download/v0.4.1/evmone-0.4.1-windows-amd64.zip";
|
||||
static constexpr auto heraFilename = "hera.dll";
|
||||
static constexpr auto heraDownloadLink = "https://github.com/ewasm/hera/archive/v0.3.0.tar.gz";
|
||||
#elif defined(__APPLE__)
|
||||
static constexpr auto evmoneFilename = "libevmone.dylib";
|
||||
static constexpr auto evmoneDownloadLink = "https://github.com/ethereum/evmone/releases/download/v0.4.1/evmone-0.4.1-darwin-x86_64.tar.gz";
|
||||
static constexpr auto heraFilename = "libhera.dylib";
|
||||
static constexpr auto heraDownloadLink = "https://github.com/ewasm/hera/releases/download/v0.3.0/hera-0.3.0-darwin-x86_64.tar.gz";
|
||||
#else
|
||||
static constexpr auto evmoneFilename = "libevmone.so";
|
||||
static constexpr auto evmoneDownloadLink = "https://github.com/ethereum/evmone/releases/download/v0.4.1/evmone-0.4.1-linux-x86_64.tar.gz";
|
||||
static constexpr auto heraFilename = "libhera.so";
|
||||
static constexpr auto heraDownloadLink = "https://github.com/ewasm/hera/releases/download/v0.3.0/hera-0.3.0-linux-x86_64.tar.gz";
|
||||
#endif
|
||||
|
||||
|
||||
struct ConfigException : public util::Exception {};
|
||||
|
||||
struct CommonOptions: boost::noncopyable
|
||||
{
|
||||
boost::filesystem::path evmonePath;
|
||||
std::vector<boost::filesystem::path> vmPaths;
|
||||
boost::filesystem::path testPath;
|
||||
bool ewasm = false;
|
||||
bool optimize = false;
|
||||
bool enforceViaYul = false;
|
||||
bool disableSMT = false;
|
||||
@@ -64,8 +72,8 @@ struct CommonOptions: boost::noncopyable
|
||||
|
||||
CommonOptions(std::string caption = "");
|
||||
virtual ~CommonOptions() {};
|
||||
protected:
|
||||
|
||||
protected:
|
||||
boost::program_options::options_description options;
|
||||
|
||||
private:
|
||||
|
||||
+38
-6
@@ -39,17 +39,18 @@ using namespace evmc::literals;
|
||||
|
||||
evmc::VM& EVMHost::getVM(string const& _path)
|
||||
{
|
||||
static evmc::VM theVM;
|
||||
if (!theVM && !_path.empty())
|
||||
static evmc::VM NullVM{nullptr};
|
||||
static map<string, unique_ptr<evmc::VM>> vms;
|
||||
if (vms.count(_path) == 0)
|
||||
{
|
||||
evmc_loader_error_code errorCode = {};
|
||||
auto vm = evmc::VM{evmc_load_and_configure(_path.c_str(), &errorCode)};
|
||||
if (vm && errorCode == EVMC_LOADER_SUCCESS)
|
||||
{
|
||||
if (vm.get_capabilities() & EVMC_CAPABILITY_EVM1)
|
||||
theVM = std::move(vm);
|
||||
if (vm.get_capabilities() & (EVMC_CAPABILITY_EVM1 | EVMC_CAPABILITY_EWASM))
|
||||
vms[_path] = make_unique<evmc::VM>(evmc::VM(move(vm)));
|
||||
else
|
||||
cerr << "VM loaded does not support EVM1" << endl;
|
||||
cerr << "VM loaded neither supports EVM1 nor EWASM" << endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -59,7 +60,38 @@ evmc::VM& EVMHost::getVM(string const& _path)
|
||||
cerr << endl;
|
||||
}
|
||||
}
|
||||
return theVM;
|
||||
|
||||
if (vms.count(_path) > 0)
|
||||
return *vms[_path];
|
||||
|
||||
return NullVM;
|
||||
}
|
||||
|
||||
bool EVMHost::checkVmPaths(vector<boost::filesystem::path> const& _vmPaths)
|
||||
{
|
||||
bool evmVmFound = false;
|
||||
bool ewasmVmFound = false;
|
||||
for (auto const& path: _vmPaths)
|
||||
{
|
||||
evmc::VM& vm = EVMHost::getVM(path.string());
|
||||
if (!vm)
|
||||
return false;
|
||||
|
||||
if (vm.has_capability(EVMC_CAPABILITY_EVM1))
|
||||
{
|
||||
if (evmVmFound)
|
||||
throw runtime_error("Multiple evm1 evmc vms defined. Please only define one evm1 evmc vm.");
|
||||
evmVmFound = true;
|
||||
}
|
||||
|
||||
if (vm.has_capability(EVMC_CAPABILITY_EWASM))
|
||||
{
|
||||
if (ewasmVmFound)
|
||||
throw runtime_error("Multiple ewasm evmc vms where defined. Please only define one ewasm evmc vm.");
|
||||
ewasmVmFound = true;
|
||||
}
|
||||
}
|
||||
return evmVmFound;
|
||||
}
|
||||
|
||||
EVMHost::EVMHost(langutil::EVMVersion _evmVersion, evmc::VM& _vm):
|
||||
|
||||
+17
-4
@@ -30,6 +30,8 @@
|
||||
|
||||
#include <libsolutil/FixedHash.h>
|
||||
|
||||
#include <boost/filesystem.hpp>
|
||||
|
||||
namespace solidity::test
|
||||
{
|
||||
using Address = util::h160;
|
||||
@@ -40,12 +42,17 @@ public:
|
||||
using MockedHost::get_code_size;
|
||||
using MockedHost::get_balance;
|
||||
|
||||
/// Tries to dynamically load libevmone. @returns nullptr on failure.
|
||||
/// The path has to be provided for the first successful run and will be ignored
|
||||
/// afterwards.
|
||||
/// Tries to dynamically load an evmc vm supporting evm1 or ewasm and caches the loaded VM.
|
||||
/// @returns vmc::VM(nullptr) on failure.
|
||||
static evmc::VM& getVM(std::string const& _path = {});
|
||||
|
||||
explicit EVMHost(langutil::EVMVersion _evmVersion, evmc::VM& _vm = getVM());
|
||||
/// Tries to load all defined evmc vm shared libraries.
|
||||
/// @param _vmPaths paths to multiple evmc shared libraries.
|
||||
/// @throw Exception if multiple evm1 or multiple ewasm evmc vms where loaded.
|
||||
/// @returns true, if an evmc vm was supporting evm1 loaded properly.
|
||||
static bool checkVmPaths(std::vector<boost::filesystem::path> const& _vmPaths);
|
||||
|
||||
explicit EVMHost(langutil::EVMVersion _evmVersion, evmc::VM& _vm);
|
||||
|
||||
void reset() { accounts.clear(); m_currentAddress = {}; }
|
||||
void newBlock()
|
||||
@@ -71,6 +78,12 @@ public:
|
||||
static util::h256 convertFromEVMC(evmc::bytes32 const& _data);
|
||||
static evmc::bytes32 convertToEVMC(util::h256 const& _data);
|
||||
|
||||
/// @returns true, if the evmc VM has the given capability.
|
||||
bool hasCapability(evmc_capabilities capability) const noexcept
|
||||
{
|
||||
return m_vm.has_capability(capability);
|
||||
}
|
||||
|
||||
private:
|
||||
evmc::address m_currentAddress = {};
|
||||
|
||||
|
||||
+45
-23
@@ -29,6 +29,8 @@
|
||||
|
||||
#include <libsolutil/CommonIO.h>
|
||||
|
||||
#include <liblangutil/Exceptions.h>
|
||||
|
||||
#include <boost/test/framework.hpp>
|
||||
#include <boost/algorithm/string/replace.hpp>
|
||||
|
||||
@@ -40,27 +42,47 @@ using namespace solidity::util;
|
||||
using namespace solidity::test;
|
||||
|
||||
ExecutionFramework::ExecutionFramework():
|
||||
ExecutionFramework(solidity::test::CommonOptions::get().evmVersion())
|
||||
ExecutionFramework(solidity::test::CommonOptions::get().evmVersion(), solidity::test::CommonOptions::get().vmPaths)
|
||||
{
|
||||
}
|
||||
|
||||
ExecutionFramework::ExecutionFramework(langutil::EVMVersion _evmVersion):
|
||||
ExecutionFramework::ExecutionFramework(langutil::EVMVersion _evmVersion, vector<boost::filesystem::path> const& _vmPaths):
|
||||
m_evmVersion(_evmVersion),
|
||||
m_optimiserSettings(solidity::frontend::OptimiserSettings::minimal()),
|
||||
m_showMessages(solidity::test::CommonOptions::get().showMessages),
|
||||
m_evmHost(make_shared<EVMHost>(m_evmVersion))
|
||||
m_vmPaths(_vmPaths)
|
||||
{
|
||||
if (solidity::test::CommonOptions::get().optimize)
|
||||
m_optimiserSettings = solidity::frontend::OptimiserSettings::standard();
|
||||
|
||||
for (auto const& path: m_vmPaths)
|
||||
if (EVMHost::getVM(path.string()).has_capability(EVMC_CAPABILITY_EWASM))
|
||||
m_supportsEwasm = true;
|
||||
|
||||
selectVM(evmc_capabilities::EVMC_CAPABILITY_EVM1);
|
||||
}
|
||||
|
||||
void ExecutionFramework::selectVM(evmc_capabilities _cap)
|
||||
{
|
||||
m_evmcHost.reset();
|
||||
for (auto const& path: m_vmPaths)
|
||||
{
|
||||
evmc::VM& vm = EVMHost::getVM(path.string());
|
||||
if (vm.has_capability(_cap))
|
||||
{
|
||||
m_evmcHost = make_unique<EVMHost>(m_evmVersion, vm);
|
||||
break;
|
||||
}
|
||||
}
|
||||
solAssert(m_evmcHost != nullptr, "");
|
||||
reset();
|
||||
}
|
||||
|
||||
void ExecutionFramework::reset()
|
||||
{
|
||||
m_evmHost->reset();
|
||||
m_evmcHost->reset();
|
||||
for (size_t i = 0; i < 10; i++)
|
||||
m_evmHost->accounts[EVMHost::convertToEVMC(account(i))].balance =
|
||||
m_evmcHost->accounts[EVMHost::convertToEVMC(account(i))].balance =
|
||||
EVMHost::convertToEVMC(u256(1) << 100);
|
||||
}
|
||||
|
||||
@@ -92,7 +114,7 @@ std::pair<bool, string> ExecutionFramework::compareAndCreateMessage(
|
||||
|
||||
u256 ExecutionFramework::gasLimit() const
|
||||
{
|
||||
return {m_evmHost->tx_context.block_gas_limit};
|
||||
return {m_evmcHost->tx_context.block_gas_limit};
|
||||
}
|
||||
|
||||
u256 ExecutionFramework::gasPrice() const
|
||||
@@ -100,24 +122,24 @@ u256 ExecutionFramework::gasPrice() const
|
||||
// here and below we use "return u256{....}" instead of just "return {....}"
|
||||
// to please MSVC and avoid unexpected
|
||||
// warning C4927 : illegal conversion; more than one user - defined conversion has been implicitly applied
|
||||
return u256{EVMHost::convertFromEVMC(m_evmHost->tx_context.tx_gas_price)};
|
||||
return u256{EVMHost::convertFromEVMC(m_evmcHost->tx_context.tx_gas_price)};
|
||||
}
|
||||
|
||||
u256 ExecutionFramework::blockHash(u256 const& _number) const
|
||||
{
|
||||
return u256{EVMHost::convertFromEVMC(
|
||||
m_evmHost->get_block_hash(static_cast<int64_t>(_number & numeric_limits<uint64_t>::max()))
|
||||
m_evmcHost->get_block_hash(static_cast<int64_t>(_number & numeric_limits<uint64_t>::max()))
|
||||
)};
|
||||
}
|
||||
|
||||
u256 ExecutionFramework::blockNumber() const
|
||||
{
|
||||
return m_evmHost->tx_context.block_number;
|
||||
return m_evmcHost->tx_context.block_number;
|
||||
}
|
||||
|
||||
void ExecutionFramework::sendMessage(bytes const& _data, bool _isCreation, u256 const& _value)
|
||||
{
|
||||
m_evmHost->newBlock();
|
||||
m_evmcHost->newBlock();
|
||||
|
||||
if (m_showMessages)
|
||||
{
|
||||
@@ -147,7 +169,7 @@ void ExecutionFramework::sendMessage(bytes const& _data, bool _isCreation, u256
|
||||
}
|
||||
message.gas = m_gas.convert_to<int64_t>();
|
||||
|
||||
evmc::result result = m_evmHost->call(message);
|
||||
evmc::result result = m_evmcHost->call(message);
|
||||
|
||||
m_output = bytes(result.output_data, result.output_data + result.output_size);
|
||||
if (_isCreation)
|
||||
@@ -166,7 +188,7 @@ void ExecutionFramework::sendMessage(bytes const& _data, bool _isCreation, u256
|
||||
|
||||
void ExecutionFramework::sendEther(Address const& _addr, u256 const& _amount)
|
||||
{
|
||||
m_evmHost->newBlock();
|
||||
m_evmcHost->newBlock();
|
||||
|
||||
if (m_showMessages)
|
||||
{
|
||||
@@ -181,12 +203,12 @@ void ExecutionFramework::sendEther(Address const& _addr, u256 const& _amount)
|
||||
message.destination = EVMHost::convertToEVMC(_addr);
|
||||
message.gas = m_gas.convert_to<int64_t>();
|
||||
|
||||
m_evmHost->call(message);
|
||||
m_evmcHost->call(message);
|
||||
}
|
||||
|
||||
size_t ExecutionFramework::currentTimestamp()
|
||||
{
|
||||
return static_cast<size_t>(m_evmHost->tx_context.block_timestamp);
|
||||
return static_cast<size_t>(m_evmcHost->tx_context.block_timestamp);
|
||||
}
|
||||
|
||||
size_t ExecutionFramework::blockTimestamp(u256 _block)
|
||||
@@ -204,32 +226,32 @@ Address ExecutionFramework::account(size_t _idx)
|
||||
|
||||
bool ExecutionFramework::addressHasCode(Address const& _addr)
|
||||
{
|
||||
return m_evmHost->get_code_size(EVMHost::convertToEVMC(_addr)) != 0;
|
||||
return m_evmcHost->get_code_size(EVMHost::convertToEVMC(_addr)) != 0;
|
||||
}
|
||||
|
||||
size_t ExecutionFramework::numLogs() const
|
||||
{
|
||||
return m_evmHost->recorded_logs.size();
|
||||
return m_evmcHost->recorded_logs.size();
|
||||
}
|
||||
|
||||
size_t ExecutionFramework::numLogTopics(size_t _logIdx) const
|
||||
{
|
||||
return m_evmHost->recorded_logs.at(_logIdx).topics.size();
|
||||
return m_evmcHost->recorded_logs.at(_logIdx).topics.size();
|
||||
}
|
||||
|
||||
h256 ExecutionFramework::logTopic(size_t _logIdx, size_t _topicIdx) const
|
||||
{
|
||||
return EVMHost::convertFromEVMC(m_evmHost->recorded_logs.at(_logIdx).topics.at(_topicIdx));
|
||||
return EVMHost::convertFromEVMC(m_evmcHost->recorded_logs.at(_logIdx).topics.at(_topicIdx));
|
||||
}
|
||||
|
||||
Address ExecutionFramework::logAddress(size_t _logIdx) const
|
||||
{
|
||||
return EVMHost::convertFromEVMC(m_evmHost->recorded_logs.at(_logIdx).creator);
|
||||
return EVMHost::convertFromEVMC(m_evmcHost->recorded_logs.at(_logIdx).creator);
|
||||
}
|
||||
|
||||
bytes ExecutionFramework::logData(size_t _logIdx) const
|
||||
{
|
||||
const auto& data = m_evmHost->recorded_logs.at(_logIdx).data;
|
||||
const auto& data = m_evmcHost->recorded_logs.at(_logIdx).data;
|
||||
// TODO: Return a copy of log data, because this is expected from REQUIRE_LOG_DATA(),
|
||||
// but reference type like string_view would be preferable.
|
||||
return {data.begin(), data.end()};
|
||||
@@ -237,13 +259,13 @@ bytes ExecutionFramework::logData(size_t _logIdx) const
|
||||
|
||||
u256 ExecutionFramework::balanceAt(Address const& _addr)
|
||||
{
|
||||
return u256(EVMHost::convertFromEVMC(m_evmHost->get_balance(EVMHost::convertToEVMC(_addr))));
|
||||
return u256(EVMHost::convertFromEVMC(m_evmcHost->get_balance(EVMHost::convertToEVMC(_addr))));
|
||||
}
|
||||
|
||||
bool ExecutionFramework::storageEmpty(Address const& _addr)
|
||||
{
|
||||
const auto it = m_evmHost->accounts.find(EVMHost::convertToEVMC(_addr));
|
||||
if (it != m_evmHost->accounts.end())
|
||||
const auto it = m_evmcHost->accounts.find(EVMHost::convertToEVMC(_addr));
|
||||
if (it != m_evmcHost->accounts.end())
|
||||
{
|
||||
for (auto const& entry: it->second.storage)
|
||||
if (!(entry.second.value == evmc::bytes32{}))
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <test/Common.h>
|
||||
#include <test/EVMHost.h>
|
||||
|
||||
#include <libsolidity/interface/OptimiserSettings.h>
|
||||
#include <libsolidity/interface/DebugSettings.h>
|
||||
@@ -39,8 +40,6 @@
|
||||
|
||||
namespace solidity::test
|
||||
{
|
||||
class EVMHost;
|
||||
|
||||
using rational = boost::rational<bigint>;
|
||||
/// An Ethereum address: 20 bytes.
|
||||
/// @NOTE This is not endian-specific; it's just a bunch of bytes.
|
||||
@@ -55,7 +54,7 @@ class ExecutionFramework
|
||||
|
||||
public:
|
||||
ExecutionFramework();
|
||||
explicit ExecutionFramework(langutil::EVMVersion _evmVersion);
|
||||
ExecutionFramework(langutil::EVMVersion _evmVersion, std::vector<boost::filesystem::path> const& _vmPaths);
|
||||
virtual ~ExecutionFramework() = default;
|
||||
|
||||
virtual bytes const& compileAndRunWithoutCheck(
|
||||
@@ -255,6 +254,7 @@ private:
|
||||
}
|
||||
|
||||
protected:
|
||||
void selectVM(evmc_capabilities _cap = evmc_capabilities::EVMC_CAPABILITY_EVM1);
|
||||
void reset();
|
||||
|
||||
void sendMessage(bytes const& _data, bool _isCreation, u256 const& _value = 0);
|
||||
@@ -279,7 +279,10 @@ protected:
|
||||
solidity::frontend::RevertStrings m_revertStrings = solidity::frontend::RevertStrings::Default;
|
||||
solidity::frontend::OptimiserSettings m_optimiserSettings = solidity::frontend::OptimiserSettings::minimal();
|
||||
bool m_showMessages = false;
|
||||
std::shared_ptr<EVMHost> m_evmHost;
|
||||
bool m_supportsEwasm = false;
|
||||
std::unique_ptr<EVMHost> m_evmcHost;
|
||||
|
||||
std::vector<boost::filesystem::path> m_vmPaths;
|
||||
|
||||
bool m_transactionSuccessful = true;
|
||||
Address m_sender = account(0);
|
||||
|
||||
@@ -39,6 +39,7 @@ public:
|
||||
{
|
||||
std::string filename;
|
||||
langutil::EVMVersion evmVersion;
|
||||
std::vector<boost::filesystem::path> vmPaths;
|
||||
bool enforceCompileViaYul;
|
||||
};
|
||||
|
||||
|
||||
+12
-8
@@ -39,7 +39,6 @@
|
||||
#include <test/InteractiveTests.h>
|
||||
#include <test/Common.h>
|
||||
#include <test/EVMHost.h>
|
||||
#include <test/Common.h>
|
||||
|
||||
#include <boost/algorithm/string.hpp>
|
||||
#include <boost/algorithm/string/predicate.hpp>
|
||||
@@ -72,7 +71,7 @@ int registerTests(
|
||||
{
|
||||
int numTestsAdded = 0;
|
||||
fs::path fullpath = _basepath / _path;
|
||||
TestCase::Config config{fullpath.string(), solidity::test::CommonOptions::get().evmVersion(), _enforceViaYul};
|
||||
TestCase::Config config{fullpath.string(), solidity::test::CommonOptions::get().evmVersion(), solidity::test::CommonOptions::get().vmPaths, _enforceViaYul};
|
||||
if (fs::is_directory(fullpath))
|
||||
{
|
||||
test_suite* sub_suite = BOOST_TEST_SUITE(_path.filename().string());
|
||||
@@ -156,14 +155,19 @@ test_suite* init_unit_test_suite( int /*argc*/, char* /*argv*/[] )
|
||||
|
||||
initializeOptions();
|
||||
|
||||
bool disableSemantics = !solidity::test::EVMHost::getVM(solidity::test::CommonOptions::get().evmonePath.string());
|
||||
if (disableSemantics)
|
||||
bool disableSemantics = true;
|
||||
try
|
||||
{
|
||||
cout << "Unable to find " << solidity::test::evmoneFilename << ". Please provide the path using -- --evmonepath <path>." << endl;
|
||||
cout << "You can download it at" << endl;
|
||||
cout << solidity::test::evmoneDownloadLink << endl;
|
||||
cout << endl << "--- SKIPPING ALL SEMANTICS TESTS ---" << endl << endl;
|
||||
disableSemantics = !solidity::test::EVMHost::checkVmPaths(solidity::test::CommonOptions::get().vmPaths);
|
||||
}
|
||||
catch (std::runtime_error const& _exception)
|
||||
{
|
||||
cerr << "Error: " << _exception.what() << endl;
|
||||
exit(1);
|
||||
}
|
||||
if (disableSemantics)
|
||||
cout << endl << "--- SKIPPING ALL SEMANTICS TESTS ---" << endl << endl;
|
||||
|
||||
// Include the interactive tests in the automatic tests as well
|
||||
for (auto const& ts: g_interactiveTestsuites)
|
||||
{
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
--optimize --ir-optimized --metadata-hash none
|
||||
@@ -0,0 +1,23 @@
|
||||
// SPDX-License-Identifier: GPL-3.0
|
||||
pragma solidity >=0.0;
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
// The point of this test is to check that the
|
||||
// AST IDs are removed from the optimized IR
|
||||
// so that they do not have a big effect on the
|
||||
// optimizer if it has a bug that makes it
|
||||
// depen on the actual identifiers.
|
||||
|
||||
struct S { uint x; }
|
||||
struct T { uint[2] y; }
|
||||
|
||||
contract C {
|
||||
S[2] values;
|
||||
T t;
|
||||
|
||||
function sumArray(S[] memory _s) public returns (uint, string memory) {
|
||||
values[0].x = _s[0].x;
|
||||
t.y[0] = _s[1].x;
|
||||
return (t.y[0], "longstringlongstringlongstringlongstringlongstringlongstringlongstringlongstringlongstringlongstring");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,129 @@
|
||||
Optimized IR:
|
||||
/*******************************************************
|
||||
* WARNING *
|
||||
* Solidity to Yul compilation is still EXPERIMENTAL *
|
||||
* It can result in LOSS OF FUNDS or worse *
|
||||
* !USE AT YOUR OWN RISK! *
|
||||
*******************************************************/
|
||||
|
||||
object "C_56" {
|
||||
code {
|
||||
{
|
||||
mstore(64, 128)
|
||||
if callvalue() { revert(0, 0) }
|
||||
let _1 := datasize("C_56_deployed")
|
||||
codecopy(0, dataoffset("C_56_deployed"), _1)
|
||||
return(0, _1)
|
||||
}
|
||||
}
|
||||
object "C_56_deployed" {
|
||||
code {
|
||||
{
|
||||
mstore(64, 128)
|
||||
if iszero(lt(calldatasize(), 4))
|
||||
{
|
||||
let _1 := 0
|
||||
if eq(0xf8eddcc6, shr(224, calldataload(_1)))
|
||||
{
|
||||
if callvalue() { revert(_1, _1) }
|
||||
let _2 := 32
|
||||
if slt(add(calldatasize(), not(3)), _2) { revert(_1, _1) }
|
||||
let offset := calldataload(4)
|
||||
let _3 := 0xffffffffffffffff
|
||||
if gt(offset, _3) { revert(_1, _1) }
|
||||
if iszero(slt(add(offset, 35), calldatasize())) { revert(_1, _1) }
|
||||
let length := calldataload(add(4, offset))
|
||||
if gt(length, _3) { revert(_1, _1) }
|
||||
let _4 := mul(length, _2)
|
||||
let dst := allocateMemory(add(_4, _2))
|
||||
let dst_1 := dst
|
||||
mstore(dst, length)
|
||||
dst := add(dst, _2)
|
||||
let src := add(offset, 36)
|
||||
if gt(add(add(offset, _4), 36), calldatasize()) { revert(_1, _1) }
|
||||
let i := _1
|
||||
for { } lt(i, length) { i := add(i, 1) }
|
||||
{
|
||||
mstore(dst, abi_decode_t_struct$_S(src, calldatasize()))
|
||||
dst := add(dst, _2)
|
||||
src := add(src, _2)
|
||||
}
|
||||
let ret, ret_1 := fun_sumArray_55(dst_1)
|
||||
let memPos := allocateMemory(_1)
|
||||
return(memPos, sub(abi_encode_uint256_t_string(memPos, ret, ret_1), memPos))
|
||||
}
|
||||
}
|
||||
revert(0, 0)
|
||||
}
|
||||
function abi_decode_t_struct$_S(headStart, end) -> value
|
||||
{
|
||||
if slt(sub(end, headStart), 0x20) { revert(value, value) }
|
||||
value := allocateMemory(0x20)
|
||||
mstore(value, calldataload(headStart))
|
||||
}
|
||||
function abi_encode_uint256_t_string(headStart, value0, value1) -> tail
|
||||
{
|
||||
mstore(headStart, value0)
|
||||
let _1 := 32
|
||||
mstore(add(headStart, _1), 64)
|
||||
let length := mload(value1)
|
||||
mstore(add(headStart, 64), length)
|
||||
let i := tail
|
||||
for { } lt(i, length) { i := add(i, _1) }
|
||||
{
|
||||
mstore(add(add(headStart, i), 96), mload(add(add(value1, i), _1)))
|
||||
}
|
||||
if gt(i, length)
|
||||
{
|
||||
mstore(add(add(headStart, length), 96), tail)
|
||||
}
|
||||
tail := add(add(headStart, and(add(length, 31), not(31))), 96)
|
||||
}
|
||||
function allocateMemory(size) -> memPtr
|
||||
{
|
||||
memPtr := mload(64)
|
||||
let newFreePtr := add(memPtr, size)
|
||||
if or(gt(newFreePtr, 0xffffffffffffffff), lt(newFreePtr, memPtr)) { revert(0, 0) }
|
||||
mstore(64, newFreePtr)
|
||||
}
|
||||
function convert_t_stringliteral_6490_to_t_string() -> converted
|
||||
{
|
||||
converted := allocateMemory(160)
|
||||
mstore(converted, 100)
|
||||
mstore(add(converted, 32), "longstringlongstringlongstringlo")
|
||||
mstore(add(converted, 64), "ngstringlongstringlongstringlong")
|
||||
mstore(add(converted, 96), "stringlongstringlongstringlongst")
|
||||
mstore(add(converted, 128), "ring")
|
||||
}
|
||||
function extract_from_storage_value_dynamict_uint256(slot_value, offset) -> value
|
||||
{
|
||||
value := shr(mul(offset, 8), slot_value)
|
||||
}
|
||||
function fun_sumArray_55(vloc__s_19_mpos) -> vloc, vloc__24_mpos
|
||||
{
|
||||
let _1 := mload(vloc__s_19_mpos)
|
||||
if iszero(lt(vloc, _1)) { invalid() }
|
||||
let _2 := mload(mload(add(add(vloc__s_19_mpos, mul(vloc, 32)), 32)))
|
||||
let _3, _4 := storage_array_index_access$_t_struct$_S_storage(vloc, vloc)
|
||||
sstore(_3, _2)
|
||||
if iszero(lt(0x01, _1)) { invalid() }
|
||||
let _5 := mload(mload(add(vloc__s_19_mpos, 64)))
|
||||
if iszero(lt(vloc, 0x02)) { invalid() }
|
||||
let slot := add(0x02, vloc)
|
||||
let _6 := sload(slot)
|
||||
let shiftBits := mul(vloc, 8)
|
||||
let mask := shl(shiftBits, not(0))
|
||||
sstore(slot, or(and(_6, not(mask)), and(shl(shiftBits, _5), mask)))
|
||||
let _7, _8 := storage_array_index_access$_t_struct$_S_storage(0x02, vloc)
|
||||
vloc := extract_from_storage_value_dynamict_uint256(sload(_7), _8)
|
||||
vloc__24_mpos := convert_t_stringliteral_6490_to_t_string()
|
||||
}
|
||||
function storage_array_index_access$_t_struct$_S_storage(array, index) -> slot, offset
|
||||
{
|
||||
if iszero(lt(index, 0x02)) { invalid() }
|
||||
slot := add(array, index)
|
||||
offset := offset
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -33,19 +33,22 @@ object "Arraysum_33" {
|
||||
for { }
|
||||
lt(vloc_i, _2)
|
||||
{
|
||||
vloc_i := increment_t_uint256(vloc_i)
|
||||
if gt(vloc_i, not(1)) { revert(_1, _1) }
|
||||
vloc_i := add(vloc_i, 1)
|
||||
}
|
||||
{
|
||||
let _3, _4 := storage_array_index_access_t_array$_t_uint256_$dyn_storage(_1, vloc_i)
|
||||
vloc_sum := checked_add_t_uint256(vloc_sum, extract_from_storage_value_dynamict_uint256(sload(_3), _4))
|
||||
mstore(_1, _1)
|
||||
let _3 := sload(add(keccak256(_1, 0x20), vloc_i))
|
||||
if gt(vloc_sum, not(_3)) { revert(_1, _1) }
|
||||
vloc_sum := add(vloc_sum, _3)
|
||||
}
|
||||
let memPos := allocateMemory(_1)
|
||||
return(memPos, sub(abi_encode_tuple_t_uint256__to_t_uint256__fromStack(memPos, _1), memPos))
|
||||
return(memPos, sub(abi_encode_uint(memPos, _1), memPos))
|
||||
}
|
||||
}
|
||||
revert(0, 0)
|
||||
}
|
||||
function abi_encode_tuple_t_uint256__to_t_uint256__fromStack(headStart, value0) -> tail
|
||||
function abi_encode_uint(headStart, value0) -> tail
|
||||
{
|
||||
tail := add(headStart, 32)
|
||||
mstore(headStart, value0)
|
||||
@@ -57,27 +60,6 @@ object "Arraysum_33" {
|
||||
if or(gt(newFreePtr, 0xffffffffffffffff), lt(newFreePtr, memPtr)) { revert(0, 0) }
|
||||
mstore(64, newFreePtr)
|
||||
}
|
||||
function checked_add_t_uint256(x, y) -> sum
|
||||
{
|
||||
if gt(x, not(y)) { revert(sum, sum) }
|
||||
sum := add(x, y)
|
||||
}
|
||||
function extract_from_storage_value_dynamict_uint256(slot_value, offset) -> value
|
||||
{
|
||||
value := shr(mul(offset, 8), slot_value)
|
||||
}
|
||||
function increment_t_uint256(value) -> ret
|
||||
{
|
||||
if gt(value, not(1)) { revert(ret, ret) }
|
||||
ret := add(value, 1)
|
||||
}
|
||||
function storage_array_index_access_t_array$_t_uint256_$dyn_storage(array, index) -> slot, offset
|
||||
{
|
||||
if iszero(lt(index, sload(array))) { invalid() }
|
||||
mstore(slot, array)
|
||||
slot := add(keccak256(slot, 0x20), index)
|
||||
offset := offset
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,9 +6,6 @@
|
||||
(import \"ethereum\" \"finish\" (func $eth.finish (param i32 i32)))
|
||||
(memory $memory (export \"memory\") 1)
|
||||
(export \"main\" (func $main))
|
||||
(global $global_ (mut i64) (i64.const 0))
|
||||
(global $global__1 (mut i64) (i64.const 0))
|
||||
(global $global__2 (mut i64) (i64.const 0))
|
||||
|
||||
(func $main
|
||||
(local $_1 i64)
|
||||
@@ -18,7 +15,6 @@
|
||||
(local $z1 i64)
|
||||
(local $z2 i64)
|
||||
(local $z3 i64)
|
||||
(local $z4 i64)
|
||||
(local $_3 i64)
|
||||
(block $label_
|
||||
(local.set $_1 (i64.const 0))
|
||||
@@ -32,18 +28,14 @@
|
||||
(i64.store (i32.add (local.get $r) (i32.const 16)) (local.get $_2))
|
||||
(i64.store (i32.add (local.get $r) (i32.const 24)) (call $endian_swap (i64.const 128)))
|
||||
(call $eth.getCallValue (i32.const 0))
|
||||
(block
|
||||
(local.set $z1 (call $mload_internal (i32.const 0)))
|
||||
(local.set $z2 (global.get $global_))
|
||||
(local.set $z3 (global.get $global__1))
|
||||
(local.set $z4 (global.get $global__2))
|
||||
|
||||
)
|
||||
(if (i32.eqz (i64.eqz (i64.or (i64.or (local.get $z1) (local.get $z2)) (i64.or (local.get $z3) (local.get $z4))))) (then
|
||||
(call $eth.revert (call $to_internal_i32ptr (local.get $_1) (local.get $_1) (local.get $_1) (local.get $_1)) (call $u256_to_i32 (local.get $_1) (local.get $_1) (local.get $_1) (local.get $_1)))))
|
||||
(local.set $z1 (call $endian_swap (i64.load (i32.const 0))))
|
||||
(local.set $z2 (call $endian_swap (i64.load (i32.add (i32.const 0) (i32.const 8)))))
|
||||
(local.set $z3 (call $endian_swap (i64.load (i32.add (i32.const 0) (i32.const 16)))))
|
||||
(if (i32.eqz (i64.eqz (i64.or (i64.or (local.get $z1) (local.get $z2)) (i64.or (local.get $z3) (call $endian_swap (i64.load (i32.add (i32.const 0) (i32.const 24)))))))) (then
|
||||
(call $revert (local.get $_1) (local.get $_1) (local.get $_1) (local.get $_1) (local.get $_1) (local.get $_1) (local.get $_1) (local.get $_1))))
|
||||
(local.set $_3 (datasize \"C_2_deployed\"))
|
||||
(call $eth.codeCopy (call $to_internal_i32ptr (local.get $_1) (local.get $_1) (local.get $_1) (local.get $_1)) (call $u256_to_i32 (local.get $_1) (local.get $_1) (local.get $_1) (dataoffset \"C_2_deployed\")) (call $u256_to_i32 (local.get $_1) (local.get $_1) (local.get $_1) (local.get $_3)))
|
||||
(call $eth.finish (call $to_internal_i32ptr (local.get $_1) (local.get $_1) (local.get $_1) (local.get $_1)) (call $u256_to_i32 (local.get $_1) (local.get $_1) (local.get $_1) (local.get $_3)))
|
||||
(call $codecopy (local.get $_1) (local.get $_1) (local.get $_1) (local.get $_1) (local.get $_1) (local.get $_1) (local.get $_1) (dataoffset \"C_2_deployed\") (local.get $_1) (local.get $_1) (local.get $_1) (local.get $_3))
|
||||
(call $return (local.get $_1) (local.get $_1) (local.get $_1) (local.get $_1) (local.get $_1) (local.get $_1) (local.get $_1) (local.get $_3))
|
||||
)
|
||||
)
|
||||
|
||||
@@ -54,7 +46,7 @@
|
||||
(param $x4 i64)
|
||||
(result i32)
|
||||
(local $v i32)
|
||||
(block $label__3
|
||||
(block $label__1
|
||||
(if (i64.ne (i64.const 0) (i64.or (i64.or (local.get $x1) (local.get $x2)) (local.get $x3))) (then
|
||||
(unreachable)))
|
||||
(if (i64.ne (i64.const 0) (i64.shr_u (local.get $x4) (i64.const 32))) (then
|
||||
@@ -73,7 +65,7 @@
|
||||
(result i32)
|
||||
(local $r i32)
|
||||
(local $p i32)
|
||||
(block $label__4
|
||||
(block $label__2
|
||||
(local.set $p (call $u256_to_i32 (local.get $x1) (local.get $x2) (local.get $x3) (local.get $x4)))
|
||||
(local.set $r (i32.add (local.get $p) (i32.const 64)))
|
||||
(if (i32.lt_u (local.get $r) (local.get $p)) (then
|
||||
@@ -83,11 +75,29 @@
|
||||
(local.get $r)
|
||||
)
|
||||
|
||||
(func $codecopy
|
||||
(param $x1 i64)
|
||||
(param $x2 i64)
|
||||
(param $x3 i64)
|
||||
(param $x4 i64)
|
||||
(param $y1 i64)
|
||||
(param $y2 i64)
|
||||
(param $y3 i64)
|
||||
(param $y4 i64)
|
||||
(param $z1 i64)
|
||||
(param $z2 i64)
|
||||
(param $z3 i64)
|
||||
(param $z4 i64)
|
||||
(block $label__3
|
||||
(call $eth.codeCopy (call $to_internal_i32ptr (local.get $x1) (local.get $x2) (local.get $x3) (local.get $x4)) (call $u256_to_i32 (local.get $y1) (local.get $y2) (local.get $y3) (local.get $y4)) (call $u256_to_i32 (local.get $z1) (local.get $z2) (local.get $z3) (local.get $z4)))
|
||||
)
|
||||
)
|
||||
|
||||
(func $endian_swap_16
|
||||
(param $x i64)
|
||||
(result i64)
|
||||
(local $y i64)
|
||||
(block $label__5
|
||||
(block $label__4
|
||||
(local.set $y (i64.or (i64.and (i64.shl (local.get $x) (i64.const 8)) (i64.const 65280)) (i64.and (i64.shr_u (local.get $x) (i64.const 8)) (i64.const 255))))
|
||||
|
||||
)
|
||||
@@ -99,7 +109,7 @@
|
||||
(result i64)
|
||||
(local $y i64)
|
||||
(local $hi i64)
|
||||
(block $label__6
|
||||
(block $label__5
|
||||
(local.set $hi (i64.shl (call $endian_swap_16 (local.get $x)) (i64.const 16)))
|
||||
(local.set $y (i64.or (local.get $hi) (call $endian_swap_16 (i64.shr_u (local.get $x) (i64.const 16)))))
|
||||
|
||||
@@ -112,7 +122,7 @@
|
||||
(result i64)
|
||||
(local $y i64)
|
||||
(local $hi i64)
|
||||
(block $label__7
|
||||
(block $label__6
|
||||
(local.set $hi (i64.shl (call $endian_swap_32 (local.get $x)) (i64.const 32)))
|
||||
(local.set $y (i64.or (local.get $hi) (call $endian_swap_32 (i64.shr_u (local.get $x) (i64.const 32)))))
|
||||
|
||||
@@ -120,24 +130,32 @@
|
||||
(local.get $y)
|
||||
)
|
||||
|
||||
(func $mload_internal
|
||||
(param $pos i32)
|
||||
(result i64)
|
||||
(local $z1 i64)
|
||||
(local $z2 i64)
|
||||
(local $z3 i64)
|
||||
(local $z4 i64)
|
||||
(func $return
|
||||
(param $x1 i64)
|
||||
(param $x2 i64)
|
||||
(param $x3 i64)
|
||||
(param $x4 i64)
|
||||
(param $y1 i64)
|
||||
(param $y2 i64)
|
||||
(param $y3 i64)
|
||||
(param $y4 i64)
|
||||
(block $label__7
|
||||
(call $eth.finish (call $to_internal_i32ptr (local.get $x1) (local.get $x2) (local.get $x3) (local.get $x4)) (call $u256_to_i32 (local.get $y1) (local.get $y2) (local.get $y3) (local.get $y4)))
|
||||
)
|
||||
)
|
||||
|
||||
(func $revert
|
||||
(param $x1 i64)
|
||||
(param $x2 i64)
|
||||
(param $x3 i64)
|
||||
(param $x4 i64)
|
||||
(param $y1 i64)
|
||||
(param $y2 i64)
|
||||
(param $y3 i64)
|
||||
(param $y4 i64)
|
||||
(block $label__8
|
||||
(local.set $z1 (call $endian_swap (i64.load (local.get $pos))))
|
||||
(local.set $z2 (call $endian_swap (i64.load (i32.add (local.get $pos) (i32.const 8)))))
|
||||
(local.set $z3 (call $endian_swap (i64.load (i32.add (local.get $pos) (i32.const 16)))))
|
||||
(local.set $z4 (call $endian_swap (i64.load (i32.add (local.get $pos) (i32.const 24)))))
|
||||
|
||||
(call $eth.revert (call $to_internal_i32ptr (local.get $x1) (local.get $x2) (local.get $x3) (local.get $x4)) (call $u256_to_i32 (local.get $y1) (local.get $y2) (local.get $y3) (local.get $y4)))
|
||||
)
|
||||
(global.set $global_ (local.get $z2))
|
||||
(global.set $global__1 (local.get $z3))
|
||||
(global.set $global__2 (local.get $z4))
|
||||
(local.get $z1)
|
||||
)
|
||||
|
||||
)
|
||||
|
||||
@@ -4,12 +4,6 @@
|
||||
Pretty printed source:
|
||||
object "object" {
|
||||
code {
|
||||
{
|
||||
let a3, b3, c3, d3, e3, f3, g3, h3, i3, j3, k3, l3, m3, o3, p3 := fun()
|
||||
let a3_1, b3_1, c3_1, d3_1, e3_1, f3_1, g3_1, h3_1, i3_1, j3_1, k3_1, l3_1, m3_1, o3_1, p3_1 := fun()
|
||||
sstore(a3, a3_1)
|
||||
}
|
||||
function fun() -> a3, b3, c3, d3, e3, f3, g3, h3, i3, j3, k3, l3, m3, o3, p3
|
||||
{
|
||||
let _1 := 1
|
||||
sstore(_1, _1)
|
||||
@@ -25,93 +19,29 @@ object "object" {
|
||||
sstore(11, _1)
|
||||
sstore(12, _1)
|
||||
sstore(13, _1)
|
||||
a3 := _1
|
||||
b3 := _1
|
||||
c3 := _1
|
||||
d3 := _1
|
||||
e3 := _1
|
||||
f3 := _1
|
||||
g3 := _1
|
||||
h3 := _1
|
||||
i3 := _1
|
||||
j3 := _1
|
||||
k3 := _1
|
||||
l3 := _1
|
||||
m3 := _1
|
||||
o3 := _1
|
||||
p3 := _1
|
||||
sstore(_1, _1)
|
||||
sstore(2, _1)
|
||||
sstore(3, _1)
|
||||
sstore(4, _1)
|
||||
sstore(5, _1)
|
||||
sstore(6, _1)
|
||||
sstore(7, _1)
|
||||
sstore(8, _1)
|
||||
sstore(9, _1)
|
||||
sstore(10, _1)
|
||||
sstore(11, _1)
|
||||
sstore(12, _1)
|
||||
sstore(13, _1)
|
||||
sstore(_1, _1)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Binary representation:
|
||||
60056030565b505050505050505050505050505060196030565b5050505050505050505050505050808255505060c3565b6000600060006000600060006000600060006000600060006000600060006001808155806002558060035580600455806005558060065580600755806008558060095580600a5580600b5580600c5580600d55809f50809e50809d50809c50809b50809a50809950809850809750809650809550809450809350809250809150505b909192939495969798999a9b9c9d9e565b
|
||||
6001808155806002558060035580600455806005558060065580600755806008558060095580600a5580600b5580600c5580600d55808155806002558060035580600455806005558060065580600755806008558060095580600a5580600b5580600c5580600d5580815550
|
||||
|
||||
Text representation:
|
||||
/* "yul_stack_opt/input.sol":3:573 */
|
||||
tag_1
|
||||
tag_2
|
||||
jump // in
|
||||
tag_1:
|
||||
pop
|
||||
pop
|
||||
pop
|
||||
pop
|
||||
pop
|
||||
pop
|
||||
pop
|
||||
pop
|
||||
pop
|
||||
pop
|
||||
pop
|
||||
pop
|
||||
pop
|
||||
pop
|
||||
tag_3
|
||||
tag_2
|
||||
jump // in
|
||||
tag_3:
|
||||
pop
|
||||
pop
|
||||
pop
|
||||
pop
|
||||
pop
|
||||
pop
|
||||
pop
|
||||
pop
|
||||
pop
|
||||
pop
|
||||
pop
|
||||
pop
|
||||
pop
|
||||
pop
|
||||
/* "yul_stack_opt/input.sol":740:742 */
|
||||
dup1
|
||||
/* "yul_stack_opt/input.sol":736:738 */
|
||||
dup3
|
||||
/* "yul_stack_opt/input.sol":729:743 */
|
||||
sstore
|
||||
pop
|
||||
pop
|
||||
/* "yul_stack_opt/input.sol":3:573 */
|
||||
jump(tag_4)
|
||||
tag_2:
|
||||
0x00
|
||||
0x00
|
||||
0x00
|
||||
0x00
|
||||
0x00
|
||||
0x00
|
||||
0x00
|
||||
0x00
|
||||
0x00
|
||||
0x00
|
||||
0x00
|
||||
0x00
|
||||
0x00
|
||||
0x00
|
||||
0x00
|
||||
/* "yul_stack_opt/input.sol":98:99 */
|
||||
0x01
|
||||
dup1
|
||||
@@ -192,96 +122,84 @@ tag_2:
|
||||
sstore
|
||||
/* "yul_stack_opt/input.sol":98:99 */
|
||||
dup1
|
||||
/* "yul_stack_opt/input.sol":423:430 */
|
||||
swap16
|
||||
pop
|
||||
dup2
|
||||
/* "yul_stack_opt/input.sol":129:141 */
|
||||
sstore
|
||||
/* "yul_stack_opt/input.sol":98:99 */
|
||||
dup1
|
||||
/* "yul_stack_opt/input.sol":433:440 */
|
||||
swap15
|
||||
pop
|
||||
/* "yul_stack_opt/input.sol":151:160 */
|
||||
0x02
|
||||
/* "yul_stack_opt/input.sol":144:164 */
|
||||
sstore
|
||||
/* "yul_stack_opt/input.sol":98:99 */
|
||||
dup1
|
||||
/* "yul_stack_opt/input.sol":443:450 */
|
||||
swap14
|
||||
pop
|
||||
/* "yul_stack_opt/input.sol":174:183 */
|
||||
0x03
|
||||
/* "yul_stack_opt/input.sol":167:187 */
|
||||
sstore
|
||||
/* "yul_stack_opt/input.sol":98:99 */
|
||||
dup1
|
||||
/* "yul_stack_opt/input.sol":453:460 */
|
||||
swap13
|
||||
pop
|
||||
/* "yul_stack_opt/input.sol":197:206 */
|
||||
0x04
|
||||
/* "yul_stack_opt/input.sol":190:210 */
|
||||
sstore
|
||||
/* "yul_stack_opt/input.sol":98:99 */
|
||||
dup1
|
||||
/* "yul_stack_opt/input.sol":463:470 */
|
||||
swap12
|
||||
pop
|
||||
/* "yul_stack_opt/input.sol":220:229 */
|
||||
0x05
|
||||
/* "yul_stack_opt/input.sol":213:233 */
|
||||
sstore
|
||||
/* "yul_stack_opt/input.sol":98:99 */
|
||||
dup1
|
||||
/* "yul_stack_opt/input.sol":473:480 */
|
||||
swap11
|
||||
pop
|
||||
/* "yul_stack_opt/input.sol":243:252 */
|
||||
0x06
|
||||
/* "yul_stack_opt/input.sol":236:256 */
|
||||
sstore
|
||||
/* "yul_stack_opt/input.sol":98:99 */
|
||||
dup1
|
||||
/* "yul_stack_opt/input.sol":483:490 */
|
||||
swap10
|
||||
pop
|
||||
/* "yul_stack_opt/input.sol":266:275 */
|
||||
0x07
|
||||
/* "yul_stack_opt/input.sol":259:279 */
|
||||
sstore
|
||||
/* "yul_stack_opt/input.sol":98:99 */
|
||||
dup1
|
||||
/* "yul_stack_opt/input.sol":493:500 */
|
||||
swap9
|
||||
pop
|
||||
/* "yul_stack_opt/input.sol":289:298 */
|
||||
0x08
|
||||
/* "yul_stack_opt/input.sol":282:302 */
|
||||
sstore
|
||||
/* "yul_stack_opt/input.sol":98:99 */
|
||||
dup1
|
||||
/* "yul_stack_opt/input.sol":503:510 */
|
||||
swap8
|
||||
pop
|
||||
/* "yul_stack_opt/input.sol":312:321 */
|
||||
0x09
|
||||
/* "yul_stack_opt/input.sol":305:325 */
|
||||
sstore
|
||||
/* "yul_stack_opt/input.sol":98:99 */
|
||||
dup1
|
||||
/* "yul_stack_opt/input.sol":513:520 */
|
||||
swap7
|
||||
pop
|
||||
/* "yul_stack_opt/input.sol":335:344 */
|
||||
0x0a
|
||||
/* "yul_stack_opt/input.sol":328:348 */
|
||||
sstore
|
||||
/* "yul_stack_opt/input.sol":98:99 */
|
||||
dup1
|
||||
/* "yul_stack_opt/input.sol":523:530 */
|
||||
swap6
|
||||
pop
|
||||
/* "yul_stack_opt/input.sol":358:368 */
|
||||
0x0b
|
||||
/* "yul_stack_opt/input.sol":351:372 */
|
||||
sstore
|
||||
/* "yul_stack_opt/input.sol":98:99 */
|
||||
dup1
|
||||
/* "yul_stack_opt/input.sol":533:540 */
|
||||
swap5
|
||||
pop
|
||||
/* "yul_stack_opt/input.sol":382:392 */
|
||||
0x0c
|
||||
/* "yul_stack_opt/input.sol":375:396 */
|
||||
sstore
|
||||
/* "yul_stack_opt/input.sol":98:99 */
|
||||
dup1
|
||||
/* "yul_stack_opt/input.sol":543:550 */
|
||||
swap4
|
||||
pop
|
||||
/* "yul_stack_opt/input.sol":406:416 */
|
||||
0x0d
|
||||
/* "yul_stack_opt/input.sol":399:420 */
|
||||
sstore
|
||||
/* "yul_stack_opt/input.sol":98:99 */
|
||||
dup1
|
||||
/* "yul_stack_opt/input.sol":553:560 */
|
||||
swap3
|
||||
dup2
|
||||
/* "yul_stack_opt/input.sol":729:743 */
|
||||
sstore
|
||||
pop
|
||||
/* "yul_stack_opt/input.sol":98:99 */
|
||||
dup1
|
||||
/* "yul_stack_opt/input.sol":563:570 */
|
||||
swap2
|
||||
pop
|
||||
pop
|
||||
/* "yul_stack_opt/input.sol":85:573 */
|
||||
tag_5:
|
||||
swap1
|
||||
swap2
|
||||
swap3
|
||||
swap4
|
||||
swap5
|
||||
swap6
|
||||
swap7
|
||||
swap8
|
||||
swap9
|
||||
swap10
|
||||
swap11
|
||||
swap12
|
||||
swap13
|
||||
swap14
|
||||
swap15
|
||||
jump // out
|
||||
tag_4:
|
||||
|
||||
@@ -417,7 +417,7 @@ BOOST_AUTO_TEST_CASE(auction_simple)
|
||||
BOOST_CHECK_EQUAL(registrar.owner(name), 0);
|
||||
// "wait" until auction end
|
||||
|
||||
m_evmHost->tx_context.block_timestamp += m_biddingTime + 10;
|
||||
m_evmcHost->tx_context.block_timestamp += m_biddingTime + 10;
|
||||
// trigger auction again
|
||||
registrar.reserve(name);
|
||||
BOOST_CHECK_EQUAL(registrar.owner(name), m_sender);
|
||||
@@ -429,7 +429,7 @@ BOOST_AUTO_TEST_CASE(auction_bidding)
|
||||
string name = "x";
|
||||
|
||||
unsigned startTime = 0x776347e2;
|
||||
m_evmHost->tx_context.block_timestamp = startTime;
|
||||
m_evmcHost->tx_context.block_timestamp = startTime;
|
||||
|
||||
RegistrarInterface registrar(*this);
|
||||
// initiate auction
|
||||
@@ -437,19 +437,19 @@ BOOST_AUTO_TEST_CASE(auction_bidding)
|
||||
registrar.reserve(name);
|
||||
BOOST_CHECK_EQUAL(registrar.owner(name), 0);
|
||||
// overbid self
|
||||
m_evmHost->tx_context.block_timestamp = startTime + m_biddingTime - 10;
|
||||
m_evmcHost->tx_context.block_timestamp = startTime + m_biddingTime - 10;
|
||||
registrar.setNextValue(12);
|
||||
registrar.reserve(name);
|
||||
// another bid by someone else
|
||||
sendEther(account(1), 10 * ether);
|
||||
m_sender = account(1);
|
||||
m_evmHost->tx_context.block_timestamp = startTime + 2 * m_biddingTime - 50;
|
||||
m_evmcHost->tx_context.block_timestamp = startTime + 2 * m_biddingTime - 50;
|
||||
registrar.setNextValue(13);
|
||||
registrar.reserve(name);
|
||||
BOOST_CHECK_EQUAL(registrar.owner(name), 0);
|
||||
// end auction by first bidder (which is not highest) trying to overbid again (too late)
|
||||
m_sender = account(0);
|
||||
m_evmHost->tx_context.block_timestamp = startTime + 4 * m_biddingTime;
|
||||
m_evmcHost->tx_context.block_timestamp = startTime + 4 * m_biddingTime;
|
||||
registrar.setNextValue(20);
|
||||
registrar.reserve(name);
|
||||
BOOST_CHECK_EQUAL(registrar.owner(name), account(1));
|
||||
|
||||
@@ -48,6 +48,7 @@ function solcjs_test
|
||||
|
||||
printLog "Copying SMTChecker tests..."
|
||||
cp -Rf "$TEST_DIR"/test/libsolidity/smtCheckerTests test/
|
||||
rm -rf test/smtCheckerTests/imports
|
||||
|
||||
# Update version (needed for some tests)
|
||||
echo "Updating package.json to version $VERSION"
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
#include <libsolidity/parsing/Parser.h>
|
||||
#include <libsolidity/analysis/DeclarationTypeChecker.h>
|
||||
#include <libsolidity/analysis/NameAndTypeResolver.h>
|
||||
#include <libsolidity/analysis/Scoper.h>
|
||||
#include <libsolidity/codegen/Compiler.h>
|
||||
#include <libsolidity/ast/AST.h>
|
||||
#include <libsolidity/analysis/TypeChecker.h>
|
||||
@@ -59,6 +60,7 @@ evmasm::AssemblyItems compileContract(std::shared_ptr<CharStream> _sourceCode)
|
||||
BOOST_REQUIRE_NO_THROW(sourceUnit = parser.parse(make_shared<Scanner>(_sourceCode)));
|
||||
BOOST_CHECK(!!sourceUnit);
|
||||
|
||||
Scoper::assignScopes(*sourceUnit);
|
||||
GlobalContext globalContext;
|
||||
NameAndTypeResolver resolver(globalContext, solidity::test::CommonOptions::get().evmVersion(), errorReporter);
|
||||
DeclarationTypeChecker declarationTypeChecker(errorReporter, solidity::test::CommonOptions::get().evmVersion());
|
||||
|
||||
+164
-125
@@ -39,8 +39,8 @@ using namespace boost::unit_test;
|
||||
namespace fs = boost::filesystem;
|
||||
|
||||
|
||||
SemanticTest::SemanticTest(string const& _filename, langutil::EVMVersion _evmVersion, bool enforceViaYul):
|
||||
SolidityExecutionFramework(_evmVersion),
|
||||
SemanticTest::SemanticTest(string const& _filename, langutil::EVMVersion _evmVersion, vector<boost::filesystem::path> const& _vmPaths, bool enforceViaYul):
|
||||
SolidityExecutionFramework(_evmVersion, _vmPaths),
|
||||
EVMVersionRestrictedTestCase(_filename),
|
||||
m_sources(m_reader.sources()),
|
||||
m_lineOffset(m_reader.lineNumber()),
|
||||
@@ -72,6 +72,21 @@ SemanticTest::SemanticTest(string const& _filename, langutil::EVMVersion _evmVer
|
||||
else
|
||||
BOOST_THROW_EXCEPTION(runtime_error("Invalid compileViaYul value: " + choice + "."));
|
||||
|
||||
string compileToEwasm = m_reader.stringSetting("compileToEwasm", "false");
|
||||
if (compileToEwasm == "also")
|
||||
m_runWithEwasm = true;
|
||||
else if (compileToEwasm == "false")
|
||||
m_runWithEwasm = false;
|
||||
else
|
||||
BOOST_THROW_EXCEPTION(runtime_error("Invalid compileToEwasm value: " + compileToEwasm + "."));
|
||||
|
||||
if (m_runWithEwasm && !m_runWithYul)
|
||||
BOOST_THROW_EXCEPTION(runtime_error("Invalid compileToEwasm value: " + compileToEwasm + ", compileViaYul need to be enabled."));
|
||||
|
||||
// run ewasm tests only, if an ewasm evmc vm was defined
|
||||
if (m_runWithEwasm && !m_supportsEwasm)
|
||||
m_runWithEwasm = false;
|
||||
|
||||
m_runWithABIEncoderV1Only = m_reader.boolSetting("ABIEncoderV1Only", false);
|
||||
if (m_runWithABIEncoderV1Only && solidity::test::CommonOptions::get().useABIEncoderV2)
|
||||
m_shouldRun = false;
|
||||
@@ -88,156 +103,180 @@ SemanticTest::SemanticTest(string const& _filename, langutil::EVMVersion _evmVer
|
||||
|
||||
TestCase::TestResult SemanticTest::run(ostream& _stream, string const& _linePrefix, bool _formatted)
|
||||
{
|
||||
TestResult result = TestResult::Success;
|
||||
bool compileViaYul = m_runWithYul || m_enforceViaYul;
|
||||
|
||||
for (bool compileViaYul: set<bool>{!m_runWithoutYul, m_runWithYul || m_enforceViaYul})
|
||||
if (m_runWithoutYul)
|
||||
result = runTest(_stream, _linePrefix, _formatted, false, false);
|
||||
|
||||
if (compileViaYul && result == TestResult::Success)
|
||||
result = runTest(_stream, _linePrefix, _formatted, true, false);
|
||||
|
||||
if (m_runWithEwasm && result == TestResult::Success)
|
||||
result = runTest(_stream, _linePrefix, _formatted, true, true);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
TestCase::TestResult SemanticTest::runTest(ostream& _stream, string const& _linePrefix, bool _formatted, bool _compileViaYul, bool _compileToEwasm)
|
||||
{
|
||||
try
|
||||
{
|
||||
try
|
||||
bool success = true;
|
||||
|
||||
if (_compileViaYul && _compileToEwasm)
|
||||
selectVM(evmc_capabilities::EVMC_CAPABILITY_EWASM);
|
||||
else
|
||||
selectVM(evmc_capabilities::EVMC_CAPABILITY_EVM1);
|
||||
|
||||
reset();
|
||||
|
||||
m_compileViaYul = _compileViaYul;
|
||||
if (_compileToEwasm)
|
||||
{
|
||||
reset();
|
||||
bool success = true;
|
||||
soltestAssert(m_compileViaYul, "");
|
||||
m_compileToEwasm = _compileToEwasm;
|
||||
}
|
||||
|
||||
m_compileViaYul = compileViaYul;
|
||||
m_compileViaYulCanBeSet = false;
|
||||
m_compileViaYulCanBeSet = false;
|
||||
|
||||
if (compileViaYul)
|
||||
AnsiColorized(_stream, _formatted, {BOLD, CYAN}) << _linePrefix << "Running via Yul:" << endl;
|
||||
if (_compileViaYul)
|
||||
AnsiColorized(_stream, _formatted, {BOLD, CYAN}) << _linePrefix << "Running via Yul:" << endl;
|
||||
|
||||
for (auto& test: m_tests)
|
||||
test.reset();
|
||||
for (auto& test: m_tests)
|
||||
test.reset();
|
||||
|
||||
map<string, solidity::test::Address> libraries;
|
||||
map<string, solidity::test::Address> libraries;
|
||||
|
||||
bool constructed = false;
|
||||
bool constructed = false;
|
||||
|
||||
for (auto& test: m_tests)
|
||||
for (auto& test: m_tests)
|
||||
{
|
||||
if (constructed)
|
||||
{
|
||||
if (constructed)
|
||||
{
|
||||
soltestAssert(!test.call().isLibrary, "Libraries have to be deployed before any other call.");
|
||||
soltestAssert(!test.call().isConstructor, "Constructor has to be the first function call expect for library deployments.");
|
||||
}
|
||||
else if (test.call().isLibrary)
|
||||
soltestAssert(!test.call().isLibrary, "Libraries have to be deployed before any other call.");
|
||||
soltestAssert(
|
||||
!test.call().isConstructor,
|
||||
"Constructor has to be the first function call expect for library deployments.");
|
||||
}
|
||||
else if (test.call().isLibrary)
|
||||
{
|
||||
soltestAssert(
|
||||
deploy(test.call().signature, 0, {}, libraries) && m_transactionSuccessful,
|
||||
"Failed to deploy library " + test.call().signature);
|
||||
libraries[test.call().signature] = m_contractAddress;
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (test.call().isConstructor)
|
||||
deploy("", test.call().value.value, test.call().arguments.rawBytes(), libraries);
|
||||
else
|
||||
soltestAssert(deploy("", 0, bytes(), libraries), "Failed to deploy contract.");
|
||||
constructed = true;
|
||||
}
|
||||
|
||||
if (test.call().isConstructor)
|
||||
{
|
||||
if (m_transactionSuccessful == test.call().expectations.failure)
|
||||
success = false;
|
||||
|
||||
test.setFailure(!m_transactionSuccessful);
|
||||
test.setRawBytes(bytes());
|
||||
}
|
||||
else
|
||||
{
|
||||
bytes output;
|
||||
if (test.call().useCallWithoutSignature)
|
||||
output = callLowLevel(test.call().arguments.rawBytes(), test.call().value.value);
|
||||
else
|
||||
{
|
||||
soltestAssert(
|
||||
deploy(test.call().signature, 0, {}, libraries) && m_transactionSuccessful,
|
||||
"Failed to deploy library " + 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");
|
||||
|
||||
output = callContractFunctionWithValueNoEncoding(
|
||||
test.call().signature, test.call().value.value, test.call().arguments.rawBytes()
|
||||
);
|
||||
libraries[test.call().signature] = m_contractAddress;
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (test.call().isConstructor)
|
||||
deploy("", test.call().value.value, test.call().arguments.rawBytes(), libraries);
|
||||
else
|
||||
soltestAssert(deploy("", 0, bytes(), libraries), "Failed to deploy contract.");
|
||||
constructed = true;
|
||||
}
|
||||
|
||||
if (test.call().isConstructor)
|
||||
{
|
||||
if (m_transactionSuccessful == test.call().expectations.failure)
|
||||
success = false;
|
||||
if ((m_transactionSuccessful == test.call().expectations.failure)
|
||||
|| (output != test.call().expectations.rawBytes()))
|
||||
success = false;
|
||||
|
||||
test.setFailure(!m_transactionSuccessful);
|
||||
test.setRawBytes(bytes());
|
||||
}
|
||||
else
|
||||
{
|
||||
bytes output;
|
||||
if (test.call().useCallWithoutSignature)
|
||||
output = callLowLevel(test.call().arguments.rawBytes(), test.call().value.value);
|
||||
else
|
||||
{
|
||||
soltestAssert(
|
||||
m_allowNonExistingFunctions || m_compiler.methodIdentifiers(m_compiler.lastContractName()).isMember(test.call().signature),
|
||||
"The function " + test.call().signature + " is not known to the compiler"
|
||||
);
|
||||
|
||||
output = callContractFunctionWithValueNoEncoding(
|
||||
test.call().signature,
|
||||
test.call().value.value,
|
||||
test.call().arguments.rawBytes()
|
||||
);
|
||||
}
|
||||
|
||||
if ((m_transactionSuccessful == test.call().expectations.failure) || (output != test.call().expectations.rawBytes()))
|
||||
success = false;
|
||||
|
||||
test.setFailure(!m_transactionSuccessful);
|
||||
test.setRawBytes(std::move(output));
|
||||
test.setContractABI(m_compiler.contractABI(m_compiler.lastContractName()));
|
||||
}
|
||||
test.setFailure(!m_transactionSuccessful);
|
||||
test.setRawBytes(std::move(output));
|
||||
test.setContractABI(m_compiler.contractABI(m_compiler.lastContractName()));
|
||||
}
|
||||
}
|
||||
|
||||
if (success && !m_runWithYul && compileViaYul)
|
||||
if (success && !m_runWithYul && _compileViaYul)
|
||||
{
|
||||
m_compileViaYulCanBeSet = true;
|
||||
AnsiColorized(_stream, _formatted, {BOLD, YELLOW}) <<
|
||||
_linePrefix << endl <<
|
||||
_linePrefix << "Test can pass via Yul and marked with compileViaYul: false." << endl;
|
||||
return TestResult::Failure;
|
||||
}
|
||||
|
||||
if (!success && (m_runWithYul || !_compileViaYul))
|
||||
{
|
||||
AnsiColorized(_stream, _formatted, {BOLD, CYAN}) << _linePrefix << "Expected result:" << endl;
|
||||
for (auto const& test: m_tests)
|
||||
{
|
||||
m_compileViaYulCanBeSet = true;
|
||||
AnsiColorized(_stream, _formatted, {BOLD, YELLOW}) << _linePrefix << endl << _linePrefix
|
||||
<< "Test can pass via Yul and marked with compileViaYul: false." << endl;
|
||||
return TestResult::Failure;
|
||||
ErrorReporter errorReporter;
|
||||
_stream << test.format(errorReporter, _linePrefix, false, _formatted) << endl;
|
||||
_stream << errorReporter.format(_linePrefix, _formatted);
|
||||
}
|
||||
|
||||
if (!success && (m_runWithYul || !compileViaYul))
|
||||
_stream << endl;
|
||||
AnsiColorized(_stream, _formatted, {BOLD, CYAN}) << _linePrefix << "Obtained result:" << endl;
|
||||
for (auto const& test: m_tests)
|
||||
{
|
||||
AnsiColorized(_stream, _formatted, {BOLD, CYAN}) << _linePrefix << "Expected result:" << endl;
|
||||
for (auto const& test: m_tests)
|
||||
{
|
||||
ErrorReporter errorReporter;
|
||||
_stream << test.format(errorReporter, _linePrefix, false, _formatted) << endl;
|
||||
_stream << errorReporter.format(_linePrefix, _formatted);
|
||||
}
|
||||
ErrorReporter errorReporter;
|
||||
_stream << test.format(errorReporter, _linePrefix, true, _formatted) << endl;
|
||||
_stream << errorReporter.format(_linePrefix, _formatted);
|
||||
}
|
||||
AnsiColorized(_stream, _formatted, {BOLD, RED})
|
||||
<< _linePrefix << endl
|
||||
<< _linePrefix << "Attention: Updates on the test will apply the detected format displayed." << endl;
|
||||
if (_compileViaYul && m_runWithoutYul)
|
||||
{
|
||||
_stream << _linePrefix << endl << _linePrefix;
|
||||
AnsiColorized(_stream, _formatted, {RED_BACKGROUND}) << "Note that the test passed without Yul.";
|
||||
_stream << endl;
|
||||
AnsiColorized(_stream, _formatted, {BOLD, CYAN}) << _linePrefix << "Obtained result:" << endl;
|
||||
for (auto const& test: m_tests)
|
||||
{
|
||||
ErrorReporter errorReporter;
|
||||
_stream << test.format(errorReporter, _linePrefix, true, _formatted) << endl;
|
||||
_stream << errorReporter.format(_linePrefix, _formatted);
|
||||
}
|
||||
AnsiColorized(_stream, _formatted, {BOLD, RED}) << _linePrefix << endl << _linePrefix
|
||||
<< "Attention: Updates on the test will apply the detected format displayed." << endl;
|
||||
if (compileViaYul && m_runWithoutYul)
|
||||
{
|
||||
_stream << _linePrefix << endl << _linePrefix;
|
||||
AnsiColorized(_stream, _formatted, {RED_BACKGROUND})
|
||||
<< "Note that the test passed without Yul.";
|
||||
_stream << endl;
|
||||
}
|
||||
else if (!compileViaYul && m_runWithYul)
|
||||
AnsiColorized(_stream, _formatted, {BOLD, YELLOW}) << _linePrefix << endl << _linePrefix
|
||||
<< "Note that the test also has to pass via Yul." << endl;
|
||||
return TestResult::Failure;
|
||||
}
|
||||
else if (!_compileViaYul && m_runWithYul)
|
||||
AnsiColorized(_stream, _formatted, {BOLD, YELLOW})
|
||||
<< _linePrefix << endl
|
||||
<< _linePrefix << "Note that the test also has to pass via Yul." << endl;
|
||||
return TestResult::Failure;
|
||||
}
|
||||
catch (WhiskersError const&)
|
||||
{
|
||||
// this is an error in Whiskers template, so should be thrown anyway
|
||||
}
|
||||
catch (WhiskersError const&)
|
||||
{
|
||||
// this is an error in Whiskers template, so should be thrown anyway
|
||||
throw;
|
||||
}
|
||||
catch (YulException const&)
|
||||
{
|
||||
// this should be an error in yul compilation or translation
|
||||
throw;
|
||||
}
|
||||
catch (boost::exception const&)
|
||||
{
|
||||
if (!_compileViaYul || m_runWithYul)
|
||||
throw;
|
||||
}
|
||||
catch (YulException const&)
|
||||
{
|
||||
// this should be an error in yul compilation or translation
|
||||
}
|
||||
catch (std::exception const&)
|
||||
{
|
||||
if (!_compileViaYul || m_runWithYul)
|
||||
throw;
|
||||
}
|
||||
catch (boost::exception const&)
|
||||
{
|
||||
if (compileViaYul && !m_runWithYul)
|
||||
continue;
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
if (!_compileViaYul || m_runWithYul)
|
||||
throw;
|
||||
}
|
||||
catch (std::exception const&)
|
||||
{
|
||||
if (compileViaYul && !m_runWithYul)
|
||||
continue;
|
||||
throw;
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
if (compileViaYul && !m_runWithYul)
|
||||
continue;
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
return TestResult::Success;
|
||||
|
||||
@@ -40,9 +40,9 @@ class SemanticTest: public SolidityExecutionFramework, public EVMVersionRestrict
|
||||
{
|
||||
public:
|
||||
static std::unique_ptr<TestCase> create(Config const& _options)
|
||||
{ return std::make_unique<SemanticTest>(_options.filename, _options.evmVersion, _options.enforceCompileViaYul); }
|
||||
{ return std::make_unique<SemanticTest>(_options.filename, _options.evmVersion, _options.vmPaths, _options.enforceCompileViaYul); }
|
||||
|
||||
explicit SemanticTest(std::string const& _filename, langutil::EVMVersion _evmVersion, bool _enforceViaYul = false);
|
||||
explicit SemanticTest(std::string const& _filename, langutil::EVMVersion _evmVersion, std::vector<boost::filesystem::path> const& _vmPaths, bool _enforceViaYul = false);
|
||||
|
||||
TestResult run(std::ostream& _stream, std::string const& _linePrefix = "", bool _formatted = false) override;
|
||||
void printSource(std::ostream &_stream, std::string const& _linePrefix = "", bool _formatted = false) const override;
|
||||
@@ -59,10 +59,12 @@ public:
|
||||
/// Returns true if deployment was successful, false otherwise.
|
||||
bool deploy(std::string const& _contractName, u256 const& _value, bytes const& _arguments, std::map<std::string, solidity::test::Address> const& _libraries = {});
|
||||
private:
|
||||
TestResult runTest(std::ostream& _stream, std::string const& _linePrefix, bool _formatted, bool _compileViaYul, bool _compileToEwasm);
|
||||
SourceMap m_sources;
|
||||
std::size_t m_lineOffset;
|
||||
std::vector<TestFunctionCall> m_tests;
|
||||
bool m_runWithYul = false;
|
||||
bool m_runWithEwasm = false;
|
||||
bool m_runWithoutYul = true;
|
||||
bool m_enforceViaYul = false;
|
||||
bool m_runWithABIEncoderV1Only = false;
|
||||
|
||||
@@ -48,18 +48,38 @@ using namespace solidity::util;
|
||||
using namespace solidity::test;
|
||||
using namespace solidity::langutil;
|
||||
|
||||
#define ALSO_VIA_YUL(CODE) \
|
||||
{ \
|
||||
{ CODE } \
|
||||
reset(); \
|
||||
m_compileViaYul = true; \
|
||||
{ CODE } \
|
||||
#define ALSO_VIA_YUL(CODE) \
|
||||
{ \
|
||||
m_doEwasmTestrun = true; \
|
||||
\
|
||||
m_compileViaYul = false; \
|
||||
m_compileToEwasm = false; \
|
||||
{ CODE } \
|
||||
\
|
||||
m_compileViaYul = true; \
|
||||
reset(); \
|
||||
{ CODE } \
|
||||
\
|
||||
if (m_doEwasmTestrun) \
|
||||
{ \
|
||||
m_compileToEwasm = true; \
|
||||
reset(); \
|
||||
{ CODE } \
|
||||
} \
|
||||
}
|
||||
|
||||
#define DISABLE_EWASM_TESTRUN() \
|
||||
{ m_doEwasmTestrun = false; }
|
||||
|
||||
namespace solidity::frontend::test
|
||||
{
|
||||
|
||||
BOOST_FIXTURE_TEST_SUITE(SolidityEndToEndTest, SolidityExecutionFramework)
|
||||
struct SolidityEndToEndTestExecutionFramework: public SolidityExecutionFramework
|
||||
{
|
||||
bool m_doEwasmTestrun = false;
|
||||
};
|
||||
|
||||
BOOST_FIXTURE_TEST_SUITE(SolidityEndToEndTest, SolidityEndToEndTestExecutionFramework)
|
||||
|
||||
int constexpr roundTo32(int _num)
|
||||
{
|
||||
@@ -115,6 +135,8 @@ BOOST_AUTO_TEST_CASE(recursive_calls)
|
||||
}
|
||||
)";
|
||||
ALSO_VIA_YUL(
|
||||
DISABLE_EWASM_TESTRUN()
|
||||
|
||||
compileAndRun(sourceCode);
|
||||
function<u256(u256)> recursive_calls_cpp = [&recursive_calls_cpp](u256 const& n) -> u256
|
||||
{
|
||||
@@ -140,6 +162,8 @@ BOOST_AUTO_TEST_CASE(while_loop)
|
||||
}
|
||||
)";
|
||||
ALSO_VIA_YUL(
|
||||
DISABLE_EWASM_TESTRUN()
|
||||
|
||||
compileAndRun(sourceCode);
|
||||
|
||||
auto while_loop_cpp = [](u256 const& n) -> u256
|
||||
@@ -168,6 +192,8 @@ BOOST_AUTO_TEST_CASE(do_while_loop)
|
||||
}
|
||||
)";
|
||||
ALSO_VIA_YUL(
|
||||
DISABLE_EWASM_TESTRUN()
|
||||
|
||||
compileAndRun(sourceCode);
|
||||
|
||||
auto do_while_loop_cpp = [](u256 const& n) -> u256
|
||||
@@ -213,6 +239,8 @@ BOOST_AUTO_TEST_CASE(do_while_loop_multiple_local_vars)
|
||||
}
|
||||
)";
|
||||
ALSO_VIA_YUL(
|
||||
DISABLE_EWASM_TESTRUN()
|
||||
|
||||
compileAndRun(sourceCode);
|
||||
|
||||
auto do_while = [](u256 n) -> u256
|
||||
@@ -263,6 +291,8 @@ BOOST_AUTO_TEST_CASE(nested_loops)
|
||||
}
|
||||
)";
|
||||
ALSO_VIA_YUL(
|
||||
DISABLE_EWASM_TESTRUN()
|
||||
|
||||
compileAndRun(sourceCode);
|
||||
|
||||
auto nested_loops_cpp = [](u256 n) -> u256
|
||||
@@ -329,6 +359,8 @@ BOOST_AUTO_TEST_CASE(nested_loops_multiple_local_vars)
|
||||
}
|
||||
)";
|
||||
ALSO_VIA_YUL(
|
||||
DISABLE_EWASM_TESTRUN()
|
||||
|
||||
compileAndRun(sourceCode);
|
||||
|
||||
auto nested_loops_cpp = [](u256 n) -> u256
|
||||
@@ -383,6 +415,8 @@ BOOST_AUTO_TEST_CASE(for_loop_multiple_local_vars)
|
||||
}
|
||||
)";
|
||||
ALSO_VIA_YUL(
|
||||
DISABLE_EWASM_TESTRUN()
|
||||
|
||||
compileAndRun(sourceCode);
|
||||
|
||||
auto for_loop = [](u256 n) -> u256
|
||||
@@ -444,6 +478,8 @@ BOOST_AUTO_TEST_CASE(nested_for_loop_multiple_local_vars)
|
||||
}
|
||||
)";
|
||||
ALSO_VIA_YUL(
|
||||
DISABLE_EWASM_TESTRUN()
|
||||
|
||||
compileAndRun(sourceCode);
|
||||
|
||||
auto for_loop = [](u256 n) -> u256
|
||||
@@ -484,6 +520,8 @@ BOOST_AUTO_TEST_CASE(for_loop)
|
||||
}
|
||||
)";
|
||||
ALSO_VIA_YUL(
|
||||
DISABLE_EWASM_TESTRUN()
|
||||
|
||||
compileAndRun(sourceCode);
|
||||
|
||||
auto for_loop_cpp = [](u256 const& n) -> u256
|
||||
@@ -512,6 +550,8 @@ BOOST_AUTO_TEST_CASE(for_loop_empty)
|
||||
}
|
||||
)";
|
||||
ALSO_VIA_YUL(
|
||||
DISABLE_EWASM_TESTRUN()
|
||||
|
||||
compileAndRun(sourceCode);
|
||||
|
||||
auto for_loop_empty_cpp = []() -> u256
|
||||
@@ -542,6 +582,8 @@ BOOST_AUTO_TEST_CASE(for_loop_simple_init_expr)
|
||||
}
|
||||
)";
|
||||
ALSO_VIA_YUL(
|
||||
DISABLE_EWASM_TESTRUN()
|
||||
|
||||
compileAndRun(sourceCode);
|
||||
|
||||
auto for_loop_simple_init_expr_cpp = [](u256 const& n) -> u256
|
||||
@@ -665,6 +707,8 @@ BOOST_AUTO_TEST_CASE(many_local_variables)
|
||||
}
|
||||
)";
|
||||
ALSO_VIA_YUL(
|
||||
DISABLE_EWASM_TESTRUN()
|
||||
|
||||
compileAndRun(sourceCode);
|
||||
auto f = [](u256 const& x1, u256 const& x2, u256 const& x3) -> u256
|
||||
{
|
||||
@@ -689,6 +733,8 @@ BOOST_AUTO_TEST_CASE(short_circuiting)
|
||||
}
|
||||
)";
|
||||
ALSO_VIA_YUL(
|
||||
DISABLE_EWASM_TESTRUN()
|
||||
|
||||
compileAndRun(sourceCode);
|
||||
|
||||
auto short_circuiting_cpp = [](u256 n) -> u256
|
||||
@@ -801,6 +847,8 @@ BOOST_AUTO_TEST_CASE(compound_assign)
|
||||
}
|
||||
)";
|
||||
ALSO_VIA_YUL(
|
||||
DISABLE_EWASM_TESTRUN()
|
||||
|
||||
compileAndRun(sourceCode);
|
||||
|
||||
u256 value1;
|
||||
@@ -863,6 +911,8 @@ BOOST_AUTO_TEST_CASE(mapping_state)
|
||||
map<u160, bool> m_voted;
|
||||
};
|
||||
ALSO_VIA_YUL(
|
||||
DISABLE_EWASM_TESTRUN()
|
||||
|
||||
compileAndRun(sourceCode);
|
||||
Ballot ballot;
|
||||
|
||||
@@ -936,6 +986,8 @@ BOOST_AUTO_TEST_CASE(mapping_state_inc_dec)
|
||||
return --table[value++];
|
||||
};
|
||||
ALSO_VIA_YUL(
|
||||
DISABLE_EWASM_TESTRUN()
|
||||
|
||||
compileAndRun(sourceCode);
|
||||
value = 0;
|
||||
table.clear();
|
||||
@@ -962,6 +1014,8 @@ BOOST_AUTO_TEST_CASE(multi_level_mapping)
|
||||
else return table[_x][_y] = _z;
|
||||
};
|
||||
ALSO_VIA_YUL(
|
||||
DISABLE_EWASM_TESTRUN()
|
||||
|
||||
compileAndRun(sourceCode);
|
||||
table.clear();
|
||||
|
||||
@@ -998,6 +1052,8 @@ BOOST_AUTO_TEST_CASE(constructor)
|
||||
};
|
||||
|
||||
ALSO_VIA_YUL(
|
||||
DISABLE_EWASM_TESTRUN()
|
||||
|
||||
compileAndRun(sourceCode);
|
||||
testContractAgainstCpp("get(uint256)", get, u256(6));
|
||||
testContractAgainstCpp("get(uint256)", get, u256(7));
|
||||
@@ -1016,12 +1072,12 @@ BOOST_AUTO_TEST_CASE(blockchain)
|
||||
}
|
||||
}
|
||||
)";
|
||||
m_evmHost->tx_context.block_coinbase = EVMHost::convertToEVMC(Address("0x1212121212121212121212121212121212121212"));
|
||||
m_evmHost->newBlock();
|
||||
m_evmHost->newBlock();
|
||||
m_evmHost->newBlock();
|
||||
m_evmHost->newBlock();
|
||||
m_evmHost->newBlock();
|
||||
m_evmcHost->tx_context.block_coinbase = EVMHost::convertToEVMC(Address("0x1212121212121212121212121212121212121212"));
|
||||
m_evmcHost->newBlock();
|
||||
m_evmcHost->newBlock();
|
||||
m_evmcHost->newBlock();
|
||||
m_evmcHost->newBlock();
|
||||
m_evmcHost->newBlock();
|
||||
compileAndRun(sourceCode, 27);
|
||||
ABI_CHECK(callContractFunctionWithValue("someInfo()", 28), encodeArgs(28, u256("0x1212121212121212121212121212121212121212"), 7));
|
||||
}
|
||||
@@ -1038,6 +1094,8 @@ BOOST_AUTO_TEST_CASE(send_ether)
|
||||
}
|
||||
)";
|
||||
ALSO_VIA_YUL(
|
||||
DISABLE_EWASM_TESTRUN()
|
||||
|
||||
u256 amount(250);
|
||||
compileAndRun(sourceCode, amount + 1);
|
||||
u160 address(23);
|
||||
@@ -1070,6 +1128,8 @@ BOOST_AUTO_TEST_CASE(transfer_ether)
|
||||
}
|
||||
)";
|
||||
ALSO_VIA_YUL(
|
||||
DISABLE_EWASM_TESTRUN()
|
||||
|
||||
compileAndRun(sourceCode, 0, "B");
|
||||
u160 const nonPayableRecipient = m_contractAddress;
|
||||
compileAndRun(sourceCode, 0, "C");
|
||||
@@ -1110,6 +1170,8 @@ BOOST_AUTO_TEST_CASE(log0)
|
||||
}
|
||||
)";
|
||||
ALSO_VIA_YUL(
|
||||
DISABLE_EWASM_TESTRUN()
|
||||
|
||||
compileAndRun(sourceCode);
|
||||
callContractFunction("a()");
|
||||
BOOST_REQUIRE_EQUAL(numLogs(), 1);
|
||||
@@ -1129,6 +1191,8 @@ BOOST_AUTO_TEST_CASE(log1)
|
||||
}
|
||||
)";
|
||||
ALSO_VIA_YUL(
|
||||
DISABLE_EWASM_TESTRUN()
|
||||
|
||||
compileAndRun(sourceCode);
|
||||
callContractFunction("a()");
|
||||
BOOST_REQUIRE_EQUAL(numLogs(), 1);
|
||||
@@ -1149,6 +1213,8 @@ BOOST_AUTO_TEST_CASE(log2)
|
||||
}
|
||||
)";
|
||||
ALSO_VIA_YUL(
|
||||
DISABLE_EWASM_TESTRUN()
|
||||
|
||||
compileAndRun(sourceCode);
|
||||
callContractFunction("a()");
|
||||
BOOST_REQUIRE_EQUAL(numLogs(), 1);
|
||||
@@ -1170,6 +1236,8 @@ BOOST_AUTO_TEST_CASE(log3)
|
||||
}
|
||||
)";
|
||||
ALSO_VIA_YUL(
|
||||
DISABLE_EWASM_TESTRUN()
|
||||
|
||||
compileAndRun(sourceCode);
|
||||
callContractFunction("a()");
|
||||
BOOST_REQUIRE_EQUAL(numLogs(), 1);
|
||||
@@ -1191,6 +1259,8 @@ BOOST_AUTO_TEST_CASE(log4)
|
||||
}
|
||||
)";
|
||||
ALSO_VIA_YUL(
|
||||
DISABLE_EWASM_TESTRUN()
|
||||
|
||||
compileAndRun(sourceCode);
|
||||
callContractFunction("a()");
|
||||
BOOST_REQUIRE_EQUAL(numLogs(), 1);
|
||||
@@ -1212,6 +1282,8 @@ BOOST_AUTO_TEST_CASE(log_in_constructor)
|
||||
}
|
||||
)";
|
||||
ALSO_VIA_YUL(
|
||||
DISABLE_EWASM_TESTRUN()
|
||||
|
||||
compileAndRun(sourceCode);
|
||||
BOOST_REQUIRE_EQUAL(numLogs(), 1);
|
||||
BOOST_CHECK_EQUAL(logAddress(0), m_contractAddress);
|
||||
@@ -1235,6 +1307,8 @@ BOOST_AUTO_TEST_CASE(selfdestruct)
|
||||
u256 amount(130);
|
||||
u160 address(23);
|
||||
ALSO_VIA_YUL(
|
||||
DISABLE_EWASM_TESTRUN()
|
||||
|
||||
compileAndRun(sourceCode, amount);
|
||||
ABI_CHECK(callContractFunction("a(address)", address), bytes());
|
||||
BOOST_CHECK(!addressHasCode(m_contractAddress));
|
||||
@@ -1665,6 +1739,8 @@ BOOST_AUTO_TEST_CASE(gaslimit)
|
||||
}
|
||||
)";
|
||||
ALSO_VIA_YUL(
|
||||
DISABLE_EWASM_TESTRUN()
|
||||
|
||||
compileAndRun(sourceCode);
|
||||
auto result = callContractFunction("f()");
|
||||
ABI_CHECK(result, encodeArgs(gasLimit()));
|
||||
@@ -1681,6 +1757,8 @@ BOOST_AUTO_TEST_CASE(gasprice)
|
||||
}
|
||||
)";
|
||||
ALSO_VIA_YUL(
|
||||
DISABLE_EWASM_TESTRUN()
|
||||
|
||||
compileAndRun(sourceCode);
|
||||
ABI_CHECK(callContractFunction("f()"), encodeArgs(gasPrice()));
|
||||
)
|
||||
@@ -1772,6 +1850,8 @@ BOOST_AUTO_TEST_CASE(event)
|
||||
}
|
||||
)";
|
||||
ALSO_VIA_YUL(
|
||||
DISABLE_EWASM_TESTRUN()
|
||||
|
||||
compileAndRun(sourceCode);
|
||||
u256 value(18);
|
||||
u256 id(0x1234);
|
||||
@@ -1800,6 +1880,8 @@ BOOST_AUTO_TEST_CASE(event_emit)
|
||||
}
|
||||
)";
|
||||
ALSO_VIA_YUL(
|
||||
DISABLE_EWASM_TESTRUN()
|
||||
|
||||
compileAndRun(sourceCode);
|
||||
u256 value(18);
|
||||
u256 id(0x1234);
|
||||
@@ -1826,6 +1908,8 @@ BOOST_AUTO_TEST_CASE(event_no_arguments)
|
||||
)";
|
||||
|
||||
ALSO_VIA_YUL(
|
||||
DISABLE_EWASM_TESTRUN()
|
||||
|
||||
compileAndRun(sourceCode);
|
||||
callContractFunction("deposit()");
|
||||
BOOST_REQUIRE_EQUAL(numLogs(), 1);
|
||||
@@ -1850,6 +1934,8 @@ BOOST_AUTO_TEST_CASE(event_access_through_base_name_emit)
|
||||
}
|
||||
)";
|
||||
ALSO_VIA_YUL(
|
||||
DISABLE_EWASM_TESTRUN()
|
||||
|
||||
compileAndRun(sourceCode);
|
||||
callContractFunction("f()");
|
||||
BOOST_REQUIRE_EQUAL(numLogs(), 1);
|
||||
@@ -1889,6 +1975,8 @@ BOOST_AUTO_TEST_CASE(events_with_same_name)
|
||||
u160 const c_loggedAddress = m_contractAddress;
|
||||
|
||||
ALSO_VIA_YUL(
|
||||
DISABLE_EWASM_TESTRUN()
|
||||
|
||||
compileAndRun(sourceCode);
|
||||
ABI_CHECK(callContractFunction("deposit()"), encodeArgs(u256(1)));
|
||||
BOOST_REQUIRE_EQUAL(numLogs(), 1);
|
||||
@@ -1950,6 +2038,8 @@ BOOST_AUTO_TEST_CASE(events_with_same_name_inherited_emit)
|
||||
u160 const c_loggedAddress = m_contractAddress;
|
||||
|
||||
ALSO_VIA_YUL(
|
||||
DISABLE_EWASM_TESTRUN()
|
||||
|
||||
compileAndRun(sourceCode);
|
||||
ABI_CHECK(callContractFunction("deposit()"), encodeArgs(u256(1)));
|
||||
BOOST_REQUIRE_EQUAL(numLogs(), 1);
|
||||
@@ -1985,6 +2075,8 @@ BOOST_AUTO_TEST_CASE(event_anonymous)
|
||||
}
|
||||
)";
|
||||
ALSO_VIA_YUL(
|
||||
DISABLE_EWASM_TESTRUN()
|
||||
|
||||
compileAndRun(sourceCode);
|
||||
callContractFunction("deposit()");
|
||||
BOOST_REQUIRE_EQUAL(numLogTopics(0), 0);
|
||||
@@ -2002,6 +2094,8 @@ BOOST_AUTO_TEST_CASE(event_anonymous_with_topics)
|
||||
}
|
||||
)";
|
||||
ALSO_VIA_YUL(
|
||||
DISABLE_EWASM_TESTRUN()
|
||||
|
||||
compileAndRun(sourceCode);
|
||||
u256 value(18);
|
||||
u256 id(0x1234);
|
||||
@@ -2028,6 +2122,8 @@ BOOST_AUTO_TEST_CASE(event_lots_of_data)
|
||||
}
|
||||
)";
|
||||
ALSO_VIA_YUL(
|
||||
DISABLE_EWASM_TESTRUN()
|
||||
|
||||
compileAndRun(sourceCode);
|
||||
u256 value(18);
|
||||
u256 id(0x1234);
|
||||
@@ -2247,6 +2343,8 @@ BOOST_AUTO_TEST_CASE(event_dynamic_array_storage)
|
||||
}
|
||||
)";
|
||||
ALSO_VIA_YUL(
|
||||
DISABLE_EWASM_TESTRUN()
|
||||
|
||||
compileAndRun(sourceCode);
|
||||
u256 x(42);
|
||||
callContractFunction("createEvent(uint256)", x);
|
||||
@@ -2276,6 +2374,8 @@ BOOST_AUTO_TEST_CASE(event_dynamic_array_storage_v2)
|
||||
}
|
||||
)";
|
||||
ALSO_VIA_YUL(
|
||||
DISABLE_EWASM_TESTRUN()
|
||||
|
||||
compileAndRun(sourceCode);
|
||||
u256 x(42);
|
||||
callContractFunction("createEvent(uint256)", x);
|
||||
@@ -2365,6 +2465,8 @@ BOOST_AUTO_TEST_CASE(empty_name_input_parameter_with_named_one)
|
||||
}
|
||||
)";
|
||||
ALSO_VIA_YUL(
|
||||
DISABLE_EWASM_TESTRUN()
|
||||
|
||||
compileAndRun(sourceCode);
|
||||
BOOST_CHECK(callContractFunction("f(uint256,uint256)", 5, 9) != encodeArgs(5, 8));
|
||||
ABI_CHECK(callContractFunction("f(uint256,uint256)", 5, 9), encodeArgs(9, 8));
|
||||
@@ -2987,6 +3089,8 @@ BOOST_AUTO_TEST_CASE(fixed_array_cleanup)
|
||||
}
|
||||
)";
|
||||
ALSO_VIA_YUL(
|
||||
DISABLE_EWASM_TESTRUN()
|
||||
|
||||
compileAndRun(sourceCode);
|
||||
BOOST_CHECK(storageEmpty(m_contractAddress));
|
||||
ABI_CHECK(callContractFunction("fill()"), bytes());
|
||||
@@ -3010,6 +3114,8 @@ BOOST_AUTO_TEST_CASE(short_fixed_array_cleanup)
|
||||
}
|
||||
)";
|
||||
ALSO_VIA_YUL(
|
||||
DISABLE_EWASM_TESTRUN()
|
||||
|
||||
compileAndRun(sourceCode);
|
||||
BOOST_CHECK(storageEmpty(m_contractAddress));
|
||||
ABI_CHECK(callContractFunction("fill()"), bytes());
|
||||
@@ -3037,6 +3143,8 @@ BOOST_AUTO_TEST_CASE(dynamic_array_cleanup)
|
||||
}
|
||||
)";
|
||||
ALSO_VIA_YUL(
|
||||
DISABLE_EWASM_TESTRUN()
|
||||
|
||||
compileAndRun(sourceCode);
|
||||
BOOST_CHECK(storageEmpty(m_contractAddress));
|
||||
ABI_CHECK(callContractFunction("fill()"), bytes());
|
||||
@@ -4305,6 +4413,8 @@ BOOST_AUTO_TEST_CASE(string_as_mapping_key)
|
||||
};
|
||||
|
||||
ALSO_VIA_YUL(
|
||||
DISABLE_EWASM_TESTRUN()
|
||||
|
||||
compileAndRun(sourceCode, 0, "Test");
|
||||
for (unsigned i = 0; i < strings.size(); i++)
|
||||
ABI_CHECK(callContractFunction(
|
||||
@@ -5415,6 +5525,8 @@ BOOST_AUTO_TEST_CASE(no_nonpayable_circumvention_by_modifier)
|
||||
}
|
||||
)";
|
||||
ALSO_VIA_YUL(
|
||||
DISABLE_EWASM_TESTRUN()
|
||||
|
||||
compileAndRun(sourceCode);
|
||||
ABI_CHECK(callContractFunctionWithValue("f()", 27), encodeArgs());
|
||||
BOOST_CHECK_EQUAL(balanceAt(m_contractAddress), 0);
|
||||
@@ -5527,6 +5639,8 @@ BOOST_AUTO_TEST_CASE(contracts_separated_with_comment)
|
||||
contract C2 {}
|
||||
)";
|
||||
ALSO_VIA_YUL(
|
||||
DISABLE_EWASM_TESTRUN()
|
||||
|
||||
compileAndRun(sourceCode, 0, "C1");
|
||||
compileAndRun(sourceCode, 0, "C2");
|
||||
)
|
||||
|
||||
@@ -43,6 +43,7 @@ bytes SolidityExecutionFramework::multiSourceCompileContract(
|
||||
entry.second = addPreamble(entry.second);
|
||||
|
||||
m_compiler.reset();
|
||||
m_compiler.enableEwasmGeneration(m_compileToEwasm);
|
||||
m_compiler.setSources(sourcesWithPreamble);
|
||||
m_compiler.setLibraries(_libraryAddresses);
|
||||
m_compiler.setRevertStringBehaviour(m_revertStrings);
|
||||
@@ -63,38 +64,40 @@ bytes SolidityExecutionFramework::multiSourceCompileContract(
|
||||
evmasm::LinkerObject obj;
|
||||
if (m_compileViaYul)
|
||||
{
|
||||
// Try compiling twice: If the first run fails due to stack errors, forcefully enable
|
||||
// the optimizer.
|
||||
for (bool forceEnableOptimizer: {false, true})
|
||||
if (m_compileToEwasm)
|
||||
obj = m_compiler.ewasmObject(contractName);
|
||||
else
|
||||
{
|
||||
OptimiserSettings optimiserSettings = m_optimiserSettings;
|
||||
if (!forceEnableOptimizer && !optimiserSettings.runYulOptimiser)
|
||||
// Try compiling twice: If the first run fails due to stack errors, forcefully enable
|
||||
// the optimizer.
|
||||
for (bool forceEnableOptimizer: {false, true})
|
||||
{
|
||||
// Enable some optimizations on the first run
|
||||
optimiserSettings.runYulOptimiser = true;
|
||||
optimiserSettings.yulOptimiserSteps = "uljmul jmul";
|
||||
}
|
||||
else if (forceEnableOptimizer)
|
||||
optimiserSettings = OptimiserSettings::full();
|
||||
OptimiserSettings optimiserSettings = m_optimiserSettings;
|
||||
if (!forceEnableOptimizer && !optimiserSettings.runYulOptimiser)
|
||||
{
|
||||
// Enable some optimizations on the first run
|
||||
optimiserSettings.runYulOptimiser = true;
|
||||
optimiserSettings.yulOptimiserSteps = "uljmul jmul";
|
||||
}
|
||||
else if (forceEnableOptimizer)
|
||||
optimiserSettings = OptimiserSettings::full();
|
||||
|
||||
yul::AssemblyStack asmStack(
|
||||
m_evmVersion,
|
||||
yul::AssemblyStack::Language::StrictAssembly,
|
||||
optimiserSettings
|
||||
);
|
||||
bool analysisSuccessful = asmStack.parseAndAnalyze("", m_compiler.yulIROptimized(contractName));
|
||||
solAssert(analysisSuccessful, "Code that passed analysis in CompilerStack can't have errors");
|
||||
yul::AssemblyStack
|
||||
asmStack(m_evmVersion, yul::AssemblyStack::Language::StrictAssembly, optimiserSettings);
|
||||
bool analysisSuccessful = asmStack.parseAndAnalyze("", m_compiler.yulIROptimized(contractName));
|
||||
solAssert(analysisSuccessful, "Code that passed analysis in CompilerStack can't have errors");
|
||||
|
||||
try
|
||||
{
|
||||
asmStack.optimize();
|
||||
obj = std::move(*asmStack.assemble(yul::AssemblyStack::Machine::EVM).bytecode);
|
||||
break;
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
if (forceEnableOptimizer || optimiserSettings == OptimiserSettings::full())
|
||||
throw;
|
||||
try
|
||||
{
|
||||
asmStack.optimize();
|
||||
obj = std::move(*asmStack.assemble(yul::AssemblyStack::Machine::EVM).bytecode);
|
||||
break;
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
if (forceEnableOptimizer || optimiserSettings == OptimiserSettings::full())
|
||||
throw;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -43,8 +43,8 @@ class SolidityExecutionFramework: public solidity::test::ExecutionFramework
|
||||
|
||||
public:
|
||||
SolidityExecutionFramework(): m_showMetadata(solidity::test::CommonOptions::get().showMetadata) {}
|
||||
explicit SolidityExecutionFramework(langutil::EVMVersion _evmVersion):
|
||||
ExecutionFramework(_evmVersion), m_showMetadata(solidity::test::CommonOptions::get().showMetadata)
|
||||
explicit SolidityExecutionFramework(langutil::EVMVersion _evmVersion, std::vector<boost::filesystem::path> const& _vmPaths):
|
||||
ExecutionFramework(_evmVersion, _vmPaths), m_showMetadata(solidity::test::CommonOptions::get().showMetadata)
|
||||
{}
|
||||
|
||||
bytes const& compileAndRunWithoutCheck(
|
||||
@@ -76,8 +76,10 @@ public:
|
||||
/// the latter only if it is required.
|
||||
static std::string addPreamble(std::string const& _sourceCode);
|
||||
protected:
|
||||
|
||||
solidity::frontend::CompilerStack m_compiler;
|
||||
bool m_compileViaYul = false;
|
||||
bool m_compileToEwasm = false;
|
||||
bool m_showMetadata = false;
|
||||
RevertStrings m_revertStrings = RevertStrings::Default;
|
||||
};
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
#include <liblangutil/Scanner.h>
|
||||
#include <libsolidity/parsing/Parser.h>
|
||||
#include <libsolidity/analysis/NameAndTypeResolver.h>
|
||||
#include <libsolidity/analysis/Scoper.h>
|
||||
#include <libsolidity/analysis/DeclarationTypeChecker.h>
|
||||
#include <libsolidity/codegen/CompilerContext.h>
|
||||
#include <libsolidity/codegen/ExpressionCompiler.h>
|
||||
@@ -117,6 +118,7 @@ bytes compileFirstExpression(
|
||||
ErrorList errors;
|
||||
ErrorReporter errorReporter(errors);
|
||||
GlobalContext globalContext;
|
||||
Scoper::assignScopes(*sourceUnit);
|
||||
NameAndTypeResolver resolver(globalContext, solidity::test::CommonOptions::get().evmVersion(), errorReporter);
|
||||
resolver.registerDeclarations(*sourceUnit);
|
||||
BOOST_REQUIRE_MESSAGE(resolver.resolveNamesAndTypes(*sourceUnit), "Resolving names failed");
|
||||
|
||||
@@ -17,9 +17,9 @@ contract C {
|
||||
// optimize-yul: true
|
||||
// ----
|
||||
// creation:
|
||||
// codeDepositCost: 614600
|
||||
// executionCost: 651
|
||||
// totalCost: 615251
|
||||
// codeDepositCost: 597000
|
||||
// executionCost: 632
|
||||
// totalCost: 597632
|
||||
// external:
|
||||
// a(): 1029
|
||||
// b(uint256): 2084
|
||||
|
||||
@@ -12,5 +12,7 @@ contract c {
|
||||
}
|
||||
}
|
||||
|
||||
// ====
|
||||
// compileViaYul: also
|
||||
// ----
|
||||
// test() -> 1, 2, 3, 4
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
contract C {
|
||||
uint8[33] a;
|
||||
uint32[9] b;
|
||||
uint120[3] c;
|
||||
|
||||
function f() public returns (uint8, uint32, uint120) {
|
||||
a[32] = 1; a[31] = 2; a[30] = 3;
|
||||
b[0] = 1; b[1] = 2; b[2] = 3;
|
||||
c[2] = 3; c[1] = 1;
|
||||
return (a[32], b[1], c[2]);
|
||||
}
|
||||
}
|
||||
// ====
|
||||
// compileViaYul: also
|
||||
// ----
|
||||
// f() -> 1, 2, 3
|
||||
@@ -8,4 +8,4 @@ contract C {
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// Warning 2529: (82-89): Empty array "pop" detected here
|
||||
// Warning 2529: (82-89): Empty array "pop" detected here.
|
||||
|
||||
@@ -8,4 +8,4 @@ contract C {
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// Warning 2529: (82-89): Empty array "pop" detected here
|
||||
// Warning 2529: (82-89): Empty array "pop" detected here.
|
||||
|
||||
@@ -8,5 +8,5 @@ contract C {
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// Warning 2529: (82-89): Empty array "pop" detected here
|
||||
// Warning 2529: (93-100): Empty array "pop" detected here
|
||||
// Warning 2529: (82-89): Empty array "pop" detected here.
|
||||
// Warning 2529: (93-100): Empty array "pop" detected here.
|
||||
|
||||
@@ -8,4 +8,4 @@ contract C {
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// Warning 2529: (94-101): Empty array "pop" detected here
|
||||
// Warning 2529: (94-101): Empty array "pop" detected here.
|
||||
|
||||
@@ -11,4 +11,4 @@ contract C {
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// Warning 2529: (122-129): Empty array "pop" detected here
|
||||
// Warning 2529: (122-129): Empty array "pop" detected here.
|
||||
|
||||
@@ -11,4 +11,4 @@ contract C {
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// Warning 2529: (127-134): Empty array "pop" detected here
|
||||
// Warning 2529: (127-134): Empty array "pop" detected here.
|
||||
|
||||
@@ -13,4 +13,4 @@ contract C {
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// Warning 2529: (82-89): Empty array "pop" detected here
|
||||
// Warning 2529: (82-89): Empty array "pop" detected here.
|
||||
|
||||
@@ -10,4 +10,4 @@ contract C {
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// Warning 6328: (153-176): Assertion violation happens here
|
||||
// Warning 6328: (153-176): Assertion violation happens here.
|
||||
|
||||
+3
-3
@@ -14,6 +14,6 @@ contract C {
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// Warning 6328: (198-224): Assertion violation happens here
|
||||
// Warning 6328: (228-254): Assertion violation happens here
|
||||
// Warning 6328: (258-281): Assertion violation happens here
|
||||
// Warning 6328: (198-224): Assertion violation happens here.
|
||||
// Warning 6328: (228-254): Assertion violation happens here.
|
||||
// Warning 6328: (258-281): Assertion violation happens here.
|
||||
|
||||
+4
-4
@@ -16,7 +16,7 @@ contract C {
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// Warning 6328: (222-248): Assertion violation happens here
|
||||
// Warning 6328: (252-278): Assertion violation happens here
|
||||
// Warning 6328: (282-305): Assertion violation happens here
|
||||
// Warning 6328: (309-335): Assertion violation happens here
|
||||
// Warning 6328: (222-248): Assertion violation happens here.
|
||||
// Warning 6328: (252-278): Assertion violation happens here.
|
||||
// Warning 6328: (282-305): Assertion violation happens here.
|
||||
// Warning 6328: (309-335): Assertion violation happens here.
|
||||
|
||||
@@ -7,4 +7,4 @@ contract C {
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// Warning 2529: (82-89): Empty array "pop" detected here
|
||||
// Warning 2529: (82-89): Empty array "pop" detected here.
|
||||
|
||||
@@ -9,4 +9,4 @@ contract C {
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// Warning 2529: (111-121): Empty array "pop" detected here
|
||||
// Warning 2529: (111-121): Empty array "pop" detected here.
|
||||
|
||||
@@ -7,4 +7,4 @@ contract C {
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// Warning 2529: (76-83): Empty array "pop" detected here
|
||||
// Warning 2529: (76-83): Empty array "pop" detected here.
|
||||
|
||||
@@ -11,4 +11,4 @@ contract C {
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// Warning 2529: (150-157): Empty array "pop" detected here
|
||||
// Warning 2529: (150-157): Empty array "pop" detected here.
|
||||
|
||||
@@ -10,5 +10,5 @@ contract C {
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// Warning 3944: (162-177): Underflow (resulting value less than 0) happens here
|
||||
// Warning 6328: (150-184): Assertion violation happens here
|
||||
// Warning 3944: (162-177): Underflow (resulting value less than 0) happens here.
|
||||
// Warning 6328: (150-184): Assertion violation happens here.
|
||||
|
||||
@@ -8,5 +8,5 @@ contract C {
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// Warning 6328: (113-139): Assertion violation happens here
|
||||
// Warning 6328: (143-189): Assertion violation happens here
|
||||
// Warning 6328: (113-139): Assertion violation happens here.
|
||||
// Warning 6328: (143-189): Assertion violation happens here.
|
||||
|
||||
@@ -10,6 +10,6 @@ contract C {
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// Warning 6328: (122-148): Assertion violation happens here
|
||||
// Warning 6328: (202-218): Assertion violation happens here
|
||||
// Warning 6328: (222-278): Assertion violation happens here
|
||||
// Warning 6328: (122-148): Assertion violation happens here.
|
||||
// Warning 6328: (202-218): Assertion violation happens here.
|
||||
// Warning 6328: (222-278): Assertion violation happens here.
|
||||
|
||||
@@ -12,5 +12,5 @@ contract C {
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// Warning 3944: (217-232): Underflow (resulting value less than 0) happens here
|
||||
// Warning 6328: (205-239): Assertion violation happens here
|
||||
// Warning 3944: (217-232): Underflow (resulting value less than 0) happens here.
|
||||
// Warning 6328: (205-239): Assertion violation happens here.
|
||||
|
||||
@@ -12,4 +12,4 @@ contract C {
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// Warning 6328: (167-188): Assertion violation happens here
|
||||
// Warning 6328: (167-188): Assertion violation happens here.
|
||||
|
||||
@@ -18,6 +18,6 @@ contract C {
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// Warning 6328: (193-217): Assertion violation happens here
|
||||
// Warning 6328: (309-333): Assertion violation happens here
|
||||
// Warning 6328: (419-436): Assertion violation happens here
|
||||
// Warning 6328: (193-217): Assertion violation happens here.
|
||||
// Warning 6328: (309-333): Assertion violation happens here.
|
||||
// Warning 6328: (419-436): Assertion violation happens here.
|
||||
|
||||
@@ -9,4 +9,4 @@ contract C {
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// Warning 6328: (111-144): Assertion violation happens here
|
||||
// Warning 6328: (111-144): Assertion violation happens here.
|
||||
|
||||
@@ -8,4 +8,4 @@ contract C {
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// Warning 6328: (94-124): Assertion violation happens here
|
||||
// Warning 6328: (94-124): Assertion violation happens here.
|
||||
|
||||
@@ -15,4 +15,4 @@ contract C {
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// Warning 6328: (184-213): Assertion violation happens here
|
||||
// Warning 6328: (184-213): Assertion violation happens here.
|
||||
|
||||
@@ -53,4 +53,4 @@ contract MyConc{
|
||||
// ----
|
||||
// Warning 2519: (773-792): This declaration shadows an existing declaration.
|
||||
// Warning 2018: (1009-1086): Function state mutability can be restricted to view
|
||||
// Warning 4984: (985-1002): Overflow (resulting value larger than 2**256 - 1) happens here
|
||||
// Warning 4984: (985-1002): Overflow (resulting value larger than 2**256 - 1) happens here.
|
||||
|
||||
@@ -15,4 +15,4 @@ contract c {
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// Warning 6328: (227-236): Assertion violation happens here
|
||||
// Warning 6328: (227-236): Assertion violation happens here.
|
||||
|
||||
@@ -17,5 +17,5 @@ contract c {
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// Warning 6328: (202-218): Assertion violation happens here
|
||||
// Warning 6328: (242-252): Assertion violation happens here
|
||||
// Warning 6328: (202-218): Assertion violation happens here.
|
||||
// Warning 6328: (242-252): Assertion violation happens here.
|
||||
|
||||
@@ -15,4 +15,4 @@ contract c {
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// Warning 6328: (225-235): Assertion violation happens here
|
||||
// Warning 6328: (225-235): Assertion violation happens here.
|
||||
|
||||
@@ -15,4 +15,4 @@ contract c {
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// Warning 6328: (225-235): Assertion violation happens here
|
||||
// Warning 6328: (225-235): Assertion violation happens here.
|
||||
|
||||
@@ -24,4 +24,4 @@ contract c {
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// Warning 6328: (360-370): Assertion violation happens here
|
||||
// Warning 6328: (360-370): Assertion violation happens here.
|
||||
|
||||
@@ -15,4 +15,4 @@ contract c {
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// Warning 6328: (225-235): Assertion violation happens here
|
||||
// Warning 6328: (225-235): Assertion violation happens here.
|
||||
|
||||
@@ -9,4 +9,4 @@ contract C {
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// Warning 6328: (159-173): Assertion violation happens here
|
||||
// Warning 6328: (159-173): Assertion violation happens here.
|
||||
|
||||
@@ -9,4 +9,4 @@ contract C {
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// Warning 6328: (159-173): Assertion violation happens here
|
||||
// Warning 6328: (159-173): Assertion violation happens here.
|
||||
|
||||
@@ -9,4 +9,4 @@ contract C {
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// Warning 6328: (161-175): Assertion violation happens here
|
||||
// Warning 6328: (161-175): Assertion violation happens here.
|
||||
|
||||
@@ -17,4 +17,4 @@ contract C {
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// Warning 6328: (200-214): Assertion violation happens here
|
||||
// Warning 6328: (200-214): Assertion violation happens here.
|
||||
|
||||
@@ -26,4 +26,4 @@ contract C {
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// Warning 6328: (423-445): Assertion violation happens here
|
||||
// Warning 6328: (423-445): Assertion violation happens here.
|
||||
|
||||
@@ -28,4 +28,4 @@ contract C {
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// Warning 6328: (431-453): Assertion violation happens here
|
||||
// Warning 6328: (431-453): Assertion violation happens here.
|
||||
|
||||
@@ -34,5 +34,5 @@ contract C {
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// Warning 6328: (528-565): Assertion violation happens here
|
||||
// Warning 6328: (528-565): Assertion violation happens here.
|
||||
// Warning 5084: (544-554): Type conversion is not yet fully supported and might yield false positives.
|
||||
|
||||
+1
-1
@@ -29,4 +29,4 @@ contract C {
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// Warning 6328: (299-313): Assertion violation happens here
|
||||
// Warning 6328: (299-313): Assertion violation happens here.
|
||||
|
||||
+2
-2
@@ -42,6 +42,6 @@ contract C {
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// Warning 6328: (452-466): Assertion violation happens here
|
||||
// Warning 6328: (470-496): Assertion violation happens here
|
||||
// Warning 6328: (452-466): Assertion violation happens here.
|
||||
// Warning 6328: (470-496): Assertion violation happens here.
|
||||
// Warning 5084: (92-102): Type conversion is not yet fully supported and might yield false positives.
|
||||
|
||||
+2
-2
@@ -34,6 +34,6 @@ contract C {
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// Warning 6328: (381-395): Assertion violation happens here
|
||||
// Warning 6328: (399-425): Assertion violation happens here
|
||||
// Warning 6328: (381-395): Assertion violation happens here.
|
||||
// Warning 6328: (399-425): Assertion violation happens here.
|
||||
// Warning 5084: (116-126): Type conversion is not yet fully supported and might yield false positives.
|
||||
|
||||
+2
-2
@@ -38,6 +38,6 @@ contract C {
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// Warning 6328: (435-461): Assertion violation happens here
|
||||
// Warning 6328: (594-631): Assertion violation happens here
|
||||
// Warning 6328: (435-461): Assertion violation happens here.
|
||||
// Warning 6328: (594-631): Assertion violation happens here.
|
||||
// Warning 5084: (610-620): Type conversion is not yet fully supported and might yield false positives.
|
||||
|
||||
@@ -18,5 +18,5 @@ contract C {
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// Warning 6328: (189-203): Assertion violation happens here
|
||||
// Warning 2661: (146-149): Overflow (resulting value larger than 2**256 - 1) happens here
|
||||
// Warning 6328: (189-203): Assertion violation happens here.
|
||||
// Warning 2661: (146-149): Overflow (resulting value larger than 2**256 - 1) happens here.
|
||||
|
||||
@@ -25,4 +25,4 @@ contract C {
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// Warning 6328: (286-303): Assertion violation happens here
|
||||
// Warning 6328: (286-303): Assertion violation happens here.
|
||||
|
||||
@@ -23,4 +23,4 @@ contract C {
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// Warning 6328: (256-273): Assertion violation happens here
|
||||
// Warning 6328: (256-273): Assertion violation happens here.
|
||||
|
||||
@@ -27,4 +27,4 @@ contract C {
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// Warning 6328: (307-321): Assertion violation happens here
|
||||
// Warning 6328: (307-321): Assertion violation happens here.
|
||||
|
||||
@@ -13,4 +13,4 @@ contract A is C {
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// Warning 6328: (152-166): Assertion violation happens here
|
||||
// Warning 6328: (152-166): Assertion violation happens here.
|
||||
|
||||
@@ -4,4 +4,4 @@ contract A is C { constructor() C(2) { assert(a == 2); } }
|
||||
contract B is C { constructor() C(3) { assert(a == 3); } }
|
||||
contract J is C { constructor() C(3) { assert(a == 4); } }
|
||||
// ----
|
||||
// Warning 6328: (243-257): Assertion violation happens here
|
||||
// Warning 6328: (243-257): Assertion violation happens here.
|
||||
|
||||
@@ -19,6 +19,6 @@ contract A is B {
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// Warning 4984: (203-208): Overflow (resulting value larger than 2**256 - 1) happens here
|
||||
// Warning 4984: (244-249): Overflow (resulting value larger than 2**256 - 1) happens here
|
||||
// Warning 6328: (232-250): Assertion violation happens here
|
||||
// Warning 4984: (203-208): Overflow (resulting value larger than 2**256 - 1) happens here.
|
||||
// Warning 4984: (244-249): Overflow (resulting value larger than 2**256 - 1) happens here.
|
||||
// Warning 6328: (232-250): Assertion violation happens here.
|
||||
|
||||
@@ -18,6 +18,6 @@ contract A is B {
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// Warning 4984: (198-203): Overflow (resulting value larger than 2**256 - 1) happens here
|
||||
// Warning 4984: (207-212): Overflow (resulting value larger than 2**256 - 1) happens here
|
||||
// Warning 4984: (230-235): Overflow (resulting value larger than 2**256 - 1) happens here
|
||||
// Warning 4984: (198-203): Overflow (resulting value larger than 2**256 - 1) happens here.
|
||||
// Warning 4984: (207-212): Overflow (resulting value larger than 2**256 - 1) happens here.
|
||||
// Warning 4984: (230-235): Overflow (resulting value larger than 2**256 - 1) happens here.
|
||||
|
||||
@@ -25,6 +25,6 @@ contract A is B2, B1 {
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// Warning 4984: (200-205): Overflow (resulting value larger than 2**256 - 1) happens here
|
||||
// Warning 4984: (314-319): Overflow (resulting value larger than 2**256 - 1) happens here
|
||||
// Warning 6328: (302-320): Assertion violation happens here
|
||||
// Warning 4984: (200-205): Overflow (resulting value larger than 2**256 - 1) happens here.
|
||||
// Warning 4984: (314-319): Overflow (resulting value larger than 2**256 - 1) happens here.
|
||||
// Warning 6328: (302-320): Assertion violation happens here.
|
||||
|
||||
@@ -25,6 +25,6 @@ contract A is B2, B1 {
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// Warning 4984: (200-205): Overflow (resulting value larger than 2**256 - 1) happens here
|
||||
// Warning 4984: (314-319): Overflow (resulting value larger than 2**256 - 1) happens here
|
||||
// Warning 6328: (302-320): Assertion violation happens here
|
||||
// Warning 4984: (200-205): Overflow (resulting value larger than 2**256 - 1) happens here.
|
||||
// Warning 4984: (314-319): Overflow (resulting value larger than 2**256 - 1) happens here.
|
||||
// Warning 6328: (302-320): Assertion violation happens here.
|
||||
|
||||
@@ -27,7 +27,7 @@ contract A is B2, B1 {
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// Warning 4984: (160-165): Overflow (resulting value larger than 2**256 - 1) happens here
|
||||
// Warning 4984: (225-230): Overflow (resulting value larger than 2**256 - 1) happens here
|
||||
// Warning 4984: (241-246): Overflow (resulting value larger than 2**256 - 1) happens here
|
||||
// Warning 6328: (334-350): Assertion violation happens here
|
||||
// Warning 4984: (160-165): Overflow (resulting value larger than 2**256 - 1) happens here.
|
||||
// Warning 4984: (225-230): Overflow (resulting value larger than 2**256 - 1) happens here.
|
||||
// Warning 4984: (241-246): Overflow (resulting value larger than 2**256 - 1) happens here.
|
||||
// Warning 6328: (334-350): Assertion violation happens here.
|
||||
|
||||
+1
-1
@@ -20,4 +20,4 @@ contract A is B, B2 {
|
||||
}
|
||||
// ----
|
||||
// Warning 5667: (164-170): Unused function parameter. Remove or comment out the variable name to silence this warning.
|
||||
// Warning 6328: (194-208): Assertion violation happens here
|
||||
// Warning 6328: (194-208): Assertion violation happens here.
|
||||
|
||||
@@ -19,4 +19,4 @@ contract A is B {
|
||||
}
|
||||
// ----
|
||||
// Warning 5667: (194-200): Unused function parameter. Remove or comment out the variable name to silence this warning.
|
||||
// Warning 6328: (224-238): Assertion violation happens here
|
||||
// Warning 6328: (224-238): Assertion violation happens here.
|
||||
|
||||
@@ -17,4 +17,4 @@ contract A is B {
|
||||
}
|
||||
// ----
|
||||
// Warning 5667: (138-144): Unused function parameter. Remove or comment out the variable name to silence this warning.
|
||||
// Warning 6328: (172-186): Assertion violation happens here
|
||||
// Warning 6328: (172-186): Assertion violation happens here.
|
||||
|
||||
+1
-1
@@ -16,4 +16,4 @@ contract A is B {
|
||||
}
|
||||
// ----
|
||||
// Warning 5667: (138-144): Unused function parameter. Remove or comment out the variable name to silence this warning.
|
||||
// Warning 6328: (150-164): Assertion violation happens here
|
||||
// Warning 6328: (150-164): Assertion violation happens here.
|
||||
|
||||
@@ -27,4 +27,4 @@ contract A is B {
|
||||
}
|
||||
// ----
|
||||
// Warning 5667: (254-260): Unused function parameter. Remove or comment out the variable name to silence this warning.
|
||||
// Warning 6328: (284-298): Assertion violation happens here
|
||||
// Warning 6328: (284-298): Assertion violation happens here.
|
||||
|
||||
+1
-1
@@ -32,4 +32,4 @@ contract A is B {
|
||||
}
|
||||
// ----
|
||||
// Warning 5667: (296-302): Unused function parameter. Remove or comment out the variable name to silence this warning.
|
||||
// Warning 6328: (357-372): Assertion violation happens here
|
||||
// Warning 6328: (357-372): Assertion violation happens here.
|
||||
|
||||
+2
-2
@@ -25,5 +25,5 @@ contract A is B {
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// Warning 4984: (247-252): Overflow (resulting value larger than 2**256 - 1) happens here
|
||||
// Warning 6328: (328-342): Assertion violation happens here
|
||||
// Warning 4984: (247-252): Overflow (resulting value larger than 2**256 - 1) happens here.
|
||||
// Warning 6328: (328-342): Assertion violation happens here.
|
||||
|
||||
+1
-1
@@ -23,4 +23,4 @@ contract B is C {
|
||||
contract A is B {
|
||||
}
|
||||
// ----
|
||||
// Warning 6328: (266-280): Assertion violation happens here
|
||||
// Warning 6328: (266-280): Assertion violation happens here.
|
||||
|
||||
@@ -14,4 +14,4 @@ contract A is C {
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// Warning 6328: (188-202): Assertion violation happens here
|
||||
// Warning 6328: (188-202): Assertion violation happens here.
|
||||
|
||||
@@ -13,5 +13,5 @@ contract A is C {
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// Warning 6328: (134-148): Assertion violation happens here
|
||||
// Warning 6328: (152-168): Assertion violation happens here
|
||||
// Warning 6328: (134-148): Assertion violation happens here.
|
||||
// Warning 6328: (152-168): Assertion violation happens here.
|
||||
|
||||
@@ -13,4 +13,4 @@ contract C {
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// Warning 6328: (141-155): Assertion violation happens here
|
||||
// Warning 6328: (141-155): Assertion violation happens here.
|
||||
|
||||
@@ -13,4 +13,4 @@ contract C {
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// Warning 6328: (145-159): Assertion violation happens here
|
||||
// Warning 6328: (145-159): Assertion violation happens here.
|
||||
|
||||
@@ -15,4 +15,4 @@ contract C is B {
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// Warning 6328: (165-179): Assertion violation happens here
|
||||
// Warning 6328: (165-179): Assertion violation happens here.
|
||||
|
||||
@@ -13,5 +13,5 @@ contract C {
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// Warning 4984: (115-120): Overflow (resulting value larger than 2**256 - 1) happens here
|
||||
// Warning 6328: (162-176): Assertion violation happens here
|
||||
// Warning 4984: (115-120): Overflow (resulting value larger than 2**256 - 1) happens here.
|
||||
// Warning 6328: (162-176): Assertion violation happens here.
|
||||
|
||||
@@ -9,4 +9,4 @@ contract C {
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// Warning 6328: (116-132): Assertion violation happens here
|
||||
// Warning 6328: (116-132): Assertion violation happens here.
|
||||
|
||||
+1
-1
@@ -16,4 +16,4 @@ contract C
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// Warning 6328: (209-223): Assertion violation happens here
|
||||
// Warning 6328: (209-223): Assertion violation happens here.
|
||||
|
||||
+2
-2
@@ -24,5 +24,5 @@ contract C
|
||||
|
||||
}
|
||||
// ----
|
||||
// Warning 6328: (209-223): Assertion violation happens here
|
||||
// Warning 6328: (321-335): Assertion violation happens here
|
||||
// Warning 6328: (209-223): Assertion violation happens here.
|
||||
// Warning 6328: (321-335): Assertion violation happens here.
|
||||
|
||||
@@ -18,4 +18,4 @@ contract C
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// Warning 6328: (261-277): Assertion violation happens here
|
||||
// Warning 6328: (261-277): Assertion violation happens here.
|
||||
|
||||
@@ -17,4 +17,5 @@ contract C
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// Warning 4661: (297-321): Assertion violation happens here
|
||||
// Warning 1218: (297-321): Error trying to invoke SMT solver.
|
||||
// Warning 4661: (297-321): Assertion violation happens here.
|
||||
|
||||
@@ -16,4 +16,4 @@ contract D
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// Warning 6328: (191-206): Assertion violation happens here
|
||||
// Warning 6328: (191-206): Assertion violation happens here.
|
||||
|
||||
@@ -12,4 +12,4 @@ contract C
|
||||
}
|
||||
|
||||
// ----
|
||||
// Warning 6328: (161-174): Assertion violation happens here
|
||||
// Warning 6328: (161-174): Assertion violation happens here.
|
||||
|
||||
@@ -16,4 +16,4 @@ contract C
|
||||
}
|
||||
|
||||
// ----
|
||||
// Warning 6328: (229-242): Assertion violation happens here
|
||||
// Warning 6328: (229-242): Assertion violation happens here.
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user