diff options
-rw-r--r-- | SolidityEndToEndTest.cpp | 20 | ||||
-rw-r--r-- | SolidityNameAndTypeResolution.cpp | 83 | ||||
-rw-r--r-- | SolidityParser.cpp | 10 |
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() } |