Merge branch 'master' of github.com:danmar/cppcheck

This commit is contained in:
Kimmo Varis 2010-01-03 19:50:45 +02:00
commit 0eb07a409d
4 changed files with 72 additions and 0 deletions

View File

@ -1625,6 +1625,26 @@ private:
return &tok; return &tok;
} }
// += etc
if (Token::Match(tok.previous(), "[;{}]") || Token::Match(tok.tokAt(-2), "[;{}] *"))
{
// goto the equal..
const Token *eq = tok.next();
if (eq && eq->str() == "[" && eq->link() && eq->link()->next())
eq = eq->link()->next();
// is it X=
if (Token::Match(eq, "+=|-=|*=|/=|&=|^=") || eq->str() == "|=")
{
if (tok.previous()->str() == "*")
use_pointer(foundError, checks, &tok);
else if (tok.next()->str() == "[")
use_array(foundError, checks, &tok);
else
use(foundError, checks, &tok);
}
}
if (Token::Match(tok.next(), "= malloc|kmalloc") || Token::simpleMatch(tok.next(), "= new char [")) if (Token::Match(tok.next(), "= malloc|kmalloc") || Token::simpleMatch(tok.next(), "= new char ["))
{ {
alloc_pointer(checks, tok.varId()); alloc_pointer(checks, tok.varId());

View File

@ -95,6 +95,12 @@ static const Token *checkExecutionPaths_(const Token *tok, std::list<ExecutionPa
return 0; return 0;
} }
if (Token::Match(tok, "abort|exit ("))
{
ExecutionPath::bailOut(checks);
return 0;
}
// don't parse into "struct type { .." // don't parse into "struct type { .."
if (Token::Match(tok, "struct %type% {")) if (Token::Match(tok, "struct %type% {"))
tok = tok->tokAt(2)->link(); tok = tok->tokAt(2)->link();

View File

@ -95,6 +95,7 @@ private:
TEST_CASE(array_index_23); TEST_CASE(array_index_23);
TEST_CASE(array_index_multidim); TEST_CASE(array_index_multidim);
TEST_CASE(array_index_switch_in_for); TEST_CASE(array_index_switch_in_for);
TEST_CASE(array_index_calculation);
TEST_CASE(buffer_overrun_1); TEST_CASE(buffer_overrun_1);
TEST_CASE(buffer_overrun_2); TEST_CASE(buffer_overrun_2);
@ -819,9 +820,24 @@ private:
" };\n" " };\n"
" }\n" " }\n"
"}\n"); "}\n");
ASSERT_EQUALS("", errout.str());
TODO_ASSERT_EQUALS("[test.cpp:12]: (error) Array index out of bounds\n", errout.str()); TODO_ASSERT_EQUALS("[test.cpp:12]: (error) Array index out of bounds\n", errout.str());
} }
void array_index_calculation()
{
// #1193 - false negative: array out of bounds in loop when there is calculation
check("void f()\n"
"{\n"
" char data[8];\n"
" for (int i = 19; i < 36; ++i) {\n"
" data[(i-0)/2] = 0;\n"
" }\n"
"}\n");
ASSERT_EQUALS("", errout.str());
TODO_ASSERT_EQUALS("[test.cpp:5]: (error) Array index out of bounds\n", errout.str());
}
void buffer_overrun_1() void buffer_overrun_1()
{ {
check("void f()\n" check("void f()\n"

View File

@ -954,6 +954,14 @@ private:
"}\n"); "}\n");
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
checkNullPointer("static void foo()\n"
"{\n"
" int *p = 0;\n"
" exit();\n"
" *p = 0;\n"
"}\n");
ASSERT_EQUALS("", errout.str());
checkNullPointer("static void foo(int a)\n" checkNullPointer("static void foo(int a)\n"
"{\n" "{\n"
" Foo *p = 0;\n" " Foo *p = 0;\n"
@ -1176,6 +1184,28 @@ private:
"}\n"); "}\n");
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
// +=
checkUninitVar("void f()\n"
"{\n"
" int c;\n"
" c += 2;\n"
"}\n");
ASSERT_EQUALS("[test.cpp:4]: (error) Uninitialized variable: c\n", errout.str());
checkUninitVar("void f()\n"
"{\n"
" char *s = malloc(100);\n"
" *s += 10;\n"
"}\n");
ASSERT_EQUALS("[test.cpp:4]: (error) Data is allocated but not initialized: s\n", errout.str());
checkUninitVar("void f()\n"
"{\n"
" int a[10];\n"
" a[0] += 10;\n"
"}\n");
ASSERT_EQUALS("[test.cpp:4]: (error) Uninitialized variable: a\n", errout.str());
// goto.. // goto..
checkUninitVar("void foo(int x)\n" checkUninitVar("void foo(int x)\n"
"{\n" "{\n"