Mark function selector accesses as pure for pure expressions and mark function accesses via contract name as pure.

This commit is contained in:
Daniel Kirchner
2020-02-14 12:33:33 +01:00
parent 08f1b591f7
commit 9f094d59b9
12 changed files with 101 additions and 9 deletions
+22
View File
@@ -2527,7 +2527,15 @@ bool TypeChecker::visit(MemberAccess const& _memberAccess)
else if (TypeType const* typeType = dynamic_cast<decltype(typeType)>(exprType))
{
if (ContractType const* contractType = dynamic_cast<decltype(contractType)>(typeType->actualType()))
{
annotation.isLValue = annotation.referencedDeclaration->isLValue();
if (
auto const* functionType = dynamic_cast<FunctionType const*>(annotation.type);
functionType &&
functionType->kind() == FunctionType::Kind::Declaration
)
annotation.isPure = _memberAccess.expression().annotation().isPure;
}
}
// TODO some members might be pure, but for example `address(0x123).balance` is not pure
@@ -2535,6 +2543,20 @@ bool TypeChecker::visit(MemberAccess const& _memberAccess)
if (auto tt = dynamic_cast<TypeType const*>(exprType))
if (tt->actualType()->category() == Type::Category::Enum)
annotation.isPure = true;
if (
auto const* functionType = dynamic_cast<FunctionType const*>(exprType);
functionType &&
functionType->hasDeclaration() &&
dynamic_cast<FunctionDefinition const*>(&functionType->declaration()) &&
memberName == "selector"
)
if (auto const* parentAccess = dynamic_cast<MemberAccess const*>(&_memberAccess.expression()))
{
annotation.isPure = parentAccess->expression().annotation().isPure;
if (auto const* exprInt = dynamic_cast<Identifier const*>(&parentAccess->expression()))
if (exprInt->name() == "this" || exprInt->name() == "super")
annotation.isPure = true;
}
if (auto magicType = dynamic_cast<MagicType const*>(exprType))
{
if (magicType->kind() == MagicType::Kind::ABI)
@@ -1303,6 +1303,8 @@ bool ExpressionCompiler::visit(MemberAccess const& _memberAccess)
{
switch (funType->kind())
{
case FunctionType::Kind::Declaration:
break;
case FunctionType::Kind::Internal:
// We do not visit the expression here on purpose, because in the case of an
// internal library function call, this would push the library address forcing