diff --git a/libsolidity/AST.cpp b/libsolidity/AST.cpp index 7fe3a9825..a111a6f88 100644 --- a/libsolidity/AST.cpp +++ b/libsolidity/AST.cpp @@ -338,7 +338,14 @@ void FunctionDefinition::checkTypeRequirements() if (!var->getType()->canLiveOutsideStorage()) BOOST_THROW_EXCEPTION(var->createTypeError("Type is required to live outside storage.")); if (getVisibility() >= Visibility::Public && !(var->getType()->externalType())) - BOOST_THROW_EXCEPTION(var->createTypeError("Internal type is not allowed for function with external visibility")); + { + // todo delete when arrays as parameter type in internal functions will be implemented + ArrayType const* type = dynamic_cast(var->getType().get()); + if (getVisibility() == Visibility::Public && type) + BOOST_THROW_EXCEPTION(var->createTypeError("Array type is not allowed as parameter for internal functions.")); + else + BOOST_THROW_EXCEPTION(var->createTypeError("Internal type is not allowed for function with external visibility.")); + } } for (ASTPointer const& modifier: m_functionModifiers) modifier->checkTypeRequirements(isConstructor() ? @@ -379,6 +386,14 @@ void VariableDeclaration::checkTypeRequirements() m_value->expectType(*m_type); if (m_isStateVariable && !m_type->externalType() && getVisibility() >= Visibility::Public) BOOST_THROW_EXCEPTION(createTypeError("Internal type is not allowed for state variables.")); + + auto sharedToExternalTypes = FunctionType(*this).externalType(); // do not distroy the shared pointer. + auto externalFunctionTypes = dynamic_cast(sharedToExternalTypes.get()); + TypePointers retParamTypes = externalFunctionTypes->getReturnParameterTypes(); + TypePointers parameterTypes = externalFunctionTypes->getParameterTypes(); + for (auto parameter: parameterTypes + retParamTypes) + if (!parameter && !(parameter->externalType())) + BOOST_THROW_EXCEPTION(createTypeError("Internal type is not allowed for state variables.")); } else { // no type declared and no previous assignment, infer the type diff --git a/test/SolidityNameAndTypeResolution.cpp b/test/SolidityNameAndTypeResolution.cpp index ddcf36140..531f3bc13 100644 --- a/test/SolidityNameAndTypeResolution.cpp +++ b/test/SolidityNameAndTypeResolution.cpp @@ -460,7 +460,7 @@ BOOST_AUTO_TEST_CASE(function_external_types) uint a; } contract Test { - function boo(uint arg2, bool arg3, bytes8 arg4, bool[2] pairs, uint[] dynamic, C carg) external returns (uint ret) { + function boo(uint arg2, bool arg3, bytes8 arg4, bool[2] pairs, uint[] dynamic, C carg, address[] addresses) external returns (uint ret) { ret = 5; } })"; @@ -471,7 +471,7 @@ BOOST_AUTO_TEST_CASE(function_external_types) auto functions = contract->getDefinedFunctions(); if (functions.empty()) continue; - BOOST_CHECK_EQUAL("boo(uint256,bool,bytes8,bool[2],uint256[],address)", functions[0]->externalSignature()); + BOOST_CHECK_EQUAL("boo(uint256,bool,bytes8,bool[2],uint256[],address,address[])", functions[0]->externalSignature()); } } @@ -503,6 +503,16 @@ BOOST_AUTO_TEST_CASE(function_external_call_not_allowed_conversion) BOOST_CHECK_THROW(parseTextAndResolveNames(text), TypeError); } +// todo delete when implemented +BOOST_AUTO_TEST_CASE(arrays_in_internal_functions) +{ + char const* text = R"( + contract Test { + function foo(address[] addresses) {} + })"; + BOOST_CHECK_THROW(parseTextAndResolveNames(text), TypeError); +} + BOOST_AUTO_TEST_CASE(function_internal_allowed_conversion) { char const* text = R"(