From f3eec965481a33939e3061effb5b72a4480a5250 Mon Sep 17 00:00:00 2001 From: Paul Date: Mon, 20 May 2024 20:04:13 -0500 Subject: [PATCH 1/4] Fix 12197: FP uninitvar with two loops over buffer --- lib/forwardanalyzer.cpp | 14 +++++++++++--- test/testuninitvar.cpp | 14 +++++++++++++- 2 files changed, 24 insertions(+), 4 deletions(-) diff --git a/lib/forwardanalyzer.cpp b/lib/forwardanalyzer.cpp index 12b0e689bf9..c70c54a54cf 100644 --- a/lib/forwardanalyzer.cpp +++ b/lib/forwardanalyzer.cpp @@ -97,6 +97,14 @@ namespace { return actions.isModified(); } + bool stopOnCondition(const Token* condTok) { + if(analyzer->isConditional() && findAstNode(condTok, [](const Token* tok) { + return tok->isIncompleteVar(); + })) + return true; + return analyzer->stopOnCondition(condTok); + } + std::pair evalCond(const Token* tok, const Token* ctx = nullptr) const { if (!tok) return std::make_pair(false, false); @@ -199,7 +207,7 @@ namespace { bool checkThen, checkElse; std::tie(checkThen, checkElse) = evalCond(condTok); if (!checkThen && !checkElse) { - if (!traverseUnknown && analyzer->stopOnCondition(condTok) && stopUpdates()) { + if (!traverseUnknown && stopOnCondition(condTok) && stopUpdates()) { return Progress::Continue; } checkThen = true; @@ -467,7 +475,7 @@ namespace { if (updateRecursive(condTok) == Progress::Break) return Break(); } - if (!checkThen && !checkElse && !isDoWhile && analyzer->stopOnCondition(condTok) && stopUpdates()) + if (!checkThen && !checkElse && !isDoWhile && stopOnCondition(condTok) && stopUpdates()) return Break(Analyzer::Terminate::Conditional); // condition is false, we don't enter the loop if (checkElse) @@ -689,7 +697,7 @@ namespace { Branch elseBranch{endBlock->tokAt(2) ? endBlock->linkAt(2) : nullptr}; // Check if condition is true or false std::tie(thenBranch.check, elseBranch.check) = evalCond(condTok); - if (!thenBranch.check && !elseBranch.check && analyzer->stopOnCondition(condTok) && stopUpdates()) + if (!thenBranch.check && !elseBranch.check && stopOnCondition(condTok) && stopUpdates()) return Break(Analyzer::Terminate::Conditional); const bool hasElse = Token::simpleMatch(endBlock, "} else {"); bool bail = false; diff --git a/test/testuninitvar.cpp b/test/testuninitvar.cpp index 08335e8cbeb..ea60d48fb1d 100644 --- a/test/testuninitvar.cpp +++ b/test/testuninitvar.cpp @@ -3645,7 +3645,7 @@ class TestUninitVar : public TestFixture { "}"); ASSERT_EQUALS("", errout_str()); - valueFlowUninit("int f(int x) {\n" + valueFlowUninit("int f(int x, int y) {\n" " int a;\n" " if (x)\n" " a = y;\n" @@ -6492,6 +6492,18 @@ class TestUninitVar : public TestFixture { " f(i);\n" "}\n"); ASSERT_EQUALS("[test.cpp:4] -> [test.cpp:1]: (warning) Uninitialized variable: r\n", errout_str()); + + // #12197 + valueFlowUninit("void f() {\n" + " char a[N];\n" + " for (int i = 0; i < N; i++)\n" + " a[i] = 1;\n" + " const int* p = a;\n" + " for (int i = 0; i < N; i++) {\n" + " if (p[i]) {}\n" + " }\n" + "}\n"); + ASSERT_EQUALS("", errout_str()); } void valueFlowUninitBreak() { // Do not show duplicate warnings about the same uninitialized value From 730442eb1d2abc0191c7887d4ce2a2cb1a51f5f8 Mon Sep 17 00:00:00 2001 From: Paul Date: Mon, 20 May 2024 20:05:36 -0500 Subject: [PATCH 2/4] Format --- lib/forwardanalyzer.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/lib/forwardanalyzer.cpp b/lib/forwardanalyzer.cpp index c70c54a54cf..30af11f59ff 100644 --- a/lib/forwardanalyzer.cpp +++ b/lib/forwardanalyzer.cpp @@ -97,8 +97,9 @@ namespace { return actions.isModified(); } - bool stopOnCondition(const Token* condTok) { - if(analyzer->isConditional() && findAstNode(condTok, [](const Token* tok) { + bool stopOnCondition(const Token* condTok) + { + if (analyzer->isConditional() && findAstNode(condTok, [](const Token* tok) { return tok->isIncompleteVar(); })) return true; From 8364bfed17e094c28ebfa30cc0c5a22209b4c064 Mon Sep 17 00:00:00 2001 From: Paul Date: Wed, 22 May 2024 10:57:13 -0500 Subject: [PATCH 3/4] Add missing const --- lib/forwardanalyzer.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/forwardanalyzer.cpp b/lib/forwardanalyzer.cpp index 48b6979bbf2..d299624cc2b 100644 --- a/lib/forwardanalyzer.cpp +++ b/lib/forwardanalyzer.cpp @@ -97,7 +97,7 @@ namespace { return actions.isModified(); } - bool stopOnCondition(const Token* condTok) + bool stopOnCondition(const Token* condTok) const { if (analyzer->isConditional() && findAstNode(condTok, [](const Token* tok) { return tok->isIncompleteVar(); @@ -203,7 +203,7 @@ namespace { template )> Progress traverseConditional(T* tok, F f, bool traverseUnknown) { if (Token::Match(tok, "?|&&|%oror%") && tok->astOperand1() && tok->astOperand2()) { - T* condTok = tok->astOperand1(); + const T* condTok = tok->astOperand1(); T* childTok = tok->astOperand2(); bool checkThen, checkElse; std::tie(checkThen, checkElse) = evalCond(condTok); From 197eb4aa1d3fd9a2b8c6bfdd133a4d7fc870c8ee Mon Sep 17 00:00:00 2001 From: Paul Date: Wed, 22 May 2024 11:04:04 -0500 Subject: [PATCH 4/4] Fix cppcheck issue --- lib/symboldatabase.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/lib/symboldatabase.cpp b/lib/symboldatabase.cpp index 2285ff0248d..69d6c3dc0b6 100644 --- a/lib/symboldatabase.cpp +++ b/lib/symboldatabase.cpp @@ -745,10 +745,8 @@ void SymbolDatabase::createSymbolDatabaseFindAllScopes() scopeList.emplace_back(this, tok, scope, Scope::eUnconditional, tok); scope->nestedList.push_back(&scopeList.back()); scope = &scopeList.back(); - } else if (scope->isExecutable()) { - endInitList.emplace(tok->link(), scope); } else { - tok = tok->link(); + endInitList.emplace(tok->link(), scope); } } else if (Token::Match(tok, "extern %type%")) { const Token * ftok = tok->next();