Fixed #375 (new check: Detect when using 'this-x')

This commit is contained in:
Daniel Marjamäki 2009-09-12 15:25:02 +02:00
parent ab4a7fdef2
commit f4b6c822d3
3 changed files with 48 additions and 1 deletions

View File

@ -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) void CheckClass::noConstructorError(const Token *tok, const std::string &classname)

View File

@ -57,6 +57,8 @@ public:
checkClass.constructors(); checkClass.constructors();
checkClass.operatorEq(); checkClass.operatorEq();
checkClass.privateFunctions(); checkClass.privateFunctions();
if (settings->_showAll)
checkClass.thisSubtraction();
} }
checkClass.virtualDestructor(); checkClass.virtualDestructor();
} }
@ -79,6 +81,7 @@ public:
// The destructor in a base class should be virtual // The destructor in a base class should be virtual
void virtualDestructor(); void virtualDestructor();
void thisSubtraction();
private: private:
class Var class Var
{ {
@ -111,6 +114,7 @@ private:
void memsetStructError(const Token *tok, const std::string &memfunc, const std::string &classname); void memsetStructError(const Token *tok, const std::string &memfunc, const std::string &classname);
void operatorEqReturnError(const Token *tok); void operatorEqReturnError(const Token *tok);
void virtualDestructorError(const Token *tok, const std::string &Base, const std::string &Derived); void virtualDestructorError(const Token *tok, const std::string &Base, const std::string &Derived);
void thisSubtractionError(const Token *tok);
void getErrorMessages() void getErrorMessages()
{ {
@ -122,6 +126,7 @@ private:
memsetStructError(0, "memfunc", "classname"); memsetStructError(0, "memfunc", "classname");
operatorEqReturnError(0); operatorEqReturnError(0);
virtualDestructorError(0, "Base", "Derived"); virtualDestructorError(0, "Base", "Derived");
thisSubtractionError(0);
} }
std::string name() const std::string name() const

View File

@ -58,13 +58,14 @@ private:
TEST_CASE(uninitVarHeader3); // Class is defined in header TEST_CASE(uninitVarHeader3); // Class is defined in header
TEST_CASE(uninitVarPublished); // Variables in the published section are auto-initialized TEST_CASE(uninitVarPublished); // Variables in the published section are auto-initialized
TEST_CASE(noConstructor1); TEST_CASE(noConstructor1);
TEST_CASE(noConstructor2); TEST_CASE(noConstructor2);
TEST_CASE(operatorEq1); TEST_CASE(operatorEq1);
TEST_CASE(memsetOnStruct); TEST_CASE(memsetOnStruct);
TEST_CASE(memsetOnClass); TEST_CASE(memsetOnClass);
TEST_CASE(this_subtraction); // warn about "this-x"
} }
// Check the operator Equal // Check the operator Equal
@ -724,6 +725,32 @@ private:
"}\n"); "}\n");
ASSERT_EQUALS("[test.cpp:10]: (error) Using 'memset' on struct that contains a 'std::string'\n", errout.str()); 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) REGISTER_TEST(TestClass)