aboutsummaryrefslogtreecommitdiffstats
path: root/test
diff options
context:
space:
mode:
Diffstat (limited to 'test')
-rw-r--r--test/RPCSession.cpp6
-rw-r--r--test/TestHelper.cpp2
-rw-r--r--test/TestHelper.h1
-rw-r--r--test/boostTest.cpp19
-rw-r--r--test/liblll/Compiler.cpp128
-rw-r--r--test/liblll/EndToEndTest.cpp86
-rw-r--r--test/libsolidity/AnalysisFramework.cpp45
-rw-r--r--test/libsolidity/AnalysisFramework.h11
-rw-r--r--test/libsolidity/GasMeter.cpp10
-rw-r--r--test/libsolidity/SMTChecker.cpp86
-rw-r--r--test/libsolidity/SolidityEndToEndTest.cpp87
-rw-r--r--test/libsolidity/SolidityNameAndTypeResolution.cpp150
12 files changed, 563 insertions, 68 deletions
diff --git a/test/RPCSession.cpp b/test/RPCSession.cpp
index c4fbfefb..768c8c4b 100644
--- a/test/RPCSession.cpp
+++ b/test/RPCSession.cpp
@@ -217,11 +217,11 @@ void RPCSession::test_setChainParams(vector<string> const& _accounts)
{
"sealEngine": "NoProof",
"params": {
- "accountStartNonce": "0x",
+ "accountStartNonce": "0x00",
"maximumExtraDataSize": "0x1000000",
"blockReward": "0x",
- "allowFutureBlocks": "1",
- "homsteadForkBlock": "0x00",
+ "allowFutureBlocks": true,
+ "homesteadForkBlock": "0x00",
"EIP150ForkBlock": "0x00",
"EIP158ForkBlock": "0x00"
},
diff --git a/test/TestHelper.cpp b/test/TestHelper.cpp
index 094b59c6..c8747a06 100644
--- a/test/TestHelper.cpp
+++ b/test/TestHelper.cpp
@@ -45,6 +45,8 @@ Options::Options()
showMessages = true;
else if (string(suite.argv[i]) == "--no-ipc")
disableIPC = true;
+ else if (string(suite.argv[i]) == "--no-smt")
+ disableSMT = true;
if (!disableIPC && ipcPath.empty())
if (auto path = getenv("ETH_TEST_IPC"))
diff --git a/test/TestHelper.h b/test/TestHelper.h
index d50568ad..d25c5cd8 100644
--- a/test/TestHelper.h
+++ b/test/TestHelper.h
@@ -35,6 +35,7 @@ struct Options: boost::noncopyable
bool showMessages = false;
bool optimize = false;
bool disableIPC = false;
+ bool disableSMT = false;
static Options const& get();
diff --git a/test/boostTest.cpp b/test/boostTest.cpp
index d8c5b678..7b452e06 100644
--- a/test/boostTest.cpp
+++ b/test/boostTest.cpp
@@ -39,6 +39,17 @@
using namespace boost::unit_test;
+namespace
+{
+void removeTestSuite(std::string const& _name)
+{
+ master_test_suite_t& master = framework::master_test_suite();
+ auto id = master.get(_name);
+ assert(id != INV_TEST_UNIT_ID);
+ master.remove(id);
+}
+}
+
test_suite* init_unit_test_suite( int /*argc*/, char* /*argv*/[] )
{
master_test_suite_t& master = framework::master_test_suite();
@@ -57,12 +68,10 @@ test_suite* init_unit_test_suite( int /*argc*/, char* /*argv*/[] )
"SolidityEndToEndTest",
"SolidityOptimizer"
})
- {
- auto id = master.get(suite);
- assert(id != INV_TEST_UNIT_ID);
- master.remove(id);
- }
+ removeTestSuite(suite);
}
+ if (dev::test::Options::get().disableSMT)
+ removeTestSuite("SMTChecker");
return 0;
}
diff --git a/test/liblll/Compiler.cpp b/test/liblll/Compiler.cpp
new file mode 100644
index 00000000..2d66bce1
--- /dev/null
+++ b/test/liblll/Compiler.cpp
@@ -0,0 +1,128 @@
+/*
+ This file is part of solidity.
+
+ solidity is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ solidity is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with solidity. If not, see <http://www.gnu.org/licenses/>.
+*/
+/**
+ * @author Alex Beregszaszi
+ * @date 2017
+ * Unit tests for the LLL compiler.
+ */
+
+#include <string>
+#include <memory>
+#include <boost/test/unit_test.hpp>
+#include <liblll/Compiler.h>
+
+using namespace std;
+
+namespace dev
+{
+namespace lll
+{
+namespace test
+{
+
+namespace
+{
+
+bool successCompile(std::string const& _sourceCode)
+{
+ std::vector<std::string> errors;
+ bytes bytecode = eth::compileLLL(_sourceCode, false, &errors);
+ if (!errors.empty())
+ return false;
+ if (bytecode.empty())
+ return false;
+ return true;
+}
+
+}
+
+BOOST_AUTO_TEST_SUITE(LLLCompiler)
+
+BOOST_AUTO_TEST_CASE(smoke_test)
+{
+ char const* sourceCode = "1";
+ BOOST_CHECK(successCompile(sourceCode));
+}
+
+BOOST_AUTO_TEST_CASE(switch_valid)
+{
+ char const* sourceCode = R"(
+ (switch (origin))
+ )";
+ BOOST_CHECK(successCompile(sourceCode));
+ sourceCode = R"(
+ (switch
+ 1 (panic)
+ 2 (panic))
+ )";
+ BOOST_CHECK(successCompile(sourceCode));
+ sourceCode = R"(
+ (switch
+ 1 (panic)
+ 2 (panic)
+ (panic))
+ )";
+ BOOST_CHECK(successCompile(sourceCode));
+ sourceCode = R"(
+ (switch
+ 1 (origin)
+ 2 (origin)
+ (origin))
+ )";
+ BOOST_CHECK(successCompile(sourceCode));
+}
+
+BOOST_AUTO_TEST_CASE(switch_invalid_arg_count)
+{
+ char const* sourceCode = R"(
+ (switch)
+ )";
+ BOOST_CHECK(!successCompile(sourceCode));
+}
+
+BOOST_AUTO_TEST_CASE(switch_inconsistent_return_count)
+{
+ // cannot return stack items if the default case is not present
+ char const* sourceCode = R"(
+ (switch
+ 1 (origin)
+ 2 (origin)
+ )";
+ BOOST_CHECK(!successCompile(sourceCode));
+ // return count mismatch
+ sourceCode = R"(
+ (switch
+ 1 (origin)
+ 2 (origin)
+ (panic))
+ )";
+ BOOST_CHECK(!successCompile(sourceCode));
+ // return count mismatch
+ sourceCode = R"(
+ (switch
+ 1 (panic)
+ 2 (panic)
+ (origin))
+ )";
+ BOOST_CHECK(!successCompile(sourceCode));
+}
+
+BOOST_AUTO_TEST_SUITE_END()
+
+}
+}
+} // end namespaces
diff --git a/test/liblll/EndToEndTest.cpp b/test/liblll/EndToEndTest.cpp
index 9292d963..1a5bb490 100644
--- a/test/liblll/EndToEndTest.cpp
+++ b/test/liblll/EndToEndTest.cpp
@@ -215,6 +215,92 @@ BOOST_AUTO_TEST_CASE(conditional_nested_then)
BOOST_CHECK(callContractFunction("test()", 0xfc) == encodeArgs(u256(6)));
}
+BOOST_AUTO_TEST_CASE(conditional_switch)
+{
+ char const* sourceCode = R"(
+ (returnlll
+ (seq
+ (def 'input (calldataload 0x04))
+ ;; Calculates width in bytes of utf-8 characters.
+ (return
+ (switch
+ (< input 0x80) 1
+ (< input 0xE0) 2
+ (< input 0xF0) 3
+ (< input 0xF8) 4
+ (< input 0xFC) 5
+ 6))))
+ )";
+ compileAndRun(sourceCode);
+ BOOST_CHECK(callContractFunction("test()", 0x00) == encodeArgs(u256(1)));
+ BOOST_CHECK(callContractFunction("test()", 0x80) == encodeArgs(u256(2)));
+ BOOST_CHECK(callContractFunction("test()", 0xe0) == encodeArgs(u256(3)));
+ BOOST_CHECK(callContractFunction("test()", 0xf0) == encodeArgs(u256(4)));
+ BOOST_CHECK(callContractFunction("test()", 0xf8) == encodeArgs(u256(5)));
+ BOOST_CHECK(callContractFunction("test()", 0xfc) == encodeArgs(u256(6)));
+}
+
+BOOST_AUTO_TEST_CASE(conditional_switch_one_arg_with_deposit)
+{
+ char const* sourceCode = R"(
+ (returnlll
+ (return
+ (switch 42)))
+ )";
+ compileAndRun(sourceCode);
+ BOOST_CHECK(callFallback() == encodeArgs(u256(42)));
+}
+
+BOOST_AUTO_TEST_CASE(conditional_switch_one_arg_no_deposit)
+{
+ char const* sourceCode = R"(
+ (returnlll
+ (seq
+ (switch [0]:42)
+ (return 0x00 0x20)))
+ )";
+ compileAndRun(sourceCode);
+ BOOST_CHECK(callFallback() == encodeArgs(u256(42)));
+}
+
+BOOST_AUTO_TEST_CASE(conditional_switch_two_args)
+{
+ char const* sourceCode = R"(
+ (returnlll
+ (seq
+ (switch (= (calldataload 0x04) 1) [0]:42)
+ (return 0x00 0x20)))
+ )";
+ compileAndRun(sourceCode);
+ BOOST_CHECK(callContractFunction("test()", 0) == encodeArgs(u256(0)));
+ BOOST_CHECK(callContractFunction("test()", 1) == encodeArgs(u256(42)));
+}
+
+BOOST_AUTO_TEST_CASE(conditional_switch_three_args_with_deposit)
+{
+ char const* sourceCode = R"(
+ (returnlll
+ (return
+ (switch (= (calldataload 0x04) 1) 41 42)))
+ )";
+ compileAndRun(sourceCode);
+ BOOST_CHECK(callContractFunction("test()", 0) == encodeArgs(u256(42)));
+ BOOST_CHECK(callContractFunction("test()", 1) == encodeArgs(u256(41)));
+}
+
+BOOST_AUTO_TEST_CASE(conditional_switch_three_args_no_deposit)
+{
+ char const* sourceCode = R"(
+ (returnlll
+ (switch
+ (= (calldataload 0x04) 1) (return 41)
+ (return 42)))
+ )";
+ compileAndRun(sourceCode);
+ BOOST_CHECK(callContractFunction("test()", 0) == encodeArgs(u256(42)));
+ BOOST_CHECK(callContractFunction("test()", 1) == encodeArgs(u256(41)));
+}
+
BOOST_AUTO_TEST_CASE(exp_operator_const)
{
char const* sourceCode = R"(
diff --git a/test/libsolidity/AnalysisFramework.cpp b/test/libsolidity/AnalysisFramework.cpp
index 5f5f6411..3bdc40a0 100644
--- a/test/libsolidity/AnalysisFramework.cpp
+++ b/test/libsolidity/AnalysisFramework.cpp
@@ -25,6 +25,8 @@
#include <libsolidity/ast/AST.h>
+#include <libsolidity/parsing/Scanner.h>
+
#include <libdevcore/SHA3.h>
#include <boost/test/unit_test.hpp>
@@ -46,8 +48,7 @@ AnalysisFramework::parseAnalyseAndReturnError(
m_compiler.addSource("", _insertVersionPragma ? "pragma solidity >=0.0;\n" + _source : _source);
if (!m_compiler.parse())
{
- printErrors();
- BOOST_ERROR("Parsing contract failed in analysis test suite.");
+ BOOST_ERROR("Parsing contract failed in analysis test suite:" + formatErrors());
}
m_compiler.analyze();
@@ -56,15 +57,24 @@ AnalysisFramework::parseAnalyseAndReturnError(
for (auto const& currentError: m_compiler.errors())
{
solAssert(currentError->comment(), "");
- if (currentError->comment()->find("This is a pre-release compiler version") == 0)
- continue;
+ if (currentError->type() == Error::Type::Warning)
+ {
+ bool ignoreWarning = false;
+ for (auto const& filter: m_warningsToFilter)
+ if (currentError->comment()->find(filter) == 0)
+ {
+ ignoreWarning = true;
+ break;
+ }
+ if (ignoreWarning)
+ continue;
+ }
if (_reportWarnings || (currentError->type() != Error::Type::Warning))
{
if (firstError && !_allowMultipleErrors)
{
- printErrors();
- BOOST_FAIL("Multiple errors found.");
+ BOOST_FAIL("Multiple errors found: " + formatErrors());
}
if (!firstError)
firstError = currentError;
@@ -78,7 +88,10 @@ SourceUnit const* AnalysisFramework::parseAndAnalyse(string const& _source)
{
auto sourceAndError = parseAnalyseAndReturnError(_source);
BOOST_REQUIRE(!!sourceAndError.first);
- BOOST_REQUIRE(!sourceAndError.second);
+ string message;
+ if (sourceAndError.second)
+ message = "Unexpected error: " + formatError(*sourceAndError.second);
+ BOOST_REQUIRE_MESSAGE(!sourceAndError.second, message);
return sourceAndError.first;
}
@@ -91,17 +104,23 @@ Error AnalysisFramework::expectError(std::string const& _source, bool _warning,
{
auto sourceAndError = parseAnalyseAndReturnError(_source, _warning, true, _allowMultiple);
BOOST_REQUIRE(!!sourceAndError.second);
- BOOST_REQUIRE(!!sourceAndError.first);
+ BOOST_REQUIRE_MESSAGE(!!sourceAndError.first, "Expected error, but no error happened.");
return *sourceAndError.second;
}
-void AnalysisFramework::printErrors()
+string AnalysisFramework::formatErrors()
{
+ string message;
for (auto const& error: m_compiler.errors())
- SourceReferenceFormatter::printExceptionInformation(
- std::cerr,
- *error,
- (error->type() == Error::Type::Warning) ? "Warning" : "Error",
+ message += formatError(*error);
+ return message;
+}
+
+string AnalysisFramework::formatError(Error const& _error)
+{
+ return SourceReferenceFormatter::formatExceptionInformation(
+ _error,
+ (_error.type() == Error::Type::Warning) ? "Warning" : "Error",
[&](std::string const& _sourceName) -> solidity::Scanner const& { return m_compiler.scanner(_sourceName); }
);
}
diff --git a/test/libsolidity/AnalysisFramework.h b/test/libsolidity/AnalysisFramework.h
index 172ae01b..a566ba1d 100644
--- a/test/libsolidity/AnalysisFramework.h
+++ b/test/libsolidity/AnalysisFramework.h
@@ -45,7 +45,7 @@ class AnalysisFramework
{
protected:
- std::pair<SourceUnit const*, std::shared_ptr<Error const>>
+ virtual std::pair<SourceUnit const*, std::shared_ptr<Error const>>
parseAnalyseAndReturnError(
std::string const& _source,
bool _reportWarnings = false,
@@ -57,7 +57,8 @@ protected:
bool success(std::string const& _source);
Error expectError(std::string const& _source, bool _warning = false, bool _allowMultiple = false);
- void printErrors();
+ std::string formatErrors();
+ std::string formatError(Error const& _error);
static ContractDefinition const* retrieveContractByName(SourceUnit const& _source, std::string const& _name);
static FunctionTypePointer retrieveFunctionBySignature(
@@ -65,6 +66,7 @@ protected:
std::string const& _signature
);
+ std::vector<std::string> m_warningsToFilter = {"This is a pre-release compiler version"};
dev::solidity::CompilerStack m_compiler;
};
@@ -104,7 +106,10 @@ CHECK_ERROR_OR_WARNING(text, Warning, substring, true, true)
do \
{ \
auto sourceAndError = parseAnalyseAndReturnError((text), true); \
- BOOST_CHECK(sourceAndError.second == nullptr); \
+ std::string message; \
+ if (sourceAndError.second) \
+ message = formatError(*sourceAndError.second); \
+ BOOST_CHECK_MESSAGE(!sourceAndError.second, message); \
} \
while(0)
diff --git a/test/libsolidity/GasMeter.cpp b/test/libsolidity/GasMeter.cpp
index b759678f..c2886f5b 100644
--- a/test/libsolidity/GasMeter.cpp
+++ b/test/libsolidity/GasMeter.cpp
@@ -21,7 +21,6 @@
*/
#include <test/libsolidity/SolidityExecutionFramework.h>
-#include <libevmasm/EVMSchedule.h>
#include <libevmasm/GasMeter.h>
#include <libevmasm/KnownState.h>
#include <libevmasm/PathGasMeter.h>
@@ -63,15 +62,13 @@ public:
void testCreationTimeGas(string const& _sourceCode)
{
- EVMSchedule schedule;
-
compileAndRun(_sourceCode);
auto state = make_shared<KnownState>();
PathGasMeter meter(*m_compiler.assemblyItems());
GasMeter::GasConsumption gas = meter.estimateMax(0, state);
u256 bytecodeSize(m_compiler.runtimeObject().bytecode.size());
// costs for deployment
- gas += bytecodeSize * schedule.createDataGas;
+ gas += bytecodeSize * GasCosts::createDataGas;
// costs for transaction
gas += gasForTransaction(m_compiler.object().bytecode, true);
@@ -103,10 +100,9 @@ public:
static GasMeter::GasConsumption gasForTransaction(bytes const& _data, bool _isCreation)
{
- EVMSchedule schedule;
- GasMeter::GasConsumption gas = _isCreation ? schedule.txCreateGas : schedule.txGas;
+ GasMeter::GasConsumption gas = _isCreation ? GasCosts::txCreateGas : GasCosts::txGas;
for (auto i: _data)
- gas += i != 0 ? schedule.txDataNonZeroGas : schedule.txDataZeroGas;
+ gas += i != 0 ? GasCosts::txDataNonZeroGas : GasCosts::txDataZeroGas;
return gas;
}
diff --git a/test/libsolidity/SMTChecker.cpp b/test/libsolidity/SMTChecker.cpp
new file mode 100644
index 00000000..d58f296f
--- /dev/null
+++ b/test/libsolidity/SMTChecker.cpp
@@ -0,0 +1,86 @@
+/*
+ This file is part of solidity.
+
+ solidity is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ solidity is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with solidity. If not, see <http://www.gnu.org/licenses/>.
+*/
+/**
+ * Unit tests for the SMT checker.
+ */
+
+#include <test/libsolidity/AnalysisFramework.h>
+
+#include <boost/test/unit_test.hpp>
+
+#include <string>
+
+using namespace std;
+
+namespace dev
+{
+namespace solidity
+{
+namespace test
+{
+
+class SMTCheckerFramework: public AnalysisFramework
+{
+public:
+ SMTCheckerFramework()
+ {
+ m_warningsToFilter.push_back("Experimental features are turned on.");
+ }
+
+protected:
+ virtual std::pair<SourceUnit const*, std::shared_ptr<Error const>>
+ parseAnalyseAndReturnError(
+ std::string const& _source,
+ bool _reportWarnings = false,
+ bool _insertVersionPragma = true,
+ bool _allowMultipleErrors = false
+ )
+ {
+ return AnalysisFramework::parseAnalyseAndReturnError(
+ "pragma experimental SMTChecker;\n" + _source,
+ _reportWarnings,
+ _insertVersionPragma,
+ _allowMultipleErrors
+ );
+ }
+};
+
+BOOST_FIXTURE_TEST_SUITE(SMTChecker, SMTCheckerFramework)
+
+BOOST_AUTO_TEST_CASE(smoke_test)
+{
+ string text = R"(
+ contract C { }
+ )";
+ CHECK_SUCCESS_NO_WARNINGS(text);
+}
+
+BOOST_AUTO_TEST_CASE(simple_overflow)
+{
+ string text = R"(
+ contract C {
+ function f(uint a, uint b) public pure returns (uint) { return a + b; }
+ }
+ )";
+ CHECK_WARNING(text, "Overflow (resulting value larger than");
+}
+
+BOOST_AUTO_TEST_SUITE_END()
+
+}
+}
+}
diff --git a/test/libsolidity/SolidityEndToEndTest.cpp b/test/libsolidity/SolidityEndToEndTest.cpp
index 82dedf85..35916ec7 100644
--- a/test/libsolidity/SolidityEndToEndTest.cpp
+++ b/test/libsolidity/SolidityEndToEndTest.cpp
@@ -1457,7 +1457,7 @@ BOOST_AUTO_TEST_CASE(msg_sig)
}
)";
compileAndRun(sourceCode);
- ABI_CHECK(callContractFunction("foo(uint256)"), encodeArgs(asString(FixedHash<4>(dev::keccak256("foo(uint256)")).asBytes())));
+ ABI_CHECK(callContractFunction("foo(uint256)", 0), encodeArgs(asString(FixedHash<4>(dev::keccak256("foo(uint256)")).asBytes())));
}
BOOST_AUTO_TEST_CASE(msg_sig_after_internal_call_is_same)
@@ -1473,7 +1473,7 @@ BOOST_AUTO_TEST_CASE(msg_sig_after_internal_call_is_same)
}
)";
compileAndRun(sourceCode);
- ABI_CHECK(callContractFunction("foo(uint256)"), encodeArgs(asString(FixedHash<4>(dev::keccak256("foo(uint256)")).asBytes())));
+ ABI_CHECK(callContractFunction("foo(uint256)", 0), encodeArgs(asString(FixedHash<4>(dev::keccak256("foo(uint256)")).asBytes())));
}
BOOST_AUTO_TEST_CASE(now)
@@ -1494,7 +1494,7 @@ BOOST_AUTO_TEST_CASE(now)
size_t endTime = blockTimestamp(endBlock);
BOOST_CHECK(startBlock != endBlock);
BOOST_CHECK(startTime != endTime);
- BOOST_CHECK(ret == encodeArgs(true, endTime));
+ ABI_CHECK(ret, encodeArgs(true, endTime));
}
BOOST_AUTO_TEST_CASE(type_conversions_cleanup)
@@ -3090,7 +3090,7 @@ BOOST_AUTO_TEST_CASE(event_anonymous_with_topics)
char const* sourceCode = R"(
contract ClientReceipt {
event Deposit(address indexed _from, bytes32 indexed _id, uint indexed _value, uint indexed _value2, bytes32 data) anonymous;
- function deposit(bytes32 _id, bool _manually) payable {
+ function deposit(bytes32 _id) payable {
Deposit(msg.sender, _id, msg.value, 2, "abc");
}
}
@@ -3098,7 +3098,7 @@ BOOST_AUTO_TEST_CASE(event_anonymous_with_topics)
compileAndRun(sourceCode);
u256 value(18);
u256 id(0x1234);
- callContractFunctionWithValue("deposit(bytes32,bool)", value, id);
+ callContractFunctionWithValue("deposit(bytes32)", value, id);
BOOST_REQUIRE_EQUAL(m_logs.size(), 1);
BOOST_CHECK_EQUAL(m_logs[0].address, m_contractAddress);
BOOST_CHECK(m_logs[0].data == encodeArgs("abc"));
@@ -3757,11 +3757,11 @@ BOOST_AUTO_TEST_CASE(struct_containing_bytes_copy_and_delete)
compileAndRun(sourceCode);
string data = "123456789012345678901234567890123";
BOOST_CHECK(storageEmpty(m_contractAddress));
- ABI_CHECK(callContractFunction("set(uint256,bytes,uint256)", 12, u256(data.length()), 13, data), encodeArgs(true));
+ ABI_CHECK(callContractFunction("set(uint256,bytes,uint256)", 12, 0x60, 13, u256(data.length()), data), encodeArgs(true));
BOOST_CHECK(!storageEmpty(m_contractAddress));
ABI_CHECK(callContractFunction("copy()"), encodeArgs(true));
BOOST_CHECK(storageEmpty(m_contractAddress));
- ABI_CHECK(callContractFunction("set(uint256,bytes,uint256)", 12, u256(data.length()), 13, data), encodeArgs(true));
+ ABI_CHECK(callContractFunction("set(uint256,bytes,uint256)", 12, 0x60, 13, u256(data.length()), data), encodeArgs(true));
BOOST_CHECK(!storageEmpty(m_contractAddress));
ABI_CHECK(callContractFunction("del()"), encodeArgs(true));
BOOST_CHECK(storageEmpty(m_contractAddress));
@@ -5185,7 +5185,7 @@ BOOST_AUTO_TEST_CASE(packed_storage_signed)
}
)";
compileAndRun(sourceCode);
- BOOST_CHECK( callContractFunction("test()") == encodeArgs(u256(-2), u256(4), u256(-112), u256(0)));
+ ABI_CHECK(callContractFunction("test()"), encodeArgs(u256(-2), u256(4), u256(-112), u256(0)));
}
BOOST_AUTO_TEST_CASE(external_types_in_calls)
@@ -5540,7 +5540,7 @@ BOOST_AUTO_TEST_CASE(evm_exceptions_in_constructor_out_of_baund)
}
}
)";
- BOOST_CHECK(compileAndRunWithoutCheck(sourceCode, 0, "A").empty());
+ ABI_CHECK(compileAndRunWithoutCheck(sourceCode, 0, "A"), encodeArgs());
}
BOOST_AUTO_TEST_CASE(positive_integers_to_signed)
@@ -6505,31 +6505,32 @@ BOOST_AUTO_TEST_CASE(string_as_mapping_key)
"1"
};
for (unsigned i = 0; i < strings.size(); i++)
- BOOST_CHECK(callContractFunction(
+ ABI_CHECK(callContractFunction(
"set(string,uint256)",
u256(0x40),
u256(7 + i),
u256(strings[i].size()),
strings[i]
- ) == encodeArgs());
+ ), encodeArgs());
for (unsigned i = 0; i < strings.size(); i++)
- BOOST_CHECK(callContractFunction(
+ ABI_CHECK(callContractFunction(
"get(string)",
u256(0x20),
u256(strings[i].size()),
strings[i]
- ) == encodeArgs(u256(7 + i)));
+ ), encodeArgs(u256(7 + i)));
}
BOOST_AUTO_TEST_CASE(accessor_for_state_variable)
{
char const* sourceCode = R"(
- contract Lotto{
+ contract Lotto {
uint public ticketPrice = 500;
- })";
+ }
+ )";
- compileAndRun(sourceCode);
- ABI_CHECK(callContractFunction("ticketPrice()"), encodeArgs(u256(500)));
+ compileAndRun(sourceCode);
+ ABI_CHECK(callContractFunction("ticketPrice()"), encodeArgs(u256(500)));
}
BOOST_AUTO_TEST_CASE(accessor_for_const_state_variable)
@@ -6537,10 +6538,11 @@ BOOST_AUTO_TEST_CASE(accessor_for_const_state_variable)
char const* sourceCode = R"(
contract Lotto{
uint constant public ticketPrice = 555;
- })";
+ }
+ )";
- compileAndRun(sourceCode);
- ABI_CHECK(callContractFunction("ticketPrice()"), encodeArgs(u256(555)));
+ compileAndRun(sourceCode);
+ ABI_CHECK(callContractFunction("ticketPrice()"), encodeArgs(u256(555)));
}
BOOST_AUTO_TEST_CASE(state_variable_under_contract_name)
@@ -7402,7 +7404,7 @@ BOOST_AUTO_TEST_CASE(string_allocation_bug)
}
)";
compileAndRun(sourceCode);
- ABI_CHECK(callContractFunction("p(uint256)"), encodeArgs(
+ ABI_CHECK(callContractFunction("p(uint256)", 0), encodeArgs(
u256(0xbbbb),
u256(0xcccc),
u256(0x80),
@@ -7913,7 +7915,7 @@ BOOST_AUTO_TEST_CASE(inline_assembly_function_call_assignment)
}
)";
compileAndRun(sourceCode, 0, "C");
- BOOST_CHECK(callContractFunction("f()") == encodeArgs(u256(1), u256(2), u256(7)));
+ ABI_CHECK(callContractFunction("f()"), encodeArgs(u256(1), u256(2), u256(7)));
}
BOOST_AUTO_TEST_CASE(inline_assembly_function_call2)
@@ -8776,8 +8778,8 @@ BOOST_AUTO_TEST_CASE(return_external_function_type)
)";
compileAndRun(sourceCode, 0, "C");
- BOOST_CHECK(
- callContractFunction("f()") ==
+ ABI_CHECK(
+ callContractFunction("f()"),
m_contractAddress.asBytes() + FixedHash<4>(dev::keccak256("g()")).asBytes() + bytes(32 - 4 - 20, 0)
);
}
@@ -10120,9 +10122,9 @@ BOOST_AUTO_TEST_CASE(function_types_sig)
}
)";
compileAndRun(sourceCode, 0, "C");
- BOOST_CHECK(callContractFunction("f()") == encodeArgs(asString(FixedHash<4>(dev::keccak256("f()")).asBytes())));
- BOOST_CHECK(callContractFunction("g()") == encodeArgs(asString(FixedHash<4>(dev::keccak256("f()")).asBytes())));
- BOOST_CHECK(callContractFunction("h()") == encodeArgs(asString(FixedHash<4>(dev::keccak256("f()")).asBytes())));
+ ABI_CHECK(callContractFunction("f()"), encodeArgs(asString(FixedHash<4>(dev::keccak256("f()")).asBytes())));
+ ABI_CHECK(callContractFunction("g()"), encodeArgs(asString(FixedHash<4>(dev::keccak256("f()")).asBytes())));
+ ABI_CHECK(callContractFunction("h()"), encodeArgs(asString(FixedHash<4>(dev::keccak256("f()")).asBytes())));
}
BOOST_AUTO_TEST_CASE(constant_string)
@@ -10144,9 +10146,34 @@ BOOST_AUTO_TEST_CASE(constant_string)
}
)";
compileAndRun(sourceCode, 0, "C");
- BOOST_CHECK(callContractFunction("f()") == encodeDyn(string("\x03\x01\x02")));
- BOOST_CHECK(callContractFunction("g()") == encodeDyn(string("\x03\x01\x02")));
- BOOST_CHECK(callContractFunction("h()") == encodeDyn(string("hello")));
+ ABI_CHECK(callContractFunction("f()"), encodeDyn(string("\x03\x01\x02")));
+ ABI_CHECK(callContractFunction("g()"), encodeDyn(string("\x03\x01\x02")));
+ ABI_CHECK(callContractFunction("h()"), encodeDyn(string("hello")));
+}
+
+BOOST_AUTO_TEST_CASE(address_overload_resolution)
+{
+ char const* sourceCode = R"(
+ contract C {
+ function balance() returns (uint) {
+ return 1;
+ }
+ function transfer(uint amount) returns (uint) {
+ return amount;
+ }
+ }
+ contract D {
+ function f() returns (uint) {
+ return (new C()).balance();
+ }
+ function g() returns (uint) {
+ return (new C()).transfer(5);
+ }
+ }
+ )";
+ compileAndRun(sourceCode, 0, "D");
+ BOOST_CHECK(callContractFunction("f()") == encodeArgs(u256(1)));
+ BOOST_CHECK(callContractFunction("g()") == encodeArgs(u256(5)));
}
BOOST_AUTO_TEST_SUITE_END()
diff --git a/test/libsolidity/SolidityNameAndTypeResolution.cpp b/test/libsolidity/SolidityNameAndTypeResolution.cpp
index 39c47f9c..ed223678 100644
--- a/test/libsolidity/SolidityNameAndTypeResolution.cpp
+++ b/test/libsolidity/SolidityNameAndTypeResolution.cpp
@@ -1395,6 +1395,61 @@ BOOST_AUTO_TEST_CASE(events_with_same_name)
BOOST_CHECK(success(text));
}
+BOOST_AUTO_TEST_CASE(events_with_same_name_unnamed_arguments)
+{
+ char const* text = R"(
+ contract test {
+ event A(uint);
+ event A(uint, uint);
+ }
+ )";
+ CHECK_SUCCESS(text);
+}
+
+BOOST_AUTO_TEST_CASE(events_with_same_name_different_types)
+{
+ char const* text = R"(
+ contract test {
+ event A(uint);
+ event A(bytes);
+ }
+ )";
+ CHECK_SUCCESS(text);
+}
+
+BOOST_AUTO_TEST_CASE(double_event_declaration)
+{
+ char const* text = R"(
+ contract test {
+ event A(uint i);
+ event A(uint i);
+ }
+ )";
+ CHECK_ERROR(text, DeclarationError, "Event with same name and arguments defined twice.");
+}
+
+BOOST_AUTO_TEST_CASE(double_event_declaration_ignores_anonymous)
+{
+ char const* text = R"(
+ contract test {
+ event A(uint i);
+ event A(uint i) anonymous;
+ }
+ )";
+ CHECK_ERROR(text, DeclarationError, "Event with same name and arguments defined twice.");
+}
+
+BOOST_AUTO_TEST_CASE(double_event_declaration_ignores_indexed)
+{
+ char const* text = R"(
+ contract test {
+ event A(uint i);
+ event A(uint indexed i);
+ }
+ )";
+ CHECK_ERROR(text, DeclarationError, "Event with same name and arguments defined twice.");
+}
+
BOOST_AUTO_TEST_CASE(event_call)
{
char const* text = R"(
@@ -2306,17 +2361,28 @@ BOOST_AUTO_TEST_CASE(assigning_value_to_const_variable)
CHECK_ERROR(text, TypeError, "Cannot assign to a constant variable.");
}
-BOOST_AUTO_TEST_CASE(assigning_state_to_const_variable)
+BOOST_AUTO_TEST_CASE(assigning_state_to_const_variable_0_4_x)
{
char const* text = R"(
contract C {
address constant x = msg.sender;
}
)";
- // Change to TypeError for 0.5.0.
CHECK_WARNING(text, "Initial value for constant variable has to be compile-time constant.");
}
+BOOST_AUTO_TEST_CASE(assigning_state_to_const_variable)
+{
+ char const* text = R"(
+ pragma experimental "v0.5.0";
+
+ contract C {
+ address constant x = msg.sender;
+ }
+ )";
+ CHECK_ERROR(text, TypeError, "Initial value for constant variable has to be compile-time constant.");
+}
+
BOOST_AUTO_TEST_CASE(constant_string_literal_disallows_assignment)
{
char const* text = R"(
@@ -2333,7 +2399,7 @@ BOOST_AUTO_TEST_CASE(constant_string_literal_disallows_assignment)
CHECK_ERROR(text, TypeError, "Index access for string is not possible.");
}
-BOOST_AUTO_TEST_CASE(assign_constant_function_value_to_constant)
+BOOST_AUTO_TEST_CASE(assign_constant_function_value_to_constant_0_4_x)
{
char const* text = R"(
contract C {
@@ -2341,10 +2407,22 @@ BOOST_AUTO_TEST_CASE(assign_constant_function_value_to_constant)
uint constant y = x();
}
)";
- // Change to TypeError for 0.5.0.
CHECK_WARNING(text, "Initial value for constant variable has to be compile-time constant.");
}
+BOOST_AUTO_TEST_CASE(assign_constant_function_value_to_constant)
+{
+ char const* text = R"(
+ pragma experimental "v0.5.0";
+
+ contract C {
+ function () constant returns (uint) x;
+ uint constant y = x();
+ }
+ )";
+ CHECK_ERROR(text, TypeError, "Initial value for constant variable has to be compile-time constant.");
+}
+
BOOST_AUTO_TEST_CASE(assignment_to_const_var_involving_conversion)
{
char const* text = R"(
@@ -4135,6 +4213,8 @@ BOOST_AUTO_TEST_CASE(rational_unary_operation)
}
)";
CHECK_SUCCESS_NO_WARNINGS(text);
+
+ // Test deprecation warning under < 0.5.0
text = R"(
contract test {
function f() pure public {
@@ -4154,6 +4234,29 @@ BOOST_AUTO_TEST_CASE(rational_unary_operation)
}
)";
CHECK_WARNING(text,"Use of unary + is deprecated");
+
+ // Test syntax error under 0.5.0
+ text = R"(
+ pragma experimental "v0.5.0";
+ contract test {
+ function f() pure public {
+ ufixed16x2 a = +3.25;
+ fixed16x2 b = -3.25;
+ a; b;
+ }
+ }
+ )";
+ CHECK_ERROR(text, SyntaxError, "Use of unary + is deprecated");
+ text = R"(
+ pragma experimental "v0.5.0";
+ contract test {
+ function f(uint x) pure public {
+ uint y = +x;
+ y;
+ }
+ }
+ )";
+ CHECK_ERROR(text, SyntaxError, "Use of unary + is deprecated");
}
BOOST_AUTO_TEST_CASE(leading_zero_rationals_convert)
@@ -4251,7 +4354,7 @@ BOOST_AUTO_TEST_CASE(invalid_array_declaration_with_rational)
}
}
)";
- CHECK_ERROR(text, TypeError, "Invalid array length, expected integer literal");
+ CHECK_ERROR(text, TypeError, "Array with fractional length specified.");
}
BOOST_AUTO_TEST_CASE(invalid_array_declaration_with_signed_fixed_type)
@@ -4263,7 +4366,7 @@ BOOST_AUTO_TEST_CASE(invalid_array_declaration_with_signed_fixed_type)
}
}
)";
- CHECK_ERROR(text, TypeError, "Invalid array length, expected integer literal");
+ CHECK_ERROR(text, TypeError, "Invalid array length, expected integer literal.");
}
BOOST_AUTO_TEST_CASE(invalid_array_declaration_with_unsigned_fixed_type)
@@ -4275,7 +4378,7 @@ BOOST_AUTO_TEST_CASE(invalid_array_declaration_with_unsigned_fixed_type)
}
}
)";
- CHECK_ERROR(text, TypeError, "Invalid array length, expected integer literal");
+ CHECK_ERROR(text, TypeError, "Invalid array length, expected integer literal.");
}
BOOST_AUTO_TEST_CASE(rational_to_bytes_implicit_conversion)
@@ -6953,6 +7056,39 @@ BOOST_AUTO_TEST_CASE(warn_about_suicide)
CHECK_WARNING(text, "\"suicide\" has been deprecated in favour of \"selfdestruct\"");
}
+BOOST_AUTO_TEST_CASE(address_overload_resolution)
+{
+ char const* text = R"(
+ contract C {
+ function balance() returns (uint) {
+ this.balance; // to avoid pureness warning
+ return 1;
+ }
+ function transfer(uint amount) {
+ address(this).transfer(amount); // to avoid pureness warning
+ }
+ }
+ contract D {
+ function f() {
+ var x = (new C()).balance();
+ x;
+ (new C()).transfer(5);
+ }
+ }
+ )";
+ CHECK_SUCCESS(text);
+}
+
+BOOST_AUTO_TEST_CASE(array_length_validation)
+{
+ char const* text = R"(
+ contract C {
+ uint[8**90] ids;
+ }
+ )";
+ CHECK_ERROR(text, TypeError, "Invalid array length, expected integer literal.");
+}
+
BOOST_AUTO_TEST_SUITE_END()
}