aboutsummaryrefslogtreecommitdiffstats
path: root/test/libsolidity
diff options
context:
space:
mode:
Diffstat (limited to 'test/libsolidity')
-rw-r--r--test/libsolidity/Assembly.cpp2
-rw-r--r--test/libsolidity/SolidityABIJSON.cpp141
-rw-r--r--test/libsolidity/SolidityEndToEndTest.cpp1033
-rw-r--r--test/libsolidity/SolidityExecutionFramework.h3
-rw-r--r--test/libsolidity/SolidityExpressionCompiler.cpp126
-rw-r--r--test/libsolidity/SolidityNameAndTypeResolution.cpp974
-rw-r--r--test/libsolidity/SolidityNatspecJSON.cpp344
-rw-r--r--test/libsolidity/SolidityOptimizer.cpp67
-rw-r--r--test/libsolidity/SolidityParser.cpp734
9 files changed, 2013 insertions, 1411 deletions
diff --git a/test/libsolidity/Assembly.cpp b/test/libsolidity/Assembly.cpp
index ed92ca2b..155dd5c9 100644
--- a/test/libsolidity/Assembly.cpp
+++ b/test/libsolidity/Assembly.cpp
@@ -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();
}
diff --git a/test/libsolidity/SolidityABIJSON.cpp b/test/libsolidity/SolidityABIJSON.cpp
index 6fc2bcee..043d74ed 100644
--- a/test/libsolidity/SolidityABIJSON.cpp
+++ b/test/libsolidity/SolidityABIJSON.cpp
@@ -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 62e9a457..2df6e9f2 100644
--- a/test/libsolidity/SolidityEndToEndTest.cpp
+++ b/test/libsolidity/SolidityEndToEndTest.cpp
@@ -44,17 +44,20 @@ 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);
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());
}
@@ -64,7 +67,8 @@ BOOST_AUTO_TEST_CASE(exp_operator)
char const* sourceCode = R"(
contract test {
function f(uint a) returns(uint d) { return 2 ** a; }
- })";
+ }
+ )";
compileAndRun(sourceCode);
testContractAgainstCppOnRange("f(uint256)", [](u256 const& a) -> u256 { return u256(1 << a.convert_to<int>()); }, 0, 16);
}
@@ -74,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)));
}
@@ -84,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)));
}
@@ -95,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)));
}
@@ -107,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)));
}
@@ -118,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)));
@@ -137,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)));
@@ -169,7 +178,7 @@ BOOST_AUTO_TEST_CASE(conditional_expression_storage_memory_1)
}
return ret;
- }
+ }
}
)";
compileAndRun(sourceCode);
@@ -203,7 +212,7 @@ BOOST_AUTO_TEST_CASE(conditional_expression_storage_memory_2)
}
return ret;
- }
+ }
}
)";
compileAndRun(sourceCode);
@@ -219,7 +228,7 @@ BOOST_AUTO_TEST_CASE(conditional_expression_different_types)
uint8 x = 0xcd;
uint16 y = 0xabab;
return cond ? x : y;
- }
+ }
}
)";
compileAndRun(sourceCode);
@@ -277,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
{
@@ -297,12 +308,14 @@ BOOST_AUTO_TEST_CASE(recursive_calls)
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)));
@@ -313,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
@@ -358,13 +377,15 @@ BOOST_AUTO_TEST_CASE(while_loop)
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
@@ -386,26 +407,28 @@ BOOST_AUTO_TEST_CASE(do_while_loop)
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)
{
@@ -434,13 +457,15 @@ BOOST_AUTO_TEST_CASE(nested_loops)
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
@@ -456,16 +481,17 @@ BOOST_AUTO_TEST_CASE(for_loop)
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
@@ -484,14 +510,16 @@ BOOST_AUTO_TEST_CASE(for_loop_empty)
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
@@ -554,20 +582,22 @@ BOOST_AUTO_TEST_CASE(for_loop_break_continue)
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
@@ -602,13 +632,15 @@ BOOST_AUTO_TEST_CASE(calling_other_functions)
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
{
@@ -623,13 +655,15 @@ BOOST_AUTO_TEST_CASE(many_local_variables)
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"));
@@ -637,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"));
@@ -650,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
@@ -680,14 +720,16 @@ BOOST_AUTO_TEST_CASE(short_circuiting)
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
{
@@ -702,13 +744,15 @@ BOOST_AUTO_TEST_CASE(high_bits_cleaning)
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
{
@@ -722,13 +766,15 @@ BOOST_AUTO_TEST_CASE(sign_extension)
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
{
@@ -741,11 +787,13 @@ BOOST_AUTO_TEST_CASE(small_unsigned_types)
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
{
@@ -756,15 +804,17 @@ BOOST_AUTO_TEST_CASE(small_signed_types)
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));
@@ -809,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));
@@ -834,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;
@@ -869,15 +923,17 @@ BOOST_AUTO_TEST_CASE(compound_assign)
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)));
@@ -899,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
{
@@ -974,17 +1032,19 @@ BOOST_AUTO_TEST_CASE(mapping_state)
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;
@@ -1005,13 +1065,15 @@ BOOST_AUTO_TEST_CASE(mapping_state_inc_dec)
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;
@@ -1032,35 +1094,37 @@ BOOST_AUTO_TEST_CASE(multi_level_mapping)
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());
@@ -1069,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());
@@ -1135,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));
@@ -1161,7 +1228,8 @@ BOOST_AUTO_TEST_CASE(deleteLocal)
delete v;
res = v;
}
- })";
+ }
+ )";
compileAndRun(sourceCode);
BOOST_CHECK(callContractFunction("delLocal()") == encodeArgs(0));
}
@@ -1178,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;
@@ -1207,12 +1278,14 @@ BOOST_AUTO_TEST_CASE(constructor)
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));
}
@@ -1254,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() {
@@ -1262,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));
@@ -1273,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"));
@@ -1338,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);
@@ -1395,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));
@@ -1413,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,
@@ -1427,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"));
}
@@ -1439,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"));
}
@@ -1451,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"));
}
@@ -1464,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")));
@@ -1477,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")));
@@ -1490,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")));
@@ -1503,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")));
@@ -1517,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));
@@ -1530,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")));
@@ -1543,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")));
@@ -1556,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")) ==
@@ -1566,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);
@@ -1582,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);
@@ -1597,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);
@@ -1613,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);
@@ -1630,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);
@@ -1647,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);
@@ -1664,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);
@@ -1679,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);
@@ -1696,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);
@@ -1713,11 +1824,13 @@ 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
{
@@ -1730,11 +1843,13 @@ BOOST_AUTO_TEST_CASE(sha3)
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
{
@@ -1753,11 +1868,13 @@ BOOST_AUTO_TEST_CASE(sha256)
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
{
@@ -1776,11 +1893,13 @@ BOOST_AUTO_TEST_CASE(ripemd)
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;
@@ -2798,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));
@@ -2811,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));
}
@@ -2824,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(
@@ -2842,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(
@@ -2864,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")));
@@ -2890,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));
}
@@ -6450,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"(
@@ -7734,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)
@@ -8406,6 +8513,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.h b/test/libsolidity/SolidityExecutionFramework.h
index 0fab7aeb..03e3a881 100644
--- a/test/libsolidity/SolidityExecutionFramework.h
+++ b/test/libsolidity/SolidityExecutionFramework.h
@@ -56,7 +56,7 @@ public:
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(
@@ -68,7 +68,6 @@ 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;
diff --git a/test/libsolidity/SolidityExpressionCompiler.cpp b/test/libsolidity/SolidityExpressionCompiler.cpp
index cab9f09f..0c5a09c3 100644
--- a/test/libsolidity/SolidityExpressionCompiler.cpp
+++ b/test/libsolidity/SolidityExpressionCompiler.cpp
@@ -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 7a132068..11c38114 100644
--- a/test/libsolidity/SolidityNameAndTypeResolution.cpp
+++ b/test/libsolidity/SolidityNameAndTypeResolution.cpp
@@ -46,7 +46,7 @@ namespace
{
pair<ASTPointer<SourceUnit>, std::shared_ptr<Error const>>
-parseAnalyseAndReturnError(string const& _source, bool _reportWarnings = false, bool _insertVersionPragma = true)
+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;
@@ -91,6 +91,8 @@ parseAnalyseAndReturnError(string const& _source, bool _reportWarnings = false,
BOOST_CHECK(success || !errors.empty());
}
+ if (errors.size() > 1 && !_allowMultipleErrors)
+ BOOST_FAIL("Multiple errors found");
for (auto const& currentError: errors)
{
if (
@@ -131,9 +133,9 @@ bool success(string const& _source)
return !parseAnalyseAndReturnError(_source).second;
}
-Error 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;
@@ -151,33 +153,38 @@ 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) \
+#define CHECK_ERROR_OR_WARNING(text, typ, substring, warning, allowMulti) \
do \
{ \
- Error err = expectError((text), (warning)); \
+ Error err = expectError((text), (warning), (allowMulti)); \
BOOST_CHECK(err.type() == (Error::Type::typ)); \
- BOOST_CHECK(searchErrorMessage(err, substring)); \
+ 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)
+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)
+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)
@@ -187,98 +194,123 @@ 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";
+ 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";
+ 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";
+ 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";
+ 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";
+ 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";
+ 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";
+ 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";
+ 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";
+ 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";
+ char const* text = R"(
+ contract test {
+ struct MyStructName1 {
+ address addr;
+ uint256 count;
+ MyStructName2 x;
+ }
+ struct MyStructName2 {
+ MyStructName1 x;
+ }
+ }
+ )";
CHECK_ERROR(text, TypeError, "");
}
@@ -295,179 +327,216 @@ BOOST_AUTO_TEST_CASE(struct_definition_not_really_recursive)
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";
+ 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";
+ 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";
+ 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";
+ 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";
+ 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";
+ 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";
+ 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";
+ 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";
+ 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";
+ 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";
+ 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";
+ 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";
+ 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";
+ 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";
+ 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";
+ 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";
+ 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());
@@ -482,7 +551,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());
@@ -501,7 +570,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());
@@ -519,9 +588,9 @@ BOOST_AUTO_TEST_CASE(create_abstract_contract)
contract base { function foo(); }
contract derived {
base b;
- function foo() { b = new base();}
- }
- )";
+ function foo() { b = new base(); }
+ }
+ )";
CHECK_ERROR(text, TypeError, "");
}
@@ -535,7 +604,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");
}
@@ -549,7 +618,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);
@@ -565,7 +634,7 @@ 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(); }
- )";
+ )";
CHECK_ERROR(text, TypeError, "");
}
@@ -587,11 +656,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()))
@@ -604,11 +675,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()))
@@ -629,9 +702,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()))
@@ -653,7 +727,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()))
@@ -670,12 +745,13 @@ 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 {}
- })";
+ }
+ )";
CHECK_SUCCESS(text);
}
@@ -684,12 +760,13 @@ 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 {}
- })";
+ }
+ )";
CHECK_ERROR(text, TypeError, "");
}
@@ -705,7 +782,8 @@ BOOST_AUTO_TEST_CASE(function_internal_allowed_conversion)
function internalCall() {
g(a);
}
- })";
+ }
+ )";
CHECK_SUCCESS(text);
}
@@ -721,18 +799,19 @@ BOOST_AUTO_TEST_CASE(function_internal_not_allowed_conversion)
function internalCall() {
g(a);
}
- })";
+ }
+ )";
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";
+ char const* text = R"(
+ contract test {
+ function gsf() { }
+ function tgeo() { }
+ }
+ )";
CHECK_ERROR(text, TypeError, "");
}
@@ -767,7 +846,7 @@ BOOST_AUTO_TEST_CASE(cyclic_inheritance)
contract A is B { }
contract B is A { }
)";
- CHECK_ERROR(text, TypeError, "");
+ CHECK_ERROR_ALLOW_MULTI(text, TypeError, "");
}
BOOST_AUTO_TEST_CASE(legal_override_direct)
@@ -989,26 +1068,28 @@ BOOST_AUTO_TEST_CASE(modifier_returns_value)
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");
@@ -1016,7 +1097,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");
@@ -1028,34 +1109,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";
+ 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");
}
@@ -1075,12 +1160,14 @@ BOOST_AUTO_TEST_CASE(missing_state_variable)
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";
+ 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);
}
@@ -1088,7 +1175,7 @@ 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;
}
)";
@@ -1097,41 +1184,47 @@ BOOST_AUTO_TEST_CASE(struct_accessor_one_array_only)
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";
+ 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";
+ 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";
+ 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, "");
}
@@ -1197,7 +1290,7 @@ BOOST_AUTO_TEST_CASE(fallback_function_twice)
function() { x = 3; }
}
)";
- CHECK_ERROR(text, DeclarationError, "");
+ CHECK_ERROR_ALLOW_MULTI(text, DeclarationError, "");
}
BOOST_AUTO_TEST_CASE(fallback_function_inheritance)
@@ -1220,7 +1313,8 @@ BOOST_AUTO_TEST_CASE(event)
contract c {
event e(uint indexed a, bytes3 indexed s, bool indexed b);
function f() { e(2, "abc", true); }
- })";
+ }
+ )";
CHECK_SUCCESS(text);
}
@@ -1229,7 +1323,8 @@ 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);
- })";
+ }
+ )";
CHECK_ERROR(text, TypeError, "");
}
@@ -1238,7 +1333,8 @@ 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;
- })";
+ }
+ )";
CHECK_SUCCESS(text);
}
@@ -1247,7 +1343,8 @@ 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;
- })";
+ }
+ )";
CHECK_ERROR(text, TypeError, "");
}
@@ -1257,7 +1354,8 @@ BOOST_AUTO_TEST_CASE(event_call)
contract c {
event e(uint a, bytes3 indexed s, bool indexed b);
function f() { e(2, "abc", true); }
- })";
+ }
+ )";
CHECK_SUCCESS(text);
}
@@ -1269,7 +1367,8 @@ BOOST_AUTO_TEST_CASE(event_inheritance)
}
contract c is base {
function f() { e(2, "abc", true); }
- })";
+ }
+ )";
CHECK_SUCCESS(text);
}
@@ -1279,7 +1378,8 @@ 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);
- })";
+ }
+ )";
CHECK_SUCCESS(text);
}
@@ -1291,7 +1391,8 @@ BOOST_AUTO_TEST_CASE(access_to_default_function_visibility)
}
contract d {
function g() { c(0).f(); }
- })";
+ }
+ )";
CHECK_SUCCESS(text);
}
@@ -1303,7 +1404,8 @@ BOOST_AUTO_TEST_CASE(access_to_internal_function)
}
contract d {
function g() { c(0).f(); }
- })";
+ }
+ )";
CHECK_ERROR(text, TypeError, "");
}
@@ -1315,7 +1417,8 @@ BOOST_AUTO_TEST_CASE(access_to_default_state_variable_visibility)
}
contract d {
function g() { c(0).a(); }
- })";
+ }
+ )";
CHECK_ERROR(text, TypeError, "");
}
@@ -1327,43 +1430,68 @@ BOOST_AUTO_TEST_CASE(access_to_internal_state_variable)
}
contract d {
function g() { c(0).a(); }
- })";
+ }
+ )";
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";
+ 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";
+ 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";
+ 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";
+ 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, "");
}
@@ -1371,9 +1499,9 @@ BOOST_AUTO_TEST_CASE(empty_name_input_parameter)
{
char const* text = R"(
contract test {
- function f(uint){
+ function f(uint) { }
}
- })";
+ )";
CHECK_SUCCESS(text);
}
@@ -1381,9 +1509,9 @@ BOOST_AUTO_TEST_CASE(empty_name_return_parameter)
{
char const* text = R"(
contract test {
- function f() returns(bool){
+ function f() returns(bool) { }
}
- })";
+ )";
CHECK_SUCCESS(text);
}
@@ -1391,10 +1519,11 @@ 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;
+ }
}
- })";
+ )";
CHECK_SUCCESS(text);
}
@@ -1402,16 +1531,21 @@ 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;
+ }
}
- })";
+ )";
CHECK_ERROR(text, TypeError, "");
}
BOOST_AUTO_TEST_CASE(disallow_declaration_of_void_type)
{
- char const* sourceCode = "contract c { function f() { var (x) = f(); } }";
+ char const* sourceCode = R"(
+ contract c {
+ function f() { var (x) = f(); }
+ }
+ )";
CHECK_ERROR(sourceCode, TypeError, "");
}
@@ -1419,22 +1553,22 @@ 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;
- })";
+ }
+ )";
CHECK_ERROR(sourceCode, TypeError, "");
}
@@ -1443,21 +1577,22 @@ BOOST_AUTO_TEST_CASE(exp_operator_exponent_too_big)
char const* sourceCode = R"(
contract test {
function f() returns(uint d) { return 2 ** 10000000000; }
- })";
+ }
+ )";
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;
+ }
)";
CHECK_SUCCESS(text);
}
@@ -1465,14 +1600,14 @@ BOOST_AUTO_TEST_CASE(enum_member_access)
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;
}
+ }
)";
CHECK_SUCCESS(text);
}
@@ -1480,14 +1615,13 @@ BOOST_AUTO_TEST_CASE(enum_member_access_accross_contracts)
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;
+ }
)";
CHECK_ERROR(text, TypeError, "");
}
@@ -1495,14 +1629,13 @@ BOOST_AUTO_TEST_CASE(enum_invalid_member_access)
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;
+ }
)";
CHECK_ERROR(text, DeclarationError, "");
}
@@ -1510,16 +1643,15 @@ BOOST_AUTO_TEST_CASE(enum_invalid_direct_member_access)
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;
+ }
)";
CHECK_SUCCESS(text);
}
@@ -1527,33 +1659,43 @@ BOOST_AUTO_TEST_CASE(enum_explicit_conversion_is_okay)
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;
+ }
)";
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;
+ }
)";
CHECK_ERROR(text, TypeError, "");
}
@@ -1564,8 +1706,7 @@ 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);
}
}
@@ -1609,7 +1750,7 @@ BOOST_AUTO_TEST_CASE(private_visibility)
contract derived is base {
function g() { f(); }
}
- )";
+ )";
CHECK_ERROR(sourceCode, DeclarationError, "");
}
@@ -1622,7 +1763,7 @@ BOOST_AUTO_TEST_CASE(private_visibility_via_explicit_base_access)
contract derived is base {
function g() { base.f(); }
}
- )";
+ )";
CHECK_ERROR(sourceCode, TypeError, "");
}
@@ -1633,7 +1774,7 @@ BOOST_AUTO_TEST_CASE(external_visibility)
function f() external {}
function g() { f(); }
}
- )";
+ )";
CHECK_ERROR(sourceCode, DeclarationError, "");
}
@@ -1646,7 +1787,7 @@ BOOST_AUTO_TEST_CASE(external_base_visibility)
contract derived is base {
function g() { base.f(); }
}
- )";
+ )";
CHECK_ERROR(sourceCode, TypeError, "");
}
@@ -1656,7 +1797,7 @@ BOOST_AUTO_TEST_CASE(external_argument_assign)
contract c {
function f(uint a) external { a = 1; }
}
- )";
+ )";
CHECK_ERROR(sourceCode, TypeError, "");
}
@@ -1666,7 +1807,7 @@ BOOST_AUTO_TEST_CASE(external_argument_increment)
contract c {
function f(uint a) external { a++; }
}
- )";
+ )";
CHECK_ERROR(sourceCode, TypeError, "");
}
@@ -1676,7 +1817,7 @@ BOOST_AUTO_TEST_CASE(external_argument_delete)
contract c {
function f(uint a) external { delete a; }
}
- )";
+ )";
CHECK_ERROR(sourceCode, TypeError, "");
}
@@ -1689,7 +1830,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");
}
@@ -1698,7 +1839,8 @@ BOOST_AUTO_TEST_CASE(array_with_nonconstant_length)
char const* text = R"(
contract c {
function f(uint a) { uint8[a] x; }
- })";
+ }
+ )";
CHECK_ERROR(text, TypeError, "");
}
@@ -1709,7 +1851,8 @@ BOOST_AUTO_TEST_CASE(array_copy_with_different_types1)
bytes a;
uint[] b;
function f() { b = a; }
- })";
+ }
+ )";
CHECK_ERROR(text, TypeError, "");
}
@@ -1720,7 +1863,8 @@ BOOST_AUTO_TEST_CASE(array_copy_with_different_types2)
uint32[] a;
uint8[] b;
function f() { b = a; }
- })";
+ }
+ )";
CHECK_ERROR(text, TypeError, "");
}
@@ -1731,7 +1875,8 @@ BOOST_AUTO_TEST_CASE(array_copy_with_different_types_conversion_possible)
uint32[] a;
uint8[] b;
function f() { a = b; }
- })";
+ }
+ )";
CHECK_SUCCESS(text);
}
@@ -1742,7 +1887,8 @@ BOOST_AUTO_TEST_CASE(array_copy_with_different_types_static_dynamic)
uint32[] a;
uint8[80] b;
function f() { a = b; }
- })";
+ }
+ )";
CHECK_SUCCESS(text);
}
@@ -1753,7 +1899,8 @@ BOOST_AUTO_TEST_CASE(array_copy_with_different_types_dynamic_static)
uint[] a;
uint[80] b;
function f() { b = a; }
- })";
+ }
+ )";
CHECK_ERROR(text, TypeError, "");
}
@@ -1762,7 +1909,8 @@ BOOST_AUTO_TEST_CASE(storage_variable_initialization_with_incorrect_type_int)
char const* text = R"(
contract c {
uint8 a = 1000;
- })";
+ }
+ )";
CHECK_ERROR(text, TypeError, "");
}
@@ -1771,7 +1919,8 @@ BOOST_AUTO_TEST_CASE(storage_variable_initialization_with_incorrect_type_string)
char const* text = R"(
contract c {
uint a = "abc";
- })";
+ }
+ )";
CHECK_ERROR(text, TypeError, "");
}
@@ -1887,7 +2036,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");
}
@@ -1897,7 +2047,8 @@ BOOST_AUTO_TEST_CASE(assigning_value_to_const_variable)
contract Foo {
function changeIt() { x = 9; }
uint constant x = 56;
- })";
+ }
+ )";
CHECK_ERROR(text, TypeError, "");
}
@@ -1906,8 +2057,10 @@ 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;
- })";
+ mapping(uint => bool) x;
+ mapping(uint => bool) constant mapVar = x;
+ }
+ )";
CHECK_ERROR(text, TypeError, "");
}
@@ -1916,7 +2069,8 @@ BOOST_AUTO_TEST_CASE(uninitialized_const_variable)
char const* text = R"(
contract Foo {
uint constant y;
- })";
+ }
+ )";
CHECK_ERROR(text, TypeError, "");
}
@@ -2009,12 +2163,12 @@ BOOST_AUTO_TEST_CASE(multiple_constructors)
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 {}
}
)";
- CHECK_ERROR(sourceCode, DeclarationError, "");
+ CHECK_ERROR_ALLOW_MULTI(sourceCode, DeclarationError, "");
}
BOOST_AUTO_TEST_CASE(uninitialized_var)
@@ -3165,7 +3319,7 @@ BOOST_AUTO_TEST_CASE(left_value_in_conditional_expression_not_supported_yet)
}
}
)";
- CHECK_ERROR(text, TypeError, "");
+ CHECK_ERROR_ALLOW_MULTI(text, TypeError, "");
}
BOOST_AUTO_TEST_CASE(conditional_expression_with_different_struct)
@@ -3179,8 +3333,8 @@ 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;
}
}
@@ -3661,7 +3815,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;
}
}
@@ -3751,14 +3905,47 @@ BOOST_AUTO_TEST_CASE(rational_to_fixed_literal_expression)
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);
}
}
@@ -3766,15 +3953,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);
}
}
)";
@@ -3824,7 +4044,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;
}
}
)";
@@ -3836,7 +4056,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;
}
}
)";
@@ -3848,7 +4068,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;
}
}
)";
@@ -3860,7 +4080,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;
}
}
)";
@@ -4161,7 +4381,7 @@ 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]; }
}
)";
CHECK_ERROR(text, TypeError, "");
@@ -4517,11 +4737,12 @@ BOOST_AUTO_TEST_CASE(inline_assembly_storage)
function f() {
assembly {
x := 2
+ pop
}
}
}
)";
- CHECK_ERROR(text, DeclarationError, "");
+ CHECK_ERROR(text, DeclarationError, "not found, not unique or not lvalue.");
}
BOOST_AUTO_TEST_CASE(inline_assembly_storage_in_modifiers)
@@ -4532,6 +4753,7 @@ BOOST_AUTO_TEST_CASE(inline_assembly_storage_in_modifiers)
modifier m {
assembly {
x := 2
+ pop
}
_;
}
diff --git a/test/libsolidity/SolidityNatspecJSON.cpp b/test/libsolidity/SolidityNatspecJSON.cpp
index ef69e85c..e32264c4 100644
--- a/test/libsolidity/SolidityNatspecJSON.cpp
+++ b/test/libsolidity/SolidityNatspecJSON.cpp
@@ -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 3c1f465a..2e2e0c6c 100644
--- a/test/libsolidity/SolidityOptimizer.cpp
+++ b/test/libsolidity/SolidityOptimizer.cpp
@@ -50,6 +50,25 @@ 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,
@@ -57,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;
}
@@ -156,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;
};
@@ -315,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)
@@ -359,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)
@@ -1187,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)
diff --git a/test/libsolidity/SolidityParser.cpp b/test/libsolidity/SolidityParser.cpp
index a3217f08..a3bfab75 100644
--- a/test/libsolidity/SolidityParser.cpp
+++ b/test/libsolidity/SolidityParser.cpp
@@ -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)