Adding Stack Height Checker and modifying the number of POP instructions to appropriately provide the pointer address

This commit is contained in:
nishant-sachdeva 2022-01-19 21:00:40 +05:30
parent c3c5937bd7
commit 27d0480e96
4 changed files with 38 additions and 2 deletions

View File

@ -17,6 +17,7 @@ Bugfixes:
* IR Generator: Fix IR syntax error when copying storage arrays of structs containing functions.
* Natspec: Fix ICE when overriding a struct getter with a Natspec-documented return value and the name in the struct is different.
* TypeChecker: Fix ICE when a constant variable declaration forward references a struct.
* Code Generator: Fix ICE when accessing the members of external functions occupying more than two stack slots.
Solc-Js:

View File

@ -1760,6 +1760,9 @@ bool ExpressionCompiler::visit(MemberAccess const& _memberAccess)
case Type::Category::Function:
if (member == "selector")
{
auto const& functionType = dynamic_cast<FunctionType const&>(*_memberAccess.expression().annotation().type);
if (functionType.kind() == FunctionType::Kind::External)
CompilerUtils(m_context).popStackSlots(functionType.sizeOnStack() - 2);
m_context << Instruction::SWAP1 << Instruction::POP;
/// need to store it as bytes4
utils().leftShiftNumberOnStack(224);
@ -1768,8 +1771,7 @@ bool ExpressionCompiler::visit(MemberAccess const& _memberAccess)
{
auto const& functionType = dynamic_cast<FunctionType const&>(*_memberAccess.expression().annotation().type);
solAssert(functionType.kind() == FunctionType::Kind::External, "");
// stack: <address> <function_id>
m_context << Instruction::POP;
CompilerUtils(m_context).popStackSlots(functionType.sizeOnStack() - 1);
}
else
solAssert(

View File

@ -0,0 +1,25 @@
contract C {
function g() external {}
function h() external payable {}
function test_function() external returns (bool){
assert (
this.g.address == this.g.address &&
this.g{gas: 42}.address == this.g.address &&
this.g{gas: 42}.selector == this.g.selector
);
assert (
this.h.address == this.h.address &&
this.h{gas: 42}.address == this.h.address &&
this.h{gas: 42}.selector == this.h.selector
);
assert (
this.h{gas: 42, value: 5}.address == this.h.address &&
this.h{gas: 42, value: 5}.selector == this.h.selector
);
return true;
}
}
// ====
// compileViaYul: also
// ----
// test_function() -> true

View File

@ -0,0 +1,8 @@
contract C {
function f (address) external returns (bool) {
this.f{gas: 42}.address;
}
}
// ----
// Warning 6321: (56-60): Unnamed return variable can remain unassigned. Add an explicit return with value to all non-reverting code paths or name the variable.
// Warning 2018: (17-102): Function state mutability can be restricted to view