@@ -2111,57 +2111,60 @@ void TypeChecker::typeCheckABIEncodeCallFunction(FunctionCall const& _functionCa
2111
2111
return ;
2112
2112
}
2113
2113
2114
- auto const functionPointerType = dynamic_cast <FunctionTypePointer>(type (*arguments.front ()));
2115
-
2116
- if (!functionPointerType)
2114
+ FunctionType const * externalFunctionType = nullptr ;
2115
+ if (auto const functionPointerType = dynamic_cast <FunctionTypePointer>(type (*arguments.front ())))
2116
+ {
2117
+ // this cannot be a library function, that is checked below
2118
+ externalFunctionType = functionPointerType->asExternallyCallableFunction (false );
2119
+ solAssert (externalFunctionType->kind () == functionPointerType->kind ());
2120
+ }
2121
+ else
2117
2122
{
2118
2123
m_errorReporter.typeError (
2119
2124
5511_error,
2120
2125
arguments.front ()->location (),
2121
2126
" Expected first argument to be a function pointer, not \" " +
2122
- type (*arguments.front ())->canonicalName () +
2127
+ type (*arguments.front ())->toString () +
2123
2128
" \" ."
2124
2129
);
2125
2130
return ;
2126
2131
}
2127
2132
2128
2133
if (
2129
- functionPointerType ->kind () != FunctionType::Kind::External &&
2130
- functionPointerType ->kind () != FunctionType::Kind::Declaration
2134
+ externalFunctionType ->kind () != FunctionType::Kind::External &&
2135
+ externalFunctionType ->kind () != FunctionType::Kind::Declaration
2131
2136
)
2132
2137
{
2133
2138
string msg = " Expected regular external function type, or external view on public function." ;
2134
- if (functionPointerType ->kind () == FunctionType::Kind::Internal)
2139
+ if (externalFunctionType ->kind () == FunctionType::Kind::Internal)
2135
2140
msg += " Provided internal function." ;
2136
- else if (functionPointerType ->kind () == FunctionType::Kind::DelegateCall)
2141
+ else if (externalFunctionType ->kind () == FunctionType::Kind::DelegateCall)
2137
2142
msg += " Cannot use library functions for abi.encodeCall." ;
2138
- else if (functionPointerType ->kind () == FunctionType::Kind::Creation)
2143
+ else if (externalFunctionType ->kind () == FunctionType::Kind::Creation)
2139
2144
msg += " Provided creation function." ;
2140
2145
else
2141
2146
msg += " Cannot use special function." ;
2142
2147
SecondarySourceLocation ssl{};
2143
2148
2144
- if (functionPointerType ->hasDeclaration ())
2149
+ if (externalFunctionType ->hasDeclaration ())
2145
2150
{
2146
- ssl.append (" Function is declared here:" , functionPointerType ->declaration ().location ());
2151
+ ssl.append (" Function is declared here:" , externalFunctionType ->declaration ().location ());
2147
2152
if (
2148
- functionPointerType ->declaration ().visibility () == Visibility::Public &&
2149
- functionPointerType ->declaration ().scope () == m_currentContract
2153
+ externalFunctionType ->declaration ().visibility () == Visibility::Public &&
2154
+ externalFunctionType ->declaration ().scope () == m_currentContract
2150
2155
)
2151
2156
msg += " Did you forget to prefix \" this.\" ?" ;
2152
2157
else if (util::contains (
2153
2158
m_currentContract->annotation ().linearizedBaseContracts ,
2154
- functionPointerType ->declaration ().scope ()
2155
- ) && functionPointerType ->declaration ().scope () != m_currentContract)
2159
+ externalFunctionType ->declaration ().scope ()
2160
+ ) && externalFunctionType ->declaration ().scope () != m_currentContract)
2156
2161
msg += " Functions from base contracts have to be external." ;
2157
2162
}
2158
2163
2159
2164
m_errorReporter.typeError (3509_error, arguments[0 ]->location (), ssl, msg);
2160
2165
return ;
2161
2166
}
2162
-
2163
- solAssert (!functionPointerType->takesArbitraryParameters (), " Function must have fixed parameters." );
2164
-
2167
+ solAssert (!externalFunctionType->takesArbitraryParameters (), " Function must have fixed parameters." );
2165
2168
// Tuples with only one component become that component
2166
2169
vector<ASTPointer<Expression const >> callArguments;
2167
2170
@@ -2174,14 +2177,14 @@ void TypeChecker::typeCheckABIEncodeCallFunction(FunctionCall const& _functionCa
2174
2177
else
2175
2178
callArguments.push_back (arguments[1 ]);
2176
2179
2177
- if (functionPointerType ->parameterTypes ().size () != callArguments.size ())
2180
+ if (externalFunctionType ->parameterTypes ().size () != callArguments.size ())
2178
2181
{
2179
2182
if (tupleType)
2180
2183
m_errorReporter.typeError (
2181
2184
7788_error,
2182
2185
_functionCall.location (),
2183
2186
" Expected " +
2184
- to_string (functionPointerType ->parameterTypes ().size ()) +
2187
+ to_string (externalFunctionType ->parameterTypes ().size ()) +
2185
2188
" instead of " +
2186
2189
to_string (callArguments.size ()) +
2187
2190
" components for the tuple parameter."
@@ -2191,18 +2194,18 @@ void TypeChecker::typeCheckABIEncodeCallFunction(FunctionCall const& _functionCa
2191
2194
7515_error,
2192
2195
_functionCall.location (),
2193
2196
" Expected a tuple with " +
2194
- to_string (functionPointerType ->parameterTypes ().size ()) +
2197
+ to_string (externalFunctionType ->parameterTypes ().size ()) +
2195
2198
" components instead of a single non-tuple parameter."
2196
2199
);
2197
2200
}
2198
2201
2199
2202
// Use min() to check as much as we can before failing fatally
2200
- size_t const numParameters = min (callArguments.size (), functionPointerType ->parameterTypes ().size ());
2203
+ size_t const numParameters = min (callArguments.size (), externalFunctionType ->parameterTypes ().size ());
2201
2204
2202
2205
for (size_t i = 0 ; i < numParameters; i++)
2203
2206
{
2204
2207
Type const & argType = *type (*callArguments[i]);
2205
- BoolResult result = argType.isImplicitlyConvertibleTo (*functionPointerType ->parameterTypes ()[i]);
2208
+ BoolResult result = argType.isImplicitlyConvertibleTo (*externalFunctionType ->parameterTypes ()[i]);
2206
2209
if (!result)
2207
2210
m_errorReporter.typeError (
2208
2211
5407_error,
@@ -2212,7 +2215,7 @@ void TypeChecker::typeCheckABIEncodeCallFunction(FunctionCall const& _functionCa
2212
2215
" from \" " +
2213
2216
argType.toString () +
2214
2217
" \" to \" " +
2215
- functionPointerType ->parameterTypes ()[i]->toString () +
2218
+ externalFunctionType ->parameterTypes ()[i]->toString () +
2216
2219
" \" " +
2217
2220
(result.message ().empty () ? " ." : " : " + result.message ())
2218
2221
);
0 commit comments