From 771188238c5795a929bfdf1fdf169ae8dc88e5fa Mon Sep 17 00:00:00 2001 From: Paul Fultz II Date: Thu, 11 Nov 2021 01:01:10 -0600 Subject: [PATCH] Fix 10574: ValueFlow: conditional values in constructor initializer list (#3556) --- lib/reverseanalyzer.cpp | 5 +++++ test/testvalueflow.cpp | 25 +++++++++++++++++++++++++ 2 files changed, 30 insertions(+) mode change 100644 => 100755 test/testvalueflow.cpp diff --git a/lib/reverseanalyzer.cpp b/lib/reverseanalyzer.cpp index 8e95f204e..08c35bf02 100644 --- a/lib/reverseanalyzer.cpp +++ b/lib/reverseanalyzer.cpp @@ -127,6 +127,11 @@ struct ReverseTraversal { i = tok->index(); if (tok == start || (tok->str() == "{" && (tok->scope()->type == Scope::ScopeType::eFunction || tok->scope()->type == Scope::ScopeType::eLambda))) { + const Function* f = tok->scope()->function; + if (f && f->isConstructor()) { + if (const Token* initList = f->constructorMemberInitialization()) + traverse(tok->previous(), tok->tokAt(initList->index() - tok->index())); + } break; } if (Token::Match(tok, "return|break|continue")) diff --git a/test/testvalueflow.cpp b/test/testvalueflow.cpp old mode 100644 new mode 100755 index 8e55e3a02..f7fa2dd55 --- a/test/testvalueflow.cpp +++ b/test/testvalueflow.cpp @@ -81,6 +81,7 @@ private: TEST_CASE(valueFlowBeforeConditionSwitch); TEST_CASE(valueFlowBeforeConditionTernaryOp); TEST_CASE(valueFlowBeforeConditionForward); + TEST_CASE(valueFlowBeforeConditionConstructor); TEST_CASE(valueFlowAfterAssign); TEST_CASE(valueFlowAfterSwap); @@ -1753,6 +1754,30 @@ private: ASSERT_EQUALS(true, testValueOfX(code, 4U, 123)); } + void valueFlowBeforeConditionConstructor() + { + const char* code; + + code = "struct Fred {\n" + " Fred(int *x)\n" + " : i(*x) {\n" // <- dereference x + " if (!x) {}\n" // <- check x + " }\n" + " int i;\n" + "};\n"; + ASSERT_EQUALS(true, testValueOfX(code, 3U, 0)); + + code = "struct Fred {\n" + " Fred(int *x)\n" + " : i(*x), j(0) {\n" // <- dereference x + " if (!x) {}\n" // <- check x + " }\n" + " int i;\n" + " int j;\n" + "};\n"; + ASSERT_EQUALS(true, testValueOfX(code, 3U, 0)); + } + void valueFlowAfterAssign() { const char *code;