UninitVar: too many warnings (function/cast operand)

This commit is contained in:
Daniel Marjamäki 2021-10-03 14:47:21 +02:00
parent fc6a791a74
commit 9f2ddf1623
3 changed files with 42 additions and 2 deletions

View File

@ -50,7 +50,7 @@ namespace {
//---------------------------------------------------------------------------
static bool isSizeOfEtc(const Token *tok)
bool isSizeOfEtc(const Token *tok)
{
return Token::Match(tok, "sizeof|typeof|offsetof|decltype|__typeof__ (");
}

View File

@ -12,6 +12,8 @@
#include <tuple>
#include <utility>
bool isSizeOfEtc(const Token *tok);
struct OnExit {
std::function<void()> f;
@ -192,8 +194,16 @@ struct ForwardTraversal {
Progress update(Token* tok) {
Analyzer::Action action = analyzer->analyze(tok, Analyzer::Direction::Forward);
actions |= action;
if (!action.isNone() && !analyzeOnly)
if (!action.isNone() && !analyzeOnly) {
analyzer->update(tok, action, Analyzer::Direction::Forward);
// uninit value => skip further analysis
auto v = std::find_if(tok->values().begin(), tok->values().end(), std::mem_fn(&ValueFlow::Value::isUninitValue));
if (v != tok->values().end()) {
if (Token::Match(tok->astParent(), "[,(]") && !isSizeOfEtc(tok->astParent()->previous()))
return Break(Analyzer::Terminate::Modified);
}
}
if (action.isInconclusive() && !analyzer->lowerToInconclusive())
return Break(Analyzer::Terminate::Inconclusive);
if (action.isInvalid())

View File

@ -120,6 +120,7 @@ private:
TEST_CASE(valueFlowSameExpression);
TEST_CASE(valueFlowUninit);
TEST_CASE(valueFlowUninitBreak);
TEST_CASE(valueFlowConditionExpressions);
@ -4651,6 +4652,35 @@ private:
ASSERT_EQUALS(0, values.size());
}
void valueFlowUninitBreak() { // break uninit analysis to avoid extra warnings
const char *code;
std::list<ValueFlow::Value> values;
code = "struct wcsstruct {\n"
" int *wcsprm;\n"
"};\n"
"\n"
"void copy_wcs(wcsstruct *wcsin) {\n"
" wcsstruct *x;\n"
" memcpy(wcsin, x, sizeof(wcsstruct));\n" // <- True positive
" x->wcsprm = NULL;\n" // <- False positive
"}";
values = tokenValues(code, "x . wcsprm", ValueFlow::Value::ValueType::UNINIT);
ASSERT_EQUALS(0, values.size());
code = "struct wcsstruct {\n"
" int *wcsprm;\n"
"};\n"
"\n"
"void copy_wcs(wcsstruct *wcsin) {\n"
" wcsstruct *x;\n"
" sizeof(x);\n"
" x->wcsprm = NULL;\n" // <- Warn
"}";
values = tokenValues(code, "x . wcsprm", ValueFlow::Value::ValueType::UNINIT);
ASSERT_EQUALS(1, values.size());
}
void valueFlowConditionExpressions() {
const char* code;