From f4b6c822d35b713b98e05f693668596e3f775d65 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Sat, 12 Sep 2009 15:25:02 +0200 Subject: [PATCH] Fixed #375 (new check: Detect when using 'this-x') --- src/checkclass.cpp | 15 +++++++++++++++ src/checkclass.h | 5 +++++ test/testclass.cpp | 29 ++++++++++++++++++++++++++++- 3 files changed, 48 insertions(+), 1 deletion(-) diff --git a/src/checkclass.cpp b/src/checkclass.cpp index 841224296..abd556d9c 100644 --- a/src/checkclass.cpp +++ b/src/checkclass.cpp @@ -851,6 +851,21 @@ void CheckClass::virtualDestructor() } //--------------------------------------------------------------------------- +void CheckClass::thisSubtractionError(const Token *tok) +{ + reportError(tok, Severity::possibleStyle, "thisSubtraction", "Suspicious pointer subtraction"); +} + +void CheckClass::thisSubtraction() +{ + const Token *tok = Token::findmatch(_tokenizer->tokens(), "this - %var%"); + if (tok) + { + thisSubtractionError(tok); + } +} + + void CheckClass::noConstructorError(const Token *tok, const std::string &classname) diff --git a/src/checkclass.h b/src/checkclass.h index 30b57c5f6..232294604 100644 --- a/src/checkclass.h +++ b/src/checkclass.h @@ -57,6 +57,8 @@ public: checkClass.constructors(); checkClass.operatorEq(); checkClass.privateFunctions(); + if (settings->_showAll) + checkClass.thisSubtraction(); } checkClass.virtualDestructor(); } @@ -79,6 +81,7 @@ public: // The destructor in a base class should be virtual void virtualDestructor(); + void thisSubtraction(); private: class Var { @@ -111,6 +114,7 @@ private: void memsetStructError(const Token *tok, const std::string &memfunc, const std::string &classname); void operatorEqReturnError(const Token *tok); void virtualDestructorError(const Token *tok, const std::string &Base, const std::string &Derived); + void thisSubtractionError(const Token *tok); void getErrorMessages() { @@ -122,6 +126,7 @@ private: memsetStructError(0, "memfunc", "classname"); operatorEqReturnError(0); virtualDestructorError(0, "Base", "Derived"); + thisSubtractionError(0); } std::string name() const diff --git a/test/testclass.cpp b/test/testclass.cpp index e61ddfe12..c9f552d5a 100644 --- a/test/testclass.cpp +++ b/test/testclass.cpp @@ -58,13 +58,14 @@ private: TEST_CASE(uninitVarHeader3); // Class is defined in header TEST_CASE(uninitVarPublished); // Variables in the published section are auto-initialized - TEST_CASE(noConstructor1); TEST_CASE(noConstructor2); TEST_CASE(operatorEq1); TEST_CASE(memsetOnStruct); TEST_CASE(memsetOnClass); + + TEST_CASE(this_subtraction); // warn about "this-x" } // Check the operator Equal @@ -724,6 +725,32 @@ private: "}\n"); ASSERT_EQUALS("[test.cpp:10]: (error) Using 'memset' on struct that contains a 'std::string'\n", errout.str()); } + + + void checkThisSubtraction(const char code[]) + { + // Tokenize.. + Tokenizer tokenizer; + std::istringstream istr(code); + tokenizer.tokenize(istr, "test.cpp"); + tokenizer.simplifyTokenList(); + + // Clear the error log + errout.str(""); + + // Check.. + Settings settings; + settings._checkCodingStyle = true; + settings._showAll = true; + CheckClass checkClass(&tokenizer, &settings, this); + checkClass.thisSubtraction(); + } + + void this_subtraction() + { + checkThisSubtraction("; this-x ;"); + ASSERT_EQUALS("[test.cpp:1]: (possible style) Suspicious pointer subtraction\n", errout.str()); + } }; REGISTER_TEST(TestClass)