aboutsummaryrefslogtreecommitdiffstats
path: root/test/libsolidity
diff options
context:
space:
mode:
authorchriseth <c@ethdev.com>2016-12-15 19:16:32 +0800
committerchriseth <c@ethdev.com>2016-12-15 19:16:56 +0800
commit822622cf5bf23e79a6e2292cb837d1a39ca1c419 (patch)
treee668cf9a257bab10e77469ba725e630bc8f3b0a5 /test/libsolidity
parent2dabbdf06f414750ef0425c664f861aeb3e470b8 (diff)
parent3a692e3df9b62852c951adece42f6d12b2d4a44a (diff)
downloaddexon-solidity-822622cf5bf23e79a6e2292cb837d1a39ca1c419.tar.gz
dexon-solidity-822622cf5bf23e79a6e2292cb837d1a39ca1c419.tar.zst
dexon-solidity-822622cf5bf23e79a6e2292cb837d1a39ca1c419.zip
Merge remote-tracking branch 'origin/develop' into release
Diffstat (limited to 'test/libsolidity')
-rw-r--r--test/libsolidity/ASTJSON.cpp8
-rw-r--r--test/libsolidity/Assembly.cpp12
-rw-r--r--test/libsolidity/ErrorCheck.cpp34
-rw-r--r--test/libsolidity/ErrorCheck.h32
-rw-r--r--test/libsolidity/GasMeter.cpp11
-rw-r--r--test/libsolidity/Imports.cpp8
-rw-r--r--test/libsolidity/InlineAssembly.cpp8
-rw-r--r--test/libsolidity/SemVerMatcher.cpp8
-rw-r--r--test/libsolidity/SolidityABIJSON.cpp149
-rw-r--r--test/libsolidity/SolidityEndToEndTest.cpp1709
-rw-r--r--test/libsolidity/SolidityExecutionFramework.cpp116
-rw-r--r--test/libsolidity/SolidityExecutionFramework.h255
-rw-r--r--test/libsolidity/SolidityExpressionCompiler.cpp134
-rw-r--r--test/libsolidity/SolidityNameAndTypeResolution.cpp1713
-rw-r--r--test/libsolidity/SolidityNatspecJSON.cpp352
-rw-r--r--test/libsolidity/SolidityOptimizer.cpp149
-rw-r--r--test/libsolidity/SolidityParser.cpp742
-rw-r--r--test/libsolidity/SolidityScanner.cpp8
-rw-r--r--test/libsolidity/SolidityTypes.cpp8
19 files changed, 3261 insertions, 2195 deletions
diff --git a/test/libsolidity/ASTJSON.cpp b/test/libsolidity/ASTJSON.cpp
index b88218e7..0972ce82 100644
--- a/test/libsolidity/ASTJSON.cpp
+++ b/test/libsolidity/ASTJSON.cpp
@@ -1,18 +1,18 @@
/*
- This file is part of cpp-ethereum.
+ This file is part of solidity.
- cpp-ethereum is free software: you can redistribute it and/or modify
+ 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.
- cpp-ethereum is distributed in the hope that it will be useful,
+ 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 cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
+ along with solidity. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* @author Christian <c@ethdev.com>
diff --git a/test/libsolidity/Assembly.cpp b/test/libsolidity/Assembly.cpp
index e5ce691b..155dd5c9 100644
--- a/test/libsolidity/Assembly.cpp
+++ b/test/libsolidity/Assembly.cpp
@@ -1,18 +1,18 @@
/*
- This file is part of cpp-ethereum.
+ This file is part of solidity.
- cpp-ethereum is free software: you can redistribute it and/or modify
+ 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.
- cpp-ethereum is distributed in the hope that it will be useful,
+ 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 cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
+ along with solidity. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* @author Lefteris Karapetsas <lefteris@ethdev.com>
@@ -75,7 +75,7 @@ eth::AssemblyItems compileContract(const string& _sourceCode)
if (ContractDefinition* contract = dynamic_cast<ContractDefinition*>(node.get()))
{
Compiler compiler;
- compiler.compileContract(*contract, map<ContractDefinition const*, Assembly const*>{});
+ compiler.compileContract(*contract, map<ContractDefinition const*, Assembly const*>{}, bytes());
return compiler.runtimeAssemblyItems();
}
@@ -116,7 +116,7 @@ BOOST_AUTO_TEST_CASE(location_test)
shared_ptr<string const> n = make_shared<string>("");
AssemblyItems items = compileContract(sourceCode);
vector<SourceLocation> locations =
- vector<SourceLocation>(16, SourceLocation(2, 75, n)) +
+ vector<SourceLocation>(18, SourceLocation(2, 75, n)) +
vector<SourceLocation>(27, SourceLocation(20, 72, n)) +
vector<SourceLocation>{SourceLocation(42, 51, n), SourceLocation(65, 67, n)} +
vector<SourceLocation>(2, SourceLocation(58, 67, n)) +
diff --git a/test/libsolidity/ErrorCheck.cpp b/test/libsolidity/ErrorCheck.cpp
new file mode 100644
index 00000000..75555c9b
--- /dev/null
+++ b/test/libsolidity/ErrorCheck.cpp
@@ -0,0 +1,34 @@
+/*
+ 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/>.
+*/
+/** @file ErrorCheck.cpp
+ * @author Yoichi Hirai <i@yoichihirai.com>
+ * @date 2016
+ */
+
+#include <test/libsolidity/ErrorCheck.h>
+#include <libdevcore/Exceptions.h>
+
+#include <string>
+
+using namespace std;
+
+bool dev::solidity::searchErrorMessage(Error const& _err, std::string const& _substr)
+{
+ if (string const* errorMessage = boost::get_error_info<dev::errinfo_comment>(_err))
+ return errorMessage->find(_substr) != std::string::npos;
+ return _substr.empty();
+}
diff --git a/test/libsolidity/ErrorCheck.h b/test/libsolidity/ErrorCheck.h
new file mode 100644
index 00000000..a309a9d3
--- /dev/null
+++ b/test/libsolidity/ErrorCheck.h
@@ -0,0 +1,32 @@
+/*
+ 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/>.
+*/
+/** @file ErrorCheck.h
+ * @author Yoichi Hirai <i@yoichihirai.com>
+ * @date 2016
+ */
+
+#pragma once
+
+#include <libsolidity/interface/Exceptions.h>
+
+namespace dev
+{
+namespace solidity
+{
+bool searchErrorMessage(Error const& _err, std::string const& _substr);
+}
+}
diff --git a/test/libsolidity/GasMeter.cpp b/test/libsolidity/GasMeter.cpp
index fc103393..0671fb15 100644
--- a/test/libsolidity/GasMeter.cpp
+++ b/test/libsolidity/GasMeter.cpp
@@ -1,18 +1,18 @@
/*
- This file is part of cpp-ethereum.
+ This file is part of solidity.
- cpp-ethereum is free software: you can redistribute it and/or modify
+ 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.
- cpp-ethereum is distributed in the hope that it will be useful,
+ 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 cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
+ along with solidity. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* @author Christian <c@ethdev.com>
@@ -32,6 +32,7 @@
using namespace std;
using namespace dev::eth;
using namespace dev::solidity;
+using namespace dev::test;
namespace dev
{
@@ -40,7 +41,7 @@ namespace solidity
namespace test
{
-class GasMeterTestFramework: public ExecutionFramework
+class GasMeterTestFramework: public SolidityExecutionFramework
{
public:
GasMeterTestFramework() { }
diff --git a/test/libsolidity/Imports.cpp b/test/libsolidity/Imports.cpp
index 1a9e16cc..bc6adc26 100644
--- a/test/libsolidity/Imports.cpp
+++ b/test/libsolidity/Imports.cpp
@@ -1,18 +1,18 @@
/*
- This file is part of cpp-ethereum.
+ This file is part of solidity.
- cpp-ethereum is free software: you can redistribute it and/or modify
+ 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.
- cpp-ethereum is distributed in the hope that it will be useful,
+ 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 cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
+ along with solidity. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* @author Christian <c@ethdev.com>
diff --git a/test/libsolidity/InlineAssembly.cpp b/test/libsolidity/InlineAssembly.cpp
index 185a6215..64073edc 100644
--- a/test/libsolidity/InlineAssembly.cpp
+++ b/test/libsolidity/InlineAssembly.cpp
@@ -1,18 +1,18 @@
/*
- This file is part of cpp-ethereum.
+ This file is part of solidity.
- cpp-ethereum is free software: you can redistribute it and/or modify
+ 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.
- cpp-ethereum is distributed in the hope that it will be useful,
+ 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 cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
+ along with solidity. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* @author Christian <c@ethdev.com>
diff --git a/test/libsolidity/SemVerMatcher.cpp b/test/libsolidity/SemVerMatcher.cpp
index 80bdf16f..08ef5277 100644
--- a/test/libsolidity/SemVerMatcher.cpp
+++ b/test/libsolidity/SemVerMatcher.cpp
@@ -1,18 +1,18 @@
/*
- This file is part of cpp-ethereum.
+ This file is part of solidity.
- cpp-ethereum is free software: you can redistribute it and/or modify
+ 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.
- cpp-ethereum is distributed in the hope that it will be useful,
+ 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 cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
+ along with solidity. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* @author Christian <chris@ethereum.org>
diff --git a/test/libsolidity/SolidityABIJSON.cpp b/test/libsolidity/SolidityABIJSON.cpp
index a8a39b0b..043d74ed 100644
--- a/test/libsolidity/SolidityABIJSON.cpp
+++ b/test/libsolidity/SolidityABIJSON.cpp
@@ -1,18 +1,18 @@
/*
- This file is part of cpp-ethereum.
+ This file is part of solidity.
- cpp-ethereum is free software: you can redistribute it and/or modify
+ 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.
- cpp-ethereum is distributed in the hope that it will be useful,
+ 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 cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
+ along with solidity. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* @author Marek Kotewicz <marek@ethdev.com>
@@ -22,8 +22,11 @@
#include "../TestHelper.h"
#include <libsolidity/interface/CompilerStack.h>
-#include <json/json.h>
+
#include <libdevcore/Exceptions.h>
+#include <libdevcore/SwarmHash.h>
+
+#include <json/json.h>
namespace dev
{
@@ -51,7 +54,7 @@ public:
);
}
-private:
+protected:
CompilerStack m_compilerStack;
Json::Reader m_reader;
};
@@ -60,9 +63,11 @@ BOOST_FIXTURE_TEST_SUITE(SolidityABIJSON, JSONInterfaceChecker)
BOOST_AUTO_TEST_CASE(basic_test)
{
- char const* sourceCode = "contract test {\n"
- " function f(uint a) returns(uint d) { return a * 7; }\n"
- "}\n";
+ char const* sourceCode = R"(
+ contract test {
+ function f(uint a) returns(uint d) { return a * 7; }
+ }
+ )";
char const* interface = R"([
{
@@ -90,8 +95,9 @@ BOOST_AUTO_TEST_CASE(basic_test)
BOOST_AUTO_TEST_CASE(empty_contract)
{
- char const* sourceCode = "contract test {\n"
- "}\n";
+ char const* sourceCode = R"(
+ contract test { }
+ )";
char const* interface = "[]";
checkInterface(sourceCode, interface);
@@ -99,10 +105,12 @@ BOOST_AUTO_TEST_CASE(empty_contract)
BOOST_AUTO_TEST_CASE(multiple_methods)
{
- char const* sourceCode = "contract test {\n"
- " function f(uint a) returns(uint d) { return a * 7; }\n"
- " function g(uint b) returns(uint e) { return b * 8; }\n"
- "}\n";
+ char const* sourceCode = R"(
+ contract test {
+ function f(uint a) returns(uint d) { return a * 7; }
+ function g(uint b) returns(uint e) { return b * 8; }
+ }
+ )";
char const* interface = R"([
{
@@ -148,9 +156,11 @@ BOOST_AUTO_TEST_CASE(multiple_methods)
BOOST_AUTO_TEST_CASE(multiple_params)
{
- char const* sourceCode = "contract test {\n"
- " function f(uint a, uint b) returns(uint d) { return a + b; }\n"
- "}\n";
+ char const* sourceCode = R"(
+ contract test {
+ function f(uint a, uint b) returns(uint d) { return a + b; }
+ }
+ )";
char const* interface = R"([
{
@@ -183,10 +193,12 @@ BOOST_AUTO_TEST_CASE(multiple_params)
BOOST_AUTO_TEST_CASE(multiple_methods_order)
{
// methods are expected to be in alpabetical order
- char const* sourceCode = "contract test {\n"
- " function f(uint a) returns(uint d) { return a * 7; }\n"
- " function c(uint b) returns(uint e) { return b * 8; }\n"
- "}\n";
+ char const* sourceCode = R"(
+ contract test {
+ function f(uint a) returns(uint d) { return a * 7; }
+ function c(uint b) returns(uint e) { return b * 8; }
+ }
+ )";
char const* interface = R"([
{
@@ -232,10 +244,12 @@ BOOST_AUTO_TEST_CASE(multiple_methods_order)
BOOST_AUTO_TEST_CASE(const_function)
{
- char const* sourceCode = "contract test {\n"
- " function foo(uint a, uint b) returns(uint d) { return a + b; }\n"
- " function boo(uint32 a) constant returns(uint b) { return a * 4; }\n"
- "}\n";
+ char const* sourceCode = R"(
+ contract test {
+ function foo(uint a, uint b) returns(uint d) { return a + b; }
+ function boo(uint32 a) constant returns(uint b) { return a * 4; }
+ }
+ )";
char const* interface = R"([
{
@@ -283,11 +297,13 @@ BOOST_AUTO_TEST_CASE(const_function)
BOOST_AUTO_TEST_CASE(events)
{
- char const* sourceCode = "contract test {\n"
- " function f(uint a) returns(uint d) { return a * 7; }\n"
- " event e1(uint b, address indexed c); \n"
- " event e2(); \n"
- "}\n";
+ char const* sourceCode = R"(
+ contract test {
+ function f(uint a) returns(uint d) { return a * 7; }
+ event e1(uint b, address indexed c);
+ event e2();
+ }
+ )";
char const* interface = R"([
{
"name": "f",
@@ -338,9 +354,11 @@ BOOST_AUTO_TEST_CASE(events)
BOOST_AUTO_TEST_CASE(events_anonymous)
{
- char const* sourceCode = "contract test {\n"
- " event e() anonymous; \n"
- "}\n";
+ char const* sourceCode = R"(
+ contract test {
+ event e() anonymous;
+ }
+ )";
char const* interface = R"([
{
"name": "e",
@@ -356,15 +374,16 @@ BOOST_AUTO_TEST_CASE(events_anonymous)
BOOST_AUTO_TEST_CASE(inherited)
{
- char const* sourceCode =
- " contract Base { \n"
- " function baseFunction(uint p) returns (uint i) { return p; } \n"
- " event baseEvent(bytes32 indexed evtArgBase); \n"
- " } \n"
- " contract Derived is Base { \n"
- " function derivedFunction(bytes32 p) returns (bytes32 i) { return p; } \n"
- " event derivedEvent(uint indexed evtArgDerived); \n"
- " }";
+ char const* sourceCode = R"(
+ contract Base {
+ function baseFunction(uint p) returns (uint i) { return p; }
+ event baseEvent(bytes32 indexed evtArgBase);
+ }
+ contract Derived is Base {
+ function derivedFunction(bytes32 p) returns (bytes32 i) { return p; }
+ event derivedEvent(uint indexed evtArgDerived);
+ }
+ )";
char const* interface = R"([
{
@@ -428,13 +447,14 @@ BOOST_AUTO_TEST_CASE(inherited)
BOOST_AUTO_TEST_CASE(empty_name_input_parameter_with_named_one)
{
char const* sourceCode = R"(
- contract test {
- function f(uint, uint k) returns(uint ret_k, uint ret_g){
- uint g = 8;
- ret_k = k;
- ret_g = g;
+ contract test {
+ function f(uint, uint k) returns(uint ret_k, uint ret_g) {
+ uint g = 8;
+ ret_k = k;
+ ret_g = g;
+ }
}
- })";
+ )";
char const* interface = R"([
{
@@ -472,10 +492,11 @@ BOOST_AUTO_TEST_CASE(empty_name_return_parameter)
{
char const* sourceCode = R"(
contract test {
- function f(uint k) returns(uint){
- return k;
+ function f(uint k) returns(uint) {
+ return k;
+ }
}
- })";
+ )";
char const* interface = R"([
{
@@ -539,7 +560,7 @@ BOOST_AUTO_TEST_CASE(return_param_in_abi)
contract test {
enum ActionChoices { GoLeft, GoRight, GoStraight, Sit }
function test(ActionChoices param) {}
- function ret() returns(ActionChoices){
+ function ret() returns(ActionChoices) {
ActionChoices action = ActionChoices.GoLeft;
return action;
}
@@ -609,7 +630,7 @@ BOOST_AUTO_TEST_CASE(library_function)
char const* sourceCode = R"(
library test {
struct StructType { uint a; }
- function f(StructType storage b, uint[] storage c, test d) returns (uint[] e, StructType storage f){}
+ function f(StructType storage b, uint[] storage c, test d) returns (uint[] e, StructType storage f) {}
}
)";
@@ -731,6 +752,26 @@ BOOST_AUTO_TEST_CASE(function_type)
checkInterface(sourceCode, interface);
}
+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;
+ contract test {
+ function g(function(uint) external returns (uint) x) {}
+ }
+ )";
+ BOOST_REQUIRE(m_compilerStack.compile(std::string(sourceCode)));
+ bytes const& bytecode = m_compilerStack.runtimeObject("test").bytecode;
+ bytes hash = dev::swarmHash(m_compilerStack.onChainMetadata("test")).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{0xa1, 0x65, 'b', 'z', 'z', 'r', '0', 0x58, 0x20} + hash;
+ BOOST_CHECK(std::equal(expectation.begin(), expectation.end(), bytecode.end() - metadataCBORSize - 2));
+}
+
BOOST_AUTO_TEST_SUITE_END()
}
diff --git a/test/libsolidity/SolidityEndToEndTest.cpp b/test/libsolidity/SolidityEndToEndTest.cpp
index 4abe0894..94d4fb7f 100644
--- a/test/libsolidity/SolidityEndToEndTest.cpp
+++ b/test/libsolidity/SolidityEndToEndTest.cpp
@@ -1,18 +1,18 @@
/*
- This file is part of cpp-ethereum.
+ This file is part of solidity.
- cpp-ethereum is free software: you can redistribute it and/or modify
+ 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.
- cpp-ethereum is distributed in the hope that it will be useful,
+ 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 cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
+ along with solidity. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* @author Christian <c@ethdev.com>
@@ -25,11 +25,13 @@
#include <string>
#include <tuple>
#include <boost/test/unit_test.hpp>
+#include <libevmasm/Assembly.h>
#include <libsolidity/interface/Exceptions.h>
#include <test/libsolidity/SolidityExecutionFramework.h>
using namespace std;
using namespace std::placeholders;
+using namespace dev::test;
namespace dev
{
@@ -38,21 +40,24 @@ namespace solidity
namespace test
{
-BOOST_FIXTURE_TEST_SUITE(SolidityEndToEndTest, ExecutionFramework)
+BOOST_FIXTURE_TEST_SUITE(SolidityEndToEndTest, SolidityExecutionFramework)
BOOST_AUTO_TEST_CASE(smoke_test)
{
- char const* sourceCode = "contract test {\n"
- " function f(uint a) returns(uint d) { return a * 7; }\n"
- "}\n";
+ char const* sourceCode = R"(
+ contract test {
+ function f(uint a) returns(uint d) { return a * 7; }
+ }
+ )";
compileAndRun(sourceCode);
- testSolidityAgainstCppOnRange("f(uint256)", [](u256 const& a) -> u256 { return a * 7; }, 0, 100);
+ testContractAgainstCppOnRange("f(uint256)", [](u256 const& a) -> u256 { return a * 7; }, 0, 100);
}
BOOST_AUTO_TEST_CASE(empty_contract)
{
- char const* sourceCode = "contract test {\n"
- "}\n";
+ char const* sourceCode = R"(
+ contract test { }
+ )";
compileAndRun(sourceCode);
BOOST_CHECK(callContractFunction("i_am_not_there()", bytes()).empty());
}
@@ -62,9 +67,10 @@ BOOST_AUTO_TEST_CASE(exp_operator)
char const* sourceCode = R"(
contract test {
function f(uint a) returns(uint d) { return 2 ** a; }
- })";
+ }
+ )";
compileAndRun(sourceCode);
- testSolidityAgainstCppOnRange("f(uint256)", [](u256 const& a) -> u256 { return u256(1 << a.convert_to<int>()); }, 0, 16);
+ testContractAgainstCppOnRange("f(uint256)", [](u256 const& a) -> u256 { return u256(1 << a.convert_to<int>()); }, 0, 16);
}
BOOST_AUTO_TEST_CASE(exp_operator_const)
@@ -72,7 +78,8 @@ BOOST_AUTO_TEST_CASE(exp_operator_const)
char const* sourceCode = R"(
contract test {
function f() returns(uint d) { return 2 ** 3; }
- })";
+ }
+ )";
compileAndRun(sourceCode);
BOOST_CHECK(callContractFunction("f()", bytes()) == toBigEndian(u256(8)));
}
@@ -82,7 +89,8 @@ BOOST_AUTO_TEST_CASE(exp_operator_const_signed)
char const* sourceCode = R"(
contract test {
function f() returns(int d) { return (-2) ** 3; }
- })";
+ }
+ )";
compileAndRun(sourceCode);
BOOST_CHECK(callContractFunction("f()", bytes()) == toBigEndian(u256(-8)));
}
@@ -93,8 +101,9 @@ BOOST_AUTO_TEST_CASE(conditional_expression_true_literal)
contract test {
function f() returns(uint d) {
return true ? 5 : 10;
- }
- })";
+ }
+ }
+ )";
compileAndRun(sourceCode);
BOOST_CHECK(callContractFunction("f()", bytes()) == toBigEndian(u256(5)));
}
@@ -105,8 +114,9 @@ BOOST_AUTO_TEST_CASE(conditional_expression_false_literal)
contract test {
function f() returns(uint d) {
return false ? 5 : 10;
- }
- })";
+ }
+ }
+ )";
compileAndRun(sourceCode);
BOOST_CHECK(callContractFunction("f()", bytes()) == toBigEndian(u256(10)));
}
@@ -116,12 +126,13 @@ BOOST_AUTO_TEST_CASE(conditional_expression_multiple)
char const* sourceCode = R"(
contract test {
function f(uint x) returns(uint d) {
- return x > 100 ?
+ return x > 100 ?
x > 1000 ? 1000 : 100
:
x > 50 ? 50 : 10;
- }
- })";
+ }
+ }
+ )";
compileAndRun(sourceCode);
BOOST_CHECK(callContractFunction("f(uint256)", u256(1001)) == toBigEndian(u256(1000)));
BOOST_CHECK(callContractFunction("f(uint256)", u256(500)) == toBigEndian(u256(100)));
@@ -135,7 +146,7 @@ BOOST_AUTO_TEST_CASE(conditional_expression_with_return_values)
contract test {
function f(bool cond, uint v) returns (uint a, uint b) {
cond ? a = v : b = v;
- }
+ }
})";
compileAndRun(sourceCode);
BOOST_CHECK(callContractFunction("f(bool,uint256)", true, u256(20)) == encodeArgs(u256(20), u256(0)));
@@ -167,7 +178,7 @@ BOOST_AUTO_TEST_CASE(conditional_expression_storage_memory_1)
}
return ret;
- }
+ }
}
)";
compileAndRun(sourceCode);
@@ -201,7 +212,7 @@ BOOST_AUTO_TEST_CASE(conditional_expression_storage_memory_2)
}
return ret;
- }
+ }
}
)";
compileAndRun(sourceCode);
@@ -217,7 +228,7 @@ BOOST_AUTO_TEST_CASE(conditional_expression_different_types)
uint8 x = 0xcd;
uint16 y = 0xabab;
return cond ? x : y;
- }
+ }
}
)";
compileAndRun(sourceCode);
@@ -275,12 +286,14 @@ BOOST_AUTO_TEST_CASE(conditional_expression_functions)
BOOST_AUTO_TEST_CASE(recursive_calls)
{
- char const* sourceCode = "contract test {\n"
- " function f(uint n) returns(uint nfac) {\n"
- " if (n <= 1) return 1;\n"
- " else return n * f(n - 1);\n"
- " }\n"
- "}\n";
+ char const* sourceCode = R"(
+ contract test {
+ function f(uint n) returns(uint nfac) {
+ if (n <= 1) return 1;
+ else return n * f(n - 1);
+ }
+ }
+ )";
compileAndRun(sourceCode);
function<u256(u256)> recursive_calls_cpp = [&recursive_calls_cpp](u256 const& n) -> u256
{
@@ -290,17 +303,19 @@ BOOST_AUTO_TEST_CASE(recursive_calls)
return n * recursive_calls_cpp(n - 1);
};
- testSolidityAgainstCppOnRange("f(uint256)", recursive_calls_cpp, 0, 5);
+ testContractAgainstCppOnRange("f(uint256)", recursive_calls_cpp, 0, 5);
}
BOOST_AUTO_TEST_CASE(multiple_functions)
{
- char const* sourceCode = "contract test {\n"
- " function a() returns(uint n) { return 0; }\n"
- " function b() returns(uint n) { return 1; }\n"
- " function c() returns(uint n) { return 2; }\n"
- " function f() returns(uint n) { return 3; }\n"
- "}\n";
+ char const* sourceCode = R"(
+ contract test {
+ function a() returns(uint n) { return 0; }
+ function b() returns(uint n) { return 1; }
+ function c() returns(uint n) { return 2; }
+ function f() returns(uint n) { return 3; }
+ }
+ )";
compileAndRun(sourceCode);
BOOST_CHECK(callContractFunction("a()", bytes()) == toBigEndian(u256(0)));
BOOST_CHECK(callContractFunction("b()", bytes()) == toBigEndian(u256(1)));
@@ -311,33 +326,39 @@ BOOST_AUTO_TEST_CASE(multiple_functions)
BOOST_AUTO_TEST_CASE(named_args)
{
- char const* sourceCode = "contract test {\n"
- " function a(uint a, uint b, uint c) returns (uint r) { r = a * 100 + b * 10 + c * 1; }\n"
- " function b() returns (uint r) { r = a({a: 1, b: 2, c: 3}); }\n"
- "}\n";
+ char const* sourceCode = R"(
+ contract test {
+ function a(uint a, uint b, uint c) returns (uint r) { r = a * 100 + b * 10 + c * 1; }
+ function b() returns (uint r) { r = a({a: 1, b: 2, c: 3}); }
+ }
+ )";
compileAndRun(sourceCode);
BOOST_CHECK(callContractFunction("b()", bytes()) == toBigEndian(u256(123)));
}
BOOST_AUTO_TEST_CASE(disorder_named_args)
{
- char const* sourceCode = "contract test {\n"
- " function a(uint a, uint b, uint c) returns (uint r) { r = a * 100 + b * 10 + c * 1; }\n"
- " function b() returns (uint r) { r = a({c: 3, a: 1, b: 2}); }\n"
- "}\n";
+ char const* sourceCode = R"(
+ contract test {
+ function a(uint a, uint b, uint c) returns (uint r) { r = a * 100 + b * 10 + c * 1; }
+ function b() returns (uint r) { r = a({c: 3, a: 1, b: 2}); }
+ }
+ )";
compileAndRun(sourceCode);
BOOST_CHECK(callContractFunction("b()", bytes()) == toBigEndian(u256(123)));
}
BOOST_AUTO_TEST_CASE(while_loop)
{
- char const* sourceCode = "contract test {\n"
- " function f(uint n) returns(uint nfac) {\n"
- " nfac = 1;\n"
- " var i = 2;\n"
- " while (i <= n) nfac *= i++;\n"
- " }\n"
- "}\n";
+ char const* sourceCode = R"(
+ contract test {
+ function f(uint n) returns(uint nfac) {
+ nfac = 1;
+ var i = 2;
+ while (i <= n) nfac *= i++;
+ }
+ }
+ )";
compileAndRun(sourceCode);
auto while_loop_cpp = [](u256 const& n) -> u256
@@ -350,19 +371,21 @@ BOOST_AUTO_TEST_CASE(while_loop)
return nfac;
};
- testSolidityAgainstCppOnRange("f(uint256)", while_loop_cpp, 0, 5);
+ testContractAgainstCppOnRange("f(uint256)", while_loop_cpp, 0, 5);
}
BOOST_AUTO_TEST_CASE(do_while_loop)
{
- char const* sourceCode = "contract test {\n"
- " function f(uint n) returns(uint nfac) {\n"
- " nfac = 1;\n"
- " var i = 2;\n"
- " do { nfac *= i++; } while (i <= n);\n"
- " }\n"
- "}\n";
+ char const* sourceCode = R"(
+ contract test {
+ function f(uint n) returns(uint nfac) {
+ nfac = 1;
+ var i = 2;
+ do { nfac *= i++; } while (i <= n);
+ }
+ }
+ )";
compileAndRun(sourceCode);
auto do_while_loop_cpp = [](u256 const& n) -> u256
@@ -378,32 +401,34 @@ BOOST_AUTO_TEST_CASE(do_while_loop)
return nfac;
};
- testSolidityAgainstCppOnRange("f(uint256)", do_while_loop_cpp, 0, 5);
+ testContractAgainstCppOnRange("f(uint256)", do_while_loop_cpp, 0, 5);
}
BOOST_AUTO_TEST_CASE(nested_loops)
{
// tests that break and continue statements in nested loops jump to the correct place
- char const* sourceCode = "contract test {\n"
- " function f(uint x) returns(uint y) {\n"
- " while (x > 1) {\n"
- " if (x == 10) break;\n"
- " while (x > 5) {\n"
- " if (x == 8) break;\n"
- " x--;\n"
- " if (x == 6) continue;\n"
- " return x;\n"
- " }\n"
- " x--;\n"
- " if (x == 3) continue;\n"
- " break;\n"
- " }\n"
- " return x;\n"
- " }\n"
- "}\n";
- compileAndRun(sourceCode);
-
- auto nested_loops_cpp = [](u256 n) -> u256
+ char const* sourceCode = R"(
+ contract test {
+ function f(uint x) returns(uint y) {
+ while (x > 1) {
+ if (x == 10) break;
+ while (x > 5) {
+ if (x == 8) break;
+ x--;
+ if (x == 6) continue;
+ return x;
+ }
+ x--;
+ if (x == 3) continue;
+ break;
+ }
+ return x;
+ }
+ }
+ )";
+ compileAndRun(sourceCode);
+
+ auto nested_loops_cpp = [](u256 n) -> u256
{
while (n > 1)
{
@@ -427,18 +452,20 @@ BOOST_AUTO_TEST_CASE(nested_loops)
return n;
};
- testSolidityAgainstCppOnRange("f(uint256)", nested_loops_cpp, 0, 12);
+ testContractAgainstCppOnRange("f(uint256)", nested_loops_cpp, 0, 12);
}
BOOST_AUTO_TEST_CASE(for_loop)
{
- char const* sourceCode = "contract test {\n"
- " function f(uint n) returns(uint nfac) {\n"
- " nfac = 1;\n"
- " for (var i = 2; i <= n; i++)\n"
- " nfac *= i;\n"
- " }\n"
- "}\n";
+ char const* sourceCode = R"(
+ contract test {
+ function f(uint n) returns(uint nfac) {
+ nfac = 1;
+ for (var i = 2; i <= n; i++)
+ nfac *= i;
+ }
+ }
+ )";
compileAndRun(sourceCode);
auto for_loop_cpp = [](u256 const& n) -> u256
@@ -449,21 +476,22 @@ BOOST_AUTO_TEST_CASE(for_loop)
return nfac;
};
- testSolidityAgainstCppOnRange("f(uint256)", for_loop_cpp, 0, 5);
+ testContractAgainstCppOnRange("f(uint256)", for_loop_cpp, 0, 5);
}
BOOST_AUTO_TEST_CASE(for_loop_empty)
{
- char const* sourceCode = "contract test {\n"
- " function f() returns(uint ret) {\n"
- " ret = 1;\n"
- " for (;;)\n"
- " {\n"
- " ret += 1;\n"
- " if (ret >= 10) break;\n"
- " }\n"
- " }\n"
- "}\n";
+ char const* sourceCode = R"(
+ contract test {
+ function f() returns(uint ret) {
+ ret = 1;
+ for (;;) {
+ ret += 1;
+ if (ret >= 10) break;
+ }
+ }
+ }
+ )";
compileAndRun(sourceCode);
auto for_loop_empty_cpp = []() -> u256
@@ -477,19 +505,21 @@ BOOST_AUTO_TEST_CASE(for_loop_empty)
return ret;
};
- testSolidityAgainstCpp("f()", for_loop_empty_cpp);
+ testContractAgainstCpp("f()", for_loop_empty_cpp);
}
BOOST_AUTO_TEST_CASE(for_loop_simple_init_expr)
{
- char const* sourceCode = "contract test {\n"
- " function f(uint n) returns(uint nfac) {\n"
- " nfac = 1;\n"
- " uint256 i;\n"
- " for (i = 2; i <= n; i++)\n"
- " nfac *= i;\n"
- " }\n"
- "}\n";
+ char const* sourceCode = R"(
+ contract test {
+ function f(uint n) returns(uint nfac) {
+ nfac = 1;
+ uint256 i;
+ for (i = 2; i <= n; i++)
+ nfac *= i;
+ }
+ }
+ )";
compileAndRun(sourceCode);
auto for_loop_simple_init_expr_cpp = [](u256 const& n) -> u256
@@ -501,7 +531,7 @@ BOOST_AUTO_TEST_CASE(for_loop_simple_init_expr)
return nfac;
};
- testSolidityAgainstCppOnRange("f(uint256)", for_loop_simple_init_expr_cpp, 0, 5);
+ testContractAgainstCppOnRange("f(uint256)", for_loop_simple_init_expr_cpp, 0, 5);
}
BOOST_AUTO_TEST_CASE(for_loop_break_continue)
@@ -547,25 +577,27 @@ BOOST_AUTO_TEST_CASE(for_loop_break_continue)
return i;
};
- testSolidityAgainstCppOnRange("f(uint256)", breakContinue, 0, 10);
+ testContractAgainstCppOnRange("f(uint256)", breakContinue, 0, 10);
}
BOOST_AUTO_TEST_CASE(calling_other_functions)
{
- char const* sourceCode = "contract collatz {\n"
- " function run(uint x) returns(uint y) {\n"
- " while ((y = x) > 1) {\n"
- " if (x % 2 == 0) x = evenStep(x);\n"
- " else x = oddStep(x);\n"
- " }\n"
- " }\n"
- " function evenStep(uint x) returns(uint y) {\n"
- " return x / 2;\n"
- " }\n"
- " function oddStep(uint x) returns(uint y) {\n"
- " return 3 * x + 1;\n"
- " }\n"
- "}\n";
+ char const* sourceCode = R"(
+ contract collatz {
+ function run(uint x) returns(uint y) {
+ while ((y = x) > 1) {
+ if (x % 2 == 0) x = evenStep(x);
+ else x = oddStep(x);
+ }
+ }
+ function evenStep(uint x) returns(uint y) {
+ return x / 2;
+ }
+ function oddStep(uint x) returns(uint y) {
+ return 3 * x + 1;
+ }
+ }
+ )";
compileAndRun(sourceCode);
auto evenStep_cpp = [](u256 const& n) -> u256
@@ -591,22 +623,24 @@ BOOST_AUTO_TEST_CASE(calling_other_functions)
return y;
};
- testSolidityAgainstCpp("run(uint256)", collatz_cpp, u256(0));
- testSolidityAgainstCpp("run(uint256)", collatz_cpp, u256(1));
- testSolidityAgainstCpp("run(uint256)", collatz_cpp, u256(2));
- testSolidityAgainstCpp("run(uint256)", collatz_cpp, u256(8));
- testSolidityAgainstCpp("run(uint256)", collatz_cpp, u256(127));
+ testContractAgainstCpp("run(uint256)", collatz_cpp, u256(0));
+ testContractAgainstCpp("run(uint256)", collatz_cpp, u256(1));
+ testContractAgainstCpp("run(uint256)", collatz_cpp, u256(2));
+ testContractAgainstCpp("run(uint256)", collatz_cpp, u256(8));
+ testContractAgainstCpp("run(uint256)", collatz_cpp, u256(127));
}
BOOST_AUTO_TEST_CASE(many_local_variables)
{
- char const* sourceCode = "contract test {\n"
- " function run(uint x1, uint x2, uint x3) returns(uint y) {\n"
- " var a = 0x1; var b = 0x10; var c = 0x100;\n"
- " y = a + b + c + x1 + x2 + x3;\n"
- " y += b + x2;\n"
- " }\n"
- "}\n";
+ char const* sourceCode = R"(
+ contract test {
+ function run(uint x1, uint x2, uint x3) returns(uint y) {
+ var a = 0x1; var b = 0x10; var c = 0x100;
+ y = a + b + c + x1 + x2 + x3;
+ y += b + x2;
+ }
+ }
+ )";
compileAndRun(sourceCode);
auto f = [](u256 const& x1, u256 const& x2, u256 const& x3) -> u256
{
@@ -616,18 +650,20 @@ BOOST_AUTO_TEST_CASE(many_local_variables)
u256 y = a + b + c + x1 + x2 + x3;
return y + b + x2;
};
- testSolidityAgainstCpp("run(uint256,uint256,uint256)", f, u256(0x1000), u256(0x10000), u256(0x100000));
+ testContractAgainstCpp("run(uint256,uint256,uint256)", f, u256(0x1000), u256(0x10000), u256(0x100000));
}
BOOST_AUTO_TEST_CASE(packing_unpacking_types)
{
- char const* sourceCode = "contract test {\n"
- " function run(bool a, uint32 b, uint64 c) returns(uint256 y) {\n"
- " if (a) y = 1;\n"
- " y = y * 0x100000000 | ~b;\n"
- " y = y * 0x10000000000000000 | ~c;\n"
- " }\n"
- "}\n";
+ char const* sourceCode = R"(
+ contract test {
+ function run(bool a, uint32 b, uint64 c) returns(uint256 y) {
+ if (a) y = 1;
+ y = y * 0x100000000 | ~b;
+ y = y * 0x10000000000000000 | ~c;
+ }
+ }
+ )";
compileAndRun(sourceCode);
BOOST_CHECK(callContractFunction("run(bool,uint32,uint64)", true, fromHex("0f0f0f0f"), fromHex("f0f0f0f0f0f0f0f0"))
== fromHex("00000000000000000000000000000000000000""01""f0f0f0f0""0f0f0f0f0f0f0f0f"));
@@ -635,12 +671,14 @@ BOOST_AUTO_TEST_CASE(packing_unpacking_types)
BOOST_AUTO_TEST_CASE(packing_signed_types)
{
- char const* sourceCode = "contract test {\n"
- " function run() returns(int8 y) {\n"
- " uint8 x = 0xfa;\n"
- " return int8(x);\n"
- " }\n"
- "}\n";
+ char const* sourceCode = R"(
+ contract test {
+ function run() returns(int8 y) {
+ uint8 x = 0xfa;
+ return int8(x);
+ }
+ }
+ )";
compileAndRun(sourceCode);
BOOST_CHECK(callContractFunction("run()")
== fromHex("fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa"));
@@ -648,23 +686,27 @@ BOOST_AUTO_TEST_CASE(packing_signed_types)
BOOST_AUTO_TEST_CASE(multiple_return_values)
{
- char const* sourceCode = "contract test {\n"
- " function run(bool x1, uint x2) returns(uint y1, bool y2, uint y3) {\n"
- " y1 = x2; y2 = x1;\n"
- " }\n"
- "}\n";
+ char const* sourceCode = R"(
+ contract test {
+ function run(bool x1, uint x2) returns(uint y1, bool y2, uint y3) {
+ y1 = x2; y2 = x1;
+ }
+ }
+ )";
compileAndRun(sourceCode);
BOOST_CHECK(callContractFunction("run(bool,uint256)", true, 0xcd) == encodeArgs(0xcd, true, 0));
}
BOOST_AUTO_TEST_CASE(short_circuiting)
{
- char const* sourceCode = "contract test {\n"
- " function run(uint x) returns(uint y) {\n"
- " x == 0 || ((x = 8) > 0);\n"
- " return x;"
- " }\n"
- "}\n";
+ char const* sourceCode = R"(
+ contract test {
+ function run(uint x) returns(uint y) {
+ x == 0 || ((x = 8) > 0);
+ return x;
+ }
+ }
+ )";
compileAndRun(sourceCode);
auto short_circuiting_cpp = [](u256 n) -> u256
@@ -673,19 +715,21 @@ BOOST_AUTO_TEST_CASE(short_circuiting)
return n;
};
- testSolidityAgainstCppOnRange("run(uint256)", short_circuiting_cpp, 0, 2);
+ testContractAgainstCppOnRange("run(uint256)", short_circuiting_cpp, 0, 2);
}
BOOST_AUTO_TEST_CASE(high_bits_cleaning)
{
- char const* sourceCode = "contract test {\n"
- " function run() returns(uint256 y) {\n"
- " uint32 t = uint32(0xffffffff);\n"
- " uint32 x = t + 10;\n"
- " if (x >= 0xffffffff) return 0;\n"
- " return x;"
- " }\n"
- "}\n";
+ char const* sourceCode = R"(
+ contract test {
+ function run() returns(uint256 y) {
+ uint32 t = uint32(0xffffffff);
+ uint32 x = t + 10;
+ if (x >= 0xffffffff) return 0;
+ return x;
+ }
+ }
+ )";
compileAndRun(sourceCode);
auto high_bits_cleaning_cpp = []() -> u256
{
@@ -695,18 +739,20 @@ BOOST_AUTO_TEST_CASE(high_bits_cleaning)
return 0;
return x;
};
- testSolidityAgainstCpp("run()", high_bits_cleaning_cpp);
+ testContractAgainstCpp("run()", high_bits_cleaning_cpp);
}
BOOST_AUTO_TEST_CASE(sign_extension)
{
- char const* sourceCode = "contract test {\n"
- " function run() returns(uint256 y) {\n"
- " int64 x = -int32(0xff);\n"
- " if (x >= 0xff) return 0;\n"
- " return -uint256(x);"
- " }\n"
- "}\n";
+ char const* sourceCode = R"(
+ contract test {
+ function run() returns(uint256 y) {
+ int64 x = -int32(0xff);
+ if (x >= 0xff) return 0;
+ return -uint256(x);
+ }
+ }
+ )";
compileAndRun(sourceCode);
auto sign_extension_cpp = []() -> u256
{
@@ -715,18 +761,20 @@ BOOST_AUTO_TEST_CASE(sign_extension)
return 0;
return u256(x) * -1;
};
- testSolidityAgainstCpp("run()", sign_extension_cpp);
+ testContractAgainstCpp("run()", sign_extension_cpp);
}
BOOST_AUTO_TEST_CASE(small_unsigned_types)
{
- char const* sourceCode = "contract test {\n"
- " function run() returns(uint256 y) {\n"
- " uint32 t = uint32(0xffffff);\n"
- " uint32 x = t * 0xffffff;\n"
- " return x / 0x100;"
- " }\n"
- "}\n";
+ char const* sourceCode = R"(
+ contract test {
+ function run() returns(uint256 y) {
+ uint32 t = uint32(0xffffff);
+ uint32 x = t * 0xffffff;
+ return x / 0x100;
+ }
+ }
+ )";
compileAndRun(sourceCode);
auto small_unsigned_types_cpp = []() -> u256
{
@@ -734,35 +782,39 @@ BOOST_AUTO_TEST_CASE(small_unsigned_types)
uint32_t x = t * 0xffffff;
return x / 0x100;
};
- testSolidityAgainstCpp("run()", small_unsigned_types_cpp);
+ testContractAgainstCpp("run()", small_unsigned_types_cpp);
}
BOOST_AUTO_TEST_CASE(small_signed_types)
{
- char const* sourceCode = "contract test {\n"
- " function run() returns(int256 y) {\n"
- " return -int32(10) * -int64(20);\n"
- " }\n"
- "}\n";
+ char const* sourceCode = R"(
+ contract test {
+ function run() returns(int256 y) {
+ return -int32(10) * -int64(20);
+ }
+ }
+ )";
compileAndRun(sourceCode);
auto small_signed_types_cpp = []() -> u256
{
return -int32_t(10) * -int64_t(20);
};
- testSolidityAgainstCpp("run()", small_signed_types_cpp);
+ testContractAgainstCpp("run()", small_signed_types_cpp);
}
BOOST_AUTO_TEST_CASE(strings)
{
- char const* sourceCode = "contract test {\n"
- " function fixedBytes() returns(bytes32 ret) {\n"
- " return \"abc\\x00\\xff__\";\n"
- " }\n"
- " function pipeThrough(bytes2 small, bool one) returns(bytes16 large, bool oneRet) {\n"
- " oneRet = one;\n"
- " large = small;\n"
- " }\n"
- "}\n";
+ char const* sourceCode = R"(
+ contract test {
+ function fixedBytes() returns(bytes32 ret) {
+ return "abc\x00\xff__";
+ }
+ function pipeThrough(bytes2 small, bool one) returns(bytes16 large, bool oneRet) {
+ oneRet = one;
+ large = small;
+ }
+ }
+ )";
compileAndRun(sourceCode);
BOOST_CHECK(callContractFunction("fixedBytes()") == encodeArgs(string("abc\0\xff__", 7)));
BOOST_CHECK(callContractFunction("pipeThrough(bytes2,bool)", string("\0\x02", 2), true) == encodeArgs(string("\0\x2", 2), true));
@@ -807,18 +859,20 @@ BOOST_AUTO_TEST_CASE(bytes_comparison)
BOOST_AUTO_TEST_CASE(state_smoke_test)
{
- char const* sourceCode = "contract test {\n"
- " uint256 value1;\n"
- " uint256 value2;\n"
- " function get(uint8 which) returns (uint256 value) {\n"
- " if (which == 0) return value1;\n"
- " else return value2;\n"
- " }\n"
- " function set(uint8 which, uint256 value) {\n"
- " if (which == 0) value1 = value;\n"
- " else value2 = value;\n"
- " }\n"
- "}\n";
+ char const* sourceCode = R"(
+ contract test {
+ uint256 value1;
+ uint256 value2;
+ function get(uint8 which) returns (uint256 value) {
+ if (which == 0) return value1;
+ else return value2;
+ }
+ function set(uint8 which, uint256 value) {
+ if (which == 0) value1 = value;
+ else value2 = value;
+ }
+ }
+ )";
compileAndRun(sourceCode);
BOOST_CHECK(callContractFunction("get(uint8)", byte(0x00)) == encodeArgs(0));
BOOST_CHECK(callContractFunction("get(uint8)", byte(0x01)) == encodeArgs(0));
@@ -832,17 +886,19 @@ BOOST_AUTO_TEST_CASE(state_smoke_test)
BOOST_AUTO_TEST_CASE(compound_assign)
{
- char const* sourceCode = "contract test {\n"
- " uint value1;\n"
- " uint value2;\n"
- " function f(uint x, uint y) returns (uint w) {\n"
- " uint value3 = y;"
- " value1 += x;\n"
- " value3 *= x;"
- " value2 *= value3 + value1;\n"
- " return value2 += 7;"
- " }\n"
- "}\n";
+ char const* sourceCode = R"(
+ contract test {
+ uint value1;
+ uint value2;
+ function f(uint x, uint y) returns (uint w) {
+ uint value3 = y;
+ value1 += x;
+ value3 *= x;
+ value2 *= value3 + value1;
+ return value2 += 7;
+ }
+ }
+ )";
compileAndRun(sourceCode);
u256 value1;
@@ -855,27 +911,29 @@ BOOST_AUTO_TEST_CASE(compound_assign)
value2 *= value3 + value1;
return value2 += 7;
};
- testSolidityAgainstCpp("f(uint256,uint256)", f, u256(0), u256(6));
- testSolidityAgainstCpp("f(uint256,uint256)", f, u256(1), u256(3));
- testSolidityAgainstCpp("f(uint256,uint256)", f, u256(2), u256(25));
- testSolidityAgainstCpp("f(uint256,uint256)", f, u256(3), u256(69));
- testSolidityAgainstCpp("f(uint256,uint256)", f, u256(4), u256(84));
- testSolidityAgainstCpp("f(uint256,uint256)", f, u256(5), u256(2));
- testSolidityAgainstCpp("f(uint256,uint256)", f, u256(6), u256(51));
- testSolidityAgainstCpp("f(uint256,uint256)", f, u256(7), u256(48));
+ testContractAgainstCpp("f(uint256,uint256)", f, u256(0), u256(6));
+ testContractAgainstCpp("f(uint256,uint256)", f, u256(1), u256(3));
+ testContractAgainstCpp("f(uint256,uint256)", f, u256(2), u256(25));
+ testContractAgainstCpp("f(uint256,uint256)", f, u256(3), u256(69));
+ testContractAgainstCpp("f(uint256,uint256)", f, u256(4), u256(84));
+ testContractAgainstCpp("f(uint256,uint256)", f, u256(5), u256(2));
+ testContractAgainstCpp("f(uint256,uint256)", f, u256(6), u256(51));
+ testContractAgainstCpp("f(uint256,uint256)", f, u256(7), u256(48));
}
BOOST_AUTO_TEST_CASE(simple_mapping)
{
- char const* sourceCode = "contract test {\n"
- " mapping(uint8 => uint8) table;\n"
- " function get(uint8 k) returns (uint8 v) {\n"
- " return table[k];\n"
- " }\n"
- " function set(uint8 k, uint8 v) {\n"
- " table[k] = v;\n"
- " }\n"
- "}";
+ char const* sourceCode = R"(
+ contract test {
+ mapping(uint8 => uint8) table;
+ function get(uint8 k) returns (uint8 v) {
+ return table[k];
+ }
+ function set(uint8 k, uint8 v) {
+ table[k] = v;
+ }
+ }
+ )";
compileAndRun(sourceCode);
BOOST_CHECK(callContractFunction("get(uint8)", byte(0)) == encodeArgs(byte(0x00)));
@@ -897,23 +955,25 @@ BOOST_AUTO_TEST_CASE(simple_mapping)
BOOST_AUTO_TEST_CASE(mapping_state)
{
- char const* sourceCode = "contract Ballot {\n"
- " mapping(address => bool) canVote;\n"
- " mapping(address => uint) voteCount;\n"
- " mapping(address => bool) voted;\n"
- " function getVoteCount(address addr) returns (uint retVoteCount) {\n"
- " return voteCount[addr];\n"
- " }\n"
- " function grantVoteRight(address addr) {\n"
- " canVote[addr] = true;\n"
- " }\n"
- " function vote(address voter, address vote) returns (bool success) {\n"
- " if (!canVote[voter] || voted[voter]) return false;\n"
- " voted[voter] = true;\n"
- " voteCount[vote] = voteCount[vote] + 1;\n"
- " return true;\n"
- " }\n"
- "}\n";
+ char const* sourceCode = R"(
+ contract Ballot {
+ mapping(address => bool) canVote;
+ mapping(address => uint) voteCount;
+ mapping(address => bool) voted;
+ function getVoteCount(address addr) returns (uint retVoteCount) {
+ return voteCount[addr];
+ }
+ function grantVoteRight(address addr) {
+ canVote[addr] = true;
+ }
+ function vote(address voter, address vote) returns (bool success) {
+ if (!canVote[voter] || voted[voter]) return false;
+ voted[voter] = true;
+ voteCount[vote] = voteCount[vote] + 1;
+ return true;
+ }
+ }
+ )";
compileAndRun(sourceCode);
class Ballot
{
@@ -936,53 +996,55 @@ BOOST_AUTO_TEST_CASE(mapping_state)
auto getVoteCount = bind(&Ballot::getVoteCount, &ballot, _1);
auto grantVoteRight = bind(&Ballot::grantVoteRight, &ballot, _1);
auto vote = bind(&Ballot::vote, &ballot, _1, _2);
- testSolidityAgainstCpp("getVoteCount(address)", getVoteCount, u160(0));
- testSolidityAgainstCpp("getVoteCount(address)", getVoteCount, u160(1));
- testSolidityAgainstCpp("getVoteCount(address)", getVoteCount, u160(2));
+ testContractAgainstCpp("getVoteCount(address)", getVoteCount, u160(0));
+ testContractAgainstCpp("getVoteCount(address)", getVoteCount, u160(1));
+ testContractAgainstCpp("getVoteCount(address)", getVoteCount, u160(2));
// voting without vote right should be rejected
- testSolidityAgainstCpp("vote(address,address)", vote, u160(0), u160(2));
- testSolidityAgainstCpp("getVoteCount(address)", getVoteCount, u160(0));
- testSolidityAgainstCpp("getVoteCount(address)", getVoteCount, u160(1));
- testSolidityAgainstCpp("getVoteCount(address)", getVoteCount, u160(2));
+ testContractAgainstCpp("vote(address,address)", vote, u160(0), u160(2));
+ testContractAgainstCpp("getVoteCount(address)", getVoteCount, u160(0));
+ testContractAgainstCpp("getVoteCount(address)", getVoteCount, u160(1));
+ testContractAgainstCpp("getVoteCount(address)", getVoteCount, u160(2));
// grant vote rights
- testSolidityAgainstCpp("grantVoteRight(address)", grantVoteRight, u160(0));
- testSolidityAgainstCpp("grantVoteRight(address)", grantVoteRight, u160(1));
+ testContractAgainstCpp("grantVoteRight(address)", grantVoteRight, u160(0));
+ testContractAgainstCpp("grantVoteRight(address)", grantVoteRight, u160(1));
// vote, should increase 2's vote count
- testSolidityAgainstCpp("vote(address,address)", vote, u160(0), u160(2));
- testSolidityAgainstCpp("getVoteCount(address)", getVoteCount, u160(0));
- testSolidityAgainstCpp("getVoteCount(address)", getVoteCount, u160(1));
- testSolidityAgainstCpp("getVoteCount(address)", getVoteCount, u160(2));
+ testContractAgainstCpp("vote(address,address)", vote, u160(0), u160(2));
+ testContractAgainstCpp("getVoteCount(address)", getVoteCount, u160(0));
+ testContractAgainstCpp("getVoteCount(address)", getVoteCount, u160(1));
+ testContractAgainstCpp("getVoteCount(address)", getVoteCount, u160(2));
// vote again, should be rejected
- testSolidityAgainstCpp("vote(address,address)", vote, u160(0), u160(1));
- testSolidityAgainstCpp("getVoteCount(address)", getVoteCount, u160(0));
- testSolidityAgainstCpp("getVoteCount(address)", getVoteCount, u160(1));
- testSolidityAgainstCpp("getVoteCount(address)", getVoteCount, u160(2));
+ testContractAgainstCpp("vote(address,address)", vote, u160(0), u160(1));
+ testContractAgainstCpp("getVoteCount(address)", getVoteCount, u160(0));
+ testContractAgainstCpp("getVoteCount(address)", getVoteCount, u160(1));
+ testContractAgainstCpp("getVoteCount(address)", getVoteCount, u160(2));
// vote without right to vote
- testSolidityAgainstCpp("vote(address,address)", vote, u160(2), u160(1));
- testSolidityAgainstCpp("getVoteCount(address)", getVoteCount, u160(0));
- testSolidityAgainstCpp("getVoteCount(address)", getVoteCount, u160(1));
- testSolidityAgainstCpp("getVoteCount(address)", getVoteCount, u160(2));
+ testContractAgainstCpp("vote(address,address)", vote, u160(2), u160(1));
+ testContractAgainstCpp("getVoteCount(address)", getVoteCount, u160(0));
+ testContractAgainstCpp("getVoteCount(address)", getVoteCount, u160(1));
+ testContractAgainstCpp("getVoteCount(address)", getVoteCount, u160(2));
// grant vote right and now vote again
- testSolidityAgainstCpp("grantVoteRight(address)", grantVoteRight, u160(2));
- testSolidityAgainstCpp("vote(address,address)", vote, u160(2), u160(1));
- testSolidityAgainstCpp("getVoteCount(address)", getVoteCount, u160(0));
- testSolidityAgainstCpp("getVoteCount(address)", getVoteCount, u160(1));
- testSolidityAgainstCpp("getVoteCount(address)", getVoteCount, u160(2));
+ testContractAgainstCpp("grantVoteRight(address)", grantVoteRight, u160(2));
+ testContractAgainstCpp("vote(address,address)", vote, u160(2), u160(1));
+ testContractAgainstCpp("getVoteCount(address)", getVoteCount, u160(0));
+ testContractAgainstCpp("getVoteCount(address)", getVoteCount, u160(1));
+ testContractAgainstCpp("getVoteCount(address)", getVoteCount, u160(2));
}
BOOST_AUTO_TEST_CASE(mapping_state_inc_dec)
{
- char const* sourceCode = "contract test {\n"
- " uint value;\n"
- " mapping(uint => uint) table;\n"
- " function f(uint x) returns (uint y) {\n"
- " value = x;\n"
- " if (x > 0) table[++value] = 8;\n"
- " if (x > 1) value--;\n"
- " if (x > 2) table[value]++;\n"
- " return --table[value++];\n"
- " }\n"
- "}\n";
+ char const* sourceCode = R"(
+ contract test {
+ uint value;
+ mapping(uint => uint) table;
+ function f(uint x) returns (uint y) {
+ value = x;
+ if (x > 0) table[++value] = 8;
+ if (x > 1) value--;
+ if (x > 2) table[value]++;
+ return --table[value++];
+ }
+ }
+ )";
compileAndRun(sourceCode);
u256 value = 0;
@@ -998,18 +1060,20 @@ BOOST_AUTO_TEST_CASE(mapping_state_inc_dec)
table[value]++;
return --table[value++];
};
- testSolidityAgainstCppOnRange("f(uint256)", f, 0, 5);
+ testContractAgainstCppOnRange("f(uint256)", f, 0, 5);
}
BOOST_AUTO_TEST_CASE(multi_level_mapping)
{
- char const* sourceCode = "contract test {\n"
- " mapping(uint => mapping(uint => uint)) table;\n"
- " function f(uint x, uint y, uint z) returns (uint w) {\n"
- " if (z == 0) return table[x][y];\n"
- " else return table[x][y] = z;\n"
- " }\n"
- "}\n";
+ char const* sourceCode = R"(
+ contract test {
+ mapping(uint => mapping(uint => uint)) table;
+ function f(uint x, uint y, uint z) returns (uint w) {
+ if (z == 0) return table[x][y];
+ else return table[x][y] = z;
+ }
+ }
+ )";
compileAndRun(sourceCode);
map<u256, map<u256, u256>> table;
@@ -1018,47 +1082,49 @@ BOOST_AUTO_TEST_CASE(multi_level_mapping)
if (_z == 0) return table[_x][_y];
else return table[_x][_y] = _z;
};
- testSolidityAgainstCpp("f(uint256,uint256,uint256)", f, u256(4), u256(5), u256(0));
- testSolidityAgainstCpp("f(uint256,uint256,uint256)", f, u256(5), u256(4), u256(0));
- testSolidityAgainstCpp("f(uint256,uint256,uint256)", f, u256(4), u256(5), u256(9));
- testSolidityAgainstCpp("f(uint256,uint256,uint256)", f, u256(4), u256(5), u256(0));
- testSolidityAgainstCpp("f(uint256,uint256,uint256)", f, u256(5), u256(4), u256(0));
- testSolidityAgainstCpp("f(uint256,uint256,uint256)", f, u256(5), u256(4), u256(7));
- testSolidityAgainstCpp("f(uint256,uint256,uint256)", f, u256(4), u256(5), u256(0));
- testSolidityAgainstCpp("f(uint256,uint256,uint256)", f, u256(5), u256(4), u256(0));
+ testContractAgainstCpp("f(uint256,uint256,uint256)", f, u256(4), u256(5), u256(0));
+ testContractAgainstCpp("f(uint256,uint256,uint256)", f, u256(5), u256(4), u256(0));
+ testContractAgainstCpp("f(uint256,uint256,uint256)", f, u256(4), u256(5), u256(9));
+ testContractAgainstCpp("f(uint256,uint256,uint256)", f, u256(4), u256(5), u256(0));
+ testContractAgainstCpp("f(uint256,uint256,uint256)", f, u256(5), u256(4), u256(0));
+ testContractAgainstCpp("f(uint256,uint256,uint256)", f, u256(5), u256(4), u256(7));
+ testContractAgainstCpp("f(uint256,uint256,uint256)", f, u256(4), u256(5), u256(0));
+ testContractAgainstCpp("f(uint256,uint256,uint256)", f, u256(5), u256(4), u256(0));
}
BOOST_AUTO_TEST_CASE(structs)
{
- char const* sourceCode = "contract test {\n"
- " struct s1 {\n"
- " uint8 x;\n"
- " bool y;\n"
- " }\n"
- " struct s2 {\n"
- " uint32 z;\n"
- " s1 s1data;\n"
- " mapping(uint8 => s2) recursive;\n"
- " }\n"
- " s2 data;\n"
- " function check() returns (bool ok) {\n"
- " return data.z == 1 && data.s1data.x == 2 && \n"
- " data.s1data.y == true && \n"
- " data.recursive[3].recursive[4].z == 5 && \n"
- " data.recursive[4].recursive[3].z == 6 && \n"
- " data.recursive[0].s1data.y == false && \n"
- " data.recursive[4].z == 9;\n"
- " }\n"
- " function set() {\n"
- " data.z = 1;\n"
- " data.s1data.x = 2;\n"
- " data.s1data.y = true;\n"
- " data.recursive[3].recursive[4].z = 5;\n"
- " data.recursive[4].recursive[3].z = 6;\n"
- " data.recursive[0].s1data.y = false;\n"
- " data.recursive[4].z = 9;\n"
- " }\n"
- "}\n";
+ char const* sourceCode = R"(
+ contract test {
+ struct s1 {
+ uint8 x;
+ bool y;
+ }
+ struct s2 {
+ uint32 z;
+ s1 s1data;
+ mapping(uint8 => s2) recursive;
+ }
+ s2 data;
+ function check() returns (bool ok) {
+ return data.z == 1 && data.s1data.x == 2 &&
+ data.s1data.y == true &&
+ data.recursive[3].recursive[4].z == 5 &&
+ data.recursive[4].recursive[3].z == 6 &&
+ data.recursive[0].s1data.y == false &&
+ data.recursive[4].z == 9;
+ }
+ function set() {
+ data.z = 1;
+ data.s1data.x = 2;
+ data.s1data.y = true;
+ data.recursive[3].recursive[4].z = 5;
+ data.recursive[4].recursive[3].z = 6;
+ data.recursive[0].s1data.y = false;
+ data.recursive[4].z = 9;
+ }
+ }
+ )";
compileAndRun(sourceCode);
BOOST_CHECK(callContractFunction("check()") == encodeArgs(false));
BOOST_CHECK(callContractFunction("set()") == bytes());
@@ -1067,26 +1133,28 @@ BOOST_AUTO_TEST_CASE(structs)
BOOST_AUTO_TEST_CASE(struct_reference)
{
- char const* sourceCode = "contract test {\n"
- " struct s2 {\n"
- " uint32 z;\n"
- " mapping(uint8 => s2) recursive;\n"
- " }\n"
- " s2 data;\n"
- " function check() returns (bool ok) {\n"
- " return data.z == 2 && \n"
- " data.recursive[0].z == 3 && \n"
- " data.recursive[0].recursive[1].z == 0 && \n"
- " data.recursive[0].recursive[0].z == 1;\n"
- " }\n"
- " function set() {\n"
- " data.z = 2;\n"
- " var map = data.recursive;\n"
- " s2 inner = map[0];\n"
- " inner.z = 3;\n"
- " inner.recursive[0].z = inner.recursive[1].z + 1;\n"
- " }\n"
- "}\n";
+ char const* sourceCode = R"(
+ contract test {
+ struct s2 {
+ uint32 z;
+ mapping(uint8 => s2) recursive;
+ }
+ s2 data;
+ function check() returns (bool ok) {
+ return data.z == 2 &&
+ data.recursive[0].z == 3 &&
+ data.recursive[0].recursive[1].z == 0 &&
+ data.recursive[0].recursive[0].z == 1;
+ }
+ function set() {
+ data.z = 2;
+ var map = data.recursive;
+ s2 inner = map[0];
+ inner.z = 3;
+ inner.recursive[0].z = inner.recursive[1].z + 1;
+ }
+ }
+ )";
compileAndRun(sourceCode);
BOOST_CHECK(callContractFunction("check()") == encodeArgs(false));
BOOST_CHECK(callContractFunction("set()") == bytes());
@@ -1133,12 +1201,13 @@ BOOST_AUTO_TEST_CASE(deleteStruct)
nestedValue = str.nstr.nestedValue;
}
function getTopMapping(uint index) returns(uint ret) {
- ret = str.topMapping[index];
+ ret = str.topMapping[index];
}
function getNestedMapping(uint index) returns(bool ret) {
return str.nstr.nestedMapping[index];
}
- })";
+ }
+ )";
compileAndRun(sourceCode);
BOOST_CHECK(callContractFunction("getToDelete()") == encodeArgs(0));
BOOST_CHECK(callContractFunction("getTopValue()") == encodeArgs(0));
@@ -1159,7 +1228,8 @@ BOOST_AUTO_TEST_CASE(deleteLocal)
delete v;
res = v;
}
- })";
+ }
+ )";
compileAndRun(sourceCode);
BOOST_CHECK(callContractFunction("delLocal()") == encodeArgs(0));
}
@@ -1176,22 +1246,25 @@ BOOST_AUTO_TEST_CASE(deleteLocals)
res1 = w;
res2 = x;
}
- })";
+ }
+ )";
compileAndRun(sourceCode);
BOOST_CHECK(callContractFunction("delLocal()") == encodeArgs(6, 7));
}
BOOST_AUTO_TEST_CASE(constructor)
{
- char const* sourceCode = "contract test {\n"
- " mapping(uint => uint) data;\n"
- " function test() {\n"
- " data[7] = 8;\n"
- " }\n"
- " function get(uint key) returns (uint value) {\n"
- " return data[key];"
- " }\n"
- "}\n";
+ char const* sourceCode = R"(
+ contract test {
+ mapping(uint => uint) data;
+ function test() {
+ data[7] = 8;
+ }
+ function get(uint key) returns (uint value) {
+ return data[key];
+ }
+ }
+ )";
compileAndRun(sourceCode);
map<u256, byte> data;
data[7] = 8;
@@ -1199,18 +1272,20 @@ BOOST_AUTO_TEST_CASE(constructor)
{
return data[_x];
};
- testSolidityAgainstCpp("get(uint256)", get, u256(6));
- testSolidityAgainstCpp("get(uint256)", get, u256(7));
+ testContractAgainstCpp("get(uint256)", get, u256(6));
+ testContractAgainstCpp("get(uint256)", get, u256(7));
}
BOOST_AUTO_TEST_CASE(simple_accessor)
{
- char const* sourceCode = "contract test {\n"
- " uint256 public data;\n"
- " function test() {\n"
- " data = 8;\n"
- " }\n"
- "}\n";
+ char const* sourceCode = R"(
+ contract test {
+ uint256 public data;
+ function test() {
+ data = 8;
+ }
+ }
+ )";
compileAndRun(sourceCode);
BOOST_CHECK(callContractFunction("data()") == encodeArgs(8));
}
@@ -1252,7 +1327,7 @@ BOOST_AUTO_TEST_CASE(array_accessor)
BOOST_AUTO_TEST_CASE(accessors_mapping_for_array)
{
char const* sourceCode = R"(
- contract test {
+ contract test {
mapping(uint => uint[8]) public data;
mapping(uint => uint[]) public dynamicData;
function test() {
@@ -1260,7 +1335,7 @@ BOOST_AUTO_TEST_CASE(accessors_mapping_for_array)
dynamicData[2].length = 3;
dynamicData[2][2] = 8;
}
- }
+ }
)";
compileAndRun(sourceCode);
BOOST_CHECK(callContractFunction("data(uint256,uint256)", 2, 2) == encodeArgs(8));
@@ -1271,20 +1346,22 @@ BOOST_AUTO_TEST_CASE(accessors_mapping_for_array)
BOOST_AUTO_TEST_CASE(multiple_elementary_accessors)
{
- char const* sourceCode = "contract test {\n"
- " uint256 public data;\n"
- " bytes6 public name;\n"
- " bytes32 public a_hash;\n"
- " address public an_address;\n"
- " function test() {\n"
- " data = 8;\n"
- " name = \"Celina\";\n"
- " a_hash = sha3(123);\n"
- " an_address = address(0x1337);\n"
- " super_secret_data = 42;\n"
- " }\n"
- " uint256 super_secret_data;"
- "}\n";
+ char const* sourceCode = R"(
+ contract test {
+ uint256 public data;
+ bytes6 public name;
+ bytes32 public a_hash;
+ address public an_address;
+ function test() {
+ data = 8;
+ name = "Celina";
+ a_hash = sha3(123);
+ an_address = address(0x1337);
+ super_secret_data = 42;
+ }
+ uint256 super_secret_data;
+ }
+ )";
compileAndRun(sourceCode);
BOOST_CHECK(callContractFunction("data()") == encodeArgs(8));
BOOST_CHECK(callContractFunction("name()") == encodeArgs("Celina"));
@@ -1336,26 +1413,30 @@ BOOST_AUTO_TEST_CASE(struct_accessor)
BOOST_AUTO_TEST_CASE(balance)
{
- char const* sourceCode = "contract test {\n"
- " function test() payable {}\n"
- " function getBalance() returns (uint256 balance) {\n"
- " return address(this).balance;\n"
- " }\n"
- "}\n";
+ char const* sourceCode = R"(
+ contract test {
+ function test() payable {}
+ function getBalance() returns (uint256 balance) {
+ return address(this).balance;
+ }
+ }
+ )";
compileAndRun(sourceCode, 23);
BOOST_CHECK(callContractFunction("getBalance()") == encodeArgs(23));
}
BOOST_AUTO_TEST_CASE(blockchain)
{
- char const* sourceCode = "contract test {\n"
- " function test() payable {}\n"
- " function someInfo() payable returns (uint256 value, address coinbase, uint256 blockNumber) {\n"
- " value = msg.value;\n"
- " coinbase = block.coinbase;\n"
- " blockNumber = block.number;\n"
- " }\n"
- "}\n";
+ char const* sourceCode = R"(
+ contract test {
+ function test() payable {}
+ function someInfo() payable returns (uint256 value, address coinbase, uint256 blockNumber) {
+ value = msg.value;
+ coinbase = block.coinbase;
+ blockNumber = block.number;
+ }
+ }
+ )";
BOOST_CHECK(m_rpc.rpcCall("miner_setEtherbase", {"\"0x1212121212121212121212121212121212121212\""}).asBool() == true);
m_rpc.test_mineBlocks(5);
compileAndRun(sourceCode, 27);
@@ -1393,12 +1474,14 @@ BOOST_AUTO_TEST_CASE(msg_sig_after_internal_call_is_same)
BOOST_AUTO_TEST_CASE(now)
{
- char const* sourceCode = "contract test {\n"
- " function someInfo() returns (bool equal, uint val) {\n"
- " equal = block.timestamp == now;\n"
- " val = now;\n"
- " }\n"
- "}\n";
+ char const* sourceCode = R"(
+ contract test {
+ function someInfo() returns (bool equal, uint val) {
+ equal = block.timestamp == now;
+ val = now;
+ }
+ }
+ )";
m_rpc.test_modifyTimestamp(0x776347e2);
compileAndRun(sourceCode);
BOOST_CHECK(callContractFunction("someInfo()") == encodeArgs(true, 0x776347e3));
@@ -1411,7 +1494,8 @@ BOOST_AUTO_TEST_CASE(type_conversions_cleanup)
char const* sourceCode = R"(
contract Test {
function test() returns (uint ret) { return uint(address(Test(address(0x11223344556677889900112233445566778899001122)))); }
- })";
+ }
+ )";
compileAndRun(sourceCode);
BOOST_REQUIRE(callContractFunction("test()") == bytes({0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0x00, 0x11, 0x22,
@@ -1425,7 +1509,8 @@ BOOST_AUTO_TEST_CASE(convert_fixed_bytes_to_fixed_bytes_smaller_size)
function bytesToBytes(bytes4 input) returns (bytes2 ret) {
return bytes2(input);
}
- })";
+ }
+ )";
compileAndRun(sourceCode);
BOOST_CHECK(callContractFunction("bytesToBytes(bytes4)", "abcd") == encodeArgs("ab"));
}
@@ -1437,7 +1522,8 @@ BOOST_AUTO_TEST_CASE(convert_fixed_bytes_to_fixed_bytes_greater_size)
function bytesToBytes(bytes2 input) returns (bytes4 ret) {
return bytes4(input);
}
- })";
+ }
+ )";
compileAndRun(sourceCode);
BOOST_CHECK(callContractFunction("bytesToBytes(bytes2)", "ab") == encodeArgs("ab"));
}
@@ -1449,7 +1535,8 @@ BOOST_AUTO_TEST_CASE(convert_fixed_bytes_to_fixed_bytes_same_size)
function bytesToBytes(bytes4 input) returns (bytes4 ret) {
return bytes4(input);
}
- })";
+ }
+ )";
compileAndRun(sourceCode);
BOOST_CHECK(callContractFunction("bytesToBytes(bytes4)", "abcd") == encodeArgs("abcd"));
}
@@ -1462,7 +1549,8 @@ BOOST_AUTO_TEST_CASE(convert_fixed_bytes_to_uint_same_size)
function bytesToUint(bytes32 s) returns (uint256 h) {
return uint(s);
}
- })";
+ }
+ )";
compileAndRun(sourceCode);
BOOST_CHECK(callContractFunction("bytesToUint(bytes32)", string("abc2")) ==
encodeArgs(u256("0x6162633200000000000000000000000000000000000000000000000000000000")));
@@ -1475,7 +1563,8 @@ BOOST_AUTO_TEST_CASE(convert_fixed_bytes_to_uint_same_min_size)
function bytesToUint(bytes1 s) returns (uint8 h) {
return uint8(s);
}
- })";
+ }
+ )";
compileAndRun(sourceCode);
BOOST_CHECK(callContractFunction("bytesToUint(bytes1)", string("a")) ==
encodeArgs(u256("0x61")));
@@ -1488,7 +1577,8 @@ BOOST_AUTO_TEST_CASE(convert_fixed_bytes_to_uint_smaller_size)
function bytesToUint(bytes4 s) returns (uint16 h) {
return uint16(s);
}
- })";
+ }
+ )";
compileAndRun(sourceCode);
BOOST_CHECK(callContractFunction("bytesToUint(bytes4)", string("abcd")) ==
encodeArgs(u256("0x6364")));
@@ -1501,7 +1591,8 @@ BOOST_AUTO_TEST_CASE(convert_fixed_bytes_to_uint_greater_size)
function bytesToUint(bytes4 s) returns (uint64 h) {
return uint64(s);
}
- })";
+ }
+ )";
compileAndRun(sourceCode);
BOOST_CHECK(callContractFunction("bytesToUint(bytes4)", string("abcd")) ==
encodeArgs(u256("0x61626364")));
@@ -1515,7 +1606,8 @@ BOOST_AUTO_TEST_CASE(convert_uint_to_fixed_bytes_same_size)
function uintToBytes(uint256 h) returns (bytes32 s) {
return bytes32(h);
}
- })";
+ }
+ )";
compileAndRun(sourceCode);
u256 a("0x6162630000000000000000000000000000000000000000000000000000000000");
BOOST_CHECK(callContractFunction("uintToBytes(uint256)", a) == encodeArgs(a));
@@ -1528,7 +1620,8 @@ BOOST_AUTO_TEST_CASE(convert_uint_to_fixed_bytes_same_min_size)
function UintToBytes(uint8 h) returns (bytes1 s) {
return bytes1(h);
}
- })";
+ }
+ )";
compileAndRun(sourceCode);
BOOST_CHECK(callContractFunction("UintToBytes(uint8)", u256("0x61")) ==
encodeArgs(string("a")));
@@ -1541,7 +1634,8 @@ BOOST_AUTO_TEST_CASE(convert_uint_to_fixed_bytes_smaller_size)
function uintToBytes(uint32 h) returns (bytes2 s) {
return bytes2(h);
}
- })";
+ }
+ )";
compileAndRun(sourceCode);
BOOST_CHECK(callContractFunction("uintToBytes(uint32)",
u160("0x61626364")) == encodeArgs(string("cd")));
@@ -1554,7 +1648,8 @@ BOOST_AUTO_TEST_CASE(convert_uint_to_fixed_bytes_greater_size)
function UintToBytes(uint16 h) returns (bytes8 s) {
return bytes8(h);
}
- })";
+ }
+ )";
compileAndRun(sourceCode);
BOOST_CHECK(
callContractFunction("UintToBytes(uint16)", u256("0x6162")) ==
@@ -1564,13 +1659,15 @@ BOOST_AUTO_TEST_CASE(convert_uint_to_fixed_bytes_greater_size)
BOOST_AUTO_TEST_CASE(send_ether)
{
- char const* sourceCode = "contract test {\n"
- " function test() payable {}\n"
- " function a(address addr, uint amount) returns (uint ret) {\n"
- " addr.send(amount);\n"
- " return address(this).balance;\n"
- " }\n"
- "}\n";
+ char const* sourceCode = R"(
+ contract test {
+ function test() payable {}
+ function a(address addr, uint amount) returns (uint ret) {
+ addr.send(amount);
+ return address(this).balance;
+ }
+ }
+ )";
u256 amount(130);
compileAndRun(sourceCode, amount + 1);
u160 address(23);
@@ -1580,11 +1677,13 @@ BOOST_AUTO_TEST_CASE(send_ether)
BOOST_AUTO_TEST_CASE(log0)
{
- char const* sourceCode = "contract test {\n"
- " function a() {\n"
- " log0(1);\n"
- " }\n"
- "}\n";
+ char const* sourceCode = R"(
+ contract test {
+ function a() {
+ log0(1);
+ }
+ }
+ )";
compileAndRun(sourceCode);
callContractFunction("a()");
BOOST_REQUIRE_EQUAL(m_logs.size(), 1);
@@ -1595,11 +1694,13 @@ BOOST_AUTO_TEST_CASE(log0)
BOOST_AUTO_TEST_CASE(log1)
{
- char const* sourceCode = "contract test {\n"
- " function a() {\n"
- " log1(1, 2);\n"
- " }\n"
- "}\n";
+ char const* sourceCode = R"(
+ contract test {
+ function a() {
+ log1(1, 2);
+ }
+ }
+ )";
compileAndRun(sourceCode);
callContractFunction("a()");
BOOST_REQUIRE_EQUAL(m_logs.size(), 1);
@@ -1611,11 +1712,13 @@ BOOST_AUTO_TEST_CASE(log1)
BOOST_AUTO_TEST_CASE(log2)
{
- char const* sourceCode = "contract test {\n"
- " function a() {\n"
- " log2(1, 2, 3);\n"
- " }\n"
- "}\n";
+ char const* sourceCode = R"(
+ contract test {
+ function a() {
+ log2(1, 2, 3);
+ }
+ }
+ )";
compileAndRun(sourceCode);
callContractFunction("a()");
BOOST_REQUIRE_EQUAL(m_logs.size(), 1);
@@ -1628,11 +1731,13 @@ BOOST_AUTO_TEST_CASE(log2)
BOOST_AUTO_TEST_CASE(log3)
{
- char const* sourceCode = "contract test {\n"
- " function a() {\n"
- " log3(1, 2, 3, 4);\n"
- " }\n"
- "}\n";
+ char const* sourceCode = R"(
+ contract test {
+ function a() {
+ log3(1, 2, 3, 4);
+ }
+ }
+ )";
compileAndRun(sourceCode);
callContractFunction("a()");
BOOST_REQUIRE_EQUAL(m_logs.size(), 1);
@@ -1645,11 +1750,13 @@ BOOST_AUTO_TEST_CASE(log3)
BOOST_AUTO_TEST_CASE(log4)
{
- char const* sourceCode = "contract test {\n"
- " function a() {\n"
- " log4(1, 2, 3, 4, 5);\n"
- " }\n"
- "}\n";
+ char const* sourceCode = R"(
+ contract test {
+ function a() {
+ log4(1, 2, 3, 4, 5);
+ }
+ }
+ )";
compileAndRun(sourceCode);
callContractFunction("a()");
BOOST_REQUIRE_EQUAL(m_logs.size(), 1);
@@ -1662,11 +1769,13 @@ BOOST_AUTO_TEST_CASE(log4)
BOOST_AUTO_TEST_CASE(log_in_constructor)
{
- char const* sourceCode = "contract test {\n"
- " function test() {\n"
- " log1(1, 2);\n"
- " }\n"
- "}\n";
+ char const* sourceCode = R"(
+ contract test {
+ function test() {
+ log1(1, 2);
+ }
+ }
+ )";
compileAndRun(sourceCode);
BOOST_REQUIRE_EQUAL(m_logs.size(), 1);
BOOST_CHECK_EQUAL(m_logs[0].address, m_contractAddress);
@@ -1677,13 +1786,15 @@ BOOST_AUTO_TEST_CASE(log_in_constructor)
BOOST_AUTO_TEST_CASE(suicide)
{
- char const* sourceCode = "contract test {\n"
- " function test() payable {}\n"
- " function a(address receiver) returns (uint ret) {\n"
- " suicide(receiver);\n"
- " return 10;\n"
- " }\n"
- "}\n";
+ char const* sourceCode = R"(
+ contract test {
+ function test() payable {}
+ function a(address receiver) returns (uint ret) {
+ suicide(receiver);
+ return 10;
+ }
+ }
+ )";
u256 amount(130);
compileAndRun(sourceCode, amount);
u160 address(23);
@@ -1694,13 +1805,15 @@ BOOST_AUTO_TEST_CASE(suicide)
BOOST_AUTO_TEST_CASE(selfdestruct)
{
- char const* sourceCode = "contract test {\n"
- " function test() payable {}\n"
- " function a(address receiver) returns (uint ret) {\n"
- " selfdestruct(receiver);\n"
- " return 10;\n"
- " }\n"
- "}\n";
+ char const* sourceCode = R"(
+ contract test {
+ function test() payable {}
+ function a(address receiver) returns (uint ret) {
+ selfdestruct(receiver);
+ return 10;
+ }
+ }
+ )";
u256 amount(130);
compileAndRun(sourceCode, amount);
u160 address(23);
@@ -1711,28 +1824,32 @@ BOOST_AUTO_TEST_CASE(selfdestruct)
BOOST_AUTO_TEST_CASE(sha3)
{
- char const* sourceCode = "contract test {\n"
- " function a(bytes32 input) returns (bytes32 sha3hash) {\n"
- " return sha3(input);\n"
- " }\n"
- "}\n";
+ char const* sourceCode = R"(
+ contract test {
+ function a(bytes32 input) returns (bytes32 sha3hash) {
+ return sha3(input);
+ }
+ }
+ )";
compileAndRun(sourceCode);
auto f = [&](u256 const& _x) -> u256
{
return dev::keccak256(toBigEndian(_x));
};
- testSolidityAgainstCpp("a(bytes32)", f, u256(4));
- testSolidityAgainstCpp("a(bytes32)", f, u256(5));
- testSolidityAgainstCpp("a(bytes32)", f, u256(-1));
+ testContractAgainstCpp("a(bytes32)", f, u256(4));
+ testContractAgainstCpp("a(bytes32)", f, u256(5));
+ testContractAgainstCpp("a(bytes32)", f, u256(-1));
}
BOOST_AUTO_TEST_CASE(sha256)
{
- char const* sourceCode = "contract test {\n"
- " function a(bytes32 input) returns (bytes32 sha256hash) {\n"
- " return sha256(input);\n"
- " }\n"
- "}\n";
+ char const* sourceCode = R"(
+ contract test {
+ function a(bytes32 input) returns (bytes32 sha256hash) {
+ return sha256(input);
+ }
+ }
+ )";
compileAndRun(sourceCode);
auto f = [&](u256 const& _x) -> bytes
{
@@ -1744,18 +1861,20 @@ BOOST_AUTO_TEST_CASE(sha256)
return fromHex("af9613760f72635fbdb44a5a0a63c39f12af30f950a6ee5c971be188e89c4051");
return fromHex("");
};
- testSolidityAgainstCpp("a(bytes32)", f, u256(4));
- testSolidityAgainstCpp("a(bytes32)", f, u256(5));
- testSolidityAgainstCpp("a(bytes32)", f, u256(-1));
+ testContractAgainstCpp("a(bytes32)", f, u256(4));
+ testContractAgainstCpp("a(bytes32)", f, u256(5));
+ testContractAgainstCpp("a(bytes32)", f, u256(-1));
}
BOOST_AUTO_TEST_CASE(ripemd)
{
- char const* sourceCode = "contract test {\n"
- " function a(bytes32 input) returns (bytes32 sha256hash) {\n"
- " return ripemd160(input);\n"
- " }\n"
- "}\n";
+ char const* sourceCode = R"(
+ contract test {
+ function a(bytes32 input) returns (bytes32 sha256hash) {
+ return ripemd160(input);
+ }
+ }
+ )";
compileAndRun(sourceCode);
auto f = [&](u256 const& _x) -> bytes
{
@@ -1767,18 +1886,20 @@ BOOST_AUTO_TEST_CASE(ripemd)
return fromHex("1cf4e77f5966e13e109703cd8a0df7ceda7f3dc3000000000000000000000000");
return fromHex("");
};
- testSolidityAgainstCpp("a(bytes32)", f, u256(4));
- testSolidityAgainstCpp("a(bytes32)", f, u256(5));
- testSolidityAgainstCpp("a(bytes32)", f, u256(-1));
+ 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 = "contract test {\n"
- " function a(bytes32 h, uint8 v, bytes32 r, bytes32 s) returns (address addr) {\n"
- " return ecrecover(h, v, r, s);\n"
- " }\n"
- "}\n";
+ char const* sourceCode = R"(
+ contract test {
+ function a(bytes32 h, uint8 v, bytes32 r, bytes32 s) returns (address addr) {
+ return ecrecover(h, v, r, s);
+ }
+ }
+ )";
compileAndRun(sourceCode);
u256 h("0x18c547e4f7b0f325ad1e56f57e26c745b09a3e503d86e00e5255ff7f715d3d1c");
byte v = 28;
@@ -2796,7 +2917,8 @@ BOOST_AUTO_TEST_CASE(empty_name_input_parameter_with_named_one)
ret_k = k;
ret_g = g;
}
- })";
+ }
+ )";
compileAndRun(sourceCode);
BOOST_CHECK(callContractFunction("f(uint256,uint256)", 5, 9) != encodeArgs(5, 8));
BOOST_CHECK(callContractFunction("f(uint256,uint256)", 5, 9) == encodeArgs(9, 8));
@@ -2809,7 +2931,8 @@ BOOST_AUTO_TEST_CASE(empty_name_return_parameter)
function f(uint k) returns(uint){
return k;
}
- })";
+ }
+ )";
compileAndRun(sourceCode);
BOOST_CHECK(callContractFunction("f(uint256)", 9) == encodeArgs(9));
}
@@ -2822,7 +2945,8 @@ BOOST_AUTO_TEST_CASE(sha3_multiple_arguments)
{
d = sha3(a, b, c);
}
- })";
+ }
+ )";
compileAndRun(sourceCode);
BOOST_CHECK(callContractFunction("foo(uint256,uint256,uint256)", 10, 12, 13) == encodeArgs(
@@ -2840,7 +2964,8 @@ BOOST_AUTO_TEST_CASE(sha3_multiple_arguments_with_numeric_literals)
{
d = sha3(a, b, 145);
}
- })";
+ }
+ )";
compileAndRun(sourceCode);
BOOST_CHECK(callContractFunction("foo(uint256,uint16)", 10, 12) == encodeArgs(
@@ -2862,7 +2987,8 @@ BOOST_AUTO_TEST_CASE(sha3_multiple_arguments_with_string_literals)
{
d = sha3(a, b, 145, "foo");
}
- })";
+ }
+ )";
compileAndRun(sourceCode);
BOOST_CHECK(callContractFunction("foo()") == encodeArgs(dev::keccak256("foo")));
@@ -2888,7 +3014,8 @@ BOOST_AUTO_TEST_CASE(sha3_with_bytes)
data[2] = "o";
return sha3(data) == sha3("foo");
}
- })";
+ }
+ )";
compileAndRun(sourceCode);
BOOST_CHECK(callContractFunction("foo()") == encodeArgs(true));
}
@@ -4464,6 +4591,34 @@ BOOST_AUTO_TEST_CASE(super_overload)
BOOST_CHECK(callContractFunction("h()") == encodeArgs(2));
}
+BOOST_AUTO_TEST_CASE(bool_conversion)
+{
+ char const* sourceCode = R"(
+ contract C {
+ function f(bool _b) returns(uint) {
+ if (_b)
+ return 1;
+ else
+ return 0;
+ }
+ function g(bool _in) returns (bool _out) {
+ _out = _in;
+ }
+ }
+ )";
+ compileAndRun(sourceCode, 0, "C");
+ BOOST_CHECK(callContractFunction("f(bool)", 0) == encodeArgs(0));
+ BOOST_CHECK(callContractFunction("f(bool)", 1) == encodeArgs(1));
+ BOOST_CHECK(callContractFunction("f(bool)", 2) == encodeArgs(1));
+ BOOST_CHECK(callContractFunction("f(bool)", 3) == encodeArgs(1));
+ BOOST_CHECK(callContractFunction("f(bool)", 255) == encodeArgs(1));
+ BOOST_CHECK(callContractFunction("g(bool)", 0) == encodeArgs(0));
+ BOOST_CHECK(callContractFunction("g(bool)", 1) == encodeArgs(1));
+ BOOST_CHECK(callContractFunction("g(bool)", 2) == encodeArgs(1));
+ BOOST_CHECK(callContractFunction("g(bool)", 3) == encodeArgs(1));
+ BOOST_CHECK(callContractFunction("g(bool)", 255) == encodeArgs(1));
+}
+
BOOST_AUTO_TEST_CASE(packed_storage_signed)
{
char const* sourceCode = R"(
@@ -4506,6 +4661,102 @@ BOOST_AUTO_TEST_CASE(external_types_in_calls)
BOOST_CHECK(callContractFunction("t2()") == encodeArgs(u256(9)));
}
+BOOST_AUTO_TEST_CASE(invalid_enum_compared)
+{
+ char const* sourceCode = R"(
+ contract C {
+ enum X { A, B }
+
+ function test_eq() returns (bool) {
+ X garbled;
+ assembly {
+ garbled := 5
+ }
+ return garbled == garbled;
+ }
+ function test_eq_ok() returns (bool) {
+ X garbled = X.A;
+ return garbled == garbled;
+ }
+ function test_neq() returns (bool) {
+ X garbled;
+ assembly {
+ garbled := 5
+ }
+ return garbled != garbled;
+ }
+ }
+ )";
+ compileAndRun(sourceCode, 0, "C");
+ BOOST_CHECK(callContractFunction("test_eq_ok()") == encodeArgs(u256(1)));
+ // both should throw
+ BOOST_CHECK(callContractFunction("test_eq()") == encodeArgs());
+ BOOST_CHECK(callContractFunction("test_neq()") == encodeArgs());
+}
+
+BOOST_AUTO_TEST_CASE(invalid_enum_logged)
+{
+ char const* sourceCode = R"(
+ contract C {
+ enum X { A, B }
+ event Log(X);
+
+ function test_log() returns (uint) {
+ X garbled = X.A;
+ assembly {
+ garbled := 5
+ }
+ Log(garbled);
+ return 1;
+ }
+ function test_log_ok() returns (uint) {
+ X x = X.A;
+ Log(x);
+ return 1;
+ }
+ }
+ )";
+ compileAndRun(sourceCode, 0, "C");
+ BOOST_CHECK(callContractFunction("test_log_ok()") == encodeArgs(u256(1)));
+ BOOST_REQUIRE_EQUAL(m_logs.size(), 1);
+ BOOST_CHECK_EQUAL(m_logs[0].address, m_contractAddress);
+ BOOST_REQUIRE_EQUAL(m_logs[0].topics.size(), 1);
+ BOOST_REQUIRE_EQUAL(m_logs[0].topics[0], dev::keccak256(string("Log(uint8)")));
+ BOOST_CHECK_EQUAL(h256(m_logs[0].data), h256(u256(0)));
+
+ // should throw
+ BOOST_CHECK(callContractFunction("test_log()") == encodeArgs());
+}
+
+BOOST_AUTO_TEST_CASE(invalid_enum_stored)
+{
+ char const* sourceCode = R"(
+ contract C {
+ enum X { A, B }
+ X public x;
+
+ function test_store() returns (uint) {
+ X garbled = X.A;
+ assembly {
+ garbled := 5
+ }
+ x = garbled;
+ return 1;
+ }
+ function test_store_ok() returns (uint) {
+ x = X.A;
+ return 1;
+ }
+ }
+ )";
+ compileAndRun(sourceCode, 0, "C");
+ BOOST_CHECK(callContractFunction("test_store_ok()") == encodeArgs(u256(1)));
+ BOOST_CHECK(callContractFunction("x()") == encodeArgs(u256(0)));
+
+ // should throw
+ BOOST_CHECK(callContractFunction("test_store()") == encodeArgs());
+}
+
BOOST_AUTO_TEST_CASE(invalid_enum_as_external_ret)
{
char const* sourceCode = R"(
@@ -6324,17 +6575,6 @@ BOOST_AUTO_TEST_CASE(calldata_offset)
BOOST_CHECK(callContractFunction("last()", encodeArgs()) == encodeDyn(string("nd")));
}
-BOOST_AUTO_TEST_CASE(version_stamp_for_libraries)
-{
- char const* sourceCode = "library lib {}";
- m_optimize = true;
- bytes runtimeCode = compileAndRun(sourceCode, 0, "lib");
- BOOST_CHECK(runtimeCode.size() >= 8);
- BOOST_CHECK_EQUAL(runtimeCode[0], int(Instruction::PUSH6)); // might change once we switch to 1.x.x
- BOOST_CHECK_EQUAL(runtimeCode[1], 4); // might change once we switch away from x.4.x
- BOOST_CHECK_EQUAL(runtimeCode[7], int(Instruction::POP));
-}
-
BOOST_AUTO_TEST_CASE(contract_binary_dependencies)
{
char const* sourceCode = R"(
@@ -7608,13 +7848,6 @@ BOOST_AUTO_TEST_CASE(mem_resize_is_not_paid_at_call)
u160 cAddr = m_contractAddress;
compileAndRun(sourceCode, 0, "D");
BOOST_CHECK(callContractFunction("f(address)", cAddr) == encodeArgs(u256(7)));
-
- m_optimize = true;
-
- compileAndRun(sourceCode, 0, "C");
- u160 cAddrOpt = m_contractAddress;
- compileAndRun(sourceCode, 0, "D");
- BOOST_CHECK(callContractFunction("f(address)", cAddrOpt) == encodeArgs(u256(7)));
}
BOOST_AUTO_TEST_CASE(calling_uninitialized_function)
@@ -8223,6 +8456,396 @@ BOOST_AUTO_TEST_CASE(shift_negative_constant_right)
BOOST_CHECK(callContractFunction("a()") == encodeArgs(u256(-0x42)));
}
+BOOST_AUTO_TEST_CASE(shift_left)
+{
+ char const* sourceCode = R"(
+ contract C {
+ function f(uint a, uint b) returns (uint) {
+ return a << b;
+ }
+ }
+ )";
+ compileAndRun(sourceCode, 0, "C");
+ BOOST_CHECK(callContractFunction("f(uint256,uint256)", u256(0x4266), u256(0)) == encodeArgs(u256(0x4266)));
+ BOOST_CHECK(callContractFunction("f(uint256,uint256)", u256(0x4266), u256(8)) == encodeArgs(u256(0x426600)));
+ BOOST_CHECK(callContractFunction("f(uint256,uint256)", u256(0x4266), u256(16)) == encodeArgs(u256(0x42660000)));
+ BOOST_CHECK(callContractFunction("f(uint256,uint256)", u256(0x4266), u256(17)) == encodeArgs(u256(0x84cc0000)));
+ BOOST_CHECK(callContractFunction("f(uint256,uint256)", u256(0x4266), u256(240)) == fromHex("4266000000000000000000000000000000000000000000000000000000000000"));
+ BOOST_CHECK(callContractFunction("f(uint256,uint256)", u256(0x4266), u256(256)) == encodeArgs(u256(0)));
+}
+
+BOOST_AUTO_TEST_CASE(shift_left_uint32)
+{
+ char const* sourceCode = R"(
+ contract C {
+ function f(uint32 a, uint32 b) returns (uint) {
+ return a << b;
+ }
+ }
+ )";
+ compileAndRun(sourceCode, 0, "C");
+ BOOST_CHECK(callContractFunction("f(uint32,uint32)", u256(0x4266), u256(0)) == encodeArgs(u256(0x4266)));
+ BOOST_CHECK(callContractFunction("f(uint32,uint32)", u256(0x4266), u256(8)) == encodeArgs(u256(0x426600)));
+ BOOST_CHECK(callContractFunction("f(uint32,uint32)", u256(0x4266), u256(16)) == encodeArgs(u256(0x42660000)));
+ BOOST_CHECK(callContractFunction("f(uint32,uint32)", u256(0x4266), u256(17)) == encodeArgs(u256(0x84cc0000)));
+ BOOST_CHECK(callContractFunction("f(uint32,uint32)", u256(0x4266), u256(32)) == encodeArgs(u256(0)));
+}
+
+BOOST_AUTO_TEST_CASE(shift_left_uint8)
+{
+ char const* sourceCode = R"(
+ contract C {
+ function f(uint8 a, uint8 b) returns (uint) {
+ return a << b;
+ }
+ }
+ )";
+ compileAndRun(sourceCode, 0, "C");
+ BOOST_CHECK(callContractFunction("f(uint8,uint8)", u256(0x66), u256(0)) == encodeArgs(u256(0x66)));
+ BOOST_CHECK(callContractFunction("f(uint8,uint8)", u256(0x66), u256(8)) == encodeArgs(u256(0)));
+}
+
+BOOST_AUTO_TEST_CASE(shift_left_larger_type)
+{
+ // This basically tests proper cleanup and conversion. It should not convert x to int8.
+ char const* sourceCode = R"(
+ contract C {
+ function f() returns (int8) {
+ uint8 x = 254;
+ int8 y = 1;
+ return y << x;
+ }
+ }
+ )";
+ compileAndRun(sourceCode, 0, "C");
+ BOOST_CHECK(callContractFunction("f()") == encodeArgs(u256(0)));
+}
+
+BOOST_AUTO_TEST_CASE(shift_left_assignment)
+{
+ char const* sourceCode = R"(
+ contract C {
+ function f(uint a, uint b) returns (uint) {
+ a <<= b;
+ return a;
+ }
+ }
+ )";
+ compileAndRun(sourceCode, 0, "C");
+ BOOST_CHECK(callContractFunction("f(uint256,uint256)", u256(0x4266), u256(0)) == encodeArgs(u256(0x4266)));
+ BOOST_CHECK(callContractFunction("f(uint256,uint256)", u256(0x4266), u256(8)) == encodeArgs(u256(0x426600)));
+ BOOST_CHECK(callContractFunction("f(uint256,uint256)", u256(0x4266), u256(16)) == encodeArgs(u256(0x42660000)));
+ BOOST_CHECK(callContractFunction("f(uint256,uint256)", u256(0x4266), u256(17)) == encodeArgs(u256(0x84cc0000)));
+ BOOST_CHECK(callContractFunction("f(uint256,uint256)", u256(0x4266), u256(240)) == fromHex("4266000000000000000000000000000000000000000000000000000000000000"));
+ BOOST_CHECK(callContractFunction("f(uint256,uint256)", u256(0x4266), u256(256)) == encodeArgs(u256(0)));
+}
+
+BOOST_AUTO_TEST_CASE(shift_left_assignment_different_type)
+{
+ char const* sourceCode = R"(
+ contract C {
+ function f(uint a, uint8 b) returns (uint) {
+ a <<= b;
+ return a;
+ }
+ }
+ )";
+ compileAndRun(sourceCode, 0, "C");
+ BOOST_CHECK(callContractFunction("f(uint256,uint8)", u256(0x4266), u256(0)) == encodeArgs(u256(0x4266)));
+ BOOST_CHECK(callContractFunction("f(uint256,uint8)", u256(0x4266), u256(8)) == encodeArgs(u256(0x426600)));
+ BOOST_CHECK(callContractFunction("f(uint256,uint8)", u256(0x4266), u256(16)) == encodeArgs(u256(0x42660000)));
+ BOOST_CHECK(callContractFunction("f(uint256,uint8)", u256(0x4266), u256(17)) == encodeArgs(u256(0x84cc0000)));
+ BOOST_CHECK(callContractFunction("f(uint256,uint8)", u256(0x4266), u256(240)) == fromHex("4266000000000000000000000000000000000000000000000000000000000000"));
+}
+
+BOOST_AUTO_TEST_CASE(shift_right)
+{
+ char const* sourceCode = R"(
+ contract C {
+ function f(uint a, uint b) returns (uint) {
+ return a >> b;
+ }
+ }
+ )";
+ compileAndRun(sourceCode, 0, "C");
+ BOOST_CHECK(callContractFunction("f(uint256,uint256)", u256(0x4266), u256(0)) == encodeArgs(u256(0x4266)));
+ BOOST_CHECK(callContractFunction("f(uint256,uint256)", u256(0x4266), u256(8)) == encodeArgs(u256(0x42)));
+ BOOST_CHECK(callContractFunction("f(uint256,uint256)", u256(0x4266), u256(16)) == encodeArgs(u256(0)));
+ BOOST_CHECK(callContractFunction("f(uint256,uint256)", u256(0x4266), u256(17)) == encodeArgs(u256(0)));
+}
+
+BOOST_AUTO_TEST_CASE(shift_right_garbled)
+{
+ char const* sourceCode = R"(
+ contract C {
+ function f(uint8 a, uint8 b) returns (uint) {
+ assembly {
+ a := 0xffffffff
+ }
+ // Higher bits should be cleared before the shift
+ return a >> b;
+ }
+ }
+ )";
+ compileAndRun(sourceCode, 0, "C");
+ BOOST_CHECK(callContractFunction("f(uint8,uint8)", u256(0x0), u256(4)) == encodeArgs(u256(0xf)));
+ BOOST_CHECK(callContractFunction("f(uint8,uint8)", u256(0x0), u256(0x1004)) == encodeArgs(u256(0xf)));
+}
+
+BOOST_AUTO_TEST_CASE(shift_right_uint32)
+{
+ char const* sourceCode = R"(
+ contract C {
+ function f(uint32 a, uint32 b) returns (uint) {
+ return a >> b;
+ }
+ }
+ )";
+ compileAndRun(sourceCode, 0, "C");
+ BOOST_CHECK(callContractFunction("f(uint32,uint32)", u256(0x4266), u256(0)) == encodeArgs(u256(0x4266)));
+ BOOST_CHECK(callContractFunction("f(uint32,uint32)", u256(0x4266), u256(8)) == encodeArgs(u256(0x42)));
+ BOOST_CHECK(callContractFunction("f(uint32,uint32)", u256(0x4266), u256(16)) == encodeArgs(u256(0)));
+ BOOST_CHECK(callContractFunction("f(uint32,uint32)", u256(0x4266), u256(17)) == encodeArgs(u256(0)));
+}
+
+BOOST_AUTO_TEST_CASE(shift_right_uint8)
+{
+ char const* sourceCode = R"(
+ contract C {
+ function f(uint8 a, uint8 b) returns (uint) {
+ return a >> b;
+ }
+ }
+ )";
+ compileAndRun(sourceCode, 0, "C");
+ BOOST_CHECK(callContractFunction("f(uint8,uint8)", u256(0x66), u256(0)) == encodeArgs(u256(0x66)));
+ BOOST_CHECK(callContractFunction("f(uint8,uint8)", u256(0x66), u256(8)) == encodeArgs(u256(0x0)));
+}
+
+BOOST_AUTO_TEST_CASE(shift_right_assignment)
+{
+ char const* sourceCode = R"(
+ contract C {
+ function f(uint a, uint b) returns (uint) {
+ a >>= b;
+ return a;
+ }
+ }
+ )";
+ compileAndRun(sourceCode, 0, "C");
+ BOOST_CHECK(callContractFunction("f(uint256,uint256)", u256(0x4266), u256(0)) == encodeArgs(u256(0x4266)));
+ BOOST_CHECK(callContractFunction("f(uint256,uint256)", u256(0x4266), u256(8)) == encodeArgs(u256(0x42)));
+ BOOST_CHECK(callContractFunction("f(uint256,uint256)", u256(0x4266), u256(16)) == encodeArgs(u256(0)));
+ BOOST_CHECK(callContractFunction("f(uint256,uint256)", u256(0x4266), u256(17)) == encodeArgs(u256(0)));
+}
+
+BOOST_AUTO_TEST_CASE(shift_right_negative_lvalue)
+{
+ char const* sourceCode = R"(
+ contract C {
+ function f(int a, int b) returns (int) {
+ return a >> b;
+ }
+ }
+ )";
+ compileAndRun(sourceCode, 0, "C");
+ BOOST_CHECK(callContractFunction("f(int256,int256)", u256(-4266), u256(0)) == encodeArgs(u256(-4266)));
+ BOOST_CHECK(callContractFunction("f(int256,int256)", u256(-4266), u256(8)) == encodeArgs(u256(-16)));
+ BOOST_CHECK(callContractFunction("f(int256,int256)", u256(-4266), u256(16)) == encodeArgs(u256(0)));
+ BOOST_CHECK(callContractFunction("f(int256,int256)", u256(-4266), u256(17)) == encodeArgs(u256(0)));
+}
+
+BOOST_AUTO_TEST_CASE(shift_right_negative_lvalue_assignment)
+{
+ char const* sourceCode = R"(
+ contract C {
+ function f(int a, int b) returns (int) {
+ a >>= b;
+ return a;
+ }
+ }
+ )";
+ compileAndRun(sourceCode, 0, "C");
+ BOOST_CHECK(callContractFunction("f(int256,int256)", u256(-4266), u256(0)) == encodeArgs(u256(-4266)));
+ BOOST_CHECK(callContractFunction("f(int256,int256)", u256(-4266), u256(8)) == encodeArgs(u256(-16)));
+ BOOST_CHECK(callContractFunction("f(int256,int256)", u256(-4266), u256(16)) == encodeArgs(u256(0)));
+ BOOST_CHECK(callContractFunction("f(int256,int256)", u256(-4266), u256(17)) == encodeArgs(u256(0)));
+}
+
+BOOST_AUTO_TEST_CASE(shift_negative_rvalue)
+{
+ char const* sourceCode = R"(
+ contract C {
+ function f(int a, int b) returns (int) {
+ return a << b;
+ }
+ function g(int a, int b) returns (int) {
+ return a >> b;
+ }
+ }
+ )";
+ compileAndRun(sourceCode, 0, "C");
+ BOOST_CHECK(callContractFunction("f(int256,int256)", u256(1), u256(-1)) == encodeArgs());
+ BOOST_CHECK(callContractFunction("g(int256,int256)", u256(1), u256(-1)) == encodeArgs());
+}
+
+BOOST_AUTO_TEST_CASE(shift_negative_rvalue_assignment)
+{
+ char const* sourceCode = R"(
+ contract C {
+ function f(int a, int b) returns (int) {
+ a <<= b;
+ return a;
+ }
+ function g(int a, int b) returns (int) {
+ a >>= b;
+ return a;
+ }
+ }
+ )";
+ compileAndRun(sourceCode, 0, "C");
+ BOOST_CHECK(callContractFunction("f(int256,int256)", u256(1), u256(-1)) == encodeArgs());
+ BOOST_CHECK(callContractFunction("g(int256,int256)", u256(1), u256(-1)) == encodeArgs());
+}
+
+BOOST_AUTO_TEST_CASE(shift_constant_left_assignment)
+{
+ char const* sourceCode = R"(
+ contract C {
+ function f() returns (uint a) {
+ a = 0x42;
+ a <<= 8;
+ }
+ }
+ )";
+ compileAndRun(sourceCode, 0, "C");
+ BOOST_CHECK(callContractFunction("f()") == encodeArgs(u256(0x4200)));
+}
+
+BOOST_AUTO_TEST_CASE(shift_constant_right_assignment)
+{
+ char const* sourceCode = R"(
+ contract C {
+ function f() returns (uint a) {
+ a = 0x4200;
+ a >>= 8;
+ }
+ }
+ )";
+ compileAndRun(sourceCode, 0, "C");
+ BOOST_CHECK(callContractFunction("f()") == encodeArgs(u256(0x42)));
+}
+
+BOOST_AUTO_TEST_CASE(shift_cleanup)
+{
+ char const* sourceCode = R"(
+ contract C {
+ function f() returns (uint16 x) {
+ x = 0xffff;
+ x += 32;
+ x <<= 8;
+ x >>= 16;
+ }
+ }
+ )";
+ compileAndRun(sourceCode, 0, "C");
+ BOOST_CHECK(callContractFunction("f()") == encodeArgs(u256(0x0)));
+}
+
+BOOST_AUTO_TEST_CASE(shift_cleanup_garbled)
+{
+ char const* sourceCode = R"(
+ contract C {
+ function f() returns (uint8 x) {
+ assembly {
+ x := 0xffff
+ }
+ x >>= 8;
+ }
+ }
+ )";
+ compileAndRun(sourceCode, 0, "C");
+ BOOST_CHECK(callContractFunction("f()") == encodeArgs(u256(0x0)));
+}
+
+BOOST_AUTO_TEST_CASE(shift_overflow)
+{
+ char const* sourceCode = R"(
+ contract C {
+ function leftU(uint8 x, uint8 y) returns (uint8) {
+ return x << y;
+ }
+ function leftS(int8 x, int8 y) returns (int8) {
+ return x << y;
+ }
+ }
+ )";
+ compileAndRun(sourceCode, 0, "C");
+ BOOST_CHECK(callContractFunction("leftU(uint8,uint8)", 255, 8) == encodeArgs(u256(0)));
+ BOOST_CHECK(callContractFunction("leftU(uint8,uint8)", 255, 1) == encodeArgs(u256(254)));
+ BOOST_CHECK(callContractFunction("leftU(uint8,uint8)", 255, 0) == encodeArgs(u256(255)));
+
+ // Result is -128 and output is sign-extended, not zero-padded.
+ BOOST_CHECK(callContractFunction("leftS(int8,int8)", 1, 7) == encodeArgs(u256(0) - 128));
+ BOOST_CHECK(callContractFunction("leftS(int8,int8)", 1, 6) == encodeArgs(u256(64)));
+}
+
+BOOST_AUTO_TEST_CASE(shift_bytes)
+{
+ char const* sourceCode = R"(
+ contract C {
+ function left(bytes20 x, uint8 y) returns (bytes20) {
+ return x << y;
+ }
+ function right(bytes20 x, uint8 y) returns (bytes20) {
+ return x >> y;
+ }
+ }
+ )";
+ compileAndRun(sourceCode, 0, "C");
+ BOOST_CHECK(callContractFunction("left(bytes20,uint8)", "12345678901234567890", 8 * 8) == encodeArgs("901234567890" + string(8, 0)));
+ BOOST_CHECK(callContractFunction("right(bytes20,uint8)", "12345678901234567890", 8 * 8) == encodeArgs(string(8, 0) + "123456789012"));
+}
+
+BOOST_AUTO_TEST_CASE(shift_bytes_cleanup)
+{
+ char const* sourceCode = R"(
+ contract C {
+ function left(uint8 y) returns (bytes20) {
+ bytes20 x;
+ assembly { x := "12345678901234567890abcde" }
+ return x << y;
+ }
+ function right(uint8 y) returns (bytes20) {
+ bytes20 x;
+ assembly { x := "12345678901234567890abcde" }
+ return x >> y;
+ }
+ }
+ )";
+ compileAndRun(sourceCode, 0, "C");
+ BOOST_CHECK(callContractFunction("left(uint8)", 8 * 8) == encodeArgs("901234567890" + string(8, 0)));
+ BOOST_CHECK(callContractFunction("right(uint8)", 8 * 8) == encodeArgs(string(8, 0) + "123456789012"));
+}
+
+BOOST_AUTO_TEST_CASE(cleanup_in_compound_assign)
+{
+ char const* sourceCode = R"(
+ contract C {
+ function test() returns (uint, uint) {
+ uint32 a = 0xffffffff;
+ uint16 x = uint16(a);
+ uint16 y = x;
+ x /= 0x100;
+ y = y / 0x100;
+ return (x, y);
+ }
+ }
+ )";
+ compileAndRun(sourceCode, 0, "C");
+ BOOST_CHECK(callContractFunction("test()") == encodeArgs(u256(0xff), u256(0xff)));
+}
+
BOOST_AUTO_TEST_CASE(inline_assembly_in_modifiers)
{
char const* sourceCode = R"(
@@ -8280,6 +8903,18 @@ BOOST_AUTO_TEST_CASE(inline_assembly_invalidjumplabel)
BOOST_CHECK(callContractFunction("f()") == encodeArgs());
}
+BOOST_AUTO_TEST_CASE(contracts_separated_with_comment)
+{
+ char const* sourceCode = R"(
+ contract C1 {}
+ /**
+ **/
+ contract C2 {}
+ )";
+ compileAndRun(sourceCode, 0, "C1");
+ compileAndRun(sourceCode, 0, "C2");
+}
+
BOOST_AUTO_TEST_SUITE_END()
}
diff --git a/test/libsolidity/SolidityExecutionFramework.cpp b/test/libsolidity/SolidityExecutionFramework.cpp
index 02548121..bb9695d1 100644
--- a/test/libsolidity/SolidityExecutionFramework.cpp
+++ b/test/libsolidity/SolidityExecutionFramework.cpp
@@ -1,18 +1,18 @@
/*
- This file is part of cpp-ethereum.
+ This file is part of solidity.
- cpp-ethereum is free software: you can redistribute it and/or modify
+ 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.
- cpp-ethereum is distributed in the hope that it will be useful,
+ 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 cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
+ along with solidity. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* @author Christian <c@ethdev.com>
@@ -22,115 +22,13 @@
#include <cstdlib>
#include <boost/test/framework.hpp>
-#include <libdevcore/CommonIO.h>
#include <test/libsolidity/SolidityExecutionFramework.h>
-using namespace std;
-using namespace dev;
+using namespace dev::test;
using namespace dev::solidity;
using namespace dev::solidity::test;
-namespace // anonymous
+SolidityExecutionFramework::SolidityExecutionFramework() :
+ ExecutionFramework()
{
- h256 const EmptyTrie("0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421");
-}
-
-string getIPCSocketPath()
-{
- string ipcPath = dev::test::Options::get().ipcPath;
- if (ipcPath.empty())
- BOOST_FAIL("ERROR: ipcPath not set! (use --ipcpath <path> or the environment variable ETH_TEST_IPC)");
-
- return ipcPath;
-}
-
-ExecutionFramework::ExecutionFramework() :
- m_rpc(RPCSession::instance(getIPCSocketPath())),
- m_sender(m_rpc.account(0))
-{
- m_rpc.test_rewindToBlock(0);
-}
-
-void ExecutionFramework::sendMessage(bytes const& _data, bool _isCreation, u256 const& _value)
-{
- RPCSession::TransactionData d;
- d.data = "0x" + toHex(_data);
- d.from = "0x" + toString(m_sender);
- d.gas = toHex(m_gas, HexPrefix::Add);
- d.gasPrice = toHex(m_gasPrice, HexPrefix::Add);
- d.value = toHex(_value, HexPrefix::Add);
- if (!_isCreation)
- {
- d.to = dev::toString(m_contractAddress);
- BOOST_REQUIRE(m_rpc.eth_getCode(d.to, "latest").size() > 2);
- // Use eth_call to get the output
- m_output = fromHex(m_rpc.eth_call(d, "latest"), WhenError::Throw);
- }
-
- string txHash = m_rpc.eth_sendTransaction(d);
- m_rpc.test_mineBlocks(1);
- RPCSession::TransactionReceipt receipt(m_rpc.eth_getTransactionReceipt(txHash));
-
- if (_isCreation)
- {
- m_contractAddress = Address(receipt.contractAddress);
- BOOST_REQUIRE(m_contractAddress);
- string code = m_rpc.eth_getCode(receipt.contractAddress, "latest");
- m_output = fromHex(code, WhenError::Throw);
- }
-
- m_gasUsed = u256(receipt.gasUsed);
- m_logs.clear();
- for (auto const& log: receipt.logEntries)
- {
- LogEntry entry;
- entry.address = Address(log.address);
- for (auto const& topic: log.topics)
- entry.topics.push_back(h256(topic));
- entry.data = fromHex(log.data, WhenError::Throw);
- m_logs.push_back(entry);
- }
-}
-
-void ExecutionFramework::sendEther(Address const& _to, u256 const& _value)
-{
- RPCSession::TransactionData d;
- d.data = "0x";
- d.from = "0x" + toString(m_sender);
- d.gas = toHex(m_gas, HexPrefix::Add);
- d.gasPrice = toHex(m_gasPrice, HexPrefix::Add);
- d.value = toHex(_value, HexPrefix::Add);
- d.to = dev::toString(_to);
-
- string txHash = m_rpc.eth_sendTransaction(d);
- m_rpc.test_mineBlocks(1);
-}
-
-size_t ExecutionFramework::currentTimestamp()
-{
- auto latestBlock = m_rpc.rpcCall("eth_getBlockByNumber", {"\"latest\"", "false"});
- return size_t(u256(latestBlock.get("timestamp", "invalid").asString()));
-}
-
-Address ExecutionFramework::account(size_t _i)
-{
- return Address(m_rpc.accountCreateIfNotExists(_i));
-}
-
-bool ExecutionFramework::addressHasCode(Address const& _addr)
-{
- string code = m_rpc.eth_getCode(toString(_addr), "latest");
- return !code.empty() && code != "0x";
-}
-
-u256 ExecutionFramework::balanceAt(Address const& _addr)
-{
- return u256(m_rpc.eth_getBalance(toString(_addr), "latest"));
-}
-
-bool ExecutionFramework::storageEmpty(Address const& _addr)
-{
- h256 root(m_rpc.eth_getStorageRoot(toString(_addr), "latest"));
- BOOST_CHECK(root);
- return root == EmptyTrie;
}
diff --git a/test/libsolidity/SolidityExecutionFramework.h b/test/libsolidity/SolidityExecutionFramework.h
index 7d44edaf..03e3a881 100644
--- a/test/libsolidity/SolidityExecutionFramework.h
+++ b/test/libsolidity/SolidityExecutionFramework.h
@@ -1,18 +1,18 @@
/*
- This file is part of cpp-ethereum.
+ This file is part of solidity.
- cpp-ethereum is free software: you can redistribute it and/or modify
+ 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.
- cpp-ethereum is distributed in the hope that it will be useful,
+ 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 cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
+ along with solidity. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* @author Christian <c@ethdev.com>
@@ -24,12 +24,7 @@
#include <functional>
-#include "../TestHelper.h"
-#include "../RPCSession.h"
-
-#include <libdevcore/ABI.h>
-#include <libdevcore/FixedHash.h>
-#include <libevmasm/Instruction.h>
+#include "../ExecutionFramework.h"
#include <libsolidity/interface/CompilerStack.h>
#include <libsolidity/interface/Exceptions.h>
@@ -39,40 +34,29 @@ namespace dev
{
namespace solidity
{
- using rational = boost::rational<dev::bigint>;
- /// An Ethereum address: 20 bytes.
- /// @NOTE This is not endian-specific; it's just a bunch of bytes.
- using Address = h160;
-
- // The various denominations; here for ease of use where needed within code.
- static const u256 ether = exp10<18>();
- static const u256 finney = exp10<15>();
- static const u256 szabo = exp10<12>();
- static const u256 shannon = exp10<9>();
- static const u256 wei = exp10<0>();
namespace test
{
-class ExecutionFramework
+class SolidityExecutionFramework: public dev::test::ExecutionFramework
{
public:
- ExecutionFramework();
+ SolidityExecutionFramework();
- bytes const& compileAndRunWithoutCheck(
+ virtual bytes const& compileAndRunWithoutCheck(
std::string const& _sourceCode,
u256 const& _value = 0,
std::string const& _contractName = "",
bytes const& _arguments = bytes(),
- std::map<std::string, Address> const& _libraryAddresses = std::map<std::string, Address>()
- )
+ std::map<std::string, dev::test::Address> const& _libraryAddresses = std::map<std::string, dev::test::Address>()
+ ) override
{
// Silence compiler version warning
std::string sourceCode = "pragma solidity >=0.0;\n" + _sourceCode;
m_compiler.reset(false);
m_compiler.addSource("", sourceCode);
- if (!m_compiler.compile(m_optimize, m_optimizeRuns))
+ if (!m_compiler.compile(m_optimize, m_optimizeRuns, _libraryAddresses))
{
for (auto const& error: m_compiler.errors())
SourceReferenceFormatter::printExceptionInformation(
@@ -84,230 +68,13 @@ public:
BOOST_ERROR("Compiling contract failed");
}
eth::LinkerObject obj = m_compiler.object(_contractName);
- obj.link(_libraryAddresses);
BOOST_REQUIRE(obj.linkReferences.empty());
sendMessage(obj.bytecode + _arguments, true, _value);
return m_output;
}
- bytes const& compileAndRun(
- std::string const& _sourceCode,
- u256 const& _value = 0,
- std::string const& _contractName = "",
- bytes const& _arguments = bytes(),
- std::map<std::string, Address> const& _libraryAddresses = std::map<std::string, Address>()
- )
- {
- compileAndRunWithoutCheck(_sourceCode, _value, _contractName, _arguments, _libraryAddresses);
- BOOST_REQUIRE(!m_output.empty());
- return m_output;
- }
-
- template <class... Args>
- bytes const& callContractFunctionWithValue(std::string _sig, u256 const& _value, Args const&... _arguments)
- {
- FixedHash<4> hash(dev::keccak256(_sig));
- sendMessage(hash.asBytes() + encodeArgs(_arguments...), false, _value);
- return m_output;
- }
-
- template <class... Args>
- bytes const& callContractFunction(std::string _sig, Args const&... _arguments)
- {
- return callContractFunctionWithValue(_sig, 0, _arguments...);
- }
-
- template <class CppFunction, class... Args>
- void testSolidityAgainstCpp(std::string _sig, CppFunction const& _cppFunction, Args const&... _arguments)
- {
- bytes solidityResult = callContractFunction(_sig, _arguments...);
- bytes cppResult = callCppAndEncodeResult(_cppFunction, _arguments...);
- BOOST_CHECK_MESSAGE(
- solidityResult == cppResult,
- "Computed values do not match.\nSolidity: " +
- toHex(solidityResult) +
- "\nC++: " +
- toHex(cppResult)
- );
- }
-
- template <class CppFunction, class... Args>
- void testSolidityAgainstCppOnRange(std::string _sig, CppFunction const& _cppFunction, u256 const& _rangeStart, u256 const& _rangeEnd)
- {
- for (u256 argument = _rangeStart; argument < _rangeEnd; ++argument)
- {
- bytes solidityResult = callContractFunction(_sig, argument);
- bytes cppResult = callCppAndEncodeResult(_cppFunction, argument);
- BOOST_CHECK_MESSAGE(
- solidityResult == cppResult,
- "Computed values do not match.\nSolidity: " +
- toHex(solidityResult) +
- "\nC++: " +
- toHex(cppResult) +
- "\nArgument: " +
- toHex(encode(argument))
- );
- }
- }
-
- static bytes encode(bool _value) { return encode(byte(_value)); }
- static bytes encode(int _value) { return encode(u256(_value)); }
- static bytes encode(size_t _value) { return encode(u256(_value)); }
- static bytes encode(char const* _value) { return encode(std::string(_value)); }
- static bytes encode(byte _value) { return bytes(31, 0) + bytes{_value}; }
- static bytes encode(u256 const& _value) { return toBigEndian(_value); }
- /// @returns the fixed-point encoding of a rational number with a given
- /// number of fractional bits.
- static bytes encode(std::pair<rational, int> const& _valueAndPrecision)
- {
- rational const& value = _valueAndPrecision.first;
- int fractionalBits = _valueAndPrecision.second;
- return encode(u256((value.numerator() << fractionalBits) / value.denominator()));
- }
- static bytes encode(h256 const& _value) { return _value.asBytes(); }
- static bytes encode(bytes const& _value, bool _padLeft = true)
- {
- bytes padding = bytes((32 - _value.size() % 32) % 32, 0);
- return _padLeft ? padding + _value : _value + padding;
- }
- static bytes encode(std::string const& _value) { return encode(asBytes(_value), false); }
- template <class _T>
- static bytes encode(std::vector<_T> const& _value)
- {
- bytes ret;
- for (auto const& v: _value)
- ret += encode(v);
- return ret;
- }
-
- template <class FirstArg, class... Args>
- static bytes encodeArgs(FirstArg const& _firstArg, Args const&... _followingArgs)
- {
- return encode(_firstArg) + encodeArgs(_followingArgs...);
- }
- static bytes encodeArgs()
- {
- return bytes();
- }
- //@todo might be extended in the future
- template <class Arg>
- static bytes encodeDyn(Arg const& _arg)
- {
- return encodeArgs(u256(0x20), u256(_arg.size()), _arg);
- }
- class ContractInterface
- {
- public:
- ContractInterface(ExecutionFramework& _framework): m_framework(_framework) {}
-
- void setNextValue(u256 const& _value) { m_nextValue = _value; }
-
- protected:
- template <class... Args>
- bytes const& call(std::string const& _sig, Args const&... _arguments)
- {
- auto const& ret = m_framework.callContractFunctionWithValue(_sig, m_nextValue, _arguments...);
- m_nextValue = 0;
- return ret;
- }
-
- void callString(std::string const& _name, std::string const& _arg)
- {
- BOOST_CHECK(call(_name + "(string)", u256(0x20), _arg.length(), _arg).empty());
- }
-
- void callStringAddress(std::string const& _name, std::string const& _arg1, u160 const& _arg2)
- {
- BOOST_CHECK(call(_name + "(string,address)", u256(0x40), _arg2, _arg1.length(), _arg1).empty());
- }
-
- void callStringAddressBool(std::string const& _name, std::string const& _arg1, u160 const& _arg2, bool _arg3)
- {
- BOOST_CHECK(call(_name + "(string,address,bool)", u256(0x60), _arg2, _arg3, _arg1.length(), _arg1).empty());
- }
-
- void callStringBytes32(std::string const& _name, std::string const& _arg1, h256 const& _arg2)
- {
- BOOST_CHECK(call(_name + "(string,bytes32)", u256(0x40), _arg2, _arg1.length(), _arg1).empty());
- }
-
- u160 callStringReturnsAddress(std::string const& _name, std::string const& _arg)
- {
- bytes const& ret = call(_name + "(string)", u256(0x20), _arg.length(), _arg);
- BOOST_REQUIRE(ret.size() == 0x20);
- BOOST_CHECK(std::count(ret.begin(), ret.begin() + 12, 0) == 12);
- return eth::abiOut<u160>(ret);
- }
-
- std::string callAddressReturnsString(std::string const& _name, u160 const& _arg)
- {
- bytesConstRef ret = ref(call(_name + "(address)", _arg));
- BOOST_REQUIRE(ret.size() >= 0x20);
- u256 offset = eth::abiOut<u256>(ret);
- BOOST_REQUIRE_EQUAL(offset, 0x20);
- u256 len = eth::abiOut<u256>(ret);
- BOOST_REQUIRE_EQUAL(ret.size(), ((len + 0x1f) / 0x20) * 0x20);
- return ret.cropped(0, size_t(len)).toString();
- }
-
- h256 callStringReturnsBytes32(std::string const& _name, std::string const& _arg)
- {
- bytes const& ret = call(_name + "(string)", u256(0x20), _arg.length(), _arg);
- BOOST_REQUIRE(ret.size() == 0x20);
- return eth::abiOut<h256>(ret);
- }
-
- private:
- u256 m_nextValue;
- ExecutionFramework& m_framework;
- };
-
-private:
- template <class CppFunction, class... Args>
- auto callCppAndEncodeResult(CppFunction const& _cppFunction, Args const&... _arguments)
- -> typename std::enable_if<std::is_void<decltype(_cppFunction(_arguments...))>::value, bytes>::type
- {
- _cppFunction(_arguments...);
- return bytes();
- }
- template <class CppFunction, class... Args>
- auto callCppAndEncodeResult(CppFunction const& _cppFunction, Args const&... _arguments)
- -> typename std::enable_if<!std::is_void<decltype(_cppFunction(_arguments...))>::value, bytes>::type
- {
- return encode(_cppFunction(_arguments...));
- }
-
protected:
- void sendMessage(bytes const& _data, bool _isCreation, u256 const& _value = 0);
- void sendEther(Address const& _to, u256 const& _value);
- size_t currentTimestamp();
-
- /// @returns the (potentially newly created) _ith address.
- Address account(size_t _i);
-
- u256 balanceAt(Address const& _addr);
- bool storageEmpty(Address const& _addr);
- bool addressHasCode(Address const& _addr);
-
- RPCSession& m_rpc;
-
- struct LogEntry
- {
- Address address;
- std::vector<h256> topics;
- bytes data;
- };
-
- size_t m_optimizeRuns = 200;
- bool m_optimize = false;
dev::solidity::CompilerStack m_compiler;
- Address m_sender;
- Address m_contractAddress;
- u256 const m_gasPrice = 100 * szabo;
- u256 const m_gas = 100000000;
- bytes m_output;
- std::vector<LogEntry> m_logs;
- u256 m_gasUsed;
};
}
diff --git a/test/libsolidity/SolidityExpressionCompiler.cpp b/test/libsolidity/SolidityExpressionCompiler.cpp
index 91edfefd..0c5a09c3 100644
--- a/test/libsolidity/SolidityExpressionCompiler.cpp
+++ b/test/libsolidity/SolidityExpressionCompiler.cpp
@@ -1,18 +1,18 @@
/*
- This file is part of cpp-ethereum.
+ This file is part of solidity.
- cpp-ethereum is free software: you can redistribute it and/or modify
+ 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.
- cpp-ethereum is distributed in the hope that it will be useful,
+ 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 cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
+ along with solidity. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* @author Christian <c@ethdev.com>
@@ -168,9 +168,11 @@ BOOST_AUTO_TEST_SUITE(SolidityExpressionCompiler)
BOOST_AUTO_TEST_CASE(literal_true)
{
- char const* sourceCode = "contract test {\n"
- " function f() { var x = true; }"
- "}\n";
+ char const* sourceCode = R"(
+ contract test {
+ function f() { var x = true; }
+ }
+ )";
bytes code = compileFirstExpression(sourceCode);
bytes expectation({byte(Instruction::PUSH1), 0x1});
@@ -179,9 +181,11 @@ BOOST_AUTO_TEST_CASE(literal_true)
BOOST_AUTO_TEST_CASE(literal_false)
{
- char const* sourceCode = "contract test {\n"
- " function f() { var x = false; }"
- "}\n";
+ char const* sourceCode = R"(
+ contract test {
+ function f() { var x = false; }
+ }
+ )";
bytes code = compileFirstExpression(sourceCode);
bytes expectation({byte(Instruction::PUSH1), 0x0});
@@ -190,9 +194,11 @@ BOOST_AUTO_TEST_CASE(literal_false)
BOOST_AUTO_TEST_CASE(int_literal)
{
- char const* sourceCode = "contract test {\n"
- " function f() { var x = 0x12345678901234567890; }"
- "}\n";
+ char const* sourceCode = R"(
+ contract test {
+ function f() { var x = 0x12345678901234567890; }
+ }
+ )";
bytes code = compileFirstExpression(sourceCode);
bytes expectation({byte(Instruction::PUSH10), 0x12, 0x34, 0x56, 0x78, 0x90,
@@ -204,11 +210,11 @@ BOOST_AUTO_TEST_CASE(int_with_wei_ether_subdenomination)
{
char const* sourceCode = R"(
contract test {
- function test ()
- {
+ function test () {
var x = 1 wei;
}
- })";
+ }
+ )";
bytes code = compileFirstExpression(sourceCode);
bytes expectation({byte(Instruction::PUSH1), 0x1});
@@ -219,11 +225,11 @@ BOOST_AUTO_TEST_CASE(int_with_szabo_ether_subdenomination)
{
char const* sourceCode = R"(
contract test {
- function test ()
- {
+ function test () {
var x = 1 szabo;
}
- })";
+ }
+ )";
bytes code = compileFirstExpression(sourceCode);
bytes expectation({byte(Instruction::PUSH5), 0xe8, 0xd4, 0xa5, 0x10, 0x00});
@@ -249,11 +255,11 @@ BOOST_AUTO_TEST_CASE(int_with_ether_ether_subdenomination)
{
char const* sourceCode = R"(
contract test {
- function test ()
- {
+ function test () {
var x = 1 ether;
}
- })";
+ }
+ )";
bytes code = compileFirstExpression(sourceCode);
bytes expectation({byte(Instruction::PUSH8), 0xd, 0xe0, 0xb6, 0xb3, 0xa7, 0x64, 0x00, 0x00});
@@ -262,9 +268,11 @@ BOOST_AUTO_TEST_CASE(int_with_ether_ether_subdenomination)
BOOST_AUTO_TEST_CASE(comparison)
{
- char const* sourceCode = "contract test {\n"
- " function f() { var x = (0x10aa < 0x11aa) != true; }"
- "}\n";
+ char const* sourceCode = R"(
+ contract test {
+ function f() { var x = (0x10aa < 0x11aa) != true; }
+ }
+ )";
bytes code = compileFirstExpression(sourceCode);
bytes expectation({byte(Instruction::PUSH1), 0x1, byte(Instruction::ISZERO), byte(Instruction::ISZERO),
@@ -278,9 +286,11 @@ BOOST_AUTO_TEST_CASE(comparison)
BOOST_AUTO_TEST_CASE(short_circuiting)
{
- char const* sourceCode = "contract test {\n"
- " function f() { var x = true != (4 <= 8 + 10 || 9 != 2); }"
- "}\n";
+ char const* sourceCode = R"(
+ contract test {
+ function f() { var x = true != (4 <= 8 + 10 || 9 != 2); }
+ }
+ )";
bytes code = compileFirstExpression(sourceCode);
bytes expectation({byte(Instruction::PUSH1), 0x12, // 8 + 10
@@ -305,9 +315,11 @@ BOOST_AUTO_TEST_CASE(short_circuiting)
BOOST_AUTO_TEST_CASE(arithmetics)
{
- char const* sourceCode = "contract test {\n"
- " function f(uint y) { var x = ((((((((y ^ 8) & 7) | 6) - 5) + 4) % 3) / 2) * 1); }"
- "}\n";
+ char const* sourceCode = R"(
+ contract test {
+ function f(uint y) { var x = ((((((((y ^ 8) & 7) | 6) - 5) + 4) % 3) / 2) * 1); }
+ }
+ )";
bytes code = compileFirstExpression(sourceCode, {}, {{"test", "f", "y"}, {"test", "f", "x"}});
bytes expectation({byte(Instruction::PUSH1), 0x1,
byte(Instruction::PUSH1), 0x2,
@@ -339,9 +351,11 @@ BOOST_AUTO_TEST_CASE(arithmetics)
BOOST_AUTO_TEST_CASE(unary_operators)
{
- char const* sourceCode = "contract test {\n"
- " function f(int y) { var x = !(~+- y == 2); }"
- "}\n";
+ char const* sourceCode = R"(
+ contract test {
+ function f(int y) { var x = !(~+- y == 2); }
+ }
+ )";
bytes code = compileFirstExpression(sourceCode, {}, {{"test", "f", "y"}, {"test", "f", "x"}});
bytes expectation({byte(Instruction::PUSH1), 0x2,
@@ -356,9 +370,11 @@ BOOST_AUTO_TEST_CASE(unary_operators)
BOOST_AUTO_TEST_CASE(unary_inc_dec)
{
- char const* sourceCode = "contract test {\n"
- " function f(uint a) { var x = --a ^ (a-- ^ (++a ^ a++)); }"
- "}\n";
+ char const* sourceCode = R"(
+ contract test {
+ function f(uint a) { var x = --a ^ (a-- ^ (++a ^ a++)); }
+ }
+ )";
bytes code = compileFirstExpression(sourceCode, {}, {{"test", "f", "a"}, {"test", "f", "x"}});
// Stack: a, x
@@ -406,9 +422,11 @@ BOOST_AUTO_TEST_CASE(unary_inc_dec)
BOOST_AUTO_TEST_CASE(assignment)
{
- char const* sourceCode = "contract test {\n"
- " function f(uint a, uint b) { (a += b) * 2; }"
- "}\n";
+ char const* sourceCode = R"(
+ contract test {
+ function f(uint a, uint b) { (a += b) * 2; }
+ }
+ )";
bytes code = compileFirstExpression(sourceCode, {}, {{"test", "f", "a"}, {"test", "f", "b"}});
// Stack: a, b
@@ -427,9 +445,11 @@ BOOST_AUTO_TEST_CASE(assignment)
BOOST_AUTO_TEST_CASE(negative_literals_8bits)
{
- char const* sourceCode = "contract test {\n"
- " function f() { int8 x = -0x80; }\n"
- "}\n";
+ char const* sourceCode = R"(
+ contract test {
+ function f() { int8 x = -0x80; }
+ }
+ )";
bytes code = compileFirstExpression(sourceCode);
bytes expectation(bytes({byte(Instruction::PUSH32)}) + bytes(31, 0xff) + bytes(1, 0x80));
@@ -438,9 +458,11 @@ BOOST_AUTO_TEST_CASE(negative_literals_8bits)
BOOST_AUTO_TEST_CASE(negative_literals_16bits)
{
- char const* sourceCode = "contract test {\n"
- " function f() { int64 x = ~0xabc; }\n"
- "}\n";
+ char const* sourceCode = R"(
+ contract test {
+ function f() { int64 x = ~0xabc; }
+ }
+ )";
bytes code = compileFirstExpression(sourceCode);
bytes expectation(bytes({byte(Instruction::PUSH32)}) + bytes(30, 0xff) + bytes{0xf5, 0x43});
@@ -451,9 +473,11 @@ BOOST_AUTO_TEST_CASE(intermediately_overflowing_literals)
{
// first literal itself is too large for 256 bits but it fits after all constant operations
// have been applied
- char const* sourceCode = "contract test {\n"
- " function f() { var x = (0xffffffffffffffffffffffffffffffffffffffff * 0xffffffffffffffffffffffffff01) & 0xbf; }\n"
- "}\n";
+ char const* sourceCode = R"(
+ contract test {
+ function f() { var x = (0xffffffffffffffffffffffffffffffffffffffff * 0xffffffffffffffffffffffffff01) & 0xbf; }
+ }
+ )";
bytes code = compileFirstExpression(sourceCode);
bytes expectation(bytes({byte(Instruction::PUSH1), 0xbf}));
@@ -462,11 +486,13 @@ BOOST_AUTO_TEST_CASE(intermediately_overflowing_literals)
BOOST_AUTO_TEST_CASE(blockhash)
{
- char const* sourceCode = "contract test {\n"
- " function f() {\n"
- " block.blockhash(3);\n"
- " }\n"
- "}\n";
+ char const* sourceCode = R"(
+ contract test {
+ function f() {
+ block.blockhash(3);
+ }
+ }
+ )";
bytes code = compileFirstExpression(sourceCode, {}, {},
{make_shared<MagicVariableDeclaration>("block", make_shared<MagicType>(MagicType::Kind::Block))});
diff --git a/test/libsolidity/SolidityNameAndTypeResolution.cpp b/test/libsolidity/SolidityNameAndTypeResolution.cpp
index 865eb7ce..576421fd 100644
--- a/test/libsolidity/SolidityNameAndTypeResolution.cpp
+++ b/test/libsolidity/SolidityNameAndTypeResolution.cpp
@@ -1,18 +1,18 @@
/*
- This file is part of cpp-ethereum.
+ This file is part of solidity.
- cpp-ethereum is free software: you can redistribute it and/or modify
+ 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.
- cpp-ethereum is distributed in the hope that it will be useful,
+ 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 cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
+ along with solidity. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* @author Christian <c@ethdev.com>
@@ -26,11 +26,13 @@
#include <libsolidity/parsing/Scanner.h>
#include <libsolidity/parsing/Parser.h>
#include <libsolidity/analysis/NameAndTypeResolver.h>
+#include <libsolidity/analysis/StaticAnalyzer.h>
#include <libsolidity/analysis/SyntaxChecker.h>
#include <libsolidity/interface/Exceptions.h>
#include <libsolidity/analysis/GlobalContext.h>
#include <libsolidity/analysis/TypeChecker.h>
#include "../TestHelper.h"
+#include "ErrorCheck.h"
using namespace std;
@@ -44,8 +46,8 @@ namespace test
namespace
{
-pair<ASTPointer<SourceUnit>, std::shared_ptr<Error::Type const>>
-parseAnalyseAndReturnError(string const& _source, bool _reportWarnings = false, bool _insertVersionPragma = true)
+pair<ASTPointer<SourceUnit>, std::shared_ptr<Error const>>
+parseAnalyseAndReturnError(string const& _source, bool _reportWarnings = false, bool _insertVersionPragma = true, bool _allowMultipleErrors = false)
{
// Silence compiler version warning
string source = _insertVersionPragma ? "pragma solidity >=0.0;\n" + _source : _source;
@@ -61,7 +63,7 @@ parseAnalyseAndReturnError(string const& _source, bool _reportWarnings = false,
SyntaxChecker syntaxChecker(errors);
if (!syntaxChecker.checkSyntax(*sourceUnit))
- return make_pair(sourceUnit, std::make_shared<Error::Type const>(errors[0]->type()));
+ return make_pair(sourceUnit, errors.at(0));
std::shared_ptr<GlobalContext> globalContext = make_shared<GlobalContext>();
NameAndTypeResolver resolver(globalContext->declarations(), errors);
@@ -88,15 +90,21 @@ parseAnalyseAndReturnError(string const& _source, bool _reportWarnings = false,
TypeChecker typeChecker(errors);
bool success = typeChecker.checkTypeRequirements(*contract);
BOOST_CHECK(success || !errors.empty());
-
}
+ if (success)
+ {
+ StaticAnalyzer staticAnalyzer(errors);
+ staticAnalyzer.analyze(*sourceUnit);
+ }
+ if (errors.size() > 1 && !_allowMultipleErrors)
+ BOOST_FAIL("Multiple errors found");
for (auto const& currentError: errors)
{
if (
(_reportWarnings && currentError->type() == Error::Type::Warning) ||
(!_reportWarnings && currentError->type() != Error::Type::Warning)
)
- return make_pair(sourceUnit, std::make_shared<Error::Type const>(currentError->type()));
+ return make_pair(sourceUnit, currentError);
}
}
catch (InternalCompilerError const& _e)
@@ -108,7 +116,7 @@ parseAnalyseAndReturnError(string const& _source, bool _reportWarnings = false,
}
catch (Error const& _e)
{
- return make_pair(sourceUnit, std::make_shared<Error::Type const>(_e.type()));
+ return make_pair(sourceUnit, std::make_shared<Error const>(_e));
}
catch (...)
{
@@ -130,9 +138,9 @@ bool success(string const& _source)
return !parseAnalyseAndReturnError(_source).second;
}
-Error::Type expectError(std::string const& _source, bool _warning = false)
+Error expectError(std::string const& _source, bool _warning = false, bool _allowMultiple = false)
{
- auto sourceAndError = parseAnalyseAndReturnError(_source, _warning);
+ auto sourceAndError = parseAnalyseAndReturnError(_source, _warning, true, _allowMultiple);
BOOST_REQUIRE(!!sourceAndError.second);
BOOST_REQUIRE(!!sourceAndError.first);
return *sourceAndError.second;
@@ -150,113 +158,173 @@ static ContractDefinition const* retrieveContract(ASTPointer<SourceUnit> _source
}
static FunctionTypePointer retrieveFunctionBySignature(
- ContractDefinition const* _contract,
+ ContractDefinition const& _contract,
std::string const& _signature
)
{
FixedHash<4> hash(dev::keccak256(_signature));
- return _contract->interfaceFunctions()[hash];
+ return _contract.interfaceFunctions()[hash];
}
}
+#define CHECK_ERROR_OR_WARNING(text, typ, substring, warning, allowMulti) \
+do \
+{ \
+ Error err = expectError((text), (warning), (allowMulti)); \
+ BOOST_CHECK(err.type() == (Error::Type::typ)); \
+ BOOST_CHECK(searchErrorMessage(err, (substring))); \
+} while(0)
+
+// [checkError(text, type, substring)] asserts that the compilation down to typechecking
+// emits an error of type [type] and with a message containing [substring].
+#define CHECK_ERROR(text, type, substring) \
+CHECK_ERROR_OR_WARNING(text, type, substring, false, false)
+
+// [checkError(text, type, substring)] asserts that the compilation down to typechecking
+// emits an error of type [type] and with a message containing [substring].
+#define CHECK_ERROR_ALLOW_MULTI(text, type, substring) \
+CHECK_ERROR_OR_WARNING(text, type, substring, false, true)
+
+// [checkWarning(text, type, substring)] asserts that the compilation down to typechecking
+// emits a warning of type [type] and with a message containing [substring].
+#define CHECK_WARNING(text, substring) \
+CHECK_ERROR_OR_WARNING(text, Warning, substring, true, false)
+
+// [checkSuccess(text)] asserts that the compilation down to typechecking succeeds.
+#define CHECK_SUCCESS(text) do { BOOST_CHECK(success((text))); } while(0)
+
+#define CHECK_SUCCESS_NO_WARNINGS(text) \
+do \
+{ \
+ auto sourceAndError = parseAnalyseAndReturnError((text), true); \
+ BOOST_CHECK(sourceAndError.second == nullptr); \
+} \
+while(0)
+
+
BOOST_AUTO_TEST_SUITE(SolidityNameAndTypeResolution)
BOOST_AUTO_TEST_CASE(smoke_test)
{
- char const* text = "contract test {\n"
- " uint256 stateVariable1;\n"
- " function fun(uint256 arg1) { uint256 y; }"
- "}\n";
- BOOST_CHECK(success(text));
+ char const* text = R"(
+ contract test {
+ uint256 stateVariable1;
+ function fun(uint256 arg1) { uint256 y; }
+ }
+ )";
+ CHECK_SUCCESS(text);
}
BOOST_AUTO_TEST_CASE(double_stateVariable_declaration)
{
- char const* text = "contract test {\n"
- " uint256 variable;\n"
- " uint128 variable;\n"
- "}\n";
- BOOST_CHECK(expectError(text) == Error::Type::DeclarationError);
+ char const* text = R"(
+ contract test {
+ uint256 variable;
+ uint128 variable;
+ }
+ )";
+ CHECK_ERROR(text, DeclarationError, "");
}
BOOST_AUTO_TEST_CASE(double_function_declaration)
{
- char const* text = "contract test {\n"
- " function fun() { uint x; }\n"
- " function fun() { uint x; }\n"
- "}\n";
- BOOST_CHECK(expectError(text) == Error::Type::DeclarationError);
+ char const* text = R"(
+ contract test {
+ function fun() { uint x; }
+ function fun() { uint x; }
+ }
+ )";
+ CHECK_ERROR(text, DeclarationError, "");
}
BOOST_AUTO_TEST_CASE(double_variable_declaration)
{
- char const* text = "contract test {\n"
- " function f() { uint256 x; if (true) { uint256 x; } }\n"
- "}\n";
- BOOST_CHECK(expectError(text) == Error::Type::DeclarationError);
+ char const* text = R"(
+ contract test {
+ function f() {
+ uint256 x;
+ if (true) { uint256 x; }
+ }
+ }
+ )";
+ CHECK_ERROR(text, DeclarationError, "");
}
BOOST_AUTO_TEST_CASE(name_shadowing)
{
- char const* text = "contract test {\n"
- " uint256 variable;\n"
- " function f() { uint32 variable ; }"
- "}\n";
- BOOST_CHECK(success(text));
+ char const* text = R"(
+ contract test {
+ uint256 variable;
+ function f() { uint32 variable; }
+ }
+ )";
+ CHECK_SUCCESS(text);
}
BOOST_AUTO_TEST_CASE(name_references)
{
- char const* text = "contract test {\n"
- " uint256 variable;\n"
- " function f(uint256 arg) returns (uint out) { f(variable); test; out; }"
- "}\n";
- BOOST_CHECK(success(text));
+ char const* text = R"(
+ contract test {
+ uint256 variable;
+ function f(uint256 arg) returns (uint out) { f(variable); test; out; }
+ }
+ )";
+ CHECK_SUCCESS(text);
}
BOOST_AUTO_TEST_CASE(undeclared_name)
{
- char const* text = "contract test {\n"
- " uint256 variable;\n"
- " function f(uint256 arg) { f(notfound); }"
- "}\n";
- BOOST_CHECK(expectError(text) == Error::Type::DeclarationError);
+ char const* text = R"(
+ contract test {
+ uint256 variable;
+ function f(uint256 arg) {
+ f(notfound);
+ }
+ }
+ )";
+ CHECK_ERROR(text, DeclarationError, "");
}
BOOST_AUTO_TEST_CASE(reference_to_later_declaration)
{
- char const* text = "contract test {\n"
- " function g() { f(); }"
- " function f() { }"
- "}\n";
- BOOST_CHECK(success(text));
+ char const* text = R"(
+ contract test {
+ function g() { f(); }
+ function f() {}
+ }
+ )";
+ CHECK_SUCCESS(text);
}
BOOST_AUTO_TEST_CASE(struct_definition_directly_recursive)
{
- char const* text = "contract test {\n"
- " struct MyStructName {\n"
- " address addr;\n"
- " MyStructName x;\n"
- " }\n"
- "}\n";
- BOOST_CHECK(expectError(text) == Error::Type::TypeError);
+ char const* text = R"(
+ contract test {
+ struct MyStructName {
+ address addr;
+ MyStructName x;
+ }
+ }
+ )";
+ CHECK_ERROR(text, TypeError, "");
}
BOOST_AUTO_TEST_CASE(struct_definition_indirectly_recursive)
{
- char const* text = "contract test {\n"
- " struct MyStructName1 {\n"
- " address addr;\n"
- " uint256 count;\n"
- " MyStructName2 x;\n"
- " }\n"
- " struct MyStructName2 {\n"
- " MyStructName1 x;\n"
- " }\n"
- "}\n";
- BOOST_CHECK(expectError(text) == Error::Type::TypeError);
+ char const* text = R"(
+ contract test {
+ struct MyStructName1 {
+ address addr;
+ uint256 count;
+ MyStructName2 x;
+ }
+ struct MyStructName2 {
+ MyStructName1 x;
+ }
+ }
+ )";
+ CHECK_ERROR(text, TypeError, "");
}
BOOST_AUTO_TEST_CASE(struct_definition_not_really_recursive)
@@ -267,184 +335,221 @@ BOOST_AUTO_TEST_CASE(struct_definition_not_really_recursive)
struct s2 { s1 x; s1 y; }
}
)";
- BOOST_CHECK(success(text));
+ CHECK_SUCCESS(text);
}
BOOST_AUTO_TEST_CASE(struct_definition_recursion_via_mapping)
{
- char const* text = "contract test {\n"
- " struct MyStructName1 {\n"
- " address addr;\n"
- " uint256 count;\n"
- " mapping(uint => MyStructName1) x;\n"
- " }\n"
- "}\n";
- BOOST_CHECK(success(text));
+ char const* text = R"(
+ contract test {
+ struct MyStructName1 {
+ address addr;
+ uint256 count;
+ mapping(uint => MyStructName1) x;
+ }
+ }
+ )";
+ CHECK_SUCCESS(text);
}
BOOST_AUTO_TEST_CASE(type_inference_smoke_test)
{
- char const* text = "contract test {\n"
- " function f(uint256 arg1, uint32 arg2) returns (bool ret) { var x = arg1 + arg2 == 8; ret = x; }"
- "}\n";
- BOOST_CHECK(success(text));
+ char const* text = R"(
+ contract test {
+ function f(uint256 arg1, uint32 arg2) returns (bool ret) {
+ var x = arg1 + arg2 == 8; ret = x;
+ }
+ }
+ )";
+ CHECK_SUCCESS(text);
}
BOOST_AUTO_TEST_CASE(type_checking_return)
{
- char const* text = "contract test {\n"
- " function f() returns (bool r) { return 1 >= 2; }"
- "}\n";
- BOOST_CHECK(success(text));
+ char const* text = R"(
+ contract test {
+ function f() returns (bool r) { return 1 >= 2; }
+ }
+ )";
+ CHECK_SUCCESS(text);
}
BOOST_AUTO_TEST_CASE(type_checking_return_wrong_number)
{
- char const* text = "contract test {\n"
- " function f() returns (bool r1, bool r2) { return 1 >= 2; }"
- "}\n";
- BOOST_CHECK(expectError(text) == Error::Type::TypeError);
+ char const* text = R"(
+ contract test {
+ function f() returns (bool r1, bool r2) { return 1 >= 2; }
+ }
+ )";
+ CHECK_ERROR(text, TypeError, "");
}
BOOST_AUTO_TEST_CASE(type_checking_return_wrong_type)
{
- char const* text = "contract test {\n"
- " function f() returns (uint256 r) { return 1 >= 2; }"
- "}\n";
- BOOST_CHECK(expectError(text) == Error::Type::TypeError);
+ char const* text = R"(
+ contract test {
+ function f() returns (uint256 r) { return 1 >= 2; }
+ }
+ )";
+ CHECK_ERROR(text, TypeError, "");
}
BOOST_AUTO_TEST_CASE(type_checking_function_call)
{
- char const* text = "contract test {\n"
- " function f() returns (bool r) { return g(12, true) == 3; }\n"
- " function g(uint256 a, bool b) returns (uint256 r) { }\n"
- "}\n";
- BOOST_CHECK(success(text));
+ char const* text = R"(
+ contract test {
+ function f() returns (bool r) { return g(12, true) == 3; }
+ function g(uint256 a, bool b) returns (uint256 r) { }
+ }
+ )";
+ CHECK_SUCCESS(text);
}
BOOST_AUTO_TEST_CASE(type_conversion_for_comparison)
{
- char const* text = "contract test {\n"
- " function f() { uint32(2) == int64(2); }"
- "}\n";
- BOOST_CHECK(success(text));
+ char const* text = R"(
+ contract test {
+ function f() { uint32(2) == int64(2); }
+ }
+ )";
+ CHECK_SUCCESS(text);
}
BOOST_AUTO_TEST_CASE(type_conversion_for_comparison_invalid)
{
- char const* text = "contract test {\n"
- " function f() { int32(2) == uint64(2); }"
- "}\n";
- BOOST_CHECK(expectError(text) == Error::Type::TypeError);
+ char const* text = R"(
+ contract test {
+ function f() { int32(2) == uint64(2); }
+ }
+ )";
+ CHECK_ERROR(text, TypeError, "");
}
BOOST_AUTO_TEST_CASE(type_inference_explicit_conversion)
{
- char const* text = "contract test {\n"
- " function f() returns (int256 r) { var x = int256(uint32(2)); return x; }"
- "}\n";
- BOOST_CHECK(success(text));
+ char const* text = R"(
+ contract test {
+ function f() returns (int256 r) { var x = int256(uint32(2)); return x; }
+ }
+ )";
+ CHECK_SUCCESS(text);
}
BOOST_AUTO_TEST_CASE(large_string_literal)
{
- char const* text = "contract test {\n"
- " function f() { var x = \"123456789012345678901234567890123\"; }"
- "}\n";
- BOOST_CHECK(success(text));
+ char const* text = R"(
+ contract test {
+ function f() { var x = "123456789012345678901234567890123"; }
+ }
+ )";
+ CHECK_SUCCESS(text);
}
BOOST_AUTO_TEST_CASE(balance)
{
- char const* text = "contract test {\n"
- " function fun() {\n"
- " uint256 x = address(0).balance;\n"
- " }\n"
- "}\n";
- BOOST_CHECK(success(text));
+ char const* text = R"(
+ contract test {
+ function fun() {
+ uint256 x = address(0).balance;
+ }
+ }
+ )";
+ CHECK_SUCCESS(text);
}
BOOST_AUTO_TEST_CASE(balance_invalid)
{
- char const* text = "contract test {\n"
- " function fun() {\n"
- " address(0).balance = 7;\n"
- " }\n"
- "}\n";
- BOOST_CHECK(expectError(text) == Error::Type::TypeError);
+ char const* text = R"(
+ contract test {
+ function fun() {
+ address(0).balance = 7;
+ }
+ }
+ )";
+ CHECK_ERROR(text, TypeError, "");
}
BOOST_AUTO_TEST_CASE(assignment_to_mapping)
{
- char const* text = "contract test {\n"
- " struct str {\n"
- " mapping(uint=>uint) map;\n"
- " }\n"
- " str data;"
- " function fun() {\n"
- " var a = data.map;\n"
- " data.map = a;\n"
- " }\n"
- "}\n";
- BOOST_CHECK(expectError(text) == Error::Type::TypeError);
+ char const* text = R"(
+ contract test {
+ struct str {
+ mapping(uint=>uint) map;
+ }
+ str data;
+ function fun() {
+ var a = data.map;
+ data.map = a;
+ }
+ }
+ )";
+ CHECK_ERROR(text, TypeError, "");
}
BOOST_AUTO_TEST_CASE(assignment_to_struct)
{
- char const* text = "contract test {\n"
- " struct str {\n"
- " mapping(uint=>uint) map;\n"
- " }\n"
- " str data;"
- " function fun() {\n"
- " var a = data;\n"
- " data = a;\n"
- " }\n"
- "}\n";
- BOOST_CHECK(success(text));
+ char const* text = R"(
+ contract test {
+ struct str {
+ mapping(uint=>uint) map;
+ }
+ str data;
+ function fun() {
+ var a = data;
+ data = a;
+ }
+ }
+ )";
+ CHECK_SUCCESS(text);
}
BOOST_AUTO_TEST_CASE(returns_in_constructor)
{
- char const* text = "contract test {\n"
- " function test() returns (uint a) {\n"
- " }\n"
- "}\n";
- BOOST_CHECK(expectError(text) == Error::Type::TypeError);
+ char const* text = R"(
+ contract test {
+ function test() returns (uint a) { }
+ }
+ )";
+ CHECK_ERROR(text, TypeError, "");
}
BOOST_AUTO_TEST_CASE(forward_function_reference)
{
- char const* text = "contract First {\n"
- " function fun() returns (bool ret) {\n"
- " return Second(1).fun(1, true, 3) > 0;\n"
- " }\n"
- "}\n"
- "contract Second {\n"
- " function fun(uint a, bool b, uint c) returns (uint ret) {\n"
- " if (First(2).fun() == true) return 1;\n"
- " }\n"
- "}\n";
- BOOST_CHECK(success(text));
+ char const* text = R"(
+ contract First {
+ function fun() returns (bool ret) {
+ return Second(1).fun(1, true, 3) > 0;
+ }
+ }
+ contract Second {
+ function fun(uint a, bool b, uint c) returns (uint ret) {
+ if (First(2).fun() == true) return 1;
+ }
+ }
+ )";
+ CHECK_SUCCESS(text);
}
BOOST_AUTO_TEST_CASE(comparison_bitop_precedence)
{
- char const* text = "contract First {\n"
- " function fun() returns (bool ret) {\n"
- " return 1 & 2 == 8 & 9 && 1 ^ 2 < 4 | 6;\n"
- " }\n"
- "}\n";
- BOOST_CHECK(success(text));
+ char const* text = R"(
+ contract First {
+ function fun() returns (bool ret) {
+ return 1 & 2 == 8 & 9 && 1 ^ 2 < 4 | 6;
+ }
+ }
+ )";
+ CHECK_SUCCESS(text);
}
BOOST_AUTO_TEST_CASE(function_no_implementation)
{
ASTPointer<SourceUnit> sourceUnit;
- char const* text = "contract test {\n"
- " function functionName(bytes32 input) returns (bytes32 out);\n"
- "}\n";
+ char const* text = R"(
+ contract test {
+ function functionName(bytes32 input) returns (bytes32 out);
+ }
+ )";
ETH_TEST_REQUIRE_NO_THROW(sourceUnit = parseAndAnalyse(text), "Parsing and name Resolving failed");
std::vector<ASTPointer<ASTNode>> nodes = sourceUnit->nodes();
ContractDefinition* contract = dynamic_cast<ContractDefinition*>(nodes[1].get());
@@ -459,7 +564,7 @@ BOOST_AUTO_TEST_CASE(abstract_contract)
char const* text = R"(
contract base { function foo(); }
contract derived is base { function foo() {} }
- )";
+ )";
ETH_TEST_REQUIRE_NO_THROW(sourceUnit = parseAndAnalyse(text), "Parsing and name Resolving failed");
std::vector<ASTPointer<ASTNode>> nodes = sourceUnit->nodes();
ContractDefinition* base = dynamic_cast<ContractDefinition*>(nodes[1].get());
@@ -478,7 +583,7 @@ BOOST_AUTO_TEST_CASE(abstract_contract_with_overload)
char const* text = R"(
contract base { function foo(bool); }
contract derived is base { function foo(uint) {} }
- )";
+ )";
ETH_TEST_REQUIRE_NO_THROW(sourceUnit = parseAndAnalyse(text), "Parsing and name Resolving failed");
std::vector<ASTPointer<ASTNode>> nodes = sourceUnit->nodes();
ContractDefinition* base = dynamic_cast<ContractDefinition*>(nodes[1].get());
@@ -496,10 +601,10 @@ BOOST_AUTO_TEST_CASE(create_abstract_contract)
contract base { function foo(); }
contract derived {
base b;
- function foo() { b = new base();}
- }
- )";
- BOOST_CHECK(expectError(text) == Error::Type::TypeError);
+ function foo() { b = new base(); }
+ }
+ )";
+ CHECK_ERROR(text, TypeError, "");
}
BOOST_AUTO_TEST_CASE(abstract_contract_constructor_args_optional)
@@ -512,7 +617,7 @@ BOOST_AUTO_TEST_CASE(abstract_contract_constructor_args_optional)
function derived(uint i) BaseBase(i){}
function foo() {}
}
- )";
+ )";
ETH_TEST_REQUIRE_NO_THROW(parseAndAnalyse(text), "Parsing and name resolving failed");
}
@@ -526,7 +631,7 @@ BOOST_AUTO_TEST_CASE(abstract_contract_constructor_args_not_provided)
function derived(uint 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);
@@ -542,8 +647,8 @@ BOOST_AUTO_TEST_CASE(redeclare_implemented_abstract_function_as_abstract)
contract base { function foo(); }
contract derived is base { function foo() {} }
contract wrong is derived { function foo(); }
- )";
- BOOST_CHECK(expectError(text) == Error::Type::TypeError);
+ )";
+ CHECK_ERROR(text, TypeError, "");
}
BOOST_AUTO_TEST_CASE(implement_abstract_via_constructor)
@@ -564,11 +669,13 @@ BOOST_AUTO_TEST_CASE(implement_abstract_via_constructor)
BOOST_AUTO_TEST_CASE(function_canonical_signature)
{
ASTPointer<SourceUnit> sourceUnit;
- char const* text = "contract Test {\n"
- " function foo(uint256 arg1, uint64 arg2, bool arg3) returns (uint256 ret) {\n"
- " ret = arg1 + arg2;\n"
- " }\n"
- "}\n";
+ char const* text = R"(
+ contract Test {
+ function foo(uint256 arg1, uint64 arg2, bool arg3) returns (uint256 ret) {
+ ret = arg1 + arg2;
+ }
+ }
+ )";
ETH_TEST_REQUIRE_NO_THROW(sourceUnit = parseAndAnalyse(text), "Parsing and name Resolving failed");
for (ASTPointer<ASTNode> const& node: sourceUnit->nodes())
if (ContractDefinition* contract = dynamic_cast<ContractDefinition*>(node.get()))
@@ -581,11 +688,13 @@ BOOST_AUTO_TEST_CASE(function_canonical_signature)
BOOST_AUTO_TEST_CASE(function_canonical_signature_type_aliases)
{
ASTPointer<SourceUnit> sourceUnit;
- char const* text = "contract Test {\n"
- " function boo(uint arg1, bytes32 arg2, address arg3) returns (uint ret) {\n"
- " ret = 5;\n"
- " }\n"
- "}\n";
+ char const* text = R"(
+ contract Test {
+ function boo(uint arg1, bytes32 arg2, address arg3) returns (uint ret) {
+ ret = 5;
+ }
+ }
+ )";
ETH_TEST_REQUIRE_NO_THROW(sourceUnit = parseAndAnalyse(text), "Parsing and name Resolving failed");
for (ASTPointer<ASTNode> const& node: sourceUnit->nodes())
if (ContractDefinition* contract = dynamic_cast<ContractDefinition*>(node.get()))
@@ -606,9 +715,10 @@ BOOST_AUTO_TEST_CASE(function_external_types)
}
contract Test {
function boo(uint arg2, bool arg3, bytes8 arg4, bool[2] pairs, uint[] dynamic, C carg, address[] addresses) external returns (uint ret) {
- ret = 5;
+ ret = 5;
}
- })";
+ }
+ )";
ETH_TEST_REQUIRE_NO_THROW(sourceUnit = parseAndAnalyse(text), "Parsing and name Resolving failed");
for (ASTPointer<ASTNode> const& node: sourceUnit->nodes())
if (ContractDefinition* contract = dynamic_cast<ContractDefinition*>(node.get()))
@@ -630,7 +740,8 @@ BOOST_AUTO_TEST_CASE(enum_external_type)
function boo(ActionChoices enumArg) external returns (uint ret) {
ret = 5;
}
- })";
+ }
+ )";
ETH_TEST_REQUIRE_NO_THROW(sourceUnit = parseAndAnalyse(text), "Parsing and name Resolving failed");
for (ASTPointer<ASTNode> const& node: sourceUnit->nodes())
if (ContractDefinition* contract = dynamic_cast<ContractDefinition*>(node.get()))
@@ -647,13 +758,14 @@ BOOST_AUTO_TEST_CASE(function_external_call_allowed_conversion)
char const* text = R"(
contract C {}
contract Test {
- function externalCall() {
+ function externalCall() {
C arg;
this.g(arg);
}
function g (C c) external {}
- })";
- BOOST_CHECK(success(text));
+ }
+ )";
+ CHECK_SUCCESS(text);
}
BOOST_AUTO_TEST_CASE(function_external_call_not_allowed_conversion)
@@ -661,13 +773,14 @@ BOOST_AUTO_TEST_CASE(function_external_call_not_allowed_conversion)
char const* text = R"(
contract C {}
contract Test {
- function externalCall() {
+ function externalCall() {
address arg;
this.g(arg);
}
function g (C c) external {}
- })";
- BOOST_CHECK(expectError(text) == Error::Type::TypeError);
+ }
+ )";
+ CHECK_ERROR(text, TypeError, "");
}
BOOST_AUTO_TEST_CASE(function_internal_allowed_conversion)
@@ -682,8 +795,9 @@ BOOST_AUTO_TEST_CASE(function_internal_allowed_conversion)
function internalCall() {
g(a);
}
- })";
- BOOST_CHECK(success(text));
+ }
+ )";
+ CHECK_SUCCESS(text);
}
BOOST_AUTO_TEST_CASE(function_internal_not_allowed_conversion)
@@ -698,19 +812,20 @@ BOOST_AUTO_TEST_CASE(function_internal_not_allowed_conversion)
function internalCall() {
g(a);
}
- })";
- BOOST_CHECK(expectError(text) == Error::Type::TypeError);
+ }
+ )";
+ CHECK_ERROR(text, TypeError, "");
}
BOOST_AUTO_TEST_CASE(hash_collision_in_interface)
{
- char const* text = "contract test {\n"
- " function gsf() {\n"
- " }\n"
- " function tgeo() {\n"
- " }\n"
- "}\n";
- BOOST_CHECK(expectError(text) == Error::Type::TypeError);
+ char const* text = R"(
+ contract test {
+ function gsf() { }
+ function tgeo() { }
+ }
+ )";
+ CHECK_ERROR(text, TypeError, "");
}
BOOST_AUTO_TEST_CASE(inheritance_basic)
@@ -722,7 +837,7 @@ BOOST_AUTO_TEST_CASE(inheritance_basic)
function f() { baseMember = 7; }
}
)";
- BOOST_CHECK(success(text));
+ CHECK_SUCCESS(text);
}
BOOST_AUTO_TEST_CASE(inheritance_diamond_basic)
@@ -735,7 +850,7 @@ BOOST_AUTO_TEST_CASE(inheritance_diamond_basic)
function g() { f(); rootFunction(); }
}
)";
- BOOST_CHECK(success(text));
+ CHECK_SUCCESS(text);
}
BOOST_AUTO_TEST_CASE(cyclic_inheritance)
@@ -744,7 +859,7 @@ BOOST_AUTO_TEST_CASE(cyclic_inheritance)
contract A is B { }
contract B is A { }
)";
- BOOST_CHECK(expectError(text) == Error::Type::TypeError);
+ CHECK_ERROR_ALLOW_MULTI(text, TypeError, "");
}
BOOST_AUTO_TEST_CASE(legal_override_direct)
@@ -753,7 +868,7 @@ BOOST_AUTO_TEST_CASE(legal_override_direct)
contract B { function f() {} }
contract C is B { function f(uint i) {} }
)";
- BOOST_CHECK(success(text));
+ CHECK_SUCCESS(text);
}
BOOST_AUTO_TEST_CASE(legal_override_indirect)
@@ -763,7 +878,7 @@ BOOST_AUTO_TEST_CASE(legal_override_indirect)
contract B { function f() {} }
contract C is A, B { }
)";
- BOOST_CHECK(success(text));
+ CHECK_SUCCESS(text);
}
BOOST_AUTO_TEST_CASE(illegal_override_visibility)
@@ -772,7 +887,7 @@ BOOST_AUTO_TEST_CASE(illegal_override_visibility)
contract B { function f() internal {} }
contract C is B { function f() public {} }
)";
- BOOST_CHECK(expectError(text) == Error::Type::TypeError);
+ CHECK_ERROR(text, TypeError, "");
}
BOOST_AUTO_TEST_CASE(illegal_override_constness)
@@ -781,7 +896,7 @@ BOOST_AUTO_TEST_CASE(illegal_override_constness)
contract B { function f() constant {} }
contract C is B { function f() {} }
)";
- BOOST_CHECK(expectError(text) == Error::Type::TypeError);
+ CHECK_ERROR(text, TypeError, "");
}
BOOST_AUTO_TEST_CASE(complex_inheritance)
@@ -791,7 +906,7 @@ BOOST_AUTO_TEST_CASE(complex_inheritance)
contract B { function f() {} function g() returns (uint8 r) {} }
contract C is A, B { }
)";
- BOOST_CHECK(success(text));
+ CHECK_SUCCESS(text);
}
BOOST_AUTO_TEST_CASE(constructor_visibility)
@@ -801,7 +916,7 @@ BOOST_AUTO_TEST_CASE(constructor_visibility)
contract A { function A() { } }
contract B is A { function f() { A x = A(0); } }
)";
- BOOST_CHECK(success(text));
+ CHECK_SUCCESS(text);
}
BOOST_AUTO_TEST_CASE(overriding_constructor)
@@ -811,7 +926,7 @@ BOOST_AUTO_TEST_CASE(overriding_constructor)
contract A { function A() { } }
contract B is A { function A() returns (uint8 r) {} }
)";
- BOOST_CHECK(success(text));
+ CHECK_SUCCESS(text);
}
BOOST_AUTO_TEST_CASE(missing_base_constructor_arguments)
@@ -820,7 +935,7 @@ BOOST_AUTO_TEST_CASE(missing_base_constructor_arguments)
contract A { function A(uint a) { } }
contract B is A { }
)";
- BOOST_CHECK(success(text));
+ CHECK_SUCCESS(text);
}
BOOST_AUTO_TEST_CASE(base_constructor_arguments_override)
@@ -829,7 +944,7 @@ BOOST_AUTO_TEST_CASE(base_constructor_arguments_override)
contract A { function A(uint a) { } }
contract B is A { }
)";
- BOOST_CHECK(success(text));
+ CHECK_SUCCESS(text);
}
BOOST_AUTO_TEST_CASE(implicit_derived_to_base_conversion)
@@ -840,7 +955,7 @@ BOOST_AUTO_TEST_CASE(implicit_derived_to_base_conversion)
function f() { A a = B(1); }
}
)";
- BOOST_CHECK(success(text));
+ CHECK_SUCCESS(text);
}
BOOST_AUTO_TEST_CASE(implicit_base_to_derived_conversion)
@@ -851,7 +966,7 @@ BOOST_AUTO_TEST_CASE(implicit_base_to_derived_conversion)
function f() { B b = A(1); }
}
)";
- BOOST_CHECK(expectError(text) == Error::Type::TypeError);
+ CHECK_ERROR(text, TypeError, "");
}
BOOST_AUTO_TEST_CASE(super_excludes_current_contract)
@@ -868,7 +983,7 @@ BOOST_AUTO_TEST_CASE(super_excludes_current_contract)
}
)";
- BOOST_CHECK(expectError(text) == Error::Type::TypeError);
+ CHECK_ERROR(text, TypeError, "");
}
BOOST_AUTO_TEST_CASE(function_modifier_invocation)
@@ -880,7 +995,7 @@ BOOST_AUTO_TEST_CASE(function_modifier_invocation)
modifier mod2(bytes7 a) { while (a == "1234567") _; }
}
)";
- BOOST_CHECK(success(text));
+ CHECK_SUCCESS(text);
}
BOOST_AUTO_TEST_CASE(invalid_function_modifier_type)
@@ -891,7 +1006,7 @@ BOOST_AUTO_TEST_CASE(invalid_function_modifier_type)
modifier mod1(uint a) { if (a > 0) _; }
}
)";
- BOOST_CHECK(expectError(text) == Error::Type::TypeError);
+ CHECK_ERROR(text, TypeError, "");
}
BOOST_AUTO_TEST_CASE(function_modifier_invocation_parameters)
@@ -903,7 +1018,7 @@ BOOST_AUTO_TEST_CASE(function_modifier_invocation_parameters)
modifier mod2(bytes7 a) { while (a == "1234567") _; }
}
)";
- BOOST_CHECK(success(text));
+ CHECK_SUCCESS(text);
}
BOOST_AUTO_TEST_CASE(function_modifier_invocation_local_variables)
@@ -914,7 +1029,7 @@ BOOST_AUTO_TEST_CASE(function_modifier_invocation_local_variables)
modifier mod(uint a) { if (a > 0) _; }
}
)";
- BOOST_CHECK(success(text));
+ CHECK_SUCCESS(text);
}
BOOST_AUTO_TEST_CASE(legal_modifier_override)
@@ -923,7 +1038,7 @@ BOOST_AUTO_TEST_CASE(legal_modifier_override)
contract A { modifier mod(uint a) { _; } }
contract B is A { modifier mod(uint a) { _; } }
)";
- BOOST_CHECK(success(text));
+ CHECK_SUCCESS(text);
}
BOOST_AUTO_TEST_CASE(illegal_modifier_override)
@@ -932,7 +1047,7 @@ BOOST_AUTO_TEST_CASE(illegal_modifier_override)
contract A { modifier mod(uint a) { _; } }
contract B is A { modifier mod(uint8 a) { _; } }
)";
- BOOST_CHECK(expectError(text) == Error::Type::TypeError);
+ CHECK_ERROR(text, TypeError, "");
}
BOOST_AUTO_TEST_CASE(modifier_overrides_function)
@@ -941,7 +1056,7 @@ BOOST_AUTO_TEST_CASE(modifier_overrides_function)
contract A { modifier mod(uint a) { _; } }
contract B is A { function mod(uint a) { } }
)";
- BOOST_CHECK(expectError(text) == Error::Type::TypeError);
+ CHECK_ERROR(text, TypeError, "");
}
BOOST_AUTO_TEST_CASE(function_overrides_modifier)
@@ -950,7 +1065,7 @@ BOOST_AUTO_TEST_CASE(function_overrides_modifier)
contract A { function mod(uint a) { } }
contract B is A { modifier mod(uint a) { _; } }
)";
- BOOST_CHECK(expectError(text) == Error::Type::TypeError);
+ CHECK_ERROR(text, TypeError, "");
}
BOOST_AUTO_TEST_CASE(modifier_returns_value)
@@ -961,31 +1076,33 @@ BOOST_AUTO_TEST_CASE(modifier_returns_value)
modifier mod(uint a) { _; return 7; }
}
)";
- BOOST_CHECK(expectError(text) == Error::Type::TypeError);
+ CHECK_ERROR(text, TypeError, "");
}
BOOST_AUTO_TEST_CASE(state_variable_accessors)
{
- char const* text = "contract test {\n"
- " function fun() {\n"
- " uint64(2);\n"
- " }\n"
- "uint256 public foo;\n"
- "mapping(uint=>bytes4) public map;\n"
- "mapping(uint=>mapping(uint=>bytes4)) public multiple_map;\n"
- "}\n";
+ char const* text = R"(
+ contract test {
+ function fun() {
+ uint64(2);
+ }
+ uint256 public foo;
+ mapping(uint=>bytes4) public map;
+ mapping(uint=>mapping(uint=>bytes4)) public multiple_map;
+ }
+ )";
ASTPointer<SourceUnit> source;
ContractDefinition const* contract;
ETH_TEST_CHECK_NO_THROW(source = parseAndAnalyse(text), "Parsing and Resolving names failed");
BOOST_REQUIRE((contract = retrieveContract(source, 0)) != nullptr);
- FunctionTypePointer function = retrieveFunctionBySignature(contract, "foo()");
+ FunctionTypePointer function = retrieveFunctionBySignature(*contract, "foo()");
BOOST_REQUIRE(function && function->hasDeclaration());
auto returnParams = function->returnParameterTypeNames(false);
BOOST_CHECK_EQUAL(returnParams.at(0), "uint256");
BOOST_CHECK(function->isConstant());
- function = retrieveFunctionBySignature(contract, "map(uint256)");
+ function = retrieveFunctionBySignature(*contract, "map(uint256)");
BOOST_REQUIRE(function && function->hasDeclaration());
auto params = function->parameterTypeNames(false);
BOOST_CHECK_EQUAL(params.at(0), "uint256");
@@ -993,7 +1110,7 @@ BOOST_AUTO_TEST_CASE(state_variable_accessors)
BOOST_CHECK_EQUAL(returnParams.at(0), "bytes4");
BOOST_CHECK(function->isConstant());
- function = retrieveFunctionBySignature(contract, "multiple_map(uint256,uint256)");
+ function = retrieveFunctionBySignature(*contract, "multiple_map(uint256,uint256)");
BOOST_REQUIRE(function && function->hasDeclaration());
params = function->parameterTypeNames(false);
BOOST_CHECK_EQUAL(params.at(0), "uint256");
@@ -1005,34 +1122,38 @@ BOOST_AUTO_TEST_CASE(state_variable_accessors)
BOOST_AUTO_TEST_CASE(function_clash_with_state_variable_accessor)
{
- char const* text = "contract test {\n"
- " function fun() {\n"
- " uint64(2);\n"
- " }\n"
- "uint256 foo;\n"
- " function foo() {}\n"
- "}\n";
- BOOST_CHECK(expectError(text) == Error::Type::DeclarationError);
+ char const* text = R"(
+ contract test {
+ function fun() {
+ uint64(2);
+ }
+ uint256 foo;
+ function foo() {}
+ }
+ )";
+ CHECK_ERROR(text, DeclarationError, "");
}
BOOST_AUTO_TEST_CASE(private_state_variable)
{
- char const* text = "contract test {\n"
- " function fun() {\n"
- " uint64(2);\n"
- " }\n"
- "uint256 private foo;\n"
- "uint256 internal bar;\n"
- "}\n";
+ char const* text = R"(
+ contract test {
+ function fun() {
+ uint64(2);
+ }
+ uint256 private foo;
+ uint256 internal bar;
+ }
+ )";
ASTPointer<SourceUnit> source;
ContractDefinition const* contract;
ETH_TEST_CHECK_NO_THROW(source = parseAndAnalyse(text), "Parsing and Resolving names failed");
BOOST_CHECK((contract = retrieveContract(source, 0)) != nullptr);
FunctionTypePointer function;
- function = retrieveFunctionBySignature(contract, "foo()");
+ function = retrieveFunctionBySignature(*contract, "foo()");
BOOST_CHECK_MESSAGE(function == nullptr, "Accessor function of a private variable should not exist");
- function = retrieveFunctionBySignature(contract, "bar()");
+ function = retrieveFunctionBySignature(*contract, "bar()");
BOOST_CHECK_MESSAGE(function == nullptr, "Accessor function of an internal variable should not exist");
}
@@ -1045,71 +1166,79 @@ BOOST_AUTO_TEST_CASE(missing_state_variable)
}
}
)";
- BOOST_CHECK(expectError(text) == Error::Type::TypeError);
+ CHECK_ERROR(text, TypeError, "");
}
BOOST_AUTO_TEST_CASE(base_class_state_variable_accessor)
{
// test for issue #1126 https://github.com/ethereum/cpp-ethereum/issues/1126
- char const* text = "contract Parent {\n"
- " uint256 public m_aMember;\n"
- "}\n"
- "contract Child is Parent{\n"
- " function foo() returns (uint256) { return Parent.m_aMember; }\n"
- "}\n";
- BOOST_CHECK(success(text));
+ char const* text = R"(
+ contract Parent {
+ uint256 public m_aMember;
+ }
+ contract Child is Parent {
+ function foo() returns (uint256) { return Parent.m_aMember; }
+ }
+ )";
+ CHECK_SUCCESS(text);
}
BOOST_AUTO_TEST_CASE(struct_accessor_one_array_only)
{
char const* sourceCode = R"(
contract test {
- struct Data { uint[15] m_array; }
+ struct Data { uint[15] m_array; }
Data public data;
}
)";
- BOOST_CHECK(expectError(sourceCode) == Error::Type::TypeError);
+ CHECK_ERROR(sourceCode, TypeError, "");
}
BOOST_AUTO_TEST_CASE(base_class_state_variable_internal_member)
{
- char const* text = "contract Parent {\n"
- " uint256 internal m_aMember;\n"
- "}\n"
- "contract Child is Parent{\n"
- " function foo() returns (uint256) { return Parent.m_aMember; }\n"
- "}\n";
- BOOST_CHECK(success(text));
+ char const* text = R"(
+ contract Parent {
+ uint256 internal m_aMember;
+ }
+ contract Child is Parent{
+ function foo() returns (uint256) { return Parent.m_aMember; }
+ }
+ )";
+ CHECK_SUCCESS(text);
}
BOOST_AUTO_TEST_CASE(state_variable_member_of_wrong_class1)
{
- char const* text = "contract Parent1 {\n"
- " uint256 internal m_aMember1;\n"
- "}\n"
- "contract Parent2 is Parent1{\n"
- " uint256 internal m_aMember2;\n"
- "}\n"
- "contract Child is Parent2{\n"
- " function foo() returns (uint256) { return Parent2.m_aMember1; }\n"
- "}\n";
- BOOST_CHECK(expectError(text) == Error::Type::TypeError);
+ char const* text = R"(
+ contract Parent1 {
+ uint256 internal m_aMember1;
+ }
+ contract Parent2 is Parent1{
+ uint256 internal m_aMember2;
+ }
+ contract Child is Parent2{
+ function foo() returns (uint256) { return Parent2.m_aMember1; }
+ }
+ )";
+ CHECK_ERROR(text, TypeError, "");
}
BOOST_AUTO_TEST_CASE(state_variable_member_of_wrong_class2)
{
- char const* text = "contract Parent1 {\n"
- " uint256 internal m_aMember1;\n"
- "}\n"
- "contract Parent2 is Parent1{\n"
- " uint256 internal m_aMember2;\n"
- "}\n"
- "contract Child is Parent2{\n"
- " function foo() returns (uint256) { return Child.m_aMember2; }\n"
- " uint256 public m_aMember3;\n"
- "}\n";
- BOOST_CHECK(expectError(text) == Error::Type::TypeError);
+ char const* text = R"(
+ contract Parent1 {
+ uint256 internal m_aMember1;
+ }
+ contract Parent2 is Parent1 {
+ uint256 internal m_aMember2;
+ }
+ contract Child is Parent2 {
+ function foo() returns (uint256) { return Child.m_aMember2; }
+ uint256 public m_aMember3;
+ }
+ )";
+ CHECK_ERROR(text, TypeError, "");
}
BOOST_AUTO_TEST_CASE(fallback_function)
@@ -1120,7 +1249,7 @@ BOOST_AUTO_TEST_CASE(fallback_function)
function() { x = 2; }
}
)";
- BOOST_CHECK(success(text));
+ CHECK_SUCCESS(text);
}
BOOST_AUTO_TEST_CASE(fallback_function_with_arguments)
@@ -1131,7 +1260,7 @@ BOOST_AUTO_TEST_CASE(fallback_function_with_arguments)
function(uint a) { x = 2; }
}
)";
- BOOST_CHECK(expectError(text) == Error::Type::TypeError);
+ CHECK_ERROR(text, TypeError, "");
}
BOOST_AUTO_TEST_CASE(fallback_function_in_library)
@@ -1141,7 +1270,7 @@ BOOST_AUTO_TEST_CASE(fallback_function_in_library)
function() {}
}
)";
- BOOST_CHECK(expectError(text) == Error::Type::TypeError);
+ CHECK_ERROR(text, TypeError, "");
}
BOOST_AUTO_TEST_CASE(fallback_function_with_return_parameters)
@@ -1151,7 +1280,7 @@ BOOST_AUTO_TEST_CASE(fallback_function_with_return_parameters)
function() returns (uint) { }
}
)";
- BOOST_CHECK(expectError(text) == Error::Type::TypeError);
+ CHECK_ERROR(text, TypeError, "");
}
BOOST_AUTO_TEST_CASE(fallback_function_with_constant_modifier)
@@ -1162,7 +1291,7 @@ BOOST_AUTO_TEST_CASE(fallback_function_with_constant_modifier)
function() constant { x = 2; }
}
)";
- BOOST_CHECK(expectError(text) == Error::Type::TypeError);
+ CHECK_ERROR(text, TypeError, "");
}
BOOST_AUTO_TEST_CASE(fallback_function_twice)
@@ -1174,7 +1303,7 @@ BOOST_AUTO_TEST_CASE(fallback_function_twice)
function() { x = 3; }
}
)";
- BOOST_CHECK(expectError(text) == Error::Type::DeclarationError);
+ CHECK_ERROR_ALLOW_MULTI(text, DeclarationError, "");
}
BOOST_AUTO_TEST_CASE(fallback_function_inheritance)
@@ -1188,7 +1317,7 @@ BOOST_AUTO_TEST_CASE(fallback_function_inheritance)
function() { x = 2; }
}
)";
- BOOST_CHECK(success(text));
+ CHECK_SUCCESS(text);
}
BOOST_AUTO_TEST_CASE(event)
@@ -1197,8 +1326,9 @@ BOOST_AUTO_TEST_CASE(event)
contract c {
event e(uint indexed a, bytes3 indexed s, bool indexed b);
function f() { e(2, "abc", true); }
- })";
- BOOST_CHECK(success(text));
+ }
+ )";
+ CHECK_SUCCESS(text);
}
BOOST_AUTO_TEST_CASE(event_too_many_indexed)
@@ -1206,8 +1336,9 @@ BOOST_AUTO_TEST_CASE(event_too_many_indexed)
char const* text = R"(
contract c {
event e(uint indexed a, bytes3 indexed b, bool indexed c, uint indexed d);
- })";
- BOOST_CHECK(expectError(text) == Error::Type::TypeError);
+ }
+ )";
+ CHECK_ERROR(text, TypeError, "");
}
BOOST_AUTO_TEST_CASE(anonymous_event_four_indexed)
@@ -1215,8 +1346,9 @@ BOOST_AUTO_TEST_CASE(anonymous_event_four_indexed)
char const* text = R"(
contract c {
event e(uint indexed a, bytes3 indexed b, bool indexed c, uint indexed d) anonymous;
- })";
- BOOST_CHECK(success(text));
+ }
+ )";
+ CHECK_SUCCESS(text);
}
BOOST_AUTO_TEST_CASE(anonymous_event_too_many_indexed)
@@ -1224,8 +1356,9 @@ BOOST_AUTO_TEST_CASE(anonymous_event_too_many_indexed)
char const* text = R"(
contract c {
event e(uint indexed a, bytes3 indexed b, bool indexed c, uint indexed d, uint indexed e) anonymous;
- })";
- BOOST_CHECK(expectError(text) == Error::Type::TypeError);
+ }
+ )";
+ CHECK_ERROR(text, TypeError, "");
}
BOOST_AUTO_TEST_CASE(event_call)
@@ -1234,8 +1367,9 @@ BOOST_AUTO_TEST_CASE(event_call)
contract c {
event e(uint a, bytes3 indexed s, bool indexed b);
function f() { e(2, "abc", true); }
- })";
- BOOST_CHECK(success(text));
+ }
+ )";
+ CHECK_SUCCESS(text);
}
BOOST_AUTO_TEST_CASE(event_inheritance)
@@ -1246,8 +1380,9 @@ BOOST_AUTO_TEST_CASE(event_inheritance)
}
contract c is base {
function f() { e(2, "abc", true); }
- })";
- BOOST_CHECK(success(text));
+ }
+ )";
+ CHECK_SUCCESS(text);
}
BOOST_AUTO_TEST_CASE(multiple_events_argument_clash)
@@ -1256,8 +1391,9 @@ BOOST_AUTO_TEST_CASE(multiple_events_argument_clash)
contract c {
event e1(uint a, uint e1, uint e2);
event e2(uint a, uint e1, uint e2);
- })";
- BOOST_CHECK(success(text));
+ }
+ )";
+ CHECK_SUCCESS(text);
}
BOOST_AUTO_TEST_CASE(access_to_default_function_visibility)
@@ -1268,8 +1404,9 @@ BOOST_AUTO_TEST_CASE(access_to_default_function_visibility)
}
contract d {
function g() { c(0).f(); }
- })";
- BOOST_CHECK(success(text));
+ }
+ )";
+ CHECK_SUCCESS(text);
}
BOOST_AUTO_TEST_CASE(access_to_internal_function)
@@ -1280,8 +1417,9 @@ BOOST_AUTO_TEST_CASE(access_to_internal_function)
}
contract d {
function g() { c(0).f(); }
- })";
- BOOST_CHECK(expectError(text) == Error::Type::TypeError);
+ }
+ )";
+ CHECK_ERROR(text, TypeError, "");
}
BOOST_AUTO_TEST_CASE(access_to_default_state_variable_visibility)
@@ -1292,8 +1430,9 @@ BOOST_AUTO_TEST_CASE(access_to_default_state_variable_visibility)
}
contract d {
function g() { c(0).a(); }
- })";
- BOOST_CHECK(expectError(text) == Error::Type::TypeError);
+ }
+ )";
+ CHECK_ERROR(text, TypeError, "");
}
BOOST_AUTO_TEST_CASE(access_to_internal_state_variable)
@@ -1304,115 +1443,146 @@ BOOST_AUTO_TEST_CASE(access_to_internal_state_variable)
}
contract d {
function g() { c(0).a(); }
- })";
- BOOST_CHECK(success(text));
+ }
+ )";
+ CHECK_SUCCESS(text);
}
BOOST_AUTO_TEST_CASE(error_count_in_named_args)
{
- char const* sourceCode = "contract test {\n"
- " function a(uint a, uint b) returns (uint r) { r = a + b; }\n"
- " function b() returns (uint r) { r = a({a: 1}); }\n"
- "}\n";
- BOOST_CHECK(expectError(sourceCode) == Error::Type::TypeError);
+ char const* sourceCode = R"(
+ contract test {
+ function a(uint a, uint b) returns (uint r) {
+ r = a + b;
+ }
+ function b() returns (uint r) {
+ r = a({a: 1});
+ }
+ }
+ )";
+ CHECK_ERROR(sourceCode, TypeError, "");
}
BOOST_AUTO_TEST_CASE(empty_in_named_args)
{
- char const* sourceCode = "contract test {\n"
- " function a(uint a, uint b) returns (uint r) { r = a + b; }\n"
- " function b() returns (uint r) { r = a({}); }\n"
- "}\n";
- BOOST_CHECK(expectError(sourceCode) == Error::Type::TypeError);
+ char const* sourceCode = R"(
+ contract test {
+ function a(uint a, uint b) returns (uint r) {
+ r = a + b;
+ }
+ function b() returns (uint r) {
+ r = a({});
+ }
+ }
+ )";
+ CHECK_ERROR(sourceCode, TypeError, "");
}
BOOST_AUTO_TEST_CASE(duplicate_parameter_names_in_named_args)
{
- char const* sourceCode = "contract test {\n"
- " function a(uint a, uint b) returns (uint r) { r = a + b; }\n"
- " function b() returns (uint r) { r = a({a: 1, a: 2}); }\n"
- "}\n";
- BOOST_CHECK(expectError(sourceCode) == Error::Type::TypeError);
+ char const* sourceCode = R"(
+ contract test {
+ function a(uint a, uint b) returns (uint r) {
+ r = a + b;
+ }
+ function b() returns (uint r) {
+ r = a({a: 1, a: 2});
+ }
+ }
+ )";
+ CHECK_ERROR(sourceCode, TypeError, "");
}
BOOST_AUTO_TEST_CASE(invalid_parameter_names_in_named_args)
{
- char const* sourceCode = "contract test {\n"
- " function a(uint a, uint b) returns (uint r) { r = a + b; }\n"
- " function b() returns (uint r) { r = a({a: 1, c: 2}); }\n"
- "}\n";
- BOOST_CHECK(expectError(sourceCode) == Error::Type::TypeError);
+ char const* sourceCode = R"(
+ contract test {
+ function a(uint a, uint b) returns (uint r) {
+ r = a + b;
+ }
+ function b() returns (uint r) {
+ r = a({a: 1, c: 2});
+ }
+ }
+ )";
+ CHECK_ERROR(sourceCode, TypeError, "");
}
BOOST_AUTO_TEST_CASE(empty_name_input_parameter)
{
char const* text = R"(
contract test {
- function f(uint){
+ function f(uint) { }
}
- })";
- BOOST_CHECK(success(text));
+ )";
+ CHECK_SUCCESS(text);
}
BOOST_AUTO_TEST_CASE(empty_name_return_parameter)
{
char const* text = R"(
contract test {
- function f() returns(bool){
+ function f() returns(bool) { }
}
- })";
- BOOST_CHECK(success(text));
+ )";
+ CHECK_SUCCESS(text);
}
BOOST_AUTO_TEST_CASE(empty_name_input_parameter_with_named_one)
{
char const* text = R"(
contract test {
- function f(uint, uint k) returns(uint ret_k){
+ function f(uint, uint k) returns(uint ret_k) {
return k;
+ }
}
- })";
- BOOST_CHECK(success(text));
+ )";
+ CHECK_SUCCESS(text);
}
BOOST_AUTO_TEST_CASE(empty_name_return_parameter_with_named_one)
{
char const* text = R"(
contract test {
- function f() returns(uint ret_k, uint){
+ function f() returns(uint ret_k, uint) {
return 5;
+ }
}
- })";
- BOOST_CHECK(expectError(text) == Error::Type::TypeError);
+ )";
+ CHECK_ERROR(text, TypeError, "");
}
BOOST_AUTO_TEST_CASE(disallow_declaration_of_void_type)
{
- char const* sourceCode = "contract c { function f() { var (x) = f(); } }";
- BOOST_CHECK(expectError(sourceCode) == Error::Type::TypeError);
+ char const* sourceCode = R"(
+ contract c {
+ function f() { var (x) = f(); }
+ }
+ )";
+ CHECK_ERROR(sourceCode, TypeError, "");
}
BOOST_AUTO_TEST_CASE(overflow_caused_by_ether_units)
{
char const* sourceCodeFine = R"(
contract c {
- function c ()
- {
- a = 115792089237316195423570985008687907853269984665640564039458;
+ function c () {
+ a = 115792089237316195423570985008687907853269984665640564039458;
}
uint256 a;
- })";
+ }
+ )";
ETH_TEST_CHECK_NO_THROW(parseAndAnalyse(sourceCodeFine),
"Parsing and Resolving names failed");
char const* sourceCode = R"(
contract c {
- function c ()
- {
+ function c () {
a = 115792089237316195423570985008687907853269984665640564039458 ether;
}
uint256 a;
- })";
- BOOST_CHECK(expectError(sourceCode) == Error::Type::TypeError);
+ }
+ )";
+ CHECK_ERROR(sourceCode, TypeError, "");
}
BOOST_AUTO_TEST_CASE(exp_operator_exponent_too_big)
@@ -1420,119 +1590,127 @@ BOOST_AUTO_TEST_CASE(exp_operator_exponent_too_big)
char const* sourceCode = R"(
contract test {
function f() returns(uint d) { return 2 ** 10000000000; }
- })";
- BOOST_CHECK(expectError(sourceCode) == Error::Type::TypeError);
+ }
+ )";
+ CHECK_ERROR(sourceCode, TypeError, "");
}
BOOST_AUTO_TEST_CASE(enum_member_access)
{
char const* text = R"(
- contract test {
- enum ActionChoices { GoLeft, GoRight, GoStraight, Sit }
- function test()
- {
- choices = ActionChoices.GoStraight;
- }
- ActionChoices choices;
+ contract test {
+ enum ActionChoices { GoLeft, GoRight, GoStraight, Sit }
+ function test()
+ {
+ choices = ActionChoices.GoStraight;
}
+ ActionChoices choices;
+ }
)";
- BOOST_CHECK(success(text));
+ CHECK_SUCCESS(text);
}
BOOST_AUTO_TEST_CASE(enum_member_access_accross_contracts)
{
char const* text = R"(
- contract Interface {
- enum MyEnum { One, Two }
- }
- contract Impl {
- function test() returns (Interface.MyEnum) {
- return Interface.MyEnum.One;
- }
+ contract Interface {
+ enum MyEnum { One, Two }
+ }
+ contract Impl {
+ function test() returns (Interface.MyEnum) {
+ return Interface.MyEnum.One;
}
+ }
)";
- BOOST_CHECK(success(text));
+ CHECK_SUCCESS(text);
}
BOOST_AUTO_TEST_CASE(enum_invalid_member_access)
{
char const* text = R"(
- contract test {
- enum ActionChoices { GoLeft, GoRight, GoStraight, Sit }
- function test()
- {
- choices = ActionChoices.RunAroundWavingYourHands;
- }
- ActionChoices choices;
+ contract test {
+ enum ActionChoices { GoLeft, GoRight, GoStraight, Sit }
+ function test() {
+ choices = ActionChoices.RunAroundWavingYourHands;
}
+ ActionChoices choices;
+ }
)";
- BOOST_CHECK(expectError(text) == Error::Type::TypeError);
+ CHECK_ERROR(text, TypeError, "");
}
BOOST_AUTO_TEST_CASE(enum_invalid_direct_member_access)
{
char const* text = R"(
- contract test {
- enum ActionChoices { GoLeft, GoRight, GoStraight, Sit }
- function test()
- {
- choices = Sit;
- }
- ActionChoices choices;
+ contract test {
+ enum ActionChoices { GoLeft, GoRight, GoStraight, Sit }
+ function test() {
+ choices = Sit;
}
+ ActionChoices choices;
+ }
)";
- BOOST_CHECK(expectError(text) == Error::Type::DeclarationError);
+ CHECK_ERROR(text, DeclarationError, "");
}
BOOST_AUTO_TEST_CASE(enum_explicit_conversion_is_okay)
{
char const* text = R"(
- contract test {
- enum ActionChoices { GoLeft, GoRight, GoStraight, Sit }
- function test()
- {
- a = uint256(ActionChoices.GoStraight);
- b = uint64(ActionChoices.Sit);
- }
- uint256 a;
- uint64 b;
+ contract test {
+ enum ActionChoices { GoLeft, GoRight, GoStraight, Sit }
+ function test() {
+ a = uint256(ActionChoices.GoStraight);
+ b = uint64(ActionChoices.Sit);
}
+ uint256 a;
+ uint64 b;
+ }
)";
- BOOST_CHECK(success(text));
+ CHECK_SUCCESS(text);
}
BOOST_AUTO_TEST_CASE(int_to_enum_explicit_conversion_is_okay)
{
char const* text = R"(
- contract test {
- enum ActionChoices { GoLeft, GoRight, GoStraight, Sit }
- function test()
- {
- a = 2;
- b = ActionChoices(a);
- }
- uint256 a;
- ActionChoices b;
+ contract test {
+ enum ActionChoices { GoLeft, GoRight, GoStraight, Sit }
+ function test() {
+ a = 2;
+ b = ActionChoices(a);
}
+ uint256 a;
+ ActionChoices b;
+ }
)";
- BOOST_CHECK(success(text));
+ CHECK_SUCCESS(text);
}
-BOOST_AUTO_TEST_CASE(enum_implicit_conversion_is_not_okay)
+BOOST_AUTO_TEST_CASE(enum_implicit_conversion_is_not_okay_256)
{
char const* text = R"(
- contract test {
- enum ActionChoices { GoLeft, GoRight, GoStraight, Sit }
- function test()
- {
- a = ActionChoices.GoStraight;
- b = ActionChoices.Sit;
- }
- uint256 a;
- uint64 b;
+ contract test {
+ enum ActionChoices { GoLeft, GoRight, GoStraight, Sit }
+ function test() {
+ a = ActionChoices.GoStraight;
}
+ uint256 a;
+ }
+ )";
+ CHECK_ERROR(text, TypeError, "");
+}
+
+BOOST_AUTO_TEST_CASE(enum_implicit_conversion_is_not_okay_64)
+{
+ char const* text = R"(
+ contract test {
+ enum ActionChoices { GoLeft, GoRight, GoStraight, Sit }
+ function test() {
+ b = ActionChoices.Sit;
+ }
+ uint64 b;
+ }
)";
- BOOST_CHECK(expectError(text) == Error::Type::TypeError);
+ CHECK_ERROR(text, TypeError, "");
}
BOOST_AUTO_TEST_CASE(enum_to_enum_conversion_is_not_okay)
@@ -1541,13 +1719,12 @@ BOOST_AUTO_TEST_CASE(enum_to_enum_conversion_is_not_okay)
contract test {
enum Paper { Up, Down, Left, Right }
enum Ground { North, South, West, East }
- function test()
- {
+ function test() {
Ground(Paper.Up);
}
}
)";
- BOOST_CHECK(expectError(text) == Error::Type::TypeError);
+ CHECK_ERROR(text, TypeError, "");
}
BOOST_AUTO_TEST_CASE(enum_duplicate_values)
@@ -1557,7 +1734,7 @@ BOOST_AUTO_TEST_CASE(enum_duplicate_values)
enum ActionChoices { GoLeft, GoRight, GoLeft, Sit }
}
)";
- BOOST_CHECK(expectError(text) == Error::Type::DeclarationError);
+ CHECK_ERROR(text, DeclarationError, "");
}
BOOST_AUTO_TEST_CASE(enum_name_resolution_under_current_contract_name)
@@ -1574,7 +1751,7 @@ BOOST_AUTO_TEST_CASE(enum_name_resolution_under_current_contract_name)
}
}
)";
- BOOST_CHECK(success(text));
+ CHECK_SUCCESS(text);
}
BOOST_AUTO_TEST_CASE(private_visibility)
@@ -1586,8 +1763,8 @@ BOOST_AUTO_TEST_CASE(private_visibility)
contract derived is base {
function g() { f(); }
}
- )";
- BOOST_CHECK(expectError(sourceCode) == Error::Type::DeclarationError);
+ )";
+ CHECK_ERROR(sourceCode, DeclarationError, "");
}
BOOST_AUTO_TEST_CASE(private_visibility_via_explicit_base_access)
@@ -1599,8 +1776,8 @@ BOOST_AUTO_TEST_CASE(private_visibility_via_explicit_base_access)
contract derived is base {
function g() { base.f(); }
}
- )";
- BOOST_CHECK(expectError(sourceCode) == Error::Type::TypeError);
+ )";
+ CHECK_ERROR(sourceCode, TypeError, "");
}
BOOST_AUTO_TEST_CASE(external_visibility)
@@ -1610,8 +1787,8 @@ BOOST_AUTO_TEST_CASE(external_visibility)
function f() external {}
function g() { f(); }
}
- )";
- BOOST_CHECK(expectError(sourceCode) == Error::Type::DeclarationError);
+ )";
+ CHECK_ERROR(sourceCode, DeclarationError, "");
}
BOOST_AUTO_TEST_CASE(external_base_visibility)
@@ -1623,8 +1800,8 @@ BOOST_AUTO_TEST_CASE(external_base_visibility)
contract derived is base {
function g() { base.f(); }
}
- )";
- BOOST_CHECK(expectError(sourceCode) == Error::Type::TypeError);
+ )";
+ CHECK_ERROR(sourceCode, TypeError, "");
}
BOOST_AUTO_TEST_CASE(external_argument_assign)
@@ -1633,8 +1810,8 @@ BOOST_AUTO_TEST_CASE(external_argument_assign)
contract c {
function f(uint a) external { a = 1; }
}
- )";
- BOOST_CHECK(expectError(sourceCode) == Error::Type::TypeError);
+ )";
+ CHECK_ERROR(sourceCode, TypeError, "");
}
BOOST_AUTO_TEST_CASE(external_argument_increment)
@@ -1643,8 +1820,8 @@ BOOST_AUTO_TEST_CASE(external_argument_increment)
contract c {
function f(uint a) external { a++; }
}
- )";
- BOOST_CHECK(expectError(sourceCode) == Error::Type::TypeError);
+ )";
+ CHECK_ERROR(sourceCode, TypeError, "");
}
BOOST_AUTO_TEST_CASE(external_argument_delete)
@@ -1653,8 +1830,8 @@ BOOST_AUTO_TEST_CASE(external_argument_delete)
contract c {
function f(uint a) external { delete a; }
}
- )";
- BOOST_CHECK(expectError(sourceCode) == Error::Type::TypeError);
+ )";
+ CHECK_ERROR(sourceCode, TypeError, "");
}
BOOST_AUTO_TEST_CASE(test_for_bug_override_function_with_bytearray_type)
@@ -1666,7 +1843,7 @@ BOOST_AUTO_TEST_CASE(test_for_bug_override_function_with_bytearray_type)
contract Bike is Vehicle {
function f(bytes _a) external returns (uint256 r) {r = 42;}
}
- )";
+ )";
ETH_TEST_CHECK_NO_THROW(parseAndAnalyse(sourceCode), "Parsing and Name Resolving failed");
}
@@ -1675,8 +1852,9 @@ BOOST_AUTO_TEST_CASE(array_with_nonconstant_length)
char const* text = R"(
contract c {
function f(uint a) { uint8[a] x; }
- })";
- BOOST_CHECK(expectError(text) == Error::Type::TypeError);
+ }
+ )";
+ CHECK_ERROR(text, TypeError, "");
}
BOOST_AUTO_TEST_CASE(array_copy_with_different_types1)
@@ -1686,8 +1864,9 @@ BOOST_AUTO_TEST_CASE(array_copy_with_different_types1)
bytes a;
uint[] b;
function f() { b = a; }
- })";
- BOOST_CHECK(expectError(text) == Error::Type::TypeError);
+ }
+ )";
+ CHECK_ERROR(text, TypeError, "");
}
BOOST_AUTO_TEST_CASE(array_copy_with_different_types2)
@@ -1697,8 +1876,9 @@ BOOST_AUTO_TEST_CASE(array_copy_with_different_types2)
uint32[] a;
uint8[] b;
function f() { b = a; }
- })";
- BOOST_CHECK(expectError(text) == Error::Type::TypeError);
+ }
+ )";
+ CHECK_ERROR(text, TypeError, "");
}
BOOST_AUTO_TEST_CASE(array_copy_with_different_types_conversion_possible)
@@ -1708,8 +1888,9 @@ BOOST_AUTO_TEST_CASE(array_copy_with_different_types_conversion_possible)
uint32[] a;
uint8[] b;
function f() { a = b; }
- })";
- BOOST_CHECK(success(text));
+ }
+ )";
+ CHECK_SUCCESS(text);
}
BOOST_AUTO_TEST_CASE(array_copy_with_different_types_static_dynamic)
@@ -1719,8 +1900,9 @@ BOOST_AUTO_TEST_CASE(array_copy_with_different_types_static_dynamic)
uint32[] a;
uint8[80] b;
function f() { a = b; }
- })";
- BOOST_CHECK(success(text));
+ }
+ )";
+ CHECK_SUCCESS(text);
}
BOOST_AUTO_TEST_CASE(array_copy_with_different_types_dynamic_static)
@@ -1730,8 +1912,9 @@ BOOST_AUTO_TEST_CASE(array_copy_with_different_types_dynamic_static)
uint[] a;
uint[80] b;
function f() { b = a; }
- })";
- BOOST_CHECK(expectError(text) == Error::Type::TypeError);
+ }
+ )";
+ CHECK_ERROR(text, TypeError, "");
}
BOOST_AUTO_TEST_CASE(storage_variable_initialization_with_incorrect_type_int)
@@ -1739,8 +1922,9 @@ BOOST_AUTO_TEST_CASE(storage_variable_initialization_with_incorrect_type_int)
char const* text = R"(
contract c {
uint8 a = 1000;
- })";
- BOOST_CHECK(expectError(text) == Error::Type::TypeError);
+ }
+ )";
+ CHECK_ERROR(text, TypeError, "");
}
BOOST_AUTO_TEST_CASE(storage_variable_initialization_with_incorrect_type_string)
@@ -1748,8 +1932,9 @@ BOOST_AUTO_TEST_CASE(storage_variable_initialization_with_incorrect_type_string)
char const* text = R"(
contract c {
uint a = "abc";
- })";
- BOOST_CHECK(expectError(text) == Error::Type::TypeError);
+ }
+ )";
+ CHECK_ERROR(text, TypeError, "");
}
BOOST_AUTO_TEST_CASE(test_fromElementaryTypeName)
@@ -1864,7 +2049,8 @@ BOOST_AUTO_TEST_CASE(test_byte_is_alias_of_byte1)
contract c {
bytes arr;
function f() { byte a = arr[0];}
- })";
+ }
+ )";
ETH_TEST_REQUIRE_NO_THROW(parseAndAnalyse(text), "Type resolving failed");
}
@@ -1874,8 +2060,9 @@ BOOST_AUTO_TEST_CASE(assigning_value_to_const_variable)
contract Foo {
function changeIt() { x = 9; }
uint constant x = 56;
- })";
- BOOST_CHECK(expectError(text) == Error::Type::TypeError);
+ }
+ )";
+ CHECK_ERROR(text, TypeError, "");
}
BOOST_AUTO_TEST_CASE(complex_const_variable)
@@ -1883,9 +2070,11 @@ BOOST_AUTO_TEST_CASE(complex_const_variable)
//for now constant specifier is valid only for uint bytesXX and enums
char const* text = R"(
contract Foo {
- mapping(uint => bool) constant mapVar;
- })";
- BOOST_CHECK(expectError(text) == Error::Type::TypeError);
+ mapping(uint => bool) x;
+ mapping(uint => bool) constant mapVar = x;
+ }
+ )";
+ CHECK_ERROR(text, TypeError, "");
}
BOOST_AUTO_TEST_CASE(uninitialized_const_variable)
@@ -1893,8 +2082,9 @@ BOOST_AUTO_TEST_CASE(uninitialized_const_variable)
char const* text = R"(
contract Foo {
uint constant y;
- })";
- BOOST_CHECK(expectError(text) == Error::Type::TypeError);
+ }
+ )";
+ CHECK_ERROR(text, TypeError, "");
}
BOOST_AUTO_TEST_CASE(overloaded_function_cannot_resolve)
@@ -1906,7 +2096,7 @@ BOOST_AUTO_TEST_CASE(overloaded_function_cannot_resolve)
function g() returns(uint) { return f(3, 5); }
}
)";
- BOOST_CHECK(expectError(sourceCode) == Error::Type::TypeError);
+ CHECK_ERROR(sourceCode, TypeError, "");
}
BOOST_AUTO_TEST_CASE(ambiguous_overloaded_function)
@@ -1919,7 +2109,7 @@ BOOST_AUTO_TEST_CASE(ambiguous_overloaded_function)
function g() returns(uint) { return f(1); }
}
)";
- BOOST_CHECK(expectError(sourceCode) == Error::Type::TypeError);
+ CHECK_ERROR(sourceCode, TypeError, "");
}
BOOST_AUTO_TEST_CASE(assignment_of_nonoverloaded_function)
@@ -1942,7 +2132,7 @@ BOOST_AUTO_TEST_CASE(assignment_of_overloaded_function)
function g() returns(uint) { var x = f; return x(7); }
}
)";
- BOOST_CHECK(expectError(sourceCode) == Error::Type::TypeError);
+ CHECK_ERROR(sourceCode, TypeError, "");
}
BOOST_AUTO_TEST_CASE(external_types_clash)
@@ -1956,7 +2146,7 @@ BOOST_AUTO_TEST_CASE(external_types_clash)
function f(uint8 a) { }
}
)";
- BOOST_CHECK(expectError(sourceCode) == Error::Type::TypeError);
+ CHECK_ERROR(sourceCode, TypeError, "");
}
BOOST_AUTO_TEST_CASE(override_changes_return_types)
@@ -1969,7 +2159,7 @@ BOOST_AUTO_TEST_CASE(override_changes_return_types)
function f(uint a) returns (uint8) { }
}
)";
- BOOST_CHECK(expectError(sourceCode) == Error::Type::TypeError);
+ CHECK_ERROR(sourceCode, TypeError, "");
}
BOOST_AUTO_TEST_CASE(multiple_constructors)
@@ -1980,18 +2170,18 @@ BOOST_AUTO_TEST_CASE(multiple_constructors)
function test() {}
}
)";
- BOOST_CHECK(expectError(sourceCode) == Error::Type::DeclarationError);
+ CHECK_ERROR(sourceCode, DeclarationError, "");
}
BOOST_AUTO_TEST_CASE(equal_overload)
{
char const* sourceCode = R"(
- contract test {
+ contract C {
function test(uint a) returns (uint b) { }
function test(uint a) external {}
}
)";
- BOOST_CHECK(expectError(sourceCode) == Error::Type::DeclarationError);
+ CHECK_ERROR_ALLOW_MULTI(sourceCode, DeclarationError, "");
}
BOOST_AUTO_TEST_CASE(uninitialized_var)
@@ -2001,7 +2191,7 @@ BOOST_AUTO_TEST_CASE(uninitialized_var)
function f() returns (uint) { var x; return 2; }
}
)";
- BOOST_CHECK(expectError(sourceCode) == Error::Type::TypeError);
+ CHECK_ERROR(sourceCode, TypeError, "");
}
BOOST_AUTO_TEST_CASE(string)
@@ -2015,6 +2205,26 @@ BOOST_AUTO_TEST_CASE(string)
BOOST_CHECK_NO_THROW(parseAndAnalyse(sourceCode));
}
+BOOST_AUTO_TEST_CASE(invalid_utf8_implicit)
+{
+ char const* sourceCode = R"(
+ contract C {
+ string s = "\xa0\x00";
+ }
+ )";
+ CHECK_ERROR(sourceCode, TypeError, "invalid UTF-8");
+}
+
+BOOST_AUTO_TEST_CASE(invalid_utf8_explicit)
+{
+ char const* sourceCode = R"(
+ contract C {
+ string s = string("\xa0\x00");
+ }
+ )";
+ CHECK_ERROR(sourceCode, TypeError, "Explicit type conversion not allowed");
+}
+
BOOST_AUTO_TEST_CASE(string_index)
{
char const* sourceCode = R"(
@@ -2023,7 +2233,7 @@ BOOST_AUTO_TEST_CASE(string_index)
function f() { var a = s[2]; }
}
)";
- BOOST_CHECK(expectError(sourceCode) == Error::Type::TypeError);
+ CHECK_ERROR(sourceCode, TypeError, "");
}
BOOST_AUTO_TEST_CASE(string_length)
@@ -2034,7 +2244,7 @@ BOOST_AUTO_TEST_CASE(string_length)
function f() { var a = s.length; }
}
)";
- BOOST_CHECK(expectError(sourceCode) == Error::Type::TypeError);
+ CHECK_ERROR(sourceCode, TypeError, "");
}
BOOST_AUTO_TEST_CASE(negative_integers_to_signed_out_of_bound)
@@ -2044,7 +2254,7 @@ BOOST_AUTO_TEST_CASE(negative_integers_to_signed_out_of_bound)
int8 public i = -129;
}
)";
- BOOST_CHECK(expectError(sourceCode) == Error::Type::TypeError);
+ CHECK_ERROR(sourceCode, TypeError, "");
}
BOOST_AUTO_TEST_CASE(negative_integers_to_signed_min)
@@ -2064,7 +2274,7 @@ BOOST_AUTO_TEST_CASE(positive_integers_to_signed_out_of_bound)
int8 public j = 128;
}
)";
- BOOST_CHECK(expectError(sourceCode) == Error::Type::TypeError);
+ CHECK_ERROR(sourceCode, TypeError, "");
}
BOOST_AUTO_TEST_CASE(positive_integers_to_signed_out_of_bound_max)
@@ -2084,7 +2294,7 @@ BOOST_AUTO_TEST_CASE(negative_integers_to_unsigned)
uint8 public x = -1;
}
)";
- BOOST_CHECK(expectError(sourceCode) == Error::Type::TypeError);
+ CHECK_ERROR(sourceCode, TypeError, "");
}
BOOST_AUTO_TEST_CASE(positive_integers_to_unsigned_out_of_bound)
@@ -2094,7 +2304,7 @@ BOOST_AUTO_TEST_CASE(positive_integers_to_unsigned_out_of_bound)
uint8 public x = 700;
}
)";
- BOOST_CHECK(expectError(sourceCode) == Error::Type::TypeError);
+ CHECK_ERROR(sourceCode, TypeError, "");
}
BOOST_AUTO_TEST_CASE(integer_boolean_operators)
@@ -2102,15 +2312,15 @@ BOOST_AUTO_TEST_CASE(integer_boolean_operators)
char const* sourceCode1 = R"(
contract test { function() { uint x = 1; uint y = 2; x || y; } }
)";
- BOOST_CHECK(expectError(sourceCode1) == Error::Type::TypeError);
+ CHECK_ERROR(sourceCode1, TypeError, "");
char const* sourceCode2 = R"(
contract test { function() { uint x = 1; uint y = 2; x && y; } }
)";
- BOOST_CHECK(expectError(sourceCode2) == Error::Type::TypeError);
+ CHECK_ERROR(sourceCode2, TypeError, "");
char const* sourceCode3 = R"(
contract test { function() { uint x = 1; !x; } }
)";
- BOOST_CHECK(expectError(sourceCode3) == Error::Type::TypeError);
+ CHECK_ERROR(sourceCode3, TypeError, "");
}
BOOST_AUTO_TEST_CASE(exp_signed_variable)
@@ -2118,15 +2328,15 @@ BOOST_AUTO_TEST_CASE(exp_signed_variable)
char const* sourceCode1 = R"(
contract test { function() { uint x = 3; int y = -4; x ** y; } }
)";
- BOOST_CHECK(expectError(sourceCode1) == Error::Type::TypeError);
+ CHECK_ERROR(sourceCode1, TypeError, "");
char const* sourceCode2 = R"(
contract test { function() { uint x = 3; int y = -4; y ** x; } }
)";
- BOOST_CHECK(expectError(sourceCode2) == Error::Type::TypeError);
+ CHECK_ERROR(sourceCode2, TypeError, "");
char const* sourceCode3 = R"(
contract test { function() { int x = -3; int y = -4; x ** y; } }
)";
- BOOST_CHECK(expectError(sourceCode3) == Error::Type::TypeError);
+ CHECK_ERROR(sourceCode3, TypeError, "");
}
BOOST_AUTO_TEST_CASE(reference_compare_operators)
@@ -2134,11 +2344,11 @@ BOOST_AUTO_TEST_CASE(reference_compare_operators)
char const* sourceCode1 = R"(
contract test { bytes a; bytes b; function() { a == b; } }
)";
- BOOST_CHECK(expectError(sourceCode1) == Error::Type::TypeError);
+ CHECK_ERROR(sourceCode1, TypeError, "");
char const* sourceCode2 = R"(
contract test { struct s {uint a;} s x; s y; function() { x == y; } }
)";
- BOOST_CHECK(expectError(sourceCode2) == Error::Type::TypeError);
+ CHECK_ERROR(sourceCode2, TypeError, "");
}
BOOST_AUTO_TEST_CASE(overwrite_memory_location_external)
@@ -2148,7 +2358,7 @@ BOOST_AUTO_TEST_CASE(overwrite_memory_location_external)
function f(uint[] memory a) external {}
}
)";
- BOOST_CHECK(expectError(sourceCode) == Error::Type::TypeError);
+ CHECK_ERROR(sourceCode, TypeError, "");
}
BOOST_AUTO_TEST_CASE(overwrite_storage_location_external)
@@ -2158,7 +2368,7 @@ BOOST_AUTO_TEST_CASE(overwrite_storage_location_external)
function f(uint[] storage a) external {}
}
)";
- BOOST_CHECK(expectError(sourceCode) == Error::Type::TypeError);
+ CHECK_ERROR(sourceCode, TypeError, "");
}
BOOST_AUTO_TEST_CASE(storage_location_local_variables)
@@ -2184,7 +2394,7 @@ BOOST_AUTO_TEST_CASE(no_mappings_in_memory_array)
}
}
)";
- BOOST_CHECK(expectError(sourceCode) == Error::Type::TypeError);
+ CHECK_ERROR(sourceCode, TypeError, "");
}
BOOST_AUTO_TEST_CASE(assignment_mem_to_local_storage_variable)
@@ -2198,7 +2408,7 @@ BOOST_AUTO_TEST_CASE(assignment_mem_to_local_storage_variable)
}
}
)";
- BOOST_CHECK(expectError(sourceCode) == Error::Type::TypeError);
+ CHECK_ERROR(sourceCode, TypeError, "");
}
BOOST_AUTO_TEST_CASE(storage_assign_to_different_local_variable)
@@ -2215,7 +2425,7 @@ BOOST_AUTO_TEST_CASE(storage_assign_to_different_local_variable)
}
}
)";
- BOOST_CHECK(expectError(sourceCode) == Error::Type::TypeError);
+ CHECK_ERROR(sourceCode, TypeError, "");
}
BOOST_AUTO_TEST_CASE(no_delete_on_storage_pointers)
@@ -2229,7 +2439,7 @@ BOOST_AUTO_TEST_CASE(no_delete_on_storage_pointers)
}
}
)";
- BOOST_CHECK(expectError(sourceCode) == Error::Type::TypeError);
+ CHECK_ERROR(sourceCode, TypeError, "");
}
BOOST_AUTO_TEST_CASE(assignment_mem_storage_variable_directly)
@@ -2256,7 +2466,7 @@ BOOST_AUTO_TEST_CASE(function_argument_mem_to_storage)
}
}
)";
- BOOST_CHECK(expectError(sourceCode) == Error::Type::TypeError);
+ CHECK_ERROR(sourceCode, TypeError, "");
}
BOOST_AUTO_TEST_CASE(function_argument_storage_to_mem)
@@ -2285,7 +2495,7 @@ BOOST_AUTO_TEST_CASE(mem_array_assignment_changes_base_type)
}
}
)";
- BOOST_CHECK(expectError(sourceCode) == Error::Type::TypeError);
+ CHECK_ERROR(sourceCode, TypeError, "");
}
BOOST_AUTO_TEST_CASE(dynamic_return_types_not_possible)
@@ -2300,7 +2510,7 @@ BOOST_AUTO_TEST_CASE(dynamic_return_types_not_possible)
}
}
)";
- BOOST_CHECK(expectError(sourceCode) == Error::Type::TypeError);
+ CHECK_ERROR(sourceCode, TypeError, "");
}
BOOST_AUTO_TEST_CASE(memory_arrays_not_resizeable)
@@ -2313,7 +2523,7 @@ BOOST_AUTO_TEST_CASE(memory_arrays_not_resizeable)
}
}
)";
- BOOST_CHECK(expectError(sourceCode) == Error::Type::TypeError);
+ CHECK_ERROR(sourceCode, TypeError, "");
}
BOOST_AUTO_TEST_CASE(struct_constructor)
@@ -2367,7 +2577,7 @@ BOOST_AUTO_TEST_CASE(literal_strings)
}
}
)";
- BOOST_CHECK(success(text));
+ CHECK_SUCCESS(text);
}
BOOST_AUTO_TEST_CASE(invalid_integer_literal_exp)
@@ -2379,7 +2589,7 @@ BOOST_AUTO_TEST_CASE(invalid_integer_literal_exp)
}
}
)";
- BOOST_CHECK(expectError(text) == Error::Type::TypeError);
+ CHECK_ERROR(text, TypeError, "");
}
BOOST_AUTO_TEST_CASE(memory_structs_with_mappings)
@@ -2394,7 +2604,7 @@ BOOST_AUTO_TEST_CASE(memory_structs_with_mappings)
}
}
)";
- BOOST_CHECK(expectError(text) == Error::Type::TypeError);
+ CHECK_ERROR(text, TypeError, "");
}
BOOST_AUTO_TEST_CASE(string_bytes_conversion)
@@ -2411,7 +2621,7 @@ BOOST_AUTO_TEST_CASE(string_bytes_conversion)
function m() internal { string(b); }
}
)";
- BOOST_CHECK(success(text));
+ CHECK_SUCCESS(text);
}
BOOST_AUTO_TEST_CASE(inheriting_from_library)
@@ -2420,7 +2630,7 @@ BOOST_AUTO_TEST_CASE(inheriting_from_library)
library Lib {}
contract Test is Lib {}
)";
- BOOST_CHECK(expectError(text) == Error::Type::TypeError);
+ CHECK_ERROR(text, TypeError, "");
}
BOOST_AUTO_TEST_CASE(inheriting_library)
@@ -2429,7 +2639,7 @@ BOOST_AUTO_TEST_CASE(inheriting_library)
contract Test {}
library Lib is Test {}
)";
- BOOST_CHECK(expectError(text) == Error::Type::TypeError);
+ CHECK_ERROR(text, TypeError, "");
}
BOOST_AUTO_TEST_CASE(library_having_variables)
@@ -2437,7 +2647,7 @@ BOOST_AUTO_TEST_CASE(library_having_variables)
char const* text = R"(
library Lib { uint x; }
)";
- BOOST_CHECK(expectError(text) == Error::Type::TypeError);
+ CHECK_ERROR(text, TypeError, "");
}
BOOST_AUTO_TEST_CASE(valid_library)
@@ -2445,7 +2655,7 @@ BOOST_AUTO_TEST_CASE(valid_library)
char const* text = R"(
library Lib { uint constant x = 9; }
)";
- BOOST_CHECK(success(text));
+ CHECK_SUCCESS(text);
}
BOOST_AUTO_TEST_CASE(call_to_library_function)
@@ -2460,7 +2670,7 @@ BOOST_AUTO_TEST_CASE(call_to_library_function)
}
}
)";
- BOOST_CHECK(success(text));
+ CHECK_SUCCESS(text);
}
BOOST_AUTO_TEST_CASE(creating_contract_within_the_contract)
@@ -2470,7 +2680,7 @@ BOOST_AUTO_TEST_CASE(creating_contract_within_the_contract)
function f() { var x = new Test(); }
}
)";
- BOOST_CHECK(expectError(sourceCode) == Error::Type::TypeError);
+ CHECK_ERROR(sourceCode, TypeError, "");
}
BOOST_AUTO_TEST_CASE(array_out_of_bound_access)
@@ -2484,7 +2694,7 @@ BOOST_AUTO_TEST_CASE(array_out_of_bound_access)
}
}
)";
- BOOST_CHECK(expectError(text) == Error::Type::TypeError);
+ CHECK_ERROR(text, TypeError, "");
}
BOOST_AUTO_TEST_CASE(literal_string_to_storage_pointer)
@@ -2494,7 +2704,7 @@ BOOST_AUTO_TEST_CASE(literal_string_to_storage_pointer)
function f() { string x = "abc"; }
}
)";
- BOOST_CHECK(expectError(text) == Error::Type::TypeError);
+ CHECK_ERROR(text, TypeError, "");
}
BOOST_AUTO_TEST_CASE(non_initialized_references)
@@ -2513,7 +2723,7 @@ BOOST_AUTO_TEST_CASE(non_initialized_references)
}
)";
- BOOST_CHECK(expectError(text, true) == Error::Type::Warning);
+ CHECK_WARNING(text, "Uninitialized storage pointer");
}
BOOST_AUTO_TEST_CASE(sha3_with_large_integer_constant)
@@ -2524,7 +2734,7 @@ BOOST_AUTO_TEST_CASE(sha3_with_large_integer_constant)
function f() { sha3(2**500); }
}
)";
- BOOST_CHECK(expectError(text) == Error::Type::TypeError);
+ CHECK_ERROR(text, TypeError, "");
}
BOOST_AUTO_TEST_CASE(cyclic_binary_dependency)
@@ -2534,7 +2744,7 @@ BOOST_AUTO_TEST_CASE(cyclic_binary_dependency)
contract B { function f() { new C(); } }
contract C { function f() { new A(); } }
)";
- BOOST_CHECK(expectError(text) == Error::Type::TypeError);
+ CHECK_ERROR(text, TypeError, "");
}
BOOST_AUTO_TEST_CASE(cyclic_binary_dependency_via_inheritance)
@@ -2544,7 +2754,7 @@ BOOST_AUTO_TEST_CASE(cyclic_binary_dependency_via_inheritance)
contract B { function f() { new C(); } }
contract C { function f() { new A(); } }
)";
- BOOST_CHECK(expectError(text) == Error::Type::TypeError);
+ CHECK_ERROR(text, TypeError, "");
}
BOOST_AUTO_TEST_CASE(multi_variable_declaration_fail)
@@ -2552,7 +2762,7 @@ BOOST_AUTO_TEST_CASE(multi_variable_declaration_fail)
char const* text = R"(
contract C { function f() { var (x,y); } }
)";
- BOOST_CHECK(expectError(text) == Error::Type::TypeError);
+ CHECK_ERROR(text, TypeError, "");
}
BOOST_AUTO_TEST_CASE(multi_variable_declaration_wildcards_fine)
@@ -2572,7 +2782,7 @@ BOOST_AUTO_TEST_CASE(multi_variable_declaration_wildcards_fine)
}
}
)";
- BOOST_CHECK(success(text));
+ CHECK_SUCCESS(text);
}
BOOST_AUTO_TEST_CASE(multi_variable_declaration_wildcards_fail_1)
@@ -2583,7 +2793,7 @@ BOOST_AUTO_TEST_CASE(multi_variable_declaration_wildcards_fail_1)
function f() { var (a, b, ) = one(); }
}
)";
- BOOST_CHECK(expectError(text) == Error::Type::TypeError);
+ CHECK_ERROR(text, TypeError, "");
}
BOOST_AUTO_TEST_CASE(multi_variable_declaration_wildcards_fail_2)
{
@@ -2593,7 +2803,7 @@ BOOST_AUTO_TEST_CASE(multi_variable_declaration_wildcards_fail_2)
function f() { var (a, , ) = one(); }
}
)";
- BOOST_CHECK(expectError(text) == Error::Type::TypeError);
+ CHECK_ERROR(text, TypeError, "");
}
BOOST_AUTO_TEST_CASE(multi_variable_declaration_wildcards_fail_3)
@@ -2604,7 +2814,7 @@ BOOST_AUTO_TEST_CASE(multi_variable_declaration_wildcards_fail_3)
function f() { var (, , a) = one(); }
}
)";
- BOOST_CHECK(expectError(text) == Error::Type::TypeError);
+ CHECK_ERROR(text, TypeError, "");
}
BOOST_AUTO_TEST_CASE(multi_variable_declaration_wildcards_fail_4)
@@ -2615,7 +2825,7 @@ BOOST_AUTO_TEST_CASE(multi_variable_declaration_wildcards_fail_4)
function f() { var (, a, b) = one(); }
}
)";
- BOOST_CHECK(expectError(text) == Error::Type::TypeError);
+ CHECK_ERROR(text, TypeError, "");
}
BOOST_AUTO_TEST_CASE(tuples)
@@ -2630,7 +2840,7 @@ BOOST_AUTO_TEST_CASE(tuples)
}
}
)";
- BOOST_CHECK(success(text));
+ CHECK_SUCCESS(text);
}
BOOST_AUTO_TEST_CASE(tuples_empty_components)
@@ -2642,7 +2852,7 @@ BOOST_AUTO_TEST_CASE(tuples_empty_components)
}
}
)";
- BOOST_CHECK(expectError(text) == Error::Type::TypeError);
+ CHECK_ERROR(text, TypeError, "");
}
BOOST_AUTO_TEST_CASE(multi_variable_declaration_wildcards_fail_5)
@@ -2653,7 +2863,7 @@ BOOST_AUTO_TEST_CASE(multi_variable_declaration_wildcards_fail_5)
function f() { var (,) = one(); }
}
)";
- BOOST_CHECK(expectError(text) == Error::Type::TypeError);
+ CHECK_ERROR(text, TypeError, "");
}
BOOST_AUTO_TEST_CASE(multi_variable_declaration_wildcards_fail_6)
@@ -2664,7 +2874,7 @@ BOOST_AUTO_TEST_CASE(multi_variable_declaration_wildcards_fail_6)
function f() { var (a, b, c) = two(); }
}
)";
- BOOST_CHECK(expectError(text) == Error::Type::TypeError);
+ CHECK_ERROR(text, TypeError, "");
}
BOOST_AUTO_TEST_CASE(member_access_parser_ambiguity)
@@ -2685,7 +2895,7 @@ BOOST_AUTO_TEST_CASE(member_access_parser_ambiguity)
}
}
)";
- BOOST_CHECK(success(text));
+ CHECK_SUCCESS(text);
}
BOOST_AUTO_TEST_CASE(using_for_library)
@@ -2696,7 +2906,7 @@ BOOST_AUTO_TEST_CASE(using_for_library)
using D for uint;
}
)";
- BOOST_CHECK(success(text));
+ CHECK_SUCCESS(text);
}
BOOST_AUTO_TEST_CASE(using_for_not_library)
@@ -2707,7 +2917,7 @@ BOOST_AUTO_TEST_CASE(using_for_not_library)
using D for uint;
}
)";
- BOOST_CHECK(expectError(text) == Error::Type::TypeError);
+ CHECK_ERROR(text, TypeError, "");
}
BOOST_AUTO_TEST_CASE(using_for_function_exists)
@@ -2721,7 +2931,7 @@ BOOST_AUTO_TEST_CASE(using_for_function_exists)
}
}
)";
- BOOST_CHECK(success(text));
+ CHECK_SUCCESS(text);
}
BOOST_AUTO_TEST_CASE(using_for_function_on_int)
@@ -2735,7 +2945,7 @@ BOOST_AUTO_TEST_CASE(using_for_function_on_int)
}
}
)";
- BOOST_CHECK(success(text));
+ CHECK_SUCCESS(text);
}
BOOST_AUTO_TEST_CASE(using_for_function_on_struct)
@@ -2750,7 +2960,7 @@ BOOST_AUTO_TEST_CASE(using_for_function_on_struct)
}
}
)";
- BOOST_CHECK(success(text));
+ CHECK_SUCCESS(text);
}
BOOST_AUTO_TEST_CASE(using_for_overload)
@@ -2769,7 +2979,7 @@ BOOST_AUTO_TEST_CASE(using_for_overload)
}
}
)";
- BOOST_CHECK(success(text));
+ CHECK_SUCCESS(text);
}
BOOST_AUTO_TEST_CASE(using_for_by_name)
@@ -2784,7 +2994,7 @@ BOOST_AUTO_TEST_CASE(using_for_by_name)
}
}
)";
- BOOST_CHECK(success(text));
+ CHECK_SUCCESS(text);
}
BOOST_AUTO_TEST_CASE(using_for_mismatch)
@@ -2798,7 +3008,7 @@ BOOST_AUTO_TEST_CASE(using_for_mismatch)
}
}
)";
- BOOST_CHECK(expectError(text) == Error::Type::TypeError);
+ CHECK_ERROR(text, TypeError, "");
}
BOOST_AUTO_TEST_CASE(using_for_not_used)
@@ -2814,7 +3024,18 @@ BOOST_AUTO_TEST_CASE(using_for_not_used)
}
}
)";
- BOOST_CHECK(expectError(text) == Error::Type::TypeError);
+ CHECK_ERROR(text, TypeError, "");
+}
+
+BOOST_AUTO_TEST_CASE(library_memory_struct)
+{
+ char const* text = R"(
+ library c {
+ struct S { uint x; }
+ function f() returns (S ) {}
+ }
+ )";
+ CHECK_ERROR(text, TypeError, "");
}
BOOST_AUTO_TEST_CASE(using_for_arbitrary_mismatch)
@@ -2829,7 +3050,7 @@ BOOST_AUTO_TEST_CASE(using_for_arbitrary_mismatch)
}
}
)";
- BOOST_CHECK(expectError(text) == Error::Type::TypeError);
+ CHECK_ERROR(text, TypeError, "");
}
BOOST_AUTO_TEST_CASE(bound_function_in_var)
@@ -2845,7 +3066,7 @@ BOOST_AUTO_TEST_CASE(bound_function_in_var)
}
}
)";
- BOOST_CHECK(success(text));
+ CHECK_SUCCESS(text);
}
BOOST_AUTO_TEST_CASE(create_memory_arrays)
@@ -2863,7 +3084,7 @@ BOOST_AUTO_TEST_CASE(create_memory_arrays)
}
}
)";
- BOOST_CHECK(success(text));
+ CHECK_SUCCESS(text);
}
BOOST_AUTO_TEST_CASE(mapping_in_memory_array)
@@ -2875,7 +3096,7 @@ BOOST_AUTO_TEST_CASE(mapping_in_memory_array)
}
}
)";
- BOOST_CHECK(expectError(text) == Error::Type::TypeError);
+ CHECK_ERROR(text, TypeError, "");
}
BOOST_AUTO_TEST_CASE(new_for_non_array)
@@ -2887,7 +3108,7 @@ BOOST_AUTO_TEST_CASE(new_for_non_array)
}
}
)";
- BOOST_CHECK(expectError(text) == Error::Type::TypeError);
+ CHECK_ERROR(text, TypeError, "");
}
BOOST_AUTO_TEST_CASE(invalid_args_creating_memory_array)
@@ -2899,7 +3120,7 @@ BOOST_AUTO_TEST_CASE(invalid_args_creating_memory_array)
}
}
)";
- BOOST_CHECK(expectError(text) == Error::Type::TypeError);
+ CHECK_ERROR(text, TypeError, "");
}
BOOST_AUTO_TEST_CASE(function_overload_array_type)
@@ -2910,7 +3131,7 @@ BOOST_AUTO_TEST_CASE(function_overload_array_type)
function f(int[] values);
}
)";
- BOOST_CHECK(success(text));
+ CHECK_SUCCESS(text);
}
BOOST_AUTO_TEST_CASE(inline_array_declaration_and_passing_implicit_conversion)
@@ -2926,7 +3147,7 @@ BOOST_AUTO_TEST_CASE(inline_array_declaration_and_passing_implicit_conversion)
}
}
)";
- BOOST_CHECK(success(text));
+ CHECK_SUCCESS(text);
}
BOOST_AUTO_TEST_CASE(inline_array_declaration_and_passing_implicit_conversion_strings)
@@ -2941,7 +3162,7 @@ BOOST_AUTO_TEST_CASE(inline_array_declaration_and_passing_implicit_conversion_st
}
}
)";
- BOOST_CHECK(success(text));
+ CHECK_SUCCESS(text);
}
BOOST_AUTO_TEST_CASE(inline_array_declaration_const_int_conversion)
@@ -2954,7 +3175,7 @@ BOOST_AUTO_TEST_CASE(inline_array_declaration_const_int_conversion)
}
}
)";
- BOOST_CHECK(success(text));
+ CHECK_SUCCESS(text);
}
BOOST_AUTO_TEST_CASE(inline_array_declaration_const_string_conversion)
@@ -2967,7 +3188,7 @@ BOOST_AUTO_TEST_CASE(inline_array_declaration_const_string_conversion)
}
}
)";
- BOOST_CHECK(success(text));
+ CHECK_SUCCESS(text);
}
BOOST_AUTO_TEST_CASE(inline_array_declaration_no_type)
@@ -2979,7 +3200,7 @@ BOOST_AUTO_TEST_CASE(inline_array_declaration_no_type)
}
}
)";
- BOOST_CHECK(success(text));
+ CHECK_SUCCESS(text);
}
BOOST_AUTO_TEST_CASE(inline_array_declaration_no_type_strings)
@@ -2991,7 +3212,7 @@ BOOST_AUTO_TEST_CASE(inline_array_declaration_no_type_strings)
}
}
)";
- BOOST_CHECK(success(text));
+ CHECK_SUCCESS(text);
}
BOOST_AUTO_TEST_CASE(inline_struct_declaration_arrays)
@@ -3007,7 +3228,7 @@ BOOST_AUTO_TEST_CASE(inline_struct_declaration_arrays)
}
}
)";
- BOOST_CHECK(success(text));
+ CHECK_SUCCESS(text);
}
BOOST_AUTO_TEST_CASE(invalid_types_in_inline_array)
@@ -3019,7 +3240,7 @@ BOOST_AUTO_TEST_CASE(invalid_types_in_inline_array)
}
}
)";
- BOOST_CHECK(expectError(text) == Error::Type::TypeError);
+ CHECK_ERROR(text, TypeError, "");
}
BOOST_AUTO_TEST_CASE(dynamic_inline_array)
@@ -3031,7 +3252,7 @@ BOOST_AUTO_TEST_CASE(dynamic_inline_array)
}
}
)";
- BOOST_CHECK(success(text));
+ CHECK_SUCCESS(text);
}
BOOST_AUTO_TEST_CASE(lvalues_as_inline_array)
@@ -3044,7 +3265,7 @@ BOOST_AUTO_TEST_CASE(lvalues_as_inline_array)
}
}
)";
- BOOST_CHECK(expectError(text) == Error::Type::TypeError);
+ CHECK_ERROR(text, TypeError, "");
}
BOOST_AUTO_TEST_CASE(break_not_in_loop)
@@ -3057,7 +3278,7 @@ BOOST_AUTO_TEST_CASE(break_not_in_loop)
}
}
)";
- BOOST_CHECK(expectError(text) == Error::Type::SyntaxError);
+ CHECK_ERROR(text, SyntaxError, "");
}
BOOST_AUTO_TEST_CASE(continue_not_in_loop)
@@ -3070,7 +3291,7 @@ BOOST_AUTO_TEST_CASE(continue_not_in_loop)
}
}
)";
- BOOST_CHECK(expectError(text) == Error::Type::SyntaxError);
+ CHECK_ERROR(text, SyntaxError, "");
}
BOOST_AUTO_TEST_CASE(continue_not_in_loop_2)
@@ -3085,7 +3306,7 @@ BOOST_AUTO_TEST_CASE(continue_not_in_loop_2)
}
}
)";
- BOOST_CHECK(expectError(text) == Error::Type::SyntaxError);
+ CHECK_ERROR(text, SyntaxError, "");
}
BOOST_AUTO_TEST_CASE(invalid_different_types_for_conditional_expression)
@@ -3097,7 +3318,7 @@ BOOST_AUTO_TEST_CASE(invalid_different_types_for_conditional_expression)
}
}
)";
- BOOST_CHECK(expectError(text) == Error::Type::TypeError);
+ CHECK_ERROR(text, TypeError, "");
}
BOOST_AUTO_TEST_CASE(left_value_in_conditional_expression_not_supported_yet)
@@ -3111,7 +3332,7 @@ BOOST_AUTO_TEST_CASE(left_value_in_conditional_expression_not_supported_yet)
}
}
)";
- BOOST_CHECK(expectError(text) == Error::Type::TypeError);
+ CHECK_ERROR_ALLOW_MULTI(text, TypeError, "");
}
BOOST_AUTO_TEST_CASE(conditional_expression_with_different_struct)
@@ -3125,13 +3346,13 @@ BOOST_AUTO_TEST_CASE(conditional_expression_with_different_struct)
uint x;
}
function f() {
- s1 x;
- s2 y;
+ s1 memory x;
+ s2 memory y;
true ? x : y;
}
}
)";
- BOOST_CHECK(expectError(text) == Error::Type::TypeError);
+ CHECK_ERROR(text, TypeError, "");
}
BOOST_AUTO_TEST_CASE(conditional_expression_with_different_function_type)
@@ -3146,7 +3367,7 @@ BOOST_AUTO_TEST_CASE(conditional_expression_with_different_function_type)
}
}
)";
- BOOST_CHECK(expectError(text) == Error::Type::TypeError);
+ CHECK_ERROR(text, TypeError, "");
}
BOOST_AUTO_TEST_CASE(conditional_expression_with_different_enum)
@@ -3164,7 +3385,7 @@ BOOST_AUTO_TEST_CASE(conditional_expression_with_different_enum)
}
}
)";
- BOOST_CHECK(expectError(text) == Error::Type::TypeError);
+ CHECK_ERROR(text, TypeError, "");
}
BOOST_AUTO_TEST_CASE(conditional_expression_with_different_mapping)
@@ -3179,7 +3400,7 @@ BOOST_AUTO_TEST_CASE(conditional_expression_with_different_mapping)
}
}
)";
- BOOST_CHECK(expectError(text) == Error::Type::TypeError);
+ CHECK_ERROR(text, TypeError, "");
}
BOOST_AUTO_TEST_CASE(conditional_with_all_types)
@@ -3261,7 +3482,7 @@ BOOST_AUTO_TEST_CASE(conditional_with_all_types)
}
}
)";
- BOOST_CHECK(success(text));
+ CHECK_SUCCESS(text);
}
BOOST_AUTO_TEST_CASE(constructor_call_invalid_arg_count)
@@ -3276,7 +3497,7 @@ BOOST_AUTO_TEST_CASE(constructor_call_invalid_arg_count)
}
)";
- BOOST_CHECK(expectError(text) == Error::Type::TypeError);
+ CHECK_ERROR(text, TypeError, "");
}
BOOST_AUTO_TEST_CASE(index_access_for_bytes)
@@ -3289,7 +3510,7 @@ BOOST_AUTO_TEST_CASE(index_access_for_bytes)
}
}
)";
- BOOST_CHECK(success(text));
+ CHECK_SUCCESS(text);
}
BOOST_AUTO_TEST_CASE(uint7_and_uintM_as_identifier)
@@ -3305,7 +3526,7 @@ BOOST_AUTO_TEST_CASE(uint7_and_uintM_as_identifier)
}
}
)";
- BOOST_CHECK(success(text));
+ CHECK_SUCCESS(text);
}
BOOST_AUTO_TEST_CASE(varM_disqualified_as_keyword)
@@ -3343,7 +3564,7 @@ BOOST_AUTO_TEST_CASE(bytes10abc_is_identifier)
}
}
)";
- BOOST_CHECK(success(text));
+ CHECK_SUCCESS(text);
}
BOOST_AUTO_TEST_CASE(int10abc_is_identifier)
@@ -3356,7 +3577,7 @@ BOOST_AUTO_TEST_CASE(int10abc_is_identifier)
}
}
)";
- BOOST_CHECK(success(text));
+ CHECK_SUCCESS(text);
}
BOOST_AUTO_TEST_CASE(library_functions_do_not_have_value)
@@ -3440,7 +3661,7 @@ BOOST_AUTO_TEST_CASE(fixed_type_int_conversion)
}
}
)";
- BOOST_CHECK(success(text));
+ CHECK_SUCCESS(text);
}
BOOST_AUTO_TEST_CASE(fixed_type_rational_int_conversion)
@@ -3453,7 +3674,7 @@ BOOST_AUTO_TEST_CASE(fixed_type_rational_int_conversion)
}
}
)";
- BOOST_CHECK(success(text));
+ CHECK_SUCCESS(text);
}
BOOST_AUTO_TEST_CASE(fixed_type_rational_fraction_conversion)
@@ -3466,7 +3687,7 @@ BOOST_AUTO_TEST_CASE(fixed_type_rational_fraction_conversion)
}
}
)";
- BOOST_CHECK(success(text));
+ CHECK_SUCCESS(text);
}
BOOST_AUTO_TEST_CASE(invalid_int_implicit_conversion_from_fixed)
@@ -3492,7 +3713,7 @@ BOOST_AUTO_TEST_CASE(rational_unary_operation)
}
}
)";
- BOOST_CHECK(success(text));
+ CHECK_SUCCESS(text);
}
BOOST_AUTO_TEST_CASE(leading_zero_rationals_convert)
@@ -3507,7 +3728,7 @@ BOOST_AUTO_TEST_CASE(leading_zero_rationals_convert)
}
}
)";
- BOOST_CHECK(success(text));
+ CHECK_SUCCESS(text);
}
BOOST_AUTO_TEST_CASE(size_capabilities_of_fixed_point_types)
@@ -3524,7 +3745,7 @@ BOOST_AUTO_TEST_CASE(size_capabilities_of_fixed_point_types)
}
}
)";
- BOOST_CHECK(success(text));
+ CHECK_SUCCESS(text);
}
BOOST_AUTO_TEST_CASE(fixed_type_invalid_implicit_conversion_size)
@@ -3563,7 +3784,7 @@ BOOST_AUTO_TEST_CASE(fixed_type_valid_explicit_conversions)
}
}
)";
- BOOST_CHECK(success(text));
+ CHECK_SUCCESS(text);
}
BOOST_AUTO_TEST_CASE(invalid_array_declaration_with_rational)
@@ -3607,7 +3828,7 @@ BOOST_AUTO_TEST_CASE(fixed_to_bytes_implicit_conversion)
char const* text = R"(
contract test {
function f() {
- fixed a = 3.2;
+ fixed a = 3.25;
bytes32 c = a;
}
}
@@ -3625,7 +3846,7 @@ BOOST_AUTO_TEST_CASE(mapping_with_fixed_literal)
}
}
)";
- BOOST_CHECK(success(text));
+ CHECK_SUCCESS(text);
}
BOOST_AUTO_TEST_CASE(fixed_points_inside_structs)
@@ -3639,7 +3860,7 @@ BOOST_AUTO_TEST_CASE(fixed_points_inside_structs)
myStruct a = myStruct(3.125, 3);
}
)";
- BOOST_CHECK(success(text));
+ CHECK_SUCCESS(text);
}
BOOST_AUTO_TEST_CASE(inline_array_fixed_types)
@@ -3651,7 +3872,7 @@ BOOST_AUTO_TEST_CASE(inline_array_fixed_types)
}
}
)";
- BOOST_CHECK(success(text));
+ CHECK_SUCCESS(text);
}
BOOST_AUTO_TEST_CASE(inline_array_rationals)
@@ -3663,7 +3884,7 @@ BOOST_AUTO_TEST_CASE(inline_array_rationals)
}
}
)";
- BOOST_CHECK(success(text));
+ CHECK_SUCCESS(text);
}
BOOST_AUTO_TEST_CASE(rational_index_access)
@@ -3694,17 +3915,50 @@ BOOST_AUTO_TEST_CASE(rational_to_fixed_literal_expression)
}
}
)";
- BOOST_CHECK(success(text));
+ CHECK_SUCCESS(text);
}
-BOOST_AUTO_TEST_CASE(rational_as_exponent_value)
+BOOST_AUTO_TEST_CASE(rational_as_exponent_value_neg_decimal)
{
char const* text = R"(
contract test {
function f() {
fixed g = 2 ** -2.2;
+ }
+ }
+ )";
+ BOOST_CHECK(!success(text));
+}
+
+BOOST_AUTO_TEST_CASE(rational_as_exponent_value_pos_decimal)
+{
+ char const* text = R"(
+ contract test {
+ function f() {
ufixed b = 3 ** 2.5;
+ }
+ }
+ )";
+ BOOST_CHECK(!success(text));
+}
+
+BOOST_AUTO_TEST_CASE(rational_as_exponent_half)
+{
+ char const* text = R"(
+ contract test {
+ function f() {
ufixed24x24 b = 2 ** (1/2);
+ }
+ }
+ )";
+ BOOST_CHECK(!success(text));
+}
+
+BOOST_AUTO_TEST_CASE(rational_as_exponent_value_neg_quarter)
+{
+ char const* text = R"(
+ contract test {
+ function f() {
fixed40x40 c = 42 ** (-1/4);
}
}
@@ -3712,15 +3966,48 @@ BOOST_AUTO_TEST_CASE(rational_as_exponent_value)
BOOST_CHECK(!success(text));
}
-BOOST_AUTO_TEST_CASE(fixed_point_casting_exponents)
+BOOST_AUTO_TEST_CASE(fixed_point_casting_exponents_15)
{
char const* text = R"(
contract test {
function f() {
ufixed a = 3 ** ufixed(1.5);
+ }
+ }
+ )";
+ BOOST_CHECK(!success(text));
+}
+
+BOOST_AUTO_TEST_CASE(fixed_point_casting_exponents_half)
+{
+ char const* text = R"(
+ contract test {
+ function f() {
ufixed b = 2 ** ufixed(1/2);
+ }
+ }
+ )";
+ BOOST_CHECK(!success(text));
+}
+
+BOOST_AUTO_TEST_CASE(fixed_point_casting_exponents_neg)
+{
+ char const* text = R"(
+ contract test {
+ function f() {
fixed c = 42 ** fixed(-1/4);
- fixed d = 16 ** fixed(-0.33);
+ }
+ }
+ )";
+ BOOST_CHECK(!success(text));
+}
+
+BOOST_AUTO_TEST_CASE(fixed_point_casting_exponents_neg_decimal)
+{
+ char const* text = R"(
+ contract test {
+ function f() {
+ fixed d = 16 ** fixed(-0.5);
}
}
)";
@@ -3738,7 +4025,7 @@ BOOST_AUTO_TEST_CASE(var_capable_of_holding_constant_rationals)
}
}
)";
- BOOST_CHECK(success(text));
+ CHECK_SUCCESS(text);
}
BOOST_AUTO_TEST_CASE(var_and_rational_with_tuple)
@@ -3750,7 +4037,7 @@ BOOST_AUTO_TEST_CASE(var_and_rational_with_tuple)
}
}
)";
- BOOST_CHECK(success(text));
+ CHECK_SUCCESS(text);
}
BOOST_AUTO_TEST_CASE(var_handle_divided_integers)
@@ -3762,7 +4049,7 @@ BOOST_AUTO_TEST_CASE(var_handle_divided_integers)
}
}
)";
- BOOST_CHECK(success(text));
+ CHECK_SUCCESS(text);
}
BOOST_AUTO_TEST_CASE(rational_bitnot_unary_operation)
@@ -3770,7 +4057,7 @@ BOOST_AUTO_TEST_CASE(rational_bitnot_unary_operation)
char const* text = R"(
contract test {
function f() {
- fixed a = ~3.56;
+ fixed a = ~3.5;
}
}
)";
@@ -3782,7 +4069,7 @@ BOOST_AUTO_TEST_CASE(rational_bitor_binary_operation)
char const* text = R"(
contract test {
function f() {
- fixed a = 1.56 | 3;
+ fixed a = 1.5 | 3;
}
}
)";
@@ -3794,7 +4081,7 @@ BOOST_AUTO_TEST_CASE(rational_bitxor_binary_operation)
char const* text = R"(
contract test {
function f() {
- fixed a = 1.56 ^ 3;
+ fixed a = 1.75 ^ 3;
}
}
)";
@@ -3806,7 +4093,7 @@ BOOST_AUTO_TEST_CASE(rational_bitand_binary_operation)
char const* text = R"(
contract test {
function f() {
- fixed a = 1.56 & 3;
+ fixed a = 1.75 & 3;
}
}
)";
@@ -3823,7 +4110,7 @@ BOOST_AUTO_TEST_CASE(zero_handling)
}
}
)";
- BOOST_CHECK(success(text));
+ CHECK_SUCCESS(text);
}
BOOST_AUTO_TEST_CASE(missing_bool_conversion)
@@ -3835,7 +4122,7 @@ BOOST_AUTO_TEST_CASE(missing_bool_conversion)
}
}
)";
- BOOST_CHECK(success(text));
+ CHECK_SUCCESS(text);
}
BOOST_AUTO_TEST_CASE(integer_and_fixed_interaction)
@@ -3847,7 +4134,7 @@ BOOST_AUTO_TEST_CASE(integer_and_fixed_interaction)
}
}
)";
- BOOST_CHECK(success(text));
+ CHECK_SUCCESS(text);
}
BOOST_AUTO_TEST_CASE(signed_rational_modulus)
@@ -3861,7 +4148,7 @@ BOOST_AUTO_TEST_CASE(signed_rational_modulus)
}
}
)";
- BOOST_CHECK(success(text));
+ CHECK_SUCCESS(text);
}
BOOST_AUTO_TEST_CASE(one_divided_by_three_integer_conversion)
@@ -3886,7 +4173,7 @@ BOOST_AUTO_TEST_CASE(unused_return_value)
}
}
)";
- BOOST_CHECK(success(text));
+ CHECK_SUCCESS(text);
}
BOOST_AUTO_TEST_CASE(unused_return_value_send)
@@ -3898,7 +4185,7 @@ BOOST_AUTO_TEST_CASE(unused_return_value_send)
}
}
)";
- BOOST_CHECK(expectError(text, true) == Error::Type::Warning);
+ CHECK_WARNING(text, "Return value of low-level calls not used");
}
BOOST_AUTO_TEST_CASE(unused_return_value_call)
@@ -3910,7 +4197,7 @@ BOOST_AUTO_TEST_CASE(unused_return_value_call)
}
}
)";
- BOOST_CHECK(expectError(text, true) == Error::Type::Warning);
+ CHECK_WARNING(text, "Return value of low-level calls not used");
}
BOOST_AUTO_TEST_CASE(unused_return_value_call_value)
@@ -3922,7 +4209,7 @@ BOOST_AUTO_TEST_CASE(unused_return_value_call_value)
}
}
)";
- BOOST_CHECK(expectError(text, true) == Error::Type::Warning);
+ CHECK_WARNING(text, "Return value of low-level calls not used");
}
BOOST_AUTO_TEST_CASE(unused_return_value_callcode)
@@ -3934,7 +4221,7 @@ BOOST_AUTO_TEST_CASE(unused_return_value_callcode)
}
}
)";
- BOOST_CHECK(expectError(text, true) == Error::Type::Warning);
+ CHECK_WARNING(text, "Return value of low-level calls not used");
}
BOOST_AUTO_TEST_CASE(unused_return_value_delegatecall)
@@ -3946,7 +4233,7 @@ BOOST_AUTO_TEST_CASE(unused_return_value_delegatecall)
}
}
)";
- BOOST_CHECK(expectError(text, true) == Error::Type::Warning);
+ CHECK_WARNING(text, "Return value of low-level calls not used");
}
BOOST_AUTO_TEST_CASE(modifier_without_underscore)
@@ -3956,7 +4243,7 @@ BOOST_AUTO_TEST_CASE(modifier_without_underscore)
modifier m() {}
}
)";
- BOOST_CHECK(expectError(text) == Error::Type::SyntaxError);
+ CHECK_ERROR(text, SyntaxError, "");
}
BOOST_AUTO_TEST_CASE(payable_in_library)
@@ -3966,7 +4253,7 @@ BOOST_AUTO_TEST_CASE(payable_in_library)
function f() payable {}
}
)";
- BOOST_CHECK(expectError(text) == Error::Type::TypeError);
+ CHECK_ERROR(text, TypeError, "");
}
BOOST_AUTO_TEST_CASE(payable_external)
@@ -3976,7 +4263,7 @@ BOOST_AUTO_TEST_CASE(payable_external)
function f() payable external {}
}
)";
- BOOST_CHECK(success(text));
+ CHECK_SUCCESS(text);
}
BOOST_AUTO_TEST_CASE(payable_internal)
@@ -3986,7 +4273,7 @@ BOOST_AUTO_TEST_CASE(payable_internal)
function f() payable internal {}
}
)";
- BOOST_CHECK(expectError(text) == Error::Type::TypeError);
+ CHECK_ERROR(text, TypeError, "");
}
BOOST_AUTO_TEST_CASE(payable_private)
@@ -3996,7 +4283,7 @@ BOOST_AUTO_TEST_CASE(payable_private)
function f() payable private {}
}
)";
- BOOST_CHECK(expectError(text) == Error::Type::TypeError);
+ CHECK_ERROR(text, TypeError, "");
}
BOOST_AUTO_TEST_CASE(illegal_override_payable)
@@ -4005,7 +4292,7 @@ BOOST_AUTO_TEST_CASE(illegal_override_payable)
contract B { function f() payable {} }
contract C is B { function f() {} }
)";
- BOOST_CHECK(expectError(text) == Error::Type::TypeError);
+ CHECK_ERROR(text, TypeError, "");
}
BOOST_AUTO_TEST_CASE(illegal_override_payable_nonpayable)
@@ -4014,7 +4301,7 @@ BOOST_AUTO_TEST_CASE(illegal_override_payable_nonpayable)
contract B { function f() {} }
contract C is B { function f() payable {} }
)";
- BOOST_CHECK(expectError(text) == Error::Type::TypeError);
+ CHECK_ERROR(text, TypeError, "");
}
BOOST_AUTO_TEST_CASE(payable_constant_conflict)
@@ -4022,7 +4309,7 @@ BOOST_AUTO_TEST_CASE(payable_constant_conflict)
char const* text = R"(
contract C { function f() payable constant {} }
)";
- BOOST_CHECK(expectError(text) == Error::Type::TypeError);
+ CHECK_ERROR(text, TypeError, "");
}
BOOST_AUTO_TEST_CASE(calling_payable)
@@ -4035,7 +4322,7 @@ BOOST_AUTO_TEST_CASE(calling_payable)
function g() { r.pay.value(10)(); }
}
)";
- BOOST_CHECK(success(text));
+ CHECK_SUCCESS(text);
}
BOOST_AUTO_TEST_CASE(calling_nonpayable)
@@ -4046,7 +4333,7 @@ BOOST_AUTO_TEST_CASE(calling_nonpayable)
function f() { (new receiver()).nopay.value(10)(); }
}
)";
- BOOST_CHECK(expectError(text) == Error::Type::TypeError);
+ CHECK_ERROR(text, TypeError, "");
}
BOOST_AUTO_TEST_CASE(non_payable_constructor)
@@ -4062,7 +4349,7 @@ BOOST_AUTO_TEST_CASE(non_payable_constructor)
}
}
)";
- BOOST_CHECK(expectError(text) == Error::Type::TypeError);
+ CHECK_ERROR(text, TypeError, "");
}
BOOST_AUTO_TEST_CASE(warn_nonpresent_pragma)
@@ -4071,7 +4358,7 @@ BOOST_AUTO_TEST_CASE(warn_nonpresent_pragma)
auto sourceAndError = parseAnalyseAndReturnError(text, true, false);
BOOST_REQUIRE(!!sourceAndError.second);
BOOST_REQUIRE(!!sourceAndError.first);
- BOOST_CHECK(*sourceAndError.second == Error::Type::Warning);
+ BOOST_CHECK(searchErrorMessage(*sourceAndError.second, "Source file does not specify required compiler version!"));
}
BOOST_AUTO_TEST_CASE(unsatisfied_version)
@@ -4079,7 +4366,7 @@ BOOST_AUTO_TEST_CASE(unsatisfied_version)
char const* text = R"(
pragma solidity ^99.99.0;
)";
- BOOST_CHECK(expectError(text, true) == Error::Type::SyntaxError);
+ BOOST_CHECK(expectError(text, true).type() == Error::Type::SyntaxError);
}
BOOST_AUTO_TEST_CASE(constant_constructor)
@@ -4089,7 +4376,7 @@ BOOST_AUTO_TEST_CASE(constant_constructor)
function test() constant {}
}
)";
- BOOST_CHECK(expectError(text, false) == Error::Type::TypeError);
+ CHECK_ERROR(text, TypeError, "");
}
BOOST_AUTO_TEST_CASE(external_constructor)
@@ -4099,7 +4386,7 @@ BOOST_AUTO_TEST_CASE(external_constructor)
function test() external {}
}
)";
- BOOST_CHECK(expectError(text, false) == Error::Type::TypeError);
+ CHECK_ERROR(text, TypeError, "");
}
BOOST_AUTO_TEST_CASE(invalid_array_as_statement)
@@ -4107,10 +4394,10 @@ BOOST_AUTO_TEST_CASE(invalid_array_as_statement)
char const* text = R"(
contract test {
struct S { uint x; }
- function test(uint k) { S[k]; }
+ function test(uint k) { S[k]; }
}
)";
- BOOST_CHECK(expectError(text, false) == Error::Type::TypeError);
+ CHECK_ERROR(text, TypeError, "");
}
BOOST_AUTO_TEST_CASE(using_directive_for_missing_selftype)
@@ -4129,7 +4416,7 @@ BOOST_AUTO_TEST_CASE(using_directive_for_missing_selftype)
}
}
)";
- BOOST_CHECK(expectError(text, false) == Error::Type::TypeError);
+ CHECK_ERROR(text, TypeError, "");
}
BOOST_AUTO_TEST_CASE(function_type)
@@ -4141,7 +4428,7 @@ BOOST_AUTO_TEST_CASE(function_type)
}
}
)";
- BOOST_CHECK(success(text));
+ CHECK_SUCCESS(text);
}
BOOST_AUTO_TEST_CASE(function_type_parameter)
@@ -4153,7 +4440,7 @@ BOOST_AUTO_TEST_CASE(function_type_parameter)
}
}
)";
- BOOST_CHECK(success(text));
+ CHECK_SUCCESS(text);
}
BOOST_AUTO_TEST_CASE(function_type_returned)
@@ -4165,7 +4452,7 @@ BOOST_AUTO_TEST_CASE(function_type_returned)
}
}
)";
- BOOST_CHECK(success(text));
+ CHECK_SUCCESS(text);
}
BOOST_AUTO_TEST_CASE(private_function_type)
@@ -4177,7 +4464,7 @@ BOOST_AUTO_TEST_CASE(private_function_type)
}
}
)";
- BOOST_CHECK(expectError(text) == Error::Type::TypeError);
+ CHECK_ERROR(text, TypeError, "");
}
BOOST_AUTO_TEST_CASE(public_function_type)
@@ -4189,7 +4476,7 @@ BOOST_AUTO_TEST_CASE(public_function_type)
}
}
)";
- BOOST_CHECK(expectError(text) == Error::Type::TypeError);
+ CHECK_ERROR(text, TypeError, "");
}
BOOST_AUTO_TEST_CASE(payable_internal_function_type)
@@ -4199,7 +4486,7 @@ BOOST_AUTO_TEST_CASE(payable_internal_function_type)
function (uint) internal payable returns (uint) x;
}
)";
- BOOST_CHECK(expectError(text) == Error::Type::TypeError);
+ CHECK_ERROR(text, TypeError, "");
}
BOOST_AUTO_TEST_CASE(call_value_on_non_payable_function_type)
@@ -4212,7 +4499,7 @@ BOOST_AUTO_TEST_CASE(call_value_on_non_payable_function_type)
}
}
)";
- BOOST_CHECK(expectError(text) == Error::Type::TypeError);
+ CHECK_ERROR(text, TypeError, "");
}
BOOST_AUTO_TEST_CASE(external_function_type_returning_internal)
@@ -4222,7 +4509,7 @@ BOOST_AUTO_TEST_CASE(external_function_type_returning_internal)
function() external returns (function () internal) x;
}
)";
- BOOST_CHECK(expectError(text) == Error::Type::TypeError);
+ CHECK_ERROR(text, TypeError, "");
}
BOOST_AUTO_TEST_CASE(external_function_type_taking_internal)
@@ -4232,7 +4519,7 @@ BOOST_AUTO_TEST_CASE(external_function_type_taking_internal)
function(function () internal) external x;
}
)";
- BOOST_CHECK(expectError(text) == Error::Type::TypeError);
+ CHECK_ERROR(text, TypeError, "");
}
BOOST_AUTO_TEST_CASE(call_value_on_payable_function_type)
@@ -4245,7 +4532,7 @@ BOOST_AUTO_TEST_CASE(call_value_on_payable_function_type)
}
}
)";
- BOOST_CHECK(success(text));
+ CHECK_SUCCESS(text);
}
BOOST_AUTO_TEST_CASE(internal_function_as_external_parameter)
@@ -4258,7 +4545,7 @@ BOOST_AUTO_TEST_CASE(internal_function_as_external_parameter)
}
}
)";
- BOOST_CHECK(expectError(text) == Error::Type::TypeError);
+ CHECK_ERROR(text, TypeError, "");
}
BOOST_AUTO_TEST_CASE(internal_function_returned_from_public_function)
@@ -4270,7 +4557,7 @@ BOOST_AUTO_TEST_CASE(internal_function_returned_from_public_function)
}
}
)";
- BOOST_CHECK(expectError(text) == Error::Type::TypeError);
+ CHECK_ERROR(text, TypeError, "");
}
BOOST_AUTO_TEST_CASE(internal_function_as_external_parameter_in_library_internal)
@@ -4281,7 +4568,7 @@ BOOST_AUTO_TEST_CASE(internal_function_as_external_parameter_in_library_internal
}
}
)";
- BOOST_CHECK(success(text));
+ CHECK_SUCCESS(text);
}
BOOST_AUTO_TEST_CASE(internal_function_as_external_parameter_in_library_external)
@@ -4292,7 +4579,7 @@ BOOST_AUTO_TEST_CASE(internal_function_as_external_parameter_in_library_external
}
}
)";
- BOOST_CHECK(expectError(text) == Error::Type::TypeError);
+ CHECK_ERROR(text, TypeError, "");
}
BOOST_AUTO_TEST_CASE(function_type_arrays)
@@ -4309,7 +4596,7 @@ BOOST_AUTO_TEST_CASE(function_type_arrays)
}
}
)";
- BOOST_CHECK(success(text));
+ CHECK_SUCCESS(text);
}
BOOST_AUTO_TEST_CASE(delete_function_type)
@@ -4330,7 +4617,7 @@ BOOST_AUTO_TEST_CASE(delete_function_type)
}
}
)";
- BOOST_CHECK(success(text));
+ CHECK_SUCCESS(text);
}
BOOST_AUTO_TEST_CASE(delete_function_type_invalid)
@@ -4342,7 +4629,7 @@ BOOST_AUTO_TEST_CASE(delete_function_type_invalid)
}
}
)";
- BOOST_CHECK(expectError(text, false) == Error::Type::TypeError);
+ CHECK_ERROR(text, TypeError, "");
}
BOOST_AUTO_TEST_CASE(delete_external_function_type_invalid)
@@ -4354,7 +4641,7 @@ BOOST_AUTO_TEST_CASE(delete_external_function_type_invalid)
}
}
)";
- BOOST_CHECK(expectError(text, false) == Error::Type::TypeError);
+ CHECK_ERROR(text, TypeError, "");
}
BOOST_AUTO_TEST_CASE(invalid_fixed_point_literal)
@@ -4366,7 +4653,7 @@ BOOST_AUTO_TEST_CASE(invalid_fixed_point_literal)
}
}
)";
- BOOST_CHECK(expectError(text, false) == Error::Type::TypeError);
+ CHECK_ERROR(text, TypeError, "");
}
BOOST_AUTO_TEST_CASE(shift_constant_left_negative_rvalue)
@@ -4376,7 +4663,7 @@ BOOST_AUTO_TEST_CASE(shift_constant_left_negative_rvalue)
uint public a = 0x42 << -8;
}
)";
- BOOST_CHECK(expectError(text, false) == Error::Type::TypeError);
+ CHECK_ERROR(text, TypeError, "");
}
BOOST_AUTO_TEST_CASE(shift_constant_right_negative_rvalue)
@@ -4386,7 +4673,7 @@ BOOST_AUTO_TEST_CASE(shift_constant_right_negative_rvalue)
uint public a = 0x42 >> -8;
}
)";
- BOOST_CHECK(expectError(text, false) == Error::Type::TypeError);
+ CHECK_ERROR(text, TypeError, "");
}
BOOST_AUTO_TEST_CASE(shift_constant_left_excessive_rvalue)
@@ -4396,7 +4683,7 @@ BOOST_AUTO_TEST_CASE(shift_constant_left_excessive_rvalue)
uint public a = 0x42 << 0x100000000;
}
)";
- BOOST_CHECK(expectError(text, false) == Error::Type::TypeError);
+ CHECK_ERROR(text, TypeError, "");
}
BOOST_AUTO_TEST_CASE(shift_constant_right_excessive_rvalue)
@@ -4406,7 +4693,7 @@ BOOST_AUTO_TEST_CASE(shift_constant_right_excessive_rvalue)
uint public a = 0x42 >> 0x100000000;
}
)";
- BOOST_CHECK(expectError(text, false) == Error::Type::TypeError);
+ CHECK_ERROR(text, TypeError, "");
}
BOOST_AUTO_TEST_CASE(inline_assembly_unbalanced_positive_stack)
@@ -4420,7 +4707,7 @@ BOOST_AUTO_TEST_CASE(inline_assembly_unbalanced_positive_stack)
}
}
)";
- BOOST_CHECK(expectError(text, true) == Error::Type::Warning);
+ CHECK_WARNING(text, "Inline assembly block is not balanced");
}
BOOST_AUTO_TEST_CASE(inline_assembly_unbalanced_negative_stack)
@@ -4434,7 +4721,7 @@ BOOST_AUTO_TEST_CASE(inline_assembly_unbalanced_negative_stack)
}
}
)";
- BOOST_CHECK(expectError(text, true) == Error::Type::Warning);
+ CHECK_WARNING(text, "Inline assembly block is not balanced");
}
BOOST_AUTO_TEST_CASE(inline_assembly_in_modifier)
@@ -4452,7 +4739,7 @@ BOOST_AUTO_TEST_CASE(inline_assembly_in_modifier)
}
}
)";
- BOOST_CHECK(success(text));
+ CHECK_SUCCESS(text);
}
BOOST_AUTO_TEST_CASE(inline_assembly_storage)
@@ -4463,11 +4750,12 @@ BOOST_AUTO_TEST_CASE(inline_assembly_storage)
function f() {
assembly {
x := 2
+ pop
}
}
}
)";
- BOOST_CHECK(expectError(text, false) == Error::Type::DeclarationError);
+ CHECK_ERROR(text, DeclarationError, "not found, not unique or not lvalue.");
}
BOOST_AUTO_TEST_CASE(inline_assembly_storage_in_modifiers)
@@ -4478,6 +4766,7 @@ BOOST_AUTO_TEST_CASE(inline_assembly_storage_in_modifiers)
modifier m {
assembly {
x := 2
+ pop
}
_;
}
@@ -4485,7 +4774,7 @@ BOOST_AUTO_TEST_CASE(inline_assembly_storage_in_modifiers)
}
}
)";
- BOOST_CHECK(expectError(text, false) == Error::Type::DeclarationError);
+ CHECK_ERROR(text, DeclarationError, "");
}
BOOST_AUTO_TEST_CASE(invalid_mobile_type)
@@ -4498,7 +4787,93 @@ BOOST_AUTO_TEST_CASE(invalid_mobile_type)
}
}
)";
- BOOST_CHECK(expectError(text, false) == Error::Type::TypeError);
+ CHECK_ERROR(text, TypeError, "");
+}
+
+BOOST_AUTO_TEST_CASE(warns_msg_value_in_non_payable_public_function)
+{
+ char const* text = R"(
+ contract C {
+ function f() {
+ msg.value;
+ }
+ }
+ )";
+ CHECK_WARNING(text, "\"msg.value\" used in non-payable function. Do you want to add the \"payable\" modifier to this function?");
+}
+
+BOOST_AUTO_TEST_CASE(does_not_warn_msg_value_in_payable_function)
+{
+ char const* text = R"(
+ contract C {
+ function f() payable {
+ msg.value;
+ }
+ }
+ )";
+ CHECK_SUCCESS_NO_WARNINGS(text);
+}
+
+BOOST_AUTO_TEST_CASE(does_not_warn_msg_value_in_internal_function)
+{
+ char const* text = R"(
+ contract C {
+ function f() internal {
+ msg.value;
+ }
+ }
+ )";
+ CHECK_SUCCESS_NO_WARNINGS(text);
+}
+
+BOOST_AUTO_TEST_CASE(does_not_warn_msg_value_in_library)
+{
+ char const* text = R"(
+ library C {
+ function f() {
+ msg.value;
+ }
+ }
+ )";
+ CHECK_SUCCESS_NO_WARNINGS(text);
+}
+
+BOOST_AUTO_TEST_CASE(does_not_warn_non_magic_msg_value)
+{
+ char const* text = R"(
+ contract C {
+ struct msg {
+ uint256 value;
+ }
+
+ function f() {
+ msg.value;
+ }
+ }
+ )";
+ CHECK_SUCCESS_NO_WARNINGS(text);
+}
+
+BOOST_AUTO_TEST_CASE(does_not_warn_msg_value_in_modifier_following_non_payable_public_function)
+{
+ char const* text = R"(
+ contract c {
+ function f() { }
+ modifier m() { msg.value; _; }
+ }
+ )";
+ CHECK_SUCCESS_NO_WARNINGS(text);
+}
+
+BOOST_AUTO_TEST_CASE(assignment_to_constant)
+{
+ char const* text = R"(
+ contract c {
+ uint constant a = 1;
+ function f() { a = 2; }
+ }
+ )";
+ CHECK_ERROR(text, TypeError, "Cannot assign to a constant variable.");
}
BOOST_AUTO_TEST_SUITE_END()
diff --git a/test/libsolidity/SolidityNatspecJSON.cpp b/test/libsolidity/SolidityNatspecJSON.cpp
index 49844f15..e32264c4 100644
--- a/test/libsolidity/SolidityNatspecJSON.cpp
+++ b/test/libsolidity/SolidityNatspecJSON.cpp
@@ -1,18 +1,18 @@
/*
- This file is part of cpp-ethereum.
+ This file is part of solidity.
- cpp-ethereum is free software: you can redistribute it and/or modify
+ 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.
- cpp-ethereum is distributed in the hope that it will be useful,
+ 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 cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
+ along with solidity. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* @author Lefteris Karapetsas <lefteris@ethdev.com>
@@ -76,10 +76,12 @@ BOOST_FIXTURE_TEST_SUITE(SolidityNatspecJSON, DocumentationChecker)
BOOST_AUTO_TEST_CASE(user_basic_test)
{
- char const* sourceCode = "contract test {\n"
- " /// @notice Multiplies `a` by 7\n"
- " function mul(uint a) returns(uint d) { return a * 7; }\n"
- "}\n";
+ char const* sourceCode = R"(
+ contract test {
+ /// @notice Multiplies `a` by 7
+ function mul(uint a) returns(uint d) { return a * 7; }
+ }
+ )";
char const* natspec = "{"
"\"methods\":{"
@@ -91,11 +93,13 @@ BOOST_AUTO_TEST_CASE(user_basic_test)
BOOST_AUTO_TEST_CASE(dev_and_user_basic_test)
{
- char const* sourceCode = "contract test {\n"
- " /// @notice Multiplies `a` by 7\n"
- " /// @dev Multiplies a number by 7\n"
- " function mul(uint a) returns(uint d) { return a * 7; }\n"
- "}\n";
+ char const* sourceCode = R"(
+ contract test {
+ /// @notice Multiplies `a` by 7
+ /// @dev Multiplies a number by 7
+ function mul(uint a) returns(uint d) { return a * 7; }
+ }
+ )";
char const* devNatspec = "{"
"\"methods\":{"
@@ -116,14 +120,15 @@ BOOST_AUTO_TEST_CASE(dev_and_user_basic_test)
BOOST_AUTO_TEST_CASE(user_multiline_comment)
{
- char const* sourceCode = "contract test {\n"
- " /// @notice Multiplies `a` by 7\n"
- " /// and then adds `b`\n"
- " function mul_and_add(uint a, uint256 b) returns(uint256 d)\n"
- " {\n"
- " return (a * 7) + b;\n"
- " }\n"
- "}\n";
+ char const* sourceCode = R"(
+ contract test {
+ /// @notice Multiplies `a` by 7
+ /// and then adds `b`
+ function mul_and_add(uint a, uint256 b) returns(uint256 d) {
+ return (a * 7) + b;
+ }
+ }
+ )";
char const* natspec = "{"
"\"methods\":{"
@@ -135,24 +140,24 @@ BOOST_AUTO_TEST_CASE(user_multiline_comment)
BOOST_AUTO_TEST_CASE(user_multiple_functions)
{
- char const* sourceCode = "contract test {\n"
- " /// @notice Multiplies `a` by 7 and then adds `b`\n"
- " function mul_and_add(uint a, uint256 b) returns(uint256 d)\n"
- " {\n"
- " return (a * 7) + b;\n"
- " }\n"
- "\n"
- " /// @notice Divides `input` by `div`\n"
- " function divide(uint input, uint div) returns(uint d)\n"
- " {\n"
- " return input / div;\n"
- " }\n"
- " /// @notice Subtracts 3 from `input`\n"
- " function sub(int input) returns(int d)\n"
- " {\n"
- " return input - 3;\n"
- " }\n"
- "}\n";
+ char const* sourceCode = R"(
+ contract test {
+ /// @notice Multiplies `a` by 7 and then adds `b`
+ function mul_and_add(uint a, uint256 b) returns(uint256 d) {
+ return (a * 7) + b;
+ }
+
+ /// @notice Divides `input` by `div`
+ function divide(uint input, uint div) returns(uint d) {
+ return input / div;
+ }
+
+ /// @notice Subtracts 3 from `input`
+ function sub(int input) returns(int d) {
+ return input - 3;
+ }
+ }
+ )";
char const* natspec = "{"
"\"methods\":{"
@@ -166,8 +171,9 @@ BOOST_AUTO_TEST_CASE(user_multiple_functions)
BOOST_AUTO_TEST_CASE(user_empty_contract)
{
- char const* sourceCode = "contract test {\n"
- "}\n";
+ char const* sourceCode = R"(
+ contract test { }
+ )";
char const* natspec = "{\"methods\":{} }";
@@ -176,13 +182,16 @@ BOOST_AUTO_TEST_CASE(user_empty_contract)
BOOST_AUTO_TEST_CASE(dev_and_user_no_doc)
{
- char const* sourceCode = "contract test {\n"
- " function mul(uint a) returns(uint d) { return a * 7; }\n"
- " function sub(int input) returns(int d)\n"
- " {\n"
- " return input - 3;\n"
- " }\n"
- "}\n";
+ char const* sourceCode = R"(
+ contract test {
+ function mul(uint a) returns(uint d) {
+ return a * 7;
+ }
+ function sub(int input) returns(int d) {
+ return input - 3;
+ }
+ }
+ )";
char const* devNatspec = "{\"methods\":{}}";
char const* userNatspec = "{\"methods\":{}}";
@@ -193,13 +202,15 @@ BOOST_AUTO_TEST_CASE(dev_and_user_no_doc)
BOOST_AUTO_TEST_CASE(dev_desc_after_nl)
{
- char const* sourceCode = "contract test {\n"
- " /// @dev\n"
- " /// Multiplies a number by 7 and adds second parameter\n"
- " /// @param a Documentation for the first parameter\n"
- " /// @param second Documentation for the second parameter\n"
- " function mul(uint a, uint second) returns(uint d) { return a * 7 + second; }\n"
- "}\n";
+ char const* sourceCode = R"(
+ contract test {
+ /// @dev
+ /// Multiplies a number by 7 and adds second parameter
+ /// @param a Documentation for the first parameter
+ /// @param second Documentation for the second parameter
+ function mul(uint a, uint second) returns(uint d) { return a * 7 + second; }
+ }
+ )";
char const* natspec = "{"
"\"methods\":{"
@@ -217,12 +228,14 @@ BOOST_AUTO_TEST_CASE(dev_desc_after_nl)
BOOST_AUTO_TEST_CASE(dev_multiple_params)
{
- char const* sourceCode = "contract test {\n"
- " /// @dev Multiplies a number by 7 and adds second parameter\n"
- " /// @param a Documentation for the first parameter\n"
- " /// @param second Documentation for the second parameter\n"
- " function mul(uint a, uint second) returns(uint d) { return a * 7 + second; }\n"
- "}\n";
+ char const* sourceCode = R"(
+ contract test {
+ /// @dev Multiplies a number by 7 and adds second parameter
+ /// @param a Documentation for the first parameter
+ /// @param second Documentation for the second parameter
+ function mul(uint a, uint second) returns(uint d) { return a * 7 + second; }
+ }
+ )";
char const* natspec = "{"
"\"methods\":{"
@@ -240,13 +253,15 @@ BOOST_AUTO_TEST_CASE(dev_multiple_params)
BOOST_AUTO_TEST_CASE(dev_mutiline_param_description)
{
- char const* sourceCode = "contract test {\n"
- " /// @dev Multiplies a number by 7 and adds second parameter\n"
- " /// @param a Documentation for the first parameter starts here.\n"
- " /// Since it's a really complicated parameter we need 2 lines\n"
- " /// @param second Documentation for the second parameter\n"
- " function mul(uint a, uint second) returns(uint d) { return a * 7 + second; }\n"
- "}\n";
+ char const* sourceCode = R"(
+ contract test {
+ /// @dev Multiplies a number by 7 and adds second parameter
+ /// @param a Documentation for the first parameter starts here.
+ /// Since it's a really complicated parameter we need 2 lines
+ /// @param second Documentation for the second parameter
+ function mul(uint a, uint second) returns(uint d) { return a * 7 + second; }
+ }
+ )";
char const* natspec = "{"
"\"methods\":{"
@@ -264,26 +279,27 @@ BOOST_AUTO_TEST_CASE(dev_mutiline_param_description)
BOOST_AUTO_TEST_CASE(dev_multiple_functions)
{
- char const* sourceCode = "contract test {\n"
- " /// @dev Multiplies a number by 7 and adds second parameter\n"
- " /// @param a Documentation for the first parameter\n"
- " /// @param second Documentation for the second parameter\n"
- " function mul(uint a, uint second) returns(uint d) { return a * 7 + second; }\n"
- " \n"
- " /// @dev Divides 2 numbers\n"
- " /// @param input Documentation for the input parameter\n"
- " /// @param div Documentation for the div parameter\n"
- " function divide(uint input, uint div) returns(uint d)\n"
- " {\n"
- " return input / div;\n"
- " }\n"
- " /// @dev Subtracts 3 from `input`\n"
- " /// @param input Documentation for the input parameter\n"
- " function sub(int input) returns(int d)\n"
- " {\n"
- " return input - 3;\n"
- " }\n"
- "}\n";
+ char const* sourceCode = R"(
+ contract test {
+ /// @dev Multiplies a number by 7 and adds second parameter
+ /// @param a Documentation for the first parameter
+ /// @param second Documentation for the second parameter
+ function mul(uint a, uint second) returns(uint d) {
+ return a * 7 + second;
+ }
+ /// @dev Divides 2 numbers
+ /// @param input Documentation for the input parameter
+ /// @param div Documentation for the div parameter
+ function divide(uint input, uint div) returns(uint d) {
+ return input / div;
+ }
+ /// @dev Subtracts 3 from `input`
+ /// @param input Documentation for the input parameter
+ function sub(int input) returns(int d) {
+ return input - 3;
+ }
+ }
+ )";
char const* natspec = "{"
"\"methods\":{"
@@ -314,14 +330,16 @@ BOOST_AUTO_TEST_CASE(dev_multiple_functions)
BOOST_AUTO_TEST_CASE(dev_return)
{
- char const* sourceCode = "contract test {\n"
- " /// @dev Multiplies a number by 7 and adds second parameter\n"
- " /// @param a Documentation for the first parameter starts here.\n"
- " /// Since it's a really complicated parameter we need 2 lines\n"
- " /// @param second Documentation for the second parameter\n"
- " /// @return The result of the multiplication\n"
- " function mul(uint a, uint second) returns(uint d) { return a * 7 + second; }\n"
- "}\n";
+ char const* sourceCode = R"(
+ contract test {
+ /// @dev Multiplies a number by 7 and adds second parameter
+ /// @param a Documentation for the first parameter starts here.
+ /// Since it's a really complicated parameter we need 2 lines
+ /// @param second Documentation for the second parameter
+ /// @return The result of the multiplication
+ function mul(uint a, uint second) returns(uint d) { return a * 7 + second; }
+ }
+ )";
char const* natspec = "{"
"\"methods\":{"
@@ -339,15 +357,19 @@ BOOST_AUTO_TEST_CASE(dev_return)
}
BOOST_AUTO_TEST_CASE(dev_return_desc_after_nl)
{
- char const* sourceCode = "contract test {\n"
- " /// @dev Multiplies a number by 7 and adds second parameter\n"
- " /// @param a Documentation for the first parameter starts here.\n"
- " /// Since it's a really complicated parameter we need 2 lines\n"
- " /// @param second Documentation for the second parameter\n"
- " /// @return\n"
- " /// The result of the multiplication\n"
- " function mul(uint a, uint second) returns(uint d) { return a * 7 + second; }\n"
- "}\n";
+ char const* sourceCode = R"(
+ contract test {
+ /// @dev Multiplies a number by 7 and adds second parameter
+ /// @param a Documentation for the first parameter starts here.
+ /// Since it's a really complicated parameter we need 2 lines
+ /// @param second Documentation for the second parameter
+ /// @return
+ /// The result of the multiplication
+ function mul(uint a, uint second) returns(uint d) {
+ return a * 7 + second;
+ }
+ }
+ )";
char const* natspec = "{"
"\"methods\":{"
@@ -367,15 +389,19 @@ BOOST_AUTO_TEST_CASE(dev_return_desc_after_nl)
BOOST_AUTO_TEST_CASE(dev_multiline_return)
{
- char const* sourceCode = "contract test {\n"
- " /// @dev Multiplies a number by 7 and adds second parameter\n"
- " /// @param a Documentation for the first parameter starts here.\n"
- " /// Since it's a really complicated parameter we need 2 lines\n"
- " /// @param second Documentation for the second parameter\n"
- " /// @return The result of the multiplication\n"
- " /// and cookies with nutella\n"
- " function mul(uint a, uint second) returns(uint d) { return a * 7 + second; }\n"
- "}\n";
+ char const* sourceCode = R"(
+ contract test {
+ /// @dev Multiplies a number by 7 and adds second parameter
+ /// @param a Documentation for the first parameter starts here.
+ /// Since it's a really complicated parameter we need 2 lines
+ /// @param second Documentation for the second parameter
+ /// @return The result of the multiplication
+ /// and cookies with nutella
+ function mul(uint a, uint second) returns(uint d) {
+ return a * 7 + second;
+ }
+ }
+ )";
char const* natspec = "{"
"\"methods\":{"
@@ -394,17 +420,21 @@ BOOST_AUTO_TEST_CASE(dev_multiline_return)
BOOST_AUTO_TEST_CASE(dev_multiline_comment)
{
- char const* sourceCode = "contract test {\n"
- " /**\n"
- " * @dev Multiplies a number by 7 and adds second parameter\n"
- " * @param a Documentation for the first parameter starts here.\n"
- " * Since it's a really complicated parameter we need 2 lines\n"
- " * @param second Documentation for the second parameter\n"
- " * @return The result of the multiplication\n"
- " * and cookies with nutella\n"
- " */"
- " function mul(uint a, uint second) returns(uint d) { return a * 7 + second; }\n"
- "}\n";
+ char const* sourceCode = R"(
+ contract test {
+ /**
+ * @dev Multiplies a number by 7 and adds second parameter
+ * @param a Documentation for the first parameter starts here.
+ * Since it's a really complicated parameter we need 2 lines
+ * @param second Documentation for the second parameter
+ * @return The result of the multiplication
+ * and cookies with nutella
+ */
+ function mul(uint a, uint second) returns(uint d) {
+ return a * 7 + second;
+ }
+ }
+ )";
char const* natspec = "{"
"\"methods\":{"
@@ -423,10 +453,12 @@ BOOST_AUTO_TEST_CASE(dev_multiline_comment)
BOOST_AUTO_TEST_CASE(dev_contract_no_doc)
{
- char const* sourceCode = "contract test {\n"
- " /// @dev Mul function\n"
- " function mul(uint a, uint second) returns(uint d) { return a * 7 + second; }\n"
- "}\n";
+ char const* sourceCode = R"(
+ contract test {
+ /// @dev Mul function
+ function mul(uint a, uint second) returns(uint d) { return a * 7 + second; }
+ }
+ )";
char const* natspec = "{"
" \"methods\":{"
@@ -441,12 +473,14 @@ BOOST_AUTO_TEST_CASE(dev_contract_no_doc)
BOOST_AUTO_TEST_CASE(dev_contract_doc)
{
- char const* sourceCode = " /// @author Lefteris\n"
- " /// @title Just a test contract\n"
- "contract test {\n"
- " /// @dev Mul function\n"
- " function mul(uint a, uint second) returns(uint d) { return a * 7 + second; }\n"
- "}\n";
+ char const* sourceCode = R"(
+ /// @author Lefteris
+ /// @title Just a test contract
+ contract test {
+ /// @dev Mul function
+ function mul(uint a, uint second) returns(uint d) { return a * 7 + second; }
+ }
+ )";
char const* natspec = "{"
" \"author\": \"Lefteris\","
@@ -463,13 +497,15 @@ BOOST_AUTO_TEST_CASE(dev_contract_doc)
BOOST_AUTO_TEST_CASE(dev_author_at_function)
{
- char const* sourceCode = " /// @author Lefteris\n"
- " /// @title Just a test contract\n"
- "contract test {\n"
- " /// @dev Mul function\n"
- " /// @author John Doe\n"
- " function mul(uint a, uint second) returns(uint d) { return a * 7 + second; }\n"
- "}\n";
+ char const* sourceCode = R"(
+ /// @author Lefteris
+ /// @title Just a test contract
+ contract test {
+ /// @dev Mul function
+ /// @author John Doe
+ function mul(uint a, uint second) returns(uint d) { return a * 7 + second; }
+ }
+ )";
char const* natspec = "{"
" \"author\": \"Lefteris\","
@@ -549,25 +585,29 @@ BOOST_AUTO_TEST_CASE(empty_comment)
BOOST_AUTO_TEST_CASE(dev_title_at_function_error)
{
- char const* sourceCode = " /// @author Lefteris\n"
- " /// @title Just a test contract\n"
- "contract test {\n"
- " /// @dev Mul function\n"
- " /// @title I really should not be here\n"
- " function mul(uint a, uint second) returns(uint d) { return a * 7 + second; }\n"
- "}\n";
+ char const* sourceCode = R"(
+ /// @author Lefteris
+ /// @title Just a test contract
+ contract test {
+ /// @dev Mul function
+ /// @title I really should not be here
+ function mul(uint a, uint second) returns(uint d) { return a * 7 + second; }
+ }
+ )";
expectNatspecError(sourceCode);
}
-BOOST_AUTO_TEST_CASE(dev_documenting_nonexistant_param)
+BOOST_AUTO_TEST_CASE(dev_documenting_nonexistent_param)
{
- char const* sourceCode = "contract test {\n"
- " /// @dev Multiplies a number by 7 and adds second parameter\n"
- " /// @param a Documentation for the first parameter\n"
- " /// @param not_existing Documentation for the second parameter\n"
- " function mul(uint a, uint second) returns(uint d) { return a * 7 + second; }\n"
- "}\n";
+ char const* sourceCode = R"(
+ contract test {
+ /// @dev Multiplies a number by 7 and adds second parameter
+ /// @param a Documentation for the first parameter
+ /// @param not_existing Documentation for the second parameter
+ function mul(uint a, uint second) returns(uint d) { return a * 7 + second; }
+ }
+ )";
expectNatspecError(sourceCode);
}
diff --git a/test/libsolidity/SolidityOptimizer.cpp b/test/libsolidity/SolidityOptimizer.cpp
index 017fc0e9..2e2e0c6c 100644
--- a/test/libsolidity/SolidityOptimizer.cpp
+++ b/test/libsolidity/SolidityOptimizer.cpp
@@ -1,18 +1,18 @@
/*
- This file is part of cpp-ethereum.
+ This file is part of solidity.
- cpp-ethereum is free software: you can redistribute it and/or modify
+ 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.
- cpp-ethereum is distributed in the hope that it will be useful,
+ 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 cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
+ along with solidity. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* @author Christian <c@ethdev.com>
@@ -20,19 +20,24 @@
* Tests for the Solidity optimizer.
*/
-#include <string>
-#include <tuple>
-#include <memory>
-#include <boost/test/unit_test.hpp>
-#include <boost/lexical_cast.hpp>
#include <test/libsolidity/SolidityExecutionFramework.h>
+
#include <libevmasm/CommonSubexpressionEliminator.h>
+#include <libevmasm/PeepholeOptimiser.h>
#include <libevmasm/ControlFlowGraph.h>
#include <libevmasm/Assembly.h>
#include <libevmasm/BlockDeduplicator.h>
+#include <boost/test/unit_test.hpp>
+#include <boost/lexical_cast.hpp>
+
+#include <string>
+#include <tuple>
+#include <memory>
+
using namespace std;
using namespace dev::eth;
+using namespace dev::test;
namespace dev
{
@@ -41,10 +46,29 @@ namespace solidity
namespace test
{
-class OptimizerTestFramework: public ExecutionFramework
+class OptimizerTestFramework: public SolidityExecutionFramework
{
public:
OptimizerTestFramework() { }
+
+ bytes const& compileAndRunWithOptimizer(
+ std::string const& _sourceCode,
+ u256 const& _value = 0,
+ std::string const& _contractName = "",
+ bool const _optimize = true,
+ unsigned const _optimizeRuns = 200
+ )
+ {
+ bool const c_optimize = m_optimize;
+ unsigned const c_optimizeRuns = m_optimizeRuns;
+ m_optimize = _optimize;
+ m_optimizeRuns = _optimizeRuns;
+ bytes const& ret = compileAndRun(_sourceCode, _value, _contractName);
+ m_optimize = c_optimize;
+ m_optimizeRuns = c_optimizeRuns;
+ return ret;
+ }
+
/// Compiles the source code with and without optimizing.
void compileBothVersions(
std::string const& _sourceCode,
@@ -52,22 +76,16 @@ public:
std::string const& _contractName = ""
)
{
- m_optimize = false;
- bytes nonOptimizedBytecode = compileAndRun(_sourceCode, _value, _contractName);
+ bytes nonOptimizedBytecode = compileAndRunWithOptimizer(_sourceCode, _value, _contractName, false);
m_nonOptimizedContract = m_contractAddress;
- m_optimize = true;
- bytes optimizedBytecode = compileAndRun(_sourceCode, _value, _contractName);
- size_t nonOptimizedSize = 0;
- solidity::eachInstruction(nonOptimizedBytecode, [&](Instruction, u256 const&) {
- nonOptimizedSize++;
- });
- size_t optimizedSize = 0;
- solidity::eachInstruction(optimizedBytecode, [&](Instruction, u256 const&) {
- optimizedSize++;
- });
+ bytes optimizedBytecode = compileAndRunWithOptimizer(_sourceCode, _value, _contractName, true);
+ size_t nonOptimizedSize = numInstructions(nonOptimizedBytecode);
+ size_t optimizedSize = numInstructions(optimizedBytecode);
BOOST_CHECK_MESSAGE(
- nonOptimizedSize > optimizedSize,
- "Optimizer did not reduce bytecode size."
+ optimizedSize < nonOptimizedSize,
+ string("Optimizer did not reduce bytecode size. Non-optimized size: ") +
+ std::to_string(nonOptimizedSize) + " - optimized size: " +
+ std::to_string(optimizedSize)
);
m_optimizedContract = m_contractAddress;
}
@@ -151,6 +169,22 @@ public:
}
protected:
+ /// @returns the number of intructions in the given bytecode, not taking the metadata hash
+ /// into account.
+ size_t numInstructions(bytes const& _bytecode)
+ {
+ BOOST_REQUIRE(_bytecode.size() > 5);
+ size_t metadataSize = (_bytecode[_bytecode.size() - 2] << 8) + _bytecode[_bytecode.size() - 1];
+ BOOST_REQUIRE_MESSAGE(metadataSize == 0x29, "Invalid metadata size");
+ BOOST_REQUIRE(_bytecode.size() >= metadataSize + 2);
+ bytes realCode = bytes(_bytecode.begin(), _bytecode.end() - metadataSize - 2);
+ size_t instructions = 0;
+ solidity::eachInstruction(realCode, [&](Instruction, u256 const&) {
+ instructions++;
+ });
+ return instructions;
+ }
+
Address m_optimizedContract;
Address m_nonOptimizedContract;
};
@@ -310,8 +344,7 @@ BOOST_AUTO_TEST_CASE(retain_information_in_branches)
compareVersions("f(uint256,bytes32)", 8, "def");
compareVersions("f(uint256,bytes32)", 10, "ghi");
- m_optimize = true;
- bytes optimizedBytecode = compileAndRun(sourceCode, 0, "c");
+ bytes optimizedBytecode = compileAndRunWithOptimizer(sourceCode, 0, "c", true);
size_t numSHA3s = 0;
eachInstruction(optimizedBytecode, [&](Instruction _instr, u256 const&) {
if (_instr == Instruction::SHA3)
@@ -354,8 +387,7 @@ BOOST_AUTO_TEST_CASE(store_tags_as_unions)
compileBothVersions(sourceCode);
compareVersions("f(uint256,bytes32)", 7, "abc");
- m_optimize = true;
- bytes optimizedBytecode = compileAndRun(sourceCode, 0, "test");
+ bytes optimizedBytecode = compileAndRunWithOptimizer(sourceCode, 0, "test", true);
size_t numSHA3s = 0;
eachInstruction(optimizedBytecode, [&](Instruction _instr, u256 const&) {
if (_instr == Instruction::SHA3)
@@ -1121,6 +1153,40 @@ BOOST_AUTO_TEST_CASE(block_deduplicator_loops)
BOOST_CHECK_EQUAL(pushTags.size(), 1);
}
+BOOST_AUTO_TEST_CASE(clear_unreachable_code)
+{
+ AssemblyItems items{
+ AssemblyItem(PushTag, 1),
+ Instruction::JUMP,
+ u256(0),
+ Instruction::SLOAD,
+ AssemblyItem(Tag, 2),
+ u256(5),
+ u256(6),
+ Instruction::SSTORE,
+ AssemblyItem(PushTag, 1),
+ Instruction::JUMP,
+ u256(5),
+ u256(6)
+ };
+ AssemblyItems expectation{
+ AssemblyItem(PushTag, 1),
+ Instruction::JUMP,
+ AssemblyItem(Tag, 2),
+ u256(5),
+ u256(6),
+ Instruction::SSTORE,
+ AssemblyItem(PushTag, 1),
+ Instruction::JUMP
+ };
+ PeepholeOptimiser peepOpt(items);
+ BOOST_REQUIRE(peepOpt.optimise());
+ BOOST_CHECK_EQUAL_COLLECTIONS(
+ items.begin(), items.end(),
+ expectation.begin(), expectation.end()
+ );
+}
+
BOOST_AUTO_TEST_CASE(computing_constants)
{
char const* sourceCode = R"(
@@ -1148,9 +1214,7 @@ BOOST_AUTO_TEST_CASE(computing_constants)
compareVersions("set()");
compareVersions("get()");
- m_optimize = true;
- m_optimizeRuns = 1;
- bytes optimizedBytecode = compileAndRun(sourceCode, 0, "c");
+ bytes optimizedBytecode = compileAndRunWithOptimizer(sourceCode, 0, "c", true, 1);
bytes complicatedConstant = toBigEndian(u256("0x817416927846239487123469187231298734162934871263941234127518276"));
unsigned occurrences = 0;
for (auto iter = optimizedBytecode.cbegin(); iter < optimizedBytecode.cend(); ++occurrences)
@@ -1266,6 +1330,29 @@ BOOST_AUTO_TEST_CASE(invalid_state_at_control_flow_join)
compareVersions("test()");
}
+BOOST_AUTO_TEST_CASE(cse_sub_zero)
+{
+ checkCSE({
+ u256(0),
+ Instruction::DUP2,
+ Instruction::SUB
+ }, {
+ Instruction::DUP1
+ });
+
+ checkCSE({
+ Instruction::DUP1,
+ u256(0),
+ Instruction::SUB
+ }, {
+ u256(0),
+ Instruction::DUP2,
+ Instruction::SWAP1,
+ Instruction::SUB
+ });
+}
+
+
BOOST_AUTO_TEST_SUITE_END()
}
diff --git a/test/libsolidity/SolidityParser.cpp b/test/libsolidity/SolidityParser.cpp
index 914dbc30..a3bfab75 100644
--- a/test/libsolidity/SolidityParser.cpp
+++ b/test/libsolidity/SolidityParser.cpp
@@ -1,18 +1,18 @@
/*
- This file is part of cpp-ethereum.
+ This file is part of solidity.
- cpp-ethereum is free software: you can redistribute it and/or modify
+ 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.
- cpp-ethereum is distributed in the hope that it will be useful,
+ 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 cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
+ along with solidity. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* @author Christian <c@ethdev.com>
@@ -26,6 +26,7 @@
#include <libsolidity/parsing/Parser.h>
#include <libsolidity/interface/Exceptions.h>
#include "../TestHelper.h"
+#include "ErrorCheck.h"
using namespace std;
@@ -71,6 +72,22 @@ bool successParse(std::string const& _source)
return true;
}
+Error getError(std::string const& _source)
+{
+ ErrorList errors;
+ try
+ {
+ parseText(_source, errors);
+ }
+ catch (FatalError const& /*_exception*/)
+ {
+ // no-op
+ }
+ Error const* error = Error::containsErrorOfType(errors, Error::Type::ParserError);
+ BOOST_REQUIRE(error);
+ return *error;
+}
+
void checkFunctionNatspec(
FunctionDefinition const* _function,
std::string const& _expectedDoc
@@ -83,78 +100,102 @@ void checkFunctionNatspec(
}
+#define CHECK_PARSE_ERROR(source, substring) \
+do \
+{\
+ Error err = getError((source)); \
+ BOOST_CHECK(searchErrorMessage(err, (substring))); \
+}\
+while(0)
+
BOOST_AUTO_TEST_SUITE(SolidityParser)
BOOST_AUTO_TEST_CASE(smoke_test)
{
- char const* text = "contract test {\n"
- " uint256 stateVariable1;\n"
- "}\n";
+ char const* text = R"(
+ contract test {
+ uint256 stateVariable1;
+ }
+ )";
BOOST_CHECK(successParse(text));
}
BOOST_AUTO_TEST_CASE(missing_variable_name_in_declaration)
{
- char const* text = "contract test {\n"
- " uint256 ;\n"
- "}\n";
- BOOST_CHECK(!successParse(text));
+ char const* text = R"(
+ contract test {
+ uint256 ;
+ }
+ )";
+ CHECK_PARSE_ERROR(text, "Expected identifier");
}
BOOST_AUTO_TEST_CASE(empty_function)
{
- char const* text = "contract test {\n"
- " uint256 stateVar;\n"
- " function functionName(bytes20 arg1, address addr) constant\n"
- " returns (int id)\n"
- " { }\n"
- "}\n";
+ char const* text = R"(
+ contract test {
+ uint256 stateVar;
+ function functionName(bytes20 arg1, address addr) constant
+ returns (int id)
+ { }
+ }
+ )";
BOOST_CHECK(successParse(text));
}
BOOST_AUTO_TEST_CASE(no_function_params)
{
- char const* text = "contract test {\n"
- " uint256 stateVar;\n"
- " function functionName() {}\n"
- "}\n";
+ char const* text = R"(
+ contract test {
+ uint256 stateVar;
+ function functionName() {}
+ }
+ )";
BOOST_CHECK(successParse(text));
}
BOOST_AUTO_TEST_CASE(single_function_param)
{
- char const* text = "contract test {\n"
- " uint256 stateVar;\n"
- " function functionName(bytes32 input) returns (bytes32 out) {}\n"
- "}\n";
+ char const* text = R"(
+ contract test {
+ uint256 stateVar;
+ function functionName(bytes32 input) returns (bytes32 out) {}
+ }
+ )";
BOOST_CHECK(successParse(text));
}
BOOST_AUTO_TEST_CASE(function_no_body)
{
- char const* text = "contract test {\n"
- " function functionName(bytes32 input) returns (bytes32 out);\n"
- "}\n";
+ char const* text = R"(
+ contract test {
+ function functionName(bytes32 input) returns (bytes32 out);
+ }
+ )";
BOOST_CHECK(successParse(text));
}
BOOST_AUTO_TEST_CASE(missing_parameter_name_in_named_args)
{
- char const* text = "contract test {\n"
- " function a(uint a, uint b, uint c) returns (uint r) { r = a * 100 + b * 10 + c * 1; }\n"
- " function b() returns (uint r) { r = a({: 1, : 2, : 3}); }\n"
- "}\n";
- BOOST_CHECK(!successParse(text));
+ char const* text = R"(
+ contract test {
+ function a(uint a, uint b, uint c) returns (uint r) { r = a * 100 + b * 10 + c * 1; }
+ function b() returns (uint r) { r = a({: 1, : 2, : 3}); }
+ }
+ )";
+ CHECK_PARSE_ERROR(text, "Expected identifier");
}
BOOST_AUTO_TEST_CASE(missing_argument_in_named_args)
{
- char const* text = "contract test {\n"
- " function a(uint a, uint b, uint c) returns (uint r) { r = a * 100 + b * 10 + c * 1; }\n"
- " function b() returns (uint r) { r = a({a: , b: , c: }); }\n"
- "}\n";
- BOOST_CHECK(!successParse(text));
+ char const* text = R"(
+ contract test {
+ function a(uint a, uint b, uint c) returns (uint r) { r = a * 100 + b * 10 + c * 1; }
+ function b() returns (uint r) { r = a({a: , b: , c: }); }
+ }
+ )";
+ CHECK_PARSE_ERROR(text, "Expected primary expression");
}
BOOST_AUTO_TEST_CASE(two_exact_functions)
@@ -184,11 +225,13 @@ BOOST_AUTO_TEST_CASE(overloaded_functions)
BOOST_AUTO_TEST_CASE(function_natspec_documentation)
{
- char const* text = "contract test {\n"
- " uint256 stateVar;\n"
- " /// This is a test function\n"
- " function functionName(bytes32 input) returns (bytes32 out) {}\n"
- "}\n";
+ char const* text = R"(
+ contract test {
+ uint256 stateVar;
+ /// This is a test function
+ function functionName(bytes32 input) returns (bytes32 out) {}
+ }
+ )";
BOOST_CHECK(successParse(text));
ErrorList errors;
ASTPointer<ContractDefinition> contract = parseText(text, errors);
@@ -202,11 +245,13 @@ BOOST_AUTO_TEST_CASE(function_natspec_documentation)
BOOST_AUTO_TEST_CASE(function_normal_comments)
{
FunctionDefinition const* function = nullptr;
- char const* text = "contract test {\n"
- " uint256 stateVar;\n"
- " // We won't see this comment\n"
- " function functionName(bytes32 input) returns (bytes32 out) {}\n"
- "}\n";
+ char const* text = R"(
+ contract test {
+ uint256 stateVar;
+ // We won't see this comment
+ function functionName(bytes32 input) returns (bytes32 out) {}
+ }
+ )";
BOOST_CHECK(successParse(text));
ErrorList errors;
ASTPointer<ContractDefinition> contract = parseText(text, errors);
@@ -219,17 +264,19 @@ BOOST_AUTO_TEST_CASE(function_normal_comments)
BOOST_AUTO_TEST_CASE(multiple_functions_natspec_documentation)
{
FunctionDefinition const* function = nullptr;
- char const* text = "contract test {\n"
- " uint256 stateVar;\n"
- " /// This is test function 1\n"
- " function functionName1(bytes32 input) returns (bytes32 out) {}\n"
- " /// This is test function 2\n"
- " function functionName2(bytes32 input) returns (bytes32 out) {}\n"
- " // nothing to see here\n"
- " function functionName3(bytes32 input) returns (bytes32 out) {}\n"
- " /// This is test function 4\n"
- " function functionName4(bytes32 input) returns (bytes32 out) {}\n"
- "}\n";
+ char const* text = R"(
+ contract test {
+ uint256 stateVar;
+ /// This is test function 1
+ function functionName1(bytes32 input) returns (bytes32 out) {}
+ /// This is test function 2
+ function functionName2(bytes32 input) returns (bytes32 out) {}
+ // nothing to see here
+ function functionName3(bytes32 input) returns (bytes32 out) {}
+ /// This is test function 4
+ function functionName4(bytes32 input) returns (bytes32 out) {}
+ }
+ )";
BOOST_CHECK(successParse(text));
ErrorList errors;
ASTPointer<ContractDefinition> contract = parseText(text, errors);
@@ -252,12 +299,14 @@ BOOST_AUTO_TEST_CASE(multiple_functions_natspec_documentation)
BOOST_AUTO_TEST_CASE(multiline_function_documentation)
{
FunctionDefinition const* function = nullptr;
- char const* text = "contract test {\n"
- " uint256 stateVar;\n"
- " /// This is a test function\n"
- " /// and it has 2 lines\n"
- " function functionName1(bytes32 input) returns (bytes32 out) {}\n"
- "}\n";
+ char const* text = R"(
+ contract test {
+ uint256 stateVar;
+ /// This is a test function
+ /// and it has 2 lines
+ function functionName1(bytes32 input) returns (bytes32 out) {}
+ }
+ )";
BOOST_CHECK(successParse(text));
ErrorList errors;
ASTPointer<ContractDefinition> contract = parseText(text, errors);
@@ -270,19 +319,21 @@ BOOST_AUTO_TEST_CASE(multiline_function_documentation)
BOOST_AUTO_TEST_CASE(natspec_comment_in_function_body)
{
FunctionDefinition const* function = nullptr;
- char const* text = "contract test {\n"
- " /// fun1 description\n"
- " function fun1(uint256 a) {\n"
- " var b;\n"
- " /// I should not interfere with actual natspec comments\n"
- " uint256 c;\n"
- " mapping(address=>bytes32) d;\n"
- " bytes7 name = \"Solidity\";"
- " }\n"
- " /// This is a test function\n"
- " /// and it has 2 lines\n"
- " function fun(bytes32 input) returns (bytes32 out) {}\n"
- "}\n";
+ char const* text = R"(
+ contract test {
+ /// fun1 description
+ function fun1(uint256 a) {
+ var b;
+ /// I should not interfere with actual natspec comments
+ uint256 c;
+ mapping(address=>bytes32) d;
+ bytes7 name = "Solidity";
+ }
+ /// This is a test function
+ /// and it has 2 lines
+ function fun(bytes32 input) returns (bytes32 out) {}
+ }
+ )";
BOOST_CHECK(successParse(text));
ErrorList errors;
ASTPointer<ContractDefinition> contract = parseText(text, errors);
@@ -299,17 +350,19 @@ BOOST_AUTO_TEST_CASE(natspec_comment_in_function_body)
BOOST_AUTO_TEST_CASE(natspec_docstring_between_keyword_and_signature)
{
FunctionDefinition const* function = nullptr;
- char const* text = "contract test {\n"
- " uint256 stateVar;\n"
- " function ///I am in the wrong place \n"
- " fun1(uint256 a) {\n"
- " var b;\n"
- " /// I should not interfere with actual natspec comments\n"
- " uint256 c;\n"
- " mapping(address=>bytes32) d;\n"
- " bytes7 name = \"Solidity\";"
- " }\n"
- "}\n";
+ char const* text = R"(
+ contract test {
+ uint256 stateVar;
+ function ///I am in the wrong place
+ fun1(uint256 a) {
+ var b;
+ /// I should not interfere with actual natspec comments
+ uint256 c;
+ mapping(address=>bytes32) d;
+ bytes7 name = "Solidity";
+ }
+ }
+ )";
BOOST_CHECK(successParse(text));
ErrorList errors;
ASTPointer<ContractDefinition> contract = parseText(text, errors);
@@ -323,17 +376,19 @@ BOOST_AUTO_TEST_CASE(natspec_docstring_between_keyword_and_signature)
BOOST_AUTO_TEST_CASE(natspec_docstring_after_signature)
{
FunctionDefinition const* function = nullptr;
- char const* text = "contract test {\n"
- " uint256 stateVar;\n"
- " function fun1(uint256 a) {\n"
- " /// I should have been above the function signature\n"
- " var b;\n"
- " /// I should not interfere with actual natspec comments\n"
- " uint256 c;\n"
- " mapping(address=>bytes32) d;\n"
- " bytes7 name = \"Solidity\";"
- " }\n"
- "}\n";
+ char const* text = R"(
+ contract test {
+ uint256 stateVar;
+ function fun1(uint256 a) {
+ /// I should have been above the function signature
+ var b;
+ /// I should not interfere with actual natspec comments
+ uint256 c;
+ mapping(address=>bytes32) d;
+ bytes7 name = "Solidity";
+ }
+ }
+ )";
BOOST_CHECK(successParse(text));
ErrorList errors;
ASTPointer<ContractDefinition> contract = parseText(text, errors);
@@ -346,71 +401,83 @@ BOOST_AUTO_TEST_CASE(natspec_docstring_after_signature)
BOOST_AUTO_TEST_CASE(struct_definition)
{
- char const* text = "contract test {\n"
- " uint256 stateVar;\n"
- " struct MyStructName {\n"
- " address addr;\n"
- " uint256 count;\n"
- " }\n"
- "}\n";
+ char const* text = R"(
+ contract test {
+ uint256 stateVar;
+ struct MyStructName {
+ address addr;
+ uint256 count;
+ }
+ }
+ )";
BOOST_CHECK(successParse(text));
}
BOOST_AUTO_TEST_CASE(mapping)
{
- char const* text = "contract test {\n"
- " mapping(address => bytes32) names;\n"
- "}\n";
+ char const* text = R"(
+ contract test {
+ mapping(address => bytes32) names;
+ }
+ )";
BOOST_CHECK(successParse(text));
}
BOOST_AUTO_TEST_CASE(mapping_in_struct)
{
- char const* text = "contract test {\n"
- " struct test_struct {\n"
- " address addr;\n"
- " uint256 count;\n"
- " mapping(bytes32 => test_struct) self_reference;\n"
- " }\n"
- "}\n";
+ char const* text = R"(
+ contract test {
+ struct test_struct {
+ address addr;
+ uint256 count;
+ mapping(bytes32 => test_struct) self_reference;
+ }
+ }
+ )";
BOOST_CHECK(successParse(text));
}
BOOST_AUTO_TEST_CASE(mapping_to_mapping_in_struct)
{
- char const* text = "contract test {\n"
- " struct test_struct {\n"
- " address addr;\n"
- " mapping (uint64 => mapping (bytes32 => uint)) complex_mapping;\n"
- " }\n"
- "}\n";
+ char const* text = R"(
+ contract test {
+ struct test_struct {
+ address addr;
+ mapping (uint64 => mapping (bytes32 => uint)) complex_mapping;
+ }
+ }
+ )";
BOOST_CHECK(successParse(text));
}
BOOST_AUTO_TEST_CASE(variable_definition)
{
- char const* text = "contract test {\n"
- " function fun(uint256 a) {\n"
- " var b;\n"
- " uint256 c;\n"
- " mapping(address=>bytes32) d;\n"
- " customtype varname;\n"
- " }\n"
- "}\n";
+ char const* text = R"(
+ contract test {
+ function fun(uint256 a) {
+ var b;
+ uint256 c;
+ mapping(address=>bytes32) d;
+ customtype varname;
+ }
+ }
+ )";
BOOST_CHECK(successParse(text));
}
BOOST_AUTO_TEST_CASE(variable_definition_with_initialization)
{
- char const* text = "contract test {\n"
- " function fun(uint256 a) {\n"
- " var b = 2;\n"
- " uint256 c = 0x87;\n"
- " mapping(address=>bytes32) d;\n"
- " bytes7 name = \"Solidity\";"
- " customtype varname;\n"
- " }\n"
- "}\n";
+ char const* text = R"(
+ contract test {
+ function fun(uint256 a) {
+ var b = 2;
+ uint256 c = 0x87;
+ mapping(address=>bytes32) d;
+ bytes7 name = "Solidity";
+ customtype varname;
+ }
+ }
+ )";
BOOST_CHECK(successParse(text));
}
@@ -421,7 +488,7 @@ BOOST_AUTO_TEST_CASE(variable_definition_in_function_parameter)
function fun(var a) {}
}
)";
- BOOST_CHECK(!successParse(text));
+ CHECK_PARSE_ERROR(text, "Expected explicit type name");
}
BOOST_AUTO_TEST_CASE(variable_definition_in_mapping)
@@ -433,7 +500,7 @@ BOOST_AUTO_TEST_CASE(variable_definition_in_mapping)
}
}
)";
- BOOST_CHECK(!successParse(text));
+ CHECK_PARSE_ERROR(text, "Expected elementary type name for mapping key type");
}
BOOST_AUTO_TEST_CASE(variable_definition_in_function_return)
@@ -445,26 +512,30 @@ BOOST_AUTO_TEST_CASE(variable_definition_in_function_return)
}
}
)";
- BOOST_CHECK(!successParse(text));
+ CHECK_PARSE_ERROR(text, "Expected explicit type name");
}
BOOST_AUTO_TEST_CASE(operator_expression)
{
- char const* text = "contract test {\n"
- " function fun(uint256 a) {\n"
- " uint256 x = (1 + 4) || false && (1 - 12) + -9;\n"
- " }\n"
- "}\n";
+ char const* text = R"(
+ contract test {
+ function fun(uint256 a) {
+ uint256 x = (1 + 4) || false && (1 - 12) + -9;
+ }
+ }
+ )";
BOOST_CHECK(successParse(text));
}
BOOST_AUTO_TEST_CASE(complex_expression)
{
- char const* text = "contract test {\n"
- " function fun(uint256 a) {\n"
- " uint256 x = (1 + 4).member(++67)[a/=9] || true;\n"
- " }\n"
- "}\n";
+ char const* text = R"(
+ contract test {
+ function fun(uint256 a) {
+ uint256 x = (1 + 4).member(++67)[a/=9] || true;
+ }
+ }
+ )";
BOOST_CHECK(successParse(text));
}
@@ -475,248 +546,294 @@ BOOST_AUTO_TEST_CASE(exp_expression)
function fun(uint256 a) {
uint256 x = 3 ** a;
}
- })";
+ }
+ )";
BOOST_CHECK(successParse(text));
}
BOOST_AUTO_TEST_CASE(while_loop)
{
- char const* text = "contract test {\n"
- " function fun(uint256 a) {\n"
- " while (true) { uint256 x = 1; break; continue; } x = 9;\n"
- " }\n"
- "}\n";
+ char const* text = R"(
+ contract test {
+ function fun(uint256 a) {
+ while (true) { uint256 x = 1; break; continue; } x = 9;
+ }
+ }
+ )";
BOOST_CHECK(successParse(text));
}
BOOST_AUTO_TEST_CASE(for_loop_vardef_initexpr)
{
- char const* text = "contract test {\n"
- " function fun(uint256 a) {\n"
- " for (uint256 i = 0; i < 10; i++)\n"
- " { uint256 x = i; break; continue; }\n"
- " }\n"
- "}\n";
+ char const* text = R"(
+ contract test {
+ function fun(uint256 a) {
+ for (uint256 i = 0; i < 10; i++) {
+ uint256 x = i; break; continue;
+ }
+ }
+ }
+ )";
BOOST_CHECK(successParse(text));
}
BOOST_AUTO_TEST_CASE(for_loop_simple_initexpr)
{
- char const* text = "contract test {\n"
- " function fun(uint256 a) {\n"
- " uint256 i =0;\n"
- " for (i = 0; i < 10; i++)\n"
- " { uint256 x = i; break; continue; }\n"
- " }\n"
- "}\n";
+ char const* text = R"(
+ contract test {
+ function fun(uint256 a) {
+ uint256 i =0;
+ for (i = 0; i < 10; i++) {
+ uint256 x = i; break; continue;
+ }
+ }
+ }
+ )";
BOOST_CHECK(successParse(text));
}
BOOST_AUTO_TEST_CASE(for_loop_simple_noexpr)
{
- char const* text = "contract test {\n"
- " function fun(uint256 a) {\n"
- " uint256 i =0;\n"
- " for (;;)\n"
- " { uint256 x = i; break; continue; }\n"
- " }\n"
- "}\n";
+ char const* text = R"(
+ contract test {
+ function fun(uint256 a) {
+ uint256 i =0;
+ for (;;) {
+ uint256 x = i; break; continue;
+ }
+ }
+ }
+ )";
BOOST_CHECK(successParse(text));
}
BOOST_AUTO_TEST_CASE(for_loop_single_stmt_body)
{
- char const* text = "contract test {\n"
- " function fun(uint256 a) {\n"
- " uint256 i =0;\n"
- " for (i = 0; i < 10; i++)\n"
- " continue;\n"
- " }\n"
- "}\n";
+ char const* text = R"(
+ contract test {
+ function fun(uint256 a) {
+ uint256 i = 0;
+ for (i = 0; i < 10; i++)
+ continue;
+ }
+ }
+ )";
BOOST_CHECK(successParse(text));
}
BOOST_AUTO_TEST_CASE(if_statement)
{
- char const* text = "contract test {\n"
- " function fun(uint256 a) {\n"
- " if (a >= 8) { return 2; } else { var b = 7; }\n"
- " }\n"
- "}\n";
+ char const* text = R"(
+ contract test {
+ function fun(uint256 a) {
+ if (a >= 8) { return 2; } else { var b = 7; }
+ }
+ }
+ )";
BOOST_CHECK(successParse(text));
}
BOOST_AUTO_TEST_CASE(else_if_statement)
{
- char const* text = "contract test {\n"
- " function fun(uint256 a) returns (address b) {\n"
- " if (a < 0) b = 0x67; else if (a == 0) b = 0x12; else b = 0x78;\n"
- " }\n"
- "}\n";
+ char const* text = R"(
+ contract test {
+ function fun(uint256 a) returns (address b) {
+ if (a < 0) b = 0x67; else if (a == 0) b = 0x12; else b = 0x78;
+ }
+ }
+ )";
BOOST_CHECK(successParse(text));
}
BOOST_AUTO_TEST_CASE(statement_starting_with_type_conversion)
{
- char const* text = "contract test {\n"
- " function fun() {\n"
- " uint64(2);\n"
- " uint64[7](3);\n"
- " uint64[](3);\n"
- " }\n"
- "}\n";
+ char const* text = R"(
+ contract test {
+ function fun() {
+ uint64(2);
+ uint64[7](3);
+ uint64[](3);
+ }
+ }
+ )";
BOOST_CHECK(successParse(text));
}
BOOST_AUTO_TEST_CASE(type_conversion_to_dynamic_array)
{
- char const* text = "contract test {\n"
- " function fun() {\n"
- " var x = uint64[](3);\n"
- " }\n"
- "}\n";
+ char const* text = R"(
+ contract test {
+ function fun() {
+ var x = uint64[](3);
+ }
+ }
+ )";
BOOST_CHECK(successParse(text));
}
BOOST_AUTO_TEST_CASE(import_directive)
{
- char const* text = "import \"abc\";\n"
- "contract test {\n"
- " function fun() {\n"
- " uint64(2);\n"
- " }\n"
- "}\n";
+ char const* text = R"(
+ import "abc";
+ contract test {
+ function fun() {
+ uint64(2);
+ }
+ }
+ )";
BOOST_CHECK(successParse(text));
}
BOOST_AUTO_TEST_CASE(multiple_contracts)
{
- char const* text = "contract test {\n"
- " function fun() {\n"
- " uint64(2);\n"
- " }\n"
- "}\n"
- "contract test2 {\n"
- " function fun() {\n"
- " uint64(2);\n"
- " }\n"
- "}\n";
+ char const* text = R"(
+ contract test {
+ function fun() {
+ uint64(2);
+ }
+ }
+ contract test2 {
+ function fun() {
+ uint64(2);
+ }
+ }
+ )";
BOOST_CHECK(successParse(text));
}
BOOST_AUTO_TEST_CASE(multiple_contracts_and_imports)
{
- char const* text = "import \"abc\";\n"
- "contract test {\n"
- " function fun() {\n"
- " uint64(2);\n"
- " }\n"
- "}\n"
- "import \"def\";\n"
- "contract test2 {\n"
- " function fun() {\n"
- " uint64(2);\n"
- " }\n"
- "}\n"
- "import \"ghi\";\n";
+ char const* text = R"(
+ import "abc";
+ contract test {
+ function fun() {
+ uint64(2);
+ }
+ }
+ import "def";
+ contract test2 {
+ function fun() {
+ uint64(2);
+ }
+ }
+ import "ghi";
+ )";
BOOST_CHECK(successParse(text));
}
BOOST_AUTO_TEST_CASE(contract_inheritance)
{
- char const* text = "contract base {\n"
- " function fun() {\n"
- " uint64(2);\n"
- " }\n"
- "}\n"
- "contract derived is base {\n"
- " function fun() {\n"
- " uint64(2);\n"
- " }\n"
- "}\n";
+ char const* text = R"(
+ contract base {
+ function fun() {
+ uint64(2);
+ }
+ }
+ contract derived is base {
+ function fun() {
+ uint64(2);
+ }
+ }
+ )";
BOOST_CHECK(successParse(text));
}
BOOST_AUTO_TEST_CASE(contract_multiple_inheritance)
{
- char const* text = "contract base {\n"
- " function fun() {\n"
- " uint64(2);\n"
- " }\n"
- "}\n"
- "contract derived is base, nonExisting {\n"
- " function fun() {\n"
- " uint64(2);\n"
- " }\n"
- "}\n";
+ char const* text = R"(
+ contract base {
+ function fun() {
+ uint64(2);
+ }
+ }
+ contract derived is base, nonExisting {
+ function fun() {
+ uint64(2);
+ }
+ }
+ )";
BOOST_CHECK(successParse(text));
}
BOOST_AUTO_TEST_CASE(contract_multiple_inheritance_with_arguments)
{
- char const* text = "contract base {\n"
- " function fun() {\n"
- " uint64(2);\n"
- " }\n"
- "}\n"
- "contract derived is base(2), nonExisting(\"abc\", \"def\", base.fun()) {\n"
- " function fun() {\n"
- " uint64(2);\n"
- " }\n"
- "}\n";
+ char const* text = R"(
+ contract base {
+ function fun() {
+ uint64(2);
+ }
+ }
+ contract derived is base(2), nonExisting("abc", "def", base.fun()) {
+ function fun() {
+ uint64(2);
+ }
+ }
+ )";
BOOST_CHECK(successParse(text));
}
BOOST_AUTO_TEST_CASE(placeholder_in_function_context)
{
- char const* text = "contract c {\n"
- " function fun() returns (uint r) {\n"
- " var _ = 8;\n"
- " return _ + 1;"
- " }\n"
- "}\n";
+ char const* text = R"(
+ contract c {
+ function fun() returns (uint r) {
+ var _ = 8;
+ return _ + 1;
+ }
+ }
+ )";
BOOST_CHECK(successParse(text));
}
BOOST_AUTO_TEST_CASE(modifier)
{
- char const* text = "contract c {\n"
- " modifier mod { if (msg.sender == 0) _; }\n"
- "}\n";
+ char const* text = R"(
+ contract c {
+ modifier mod { if (msg.sender == 0) _; }
+ }
+ )";
BOOST_CHECK(successParse(text));
}
BOOST_AUTO_TEST_CASE(modifier_without_semicolon)
{
- char const* text = "contract c {\n"
- " modifier mod { if (msg.sender == 0) _ }\n"
- "}\n";
- BOOST_CHECK(!successParse(text));
+ char const* text = R"(
+ contract c {
+ modifier mod { if (msg.sender == 0) _ }
+ }
+ )";
+ CHECK_PARSE_ERROR(text, "Expected token Semicolon got");
}
BOOST_AUTO_TEST_CASE(modifier_arguments)
{
- char const* text = "contract c {\n"
- " modifier mod(uint a) { if (msg.sender == a) _; }\n"
- "}\n";
+ char const* text = R"(
+ contract c {
+ modifier mod(address a) { if (msg.sender == a) _; }
+ }
+ )";
BOOST_CHECK(successParse(text));
}
BOOST_AUTO_TEST_CASE(modifier_invocation)
{
- char const* text = "contract c {\n"
- " modifier mod1(uint a) { if (msg.sender == a) _; }\n"
- " modifier mod2 { if (msg.sender == 2) _; }\n"
- " function f() mod1(7) mod2 { }\n"
- "}\n";
+ char const* text = R"(
+ contract c {
+ modifier mod1(uint a) { if (msg.sender == a) _; }
+ modifier mod2 { if (msg.sender == 2) _; }
+ function f() mod1(7) mod2 { }
+ }
+ )";
BOOST_CHECK(successParse(text));
}
BOOST_AUTO_TEST_CASE(fallback_function)
{
- char const* text = "contract c {\n"
- " function() { }\n"
- "}\n";
+ char const* text = R"(
+ contract c {
+ function() { }
+ }
+ )";
BOOST_CHECK(successParse(text));
}
@@ -769,7 +886,7 @@ BOOST_AUTO_TEST_CASE(multiple_visibility_specifiers)
contract c {
uint private internal a;
})";
- BOOST_CHECK(!successParse(text));
+ CHECK_PARSE_ERROR(text, "Visibility already specified");
}
BOOST_AUTO_TEST_CASE(literal_constants_with_ether_subdenominations)
@@ -824,7 +941,7 @@ BOOST_AUTO_TEST_CASE(empty_enum_declaration)
contract c {
enum foo { }
})";
- BOOST_CHECK(!successParse(text));
+ CHECK_PARSE_ERROR(text, "enum with no members is not allowed");
}
BOOST_AUTO_TEST_CASE(malformed_enum_declaration)
@@ -833,7 +950,7 @@ BOOST_AUTO_TEST_CASE(malformed_enum_declaration)
contract c {
enum foo { WARNING,}
})";
- BOOST_CHECK(!successParse(text));
+ CHECK_PARSE_ERROR(text, "Expected Identifier after");
}
BOOST_AUTO_TEST_CASE(external_function)
@@ -851,7 +968,7 @@ BOOST_AUTO_TEST_CASE(external_variable)
contract c {
uint external x;
})";
- BOOST_CHECK(!successParse(text));
+ CHECK_PARSE_ERROR(text, "Expected identifier");
}
BOOST_AUTO_TEST_CASE(arrays_in_storage)
@@ -899,7 +1016,7 @@ BOOST_AUTO_TEST_CASE(constant_is_keyword)
contract Foo {
uint constant = 4;
})";
- BOOST_CHECK(!successParse(text));
+ CHECK_PARSE_ERROR(text, "Expected identifier");
}
BOOST_AUTO_TEST_CASE(var_array)
@@ -908,7 +1025,7 @@ BOOST_AUTO_TEST_CASE(var_array)
contract Foo {
function f() { var[] a; }
})";
- BOOST_CHECK(!successParse(text));
+ CHECK_PARSE_ERROR(text, "Expected identifier");
}
BOOST_AUTO_TEST_CASE(location_specifiers_for_params)
@@ -940,7 +1057,7 @@ BOOST_AUTO_TEST_CASE(location_specifiers_for_state)
contract Foo {
uint[] memory x;
})";
- BOOST_CHECK(!successParse(text));
+ CHECK_PARSE_ERROR(text, "Expected identifier");
}
BOOST_AUTO_TEST_CASE(location_specifiers_with_var)
@@ -949,7 +1066,7 @@ BOOST_AUTO_TEST_CASE(location_specifiers_with_var)
contract Foo {
function f() { var memory x; }
})";
- BOOST_CHECK(!successParse(text));
+ CHECK_PARSE_ERROR(text, "Location specifier needs explicit type name");
}
BOOST_AUTO_TEST_CASE(empty_comment)
@@ -962,6 +1079,19 @@ BOOST_AUTO_TEST_CASE(empty_comment)
BOOST_CHECK(successParse(text));
}
+BOOST_AUTO_TEST_CASE(comment_end_with_double_star)
+{
+ char const* text = R"(
+ contract C1 {
+ /**
+ **/
+ }
+ contract C2 {}
+ )";
+ BOOST_CHECK(successParse(text));
+}
+
+
BOOST_AUTO_TEST_CASE(library_simple)
{
char const* text = R"(
@@ -983,7 +1113,7 @@ BOOST_AUTO_TEST_CASE(local_const_variable)
return local;
}
})";
- BOOST_CHECK(!successParse(text));
+ CHECK_PARSE_ERROR(text, "Expected token Semicolon");
}
BOOST_AUTO_TEST_CASE(multi_variable_declaration)
@@ -1102,7 +1232,7 @@ BOOST_AUTO_TEST_CASE(inline_array_empty_cells_check_lvalue)
}
}
)";
- BOOST_CHECK(!successParse(text));
+ CHECK_PARSE_ERROR(text, "Expected expression");
}
BOOST_AUTO_TEST_CASE(inline_array_empty_cells_check_without_lvalue)
@@ -1115,7 +1245,7 @@ BOOST_AUTO_TEST_CASE(inline_array_empty_cells_check_without_lvalue)
}
}
)";
- BOOST_CHECK(!successParse(text));
+ CHECK_PARSE_ERROR(text, "Expected expression");
}
BOOST_AUTO_TEST_CASE(conditional_true_false_literal)
@@ -1216,7 +1346,7 @@ BOOST_AUTO_TEST_CASE(no_double_radix_in_fixed_literal)
fixed40x40 pi = 3.14.15;
}
)";
- BOOST_CHECK(!successParse(text));
+ CHECK_PARSE_ERROR(text, "Expected token Semicolon");
}
BOOST_AUTO_TEST_CASE(invalid_fixed_conversion_leading_zeroes_check)
@@ -1228,7 +1358,7 @@ BOOST_AUTO_TEST_CASE(invalid_fixed_conversion_leading_zeroes_check)
}
}
)";
- BOOST_CHECK(!successParse(text));
+ CHECK_PARSE_ERROR(text, "Expected primary expression");
}
BOOST_AUTO_TEST_CASE(payable_accessor)
@@ -1238,7 +1368,7 @@ BOOST_AUTO_TEST_CASE(payable_accessor)
uint payable x;
}
)";
- BOOST_CHECK(!successParse(text));
+ CHECK_PARSE_ERROR(text, "Expected identifier");
}
BOOST_AUTO_TEST_CASE(function_type_in_expression)
@@ -1271,7 +1401,7 @@ BOOST_AUTO_TEST_CASE(function_type_as_storage_variable_with_modifiers)
function (uint, uint) modifier1() returns (uint) f1;
}
)";
- BOOST_CHECK(!successParse(text));
+ CHECK_PARSE_ERROR(text, "Expected token LBrace");
}
BOOST_AUTO_TEST_CASE(function_type_as_storage_variable_with_assignment)
diff --git a/test/libsolidity/SolidityScanner.cpp b/test/libsolidity/SolidityScanner.cpp
index 31b75f25..eb2f042c 100644
--- a/test/libsolidity/SolidityScanner.cpp
+++ b/test/libsolidity/SolidityScanner.cpp
@@ -1,18 +1,18 @@
/*
- This file is part of cpp-ethereum.
+ This file is part of solidity.
- cpp-ethereum is free software: you can redistribute it and/or modify
+ 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.
- cpp-ethereum is distributed in the hope that it will be useful,
+ 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 cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
+ along with solidity. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* @author Christian <c@ethdev.com>
diff --git a/test/libsolidity/SolidityTypes.cpp b/test/libsolidity/SolidityTypes.cpp
index 87dda9c2..dc3143c8 100644
--- a/test/libsolidity/SolidityTypes.cpp
+++ b/test/libsolidity/SolidityTypes.cpp
@@ -1,18 +1,18 @@
/*
- This file is part of cpp-ethereum.
+ This file is part of solidity.
- cpp-ethereum is free software: you can redistribute it and/or modify
+ 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.
- cpp-ethereum is distributed in the hope that it will be useful,
+ 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 cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
+ along with solidity. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* @author Christian <c@ethdev.com>