Check if constructor is public or not.

This commit is contained in:
chriseth 2017-01-20 19:21:43 +01:00
parent df4ef74199
commit 0ef460461a
3 changed files with 13 additions and 2 deletions

View File

@ -75,7 +75,10 @@ bool TypeChecker::visit(ContractDefinition const& _contract)
checkContractAbstractConstructors(_contract); checkContractAbstractConstructors(_contract);
FunctionDefinition const* function = _contract.constructor(); FunctionDefinition const* function = _contract.constructor();
if (function) { if (function)
{
if (!function->isPublic())
_contract.annotation().hasPublicConstructor = false;
if (!function->returnParameters().empty()) if (!function->returnParameters().empty())
typeError(function->returnParameterList()->location(), "Non-empty \"returns\" directive for constructor."); typeError(function->returnParameterList()->location(), "Non-empty \"returns\" directive for constructor.");
if (function->isDeclaredConst()) if (function->isDeclaredConst())
@ -1280,6 +1283,8 @@ void TypeChecker::endVisit(NewExpression const& _newExpression)
fatalTypeError(_newExpression.location(), "Identifier is not a contract."); fatalTypeError(_newExpression.location(), "Identifier is not a contract.");
if (!contract->annotation().isFullyImplemented) if (!contract->annotation().isFullyImplemented)
typeError(_newExpression.location(), "Trying to create an instance of an abstract contract."); typeError(_newExpression.location(), "Trying to create an instance of an abstract contract.");
if (!contract->annotation().hasPublicConstructor)
typeError(_newExpression.location(), "Contract with internal constructor cannot be created directly.");
solAssert(!!m_scope, ""); solAssert(!!m_scope, "");
m_scope->annotation().contractDependencies.insert(contract); m_scope->annotation().contractDependencies.insert(contract);

View File

@ -80,6 +80,8 @@ struct ContractDefinitionAnnotation: TypeDeclarationAnnotation, DocumentedAnnota
{ {
/// Whether all functions are implemented. /// Whether all functions are implemented.
bool isFullyImplemented = true; bool isFullyImplemented = true;
/// Whether a public constructor (even the default one) is available.
bool hasPublicConstructor = true;
/// List of all (direct and indirect) base contracts in order from derived to /// List of all (direct and indirect) base contracts in order from derived to
/// base, including the contract itself. /// base, including the contract itself.
std::vector<ContractDefinition const*> linearizedBaseContracts; std::vector<ContractDefinition const*> linearizedBaseContracts;

View File

@ -624,7 +624,11 @@ void CompilerStack::compileContract(
map<ContractDefinition const*, eth::Assembly const*>& _compiledContracts map<ContractDefinition const*, eth::Assembly const*>& _compiledContracts
) )
{ {
if (_compiledContracts.count(&_contract) || !_contract.annotation().isFullyImplemented) if (
_compiledContracts.count(&_contract) ||
!_contract.annotation().isFullyImplemented ||
!_contract.annotation().hasPublicConstructor
)
return; return;
for (auto const* dependency: _contract.annotation().contractDependencies) for (auto const* dependency: _contract.annotation().contractDependencies)
compileContract(*dependency, _compiledContracts); compileContract(*dependency, _compiledContracts);