From acba7b92e5456d14bda1db8b3c71909d6d49c53f Mon Sep 17 00:00:00 2001 From: Yoichi Hirai Date: Fri, 21 Oct 2016 20:02:31 +0200 Subject: codegen: if a member access has been resolved as a variable, follow that This fixes at least the first example in #988 --- libsolidity/codegen/ExpressionCompiler.cpp | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'libsolidity') diff --git a/libsolidity/codegen/ExpressionCompiler.cpp b/libsolidity/codegen/ExpressionCompiler.cpp index da3e56cc..1cb74c06 100644 --- a/libsolidity/codegen/ExpressionCompiler.cpp +++ b/libsolidity/codegen/ExpressionCompiler.cpp @@ -888,6 +888,18 @@ bool ExpressionCompiler::visit(MemberAccess const& _memberAccess) { // no-op } + else if (auto variable = dynamic_cast(_memberAccess.annotation().referencedDeclaration)) + { + // TODO duplicate code should be unified + + if (!variable->isConstant()) + setLValueFromDeclaration(*_memberAccess.annotation().referencedDeclaration, _memberAccess); + else + { + variable->value()->accept(*this); + utils().convertType(*variable->value()->annotation().type, *variable->annotation().type); + } + } else _memberAccess.expression().accept(*this); } -- cgit From 5245a3cf744260be3b4b02bed56759ed89ffc89a Mon Sep 17 00:00:00 2001 From: Yoichi Hirai Date: Fri, 21 Oct 2016 20:16:21 +0200 Subject: codegen: refactor common code --- libsolidity/codegen/ExpressionCompiler.cpp | 33 ++++++++++++------------------ libsolidity/codegen/ExpressionCompiler.h | 2 ++ 2 files changed, 15 insertions(+), 20 deletions(-) (limited to 'libsolidity') diff --git a/libsolidity/codegen/ExpressionCompiler.cpp b/libsolidity/codegen/ExpressionCompiler.cpp index 1cb74c06..98b7f6e5 100644 --- a/libsolidity/codegen/ExpressionCompiler.cpp +++ b/libsolidity/codegen/ExpressionCompiler.cpp @@ -889,17 +889,7 @@ bool ExpressionCompiler::visit(MemberAccess const& _memberAccess) // no-op } else if (auto variable = dynamic_cast(_memberAccess.annotation().referencedDeclaration)) - { - // TODO duplicate code should be unified - - if (!variable->isConstant()) - setLValueFromDeclaration(*_memberAccess.annotation().referencedDeclaration, _memberAccess); - else - { - variable->value()->accept(*this); - utils().convertType(*variable->value()->annotation().type, *variable->annotation().type); - } - } + appendVariable(*variable, static_cast(_memberAccess)); else _memberAccess.expression().accept(*this); } @@ -1213,15 +1203,7 @@ void ExpressionCompiler::endVisit(Identifier const& _identifier) else if (FunctionDefinition const* functionDef = dynamic_cast(declaration)) m_context << m_context.virtualFunctionEntryLabel(*functionDef).pushTag(); else if (auto variable = dynamic_cast(declaration)) - { - if (!variable->isConstant()) - setLValueFromDeclaration(*declaration, _identifier); - else - { - variable->value()->accept(*this); - utils().convertType(*variable->value()->annotation().type, *variable->annotation().type); - } - } + appendVariable(*variable, static_cast(_identifier)); else if (auto contract = dynamic_cast(declaration)) { if (contract->isLibrary()) @@ -1650,6 +1632,17 @@ void ExpressionCompiler::appendExpressionCopyToMemory(Type const& _expectedType, utils().storeInMemoryDynamic(_expectedType); } +void ExpressionCompiler::appendVariable(VariableDeclaration const& _variable, Expression const& _expression) +{ + if (!_variable.isConstant()) + setLValueFromDeclaration(_variable, _expression); + else + { + _variable.value()->accept(*this); + utils().convertType(*_variable.value()->annotation().type, *_variable.annotation().type); + } +} + void ExpressionCompiler::setLValueFromDeclaration(Declaration const& _declaration, Expression const& _expression) { if (m_context.isLocalVariable(&_declaration)) diff --git a/libsolidity/codegen/ExpressionCompiler.h b/libsolidity/codegen/ExpressionCompiler.h index 43a92a10..f4ce1fec 100644 --- a/libsolidity/codegen/ExpressionCompiler.h +++ b/libsolidity/codegen/ExpressionCompiler.h @@ -103,6 +103,8 @@ private: /// expected to be on the stack and is updated by this call. void appendExpressionCopyToMemory(Type const& _expectedType, Expression const& _expression); + /// Appends code for a variable that might be a constant or not + void appendVariable(VariableDeclaration const& _variable, Expression const& _expression); /// Sets the current LValue to a new one (of the appropriate type) from the given declaration. /// Also retrieves the value if it was not requested by @a _expression. void setLValueFromDeclaration(Declaration const& _declaration, Expression const& _expression); -- cgit From 59f6c18c2be86152261bb20732161c60fd2a6485 Mon Sep 17 00:00:00 2001 From: Yoichi Hirai Date: Mon, 24 Oct 2016 19:22:09 +0200 Subject: analysis: determine if a member access on a contract is an l-value --- libsolidity/analysis/TypeChecker.cpp | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'libsolidity') diff --git a/libsolidity/analysis/TypeChecker.cpp b/libsolidity/analysis/TypeChecker.cpp index b5955c8f..f871e3a1 100644 --- a/libsolidity/analysis/TypeChecker.cpp +++ b/libsolidity/analysis/TypeChecker.cpp @@ -1376,6 +1376,11 @@ bool TypeChecker::visit(MemberAccess const& _memberAccess) } else if (exprType->category() == Type::Category::FixedBytes) annotation.isLValue = false; + else if (TypeType const* typeType = dynamic_cast(exprType.get())) + { + if (ContractType const* contractType = dynamic_cast(typeType->actualType().get())) + annotation.isLValue = annotation.referencedDeclaration->isLValue(); + } return false; } -- cgit