Skip to content

Commit ab93362

Browse files
Improve mismatchingContainerIterator message (#5897)
1 parent 915824a commit ab93362

3 files changed

Lines changed: 31 additions & 30 deletions

File tree

lib/checkstl.cpp

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -231,21 +231,21 @@ void CheckStl::outOfBoundsError(const Token *tok, const std::string &containerNa
231231
if (indexValue && indexValue->condition)
232232
errmsg = ValueFlow::eitherTheConditionIsRedundant(indexValue->condition) + " or '" + index +
233233
"' can have the value " + indexValueString(*indexValue, containerName) + ". Expression '" +
234-
expression + "' cause access out of bounds.";
234+
expression + "' causes access out of bounds.";
235235
else
236236
errmsg = "Out of bounds access in expression '" + expression + "'";
237237
} else if (containerSize->intvalue == 0) {
238238
if (containerSize->condition)
239-
errmsg = ValueFlow::eitherTheConditionIsRedundant(containerSize->condition) + " or expression '" + expression + "' cause access out of bounds.";
239+
errmsg = ValueFlow::eitherTheConditionIsRedundant(containerSize->condition) + " or expression '" + expression + "' causes access out of bounds.";
240240
else if (indexValue == nullptr && !index.empty() && tok->valueType() && tok->valueType()->type == ValueType::ITERATOR)
241241
errmsg = "Out of bounds access in expression '" + expression + "' because '$symbol' is empty and '" + index + "' may be non-zero.";
242242
else
243243
errmsg = "Out of bounds access in expression '" + expression + "' because '$symbol' is empty.";
244244
} else if (indexValue) {
245245
if (containerSize->condition)
246-
errmsg = ValueFlow::eitherTheConditionIsRedundant(containerSize->condition) + " or $symbol size can be " + std::to_string(containerSize->intvalue) + ". Expression '" + expression + "' cause access out of bounds.";
246+
errmsg = ValueFlow::eitherTheConditionIsRedundant(containerSize->condition) + " or size of '$symbol' can be " + std::to_string(containerSize->intvalue) + ". Expression '" + expression + "' causes access out of bounds.";
247247
else if (indexValue->condition)
248-
errmsg = ValueFlow::eitherTheConditionIsRedundant(indexValue->condition) + " or '" + index + "' can have the value " + indexValueString(*indexValue) + ". Expression '" + expression + "' cause access out of bounds.";
248+
errmsg = ValueFlow::eitherTheConditionIsRedundant(indexValue->condition) + " or '" + index + "' can have the value " + indexValueString(*indexValue) + ". Expression '" + expression + "' causes access out of bounds.";
249249
else
250250
errmsg = "Out of bounds access in '" + expression + "', if '$symbol' size is " + std::to_string(containerSize->intvalue) + " and '" + index + "' is " + indexValueString(*indexValue);
251251
} else {
@@ -646,14 +646,15 @@ void CheckStl::iterators()
646646
}
647647
}
648648

649-
void CheckStl::mismatchingContainerIteratorError(const Token* tok, const Token* iterTok)
649+
void CheckStl::mismatchingContainerIteratorError(const Token* containerTok, const Token* iterTok, const Token* containerTok2)
650650
{
651-
const std::string container(tok ? tok->expressionString() : std::string("v1"));
651+
const std::string container(containerTok ? containerTok->expressionString() : std::string("v1"));
652+
const std::string container2(containerTok2 ? containerTok2->expressionString() : std::string("v2"));
652653
const std::string iter(iterTok ? iterTok->expressionString() : std::string("it"));
653-
reportError(tok,
654+
reportError(containerTok,
654655
Severity::error,
655656
"mismatchingContainerIterator",
656-
"Iterator '" + iter + "' from different container '" + container + "' are used together.",
657+
"Iterator '" + iter + "' referring to container '" + container2 + "' is used with container '" + container + "'.",
657658
CWE664,
658659
Certainty::normal);
659660
}
@@ -869,7 +870,7 @@ void CheckStl::mismatchingContainerIterator()
869870
continue;
870871
if (isSameIteratorContainerExpression(tok, val.tokvalue, mSettings->library))
871872
continue;
872-
mismatchingContainerIteratorError(tok, iterTok);
873+
mismatchingContainerIteratorError(tok, iterTok, val.tokvalue);
873874
}
874875
}
875876
}

