Fix issue 9190: FP uninitvar for struct member (#2112)
* Fix issue 9190: FP uninitvar for struct member * Add more test cases * Fix false negative
This commit is contained in:
parent
f25dcd5cda
commit
5c488b9519
|
@ -1334,9 +1334,11 @@ void CheckUninitVar::valueFlowUninit()
|
|||
const bool deref = CheckNullPointer::isPointerDeRef(tok, unknown, mSettings);
|
||||
if (v->indirect == 1 && !deref)
|
||||
continue;
|
||||
if (Token::Match(tok->astParent(), ". %var%") && !(isLeafDot(tok) || deref))
|
||||
const bool uninitderef = deref && v->indirect == 0;
|
||||
const bool isleaf = isLeafDot(tok) || uninitderef;
|
||||
if (Token::Match(tok->astParent(), ". %var%") && !isleaf)
|
||||
continue;
|
||||
if (!Token::Match(tok->astParent(), ". %name% (") && isVariableChanged(tok, mSettings, mTokenizer->isCPP()))
|
||||
if (!Token::Match(tok->astParent(), ". %name% (") && !uninitderef && isVariableChanged(tok, mSettings, mTokenizer->isCPP()))
|
||||
continue;
|
||||
uninitvarError(tok, tok->str(), v->errorPath);
|
||||
const Token * nextTok = tok;
|
||||
|
|
|
@ -1626,6 +1626,9 @@ void Token::printValueFlow(bool xml, std::ostream &out) const
|
|||
out << "lifetime=" << value.tokvalue->str();
|
||||
break;
|
||||
}
|
||||
if (value.indirect > 0)
|
||||
for(int i=0;i<value.indirect;i++)
|
||||
out << "*";
|
||||
}
|
||||
}
|
||||
if (xml)
|
||||
|
|
|
@ -2703,6 +2703,10 @@ static bool valueFlowForward(Token * const startToken,
|
|||
return false;
|
||||
}
|
||||
}
|
||||
// Variable changed
|
||||
if (isVariableChanged(tok2, settings, tokenlist->isCPP())) {
|
||||
values.remove_if(std::mem_fn(&ValueFlow::Value::isUninitValue));
|
||||
}
|
||||
}
|
||||
|
||||
// Lambda function
|
||||
|
@ -2716,6 +2720,7 @@ static bool valueFlowForward(Token * const startToken,
|
|||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -4064,7 +4064,6 @@ private:
|
|||
" return ostr.str();\n"
|
||||
"}\n");
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
|
||||
// #9281
|
||||
valueFlowUninit("struct s {\n"
|
||||
" char a[20];\n"
|
||||
|
@ -4080,6 +4079,40 @@ private:
|
|||
" b(&s1);\n"
|
||||
"}\n");
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
|
||||
// # 9290
|
||||
valueFlowUninit("struct A {\n"
|
||||
" double x;\n"
|
||||
"};\n"
|
||||
"double b() {\n"
|
||||
" A * c;\n"
|
||||
" c->x = 42;\n"
|
||||
" return c->x;\n"
|
||||
"}\n");
|
||||
ASSERT_EQUALS("[test.cpp:6]: (error) Uninitialized variable: c\n", errout.str());
|
||||
|
||||
valueFlowUninit("struct A {\n"
|
||||
" double x;\n"
|
||||
"};\n"
|
||||
"double b() {\n"
|
||||
" A c;\n"
|
||||
" c.x = 42;\n"
|
||||
" return c->x;\n"
|
||||
"}\n");
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
|
||||
valueFlowUninit("struct A {\n"
|
||||
" double x;\n"
|
||||
"};\n"
|
||||
"double d(A * e) {\n"
|
||||
" e->x = 42;\n"
|
||||
" return e->x;\n"
|
||||
"}\n"
|
||||
"double b() {\n"
|
||||
" A c;\n"
|
||||
" return d(&c);\n"
|
||||
"}\n");
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
}
|
||||
|
||||
void uninitvar_memberfunction() {
|
||||
|
|
Loading…
Reference in New Issue