Uninitialized member variables: Improvements
This commit is contained in:
parent
d87d54339d
commit
2c6b383822
|
@ -1082,7 +1082,7 @@ void CheckUninitVar::checkScope(const Scope* scope)
|
|||
tok = tok->next();
|
||||
if (stdtype || i->isPointer())
|
||||
checkScopeForVariable(scope, tok, *i, NULL, NULL, NULL);
|
||||
if (_settings->experimental && Token::Match(i->typeStartToken(), "struct %type% %var% ;")) {
|
||||
if (_settings->experimental && _settings->isEnabled("style") && Token::Match(i->typeStartToken(), "struct %type% %var% ;")) {
|
||||
const std::string structname(i->typeStartToken()->next()->str());
|
||||
const SymbolDatabase * symbolDatabase = _tokenizer->getSymbolDatabase();
|
||||
for (std::size_t j = 0U; j < symbolDatabase->classAndStructScopes.size(); ++j) {
|
||||
|
@ -1343,12 +1343,14 @@ bool CheckUninitVar::checkScopeForVariable(const Scope* scope, const Token *tok,
|
|||
// variable is seen..
|
||||
if (tok->varId() == var.varId()) {
|
||||
if (membervar) {
|
||||
if (Token::Match(tok, "%var% . %var% =") && tok->strAt(2) == membervar->name())
|
||||
if (Token::Match(tok, "%var% . %var% [=.[]") && tok->strAt(2) == membervar->name())
|
||||
return true;
|
||||
else if (Token::Match(tok, "%var% ="))
|
||||
else if (tok->strAt(1) == "=")
|
||||
return true;
|
||||
else if (tok->strAt(-1) == "&")
|
||||
return true;
|
||||
else if (Token::Match(tok->previous(), "[(,] %var% [,)]") && isVariableUsage(scope, tok, var.isPointer()))
|
||||
uninitvarError(tok, tok->str() + "." + membervar->name());
|
||||
uninitStructMemberError(tok, tok->str() + "." + membervar->name());
|
||||
} else {
|
||||
// Use variable
|
||||
if (!suppressErrors && isVariableUsage(scope, tok, var.isPointer()))
|
||||
|
@ -1512,3 +1514,14 @@ void CheckUninitVar::uninitvarError(const Token *tok, const std::string &varname
|
|||
{
|
||||
reportError(tok, Severity::error, "uninitvar", "Uninitialized variable: " + varname);
|
||||
}
|
||||
|
||||
void CheckUninitVar::uninitStructMemberError(const Token *tok, const std::string &membername)
|
||||
{
|
||||
reportError(tok,
|
||||
Severity::warning,
|
||||
"uninitStructMember",
|
||||
"Perhaps '" + membername + "' should be initialized before calling function.\n"
|
||||
"The struct is not fully initialized, '" + membername + "' hasn't been initialized. "
|
||||
"Using the struct in function call might be dangerous, unless you know for sure that the member "
|
||||
"will not be used by the function.");
|
||||
}
|
||||
|
|
|
@ -85,6 +85,7 @@ public:
|
|||
void uninitstringError(const Token *tok, const std::string &varname, bool strncpy_);
|
||||
void uninitdataError(const Token *tok, const std::string &varname);
|
||||
void uninitvarError(const Token *tok, const std::string &varname);
|
||||
void uninitStructMemberError(const Token *tok, const std::string &membername);
|
||||
|
||||
private:
|
||||
void getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) const {
|
||||
|
@ -94,6 +95,7 @@ private:
|
|||
c.uninitstringError(0, "varname", true);
|
||||
c.uninitdataError(0, "varname");
|
||||
c.uninitvarError(0, "varname");
|
||||
c.uninitStructMemberError(0, "a.b");
|
||||
}
|
||||
|
||||
static std::string myName() {
|
||||
|
|
|
@ -1944,6 +1944,7 @@ private:
|
|||
|
||||
Settings settings;
|
||||
settings.experimental = experimental;
|
||||
settings.addEnabled("style");
|
||||
|
||||
// Tokenize..
|
||||
Tokenizer tokenizer(&settings, this);
|
||||
|
@ -2561,7 +2562,7 @@ private:
|
|||
" ab.a = 0;\n"
|
||||
" do_something(ab);\n"
|
||||
"}\n", "test.c", true);
|
||||
ASSERT_EQUALS("[test.c:6]: (error) Uninitialized variable: ab.b\n", errout.str());
|
||||
ASSERT_EQUALS("[test.c:6]: (warning) Perhaps 'ab.b' should be initialized before calling function.\n", errout.str());
|
||||
|
||||
checkUninitVar2("struct AB { int a; int b; };\n"
|
||||
"void do_something(const struct AB ab);\n"
|
||||
|
@ -2581,6 +2582,30 @@ private:
|
|||
" do_something(ab);\n"
|
||||
"}\n", "test.c", true);
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
|
||||
checkUninitVar2("struct AB { int a; struct { int b; int c; } s; };\n"
|
||||
"void do_something(const struct AB ab);\n"
|
||||
"void f(void) {\n"
|
||||
" struct AB ab;\n"
|
||||
" ab.a = 1;\n"
|
||||
" ab.s.b = 2;\n"
|
||||
" ab.s.c = 3;\n"
|
||||
" do_something(ab);\n"
|
||||
"}\n", "test.c", true);
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
|
||||
checkUninitVar2("struct conf {\n"
|
||||
" char x;\n"
|
||||
"};\n"
|
||||
"\n"
|
||||
"void do_something(struct conf ant_conf);\n"
|
||||
"\n"
|
||||
"void f(void) {\n"
|
||||
" struct conf c;\n"
|
||||
" initdata(&c);\n"
|
||||
" do_something(c);\n"
|
||||
"}\n", "test.c", true);
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
}
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in New Issue