From 025881cf35fdde1299d16a09059e7305f8c9bd13 Mon Sep 17 00:00:00 2001 From: Paul Fultz II Date: Mon, 17 Dec 2018 06:07:34 +0100 Subject: [PATCH] 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 } ``` --- lib/checkio.cpp | 8 +++++--- lib/valueflow.cpp | 6 ++++++ test/testcondition.cpp | 6 ++++++ 3 files changed, 17 insertions(+), 3 deletions(-) diff --git a/lib/checkio.cpp b/lib/checkio.cpp index 73ca0006a..acdf2fa79 100644 --- a/lib/checkio.cpp +++ b/lib/checkio.cpp @@ -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::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; diff --git a/lib/valueflow.cpp b/lib/valueflow.cpp index e0fc45d05..6117cdb05 100644 --- a/lib/valueflow.cpp +++ b/lib/valueflow.cpp @@ -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::const_iterator it = constantArrays.find(tok->varId()); if (it != constantArrays.end()) { ValueFlow::Value value; diff --git a/test/testcondition.cpp b/test/testcondition.cpp index 10772ee53..8984f282e 100644 --- a/test/testcondition.cpp +++ b/test/testcondition.cpp @@ -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"