aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Changelog.md4
-rw-r--r--libsolidity/analysis/TypeChecker.cpp17
-rw-r--r--test/libsolidity/SolidityNameAndTypeResolution.cpp22
3 files changed, 14 insertions, 29 deletions
diff --git a/Changelog.md b/Changelog.md
index 9087742d..3484b369 100644
--- a/Changelog.md
+++ b/Changelog.md
@@ -7,9 +7,9 @@ Bugfixes:
* Code Generator: ``.delegatecall()`` should always return execution outcome.
* Code Generator: Provide "new account gas" for low-level ``callcode`` and ``delegatecall``.
* Type Checker: Constructors must be implemented if declared.
- * Type Checker: Do not mark overloaded functions as shadowing other functions.
* Type Checker: Disallow the ``.gas()`` modifier on ``ecrecover``, ``sha256`` and ``ripemd160``.
- * Type Checker: Raise error when using unimplemented internal library functions.
+ * Type Checker: Do not mark overloaded functions as shadowing other functions.
+ * Type Checker: Internal library functions must be implemented if declared.
### 0.4.14 (2017-07-31)
diff --git a/libsolidity/analysis/TypeChecker.cpp b/libsolidity/analysis/TypeChecker.cpp
index fbdac1c7..6852c13d 100644
--- a/libsolidity/analysis/TypeChecker.cpp
+++ b/libsolidity/analysis/TypeChecker.cpp
@@ -518,6 +518,8 @@ bool TypeChecker::visit(FunctionDefinition const& _function)
_function.body().accept(*this);
else if (_function.isConstructor())
m_errorReporter.typeError(_function.location(), "Constructor must be implemented if declared.");
+ else if (isLibraryFunction && _function.visibility() <= FunctionDefinition::Visibility::Internal)
+ m_errorReporter.typeError(_function.location(), "Internal library function must be implemented if declared.");
return false;
}
@@ -1403,21 +1405,6 @@ bool TypeChecker::visit(FunctionCall const& _functionCall)
else
_functionCall.annotation().type = make_shared<TupleType>(functionType->returnParameterTypes());
- // Internal library functions must be implemented, because of inlining rules.
- if (
- functionType->kind() == FunctionType::Kind::Internal &&
- functionType->hasDeclaration() &&
- dynamic_cast<FunctionDefinition const*>(&functionType->declaration())
- )
- {
- FunctionDefinition const* function = dynamic_cast<FunctionDefinition const*>(&functionType->declaration());
- bool isLibraryFunction =
- dynamic_cast<ContractDefinition const*>(function->scope()) &&
- dynamic_cast<ContractDefinition const*>(function->scope())->isLibrary();
- if (!function->isImplemented() && isLibraryFunction)
- m_errorReporter.typeError(_functionCall.location(), "Inlined library function is lacking implementation.");
- }
-
TypePointers parameterTypes = functionType->parameterTypes();
if (!functionType->takesArbitraryParameters() && parameterTypes.size() != arguments.size())
{
diff --git a/test/libsolidity/SolidityNameAndTypeResolution.cpp b/test/libsolidity/SolidityNameAndTypeResolution.cpp
index ef83cc61..2fbc6ac8 100644
--- a/test/libsolidity/SolidityNameAndTypeResolution.cpp
+++ b/test/libsolidity/SolidityNameAndTypeResolution.cpp
@@ -6536,28 +6536,26 @@ BOOST_AUTO_TEST_CASE(constructor_without_implementation)
CHECK_ERROR(text, TypeError, "Constructor must be implemented if declared.");
}
-BOOST_AUTO_TEST_CASE(calling_unimplemented_internal_functions)
+BOOST_AUTO_TEST_CASE(library_function_without_implementation)
{
char const* text = R"(
- contract C {
- function f() internal;
- function g() { f(); }
+ library L {
+ function f();
}
)";
CHECK_SUCCESS_NO_WARNINGS(text);
-}
-
-BOOST_AUTO_TEST_CASE(calling_unimplemented_internal_library_functions)
-{
- char const* text = R"(
+ text = R"(
library L {
function f() internal;
}
- contract C {
- function g() { L.f(); }
+ )";
+ CHECK_ERROR(text, TypeError, "Internal library function must be implemented if declared.");
+ text = R"(
+ library L {
+ function f() private;
}
)";
- CHECK_ERROR(text, TypeError, "Inlined library function is lacking implementation.");
+ CHECK_ERROR(text, TypeError, "Internal library function must be implemented if declared.");
}
BOOST_AUTO_TEST_SUITE_END()