diff options
author | Daniel Kirchner <daniel@ekpyron.org> | 2018-04-13 00:14:48 +0800 |
---|---|---|
committer | Daniel Kirchner <daniel@ekpyron.org> | 2018-04-13 21:57:13 +0800 |
commit | be37e3a912f6d5a2a57544f60362be65b7be8284 (patch) | |
tree | ff77c1e784eac895f85672cf82df9b243b8891fc | |
parent | c3dc67d0e0c311a907e7a27e159f9159d78af949 (diff) | |
download | dexon-solidity-be37e3a912f6d5a2a57544f60362be65b7be8284.tar dexon-solidity-be37e3a912f6d5a2a57544f60362be65b7be8284.tar.gz dexon-solidity-be37e3a912f6d5a2a57544f60362be65b7be8284.tar.bz2 dexon-solidity-be37e3a912f6d5a2a57544f60362be65b7be8284.tar.lz dexon-solidity-be37e3a912f6d5a2a57544f60362be65b7be8284.tar.xz dexon-solidity-be37e3a912f6d5a2a57544f60362be65b7be8284.tar.zst dexon-solidity-be37e3a912f6d5a2a57544f60362be65b7be8284.zip |
Stricter check for member access to "this" in constructor.
4 files changed, 76 insertions, 4 deletions
diff --git a/libsolidity/analysis/StaticAnalyzer.cpp b/libsolidity/analysis/StaticAnalyzer.cpp index 51aa0b28..00a581d0 100644 --- a/libsolidity/analysis/StaticAnalyzer.cpp +++ b/libsolidity/analysis/StaticAnalyzer.cpp @@ -206,10 +206,32 @@ bool StaticAnalyzer::visit(MemberAccess const& _memberAccess) ); } - if (m_constructor && m_currentContract) - if (ContractType const* type = dynamic_cast<ContractType const*>(_memberAccess.expression().annotation().type.get())) - if (type->contractDefinition() == *m_currentContract) - m_errorReporter.warning(_memberAccess.location(), "\"this\" used in constructor."); + if (m_constructor) + { + auto const* expr = &_memberAccess.expression(); + while(expr) + { + if (auto id = dynamic_cast<Identifier const*>(expr)) + { + if (id->name() == "this") + m_errorReporter.warning( + id->location(), + "\"this\" used in constructor. " + "Note that external functions of a contract " + "cannot be called while it is being constructed."); + break; + } + else if (auto tuple = dynamic_cast<TupleExpression const*>(expr)) + { + if (tuple->components().size() == 1) + expr = tuple->components().front().get(); + else + break; + } + else + break; + } + } return true; } diff --git a/test/libsolidity/syntaxTests/constructor_this.sol b/test/libsolidity/syntaxTests/constructor_this.sol new file mode 100644 index 00000000..9d22a161 --- /dev/null +++ b/test/libsolidity/syntaxTests/constructor_this.sol @@ -0,0 +1,12 @@ +contract C { + function f() public pure {} + constructor() public { + C c = this; + c.f(); // this does not warn now, but should warn in the future + this.f(); + (this).f(); + } +} +// ---- +// Warning: (172-176): "this" used in constructor. Note that external functions of a contract cannot be called while it is being constructed. +// Warning: (191-195): "this" used in constructor. Note that external functions of a contract cannot be called while it is being constructed. diff --git a/test/libsolidity/syntaxTests/parsing/constructor_allowed_this.sol b/test/libsolidity/syntaxTests/parsing/constructor_allowed_this.sol new file mode 100644 index 00000000..9f714aea --- /dev/null +++ b/test/libsolidity/syntaxTests/parsing/constructor_allowed_this.sol @@ -0,0 +1,28 @@ +contract A { + function a() public pure { + } +} +contract B { + constructor(address) public { + } + function b(address) public returns (A) { + return new A(); + } +} +contract C { + B m_b; + C m_c; + constructor(C other_c) public { + m_c = other_c; + m_b = new B(this); + m_b.b(this).a(); + g(this).f(); + other_c.f(); + m_c.f(); + } + function f() public pure { + } + function g(C) public view returns (C) { + return m_c; + } +} diff --git a/test/libsolidity/syntaxTests/parsing/constructor_super.sol b/test/libsolidity/syntaxTests/parsing/constructor_super.sol new file mode 100644 index 00000000..fa1be187 --- /dev/null +++ b/test/libsolidity/syntaxTests/parsing/constructor_super.sol @@ -0,0 +1,10 @@ +contract A { + function x() pure internal {} +} + +contract B is A { + constructor() public { + // used to trigger warning about using ``this`` in constructor + super.x(); + } +} |