mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
abi.encodeCall for declarations.
This commit is contained in:
@@ -2122,16 +2122,35 @@ void TypeChecker::typeCheckABIEncodeCallFunction(FunctionCall const& _functionCa
|
||||
return;
|
||||
}
|
||||
|
||||
if (functionPointerType->kind() != FunctionType::Kind::External)
|
||||
if (
|
||||
functionPointerType->kind() != FunctionType::Kind::External &&
|
||||
functionPointerType->kind() != FunctionType::Kind::Declaration
|
||||
)
|
||||
{
|
||||
string msg = "Function must be \"public\" or \"external\".";
|
||||
string msg = "Expected regular external function type, or external view on public function.";
|
||||
if (functionPointerType->kind() == FunctionType::Kind::Internal)
|
||||
msg += " Provided internal function.";
|
||||
else if (functionPointerType->kind() == FunctionType::Kind::DelegateCall)
|
||||
msg += " Cannot use library functions for abi.encodeCall.";
|
||||
else if (functionPointerType->kind() == FunctionType::Kind::Creation)
|
||||
msg += " Provided creation function.";
|
||||
else
|
||||
msg += " Cannot use special function.";
|
||||
SecondarySourceLocation ssl{};
|
||||
|
||||
if (functionPointerType->hasDeclaration())
|
||||
{
|
||||
ssl.append("Function is declared here:", functionPointerType->declaration().location());
|
||||
if (functionPointerType->declaration().scope() == m_currentContract)
|
||||
if (
|
||||
functionPointerType->declaration().visibility() == Visibility::Public &&
|
||||
functionPointerType->declaration().scope() == m_currentContract
|
||||
)
|
||||
msg += " Did you forget to prefix \"this.\"?";
|
||||
else if (contains(
|
||||
m_currentContract->annotation().linearizedBaseContracts,
|
||||
functionPointerType->declaration().scope()
|
||||
) && functionPointerType->declaration().scope() != m_currentContract)
|
||||
msg += " Functions from base contracts have to be external.";
|
||||
}
|
||||
|
||||
m_errorReporter.typeError(3509_error, arguments[0]->location(), ssl, msg);
|
||||
|
||||
@@ -1255,7 +1255,6 @@ bool ExpressionCompiler::visit(FunctionCall const& _functionCall)
|
||||
|
||||
auto const functionPtr = dynamic_cast<FunctionTypePointer>(arguments[0]->annotation().type);
|
||||
solAssert(functionPtr);
|
||||
solAssert(functionPtr->sizeOnStack() == 2);
|
||||
|
||||
// Account for tuples with one component which become that component
|
||||
if (auto const tupleType = dynamic_cast<TupleType const*>(arguments[1]->annotation().type))
|
||||
@@ -1330,9 +1329,20 @@ bool ExpressionCompiler::visit(FunctionCall const& _functionCall)
|
||||
}
|
||||
else if (function.kind() == FunctionType::Kind::ABIEncodeCall)
|
||||
{
|
||||
// stack: <memory pointer> <functionPointer>
|
||||
// Extract selector from the stack
|
||||
m_context << Instruction::SWAP1 << Instruction::POP;
|
||||
auto const& funType = dynamic_cast<FunctionType const&>(*selectorType);
|
||||
if (funType.kind() == FunctionType::Kind::Declaration)
|
||||
{
|
||||
solAssert(funType.hasDeclaration());
|
||||
solAssert(selectorType->sizeOnStack() == 0);
|
||||
m_context << funType.externalIdentifier();
|
||||
}
|
||||
else
|
||||
{
|
||||
solAssert(selectorType->sizeOnStack() == 2);
|
||||
// stack: <memory pointer> <functionPointer>
|
||||
// Extract selector from the stack
|
||||
m_context << Instruction::SWAP1 << Instruction::POP;
|
||||
}
|
||||
// Conversion will be done below
|
||||
dataOnStack = TypeProvider::uint(32);
|
||||
}
|
||||
|
||||
@@ -1150,10 +1150,21 @@ void IRGeneratorForStatements::endVisit(FunctionCall const& _functionCall)
|
||||
}
|
||||
|
||||
if (functionType->kind() == FunctionType::Kind::ABIEncodeCall)
|
||||
selector = convert(
|
||||
IRVariable(*arguments[0]).part("functionSelector"),
|
||||
*TypeProvider::fixedBytes(4)
|
||||
).name();
|
||||
{
|
||||
auto const& selectorType = dynamic_cast<FunctionType const&>(type(*arguments.front()));
|
||||
if (selectorType.kind() == FunctionType::Kind::Declaration)
|
||||
{
|
||||
solAssert(selectorType.hasDeclaration());
|
||||
selector = formatNumber(selectorType.externalIdentifier() << (256 - 32));
|
||||
}
|
||||
else
|
||||
{
|
||||
selector = convert(
|
||||
IRVariable(*arguments[0]).part("functionSelector"),
|
||||
*TypeProvider::fixedBytes(4)
|
||||
).name();
|
||||
}
|
||||
}
|
||||
else if (functionType->kind() == FunctionType::Kind::ABIEncodeWithSignature)
|
||||
{
|
||||
// hash the signature
|
||||
|
||||
Reference in New Issue
Block a user