Skip to content

Commit 923f7f8

Browse files
committed
Better distinguishing between possible and known null pointer dereferenciations (#7157)
1 parent 11be3a9 commit 923f7f8

3 files changed

Lines changed: 42 additions & 44 deletions

File tree

lib/checknullpointer.cpp

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -291,7 +291,7 @@ void CheckNullPointer::nullPointerLinkedList()
291291
// for statement.
292292
for (const Token *tok4 = scope->classStart; tok4; tok4 = tok4->next()) {
293293
if (tok4 == i->classEnd) {
294-
nullPointerError(tok1, var->name(), scope->classDef);
294+
nullPointerError(tok1, var->name(), scope->classDef, false);
295295
break;
296296
}
297297

@@ -345,7 +345,7 @@ void CheckNullPointer::nullPointerByDeRefAndChec()
345345
parseFunctionCall(*ftok->previous(), varlist, &_settings->library, 0);
346346
if (std::find(varlist.begin(), varlist.end(), tok) != varlist.end()) {
347347
if (value->condition == nullptr)
348-
nullPointerError(tok, tok->str(), false, value->defaultArg);
348+
nullPointerError(tok, tok->str(), false, value->defaultArg, !value->isKnown());
349349
else if (printWarnings)
350350
nullPointerError(tok, tok->str(), value->condition, value->inconclusive);
351351
}
@@ -357,15 +357,15 @@ void CheckNullPointer::nullPointerByDeRefAndChec()
357357
if (!isPointerDeRef(tok,unknown)) {
358358
if (printInconclusive && unknown) {
359359
if (value->condition == nullptr)
360-
nullPointerError(tok, tok->str(), true, value->defaultArg);
360+
nullPointerError(tok, tok->str(), true, value->defaultArg, !value->isKnown());
361361
else
362362
nullPointerError(tok, tok->str(), value->condition, true);
363363
}
364364
continue;
365365
}
366366

367367
if (value->condition == nullptr)
368-
nullPointerError(tok, tok->str(), value->inconclusive, value->defaultArg);
368+
nullPointerError(tok, tok->str(), value->inconclusive, value->defaultArg, !value->isKnown());
369369
else if (printWarnings)
370370
nullPointerError(tok, tok->str(), value->condition, value->inconclusive);
371371
}
@@ -471,13 +471,16 @@ void CheckNullPointer::nullPointerError(const Token *tok)
471471
reportError(tok, Severity::error, "nullPointer", "Null pointer dereference", CWE476, false);
472472
}
473473

474-
void CheckNullPointer::nullPointerError(const Token *tok, const std::string &varname, bool inconclusive, bool defaultArg)
474+
void CheckNullPointer::nullPointerError(const Token *tok, const std::string &varname, bool inconclusive, bool defaultArg, bool possible)
475475
{
476476
if (defaultArg) {
477477
if (_settings->isEnabled("warning"))
478478
reportError(tok, Severity::warning, "nullPointerDefaultArg", "Possible null pointer dereference if the default parameter value is used: " + varname, CWE(0U), inconclusive);
479+
} else if (possible) {
480+
if (_settings->isEnabled("warning"))
481+
reportError(tok, Severity::warning, "nullPointer", "Possible null pointer dereference: " + varname, CWE476, inconclusive);
479482
} else
480-
reportError(tok, Severity::error, "nullPointer", "Possible null pointer dereference: " + varname, CWE476, inconclusive);
483+
reportError(tok, Severity::error, "nullPointer", "Null pointer dereference: " + varname, CWE476, inconclusive);
481484
}
482485

483486
void CheckNullPointer::nullPointerError(const Token *tok, const std::string &varname, const Token* nullCheck, bool inconclusive)

lib/checknullpointer.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -86,16 +86,16 @@ class CPPCHECKLIB CheckNullPointer : public Check {
8686
void nullConstantDereference();
8787

8888
void nullPointerError(const Token *tok); // variable name unknown / doesn't exist
89-
void nullPointerError(const Token *tok, const std::string &varname, bool inconclusive = false, bool defaultArg = false);
90-
void nullPointerError(const Token *tok, const std::string &varname, const Token* nullcheck, bool inconclusive = false);
89+
void nullPointerError(const Token *tok, const std::string &varname, bool inconclusive, bool defaultArg, bool possible);
90+
void nullPointerError(const Token *tok, const std::string &varname, const Token* nullcheck, bool inconclusive);
9191
private:
9292

9393
/** Get error messages. Used by --errorlist */
9494
void getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) const {
9595
CheckNullPointer c(0, settings, errorLogger);
9696
c.nullPointerError(0);
97-
c.nullPointerError(0, "pointer", false, true);
98-
c.nullPointerError(0, "pointer", nullptr);
97+
c.nullPointerError(0, "pointer", false, true, true);
98+
c.nullPointerError(0, "pointer", nullptr, false);
9999
}
100100

