aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--SolidityEndToEndTest.cpp20
-rw-r--r--SolidityNameAndTypeResolution.cpp83
-rw-r--r--SolidityParser.cpp10
3 files changed, 113 insertions, 0 deletions
diff --git a/SolidityEndToEndTest.cpp b/SolidityEndToEndTest.cpp
index cf04edaa..8bce1788 100644
--- a/SolidityEndToEndTest.cpp
+++ b/SolidityEndToEndTest.cpp
@@ -1650,6 +1650,26 @@ BOOST_AUTO_TEST_CASE(constructor_argument_overriding)
BOOST_CHECK(callContractFunction("getA()") == encodeArgs(3));
}
+BOOST_AUTO_TEST_CASE(function_modifier)
+{
+ char const* sourceCode = R"(
+ contract BaseBase {
+ uint m_a;
+ function BaseBase(uint a) {
+ m_a = a;
+ }
+ }
+ contract Base is BaseBase(2) { }
+ contract Derived is Base, BaseBase(3) {
+ function getA() returns (uint r) { return m_a; }
+ }
+ )";
+ compileAndRun(sourceCode, 0, "Derived");
+ BOOST_CHECK(callContractFunction("getA()") == encodeArgs(3));
+}
+
+// modifier overriding
+
BOOST_AUTO_TEST_SUITE_END()
}
diff --git a/SolidityNameAndTypeResolution.cpp b/SolidityNameAndTypeResolution.cpp
index 6c8fd1b1..c195539f 100644
--- a/SolidityNameAndTypeResolution.cpp
+++ b/SolidityNameAndTypeResolution.cpp
@@ -479,6 +479,7 @@ BOOST_AUTO_TEST_CASE(implicit_derived_to_base_conversion)
)";
BOOST_CHECK_NO_THROW(parseTextAndResolveNames(text));
}
+
BOOST_AUTO_TEST_CASE(implicit_base_to_derived_conversion)
{
char const* text = R"(
@@ -490,6 +491,88 @@ BOOST_AUTO_TEST_CASE(implicit_base_to_derived_conversion)
BOOST_CHECK_THROW(parseTextAndResolveNames(text), TypeError);
}
+BOOST_AUTO_TEST_CASE(function_modifier_invocation)
+{
+ char const* text = R"(
+ contract B {
+ function f() mod1(2, true) mod2("0123456") { }
+ modifier mod1(uint a, bool b) { if (b) _ }
+ modifier mod2(string7 a) { while (a == "1234567") _ }
+ }
+ )";
+ BOOST_CHECK_NO_THROW(parseTextAndResolveNames(text));
+}
+
+BOOST_AUTO_TEST_CASE(invalid_function_modifier_type)
+{
+ char const* text = R"(
+ contract B {
+ function f() mod1(true) { }
+ modifier mod1(uint a) { if (a > 0) _ }
+ }
+ )";
+ BOOST_CHECK_THROW(parseTextAndResolveNames(text), TypeError);
+}
+
+BOOST_AUTO_TEST_CASE(function_modifier_invocation_parameters)
+{
+ char const* text = R"(
+ contract B {
+ function f(uint8 a) mod1(a, true) mod2(r) returns (string7 r) { }
+ modifier mod1(uint a, bool b) { if (b) _ }
+ modifier mod2(string7 a) { while (a == "1234567") _ }
+ }
+ )";
+ BOOST_CHECK_NO_THROW(parseTextAndResolveNames(text));
+}
+
+BOOST_AUTO_TEST_CASE(function_modifier_invocation_local_variables)
+{
+ char const* text = R"(
+ contract B {
+ function f() mod(x) { uint x = 7; }
+ modifier mod(uint a) { if (a > 0) _ }
+ }
+ )";
+ BOOST_CHECK_NO_THROW(parseTextAndResolveNames(text));
+}
+
+BOOST_AUTO_TEST_CASE(legal_modifier_override)
+{
+ char const* text = R"(
+ contract A { modifier mod(uint a) {} }
+ contract B is A { modifier mod(uint a) {} }
+ )";
+ BOOST_CHECK_NO_THROW(parseTextAndResolveNames(text));
+}
+
+BOOST_AUTO_TEST_CASE(illegal_modifier_override)
+{
+ char const* text = R"(
+ contract A { modifier mod(uint a) {} }
+ contract B is A { modifier mod(uint8 a) {} }
+ )";
+ BOOST_CHECK_THROW(parseTextAndResolveNames(text), TypeError);
+}
+
+BOOST_AUTO_TEST_CASE(modifier_overrides_function)
+{
+ char const* text = R"(
+ contract A { modifier mod(uint a) {} }
+ contract B is A { function mod(uint a) {} }
+ )";
+ BOOST_CHECK_THROW(parseTextAndResolveNames(text), TypeError);
+}
+
+BOOST_AUTO_TEST_CASE(function_overrides_modifier)
+{
+ char const* text = R"(
+ contract A { function mod(uint a) {} }
+ contract B is A { modifier mod(uint a) {} }
+ )";
+ BOOST_CHECK_THROW(parseTextAndResolveNames(text), TypeError);
+}
+
BOOST_AUTO_TEST_SUITE_END()
}
diff --git a/SolidityParser.cpp b/SolidityParser.cpp
index e476bee3..e331b9c6 100644
--- a/SolidityParser.cpp
+++ b/SolidityParser.cpp
@@ -567,6 +567,16 @@ BOOST_AUTO_TEST_CASE(modifier_arguments)
BOOST_CHECK_NO_THROW(parseText(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";
+ BOOST_CHECK_NO_THROW(parseText(text));
+}
+
BOOST_AUTO_TEST_SUITE_END()
}