From 0f8ad1d68f60270fb22057e787ff689318c31fa9 Mon Sep 17 00:00:00 2001 From: Federico Bond Date: Thu, 15 Jun 2017 12:36:14 -0300 Subject: [PATCH] Fix segmentation fault with constant function parameters --- Changelog.md | 1 + libsolidity/analysis/TypeChecker.cpp | 9 ++++++++- .../SolidityNameAndTypeResolution.cpp | 20 +++++++++++++++++++ 3 files changed, 29 insertions(+), 1 deletion(-) diff --git a/Changelog.md b/Changelog.md index 0fb2fe5ce..4bf85d5f7 100644 --- a/Changelog.md +++ b/Changelog.md @@ -16,6 +16,7 @@ Bugfixes: * Fixed crash concerning non-callable types. * Unused variable warnings no longer issued for variables used inside inline assembly. * Inline Assembly: Enforce function arguments when parsing functional instructions. + * Fixed segfault with constant function parameters ### 0.4.11 (2017-05-03) diff --git a/libsolidity/analysis/TypeChecker.cpp b/libsolidity/analysis/TypeChecker.cpp index 2a8d1ff6a..4194e1c25 100644 --- a/libsolidity/analysis/TypeChecker.cpp +++ b/libsolidity/analysis/TypeChecker.cpp @@ -463,6 +463,8 @@ bool TypeChecker::visit(FunctionDefinition const& _function) m_errorReporter.typeError(var->location(), "Type is required to live outside storage."); if (_function.visibility() >= FunctionDefinition::Visibility::Public && !(type(*var)->interfaceType(isLibraryFunction))) m_errorReporter.fatalTypeError(var->location(), "Internal type is not allowed for public or external functions."); + + var->accept(*this); } for (ASTPointer const& modifier: _function.modifiers()) visitManually( @@ -487,7 +489,12 @@ bool TypeChecker::visit(FunctionDefinition const& _function) bool TypeChecker::visit(VariableDeclaration const& _variable) { - if (m_scope->contractKind() == ContractDefinition::ContractKind::Interface) + // Forbid any variable declarations inside interfaces unless they are part of + // a function's input/output parameters. + if ( + m_scope->contractKind() == ContractDefinition::ContractKind::Interface + && !_variable.isCallableParameter() + ) m_errorReporter.typeError(_variable.location(), "Variables cannot be declared in interfaces."); // Variables can be declared without type (with "var"), in which case the first assignment diff --git a/test/libsolidity/SolidityNameAndTypeResolution.cpp b/test/libsolidity/SolidityNameAndTypeResolution.cpp index 0b3cb481b..c4b1250f9 100644 --- a/test/libsolidity/SolidityNameAndTypeResolution.cpp +++ b/test/libsolidity/SolidityNameAndTypeResolution.cpp @@ -1597,6 +1597,16 @@ BOOST_AUTO_TEST_CASE(empty_name_input_parameter) CHECK_SUCCESS(text); } +BOOST_AUTO_TEST_CASE(constant_input_parameter) +{ + char const* text = R"( + contract test { + function f(uint[] constant a) { } + } + )"; + CHECK_ERROR_ALLOW_MULTI(text, TypeError, "Illegal use of \"constant\" specifier."); +} + BOOST_AUTO_TEST_CASE(empty_name_return_parameter) { char const* text = R"( @@ -5582,6 +5592,16 @@ BOOST_AUTO_TEST_CASE(interface_variables) CHECK_ERROR(text, TypeError, "Variables cannot be declared in interfaces"); } +BOOST_AUTO_TEST_CASE(interface_function_parameters) +{ + char const* text = R"( + interface I { + function f(uint a) returns(bool); + } + )"; + success(text); +} + BOOST_AUTO_TEST_CASE(interface_enums) { char const* text = R"(