Reviewed handling of unknown types in C files in UninitVar

This commit is contained in:
Daniel Marjamäki 2012-06-22 19:57:07 +02:00
parent abaa044e03
commit d2dbaca24b
2 changed files with 21 additions and 12 deletions

View File

@ -42,8 +42,8 @@ namespace {
class UninitVar : public ExecutionPath { class UninitVar : public ExecutionPath {
public: public:
/** Startup constructor */ /** Startup constructor */
explicit UninitVar(Check *c, const SymbolDatabase* db) explicit UninitVar(Check *c, const SymbolDatabase* db, bool isc)
: ExecutionPath(c, 0), symbolDatabase(db), var(0), alloc(false), strncpy_(false), memset_nonzero(false) { : ExecutionPath(c, 0), symbolDatabase(db), isC(isc), var(0), alloc(false), strncpy_(false), memset_nonzero(false) {
} }
private: private:
@ -56,8 +56,8 @@ private:
void operator=(const UninitVar &); void operator=(const UninitVar &);
/** internal constructor for creating extra checks */ /** internal constructor for creating extra checks */
UninitVar(Check *c, const Variable* v, const SymbolDatabase* db) UninitVar(Check *c, const Variable* v, const SymbolDatabase* db, bool isc)
: ExecutionPath(c, v->varId()), symbolDatabase(db), var(v), alloc(false), strncpy_(false), memset_nonzero(false) { : ExecutionPath(c, v->varId()), symbolDatabase(db), isC(isc), var(v), alloc(false), strncpy_(false), memset_nonzero(false) {
} }
/** is other execution path equal? */ /** is other execution path equal? */
@ -69,6 +69,8 @@ private:
/** pointer to symbol database */ /** pointer to symbol database */
const SymbolDatabase* symbolDatabase; const SymbolDatabase* symbolDatabase;
const bool isC;
/** variable for this check */ /** variable for this check */
const Variable* var; const Variable* var;
@ -408,17 +410,17 @@ private:
} }
if (var2->isPointer()) if (var2->isPointer())
checks.push_back(new UninitVar(owner, var2, symbolDatabase)); checks.push_back(new UninitVar(owner, var2, symbolDatabase, isC));
else if (var2->typeEndToken()->str() != ">") { else if (var2->typeEndToken()->str() != ">") {
bool b = false; bool stdtype = isC;
for (const Token* tok2 = var2->typeStartToken(); tok2 != var2->nameToken(); tok2 = tok2->next()) { for (const Token* tok2 = var2->typeStartToken(); tok2 != var2->nameToken(); tok2 = tok2->next()) {
if (tok2->isStandardType()) { if (tok2->isStandardType()) {
b = true; stdtype = true;
break; break;
} }
} }
if (b && (!var2->isArray() || var2->nameToken()->linkAt(1)->strAt(1) == ";")) if (stdtype && (!var2->isArray() || var2->nameToken()->linkAt(1)->strAt(1) == ";"))
checks.push_back(new UninitVar(owner, var2, symbolDatabase)); checks.push_back(new UninitVar(owner, var2, symbolDatabase, isC));
} }
return &tok; return &tok;
} }
@ -1013,7 +1015,7 @@ void CheckUninitVar::executionPaths()
if (_settings->_jobs == 1) if (_settings->_jobs == 1)
UninitVar::analyseFunctions(_tokenizer->tokens(), UninitVar::uvarFunctions); UninitVar::analyseFunctions(_tokenizer->tokens(), UninitVar::uvarFunctions);
UninitVar c(this, _tokenizer->getSymbolDatabase()); UninitVar c(this, _tokenizer->getSymbolDatabase(), _tokenizer->isC());
checkExecutionPaths(_tokenizer->getSymbolDatabase(), &c); checkExecutionPaths(_tokenizer->getSymbolDatabase(), &c);
} }
} }

View File

@ -58,7 +58,7 @@ private:
TEST_CASE(uninitvar6); // handling unknown types in C and C++ files TEST_CASE(uninitvar6); // handling unknown types in C and C++ files
} }
void checkUninitVar(const char code[]) { void checkUninitVar(const char code[], const char filename[] = "test.cpp") {
// Clear the error buffer.. // Clear the error buffer..
errout.str(""); errout.str("");
@ -67,7 +67,7 @@ private:
// Tokenize.. // Tokenize..
Tokenizer tokenizer(&settings, this); Tokenizer tokenizer(&settings, this);
std::istringstream istr(code); std::istringstream istr(code);
tokenizer.tokenize(istr, "test.cpp"); tokenizer.tokenize(istr, filename);
tokenizer.simplifyTokenList(); tokenizer.simplifyTokenList();
// Check code.. // Check code..
@ -93,6 +93,13 @@ private:
"}\n"); "}\n");
ASSERT_EQUALS("[test.cpp:3]: (error) Uninitialized variable: a\n", errout.str()); ASSERT_EQUALS("[test.cpp:3]: (error) Uninitialized variable: a\n", errout.str());
checkUninitVar("void foo() {\n"
" dfs a;\n"
" b = c - a;\n"
"}\n",
"test.c");
ASSERT_EQUALS("[test.c:3]: (error) Uninitialized variable: a\n", errout.str());
checkUninitVar("void foo() {\n" checkUninitVar("void foo() {\n"
" int a;\n" " int a;\n"
" b = a - c;\n" " b = a - c;\n"