diff --git a/lib/checkother.cpp b/lib/checkother.cpp index 11d1b254b..628fff602 100644 --- a/lib/checkother.cpp +++ b/lib/checkother.cpp @@ -4134,6 +4134,41 @@ void CheckOther::sizeofsizeofError(const Token *tok) "sizeofsizeof", "Suspicious code 'sizeof sizeof ..', most likely there should only be one sizeof. The current code is equivalent to 'sizeof(size_t)'."); } +void CheckOther::sizeofCalculation() +{ + if (!_settings->_checkCodingStyle) + return; + for (const Token *tok = _tokenizer->tokens(); tok; tok = tok->next()) + { + if (Token::simpleMatch(tok, "sizeof (")) + { + unsigned int parlevel = 0; + for (const Token *tok2 = tok->tokAt(2); tok2; tok2 = tok2->next()) + { + if (tok2->str() == "(") + ++parlevel; + else if (tok2->str() == ")") + { + if (parlevel <= 1) + break; + --parlevel; + } + else if (Token::Match(tok2, "+|/")) + { + sizeofCalculationError(tok2); + break; + } + } + } + } +} + +void CheckOther::sizeofCalculationError(const Token *tok) +{ + reportError(tok, Severity::style, + "sizeofCalculation", "Found calculation inside sizeof()"); +} + void CheckOther::redundantAssignmentInSwitchError(const Token *tok, const std::string &varname) { reportError(tok, Severity::style, diff --git a/lib/checkother.h b/lib/checkother.h index cf361ae3e..cd560e71d 100644 --- a/lib/checkother.h +++ b/lib/checkother.h @@ -61,6 +61,7 @@ public: checkOther.checkStructMemberUsage(); checkOther.strPlusChar(); checkOther.sizeofsizeof(); + checkOther.sizeofCalculation(); checkOther.checkEmptyCatchBlock(); checkOther.checkRedundantAssignmentInSwitch(); } @@ -179,6 +180,10 @@ public: void sizeofsizeof(); void sizeofsizeofError(const Token *tok); + /** @brief %Check for calculations inside sizeof */ + void sizeofCalculation(); + void sizeofCalculationError(const Token *tok); + /** @brief %Check for assigning to the same variable twice in a switch statement*/ void checkRedundantAssignmentInSwitch(); @@ -238,6 +243,7 @@ public: conditionAlwaysTrueFalse(0, "true/false"); strPlusChar(0); sizeofsizeofError(0); + sizeofCalculationError(0); emptyCatchBlockError(0); redundantAssignmentInSwitchError(0, "varname"); @@ -276,6 +282,8 @@ public: "* unusal pointer arithmetic. For example: \"abc\" + 'd'\n" "* empty catch() block\n" "* redundant assignment in a switch statement\n" + "* look for 'sizeof sizeof ..'\n" + "* look for calculations inside sizeof()\n" // optimisations "* optimisation: detect post increment/decrement\n" diff --git a/test/testother.cpp b/test/testother.cpp index 6d638087f..9d00decbd 100644 --- a/test/testother.cpp +++ b/test/testother.cpp @@ -98,6 +98,7 @@ private: TEST_CASE(fflushOnInputStreamTest); TEST_CASE(sizeofsizeof); + TEST_CASE(sizeofCalculation); TEST_CASE(emptyCatchBlock); @@ -120,6 +121,7 @@ private: errout.str(""); checkOther.sizeofsizeof(); + checkOther.sizeofCalculation(); checkOther.checkEmptyCatchBlock(); checkOther.checkRedundantAssignmentInSwitch(); @@ -2783,6 +2785,12 @@ private: ASSERT_EQUALS("[test.cpp:3]: (style) Suspicious code 'sizeof sizeof ..', most likely there should only be one sizeof. The current code is equivalent to 'sizeof(size_t)'.\n", errout.str()); } + void sizeofCalculation() + { + check("sizeof(a+b)"); + ASSERT_EQUALS("[test.cpp:1]: (style) Found calculation inside sizeof()\n", errout.str()); + } + void emptyCatchBlock() { check("void Open(String name)\n"