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) if (identifier)
functionDef = &functionDef->resolveVirtual(m_context.mostDerivedContract()); 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(), ""); solAssert(!functionType->takesArbitraryParameters(), "");
@ -1397,7 +1407,17 @@ void IRGeneratorForStatements::endVisit(MemberAccess const& _memberAccess)
ContractType const& type = dynamic_cast<ContractType const&>(*_memberAccess.expression().annotation().type); ContractType const& type = dynamic_cast<ContractType const&>(*_memberAccess.expression().annotation().type);
if (type.isSuper()) 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 // ordinary contract type
else if (Declaration const* declaration = _memberAccess.annotation().referencedDeclaration) else if (Declaration const* declaration = _memberAccess.annotation().referencedDeclaration)

View File

@ -30,6 +30,7 @@ contract D is B, C {
return data; return data;
} }
} }
// ====
// compileViaYul: also
// ---- // ----
// f() -> 15 // 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 // g() -> 10
// h() -> 2 // h() -> 2

View File

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