Fixed #3345 (false positive: possible null pointer dereference (guarded by &&))

This commit is contained in:
Daniel Marjamäki 2011-12-02 06:11:55 +01:00
parent d2c8b9be56
commit 6763e596b9
2 changed files with 26 additions and 2 deletions

View File

@ -507,6 +507,21 @@ void CheckNullPointer::nullPointerStructByDeRefAndChec()
} }
if (assignment) if (assignment)
continue; continue;
// Is the dereference checked with a previous &&
bool checked = false;
for (tok2 = tok1->tokAt(-2); tok2; tok2 = tok2->previous()) {
if (Token::Match(tok2, "[,(;{}]"))
break;
else if (tok2->str() == ")")
tok2 = tok2->link();
else if (Token::Match(tok2, "%varid% &&", varid1)) {
checked = true;
break;
}
}
if (checked)
continue;
} }
// Goto next token // Goto next token
@ -673,16 +688,19 @@ void CheckNullPointer::nullPointerByDeRefAndChec()
if (tok1->varId() == varid) { if (tok1->varId() == varid) {
// Don't write warning if the dereferencing is // Don't write warning if the dereferencing is
// guarded by ?: // guarded by ?: or &&
const Token *tok2 = tok1->previous(); const Token *tok2 = tok1->previous();
if (tok2 && (tok2->isArithmeticalOp() || tok2->str() == "(")) { if (tok2 && (tok2->isArithmeticalOp() || tok2->str() == "(")) {
while (tok2 && !Token::Match(tok2, "[;{}?:]")) { while (tok2 && !Token::Match(tok2, "[;{}?:]")) {
if (tok2->str() == ")") if (tok2->str() == ")")
tok2 = tok2->link(); tok2 = tok2->link();
// guarded by &&
if (tok2->varId() == varid && tok2->next()->str() == "&&")
break;
tok2 = tok2->previous(); tok2 = tok2->previous();
} }
} }
if (Token::Match(tok2, "[?:]")) if (Token::Match(tok2, "[?:]") || tok2->varId() == varid)
continue; continue;
// unknown : this is set by isPointerDeRef if it is // unknown : this is set by isPointerDeRef if it is

View File

@ -301,6 +301,12 @@ private:
"}\n"); "}\n");
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
check("void f(struct ABC *abc) {\n"
" int x = abc && a(abc->x);\n"
" if (abc) { }\n"
"}");
ASSERT_EQUALS("", errout.str());
// ok to use a linked list.. // ok to use a linked list..
check("void foo(struct ABC *abc)\n" check("void foo(struct ABC *abc)\n"
"{\n" "{\n"