mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Merge pull request #9106 from ethereum/develop
Merge develop into breaking.
This commit is contained in:
@@ -116,11 +116,11 @@ void CommonSyntaxTest::printSource(ostream& _stream, string const& _linePrefix,
|
||||
for (int i = error.locationStart; i < error.locationEnd; i++)
|
||||
if (isWarning)
|
||||
{
|
||||
if (sourceFormatting[i] == formatting::RESET)
|
||||
sourceFormatting[i] = formatting::ORANGE_BACKGROUND_256;
|
||||
if (sourceFormatting[static_cast<size_t>(i)] == formatting::RESET)
|
||||
sourceFormatting[static_cast<size_t>(i)] = formatting::ORANGE_BACKGROUND_256;
|
||||
}
|
||||
else
|
||||
sourceFormatting[i] = formatting::RED_BACKGROUND;
|
||||
sourceFormatting[static_cast<size_t>(i)] = formatting::RED_BACKGROUND;
|
||||
}
|
||||
|
||||
_stream << _linePrefix << sourceFormatting.front() << source.front();
|
||||
|
||||
+1
-1
@@ -223,7 +223,7 @@ evmc::result EVMHost::call(evmc_message const& _message) noexcept
|
||||
|
||||
if (message.kind == EVMC_CREATE || message.kind == EVMC_CREATE2)
|
||||
{
|
||||
result.gas_left -= evmasm::GasCosts::createDataGas * result.output_size;
|
||||
result.gas_left -= static_cast<int64_t>(evmasm::GasCosts::createDataGas * result.output_size);
|
||||
if (result.gas_left < 0)
|
||||
{
|
||||
result.gas_left = 0;
|
||||
|
||||
@@ -101,7 +101,9 @@ u256 ExecutionFramework::gasPrice() const
|
||||
|
||||
u256 ExecutionFramework::blockHash(u256 const& _number) const
|
||||
{
|
||||
return {EVMHost::convertFromEVMC(m_evmHost->get_block_hash(uint64_t(_number & numeric_limits<uint64_t>::max())))};
|
||||
return {EVMHost::convertFromEVMC(
|
||||
m_evmHost->get_block_hash(static_cast<int64_t>(_number & numeric_limits<uint64_t>::max()))
|
||||
)};
|
||||
}
|
||||
|
||||
u256 ExecutionFramework::blockNumber() const
|
||||
@@ -153,7 +155,7 @@ void ExecutionFramework::sendMessage(bytes const& _data, bool _isCreation, u256
|
||||
if (m_showMessages)
|
||||
{
|
||||
cout << " out: " << toHex(m_output) << endl;
|
||||
cout << " result: " << size_t(result.status_code) << endl;
|
||||
cout << " result: " << static_cast<size_t>(result.status_code) << endl;
|
||||
cout << " gas used: " << m_gasUsed.str() << endl;
|
||||
}
|
||||
}
|
||||
@@ -180,7 +182,7 @@ void ExecutionFramework::sendEther(Address const& _addr, u256 const& _amount)
|
||||
|
||||
size_t ExecutionFramework::currentTimestamp()
|
||||
{
|
||||
return m_evmHost->tx_context.block_timestamp;
|
||||
return static_cast<size_t>(m_evmHost->tx_context.block_timestamp);
|
||||
}
|
||||
|
||||
size_t ExecutionFramework::blockTimestamp(u256 _block)
|
||||
@@ -188,7 +190,7 @@ size_t ExecutionFramework::blockTimestamp(u256 _block)
|
||||
if (_block > blockNumber())
|
||||
return 0;
|
||||
else
|
||||
return size_t((currentTimestamp() / blockNumber()) * _block);
|
||||
return static_cast<size_t>((currentTimestamp() / blockNumber()) * _block);
|
||||
}
|
||||
|
||||
Address ExecutionFramework::account(size_t _idx)
|
||||
|
||||
+2
-2
@@ -36,14 +36,14 @@ bytes onlyMetadata(bytes const& _bytecode)
|
||||
unsigned size = _bytecode.size();
|
||||
if (size < 5)
|
||||
return bytes{};
|
||||
size_t metadataSize = (_bytecode[size - 2] << 8) + _bytecode[size - 1];
|
||||
size_t metadataSize = (static_cast<size_t>(_bytecode[size - 2]) << 8ul) + static_cast<size_t>(_bytecode[size - 1]);
|
||||
if (size < (metadataSize + 2))
|
||||
return bytes{};
|
||||
// Sanity check: assume the first byte is a fixed-size CBOR array with 1, 2 or 3 entries
|
||||
unsigned char firstByte = _bytecode[size - metadataSize - 2];
|
||||
if (firstByte != 0xa1 && firstByte != 0xa2 && firstByte != 0xa3)
|
||||
return bytes{};
|
||||
return bytes(_bytecode.end() - metadataSize - 2, _bytecode.end() - 2);
|
||||
return bytes(_bytecode.end() - static_cast<ptrdiff_t>(metadataSize) - 2, _bytecode.end() - 2);
|
||||
}
|
||||
|
||||
bytes bytecodeSansMetadata(bytes const& _bytecode)
|
||||
|
||||
+31
-2
@@ -18,11 +18,13 @@
|
||||
#include <test/Common.h>
|
||||
#include <test/TestCase.h>
|
||||
|
||||
#include <libsolutil/AnsiColorized.h>
|
||||
|
||||
#include <boost/algorithm/string.hpp>
|
||||
#include <boost/algorithm/string/predicate.hpp>
|
||||
#include <boost/algorithm/string.hpp>
|
||||
|
||||
#include <stdexcept>
|
||||
#include <iostream>
|
||||
#include <stdexcept>
|
||||
|
||||
using namespace std;
|
||||
using namespace solidity;
|
||||
@@ -78,6 +80,33 @@ void TestCase::printIndented(ostream& _stream, string const& _output, string con
|
||||
_stream << _linePrefix << line << endl;
|
||||
}
|
||||
|
||||
void TestCase::printSource(ostream& _stream, string const& _linePrefix, bool const) const
|
||||
{
|
||||
printIndented(_stream, m_source, _linePrefix);
|
||||
}
|
||||
|
||||
void TestCase::printUpdatedExpectations(ostream& _stream, string const& _linePrefix) const
|
||||
{
|
||||
printIndented(_stream, m_obtainedResult, _linePrefix);
|
||||
}
|
||||
|
||||
TestCase::TestResult TestCase::checkResult(std::ostream& _stream, const std::string& _linePrefix, bool const _formatted)
|
||||
{
|
||||
if (m_expectation != m_obtainedResult)
|
||||
{
|
||||
string nextIndentLevel = _linePrefix + " ";
|
||||
util::AnsiColorized(_stream, _formatted, {util::formatting::BOLD, util::formatting::CYAN})
|
||||
<< _linePrefix << "Expected result:" << endl;
|
||||
// TODO could compute a simple diff with highlighted lines
|
||||
printIndented(_stream, m_expectation, nextIndentLevel);
|
||||
util::AnsiColorized(_stream, _formatted, {util::formatting::BOLD, util::formatting::CYAN})
|
||||
<< _linePrefix << "Obtained result:" << endl;
|
||||
printIndented(_stream, m_obtainedResult, nextIndentLevel);
|
||||
return TestResult::Failure;
|
||||
}
|
||||
return TestResult::Success;
|
||||
}
|
||||
|
||||
EVMVersionRestrictedTestCase::EVMVersionRestrictedTestCase(string const& _filename):
|
||||
TestCase(_filename)
|
||||
{
|
||||
|
||||
+7
-2
@@ -57,14 +57,14 @@ public:
|
||||
/// Each line of output is prefixed with @arg _linePrefix.
|
||||
/// If @arg _formatted is true, color-coding may be used to indicate
|
||||
/// error locations in the contract, if applicable.
|
||||
virtual void printSource(std::ostream &_stream, std::string const &_linePrefix = "", bool const _formatted = false) const = 0;
|
||||
virtual void printSource(std::ostream &_stream, std::string const &_linePrefix = "", bool const _formatted = false) const;
|
||||
/// Outputs settings.
|
||||
virtual void printSettings(std::ostream &_stream, std::string const &_linePrefix = "", bool const _formatted = false);
|
||||
/// Outputs updated settings
|
||||
virtual void printUpdatedSettings(std::ostream& _stream, std::string const& _linePrefix = "");
|
||||
/// Outputs test expectations to @arg _stream that match the actual results of the test.
|
||||
/// Each line of output is prefixed with @arg _linePrefix.
|
||||
virtual void printUpdatedExpectations(std::ostream& _stream, std::string const& _linePrefix) const = 0;
|
||||
virtual void printUpdatedExpectations(std::ostream& _stream, std::string const& _linePrefix) const;
|
||||
|
||||
static bool isTestFilename(boost::filesystem::path const& _filename);
|
||||
|
||||
@@ -97,6 +97,11 @@ protected:
|
||||
}
|
||||
|
||||
void printIndented(std::ostream& _stream, std::string const& _output, std::string const& _linePrefix = "") const;
|
||||
TestCase::TestResult checkResult(std::ostream& _stream, const std::string& _linePrefix, bool const _formatted);
|
||||
|
||||
std::string m_source;
|
||||
std::string m_obtainedResult;
|
||||
std::string m_expectation;
|
||||
|
||||
TestCaseReader m_reader;
|
||||
bool m_shouldRun = true;
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
Warning: SPDX license identifier not provided in source file. Before publishing, consider adding a comment containing "SPDX-License-Identifier: <SPDX-License>" to each source file. Use "SPDX-License-Identifier: UNLICENSED" for non-open-source code. Please see https://spdx.org for more information.
|
||||
--> message_format_utf16/input.sol
|
||||
|
||||
Warning: Source file does not specify required compiler version!
|
||||
--> message_format_utf16/input.sol
|
||||
|
||||
Warning: Statement has no effect.
|
||||
--> message_format_utf16/input.sol:2:58:
|
||||
|
|
||||
2 | /* ©©©©ᄅ©©©©© 2017 */ constructor () public { "©©©©ᄅ©©©©©" ; }
|
||||
| ^^^^^^^^^^^^
|
||||
@@ -1,3 +0,0 @@
|
||||
contract Foo {
|
||||
/* ©©©©ᄅ©©©©© 2017 */ constructor () public { "©©©©ᄅ©©©©©" ; }
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
Warning: SPDX license identifier not provided in source file. Before publishing, consider adding a comment containing "SPDX-License-Identifier: <SPDX-License>" to each source file. Use "SPDX-License-Identifier: UNLICENSED" for non-open-source code. Please see https://spdx.org for more information.
|
||||
--> message_format_utf8/input.sol
|
||||
|
||||
Warning: Source file does not specify required compiler version!
|
||||
--> message_format_utf8/input.sol
|
||||
|
||||
Warning: Statement has no effect.
|
||||
--> message_format_utf8/input.sol:2:58:
|
||||
|
|
||||
2 | /* ©©©©ᄅ©©©©© 2017 */ constructor () public { "©©©©ᄅ©©©©©" ; }
|
||||
| ^^^^^^^^^^^^
|
||||
|
||||
Warning: Statement has no effect.
|
||||
--> message_format_utf8/input.sol:6:25:
|
||||
|
|
||||
6 | "S = π × r²";
|
||||
| ^^^^^^^^^^^^
|
||||
|
||||
Warning: Statement has no effect.
|
||||
--> message_format_utf8/input.sol:7:39:
|
||||
|
|
||||
7 | /* ₀₁₂₃₄⁵⁶⁷⁸⁹ */ "∑ 1/n! ≈ 2.7"; // tabs in-between
|
||||
| ^^^^^^^^^^^^^^
|
||||
|
||||
Warning: Statement has no effect.
|
||||
--> message_format_utf8/input.sol:8:30:
|
||||
|
|
||||
8 | /* Ŀŏŗėɯ ïƥŝʉɱ */ "μὴ χεῖρον βέλτιστον"; // tabs in-between and inside
|
||||
| ^^^ ^^^^^^ ^^^^^^^^^^
|
||||
|
||||
Warning: Function state mutability can be restricted to pure
|
||||
--> message_format_utf8/input.sol:12:2:
|
||||
|
|
||||
12 | function selector() public returns(uint) { // starts with tab
|
||||
| ^ (Relevant source part starts here and spans across multiple lines).
|
||||
@@ -0,0 +1,15 @@
|
||||
contract Foo {
|
||||
/* ©©©©ᄅ©©©©© 2017 */ constructor () public { "©©©©ᄅ©©©©©" ; }
|
||||
|
||||
function f() public pure {
|
||||
|
||||
"S = π × r²";
|
||||
/* ₀₁₂₃₄⁵⁶⁷⁸⁹ */ "∑ 1/n! ≈ 2.7"; // tabs in-between
|
||||
/* Ŀŏŗėɯ ïƥŝʉɱ */ "μὴ χεῖρον βέλτιστον"; // tabs in-between and inside
|
||||
|
||||
}
|
||||
|
||||
function selector() public returns(uint) { // starts with tab
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -19,20 +19,14 @@ EVM assembly:
|
||||
sstore
|
||||
/* "optimizer_BlockDeDuplicator/input.sol":60:213 contract C {... */
|
||||
callvalue
|
||||
/* "--CODEGEN--":2:4 */
|
||||
dup1
|
||||
iszero
|
||||
tag_5
|
||||
jumpi
|
||||
/* "--CODEGEN--":27:28 */
|
||||
0x00
|
||||
/* "--CODEGEN--":24:25 */
|
||||
dup1
|
||||
/* "--CODEGEN--":17:29 */
|
||||
revert
|
||||
/* "--CODEGEN--":2:4 */
|
||||
tag_5:
|
||||
/* "optimizer_BlockDeDuplicator/input.sol":60:213 contract C {... */
|
||||
pop
|
||||
jump(tag_6)
|
||||
/* "optimizer_BlockDeDuplicator/input.sol":77:103 function fun_x() public {} */
|
||||
@@ -53,21 +47,14 @@ sub_0: assembly {
|
||||
/* "optimizer_BlockDeDuplicator/input.sol":60:213 contract C {... */
|
||||
mstore(0x40, 0x80)
|
||||
callvalue
|
||||
/* "--CODEGEN--":5:14 */
|
||||
dup1
|
||||
/* "--CODEGEN--":2:4 */
|
||||
iszero
|
||||
tag_1
|
||||
jumpi
|
||||
/* "--CODEGEN--":27:28 */
|
||||
0x00
|
||||
/* "--CODEGEN--":24:25 */
|
||||
dup1
|
||||
/* "--CODEGEN--":17:29 */
|
||||
revert
|
||||
/* "--CODEGEN--":2:4 */
|
||||
tag_1:
|
||||
/* "optimizer_BlockDeDuplicator/input.sol":60:213 contract C {... */
|
||||
pop
|
||||
jumpi(tag_2, lt(calldatasize, 0x04))
|
||||
shr(0xe0, calldataload(0x00))
|
||||
@@ -87,11 +74,8 @@ sub_0: assembly {
|
||||
tag_3
|
||||
jumpi
|
||||
tag_2:
|
||||
/* "--CODEGEN--":12:13 */
|
||||
0x00
|
||||
/* "--CODEGEN--":9:10 */
|
||||
dup1
|
||||
/* "--CODEGEN--":2:14 */
|
||||
revert
|
||||
/* "optimizer_BlockDeDuplicator/input.sol":138:174 function f() public { true ? 1 : 3;} */
|
||||
tag_3:
|
||||
|
||||
@@ -76,11 +76,8 @@ stop
|
||||
sub_0: assembly {
|
||||
/* "optimizer_user_yul/input.sol":60:525 contract C... */
|
||||
mstore(0x40, 0x80)
|
||||
/* "--CODEGEN--":12:13 */
|
||||
0x00
|
||||
/* "--CODEGEN--":9:10 */
|
||||
dup1
|
||||
/* "--CODEGEN--":2:14 */
|
||||
revert
|
||||
|
||||
auxdata: AUXDATA REMOVED
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
{"contracts":{"a.sol":{"A":{"evm":{"deployedBytecode":{"immutableReferences":{"3":[{"length":32,"start":77}]},"linkReferences":{},"object":"bytecode removed","opcodes":"opcodes removed","sourceMap":"36:96:0:-:0;;;;5:9:-1;2:2;;;27:1;24;17:12;2:2;36:96:0;;;;;;;;;;;;;;;;12:1:-1;9;2:12;74:56:0;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;108:7;126:1;119:8;;74:56;:::o"}}}}},"errors":[{"component":"general","formattedMessage":"a.sol: Warning: Source file does not specify required compiler version!
|
||||
{"contracts":{"a.sol":{"A":{"evm":{"deployedBytecode":{"immutableReferences":{"3":[{"length":32,"start":77}]},"linkReferences":{},"object":"bytecode removed","opcodes":"opcodes removed","sourceMap":"36:96:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;74:56;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;108:7;126:1;119:8;;74:56;:::o"}}}}},"errors":[{"component":"general","formattedMessage":"a.sol: Warning: Source file does not specify required compiler version!
|
||||
","message":"Source file does not specify required compiler version!","severity":"warning","sourceLocation":{"end":-1,"file":"a.sol","start":-1},"type":"Warning"}],"sources":{"a.sol":{"id":0}}}
|
||||
|
||||
@@ -64,25 +64,6 @@ TestCase::TestResult ABIJsonTest::run(ostream& _stream, string const& _linePrefi
|
||||
m_obtainedResult += jsonPrettyPrint(compiler.contractABI(contractName)) + "\n";
|
||||
first = false;
|
||||
}
|
||||
if (m_expectation != m_obtainedResult)
|
||||
{
|
||||
string nextIndentLevel = _linePrefix + " ";
|
||||
AnsiColorized(_stream, _formatted, {formatting::BOLD, formatting::CYAN}) << _linePrefix << "Expected result:" << endl;
|
||||
printIndented(_stream, m_expectation, nextIndentLevel);
|
||||
AnsiColorized(_stream, _formatted, {formatting::BOLD, formatting::CYAN}) << _linePrefix << "Obtained result:" << endl;
|
||||
printIndented(_stream, m_obtainedResult, nextIndentLevel);
|
||||
return TestResult::Failure;
|
||||
}
|
||||
return TestResult::Success;
|
||||
}
|
||||
|
||||
|
||||
void ABIJsonTest::printSource(ostream& _stream, string const& _linePrefix, bool const) const
|
||||
{
|
||||
printIndented(_stream, m_source, _linePrefix);
|
||||
}
|
||||
|
||||
void ABIJsonTest::printUpdatedExpectations(ostream& _stream, string const& _linePrefix) const
|
||||
{
|
||||
printIndented(_stream, m_obtainedResult, _linePrefix);
|
||||
return checkResult(_stream, _linePrefix, _formatted);
|
||||
}
|
||||
|
||||
@@ -36,14 +36,6 @@ public:
|
||||
ABIJsonTest(std::string const& _filename);
|
||||
|
||||
TestResult run(std::ostream& _stream, std::string const& _linePrefix = "", bool const _formatted = false) override;
|
||||
|
||||
void printSource(std::ostream& _stream, std::string const& _linePrefix = "", bool const _formatted = false) const override;
|
||||
void printUpdatedExpectations(std::ostream& _stream, std::string const& _linePrefix) const override;
|
||||
|
||||
private:
|
||||
std::string m_source;
|
||||
std::string m_expectation;
|
||||
std::string m_obtainedResult;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -41,7 +41,6 @@ public:
|
||||
void printUpdatedExpectations(std::ostream& _stream, std::string const& _linePrefix) const override;
|
||||
private:
|
||||
std::vector<std::pair<std::string, std::string>> m_sources;
|
||||
std::string m_expectation;
|
||||
std::string m_expectationLegacy;
|
||||
std::string m_astFilename;
|
||||
std::string m_legacyAstFilename;
|
||||
|
||||
@@ -107,13 +107,13 @@ void printAssemblyLocations(AssemblyItems const& _items)
|
||||
cout <<
|
||||
"\t\tvector<SourceLocation>(" <<
|
||||
_repetitions <<
|
||||
", SourceLocation(" <<
|
||||
", SourceLocation{" <<
|
||||
_loc.start <<
|
||||
", " <<
|
||||
_loc.end <<
|
||||
", make_shared<string>(\"" <<
|
||||
_loc.source->name() <<
|
||||
"\"))) +" << endl;
|
||||
"\")}) +" << endl;
|
||||
};
|
||||
|
||||
vector<SourceLocation> locations;
|
||||
@@ -175,33 +175,13 @@ BOOST_AUTO_TEST_CASE(location_test)
|
||||
vector<SourceLocation> locations;
|
||||
if (solidity::test::CommonOptions::get().optimize)
|
||||
locations =
|
||||
vector<SourceLocation>(4, SourceLocation{2, 82, sourceCode}) +
|
||||
vector<SourceLocation>(1, SourceLocation{5, 14, codegenCharStream}) +
|
||||
vector<SourceLocation>(3, SourceLocation{2, 4, codegenCharStream}) +
|
||||
vector<SourceLocation>(1, SourceLocation{27, 28, codegenCharStream}) +
|
||||
vector<SourceLocation>(1, SourceLocation{24, 25, codegenCharStream}) +
|
||||
vector<SourceLocation>(1, SourceLocation{17, 29, codegenCharStream}) +
|
||||
vector<SourceLocation>(1, SourceLocation{2, 4, codegenCharStream}) +
|
||||
vector<SourceLocation>(16, SourceLocation{2, 82, sourceCode}) +
|
||||
vector<SourceLocation>(1, SourceLocation{12, 13, codegenCharStream}) +
|
||||
vector<SourceLocation>(1, SourceLocation{9, 10, codegenCharStream}) +
|
||||
vector<SourceLocation>(1, SourceLocation{2, 14, codegenCharStream}) +
|
||||
vector<SourceLocation>(31, SourceLocation{2, 82, sourceCode}) +
|
||||
vector<SourceLocation>(21, SourceLocation{20, 79, sourceCode}) +
|
||||
vector<SourceLocation>(1, SourceLocation{72, 74, sourceCode}) +
|
||||
vector<SourceLocation>(2, SourceLocation{20, 79, sourceCode});
|
||||
else
|
||||
locations =
|
||||
vector<SourceLocation>(4, SourceLocation{2, 82, sourceCode}) +
|
||||
vector<SourceLocation>(1, SourceLocation{5, 14, codegenCharStream}) +
|
||||
vector<SourceLocation>(3, SourceLocation{2, 4, codegenCharStream}) +
|
||||
vector<SourceLocation>(1, SourceLocation{27, 28, codegenCharStream}) +
|
||||
vector<SourceLocation>(1, SourceLocation{24, 25, codegenCharStream}) +
|
||||
vector<SourceLocation>(1, SourceLocation{17, 29, codegenCharStream}) +
|
||||
vector<SourceLocation>(1, SourceLocation{2, 4, codegenCharStream}) +
|
||||
vector<SourceLocation>(hasShifts ? 16 : 17, SourceLocation{2, 82, sourceCode}) +
|
||||
vector<SourceLocation>(1, SourceLocation{12, 13, codegenCharStream}) +
|
||||
vector<SourceLocation>(1, SourceLocation{9, 10, codegenCharStream}) +
|
||||
vector<SourceLocation>(1, SourceLocation{2, 14, codegenCharStream}) +
|
||||
vector<SourceLocation>(hasShifts ? 31 : 32, SourceLocation{2, 82, sourceCode}) +
|
||||
vector<SourceLocation>(24, SourceLocation{20, 79, sourceCode}) +
|
||||
vector<SourceLocation>(1, SourceLocation{49, 58, sourceCode}) +
|
||||
vector<SourceLocation>(1, SourceLocation{72, 74, sourceCode}) +
|
||||
|
||||
@@ -47,7 +47,6 @@ private:
|
||||
bool m_optimise = false;
|
||||
bool m_optimiseYul = false;
|
||||
size_t m_optimiseRuns = 200;
|
||||
std::string m_source;
|
||||
std::map<std::string, std::map<std::string, std::string>> m_expectations;
|
||||
};
|
||||
|
||||
|
||||
@@ -62,6 +62,8 @@ SemanticTest::SemanticTest(string const& _filename, langutil::EVMVersion _evmVer
|
||||
{
|
||||
m_runWithYul = false;
|
||||
m_runWithoutYul = true;
|
||||
// Do not try to run via yul if explicitly denied.
|
||||
m_enforceViaYul = false;
|
||||
}
|
||||
else
|
||||
BOOST_THROW_EXCEPTION(runtime_error("Invalid compileViaYul value: " + choice + "."));
|
||||
|
||||
@@ -66,20 +66,15 @@ bytes SolidityExecutionFramework::compileContract(
|
||||
if (m_compileViaYul)
|
||||
{
|
||||
yul::AssemblyStack asmStack(
|
||||
m_evmVersion,
|
||||
yul::AssemblyStack::Language::StrictAssembly,
|
||||
// Ignore optimiser settings here because we need Yul optimisation to
|
||||
// get code that does not exhaust the stack.
|
||||
OptimiserSettings::full()
|
||||
);
|
||||
if (!asmStack.parseAndAnalyze("", m_compiler.yulIROptimized(contractName)))
|
||||
{
|
||||
langutil::SourceReferenceFormatter formatter(std::cerr);
|
||||
m_evmVersion,
|
||||
yul::AssemblyStack::Language::StrictAssembly,
|
||||
// Ignore optimiser settings here because we need Yul optimisation to
|
||||
// get code that does not exhaust the stack.
|
||||
OptimiserSettings::full()
|
||||
);
|
||||
bool analysisSuccessful = asmStack.parseAndAnalyze("", m_compiler.yulIROptimized(contractName));
|
||||
solAssert(analysisSuccessful, "Code that passed analysis in CompilerStack can't have errors");
|
||||
|
||||
for (auto const& error: m_compiler.errors())
|
||||
formatter.printErrorInformation(*error);
|
||||
BOOST_ERROR("Assembly contract failed. IR: " + m_compiler.yulIROptimized({}));
|
||||
}
|
||||
asmStack.optimize();
|
||||
obj = std::move(*asmStack.assemble(yul::AssemblyStack::Machine::EVM).bytecode);
|
||||
}
|
||||
|
||||
@@ -370,15 +370,15 @@ BOOST_AUTO_TEST_CASE(basic_compilation)
|
||||
BOOST_CHECK(contract["evm"]["assembly"].isString());
|
||||
BOOST_CHECK(contract["evm"]["assembly"].asString().find(
|
||||
" /* \"fileA\":0:14 contract A { } */\n mstore(0x40, 0x80)\n "
|
||||
"callvalue\n /* \"--CODEGEN--\":5:14 */\n dup1\n "
|
||||
"/* \"--CODEGEN--\":2:4 */\n iszero\n tag_1\n jumpi\n "
|
||||
"/* \"--CODEGEN--\":27:28 */\n 0x00\n /* \"--CODEGEN--\":24:25 */\n "
|
||||
"dup1\n /* \"--CODEGEN--\":17:29 */\n revert\n /* \"--CODEGEN--\":2:4 */\n"
|
||||
"tag_1:\n /* \"fileA\":0:14 contract A { } */\n pop\n dataSize(sub_0)\n dup1\n "
|
||||
"callvalue\n dup1\n "
|
||||
"iszero\n tag_1\n jumpi\n "
|
||||
"0x00\n "
|
||||
"dup1\n revert\n"
|
||||
"tag_1:\n pop\n dataSize(sub_0)\n dup1\n "
|
||||
"dataOffset(sub_0)\n 0x00\n codecopy\n 0x00\n return\nstop\n\nsub_0: assembly {\n "
|
||||
"/* \"fileA\":0:14 contract A { } */\n mstore(0x40, 0x80)\n "
|
||||
"/* \"--CODEGEN--\":12:13 */\n 0x00\n /* \"--CODEGEN--\":9:10 */\n "
|
||||
"dup1\n /* \"--CODEGEN--\":2:14 */\n revert\n\n auxdata: 0xa26469706673582212"
|
||||
"/* \"fileA\":0:14 contract A { } */\n mstore(0x40, 0x80)\n "
|
||||
"0x00\n "
|
||||
"dup1\n revert\n\n auxdata: 0xa26469706673582212"
|
||||
) == 0);
|
||||
BOOST_CHECK(contract["evm"]["gasEstimates"].isObject());
|
||||
BOOST_CHECK_EQUAL(contract["evm"]["gasEstimates"].size(), 1);
|
||||
@@ -402,15 +402,15 @@ BOOST_AUTO_TEST_CASE(basic_compilation)
|
||||
"{\"begin\":0,\"end\":14,\"name\":\"PUSH\",\"source\":0,\"value\":\"40\"},"
|
||||
"{\"begin\":0,\"end\":14,\"name\":\"MSTORE\",\"source\":0},"
|
||||
"{\"begin\":0,\"end\":14,\"name\":\"CALLVALUE\",\"source\":0},"
|
||||
"{\"begin\":5,\"end\":14,\"name\":\"DUP1\",\"source\":-1},"
|
||||
"{\"begin\":2,\"end\":4,\"name\":\"ISZERO\",\"source\":-1},"
|
||||
"{\"begin\":2,\"end\":4,\"name\":\"PUSH [tag]\",\"source\":-1,\"value\":\"1\"},"
|
||||
"{\"begin\":2,\"end\":4,\"name\":\"JUMPI\",\"source\":-1},"
|
||||
"{\"begin\":27,\"end\":28,\"name\":\"PUSH\",\"source\":-1,\"value\":\"0\"},"
|
||||
"{\"begin\":24,\"end\":25,\"name\":\"DUP1\",\"source\":-1},"
|
||||
"{\"begin\":17,\"end\":29,\"name\":\"REVERT\",\"source\":-1},"
|
||||
"{\"begin\":2,\"end\":4,\"name\":\"tag\",\"source\":-1,\"value\":\"1\"},"
|
||||
"{\"begin\":2,\"end\":4,\"name\":\"JUMPDEST\",\"source\":-1},"
|
||||
"{\"begin\":0,\"end\":14,\"name\":\"DUP1\",\"source\":0},"
|
||||
"{\"begin\":0,\"end\":14,\"name\":\"ISZERO\",\"source\":0},"
|
||||
"{\"begin\":0,\"end\":14,\"name\":\"PUSH [tag]\",\"source\":0,\"value\":\"1\"},"
|
||||
"{\"begin\":0,\"end\":14,\"name\":\"JUMPI\",\"source\":0},"
|
||||
"{\"begin\":0,\"end\":14,\"name\":\"PUSH\",\"source\":0,\"value\":\"0\"},"
|
||||
"{\"begin\":0,\"end\":14,\"name\":\"DUP1\",\"source\":0},"
|
||||
"{\"begin\":0,\"end\":14,\"name\":\"REVERT\",\"source\":0},"
|
||||
"{\"begin\":0,\"end\":14,\"name\":\"tag\",\"source\":0,\"value\":\"1\"},"
|
||||
"{\"begin\":0,\"end\":14,\"name\":\"JUMPDEST\",\"source\":0},"
|
||||
"{\"begin\":0,\"end\":14,\"name\":\"POP\",\"source\":0},"
|
||||
"{\"begin\":0,\"end\":14,\"name\":\"PUSH #[$]\",\"source\":0,\"value\":\"0000000000000000000000000000000000000000000000000000000000000000\"},"
|
||||
"{\"begin\":0,\"end\":14,\"name\":\"DUP1\",\"source\":0},"
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
pragma experimental SMTChecker;
|
||||
contract C {
|
||||
struct S {
|
||||
int[] b;
|
||||
}
|
||||
S s;
|
||||
struct T {
|
||||
S s;
|
||||
}
|
||||
T t;
|
||||
function f() public {
|
||||
s.b.push();
|
||||
t.s.b.push();
|
||||
}
|
||||
}
|
||||
|
||||
// ----
|
||||
// Warning: (72-75): Assertion checker does not yet support the type of this variable.
|
||||
// Warning: (100-103): Assertion checker does not yet support the type of this variable.
|
||||
// Warning: (130-133): Assertion checker does not yet support this expression.
|
||||
// Warning: (130-131): Assertion checker does not yet implement type struct C.S storage ref
|
||||
// Warning: (130-133): Assertion checker does not yet implement this expression.
|
||||
// Warning: (144-149): Assertion checker does not yet support this expression.
|
||||
// Warning: (144-147): Assertion checker does not yet implement type struct C.S storage ref
|
||||
// Warning: (144-147): Assertion checker does not yet support this expression.
|
||||
// Warning: (144-145): Assertion checker does not yet implement type struct C.T storage ref
|
||||
// Warning: (144-149): Assertion checker does not yet implement this expression.
|
||||
@@ -0,0 +1,33 @@
|
||||
pragma experimental SMTChecker;
|
||||
contract C {
|
||||
struct S {
|
||||
int[] b;
|
||||
}
|
||||
S s;
|
||||
struct T {
|
||||
S[] s;
|
||||
}
|
||||
T t;
|
||||
function f() public {
|
||||
s.b.push();
|
||||
t.s.push();
|
||||
t.s[0].b.push();
|
||||
}
|
||||
}
|
||||
|
||||
// ----
|
||||
// Warning: (72-75): Assertion checker does not yet support the type of this variable.
|
||||
// Warning: (102-105): Assertion checker does not yet support the type of this variable.
|
||||
// Warning: (132-135): Assertion checker does not yet support this expression.
|
||||
// Warning: (132-133): Assertion checker does not yet implement type struct C.S storage ref
|
||||
// Warning: (132-135): Assertion checker does not yet implement this expression.
|
||||
// Warning: (146-149): Assertion checker does not yet support this expression.
|
||||
// Warning: (146-147): Assertion checker does not yet implement type struct C.T storage ref
|
||||
// Warning: (146-156): Assertion checker does not yet implement type struct C.S storage ref
|
||||
// Warning: (146-149): Assertion checker does not yet implement this expression.
|
||||
// Warning: (160-168): Assertion checker does not yet support this expression.
|
||||
// Warning: (160-163): Assertion checker does not yet support this expression.
|
||||
// Warning: (160-161): Assertion checker does not yet implement type struct C.T storage ref
|
||||
// Warning: (160-166): Assertion checker does not yet implement type struct C.S storage ref
|
||||
// Warning: (160-166): Assertion checker does not yet implement this expression.
|
||||
// Warning: (160-168): Assertion checker does not yet implement this expression.
|
||||
@@ -0,0 +1,12 @@
|
||||
pragma experimental SMTChecker;
|
||||
contract C {
|
||||
function g() public returns (uint) {
|
||||
try this.g() returns (uint x) { x; }
|
||||
catch Error(string memory s) { s; }
|
||||
}
|
||||
}
|
||||
// ====
|
||||
// EVMVersion: >=byzantium
|
||||
// ----
|
||||
// Warning: (98-121): Assertion checker does not support try/catch clauses.
|
||||
// Warning: (124-159): Assertion checker does not support try/catch clauses.
|
||||
@@ -0,0 +1,14 @@
|
||||
pragma experimental SMTChecker;
|
||||
contract C {
|
||||
function f() public {
|
||||
try this.f() {}
|
||||
catch (bytes memory x) {
|
||||
x;
|
||||
}
|
||||
}
|
||||
}
|
||||
// ====
|
||||
// EVMVersion: >=byzantium
|
||||
// ----
|
||||
// Warning: (83-85): Assertion checker does not support try/catch clauses.
|
||||
// Warning: (88-122): Assertion checker does not support try/catch clauses.
|
||||
@@ -0,0 +1,5 @@
|
||||
pragma experimental SMTChecker;
|
||||
contract c {
|
||||
bool b = (f() == 0) && (f() == 0);
|
||||
function f() internal returns (uint) {}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
pragma experimental SMTChecker;
|
||||
contract c {
|
||||
uint x;
|
||||
function f() internal returns (uint) {
|
||||
x = x + 1;
|
||||
}
|
||||
bool b = (f() > 0) || (f() > 0);
|
||||
}
|
||||
// ----
|
||||
// Warning: (100-105): Overflow (resulting value larger than 2**256 - 1) happens here
|
||||
// Warning: (100-105): Underflow (resulting value less than 0) happens here
|
||||
// Warning: (100-105): Overflow (resulting value larger than 2**256 - 1) happens here
|
||||
@@ -0,0 +1,18 @@
|
||||
pragma experimental SMTChecker;
|
||||
|
||||
contract C {
|
||||
function f() public pure {
|
||||
int8 x = 1;
|
||||
int8 y = 0;
|
||||
assert(x & y != 0);
|
||||
x = -1; y = 3;
|
||||
assert(x & y == 3);
|
||||
y = -1;
|
||||
int8 z = x & y;
|
||||
assert(z == -1);
|
||||
y = 127;
|
||||
assert(x & y == 127);
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// Warning: (104-122): Assertion violation happens here
|
||||
@@ -0,0 +1,12 @@
|
||||
pragma experimental SMTChecker;
|
||||
|
||||
contract C {
|
||||
function f() public pure {
|
||||
assert(1 & 0 != 0);
|
||||
assert(-1 & 3 == 3);
|
||||
assert(-1 & -1 == -1);
|
||||
assert(-1 & 127 == 127);
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// Warning: (76-94): Assertion violation happens here
|
||||
@@ -0,0 +1,18 @@
|
||||
pragma experimental SMTChecker;
|
||||
|
||||
contract C {
|
||||
function f() public pure {
|
||||
uint8 x = 1;
|
||||
uint16 y = 0;
|
||||
assert(x & y != 0);
|
||||
x = 0xff;
|
||||
y = 0xffff;
|
||||
assert(x & y == 0xff);
|
||||
assert(x & y == 0xffff);
|
||||
assert(x & y == 0x0000);
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// Warning: (107-125): Assertion violation happens here
|
||||
// Warning: (180-203): Assertion violation happens here
|
||||
// Warning: (207-230): Assertion violation happens here
|
||||
@@ -0,0 +1,42 @@
|
||||
pragma experimental SMTChecker;
|
||||
|
||||
contract C {
|
||||
uint[] a;
|
||||
uint[][] b;
|
||||
function f(uint x, uint y, uint v) public {
|
||||
a[x] = v;
|
||||
delete a;
|
||||
assert(a[y] == 0);
|
||||
}
|
||||
function g(uint x, uint y, uint v) public {
|
||||
b[x][y] = v;
|
||||
delete b;
|
||||
assert(b[y][x] == 0);
|
||||
}
|
||||
function h(uint x, uint y, uint v) public {
|
||||
b[x][y] = v;
|
||||
delete b[x];
|
||||
// Not necessarily the case.
|
||||
assert(b[y][x] == 0);
|
||||
}
|
||||
function i(uint x, uint y, uint v) public {
|
||||
b[x][y] = v;
|
||||
delete b[y];
|
||||
assert(b[y][x] == 0);
|
||||
}
|
||||
function j(uint x, uint y, uint z, uint v) public {
|
||||
b[x][y] = v;
|
||||
delete b[z];
|
||||
// Not necessarily the case.
|
||||
assert(b[y][x] == 0);
|
||||
}
|
||||
function setA(uint x, uint y) public {
|
||||
a[x] = y;
|
||||
}
|
||||
function setB(uint x, uint y, uint z) public {
|
||||
b[x][y] = z;
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// Warning: (372-392): Assertion violation happens here
|
||||
// Warning: (617-637): Assertion violation happens here
|
||||
@@ -0,0 +1,19 @@
|
||||
pragma experimental SMTChecker;
|
||||
contract C
|
||||
{
|
||||
struct S {
|
||||
uint x;
|
||||
}
|
||||
mapping (uint => S) smap;
|
||||
function f(uint y, uint v) public {
|
||||
if (0==1)
|
||||
smap[y] = S(v);
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// Warning: (140-144): Condition is always false.
|
||||
// Warning: (149-156): Assertion checker does not yet implement type struct C.S storage ref
|
||||
// Warning: (159-160): Assertion checker does not yet implement type type(struct C.S storage pointer)
|
||||
// Warning: (159-163): Assertion checker does not yet implement type struct C.S memory
|
||||
// Warning: (159-163): Assertion checker does not yet implement this expression.
|
||||
// Warning: (149-163): Assertion checker does not yet implement type struct C.S storage ref
|
||||
@@ -0,0 +1,11 @@
|
||||
contract A {
|
||||
function f() virtual internal {}
|
||||
}
|
||||
contract B is A {
|
||||
function f() virtual override internal {}
|
||||
function h() pure internal { f; }
|
||||
}
|
||||
contract C is B {
|
||||
function f() override internal {}
|
||||
function i() pure internal { f; }
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
contract C {
|
||||
function f() public pure {
|
||||
assembly {
|
||||
pop(add(add(1, 2), c))
|
||||
}
|
||||
}
|
||||
int constant c = 1;
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
contract C {
|
||||
function f() {
|
||||
assembly {
|
||||
c := add(add(1, 2), c)
|
||||
}
|
||||
}
|
||||
int constant c = 0 + 1;
|
||||
}
|
||||
// ----
|
||||
// SyntaxError: (15-83): No visibility specified. Did you intend to add "public"?
|
||||
// TypeError: (71-72): Constant variables with non-literal values cannot be forward referenced from inline assembly.
|
||||
// TypeError: (51-52): Constant variables cannot be assigned to.
|
||||
@@ -13,7 +13,7 @@ contract C {
|
||||
// ====
|
||||
// EVMVersion: =petersburg
|
||||
// ----
|
||||
// TypeError: (101-108): The "chainid" instruction is only available for Istanbul-compatible VMs (you are currently compiling for "petersburg").
|
||||
// TypeError: (101-108): The "chainid" instruction is only available for Istanbul-compatible VMs (you are currently compiling for "petersburg").
|
||||
// DeclarationError: (95-110): Variable count does not match number of values (1 vs. 0)
|
||||
// TypeError: (215-226): The "selfbalance" instruction is only available for Istanbul-compatible VMs (you are currently compiling for "petersburg").
|
||||
// TypeError: (215-226): The "selfbalance" instruction is only available for Istanbul-compatible VMs (you are currently compiling for "petersburg").
|
||||
// DeclarationError: (209-228): Variable count does not match number of values (1 vs. 0)
|
||||
|
||||
@@ -81,7 +81,7 @@ bytes BytesUtils::convertBoolean(string const& _literal)
|
||||
else if (_literal == "false")
|
||||
return bytes{false};
|
||||
else
|
||||
throw Error(Error::Type::ParserError, "Boolean literal invalid.");
|
||||
throw TestParserError("Boolean literal invalid.");
|
||||
}
|
||||
|
||||
bytes BytesUtils::convertNumber(string const& _literal)
|
||||
@@ -92,7 +92,7 @@ bytes BytesUtils::convertNumber(string const& _literal)
|
||||
}
|
||||
catch (std::exception const&)
|
||||
{
|
||||
throw Error(Error::Type::ParserError, "Number encoding invalid.");
|
||||
throw TestParserError("Number encoding invalid.");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -104,7 +104,7 @@ bytes BytesUtils::convertHexNumber(string const& _literal)
|
||||
}
|
||||
catch (std::exception const&)
|
||||
{
|
||||
throw Error(Error::Type::ParserError, "Hex number encoding invalid.");
|
||||
throw TestParserError("Hex number encoding invalid.");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -116,7 +116,7 @@ bytes BytesUtils::convertString(string const& _literal)
|
||||
}
|
||||
catch (std::exception const&)
|
||||
{
|
||||
throw Error(Error::Type::ParserError, "String encoding invalid.");
|
||||
throw TestParserError("String encoding invalid.");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -30,6 +30,15 @@ namespace solidity::frontend::test
|
||||
while (false)
|
||||
|
||||
|
||||
class TestParserError: virtual public util::Exception
|
||||
{
|
||||
public:
|
||||
explicit TestParserError(std::string const& _description)
|
||||
{
|
||||
*this << util::errinfo_comment(_description);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Representation of a notice, warning or error that can occur while
|
||||
* formatting and therefore updating an interactive function call test.
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
#include <test/libsolidity/util/TestFileParser.h>
|
||||
|
||||
#include <test/libsolidity/util/BytesUtils.h>
|
||||
#include <test/libsolidity/util/SoltestErrors.h>
|
||||
#include <test/Common.h>
|
||||
|
||||
#include <liblangutil/Common.h>
|
||||
@@ -128,9 +129,9 @@ vector<solidity::frontend::test::FunctionCall> TestFileParser::parseFunctionCall
|
||||
|
||||
calls.emplace_back(std::move(call));
|
||||
}
|
||||
catch (Error const& _e)
|
||||
catch (TestParserError const& _e)
|
||||
{
|
||||
throw Error{_e.type(), "Line " + to_string(_lineOffset + m_lineNumber) + ": " + _e.what()};
|
||||
throw TestParserError("Line " + to_string(_lineOffset + m_lineNumber) + ": " + _e.what());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -150,8 +151,7 @@ bool TestFileParser::accept(soltest::Token _token, bool const _expect)
|
||||
bool TestFileParser::expect(soltest::Token _token, bool const _advance)
|
||||
{
|
||||
if (m_scanner.currentToken() != _token || m_scanner.currentToken() == Token::Invalid)
|
||||
throw Error(
|
||||
Error::Type::ParserError,
|
||||
throw TestParserError(
|
||||
"Unexpected " + formatToken(m_scanner.currentToken()) + ": \"" +
|
||||
m_scanner.currentLiteral() + "\". " +
|
||||
"Expected \"" + formatToken(_token) + "\"."
|
||||
@@ -187,10 +187,10 @@ pair<string, bool> TestFileParser::parseFunctionSignature()
|
||||
parameters += parseIdentifierOrTuple();
|
||||
}
|
||||
if (accept(Token::Arrow, true))
|
||||
throw Error(Error::Type::ParserError, "Invalid signature detected: " + signature);
|
||||
throw TestParserError("Invalid signature detected: " + signature);
|
||||
|
||||
if (!hasName && !parameters.empty())
|
||||
throw Error(Error::Type::ParserError, "Signatures without a name cannot have parameters: " + signature);
|
||||
throw TestParserError("Signatures without a name cannot have parameters: " + signature);
|
||||
else
|
||||
signature += parameters;
|
||||
|
||||
@@ -207,7 +207,7 @@ FunctionValue TestFileParser::parseFunctionCallValue()
|
||||
u256 value{ parseDecimalNumber() };
|
||||
Token token = m_scanner.currentToken();
|
||||
if (token != Token::Ether && token != Token::Wei)
|
||||
throw Error(Error::Type::ParserError, "Invalid value unit provided. Coins can be wei or ether.");
|
||||
throw TestParserError("Invalid value unit provided. Coins can be wei or ether.");
|
||||
|
||||
m_scanner.scanNextToken();
|
||||
|
||||
@@ -216,7 +216,7 @@ FunctionValue TestFileParser::parseFunctionCallValue()
|
||||
}
|
||||
catch (std::exception const&)
|
||||
{
|
||||
throw Error(Error::Type::ParserError, "Ether value encoding invalid.");
|
||||
throw TestParserError("Ether value encoding invalid.");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -226,7 +226,7 @@ FunctionCallArgs TestFileParser::parseFunctionCallArguments()
|
||||
|
||||
auto param = parseParameter();
|
||||
if (param.abiType.type == ABIType::None)
|
||||
throw Error(Error::Type::ParserError, "No argument provided.");
|
||||
throw TestParserError("No argument provided.");
|
||||
arguments.parameters.emplace_back(param);
|
||||
|
||||
while (accept(Token::Comma, true))
|
||||
@@ -290,7 +290,7 @@ Parameter TestFileParser::parseParameter()
|
||||
if (accept(Token::Boolean))
|
||||
{
|
||||
if (isSigned)
|
||||
throw Error(Error::Type::ParserError, "Invalid boolean literal.");
|
||||
throw TestParserError("Invalid boolean literal.");
|
||||
|
||||
parameter.abiType = ABIType{ABIType::Boolean, ABIType::AlignRight, 32};
|
||||
string parsed = parseBoolean();
|
||||
@@ -304,7 +304,7 @@ Parameter TestFileParser::parseParameter()
|
||||
else if (accept(Token::HexNumber))
|
||||
{
|
||||
if (isSigned)
|
||||
throw Error(Error::Type::ParserError, "Invalid hex number literal.");
|
||||
throw TestParserError("Invalid hex number literal.");
|
||||
|
||||
parameter.abiType = ABIType{ABIType::Hex, ABIType::AlignRight, 32};
|
||||
string parsed = parseHexNumber();
|
||||
@@ -318,9 +318,9 @@ Parameter TestFileParser::parseParameter()
|
||||
else if (accept(Token::Hex, true))
|
||||
{
|
||||
if (isSigned)
|
||||
throw Error(Error::Type::ParserError, "Invalid hex string literal.");
|
||||
throw TestParserError("Invalid hex string literal.");
|
||||
if (parameter.alignment != Parameter::Alignment::None)
|
||||
throw Error(Error::Type::ParserError, "Hex string literals cannot be aligned or padded.");
|
||||
throw TestParserError("Hex string literals cannot be aligned or padded.");
|
||||
|
||||
string parsed = parseString();
|
||||
parameter.rawString += "hex\"" + parsed + "\"";
|
||||
@@ -332,9 +332,9 @@ Parameter TestFileParser::parseParameter()
|
||||
else if (accept(Token::String))
|
||||
{
|
||||
if (isSigned)
|
||||
throw Error(Error::Type::ParserError, "Invalid string literal.");
|
||||
throw TestParserError("Invalid string literal.");
|
||||
if (parameter.alignment != Parameter::Alignment::None)
|
||||
throw Error(Error::Type::ParserError, "String literals cannot be aligned or padded.");
|
||||
throw TestParserError("String literals cannot be aligned or padded.");
|
||||
|
||||
string parsed = parseString();
|
||||
parameter.abiType = ABIType{ABIType::String, ABIType::AlignLeft, parsed.size()};
|
||||
@@ -364,7 +364,7 @@ Parameter TestFileParser::parseParameter()
|
||||
else if (accept(Token::Failure, true))
|
||||
{
|
||||
if (isSigned)
|
||||
throw Error(Error::Type::ParserError, "Invalid failure literal.");
|
||||
throw TestParserError("Invalid failure literal.");
|
||||
|
||||
parameter.abiType = ABIType{ABIType::Failure, ABIType::AlignRight, 0};
|
||||
parameter.rawBytes = bytes{};
|
||||
@@ -555,10 +555,7 @@ void TestFileParser::Scanner::scanNextToken()
|
||||
else if (isEndOfLine())
|
||||
token = make_pair(Token::EOS, "EOS");
|
||||
else
|
||||
throw Error(
|
||||
Error::Type::ParserError,
|
||||
"Unexpected character: '" + string{current()} + "'"
|
||||
);
|
||||
throw TestParserError("Unexpected character: '" + string{current()} + "'");
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -651,7 +648,7 @@ string TestFileParser::Scanner::scanString()
|
||||
str += scanHexPart();
|
||||
break;
|
||||
default:
|
||||
throw Error(Error::Type::ParserError, "Invalid or escape sequence found in string literal.");
|
||||
throw TestParserError("Invalid or escape sequence found in string literal.");
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -673,7 +670,7 @@ char TestFileParser::Scanner::scanHexPart()
|
||||
else if (tolower(current()) >= 'a' && tolower(current()) <= 'f')
|
||||
value = tolower(current()) - 'a' + 10;
|
||||
else
|
||||
throw Error(Error::Type::ParserError, "\\x used with no following hex digits.");
|
||||
throw TestParserError("\\x used with no following hex digits.");
|
||||
|
||||
advance();
|
||||
if (current() == '"')
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
#include <liblangutil/Exceptions.h>
|
||||
#include <test/ExecutionFramework.h>
|
||||
|
||||
#include <test/libsolidity/util/SoltestErrors.h>
|
||||
#include <test/libsolidity/util/TestFileParser.h>
|
||||
|
||||
using namespace std;
|
||||
@@ -365,7 +366,7 @@ BOOST_AUTO_TEST_CASE(scanner_hex_values_invalid1)
|
||||
char const* source = R"(
|
||||
// f(uint256): "\x" ->
|
||||
)";
|
||||
BOOST_REQUIRE_THROW(parse(source), langutil::Error);
|
||||
BOOST_REQUIRE_THROW(parse(source), TestParserError);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(scanner_hex_values_invalid2)
|
||||
@@ -383,7 +384,7 @@ BOOST_AUTO_TEST_CASE(scanner_hex_values_invalid3)
|
||||
char const* source = R"(
|
||||
// f(uint256): "\xZ" ->
|
||||
)";
|
||||
BOOST_REQUIRE_THROW(parse(source), langutil::Error);
|
||||
BOOST_REQUIRE_THROW(parse(source), TestParserError);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(scanner_hex_values_invalid4)
|
||||
@@ -391,7 +392,7 @@ BOOST_AUTO_TEST_CASE(scanner_hex_values_invalid4)
|
||||
char const* source = R"(
|
||||
// f(uint256): "\xZZ" ->
|
||||
)";
|
||||
BOOST_REQUIRE_THROW(parse(source), langutil::Error);
|
||||
BOOST_REQUIRE_THROW(parse(source), TestParserError);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(call_arguments_hex_string)
|
||||
@@ -741,7 +742,7 @@ BOOST_AUTO_TEST_CASE(call_arguments_hex_string_left_align)
|
||||
char const* source = R"(
|
||||
// f(bytes): left(hex"4200ef") ->
|
||||
)";
|
||||
BOOST_REQUIRE_THROW(parse(source), langutil::Error);
|
||||
BOOST_REQUIRE_THROW(parse(source), TestParserError);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(call_arguments_hex_string_right_align)
|
||||
@@ -749,7 +750,7 @@ BOOST_AUTO_TEST_CASE(call_arguments_hex_string_right_align)
|
||||
char const* source = R"(
|
||||
// f(bytes): right(hex"4200ef") ->
|
||||
)";
|
||||
BOOST_REQUIRE_THROW(parse(source), langutil::Error);
|
||||
BOOST_REQUIRE_THROW(parse(source), TestParserError);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(call_newline_invalid)
|
||||
@@ -757,7 +758,7 @@ BOOST_AUTO_TEST_CASE(call_newline_invalid)
|
||||
char const* source = R"(
|
||||
/
|
||||
)";
|
||||
BOOST_REQUIRE_THROW(parse(source), langutil::Error);
|
||||
BOOST_REQUIRE_THROW(parse(source), TestParserError);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(call_invalid)
|
||||
@@ -765,7 +766,7 @@ BOOST_AUTO_TEST_CASE(call_invalid)
|
||||
char const* source = R"(
|
||||
/ f() ->
|
||||
)";
|
||||
BOOST_REQUIRE_THROW(parse(source), langutil::Error);
|
||||
BOOST_REQUIRE_THROW(parse(source), TestParserError);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(call_signature_invalid)
|
||||
@@ -773,7 +774,7 @@ BOOST_AUTO_TEST_CASE(call_signature_invalid)
|
||||
char const* source = R"(
|
||||
// f(uint8,) -> FAILURE
|
||||
)";
|
||||
BOOST_REQUIRE_THROW(parse(source), langutil::Error);
|
||||
BOOST_REQUIRE_THROW(parse(source), TestParserError);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(call_arguments_tuple_invalid)
|
||||
@@ -781,7 +782,7 @@ BOOST_AUTO_TEST_CASE(call_arguments_tuple_invalid)
|
||||
char const* source = R"(
|
||||
// f((uint8,) -> FAILURE
|
||||
)";
|
||||
BOOST_REQUIRE_THROW(parse(source), langutil::Error);
|
||||
BOOST_REQUIRE_THROW(parse(source), TestParserError);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(call_arguments_tuple_invalid_empty)
|
||||
@@ -789,7 +790,7 @@ BOOST_AUTO_TEST_CASE(call_arguments_tuple_invalid_empty)
|
||||
char const* source = R"(
|
||||
// f(uint8, ()) -> FAILURE
|
||||
)";
|
||||
BOOST_REQUIRE_THROW(parse(source), langutil::Error);
|
||||
BOOST_REQUIRE_THROW(parse(source), TestParserError);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(call_arguments_tuple_invalid_parantheses)
|
||||
@@ -797,14 +798,14 @@ BOOST_AUTO_TEST_CASE(call_arguments_tuple_invalid_parantheses)
|
||||
char const* source = R"(
|
||||
// f((uint8,() -> FAILURE
|
||||
)";
|
||||
BOOST_REQUIRE_THROW(parse(source), langutil::Error);
|
||||
BOOST_REQUIRE_THROW(parse(source), TestParserError);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(call_ether_value_expectations_missing)
|
||||
{
|
||||
char const* source = R"(
|
||||
// f(), 0)";
|
||||
BOOST_REQUIRE_THROW(parse(source), langutil::Error);
|
||||
BOOST_REQUIRE_THROW(parse(source), TestParserError);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(call_arguments_invalid)
|
||||
@@ -812,7 +813,7 @@ BOOST_AUTO_TEST_CASE(call_arguments_invalid)
|
||||
char const* source = R"(
|
||||
// f(uint256): abc -> 1
|
||||
)";
|
||||
BOOST_REQUIRE_THROW(parse(source), langutil::Error);
|
||||
BOOST_REQUIRE_THROW(parse(source), TestParserError);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(call_arguments_invalid_decimal)
|
||||
@@ -820,7 +821,7 @@ BOOST_AUTO_TEST_CASE(call_arguments_invalid_decimal)
|
||||
char const* source = R"(
|
||||
// sig(): 0.h3 ->
|
||||
)";
|
||||
BOOST_REQUIRE_THROW(parse(source), langutil::Error);
|
||||
BOOST_REQUIRE_THROW(parse(source), TestParserError);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(call_ether_value_invalid)
|
||||
@@ -828,7 +829,7 @@ BOOST_AUTO_TEST_CASE(call_ether_value_invalid)
|
||||
char const* source = R"(
|
||||
// f(uint256), abc : 1 -> 1
|
||||
)";
|
||||
BOOST_REQUIRE_THROW(parse(source), langutil::Error);
|
||||
BOOST_REQUIRE_THROW(parse(source), TestParserError);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(call_ether_value_invalid_decimal)
|
||||
@@ -836,7 +837,7 @@ BOOST_AUTO_TEST_CASE(call_ether_value_invalid_decimal)
|
||||
char const* source = R"(
|
||||
// sig(): 0.1hd ether ->
|
||||
)";
|
||||
BOOST_REQUIRE_THROW(parse(source), langutil::Error);
|
||||
BOOST_REQUIRE_THROW(parse(source), TestParserError);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(call_ether_type_invalid)
|
||||
@@ -844,7 +845,7 @@ BOOST_AUTO_TEST_CASE(call_ether_type_invalid)
|
||||
char const* source = R"(
|
||||
// f(uint256), 2 btc : 1 -> 1
|
||||
)";
|
||||
BOOST_REQUIRE_THROW(parse(source), langutil::Error);
|
||||
BOOST_REQUIRE_THROW(parse(source), TestParserError);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(call_signed_bool_invalid)
|
||||
@@ -852,7 +853,7 @@ BOOST_AUTO_TEST_CASE(call_signed_bool_invalid)
|
||||
char const* source = R"(
|
||||
// f() -> -true
|
||||
)";
|
||||
BOOST_REQUIRE_THROW(parse(source), langutil::Error);
|
||||
BOOST_REQUIRE_THROW(parse(source), TestParserError);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(call_signed_failure_invalid)
|
||||
@@ -860,7 +861,7 @@ BOOST_AUTO_TEST_CASE(call_signed_failure_invalid)
|
||||
char const* source = R"(
|
||||
// f() -> -FAILURE
|
||||
)";
|
||||
BOOST_REQUIRE_THROW(parse(source), langutil::Error);
|
||||
BOOST_REQUIRE_THROW(parse(source), TestParserError);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(call_signed_hex_number_invalid)
|
||||
@@ -868,7 +869,7 @@ BOOST_AUTO_TEST_CASE(call_signed_hex_number_invalid)
|
||||
char const* source = R"(
|
||||
// f() -> -0x42
|
||||
)";
|
||||
BOOST_REQUIRE_THROW(parse(source), langutil::Error);
|
||||
BOOST_REQUIRE_THROW(parse(source), TestParserError);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(call_arguments_colon)
|
||||
@@ -877,7 +878,7 @@ BOOST_AUTO_TEST_CASE(call_arguments_colon)
|
||||
// h256():
|
||||
// -> 1
|
||||
)";
|
||||
BOOST_REQUIRE_THROW(parse(source), langutil::Error);
|
||||
BOOST_REQUIRE_THROW(parse(source), TestParserError);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(call_arguments_newline_colon)
|
||||
@@ -887,7 +888,7 @@ BOOST_AUTO_TEST_CASE(call_arguments_newline_colon)
|
||||
// :
|
||||
// -> 1
|
||||
)";
|
||||
BOOST_REQUIRE_THROW(parse(source), langutil::Error);
|
||||
BOOST_REQUIRE_THROW(parse(source), TestParserError);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(call_arrow_missing)
|
||||
@@ -895,7 +896,7 @@ BOOST_AUTO_TEST_CASE(call_arrow_missing)
|
||||
char const* source = R"(
|
||||
// h256() FAILURE
|
||||
)";
|
||||
BOOST_REQUIRE_THROW(parse(source), langutil::Error);
|
||||
BOOST_REQUIRE_THROW(parse(source), TestParserError);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(call_unexpected_character)
|
||||
@@ -903,7 +904,7 @@ BOOST_AUTO_TEST_CASE(call_unexpected_character)
|
||||
char const* source = R"(
|
||||
// f() -> ??
|
||||
)";
|
||||
BOOST_REQUIRE_THROW(parse(source), langutil::Error);
|
||||
BOOST_REQUIRE_THROW(parse(source), TestParserError);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(constructor)
|
||||
|
||||
@@ -36,10 +36,10 @@ BOOST_AUTO_TEST_CASE(test_small)
|
||||
BOOST_CHECK_EQUAL(ipfsHashBase58({}), "QmbFMke1KXqnYyBBWxB74N4c5SBnJMVAiMNRcGu6x1AwQH");
|
||||
BOOST_CHECK_EQUAL(ipfsHashBase58("x"), "QmULKig5Fxrs2sC4qt9nNduucXfb92AFYQ6Hi3YRqDmrYC");
|
||||
BOOST_CHECK_EQUAL(ipfsHashBase58("Solidity\n"), "QmSsm9M7PQRBnyiz1smizk8hZw3URfk8fSeHzeTo3oZidS");
|
||||
BOOST_CHECK_EQUAL(ipfsHashBase58(string(size_t(200), char(0))), "QmSXR1N23uWzsANi8wpxMPw5dmmhqBVUAb4hUrHVLpNaMr");
|
||||
BOOST_CHECK_EQUAL(ipfsHashBase58(string(size_t(10250), char(0))), "QmVJJBB3gKKBWYC9QTywpH8ZL1bDeTDJ17B63Af5kino9i");
|
||||
BOOST_CHECK_EQUAL(ipfsHashBase58(string(size_t(100000), char(0))), "QmYgKa25YqEGpQmmZtPPFMNK3kpqqneHk6nMSEUYryEX1C");
|
||||
BOOST_CHECK_EQUAL(ipfsHashBase58(string(size_t(121071), char(0))), "QmdMdRshQmqvyc92N82r7AKYdUF5FRh4DJo6GtrmEk3wgj");
|
||||
BOOST_CHECK_EQUAL(ipfsHashBase58(string(200ul, char(0))), "QmSXR1N23uWzsANi8wpxMPw5dmmhqBVUAb4hUrHVLpNaMr");
|
||||
BOOST_CHECK_EQUAL(ipfsHashBase58(string(10250ul, char(0))), "QmVJJBB3gKKBWYC9QTywpH8ZL1bDeTDJ17B63Af5kino9i");
|
||||
BOOST_CHECK_EQUAL(ipfsHashBase58(string(100000ul, char(0))), "QmYgKa25YqEGpQmmZtPPFMNK3kpqqneHk6nMSEUYryEX1C");
|
||||
BOOST_CHECK_EQUAL(ipfsHashBase58(string(121071ul, char(0))), "QmdMdRshQmqvyc92N82r7AKYdUF5FRh4DJo6GtrmEk3wgj");
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(test_medium)
|
||||
|
||||
@@ -71,27 +71,7 @@ TestCase::TestResult EwasmTranslationTest::run(ostream& _stream, string const& _
|
||||
|
||||
m_obtainedResult = interpret();
|
||||
|
||||
if (m_expectation != m_obtainedResult)
|
||||
{
|
||||
string nextIndentLevel = _linePrefix + " ";
|
||||
AnsiColorized(_stream, _formatted, {formatting::BOLD, formatting::CYAN}) << _linePrefix << "Expected result:" << endl;
|
||||
// TODO could compute a simple diff with highlighted lines
|
||||
printIndented(_stream, m_expectation, nextIndentLevel);
|
||||
AnsiColorized(_stream, _formatted, {formatting::BOLD, formatting::CYAN}) << _linePrefix << "Obtained result:" << endl;
|
||||
printIndented(_stream, m_obtainedResult, nextIndentLevel);
|
||||
return TestResult::Failure;
|
||||
}
|
||||
return TestResult::Success;
|
||||
}
|
||||
|
||||
void EwasmTranslationTest::printSource(ostream& _stream, string const& _linePrefix, bool const) const
|
||||
{
|
||||
printIndented(_stream, m_source, _linePrefix);
|
||||
}
|
||||
|
||||
void EwasmTranslationTest::printUpdatedExpectations(ostream& _stream, string const& _linePrefix) const
|
||||
{
|
||||
printIndented(_stream, m_obtainedResult, _linePrefix);
|
||||
return checkResult(_stream, _linePrefix, _formatted);
|
||||
}
|
||||
|
||||
bool EwasmTranslationTest::parse(ostream& _stream, string const& _linePrefix, bool const _formatted)
|
||||
|
||||
@@ -42,20 +42,13 @@ public:
|
||||
|
||||
TestResult run(std::ostream& _stream, std::string const& _linePrefix = "", bool const _formatted = false) override;
|
||||
|
||||
void printSource(std::ostream& _stream, std::string const &_linePrefix = "", bool const _formatted = false) const override;
|
||||
void printUpdatedExpectations(std::ostream& _stream, std::string const& _linePrefix) const override;
|
||||
|
||||
private:
|
||||
bool parse(std::ostream& _stream, std::string const& _linePrefix, bool const _formatted);
|
||||
std::string interpret();
|
||||
|
||||
static void printErrors(std::ostream& _stream, langutil::ErrorList const& _errors);
|
||||
|
||||
std::string m_source;
|
||||
std::string m_expectation;
|
||||
|
||||
std::shared_ptr<Object> m_object;
|
||||
std::string m_obtainedResult;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -87,37 +87,5 @@ TestCase::TestResult FunctionSideEffects::run(ostream& _stream, string const& _l
|
||||
for (auto const& fun: functionSideEffectsStr)
|
||||
m_obtainedResult += fun.first + ":" + (fun.second.empty() ? "" : " ") + fun.second + "\n";
|
||||
|
||||
if (m_expectation != m_obtainedResult)
|
||||
{
|
||||
string nextIndentLevel = _linePrefix + " ";
|
||||
AnsiColorized(_stream, _formatted, {formatting::BOLD, formatting::CYAN}) << _linePrefix << "Expected result:" << endl;
|
||||
printIndented(_stream, m_expectation, nextIndentLevel);
|
||||
AnsiColorized(_stream, _formatted, {formatting::BOLD, formatting::CYAN}) << _linePrefix << "Obtained result:" << endl;
|
||||
printIndented(_stream, m_obtainedResult, nextIndentLevel);
|
||||
return TestResult::Failure;
|
||||
}
|
||||
return TestResult::Success;
|
||||
}
|
||||
|
||||
|
||||
void FunctionSideEffects::printSource(ostream& _stream, string const& _linePrefix, bool const) const
|
||||
{
|
||||
printIndented(_stream, m_source, _linePrefix);
|
||||
}
|
||||
|
||||
void FunctionSideEffects::printUpdatedExpectations(ostream& _stream, string const& _linePrefix) const
|
||||
{
|
||||
printIndented(_stream, m_obtainedResult, _linePrefix);
|
||||
}
|
||||
|
||||
void FunctionSideEffects::printIndented(ostream& _stream, string const& _output, string const& _linePrefix) const
|
||||
{
|
||||
stringstream output(_output);
|
||||
string line;
|
||||
while (getline(output, line))
|
||||
if (line.empty())
|
||||
// Avoid trailing spaces.
|
||||
_stream << boost::trim_right_copy(_linePrefix) << endl;
|
||||
else
|
||||
_stream << _linePrefix << line << endl;
|
||||
return checkResult(_stream, _linePrefix, _formatted);
|
||||
}
|
||||
|
||||
@@ -36,16 +36,6 @@ public:
|
||||
explicit FunctionSideEffects(std::string const& _filename);
|
||||
|
||||
TestResult run(std::ostream& _stream, std::string const& _linePrefix = "", bool const _formatted = false) override;
|
||||
|
||||
void printSource(std::ostream& _stream, std::string const& _linePrefix = "", bool const _formatted = false) const override;
|
||||
void printUpdatedExpectations(std::ostream& _stream, std::string const& _linePrefix) const override;
|
||||
|
||||
private:
|
||||
void printIndented(std::ostream& _stream, std::string const& _output, std::string const& _linePrefix = "") const;
|
||||
|
||||
std::string m_source;
|
||||
std::string m_expectation;
|
||||
std::string m_obtainedResult;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -78,38 +78,7 @@ TestCase::TestResult ObjectCompilerTest::run(ostream& _stream, string const& _li
|
||||
(obj.sourceMappings->empty() ? "" : " " + *obj.sourceMappings) +
|
||||
"\n";
|
||||
|
||||
if (m_expectation != m_obtainedResult)
|
||||
{
|
||||
string nextIndentLevel = _linePrefix + " ";
|
||||
AnsiColorized(_stream, _formatted, {formatting::BOLD, formatting::CYAN}) << _linePrefix << "Expected result:" << endl;
|
||||
printIndented(_stream, m_expectation, nextIndentLevel);
|
||||
AnsiColorized(_stream, _formatted, {formatting::BOLD, formatting::CYAN}) << _linePrefix << "Obtained result:" << endl;
|
||||
printIndented(_stream, m_obtainedResult, nextIndentLevel);
|
||||
return TestResult::Failure;
|
||||
}
|
||||
return TestResult::Success;
|
||||
}
|
||||
|
||||
void ObjectCompilerTest::printSource(ostream& _stream, string const& _linePrefix, bool const) const
|
||||
{
|
||||
printIndented(_stream, m_source, _linePrefix);
|
||||
}
|
||||
|
||||
void ObjectCompilerTest::printUpdatedExpectations(ostream& _stream, string const& _linePrefix) const
|
||||
{
|
||||
printIndented(_stream, m_obtainedResult, _linePrefix);
|
||||
}
|
||||
|
||||
void ObjectCompilerTest::printIndented(ostream& _stream, string const& _output, string const& _linePrefix) const
|
||||
{
|
||||
stringstream output(_output);
|
||||
string line;
|
||||
while (getline(output, line))
|
||||
if (line.empty())
|
||||
// Avoid trailing spaces.
|
||||
_stream << boost::trim_right_copy(_linePrefix) << endl;
|
||||
else
|
||||
_stream << _linePrefix << line << endl;
|
||||
return checkResult(_stream, _linePrefix, _formatted);
|
||||
}
|
||||
|
||||
void ObjectCompilerTest::printErrors(ostream& _stream, ErrorList const& _errors)
|
||||
|
||||
@@ -47,20 +47,13 @@ public:
|
||||
|
||||
TestResult run(std::ostream& _stream, std::string const& _linePrefix = "", bool const _formatted = false) override;
|
||||
|
||||
void printSource(std::ostream& _stream, std::string const &_linePrefix = "", bool const _formatted = false) const override;
|
||||
void printUpdatedExpectations(std::ostream& _stream, std::string const& _linePrefix) const override;
|
||||
|
||||
private:
|
||||
void printIndented(std::ostream& _stream, std::string const& _output, std::string const& _linePrefix = "") const;
|
||||
bool parse(std::ostream& _stream, std::string const& _linePrefix, bool const _formatted);
|
||||
void disambiguate();
|
||||
|
||||
static void printErrors(std::ostream& _stream, langutil::ErrorList const& _errors);
|
||||
|
||||
std::string m_source;
|
||||
bool m_optimize = false;
|
||||
std::string m_expectation;
|
||||
std::string m_obtainedResult;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -59,27 +59,7 @@ TestCase::TestResult YulInterpreterTest::run(ostream& _stream, string const& _li
|
||||
|
||||
m_obtainedResult = interpret();
|
||||
|
||||
if (m_expectation != m_obtainedResult)
|
||||
{
|
||||
string nextIndentLevel = _linePrefix + " ";
|
||||
AnsiColorized(_stream, _formatted, {formatting::BOLD, formatting::CYAN}) << _linePrefix << "Expected result:" << endl;
|
||||
// TODO could compute a simple diff with highlighted lines
|
||||
printIndented(_stream, m_expectation, nextIndentLevel);
|
||||
AnsiColorized(_stream, _formatted, {formatting::BOLD, formatting::CYAN}) << _linePrefix << "Obtained result:" << endl;
|
||||
printIndented(_stream, m_obtainedResult, nextIndentLevel);
|
||||
return TestResult::Failure;
|
||||
}
|
||||
return TestResult::Success;
|
||||
}
|
||||
|
||||
void YulInterpreterTest::printSource(ostream& _stream, string const& _linePrefix, bool const) const
|
||||
{
|
||||
printIndented(_stream, m_source, _linePrefix);
|
||||
}
|
||||
|
||||
void YulInterpreterTest::printUpdatedExpectations(ostream& _stream, string const& _linePrefix) const
|
||||
{
|
||||
printIndented(_stream, m_obtainedResult, _linePrefix);
|
||||
return checkResult(_stream, _linePrefix, _formatted);
|
||||
}
|
||||
|
||||
bool YulInterpreterTest::parse(ostream& _stream, string const& _linePrefix, bool const _formatted)
|
||||
|
||||
@@ -47,21 +47,14 @@ public:
|
||||
|
||||
TestResult run(std::ostream& _stream, std::string const& _linePrefix = "", bool const _formatted = false) override;
|
||||
|
||||
void printSource(std::ostream& _stream, std::string const &_linePrefix = "", bool const _formatted = false) const override;
|
||||
void printUpdatedExpectations(std::ostream& _stream, std::string const& _linePrefix) const override;
|
||||
|
||||
private:
|
||||
bool parse(std::ostream& _stream, std::string const& _linePrefix, bool const _formatted);
|
||||
std::string interpret();
|
||||
|
||||
static void printErrors(std::ostream& _stream, langutil::ErrorList const& _errors);
|
||||
|
||||
std::string m_source;
|
||||
std::string m_expectation;
|
||||
|
||||
std::shared_ptr<Block> m_ast;
|
||||
std::shared_ptr<AsmAnalysisInfo> m_analysisInfo;
|
||||
std::string m_obtainedResult;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -354,27 +354,7 @@ TestCase::TestResult YulOptimizerTest::run(ostream& _stream, string const& _line
|
||||
|
||||
m_obtainedResult = "step: " + m_optimizerStep + "\n\n" + AsmPrinter{ *m_dialect }(*m_ast) + "\n";
|
||||
|
||||
if (m_expectation != m_obtainedResult)
|
||||
{
|
||||
string nextIndentLevel = _linePrefix + " ";
|
||||
AnsiColorized(_stream, _formatted, {formatting::BOLD, formatting::CYAN}) << _linePrefix << "Expected result:" << endl;
|
||||
// TODO could compute a simple diff with highlighted lines
|
||||
printIndented(_stream, m_expectation, nextIndentLevel);
|
||||
AnsiColorized(_stream, _formatted, {formatting::BOLD, formatting::CYAN}) << _linePrefix << "Obtained result:" << endl;
|
||||
printIndented(_stream, m_obtainedResult, nextIndentLevel);
|
||||
return TestResult::Failure;
|
||||
}
|
||||
return TestResult::Success;
|
||||
}
|
||||
|
||||
void YulOptimizerTest::printSource(ostream& _stream, string const& _linePrefix, bool const) const
|
||||
{
|
||||
printIndented(_stream, m_source, _linePrefix);
|
||||
}
|
||||
|
||||
void YulOptimizerTest::printUpdatedExpectations(ostream& _stream, string const& _linePrefix) const
|
||||
{
|
||||
printIndented(_stream, m_obtainedResult, _linePrefix);
|
||||
return checkResult(_stream, _linePrefix, _formatted);
|
||||
}
|
||||
|
||||
bool YulOptimizerTest::parse(ostream& _stream, string const& _linePrefix, bool const _formatted)
|
||||
|
||||
@@ -56,9 +56,6 @@ public:
|
||||
|
||||
TestResult run(std::ostream& _stream, std::string const& _linePrefix = "", bool const _formatted = false) override;
|
||||
|
||||
void printSource(std::ostream& _stream, std::string const &_linePrefix = "", bool const _formatted = false) const override;
|
||||
void printUpdatedExpectations(std::ostream& _stream, std::string const& _linePrefix) const override;
|
||||
|
||||
private:
|
||||
bool parse(std::ostream& _stream, std::string const& _linePrefix, bool const _formatted);
|
||||
void disambiguate();
|
||||
@@ -66,9 +63,7 @@ private:
|
||||
|
||||
static void printErrors(std::ostream& _stream, langutil::ErrorList const& _errors);
|
||||
|
||||
std::string m_source;
|
||||
std::string m_optimizerStep;
|
||||
std::string m_expectation;
|
||||
|
||||
Dialect const* m_dialect = nullptr;
|
||||
std::set<YulString> m_reservedIdentifiers;
|
||||
@@ -77,7 +72,6 @@ private:
|
||||
|
||||
std::shared_ptr<Block> m_ast;
|
||||
std::shared_ptr<AsmAnalysisInfo> m_analysisInfo;
|
||||
std::string m_obtainedResult;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -156,7 +156,7 @@ void FuzzerUtil::testConstantOptimizer(string const& _input, bool _quiet)
|
||||
assembly.append(n);
|
||||
}
|
||||
for (bool isCreation: {false, true})
|
||||
for (unsigned runs: {1, 2, 3, 20, 40, 100, 200, 400, 1000})
|
||||
for (unsigned runs: {1u, 2u, 3u, 20u, 40u, 100u, 200u, 400u, 1000u})
|
||||
{
|
||||
// Make a copy here so that each time we start with the original state.
|
||||
Assembly tmp = assembly;
|
||||
|
||||
@@ -48,10 +48,10 @@ u256 readZeroExtended(bytes const& _data, u256 const& _offset)
|
||||
if (_offset >= _data.size())
|
||||
return 0;
|
||||
else if (_offset + 32 <= _data.size())
|
||||
return *reinterpret_cast<h256 const*>(_data.data() + size_t(_offset));
|
||||
return *reinterpret_cast<h256 const*>(_data.data() + static_cast<size_t>(_offset));
|
||||
else
|
||||
{
|
||||
size_t off = size_t(_offset);
|
||||
size_t off = static_cast<size_t>(_offset);
|
||||
u256 val;
|
||||
for (size_t i = 0; i < 32; ++i)
|
||||
{
|
||||
@@ -88,7 +88,7 @@ u256 EVMInstructionInterpreter::eval(
|
||||
using evmasm::Instruction;
|
||||
|
||||
auto info = instructionInfo(_instruction);
|
||||
yulAssert(size_t(info.args) == _arguments.size(), "");
|
||||
yulAssert(static_cast<size_t>(info.args) == _arguments.size(), "");
|
||||
|
||||
auto const& arg = _arguments;
|
||||
switch (_instruction)
|
||||
@@ -442,7 +442,7 @@ u256 EVMInstructionInterpreter::evalBuiltin(BuiltinFunctionForEVM const& _fun, c
|
||||
m_state.memory,
|
||||
m_state.code,
|
||||
size_t(_arguments.at(0)),
|
||||
size_t(_arguments.at(1) & size_t(-1)),
|
||||
size_t(_arguments.at(1) & numeric_limits<size_t>::max()),
|
||||
size_t(_arguments.at(2))
|
||||
);
|
||||
}
|
||||
|
||||
@@ -87,9 +87,9 @@ u256 EwasmBuiltinInterpreter::evalBuiltin(YulString _fun, vector<u256> const& _a
|
||||
copyZeroExtended(
|
||||
m_state.memory,
|
||||
m_state.code,
|
||||
size_t(_arguments.at(0)),
|
||||
size_t(_arguments.at(1) & size_t(-1)),
|
||||
size_t(_arguments.at(2))
|
||||
static_cast<size_t>(_arguments.at(0)),
|
||||
static_cast<size_t>(_arguments.at(1) & numeric_limits<size_t>::max()),
|
||||
static_cast<size_t>(_arguments.at(2))
|
||||
);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -54,7 +54,7 @@ void InterpreterState::dumpTraceAndState(ostream& _out) const
|
||||
_out << "Memory dump:\n";
|
||||
map<u256, u256> words;
|
||||
for (auto const& [offset, value]: memory)
|
||||
words[(offset / 0x20) * 0x20] |= u256(uint32_t(value)) << (256 - 8 - 8 * size_t(offset % 0x20));
|
||||
words[(offset / 0x20) * 0x20] |= u256(uint32_t(value)) << (256 - 8 - 8 * static_cast<size_t>(offset % 0x20));
|
||||
for (auto const& [offset, value]: words)
|
||||
if (value != 0)
|
||||
_out << " " << std::uppercase << std::hex << std::setw(4) << offset << ": " << h256(value).hex() << endl;
|
||||
|
||||
Reference in New Issue
Block a user