aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLianaHus <liana@ethdev.com>2015-09-30 00:22:02 +0800
committerLianaHus <liana@ethdev.com>2015-10-02 18:38:48 +0800
commitfe2b9a3b3c73b77069a0d6d36578f60e1f8d4203 (patch)
treecd45a044bd7c408df1ca954fb0d77530f1a8a81f
parent6712437e6b65871787c9860168515b38a7751afc (diff)
downloaddexon-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.h3
-rw-r--r--libsolidity/TypeChecker.cpp22
-rw-r--r--libsolidity/TypeChecker.h7
-rw-r--r--test/libsolidity/SolidityNameAndTypeResolution.cpp32
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()