aboutsummaryrefslogtreecommitdiffstats
path: root/test
diff options
context:
space:
mode:
Diffstat (limited to 'test')
-rw-r--r--test/boostTest.cpp1
-rw-r--r--test/libdevcore/IndentedWriter.cpp75
-rw-r--r--test/libsolidity/ABIEncoderTests.cpp405
-rw-r--r--test/libsolidity/Imports.cpp9
-rw-r--r--test/libsolidity/Metadata.cpp30
-rw-r--r--test/libsolidity/SolidityABIJSON.cpp54
-rw-r--r--test/libsolidity/SolidityEndToEndTest.cpp316
-rw-r--r--test/libsolidity/SolidityNameAndTypeResolution.cpp641
-rw-r--r--test/libsolidity/SolidityParser.cpp72
9 files changed, 1350 insertions, 253 deletions
diff --git a/test/boostTest.cpp b/test/boostTest.cpp
index c2121940..d8c5b678 100644
--- a/test/boostTest.cpp
+++ b/test/boostTest.cpp
@@ -46,6 +46,7 @@ test_suite* init_unit_test_suite( int /*argc*/, char* /*argv*/[] )
if (dev::test::Options::get().disableIPC)
{
for (auto suite: {
+ "ABIEncoderTest",
"SolidityAuctionRegistrar",
"SolidityFixedFeeRegistrar",
"SolidityWallet",
diff --git a/test/libdevcore/IndentedWriter.cpp b/test/libdevcore/IndentedWriter.cpp
new file mode 100644
index 00000000..a694aa1b
--- /dev/null
+++ b/test/libdevcore/IndentedWriter.cpp
@@ -0,0 +1,75 @@
+/*
+ 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 IndentedWriter.
+ */
+
+#include <libdevcore/IndentedWriter.h>
+
+#include "../TestHelper.h"
+
+using namespace std;
+
+namespace dev
+{
+namespace test
+{
+
+BOOST_AUTO_TEST_SUITE(IndentedWriterTest)
+
+BOOST_AUTO_TEST_CASE(empty)
+{
+ IndentedWriter iw;
+ BOOST_CHECK_EQUAL(iw.format(), "\n");
+}
+
+BOOST_AUTO_TEST_CASE(new_lines)
+{
+ IndentedWriter iw;
+ iw.newLine();
+ BOOST_CHECK_EQUAL(iw.format(), "\n");
+}
+
+BOOST_AUTO_TEST_CASE(text_without_newline)
+{
+ IndentedWriter iw;
+ iw.add("Hello World");
+ BOOST_CHECK_EQUAL(iw.format(), "Hello World\n");
+}
+
+BOOST_AUTO_TEST_CASE(text_with_newline)
+{
+ IndentedWriter iw;
+ iw.addLine("Hello World");
+ BOOST_CHECK_EQUAL(iw.format(), "Hello World\n\n");
+}
+
+BOOST_AUTO_TEST_CASE(indent)
+{
+ IndentedWriter iw;
+ iw.addLine("Hello");
+ iw.indent();
+ iw.addLine("World");
+ iw.unindent();
+ iw.addLine("and everyone else");
+ BOOST_CHECK_EQUAL(iw.format(), "Hello\n World\nand everyone else\n\n");
+}
+
+BOOST_AUTO_TEST_SUITE_END()
+
+}
+}
diff --git a/test/libsolidity/ABIEncoderTests.cpp b/test/libsolidity/ABIEncoderTests.cpp
new file mode 100644
index 00000000..297c4ef0
--- /dev/null
+++ b/test/libsolidity/ABIEncoderTests.cpp
@@ -0,0 +1,405 @@
+/*
+ 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 Solidity's ABI encoder.
+ */
+
+#include <functional>
+#include <string>
+#include <tuple>
+#include <boost/test/unit_test.hpp>
+#include <libsolidity/interface/Exceptions.h>
+#include <test/libsolidity/SolidityExecutionFramework.h>
+
+using namespace std;
+using namespace std::placeholders;
+using namespace dev::test;
+
+namespace dev
+{
+namespace solidity
+{
+namespace test
+{
+
+#define REQUIRE_LOG_DATA(DATA) do { \
+ BOOST_REQUIRE_EQUAL(m_logs.size(), 1); \
+ BOOST_CHECK_EQUAL(m_logs[0].address, m_contractAddress); \
+ BOOST_CHECK_EQUAL(toHex(m_logs[0].data), toHex(DATA)); \
+} while (false)
+
+static string const NewEncoderPragma = "pragma experimental ABIEncoderV2;\n";
+
+#define NEW_ENCODER(CODE) \
+{ \
+ sourceCode = NewEncoderPragma + sourceCode; \
+ { CODE } \
+}
+
+#define BOTH_ENCODERS(CODE) \
+{ \
+ { CODE } \
+ NEW_ENCODER(CODE) \
+}
+
+BOOST_FIXTURE_TEST_SUITE(ABIEncoderTest, SolidityExecutionFramework)
+
+BOOST_AUTO_TEST_CASE(both_encoders_macro)
+{
+ // This tests that the "both encoders macro" at least runs twice and
+ // modifies the source.
+ string sourceCode;
+ int runs = 0;
+ BOTH_ENCODERS(runs++;)
+ BOOST_CHECK(sourceCode == NewEncoderPragma);
+ BOOST_CHECK_EQUAL(runs, 2);
+}
+
+BOOST_AUTO_TEST_CASE(value_types)
+{
+ string sourceCode = R"(
+ contract C {
+ event E(uint a, uint16 b, uint24 c, int24 d, bytes3 x, bool, C);
+ function f() {
+ bytes6 x = hex"1bababababa2";
+ bool b;
+ assembly { b := 7 }
+ C c;
+ assembly { c := sub(0, 5) }
+ E(10, uint16(uint256(-2)), uint24(0x12121212), int24(int256(-1)), bytes3(x), b, c);
+ }
+ }
+ )";
+ BOTH_ENCODERS(
+ compileAndRun(sourceCode);
+ callContractFunction("f()");
+ REQUIRE_LOG_DATA(encodeArgs(
+ 10, u256(65534), u256(0x121212), u256(-1), string("\x1b\xab\xab"), true, u160(u256(-5))
+ ));
+ )
+}
+
+BOOST_AUTO_TEST_CASE(string_literal)
+{
+ string sourceCode = R"(
+ contract C {
+ event E(string, bytes20, string);
+ function f() {
+ E("abcdef", "abcde", "abcdefabcdefgehabcabcasdfjklabcdefabcedefghabcabcasdfjklabcdefabcdefghabcabcasdfjklabcdeefabcdefghabcabcasdefjklabcdefabcdefghabcabcasdfjkl");
+ }
+ }
+ )";
+ BOTH_ENCODERS(
+ compileAndRun(sourceCode);
+ callContractFunction("f()");
+ REQUIRE_LOG_DATA(encodeArgs(
+ 0x60, string("abcde"), 0xa0,
+ 6, string("abcdef"),
+ 0x8b, string("abcdefabcdefgehabcabcasdfjklabcdefabcedefghabcabcasdfjklabcdefabcdefghabcabcasdfjklabcdeefabcdefghabcabcasdefjklabcdefabcdefghabcabcasdfjkl")
+ ));
+ )
+}
+
+
+BOOST_AUTO_TEST_CASE(enum_type_cleanup)
+{
+ string sourceCode = R"(
+ contract C {
+ enum E { A, B }
+ function f(uint x) returns (E en) {
+ assembly { en := x }
+ }
+ }
+ )";
+ BOTH_ENCODERS(
+ compileAndRun(sourceCode);
+ BOOST_CHECK(callContractFunction("f(uint256)", 0) == encodeArgs(0));
+ BOOST_CHECK(callContractFunction("f(uint256)", 1) == encodeArgs(1));
+ BOOST_CHECK(callContractFunction("f(uint256)", 2) == encodeArgs());
+ )
+}
+
+BOOST_AUTO_TEST_CASE(conversion)
+{
+ string sourceCode = R"(
+ contract C {
+ event E(bytes4, bytes4, uint16, uint8, int16, int8);
+ function f() {
+ bytes2 x; assembly { x := 0xf1f2f3f400000000000000000000000000000000000000000000000000000000 }
+ uint8 a;
+ uint16 b = 0x1ff;
+ int8 c;
+ int16 d;
+ assembly { a := sub(0, 1) c := 0x0101ff d := 0xff01 }
+ E(10, x, a, uint8(b), c, int8(d));
+ }
+ }
+ )";
+ BOTH_ENCODERS(
+ compileAndRun(sourceCode);
+ callContractFunction("f()");
+ REQUIRE_LOG_DATA(encodeArgs(
+ string(3, 0) + string("\x0a"), string("\xf1\xf2"),
+ 0xff, 0xff, u256(-1), u256(1)
+ ));
+ )
+}
+
+BOOST_AUTO_TEST_CASE(memory_array_one_dim)
+{
+ string sourceCode = R"(
+ contract C {
+ event E(uint a, int16[] b, uint c);
+ function f() {
+ int16[] memory x = new int16[](3);
+ assembly {
+ for { let i := 0 } lt(i, 3) { i := add(i, 1) } {
+ mstore(add(x, mul(add(i, 1), 0x20)), add(0xfffffffe, i))
+ }
+ }
+ E(10, x, 11);
+ }
+ }
+ )";
+
+ compileAndRun(sourceCode);
+ callContractFunction("f()");
+ // The old encoder does not clean array elements.
+ REQUIRE_LOG_DATA(encodeArgs(10, 0x60, 11, 3, u256("0xfffffffe"), u256("0xffffffff"), u256("0x100000000")));
+
+ compileAndRun(NewEncoderPragma + sourceCode);
+ callContractFunction("f()");
+ REQUIRE_LOG_DATA(encodeArgs(10, 0x60, 11, 3, u256(-2), u256(-1), u256(0)));
+}
+
+BOOST_AUTO_TEST_CASE(memory_array_two_dim)
+{
+ string sourceCode = R"(
+ contract C {
+ event E(uint a, int16[][2] b, uint c);
+ function f() {
+ int16[][2] memory x;
+ x[0] = new int16[](3);
+ x[1] = new int16[](2);
+ x[0][0] = 7;
+ x[0][1] = int16(0x010203040506);
+ x[0][2] = -1;
+ x[1][0] = 4;
+ x[1][1] = 5;
+ E(10, x, 11);
+ }
+ }
+ )";
+ NEW_ENCODER(
+ compileAndRun(sourceCode);
+ callContractFunction("f()");
+ REQUIRE_LOG_DATA(encodeArgs(10, 0x60, 11, 0x40, 0xc0, 3, 7, 0x0506, u256(-1), 2, 4, 5));
+ )
+}
+
+BOOST_AUTO_TEST_CASE(memory_byte_array)
+{
+ string sourceCode = R"(
+ contract C {
+ event E(uint a, bytes[] b, uint c);
+ function f() {
+ bytes[] memory x = new bytes[](2);
+ x[0] = "abcabcdefghjklmnopqrsuvwabcdefgijklmnopqrstuwabcdefgijklmnoprstuvw";
+ x[1] = "abcdefghijklmnopqrtuvwabcfghijklmnopqstuvwabcdeghijklmopqrstuvw";
+ E(10, x, 11);
+ }
+ }
+ )";
+ NEW_ENCODER(
+ compileAndRun(sourceCode);
+ callContractFunction("f()");
+ REQUIRE_LOG_DATA(encodeArgs(
+ 10, 0x60, 11,
+ 2, 0x40, 0xc0,
+ 66, string("abcabcdefghjklmnopqrsuvwabcdefgijklmnopqrstuwabcdefgijklmnoprstuvw"),
+ 63, string("abcdefghijklmnopqrtuvwabcfghijklmnopqstuvwabcdeghijklmopqrstuvw")
+ ));
+ )
+}
+
+BOOST_AUTO_TEST_CASE(storage_byte_array)
+{
+ string sourceCode = R"(
+ contract C {
+ bytes short;
+ bytes long;
+ event E(bytes s, bytes l);
+ function f() {
+ short = "123456789012345678901234567890a";
+ long = "ffff123456789012345678901234567890afffffffff123456789012345678901234567890a";
+ E(short, long);
+ }
+ }
+ )";
+ BOTH_ENCODERS(
+ compileAndRun(sourceCode);
+ callContractFunction("f()");
+ REQUIRE_LOG_DATA(encodeArgs(
+ 0x40, 0x80,
+ 31, string("123456789012345678901234567890a"),
+ 75, string("ffff123456789012345678901234567890afffffffff123456789012345678901234567890a")
+ ));
+ )
+}
+
+BOOST_AUTO_TEST_CASE(storage_array)
+{
+ string sourceCode = R"(
+ contract C {
+ address[3] addr;
+ event E(address[3] a);
+ function f() {
+ assembly {
+ sstore(0, sub(0, 1))
+ sstore(1, sub(0, 2))
+ sstore(2, sub(0, 3))
+ }
+ E(addr);
+ }
+ }
+ )";
+ BOTH_ENCODERS(
+ compileAndRun(sourceCode);
+ callContractFunction("f()");
+ REQUIRE_LOG_DATA(encodeArgs(u160(-1), u160(-2), u160(-3)));
+ )
+}
+
+BOOST_AUTO_TEST_CASE(storage_array_dyn)
+{
+ string sourceCode = R"(
+ contract C {
+ address[] addr;
+ event E(address[] a);
+ function f() {
+ addr.push(1);
+ addr.push(2);
+ addr.push(3);
+ E(addr);
+ }
+ }
+ )";
+ BOTH_ENCODERS(
+ compileAndRun(sourceCode);
+ callContractFunction("f()");
+ REQUIRE_LOG_DATA(encodeArgs(0x20, 3, u160(1), u160(2), u160(3)));
+ )
+}
+
+BOOST_AUTO_TEST_CASE(storage_array_compact)
+{
+ string sourceCode = R"(
+ contract C {
+ int72[] x;
+ event E(int72[]);
+ function f() {
+ x.push(-1);
+ x.push(2);
+ x.push(-3);
+ x.push(4);
+ x.push(-5);
+ x.push(6);
+ x.push(-7);
+ x.push(8);
+ E(x);
+ }
+ }
+ )";
+ BOTH_ENCODERS(
+ compileAndRun(sourceCode);
+ callContractFunction("f()");
+ REQUIRE_LOG_DATA(encodeArgs(
+ 0x20, 8, u256(-1), 2, u256(-3), 4, u256(-5), 6, u256(-7), 8
+ ));
+ )
+}
+
+BOOST_AUTO_TEST_CASE(external_function)
+{
+ string sourceCode = R"(
+ contract C {
+ event E(function(uint) external returns (uint), function(uint) external returns (uint));
+ function(uint) external returns (uint) g;
+ function f(uint) returns (uint) {
+ g = this.f;
+ E(this.f, g);
+ }
+ }
+ )";
+ BOTH_ENCODERS(
+ compileAndRun(sourceCode);
+ callContractFunction("f(uint256)");
+ string functionIdF = asString(m_contractAddress.ref()) + asString(FixedHash<4>(dev::keccak256("f(uint256)")).ref());
+ REQUIRE_LOG_DATA(encodeArgs(functionIdF, functionIdF));
+ )
+}
+
+BOOST_AUTO_TEST_CASE(external_function_cleanup)
+{
+ string sourceCode = R"(
+ contract C {
+ event E(function(uint) external returns (uint), function(uint) external returns (uint));
+ // This test relies on the fact that g is stored in slot zero.
+ function(uint) external returns (uint) g;
+ function f(uint) returns (uint) {
+ function(uint) external returns (uint)[1] memory h;
+ assembly { sstore(0, sub(0, 1)) mstore(h, sub(0, 1)) }
+ E(h[0], g);
+ }
+ }
+ )";
+ BOTH_ENCODERS(
+ compileAndRun(sourceCode);
+ callContractFunction("f(uint256)");
+ REQUIRE_LOG_DATA(encodeArgs(string(24, char(-1)), string(24, char(-1))));
+ )
+}
+
+BOOST_AUTO_TEST_CASE(calldata)
+{
+ string sourceCode = R"(
+ contract C {
+ event E(bytes);
+ function f(bytes a) external {
+ E(a);
+ }
+ }
+ )";
+ string s("abcdef");
+ string t("abcdefgggggggggggggggggggggggggggggggggggggggghhheeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeggg");
+ bool newEncoder = false;
+ BOTH_ENCODERS(
+ compileAndRun(sourceCode);
+ callContractFunction("f(bytes)", 0x20, s.size(), s);
+ // The old encoder did not pad to multiples of 32 bytes
+ REQUIRE_LOG_DATA(encodeArgs(0x20, s.size()) + (newEncoder ? encodeArgs(s) : asBytes(s)));
+ callContractFunction("f(bytes)", 0x20, t.size(), t);
+ REQUIRE_LOG_DATA(encodeArgs(0x20, t.size()) + (newEncoder ? encodeArgs(t) : asBytes(t)));
+ newEncoder = true;
+ )
+}
+
+BOOST_AUTO_TEST_SUITE_END()
+
+}
+}
+} // end namespaces
diff --git a/test/libsolidity/Imports.cpp b/test/libsolidity/Imports.cpp
index 00f093b7..03287b28 100644
--- a/test/libsolidity/Imports.cpp
+++ b/test/libsolidity/Imports.cpp
@@ -226,18 +226,19 @@ BOOST_AUTO_TEST_CASE(shadowing_builtins_with_imports)
}
)");
BOOST_CHECK(c.compile());
- auto numErrors = c.errors().size();
- // Sometimes we get the prerelease warning, sometimes not.
- BOOST_CHECK(2 <= numErrors && numErrors <= 3);
+ size_t errorCount = 0;
for (auto const& e: c.errors())
{
string const* msg = e->comment();
BOOST_REQUIRE(msg);
+ if (msg->find("pre-release") != string::npos)
+ continue;
BOOST_CHECK(
- msg->find("pre-release") != string::npos ||
msg->find("shadows a builtin symbol") != string::npos
);
+ errorCount++;
}
+ BOOST_CHECK_EQUAL(errorCount, 1);
}
BOOST_AUTO_TEST_CASE(shadowing_builtins_with_multiple_imports)
diff --git a/test/libsolidity/Metadata.cpp b/test/libsolidity/Metadata.cpp
index 0d3caddd..c46e3160 100644
--- a/test/libsolidity/Metadata.cpp
+++ b/test/libsolidity/Metadata.cpp
@@ -38,6 +38,7 @@ BOOST_AUTO_TEST_CASE(metadata_stamp)
// Check that the metadata stamp is at the end of the runtime bytecode.
char const* sourceCode = R"(
pragma solidity >=0.0;
+ pragma experimental __testOnlyAnalysis;
contract test {
function g(function(uint) external returns (uint) x) {}
}
@@ -58,6 +59,35 @@ BOOST_AUTO_TEST_CASE(metadata_stamp)
BOOST_CHECK(std::equal(expectation.begin(), expectation.end(), bytecode.end() - metadataCBORSize - 2));
}
+BOOST_AUTO_TEST_CASE(metadata_stamp_experimental)
+{
+ // Check that the metadata stamp is at the end of the runtime bytecode.
+ char const* sourceCode = R"(
+ pragma solidity >=0.0;
+ pragma experimental __test;
+ contract test {
+ function g(function(uint) external returns (uint) x) {}
+ }
+ )";
+ CompilerStack compilerStack;
+ compilerStack.addSource("", std::string(sourceCode));
+ compilerStack.setOptimiserSettings(dev::test::Options::get().optimize);
+ ETH_TEST_REQUIRE_NO_THROW(compilerStack.compile(), "Compiling contract failed");
+ bytes const& bytecode = compilerStack.runtimeObject("test").bytecode;
+ std::string const& metadata = compilerStack.metadata("test");
+ BOOST_CHECK(dev::test::isValidMetadata(metadata));
+ bytes hash = dev::swarmHash(metadata).asBytes();
+ BOOST_REQUIRE(hash.size() == 32);
+ BOOST_REQUIRE(bytecode.size() >= 2);
+ size_t metadataCBORSize = (size_t(bytecode.end()[-2]) << 8) + size_t(bytecode.end()[-1]);
+ BOOST_REQUIRE(metadataCBORSize < bytecode.size() - 2);
+ bytes expectation =
+ bytes{0xa2, 0x65, 'b', 'z', 'z', 'r', '0', 0x58, 0x20} +
+ hash +
+ bytes{0x6c, 'e', 'x', 'p', 'e', 'r', 'i', 'm', 'e', 'n', 't', 'a', 'l', 0xf5};
+ BOOST_CHECK(std::equal(expectation.begin(), expectation.end(), bytecode.end() - metadataCBORSize - 2));
+}
+
BOOST_AUTO_TEST_CASE(metadata_relevant_sources)
{
CompilerStack compilerStack;
diff --git a/test/libsolidity/SolidityABIJSON.cpp b/test/libsolidity/SolidityABIJSON.cpp
index 452a2662..80b4b6ad 100644
--- a/test/libsolidity/SolidityABIJSON.cpp
+++ b/test/libsolidity/SolidityABIJSON.cpp
@@ -76,6 +76,7 @@ BOOST_AUTO_TEST_CASE(basic_test)
"name": "f",
"constant": false,
"payable" : false,
+ "statemutability": "nonpayable",
"type": "function",
"inputs": [
{
@@ -119,6 +120,7 @@ BOOST_AUTO_TEST_CASE(multiple_methods)
"name": "f",
"constant": false,
"payable" : false,
+ "statemutability": "nonpayable",
"type": "function",
"inputs": [
{
@@ -137,6 +139,7 @@ BOOST_AUTO_TEST_CASE(multiple_methods)
"name": "g",
"constant": false,
"payable" : false,
+ "statemutability": "nonpayable",
"type": "function",
"inputs": [
{
@@ -169,6 +172,7 @@ BOOST_AUTO_TEST_CASE(multiple_params)
"name": "f",
"constant": false,
"payable" : false,
+ "statemutability": "nonpayable",
"type": "function",
"inputs": [
{
@@ -207,6 +211,7 @@ BOOST_AUTO_TEST_CASE(multiple_methods_order)
"name": "c",
"constant": false,
"payable" : false,
+ "statemutability": "nonpayable",
"type": "function",
"inputs": [
{
@@ -225,6 +230,7 @@ BOOST_AUTO_TEST_CASE(multiple_methods_order)
"name": "f",
"constant": false,
"payable" : false,
+ "statemutability": "nonpayable",
"type": "function",
"inputs": [
{
@@ -258,6 +264,7 @@ BOOST_AUTO_TEST_CASE(const_function)
"name": "foo",
"constant": false,
"payable" : false,
+ "statemutability": "nonpayable",
"type": "function",
"inputs": [
{
@@ -280,6 +287,7 @@ BOOST_AUTO_TEST_CASE(const_function)
"name": "boo",
"constant": true,
"payable" : false,
+ "statemutability": "view",
"type": "function",
"inputs": [{
"name": "a",
@@ -311,6 +319,7 @@ BOOST_AUTO_TEST_CASE(events)
"name": "f",
"constant": false,
"payable" : false,
+ "statemutability": "nonpayable",
"type": "function",
"inputs": [
{
@@ -392,6 +401,7 @@ BOOST_AUTO_TEST_CASE(inherited)
"name": "baseFunction",
"constant": false,
"payable" : false,
+ "statemutability": "nonpayable",
"type": "function",
"inputs":
[{
@@ -408,6 +418,7 @@ BOOST_AUTO_TEST_CASE(inherited)
"name": "derivedFunction",
"constant": false,
"payable" : false,
+ "statemutability": "nonpayable",
"type": "function",
"inputs":
[{
@@ -463,6 +474,7 @@ BOOST_AUTO_TEST_CASE(empty_name_input_parameter_with_named_one)
"name": "f",
"constant": false,
"payable" : false,
+ "statemutability": "nonpayable",
"type": "function",
"inputs": [
{
@@ -505,6 +517,7 @@ BOOST_AUTO_TEST_CASE(empty_name_return_parameter)
"name": "f",
"constant": false,
"payable" : false,
+ "statemutability": "nonpayable",
"type": "function",
"inputs": [
{
@@ -548,12 +561,44 @@ BOOST_AUTO_TEST_CASE(constructor_abi)
}
],
"payable": false,
+ "statemutability": "nonpayable",
"type": "constructor"
}
])";
checkInterface(sourceCode, interface);
}
+BOOST_AUTO_TEST_CASE(payable_constructor_abi)
+{
+ char const* sourceCode = R"(
+ contract test {
+ function test(uint param1, test param2, bool param3) payable {}
+ }
+ )";
+
+ char const* interface = R"([
+ {
+ "inputs": [
+ {
+ "name": "param1",
+ "type": "uint256"
+ },
+ {
+ "name": "param2",
+ "type": "address"
+ },
+ {
+ "name": "param3",
+ "type": "bool"
+ }
+ ],
+ "payable": true,
+ "statemutability": "payable",
+ "type": "constructor"
+ }
+ ])";
+ checkInterface(sourceCode, interface);
+}
BOOST_AUTO_TEST_CASE(return_param_in_abi)
{
@@ -574,6 +619,7 @@ BOOST_AUTO_TEST_CASE(return_param_in_abi)
{
"constant" : false,
"payable" : false,
+ "statemutability": "nonpayable",
"inputs" : [],
"name" : "ret",
"outputs" : [
@@ -592,6 +638,7 @@ BOOST_AUTO_TEST_CASE(return_param_in_abi)
}
],
"payable": false,
+ "statemutability": "nonpayable",
"type": "constructor"
}
]
@@ -613,6 +660,7 @@ BOOST_AUTO_TEST_CASE(strings_and_arrays)
{
"constant" : false,
"payable" : false,
+ "statemutability": "nonpayable",
"name": "f",
"inputs": [
{ "name": "a", "type": "string" },
@@ -641,6 +689,7 @@ BOOST_AUTO_TEST_CASE(library_function)
{
"constant" : false,
"payable" : false,
+ "statemutability": "nonpayable",
"name": "f",
"inputs": [
{ "name": "b", "type": "test.StructType storage" },
@@ -670,6 +719,7 @@ BOOST_AUTO_TEST_CASE(include_fallback_function)
[
{
"payable": false,
+ "statemutability": "nonpayable",
"type" : "fallback"
}
]
@@ -691,6 +741,7 @@ BOOST_AUTO_TEST_CASE(payable_function)
{
"constant" : false,
"payable": false,
+ "statemutability": "nonpayable",
"inputs": [],
"name": "f",
"outputs": [],
@@ -699,6 +750,7 @@ BOOST_AUTO_TEST_CASE(payable_function)
{
"constant" : false,
"payable": true,
+ "statemutability": "payable",
"inputs": [],
"name": "g",
"outputs": [],
@@ -721,6 +773,7 @@ BOOST_AUTO_TEST_CASE(payable_fallback_function)
[
{
"payable": true,
+ "statemutability": "payable",
"type" : "fallback"
}
]
@@ -741,6 +794,7 @@ BOOST_AUTO_TEST_CASE(function_type)
{
"constant" : false,
"payable": false,
+ "statemutability": "nonpayable",
"inputs": [{
"name": "x",
"type": "function"
diff --git a/test/libsolidity/SolidityEndToEndTest.cpp b/test/libsolidity/SolidityEndToEndTest.cpp
index 5bcde441..73dd7d22 100644
--- a/test/libsolidity/SolidityEndToEndTest.cpp
+++ b/test/libsolidity/SolidityEndToEndTest.cpp
@@ -1950,6 +1950,87 @@ BOOST_AUTO_TEST_CASE(ripemd)
testContractAgainstCpp("a(bytes32)", f, u256(-1));
}
+BOOST_AUTO_TEST_CASE(packed_keccak256)
+{
+ char const* sourceCode = R"(
+ contract test {
+ function a(bytes32 input) returns (bytes32 hash) {
+ var b = 65536;
+ uint c = 256;
+ return keccak256(8, input, b, input, c);
+ }
+ }
+ )";
+ compileAndRun(sourceCode);
+ auto f = [&](u256 const& _x) -> u256
+ {
+ return dev::keccak256(
+ toCompactBigEndian(unsigned(8)) +
+ toBigEndian(_x) +
+ toCompactBigEndian(unsigned(65536)) +
+ toBigEndian(_x) +
+ toBigEndian(u256(256))
+ );
+ };
+ testContractAgainstCpp("a(bytes32)", f, u256(4));
+ testContractAgainstCpp("a(bytes32)", f, u256(5));
+ testContractAgainstCpp("a(bytes32)", f, u256(-1));
+}
+
+BOOST_AUTO_TEST_CASE(packed_sha256)
+{
+ char const* sourceCode = R"(
+ contract test {
+ function a(bytes32 input) returns (bytes32 hash) {
+ var b = 65536;
+ uint c = 256;
+ return sha256(8, input, b, input, c);
+ }
+ }
+ )";
+ compileAndRun(sourceCode);
+ auto f = [&](u256 const& _x) -> bytes
+ {
+ if (_x == u256(4))
+ return fromHex("804e0d7003cfd70fc925dc103174d9f898ebb142ecc2a286da1abd22ac2ce3ac");
+ if (_x == u256(5))
+ return fromHex("e94921945f9068726c529a290a954f412bcac53184bb41224208a31edbf63cf0");
+ if (_x == u256(-1))
+ return fromHex("f14def4d07cd185ddd8b10a81b2238326196a38867e6e6adbcc956dc913488c7");
+ return fromHex("");
+ };
+ testContractAgainstCpp("a(bytes32)", f, u256(4));
+ testContractAgainstCpp("a(bytes32)", f, u256(5));
+ testContractAgainstCpp("a(bytes32)", f, u256(-1));
+}
+
+BOOST_AUTO_TEST_CASE(packed_ripemd160)
+{
+ char const* sourceCode = R"(
+ contract test {
+ function a(bytes32 input) returns (bytes32 hash) {
+ var b = 65536;
+ uint c = 256;
+ return ripemd160(8, input, b, input, c);
+ }
+ }
+ )";
+ compileAndRun(sourceCode);
+ auto f = [&](u256 const& _x) -> bytes
+ {
+ if (_x == u256(4))
+ return fromHex("f93175303eba2a7b372174fc9330237f5ad202fc000000000000000000000000");
+ if (_x == u256(5))
+ return fromHex("04f4fc112e2bfbe0d38f896a46629e08e2fcfad5000000000000000000000000");
+ if (_x == u256(-1))
+ return fromHex("c0a2e4b1f3ff766a9a0089e7a410391730872495000000000000000000000000");
+ return fromHex("");
+ };
+ testContractAgainstCpp("a(bytes32)", f, u256(4));
+ testContractAgainstCpp("a(bytes32)", f, u256(5));
+ testContractAgainstCpp("a(bytes32)", f, u256(-1));
+}
+
BOOST_AUTO_TEST_CASE(ecrecover)
{
char const* sourceCode = R"(
@@ -2318,21 +2399,6 @@ BOOST_AUTO_TEST_CASE(gas_and_value_basic)
BOOST_REQUIRE(callContractFunction("checkState()") == encodeArgs(false, 20 - 5));
}
-BOOST_AUTO_TEST_CASE(gas_for_builtin)
-{
- char const* sourceCode = R"(
- contract Contract {
- function test(uint g) returns (bytes32 data, bool flag) {
- data = ripemd160.gas(g)("abc");
- flag = true;
- }
- }
- )";
- compileAndRun(sourceCode);
- BOOST_CHECK(callContractFunction("test(uint256)", 500) == bytes());
- BOOST_CHECK(callContractFunction("test(uint256)", 800) == encodeArgs(u256("0x8eb208f7e05d987a9b044a8e98c6b087f15a0bfc000000000000000000000000"), true));
-}
-
BOOST_AUTO_TEST_CASE(value_complex)
{
char const* sourceCode = R"(
@@ -3062,7 +3128,7 @@ BOOST_AUTO_TEST_CASE(event_really_lots_of_data)
callContractFunction("deposit()");
BOOST_REQUIRE_EQUAL(m_logs.size(), 1);
BOOST_CHECK_EQUAL(m_logs[0].address, m_contractAddress);
- BOOST_CHECK(m_logs[0].data == encodeArgs(10, 0x60, 15, 4) + FixedHash<4>(dev::keccak256("deposit()")).asBytes());
+ BOOST_CHECK_EQUAL(toHex(m_logs[0].data), toHex(encodeArgs(10, 0x60, 15, 4) + FixedHash<4>(dev::keccak256("deposit()")).asBytes()));
BOOST_REQUIRE_EQUAL(m_logs[0].topics.size(), 1);
BOOST_CHECK_EQUAL(m_logs[0].topics[0], dev::keccak256(string("Deposit(uint256,bytes,uint256)")));
}
@@ -3086,7 +3152,32 @@ BOOST_AUTO_TEST_CASE(event_really_lots_of_data_from_storage)
callContractFunction("deposit()");
BOOST_REQUIRE_EQUAL(m_logs.size(), 1);
BOOST_CHECK_EQUAL(m_logs[0].address, m_contractAddress);
- BOOST_CHECK(m_logs[0].data == encodeArgs(10, 0x60, 15, 3, string("ABC")));
+ BOOST_CHECK_EQUAL(toHex(m_logs[0].data), toHex(encodeArgs(10, 0x60, 15, 3, string("ABC"))));
+ BOOST_REQUIRE_EQUAL(m_logs[0].topics.size(), 1);
+ BOOST_CHECK_EQUAL(m_logs[0].topics[0], dev::keccak256(string("Deposit(uint256,bytes,uint256)")));
+}
+
+BOOST_AUTO_TEST_CASE(event_really_really_lots_of_data_from_storage)
+{
+ char const* sourceCode = R"(
+ contract ClientReceipt {
+ bytes x;
+ event Deposit(uint fixeda, bytes dynx, uint fixedb);
+ function deposit() {
+ x.length = 31;
+ x[0] = "A";
+ x[1] = "B";
+ x[2] = "C";
+ x[30] = "Z";
+ Deposit(10, x, 15);
+ }
+ }
+ )";
+ compileAndRun(sourceCode);
+ callContractFunction("deposit()");
+ BOOST_REQUIRE_EQUAL(m_logs.size(), 1);
+ BOOST_CHECK_EQUAL(m_logs[0].address, m_contractAddress);
+ BOOST_CHECK(m_logs[0].data == encodeArgs(10, 0x60, 15, 31, string("ABC") + string(27, 0) + "Z"));
BOOST_REQUIRE_EQUAL(m_logs[0].topics.size(), 1);
BOOST_CHECK_EQUAL(m_logs[0].topics[0], dev::keccak256(string("Deposit(uint256,bytes,uint256)")));
}
@@ -4336,6 +4427,92 @@ BOOST_AUTO_TEST_CASE(array_copy_storage_storage_struct)
BOOST_CHECK(storageEmpty(m_contractAddress));
}
+BOOST_AUTO_TEST_CASE(array_copy_storage_abi)
+{
+ // NOTE: This does not really test copying from storage to ABI directly,
+ // because it will always copy to memory first.
+ char const* sourceCode = R"(
+ pragma experimental ABIEncoderV2;
+ contract c {
+ uint8[] x;
+ uint16[] y;
+ uint24[] z;
+ uint24[][] w;
+ function test1() returns (uint8[]) {
+ for (uint i = 0; i < 101; ++i)
+ x.push(uint8(i));
+ return x;
+ }
+ function test2() returns (uint16[]) {
+ for (uint i = 0; i < 101; ++i)
+ y.push(uint16(i));
+ return y;
+ }
+ function test3() returns (uint24[]) {
+ for (uint i = 0; i < 101; ++i)
+ z.push(uint24(i));
+ return z;
+ }
+ function test4() returns (uint24[][]) {
+ w.length = 5;
+ for (uint i = 0; i < 5; ++i)
+ for (uint j = 0; j < 101; ++j)
+ w[i].push(uint24(j));
+ return w;
+ }
+ }
+ )";
+ compileAndRun(sourceCode);
+ bytes valueSequence;
+ for (size_t i = 0; i < 101; ++i)
+ valueSequence += toBigEndian(u256(i));
+ BOOST_CHECK(callContractFunction("test1()") == encodeArgs(0x20, 101) + valueSequence);
+ BOOST_CHECK(callContractFunction("test2()") == encodeArgs(0x20, 101) + valueSequence);
+ BOOST_CHECK(callContractFunction("test3()") == encodeArgs(0x20, 101) + valueSequence);
+ BOOST_CHECK(callContractFunction("test4()") ==
+ encodeArgs(0x20, 5, 0xa0, 0xa0 + 102 * 32 * 1, 0xa0 + 102 * 32 * 2, 0xa0 + 102 * 32 * 3, 0xa0 + 102 * 32 * 4) +
+ encodeArgs(101) + valueSequence +
+ encodeArgs(101) + valueSequence +
+ encodeArgs(101) + valueSequence +
+ encodeArgs(101) + valueSequence +
+ encodeArgs(101) + valueSequence
+ );
+}
+
+BOOST_AUTO_TEST_CASE(array_copy_storage_abi_signed)
+{
+ // NOTE: This does not really test copying from storage to ABI directly,
+ // because it will always copy to memory first.
+ char const* sourceCode = R"(
+ contract c {
+ int16[] x;
+ function test() returns (int16[]) {
+ x.push(int16(-1));
+ x.push(int16(-1));
+ x.push(int16(8));
+ x.push(int16(-16));
+ x.push(int16(-2));
+ x.push(int16(6));
+ x.push(int16(8));
+ x.push(int16(-1));
+ return x;
+ }
+ }
+ )";
+ compileAndRun(sourceCode);
+ bytes valueSequence;
+ BOOST_CHECK(callContractFunction("test()") == encodeArgs(0x20, 8,
+ u256(-1),
+ u256(-1),
+ u256(8),
+ u256(-16),
+ u256(-2),
+ u256(6),
+ u256(8),
+ u256(-1)
+ ));
+}
+
BOOST_AUTO_TEST_CASE(array_push)
{
char const* sourceCode = R"(
@@ -8251,6 +8428,53 @@ BOOST_AUTO_TEST_CASE(failing_ecrecover_invalid_input)
BOOST_CHECK(callContractFunction("f()") == encodeArgs(u256(0)));
}
+BOOST_AUTO_TEST_CASE(failing_ecrecover_invalid_input_proper)
+{
+ char const* sourceCode = R"(
+ contract C {
+ function f() returns (address) {
+ return recover(
+ 0x77e5189111eb6557e8a637b27ef8fbb15bc61d61c2f00cc48878f3a296e5e0ca,
+ 0, // invalid v value
+ 0x6944c77849b18048f6abe0db8084b0d0d0689cdddb53d2671c36967b58691ad4,
+ 0xef4f06ba4f78319baafd0424365777241af4dfd3da840471b4b4b087b7750d0d,
+ 0xca35b7d915458ef540ade6068dfe2f44e8fa733c,
+ 0xca35b7d915458ef540ade6068dfe2f44e8fa733c
+ );
+ }
+ function recover(bytes32 hash, uint8 v, bytes32 r, bytes32 s, uint blockExpired, bytes32 salt)
+ returns (address)
+ {
+ require(hash == keccak256(blockExpired, salt));
+ return ecrecover(hash, v, r, s);
+ }
+ }
+ )";
+ compileAndRun(sourceCode, 0, "C");
+ BOOST_CHECK(callContractFunction("f()") == encodeArgs(u256(0)));
+}
+
+BOOST_AUTO_TEST_CASE(failing_ecrecover_invalid_input_asm)
+{
+ char const* sourceCode = R"(
+ contract C {
+ function f() returns (address) {
+ assembly {
+ mstore(mload(0x40), 0xca35b7d915458ef540ade6068dfe2f44e8fa733c)
+ }
+ return ecrecover(
+ 0x77e5189111eb6557e8a637b27ef8fbb15bc61d61c2f00cc48878f3a296e5e0ca,
+ 0, // invalid v value
+ 0x6944c77849b18048f6abe0db8084b0d0d0689cdddb53d2671c36967b58691ad4,
+ 0xef4f06ba4f78319baafd0424365777241af4dfd3da840471b4b4b087b7750d0d
+ );
+ }
+ }
+ )";
+ compileAndRun(sourceCode, 0, "C");
+ BOOST_CHECK(callContractFunction("f()") == encodeArgs(u256(0)));
+}
+
BOOST_AUTO_TEST_CASE(calling_nonexisting_contract_throws)
{
char const* sourceCode = R"(
@@ -9769,6 +9993,64 @@ BOOST_AUTO_TEST_CASE(inlineasm_empty_let)
BOOST_CHECK(callContractFunction("f()") == encodeArgs(u256(0), u256(0)));
}
+BOOST_AUTO_TEST_CASE(bare_call_invalid_address)
+{
+ char const* sourceCode = R"(
+ contract C {
+ /// Calling into non-existant account is successful (creates the account)
+ function f() external constant returns (bool) {
+ return address(0x4242).call();
+ }
+ function g() external constant returns (bool) {
+ return address(0x4242).callcode();
+ }
+ function h() external constant returns (bool) {
+ return address(0x4242).delegatecall();
+ }
+ }
+ )";
+ compileAndRun(sourceCode, 0, "C");
+ BOOST_CHECK(callContractFunction("f()") == encodeArgs(u256(1)));
+ BOOST_CHECK(callContractFunction("g()") == encodeArgs(u256(1)));
+ BOOST_CHECK(callContractFunction("h()") == encodeArgs(u256(1)));
+}
+
+BOOST_AUTO_TEST_CASE(delegatecall_return_value)
+{
+ char const* sourceCode = R"DELIMITER(
+ contract C {
+ uint value;
+ function set(uint _value) external {
+ value = _value;
+ }
+ function get() external constant returns (uint) {
+ return value;
+ }
+ function get_delegated() external constant returns (bool) {
+ return this.delegatecall(bytes4(sha3("get()")));
+ }
+ function assert0() external constant {
+ assert(value == 0);
+ }
+ function assert0_delegated() external constant returns (bool) {
+ return this.delegatecall(bytes4(sha3("assert0()")));
+ }
+ }
+ )DELIMITER";
+ compileAndRun(sourceCode, 0, "C");
+ BOOST_CHECK(callContractFunction("get()") == encodeArgs(u256(0)));
+ BOOST_CHECK(callContractFunction("assert0_delegated()") == encodeArgs(u256(1)));
+ BOOST_CHECK(callContractFunction("get_delegated()") == encodeArgs(u256(1)));
+ BOOST_CHECK(callContractFunction("set(uint256)", u256(1)) == encodeArgs());
+ BOOST_CHECK(callContractFunction("get()") == encodeArgs(u256(1)));
+ BOOST_CHECK(callContractFunction("assert0_delegated()") == encodeArgs(u256(0)));
+ BOOST_CHECK(callContractFunction("get_delegated()") == encodeArgs(u256(1)));
+ BOOST_CHECK(callContractFunction("set(uint256)", u256(42)) == encodeArgs());
+ BOOST_CHECK(callContractFunction("get()") == encodeArgs(u256(42)));
+ BOOST_CHECK(callContractFunction("assert0_delegated()") == encodeArgs(u256(0)));
+ BOOST_CHECK(callContractFunction("get_delegated()") == encodeArgs(u256(1)));
+}
+
BOOST_AUTO_TEST_SUITE_END()
}
diff --git a/test/libsolidity/SolidityNameAndTypeResolution.cpp b/test/libsolidity/SolidityNameAndTypeResolution.cpp
index cd922cc8..51d60596 100644
--- a/test/libsolidity/SolidityNameAndTypeResolution.cpp
+++ b/test/libsolidity/SolidityNameAndTypeResolution.cpp
@@ -249,7 +249,7 @@ BOOST_AUTO_TEST_CASE(double_stateVariable_declaration)
uint128 variable;
}
)";
- CHECK_ERROR(text, DeclarationError, "");
+ CHECK_ERROR(text, DeclarationError, "Identifier already declared.");
}
BOOST_AUTO_TEST_CASE(double_function_declaration)
@@ -260,7 +260,7 @@ BOOST_AUTO_TEST_CASE(double_function_declaration)
function fun() { }
}
)";
- CHECK_ERROR(text, DeclarationError, "");
+ CHECK_ERROR(text, DeclarationError, "Function with same name and arguments defined twice.");
}
BOOST_AUTO_TEST_CASE(double_variable_declaration)
@@ -273,7 +273,7 @@ BOOST_AUTO_TEST_CASE(double_variable_declaration)
}
}
)";
- CHECK_ERROR(text, DeclarationError, "");
+ CHECK_ERROR(text, DeclarationError, "Identifier already declared.");
}
BOOST_AUTO_TEST_CASE(name_shadowing)
@@ -308,7 +308,7 @@ BOOST_AUTO_TEST_CASE(undeclared_name)
}
}
)";
- CHECK_ERROR(text, DeclarationError, "");
+ CHECK_ERROR(text, DeclarationError, "Undeclared identifier.");
}
BOOST_AUTO_TEST_CASE(reference_to_later_declaration)
@@ -332,7 +332,7 @@ BOOST_AUTO_TEST_CASE(struct_definition_directly_recursive)
}
}
)";
- CHECK_ERROR(text, TypeError, "");
+ CHECK_ERROR(text, TypeError, "Recursive struct definition.");
}
BOOST_AUTO_TEST_CASE(struct_definition_indirectly_recursive)
@@ -349,7 +349,7 @@ BOOST_AUTO_TEST_CASE(struct_definition_indirectly_recursive)
}
}
)";
- CHECK_ERROR(text, TypeError, "");
+ CHECK_ERROR(text, TypeError, "Recursive struct definition.");
}
BOOST_AUTO_TEST_CASE(struct_definition_not_really_recursive)
@@ -406,7 +406,7 @@ BOOST_AUTO_TEST_CASE(type_checking_return_wrong_number)
function f() returns (bool r1, bool r2) { return 1 >= 2; }
}
)";
- CHECK_ERROR(text, TypeError, "");
+ CHECK_ERROR(text, TypeError, "Different number of arguments in return statement than in returns declaration.");
}
BOOST_AUTO_TEST_CASE(type_checking_return_wrong_type)
@@ -416,7 +416,7 @@ BOOST_AUTO_TEST_CASE(type_checking_return_wrong_type)
function f() returns (uint256 r) { return 1 >= 2; }
}
)";
- CHECK_ERROR(text, TypeError, "");
+ CHECK_ERROR(text, TypeError, "Return argument type bool is not implicitly convertible to expected type (type of first return variable) uint256.");
}
BOOST_AUTO_TEST_CASE(type_checking_function_call)
@@ -447,7 +447,7 @@ BOOST_AUTO_TEST_CASE(type_conversion_for_comparison_invalid)
function f() { int32(2) == uint64(2); }
}
)";
- CHECK_ERROR(text, TypeError, "");
+ CHECK_ERROR(text, TypeError, "Operator == not compatible with types int32 and uint64");
}
BOOST_AUTO_TEST_CASE(type_inference_explicit_conversion)
@@ -491,7 +491,7 @@ BOOST_AUTO_TEST_CASE(balance_invalid)
}
}
)";
- CHECK_ERROR(text, TypeError, "");
+ CHECK_ERROR(text, TypeError, "Expression has to be an lvalue.");
}
BOOST_AUTO_TEST_CASE(assignment_to_mapping)
@@ -508,7 +508,7 @@ BOOST_AUTO_TEST_CASE(assignment_to_mapping)
}
}
)";
- CHECK_ERROR(text, TypeError, "");
+ CHECK_ERROR(text, TypeError, "Mappings cannot be assigned to.");
}
BOOST_AUTO_TEST_CASE(assignment_to_struct)
@@ -535,7 +535,7 @@ BOOST_AUTO_TEST_CASE(returns_in_constructor)
function test() returns (uint a) { }
}
)";
- CHECK_ERROR(text, TypeError, "");
+ CHECK_ERROR(text, TypeError, "Non-empty \"returns\" directive for constructor.");
}
BOOST_AUTO_TEST_CASE(forward_function_reference)
@@ -624,7 +624,7 @@ BOOST_AUTO_TEST_CASE(function_no_implementation)
std::vector<ASTPointer<ASTNode>> nodes = sourceUnit->nodes();
ContractDefinition* contract = dynamic_cast<ContractDefinition*>(nodes[1].get());
BOOST_REQUIRE(contract);
- BOOST_CHECK(!contract->annotation().isFullyImplemented);
+ BOOST_CHECK(!contract->annotation().unimplementedFunctions.empty());
BOOST_CHECK(!contract->definedFunctions()[0]->isImplemented());
}
@@ -640,10 +640,10 @@ BOOST_AUTO_TEST_CASE(abstract_contract)
ContractDefinition* base = dynamic_cast<ContractDefinition*>(nodes[1].get());
ContractDefinition* derived = dynamic_cast<ContractDefinition*>(nodes[2].get());
BOOST_REQUIRE(base);
- BOOST_CHECK(!base->annotation().isFullyImplemented);
+ BOOST_CHECK(!base->annotation().unimplementedFunctions.empty());
BOOST_CHECK(!base->definedFunctions()[0]->isImplemented());
BOOST_REQUIRE(derived);
- BOOST_CHECK(derived->annotation().isFullyImplemented);
+ BOOST_CHECK(derived->annotation().unimplementedFunctions.empty());
BOOST_CHECK(derived->definedFunctions()[0]->isImplemented());
}
@@ -659,9 +659,9 @@ BOOST_AUTO_TEST_CASE(abstract_contract_with_overload)
ContractDefinition* base = dynamic_cast<ContractDefinition*>(nodes[1].get());
ContractDefinition* derived = dynamic_cast<ContractDefinition*>(nodes[2].get());
BOOST_REQUIRE(base);
- BOOST_CHECK(!base->annotation().isFullyImplemented);
+ BOOST_CHECK(!base->annotation().unimplementedFunctions.empty());
BOOST_REQUIRE(derived);
- BOOST_CHECK(!derived->annotation().isFullyImplemented);
+ BOOST_CHECK(!derived->annotation().unimplementedFunctions.empty());
}
BOOST_AUTO_TEST_CASE(create_abstract_contract)
@@ -674,45 +674,7 @@ BOOST_AUTO_TEST_CASE(create_abstract_contract)
function foo() { b = new base(); }
}
)";
- CHECK_ERROR(text, TypeError, "");
-}
-
-BOOST_AUTO_TEST_CASE(abstract_contract_constructor_args_optional)
-{
- ASTPointer<SourceUnit> sourceUnit;
- char const* text = R"(
- contract BaseBase { function BaseBase(uint j); }
- contract base is BaseBase { function foo(); }
- contract derived is base {
- function derived(uint i) BaseBase(i){}
- function foo() {}
- }
- )";
- ETH_TEST_REQUIRE_NO_THROW(sourceUnit = parseAndAnalyse(text), "Parsing and name resolving failed");
- std::vector<ASTPointer<ASTNode>> nodes = sourceUnit->nodes();
- BOOST_CHECK_EQUAL(nodes.size(), 4);
- ContractDefinition* derived = dynamic_cast<ContractDefinition*>(nodes[3].get());
- BOOST_REQUIRE(derived);
- BOOST_CHECK(!derived->annotation().isFullyImplemented);
-}
-
-BOOST_AUTO_TEST_CASE(abstract_contract_constructor_args_not_provided)
-{
- ASTPointer<SourceUnit> sourceUnit;
- char const* text = R"(
- contract BaseBase { function BaseBase(uint); }
- contract base is BaseBase { function foo(); }
- contract derived is base {
- function derived(uint) {}
- function foo() {}
- }
- )";
- ETH_TEST_REQUIRE_NO_THROW(sourceUnit = parseAndAnalyse(text), "Parsing and name resolving failed");
- std::vector<ASTPointer<ASTNode>> nodes = sourceUnit->nodes();
- BOOST_CHECK_EQUAL(nodes.size(), 4);
- ContractDefinition* derived = dynamic_cast<ContractDefinition*>(nodes[3].get());
- BOOST_REQUIRE(derived);
- BOOST_CHECK(!derived->annotation().isFullyImplemented);
+ CHECK_ERROR(text, TypeError, "Trying to create an instance of an abstract contract.");
}
BOOST_AUTO_TEST_CASE(redeclare_implemented_abstract_function_as_abstract)
@@ -723,7 +685,7 @@ BOOST_AUTO_TEST_CASE(redeclare_implemented_abstract_function_as_abstract)
contract derived is base { function foo() {} }
contract wrong is derived { function foo(); }
)";
- CHECK_ERROR(text, TypeError, "");
+ CHECK_ERROR(text, TypeError, "Redeclaring an already implemented function as abstract");
}
BOOST_AUTO_TEST_CASE(implement_abstract_via_constructor)
@@ -738,7 +700,7 @@ BOOST_AUTO_TEST_CASE(implement_abstract_via_constructor)
BOOST_CHECK_EQUAL(nodes.size(), 3);
ContractDefinition* derived = dynamic_cast<ContractDefinition*>(nodes[2].get());
BOOST_REQUIRE(derived);
- BOOST_CHECK(!derived->annotation().isFullyImplemented);
+ BOOST_CHECK(!derived->annotation().unimplementedFunctions.empty());
}
BOOST_AUTO_TEST_CASE(function_canonical_signature)
@@ -855,7 +817,7 @@ BOOST_AUTO_TEST_CASE(function_external_call_not_allowed_conversion)
function g (C c) external {}
}
)";
- CHECK_ERROR(text, TypeError, "");
+ CHECK_ERROR(text, TypeError, "Invalid type for argument in function call. Invalid implicit conversion from address to contract C requested.");
}
BOOST_AUTO_TEST_CASE(function_internal_allowed_conversion)
@@ -889,7 +851,7 @@ BOOST_AUTO_TEST_CASE(function_internal_not_allowed_conversion)
}
}
)";
- CHECK_ERROR(text, TypeError, "");
+ CHECK_ERROR(text, TypeError, "Invalid type for argument in function call. Invalid implicit conversion from address to contract C requested.");
}
BOOST_AUTO_TEST_CASE(hash_collision_in_interface)
@@ -900,7 +862,7 @@ BOOST_AUTO_TEST_CASE(hash_collision_in_interface)
function tgeo() { }
}
)";
- CHECK_ERROR(text, TypeError, "");
+ CHECK_ERROR(text, TypeError, "Function signature hash collision for tgeo()");
}
BOOST_AUTO_TEST_CASE(inheritance_basic)
@@ -934,7 +896,7 @@ BOOST_AUTO_TEST_CASE(cyclic_inheritance)
contract A is B { }
contract B is A { }
)";
- CHECK_ERROR_ALLOW_MULTI(text, TypeError, "");
+ CHECK_ERROR_ALLOW_MULTI(text, TypeError, "Definition of base has to precede definition of derived contract");
}
BOOST_AUTO_TEST_CASE(legal_override_direct)
@@ -962,16 +924,25 @@ BOOST_AUTO_TEST_CASE(illegal_override_visibility)
contract B { function f() internal {} }
contract C is B { function f() public {} }
)";
- CHECK_ERROR(text, TypeError, "");
+ CHECK_ERROR(text, TypeError, "Overriding function visibility differs");
}
-BOOST_AUTO_TEST_CASE(illegal_override_constness)
+BOOST_AUTO_TEST_CASE(illegal_override_remove_constness)
{
char const* text = R"(
contract B { function f() constant {} }
contract C is B { function f() {} }
)";
- CHECK_ERROR(text, TypeError, "");
+ CHECK_ERROR(text, TypeError, "Overriding function should be declared constant.");
+}
+
+BOOST_AUTO_TEST_CASE(illegal_override_add_constness)
+{
+ char const* text = R"(
+ contract B { function f() {} }
+ contract C is B { function f() constant {} }
+ )";
+ CHECK_ERROR(text, TypeError, "Overriding function should not be declared constant.");
}
BOOST_AUTO_TEST_CASE(complex_inheritance)
@@ -1041,7 +1012,7 @@ BOOST_AUTO_TEST_CASE(implicit_base_to_derived_conversion)
function f() { B b = A(1); }
}
)";
- CHECK_ERROR(text, TypeError, "");
+ CHECK_ERROR(text, TypeError, "Type contract A is not implicitly convertible to expected type contract B.");
}
BOOST_AUTO_TEST_CASE(super_excludes_current_contract)
@@ -1058,7 +1029,7 @@ BOOST_AUTO_TEST_CASE(super_excludes_current_contract)
}
)";
- CHECK_ERROR(text, TypeError, "");
+ CHECK_ERROR(text, TypeError, "Member \"f\" not found or not visible after argument-dependent lookup in contract super B");
}
BOOST_AUTO_TEST_CASE(function_modifier_invocation)
@@ -1081,7 +1052,7 @@ BOOST_AUTO_TEST_CASE(invalid_function_modifier_type)
modifier mod1(uint a) { if (a > 0) _; }
}
)";
- CHECK_ERROR(text, TypeError, "");
+ CHECK_ERROR(text, TypeError, "Invalid type for argument in modifier invocation. Invalid implicit conversion from bool to uint256 requested.");
}
BOOST_AUTO_TEST_CASE(function_modifier_invocation_parameters)
@@ -1144,7 +1115,7 @@ BOOST_AUTO_TEST_CASE(illegal_modifier_override)
contract A { modifier mod(uint a) { _; } }
contract B is A { modifier mod(uint8 a) { _; } }
)";
- CHECK_ERROR(text, TypeError, "");
+ CHECK_ERROR(text, TypeError, "Override changes modifier signature.");
}
BOOST_AUTO_TEST_CASE(modifier_overrides_function)
@@ -1155,7 +1126,7 @@ BOOST_AUTO_TEST_CASE(modifier_overrides_function)
)";
// Error: Identifier already declared.
// Error: Override changes modifier to function.
- CHECK_ERROR_ALLOW_MULTI(text, DeclarationError, "Identifier already declared");
+ CHECK_ERROR_ALLOW_MULTI(text, DeclarationError, "Identifier already declared.");
}
BOOST_AUTO_TEST_CASE(function_overrides_modifier)
@@ -1166,7 +1137,7 @@ BOOST_AUTO_TEST_CASE(function_overrides_modifier)
)";
// Error: Identifier already declared.
// Error: Override changes function to modifier.
- CHECK_ERROR_ALLOW_MULTI(text, DeclarationError, "");
+ CHECK_ERROR_ALLOW_MULTI(text, DeclarationError, "Identifier already declared.");
}
BOOST_AUTO_TEST_CASE(modifier_returns_value)
@@ -1232,7 +1203,7 @@ BOOST_AUTO_TEST_CASE(function_clash_with_state_variable_accessor)
function foo() {}
}
)";
- CHECK_ERROR(text, DeclarationError, "");
+ CHECK_ERROR(text, DeclarationError, "Identifier already declared.");
}
BOOST_AUTO_TEST_CASE(private_state_variable)
@@ -1267,7 +1238,7 @@ BOOST_AUTO_TEST_CASE(missing_state_variable)
}
}
)";
- CHECK_ERROR(text, TypeError, "");
+ CHECK_ERROR(text, TypeError, "Member \"stateVar\" not found or not visible after argument-dependent lookup in type(contract Scope)");
}
@@ -1293,7 +1264,7 @@ BOOST_AUTO_TEST_CASE(struct_accessor_one_array_only)
Data public data;
}
)";
- CHECK_ERROR(sourceCode, TypeError, "");
+ CHECK_ERROR(sourceCode, TypeError, "Internal type is not allowed for public state variables.");
}
BOOST_AUTO_TEST_CASE(base_class_state_variable_internal_member)
@@ -1322,7 +1293,7 @@ BOOST_AUTO_TEST_CASE(state_variable_member_of_wrong_class1)
function foo() returns (uint256) { return Parent2.m_aMember1; }
}
)";
- CHECK_ERROR(text, TypeError, "");
+ CHECK_ERROR(text, TypeError, "Member \"m_aMember1\" not found or not visible after argument-dependent lookup in type(contract Parent2)");
}
BOOST_AUTO_TEST_CASE(state_variable_member_of_wrong_class2)
@@ -1339,7 +1310,7 @@ BOOST_AUTO_TEST_CASE(state_variable_member_of_wrong_class2)
uint256 public m_aMember3;
}
)";
- CHECK_ERROR(text, TypeError, "");
+ CHECK_ERROR(text, TypeError, "Member \"m_aMember2\" not found or not visible after argument-dependent lookup in type(contract Child)");
}
BOOST_AUTO_TEST_CASE(fallback_function)
@@ -1361,7 +1332,7 @@ BOOST_AUTO_TEST_CASE(fallback_function_with_arguments)
function(uint a) { x = 2; }
}
)";
- CHECK_ERROR(text, TypeError, "");
+ CHECK_ERROR(text, TypeError, "Fallback function cannot take parameters.");
}
BOOST_AUTO_TEST_CASE(fallback_function_in_library)
@@ -1371,7 +1342,7 @@ BOOST_AUTO_TEST_CASE(fallback_function_in_library)
function() {}
}
)";
- CHECK_ERROR(text, TypeError, "");
+ CHECK_ERROR(text, TypeError, "Libraries cannot have fallback functions.");
}
BOOST_AUTO_TEST_CASE(fallback_function_with_return_parameters)
@@ -1381,7 +1352,7 @@ BOOST_AUTO_TEST_CASE(fallback_function_with_return_parameters)
function() returns (uint) { }
}
)";
- CHECK_ERROR(text, TypeError, "");
+ CHECK_ERROR(text, TypeError, "Fallback function cannot return values.");
}
BOOST_AUTO_TEST_CASE(fallback_function_with_constant_modifier)
@@ -1392,7 +1363,7 @@ BOOST_AUTO_TEST_CASE(fallback_function_with_constant_modifier)
function() constant { x = 2; }
}
)";
- CHECK_ERROR(text, TypeError, "");
+ CHECK_ERROR(text, TypeError, "Fallback function cannot be declared constant.");
}
BOOST_AUTO_TEST_CASE(fallback_function_twice)
@@ -1404,7 +1375,7 @@ BOOST_AUTO_TEST_CASE(fallback_function_twice)
function() { x = 3; }
}
)";
- CHECK_ERROR_ALLOW_MULTI(text, DeclarationError, "");
+ CHECK_ERROR_ALLOW_MULTI(text, DeclarationError, "Function with same name and arguments defined twice.");
}
BOOST_AUTO_TEST_CASE(fallback_function_inheritance)
@@ -1439,7 +1410,7 @@ BOOST_AUTO_TEST_CASE(event_too_many_indexed)
event e(uint indexed a, bytes3 indexed b, bool indexed c, uint indexed d);
}
)";
- CHECK_ERROR(text, TypeError, "");
+ CHECK_ERROR(text, TypeError, "More than 3 indexed arguments for event.");
}
BOOST_AUTO_TEST_CASE(anonymous_event_four_indexed)
@@ -1459,7 +1430,7 @@ BOOST_AUTO_TEST_CASE(anonymous_event_too_many_indexed)
event e(uint indexed a, bytes3 indexed b, bool indexed c, uint indexed d, uint indexed e) anonymous;
}
)";
- CHECK_ERROR(text, TypeError, "");
+ CHECK_ERROR(text, TypeError, "More than 4 indexed arguments for anonymous event.");
}
BOOST_AUTO_TEST_CASE(events_with_same_name)
@@ -1578,7 +1549,7 @@ BOOST_AUTO_TEST_CASE(access_to_internal_function)
function g() { c(0).f(); }
}
)";
- CHECK_ERROR(text, TypeError, "");
+ CHECK_ERROR(text, TypeError, "Member \"f\" not found or not visible after argument-dependent lookup in contract c");
}
BOOST_AUTO_TEST_CASE(access_to_default_state_variable_visibility)
@@ -1591,7 +1562,7 @@ BOOST_AUTO_TEST_CASE(access_to_default_state_variable_visibility)
function g() { c(0).a(); }
}
)";
- CHECK_ERROR(text, TypeError, "");
+ CHECK_ERROR(text, TypeError, "Member \"a\" not found or not visible after argument-dependent lookup in contract c");
}
BOOST_AUTO_TEST_CASE(access_to_internal_state_variable)
@@ -1619,7 +1590,7 @@ BOOST_AUTO_TEST_CASE(error_count_in_named_args)
}
}
)";
- CHECK_ERROR(sourceCode, TypeError, "");
+ CHECK_ERROR(sourceCode, TypeError, "Wrong argument count for function call: 1 arguments given but expected 2.");
}
BOOST_AUTO_TEST_CASE(empty_in_named_args)
@@ -1634,7 +1605,7 @@ BOOST_AUTO_TEST_CASE(empty_in_named_args)
}
}
)";
- CHECK_ERROR(sourceCode, TypeError, "");
+ CHECK_ERROR(sourceCode, TypeError, "Wrong argument count for function call: 0 arguments given but expected 2.");
}
BOOST_AUTO_TEST_CASE(duplicate_parameter_names_in_named_args)
@@ -1649,7 +1620,7 @@ BOOST_AUTO_TEST_CASE(duplicate_parameter_names_in_named_args)
}
}
)";
- CHECK_ERROR(sourceCode, TypeError, "");
+ CHECK_ERROR(sourceCode, TypeError, "Duplicate named argument.");
}
BOOST_AUTO_TEST_CASE(invalid_parameter_names_in_named_args)
@@ -1664,7 +1635,7 @@ BOOST_AUTO_TEST_CASE(invalid_parameter_names_in_named_args)
}
}
)";
- CHECK_ERROR(sourceCode, TypeError, "");
+ CHECK_ERROR(sourceCode, TypeError, "Named argument does not match function declaration.");
}
BOOST_AUTO_TEST_CASE(empty_name_input_parameter)
@@ -1718,7 +1689,7 @@ BOOST_AUTO_TEST_CASE(empty_name_return_parameter_with_named_one)
}
}
)";
- CHECK_ERROR(text, TypeError, "");
+ CHECK_ERROR(text, TypeError, "Different number of arguments in return statement than in returns declaration.");
}
BOOST_AUTO_TEST_CASE(disallow_declaration_of_void_type)
@@ -1728,7 +1699,7 @@ BOOST_AUTO_TEST_CASE(disallow_declaration_of_void_type)
function f() { var (x) = f(); }
}
)";
- CHECK_ERROR(sourceCode, TypeError, "");
+ CHECK_ERROR(sourceCode, TypeError, "Not enough components (0) in value to assign all variables (1).");
}
BOOST_AUTO_TEST_CASE(overflow_caused_by_ether_units)
@@ -1751,7 +1722,7 @@ BOOST_AUTO_TEST_CASE(overflow_caused_by_ether_units)
uint256 a;
}
)";
- CHECK_ERROR(sourceCode, TypeError, "");
+ CHECK_ERROR(sourceCode, TypeError, "Type int_const 115792089237316195423570985008687907853269984665640564039458000000000000000000 is not implicitly convertible to expected type uint256.");
}
BOOST_AUTO_TEST_CASE(exp_operator_exponent_too_big)
@@ -1761,7 +1732,7 @@ BOOST_AUTO_TEST_CASE(exp_operator_exponent_too_big)
function f() returns(uint d) { return 2 ** 10000000000; }
}
)";
- CHECK_ERROR(sourceCode, TypeError, "");
+ CHECK_ERROR(sourceCode, TypeError, "Operator ** not compatible with types int_const 2 and int_const 10000000000");
}
BOOST_AUTO_TEST_CASE(exp_warn_literal_base)
@@ -1875,7 +1846,7 @@ BOOST_AUTO_TEST_CASE(enum_invalid_member_access)
ActionChoices choices;
}
)";
- CHECK_ERROR(text, TypeError, "");
+ CHECK_ERROR(text, TypeError, "Member \"RunAroundWavingYourHands\" not found or not visible after argument-dependent lookup in type(enum test.ActionChoices)");
}
BOOST_AUTO_TEST_CASE(enum_invalid_direct_member_access)
@@ -1889,7 +1860,7 @@ BOOST_AUTO_TEST_CASE(enum_invalid_direct_member_access)
ActionChoices choices;
}
)";
- CHECK_ERROR(text, DeclarationError, "");
+ CHECK_ERROR(text, DeclarationError, "Undeclared identifier.");
}
BOOST_AUTO_TEST_CASE(enum_explicit_conversion_is_okay)
@@ -1935,7 +1906,7 @@ BOOST_AUTO_TEST_CASE(enum_implicit_conversion_is_not_okay_256)
uint256 a;
}
)";
- CHECK_ERROR(text, TypeError, "");
+ CHECK_ERROR(text, TypeError, "Type enum test.ActionChoices is not implicitly convertible to expected type uint256.");
}
BOOST_AUTO_TEST_CASE(enum_implicit_conversion_is_not_okay_64)
@@ -1949,7 +1920,7 @@ BOOST_AUTO_TEST_CASE(enum_implicit_conversion_is_not_okay_64)
uint64 b;
}
)";
- CHECK_ERROR(text, TypeError, "");
+ CHECK_ERROR(text, TypeError, "Type enum test.ActionChoices is not implicitly convertible to expected type uint64.");
}
BOOST_AUTO_TEST_CASE(enum_to_enum_conversion_is_not_okay)
@@ -1963,7 +1934,7 @@ BOOST_AUTO_TEST_CASE(enum_to_enum_conversion_is_not_okay)
}
}
)";
- CHECK_ERROR(text, TypeError, "");
+ CHECK_ERROR(text, TypeError, "Explicit type conversion not allowed from \"enum test.Paper\" to \"enum test.Ground\".");
}
BOOST_AUTO_TEST_CASE(enum_duplicate_values)
@@ -1973,7 +1944,7 @@ BOOST_AUTO_TEST_CASE(enum_duplicate_values)
enum ActionChoices { GoLeft, GoRight, GoLeft, Sit }
}
)";
- CHECK_ERROR(text, DeclarationError, "");
+ CHECK_ERROR(text, DeclarationError, "Identifier already declared.");
}
BOOST_AUTO_TEST_CASE(enum_name_resolution_under_current_contract_name)
@@ -2003,7 +1974,7 @@ BOOST_AUTO_TEST_CASE(private_visibility)
function g() { f(); }
}
)";
- CHECK_ERROR(sourceCode, DeclarationError, "");
+ CHECK_ERROR(sourceCode, DeclarationError, "Undeclared identifier.");
}
BOOST_AUTO_TEST_CASE(private_visibility_via_explicit_base_access)
@@ -2016,7 +1987,7 @@ BOOST_AUTO_TEST_CASE(private_visibility_via_explicit_base_access)
function g() { base.f(); }
}
)";
- CHECK_ERROR(sourceCode, TypeError, "");
+ CHECK_ERROR(sourceCode, TypeError, "Member \"f\" not found or not visible after argument-dependent lookup in type(contract base)");
}
BOOST_AUTO_TEST_CASE(external_visibility)
@@ -2027,7 +1998,7 @@ BOOST_AUTO_TEST_CASE(external_visibility)
function g() { f(); }
}
)";
- CHECK_ERROR(sourceCode, DeclarationError, "");
+ CHECK_ERROR(sourceCode, DeclarationError, "Undeclared identifier.");
}
BOOST_AUTO_TEST_CASE(external_base_visibility)
@@ -2040,7 +2011,7 @@ BOOST_AUTO_TEST_CASE(external_base_visibility)
function g() { base.f(); }
}
)";
- CHECK_ERROR(sourceCode, TypeError, "");
+ CHECK_ERROR(sourceCode, TypeError, "Member \"f\" not found or not visible after argument-dependent lookup in type(contract base)");
}
BOOST_AUTO_TEST_CASE(external_argument_assign)
@@ -2050,7 +2021,7 @@ BOOST_AUTO_TEST_CASE(external_argument_assign)
function f(uint a) external { a = 1; }
}
)";
- CHECK_ERROR(sourceCode, TypeError, "");
+ CHECK_ERROR(sourceCode, TypeError, "Expression has to be an lvalue.");
}
BOOST_AUTO_TEST_CASE(external_argument_increment)
@@ -2060,7 +2031,7 @@ BOOST_AUTO_TEST_CASE(external_argument_increment)
function f(uint a) external { a++; }
}
)";
- CHECK_ERROR(sourceCode, TypeError, "");
+ CHECK_ERROR(sourceCode, TypeError, "Expression has to be an lvalue.");
}
BOOST_AUTO_TEST_CASE(external_argument_delete)
@@ -2070,7 +2041,7 @@ BOOST_AUTO_TEST_CASE(external_argument_delete)
function f(uint a) external { delete a; }
}
)";
- CHECK_ERROR(sourceCode, TypeError, "");
+ CHECK_ERROR(sourceCode, TypeError, "Expression has to be an lvalue.");
}
BOOST_AUTO_TEST_CASE(test_for_bug_override_function_with_bytearray_type)
@@ -2093,7 +2064,7 @@ BOOST_AUTO_TEST_CASE(array_with_nonconstant_length)
function f(uint a) { uint8[a] x; }
}
)";
- CHECK_ERROR(text, TypeError, "");
+ CHECK_ERROR(text, TypeError, "Invalid array length, expected integer literal.");
}
BOOST_AUTO_TEST_CASE(array_with_negative_length)
@@ -2115,7 +2086,7 @@ BOOST_AUTO_TEST_CASE(array_copy_with_different_types1)
function f() { b = a; }
}
)";
- CHECK_ERROR(text, TypeError, "");
+ CHECK_ERROR(text, TypeError, "Type bytes storage ref is not implicitly convertible to expected type uint256[] storage ref.");
}
BOOST_AUTO_TEST_CASE(array_copy_with_different_types2)
@@ -2127,7 +2098,7 @@ BOOST_AUTO_TEST_CASE(array_copy_with_different_types2)
function f() { b = a; }
}
)";
- CHECK_ERROR(text, TypeError, "");
+ CHECK_ERROR(text, TypeError, "Type uint32[] storage ref is not implicitly convertible to expected type uint8[] storage ref.");
}
BOOST_AUTO_TEST_CASE(array_copy_with_different_types_conversion_possible)
@@ -2163,7 +2134,7 @@ BOOST_AUTO_TEST_CASE(array_copy_with_different_types_dynamic_static)
function f() { b = a; }
}
)";
- CHECK_ERROR(text, TypeError, "");
+ CHECK_ERROR(text, TypeError, "Type uint256[] storage ref is not implicitly convertible to expected type uint256[80] storage ref.");
}
BOOST_AUTO_TEST_CASE(storage_variable_initialization_with_incorrect_type_int)
@@ -2173,7 +2144,7 @@ BOOST_AUTO_TEST_CASE(storage_variable_initialization_with_incorrect_type_int)
uint8 a = 1000;
}
)";
- CHECK_ERROR(text, TypeError, "");
+ CHECK_ERROR(text, TypeError, "Type int_const 1000 is not implicitly convertible to expected type uint8.");
}
BOOST_AUTO_TEST_CASE(storage_variable_initialization_with_incorrect_type_string)
@@ -2183,7 +2154,7 @@ BOOST_AUTO_TEST_CASE(storage_variable_initialization_with_incorrect_type_string)
uint a = "abc";
}
)";
- CHECK_ERROR(text, TypeError, "");
+ CHECK_ERROR(text, TypeError, "Type literal_string \"abc\" is not implicitly convertible to expected type uint256.");
}
BOOST_AUTO_TEST_CASE(test_fromElementaryTypeName)
@@ -2344,7 +2315,7 @@ BOOST_AUTO_TEST_CASE(assigning_value_to_const_variable)
uint constant x = 56;
}
)";
- CHECK_ERROR(text, TypeError, "");
+ CHECK_ERROR(text, TypeError, "Cannot assign to a constant variable.");
}
BOOST_AUTO_TEST_CASE(assigning_state_to_const_variable)
@@ -2454,7 +2425,7 @@ BOOST_AUTO_TEST_CASE(uninitialized_const_variable)
uint constant y;
}
)";
- CHECK_ERROR(text, TypeError, "");
+ CHECK_ERROR(text, TypeError, "Uninitialized \"constant\" variable.");
}
BOOST_AUTO_TEST_CASE(overloaded_function_cannot_resolve)
@@ -2466,7 +2437,7 @@ BOOST_AUTO_TEST_CASE(overloaded_function_cannot_resolve)
function g() returns(uint) { return f(3, 5); }
}
)";
- CHECK_ERROR(sourceCode, TypeError, "");
+ CHECK_ERROR(sourceCode, TypeError, "No matching declaration found after argument-dependent lookup.");
}
BOOST_AUTO_TEST_CASE(ambiguous_overloaded_function)
@@ -2479,7 +2450,7 @@ BOOST_AUTO_TEST_CASE(ambiguous_overloaded_function)
function g() returns(uint) { return f(1); }
}
)";
- CHECK_ERROR(sourceCode, TypeError, "");
+ CHECK_ERROR(sourceCode, TypeError, "No unique declaration found after argument-dependent lookup.");
}
BOOST_AUTO_TEST_CASE(assignment_of_nonoverloaded_function)
@@ -2502,7 +2473,7 @@ BOOST_AUTO_TEST_CASE(assignment_of_overloaded_function)
function g() returns(uint) { var x = f; return x(7); }
}
)";
- CHECK_ERROR(sourceCode, TypeError, "");
+ CHECK_ERROR(sourceCode, TypeError, "No matching declaration found after variable lookup.");
}
BOOST_AUTO_TEST_CASE(external_types_clash)
@@ -2516,7 +2487,7 @@ BOOST_AUTO_TEST_CASE(external_types_clash)
function f(uint8 a) { }
}
)";
- CHECK_ERROR(sourceCode, TypeError, "");
+ CHECK_ERROR(sourceCode, TypeError, "Function overload clash during conversion to external types for arguments.");
}
BOOST_AUTO_TEST_CASE(override_changes_return_types)
@@ -2529,7 +2500,7 @@ BOOST_AUTO_TEST_CASE(override_changes_return_types)
function f(uint a) returns (uint8) { }
}
)";
- CHECK_ERROR(sourceCode, TypeError, "");
+ CHECK_ERROR(sourceCode, TypeError, "Overriding function return types differ");
}
BOOST_AUTO_TEST_CASE(multiple_constructors)
@@ -2540,7 +2511,7 @@ BOOST_AUTO_TEST_CASE(multiple_constructors)
function test() {}
}
)";
- CHECK_ERROR(sourceCode, DeclarationError, "");
+ CHECK_ERROR(sourceCode, DeclarationError, "More than one constructor defined");
}
BOOST_AUTO_TEST_CASE(equal_overload)
@@ -2551,7 +2522,7 @@ BOOST_AUTO_TEST_CASE(equal_overload)
function test(uint a) external {}
}
)";
- CHECK_ERROR_ALLOW_MULTI(sourceCode, DeclarationError, "");
+ CHECK_ERROR_ALLOW_MULTI(sourceCode, DeclarationError, "Function with same name and arguments defined twice.");
}
BOOST_AUTO_TEST_CASE(uninitialized_var)
@@ -2561,7 +2532,7 @@ BOOST_AUTO_TEST_CASE(uninitialized_var)
function f() returns (uint) { var x; return 2; }
}
)";
- CHECK_ERROR(sourceCode, TypeError, "");
+ CHECK_ERROR(sourceCode, TypeError, "Assignment necessary for type detection.");
}
BOOST_AUTO_TEST_CASE(string)
@@ -2613,7 +2584,7 @@ BOOST_AUTO_TEST_CASE(string_index)
function f() { var a = s[2]; }
}
)";
- CHECK_ERROR(sourceCode, TypeError, "");
+ CHECK_ERROR(sourceCode, TypeError, "Index access for string is not possible.");
}
BOOST_AUTO_TEST_CASE(string_length)
@@ -2624,7 +2595,7 @@ BOOST_AUTO_TEST_CASE(string_length)
function f() { var a = s.length; }
}
)";
- CHECK_ERROR(sourceCode, TypeError, "");
+ CHECK_ERROR(sourceCode, TypeError, "Member \"length\" not found or not visible after argument-dependent lookup in string storage ref");
}
BOOST_AUTO_TEST_CASE(negative_integers_to_signed_out_of_bound)
@@ -2634,7 +2605,7 @@ BOOST_AUTO_TEST_CASE(negative_integers_to_signed_out_of_bound)
int8 public i = -129;
}
)";
- CHECK_ERROR(sourceCode, TypeError, "");
+ CHECK_ERROR(sourceCode, TypeError, "Type int_const -129 is not implicitly convertible to expected type int8.");
}
BOOST_AUTO_TEST_CASE(negative_integers_to_signed_min)
@@ -2654,7 +2625,7 @@ BOOST_AUTO_TEST_CASE(positive_integers_to_signed_out_of_bound)
int8 public j = 128;
}
)";
- CHECK_ERROR(sourceCode, TypeError, "");
+ CHECK_ERROR(sourceCode, TypeError, "Type int_const 128 is not implicitly convertible to expected type int8.");
}
BOOST_AUTO_TEST_CASE(positive_integers_to_signed_out_of_bound_max)
@@ -2674,7 +2645,7 @@ BOOST_AUTO_TEST_CASE(negative_integers_to_unsigned)
uint8 public x = -1;
}
)";
- CHECK_ERROR(sourceCode, TypeError, "");
+ CHECK_ERROR(sourceCode, TypeError, "Type int_const -1 is not implicitly convertible to expected type uint8.");
}
BOOST_AUTO_TEST_CASE(positive_integers_to_unsigned_out_of_bound)
@@ -2684,7 +2655,7 @@ BOOST_AUTO_TEST_CASE(positive_integers_to_unsigned_out_of_bound)
uint8 public x = 700;
}
)";
- CHECK_ERROR(sourceCode, TypeError, "");
+ CHECK_ERROR(sourceCode, TypeError, "Type int_const 700 is not implicitly convertible to expected type uint8.");
}
BOOST_AUTO_TEST_CASE(integer_boolean_operators)
@@ -2692,15 +2663,15 @@ BOOST_AUTO_TEST_CASE(integer_boolean_operators)
char const* sourceCode1 = R"(
contract test { function() { uint x = 1; uint y = 2; x || y; } }
)";
- CHECK_ERROR(sourceCode1, TypeError, "");
+ CHECK_ERROR(sourceCode1, TypeError, "Operator || not compatible with types uint256 and uint256");
char const* sourceCode2 = R"(
contract test { function() { uint x = 1; uint y = 2; x && y; } }
)";
- CHECK_ERROR(sourceCode2, TypeError, "");
+ CHECK_ERROR(sourceCode2, TypeError, "Operator && not compatible with types uint256 and uint256");
char const* sourceCode3 = R"(
contract test { function() { uint x = 1; !x; } }
)";
- CHECK_ERROR(sourceCode3, TypeError, "");
+ CHECK_ERROR(sourceCode3, TypeError, "Unary operator ! cannot be applied to type uint256");
}
BOOST_AUTO_TEST_CASE(exp_signed_variable)
@@ -2708,15 +2679,15 @@ BOOST_AUTO_TEST_CASE(exp_signed_variable)
char const* sourceCode1 = R"(
contract test { function() { uint x = 3; int y = -4; x ** y; } }
)";
- CHECK_ERROR(sourceCode1, TypeError, "");
+ CHECK_ERROR(sourceCode1, TypeError, "Operator ** not compatible with types uint256 and int256");
char const* sourceCode2 = R"(
contract test { function() { uint x = 3; int y = -4; y ** x; } }
)";
- CHECK_ERROR(sourceCode2, TypeError, "");
+ CHECK_ERROR(sourceCode2, TypeError, "Operator ** not compatible with types int256 and uint256");
char const* sourceCode3 = R"(
contract test { function() { int x = -3; int y = -4; x ** y; } }
)";
- CHECK_ERROR(sourceCode3, TypeError, "");
+ CHECK_ERROR(sourceCode3, TypeError, "Operator ** not compatible with types int256 and int256");
}
BOOST_AUTO_TEST_CASE(reference_compare_operators)
@@ -2724,11 +2695,11 @@ BOOST_AUTO_TEST_CASE(reference_compare_operators)
char const* sourceCode1 = R"(
contract test { bytes a; bytes b; function() { a == b; } }
)";
- CHECK_ERROR(sourceCode1, TypeError, "");
+ CHECK_ERROR(sourceCode1, TypeError, "Operator == not compatible with types bytes storage ref and bytes storage ref");
char const* sourceCode2 = R"(
contract test { struct s {uint a;} s x; s y; function() { x == y; } }
)";
- CHECK_ERROR(sourceCode2, TypeError, "");
+ CHECK_ERROR(sourceCode2, TypeError, "Operator == not compatible with types struct test.s storage ref and struct test.s storage ref");
}
BOOST_AUTO_TEST_CASE(overwrite_memory_location_external)
@@ -2738,7 +2709,7 @@ BOOST_AUTO_TEST_CASE(overwrite_memory_location_external)
function f(uint[] memory a) external {}
}
)";
- CHECK_ERROR(sourceCode, TypeError, "");
+ CHECK_ERROR(sourceCode, TypeError, "Location has to be calldata for external functions (remove the \"memory\" or \"storage\" keyword).");
}
BOOST_AUTO_TEST_CASE(overwrite_storage_location_external)
@@ -2748,7 +2719,7 @@ BOOST_AUTO_TEST_CASE(overwrite_storage_location_external)
function f(uint[] storage a) external {}
}
)";
- CHECK_ERROR(sourceCode, TypeError, "");
+ CHECK_ERROR(sourceCode, TypeError, "Location has to be calldata for external functions (remove the \"memory\" or \"storage\" keyword).");
}
BOOST_AUTO_TEST_CASE(storage_location_local_variables)
@@ -2775,7 +2746,7 @@ BOOST_AUTO_TEST_CASE(no_mappings_in_memory_array)
}
}
)";
- CHECK_ERROR(sourceCode, TypeError, "");
+ CHECK_ERROR(sourceCode, TypeError, "Type mapping(uint256 => uint256)[] memory is only valid in storage.");
}
BOOST_AUTO_TEST_CASE(assignment_mem_to_local_storage_variable)
@@ -2789,7 +2760,7 @@ BOOST_AUTO_TEST_CASE(assignment_mem_to_local_storage_variable)
}
}
)";
- CHECK_ERROR(sourceCode, TypeError, "");
+ CHECK_ERROR(sourceCode, TypeError, "Type uint256[] memory is not implicitly convertible to expected type uint256[] storage pointer.");
}
BOOST_AUTO_TEST_CASE(storage_assign_to_different_local_variable)
@@ -2806,7 +2777,7 @@ BOOST_AUTO_TEST_CASE(storage_assign_to_different_local_variable)
}
}
)";
- CHECK_ERROR(sourceCode, TypeError, "");
+ CHECK_ERROR(sourceCode, TypeError, "Type uint8[] storage pointer is not implicitly convertible to expected type uint256[] storage pointer.");
}
BOOST_AUTO_TEST_CASE(uninitialized_mapping_variable)
@@ -2846,7 +2817,7 @@ BOOST_AUTO_TEST_CASE(no_delete_on_storage_pointers)
}
}
)";
- CHECK_ERROR(sourceCode, TypeError, "");
+ CHECK_ERROR(sourceCode, TypeError, "Unary operator delete cannot be applied to type uint256[] storage pointer");
}
BOOST_AUTO_TEST_CASE(assignment_mem_storage_variable_directly)
@@ -2873,7 +2844,7 @@ BOOST_AUTO_TEST_CASE(function_argument_mem_to_storage)
}
}
)";
- CHECK_ERROR(sourceCode, TypeError, "");
+ CHECK_ERROR(sourceCode, TypeError, "Invalid type for argument in function call. Invalid implicit conversion from uint256[] memory to uint256[] storage pointer requested.");
}
BOOST_AUTO_TEST_CASE(function_argument_storage_to_mem)
@@ -2902,7 +2873,7 @@ BOOST_AUTO_TEST_CASE(mem_array_assignment_changes_base_type)
}
}
)";
- CHECK_ERROR(sourceCode, TypeError, "");
+ CHECK_ERROR(sourceCode, TypeError, "Type uint8[] memory is not implicitly convertible to expected type uint256[] memory.");
}
BOOST_AUTO_TEST_CASE(dynamic_return_types_not_possible)
@@ -2917,7 +2888,7 @@ BOOST_AUTO_TEST_CASE(dynamic_return_types_not_possible)
}
}
)";
- CHECK_ERROR(sourceCode, TypeError, "");
+ CHECK_ERROR(sourceCode, TypeError, "Explicit type conversion not allowed from \"inaccessible dynamic type\" to \"bytes storage pointer\".");
}
BOOST_AUTO_TEST_CASE(memory_arrays_not_resizeable)
@@ -2930,7 +2901,7 @@ BOOST_AUTO_TEST_CASE(memory_arrays_not_resizeable)
}
}
)";
- CHECK_ERROR(sourceCode, TypeError, "");
+ CHECK_ERROR(sourceCode, TypeError, "Expression has to be an lvalue.");
}
BOOST_AUTO_TEST_CASE(struct_constructor)
@@ -3000,7 +2971,7 @@ BOOST_AUTO_TEST_CASE(memory_structs_with_mappings)
}
}
)";
- CHECK_ERROR(text, TypeError, "");
+ CHECK_ERROR(text, TypeError, "Member \"b\" is not available in struct Test.S memory outside of storage.");
}
BOOST_AUTO_TEST_CASE(string_bytes_conversion)
@@ -3026,7 +2997,7 @@ BOOST_AUTO_TEST_CASE(inheriting_from_library)
library Lib {}
contract Test is Lib {}
)";
- CHECK_ERROR(text, TypeError, "");
+ CHECK_ERROR(text, TypeError, "Libraries cannot be inherited from.");
}
BOOST_AUTO_TEST_CASE(inheriting_library)
@@ -3035,7 +3006,7 @@ BOOST_AUTO_TEST_CASE(inheriting_library)
contract Test {}
library Lib is Test {}
)";
- CHECK_ERROR(text, TypeError, "");
+ CHECK_ERROR(text, TypeError, "Library is not allowed to inherit.");
}
BOOST_AUTO_TEST_CASE(library_having_variables)
@@ -3043,7 +3014,7 @@ BOOST_AUTO_TEST_CASE(library_having_variables)
char const* text = R"(
library Lib { uint x; }
)";
- CHECK_ERROR(text, TypeError, "");
+ CHECK_ERROR(text, TypeError, "Library cannot have non-constant state variables");
}
BOOST_AUTO_TEST_CASE(valid_library)
@@ -3076,7 +3047,7 @@ BOOST_AUTO_TEST_CASE(creating_contract_within_the_contract)
function f() { var x = new Test(); }
}
)";
- CHECK_ERROR(sourceCode, TypeError, "");
+ CHECK_ERROR(sourceCode, TypeError, "Circular reference for contract creation (cannot create instance of derived or same contract).");
}
BOOST_AUTO_TEST_CASE(array_out_of_bound_access)
@@ -3090,7 +3061,7 @@ BOOST_AUTO_TEST_CASE(array_out_of_bound_access)
}
}
)";
- CHECK_ERROR(text, TypeError, "");
+ CHECK_ERROR(text, TypeError, "Out of bounds array access.");
}
BOOST_AUTO_TEST_CASE(literal_string_to_storage_pointer)
@@ -3100,7 +3071,7 @@ BOOST_AUTO_TEST_CASE(literal_string_to_storage_pointer)
function f() { string x = "abc"; }
}
)";
- CHECK_ERROR(text, TypeError, "");
+ CHECK_ERROR(text, TypeError, "Type literal_string \"abc\" is not implicitly convertible to expected type string storage pointer.");
}
BOOST_AUTO_TEST_CASE(non_initialized_references)
@@ -3130,7 +3101,7 @@ BOOST_AUTO_TEST_CASE(keccak256_with_large_integer_constant)
function f() { keccak256(2**500); }
}
)";
- CHECK_ERROR(text, TypeError, "");
+ CHECK_ERROR(text, TypeError, "Invalid rational number (too large or division by zero).");
}
BOOST_AUTO_TEST_CASE(cyclic_binary_dependency)
@@ -3140,7 +3111,7 @@ BOOST_AUTO_TEST_CASE(cyclic_binary_dependency)
contract B { function f() { new C(); } }
contract C { function f() { new A(); } }
)";
- CHECK_ERROR(text, TypeError, "");
+ CHECK_ERROR(text, TypeError, "Circular reference for contract creation (cannot create instance of derived or same contract).");
}
BOOST_AUTO_TEST_CASE(cyclic_binary_dependency_via_inheritance)
@@ -3150,7 +3121,7 @@ BOOST_AUTO_TEST_CASE(cyclic_binary_dependency_via_inheritance)
contract B { function f() { new C(); } }
contract C { function f() { new A(); } }
)";
- CHECK_ERROR(text, TypeError, "");
+ CHECK_ERROR(text, TypeError, "Definition of base has to precede definition of derived contract");
}
BOOST_AUTO_TEST_CASE(multi_variable_declaration_fail)
@@ -3190,7 +3161,7 @@ BOOST_AUTO_TEST_CASE(multi_variable_declaration_wildcards_fail_1)
function f() { var (a, b, ) = one(); }
}
)";
- CHECK_ERROR(text, TypeError, "");
+ CHECK_ERROR(text, TypeError, "Not enough components (1) in value to assign all variables (2).");
}
BOOST_AUTO_TEST_CASE(multi_variable_declaration_wildcards_fail_2)
{
@@ -3200,7 +3171,7 @@ BOOST_AUTO_TEST_CASE(multi_variable_declaration_wildcards_fail_2)
function f() { var (a, , ) = one(); }
}
)";
- CHECK_ERROR(text, TypeError, "");
+ CHECK_ERROR(text, TypeError, "Not enough components (1) in value to assign all variables (2).");
}
BOOST_AUTO_TEST_CASE(multi_variable_declaration_wildcards_fail_3)
@@ -3211,7 +3182,7 @@ BOOST_AUTO_TEST_CASE(multi_variable_declaration_wildcards_fail_3)
function f() { var (, , a) = one(); }
}
)";
- CHECK_ERROR(text, TypeError, "");
+ CHECK_ERROR(text, TypeError, "Not enough components (1) in value to assign all variables (2).");
}
BOOST_AUTO_TEST_CASE(multi_variable_declaration_wildcards_fail_4)
@@ -3222,7 +3193,7 @@ BOOST_AUTO_TEST_CASE(multi_variable_declaration_wildcards_fail_4)
function f() { var (, a, b) = one(); }
}
)";
- CHECK_ERROR(text, TypeError, "");
+ CHECK_ERROR(text, TypeError, "Not enough components (1) in value to assign all variables (2).");
}
BOOST_AUTO_TEST_CASE(tuples)
@@ -3250,7 +3221,7 @@ BOOST_AUTO_TEST_CASE(tuples_empty_components)
}
}
)";
- CHECK_ERROR(text, TypeError, "");
+ CHECK_ERROR(text, TypeError, "Tuple component cannot be empty.");
}
BOOST_AUTO_TEST_CASE(multi_variable_declaration_wildcards_fail_5)
@@ -3261,7 +3232,7 @@ BOOST_AUTO_TEST_CASE(multi_variable_declaration_wildcards_fail_5)
function f() { var (,) = one(); }
}
)";
- CHECK_ERROR(text, TypeError, "");
+ CHECK_ERROR(text, TypeError, "Wildcard both at beginning and end of variable declaration list is only allowed if the number of components is equal.");
}
BOOST_AUTO_TEST_CASE(multi_variable_declaration_wildcards_fail_6)
@@ -3272,7 +3243,7 @@ BOOST_AUTO_TEST_CASE(multi_variable_declaration_wildcards_fail_6)
function f() { var (a, b, c) = two(); }
}
)";
- CHECK_ERROR(text, TypeError, "");
+ CHECK_ERROR(text, TypeError, "Not enough components (2) in value to assign all variables (3)");
}
BOOST_AUTO_TEST_CASE(tuple_assignment_from_void_function)
@@ -3340,7 +3311,7 @@ BOOST_AUTO_TEST_CASE(using_for_not_library)
using D for uint;
}
)";
- CHECK_ERROR(text, TypeError, "");
+ CHECK_ERROR(text, TypeError, "Library name expected.");
}
BOOST_AUTO_TEST_CASE(using_for_function_exists)
@@ -3431,7 +3402,7 @@ BOOST_AUTO_TEST_CASE(using_for_mismatch)
}
}
)";
- CHECK_ERROR(text, TypeError, "");
+ CHECK_ERROR(text, TypeError, "Member \"double\" not found or not visible after argument-dependent lookup in uint256");
}
BOOST_AUTO_TEST_CASE(using_for_not_used)
@@ -3447,7 +3418,7 @@ BOOST_AUTO_TEST_CASE(using_for_not_used)
}
}
)";
- CHECK_ERROR(text, TypeError, "");
+ CHECK_ERROR(text, TypeError, "Member \"double\" not found or not visible after argument-dependent lookup in uint16");
}
BOOST_AUTO_TEST_CASE(library_memory_struct)
@@ -3458,7 +3429,7 @@ BOOST_AUTO_TEST_CASE(library_memory_struct)
function f() returns (S ) {}
}
)";
- CHECK_ERROR(text, TypeError, "");
+ CHECK_ERROR(text, TypeError, "Internal type is not allowed for public or external functions.");
}
BOOST_AUTO_TEST_CASE(using_for_arbitrary_mismatch)
@@ -3473,7 +3444,7 @@ BOOST_AUTO_TEST_CASE(using_for_arbitrary_mismatch)
}
}
)";
- CHECK_ERROR(text, TypeError, "");
+ CHECK_ERROR(text, TypeError, "Member \"double\" not found or not visible after argument-dependent lookup in uint256");
}
BOOST_AUTO_TEST_CASE(bound_function_in_var)
@@ -3520,7 +3491,7 @@ BOOST_AUTO_TEST_CASE(mapping_in_memory_array)
}
}
)";
- CHECK_ERROR(text, TypeError, "");
+ CHECK_ERROR(text, TypeError, "Type cannot live outside storage.");
}
BOOST_AUTO_TEST_CASE(new_for_non_array)
@@ -3532,7 +3503,7 @@ BOOST_AUTO_TEST_CASE(new_for_non_array)
}
}
)";
- CHECK_ERROR(text, TypeError, "");
+ CHECK_ERROR(text, TypeError, "Contract or array type expected.");
}
BOOST_AUTO_TEST_CASE(invalid_args_creating_memory_array)
@@ -3544,7 +3515,7 @@ BOOST_AUTO_TEST_CASE(invalid_args_creating_memory_array)
}
}
)";
- CHECK_ERROR(text, TypeError, "");
+ CHECK_ERROR(text, TypeError, "Wrong argument count for function call: 0 arguments given but expected 1.");
}
BOOST_AUTO_TEST_CASE(function_overload_array_type)
@@ -3664,7 +3635,7 @@ BOOST_AUTO_TEST_CASE(invalid_types_in_inline_array)
}
}
)";
- CHECK_ERROR(text, TypeError, "");
+ CHECK_ERROR(text, TypeError, "Unable to deduce common type for array elements.");
}
BOOST_AUTO_TEST_CASE(dynamic_inline_array)
@@ -3689,7 +3660,7 @@ BOOST_AUTO_TEST_CASE(lvalues_as_inline_array)
}
}
)";
- CHECK_ERROR(text, TypeError, "");
+ CHECK_ERROR(text, TypeError, "Inline array type cannot be declared as LValue.");
}
BOOST_AUTO_TEST_CASE(break_not_in_loop)
@@ -3702,7 +3673,7 @@ BOOST_AUTO_TEST_CASE(break_not_in_loop)
}
}
)";
- CHECK_ERROR(text, SyntaxError, "");
+ CHECK_ERROR(text, SyntaxError, "\"break\" has to be in a \"for\" or \"while\" loop.");
}
BOOST_AUTO_TEST_CASE(continue_not_in_loop)
@@ -3715,7 +3686,7 @@ BOOST_AUTO_TEST_CASE(continue_not_in_loop)
}
}
)";
- CHECK_ERROR(text, SyntaxError, "");
+ CHECK_ERROR(text, SyntaxError, "\"continue\" has to be in a \"for\" or \"while\" loop.");
}
BOOST_AUTO_TEST_CASE(continue_not_in_loop_2)
@@ -3730,7 +3701,7 @@ BOOST_AUTO_TEST_CASE(continue_not_in_loop_2)
}
}
)";
- CHECK_ERROR(text, SyntaxError, "");
+ CHECK_ERROR(text, SyntaxError, "\"continue\" has to be in a \"for\" or \"while\" loop.");
}
BOOST_AUTO_TEST_CASE(invalid_different_types_for_conditional_expression)
@@ -3742,7 +3713,7 @@ BOOST_AUTO_TEST_CASE(invalid_different_types_for_conditional_expression)
}
}
)";
- CHECK_ERROR(text, TypeError, "");
+ CHECK_ERROR(text, TypeError, "True expression's type bool doesn't match false expression's type uint8.");
}
BOOST_AUTO_TEST_CASE(left_value_in_conditional_expression_not_supported_yet)
@@ -3756,7 +3727,7 @@ BOOST_AUTO_TEST_CASE(left_value_in_conditional_expression_not_supported_yet)
}
}
)";
- CHECK_ERROR_ALLOW_MULTI(text, TypeError, "");
+ CHECK_ERROR_ALLOW_MULTI(text, TypeError, "Conditional expression as left value is not supported yet.");
}
BOOST_AUTO_TEST_CASE(conditional_expression_with_different_struct)
@@ -3776,7 +3747,7 @@ BOOST_AUTO_TEST_CASE(conditional_expression_with_different_struct)
}
}
)";
- CHECK_ERROR(text, TypeError, "");
+ CHECK_ERROR(text, TypeError, "True expression's type struct C.s1 memory doesn't match false expression's type struct C.s2 memory.");
}
BOOST_AUTO_TEST_CASE(conditional_expression_with_different_function_type)
@@ -3791,7 +3762,7 @@ BOOST_AUTO_TEST_CASE(conditional_expression_with_different_function_type)
}
}
)";
- CHECK_ERROR(text, TypeError, "");
+ CHECK_ERROR(text, TypeError, "True expression's type function (bool) doesn't match false expression's type function ().");
}
BOOST_AUTO_TEST_CASE(conditional_expression_with_different_enum)
@@ -3809,7 +3780,7 @@ BOOST_AUTO_TEST_CASE(conditional_expression_with_different_enum)
}
}
)";
- CHECK_ERROR(text, TypeError, "");
+ CHECK_ERROR(text, TypeError, "True expression's type enum C.small doesn't match false expression's type enum C.big.");
}
BOOST_AUTO_TEST_CASE(conditional_expression_with_different_mapping)
@@ -3824,7 +3795,7 @@ BOOST_AUTO_TEST_CASE(conditional_expression_with_different_mapping)
}
}
)";
- CHECK_ERROR(text, TypeError, "");
+ CHECK_ERROR(text, TypeError, "True expression's type mapping(uint8 => uint8) doesn't match false expression's type mapping(uint32 => uint8).");
}
BOOST_AUTO_TEST_CASE(conditional_with_all_types)
@@ -3931,7 +3902,7 @@ BOOST_AUTO_TEST_CASE(constructor_call_invalid_arg_count)
}
)";
- CHECK_ERROR(text, TypeError, "");
+ CHECK_ERROR(text, TypeError, "Wrong argument count for modifier invocation: 1 arguments given but expected 0.");
}
BOOST_AUTO_TEST_CASE(index_access_for_bytes)
@@ -4721,7 +4692,7 @@ BOOST_AUTO_TEST_CASE(modifier_without_underscore)
modifier m() {}
}
)";
- CHECK_ERROR(text, SyntaxError, "");
+ CHECK_ERROR(text, SyntaxError, "Modifier body does not contain '_'.");
}
BOOST_AUTO_TEST_CASE(payable_in_library)
@@ -4731,7 +4702,7 @@ BOOST_AUTO_TEST_CASE(payable_in_library)
function f() payable {}
}
)";
- CHECK_ERROR(text, TypeError, "");
+ CHECK_ERROR(text, TypeError, "Library functions cannot be payable.");
}
BOOST_AUTO_TEST_CASE(payable_external)
@@ -4751,7 +4722,7 @@ BOOST_AUTO_TEST_CASE(payable_internal)
function f() payable internal {}
}
)";
- CHECK_ERROR(text, TypeError, "");
+ CHECK_ERROR(text, TypeError, "Internal functions cannot be payable.");
}
BOOST_AUTO_TEST_CASE(payable_private)
@@ -4761,7 +4732,7 @@ BOOST_AUTO_TEST_CASE(payable_private)
function f() payable private {}
}
)";
- CHECK_ERROR(text, TypeError, "");
+ CHECK_ERROR(text, TypeError, "Internal functions cannot be payable.");
}
BOOST_AUTO_TEST_CASE(illegal_override_payable)
@@ -4770,7 +4741,7 @@ BOOST_AUTO_TEST_CASE(illegal_override_payable)
contract B { function f() payable {} }
contract C is B { function f() {} }
)";
- CHECK_ERROR(text, TypeError, "");
+ CHECK_ERROR(text, TypeError, "Overriding function should be declared payable.");
}
BOOST_AUTO_TEST_CASE(illegal_override_payable_nonpayable)
@@ -4779,7 +4750,7 @@ BOOST_AUTO_TEST_CASE(illegal_override_payable_nonpayable)
contract B { function f() {} }
contract C is B { function f() payable {} }
)";
- CHECK_ERROR(text, TypeError, "");
+ CHECK_ERROR(text, TypeError, "Overriding function should not be declared payable.");
}
BOOST_AUTO_TEST_CASE(function_variable_mixin)
@@ -4797,16 +4768,7 @@ BOOST_AUTO_TEST_CASE(function_variable_mixin)
function checkOk() returns (bool) { return ok(); }
}
)";
- CHECK_ERROR(text, DeclarationError, "");
-}
-
-
-BOOST_AUTO_TEST_CASE(payable_constant_conflict)
-{
- char const* text = R"(
- contract C { function f() payable constant {} }
- )";
- CHECK_ERROR(text, TypeError, "");
+ CHECK_ERROR(text, DeclarationError, "Identifier already declared.");
}
BOOST_AUTO_TEST_CASE(calling_payable)
@@ -4830,7 +4792,7 @@ BOOST_AUTO_TEST_CASE(calling_nonpayable)
function f() { (new receiver()).nopay.value(10)(); }
}
)";
- CHECK_ERROR(text, TypeError, "");
+ CHECK_ERROR(text, TypeError, "Member \"value\" not found or not visible after argument-dependent lookup in function () external - did you forget the \"payable\" modifier?");
}
BOOST_AUTO_TEST_CASE(non_payable_constructor)
@@ -4846,7 +4808,7 @@ BOOST_AUTO_TEST_CASE(non_payable_constructor)
}
}
)";
- CHECK_ERROR(text, TypeError, "");
+ CHECK_ERROR(text, TypeError, "Member \"value\" not found or not visible after argument-dependent lookup in function () returns (contract C) - did you forget the \"payable\" modifier?");
}
BOOST_AUTO_TEST_CASE(warn_nonpresent_pragma)
@@ -4873,7 +4835,7 @@ BOOST_AUTO_TEST_CASE(constant_constructor)
function test() constant {}
}
)";
- CHECK_ERROR(text, TypeError, "");
+ CHECK_ERROR(text, TypeError, "Constructor cannot be defined as constant.");
}
BOOST_AUTO_TEST_CASE(external_constructor)
@@ -4883,7 +4845,7 @@ BOOST_AUTO_TEST_CASE(external_constructor)
function test() external {}
}
)";
- CHECK_ERROR(text, TypeError, "");
+ CHECK_ERROR(text, TypeError, "Constructor must be public or internal.");
}
BOOST_AUTO_TEST_CASE(invalid_array_as_statement)
@@ -4894,7 +4856,7 @@ BOOST_AUTO_TEST_CASE(invalid_array_as_statement)
function test(uint k) { S[k]; }
}
)";
- CHECK_ERROR(text, TypeError, "");
+ CHECK_ERROR(text, TypeError, "Integer constant expected.");
}
BOOST_AUTO_TEST_CASE(using_directive_for_missing_selftype)
@@ -4913,7 +4875,7 @@ BOOST_AUTO_TEST_CASE(using_directive_for_missing_selftype)
}
}
)";
- CHECK_ERROR(text, TypeError, "");
+ CHECK_ERROR(text, TypeError, "Member \"b\" not found or not visible after argument-dependent lookup in bytes memory");
}
BOOST_AUTO_TEST_CASE(function_type)
@@ -4961,7 +4923,7 @@ BOOST_AUTO_TEST_CASE(private_function_type)
}
}
)";
- CHECK_ERROR(text, TypeError, "");
+ CHECK_ERROR(text, TypeError, "Invalid visibility, can only be \"external\" or \"internal\".");
}
BOOST_AUTO_TEST_CASE(public_function_type)
@@ -4973,7 +4935,7 @@ BOOST_AUTO_TEST_CASE(public_function_type)
}
}
)";
- CHECK_ERROR(text, TypeError, "");
+ CHECK_ERROR(text, TypeError, "Invalid visibility, can only be \"external\" or \"internal\".");
}
BOOST_AUTO_TEST_CASE(payable_internal_function_type)
@@ -4983,7 +4945,7 @@ BOOST_AUTO_TEST_CASE(payable_internal_function_type)
function (uint) internal payable returns (uint) x;
}
)";
- CHECK_ERROR(text, TypeError, "");
+ CHECK_ERROR(text, TypeError, "Only external function types can be payable.");
}
BOOST_AUTO_TEST_CASE(call_value_on_non_payable_function_type)
@@ -4996,7 +4958,7 @@ BOOST_AUTO_TEST_CASE(call_value_on_non_payable_function_type)
}
}
)";
- CHECK_ERROR(text, TypeError, "");
+ CHECK_ERROR(text, TypeError, "Member \"value\" not found or not visible after argument-dependent lookup in function (uint256) external returns (uint256) - did you forget the \"payable\" modifier?");
}
BOOST_AUTO_TEST_CASE(external_function_type_returning_internal)
@@ -5006,7 +4968,7 @@ BOOST_AUTO_TEST_CASE(external_function_type_returning_internal)
function() external returns (function () internal) x;
}
)";
- CHECK_ERROR(text, TypeError, "");
+ CHECK_ERROR(text, TypeError, "Internal type cannot be used for external function type.");
}
BOOST_AUTO_TEST_CASE(external_function_type_taking_internal)
@@ -5016,7 +4978,7 @@ BOOST_AUTO_TEST_CASE(external_function_type_taking_internal)
function(function () internal) external x;
}
)";
- CHECK_ERROR(text, TypeError, "");
+ CHECK_ERROR(text, TypeError, "Internal type cannot be used for external function type.");
}
BOOST_AUTO_TEST_CASE(call_value_on_payable_function_type)
@@ -5042,7 +5004,7 @@ BOOST_AUTO_TEST_CASE(internal_function_as_external_parameter)
}
}
)";
- CHECK_ERROR(text, TypeError, "");
+ CHECK_ERROR(text, TypeError, "Internal type is not allowed for public or external functions.");
}
BOOST_AUTO_TEST_CASE(internal_function_returned_from_public_function)
@@ -5054,7 +5016,7 @@ BOOST_AUTO_TEST_CASE(internal_function_returned_from_public_function)
}
}
)";
- CHECK_ERROR(text, TypeError, "");
+ CHECK_ERROR(text, TypeError, "Internal type is not allowed for public or external functions.");
}
BOOST_AUTO_TEST_CASE(internal_function_as_external_parameter_in_library_internal)
@@ -5076,7 +5038,7 @@ BOOST_AUTO_TEST_CASE(internal_function_as_external_parameter_in_library_external
}
}
)";
- CHECK_ERROR(text, TypeError, "");
+ CHECK_ERROR(text, TypeError, "Internal type is not allowed for public or external functions.");
}
BOOST_AUTO_TEST_CASE(function_type_arrays)
@@ -5127,7 +5089,7 @@ BOOST_AUTO_TEST_CASE(delete_function_type_invalid)
}
}
)";
- CHECK_ERROR(text, TypeError, "");
+ CHECK_ERROR(text, TypeError, "Expression has to be an lvalue.");
}
BOOST_AUTO_TEST_CASE(delete_external_function_type_invalid)
@@ -5139,7 +5101,7 @@ BOOST_AUTO_TEST_CASE(delete_external_function_type_invalid)
}
}
)";
- CHECK_ERROR(text, TypeError, "");
+ CHECK_ERROR(text, TypeError, "Expression has to be an lvalue.");
}
BOOST_AUTO_TEST_CASE(external_function_to_function_type_calldata_parameter)
@@ -5222,7 +5184,7 @@ BOOST_AUTO_TEST_CASE(shift_constant_left_negative_rvalue)
uint public a = 0x42 << -8;
}
)";
- CHECK_ERROR(text, TypeError, "");
+ CHECK_ERROR(text, TypeError, "Operator << not compatible with types int_const 66 and int_const -8");
}
BOOST_AUTO_TEST_CASE(shift_constant_right_negative_rvalue)
@@ -5232,7 +5194,7 @@ BOOST_AUTO_TEST_CASE(shift_constant_right_negative_rvalue)
uint public a = 0x42 >> -8;
}
)";
- CHECK_ERROR(text, TypeError, "");
+ CHECK_ERROR(text, TypeError, "Operator >> not compatible with types int_const 66 and int_const -8");
}
BOOST_AUTO_TEST_CASE(shift_constant_left_excessive_rvalue)
@@ -5242,7 +5204,7 @@ BOOST_AUTO_TEST_CASE(shift_constant_left_excessive_rvalue)
uint public a = 0x42 << 0x100000000;
}
)";
- CHECK_ERROR(text, TypeError, "");
+ CHECK_ERROR(text, TypeError, "Operator << not compatible with types int_const 66 and int_const 4294967296");
}
BOOST_AUTO_TEST_CASE(shift_constant_right_excessive_rvalue)
@@ -5252,7 +5214,7 @@ BOOST_AUTO_TEST_CASE(shift_constant_right_excessive_rvalue)
uint public a = 0x42 >> 0x100000000;
}
)";
- CHECK_ERROR(text, TypeError, "");
+ CHECK_ERROR(text, TypeError, "Operator >> not compatible with types int_const 66 and int_const 4294967296");
}
BOOST_AUTO_TEST_CASE(inline_assembly_unbalanced_positive_stack)
@@ -5447,7 +5409,7 @@ BOOST_AUTO_TEST_CASE(invalid_mobile_type)
}
}
)";
- CHECK_ERROR(text, TypeError, "");
+ CHECK_ERROR(text, TypeError, "Invalid mobile type.");
}
BOOST_AUTO_TEST_CASE(warns_msg_value_in_non_payable_public_function)
@@ -5714,7 +5676,7 @@ BOOST_AUTO_TEST_CASE(interface_constructor)
function I();
}
)";
- CHECK_ERROR(text, TypeError, "Constructor cannot be defined in interfaces");
+ CHECK_ERROR_ALLOW_MULTI(text, TypeError, "Constructor cannot be defined in interfaces");
}
BOOST_AUTO_TEST_CASE(interface_functions)
@@ -6134,6 +6096,25 @@ BOOST_AUTO_TEST_CASE(shadowing_builtins_with_variables)
CHECK_WARNING(text, "shadows a builtin symbol");
}
+BOOST_AUTO_TEST_CASE(shadowing_builtins_with_storage_variables)
+{
+ char const* text = R"(
+ contract C {
+ uint msg;
+ }
+ )";
+ CHECK_WARNING(text, "shadows a builtin symbol");
+}
+
+BOOST_AUTO_TEST_CASE(shadowing_builtin_at_global_scope)
+{
+ char const* text = R"(
+ contract msg {
+ }
+ )";
+ CHECK_WARNING(text, "shadows a builtin symbol");
+}
+
BOOST_AUTO_TEST_CASE(shadowing_builtins_with_parameters)
{
char const* text = R"(
@@ -6190,6 +6171,28 @@ BOOST_AUTO_TEST_CASE(shadowing_builtins_ignores_constructor)
CHECK_SUCCESS_NO_WARNINGS(text);
}
+BOOST_AUTO_TEST_CASE(function_overload_is_not_shadowing)
+{
+ char const* text = R"(
+ contract C {
+ function f() {}
+ function f(uint) {}
+ }
+ )";
+ CHECK_SUCCESS_NO_WARNINGS(text);
+}
+
+BOOST_AUTO_TEST_CASE(function_override_is_not_shadowing)
+{
+ char const* text = R"(
+ contract D { function f() {} }
+ contract C is D {
+ function f(uint) {}
+ }
+ )";
+ CHECK_SUCCESS_NO_WARNINGS(text);
+}
+
BOOST_AUTO_TEST_CASE(callable_crash)
{
char const* text = R"(
@@ -6437,7 +6440,7 @@ BOOST_AUTO_TEST_CASE(using_this_in_constructor)
CHECK_WARNING(text, "\"this\" used in constructor");
}
-BOOST_AUTO_TEST_CASE(do_not_crash_on_not_lalue)
+BOOST_AUTO_TEST_CASE(do_not_crash_on_not_lvalue)
{
// This checks for a bug that caused a crash because of continued analysis.
char const* text = R"(
@@ -6451,6 +6454,198 @@ BOOST_AUTO_TEST_CASE(do_not_crash_on_not_lalue)
CHECK_ERROR_ALLOW_MULTI(text, TypeError, "is not callable");
}
+BOOST_AUTO_TEST_CASE(builtin_reject_gas)
+{
+ char const* text = R"(
+ contract C {
+ function f() {
+ keccak256.gas();
+ }
+ }
+ )";
+ CHECK_ERROR(text, TypeError, "Member \"gas\" not found or not visible after argument-dependent lookup");
+ text = R"(
+ contract C {
+ function f() {
+ sha256.gas();
+ }
+ }
+ )";
+ CHECK_ERROR(text, TypeError, "Member \"gas\" not found or not visible after argument-dependent lookup");
+ text = R"(
+ contract C {
+ function f() {
+ ripemd160.gas();
+ }
+ }
+ )";
+ CHECK_ERROR(text, TypeError, "Member \"gas\" not found or not visible after argument-dependent lookup");
+ text = R"(
+ contract C {
+ function f() {
+ ecrecover.gas();
+ }
+ }
+ )";
+ CHECK_ERROR(text, TypeError, "Member \"gas\" not found or not visible after argument-dependent lookup");
+}
+
+BOOST_AUTO_TEST_CASE(builtin_reject_value)
+{
+ char const* text = R"(
+ contract C {
+ function f() {
+ keccak256.value();
+ }
+ }
+ )";
+ CHECK_ERROR(text, TypeError, "Member \"value\" not found or not visible after argument-dependent lookup");
+ text = R"(
+ contract C {
+ function f() {
+ sha256.value();
+ }
+ }
+ )";
+ CHECK_ERROR(text, TypeError, "Member \"value\" not found or not visible after argument-dependent lookup");
+ text = R"(
+ contract C {
+ function f() {
+ ripemd160.value();
+ }
+ }
+ )";
+ CHECK_ERROR(text, TypeError, "Member \"value\" not found or not visible after argument-dependent lookup");
+ text = R"(
+ contract C {
+ function f() {
+ ecrecover.value();
+ }
+ }
+ )";
+ CHECK_ERROR(text, TypeError, "Member \"value\" not found or not visible after argument-dependent lookup");
+}
+
+BOOST_AUTO_TEST_CASE(constructor_without_implementation)
+{
+ char const* text = R"(
+ contract C {
+ function C();
+ }
+ )";
+ CHECK_ERROR(text, TypeError, "Constructor must be implemented if declared.");
+}
+
+BOOST_AUTO_TEST_CASE(large_storage_array_fine)
+{
+ char const* text = R"(
+ contract C {
+ uint[2**64 - 1] x;
+ }
+ )";
+ CHECK_SUCCESS_NO_WARNINGS(text);
+}
+
+BOOST_AUTO_TEST_CASE(large_storage_array_simple)
+{
+ char const* text = R"(
+ contract C {
+ uint[2**64] x;
+ }
+ )";
+ CHECK_WARNING(text, "covers a large part of storage and thus makes collisions likely");
+}
+
+BOOST_AUTO_TEST_CASE(large_storage_arrays_combined)
+{
+ char const* text = R"(
+ contract C {
+ uint[200][200][2**30][][2**30] x;
+ }
+ )";
+ CHECK_WARNING(text, "covers a large part of storage and thus makes collisions likely");
+}
+
+BOOST_AUTO_TEST_CASE(large_storage_arrays_struct)
+{
+ char const* text = R"(
+ contract C {
+ struct S { uint[2**30] x; uint[2**50] y; }
+ S[2**20] x;
+ }
+ )";
+ CHECK_WARNING(text, "covers a large part of storage and thus makes collisions likely");
+}
+
+BOOST_AUTO_TEST_CASE(large_storage_array_mapping)
+{
+ char const* text = R"(
+ contract C {
+ mapping(uint => uint[2**100]) x;
+ }
+ )";
+ CHECK_WARNING(text, "covers a large part of storage and thus makes collisions likely");
+}
+
+BOOST_AUTO_TEST_CASE(library_function_without_implementation)
+{
+ char const* text = R"(
+ library L {
+ function f();
+ }
+ )";
+ CHECK_SUCCESS_NO_WARNINGS(text);
+ text = R"(
+ library L {
+ function f() internal;
+ }
+ )";
+ CHECK_ERROR(text, TypeError, "Internal library function must be implemented if declared.");
+ text = R"(
+ library L {
+ function f() private;
+ }
+ )";
+ CHECK_ERROR(text, TypeError, "Internal library function must be implemented if declared.");
+}
+
+BOOST_AUTO_TEST_CASE(experimental_pragma)
+{
+ char const* text = R"(
+ pragma experimental;
+ )";
+ CHECK_ERROR(text, SyntaxError, "Experimental feature name is missing.");
+ text = R"(
+ pragma experimental 123;
+ )";
+ CHECK_ERROR(text, SyntaxError, "Unsupported experimental feature name.");
+ text = R"(
+ pragma experimental unsupportedName;
+ )";
+ CHECK_ERROR(text, SyntaxError, "Unsupported experimental feature name.");
+ text = R"(
+ pragma experimental "unsupportedName";
+ )";
+ CHECK_ERROR(text, SyntaxError, "Unsupported experimental feature name.");
+ text = R"(
+ pragma experimental "";
+ )";
+ CHECK_ERROR(text, SyntaxError, "Empty experimental feature name is invalid.");
+ text = R"(
+ pragma experimental unsupportedName unsupportedName;
+ )";
+ CHECK_ERROR(text, SyntaxError, "Stray arguments.");
+ text = R"(
+ pragma experimental __test;
+ )";
+ CHECK_WARNING(text, "Experimental features are turned on. Do not use experimental features on live deployments.");
+// text = R"(
+// pragma experimental __test;
+// pragma experimental __test;
+// )";
+// CHECK_ERROR_ALLOW_MULTI(text, SyntaxError, "Duplicate experimental feature name.");
+}
+
BOOST_AUTO_TEST_SUITE_END()
}
diff --git a/test/libsolidity/SolidityParser.cpp b/test/libsolidity/SolidityParser.cpp
index 78edd4d1..30dc80d9 100644
--- a/test/libsolidity/SolidityParser.cpp
+++ b/test/libsolidity/SolidityParser.cpp
@@ -898,25 +898,31 @@ BOOST_AUTO_TEST_CASE(multiple_visibility_specifiers)
contract c {
uint private internal a;
})";
- CHECK_PARSE_ERROR(text, "Visibility already specified");
+ CHECK_PARSE_ERROR(text, "Visibility already specified as \"private\".");
+ text = R"(
+ contract c {
+ function f() private external {}
+ })";
+ CHECK_PARSE_ERROR(text, "Visibility already specified as \"private\".");
}
-BOOST_AUTO_TEST_CASE(multiple_payable_specifiers)
+BOOST_AUTO_TEST_CASE(multiple_statemutability_specifiers)
{
char const* text = R"(
contract c {
function f() payable payable {}
})";
- CHECK_PARSE_ERROR(text, "Multiple \"payable\" specifiers.");
-}
-
-BOOST_AUTO_TEST_CASE(multiple_constant_specifiers)
-{
- char const* text = R"(
+ CHECK_PARSE_ERROR(text, "State mutability already specified as \"payable\".");
+ text = R"(
contract c {
function f() constant constant {}
})";
- CHECK_PARSE_ERROR(text, "Multiple \"constant\" specifiers.");
+ CHECK_PARSE_ERROR(text, "State mutability already specified as \"view\".");
+ text = R"(
+ contract c {
+ function f() payable constant {}
+ })";
+ CHECK_PARSE_ERROR(text, "State mutability already specified as \"payable\".");
}
BOOST_AUTO_TEST_CASE(literal_constants_with_ether_subdenominations)
@@ -1182,6 +1188,18 @@ BOOST_AUTO_TEST_CASE(tuples)
BOOST_CHECK(successParse(text));
}
+BOOST_AUTO_TEST_CASE(tuples_without_commas)
+{
+ char const* text = R"(
+ contract C {
+ function f() {
+ var a = (2 2);
+ }
+ }
+ )";
+ CHECK_PARSE_ERROR(text, "Expected token Comma");
+}
+
BOOST_AUTO_TEST_CASE(member_access_parser_ambiguity)
{
char const* text = R"(
@@ -1345,6 +1363,42 @@ BOOST_AUTO_TEST_CASE(conditional_with_assignment)
BOOST_CHECK(successParse(text));
}
+BOOST_AUTO_TEST_CASE(recursion_depth1)
+{
+ string text("contract C { bytes");
+ for (size_t i = 0; i < 30000; i++)
+ text += "[";
+ CHECK_PARSE_ERROR(text.c_str(), "Maximum recursion depth reached during parsing");
+}
+
+BOOST_AUTO_TEST_CASE(recursion_depth2)
+{
+ string text("contract C { function f() {");
+ for (size_t i = 0; i < 30000; i++)
+ text += "{";
+ CHECK_PARSE_ERROR(text, "Maximum recursion depth reached during parsing");
+}
+
+BOOST_AUTO_TEST_CASE(recursion_depth3)
+{
+ string text("contract C { function f() { uint x = f(");
+ for (size_t i = 0; i < 30000; i++)
+ text += "(";
+ CHECK_PARSE_ERROR(text, "Maximum recursion depth reached during parsing");
+}
+
+BOOST_AUTO_TEST_CASE(recursion_depth4)
+{
+ string text("contract C { function f() { uint a;");
+ for (size_t i = 0; i < 30000; i++)
+ text += "(";
+ text += "a";
+ for (size_t i = 0; i < 30000; i++)
+ text += "++)";
+ text += "}}";
+ CHECK_PARSE_ERROR(text, "Maximum recursion depth reached during parsing");
+}
+
BOOST_AUTO_TEST_CASE(declaring_fixed_and_ufixed_variables)
{
char const* text = R"(