Fix abi.encodeCall checks

This commit is contained in:
Duc Thanh Nguyen 2022-07-17 01:00:12 -04:00
parent 800088e38b
commit 5072472917
6 changed files with 63 additions and 12 deletions

View File

@ -13,6 +13,7 @@ Compiler Features:
Bugfixes:
* Commandline Interface: Disallow the following options outside of the compiler mode: ``--via-ir``,``--metadata-literal``, ``--metadata-hash``, ``--model-checker-show-unproved``, ``--model-checker-div-mod-no-slacks``, ``--model-checker-engine``, ``--model-checker-invariants``, ``--model-checker-solvers``, ``--model-checker-timeout``, ``--model-checker-contracts``, ``--model-checker-targets``.
* Type Checker: Fix null dereference in `abi.encodeCall` type checking of free function.
### 0.8.15 (2022-06-15)

View File

@ -2195,14 +2195,28 @@ void TypeChecker::typeCheckABIEncodeCallFunction(FunctionCall const& _functionCa
)
{
string msg = "Expected regular external function type, or external view on public function.";
if (externalFunctionType->kind() == FunctionType::Kind::Internal)
msg += " Provided internal function.";
else if (externalFunctionType->kind() == FunctionType::Kind::DelegateCall)
msg += " Cannot use library functions for abi.encodeCall.";
else if (externalFunctionType->kind() == FunctionType::Kind::Creation)
msg += " Provided creation function.";
else
msg += " Cannot use special function.";
switch (externalFunctionType->kind())
{
case FunctionType::Kind::Internal:
msg += " Provided internal function.";
break;
case FunctionType::Kind::DelegateCall:
msg += " Cannot use library functions for abi.encodeCall.";
break;
case FunctionType::Kind::Creation:
msg += " Provided creation function.";
break;
case FunctionType::Kind::Event:
msg += " Cannot use events for abi.encodeCall.";
break;
case FunctionType::Kind::Error:
msg += " Cannot use errors for abi.encodeCall.";
break;
default:
msg += " Cannot use special function.";
}
SecondarySourceLocation ssl{};
if (externalFunctionType->hasDeclaration())
@ -2213,10 +2227,14 @@ void TypeChecker::typeCheckABIEncodeCallFunction(FunctionCall const& _functionCa
externalFunctionType->declaration().scope() == m_currentContract
)
msg += " Did you forget to prefix \"this.\"?";
else if (util::contains(
m_currentContract->annotation().linearizedBaseContracts,
externalFunctionType->declaration().scope()
) && externalFunctionType->declaration().scope() != m_currentContract)
else if (
m_currentContract &&
externalFunctionType->declaration().scope() != m_currentContract &&
util::contains(
m_currentContract->annotation().linearizedBaseContracts,
externalFunctionType->declaration().scope()
)
)
msg += " Functions from base contracts have to be external.";
}

View File

@ -0,0 +1,7 @@
error E(uint);
function f() {
abi.encodeCall(E, (1));
}
// ----
// TypeError 3509: (50-51): Expected regular external function type, or external view on public function. Cannot use errors for abi.encodeCall.

View File

@ -0,0 +1,9 @@
library L {
event E(uint);
}
function f() {
abi.encodeCall(L.E, (1));
}
// ----
// TypeError 3509: (68-71): Expected regular external function type, or external view on public function. Cannot use events for abi.encodeCall.

View File

@ -0,0 +1,7 @@
function g(uint) {}
function f() {
abi.encodeCall(g, (1));
}
// ----
// TypeError 3509: (55-56): Expected regular external function type, or external view on public function. Provided internal function.

View File

@ -0,0 +1,9 @@
library L {
function g() external {}
}
function f() {
abi.encodeCall(L.g, (1));
}
// ----
// TypeError 3509: (78-81): Expected regular external function type, or external view on public function. Cannot use library functions for abi.encodeCall.