mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Merge pull request #3875 from ethereum/constructorSelfRef
Stricter check for "this" in constructor.
This commit is contained in:
commit
95c49b367e
@ -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;
|
||||
}
|
||||
|
12
test/libsolidity/syntaxTests/constructor_this.sol
Normal file
12
test/libsolidity/syntaxTests/constructor_this.sol
Normal file
@ -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.
|
@ -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;
|
||||
}
|
||||
}
|
10
test/libsolidity/syntaxTests/parsing/constructor_super.sol
Normal file
10
test/libsolidity/syntaxTests/parsing/constructor_super.sol
Normal file
@ -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();
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user