Fix namespaced types for auto_ptr new[] errors
This fixes false negatives for code such as: std::auto_ptr<foo::bar> p(new foo::bar[10]); The idea is to find a "new", search for the end token ";", then see if the declaration ends in a closing square bracket. Also fixes other cases that checked for "new %type% [" so that they work with namespaces.
This commit is contained in:
parent
7ef1107a55
commit
7f88b66842
|
@ -1081,6 +1081,18 @@ void CheckStl::string_c_strError(const Token* tok, bool is_inconlusive)
|
|||
reportError(tok, Severity::error, "stlcstr", "Dangerous usage of c_str()");
|
||||
}
|
||||
|
||||
static bool hasArrayEnd(const Token *tok1)
|
||||
{
|
||||
const Token *end = Token::findsimplematch(tok1, ";");
|
||||
return (end && Token::simpleMatch(end->previous(), "] ;"));
|
||||
}
|
||||
|
||||
static bool hasArrayEndParen(const Token *tok1)
|
||||
{
|
||||
const Token *end = Token::findsimplematch(tok1, ";");
|
||||
return (end && end->previous() &&
|
||||
Token::simpleMatch(end->previous()->previous(), "] ) ;"));
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
|
@ -1101,7 +1113,7 @@ void CheckStl::checkAutoPointer()
|
|||
while (tok2) {
|
||||
if (Token::Match(tok2, "> %var%")) {
|
||||
const Token *tok3 = tok2->next()->next();
|
||||
if (Token::Match(tok3, "( new %type% [")) {
|
||||
if (Token::Match(tok3, "( new %type%") && hasArrayEndParen(tok3)) {
|
||||
autoPointerArrayError(tok2->next());
|
||||
break;
|
||||
}
|
||||
|
@ -1113,8 +1125,8 @@ void CheckStl::checkAutoPointer()
|
|||
if (Token::simpleMatch(tok3->previous(), "[ ] )")) {
|
||||
autoPointerArrayError(tok2->next());
|
||||
} else if (tok3->varId()) {
|
||||
const Token *decltok = Token::findmatch(_tokenizer->tokens(), "%varid% = new %type% [", tok3->varId());
|
||||
if (decltok) {
|
||||
const Token *decltok = Token::findmatch(_tokenizer->tokens(), "%varid% = new %type%", tok3->varId());
|
||||
if (decltok && hasArrayEnd(decltok)) {
|
||||
autoPointerArrayError(tok2->next());
|
||||
}
|
||||
}
|
||||
|
@ -1135,7 +1147,8 @@ void CheckStl::checkAutoPointer()
|
|||
autoPointerError(tok->next()->next());
|
||||
}
|
||||
}
|
||||
} else if (Token::Match(tok, "%var% = new %type% [") || Token::Match(tok, "%var% . reset ( new %type% [")) {
|
||||
} else if ((Token::Match(tok, "%var% = new %type% ") && hasArrayEnd(tok)) ||
|
||||
(Token::Match(tok, "%var% . reset ( new %type% ") && hasArrayEndParen(tok))) {
|
||||
iter = autoPtrVarId.find(tok->varId());
|
||||
if (iter != autoPtrVarId.end()) {
|
||||
autoPointerArrayError(tok);
|
||||
|
|
|
@ -1427,6 +1427,13 @@ private:
|
|||
"}\n");
|
||||
ASSERT_EQUALS("[test.cpp:4]: (error) Object pointed by an 'auto_ptr' is destroyed using operator 'delete'. You should not use 'auto_ptr' for pointers obtained with operator 'new[]'.\n", errout.str());
|
||||
|
||||
check("void f() \n"
|
||||
"{\n"
|
||||
" foo::bar::baz* var = new foo::bar::baz[10];\n"
|
||||
" auto_ptr<foo::bar::baz> p2( var );\n"
|
||||
"}\n");
|
||||
ASSERT_EQUALS("[test.cpp:4]: (error) Object pointed by an 'auto_ptr' is destroyed using operator 'delete'. You should not use 'auto_ptr' for pointers obtained with operator 'new[]'.\n", errout.str());
|
||||
|
||||
check("void f() \n"
|
||||
"{\n"
|
||||
" auto_ptr<T> p2( new T[] );\n"
|
||||
|
@ -1439,6 +1446,12 @@ private:
|
|||
"}\n");
|
||||
ASSERT_EQUALS("[test.cpp:3]: (error) Object pointed by an 'auto_ptr' is destroyed using operator 'delete'. You should not use 'auto_ptr' for pointers obtained with operator 'new[]'.\n", errout.str());
|
||||
|
||||
check("void f() \n"
|
||||
"{\n"
|
||||
" auto_ptr<foo::bar> p(new foo::bar[10]);\n"
|
||||
"}\n");
|
||||
ASSERT_EQUALS("[test.cpp:3]: (error) Object pointed by an 'auto_ptr' is destroyed using operator 'delete'. You should not use 'auto_ptr' for pointers obtained with operator 'new[]'.\n", errout.str());
|
||||
|
||||
check("void f() \n"
|
||||
"{\n"
|
||||
" auto_ptr<T> p2;\n"
|
||||
|
@ -1460,6 +1473,13 @@ private:
|
|||
"}\n");
|
||||
ASSERT_EQUALS("[test.cpp:4]: (error) Object pointed by an 'auto_ptr' is destroyed using operator 'delete'. You should not use 'auto_ptr' for pointers obtained with operator 'new[]'.\n", errout.str());
|
||||
|
||||
check("void f() \n"
|
||||
"{\n"
|
||||
" auto_ptr<T::B> p2;\n"
|
||||
" p2 = new T::B[10];\n"
|
||||
"}\n");
|
||||
ASSERT_EQUALS("[test.cpp:4]: (error) Object pointed by an 'auto_ptr' is destroyed using operator 'delete'. You should not use 'auto_ptr' for pointers obtained with operator 'new[]'.\n", errout.str());
|
||||
|
||||
check("void f() \n"
|
||||
"{\n"
|
||||
" auto_ptr<T> p2;\n"
|
||||
|
@ -1467,6 +1487,13 @@ private:
|
|||
"}\n");
|
||||
ASSERT_EQUALS("[test.cpp:4]: (error) Object pointed by an 'auto_ptr' is destroyed using operator 'delete'. You should not use 'auto_ptr' for pointers obtained with operator 'new[]'.\n", errout.str());
|
||||
|
||||
check("void f() \n"
|
||||
"{\n"
|
||||
" auto_ptr<T::B> p2;\n"
|
||||
" p2.reset( new T::B[10] );\n"
|
||||
"}\n");
|
||||
ASSERT_EQUALS("[test.cpp:4]: (error) Object pointed by an 'auto_ptr' is destroyed using operator 'delete'. You should not use 'auto_ptr' for pointers obtained with operator 'new[]'.\n", errout.str());
|
||||
|
||||
// ticket #2887 (infinite loop)
|
||||
check("A::A(std::auto_ptr<X> e){}\n");
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
|
|
Loading…
Reference in New Issue