From 0b81a267f41cbb9287bfe54170c3e6b9caad37a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Thu, 23 Jul 2015 14:51:38 +0200 Subject: [PATCH] uninitvar: handling arrays in non-executionpath checker --- lib/checkuninitvar.cpp | 17 ++++++- lib/checkuninitvar.h | 8 ++-- test/testuninitvar.cpp | 103 ++++++++++++++++++----------------------- 3 files changed, 65 insertions(+), 63 deletions(-) diff --git a/lib/checkuninitvar.cpp b/lib/checkuninitvar.cpp index da1f80b26..f756e1f62 100644 --- a/lib/checkuninitvar.cpp +++ b/lib/checkuninitvar.cpp @@ -1058,7 +1058,7 @@ void CheckUninitVar::checkScope(const Scope* scope) { for (std::list::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, ""); diff --git a/lib/checkuninitvar.h b/lib/checkuninitvar.h index 485ff2fca..4960ac99e 100644 --- a/lib/checkuninitvar.h +++ b/lib/checkuninitvar.h @@ -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); diff --git a/test/testuninitvar.cpp b/test/testuninitvar.cpp index e7ab9fdef..1db6d5b5b 100644 --- a/test/testuninitvar.cpp +++ b/test/testuninitvar.cpp @@ -1248,19 +1248,17 @@ private: "}"); ASSERT_EQUALS("[test.cpp:4]: (error) Uninitialized variable: a\n", errout.str()); - checkUninitVar("int f()\n" - "{\n" - " char a[10];\n" - " char c = *a;\n" - "}"); - ASSERT_EQUALS("[test.cpp:4]: (error) Uninitialized variable: a\n", errout.str()); + checkUninitVar2("int f() {\n" + " char a[10];\n" + " char c = *a;\n" + "}"); + ASSERT_EQUALS("[test.cpp:3]: (error) Uninitialized variable: a\n", errout.str()); - checkUninitVar("int f()\n" - "{\n" - " char a[SIZE+10];\n" - " char c = *a;\n" - "}"); - ASSERT_EQUALS("[test.cpp:4]: (error) Uninitialized variable: a\n", errout.str()); + checkUninitVar2("int f() {\n" + " char a[SIZE+10];\n" + " char c = *a;\n" + "}"); + 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" - " char s[20];\n" - " strcpy(s2, s);\n" - "};"); - ASSERT_EQUALS("[test.cpp:4]: (error) Uninitialized variable: s\n", errout.str()); + checkUninitVar2("void f() {\n" + " char s[20];\n" + " strcpy(s2, s);\n" + "};"); + ASSERT_EQUALS("[test.cpp:3]: (error) Uninitialized variable: s\n", errout.str()); - checkUninitVar("void f()\n" - "{\n" - " char s[20];\n" - " strcat(s, \"abc\");\n" - "};"); - ASSERT_EQUALS("[test.cpp:4]: (error) Uninitialized variable: s\n", errout.str()); + checkUninitVar2("void f() {\n" + " char s[20];\n" + " strcat(s, \"abc\");\n" + "};"); + ASSERT_EQUALS("[test.cpp:3]: (error) Uninitialized variable: s\n", errout.str()); - checkUninitVar("void f()\n" - "{\n" - " char s[20];\n" - " strchr(s, ' ');\n" - "};"); - ASSERT_EQUALS("[test.cpp:4]: (error) Uninitialized variable: s\n", errout.str()); + checkUninitVar2("void f() {\n" + " char s[20];\n" + " strchr(s, ' ');\n" + "};"); + 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" - " char *strMsg = \"This is a message\";\n" - " char *buffer=(char*)malloc(128*sizeof(char));\n" - " strcpy(strMsg,buffer);\n" - " free(buffer);\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,10 +1415,10 @@ private: "}"); ASSERT_EQUALS("[test.cpp:3]: (error) Uninitialized variable: a\n", errout.str()); - checkUninitVar2("int foo() {\n" - " int a[2][2];\n" - " return a[0][1];\n" - "}"); + checkUninitVar("int foo() {\n" + " int a[2][2];\n" + " return a[0][1];\n" + "}"); TODO_ASSERT_EQUALS("[test.cpp:3]: (error) Uninitialized variable: a\n", "", errout.str()); // # 4740 @@ -1436,25 +1431,17 @@ private: // alloc.. void uninitvar_alloc() { - checkUninitVar("void f()\n" - "{\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()); + checkUninitVar2("void f() {\n" + " char *s = malloc(100);\n" + " strcat(s, \"abc\");\n" + "};"); + 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" - "{\n" - " char *s1 = new char[10];\n" - " char *s2 = new char[strlen(s1)];\n" - "};"); + checkUninitVar2("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()); checkUninitVar("void f()\n"