Merge pull request #11009 from ethereum/properlyParseAddressMember

Properly parse address member.
This commit is contained in:
chriseth 2021-02-24 17:12:00 +01:00 committed by GitHub
commit eacf7c1cf9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 43 additions and 11 deletions

View File

@ -14,6 +14,7 @@ Bugfixes:
* SMTChecker: Fix missing type constraints on block and transaction variables in the deployment phase. * SMTChecker: Fix missing type constraints on block and transaction variables in the deployment phase.
* AST: Added ``referencedDeclaration`` for enum members. * AST: Added ``referencedDeclaration`` for enum members.
* Code Generator: Fix internal error when functions are passed as parameters of other callables, when the function types can be implicitly converted, but not identical. * Code Generator: Fix internal error when functions are passed as parameters of other callables, when the function types can be implicitly converted, but not identical.
* Parser: Properly parse ``.address`` in some situations.
* Type Checker: Make function-hash collision errors into fatal type errors. * Type Checker: Make function-hash collision errors into fatal type errors.

View File

@ -961,6 +961,14 @@ ASTPointer<Identifier> Parser::parseIdentifier()
return nodeFactory.createNode<Identifier>(expectIdentifierToken()); return nodeFactory.createNode<Identifier>(expectIdentifierToken());
} }
ASTPointer<Identifier> Parser::parseIdentifierOrAddress()
{
RecursionGuard recursionGuard(*this);
ASTNodeFactory nodeFactory(*this);
nodeFactory.markEndPosition();
return nodeFactory.createNode<Identifier>(expectIdentifierTokenOrAddress());
}
ASTPointer<UserDefinedTypeName> Parser::parseUserDefinedTypeName() ASTPointer<UserDefinedTypeName> Parser::parseUserDefinedTypeName()
{ {
ASTNodeFactory nodeFactory(*this); ASTNodeFactory nodeFactory(*this);
@ -979,7 +987,7 @@ ASTPointer<IdentifierPath> Parser::parseIdentifierPath()
{ {
m_scanner->next(); m_scanner->next();
nodeFactory.markEndPosition(); nodeFactory.markEndPosition();
identifierPath.push_back(*expectIdentifierToken()); identifierPath.push_back(*expectIdentifierTokenOrAddress());
} }
return nodeFactory.createNode<IdentifierPath>(identifierPath); return nodeFactory.createNode<IdentifierPath>(identifierPath);
} }
@ -1751,13 +1759,7 @@ ASTPointer<Expression> Parser::parseLeftHandSideExpression(
{ {
m_scanner->next(); m_scanner->next();
nodeFactory.markEndPosition(); nodeFactory.markEndPosition();
if (m_scanner->currentToken() == Token::Address) expression = nodeFactory.createNode<MemberAccess>(expression, expectIdentifierTokenOrAddress());
{
expression = nodeFactory.createNode<MemberAccess>(expression, make_shared<ASTString>("address"));
m_scanner->next();
}
else
expression = nodeFactory.createNode<MemberAccess>(expression, expectIdentifierToken());
break; break;
} }
case Token::LParen: case Token::LParen:
@ -2081,7 +2083,7 @@ Parser::IndexAccessedPath Parser::parseIndexAccessedPath()
while (m_scanner->currentToken() == Token::Period) while (m_scanner->currentToken() == Token::Period)
{ {
m_scanner->next(); m_scanner->next();
iap.path.push_back(parseIdentifier()); iap.path.push_back(parseIdentifierOrAddress());
} }
} }
else else
@ -2199,11 +2201,26 @@ ASTPointer<ParameterList> Parser::createEmptyParameterList()
ASTPointer<ASTString> Parser::expectIdentifierToken() ASTPointer<ASTString> Parser::expectIdentifierToken()
{ {
// do not advance on success expectToken(Token::Identifier, false /* do not advance */);
expectToken(Token::Identifier, false);
return getLiteralAndAdvance(); return getLiteralAndAdvance();
} }
ASTPointer<ASTString> Parser::expectIdentifierTokenOrAddress()
{
ASTPointer<ASTString> result;
if (m_scanner->currentToken() == Token::Address)
{
result = make_shared<ASTString>("address");
m_scanner->next();
}
else
{
expectToken(Token::Identifier, false /* do not advance */);
result = getLiteralAndAdvance();
}
return result;
}
ASTPointer<ASTString> Parser::getLiteralAndAdvance() ASTPointer<ASTString> Parser::getLiteralAndAdvance()
{ {
ASTPointer<ASTString> identifier = make_shared<ASTString>(m_scanner->currentLiteral()); ASTPointer<ASTString> identifier = make_shared<ASTString>(m_scanner->currentLiteral());

View File

@ -105,6 +105,7 @@ private:
ASTPointer<UsingForDirective> parseUsingDirective(); ASTPointer<UsingForDirective> parseUsingDirective();
ASTPointer<ModifierInvocation> parseModifierInvocation(); ASTPointer<ModifierInvocation> parseModifierInvocation();
ASTPointer<Identifier> parseIdentifier(); ASTPointer<Identifier> parseIdentifier();
ASTPointer<Identifier> parseIdentifierOrAddress();
ASTPointer<UserDefinedTypeName> parseUserDefinedTypeName(); ASTPointer<UserDefinedTypeName> parseUserDefinedTypeName();
ASTPointer<IdentifierPath> parseIdentifierPath(); ASTPointer<IdentifierPath> parseIdentifierPath();
ASTPointer<TypeName> parseTypeNameSuffix(ASTPointer<TypeName> type, ASTNodeFactory& nodeFactory); ASTPointer<TypeName> parseTypeNameSuffix(ASTPointer<TypeName> type, ASTNodeFactory& nodeFactory);
@ -201,6 +202,7 @@ private:
ASTPointer<Expression> expressionFromIndexAccessStructure(IndexAccessedPath const& _pathAndIndices); ASTPointer<Expression> expressionFromIndexAccessStructure(IndexAccessedPath const& _pathAndIndices);
ASTPointer<ASTString> expectIdentifierToken(); ASTPointer<ASTString> expectIdentifierToken();
ASTPointer<ASTString> expectIdentifierTokenOrAddress();
ASTPointer<ASTString> getLiteralAndAdvance(); ASTPointer<ASTString> getLiteralAndAdvance();
///@} ///@}

View File

@ -0,0 +1,12 @@
contract C {
function f() public view returns (address a1, address a2) {
a1 = this.f.address;
this.f.address;
[this.f.address][0];
a2 = [this.f.address][0];
}
}
// ====
// compileViaYul: also
// ----
// f() -> 90572315268751552425567948436632610904688605307, 90572315268751552425567948436632610904688605307