Fix 9870: False negative: null pointer after duplicate conditions (#3481)
This commit is contained in:
parent
8668d445c7
commit
9b6c7007d2
|
@ -48,6 +48,7 @@ struct ForwardTraversal {
|
|||
bool check = false;
|
||||
bool escape = false;
|
||||
bool escapeUnknown = false;
|
||||
bool active = false;
|
||||
bool isEscape() const {
|
||||
return escape || escapeUnknown;
|
||||
}
|
||||
|
@ -628,9 +629,11 @@ struct ForwardTraversal {
|
|||
// Traverse then block
|
||||
thenBranch.escape = isEscapeScope(endBlock, thenBranch.escapeUnknown);
|
||||
if (thenBranch.check) {
|
||||
thenBranch.active = true;
|
||||
if (updateRange(endCond->next(), endBlock, depth - 1) == Progress::Break)
|
||||
return Break();
|
||||
} else if (!elseBranch.check) {
|
||||
thenBranch.active = true;
|
||||
if (checkBranch(thenBranch))
|
||||
bail = true;
|
||||
}
|
||||
|
@ -638,10 +641,12 @@ struct ForwardTraversal {
|
|||
if (hasElse) {
|
||||
elseBranch.escape = isEscapeScope(endBlock->linkAt(2), elseBranch.escapeUnknown);
|
||||
if (elseBranch.check) {
|
||||
elseBranch.active = true;
|
||||
Progress result = updateRange(endBlock->tokAt(2), endBlock->linkAt(2), depth - 1);
|
||||
if (result == Progress::Break)
|
||||
return Break();
|
||||
} else if (!thenBranch.check) {
|
||||
elseBranch.active = true;
|
||||
if (checkBranch(elseBranch))
|
||||
bail = true;
|
||||
}
|
||||
|
@ -649,7 +654,10 @@ struct ForwardTraversal {
|
|||
} else {
|
||||
tok = endBlock;
|
||||
}
|
||||
actions |= (thenBranch.action | elseBranch.action);
|
||||
if (thenBranch.active)
|
||||
actions |= thenBranch.action;
|
||||
if (elseBranch.active)
|
||||
actions |= elseBranch.action;
|
||||
if (bail)
|
||||
return Break(Analyzer::Terminate::Bail);
|
||||
if (thenBranch.isDead() && elseBranch.isDead()) {
|
||||
|
@ -660,7 +668,7 @@ struct ForwardTraversal {
|
|||
return Break(Analyzer::Terminate::Bail);
|
||||
}
|
||||
// Conditional return
|
||||
if (thenBranch.isEscape() && !hasElse) {
|
||||
if (thenBranch.active && thenBranch.isEscape() && !hasElse) {
|
||||
if (!thenBranch.isConclusiveEscape()) {
|
||||
if (!analyzer->lowerToInconclusive())
|
||||
return Break(Analyzer::Terminate::Bail);
|
||||
|
|
|
@ -122,6 +122,7 @@ private:
|
|||
TEST_CASE(nullpointer80); // #10410
|
||||
TEST_CASE(nullpointer81); // #8724
|
||||
TEST_CASE(nullpointer82); // #10331
|
||||
TEST_CASE(nullpointer83); // #9870
|
||||
TEST_CASE(nullpointer_addressOf); // address of
|
||||
TEST_CASE(nullpointerSwitch); // #2626
|
||||
TEST_CASE(nullpointer_cast); // #4692
|
||||
|
@ -2495,6 +2496,21 @@ private:
|
|||
ASSERT_EQUALS("", errout.str());
|
||||
}
|
||||
|
||||
void nullpointer83() // #9870
|
||||
{
|
||||
check("int* qux();\n"
|
||||
"int* f7c2(int *x) {\n"
|
||||
" int* p = 0;\n"
|
||||
" if (nullptr == x)\n"
|
||||
" p = qux();\n"
|
||||
" if (nullptr == x)\n"
|
||||
" return x;\n"
|
||||
" *p = 1;\n"
|
||||
" return x;\n"
|
||||
"}\n");
|
||||
ASSERT_EQUALS("[test.cpp:8]: (warning) Possible null pointer dereference: p\n", errout.str());
|
||||
}
|
||||
|
||||
void nullpointer_addressOf() { // address of
|
||||
check("void f() {\n"
|
||||
" struct X *x = 0;\n"
|
||||
|
|
Loading…
Reference in New Issue