aboutsummaryrefslogtreecommitdiffstats
path: root/test
diff options
context:
space:
mode:
Diffstat (limited to 'test')
-rw-r--r--test/fuzzer.cpp1
-rw-r--r--test/libdevcore/MiniMoustache.cpp127
-rw-r--r--test/libdevcore/UTF8.cpp216
-rw-r--r--test/liblll/EndToEndTest.cpp20
-rw-r--r--test/libsolidity/Assembly.cpp4
-rw-r--r--test/libsolidity/JSONCompiler.cpp26
-rw-r--r--test/libsolidity/SolidityEndToEndTest.cpp55
-rw-r--r--test/libsolidity/SolidityNameAndTypeResolution.cpp204
-rw-r--r--test/libsolidity/StandardCompiler.cpp30
9 files changed, 657 insertions, 26 deletions
diff --git a/test/fuzzer.cpp b/test/fuzzer.cpp
index 053d880f..cf99755f 100644
--- a/test/fuzzer.cpp
+++ b/test/fuzzer.cpp
@@ -152,7 +152,6 @@ void testCompiler()
"Exception during compilation",
"Unknown exception during compilation",
"Unknown exception while generating contract data output",
- "Unknown exception while generating formal method output",
"Unknown exception while generating source name output",
"Unknown error while generating JSON"
});
diff --git a/test/libdevcore/MiniMoustache.cpp b/test/libdevcore/MiniMoustache.cpp
new file mode 100644
index 00000000..84149173
--- /dev/null
+++ b/test/libdevcore/MiniMoustache.cpp
@@ -0,0 +1,127 @@
+/*
+ This file is part of solidity.
+
+ solidity is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ solidity is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with solidity. If not, see <http://www.gnu.org/licenses/>.
+*/
+/**
+ * Unit tests for the mini moustache class.
+ */
+
+#include <libdevcore/Whiskers.h>
+
+#include "../TestHelper.h"
+
+using namespace std;
+
+namespace dev
+{
+namespace test
+{
+
+BOOST_AUTO_TEST_SUITE(WhiskersTest)
+
+BOOST_AUTO_TEST_CASE(no_templates)
+{
+ string templ = "this text does not contain templates";
+ BOOST_CHECK_EQUAL(Whiskers(templ).render(), templ);
+}
+
+BOOST_AUTO_TEST_CASE(basic_replacement)
+{
+ string templ = "a <b> x <c> -> <d>.";
+ string result = Whiskers(templ)
+ ("b", "BE")
+ ("c", "CE")
+ ("d", "DE")
+ .render();
+ BOOST_CHECK_EQUAL(result, "a BE x CE -> DE.");
+}
+
+BOOST_AUTO_TEST_CASE(tag_unavailable)
+{
+ string templ = "<b>";
+ Whiskers m(templ);
+ BOOST_CHECK_THROW(m.render(), WhiskersError);
+}
+
+BOOST_AUTO_TEST_CASE(complicated_replacement)
+{
+ string templ = "a <b> x <complicated> \n <nes<ted>>.";
+ string result = Whiskers(templ)
+ ("b", "BE")
+ ("complicated", "CO<M>PL")
+ ("nes<ted", "NEST")
+ .render();
+ BOOST_CHECK_EQUAL(result, "a BE x CO<M>PL \n NEST>.");
+}
+
+BOOST_AUTO_TEST_CASE(non_existing_list)
+{
+ string templ = "a <#b></b>";
+ Whiskers m(templ);
+ BOOST_CHECK_THROW(m.render(), WhiskersError);
+}
+
+BOOST_AUTO_TEST_CASE(empty_list)
+{
+ string templ = "a <#b></b>x";
+ string result = Whiskers(templ)("b", vector<Whiskers::StringMap>{}).render();
+ BOOST_CHECK_EQUAL(result, "a x");
+}
+
+BOOST_AUTO_TEST_CASE(list)
+{
+ string templ = "a<#b>( <g> - <h> )</b>x";
+ vector<map<string, string>> list(2);
+ list[0]["g"] = "GE";
+ list[0]["h"] = "H";
+ list[1]["g"] = "2GE";
+ list[1]["h"] = "2H";
+ string result = Whiskers(templ)("b", list).render();
+ BOOST_CHECK_EQUAL(result, "a( GE - H )( 2GE - 2H )x");
+}
+
+BOOST_AUTO_TEST_CASE(recursive_list)
+{
+ // Check that templates resulting from lists are not expanded again
+ string templ = "a<#b> 1<g>3 </b><x>";
+ vector<map<string, string>> list(1);
+ list[0]["g"] = "<x>";
+ string result = Whiskers(templ)("x", "X")("b", list).render();
+ BOOST_CHECK_EQUAL(result, "a 1<x>3 X");
+}
+
+BOOST_AUTO_TEST_CASE(list_can_access_upper)
+{
+ string templ = "<#b>(<a>)</b>";
+ vector<map<string, string>> list(2);
+ Whiskers m(templ);
+ string result = m("a", "A")("b", list).render();
+ BOOST_CHECK_EQUAL(result, "(A)(A)");
+}
+
+BOOST_AUTO_TEST_CASE(parameter_collision)
+{
+ string templ = "a <#b></b>";
+ vector<map<string, string>> list(1);
+ list[0]["a"] = "x";
+ Whiskers m(templ);
+ m("a", "X")("b", list);
+ BOOST_CHECK_THROW(m.render(), WhiskersError);
+}
+
+BOOST_AUTO_TEST_SUITE_END()
+
+}
+}
diff --git a/test/libdevcore/UTF8.cpp b/test/libdevcore/UTF8.cpp
new file mode 100644
index 00000000..719ada72
--- /dev/null
+++ b/test/libdevcore/UTF8.cpp
@@ -0,0 +1,216 @@
+/*
+ This file is part of solidity.
+
+ solidity is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ solidity is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with solidity. If not, see <http://www.gnu.org/licenses/>.
+*/
+/**
+ * Unit tests for UTF-8 validation.
+ */
+
+#include <libdevcore/CommonData.h>
+#include <libdevcore/UTF8.h>
+
+#include "../TestHelper.h"
+
+using namespace std;
+
+namespace dev
+{
+namespace test
+{
+
+BOOST_AUTO_TEST_SUITE(UTF8)
+
+namespace {
+
+bool isValidUTF8(string const& _value)
+{
+ size_t pos;
+ return validateUTF8(asString(fromHex(_value)), pos);
+}
+
+bool isInvalidUTF8(string const& _value, size_t _expectedPos)
+{
+ size_t pos;
+ if (validateUTF8(asString(fromHex(_value)), pos))
+ return false;
+ if (pos != _expectedPos)
+ return false;
+ return true;
+}
+
+}
+
+BOOST_AUTO_TEST_CASE(valid)
+{
+ BOOST_CHECK(isValidUTF8("00"));
+ BOOST_CHECK(isValidUTF8("20"));
+ BOOST_CHECK(isValidUTF8("7f"));
+ BOOST_CHECK(isValidUTF8("c281"));
+ BOOST_CHECK(isValidUTF8("df81"));
+ BOOST_CHECK(isValidUTF8("e0a081"));
+ BOOST_CHECK(isValidUTF8("e18081"));
+ BOOST_CHECK(isValidUTF8("ec8081"));
+ BOOST_CHECK(isValidUTF8("ed8081"));
+ BOOST_CHECK(isValidUTF8("ee8081"));
+ BOOST_CHECK(isValidUTF8("ef8081"));
+ BOOST_CHECK(isValidUTF8("f0908081"));
+ BOOST_CHECK(isValidUTF8("f3808081"));
+ BOOST_CHECK(isValidUTF8("f2808081"));
+ BOOST_CHECK(isValidUTF8("f3808081"));
+ BOOST_CHECK(isValidUTF8("f48e8081"));
+}
+
+BOOST_AUTO_TEST_CASE(invalid)
+{
+ // anything between 0x80 and 0xc0 is disallowed
+ BOOST_CHECK(isInvalidUTF8("80", 0)); // invalid per table 3.6
+ BOOST_CHECK(isInvalidUTF8("a0", 0)); // invalid per table 3.6
+ BOOST_CHECK(isInvalidUTF8("c0", 0)); // invalid per table 3.7
+ BOOST_CHECK(isInvalidUTF8("c1", 0)); // invalid per table 3.7
+ BOOST_CHECK(isInvalidUTF8("c2", 0)); // too short (position is reported as the first byte)
+ BOOST_CHECK(isInvalidUTF8("e08081", 2)); // e0 must be followed by >= a0
+ BOOST_CHECK(isInvalidUTF8("e180", 0)); // too short
+ BOOST_CHECK(isInvalidUTF8("ec80", 0)); // too short
+ BOOST_CHECK(isInvalidUTF8("f08f8001", 2)); // f0 must be followed by >= 90
+ BOOST_CHECK(isInvalidUTF8("f18080", 0)); // too short
+ BOOST_CHECK(isInvalidUTF8("f4908081", 2)); // f4 must be followed by < 90
+ // anything above 0xf7 is disallowed
+ BOOST_CHECK(isInvalidUTF8("f8", 0)); // invalid per table 3.7
+ BOOST_CHECK(isInvalidUTF8("f9", 0)); // invalid per table 3.7
+}
+
+BOOST_AUTO_TEST_CASE(corpus)
+{
+ string source = R"(
+κόσμε
+
+hélló
+
+Ā ā Ă ă Ą ą
+
+ƀ Ɓ Ƃ ƃ Ƅ ƅ
+
+ɐ ɑ ɒ ɓ ɔ ɕ
+
+ʰ ʱ ʲ ʳ ʴ ʵ
+
+̀ ́ ̂ ̃ ̄ ̅
+
+ϩ Ϫ ϫ Ϭ ϭ Ϯ
+
+Ё Ђ Ѓ Є Ѕ І
+
+Ա Բ Գ Դ Ե Զ
+
+ ק ר ש ת װ ױ
+
+ځ ڂ ڃ ڄ څ چ
+
+ऑ ऒ ओ औ क ख
+
+ও ঔ ক খ গ ঘ
+
+ਘ ਙ ਚ ਛ ਜ ਝ
+
+ઓ ઔ ક ખ ગ ઘ
+
+ଗ ଘ ଙ ଚ ଛ ଜ
+
+ஔ க ங ச ஜ ஞ
+
+ఎ ఏ ఐ ఒ ఓ ఔ
+
+ಓ ಔ ಕ ಖ ಗ ಘ
+
+ഐ ഒ ഓ ഔ ക
+
+ฒ ณ ด ต ถ ท
+
+ມ ຢ ຣ ລ ວ ສ
+
+༄ ༅ ༆ ༇ ༈ ༉
+
+Ⴑ Ⴒ Ⴓ Ⴔ Ⴕ Ⴖ
+
+ᄌ ᄍ ᄎ ᄏ ᄐ
+
+Ḕ ḕ Ḗ ḗ Ḙ ḙ Ḛ
+
+ἐ ἑ ἒ ἓ ἔ ἕ
+
+₠ ₡ ₢ ₣ ₤ ₥
+
+⃐ ⃑ ⃒ ⃓ ⃔ ⃕ ⃖ ⃗ ⃘ ⃙ ⃚
+
+ℋ ℌ ℍ ℎ ℏ ℐ ℑ
+
+⅓ ⅔ ⅕ ⅖ ⅗
+
+∬ ∭ ∮ ∯ ∰
+
+⌖ ⌗ ⌘ ⌙ ⌚ ⌛
+
+␀ ␁ ␂ ␃ ␄ ␅
+
+⑀ ⑁ ⑂ ⑃ ⑄
+
+① ② ③ ④ ⑤
+
+╘ ╙ ╚ ╛ ╜ ╝
+
+▁ ▂ ▃ ▄ ▅ ▆
+
+▤ ▥ ▦ ▧ ▨
+
+♔ ♕ ♖ ♗ ♘ ♙
+
+✈ ✉ ✌ ✍ ✎
+
+ぁ あ ぃ い ぅ
+
+ァ ア ィ イ ゥ
+
+ㄅ ㄆ ㄇ ㄈ ㄉ
+
+ㄱ ㄲ ㄳ ㄴ ㄵ
+
+㆚ ㆛ ㆜ ㆝ ㆞
+
+㈀ ㈁ ㈂ ㈃ ㈄
+
+㌀ ㌁ ㌂ ㌃ ㌄
+
+乺 乻 乼 乽 乾
+
+걺 걻 걼 걽 걾
+
+豈 更 車 賈 滑
+
+שּׁ שּׂ אַ אָ אּ
+
+ﮄ ﮅ ﮆ ﮇ ﮈ ﮉ
+
+ ﺵ ﺶ ﺷ ﺸ
+
+「 」 、 ・ ヲ ァ ィ ゥ
+ )";
+ size_t pos;
+ BOOST_CHECK(validateUTF8(source, pos));
+}
+
+BOOST_AUTO_TEST_SUITE_END()
+
+}
+}
diff --git a/test/liblll/EndToEndTest.cpp b/test/liblll/EndToEndTest.cpp
index 02d024a4..3037b14b 100644
--- a/test/liblll/EndToEndTest.cpp
+++ b/test/liblll/EndToEndTest.cpp
@@ -57,6 +57,26 @@ BOOST_AUTO_TEST_CASE(panic)
BOOST_REQUIRE(m_output.empty());
}
+BOOST_AUTO_TEST_CASE(variables)
+{
+ char const* sourceCode = R"(
+ (returnlll
+ (seq
+ (set 'x 1)
+ (set 'y 2)
+ ;; this should equal to 3
+ (set 'z (add (get 'x) (get 'y)))
+ ;; overwriting it here
+ (set 'y 4)
+ ;; each variable has a 32 byte slot, starting from memory location 0x80
+ ;; variable addresses can also be retrieved by x or (ref 'x)
+ (set 'k (add (add (ref 'x) (ref 'y)) z))
+ (return (add (add (get 'x) (add (get 'y) (get 'z))) (get 'k)))))
+ )";
+ compileAndRun(sourceCode);
+ BOOST_CHECK(callFallback() == encodeArgs(u256(488)));
+}
+
BOOST_AUTO_TEST_CASE(when)
{
char const* sourceCode = R"(
diff --git a/test/libsolidity/Assembly.cpp b/test/libsolidity/Assembly.cpp
index e52f4d50..99a2996e 100644
--- a/test/libsolidity/Assembly.cpp
+++ b/test/libsolidity/Assembly.cpp
@@ -119,8 +119,8 @@ BOOST_AUTO_TEST_CASE(location_test)
shared_ptr<string const> n = make_shared<string>("");
AssemblyItems items = compileContract(sourceCode);
vector<SourceLocation> locations =
- vector<SourceLocation>(17, SourceLocation(2, 75, n)) +
- vector<SourceLocation>(30, SourceLocation(20, 72, n)) +
+ vector<SourceLocation>(19, SourceLocation(2, 75, n)) +
+ vector<SourceLocation>(32, SourceLocation(20, 72, n)) +
vector<SourceLocation>{SourceLocation(42, 51, n), SourceLocation(65, 67, n)} +
vector<SourceLocation>(2, SourceLocation(58, 67, n)) +
vector<SourceLocation>(3, SourceLocation(20, 72, n));
diff --git a/test/libsolidity/JSONCompiler.cpp b/test/libsolidity/JSONCompiler.cpp
index f5154395..aa690f0b 100644
--- a/test/libsolidity/JSONCompiler.cpp
+++ b/test/libsolidity/JSONCompiler.cpp
@@ -73,28 +73,36 @@ BOOST_AUTO_TEST_CASE(basic_compilation)
Json::Value contract = result["contracts"]["fileA:A"];
BOOST_CHECK(contract.isObject());
BOOST_CHECK(contract["interface"].isString());
- BOOST_CHECK(contract["interface"].asString() == "[]");
+ BOOST_CHECK_EQUAL(contract["interface"].asString(), "[]");
BOOST_CHECK(contract["bytecode"].isString());
- BOOST_CHECK(dev::test::bytecodeSansMetadata(contract["bytecode"].asString()) ==
- "60606040523415600b57fe5b5b60338060196000396000f30060606040525bfe00");
+ BOOST_CHECK_EQUAL(
+ dev::test::bytecodeSansMetadata(contract["bytecode"].asString()),
+ "60606040523415600e57600080fd5b5b603680601c6000396000f30060606040525b600080fd00"
+ );
BOOST_CHECK(contract["runtimeBytecode"].isString());
- BOOST_CHECK(dev::test::bytecodeSansMetadata(contract["runtimeBytecode"].asString()) ==
- "60606040525bfe00");
+ BOOST_CHECK_EQUAL(
+ dev::test::bytecodeSansMetadata(contract["runtimeBytecode"].asString()),
+ "60606040525b600080fd00"
+ );
BOOST_CHECK(contract["functionHashes"].isObject());
BOOST_CHECK(contract["gasEstimates"].isObject());
- BOOST_CHECK(dev::jsonCompactPrint(contract["gasEstimates"]) ==
- "{\"creation\":[62,10200],\"external\":{},\"internal\":{}}");
+ BOOST_CHECK_EQUAL(
+ dev::jsonCompactPrint(contract["gasEstimates"]),
+ "{\"creation\":[62,10800],\"external\":{},\"internal\":{}}"
+ );
BOOST_CHECK(contract["metadata"].isString());
BOOST_CHECK(dev::test::isValidMetadata(contract["metadata"].asString()));
BOOST_CHECK(result["sources"].isObject());
BOOST_CHECK(result["sources"]["fileA"].isObject());
BOOST_CHECK(result["sources"]["fileA"]["AST"].isObject());
- BOOST_CHECK(dev::jsonCompactPrint(result["sources"]["fileA"]["AST"]) ==
+ BOOST_CHECK_EQUAL(
+ dev::jsonCompactPrint(result["sources"]["fileA"]["AST"]),
"{\"attributes\":{\"absolutePath\":\"fileA\",\"exportedSymbols\":{\"A\":[1]}},"
"\"children\":[{\"attributes\":{\"baseContracts\":[null],\"contractDependencies\":[null],"
"\"contractKind\":\"contract\",\"documentation\":null,\"fullyImplemented\":true,\"linearizedBaseContracts\":[1],"
"\"name\":\"A\",\"nodes\":[null],\"scope\":2},\"id\":1,\"name\":\"ContractDefinition\","
- "\"src\":\"0:14:0\"}],\"id\":2,\"name\":\"SourceUnit\",\"src\":\"0:14:0\"}");
+ "\"src\":\"0:14:0\"}],\"id\":2,\"name\":\"SourceUnit\",\"src\":\"0:14:0\"}"
+ );
}
BOOST_AUTO_TEST_SUITE_END()
diff --git a/test/libsolidity/SolidityEndToEndTest.cpp b/test/libsolidity/SolidityEndToEndTest.cpp
index ba507e0c..ffee5e36 100644
--- a/test/libsolidity/SolidityEndToEndTest.cpp
+++ b/test/libsolidity/SolidityEndToEndTest.cpp
@@ -4483,6 +4483,38 @@ BOOST_AUTO_TEST_CASE(array_copy_including_mapping)
BOOST_CHECK(storageEmpty(m_contractAddress));
}
+BOOST_AUTO_TEST_CASE(swap_in_storage_overwrite)
+{
+ // This tests a swap in storage which does not work as one
+ // might expect because we do not have temporary storage.
+ // (x, y) = (y, x) is the same as
+ // y = x;
+ // x = y;
+ char const* sourceCode = R"(
+ contract c {
+ struct S { uint a; uint b; }
+ S public x;
+ S public y;
+ function set() {
+ x.a = 1; x.b = 2;
+ y.a = 3; y.b = 4;
+ }
+ function swap() {
+ (x, y) = (y, x);
+ }
+ }
+ )";
+ compileAndRun(sourceCode);
+ BOOST_CHECK(callContractFunction("x()") == encodeArgs(u256(0), u256(0)));
+ BOOST_CHECK(callContractFunction("y()") == encodeArgs(u256(0), u256(0)));
+ BOOST_CHECK(callContractFunction("set()") == encodeArgs());
+ BOOST_CHECK(callContractFunction("x()") == encodeArgs(u256(1), u256(2)));
+ BOOST_CHECK(callContractFunction("y()") == encodeArgs(u256(3), u256(4)));
+ BOOST_CHECK(callContractFunction("swap()") == encodeArgs());
+ BOOST_CHECK(callContractFunction("x()") == encodeArgs(u256(1), u256(2)));
+ BOOST_CHECK(callContractFunction("y()") == encodeArgs(u256(1), u256(2)));
+}
+
BOOST_AUTO_TEST_CASE(pass_dynamic_arguments_to_the_base)
{
char const* sourceCode = R"(
@@ -9469,6 +9501,29 @@ BOOST_AUTO_TEST_CASE(revert)
BOOST_CHECK(callContractFunction("a()") == encodeArgs(u256(42)));
}
+BOOST_AUTO_TEST_CASE(literal_empty_string)
+{
+ char const* sourceCode = R"(
+ contract C {
+ bytes32 public x;
+ uint public a;
+ function f(bytes32 _x, uint _a) {
+ x = _x;
+ a = _a;
+ }
+ function g() {
+ this.f("", 2);
+ }
+ }
+ )";
+ compileAndRun(sourceCode, 0, "C");
+ BOOST_CHECK(callContractFunction("x()") == encodeArgs(u256(0)));
+ BOOST_CHECK(callContractFunction("a()") == encodeArgs(u256(0)));
+ BOOST_CHECK(callContractFunction("g()") == encodeArgs());
+ BOOST_CHECK(callContractFunction("x()") == encodeArgs(u256(0)));
+ BOOST_CHECK(callContractFunction("a()") == encodeArgs(u256(2)));
+}
+
BOOST_AUTO_TEST_CASE(scientific_notation)
{
char const* sourceCode = R"(
diff --git a/test/libsolidity/SolidityNameAndTypeResolution.cpp b/test/libsolidity/SolidityNameAndTypeResolution.cpp
index a1428972..c8a04539 100644
--- a/test/libsolidity/SolidityNameAndTypeResolution.cpp
+++ b/test/libsolidity/SolidityNameAndTypeResolution.cpp
@@ -554,6 +554,51 @@ BOOST_AUTO_TEST_CASE(comparison_bitop_precedence)
CHECK_SUCCESS(text);
}
+BOOST_AUTO_TEST_CASE(comparison_of_function_types)
+{
+ char const* text = R"(
+ contract C {
+ function f() returns (bool ret) {
+ return this.f < this.f;
+ }
+ }
+ )";
+ CHECK_ERROR(text, TypeError, "Operator < not compatible");
+ text = R"(
+ contract C {
+ function f() returns (bool ret) {
+ return f < f;
+ }
+ }
+ )";
+ CHECK_ERROR(text, TypeError, "Operator < not compatible");
+ text = R"(
+ contract C {
+ function f() returns (bool ret) {
+ return f == f;
+ }
+ function g() returns (bool ret) {
+ return f != f;
+ }
+ }
+ )";
+ CHECK_SUCCESS(text);
+}
+
+BOOST_AUTO_TEST_CASE(comparison_of_mapping_types)
+{
+ char const* text = R"(
+ contract C {
+ mapping(uint => uint) x;
+ function f() returns (bool ret) {
+ var y = x;
+ return x == y;
+ }
+ }
+ )";
+ CHECK_ERROR(text, TypeError, "Operator == not compatible");
+}
+
BOOST_AUTO_TEST_CASE(function_no_implementation)
{
ASTPointer<SourceUnit> sourceUnit;
@@ -1049,6 +1094,28 @@ BOOST_AUTO_TEST_CASE(function_modifier_invocation_local_variables)
CHECK_SUCCESS(text);
}
+BOOST_AUTO_TEST_CASE(function_modifier_double_invocation)
+{
+ char const* text = R"(
+ contract B {
+ function f(uint x) mod(x) mod(2) { }
+ modifier mod(uint a) { if (a > 0) _; }
+ }
+ )";
+ CHECK_ERROR(text, DeclarationError, "Modifier already used for this function");
+}
+
+BOOST_AUTO_TEST_CASE(base_constructor_double_invocation)
+{
+ char const* text = R"(
+ contract C { function C(uint a) {} }
+ contract B is C {
+ function B() C(2) C(2) {}
+ }
+ )";
+ CHECK_ERROR(text, DeclarationError, "Base constructor already provided");
+}
+
BOOST_AUTO_TEST_CASE(legal_modifier_override)
{
char const* text = R"(
@@ -2183,6 +2250,36 @@ BOOST_AUTO_TEST_CASE(test_byte_is_alias_of_byte1)
ETH_TEST_REQUIRE_NO_THROW(parseAndAnalyse(text), "Type resolving failed");
}
+BOOST_AUTO_TEST_CASE(warns_assigning_decimal_to_bytesxx)
+{
+ char const* text = R"(
+ contract Foo {
+ bytes32 a = 7;
+ }
+ )";
+ CHECK_WARNING(text, "Decimal literal assigned to bytesXX variable will be left-aligned.");
+}
+
+BOOST_AUTO_TEST_CASE(does_not_warn_assigning_hex_number_to_bytesxx)
+{
+ char const* text = R"(
+ contract Foo {
+ bytes32 a = 0x1234;
+ }
+ )";
+ CHECK_SUCCESS_NO_WARNINGS(text);
+}
+
+BOOST_AUTO_TEST_CASE(explicit_conversion_from_decimal_to_bytesxx)
+{
+ char const* text = R"(
+ contract Foo {
+ bytes32 a = bytes32(7);
+ }
+ )";
+ CHECK_SUCCESS_NO_WARNINGS(text);
+}
+
BOOST_AUTO_TEST_CASE(assigning_value_to_const_variable)
{
char const* text = R"(
@@ -2284,6 +2381,16 @@ BOOST_AUTO_TEST_CASE(constant_struct)
CHECK_ERROR(text, TypeError, "implemented");
}
+BOOST_AUTO_TEST_CASE(address_is_constant)
+{
+ char const* text = R"(
+ contract C {
+ address constant x = 0x1212121212121212121212121212121212121212;
+ }
+ )";
+ CHECK_SUCCESS_NO_WARNINGS(text);
+}
+
BOOST_AUTO_TEST_CASE(uninitialized_const_variable)
{
char const* text = R"(
@@ -3708,12 +3815,12 @@ BOOST_AUTO_TEST_CASE(conditional_with_all_types)
byte[2] memory a;
byte[2] memory b;
var k = true ? a : b;
- k[0] = 0; //Avoid unused var warning
+ k[0] = byte(0); //Avoid unused var warning
bytes memory e;
bytes memory f;
var l = true ? e : f;
- l[0] = 0; // Avoid unused var warning
+ l[0] = byte(0); // Avoid unused var warning
// fixed bytes
bytes2 c;
@@ -5445,6 +5552,25 @@ BOOST_AUTO_TEST_CASE(invalid_address_length)
CHECK_WARNING(text, "checksum");
}
+BOOST_AUTO_TEST_CASE(address_test_for_bug_in_implementation)
+{
+ // A previous implementation claimed the string would be an address
+ char const* text = R"(
+ contract AddrString {
+ address public test = "0xCA35b7d915458EF540aDe6068dFe2F44E8fa733c";
+ }
+ )";
+ CHECK_ERROR(text, TypeError, "is not implicitly convertible to expected type address");
+ text = R"(
+ contract AddrString {
+ function f() returns (address) {
+ return "0xCA35b7d915458EF540aDe6068dFe2F44E8fa733c";
+ }
+ }
+ )";
+ CHECK_ERROR(text, TypeError, "is not implicitly convertible to expected type");
+}
+
BOOST_AUTO_TEST_CASE(early_exit_on_fatal_errors)
{
// This tests a crash that occured because we did not stop for fatal errors.
@@ -5710,6 +5836,80 @@ BOOST_AUTO_TEST_CASE(pure_statement_check_for_regular_for_loop)
success(text);
}
+BOOST_AUTO_TEST_CASE(warn_multiple_storage_storage_copies)
+{
+ char const* text = R"(
+ contract C {
+ struct S { uint a; uint b; }
+ S x; S y;
+ function f() {
+ (x, y) = (y, x);
+ }
+ }
+ )";
+ CHECK_WARNING(text, "This assignment performs two copies to storage.");
+}
+
+BOOST_AUTO_TEST_CASE(warn_multiple_storage_storage_copies_fill_right)
+{
+ char const* text = R"(
+ contract C {
+ struct S { uint a; uint b; }
+ S x; S y;
+ function f() {
+ (x, y, ) = (y, x, 1, 2);
+ }
+ }
+ )";
+ CHECK_WARNING(text, "This assignment performs two copies to storage.");
+}
+
+BOOST_AUTO_TEST_CASE(warn_multiple_storage_storage_copies_fill_left)
+{
+ char const* text = R"(
+ contract C {
+ struct S { uint a; uint b; }
+ S x; S y;
+ function f() {
+ (,x, y) = (1, 2, y, x);
+ }
+ }
+ )";
+ CHECK_WARNING(text, "This assignment performs two copies to storage.");
+}
+
+BOOST_AUTO_TEST_CASE(nowarn_swap_memory)
+{
+ char const* text = R"(
+ contract C {
+ struct S { uint a; uint b; }
+ function f() {
+ S memory x;
+ S memory y;
+ (x, y) = (y, x);
+ }
+ }
+ )";
+ CHECK_SUCCESS_NO_WARNINGS(text);
+}
+
+BOOST_AUTO_TEST_CASE(nowarn_swap_storage_pointers)
+{
+ char const* text = R"(
+ contract C {
+ struct S { uint a; uint b; }
+ S x; S y;
+ function f() {
+ S storage x_local = x;
+ S storage y_local = y;
+ S storage z_local = x;
+ (x, y_local, x_local, z_local) = (y, x_local, y_local, y);
+ }
+ }
+ )";
+ CHECK_SUCCESS_NO_WARNINGS(text);
+}
+
BOOST_AUTO_TEST_CASE(warn_unused_local)
{
char const* text = R"(
diff --git a/test/libsolidity/StandardCompiler.cpp b/test/libsolidity/StandardCompiler.cpp
index 35644a4d..be13d46b 100644
--- a/test/libsolidity/StandardCompiler.cpp
+++ b/test/libsolidity/StandardCompiler.cpp
@@ -189,37 +189,43 @@ BOOST_AUTO_TEST_CASE(basic_compilation)
Json::Value contract = getContractResult(result, "fileA", "A");
BOOST_CHECK(contract.isObject());
BOOST_CHECK(contract["abi"].isArray());
- BOOST_CHECK(dev::jsonCompactPrint(contract["abi"]) == "[]");
+ BOOST_CHECK_EQUAL(dev::jsonCompactPrint(contract["abi"]), "[]");
BOOST_CHECK(contract["devdoc"].isObject());
- BOOST_CHECK(dev::jsonCompactPrint(contract["devdoc"]) == "{\"methods\":{}}");
+ BOOST_CHECK_EQUAL(dev::jsonCompactPrint(contract["devdoc"]), "{\"methods\":{}}");
BOOST_CHECK(contract["userdoc"].isObject());
- BOOST_CHECK(dev::jsonCompactPrint(contract["userdoc"]) == "{\"methods\":{}}");
+ BOOST_CHECK_EQUAL(dev::jsonCompactPrint(contract["userdoc"]), "{\"methods\":{}}");
BOOST_CHECK(contract["evm"].isObject());
/// @TODO check evm.methodIdentifiers, legacyAssembly, bytecode, deployedBytecode
BOOST_CHECK(contract["evm"]["bytecode"].isObject());
BOOST_CHECK(contract["evm"]["bytecode"]["object"].isString());
- BOOST_CHECK(dev::test::bytecodeSansMetadata(contract["evm"]["bytecode"]["object"].asString()) ==
- "60606040523415600b57fe5b5b60338060196000396000f30060606040525bfe00");
+ BOOST_CHECK_EQUAL(
+ dev::test::bytecodeSansMetadata(contract["evm"]["bytecode"]["object"].asString()),
+ "60606040523415600e57600080fd5b5b603680601c6000396000f30060606040525b600080fd00"
+ );
BOOST_CHECK(contract["evm"]["assembly"].isString());
BOOST_CHECK(contract["evm"]["assembly"].asString().find(
" /* \"fileA\":0:14 contract A { } */\n mstore(0x40, 0x60)\n jumpi(tag_1, iszero(callvalue))\n"
- " invalid\ntag_1:\ntag_2:\n dataSize(sub_0)\n dup1\n dataOffset(sub_0)\n 0x0\n codecopy\n 0x0\n"
+ " 0x0\n dup1\n revert\ntag_1:\ntag_2:\n dataSize(sub_0)\n dup1\n dataOffset(sub_0)\n 0x0\n codecopy\n 0x0\n"
" return\nstop\n\nsub_0: assembly {\n /* \"fileA\":0:14 contract A { } */\n"
- " mstore(0x40, 0x60)\n tag_1:\n invalid\n\n"
- " auxdata: 0xa165627a7a72305820") != std::string::npos);
+ " mstore(0x40, 0x60)\n tag_1:\n 0x0\n dup1\n revert\n\n"
+ " auxdata: 0xa165627a7a7230582") == 0);
BOOST_CHECK(contract["evm"]["gasEstimates"].isObject());
- BOOST_CHECK(dev::jsonCompactPrint(contract["evm"]["gasEstimates"]) ==
- "{\"creation\":{\"codeDepositCost\":\"10200\",\"executionCost\":\"62\",\"totalCost\":\"10262\"}}");
+ BOOST_CHECK_EQUAL(
+ dev::jsonCompactPrint(contract["evm"]["gasEstimates"]),
+ "{\"creation\":{\"codeDepositCost\":\"10800\",\"executionCost\":\"62\",\"totalCost\":\"10862\"}}"
+ );
BOOST_CHECK(contract["metadata"].isString());
BOOST_CHECK(dev::test::isValidMetadata(contract["metadata"].asString()));
BOOST_CHECK(result["sources"].isObject());
BOOST_CHECK(result["sources"]["fileA"].isObject());
BOOST_CHECK(result["sources"]["fileA"]["legacyAST"].isObject());
- BOOST_CHECK(dev::jsonCompactPrint(result["sources"]["fileA"]["legacyAST"]) ==
+ BOOST_CHECK_EQUAL(
+ dev::jsonCompactPrint(result["sources"]["fileA"]["legacyAST"]),
"{\"attributes\":{\"absolutePath\":\"fileA\",\"exportedSymbols\":{\"A\":[1]}},\"children\":"
"[{\"attributes\":{\"baseContracts\":[null],\"contractDependencies\":[null],\"contractKind\":\"contract\","
"\"documentation\":null,\"fullyImplemented\":true,\"linearizedBaseContracts\":[1],\"name\":\"A\",\"nodes\":[null],\"scope\":2},"
- "\"id\":1,\"name\":\"ContractDefinition\",\"src\":\"0:14:0\"}],\"id\":2,\"name\":\"SourceUnit\",\"src\":\"0:14:0\"}");
+ "\"id\":1,\"name\":\"ContractDefinition\",\"src\":\"0:14:0\"}],\"id\":2,\"name\":\"SourceUnit\",\"src\":\"0:14:0\"}"
+ );
}
BOOST_AUTO_TEST_SUITE_END()