Fixed #3128 (False positive: null pointer dereference check does not handle complex boolean logic properly)

This commit is contained in:
Daniel Marjamäki 2011-10-07 21:08:21 +02:00
parent 12218e1bff
commit e2ec5a127f
2 changed files with 33 additions and 0 deletions

View File

@ -367,6 +367,15 @@ void CheckNullPointer::nullPointerStructByDeRefAndChec()
skipvar.insert(tok1->varId()); skipvar.insert(tok1->varId());
continue; continue;
} }
else if (Token::Match(tok1, "( ! %var% ||") ||
Token::Match(tok1, "( %var% &&"))
{
tok1 = tok1->next();
if (tok1->str() == "!")
tok1 = tok1->next();
skipvar.insert(tok1->varId());
continue;
}
/** /**
* @todo There are lots of false negatives here. A dereference * @todo There are lots of false negatives here. A dereference
@ -564,6 +573,10 @@ void CheckNullPointer::nullPointerByDeRefAndChec()
if (Token::Match(tok1->link()->previous(), "while ( %varid%", varid)) if (Token::Match(tok1->link()->previous(), "while ( %varid%", varid))
break; break;
if (Token::Match(tok1->link(), "( ! %varid% ||", varid) ||
Token::Match(tok1->link(), "( %varid% &&", varid))
break;
if (Token::simpleMatch(tok1->link()->previous(), "sizeof (")) if (Token::simpleMatch(tok1->link()->previous(), "sizeof ("))
{ {
tok1 = tok1->link()->previous(); tok1 = tok1->link()->previous();

View File

@ -385,6 +385,13 @@ private:
" }\n" " }\n"
"}"); "}");
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
// #3128
check("void f(ABC *abc) {\n"
" x(!abc || y(abc->a));\n"
" if (abc) {}\n"
"}");
ASSERT_EQUALS("", errout.str());
} }
// Dereferencing a pointer and then checking if it is null // Dereferencing a pointer and then checking if it is null
@ -524,6 +531,19 @@ private:
"}"); "}");
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
// #3128 - false positive
check("void f(int *p) {\n"
" assert(!p || (*p<=6));\n"
" if (p) { *p = 0; }\n"
"}");
ASSERT_EQUALS("", errout.str());
check("void f(int *p) {\n"
" assert(p && (*p<=6));\n"
" if (p) { *p = 0; }\n"
"}");
ASSERT_EQUALS("", errout.str());
check("void foo(x *p)\n" check("void foo(x *p)\n"
"{\n" "{\n"
" p = p->next;\n" " p = p->next;\n"