Skip to content

Commit c24527d

Browse files
committed
Improved handling of dereferences in CheckClass::noMemset(), fixing false negatives and false positives related to multidimensional arrays and arrays of pointers.
1 parent dc65667 commit c24527d

File tree

2 files changed

+40
-4
lines changed

2 files changed

+40
-4
lines changed

lib/checkclass.cpp

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -838,10 +838,28 @@ void CheckClass::noMemset()
838838
typeTok = arg3->tokAt(3);
839839
else if (Token::simpleMatch(arg3, "sizeof ( * this ) )") || Token::simpleMatch(arg1, "this ,")) {
840840
type = findFunctionOf(arg3->scope());
841-
} else if (Token::Match(arg1, "&| %var% ,")) {
842-
const Variable *var = arg1->str() == "&" ? arg1->next()->variable() : arg1->variable();
843-
if (var && (arg1->str() == "&" || var->isPointer() || var->isArray()))
844-
type = var->type();
841+
} else if (Token::Match(arg1, "&|*|%var%")) {
842+
int derefs = 1;
843+
for (;; arg1 = arg1->next()) {
844+
if (arg1->str() == "&")
845+
derefs--;
846+
else if (arg1->str() == "*")
847+
derefs++;
848+
else
849+
break;
850+
}
851+
852+
const Variable *var = arg1->variable();
853+
if (var && arg1->strAt(1) == ",") {
854+
if (var->isPointer())
855+
derefs--;
856+
if (var->isArray())
857+
derefs -= var->dimensions().size();
858+
859+
if (derefs == 0)
860+
type = var->type();
861+
}
862+
845863
}
846864

847865
// No type defined => The tokens didn't match

test/testclass.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2305,6 +2305,24 @@ class TestClass : public TestFixture {
23052305
" memset(a, 0, 100);\n"
23062306
"}");
23072307
ASSERT_EQUALS("", errout.str()); // #4460
2308+
2309+
checkNoMemset("struct C {\n"
2310+
" std::string s;\n"
2311+
"};\n"
2312+
"int foo() {\n"
2313+
" C* c1[10][10];\n"
2314+
" C* c2[10];\n"
2315+
" C c3[10][10];\n"
2316+
" memset(**c1, 0, 10);\n"
2317+
" memset(*c1, 0, 10);\n"
2318+
" memset(*c2, 0, 10);\n"
2319+
" memset(*c3, 0, 10);\n"
2320+
" memset(c2, 0, 10);\n"
2321+
" memset(c3, 0, 10);\n"
2322+
"}");
2323+
ASSERT_EQUALS("[test.cpp:8]: (error) Using 'memset' on struct that contains a 'std::string'.\n"
2324+
"[test.cpp:10]: (error) Using 'memset' on struct that contains a 'std::string'.\n"
2325+
"[test.cpp:11]: (error) Using 'memset' on struct that contains a 'std::string'.\n", errout.str());
23082326
}
23092327

23102328
void mallocOnClass() {

0 commit comments

Comments
 (0)