diff --git a/lib/checkother.cpp b/lib/checkother.cpp index ffbe2cd2d..4b0416786 100644 --- a/lib/checkother.cpp +++ b/lib/checkother.cpp @@ -210,6 +210,16 @@ void CheckOther::checkFflushOnInputStream() } } +void CheckOther::checkSizeofForNumericParameter() +{ + for (const Token *tok = _tokenizer->tokens(); tok; tok = tok->next()) + { + if (Token::Match(tok, "sizeof ( %num% )") || Token::Match(tok, "sizeof %num%")) + { + sizeofForNumericParameterError(tok); + } + } +} void CheckOther::checkSizeofForArrayParameter() { @@ -853,6 +863,19 @@ void CheckOther::checkComparisonOfBoolWithInt() } } +void CheckOther::sizeofForNumericParameterError(const Token *tok) +{ + reportError(tok, Severity::error, + "sizeofwithnulericparamter", "Using sizeof with a numeric constant as function " + "argument might not be what you intended.\n" + "It is unusual to use contant value with sizeof. For example, this code:\n" + " int f() {\n" + " return sizeof(10);\n" + " }\n" + " returns 4 (in 32-bit systems) or 8 (in 64-bit systems) instead of 10." + ); +} + void CheckOther::sizeofForArrayParameterError(const Token *tok) { reportError(tok, Severity::error, @@ -869,6 +892,7 @@ void CheckOther::sizeofForArrayParameterError(const Token *tok) "size of the array in bytes)." ); } + void CheckOther::invalidScanfError(const Token *tok) { reportError(tok, Severity::warning, diff --git a/lib/checkother.h b/lib/checkother.h index ca08afa07..9ee973359 100644 --- a/lib/checkother.h +++ b/lib/checkother.h @@ -62,6 +62,7 @@ public: checkOther.checkRedundantAssignmentInSwitch(); checkOther.checkAssignmentInAssert(); checkOther.checkSizeofForArrayParameter(); + checkOther.checkSizeofForNumericParameter(); checkOther.checkSelfAssignment(); checkOther.checkDuplicateIf(); checkOther.checkDuplicateBranch(); @@ -199,6 +200,9 @@ public: /** @brief %Check for using sizeof with array given as function argument */ void checkSizeofForArrayParameter(); + /** @brief %Check for using sizeof with numeric given as function argument */ + void checkSizeofForNumericParameter(); + /** @brief %Check for using bad usage of strncmp and substr */ void checkIncorrectStringCompare(); @@ -245,6 +249,7 @@ public: void catchExceptionByValueError(const Token *tok); void memsetZeroBytesError(const Token *tok, const std::string &varname); void sizeofForArrayParameterError(const Token *tok); + void sizeofForNumericParameterError(const Token *tok); void incorrectStringCompareError(const Token *tok, const std::string& func, const std::string &string, const std::string &len); void incrementBooleanError(const Token *tok); void comparisonOfBoolWithIntError(const Token *tok, const std::string &varname); @@ -265,6 +270,7 @@ public: c.fflushOnInputStreamError(0, "stdin"); c.misusedScopeObjectError(NULL, "varname"); c.sizeofForArrayParameterError(0); + c.sizeofForNumericParameterError(0); // style/warning c.cstyleCastError(0); @@ -318,6 +324,7 @@ public: "* scoped object destroyed immediately after construction\n" "* assignment in an assert statement\n" "* sizeof for array given as function argument\n" + "* sizeof for numeric given as function argument\n" "* incorrect length arguments for 'substr' and 'strncmp'\n" // style diff --git a/test/testother.cpp b/test/testother.cpp index 739c2cd94..06ab52065 100644 --- a/test/testother.cpp +++ b/test/testother.cpp @@ -104,6 +104,7 @@ private: TEST_CASE(memsetZeroBytes); TEST_CASE(sizeofForArrayParameter); + TEST_CASE(sizeofForNumericParameter); TEST_CASE(clarifyCalculation); @@ -143,6 +144,7 @@ private: checkOther.checkRedundantAssignmentInSwitch(); checkOther.checkAssignmentInAssert(); checkOther.checkSizeofForArrayParameter(); + checkOther.checkSizeofForNumericParameter(); checkOther.clarifyCondition(); checkOther.checkDuplicateIf(); checkOther.checkDuplicateBranch(); @@ -2301,7 +2303,21 @@ private: ); ASSERT_EQUALS("", errout.str()); + } + void sizeofForNumericParameter() + { + check("void f() {\n" + " std::cout << sizeof(10) << std::endl;\n" + "}\n" + ); + ASSERT_EQUALS("[test.cpp:2]: (error) Using sizeof with a numeric constant as function argument might not be what you intended.\n", errout.str()); + + check("void f() {\n" + " std::cout << sizeof 10 << std::endl;\n" + "}\n" + ); + ASSERT_EQUALS("[test.cpp:2]: (error) Using sizeof with a numeric constant as function argument might not be what you intended.\n", errout.str()); }