Merge pull request #2408 from federicobond/constant-parameters

Fix segmentation fault with constant function parameters
This commit is contained in:
chriseth 2017-06-22 18:46:15 +02:00 committed by GitHub
commit bffb8c404f
3 changed files with 29 additions and 1 deletions

View File

@ -16,6 +16,7 @@ Bugfixes:
* Fixed crash concerning non-callable types. * Fixed crash concerning non-callable types.
* Unused variable warnings no longer issued for variables used inside inline assembly. * Unused variable warnings no longer issued for variables used inside inline assembly.
* Inline Assembly: Enforce function arguments when parsing functional instructions. * Inline Assembly: Enforce function arguments when parsing functional instructions.
* Fixed segfault with constant function parameters
### 0.4.11 (2017-05-03) ### 0.4.11 (2017-05-03)

View File

@ -463,6 +463,8 @@ bool TypeChecker::visit(FunctionDefinition const& _function)
m_errorReporter.typeError(var->location(), "Type is required to live outside storage."); m_errorReporter.typeError(var->location(), "Type is required to live outside storage.");
if (_function.visibility() >= FunctionDefinition::Visibility::Public && !(type(*var)->interfaceType(isLibraryFunction))) 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."); m_errorReporter.fatalTypeError(var->location(), "Internal type is not allowed for public or external functions.");
var->accept(*this);
} }
for (ASTPointer<ModifierInvocation> const& modifier: _function.modifiers()) for (ASTPointer<ModifierInvocation> const& modifier: _function.modifiers())
visitManually( visitManually(
@ -487,7 +489,12 @@ bool TypeChecker::visit(FunctionDefinition const& _function)
bool TypeChecker::visit(VariableDeclaration const& _variable) 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."); 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 // Variables can be declared without type (with "var"), in which case the first assignment

View File

@ -1597,6 +1597,16 @@ BOOST_AUTO_TEST_CASE(empty_name_input_parameter)
CHECK_SUCCESS(text); 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) BOOST_AUTO_TEST_CASE(empty_name_return_parameter)
{ {
char const* text = R"( char const* text = R"(
@ -5582,6 +5592,16 @@ BOOST_AUTO_TEST_CASE(interface_variables)
CHECK_ERROR(text, TypeError, "Variables cannot be declared in interfaces"); 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) BOOST_AUTO_TEST_CASE(interface_enums)
{ {
char const* text = R"( char const* text = R"(