diff options
author | LianaHus <liana@ethdev.com> | 2015-09-30 00:22:02 +0800 |
---|---|---|
committer | LianaHus <liana@ethdev.com> | 2015-10-02 18:38:48 +0800 |
commit | fe2b9a3b3c73b77069a0d6d36578f60e1f8d4203 (patch) | |
tree | cd45a044bd7c408df1ca954fb0d77530f1a8a81f | |
parent | 6712437e6b65871787c9860168515b38a7751afc (diff) | |
download | dexon-solidity-fe2b9a3b3c73b77069a0d6d36578f60e1f8d4203.tar dexon-solidity-fe2b9a3b3c73b77069a0d6d36578f60e1f8d4203.tar.gz dexon-solidity-fe2b9a3b3c73b77069a0d6d36578f60e1f8d4203.tar.bz2 dexon-solidity-fe2b9a3b3c73b77069a0d6d36578f60e1f8d4203.tar.lz dexon-solidity-fe2b9a3b3c73b77069a0d6d36578f60e1f8d4203.tar.xz dexon-solidity-fe2b9a3b3c73b77069a0d6d36578f60e1f8d4203.tar.zst dexon-solidity-fe2b9a3b3c73b77069a0d6d36578f60e1f8d4203.zip |
added warning for noninitialized references in storage.
-rw-r--r-- | libsolidity/Exceptions.h | 3 | ||||
-rw-r--r-- | libsolidity/TypeChecker.cpp | 22 | ||||
-rw-r--r-- | libsolidity/TypeChecker.h | 7 | ||||
-rw-r--r-- | test/libsolidity/SolidityNameAndTypeResolution.cpp | 32 |
4 files changed, 49 insertions, 15 deletions
diff --git a/libsolidity/Exceptions.h b/libsolidity/Exceptions.h index 645b368f..8ab33999 100644 --- a/libsolidity/Exceptions.h +++ b/libsolidity/Exceptions.h @@ -31,13 +31,13 @@ namespace dev { namespace solidity { - struct Error: virtual Exception {}; struct ParserError: virtual Error {}; struct TypeError: virtual Error {}; struct DeclarationError: virtual Error {}; struct DocstringParsingError: virtual Error {}; +struct Warning: virtual Error {}; struct CompilerError: virtual Exception {}; struct InternalCompilerError: virtual Exception {}; @@ -53,7 +53,6 @@ public: infos.push_back(std::make_pair(_errMsg, _sourceLocation)); return *this; } - std::vector<errorSourceLocationInfo> infos; }; diff --git a/libsolidity/TypeChecker.cpp b/libsolidity/TypeChecker.cpp index f453e2fa..3fcedbda 100644 --- a/libsolidity/TypeChecker.cpp +++ b/libsolidity/TypeChecker.cpp @@ -43,8 +43,14 @@ bool TypeChecker::checkTypeRequirements(const ContractDefinition& _contract) if (m_errors.empty()) throw; // Something is weird here, rather throw again. } - - return m_errors.empty(); + bool success = m_errors.empty(); + for (auto const& it: m_errors) + if (!dynamic_cast<Warning const*>(it.get())) + { + success = false; + break; + } + return success; } TypePointer const& TypeChecker::type(Expression const& _expression) const @@ -443,6 +449,18 @@ bool TypeChecker::visit(VariableDeclaration const& _variable) { if (_variable.value()) expectType(*_variable.value(), *varType); + else + { + if (auto ref = dynamic_cast<ReferenceType const *>(varType.get())) + if (ref->dataStoredIn(DataLocation::Storage) && _variable.isLocalVariable() && !_variable.isCallableParameter()) + { + auto err = make_shared<Warning>(); + *err << + errinfo_sourceLocation(_variable.location()) << + errinfo_comment("Uninitialized storage pointer. Did you mean '" + varType->toString(true) + " memory'?"); + m_errors.push_back(err); + } + } } else { diff --git a/libsolidity/TypeChecker.h b/libsolidity/TypeChecker.h index cc539e22..150f0a56 100644 --- a/libsolidity/TypeChecker.h +++ b/libsolidity/TypeChecker.h @@ -43,10 +43,10 @@ class TypeChecker: private ASTConstVisitor { public: /// Performs type checking on the given contract and all of its sub-nodes. - /// @returns true iff all checks passed. + /// @returns true iff all checks passed. Note even if all checks passed, errors() can still contain warnings bool checkTypeRequirements(ContractDefinition const& _contract); - /// @returns the list of errors found during type checking. + /// @returns the list of errors and warnings found during type checking. std::vector<std::shared_ptr<Error const>> const& errors() const { return m_errors; } /// @returns the type of an expression and asserts that it is present. @@ -57,6 +57,9 @@ public: /// Adds a new error to the list of errors. void typeError(ASTNode const& _node, std::string const& _description); + /// Adds a new warning to the list of errors. + void typeWarning(ASTNode const& _node, std::string const& _description); + /// Adds a new error to the list of errors and throws to abort type checking. void fatalTypeError(ASTNode const& _node, std::string const& _description); diff --git a/test/libsolidity/SolidityNameAndTypeResolution.cpp b/test/libsolidity/SolidityNameAndTypeResolution.cpp index fd908955..ad7b59ce 100644 --- a/test/libsolidity/SolidityNameAndTypeResolution.cpp +++ b/test/libsolidity/SolidityNameAndTypeResolution.cpp @@ -45,7 +45,7 @@ namespace { pair<ASTPointer<SourceUnit>, shared_ptr<Exception const>> -parseAnalyseAndReturnError(string const& _source) +parseAnalyseAndReturnError(string const& _source, bool _warning = false) { Parser parser; ASTPointer<SourceUnit> sourceUnit; @@ -74,7 +74,19 @@ parseAnalyseAndReturnError(string const& _source) TypeChecker typeChecker; if (!typeChecker.checkTypeRequirements(*contract)) { - err = typeChecker.errors().front(); + for (auto const& firstError: typeChecker.errors()) + { + if (!dynamic_pointer_cast<Warning const>(firstError)) + { + err = firstError; + break; + } + else if (_warning) + { + err = firstError; + break; + } + } break; } } @@ -101,9 +113,9 @@ ASTPointer<SourceUnit> parseAndAnalyse(string const& _source) return sourceAndError.first; } -shared_ptr<Exception const> parseAndAnalyseReturnError(std::string const& _source) +shared_ptr<Exception const> parseAndAnalyseReturnError(std::string const& _source, bool _warning = false) { - auto sourceAndError = parseAnalyseAndReturnError(_source); + auto sourceAndError = parseAnalyseAndReturnError(_source, _warning); BOOST_REQUIRE(!!sourceAndError.second); return sourceAndError.second; } @@ -119,8 +131,10 @@ static ContractDefinition const* retrieveContract(ASTPointer<SourceUnit> _source return nullptr; } -static FunctionTypePointer const& retrieveFunctionBySignature(ContractDefinition const* _contract, - std::string const& _signature) +static FunctionTypePointer const& retrieveFunctionBySignature( + ContractDefinition const* _contract, + std::string const& _signature +) { FixedHash<4> hash(dev::sha3(_signature)); return _contract->interfaceFunctions()[hash]; @@ -155,8 +169,8 @@ BOOST_AUTO_TEST_CASE(double_stateVariable_declaration) BOOST_AUTO_TEST_CASE(double_function_declaration) { char const* text = "contract test {\n" - " function fun() { var x; }\n" - " function fun() { var x; }\n" + " function fun() { uint x; }\n" + " function fun() { uint x; }\n" "}\n"; SOLIDITY_CHECK_ERROR_TYPE(parseAndAnalyseReturnError(text), DeclarationError); } @@ -2333,7 +2347,7 @@ BOOST_AUTO_TEST_CASE(non_initialized_references) } } )"; - SOLIDITY_CHECK_ERROR_TYPE(parseAndAnalyseReturnError(text), TypeError); + SOLIDITY_CHECK_ERROR_TYPE(parseAndAnalyseReturnError(text, true), Warning); } BOOST_AUTO_TEST_SUITE_END() |