aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLeonardo Alt <leo@ethereum.org>2018-07-19 01:51:24 +0800
committerLeonardo Alt <leo@ethereum.org>2018-07-19 01:51:24 +0800
commitfaa9c221d41c45e12411c654919f318f6e7fc98f (patch)
tree4393a4143da54f183e0459c59b0f3687bc5fbe37
parent25fa1142bc2ba74e75f24f8267d7fcb282423335 (diff)
downloaddexon-solidity-faa9c221d41c45e12411c654919f318f6e7fc98f.tar.gz
dexon-solidity-faa9c221d41c45e12411c654919f318f6e7fc98f.tar.zst
dexon-solidity-faa9c221d41c45e12411c654919f318f6e7fc98f.zip
Changes in ExpressionCompiler
-rw-r--r--Changelog.md4
-rw-r--r--libsolidity/analysis/TypeChecker.cpp5
-rw-r--r--libsolidity/codegen/ExpressionCompiler.cpp89
-rw-r--r--test/libsolidity/syntaxTests/types/address_members_in_contract.sol6
4 files changed, 50 insertions, 54 deletions
diff --git a/Changelog.md b/Changelog.md
index c18b589e..6776de7e 100644
--- a/Changelog.md
+++ b/Changelog.md
@@ -5,7 +5,7 @@ How to update your code:
* Change every ``keccak256(a, b, c)`` to ``keccak256(abi.encodePacked(a, b, c))``.
* Make your fallback functions ``external``.
* Explicitly state the storage location for local variables of struct and array types, e.g. change ``uint[] x = m_x`` to ``uint[] storage x = m_x``.
- * Explicitly convert ``contract`` to ``address`` before using an ``address`` member. Example: if ``c`` is a variable of type ``contract``, change ``c.transfer(...)`` to ``address(c).transfer(...)``.
+ * Explicitly convert values of contract type to addresses before using an ``address`` member. Example: if ``c`` is a contract, change ``c.transfer(...)`` to ``address(c).transfer(...)``.
Breaking Changes:
@@ -47,7 +47,7 @@ Breaking Changes:
* Type Checker: Only accept a single ``bytes`` type for ``.call()`` (and family), ``keccak256()``, ``sha256()`` and ``ripemd160()``.
* Type Checker: Fallback function must be external. This was already the case in the experimental 0.5.0 mode.
* Type Checker: Interface functions must be declared external. This was already the case in the experimental 0.5.0 mode.
- * Type Checker: ``Contract`` does not have access to ``address`` members anymore. An explicit conversion is now required before invoking an ``address`` member from a ``contract``.
+ * Type Checker: Address members are not included in contract types anymore. An explicit conversion is now required before invoking an ``address`` member from a contract.
* Remove obsolete ``std`` directory from the Solidity repository. This means accessing ``https://github.com/ethereum/soldity/blob/develop/std/*.sol`` (or ``https://github.com/ethereum/solidity/std/*.sol`` in Remix) will not be possible.
* References Resolver: Turn missing storage locations into an error. This was already the case in the experimental 0.5.0 mode.
* Syntax Checker: Named return values in function types are an error.
diff --git a/libsolidity/analysis/TypeChecker.cpp b/libsolidity/analysis/TypeChecker.cpp
index fc5a3608..8536e934 100644
--- a/libsolidity/analysis/TypeChecker.cpp
+++ b/libsolidity/analysis/TypeChecker.cpp
@@ -1957,8 +1957,9 @@ bool TypeChecker::visit(MemberAccess const& _memberAccess)
for (auto const& addressMember: IntegerType(160, IntegerType::Modifier::Address).nativeMembers(nullptr))
if (addressMember.name == memberName)
{
- Identifier const& var = dynamic_cast<Identifier const&>(_memberAccess.expression());
- errorMsg += " Use \"address(" + var.name() + ")." + memberName + "\" to access this address member.";
+ Identifier const* var = dynamic_cast<Identifier const*>(&_memberAccess.expression());
+ string varName = var ? var->name() : "...";
+ errorMsg += " Use \"address(" + varName + ")." + memberName + "\" to access this address member.";
break;
}
m_errorReporter.fatalTypeError(
diff --git a/libsolidity/codegen/ExpressionCompiler.cpp b/libsolidity/codegen/ExpressionCompiler.cpp
index 4cec69c8..54518906 100644
--- a/libsolidity/codegen/ExpressionCompiler.cpp
+++ b/libsolidity/codegen/ExpressionCompiler.cpp
@@ -1214,63 +1214,52 @@ bool ExpressionCompiler::visit(MemberAccess const& _memberAccess)
switch (_memberAccess.expression().annotation().type->category())
{
case Type::Category::Contract:
- case Type::Category::Integer:
{
- bool alsoSearchInteger = false;
- if (_memberAccess.expression().annotation().type->category() == Type::Category::Contract)
+ ContractType const& type = dynamic_cast<ContractType const&>(*_memberAccess.expression().annotation().type);
+ if (type.isSuper())
{
- ContractType const& type = dynamic_cast<ContractType const&>(*_memberAccess.expression().annotation().type);
- if (type.isSuper())
- {
- solAssert(!!_memberAccess.annotation().referencedDeclaration, "Referenced declaration not resolved.");
- utils().pushCombinedFunctionEntryLabel(m_context.superFunction(
- dynamic_cast<FunctionDefinition const&>(*_memberAccess.annotation().referencedDeclaration),
- type.contractDefinition()
- ));
- }
+ solAssert(!!_memberAccess.annotation().referencedDeclaration, "Referenced declaration not resolved.");
+ utils().pushCombinedFunctionEntryLabel(m_context.superFunction(
+ dynamic_cast<FunctionDefinition const&>(*_memberAccess.annotation().referencedDeclaration),
+ type.contractDefinition()
+ ));
+ }
+ // ordinary contract type
+ else if (Declaration const* declaration = _memberAccess.annotation().referencedDeclaration)
+ {
+ u256 identifier;
+ if (auto const* variable = dynamic_cast<VariableDeclaration const*>(declaration))
+ identifier = FunctionType(*variable).externalIdentifier();
+ else if (auto const* function = dynamic_cast<FunctionDefinition const*>(declaration))
+ identifier = FunctionType(*function).externalIdentifier();
else
- {
- // ordinary contract type
- if (Declaration const* declaration = _memberAccess.annotation().referencedDeclaration)
- {
- u256 identifier;
- if (auto const* variable = dynamic_cast<VariableDeclaration const*>(declaration))
- identifier = FunctionType(*variable).externalIdentifier();
- else if (auto const* function = dynamic_cast<FunctionDefinition const*>(declaration))
- identifier = FunctionType(*function).externalIdentifier();
- else
- solAssert(false, "Contract member is neither variable nor function.");
- utils().convertType(type, IntegerType(160, IntegerType::Modifier::Address), true);
- m_context << identifier;
- }
- else
- // not found in contract, search in members inherited from address
- alsoSearchInteger = true;
- }
+ solAssert(false, "Contract member is neither variable nor function.");
+ utils().convertType(type, IntegerType(160, IntegerType::Modifier::Address), true);
+ m_context << identifier;
}
else
- alsoSearchInteger = true;
-
- if (alsoSearchInteger)
+ solAssert(false, "Invalid member access in contract");
+ break;
+ }
+ case Type::Category::Integer:
+ {
+ if (member == "balance")
{
- if (member == "balance")
- {
- utils().convertType(
- *_memberAccess.expression().annotation().type,
- IntegerType(160, IntegerType::Modifier::Address),
- true
- );
- m_context << Instruction::BALANCE;
- }
- else if ((set<string>{"send", "transfer", "call", "callcode", "delegatecall"}).count(member))
- utils().convertType(
- *_memberAccess.expression().annotation().type,
- IntegerType(160, IntegerType::Modifier::Address),
- true
- );
- else
- solAssert(false, "Invalid member access to integer");
+ utils().convertType(
+ *_memberAccess.expression().annotation().type,
+ IntegerType(160, IntegerType::Modifier::Address),
+ true
+ );
+ m_context << Instruction::BALANCE;
}
+ else if ((set<string>{"send", "transfer", "call", "callcode", "delegatecall"}).count(member))
+ utils().convertType(
+ *_memberAccess.expression().annotation().type,
+ IntegerType(160, IntegerType::Modifier::Address),
+ true
+ );
+ else
+ solAssert(false, "Invalid member access to integer");
break;
}
case Type::Category::Function:
diff --git a/test/libsolidity/syntaxTests/types/address_members_in_contract.sol b/test/libsolidity/syntaxTests/types/address_members_in_contract.sol
new file mode 100644
index 00000000..eafc8268
--- /dev/null
+++ b/test/libsolidity/syntaxTests/types/address_members_in_contract.sol
@@ -0,0 +1,6 @@
+contract C {
+ function f() public returns (C) { return this; }
+ function g() public returns (uint) { return f().balance(); }
+}
+// ----
+// TypeError: (114-125): Member "balance" not found or not visible after argument-dependent lookup in contract C. Use "address(...).balance" to access this address member.