Uninitialized variables; Clarify warnings, bailout for binary & to avoid FPs

This commit is contained in:
Daniel Marjamäki 2021-05-17 09:22:19 +02:00
parent 224492b0b5
commit 16ce0f1dbf
2 changed files with 17 additions and 11 deletions

View File

@ -802,10 +802,10 @@ bool CheckUninitVar::checkIfForWhileHead(const Token *startparentheses, const Va
continue; continue;
} }
if (isVariableUsage(tok, var.isPointer(), alloc)) { if (const Token *errorToken = isVariableUsage(tok, var.isPointer(), alloc)) {
if (suppressErrors) if (suppressErrors)
continue; continue;
uninitvarError(tok, tok->str(), alloc); uninitvarError(errorToken, errorToken->expressionString(), alloc);
} }
return true; return true;
} }
@ -920,8 +920,8 @@ const Token* CheckUninitVar::checkLoopBodyRecursive(const Token *start, const Va
return nullptr; return nullptr;
} }
} else { } else {
if (isVariableUsage(tok, var.isPointer(), alloc)) if (const Token *errorToken = isVariableUsage(tok, var.isPointer(), alloc))
return tok; return errorToken;
else if (tok->strAt(1) == "=") { else if (tok->strAt(1) == "=") {
bool varIsUsedInRhs = false; bool varIsUsedInRhs = false;
visitAstNodes(tok->next()->astOperand2(), [&](const Token * t) { visitAstNodes(tok->next()->astOperand2(), [&](const Token * t) {
@ -1069,6 +1069,10 @@ const Token* CheckUninitVar::isVariableUsage(const Token *vartok, bool pointer,
if (derefValue && derefValue->astParent() && derefValue->astParent()->isUnaryOp("&")) if (derefValue && derefValue->astParent() && derefValue->astParent()->isUnaryOp("&"))
return nullptr; return nullptr;
// BAILOUT for binary &
if (Token::simpleMatch(valueExpr->astParent(), "&") && astIsRhs(valueExpr) && Token::Match(valueExpr->astParent()->tokAt(-3), "( %name% ) &"))
return nullptr;
// safe operations // safe operations
if (isVoidCast(valueExpr->astParent())) if (isVoidCast(valueExpr->astParent()))
return nullptr; return nullptr;

View File

@ -1698,7 +1698,7 @@ private:
" char *p = (char*)malloc(64);\n" " char *p = (char*)malloc(64);\n"
" if (p[0]) { }\n" " if (p[0]) { }\n"
"}"); "}");
ASSERT_EQUALS("[test.cpp:3]: (error) Memory is allocated but not initialized: p\n", errout.str()); ASSERT_EQUALS("[test.cpp:3]: (error) Memory is allocated but not initialized: p[0]\n", errout.str());
checkUninitVar("char f() {\n" checkUninitVar("char f() {\n"
" char *p = (char*)malloc(64);\n" " char *p = (char*)malloc(64);\n"
@ -1787,9 +1787,11 @@ private:
checkUninitVar("void f()\n" checkUninitVar("void f()\n"
"{\n" "{\n"
" char *s = (char*)malloc(100);\n" " char *s = (char*)malloc(100);\n"
" if (!s) {}\n" " if (!s)\n"
"};"); " return;\n"
ASSERT_EQUALS("", errout.str()); " char c = *s;\n"
"}");
TODO_ASSERT_EQUALS("[test.cpp:6]: (error) Memory is allocated but not initialized: s\n", "", errout.str());
// #3708 - false positive when using ptr typedef // #3708 - false positive when using ptr typedef
checkUninitVar("void f() {\n" checkUninitVar("void f() {\n"
@ -2748,7 +2750,7 @@ private:
" int done;\n" " int done;\n"
" dostuff(1, (AuPointer) &done);\n" // <- It is not conclusive if the "&" is a binary or unary operator. Bailout. " dostuff(1, (AuPointer) &done);\n" // <- It is not conclusive if the "&" is a binary or unary operator. Bailout.
"}"); "}");
// FP ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
checkUninitVar("void f() {\n" // #4778 - cast address of uninitialized variable checkUninitVar("void f() {\n" // #4778 - cast address of uninitialized variable
" long a;\n" " long a;\n"
@ -3324,7 +3326,7 @@ private:
" ab.a = (addr)&x;\n" " ab.a = (addr)&x;\n"
" dostuff(&ab,0);\n" " dostuff(&ab,0);\n"
"}\n", "test.c"); "}\n", "test.c");
// FP ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
checkUninitVar("struct Element {\n" checkUninitVar("struct Element {\n"
" static void f() { }\n" " static void f() { }\n"
@ -3939,7 +3941,7 @@ private:
" while(*p && *p == '_')\n" " while(*p && *p == '_')\n"
" p++;\n" " p++;\n"
"}"); "}");
ASSERT_EQUALS("[test.cpp:3]: (error) Memory is allocated but not initialized: p\n", errout.str()); ASSERT_EQUALS("[test.cpp:3]: (error) Memory is allocated but not initialized: *p\n", errout.str());
// #6646 - init in for loop // #6646 - init in for loop
checkUninitVar("void f() {\n" // No FP checkUninitVar("void f() {\n" // No FP