Fix issue 8829: Condition '...' is always true (int buf[42]; if(buf != NULL){})

This makes arrays non-null in valueflow, so it can catch comparisons against null that is always true:

```cpp
void f(void) {
   int buf[42];
   if( buf != 0) {;} // << always true
}
```
This commit is contained in:
Paul Fultz II 2018-12-17 06:07:34 +01:00 committed by Daniel Marjamäki
parent 9b973e652c
commit 025881cf35
3 changed files with 17 additions and 3 deletions

View File

@ -472,9 +472,11 @@ static bool findFormat(unsigned int arg, const Token *firstArg,
argTok->variable()->dimension(0) != 0))) {
*formatArgTok = argTok->nextArgument();
if (!argTok->values().empty()) {
const ValueFlow::Value &value = argTok->values().front();
if (value.isTokValue() && value.tokvalue && value.tokvalue->tokType() == Token::eString) {
*formatStringTok = value.tokvalue;
std::list<ValueFlow::Value>::const_iterator value = std::find_if(
argTok->values().begin(), argTok->values().end(), std::mem_fn(&ValueFlow::Value::isTokValue));
if (value != argTok->values().end() && value->isTokValue() && value->tokvalue &&
value->tokvalue->tokType() == Token::eString) {
*formatStringTok = value->tokvalue;
}
}
return true;

View File

@ -1001,6 +1001,12 @@ static void valueFlowArray(TokenList *tokenlist)
for (Token *tok = tokenlist->front(); tok; tok = tok->next()) {
if (tok->varId() > 0U) {
// array
if (tok->variable() && tok->variable()->isArray() && !tok->variable()->isStlType()) {
ValueFlow::Value value{1};
value.setKnown();
setTokenValue(tok, value, tokenlist->getSettings());
}
const std::map<unsigned int, const Token *>::const_iterator it = constantArrays.find(tok->varId());
if (it != constantArrays.end()) {
ValueFlow::Value value;

View File

@ -2520,6 +2520,12 @@ private:
check("void f1(const std::string &s) { if(s.empty()) if(s.size() == 0) {}} ");
ASSERT_EQUALS("[test.cpp:1] -> [test.cpp:1]: (style) Condition 's.size()==0' is always true\n", errout.str());
check("void f() {\n"
" int buf[42];\n"
" if( buf != 0) {}\n"
"}\n");
ASSERT_EQUALS("[test.cpp:3]: (style) Condition 'buf!=0' is always true\n", errout.str());
// Avoid FP when condition comes from macro
check("#define NOT !\n"
"void f() {\n"