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

View File

@ -58,7 +58,7 @@ private:
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..
errout.str("");
@ -67,7 +67,7 @@ private:
// Tokenize..
Tokenizer tokenizer(&settings, this);
std::istringstream istr(code);
tokenizer.tokenize(istr, "test.cpp");
tokenizer.tokenize(istr, filename);
tokenizer.simplifyTokenList();
// Check code..
@ -93,6 +93,13 @@ private:
"}\n");
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"
" int a;\n"
" b = a - c;\n"