lib/checkstl.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -206,7 +206,7 @@ class CPPCHECKLIB CheckStl : public Check {
206206
void iteratorsError(const Token* tok, const std::string& containerName1, const std::string& containerName2);
207207
void iteratorsError(const Token* tok, const Token* containerTok, const std::string& containerName1, const std::string& containerName2);
208208
void iteratorsError(const Token* tok, const Token* containerTok, const std::string& containerName);
209-
void mismatchingContainerIteratorError(const Token* tok, const Token* iterTok);
209+
void mismatchingContainerIteratorError(const Token* containerTok, const Token* iterTok, const Token* containerTok2);
210210
void mismatchingContainersError(const Token* tok1, const Token* tok2);
211211
void mismatchingContainerExpressionError(const Token *tok1, const Token *tok2);
212212
void sameIteratorExpressionError(const Token *tok);
@@ -247,7 +247,7 @@ class CPPCHECKLIB CheckStl : public Check {
247247
c.iteratorsError(nullptr, nullptr, "container");
248248
c.invalidContainerLoopError(nullptr, nullptr, errorPath);
249249
c.invalidContainerError(nullptr, nullptr, nullptr, errorPath);
250-
c.mismatchingContainerIteratorError(nullptr, nullptr);
250+
c.mismatchingContainerIteratorError(nullptr, nullptr, nullptr);
251251
c.mismatchingContainersError(nullptr, nullptr);
252252
c.mismatchingContainerExpressionError(nullptr, nullptr);
253253
c.sameIteratorExpressionError(nullptr);

test/teststl.cpp

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -224,10 +224,10 @@ class TestStl : public TestFixture {
224224
" bar(v[2], v[3]) )\n" // v[3] is accessed
225225
" {;}\n"
226226
"}\n");
227-
ASSERT_EQUALS("test.cpp:9:warning:Either the condition 'v.size()>=2' is redundant or v size can be 2. Expression 'v[2]' cause access out of bounds.\n"
227+
ASSERT_EQUALS("test.cpp:9:warning:Either the condition 'v.size()>=2' is redundant or size of 'v' can be 2. Expression 'v[2]' causes access out of bounds.\n"
228228
"test.cpp:8:note:condition 'v.size()>=2'\n"
229229
"test.cpp:9:note:Access out of bounds\n"
230-
"test.cpp:9:warning:Either the condition 'v.size()>=2' is redundant or v size can be 2. Expression 'v[3]' cause access out of bounds.\n"
230+
"test.cpp:9:warning:Either the condition 'v.size()>=2' is redundant or size of 'v' can be 2. Expression 'v[3]' causes access out of bounds.\n"
231231
"test.cpp:8:note:condition 'v.size()>=2'\n"
232232
"test.cpp:9:note:Access out of bounds\n", errout.str());
233233

@@ -247,15 +247,15 @@ class TestStl : public TestFixture {
247247
" v.front();\n"
248248
" if (v.empty()) {}\n"
249249
"}");
250-
ASSERT_EQUALS("test.cpp:2:warning:Either the condition 'v.empty()' is redundant or expression 'v.front()' cause access out of bounds.\n"
250+
ASSERT_EQUALS("test.cpp:2:warning:Either the condition 'v.empty()' is redundant or expression 'v.front()' causes access out of bounds.\n"
251251
"test.cpp:3:note:condition 'v.empty()'\n"
252252
"test.cpp:2:note:Access out of bounds\n", errout.str());
253253

254254
checkNormal("void f(std::vector<int> v) {\n"
255255
" if (v.size() == 3) {}\n"
256256
" v[16] = 0;\n"
257257
"}");
258-
ASSERT_EQUALS("test.cpp:3:warning:Either the condition 'v.size()==3' is redundant or v size can be 3. Expression 'v[16]' cause access out of bounds.\n"
258+
ASSERT_EQUALS("test.cpp:3:warning:Either the condition 'v.size()==3' is redundant or size of 'v' can be 3. Expression 'v[16]' causes access out of bounds.\n"
259259
"test.cpp:2:note:condition 'v.size()==3'\n"
260260
"test.cpp:3:note:Access out of bounds\n", errout.str());
261261

@@ -265,7 +265,7 @@ class TestStl : public TestFixture {
265265
" v[i] = 0;\n"
266266
" }\n"
267267
"}");
268-
ASSERT_EQUALS("test.cpp:4:warning:Either the condition 'v.size()==3' is redundant or v size can be 3. Expression 'v[i]' cause access out of bounds.\n"
268+
ASSERT_EQUALS("test.cpp:4:warning:Either the condition 'v.size()==3' is redundant or size of 'v' can be 3. Expression 'v[i]' causes access out of bounds.\n"
269269
"test.cpp:3:note:condition 'v.size()==3'\n"
270270
"test.cpp:4:note:Access out of bounds\n", errout.str());
271271

@@ -285,7 +285,7 @@ class TestStl : public TestFixture {
285285
" s[2] = 0;\n"
286286
" }\n"
287287
"}");
288-
ASSERT_EQUALS("test.cpp:3:warning:Either the condition 's.size()==1' is redundant or s size can be 1. Expression 's[2]' cause access out of bounds.\n"
288+
ASSERT_EQUALS("test.cpp:3:warning:Either the condition 's.size()==1' is redundant or size of 's' can be 1. Expression 's[2]' causes access out of bounds.\n"
289289
"test.cpp:2:note:condition 's.size()==1'\n"
290290
"test.cpp:3:note:Access out of bounds\n", errout.str());
291291

@@ -385,7 +385,7 @@ class TestStl : public TestFixture {
385385
" if(v.at(b?42:0)) {}\n"
386386
"}\n");
387387
ASSERT_EQUALS(
388-
"test.cpp:3:warning:Either the condition 'v.size()==1' is redundant or v size can be 1. Expression 'v.at(b?42:0)' cause access out of bounds.\n"
388+
"test.cpp:3:warning:Either the condition 'v.size()==1' is redundant or size of 'v' can be 1. Expression 'v.at(b?42:0)' causes access out of bounds.\n"
389389
"test.cpp:2:note:condition 'v.size()==1'\n"
390390
"test.cpp:3:note:Access out of bounds\n",
391391
errout.str());
@@ -628,7 +628,7 @@ class TestStl : public TestFixture {
628628
checkNormal("void foo(const std::vector<int> &v) {\n"
629629
" if(v.size() >=1 && v[0] == 4 && v[1] == 2){}\n"
630630
"}\n");
631-
ASSERT_EQUALS("test.cpp:2:warning:Either the condition 'v.size()>=1' is redundant or v size can be 1. Expression 'v[1]' cause access out of bounds.\n"
631+
ASSERT_EQUALS("test.cpp:2:warning:Either the condition 'v.size()>=1' is redundant or size of 'v' can be 1. Expression 'v[1]' causes access out of bounds.\n"
632632
"test.cpp:2:note:condition 'v.size()>=1'\n"
633633
"test.cpp:2:note:Access out of bounds\n", errout.str());
634634

@@ -641,7 +641,7 @@ class TestStl : public TestFixture {
641641
" return y;\n"
642642
"}\n");
643643
ASSERT_EQUALS(
644-
"test.cpp:6:warning:Either the condition 'x<2' is redundant or 'x' can have the value greater or equal to 3. Expression 'a[x]' cause access out of bounds.\n"
644+
"test.cpp:6:warning:Either the condition 'x<2' is redundant or 'x' can have the value greater or equal to 3. Expression 'a[x]' causes access out of bounds.\n"
645645
"test.cpp:3:note:condition 'x<2'\n"
646646
"test.cpp:6:note:Access out of bounds\n",
647647
errout.str());
@@ -692,10 +692,10 @@ class TestStl : public TestFixture {
692692
" if (v[i]) {}\n"
693693
" }\n"
694694
"}\n");
695-
ASSERT_EQUALS("test.cpp:3:warning:Either the condition 'i<=(int)v.size()' is redundant or 'i' can have the value v.size(). Expression 'v[i]' cause access out of bounds.\n"
695+
ASSERT_EQUALS("test.cpp:3:warning:Either the condition 'i<=(int)v.size()' is redundant or 'i' can have the value v.size(). Expression 'v[i]' causes access out of bounds.\n"
696696
"test.cpp:2:note:condition 'i<=(int)v.size()'\n"
697697
"test.cpp:3:note:Access out of bounds\n"
698-
"test.cpp:6:warning:Either the condition 'i<=static_cast<int>(v.size())' is redundant or 'i' can have the value v.size(). Expression 'v[i]' cause access out of bounds.\n"
698+
"test.cpp:6:warning:Either the condition 'i<=static_cast<int>(v.size())' is redundant or 'i' can have the value v.size(). Expression 'v[i]' causes access out of bounds.\n"
699699
"test.cpp:5:note:condition 'i<=static_cast<int>(v.size())'\n"
700700
"test.cpp:6:note:Access out of bounds\n",
701701
errout.str());
@@ -730,7 +730,7 @@ class TestStl : public TestFixture {
730730
"}\n",
731731
true);
732732
ASSERT_EQUALS(
733-
"test.cpp:2:warning:Either the condition 'v.empty()' is redundant or expression 'v.back()' cause access out of bounds.\n"
733+
"test.cpp:2:warning:Either the condition 'v.empty()' is redundant or expression 'v.back()' causes access out of bounds.\n"
734734
"test.cpp:2:note:condition 'v.empty()'\n"
735735
"test.cpp:2:note:Access out of bounds\n",
736736
errout.str());
@@ -936,7 +936,7 @@ class TestStl : public TestFixture {
936936
" int x = textline[col];\n"
937937
"}\n");
938938
ASSERT_EQUALS(
939-
"[test.cpp:2] -> [test.cpp:4]: (warning) Either the condition 'col>textline.size()' is redundant or 'col' can have the value textline.size(). Expression 'textline[col]' cause access out of bounds.\n",
939+
"[test.cpp:2] -> [test.cpp:4]: (warning) Either the condition 'col>textline.size()' is redundant or 'col' can have the value textline.size(). Expression 'textline[col]' causes access out of bounds.\n",
940940
errout.str());
941941
}
942942

@@ -1108,7 +1108,7 @@ class TestStl : public TestFixture {
11081108
" l2.insert(it, 0);\n"
11091109
"}");
11101110
ASSERT_EQUALS("[test.cpp:6]: (error) Same iterator is used with different containers 'l1' and 'l2'.\n"
1111-
"[test.cpp:6]: (error) Iterator 'it' from different container 'l2' are used together.\n",
1111+
"[test.cpp:6]: (error) Iterator 'it' referring to container 'l1' is used with container 'l2'.\n",
11121112
errout.str());
11131113

11141114
check("void foo() {\n" // #5803
@@ -1857,7 +1857,7 @@ class TestStl : public TestFixture {
18571857
" while (it != g().end())\n"
18581858
" it = v.erase(it);\n"
18591859
"}\n");
1860-
ASSERT_EQUALS("[test.cpp:6]: (error) Iterator 'it' from different container 'v' are used together.\n", errout.str());
1860+
ASSERT_EQUALS("[test.cpp:6]: (error) Iterator 'it' referring to container 'g()' is used with container 'v'.\n", errout.str());
18611861

18621862
check("std::vector<int>& g(int);\n"
18631863
"void f(int i, int j) {\n"
@@ -1866,7 +1866,7 @@ class TestStl : public TestFixture {
18661866
" while (it != g(j).end())\n"
18671867
" it = r.erase(it);\n"
18681868
"}\n");
1869-
ASSERT_EQUALS("[test.cpp:6]: (error) Iterator 'it' from different container 'r' are used together.\n", errout.str());
1869+
ASSERT_EQUALS("[test.cpp:6]: (error) Iterator 'it' referring to container 'g(j)' is used with container 'r'.\n", errout.str());
18701870

18711871
check("std::vector<int>& g();\n"
18721872
"void f() {\n"
@@ -2085,13 +2085,13 @@ class TestStl : public TestFixture {
20852085
" a.insert(b.end(), value);\n"
20862086
" return a;\n"
20872087
"}");
2088-
ASSERT_EQUALS("[test.cpp:3]: (error) Iterator 'b.end()' from different container 'a' are used together.\n", errout.str());
2088+
ASSERT_EQUALS("[test.cpp:3]: (error) Iterator 'b.end()' referring to container 'b' is used with container 'a'.\n", errout.str());
20892089

20902090
check("std::vector<int> f(std::vector<int> a, std::vector<int> b) {\n"
20912091
" a.erase(b.begin());\n"
20922092
" return a;\n"
20932093
"}");
2094-
ASSERT_EQUALS("[test.cpp:2]: (error) Iterator 'b.begin()' from different container 'a' are used together.\n", errout.str());
2094+
ASSERT_EQUALS("[test.cpp:2]: (error) Iterator 'b.begin()' referring to container 'b' is used with container 'a'.\n", errout.str());
20952095

20962096
// #9973
20972097
check("void f() {\n"
@@ -3206,7 +3206,7 @@ class TestStl : public TestFixture {
32063206
" if (v.empty()) {}\n"
32073207
" v.pop_back();\n"
32083208
"}\n");
3209-
ASSERT_EQUALS("[test.cpp:2] -> [test.cpp:3]: (warning) Either the condition 'v.empty()' is redundant or expression 'v.pop_back()' cause access out of bounds.\n",
3209+
ASSERT_EQUALS("[test.cpp:2] -> [test.cpp:3]: (warning) Either the condition 'v.empty()' is redundant or expression 'v.pop_back()' causes access out of bounds.\n",
32103210
errout.str());
32113211

32123212
check("void f(std::vector<int>& v) {\n"

0 commit comments

Comments
 (0)