diff options
author | LianaHus <liana@ethdev.com> | 2015-11-07 00:22:46 +0800 |
---|---|---|
committer | LianaHus <liana@ethdev.com> | 2015-11-07 01:45:06 +0800 |
commit | 7eb162c0df52fc6335613f00e9d105fe2a4df7ff (patch) | |
tree | 41f3855a4a94dda669053f17306ec9e7f5ace34e /libsolidity/analysis | |
parent | 79177de80b83eeecc41f49690c0e70485d75937f (diff) | |
download | dexon-solidity-7eb162c0df52fc6335613f00e9d105fe2a4df7ff.tar.gz dexon-solidity-7eb162c0df52fc6335613f00e9d105fe2a4df7ff.tar.zst dexon-solidity-7eb162c0df52fc6335613f00e9d105fe2a4df7ff.zip |
fix
Diffstat (limited to 'libsolidity/analysis')
-rw-r--r-- | libsolidity/analysis/NameAndTypeResolver.cpp | 24 | ||||
-rw-r--r-- | libsolidity/analysis/ReferencesResolver.cpp | 56 | ||||
-rw-r--r-- | libsolidity/analysis/ReferencesResolver.h | 15 |
3 files changed, 60 insertions, 35 deletions
diff --git a/libsolidity/analysis/NameAndTypeResolver.cpp b/libsolidity/analysis/NameAndTypeResolver.cpp index cf03c808..d681b99b 100644 --- a/libsolidity/analysis/NameAndTypeResolver.cpp +++ b/libsolidity/analysis/NameAndTypeResolver.cpp @@ -84,6 +84,9 @@ bool NameAndTypeResolver::resolveNamesAndTypes(ContractDefinition& _contract) importInheritedScope(*base); } + if (!success) + return false; + for (ASTPointer<StructDefinition> const& structDef: _contract.definedStructs()) if (!resolver.resolve(*structDef)) success = false; @@ -97,6 +100,8 @@ bool NameAndTypeResolver::resolveNamesAndTypes(ContractDefinition& _contract) if (!resolver.resolve(*event)) success = false; // these can contain code, only resolve parameters for now + if (!success) + return false; for (ASTPointer<ModifierDefinition> const& modifier: _contract.functionModifiers()) { m_currentScope = &m_scopes[modifier.get()]; @@ -104,19 +109,24 @@ bool NameAndTypeResolver::resolveNamesAndTypes(ContractDefinition& _contract) if (!resolver.resolve(*modifier)) success = false; } + + if (!success) + return false; for (ASTPointer<FunctionDefinition> const& function: _contract.definedFunctions()) { m_currentScope = &m_scopes[function.get()]; - ReferencesResolver referencesResolver( + if (! ReferencesResolver( m_errors, *this, &_contract, function->returnParameterList().get() - ); - if (!resolver.resolve(*function)) + ).resolve(*function)) success = false; } + if (!success) + return false; + m_currentScope = &m_scopes[&_contract]; // now resolve references inside the code @@ -127,17 +137,19 @@ bool NameAndTypeResolver::resolveNamesAndTypes(ContractDefinition& _contract) if (!resolver.resolve(*modifier)) success = false; } + + if (!success) + return false; for (ASTPointer<FunctionDefinition> const& function: _contract.definedFunctions()) { m_currentScope = &m_scopes[function.get()]; - ReferencesResolver referencesResolver( + if (! ReferencesResolver( m_errors, *this, &_contract, function->returnParameterList().get(), true - ); - if (!resolver.resolve(*function)) + ).resolve(*function)) success = false; } if (!success) diff --git a/libsolidity/analysis/ReferencesResolver.cpp b/libsolidity/analysis/ReferencesResolver.cpp index 6fda8969..6878f79f 100644 --- a/libsolidity/analysis/ReferencesResolver.cpp +++ b/libsolidity/analysis/ReferencesResolver.cpp @@ -41,11 +41,8 @@ bool ReferencesResolver::visit(UserDefinedTypeName const& _typeName) { Declaration const* declaration = m_resolver.pathFromCurrentScope(_typeName.namePath()); if (!declaration) - BOOST_THROW_EXCEPTION( - Error(Error::Type::DeclarationError) << - errinfo_sourceLocation(_typeName.location()) << - errinfo_comment("Identifier not found or not unique.") - ); + DeclarationFatalError(_typeName.location(), "Identifier not found or not unique."); + _typeName.annotation().referencedDeclaration = declaration; return true; } @@ -54,11 +51,7 @@ bool ReferencesResolver::visit(Identifier const& _identifier) { auto declarations = m_resolver.nameFromCurrentScope(_identifier.name()); if (declarations.empty()) - BOOST_THROW_EXCEPTION( - Error(Error::Type::DeclarationError) << - errinfo_sourceLocation(_identifier.location()) << - errinfo_comment("Undeclared identifier.") - ); + DeclarationFatalError(_identifier.location(), "Undeclared identifier."); else if (declarations.size() == 1) { _identifier.annotation().referencedDeclaration = declarations.front(); @@ -93,7 +86,7 @@ void ReferencesResolver::endVisit(VariableDeclaration const& _variable) if (contract.isLibrary()) { if (loc == Location::Memory) - fatalTypeError(_variable.location(), + TypeFatalError(_variable.location(), "Location has to be calldata or storage for external " "library functions (remove the \"memory\" keyword)." ); @@ -102,7 +95,7 @@ void ReferencesResolver::endVisit(VariableDeclaration const& _variable) { // force location of external function parameters (not return) to calldata if (loc != Location::Default) - fatalTypeError(_variable.location(), + TypeFatalError(_variable.location(), "Location has to be calldata for external functions " "(remove the \"memory\" or \"storage\" keyword)." ); @@ -115,7 +108,7 @@ void ReferencesResolver::endVisit(VariableDeclaration const& _variable) auto const& contract = dynamic_cast<ContractDefinition const&>(*_variable.scope()->scope()); // force locations of public or external function (return) parameters to memory if (loc == Location::Storage && !contract.isLibrary()) - fatalTypeError(_variable.location(), + TypeFatalError(_variable.location(), "Location has to be memory for publicly visible functions " "(remove the \"storage\" keyword)." ); @@ -127,7 +120,7 @@ void ReferencesResolver::endVisit(VariableDeclaration const& _variable) if (_variable.isConstant()) { if (loc != Location::Default && loc != Location::Memory) - fatalTypeError( + TypeFatalError( _variable.location(), "Storage location has to be \"memory\" (or unspecified) for constants." ); @@ -145,14 +138,14 @@ void ReferencesResolver::endVisit(VariableDeclaration const& _variable) } } else if (loc != Location::Default && !ref) - fatalTypeError(_variable.location(), "Storage location can only be given for array or struct types."); + TypeFatalError(_variable.location(), "Storage location can only be given for array or struct types."); if (!type) - fatalTypeError(_variable.location(), "Invalid type name."); + TypeFatalError(_variable.location(), "Invalid type name."); } else if (!_variable.canHaveAutoType()) - fatalTypeError(_variable.location(), "Explicit type needed."); + TypeFatalError(_variable.location(), "Explicit type needed."); // otherwise we have a "var"-declaration whose type is resolved by the first assignment _variable.annotation().type = type; @@ -178,7 +171,7 @@ TypePointer ReferencesResolver::typeFor(TypeName const& _typeName) else if (ContractDefinition const* contract = dynamic_cast<ContractDefinition const*>(declaration)) type = make_shared<ContractType>(*contract); else - fatalTypeError(typeName->location(), "Name has to refer to a struct, enum or contract."); + TypeFatalError(typeName->location(), "Name has to refer to a struct, enum or contract."); } else if (auto mapping = dynamic_cast<Mapping const*>(&_typeName)) { @@ -194,7 +187,7 @@ TypePointer ReferencesResolver::typeFor(TypeName const& _typeName) { TypePointer baseType = typeFor(arrayType->baseType()); if (baseType->storageBytes() == 0) - fatalTypeError(arrayType->location(), "Illegal base type of storage size zero for array."); + TypeFatalError(arrayType->baseType().location(), "Illegal base type of storage size zero for array."); if (Expression const* length = arrayType->length()) { if (!length->annotation().type) @@ -202,8 +195,8 @@ TypePointer ReferencesResolver::typeFor(TypeName const& _typeName) auto const* lengthType = dynamic_cast<IntegerConstantType const*>(length->annotation().type.get()); if (!lengthType) - fatalTypeError(length->location(), "Invalid array length."); - type = make_shared<ArrayType>(DataLocation::Storage, baseType, lengthType->literalValue(nullptr)); + TypeFatalError(length->location(), "Invalid array length."); + else type = make_shared<ArrayType>(DataLocation::Storage, baseType, lengthType->literalValue(nullptr)); } else type = make_shared<ArrayType>(DataLocation::Storage, baseType); @@ -212,18 +205,31 @@ TypePointer ReferencesResolver::typeFor(TypeName const& _typeName) return _typeName.annotation().type = move(type); } -void ReferencesResolver::typeError(SourceLocation const& _location, string const& _description) +void ReferencesResolver::TypeError(SourceLocation const& _location, string const& _description) { auto err = make_shared<Error>(Error::Type::TypeError); *err << errinfo_sourceLocation(_location) << errinfo_comment(_description); - + m_errorOccurred = true; m_errors.push_back(err); } -void ReferencesResolver::fatalTypeError(SourceLocation const& _location, string const& _description) +void ReferencesResolver::TypeFatalError(SourceLocation const& _location, string const& _description) { - typeError(_location, _description); + TypeError(_location, _description); BOOST_THROW_EXCEPTION(FatalError()); } +void ReferencesResolver::DeclarationError(SourceLocation const& _location, string const& _description) +{ + auto err = make_shared<Error>(Error::Type::DeclarationError); + *err << errinfo_sourceLocation(_location) << errinfo_comment(_description); + m_errorOccurred = true; + m_errors.push_back(err); +} + +void ReferencesResolver::DeclarationFatalError(SourceLocation const& _location, string const& _description) +{ + DeclarationError(_location, _description); + BOOST_THROW_EXCEPTION(FatalError()); +} diff --git a/libsolidity/analysis/ReferencesResolver.h b/libsolidity/analysis/ReferencesResolver.h index 34e68054..237d01a0 100644 --- a/libsolidity/analysis/ReferencesResolver.h +++ b/libsolidity/analysis/ReferencesResolver.h @@ -60,7 +60,7 @@ public: bool resolve(ASTNode& _root) { _root.accept(*this); - return Error::containsOnlyWarnings(m_errors); + return !m_errorOccurred; } private: @@ -73,16 +73,23 @@ private: TypePointer typeFor(TypeName const& _typeName); /// Adds a new error to the list of errors. - void typeError(SourceLocation const& _location, std::string const& _description); + void TypeError(SourceLocation const& _location, std::string const& _description); /// Adds a new error to the list of errors and throws to abort type checking. - void fatalTypeError(SourceLocation const& _location, std::string const& _description); + void TypeFatalError(SourceLocation const& _location, std::string const& _description); + + /// Adds a new error to the list of errors. + void DeclarationError(const SourceLocation& _location, std::string const& _description); + + /// Adds a new error to the list of errors and throws to abort type checking. + void DeclarationFatalError(const SourceLocation& _location, std::string const& _description); ErrorList& m_errors; NameAndTypeResolver& m_resolver; ContractDefinition const* m_currentContract; ParameterList const* m_returnParameters; - bool m_resolveInsideCode; + bool const m_resolveInsideCode; + bool m_errorOccurred = false; }; } |