diff --git a/lib/checkstring.cpp b/lib/checkstring.cpp index c9965b53e51..e58f065185c 100644 --- a/lib/checkstring.cpp +++ b/lib/checkstring.cpp @@ -288,7 +288,9 @@ void CheckString::checkIncorrectStringCompare() incorrectStringCompareError(tok->next(), "substr", end->strAt(1)); } } - } else if (Token::Match(tok, "%str%|%char%") && isUsedAsBool(tok)) + } else if (Token::Match(tok, "%str%|%char%") && + !(tok->astParent() && tok->astParent()->isExpandedMacro()) && + isUsedAsBool(tok)) incorrectStringBooleanError(tok, tok->str()); } } diff --git a/test/teststring.cpp b/test/teststring.cpp index 87ffcccaaf0..56e886afdc1 100644 --- a/test/teststring.cpp +++ b/test/teststring.cpp @@ -23,6 +23,8 @@ #include "fixture.h" #include "tokenize.h" +#include + #include // IWYU pragma: keep @@ -60,15 +62,24 @@ class TestString : public TestFixture { TEST_CASE(deadStrcmp); } -#define check(...) check_(__FILE__, __LINE__, __VA_ARGS__) - void check_(const char* file, int line, const char code[], const char filename[] = "test.cpp") { + void check(const char code[], const char filename[] = "test.cpp") { // Clear the error buffer.. errout.str(""); + // Raw tokens.. + std::vector files(1, filename); + std::istringstream istr(code); + const simplecpp::TokenList tokens1(istr, files, files[0]); + + // Preprocess.. + simplecpp::TokenList tokens2(files); + std::map filedata; + simplecpp::preprocess(tokens2, tokens1, files, filedata, simplecpp::DUI()); + // Tokenize.. Tokenizer tokenizer(&settings, this); - std::istringstream istr(code); - ASSERT_LOC(tokenizer.tokenize(istr, filename), file, line); + tokenizer.createTokens(std::move(tokens2)); + tokenizer.simplifyTokens1(""); // Check char variable usage.. runChecks(tokenizer, this); @@ -768,6 +779,12 @@ class TestString : public TestFixture { ASSERT_EQUALS("[test.cpp:3]: (warning) Conversion of char literal '\\0' to bool always evaluates to false.\n" "[test.cpp:4]: (warning) Conversion of char literal 'a' to bool always evaluates to true.\n", errout.str()); + + check("#define ERROR(msg) if (msg) printf(\"%s\\n\", msg);\n" + "void f() {\n" + " ERROR(\"abc\")\n" + "}\n"); + ASSERT_EQUALS("", errout.str()); } void deadStrcmp() {