uninitvar: handling arrays in non-executionpath checker
This commit is contained in:
parent
ce9272a4ed
commit
0b81a267f4
|
@ -1058,7 +1058,7 @@ void CheckUninitVar::checkScope(const Scope* scope)
|
|||
{
|
||||
for (std::list<Variable>::const_iterator i = scope->varlist.begin(); i != scope->varlist.end(); ++i) {
|
||||
if ((_tokenizer->isCPP() && i->type() && !i->isPointer() && i->type()->needInitialization != Type::True) ||
|
||||
i->isStatic() || i->isExtern() || i->isArray() || i->isReference())
|
||||
i->isStatic() || i->isExtern() || i->isReference())
|
||||
continue;
|
||||
|
||||
// don't warn for try/catch exception variable
|
||||
|
@ -1077,18 +1077,33 @@ void CheckUninitVar::checkScope(const Scope* scope)
|
|||
continue;
|
||||
}
|
||||
|
||||
if (i->isArray()) {
|
||||
const Token *tok = i->nameToken()->next();
|
||||
while (Token::simpleMatch(tok->link(), "] ["))
|
||||
tok = tok->link()->next();
|
||||
if (Token::simpleMatch(tok->link(), "] ="))
|
||||
continue;
|
||||
}
|
||||
|
||||
bool stdtype = _tokenizer->isC();
|
||||
const Token* tok = i->typeStartToken();
|
||||
for (; tok && tok->str() != ";" && tok->str() != "<"; tok = tok->next()) {
|
||||
if (tok->isStandardType())
|
||||
stdtype = true;
|
||||
}
|
||||
if (i->isArray() && !stdtype)
|
||||
continue;
|
||||
|
||||
while (tok && tok->str() != ";")
|
||||
tok = tok->next();
|
||||
if (!tok)
|
||||
continue;
|
||||
|
||||
if (i->isArray()) {
|
||||
Alloc alloc = ARRAY;
|
||||
checkScopeForVariable(tok, *i, nullptr, nullptr, &alloc, "");
|
||||
continue;
|
||||
}
|
||||
if (stdtype || i->isPointer()) {
|
||||
Alloc alloc = NO_ALLOC;
|
||||
checkScopeForVariable(tok, *i, nullptr, nullptr, &alloc, "");
|
||||
|
|
|
@ -57,7 +57,7 @@ public:
|
|||
void check();
|
||||
void checkScope(const Scope* scope);
|
||||
void checkStruct(const Token *tok, const Variable &structvar);
|
||||
enum Alloc { NO_ALLOC, NO_CTOR_CALL, CTOR_CALL };
|
||||
enum Alloc { NO_ALLOC, NO_CTOR_CALL, CTOR_CALL, ARRAY };
|
||||
bool checkScopeForVariable(const Token *tok, const Variable& var, bool* const possibleInit, bool* const noreturn, Alloc* const alloc, const std::string &membervar);
|
||||
bool checkIfForWhileHead(const Token *startparentheses, const Variable& var, bool suppressErrors, bool isuninit, Alloc alloc, const std::string &membervar);
|
||||
bool checkLoopBody(const Token *tok, const Variable& var, const Alloc alloc, const std::string &membervar, const bool suppressErrors);
|
||||
|
@ -96,10 +96,10 @@ public:
|
|||
void uninitdataError(const Token *tok, const std::string &varname);
|
||||
void uninitvarError(const Token *tok, const std::string &varname);
|
||||
void uninitvarError(const Token *tok, const std::string &varname, Alloc alloc) {
|
||||
if (alloc == NO_ALLOC)
|
||||
uninitvarError(tok, varname);
|
||||
else
|
||||
if (alloc == NO_CTOR_CALL || alloc == CTOR_CALL)
|
||||
uninitdataError(tok, varname);
|
||||
else
|
||||
uninitvarError(tok, varname);
|
||||
}
|
||||
void uninitStructMemberError(const Token *tok, const std::string &membername);
|
||||
|
||||
|
|
|
@ -1248,19 +1248,17 @@ private:
|
|||
"}");
|
||||
ASSERT_EQUALS("[test.cpp:4]: (error) Uninitialized variable: a\n", errout.str());
|
||||
|
||||
checkUninitVar("int f()\n"
|
||||
"{\n"
|
||||
checkUninitVar2("int f() {\n"
|
||||
" char a[10];\n"
|
||||
" char c = *a;\n"
|
||||
"}");
|
||||
ASSERT_EQUALS("[test.cpp:4]: (error) Uninitialized variable: a\n", errout.str());
|
||||
ASSERT_EQUALS("[test.cpp:3]: (error) Uninitialized variable: a\n", errout.str());
|
||||
|
||||
checkUninitVar("int f()\n"
|
||||
"{\n"
|
||||
checkUninitVar2("int f() {\n"
|
||||
" char a[SIZE+10];\n"
|
||||
" char c = *a;\n"
|
||||
"}");
|
||||
ASSERT_EQUALS("[test.cpp:4]: (error) Uninitialized variable: a\n", errout.str());
|
||||
ASSERT_EQUALS("[test.cpp:3]: (error) Uninitialized variable: a\n", errout.str());
|
||||
|
||||
checkUninitVarB("int f()\n"
|
||||
"{\n"
|
||||
|
@ -1304,26 +1302,23 @@ private:
|
|||
"}");
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
|
||||
checkUninitVar("void f()\n"
|
||||
"{\n"
|
||||
checkUninitVar2("void f() {\n"
|
||||
" char s[20];\n"
|
||||
" strcpy(s2, s);\n"
|
||||
"};");
|
||||
ASSERT_EQUALS("[test.cpp:4]: (error) Uninitialized variable: s\n", errout.str());
|
||||
ASSERT_EQUALS("[test.cpp:3]: (error) Uninitialized variable: s\n", errout.str());
|
||||
|
||||
checkUninitVar("void f()\n"
|
||||
"{\n"
|
||||
checkUninitVar2("void f() {\n"
|
||||
" char s[20];\n"
|
||||
" strcat(s, \"abc\");\n"
|
||||
"};");
|
||||
ASSERT_EQUALS("[test.cpp:4]: (error) Uninitialized variable: s\n", errout.str());
|
||||
ASSERT_EQUALS("[test.cpp:3]: (error) Uninitialized variable: s\n", errout.str());
|
||||
|
||||
checkUninitVar("void f()\n"
|
||||
"{\n"
|
||||
checkUninitVar2("void f() {\n"
|
||||
" char s[20];\n"
|
||||
" strchr(s, ' ');\n"
|
||||
"};");
|
||||
ASSERT_EQUALS("[test.cpp:4]: (error) Uninitialized variable: s\n", errout.str());
|
||||
ASSERT_EQUALS("[test.cpp:3]: (error) Uninitialized variable: s\n", errout.str());
|
||||
|
||||
checkUninitVarB("void foo()\n"
|
||||
"{\n"
|
||||
|
@ -1393,12 +1388,12 @@ private:
|
|||
ASSERT_EQUALS("", errout.str());
|
||||
|
||||
// ticket #3344
|
||||
checkUninitVar("void f(){\n"
|
||||
checkUninitVar2("void f(){\n"
|
||||
" char *strMsg = \"This is a message\";\n"
|
||||
" char *buffer=(char*)malloc(128*sizeof(char));\n"
|
||||
" strcpy(strMsg,buffer);\n"
|
||||
" free(buffer);\n"
|
||||
"}");
|
||||
"}", "test.cpp", false);
|
||||
ASSERT_EQUALS("[test.cpp:4]: (error) Memory is allocated but not initialized: buffer\n", errout.str());
|
||||
|
||||
// #3845
|
||||
|
@ -1420,7 +1415,7 @@ private:
|
|||
"}");
|
||||
ASSERT_EQUALS("[test.cpp:3]: (error) Uninitialized variable: a\n", errout.str());
|
||||
|
||||
checkUninitVar2("int foo() {\n"
|
||||
checkUninitVar("int foo() {\n"
|
||||
" int a[2][2];\n"
|
||||
" return a[0][1];\n"
|
||||
"}");
|
||||
|
@ -1436,21 +1431,13 @@ private:
|
|||
|
||||
// alloc..
|
||||
void uninitvar_alloc() {
|
||||
checkUninitVar("void f()\n"
|
||||
"{\n"
|
||||
checkUninitVar2("void f() {\n"
|
||||
" char *s = malloc(100);\n"
|
||||
" strcat(s, \"abc\");\n"
|
||||
"};");
|
||||
ASSERT_EQUALS("[test.cpp:4]: (error) Memory is allocated but not initialized: s\n", errout.str());
|
||||
ASSERT_EQUALS("[test.cpp:3]: (error) Memory is allocated but not initialized: s\n", errout.str());
|
||||
|
||||
checkUninitVar("void f()\n"
|
||||
"{\n"
|
||||
" char *s = malloc(100);\n"
|
||||
" perror(s);\n"
|
||||
"};");
|
||||
ASSERT_EQUALS("[test.cpp:4]: (error) Memory is allocated but not initialized: s\n", errout.str());
|
||||
|
||||
checkUninitVar("void f()\n"
|
||||
checkUninitVar2("void f()\n"
|
||||
"{\n"
|
||||
" char *s1 = new char[10];\n"
|
||||
" char *s2 = new char[strlen(s1)];\n"
|
||||
|
|
Loading…
Reference in New Issue