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) {
|
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) ||
|
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;
|
continue;
|
||||||
|
|
||||||
// don't warn for try/catch exception variable
|
// don't warn for try/catch exception variable
|
||||||
|
@ -1077,18 +1077,33 @@ void CheckUninitVar::checkScope(const Scope* scope)
|
||||||
continue;
|
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();
|
bool stdtype = _tokenizer->isC();
|
||||||
const Token* tok = i->typeStartToken();
|
const Token* tok = i->typeStartToken();
|
||||||
for (; tok && tok->str() != ";" && tok->str() != "<"; tok = tok->next()) {
|
for (; tok && tok->str() != ";" && tok->str() != "<"; tok = tok->next()) {
|
||||||
if (tok->isStandardType())
|
if (tok->isStandardType())
|
||||||
stdtype = true;
|
stdtype = true;
|
||||||
}
|
}
|
||||||
|
if (i->isArray() && !stdtype)
|
||||||
|
continue;
|
||||||
|
|
||||||
while (tok && tok->str() != ";")
|
while (tok && tok->str() != ";")
|
||||||
tok = tok->next();
|
tok = tok->next();
|
||||||
if (!tok)
|
if (!tok)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
if (i->isArray()) {
|
||||||
|
Alloc alloc = ARRAY;
|
||||||
|
checkScopeForVariable(tok, *i, nullptr, nullptr, &alloc, "");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
if (stdtype || i->isPointer()) {
|
if (stdtype || i->isPointer()) {
|
||||||
Alloc alloc = NO_ALLOC;
|
Alloc alloc = NO_ALLOC;
|
||||||
checkScopeForVariable(tok, *i, nullptr, nullptr, &alloc, "");
|
checkScopeForVariable(tok, *i, nullptr, nullptr, &alloc, "");
|
||||||
|
|
|
@ -57,7 +57,7 @@ public:
|
||||||
void check();
|
void check();
|
||||||
void checkScope(const Scope* scope);
|
void checkScope(const Scope* scope);
|
||||||
void checkStruct(const Token *tok, const Variable &structvar);
|
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 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 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);
|
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 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);
|
||||||
void uninitvarError(const Token *tok, const std::string &varname, Alloc alloc) {
|
void uninitvarError(const Token *tok, const std::string &varname, Alloc alloc) {
|
||||||
if (alloc == NO_ALLOC)
|
if (alloc == NO_CTOR_CALL || alloc == CTOR_CALL)
|
||||||
uninitvarError(tok, varname);
|
|
||||||
else
|
|
||||||
uninitdataError(tok, varname);
|
uninitdataError(tok, varname);
|
||||||
|
else
|
||||||
|
uninitvarError(tok, varname);
|
||||||
}
|
}
|
||||||
void uninitStructMemberError(const Token *tok, const std::string &membername);
|
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());
|
ASSERT_EQUALS("[test.cpp:4]: (error) Uninitialized variable: a\n", errout.str());
|
||||||
|
|
||||||
checkUninitVar("int f()\n"
|
checkUninitVar2("int f() {\n"
|
||||||
"{\n"
|
" char a[10];\n"
|
||||||
" char a[10];\n"
|
" char c = *a;\n"
|
||||||
" char c = *a;\n"
|
"}");
|
||||||
"}");
|
ASSERT_EQUALS("[test.cpp:3]: (error) Uninitialized variable: a\n", errout.str());
|
||||||
ASSERT_EQUALS("[test.cpp:4]: (error) Uninitialized variable: a\n", errout.str());
|
|
||||||
|
|
||||||
checkUninitVar("int f()\n"
|
checkUninitVar2("int f() {\n"
|
||||||
"{\n"
|
" char a[SIZE+10];\n"
|
||||||
" char a[SIZE+10];\n"
|
" char c = *a;\n"
|
||||||
" char c = *a;\n"
|
"}");
|
||||||
"}");
|
ASSERT_EQUALS("[test.cpp:3]: (error) Uninitialized variable: a\n", errout.str());
|
||||||
ASSERT_EQUALS("[test.cpp:4]: (error) Uninitialized variable: a\n", errout.str());
|
|
||||||
|
|
||||||
checkUninitVarB("int f()\n"
|
checkUninitVarB("int f()\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
|
@ -1304,26 +1302,23 @@ private:
|
||||||
"}");
|
"}");
|
||||||
ASSERT_EQUALS("", errout.str());
|
ASSERT_EQUALS("", errout.str());
|
||||||
|
|
||||||
checkUninitVar("void f()\n"
|
checkUninitVar2("void f() {\n"
|
||||||
"{\n"
|
" char s[20];\n"
|
||||||
" char s[20];\n"
|
" strcpy(s2, s);\n"
|
||||||
" strcpy(s2, s);\n"
|
"};");
|
||||||
"};");
|
ASSERT_EQUALS("[test.cpp:3]: (error) Uninitialized variable: s\n", errout.str());
|
||||||
ASSERT_EQUALS("[test.cpp:4]: (error) Uninitialized variable: s\n", errout.str());
|
|
||||||
|
|
||||||
checkUninitVar("void f()\n"
|
checkUninitVar2("void f() {\n"
|
||||||
"{\n"
|
" char s[20];\n"
|
||||||
" char s[20];\n"
|
" strcat(s, \"abc\");\n"
|
||||||
" strcat(s, \"abc\");\n"
|
"};");
|
||||||
"};");
|
ASSERT_EQUALS("[test.cpp:3]: (error) Uninitialized variable: s\n", errout.str());
|
||||||
ASSERT_EQUALS("[test.cpp:4]: (error) Uninitialized variable: s\n", errout.str());
|
|
||||||
|
|
||||||
checkUninitVar("void f()\n"
|
checkUninitVar2("void f() {\n"
|
||||||
"{\n"
|
" char s[20];\n"
|
||||||
" char s[20];\n"
|
" strchr(s, ' ');\n"
|
||||||
" strchr(s, ' ');\n"
|
"};");
|
||||||
"};");
|
ASSERT_EQUALS("[test.cpp:3]: (error) Uninitialized variable: s\n", errout.str());
|
||||||
ASSERT_EQUALS("[test.cpp:4]: (error) Uninitialized variable: s\n", errout.str());
|
|
||||||
|
|
||||||
checkUninitVarB("void foo()\n"
|
checkUninitVarB("void foo()\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
|
@ -1393,12 +1388,12 @@ private:
|
||||||
ASSERT_EQUALS("", errout.str());
|
ASSERT_EQUALS("", errout.str());
|
||||||
|
|
||||||
// ticket #3344
|
// ticket #3344
|
||||||
checkUninitVar("void f(){\n"
|
checkUninitVar2("void f(){\n"
|
||||||
" char *strMsg = \"This is a message\";\n"
|
" char *strMsg = \"This is a message\";\n"
|
||||||
" char *buffer=(char*)malloc(128*sizeof(char));\n"
|
" char *buffer=(char*)malloc(128*sizeof(char));\n"
|
||||||
" strcpy(strMsg,buffer);\n"
|
" strcpy(strMsg,buffer);\n"
|
||||||
" free(buffer);\n"
|
" free(buffer);\n"
|
||||||
"}");
|
"}", "test.cpp", false);
|
||||||
ASSERT_EQUALS("[test.cpp:4]: (error) Memory is allocated but not initialized: buffer\n", errout.str());
|
ASSERT_EQUALS("[test.cpp:4]: (error) Memory is allocated but not initialized: buffer\n", errout.str());
|
||||||
|
|
||||||
// #3845
|
// #3845
|
||||||
|
@ -1420,10 +1415,10 @@ private:
|
||||||
"}");
|
"}");
|
||||||
ASSERT_EQUALS("[test.cpp:3]: (error) Uninitialized variable: a\n", errout.str());
|
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"
|
" int a[2][2];\n"
|
||||||
" return a[0][1];\n"
|
" return a[0][1];\n"
|
||||||
"}");
|
"}");
|
||||||
TODO_ASSERT_EQUALS("[test.cpp:3]: (error) Uninitialized variable: a\n", "", errout.str());
|
TODO_ASSERT_EQUALS("[test.cpp:3]: (error) Uninitialized variable: a\n", "", errout.str());
|
||||||
|
|
||||||
// # 4740
|
// # 4740
|
||||||
|
@ -1436,25 +1431,17 @@ private:
|
||||||
|
|
||||||
// alloc..
|
// alloc..
|
||||||
void uninitvar_alloc() {
|
void uninitvar_alloc() {
|
||||||
checkUninitVar("void f()\n"
|
checkUninitVar2("void f() {\n"
|
||||||
"{\n"
|
" char *s = malloc(100);\n"
|
||||||
" char *s = malloc(100);\n"
|
" strcat(s, \"abc\");\n"
|
||||||
" strcat(s, \"abc\");\n"
|
"};");
|
||||||
"};");
|
ASSERT_EQUALS("[test.cpp:3]: (error) Memory is allocated but not initialized: s\n", errout.str());
|
||||||
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"
|
"{\n"
|
||||||
" char *s = malloc(100);\n"
|
" char *s1 = new char[10];\n"
|
||||||
" perror(s);\n"
|
" char *s2 = new char[strlen(s1)];\n"
|
||||||
"};");
|
"};");
|
||||||
ASSERT_EQUALS("[test.cpp:4]: (error) Memory is allocated but not initialized: s\n", errout.str());
|
|
||||||
|
|
||||||
checkUninitVar("void f()\n"
|
|
||||||
"{\n"
|
|
||||||
" char *s1 = new char[10];\n"
|
|
||||||
" char *s2 = new char[strlen(s1)];\n"
|
|
||||||
"};");
|
|
||||||
ASSERT_EQUALS("[test.cpp:4]: (error) Memory is allocated but not initialized: s1\n", errout.str());
|
ASSERT_EQUALS("[test.cpp:4]: (error) Memory is allocated but not initialized: s1\n", errout.str());
|
||||||
|
|
||||||
checkUninitVar("void f()\n"
|
checkUninitVar("void f()\n"
|
||||||
|
|
Loading…
Reference in New Issue