aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorchriseth <chris@ethereum.org>2018-04-12 04:25:36 +0800
committerGitHub <noreply@github.com>2018-04-12 04:25:36 +0800
commitee5d0ef79bee71a47249ed36081738dd34707900 (patch)
treefcc1d4e910eef36fef15fca3e036f3039146450c
parent7626c8ab7276266c3721310d41455c393d1ee888 (diff)
parentb5a696ad48780bf0614eef2a737a2e89963d4640 (diff)
downloaddexon-solidity-ee5d0ef79bee71a47249ed36081738dd34707900.tar
dexon-solidity-ee5d0ef79bee71a47249ed36081738dd34707900.tar.gz
dexon-solidity-ee5d0ef79bee71a47249ed36081738dd34707900.tar.bz2
dexon-solidity-ee5d0ef79bee71a47249ed36081738dd34707900.tar.lz
dexon-solidity-ee5d0ef79bee71a47249ed36081738dd34707900.tar.xz
dexon-solidity-ee5d0ef79bee71a47249ed36081738dd34707900.tar.zst
dexon-solidity-ee5d0ef79bee71a47249ed36081738dd34707900.zip
Merge pull request #3752 from ethereum/fixStateVariableParsing
Fix state variable parsing
-rw-r--r--Changelog.md2
-rw-r--r--libsolidity/analysis/SyntaxChecker.cpp7
-rw-r--r--libsolidity/parsing/Parser.cpp19
-rw-r--r--test/libsolidity/SolidityNameAndTypeResolution.cpp471
-rw-r--r--test/libsolidity/syntaxTests/functionTypes/call_value_on_non_payable_function_type.sol8
-rw-r--r--test/libsolidity/syntaxTests/functionTypes/call_value_on_payable_function_type.sol6
-rw-r--r--test/libsolidity/syntaxTests/functionTypes/delete_external_function_type_invalid.sol7
-rw-r--r--test/libsolidity/syntaxTests/functionTypes/delete_function_type.sol17
-rw-r--r--test/libsolidity/syntaxTests/functionTypes/delete_function_type_invalid.sol7
-rw-r--r--test/libsolidity/syntaxTests/functionTypes/external_function_to_function_type_calldata_parameter.sol10
-rw-r--r--test/libsolidity/syntaxTests/functionTypes/external_function_type_public_variable.sol11
-rw-r--r--test/libsolidity/syntaxTests/functionTypes/external_function_type_returning_internal.sol5
-rw-r--r--test/libsolidity/syntaxTests/functionTypes/external_function_type_taking_internal.sol5
-rw-r--r--test/libsolidity/syntaxTests/functionTypes/external_function_type_to_address.sol5
-rw-r--r--test/libsolidity/syntaxTests/functionTypes/external_function_type_to_uint.sol7
-rw-r--r--test/libsolidity/syntaxTests/functionTypes/function_type.sol6
-rw-r--r--test/libsolidity/syntaxTests/functionTypes/function_type_arrays.sol11
-rw-r--r--test/libsolidity/syntaxTests/functionTypes/function_type_constructor.sol7
-rw-r--r--test/libsolidity/syntaxTests/functionTypes/function_type_constructor_local.sol8
-rw-r--r--test/libsolidity/syntaxTests/functionTypes/function_type_internal_public_variable.sol5
-rw-r--r--test/libsolidity/syntaxTests/functionTypes/function_type_parameter.sol7
-rw-r--r--test/libsolidity/syntaxTests/functionTypes/function_type_returned.sol5
-rw-r--r--test/libsolidity/syntaxTests/functionTypes/function_type_variable_external_internal.sol6
-rw-r--r--test/libsolidity/syntaxTests/functionTypes/function_types_internal_visibility_error.sol7
-rw-r--r--test/libsolidity/syntaxTests/functionTypes/function_types_variable_visibility.sol9
-rw-r--r--test/libsolidity/syntaxTests/functionTypes/internal_function_as_external_parameter.sol8
-rw-r--r--test/libsolidity/syntaxTests/functionTypes/internal_function_as_external_parameter_in_library_external.sol6
-rw-r--r--test/libsolidity/syntaxTests/functionTypes/internal_function_as_external_parameter_in_library_internal.sol4
-rw-r--r--test/libsolidity/syntaxTests/functionTypes/internal_function_returned_from_public_function.sol7
-rw-r--r--test/libsolidity/syntaxTests/functionTypes/internal_function_type_to_address.sol7
-rw-r--r--test/libsolidity/syntaxTests/functionTypes/payable_internal_function_type.sol5
-rw-r--r--test/libsolidity/syntaxTests/functionTypes/payable_internal_function_type_is_not_fatal.sol9
-rw-r--r--test/libsolidity/syntaxTests/functionTypes/private_function_type.sol7
-rw-r--r--test/libsolidity/syntaxTests/functionTypes/public_function_type.sol7
-rw-r--r--test/libsolidity/syntaxTests/functionTypes/valid_function_type_variables.sol23
-rw-r--r--test/libsolidity/syntaxTests/functionTypes/warn_function_type_parameters_with_names.sol5
-rw-r--r--test/libsolidity/syntaxTests/functionTypes/warn_function_type_return_parameters_with_names.sol5
-rw-r--r--test/libsolidity/syntaxTests/modifiers/base_constructor_double_invocation.sol7
-rw-r--r--test/libsolidity/syntaxTests/modifiers/constructor_call_invalid_arg_count.sol9
-rw-r--r--test/libsolidity/syntaxTests/modifiers/function_modifier_double_invocation.sol4
-rw-r--r--test/libsolidity/syntaxTests/modifiers/function_modifier_invocation.sol5
-rw-r--r--test/libsolidity/syntaxTests/modifiers/function_modifier_invocation_local_variables.sol4
-rw-r--r--test/libsolidity/syntaxTests/modifiers/function_modifier_invocation_local_variables050.sol7
-rw-r--r--test/libsolidity/syntaxTests/modifiers/function_modifier_invocation_parameters.sol5
-rw-r--r--test/libsolidity/syntaxTests/modifiers/function_overrides_modifier.sol5
-rw-r--r--test/libsolidity/syntaxTests/modifiers/illegal_modifier_override.sol4
-rw-r--r--test/libsolidity/syntaxTests/modifiers/invalid_function_modifier_type.sol6
-rw-r--r--test/libsolidity/syntaxTests/modifiers/legal_modifier_override.sol2
-rw-r--r--test/libsolidity/syntaxTests/modifiers/modifier_overrides_function.sol5
-rw-r--r--test/libsolidity/syntaxTests/modifiers/modifier_returns_value.sol6
-rw-r--r--test/libsolidity/syntaxTests/modifiers/modifier_without_underscore.sol5
-rw-r--r--test/libsolidity/syntaxTests/modifiers/modifiers_on_abstract_functions_050.sol10
-rw-r--r--test/libsolidity/syntaxTests/modifiers/modifiers_on_abstract_functions_no_parser_error.sol13
53 files changed, 373 insertions, 475 deletions
diff --git a/Changelog.md b/Changelog.md
index d0af8025..e2174cfd 100644
--- a/Changelog.md
+++ b/Changelog.md
@@ -14,6 +14,7 @@ Features:
* Optimizer: Optimize across ``mload`` if ``msize()`` is not used.
* Static Analyzer: Error on duplicated super constructor calls as experimental 0.5.0 feature.
* Syntax Checker: Issue warning for empty structs (or error as experimental 0.5.0 feature).
+ * Syntax Checker: Warn about modifiers on functions without implementation (this will turn into an error with version 0.5.0).
* Syntax Tests: Add source locations to syntax test expectations.
* General: Introduce new constructor syntax using the ``constructor`` keyword as experimental 0.5.0 feature.
* Inheritance: Error when using empty parentheses for base class constructors that require arguments as experimental 0.5.0 feature.
@@ -30,6 +31,7 @@ Bugfixes:
* Commandline interface: Support ``--evm-version constantinople`` properly.
* DocString Parser: Fix error message for empty descriptions.
* Gas Estimator: Correctly ignore costs of fallback function for other functions.
+ * Parser: Fix parsing of getters for function type variables.
* Standard JSON: Support ``constantinople`` as ``evmVersion`` properly.
* Type Checker: Fix detection of recursive structs.
* Type Checker: Fix asymmetry bug when comparing with literal numbers.
diff --git a/libsolidity/analysis/SyntaxChecker.cpp b/libsolidity/analysis/SyntaxChecker.cpp
index 343b4ba8..f648e5b4 100644
--- a/libsolidity/analysis/SyntaxChecker.cpp
+++ b/libsolidity/analysis/SyntaxChecker.cpp
@@ -232,6 +232,13 @@ bool SyntaxChecker::visit(FunctionDefinition const& _function)
"Use \"constructor(...) { ... }\" instead."
);
}
+ if (!_function.isImplemented() && !_function.modifiers().empty())
+ {
+ if (v050)
+ m_errorReporter.syntaxError(_function.location(), "Functions without implementation cannot have modifiers.");
+ else
+ m_errorReporter.warning( _function.location(), "Modifiers of functions without implementation are ignored." );
+ }
return true;
}
diff --git a/libsolidity/parsing/Parser.cpp b/libsolidity/parsing/Parser.cpp
index 18ef740a..2d8ca7d3 100644
--- a/libsolidity/parsing/Parser.cpp
+++ b/libsolidity/parsing/Parser.cpp
@@ -365,12 +365,13 @@ Parser::FunctionHeaderParserResult Parser::parseFunctionHeader(
Token::Value token = m_scanner->currentToken();
if (_allowModifiers && token == Token::Identifier)
{
- // This can either be a modifier (function declaration) or the name of the
- // variable (function type name plus variable).
- if (
+ // If the name is empty (and this is not a constructor),
+ // then this can either be a modifier (fallback function declaration)
+ // or the name of the state variable (function type name plus variable).
+ if ((result.name->empty() && !result.isConstructor) && (
m_scanner->peekNextToken() == Token::Semicolon ||
m_scanner->peekNextToken() == Token::Assign
- )
+ ))
// Variable declaration, break here.
break;
else
@@ -380,6 +381,14 @@ Parser::FunctionHeaderParserResult Parser::parseFunctionHeader(
{
if (result.visibility != Declaration::Visibility::Default)
{
+ // There is the special case of a public state variable of function type.
+ // Detect this and return early.
+ if (
+ (result.visibility == Declaration::Visibility::External || result.visibility == Declaration::Visibility::Internal) &&
+ result.modifiers.empty() &&
+ (result.name->empty() && !result.isConstructor)
+ )
+ break;
parserError(string(
"Visibility already specified as \"" +
Declaration::visibilityToString(result.visibility) +
@@ -429,6 +438,7 @@ ASTPointer<ASTNode> Parser::parseFunctionDefinitionOrFunctionTypeStateVariable(A
FunctionHeaderParserResult header = parseFunctionHeader(false, true, _contractName);
if (
+ header.isConstructor ||
!header.modifiers.empty() ||
!header.name->empty() ||
m_scanner->currentToken() == Token::Semicolon ||
@@ -794,6 +804,7 @@ ASTPointer<FunctionTypeName> Parser::parseFunctionType()
RecursionGuard recursionGuard(*this);
ASTNodeFactory nodeFactory(*this);
FunctionHeaderParserResult header = parseFunctionHeader(true, false);
+ solAssert(!header.isConstructor, "Tried to parse type as constructor.");
return nodeFactory.createNode<FunctionTypeName>(
header.parameters,
header.returnParameters,
diff --git a/test/libsolidity/SolidityNameAndTypeResolution.cpp b/test/libsolidity/SolidityNameAndTypeResolution.cpp
index 293f5f44..18a414e0 100644
--- a/test/libsolidity/SolidityNameAndTypeResolution.cpp
+++ b/test/libsolidity/SolidityNameAndTypeResolution.cpp
@@ -975,139 +975,6 @@ BOOST_AUTO_TEST_CASE(super_excludes_current_contract)
CHECK_ERROR(text, TypeError, "Member \"f\" not found or not visible after argument-dependent lookup in contract super B");
}
-BOOST_AUTO_TEST_CASE(function_modifier_invocation)
-{
- char const* text = R"(
- contract B {
- function f() mod1(2, true) mod2("0123456") pure public { }
- modifier mod1(uint a, bool b) { if (b) _; }
- modifier mod2(bytes7 a) { while (a == "1234567") _; }
- }
- )";
- CHECK_SUCCESS(text);
-}
-
-BOOST_AUTO_TEST_CASE(invalid_function_modifier_type)
-{
- char const* text = R"(
- contract B {
- function f() mod1(true) public { }
- modifier mod1(uint a) { if (a > 0) _; }
- }
- )";
- CHECK_ERROR(text, TypeError, "Invalid type for argument in modifier invocation. Invalid implicit conversion from bool to uint256 requested.");
-}
-
-BOOST_AUTO_TEST_CASE(function_modifier_invocation_parameters)
-{
- char const* text = R"(
- contract B {
- function f(uint8 a) mod1(a, true) mod2(r) public returns (bytes7 r) { }
- modifier mod1(uint a, bool b) { if (b) _; }
- modifier mod2(bytes7 a) { while (a == "1234567") _; }
- }
- )";
- CHECK_SUCCESS(text);
-}
-
-BOOST_AUTO_TEST_CASE(function_modifier_invocation_local_variables)
-{
- char const* text = R"(
- contract B {
- function f() mod(x) pure public { uint x = 7; }
- modifier mod(uint a) { if (a > 0) _; }
- }
- )";
- CHECK_SUCCESS_NO_WARNINGS(text);
-}
-
-BOOST_AUTO_TEST_CASE(function_modifier_invocation_local_variables050)
-{
- char const* text = R"(
- pragma experimental "v0.5.0";
- contract B {
- function f() mod(x) pure public { uint x = 7; }
- modifier mod(uint a) { if (a > 0) _; }
- }
- )";
- CHECK_ERROR(text, DeclarationError, "Undeclared identifier.");
-}
-
-BOOST_AUTO_TEST_CASE(function_modifier_double_invocation)
-{
- char const* text = R"(
- contract B {
- function f(uint x) mod(x) mod(2) public { }
- modifier mod(uint a) { if (a > 0) _; }
- }
- )";
- CHECK_SUCCESS(text);
-}
-
-BOOST_AUTO_TEST_CASE(base_constructor_double_invocation)
-{
- char const* text = R"(
- contract C { function C(uint a) public {} }
- contract B is C {
- function B() C(2) C(2) public {}
- }
- )";
- CHECK_ERROR(text, DeclarationError, "Base constructor already provided");
-}
-
-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) { _; } }
- )";
- CHECK_SUCCESS(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) { _; } }
- )";
- CHECK_ERROR(text, TypeError, "Override changes modifier signature.");
-}
-
-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) public { } }
- )";
- CHECK_ALLOW_MULTI(text, (vector<pair<Error::Type, string>>{
- {Error::Type::DeclarationError, "Identifier already declared"},
- {Error::Type::TypeError, "Override changes modifier to function"}
- }));
-}
-
-BOOST_AUTO_TEST_CASE(function_overrides_modifier)
-{
- char const* text = R"(
- contract A { function mod(uint a) public { } }
- contract B is A { modifier mod(uint a) { _; } }
- )";
- CHECK_ALLOW_MULTI(text, (vector<pair<Error::Type, string>>{
- {Error::Type::DeclarationError, "Identifier already declared"},
- {Error::Type::TypeError, "Override changes function to modifier"}
- }));
-}
-
-BOOST_AUTO_TEST_CASE(modifier_returns_value)
-{
- char const* text = R"(
- contract A {
- function f(uint a) mod(2) public returns (uint r) { }
- modifier mod(uint a) { _; return 7; }
- }
- )";
- CHECK_ERROR(text, TypeError, "Return arguments not allowed.");
-}
-
BOOST_AUTO_TEST_CASE(state_variable_accessors)
{
char const* text = R"(
@@ -4176,21 +4043,6 @@ BOOST_AUTO_TEST_CASE(conditional_with_all_types)
CHECK_SUCCESS(text);
}
-BOOST_AUTO_TEST_CASE(constructor_call_invalid_arg_count)
-{
- // This caused a segfault in an earlier version
- char const* text = R"(
- contract C {
- function C(){}
- }
- contract D is C {
- function D() C(5){}
- }
- )";
-
- CHECK_ERROR(text, TypeError, "Wrong argument count for modifier invocation: 1 arguments given but expected 0.");
-}
-
BOOST_AUTO_TEST_CASE(index_access_for_bytes)
{
char const* text = R"(
@@ -5055,16 +4907,6 @@ BOOST_AUTO_TEST_CASE(no_warn_about_callcode_as_function)
CHECK_SUCCESS_NO_WARNINGS(text);
}
-BOOST_AUTO_TEST_CASE(modifier_without_underscore)
-{
- char const* text = R"(
- contract test {
- modifier m() {}
- }
- )";
- CHECK_ERROR(text, SyntaxError, "Modifier body does not contain '_'.");
-}
-
BOOST_AUTO_TEST_CASE(payable_in_library)
{
char const* text = R"(
@@ -5264,319 +5106,6 @@ BOOST_AUTO_TEST_CASE(using_directive_for_missing_selftype)
CHECK_ERROR(text, TypeError, "Member \"b\" not found or not visible after argument-dependent lookup in bytes memory");
}
-BOOST_AUTO_TEST_CASE(function_type)
-{
- char const* text = R"(
- contract C {
- function f() public {
- function(uint) returns (uint) x;
- }
- }
- )";
- CHECK_SUCCESS(text);
-}
-
-BOOST_AUTO_TEST_CASE(function_type_parameter)
-{
- char const* text = R"(
- contract C {
- function f(function(uint) external returns (uint) g) public returns (function(uint) external returns (uint)) {
- return g;
- }
- }
- )";
- CHECK_SUCCESS(text);
-}
-
-BOOST_AUTO_TEST_CASE(function_type_returned)
-{
- char const* text = R"(
- contract C {
- function f() public returns (function(uint) external returns (uint) g) {
- return g;
- }
- }
- )";
- CHECK_SUCCESS(text);
-}
-
-BOOST_AUTO_TEST_CASE(private_function_type)
-{
- char const* text = R"(
- contract C {
- function f() public {
- function(uint) private returns (uint) x;
- }
- }
- )";
- CHECK_ERROR(text, TypeError, "Invalid visibility, can only be \"external\" or \"internal\".");
-}
-
-BOOST_AUTO_TEST_CASE(public_function_type)
-{
- char const* text = R"(
- contract C {
- function f() public {
- function(uint) public returns (uint) x;
- }
- }
- )";
- CHECK_ERROR(text, TypeError, "Invalid visibility, can only be \"external\" or \"internal\".");
-}
-
-BOOST_AUTO_TEST_CASE(payable_internal_function_type)
-{
- char const* text = R"(
- contract C {
- function (uint) internal payable returns (uint) x;
- }
- )";
- CHECK_ERROR(text, TypeError, "Only external function types can be payable.");
-}
-
-BOOST_AUTO_TEST_CASE(payable_internal_function_type_is_not_fatal)
-{
- char const* text = R"(
- contract C {
- function (uint) internal payable returns (uint) x;
-
- function g() {
- x = g;
- }
- }
- )";
- CHECK_ERROR_ALLOW_MULTI(text, TypeError, (std::vector<std::string>{"Only external function types can be payable."}));
-}
-
-BOOST_AUTO_TEST_CASE(call_value_on_non_payable_function_type)
-{
- char const* text = R"(
- contract C {
- function (uint) external returns (uint) x;
- function f() public {
- x.value(2)();
- }
- }
- )";
- CHECK_ERROR(text, TypeError, "Member \"value\" not found or not visible after argument-dependent lookup in function (uint256) external returns (uint256) - did you forget the \"payable\" modifier?");
-}
-
-BOOST_AUTO_TEST_CASE(external_function_type_returning_internal)
-{
- char const* text = R"(
- contract C {
- function() external returns (function () internal) x;
- }
- )";
- CHECK_ERROR(text, TypeError, "Internal type cannot be used for external function type.");
-}
-
-BOOST_AUTO_TEST_CASE(external_function_type_taking_internal)
-{
- char const* text = R"(
- contract C {
- function(function () internal) external x;
- }
- )";
- CHECK_ERROR(text, TypeError, "Internal type cannot be used for external function type.");
-}
-
-BOOST_AUTO_TEST_CASE(call_value_on_payable_function_type)
-{
- char const* text = R"(
- contract C {
- function (uint) external payable returns (uint) x;
- function f() public {
- x.value(2)(1);
- }
- }
- )";
- CHECK_SUCCESS(text);
-}
-
-BOOST_AUTO_TEST_CASE(internal_function_as_external_parameter)
-{
- // It should not be possible to give internal functions
- // as parameters to external functions.
- char const* text = R"(
- contract C {
- function f(function(uint) internal returns (uint) x) public {
- }
- }
- )";
- CHECK_ERROR(text, TypeError, "Internal or recursive type is not allowed for public or external functions.");
-}
-
-BOOST_AUTO_TEST_CASE(internal_function_returned_from_public_function)
-{
- // It should not be possible to return internal functions from external functions.
- char const* text = R"(
- contract C {
- function f() public returns (function(uint) internal returns (uint) x) {
- }
- }
- )";
- CHECK_ERROR(text, TypeError, "Internal or recursive type is not allowed for public or external functions.");
-}
-
-BOOST_AUTO_TEST_CASE(internal_function_as_external_parameter_in_library_internal)
-{
- char const* text = R"(
- library L {
- function f(function(uint) internal returns (uint) x) internal {
- }
- }
- )";
- CHECK_SUCCESS(text);
-}
-
-BOOST_AUTO_TEST_CASE(internal_function_as_external_parameter_in_library_external)
-{
- char const* text = R"(
- library L {
- function f(function(uint) internal returns (uint) x) public {
- }
- }
- )";
- CHECK_ERROR(text, TypeError, "Internal or recursive type is not allowed for public or external functions.");
-}
-
-BOOST_AUTO_TEST_CASE(function_type_arrays)
-{
- char const* text = R"(
- contract C {
- function(uint) external returns (uint)[] public x;
- function(uint) internal returns (uint)[10] y;
- function f() public {
- function(uint) returns (uint)[10] memory a;
- function(uint) returns (uint)[10] storage b = y;
- function(uint) external returns (uint)[] memory c;
- c = new function(uint) external returns (uint)[](200);
- a; b;
- }
- }
- )";
- CHECK_SUCCESS(text);
-}
-
-BOOST_AUTO_TEST_CASE(delete_function_type)
-{
- char const* text = R"(
- contract C {
- function(uint) external returns (uint) x;
- function(uint) internal returns (uint) y;
- function f() public {
- delete x;
- var a = y;
- delete a;
- delete y;
- var c = f;
- delete c;
- function(uint) internal returns (uint) g;
- delete g;
- }
- }
- )";
- CHECK_SUCCESS(text);
-}
-
-BOOST_AUTO_TEST_CASE(delete_function_type_invalid)
-{
- char const* text = R"(
- contract C {
- function f() public {
- delete f;
- }
- }
- )";
- CHECK_ERROR(text, TypeError, "Expression has to be an lvalue.");
-}
-
-BOOST_AUTO_TEST_CASE(delete_external_function_type_invalid)
-{
- char const* text = R"(
- contract C {
- function f() public {
- delete this.f;
- }
- }
- )";
- CHECK_ERROR(text, TypeError, "Expression has to be an lvalue.");
-}
-
-BOOST_AUTO_TEST_CASE(external_function_to_function_type_calldata_parameter)
-{
- // This is a test that checks that the type of the `bytes` parameter is
- // correctly changed from its own type `bytes calldata` to `bytes memory`
- // when converting to a function type.
- char const* text = R"(
- contract C {
- function f(function(bytes memory) external g) public { }
- function callback(bytes) external {}
- function g() public {
- f(this.callback);
- }
- }
- )";
- CHECK_SUCCESS(text);
-}
-
-BOOST_AUTO_TEST_CASE(external_function_type_to_address)
-{
- char const* text = R"(
- contract C {
- function f() public returns (address) {
- return address(this.f);
- }
- }
- )";
- CHECK_SUCCESS(text);
-}
-
-BOOST_AUTO_TEST_CASE(internal_function_type_to_address)
-{
- char const* text = R"(
- contract C {
- function f() public returns (address) {
- return address(f);
- }
- }
- )";
- CHECK_ERROR(text, TypeError, "Explicit type conversion not allowed");
-}
-
-BOOST_AUTO_TEST_CASE(external_function_type_to_uint)
-{
- char const* text = R"(
- contract C {
- function f() public returns (uint) {
- return uint(this.f);
- }
- }
- )";
- CHECK_ERROR(text, TypeError, "Explicit type conversion not allowed");
-}
-
-BOOST_AUTO_TEST_CASE(warn_function_type_parameters_with_names)
-{
- char const* text = R"(
- contract C {
- function(uint a) f;
- }
- )";
- CHECK_WARNING(text, "Naming function type parameters is deprecated.");
-}
-
-BOOST_AUTO_TEST_CASE(warn_function_type_return_parameters_with_names)
-{
- char const* text = R"(
- contract C {
- function(uint) returns (bool ret) f;
- }
- )";
- CHECK_WARNING(text, "Naming function type return parameters is deprecated.");
-}
-
BOOST_AUTO_TEST_CASE(shift_constant_left_negative_rvalue)
{
char const* text = R"(
diff --git a/test/libsolidity/syntaxTests/functionTypes/call_value_on_non_payable_function_type.sol b/test/libsolidity/syntaxTests/functionTypes/call_value_on_non_payable_function_type.sol
new file mode 100644
index 00000000..87c3b05b
--- /dev/null
+++ b/test/libsolidity/syntaxTests/functionTypes/call_value_on_non_payable_function_type.sol
@@ -0,0 +1,8 @@
+contract C {
+ function (uint) external returns (uint) x;
+ function f() public {
+ x.value(2)();
+ }
+}
+// ----
+// TypeError: (94-101): Member "value" not found or not visible after argument-dependent lookup in function (uint256) external returns (uint256) - did you forget the "payable" modifier?
diff --git a/test/libsolidity/syntaxTests/functionTypes/call_value_on_payable_function_type.sol b/test/libsolidity/syntaxTests/functionTypes/call_value_on_payable_function_type.sol
new file mode 100644
index 00000000..ca2a0196
--- /dev/null
+++ b/test/libsolidity/syntaxTests/functionTypes/call_value_on_payable_function_type.sol
@@ -0,0 +1,6 @@
+contract C {
+ function (uint) external payable returns (uint) x;
+ function f() public {
+ x.value(2)(1);
+ }
+}
diff --git a/test/libsolidity/syntaxTests/functionTypes/delete_external_function_type_invalid.sol b/test/libsolidity/syntaxTests/functionTypes/delete_external_function_type_invalid.sol
new file mode 100644
index 00000000..2711dae8
--- /dev/null
+++ b/test/libsolidity/syntaxTests/functionTypes/delete_external_function_type_invalid.sol
@@ -0,0 +1,7 @@
+contract C {
+ function f() public {
+ delete this.f;
+ }
+}
+// ----
+// TypeError: (54-60): Expression has to be an lvalue.
diff --git a/test/libsolidity/syntaxTests/functionTypes/delete_function_type.sol b/test/libsolidity/syntaxTests/functionTypes/delete_function_type.sol
new file mode 100644
index 00000000..a6fe6c22
--- /dev/null
+++ b/test/libsolidity/syntaxTests/functionTypes/delete_function_type.sol
@@ -0,0 +1,17 @@
+contract C {
+ function(uint) external returns (uint) x;
+ function(uint) internal returns (uint) y;
+ function f() public {
+ delete x;
+ var a = y;
+ delete a;
+ delete y;
+ var c = f;
+ delete c;
+ function(uint) internal returns (uint) g;
+ delete g;
+ }
+}
+// ----
+// Warning: (157-162): Use of the "var" keyword is deprecated.
+// Warning: (212-217): Use of the "var" keyword is deprecated.
diff --git a/test/libsolidity/syntaxTests/functionTypes/delete_function_type_invalid.sol b/test/libsolidity/syntaxTests/functionTypes/delete_function_type_invalid.sol
new file mode 100644
index 00000000..60da19e4
--- /dev/null
+++ b/test/libsolidity/syntaxTests/functionTypes/delete_function_type_invalid.sol
@@ -0,0 +1,7 @@
+contract C {
+ function f() public {
+ delete f;
+ }
+}
+// ----
+// TypeError: (54-55): Expression has to be an lvalue.
diff --git a/test/libsolidity/syntaxTests/functionTypes/external_function_to_function_type_calldata_parameter.sol b/test/libsolidity/syntaxTests/functionTypes/external_function_to_function_type_calldata_parameter.sol
new file mode 100644
index 00000000..eb4f0693
--- /dev/null
+++ b/test/libsolidity/syntaxTests/functionTypes/external_function_to_function_type_calldata_parameter.sol
@@ -0,0 +1,10 @@
+// This is a test that checks that the type of the `bytes` parameter is
+// correctly changed from its own type `bytes calldata` to `bytes memory`
+// when converting to a function type.
+contract C {
+ function f(function(bytes memory) pure external /*g*/) pure public { }
+ function callback(bytes) pure external {}
+ function g() view public {
+ f(this.callback);
+ }
+}
diff --git a/test/libsolidity/syntaxTests/functionTypes/external_function_type_public_variable.sol b/test/libsolidity/syntaxTests/functionTypes/external_function_type_public_variable.sol
new file mode 100644
index 00000000..0a6d1e53
--- /dev/null
+++ b/test/libsolidity/syntaxTests/functionTypes/external_function_type_public_variable.sol
@@ -0,0 +1,11 @@
+contract C {
+ function (uint) external public x;
+
+ function g(uint) public {
+ x = this.g;
+ }
+ function f() public view returns (function(uint) external) {
+ return this.x();
+ }
+}
+// ----
diff --git a/test/libsolidity/syntaxTests/functionTypes/external_function_type_returning_internal.sol b/test/libsolidity/syntaxTests/functionTypes/external_function_type_returning_internal.sol
new file mode 100644
index 00000000..8b14d3dc
--- /dev/null
+++ b/test/libsolidity/syntaxTests/functionTypes/external_function_type_returning_internal.sol
@@ -0,0 +1,5 @@
+contract C {
+ function() external returns (function () internal) x;
+}
+// ----
+// TypeError: (46-67): Internal type cannot be used for external function type.
diff --git a/test/libsolidity/syntaxTests/functionTypes/external_function_type_taking_internal.sol b/test/libsolidity/syntaxTests/functionTypes/external_function_type_taking_internal.sol
new file mode 100644
index 00000000..3e264c8c
--- /dev/null
+++ b/test/libsolidity/syntaxTests/functionTypes/external_function_type_taking_internal.sol
@@ -0,0 +1,5 @@
+contract C {
+ function(function () internal) external x;
+}
+// ----
+// TypeError: (26-47): Internal type cannot be used for external function type.
diff --git a/test/libsolidity/syntaxTests/functionTypes/external_function_type_to_address.sol b/test/libsolidity/syntaxTests/functionTypes/external_function_type_to_address.sol
new file mode 100644
index 00000000..b86425db
--- /dev/null
+++ b/test/libsolidity/syntaxTests/functionTypes/external_function_type_to_address.sol
@@ -0,0 +1,5 @@
+contract C {
+ function f() public view returns (address) {
+ return address(this.f);
+ }
+}
diff --git a/test/libsolidity/syntaxTests/functionTypes/external_function_type_to_uint.sol b/test/libsolidity/syntaxTests/functionTypes/external_function_type_to_uint.sol
new file mode 100644
index 00000000..f4287223
--- /dev/null
+++ b/test/libsolidity/syntaxTests/functionTypes/external_function_type_to_uint.sol
@@ -0,0 +1,7 @@
+contract C {
+ function f() public returns (uint) {
+ return uint(this.f);
+ }
+}
+// ----
+// TypeError: (69-81): Explicit type conversion not allowed from "function () external returns (uint256)" to "uint256".
diff --git a/test/libsolidity/syntaxTests/functionTypes/function_type.sol b/test/libsolidity/syntaxTests/functionTypes/function_type.sol
new file mode 100644
index 00000000..23d50136
--- /dev/null
+++ b/test/libsolidity/syntaxTests/functionTypes/function_type.sol
@@ -0,0 +1,6 @@
+contract C {
+ function f() pure public {
+ function(uint) returns (uint) x;
+ x;
+ }
+}
diff --git a/test/libsolidity/syntaxTests/functionTypes/function_type_arrays.sol b/test/libsolidity/syntaxTests/functionTypes/function_type_arrays.sol
new file mode 100644
index 00000000..ec23d637
--- /dev/null
+++ b/test/libsolidity/syntaxTests/functionTypes/function_type_arrays.sol
@@ -0,0 +1,11 @@
+contract C {
+ function(uint) external returns (uint)[] public x;
+ function(uint) internal returns (uint)[10] y;
+ function f() view public {
+ function(uint) returns (uint)[10] memory a;
+ function(uint) returns (uint)[10] storage b = y;
+ function(uint) external returns (uint)[] memory c;
+ c = new function(uint) external returns (uint)[](200);
+ a; b;
+ }
+}
diff --git a/test/libsolidity/syntaxTests/functionTypes/function_type_constructor.sol b/test/libsolidity/syntaxTests/functionTypes/function_type_constructor.sol
new file mode 100644
index 00000000..95ebc179
--- /dev/null
+++ b/test/libsolidity/syntaxTests/functionTypes/function_type_constructor.sol
@@ -0,0 +1,7 @@
+contract C {
+ // Fool parser into parsing a constructor as a function type.
+ constructor() x;
+}
+// ----
+// Warning: (83-99): Modifiers of functions without implementation are ignored.
+// DeclarationError: (97-98): Undeclared identifier.
diff --git a/test/libsolidity/syntaxTests/functionTypes/function_type_constructor_local.sol b/test/libsolidity/syntaxTests/functionTypes/function_type_constructor_local.sol
new file mode 100644
index 00000000..b7763d28
--- /dev/null
+++ b/test/libsolidity/syntaxTests/functionTypes/function_type_constructor_local.sol
@@ -0,0 +1,8 @@
+contract C {
+ // Fool parser into parsing a constructor as a function type.
+ function f() {
+ constructor() x;
+ }
+}
+// ----
+// ParserError: (118-118): Expected token Semicolon got 'Identifier'
diff --git a/test/libsolidity/syntaxTests/functionTypes/function_type_internal_public_variable.sol b/test/libsolidity/syntaxTests/functionTypes/function_type_internal_public_variable.sol
new file mode 100644
index 00000000..4eb53227
--- /dev/null
+++ b/test/libsolidity/syntaxTests/functionTypes/function_type_internal_public_variable.sol
@@ -0,0 +1,5 @@
+contract C {
+ function(bytes memory) internal public a;
+}
+// ----
+// TypeError: (17-57): Internal or recursive type is not allowed for public state variables.
diff --git a/test/libsolidity/syntaxTests/functionTypes/function_type_parameter.sol b/test/libsolidity/syntaxTests/functionTypes/function_type_parameter.sol
new file mode 100644
index 00000000..da66ec8a
--- /dev/null
+++ b/test/libsolidity/syntaxTests/functionTypes/function_type_parameter.sol
@@ -0,0 +1,7 @@
+contract C {
+ uint x;
+ function f(function(uint) external returns (uint) g) public returns (function(uint) external returns (uint)) {
+ x = 2;
+ return g;
+ }
+}
diff --git a/test/libsolidity/syntaxTests/functionTypes/function_type_returned.sol b/test/libsolidity/syntaxTests/functionTypes/function_type_returned.sol
new file mode 100644
index 00000000..9cd313c8
--- /dev/null
+++ b/test/libsolidity/syntaxTests/functionTypes/function_type_returned.sol
@@ -0,0 +1,5 @@
+contract C {
+ function f() public pure returns (function(uint) pure external returns (uint) g) {
+ return g;
+ }
+}
diff --git a/test/libsolidity/syntaxTests/functionTypes/function_type_variable_external_internal.sol b/test/libsolidity/syntaxTests/functionTypes/function_type_variable_external_internal.sol
new file mode 100644
index 00000000..f0240472
--- /dev/null
+++ b/test/libsolidity/syntaxTests/functionTypes/function_type_variable_external_internal.sol
@@ -0,0 +1,6 @@
+contract test {
+ function fa(bytes memory) public { }
+ function(bytes memory) external internal a = fa;
+}
+// ----
+// TypeError: (106-108): Type function (bytes memory) is not implicitly convertible to expected type function (bytes memory) external.
diff --git a/test/libsolidity/syntaxTests/functionTypes/function_types_internal_visibility_error.sol b/test/libsolidity/syntaxTests/functionTypes/function_types_internal_visibility_error.sol
new file mode 100644
index 00000000..36206d63
--- /dev/null
+++ b/test/libsolidity/syntaxTests/functionTypes/function_types_internal_visibility_error.sol
@@ -0,0 +1,7 @@
+contract C {
+ // This is an error, you should explicitly use
+ // `external public` to fix it - `internal public` does not exist.
+ function(bytes memory) public a;
+}
+// ----
+// TypeError: (139-170): Invalid visibility, can only be "external" or "internal".
diff --git a/test/libsolidity/syntaxTests/functionTypes/function_types_variable_visibility.sol b/test/libsolidity/syntaxTests/functionTypes/function_types_variable_visibility.sol
new file mode 100644
index 00000000..91c2420a
--- /dev/null
+++ b/test/libsolidity/syntaxTests/functionTypes/function_types_variable_visibility.sol
@@ -0,0 +1,9 @@
+contract C {
+ function(bytes memory) a1;
+ function(bytes memory) internal b1;
+ function(bytes memory) internal internal b2;
+ function(bytes memory) external c1;
+ function(bytes memory) external internal c2;
+ function(bytes memory) external public c3;
+}
+// ----
diff --git a/test/libsolidity/syntaxTests/functionTypes/internal_function_as_external_parameter.sol b/test/libsolidity/syntaxTests/functionTypes/internal_function_as_external_parameter.sol
new file mode 100644
index 00000000..fa92d559
--- /dev/null
+++ b/test/libsolidity/syntaxTests/functionTypes/internal_function_as_external_parameter.sol
@@ -0,0 +1,8 @@
+// It should not be possible to give internal functions
+// as parameters to external functions.
+contract C {
+ function f(function(uint) internal returns (uint) x) public {
+ }
+}
+// ----
+// TypeError: (124-164): Internal or recursive type is not allowed for public or external functions.
diff --git a/test/libsolidity/syntaxTests/functionTypes/internal_function_as_external_parameter_in_library_external.sol b/test/libsolidity/syntaxTests/functionTypes/internal_function_as_external_parameter_in_library_external.sol
new file mode 100644
index 00000000..b37fb285
--- /dev/null
+++ b/test/libsolidity/syntaxTests/functionTypes/internal_function_as_external_parameter_in_library_external.sol
@@ -0,0 +1,6 @@
+library L {
+ function f(function(uint) internal returns (uint) x) public {
+ }
+}
+// ----
+// TypeError: (27-67): Internal or recursive type is not allowed for public or external functions.
diff --git a/test/libsolidity/syntaxTests/functionTypes/internal_function_as_external_parameter_in_library_internal.sol b/test/libsolidity/syntaxTests/functionTypes/internal_function_as_external_parameter_in_library_internal.sol
new file mode 100644
index 00000000..7ffa447e
--- /dev/null
+++ b/test/libsolidity/syntaxTests/functionTypes/internal_function_as_external_parameter_in_library_internal.sol
@@ -0,0 +1,4 @@
+library L {
+ function f(function(uint) internal returns (uint) /*x*/) pure internal {
+ }
+}
diff --git a/test/libsolidity/syntaxTests/functionTypes/internal_function_returned_from_public_function.sol b/test/libsolidity/syntaxTests/functionTypes/internal_function_returned_from_public_function.sol
new file mode 100644
index 00000000..41fcd0a4
--- /dev/null
+++ b/test/libsolidity/syntaxTests/functionTypes/internal_function_returned_from_public_function.sol
@@ -0,0 +1,7 @@
+// It should not be possible to return internal functions from external functions.
+contract C {
+ function f() public returns (function(uint) internal returns (uint) x) {
+ }
+}
+// ----
+// TypeError: (129-169): Internal or recursive type is not allowed for public or external functions.
diff --git a/test/libsolidity/syntaxTests/functionTypes/internal_function_type_to_address.sol b/test/libsolidity/syntaxTests/functionTypes/internal_function_type_to_address.sol
new file mode 100644
index 00000000..b75a0d43
--- /dev/null
+++ b/test/libsolidity/syntaxTests/functionTypes/internal_function_type_to_address.sol
@@ -0,0 +1,7 @@
+contract C {
+ function f() public returns (address) {
+ return address(f);
+ }
+}
+// ----
+// TypeError: (72-82): Explicit type conversion not allowed from "function () returns (address)" to "address".
diff --git a/test/libsolidity/syntaxTests/functionTypes/payable_internal_function_type.sol b/test/libsolidity/syntaxTests/functionTypes/payable_internal_function_type.sol
new file mode 100644
index 00000000..a7cb9d92
--- /dev/null
+++ b/test/libsolidity/syntaxTests/functionTypes/payable_internal_function_type.sol
@@ -0,0 +1,5 @@
+contract C {
+ function (uint) internal payable returns (uint) x;
+}
+// ----
+// TypeError: (17-66): Only external function types can be payable.
diff --git a/test/libsolidity/syntaxTests/functionTypes/payable_internal_function_type_is_not_fatal.sol b/test/libsolidity/syntaxTests/functionTypes/payable_internal_function_type_is_not_fatal.sol
new file mode 100644
index 00000000..5c6dc056
--- /dev/null
+++ b/test/libsolidity/syntaxTests/functionTypes/payable_internal_function_type_is_not_fatal.sol
@@ -0,0 +1,9 @@
+contract C {
+ function (uint) internal payable returns (uint) x;
+
+ function g() public {
+ x = g;
+ }
+}
+// ----
+// TypeError: (17-66): Only external function types can be payable.
diff --git a/test/libsolidity/syntaxTests/functionTypes/private_function_type.sol b/test/libsolidity/syntaxTests/functionTypes/private_function_type.sol
new file mode 100644
index 00000000..9d4f0a09
--- /dev/null
+++ b/test/libsolidity/syntaxTests/functionTypes/private_function_type.sol
@@ -0,0 +1,7 @@
+contract C {
+ function f() public {
+ function(uint) private returns (uint) x;
+ }
+}
+// ----
+// TypeError: (47-86): Invalid visibility, can only be "external" or "internal".
diff --git a/test/libsolidity/syntaxTests/functionTypes/public_function_type.sol b/test/libsolidity/syntaxTests/functionTypes/public_function_type.sol
new file mode 100644
index 00000000..756766d3
--- /dev/null
+++ b/test/libsolidity/syntaxTests/functionTypes/public_function_type.sol
@@ -0,0 +1,7 @@
+contract C {
+ function f() public {
+ function(uint) public returns (uint) x;
+ }
+}
+// ----
+// TypeError: (47-85): Invalid visibility, can only be "external" or "internal".
diff --git a/test/libsolidity/syntaxTests/functionTypes/valid_function_type_variables.sol b/test/libsolidity/syntaxTests/functionTypes/valid_function_type_variables.sol
new file mode 100644
index 00000000..10c6767c
--- /dev/null
+++ b/test/libsolidity/syntaxTests/functionTypes/valid_function_type_variables.sol
@@ -0,0 +1,23 @@
+contract test {
+ function fa(uint) {}
+ function fb(uint) internal {}
+ function fc(uint) internal {}
+ function fd(uint) external {}
+ function fe(uint) external {}
+ function ff(uint) internal {}
+ function fg(uint) internal pure {}
+ function fh(uint) pure internal {}
+
+ function(uint) a = fa;
+ function(uint) internal b = fb; // (explicit internal applies to the function type)
+ function(uint) internal internal c = fc;
+ function(uint) external d = this.fd;
+ function(uint) external internal e = this.fe;
+ function(uint) internal public f = ff;
+ function(uint) internal pure public g = fg;
+ function(uint) pure internal public h = fh;
+}
+// ----
+// TypeError: (545-582): Internal or recursive type is not allowed for public state variables.
+// TypeError: (588-630): Internal or recursive type is not allowed for public state variables.
+// TypeError: (636-678): Internal or recursive type is not allowed for public state variables.
diff --git a/test/libsolidity/syntaxTests/functionTypes/warn_function_type_parameters_with_names.sol b/test/libsolidity/syntaxTests/functionTypes/warn_function_type_parameters_with_names.sol
new file mode 100644
index 00000000..072c7eb7
--- /dev/null
+++ b/test/libsolidity/syntaxTests/functionTypes/warn_function_type_parameters_with_names.sol
@@ -0,0 +1,5 @@
+contract C {
+ function(uint a) f;
+}
+// ----
+// Warning: (26-32): Naming function type parameters is deprecated.
diff --git a/test/libsolidity/syntaxTests/functionTypes/warn_function_type_return_parameters_with_names.sol b/test/libsolidity/syntaxTests/functionTypes/warn_function_type_return_parameters_with_names.sol
new file mode 100644
index 00000000..67a74e54
--- /dev/null
+++ b/test/libsolidity/syntaxTests/functionTypes/warn_function_type_return_parameters_with_names.sol
@@ -0,0 +1,5 @@
+contract C {
+ function(uint) returns (bool ret) f;
+}
+// ----
+// Warning: (41-49): Naming function type return parameters is deprecated.
diff --git a/test/libsolidity/syntaxTests/modifiers/base_constructor_double_invocation.sol b/test/libsolidity/syntaxTests/modifiers/base_constructor_double_invocation.sol
new file mode 100644
index 00000000..bdbab5d8
--- /dev/null
+++ b/test/libsolidity/syntaxTests/modifiers/base_constructor_double_invocation.sol
@@ -0,0 +1,7 @@
+contract C { constructor(uint a) public {} }
+contract B is C {
+ constructor() C(2) C(2) public {}
+}
+// ----
+// Warning: (81-85): Base constructor arguments given twice.
+// DeclarationError: (86-90): Base constructor already provided.
diff --git a/test/libsolidity/syntaxTests/modifiers/constructor_call_invalid_arg_count.sol b/test/libsolidity/syntaxTests/modifiers/constructor_call_invalid_arg_count.sol
new file mode 100644
index 00000000..4a2b5c4a
--- /dev/null
+++ b/test/libsolidity/syntaxTests/modifiers/constructor_call_invalid_arg_count.sol
@@ -0,0 +1,9 @@
+// This caused a segfault in an earlier version
+contract C {
+ constructor() public {}
+}
+contract D is C {
+ constructor() C(5) public {}
+}
+// ----
+// TypeError: (127-131): Wrong argument count for modifier invocation: 1 arguments given but expected 0.
diff --git a/test/libsolidity/syntaxTests/modifiers/function_modifier_double_invocation.sol b/test/libsolidity/syntaxTests/modifiers/function_modifier_double_invocation.sol
new file mode 100644
index 00000000..75624192
--- /dev/null
+++ b/test/libsolidity/syntaxTests/modifiers/function_modifier_double_invocation.sol
@@ -0,0 +1,4 @@
+contract B {
+ function f(uint x) mod(x) mod(2) public pure { }
+ modifier mod(uint a) { if (a > 0) _; }
+}
diff --git a/test/libsolidity/syntaxTests/modifiers/function_modifier_invocation.sol b/test/libsolidity/syntaxTests/modifiers/function_modifier_invocation.sol
new file mode 100644
index 00000000..e15fcf49
--- /dev/null
+++ b/test/libsolidity/syntaxTests/modifiers/function_modifier_invocation.sol
@@ -0,0 +1,5 @@
+contract B {
+ function f() mod1(2, true) mod2("0123456") pure public { }
+ modifier mod1(uint a, bool b) { if (b) _; }
+ modifier mod2(bytes7 a) { while (a == "1234567") _; }
+}
diff --git a/test/libsolidity/syntaxTests/modifiers/function_modifier_invocation_local_variables.sol b/test/libsolidity/syntaxTests/modifiers/function_modifier_invocation_local_variables.sol
new file mode 100644
index 00000000..00031924
--- /dev/null
+++ b/test/libsolidity/syntaxTests/modifiers/function_modifier_invocation_local_variables.sol
@@ -0,0 +1,4 @@
+contract B {
+ function f() mod(x) pure public { uint x = 7; }
+ modifier mod(uint a) { if (a > 0) _; }
+}
diff --git a/test/libsolidity/syntaxTests/modifiers/function_modifier_invocation_local_variables050.sol b/test/libsolidity/syntaxTests/modifiers/function_modifier_invocation_local_variables050.sol
new file mode 100644
index 00000000..c19ccf2c
--- /dev/null
+++ b/test/libsolidity/syntaxTests/modifiers/function_modifier_invocation_local_variables050.sol
@@ -0,0 +1,7 @@
+pragma experimental "v0.5.0";
+contract B {
+ function f() mod(x) pure public { uint x = 7; }
+ modifier mod(uint a) { if (a > 0) _; }
+}
+// ----
+// DeclarationError: (64-65): Undeclared identifier.
diff --git a/test/libsolidity/syntaxTests/modifiers/function_modifier_invocation_parameters.sol b/test/libsolidity/syntaxTests/modifiers/function_modifier_invocation_parameters.sol
new file mode 100644
index 00000000..de2a8f48
--- /dev/null
+++ b/test/libsolidity/syntaxTests/modifiers/function_modifier_invocation_parameters.sol
@@ -0,0 +1,5 @@
+contract B {
+ function f(uint8 a) mod1(a, true) mod2(r) pure public returns (bytes7 r) { }
+ modifier mod1(uint a, bool b) { if (b) _; }
+ modifier mod2(bytes7 a) { while (a == "1234567") _; }
+}
diff --git a/test/libsolidity/syntaxTests/modifiers/function_overrides_modifier.sol b/test/libsolidity/syntaxTests/modifiers/function_overrides_modifier.sol
new file mode 100644
index 00000000..a64c2790
--- /dev/null
+++ b/test/libsolidity/syntaxTests/modifiers/function_overrides_modifier.sol
@@ -0,0 +1,5 @@
+contract A { function mod(uint a) public { } }
+contract B is A { modifier mod(uint a) { _; } }
+// ----
+// DeclarationError: (65-92): Identifier already declared.
+// TypeError: (65-92): Override changes function to modifier.
diff --git a/test/libsolidity/syntaxTests/modifiers/illegal_modifier_override.sol b/test/libsolidity/syntaxTests/modifiers/illegal_modifier_override.sol
new file mode 100644
index 00000000..958be686
--- /dev/null
+++ b/test/libsolidity/syntaxTests/modifiers/illegal_modifier_override.sol
@@ -0,0 +1,4 @@
+contract A { modifier mod(uint a) { _; } }
+contract B is A { modifier mod(uint8 a) { _; } }
+// ----
+// TypeError: (61-89): Override changes modifier signature.
diff --git a/test/libsolidity/syntaxTests/modifiers/invalid_function_modifier_type.sol b/test/libsolidity/syntaxTests/modifiers/invalid_function_modifier_type.sol
new file mode 100644
index 00000000..c1e3108b
--- /dev/null
+++ b/test/libsolidity/syntaxTests/modifiers/invalid_function_modifier_type.sol
@@ -0,0 +1,6 @@
+contract B {
+ function f() mod1(true) public { }
+ modifier mod1(uint a) { if (a > 0) _; }
+}
+// ----
+// TypeError: (35-39): Invalid type for argument in modifier invocation. Invalid implicit conversion from bool to uint256 requested.
diff --git a/test/libsolidity/syntaxTests/modifiers/legal_modifier_override.sol b/test/libsolidity/syntaxTests/modifiers/legal_modifier_override.sol
new file mode 100644
index 00000000..51c3fd80
--- /dev/null
+++ b/test/libsolidity/syntaxTests/modifiers/legal_modifier_override.sol
@@ -0,0 +1,2 @@
+contract A { modifier mod(uint a) { _; } }
+contract B is A { modifier mod(uint a) { _; } }
diff --git a/test/libsolidity/syntaxTests/modifiers/modifier_overrides_function.sol b/test/libsolidity/syntaxTests/modifiers/modifier_overrides_function.sol
new file mode 100644
index 00000000..a43646c3
--- /dev/null
+++ b/test/libsolidity/syntaxTests/modifiers/modifier_overrides_function.sol
@@ -0,0 +1,5 @@
+contract A { modifier mod(uint a) { _; } }
+contract B is A { function mod(uint a) public { } }
+// ----
+// DeclarationError: (61-92): Identifier already declared.
+// TypeError: (13-40): Override changes modifier to function.
diff --git a/test/libsolidity/syntaxTests/modifiers/modifier_returns_value.sol b/test/libsolidity/syntaxTests/modifiers/modifier_returns_value.sol
new file mode 100644
index 00000000..d22e836c
--- /dev/null
+++ b/test/libsolidity/syntaxTests/modifiers/modifier_returns_value.sol
@@ -0,0 +1,6 @@
+contract A {
+ function f(uint a) mod(2) public returns (uint r) { }
+ modifier mod(uint a) { _; return 7; }
+}
+// ----
+// TypeError: (101-109): Return arguments not allowed.
diff --git a/test/libsolidity/syntaxTests/modifiers/modifier_without_underscore.sol b/test/libsolidity/syntaxTests/modifiers/modifier_without_underscore.sol
new file mode 100644
index 00000000..6198d3c5
--- /dev/null
+++ b/test/libsolidity/syntaxTests/modifiers/modifier_without_underscore.sol
@@ -0,0 +1,5 @@
+contract test {
+ modifier m() {}
+}
+// ----
+// SyntaxError: (33-35): Modifier body does not contain '_'.
diff --git a/test/libsolidity/syntaxTests/modifiers/modifiers_on_abstract_functions_050.sol b/test/libsolidity/syntaxTests/modifiers/modifiers_on_abstract_functions_050.sol
new file mode 100644
index 00000000..af1babbc
--- /dev/null
+++ b/test/libsolidity/syntaxTests/modifiers/modifiers_on_abstract_functions_050.sol
@@ -0,0 +1,10 @@
+pragma experimental "v0.5.0";
+contract C
+{
+ modifier only_owner() { _; }
+ function foo() only_owner public;
+ function bar() public only_owner;
+}
+// ----
+// SyntaxError: (80-113): Functions without implementation cannot have modifiers.
+// SyntaxError: (118-151): Functions without implementation cannot have modifiers.
diff --git a/test/libsolidity/syntaxTests/modifiers/modifiers_on_abstract_functions_no_parser_error.sol b/test/libsolidity/syntaxTests/modifiers/modifiers_on_abstract_functions_no_parser_error.sol
new file mode 100644
index 00000000..e18c5cf9
--- /dev/null
+++ b/test/libsolidity/syntaxTests/modifiers/modifiers_on_abstract_functions_no_parser_error.sol
@@ -0,0 +1,13 @@
+// Previous versions of Solidity turned this
+// into a parser error (they wrongly recognized
+// these functions as state variables of
+// function type).
+contract C
+{
+ modifier only_owner() { _; }
+ function foo() only_owner public;
+ function bar() public only_owner;
+}
+// ----
+// Warning: (203-236): Modifiers of functions without implementation are ignored.
+// Warning: (241-274): Modifiers of functions without implementation are ignored.