Merge branch 'master' of github.com:danmar/cppcheck
This commit is contained in:
commit
687c3a4654
@ -838,10 +838,28 @@ void CheckClass::noMemset()
|
|||||||
typeTok = arg3->tokAt(3);
|
typeTok = arg3->tokAt(3);
|
||||||
else if (Token::simpleMatch(arg3, "sizeof ( * this ) )") || Token::simpleMatch(arg1, "this ,")) {
|
else if (Token::simpleMatch(arg3, "sizeof ( * this ) )") || Token::simpleMatch(arg1, "this ,")) {
|
||||||
type = findFunctionOf(arg3->scope());
|
type = findFunctionOf(arg3->scope());
|
||||||
} else if (Token::Match(arg1, "&| %var% ,")) {
|
} else if (Token::Match(arg1, "&|*|%var%")) {
|
||||||
const Variable *var = arg1->str() == "&" ? arg1->next()->variable() : arg1->variable();
|
int derefs = 1;
|
||||||
if (var && (arg1->str() == "&" || var->isPointer() || var->isArray()))
|
for (;; arg1 = arg1->next()) {
|
||||||
type = var->type();
|
if (arg1->str() == "&")
|
||||||
|
derefs--;
|
||||||
|
else if (arg1->str() == "*")
|
||||||
|
derefs++;
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
const Variable *var = arg1->variable();
|
||||||
|
if (var && arg1->strAt(1) == ",") {
|
||||||
|
if (var->isPointer())
|
||||||
|
derefs--;
|
||||||
|
if (var->isArray())
|
||||||
|
derefs -= var->dimensions().size();
|
||||||
|
|
||||||
|
if (derefs == 0)
|
||||||
|
type = var->type();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// No type defined => The tokens didn't match
|
// No type defined => The tokens didn't match
|
||||||
|
@ -638,7 +638,7 @@ void CheckStl::pushback()
|
|||||||
if (tok3->str() == "break" || tok3->str() == "return") {
|
if (tok3->str() == "break" || tok3->str() == "return") {
|
||||||
pushbackTok = 0;
|
pushbackTok = 0;
|
||||||
break;
|
break;
|
||||||
} else if (Token::Match(tok3, "%varid% . push_front|push_back|insert|reserve|resize|clear (", varId)) {
|
} else if (Token::Match(tok3, "%varid% . push_front|push_back|insert|reserve|resize|clear (", varId) && !tok3->previous()->isAssignmentOp()) {
|
||||||
pushbackTok = tok3->tokAt(2);
|
pushbackTok = tok3->tokAt(2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -649,9 +649,13 @@ void CheckStl::pushback()
|
|||||||
|
|
||||||
// Assigning iterator..
|
// Assigning iterator..
|
||||||
if (Token::Match(tok2, "%varid% =", iteratorid)) {
|
if (Token::Match(tok2, "%varid% =", iteratorid)) {
|
||||||
if (Token::Match(tok2->tokAt(2), "%var% . begin|end|rbegin|rend|cbegin|cend|crbegin|crend ( )")) {
|
if (Token::Match(tok2->tokAt(2), "%var% . begin|end|rbegin|rend|cbegin|cend|crbegin|crend|insert (")) {
|
||||||
|
if (!invalidIterator.empty() && Token::Match(tok2->tokAt(4), "insert ( %varid% ,", iteratorid)) {
|
||||||
|
invalidIteratorError(tok2, invalidIterator, tok2->strAt(6));
|
||||||
|
break;
|
||||||
|
}
|
||||||
vectorid = tok2->tokAt(2)->varId();
|
vectorid = tok2->tokAt(2)->varId();
|
||||||
tok2 = tok2->tokAt(6);
|
tok2 = tok2->linkAt(5);
|
||||||
} else {
|
} else {
|
||||||
vectorid = 0;
|
vectorid = 0;
|
||||||
}
|
}
|
||||||
|
@ -2305,6 +2305,24 @@ private:
|
|||||||
" memset(a, 0, 100);\n"
|
" memset(a, 0, 100);\n"
|
||||||
"}");
|
"}");
|
||||||
ASSERT_EQUALS("", errout.str()); // #4460
|
ASSERT_EQUALS("", errout.str()); // #4460
|
||||||
|
|
||||||
|
checkNoMemset("struct C {\n"
|
||||||
|
" std::string s;\n"
|
||||||
|
"};\n"
|
||||||
|
"int foo() {\n"
|
||||||
|
" C* c1[10][10];\n"
|
||||||
|
" C* c2[10];\n"
|
||||||
|
" C c3[10][10];\n"
|
||||||
|
" memset(**c1, 0, 10);\n"
|
||||||
|
" memset(*c1, 0, 10);\n"
|
||||||
|
" memset(*c2, 0, 10);\n"
|
||||||
|
" memset(*c3, 0, 10);\n"
|
||||||
|
" memset(c2, 0, 10);\n"
|
||||||
|
" memset(c3, 0, 10);\n"
|
||||||
|
"}");
|
||||||
|
ASSERT_EQUALS("[test.cpp:8]: (error) Using 'memset' on struct that contains a 'std::string'.\n"
|
||||||
|
"[test.cpp:10]: (error) Using 'memset' on struct that contains a 'std::string'.\n"
|
||||||
|
"[test.cpp:11]: (error) Using 'memset' on struct that contains a 'std::string'.\n", errout.str());
|
||||||
}
|
}
|
||||||
|
|
||||||
void mallocOnClass() {
|
void mallocOnClass() {
|
||||||
|
@ -1161,6 +1161,31 @@ private:
|
|||||||
" return i->foo;\n"
|
" return i->foo;\n"
|
||||||
"}");
|
"}");
|
||||||
ASSERT_EQUALS("[test.cpp:4]: (error) After insert(), the iterator 'i' may be invalid.\n", errout.str());
|
ASSERT_EQUALS("[test.cpp:4]: (error) After insert(), the iterator 'i' may be invalid.\n", errout.str());
|
||||||
|
|
||||||
|
check("void f(const std::vector<Bar>& bars) {\n"
|
||||||
|
" for(std::vector<Bar>::iterator i = bars.begin(); i != bars.end(); ++i) {\n"
|
||||||
|
" i = bars.insert(i, bar);\n"
|
||||||
|
" }\n"
|
||||||
|
"}");
|
||||||
|
ASSERT_EQUALS("", errout.str());
|
||||||
|
|
||||||
|
check("void f(const std::vector<Bar>& bars) {\n"
|
||||||
|
" for(std::vector<Bar>::iterator i = bars.begin(); i != bars.end(); ++i) {\n"
|
||||||
|
" bars.insert(i, bar);\n"
|
||||||
|
" i = bars.insert(i, bar);\n"
|
||||||
|
" }\n"
|
||||||
|
"}");
|
||||||
|
ASSERT_EQUALS("[test.cpp:3]: (error) After insert(), the iterator 'i' may be invalid.\n"
|
||||||
|
"[test.cpp:4]: (error) After insert(), the iterator 'i' may be invalid.\n", errout.str());
|
||||||
|
|
||||||
|
check("void* f(const std::vector<Bar>& bars) {\n"
|
||||||
|
" std::vector<Bar>::iterator i = bars.begin();\n"
|
||||||
|
" bars.insert(i, Bar());\n"
|
||||||
|
" i = bars.insert(i, Bar());\n"
|
||||||
|
" void* v = &i->foo;\n"
|
||||||
|
" return v;\n"
|
||||||
|
"}");
|
||||||
|
ASSERT_EQUALS("[test.cpp:4]: (error) After insert(), the iterator 'i' may be invalid.\n", errout.str());
|
||||||
}
|
}
|
||||||
|
|
||||||
void insert2() {
|
void insert2() {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user