Skip to content

Commit a46d2fb

Browse files
Fix #15016 Inconsistent error paths for if conditions (#8870)
After #8836 --------- Co-authored-by: chrchr-github <noreply@github.com>
1 parent c83bee7 commit a46d2fb

4 files changed

Lines changed: 22 additions & 11 deletions

File tree

lib/forwardanalyzer.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -709,7 +709,7 @@ namespace {
709709
return Break();
710710
}
711711
}
712-
analyzer->assume(condTok, !inElse, Analyzer::Assume::Quiet);
712+
analyzer->assume(condTok, !inElse);
713713
assert(!inDoWhile || Token::simpleMatch(tok, "} while ("));
714714
if (hasElse || inDoWhile)
715715
tok = tok->linkAt(2);

lib/vf_analyzers.cpp

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -998,7 +998,12 @@ struct MultiValueFlowAnalyzer : ValueFlowAnalyzer {
998998

999999
void addErrorPath(const Token* tok, const std::string& s) override {
10001000
for (auto&& p:values) {
1001-
p.second.errorPath.emplace_back(tok, s);
1001+
auto& ep = p.second.errorPath;
1002+
if (std::any_of(ep.begin(), ep.end(), [&](const ErrorPathItem& epi) {
1003+
return epi.first == tok && epi.second == s;
1004+
}))
1005+
continue;
1006+
ep.emplace_back(tok, s);
10021007
}
10031008
}
10041009

@@ -1146,7 +1151,12 @@ struct SingleValueFlowAnalyzer : ValueFlowAnalyzer {
11461151
}
11471152

11481153
void addErrorPath(const Token* tok, const std::string& s) override {
1149-
value.errorPath.emplace_back(tok, s);
1154+
auto& ep = value.errorPath;
1155+
if (std::any_of(ep.begin(), ep.end(), [&](const ErrorPathItem& epi) {
1156+
return epi.first == tok && epi.second == s;
1157+
}))
1158+
return;
1159+
ep.emplace_back(tok, s);
11501160
}
11511161

11521162
template<class T>

test/testautovariables.cpp

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3591,7 +3591,7 @@ class TestAutoVariables : public TestFixture {
35913591
" }\n"
35923592
" *p = 0;\n"
35933593
"}\n");
3594-
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());
3594+
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());
35953595

35963596
// #10902
35973597
check("void f() {\n"
@@ -4330,7 +4330,7 @@ class TestAutoVariables : public TestFixture {
43304330
" std::vector<char*> cargs = f({ \"0\", \"0\" });\n"
43314331
" (void)cargs;\n"
43324332
"};\n");
4333-
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());
4333+
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());
43344334

43354335
check("struct C {\n" // #9194
43364336
" const int& m;\n"
@@ -4692,7 +4692,7 @@ class TestAutoVariables : public TestFixture {
46924692
" }\n"
46934693
" f();\n"
46944694
"}\n");
4695-
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());
4695+
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());
46964696

46974697
check("void f(bool b) {\n"
46984698
" int* x;\n"
@@ -4703,7 +4703,7 @@ class TestAutoVariables : public TestFixture {
47034703
" x[3];\n"
47044704
"}\n");
47054705
ASSERT_EQUALS(
4706-
"[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",
4706+
"[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",
47074707
errout_str());
47084708

47094709
check("void foo(int a) {\n"
@@ -4893,7 +4893,7 @@ class TestAutoVariables : public TestFixture {
48934893
" }\n"
48944894
" *p = 0;\n"
48954895
"}\n");
4896-
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());
4896+
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());
48974897

48984898
// FP: don't warn in subfunction
48994899
check("void f(struct KEY *key) {\n"
@@ -4934,7 +4934,7 @@ class TestAutoVariables : public TestFixture {
49344934
" dosth();\n"
49354935
"}\n");
49364936
ASSERT_EQUALS(
4937-
"[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",
4937+
"[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",
49384938
errout_str());
49394939

49404940
// #6575
@@ -4960,7 +4960,7 @@ class TestAutoVariables : public TestFixture {
49604960
" return 0;\n"
49614961
"}\n");
49624962
ASSERT_EQUALS(
4963-
"[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",
4963+
"[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",
49644964
errout_str());
49654965

49664966
// #11753
@@ -4972,7 +4972,7 @@ class TestAutoVariables : public TestFixture {
49724972
" }\n"
49734973
" std::cout << s;\n"
49744974
"}\n");
4975-
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());
4975+
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());
49764976

49774977
check("char* f(char* dst) {\n"
49784978
" const char* src = \"abc\";\n"

test/testother.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -927,6 +927,7 @@ class TestOther : public TestFixture {
927927
"[test.cpp:7:14]: note: Division by zero\n"
928928
"[test.cpp:13:14]: warning: Division by zero. [zerodivcond]\n"
929929
"[test.cpp:12:13]: note: Assignment 'j=0', assigned value is 0\n"
930+
"[test.cpp:11:9]: note: Assuming condition is true\n"
930931
"[test.cpp:13:14]: note: Division by zero\n", errout_str());
931932
}
932933

0 commit comments

Comments
 (0)