diff --git a/src/checkother.cpp b/src/checkother.cpp index 3e750f31d..d86b63c00 100644 --- a/src/checkother.cpp +++ b/src/checkother.cpp @@ -971,15 +971,30 @@ void CheckOther::functionVariableUsage() void CheckOther::strPlusChar() { + bool charVars[10000] = {0}; + for (const Token *tok = _tokenizer->tokens(); tok; tok = tok->next()) { - if (Token::Match(tok, "%str% + %any%")) + // Declaring char variable.. + if (Token::Match(tok, "char %var% [;=]")) { - const char *s = tok->strAt(2); + unsigned int varid = tok->next()->varId(); + if (varid>0 && varid<10000) + charVars[varid] = true; + } + // + else if (Token::Match(tok, "%str% + %any%")) + { // char constant.. + const char *s = tok->strAt(2); if (*s == '\'') _errorLogger->reportErr(ErrorMessage::strPlusChar(_tokenizer, tok)); + + // char variable.. + unsigned int varid = tok->tokAt(2)->varId(); + if (varid>0 && varid<10000 && charVars[varid]) + _errorLogger->reportErr(ErrorMessage::strPlusChar(_tokenizer, tok)); } } } diff --git a/test/testother.cpp b/test/testother.cpp index 049413078..c75a65eca 100644 --- a/test/testother.cpp +++ b/test/testother.cpp @@ -43,6 +43,7 @@ private: TEST_CASE(sprintf4); // struct member TEST_CASE(strPlusChar1); // "/usr" + '/' + TEST_CASE(strPlusChar2); // "/usr" + ch } void check(const char code[]) @@ -189,6 +190,17 @@ private: ASSERT_EQUALS(std::string("[test.cpp:3]: Unusual pointer arithmetic\n"), errout.str()); } + void strPlusChar2() + { + // Strange looking pointer arithmetic.. + strPlusChar("void foo()\n" + "{\n" + " char ch = '/';\n" + " const char *p = \"/usr\" + ch;\n" + "}\n"); + ASSERT_EQUALS(std::string("[test.cpp:4]: Unusual pointer arithmetic\n"), errout.str()); + } + }; REGISTER_TEST(TestOther)