From 8a3ec4549b28a11bf4165cd22e7c458a560e77f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Sat, 20 Jun 2009 19:24:58 +0200 Subject: [PATCH] Fixed #425 (False positive: usage of char variable.. c = c & 0x03) Using char variables in bit operations are ok if: * the result is stored in a char * the variable is and'ed with a number that is less than 0x100 --- src/checkother.cpp | 22 +++++++++++++++++++--- test/testcharvar.cpp | 25 +++++++++++++++++++++++++ 2 files changed, 44 insertions(+), 3 deletions(-) diff --git a/src/checkother.cpp b/src/checkother.cpp index 2c2ac9223..5a37e9c93 100644 --- a/src/checkother.cpp +++ b/src/checkother.cpp @@ -752,10 +752,26 @@ void CheckOther::CheckCharVariable() break; } - std::string tempFirst = "%var% [&|] " + tok->str(); - std::string tempSecond = tok->str() + " [&|]"; - if (Token::Match(tok2, tempFirst.c_str()) || Token::Match(tok2, tempSecond.c_str())) + if (Token::Match(tok2, "[;{}] %var% = %any% [&|] %any% ;")) { + // is the char variable used in the calculation? + if (tok2->tokAt(3)->varId() != tok->varId() && tok2->tokAt(5)->varId() != tok->varId()) + continue; + + // it's ok with a bitwise and where the other operand is 0xff or less.. + if (std::string(tok2->strAt(4)) == "&") + { + if (tok2->tokAt(3)->isNumber() && MathLib::isGreater("0x100", tok2->strAt(3))) + continue; + if (tok2->tokAt(5)->isNumber() && MathLib::isGreater("0x100", tok2->strAt(5))) + continue; + } + + // is the result stored in a short|int|long? + if (!Token::findmatch(_tokenizer->tokens(), "short|int|long %varid%", tok2->next()->varId())) + continue; + + // This is an error.. charBitOpError(tok2); break; } diff --git a/test/testcharvar.cpp b/test/testcharvar.cpp index 2f16baf83..8c3336834 100644 --- a/test/testcharvar.cpp +++ b/test/testcharvar.cpp @@ -39,6 +39,8 @@ private: TEST_CASE(bitop1); TEST_CASE(bitop2); TEST_CASE(return1); + TEST_CASE(assignChar); + TEST_CASE(and03); } void check(const char code[]) @@ -93,6 +95,7 @@ private: { check("void foo()\n" "{\n" + " int result = 0;\n" " char ch;\n" " result = a | ch;\n" "}\n"); @@ -118,6 +121,28 @@ private: "}\n"); ASSERT_EQUALS("", errout.str()); } + + + void assignChar() + { + check("void foo()\n" + "{\n" + " char c;\n" + " c = c & 0x123;\n" + "}\n"); + ASSERT_EQUALS("", errout.str()); + } + + void and03() + { + check("void foo()\n" + "{\n" + " char c;\n" + " int i = c & 0x03;\n" + "}\n"); + ASSERT_EQUALS("", errout.str()); + } + }; REGISTER_TEST(TestCharVar)