diff --git a/libsolidity/analysis/TypeChecker.cpp b/libsolidity/analysis/TypeChecker.cpp index 25bd4a915197..89395aeb73ef 100644 --- a/libsolidity/analysis/TypeChecker.cpp +++ b/libsolidity/analysis/TypeChecker.cpp @@ -4052,6 +4052,20 @@ void TypeChecker::endVisit(UsingForDirective const& _usingFor) FunctionDefinition const& functionDefinition = dynamic_cast(*path->annotation().referencedDeclaration); + // Free functions with an explicit visibility were already flagged by the + // SyntaxChecker (error 4126). That error is not fatal, so resolution + // continues into this directive and calls `functionDefinition.type()`, + // which asserts non-external. Skip the entry to avoid the ICE; the user + // will still see the visibility error from the function definition. + if ( + !functionDefinition.libraryFunction() && + functionDefinition.visibility() == Visibility::External + ) + { + solAssert(m_errorReporter.hasErrors()); + continue; + } + FunctionType const* functionType = dynamic_cast( functionDefinition.libraryFunction() ? functionDefinition.typeViaContractName() : diff --git a/test/libsolidity/syntaxTests/using/external_free_function.sol b/test/libsolidity/syntaxTests/using/external_free_function.sol new file mode 100644 index 000000000000..3cb57697bb3f --- /dev/null +++ b/test/libsolidity/syntaxTests/using/external_free_function.sol @@ -0,0 +1,7 @@ +// Used to cause ICE in FunctionDefinition::type() when an external free +// function (already a syntax error) was bound via `using for`. +function f(int) external; +using {f} for int global; +// ---- +// SyntaxError 4126: (0-26): Free functions cannot have visibility. +// TypeError 4668: (0-26): Free functions must be implemented.