From 92caa835b6c3aacbe1acebd3f71c0d53e5552963 Mon Sep 17 00:00:00 2001 From: Paul Fultz II Date: Mon, 17 Jul 2023 03:34:54 -0500 Subject: [PATCH] Fix 11806: FP uninitvar for reference to unitvar in ternary ?: operator (#5247) --- lib/astutils.cpp | 2 ++ lib/forwardanalyzer.cpp | 2 +- test/testuninitvar.cpp | 14 +++++++++++++- test/testvalueflow.cpp | 11 +++++++++++ 4 files changed, 27 insertions(+), 2 deletions(-) diff --git a/lib/astutils.cpp b/lib/astutils.cpp index 7dea9a460..3652eefbe 100644 --- a/lib/astutils.cpp +++ b/lib/astutils.cpp @@ -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(), "=") && diff --git a/lib/forwardanalyzer.cpp b/lib/forwardanalyzer.cpp index dc31c76b3..494dbd13b 100644 --- a/lib/forwardanalyzer.cpp +++ b/lib/forwardanalyzer.cpp @@ -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() == "}") { diff --git a/test/testuninitvar.cpp b/test/testuninitvar.cpp index 6096a4568..e063a2a28 100644 --- a/test/testuninitvar.cpp +++ b/test/testuninitvar.cpp @@ -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 diff --git a/test/testvalueflow.cpp b/test/testvalueflow.cpp index 0115c5848..2592eeec6 100644 --- a/test/testvalueflow.cpp +++ b/test/testvalueflow.cpp @@ -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() {