Fix 11806: FP uninitvar for reference to unitvar in ternary ?: operator (#5247)

This commit is contained in:
Paul Fultz II 2023-07-17 03:34:54 -05:00 committed by GitHub
parent e4827cb3df
commit 92caa835b6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 27 additions and 2 deletions

View File

@ -3133,6 +3133,8 @@ ExprUsage getExprUsage(const Token* tok, int indirect, const Settings* settings)
return ExprUsage::NotUsed;
if (tok->astParent()->isCast())
return ExprUsage::NotUsed;
if (Token::simpleMatch(tok->astParent(), ":") && Token::simpleMatch(tok->astParent()->astParent(), "?"))
return getExprUsage(tok->astParent()->astParent(), indirect, settings);
}
if (indirect == 0) {
if (Token::Match(tok->astParent(), "%cop%|%assign%|++|--") && !Token::simpleMatch(tok->astParent(), "=") &&

View File

@ -593,7 +593,7 @@ struct ForwardTraversal {
// TODO: Don't break, instead move to the outer scope
if (!tok)
return Break();
} else if (Token::Match(tok, "%name% :") || tok->str() == "case") {
} else if (!tok->variable() && (Token::Match(tok, "%name% :") || tok->str() == "case")) {
if (!analyzer->lowerToPossible())
return Break(Analyzer::Terminate::Bail);
} else if (tok->link() && tok->str() == "}") {

View File

@ -3794,7 +3794,7 @@ private:
" int a;\n"
" int *p = ptr ? ptr : &a;\n"
"}");
TODO_ASSERT_EQUALS("", "[test.cpp:3]: (error) Uninitialized variable: &a\n", errout.str());
ASSERT_EQUALS("", errout.str());
valueFlowUninit("int f(int a) {\n"
" int x;\n"
@ -6116,6 +6116,18 @@ private:
" (void)a[i];\n"
"}\n");
ASSERT_EQUALS("", errout.str());
valueFlowUninit("void f() {\n"
" int x;\n"
" int *p = 0 ? 0 : &x;\n"
"}\n");
ASSERT_EQUALS("", errout.str());
valueFlowUninit("void g() {\n"
" int y;\n"
" int *q = 1 ? &y : 0;\n"
"}\n");
ASSERT_EQUALS("", errout.str());
}
void valueFlowUninitBreak() { // Do not show duplicate warnings about the same uninitialized value

View File

@ -5565,6 +5565,17 @@ private:
"}";
values = tokenValues(code, "x + 1", ValueFlow::Value::ValueType::UNINIT);
ASSERT_EQUALS(0, values.size());
code = "void g() {\n"
" int y;\n"
" int *q = 1 ? &y : 0;\n"
"}\n";
values = tokenValues(code, "y :", ValueFlow::Value::ValueType::UNINIT);
ASSERT_EQUALS(1, values.size());
ASSERT_EQUALS(true, values.front().isUninitValue());
values = tokenValues(code, "& y :", ValueFlow::Value::ValueType::UNINIT);
ASSERT_EQUALS(1, values.size());
ASSERT_EQUALS(true, values.front().isUninitValue());
}
void valueFlowConditionExpressions() {