mirror of
				https://github.com/ethereum/solidity
				synced 2023-10-03 13:03:40 +00:00 
			
		
		
		
	Merge pull request #2605 from roadriverrail/this-in-constructor
This in constructor
This commit is contained in:
		
						commit
						1274108ac7
					
				| @ -7,6 +7,7 @@ Features: | |||||||
|  * Type Checker: Disallow value transfers to contracts without a payable fallback function. |  * Type Checker: Disallow value transfers to contracts without a payable fallback function. | ||||||
|  * Type Checker: Include types in explicit conversion error message. |  * Type Checker: Include types in explicit conversion error message. | ||||||
|  * Type Checker: Raise proper error for arrays too large for ABI encoding. |  * Type Checker: Raise proper error for arrays too large for ABI encoding. | ||||||
|  |  * Type checker: Warn if using ``this`` in a constructor. | ||||||
| 
 | 
 | ||||||
| Bugfixes: | Bugfixes: | ||||||
|  * Type Checker: Fix invalid "specify storage keyword" warning for reference members of structs. |  * Type Checker: Fix invalid "specify storage keyword" warning for reference members of structs. | ||||||
|  | |||||||
| @ -38,12 +38,14 @@ bool StaticAnalyzer::analyze(SourceUnit const& _sourceUnit) | |||||||
| bool StaticAnalyzer::visit(ContractDefinition const& _contract) | bool StaticAnalyzer::visit(ContractDefinition const& _contract) | ||||||
| { | { | ||||||
| 	m_library = _contract.isLibrary(); | 	m_library = _contract.isLibrary(); | ||||||
|  | 	m_currentContract = &_contract; | ||||||
| 	return true; | 	return true; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void StaticAnalyzer::endVisit(ContractDefinition const&) | void StaticAnalyzer::endVisit(ContractDefinition const&) | ||||||
| { | { | ||||||
| 	m_library = false; | 	m_library = false; | ||||||
|  | 	m_currentContract = nullptr; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| bool StaticAnalyzer::visit(FunctionDefinition const& _function) | bool StaticAnalyzer::visit(FunctionDefinition const& _function) | ||||||
| @ -54,6 +56,7 @@ bool StaticAnalyzer::visit(FunctionDefinition const& _function) | |||||||
| 		solAssert(!m_currentFunction, ""); | 		solAssert(!m_currentFunction, ""); | ||||||
| 	solAssert(m_localVarUseCount.empty(), ""); | 	solAssert(m_localVarUseCount.empty(), ""); | ||||||
| 	m_nonPayablePublic = _function.isPublic() && !_function.isPayable(); | 	m_nonPayablePublic = _function.isPublic() && !_function.isPayable(); | ||||||
|  | 	m_constructor = _function.isConstructor(); | ||||||
| 	return true; | 	return true; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @ -61,6 +64,7 @@ void StaticAnalyzer::endVisit(FunctionDefinition const&) | |||||||
| { | { | ||||||
| 	m_currentFunction = nullptr; | 	m_currentFunction = nullptr; | ||||||
| 	m_nonPayablePublic = false; | 	m_nonPayablePublic = false; | ||||||
|  | 	m_constructor = false; | ||||||
| 	for (auto const& var: m_localVarUseCount) | 	for (auto const& var: m_localVarUseCount) | ||||||
| 		if (var.second == 0) | 		if (var.second == 0) | ||||||
| 			m_errorReporter.warning(var.first->location(), "Unused local variable"); | 			m_errorReporter.warning(var.first->location(), "Unused local variable"); | ||||||
| @ -131,6 +135,11 @@ bool StaticAnalyzer::visit(MemberAccess const& _memberAccess) | |||||||
| 					"\"callcode\" has been deprecated in favour of \"delegatecall\"." | 					"\"callcode\" has been deprecated in favour of \"delegatecall\"." | ||||||
| 				); | 				); | ||||||
| 
 | 
 | ||||||
|  | 	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."); | ||||||
|  | 
 | ||||||
| 	return true; | 	return true; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -77,6 +77,12 @@ private: | |||||||
| 	std::map<VariableDeclaration const*, int> m_localVarUseCount; | 	std::map<VariableDeclaration const*, int> m_localVarUseCount; | ||||||
| 
 | 
 | ||||||
| 	FunctionDefinition const* m_currentFunction = nullptr; | 	FunctionDefinition const* m_currentFunction = nullptr; | ||||||
|  | 
 | ||||||
|  | 	/// Flag that indicates a constructor.
 | ||||||
|  | 	bool m_constructor = false; | ||||||
|  | 
 | ||||||
|  | 	/// Current contract.
 | ||||||
|  | 	ContractDefinition const* m_currentContract = nullptr; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| } | } | ||||||
|  | |||||||
| @ -4506,7 +4506,7 @@ BOOST_AUTO_TEST_CASE(var_handle_divided_integers) | |||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 	)"; | 	)"; | ||||||
| 	CHECK_SUCCESS(text);	 | 	CHECK_SUCCESS(text); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| BOOST_AUTO_TEST_CASE(rational_bitnot_unary_operation) | BOOST_AUTO_TEST_CASE(rational_bitnot_unary_operation) | ||||||
| @ -6373,6 +6373,20 @@ BOOST_AUTO_TEST_CASE(modifiers_access_storage_pointer) | |||||||
| 	CHECK_SUCCESS_NO_WARNINGS(text); | 	CHECK_SUCCESS_NO_WARNINGS(text); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | BOOST_AUTO_TEST_CASE(using_this_in_constructor) | ||||||
|  | { | ||||||
|  | 	char const* text = R"( | ||||||
|  | 		contract C { | ||||||
|  | 			function C() { | ||||||
|  | 				this.f(); | ||||||
|  | 			} | ||||||
|  | 			function f() { | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 	)"; | ||||||
|  | 	CHECK_WARNING(text, "\"this\" used in constructor"); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| BOOST_AUTO_TEST_SUITE_END() | BOOST_AUTO_TEST_SUITE_END() | ||||||
| 
 | 
 | ||||||
| } | } | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user