Merge pull request #58 from richq/autoptr

Fix namespaced types for auto_ptr new[] errors
This commit is contained in:
Daniel Marjamäki 2011-11-08 23:49:59 -08:00
commit 3b11ae3fac
2 changed files with 44 additions and 4 deletions

View File

@ -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()"); 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) { while (tok2) {
if (Token::Match(tok2, "> %var%")) { if (Token::Match(tok2, "> %var%")) {
const Token *tok3 = tok2->next()->next(); const Token *tok3 = tok2->next()->next();
if (Token::Match(tok3, "( new %type% [")) { if (Token::Match(tok3, "( new %type%") && hasArrayEndParen(tok3)) {
autoPointerArrayError(tok2->next()); autoPointerArrayError(tok2->next());
break; break;
} }
@ -1113,8 +1125,8 @@ void CheckStl::checkAutoPointer()
if (Token::simpleMatch(tok3->previous(), "[ ] )")) { if (Token::simpleMatch(tok3->previous(), "[ ] )")) {
autoPointerArrayError(tok2->next()); autoPointerArrayError(tok2->next());
} else if (tok3->varId()) { } else if (tok3->varId()) {
const Token *decltok = Token::findmatch(_tokenizer->tokens(), "%varid% = new %type% [", tok3->varId()); const Token *decltok = Token::findmatch(_tokenizer->tokens(), "%varid% = new %type%", tok3->varId());
if (decltok) { if (decltok && hasArrayEnd(decltok)) {
autoPointerArrayError(tok2->next()); autoPointerArrayError(tok2->next());
} }
} }
@ -1135,7 +1147,8 @@ void CheckStl::checkAutoPointer()
autoPointerError(tok->next()->next()); 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()); iter = autoPtrVarId.find(tok->varId());
if (iter != autoPtrVarId.end()) { if (iter != autoPtrVarId.end()) {
autoPointerArrayError(tok); autoPointerArrayError(tok);

View File

@ -1427,6 +1427,13 @@ private:
"}\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()); 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" check("void f() \n"
"{\n" "{\n"
" auto_ptr<T> p2( new T[] );\n" " auto_ptr<T> p2( new T[] );\n"
@ -1439,6 +1446,12 @@ private:
"}\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()); 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" check("void f() \n"
"{\n" "{\n"
" auto_ptr<T> p2;\n" " auto_ptr<T> p2;\n"
@ -1460,6 +1473,13 @@ private:
"}\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()); 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" check("void f() \n"
"{\n" "{\n"
" auto_ptr<T> p2;\n" " auto_ptr<T> p2;\n"
@ -1467,6 +1487,13 @@ private:
"}\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()); 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) // ticket #2887 (infinite loop)
check("A::A(std::auto_ptr<X> e){}\n"); check("A::A(std::auto_ptr<X> e){}\n");
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());