mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
added warning for noninitialized references in storage.
This commit is contained in:
parent
6712437e6b
commit
fe2b9a3b3c
@ -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;
|
||||
};
|
||||
|
||||
|
@ -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
|
||||
{
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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()
|
||||
|
Loading…
Reference in New Issue
Block a user