Fix 12033: false negative: uninitialized data passed as const data to function (#5747)
This commit is contained in:
parent
2af3b7bf44
commit
77157a678a
|
@ -2651,8 +2651,11 @@ bool isVariableChanged(const Token *tok, int indirect, const Settings *settings,
|
|||
const Token * ptok = tok2;
|
||||
while (Token::Match(ptok->astParent(), ".|::|["))
|
||||
ptok = ptok->astParent();
|
||||
int pindirect = indirect;
|
||||
if (indirect == 0 && astIsLHS(tok2) && Token::Match(ptok, ". %var%") && astIsPointer(ptok->next()))
|
||||
pindirect = 1;
|
||||
bool inconclusive = false;
|
||||
bool isChanged = isVariableChangedByFunctionCall(ptok, indirect, settings, &inconclusive);
|
||||
bool isChanged = isVariableChangedByFunctionCall(ptok, pindirect, settings, &inconclusive);
|
||||
isChanged |= inconclusive;
|
||||
if (isChanged)
|
||||
return true;
|
||||
|
@ -3257,6 +3260,8 @@ static ExprUsage getFunctionUsage(const Token* tok, int indirect, const Settings
|
|||
continue;
|
||||
if (arg->isReference())
|
||||
return ExprUsage::PassedByReference;
|
||||
if (arg->isPointer() && indirect == 1)
|
||||
return ExprUsage::PassedByReference;
|
||||
}
|
||||
if (!args.empty() && indirect == 0 && !addressOf)
|
||||
return ExprUsage::Used;
|
||||
|
@ -3301,6 +3306,8 @@ ExprUsage getExprUsage(const Token* tok, int indirect, const Settings* settings,
|
|||
parent = parent->astParent();
|
||||
if (Token::Match(parent, "%assign%") && (astIsRHS(tok) || astIsLHS(parent->astOperand1())))
|
||||
return ExprUsage::NotUsed;
|
||||
if (Token::Match(parent, "++|--"))
|
||||
return ExprUsage::NotUsed;
|
||||
if (parent->isConstOp())
|
||||
return ExprUsage::NotUsed;
|
||||
if (parent->isCast())
|
||||
|
|
|
@ -1642,12 +1642,7 @@ void CheckUninitVar::valueFlowUninit()
|
|||
const bool isarray = tok->variable()->isArray();
|
||||
if (isarray && tok->variable()->isMember())
|
||||
continue; // Todo: this is a bailout
|
||||
const bool ispointer = astIsPointer(tok) && !isarray;
|
||||
const bool deref = CheckNullPointer::isPointerDeRef(tok, unknown, mSettings);
|
||||
if (ispointer && v->indirect == 1 && !deref)
|
||||
continue;
|
||||
if (isarray && !deref)
|
||||
continue;
|
||||
uninitderef = deref && v->indirect == 0;
|
||||
const bool isleaf = isLeafDot(tok) || uninitderef;
|
||||
if (!isleaf && Token::Match(tok->astParent(), ". %name%") && (tok->astParent()->next()->varId() || tok->astParent()->next()->isEnumerator()))
|
||||
|
|
|
@ -6313,7 +6313,7 @@ private:
|
|||
" f(a, b);\n"
|
||||
" printf(\"%s\", a);\n"
|
||||
"}");
|
||||
ASSERT_EQUALS("[test.cpp:5]: (error) Uninitialized variable: a\n", errout.str());
|
||||
ASSERT_EQUALS("[test.cpp:4]: (error) Uninitialized variable: a\n", errout.str());
|
||||
|
||||
valueFlowUninit("void usage(const char *);\n" // #10330
|
||||
"int main(int argc, char* argv[]) {\n"
|
||||
|
@ -6334,6 +6334,14 @@ private:
|
|||
" if (pwd == NULL) {}\n"
|
||||
"}");
|
||||
ASSERT_EQUALS("[test.cpp:15] -> [test.cpp:17]: (warning) Uninitialized variable: pwd\n", errout.str());
|
||||
|
||||
// #12033
|
||||
valueFlowUninit("void g(const char*p);\n"
|
||||
"void f() {\n"
|
||||
" char buf[10];\n"
|
||||
" g(buf);\n"
|
||||
"}\n");
|
||||
ASSERT_EQUALS("[test.cpp:4]: (error) Uninitialized variable: buf\n", errout.str());
|
||||
}
|
||||
|
||||
void valueFlowUninitBreak() { // Do not show duplicate warnings about the same uninitialized value
|
||||
|
@ -6385,7 +6393,7 @@ private:
|
|||
" someType_t gVar;\n"
|
||||
" bar(&gVar);\n"
|
||||
"}");
|
||||
ASSERT_EQUALS("[test.cpp:9] -> [test.cpp:5]: (warning) Uninitialized variable: p->flags\n", errout.str());
|
||||
ASSERT_EQUALS("[test.cpp:9]: (error) Uninitialized variable: &gVar\n", errout.str());
|
||||
|
||||
valueFlowUninit("typedef struct\n"
|
||||
"{\n"
|
||||
|
@ -6917,7 +6925,7 @@ private:
|
|||
" foo(123, &abc);\n"
|
||||
" return abc.b;\n"
|
||||
"}");
|
||||
ASSERT_EQUALS("[test.cpp:6]: (error) Uninitialized variable: abc.b\n", errout.str());
|
||||
ASSERT_EQUALS("[test.cpp:5]: (error) Uninitialized variable: &abc\n", errout.str());
|
||||
|
||||
valueFlowUninit("struct ABC { int a; int b; int c; };\n"
|
||||
"void foo() {\n"
|
||||
|
|
Loading…
Reference in New Issue