Merge pull request #9724 from ethereum/superForYul

Implement ``super``.
This commit is contained in:
chriseth 2020-09-02 12:48:39 +02:00 committed by GitHub
commit 23514c1749
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 98 additions and 3 deletions

View File

@ -749,8 +749,18 @@ void IRGeneratorForStatements::endVisit(FunctionCall const& _functionCall)
if (identifier)
functionDef = &functionDef->resolveVirtual(m_context.mostDerivedContract());
else
{
ContractType const* type = dynamic_cast<ContractType const*>(memberAccess->expression().annotation().type);
if (type && type->isSuper())
{
ContractDefinition const* super = type->contractDefinition().superContract(m_context.mostDerivedContract());
solAssert(super, "Super contract not available.");
functionDef = &functionDef->resolveVirtual(m_context.mostDerivedContract(), super);
}
}
solAssert(functionDef->isImplemented(), "");
solAssert(functionDef && functionDef->isImplemented(), "");
}
solAssert(!functionType->takesArbitraryParameters(), "");
@ -1397,7 +1407,17 @@ void IRGeneratorForStatements::endVisit(MemberAccess const& _memberAccess)
ContractType const& type = dynamic_cast<ContractType const&>(*_memberAccess.expression().annotation().type);
if (type.isSuper())
{
solUnimplementedAssert(false, "");
solAssert(!!_memberAccess.annotation().referencedDeclaration, "Referenced declaration not resolved.");
ContractDefinition const* super = type.contractDefinition().superContract(m_context.mostDerivedContract());
solAssert(super, "Super contract not available.");
FunctionDefinition const& resolvedFunctionDef = dynamic_cast<FunctionDefinition const&>(
*_memberAccess.annotation().referencedDeclaration
).resolveVirtual(m_context.mostDerivedContract(), super);
define(_memberAccess) << to_string(resolvedFunctionDef.id()) << "\n";
solAssert(resolvedFunctionDef.functionType(true), "");
solAssert(resolvedFunctionDef.functionType(true)->kind() == FunctionType::Kind::Internal, "");
m_context.internalFunctionAccessed(_memberAccess, resolvedFunctionDef);
}
// ordinary contract type
else if (Declaration const* declaration = _memberAccess.annotation().referencedDeclaration)

View File

@ -30,6 +30,7 @@ contract D is B, C {
return data;
}
}
// ====
// compileViaYul: also
// ----
// f() -> 15

View File

@ -0,0 +1,39 @@
contract A {
function f() public virtual returns (uint256 r) {
return 1;
}
}
contract B is A {
function f() public virtual override returns (uint256 r) {
function() internal returns (uint) x = super.f;
return x() | 2;
}
}
contract C is A {
function f() public virtual override returns (uint256 r) {
function() internal returns (uint) x = super.f;
return x() | 4;
}
}
contract D is B, C {
uint256 data;
constructor() {
function() internal returns (uint) x = super.f;
data = x() | 8;
}
function f() public override (B, C) returns (uint256 r) {
return data;
}
}
// ====
// compileViaYul: also
// ----
// f() -> 15

View File

@ -22,6 +22,8 @@ contract C is A, B {
}
}
// ====
// compileViaYul: also
// ----
// g() -> 10
// h() -> 2

View File

@ -25,5 +25,7 @@ contract D is B, C {
}
}
// ====
// compileViaYul: also
// ----
// f() -> 15

View File

@ -0,0 +1,31 @@
contract A {
function f() public virtual returns (uint256 r) {
return 1;
}
}
contract B is A {
function f() public virtual override returns (uint256 r) {
return ((super).f)() | 2;
}
}
contract C is A {
function f() public virtual override returns (uint256 r) {
return ((super).f)() | 4;
}
}
contract D is B, C {
function f() public override(B, C) returns (uint256 r) {
return ((super).f)() | 8;
}
}
// ====
// compileViaYul: also
// ----
// f() -> 15