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:
Paul Fultz II 2019-08-24 04:27:47 -05:00 committed by Daniel Marjamäki
parent f25dcd5cda
commit 5c488b9519
4 changed files with 46 additions and 3 deletions

View File

@ -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;

View File

@ -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)

View File

@ -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;
}

View File

@ -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() {