diff --git a/lib/checkstring.cpp b/lib/checkstring.cpp index e58f065185c..055dac64278 100644 --- a/lib/checkstring.cpp +++ b/lib/checkstring.cpp @@ -246,6 +246,21 @@ void CheckString::strPlusCharError(const Token *tok) reportError(tok, Severity::error, "strPlusChar", "Unusual pointer arithmetic. A value of type '" + charType +"' is added to a string literal.", CWE665, Certainty::normal); } +static bool isMacroUsage(const Token* tok) +{ + if (const Token* parent = tok->astParent()) { + if (parent->isExpandedMacro()) + return true; + if (parent->isUnaryOp("!")) { + int argn{}; + const Token* ftok = getTokenArgumentFunction(parent, argn); + if (ftok && !ftok->function()) + return true; + } + } + return false; +} + //--------------------------------------------------------------------------- // Implicit casts of string literals to bool // Comparing string literal with strlen() with wrong length @@ -289,8 +304,8 @@ void CheckString::checkIncorrectStringCompare() } } } else if (Token::Match(tok, "%str%|%char%") && - !(tok->astParent() && tok->astParent()->isExpandedMacro()) && - isUsedAsBool(tok)) + isUsedAsBool(tok) && + !isMacroUsage(tok)) incorrectStringBooleanError(tok, tok->str()); } } diff --git a/test/teststring.cpp b/test/teststring.cpp index 56e886afdc1..05e88abd135 100644 --- a/test/teststring.cpp +++ b/test/teststring.cpp @@ -785,6 +785,13 @@ class TestString : public TestFixture { " ERROR(\"abc\")\n" "}\n"); ASSERT_EQUALS("", errout.str()); + + check("void g(int, bool);\n" + "void f() {\n" + " MyAssert(!\"abc\");\n" + " g(2, !\"def\");\n" + "}\n"); + ASSERT_EQUALS("[test.cpp:4]: (warning) Conversion of string literal \"def\" to bool always evaluates to true.\n", errout.str()); } void deadStrcmp() {