101101
/** Name of check */

test/testnullpointer.cpp

Lines changed: 29 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -892,7 +892,7 @@ class TestNullPointer : public TestFixture {
892892

893893
// inconclusive=true => error
894894
check(code, true);
895-
ASSERT_EQUALS("[test.cpp:3]: (error, inconclusive) Possible null pointer dereference: abc\n", errout.str());
895+
ASSERT_EQUALS("[test.cpp:3]: (error, inconclusive) Null pointer dereference: abc\n", errout.str());
896896
}
897897

898898
check("static void foo() {\n"
@@ -908,7 +908,7 @@ class TestNullPointer : public TestFixture {
908908
" }\n"
909909
" c[0] = 0;\n"
910910
"}");
911-
ASSERT_EQUALS("[test.cpp:7]: (error) Possible null pointer dereference: c\n", errout.str());
911+
ASSERT_EQUALS("[test.cpp:7]: (error) Null pointer dereference: c\n", errout.str());
912912

913913
check("static void foo() {\n"
914914
" if (3 > *0);\n"
@@ -970,7 +970,7 @@ class TestNullPointer : public TestFixture {
970970
" *Q=1;\n"
971971
" return Q;\n"
972972
"}");
973-
ASSERT_EQUALS("[test.cpp:12]: (error) Possible null pointer dereference: Q\n", errout.str());
973+
ASSERT_EQUALS("[test.cpp:12]: (warning) Possible null pointer dereference: Q\n", errout.str());
974974

975975
// Ticket #2052 (false positive for 'else continue;')
976976
check("void f() {\n"
@@ -990,7 +990,7 @@ class TestNullPointer : public TestFixture {
990990
" f = 0;\n"
991991
" f();\n"
992992
"}");
993-
ASSERT_EQUALS("[test.cpp:5]: (error) Possible null pointer dereference: f\n", errout.str());
993+
ASSERT_EQUALS("[test.cpp:5]: (error) Null pointer dereference: f\n", errout.str());
994994

995995
// loops..
996996
check("void f() {\n"
@@ -999,7 +999,7 @@ class TestNullPointer : public TestFixture {
999999
" int x = *p + 1;\n"
10001000
" }\n"
10011001
"}");
1002-
ASSERT_EQUALS("[test.cpp:4]: (error) Possible null pointer dereference: p\n", errout.str());
1002+
ASSERT_EQUALS("[test.cpp:4]: (error) Null pointer dereference: p\n", errout.str());
10031003

10041004
check("void f(int a) {\n"
10051005
" const char *p = 0;\n"
@@ -1098,7 +1098,7 @@ class TestNullPointer : public TestFixture {
10981098
"\n"
10991099
" *p = 0;\n"
11001100
"}");
1101-
ASSERT_EQUALS("[test.cpp:11]: (error) Possible null pointer dereference: p\n", errout.str());
1101+
ASSERT_EQUALS("[test.cpp:11]: (warning) Possible null pointer dereference: p\n", errout.str());
11021102
}
11031103

11041104
void nullpointer7() {
@@ -1116,8 +1116,7 @@ class TestNullPointer : public TestFixture {
11161116
" std::string * x = 0;\n"
11171117
" *x = \"test\";\n"
11181118
"}");
1119-
ASSERT_EQUALS("[test.cpp:4]: (error) Possible null pointer dereference: x\n"
1120-
"[test.cpp:4]: (error) Null pointer dereference\n", errout.str());
1119+
ASSERT_EQUALS("[test.cpp:4]: (error) Null pointer dereference: x\n", errout.str());
11211120
}
11221121

11231122
void nullpointer10() {
@@ -1126,7 +1125,7 @@ class TestNullPointer : public TestFixture {
11261125
" struct my_type* p = 0;\n"
11271126
" p->x = 0;\n"
11281127
"}");
1129-
ASSERT_EQUALS("[test.cpp:4]: (error) Possible null pointer dereference: p\n", errout.str());
1128+
ASSERT_EQUALS("[test.cpp:4]: (error) Null pointer dereference: p\n", errout.str());
11301129
}
11311130

11321131
void nullpointer11() { // ticket #2812
@@ -1136,7 +1135,7 @@ class TestNullPointer : public TestFixture {
11361135
" p = 0;\n"
11371136
" return p->x;\n"
11381137
"}");
1139-
ASSERT_EQUALS("[test.cpp:5]: (error) Possible null pointer dereference: p\n", errout.str());
1138+
ASSERT_EQUALS("[test.cpp:5]: (error) Null pointer dereference: p\n", errout.str());
11401139
}
11411140

11421141
void nullpointer12() { // ticket #2470, #4035
@@ -1147,8 +1146,7 @@ class TestNullPointer : public TestFixture {
11471146
"}\n";
11481147

11491148
check(code, false, "test.cpp"); // C++ file => nullptr means NULL
1150-
ASSERT_EQUALS("[test.cpp:4]: (error) Possible null pointer dereference: i\n"
1151-
"[test.cpp:4]: (error) Null pointer dereference\n", errout.str());
1149+
ASSERT_EQUALS("[test.cpp:4]: (error) Null pointer dereference: i\n", errout.str());
11521150

11531151
check(code, false, "test.c"); // C file => nullptr does not mean NULL
11541152
ASSERT_EQUALS("", errout.str());
@@ -1198,8 +1196,7 @@ class TestNullPointer : public TestFixture {
11981196
" i++;\n"
11991197
" };\n"
12001198
"}");
1201-
ASSERT_EQUALS("[test.cpp:5]: (error) Possible null pointer dereference: str\n"
1202-
"[test.cpp:5]: (error) Null pointer dereference\n", errout.str());
1199+
ASSERT_EQUALS("[test.cpp:5]: (error) Null pointer dereference: str\n", errout.str());
12031200
}
12041201

12051202
void nullpointer19() { // #3811
@@ -1222,7 +1219,7 @@ class TestNullPointer : public TestFixture {
12221219
" if (x) p = q;\n"
12231220
" if (y ? p->x : p->y) { }\n"
12241221
"}");
1225-
ASSERT_EQUALS("[test.cpp:4]: (error) Possible null pointer dereference: p\n", errout.str());
1222+
ASSERT_EQUALS("[test.cpp:4]: (warning) Possible null pointer dereference: p\n", errout.str());
12261223
}
12271224

12281225
void nullpointer21() { // #4038 - fp: if (x) p=q; else return;
@@ -1260,7 +1257,7 @@ class TestNullPointer : public TestFixture {
12601257
" if (data == 1 && array[i] == 0)\n"
12611258
" std::cout << \"test\";\n"
12621259
"}");
1263-
ASSERT_EQUALS("[test.cpp:4]: (error) Possible null pointer dereference: array\n", errout.str());
1260+
ASSERT_EQUALS("[test.cpp:4]: (error) Null pointer dereference: array\n", errout.str());
12641261
}
12651262

12661263
void nullpointer26() { // #3589
@@ -1291,8 +1288,7 @@ class TestNullPointer : public TestFixture {
12911288
" *pointer_=0;\n"
12921289
" return *this;\n"
12931290
"}");
1294-
ASSERT_EQUALS("[test.cpp:8]: (error) Possible null pointer dereference: pointer_\n"
1295-
"[test.cpp:8]: (error) Null pointer dereference\n", errout.str());
1291+
ASSERT_EQUALS("[test.cpp:8]: (error) Null pointer dereference: pointer_\n", errout.str());
12961292
}
12971293

12981294
void nullpointer28() { // #6491
@@ -1303,7 +1299,7 @@ class TestNullPointer : public TestFixture {
13031299
" return i;\n"
13041300
"}\n"
13051301
"int main(){f(0);}\n", true);
1306-
ASSERT_EQUALS("[test.cpp:4]: (error) Possible null pointer dereference: s\n", errout.str());
1302+
ASSERT_EQUALS("[test.cpp:4]: (warning) Possible null pointer dereference: s\n", errout.str());
13071303
}
13081304

13091305
void nullpointer30() { // #6392
@@ -1347,7 +1343,7 @@ class TestNullPointer : public TestFixture {
13471343
" }\n"
13481344
" return p;\n"
13491345
"}", true);
1350-
ASSERT_EQUALS("[test.cpp:7]: (error) Possible null pointer dereference: p\n"
1346+
ASSERT_EQUALS("[test.cpp:7]: (warning) Possible null pointer dereference: p\n"
13511347
"[test.cpp:7]: (error) Null pointer dereference\n", errout.str());
13521348
}
13531349

@@ -1756,8 +1752,7 @@ class TestNullPointer : public TestFixture {
17561752
" int* p = 0;\n"
17571753
" return p[4];\n"
17581754
"}");
1759-
ASSERT_EQUALS("[test.cpp:3]: (error) Possible null pointer dereference: p\n"
1760-
"[test.cpp:3]: (error) Null pointer dereference\n", errout.str());
1755+
ASSERT_EQUALS("[test.cpp:3]: (error) Null pointer dereference: p\n", errout.str());
17611756

17621757
check("void f() {\n"
17631758
" typeof(*NULL) y;\n"
@@ -1804,7 +1799,7 @@ class TestNullPointer : public TestFixture {
18041799
" char* s = 0;\n"
18051800
" printf(\"%s\", s);\n"
18061801
"}");
1807-
ASSERT_EQUALS("[test.cpp:3]: (error) Possible null pointer dereference: s\n", errout.str());
1802+
ASSERT_EQUALS("[test.cpp:3]: (error) Null pointer dereference: s\n", errout.str());
18081803

18091804
check("void f() {\n"
18101805
" char *s = 0;\n"
@@ -1826,7 +1821,7 @@ class TestNullPointer : public TestFixture {
18261821
" char* s = 0;\n"
18271822
" printf(\"%u%s\", 123, s);\n"
18281823
"}");
1829-
ASSERT_EQUALS("[test.cpp:3]: (error) Possible null pointer dereference: s\n", errout.str());
1824+
ASSERT_EQUALS("[test.cpp:3]: (error) Null pointer dereference: s\n", errout.str());
18301825

18311826

18321827
check("void f() {\n"
@@ -1893,7 +1888,7 @@ class TestNullPointer : public TestFixture {
18931888
" int* iVal = 0;\n"
18941889
" sscanf(dummy, \"%d\", iVal);\n"
18951890
"}");
1896-
ASSERT_EQUALS("[test.cpp:3]: (error) Possible null pointer dereference: iVal\n", errout.str());
1891+
ASSERT_EQUALS("[test.cpp:3]: (error) Null pointer dereference: iVal\n", errout.str());
18971892

18981893
check("void f(char *dummy) {\n"
18991894
" int* iVal;\n"
@@ -1919,7 +1914,7 @@ class TestNullPointer : public TestFixture {
19191914
" if(g()) iVal = g();\n"
19201915
" return iVal[0];\n"
19211916
"}");
1922-
ASSERT_EQUALS("[test.cpp:4]: (error) Possible null pointer dereference: iVal\n", errout.str());
1917+
ASSERT_EQUALS("[test.cpp:4]: (warning) Possible null pointer dereference: iVal\n", errout.str());
19231918

19241919
check("int foo(int* iVal) {\n"
19251920
" return iVal[0];\n"
@@ -2005,8 +2000,8 @@ class TestNullPointer : public TestFixture {
20052000
" std::string s5(p);\n"
20062001
" foo(std::string(p));\n"
20072002
"}", true);
2008-
ASSERT_EQUALS("[test.cpp:9]: (error) Possible null pointer dereference: p\n"
2009-
"[test.cpp:10]: (error) Possible null pointer dereference: p\n"
2003+
ASSERT_EQUALS("[test.cpp:9]: (error) Null pointer dereference: p\n"
2004+
"[test.cpp:10]: (error) Null pointer dereference: p\n"
20102005
"[test.cpp:3]: (error) Null pointer dereference\n"
20112006
"[test.cpp:5]: (error) Null pointer dereference\n"
20122007
"[test.cpp:7]: (error) Null pointer dereference\n"
@@ -2025,10 +2020,10 @@ class TestNullPointer : public TestFixture {
20252020
" foo(p == s2);\n"
20262021
" foo(p == s3);\n"
20272022
"}", true);
2028-
ASSERT_EQUALS("[test.cpp:4]: (error) Possible null pointer dereference: p\n"
2029-
"[test.cpp:5]: (error) Possible null pointer dereference: p\n"
2030-
"[test.cpp:7]: (error) Possible null pointer dereference: p\n"
2031-
"[test.cpp:8]: (error) Possible null pointer dereference: p\n", errout.str());
2023+
ASSERT_EQUALS("[test.cpp:4]: (error) Null pointer dereference: p\n"
2024+
"[test.cpp:5]: (error) Null pointer dereference: p\n"
2025+
"[test.cpp:7]: (error) Null pointer dereference: p\n"
2026+
"[test.cpp:8]: (error) Null pointer dereference: p\n", errout.str());
20322027

20332028
check("void f(std::string s1, const std::string& s2, const std::string* s3) {\n"
20342029
" void* p = 0;\n"
@@ -2098,8 +2093,8 @@ class TestNullPointer : public TestFixture {
20982093
" if(q == 0)\n"
20992094
" oss << foo << q;\n"
21002095
"}", false);
2101-
ASSERT_EQUALS("[test.cpp:3]: (error) Possible null pointer dereference: p\n"
2102-
"[test.cpp:4]: (error) Possible null pointer dereference: p\n"
2096+
ASSERT_EQUALS("[test.cpp:3]: (error) Null pointer dereference: p\n"
2097+
"[test.cpp:4]: (error) Null pointer dereference: p\n"
21032098
"[test.cpp:6] -> [test.cpp:5]: (warning) Either the condition 'q==0' is redundant or there is possible null pointer dereference: q.\n", errout.str());
21042099

21052100
check("void f(const char* p) {\n"

0 commit comments

Comments
 (0)