diff --git a/lib/forwardanalyzer.cpp b/lib/forwardanalyzer.cpp index 9a75d65b3a7..3398d2fe723 100644 --- a/lib/forwardanalyzer.cpp +++ b/lib/forwardanalyzer.cpp @@ -709,7 +709,7 @@ namespace { return Break(); } } - analyzer->assume(condTok, !inElse, Analyzer::Assume::Quiet); + analyzer->assume(condTok, !inElse); assert(!inDoWhile || Token::simpleMatch(tok, "} while (")); if (hasElse || inDoWhile) tok = tok->linkAt(2); diff --git a/lib/vf_analyzers.cpp b/lib/vf_analyzers.cpp index e61f786a526..1a4d17aa849 100644 --- a/lib/vf_analyzers.cpp +++ b/lib/vf_analyzers.cpp @@ -998,7 +998,12 @@ struct MultiValueFlowAnalyzer : ValueFlowAnalyzer { void addErrorPath(const Token* tok, const std::string& s) override { for (auto&& p:values) { - p.second.errorPath.emplace_back(tok, s); + auto& ep = p.second.errorPath; + if (std::any_of(ep.begin(), ep.end(), [&](const ErrorPathItem& epi) { + return epi.first == tok && epi.second == s; + })) + continue; + ep.emplace_back(tok, s); } } @@ -1146,7 +1151,12 @@ struct SingleValueFlowAnalyzer : ValueFlowAnalyzer { } void addErrorPath(const Token* tok, const std::string& s) override { - value.errorPath.emplace_back(tok, s); + auto& ep = value.errorPath; + if (std::any_of(ep.begin(), ep.end(), [&](const ErrorPathItem& epi) { + return epi.first == tok && epi.second == s; + })) + return; + ep.emplace_back(tok, s); } template diff --git a/test/testautovariables.cpp b/test/testautovariables.cpp index 3679a91db6c..d1bc3bf830f 100644 --- a/test/testautovariables.cpp +++ b/test/testautovariables.cpp @@ -3591,7 +3591,7 @@ class TestAutoVariables : public TestFixture { " }\n" " *p = 0;\n" "}\n"); - ASSERT_EQUALS("[test.cpp:5:13] -> [test.cpp:2:9] -> [test.cpp:7:6]: (error) Static variable 'p' will use pointer to local variable 'a'. [danglingLifetime]\n", errout_str()); + ASSERT_EQUALS("[test.cpp:5:13] -> [test.cpp:4:9] -> [test.cpp:2:9] -> [test.cpp:7:6]: (error) Static variable 'p' will use pointer to local variable 'a'. [danglingLifetime]\n", errout_str()); // #10902 check("void f() {\n" @@ -4330,7 +4330,7 @@ class TestAutoVariables : public TestFixture { " std::vector cargs = f({ \"0\", \"0\" });\n" " (void)cargs;\n" "};\n"); - ASSERT_EQUALS("[test.cpp:6:12] -> [test.cpp:4:47] -> [test.cpp:3:22] -> [test.cpp:1:58] -> [test.cpp:4:40] -> [test.cpp:9:34] -> [test.cpp:9:34] -> [test.cpp:10:11]: (error) Using object that is a temporary. [danglingTemporaryLifetime]\n", errout_str()); + ASSERT_EQUALS("[test.cpp:6:12] -> [test.cpp:4:47] -> [test.cpp:3:22] -> [test.cpp:1:58] -> [test.cpp:4:40] -> [test.cpp:3:24] -> [test.cpp:9:34] -> [test.cpp:9:34] -> [test.cpp:10:11]: (error) Using object that is a temporary. [danglingTemporaryLifetime]\n", errout_str()); check("struct C {\n" // #9194 " const int& m;\n" @@ -4692,7 +4692,7 @@ class TestAutoVariables : public TestFixture { " }\n" " f();\n" "}\n"); - ASSERT_EQUALS("[test.cpp:5:25] -> [test.cpp:4:13] -> [test.cpp:7:5]: (error) Using lambda that captures local variable 'b' that is out of scope. [invalidLifetime]\n", errout_str()); + ASSERT_EQUALS("[test.cpp:5:25] -> [test.cpp:3:11] -> [test.cpp:4:13] -> [test.cpp:7:5]: (error) Using lambda that captures local variable 'b' that is out of scope. [invalidLifetime]\n", errout_str()); check("void f(bool b) {\n" " int* x;\n" @@ -4703,7 +4703,7 @@ class TestAutoVariables : public TestFixture { " x[3];\n" "}\n"); ASSERT_EQUALS( - "[test.cpp:5:9] -> [test.cpp:4:9] -> [test.cpp:7:3]: (error) Using pointer to local variable 'y' that is out of scope. [invalidLifetime]\n", + "[test.cpp:5:9] -> [test.cpp:3:6] -> [test.cpp:4:9] -> [test.cpp:7:3]: (error) Using pointer to local variable 'y' that is out of scope. [invalidLifetime]\n", errout_str()); check("void foo(int a) {\n" @@ -4893,7 +4893,7 @@ class TestAutoVariables : public TestFixture { " }\n" " *p = 0;\n" "}\n"); - ASSERT_EQUALS("[test.cpp:5:9] -> [test.cpp:4:9] -> [test.cpp:7:4]: (error) Using pointer to local variable 'x' that is out of scope. [invalidLifetime]\n", errout_str()); + ASSERT_EQUALS("[test.cpp:5:9] -> [test.cpp:3:7] -> [test.cpp:4:9] -> [test.cpp:7:4]: (error) Using pointer to local variable 'x' that is out of scope. [invalidLifetime]\n", errout_str()); // FP: don't warn in subfunction check("void f(struct KEY *key) {\n" @@ -4934,7 +4934,7 @@ class TestAutoVariables : public TestFixture { " dosth();\n" "}\n"); ASSERT_EQUALS( - "[test.cpp:5:24] -> [test.cpp:3:47] -> [test.cpp:4:26] -> [test.cpp:7:9]: (error) Using pointer to local variable 'item' that is out of scope. [invalidLifetime]\n", + "[test.cpp:5:24] -> [test.cpp:3:47] -> [test.cpp:3:47] -> [test.cpp:4:26] -> [test.cpp:7:9]: (error) Using pointer to local variable 'item' that is out of scope. [invalidLifetime]\n", errout_str()); // #6575 @@ -4960,7 +4960,7 @@ class TestAutoVariables : public TestFixture { " return 0;\n" "}\n"); ASSERT_EQUALS( - "[test.cpp:5:16] -> [test.cpp:7:10] -> [test.cpp:4:13] -> [test.cpp:8:17]: (error) Using pointer to local variable 'x' that is out of scope. [invalidLifetime]\n", + "[test.cpp:5:16] -> [test.cpp:3:8] -> [test.cpp:7:10] -> [test.cpp:4:13] -> [test.cpp:8:17]: (error) Using pointer to local variable 'x' that is out of scope. [invalidLifetime]\n", errout_str()); // #11753 @@ -4972,7 +4972,7 @@ class TestAutoVariables : public TestFixture { " }\n" " std::cout << s;\n" "}\n"); - ASSERT_EQUALS("[test.cpp:5:26] -> [test.cpp:4:14] -> [test.cpp:7:18]: (error) Using pointer to local variable 'buff' that is out of scope. [invalidLifetime]\n", errout_str()); + ASSERT_EQUALS("[test.cpp:5:26] -> [test.cpp:3:14] -> [test.cpp:4:14] -> [test.cpp:7:18]: (error) Using pointer to local variable 'buff' that is out of scope. [invalidLifetime]\n", errout_str()); check("char* f(char* dst) {\n" " const char* src = \"abc\";\n" diff --git a/test/testother.cpp b/test/testother.cpp index f64745f80a4..8b399b4c0aa 100644 --- a/test/testother.cpp +++ b/test/testother.cpp @@ -927,6 +927,7 @@ class TestOther : public TestFixture { "[test.cpp:7:14]: note: Division by zero\n" "[test.cpp:13:14]: warning: Division by zero. [zerodivcond]\n" "[test.cpp:12:13]: note: Assignment 'j=0', assigned value is 0\n" + "[test.cpp:11:9]: note: Assuming condition is true\n" "[test.cpp:13:14]: note: Division by zero\n", errout_str()); }