value flow: use more specific bailouts when analysing value flow after assignment
This commit is contained in:
parent
cc38dec3ad
commit
43db1ee797
|
@ -583,7 +583,7 @@ void CheckNullPointer::nullPointerByDeRefAndChec()
|
|||
parseFunctionCall(*ftok->previous(), varlist, &_settings->library, 0);
|
||||
if (std::find(varlist.begin(), varlist.end(), tok) != varlist.end()) {
|
||||
if (value->condition == NULL)
|
||||
nullPointerError(tok);
|
||||
nullPointerError(tok, tok->str());
|
||||
else if (_settings->isEnabled("warning"))
|
||||
nullPointerError(tok, tok->str(), value->condition, value->inconclusive);
|
||||
}
|
||||
|
@ -593,13 +593,13 @@ void CheckNullPointer::nullPointerByDeRefAndChec()
|
|||
// Pointer dereference.
|
||||
bool unknown = false;
|
||||
if (!isPointerDeRef(tok,unknown)) {
|
||||
if (_settings->inconclusive && unknown)
|
||||
if (_settings->inconclusive && unknown && value->condition)
|
||||
nullPointerError(tok, tok->str(), value->condition, true);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (value->condition == NULL)
|
||||
nullPointerError(tok);
|
||||
nullPointerError(tok, tok->str());
|
||||
else if (_settings->isEnabled("warning"))
|
||||
nullPointerError(tok, tok->str(), value->condition, value->inconclusive);
|
||||
}
|
||||
|
|
|
@ -461,15 +461,34 @@ static void valueFlowAfterAssign(TokenList *tokenlist, ErrorLogger *errorLogger,
|
|||
for (Token *tok2 = tok; tok2; tok2 = tok2->next()) {
|
||||
if (Token::Match(tok2, "[{}]"))
|
||||
break;
|
||||
if (Token::Match(tok2, "sizeof ("))
|
||||
if (Token::Match(tok2, "sizeof|typeof|typeid ("))
|
||||
tok2 = tok2->linkAt(1);
|
||||
if (tok2->varId() == varid) {
|
||||
if (!Token::Match(tok2->previous(), "%cop%|= %var% %cop%|;"))
|
||||
// bailout: assignment
|
||||
if (Token::Match(tok2->previous(), "!!* %var% =")) {
|
||||
if (settings->debugwarnings)
|
||||
bailout(tokenlist, errorLogger, tok2, "assignment of " + tok2->str());
|
||||
break;
|
||||
}
|
||||
|
||||
std::list<ValueFlow::Value>::const_iterator it;
|
||||
for (it = values.begin(); it != values.end(); ++it)
|
||||
setTokenValue(tok2, *it);
|
||||
{
|
||||
std::list<ValueFlow::Value>::const_iterator it;
|
||||
for (it = values.begin(); it != values.end(); ++it)
|
||||
setTokenValue(tok2, *it);
|
||||
}
|
||||
|
||||
// assigned by subfunction?
|
||||
bool inconclusive = false;
|
||||
if (bailoutFunctionPar(tok2, ValueFlow::Value(), settings, &inconclusive)) {
|
||||
if (settings->debugwarnings)
|
||||
bailout(tokenlist, errorLogger, tok2, "possible assignment of " + tok2->str() + " by subfunction");
|
||||
break;
|
||||
}
|
||||
if (inconclusive) {
|
||||
std::list<ValueFlow::Value>::iterator it;
|
||||
for (it = values.begin(); it != values.end(); ++it)
|
||||
it->inconclusive = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1126,7 +1126,8 @@ private:
|
|||
" std::string * x = 0;\n"
|
||||
" *x = \"test\";\n"
|
||||
"}", false, "test.cpp", false);
|
||||
ASSERT_EQUALS("[test.cpp:4]: (error) Null pointer dereference\n", errout.str());
|
||||
ASSERT_EQUALS("[test.cpp:4]: (error) Possible null pointer dereference: x\n"
|
||||
"[test.cpp:4]: (error) Null pointer dereference\n", errout.str());
|
||||
}
|
||||
|
||||
void nullpointer10() {
|
||||
|
@ -1156,7 +1157,8 @@ private:
|
|||
"}\n";
|
||||
|
||||
check(code, false, "test.cpp", false); // C++ file => nullptr means NULL
|
||||
ASSERT_EQUALS("[test.cpp:4]: (error) Null pointer dereference\n", errout.str());
|
||||
ASSERT_EQUALS("[test.cpp:4]: (error) Possible null pointer dereference: i\n"
|
||||
"[test.cpp:4]: (error) Null pointer dereference\n", errout.str());
|
||||
|
||||
check(code, false, "test.c", false); // C file => nullptr does not mean NULL
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
|
@ -1229,7 +1231,8 @@ private:
|
|||
" i++;\n"
|
||||
" };\n"
|
||||
"}\n", false, "test.cpp", false);
|
||||
ASSERT_EQUALS("[test.cpp:5]: (error) Null pointer dereference\n", errout.str());
|
||||
ASSERT_EQUALS("[test.cpp:5]: (error) Possible null pointer dereference: str\n"
|
||||
"[test.cpp:5]: (error) Null pointer dereference\n", errout.str());
|
||||
}
|
||||
|
||||
void nullpointer19() { // #3811
|
||||
|
@ -1715,7 +1718,8 @@ private:
|
|||
" int* p = 0;\n"
|
||||
" return p[4];\n"
|
||||
"}", false, "test.cpp", false);
|
||||
ASSERT_EQUALS("[test.cpp:3]: (error) Null pointer dereference\n", errout.str());
|
||||
ASSERT_EQUALS("[test.cpp:3]: (error) Possible null pointer dereference: p\n"
|
||||
"[test.cpp:3]: (error) Null pointer dereference\n", errout.str());
|
||||
|
||||
check("void f(int x) {\n" // #4809 - passing "NULL"
|
||||
" itoa(x,NULL,10);\n"
|
||||
|
@ -1969,14 +1973,12 @@ private:
|
|||
" std::string s5(p);\n"
|
||||
" foo(std::string(p));\n"
|
||||
"}", true);
|
||||
ASSERT_EQUALS("[test.cpp:7]: (error) Null pointer dereference\n"
|
||||
"[test.cpp:8]: (error) Null pointer dereference\n"
|
||||
ASSERT_EQUALS("[test.cpp:7]: (error) Possible null pointer dereference: p\n"
|
||||
"[test.cpp:8]: (error) Possible null pointer dereference: p\n"
|
||||
"[test.cpp:3]: (error) Null pointer dereference\n"
|
||||
"[test.cpp:4]: (error) Null pointer dereference\n"
|
||||
"[test.cpp:5]: (error) Null pointer dereference\n"
|
||||
"[test.cpp:6]: (error) Null pointer dereference\n"
|
||||
"[test.cpp:7]: (error) Possible null pointer dereference: p\n"
|
||||
"[test.cpp:8]: (error) Possible null pointer dereference: p\n"
|
||||
"[test.cpp:9]: (error) Possible null pointer dereference: p\n"
|
||||
"[test.cpp:10]: (error) Possible null pointer dereference: p\n", errout.str());
|
||||
|
||||
|
|
|
@ -4361,7 +4361,8 @@ private:
|
|||
ASSERT_EQUALS("[test.cpp:5] -> [test.cpp:1]: (style, inconclusive) The typedef 'A' hides a typedef with the same name.\n"
|
||||
"[test.cpp:20] -> [test.cpp:1]: (style, inconclusive) The function parameter 'A' hides a typedef with the same name.\n"
|
||||
"[test.cpp:21] -> [test.cpp:1]: (style, inconclusive) The variable 'A' hides a typedef with the same name.\n"
|
||||
"[test.cpp:24] -> [test.cpp:1]: (style, inconclusive) The typedef 'A' hides a typedef with the same name.\n", errout.str());
|
||||
"[test.cpp:24] -> [test.cpp:1]: (style, inconclusive) The typedef 'A' hides a typedef with the same name.\n"
|
||||
"[test.cpp:24]: (debug) ValueFlow bailout: parameter a\n", errout.str());
|
||||
}
|
||||
|
||||
void simplifyTypedef36() {
|
||||
|
|
Loading…
Reference in New Issue