Skip to content

Commit 515d65c

Browse files
committed
extracted code for actual check implementation from Check into CheckImpl
1 parent d1b42d0 commit 515d65c

60 files changed

Lines changed: 2656 additions & 2399 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

Makefile

Lines changed: 58 additions & 54 deletions
Large diffs are not rendered by default.

lib/check.cpp

Lines changed: 0 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -60,32 +60,6 @@ void Check::writeToErrorList(const ErrorMessage &errmsg)
6060
std::cout << errmsg.toXML() << std::endl;
6161
}
6262

63-
64-
void Check::reportError(const std::list<const Token *> &callstack, Severity severity, const std::string &id, const std::string &msg, const CWE &cwe, Certainty certainty)
65-
{
66-
const ErrorMessage errmsg(callstack, mTokenizer ? &mTokenizer->list : nullptr, severity, id, msg, cwe, certainty);
67-
if (mErrorLogger)
68-
mErrorLogger->reportErr(errmsg);
69-
else
70-
writeToErrorList(errmsg);
71-
}
72-
73-
void Check::reportError(const ErrorPath &errorPath, Severity severity, const char id[], const std::string &msg, const CWE &cwe, Certainty certainty)
74-
{
75-
const ErrorMessage errmsg(errorPath, mTokenizer ? &mTokenizer->list : nullptr, severity, id, msg, cwe, certainty);
76-
if (mErrorLogger)
77-
mErrorLogger->reportErr(errmsg);
78-
else
79-
writeToErrorList(errmsg);
80-
}
81-
82-
bool Check::wrongData(const Token *tok, const char *str)
83-
{
84-
if (mSettings->daca)
85-
reportError(tok, Severity::debug, "DacaWrongData", "Wrong data detected by condition " + std::string(str));
86-
return true;
87-
}
88-
8963
std::list<Check *> &Check::instances()
9064
{
9165
#ifdef __SVR4
@@ -98,36 +72,3 @@ std::list<Check *> &Check::instances()
9872
return _instances;
9973
#endif
10074
}
101-
102-
std::string Check::getMessageId(const ValueFlow::Value &value, const char id[])
103-
{
104-
if (value.condition != nullptr)
105-
return id + std::string("Cond");
106-
if (value.safe)
107-
return std::string("safe") + (char)std::toupper(id[0]) + (id + 1);
108-
return id;
109-
}
110-
111-
ErrorPath Check::getErrorPath(const Token* errtok, const ValueFlow::Value* value, std::string bug) const
112-
{
113-
ErrorPath errorPath;
114-
if (!value) {
115-
errorPath.emplace_back(errtok, std::move(bug));
116-
} else if (mSettings->verbose || mSettings->xml || !mSettings->templateLocation.empty()) {
117-
errorPath = value->errorPath;
118-
errorPath.emplace_back(errtok, std::move(bug));
119-
} else {
120-
if (value->condition)
121-
errorPath.emplace_back(value->condition, "condition '" + value->condition->expressionString() + "'");
122-
//else if (!value->isKnown() || value->defaultArg)
123-
// errorPath = value->callstack;
124-
errorPath.emplace_back(errtok, std::move(bug));
125-
}
126-
return errorPath;
127-
}
128-
129-
void Check::logChecker(const char id[])
130-
{
131-
reportError(nullptr, Severity::none, "logChecker", id);
132-
}
133-

lib/check.h

Lines changed: 1 addition & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -61,15 +61,8 @@ class CPPCHECKLIB Check {
6161
/** This constructor is used when registering the CheckClass */
6262
explicit Check(const std::string &aname);
6363

64-
protected:
65-
/** This constructor is used when running checks. */
66-
Check(std::string aname, const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger)
67-
: mTokenizer(tokenizer), mSettings(settings), mErrorLogger(errorLogger), mName(std::move(aname)) {}
68-
69-
public:
7064
virtual ~Check() {
71-
if (!mTokenizer)
72-
instances().remove(this);
65+
instances().remove(this);
7366
}
7467

7568
Check(const Check &) = delete;
@@ -129,45 +122,6 @@ class CPPCHECKLIB Check {
129122
return false;
130123
}
131124

132-
protected:
133-
static std::string getMessageId(const ValueFlow::Value &value, const char id[]);
134-
135-
const Tokenizer* const mTokenizer{};
136-
const Settings* const mSettings{};
137-
ErrorLogger* const mErrorLogger{};
138-
139-
/** report an error */
140-
void reportError(const Token *tok, const Severity severity, const std::string &id, const std::string &msg) {
141-
reportError(tok, severity, id, msg, CWE(0U), Certainty::normal);
142-
}
143-
144-
/** report an error */
145-
void reportError(const Token *tok, const Severity severity, const std::string &id, const std::string &msg, const CWE &cwe, Certainty certainty) {
146-
const std::list<const Token *> callstack(1, tok);
147-
reportError(callstack, severity, id, msg, cwe, certainty);
148-
}
149-
150-
/** report an error */
151-
void reportError(const std::list<const Token *> &callstack, Severity severity, const std::string &id, const std::string &msg) {
152-
reportError(callstack, severity, id, msg, CWE(0U), Certainty::normal);
153-
}
154-
155-
/** report an error */
156-
void reportError(const std::list<const Token *> &callstack, Severity severity, const std::string &id, const std::string &msg, const CWE &cwe, Certainty certainty);
157-
158-
void reportError(const ErrorPath &errorPath, Severity severity, const char id[], const std::string &msg, const CWE &cwe, Certainty certainty);
159-
160-
/** log checker */
161-
void logChecker(const char id[]);
162-
163-
ErrorPath getErrorPath(const Token* errtok, const ValueFlow::Value* value, std::string bug) const;
164-
165-
/**
166-
* Use WRONG_DATA in checkers when you check for wrong data. That
167-
* will call this method
168-
*/
169-
bool wrongData(const Token *tok, const char *str);
170-
171125
private:
172126
const std::string mName;
173127
};

lib/check64bit.cpp

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ namespace {
4040
Check64BitPortability instance;
4141
}
4242

43-
void Check64BitPortability::pointerassignment()
43+
void Check64BitPortabilityImpl::pointerassignment()
4444
{
4545
if (!mSettings->severity.isEnabled(Severity::portability))
4646
return;
@@ -118,7 +118,7 @@ void Check64BitPortability::pointerassignment()
118118
}
119119
}
120120

121-
void Check64BitPortability::assignmentAddressToIntegerError(const Token *tok)
121+
void Check64BitPortabilityImpl::assignmentAddressToIntegerError(const Token *tok)
122122
{
123123
reportError(tok, Severity::portability,
124124
"AssignmentAddressToInteger",
@@ -129,7 +129,7 @@ void Check64BitPortability::assignmentAddressToIntegerError(const Token *tok)
129129
"way is to store addresses only in pointer types (or typedefs like uintptr_t).", CWE758, Certainty::normal);
130130
}
131131

132-
void Check64BitPortability::assignmentIntegerToAddressError(const Token *tok)
132+
void Check64BitPortabilityImpl::assignmentIntegerToAddressError(const Token *tok)
133133
{
134134
reportError(tok, Severity::portability,
135135
"AssignmentIntegerToAddress",
@@ -140,7 +140,7 @@ void Check64BitPortability::assignmentIntegerToAddressError(const Token *tok)
140140
"way is to store addresses only in pointer types (or typedefs like uintptr_t).", CWE758, Certainty::normal);
141141
}
142142

143-
void Check64BitPortability::returnPointerError(const Token *tok)
143+
void Check64BitPortabilityImpl::returnPointerError(const Token *tok)
144144
{
145145
reportError(tok, Severity::portability,
146146
"CastAddressToIntegerAtReturn",
@@ -151,7 +151,7 @@ void Check64BitPortability::returnPointerError(const Token *tok)
151151
"to 32-bit integer. The safe way is to always return an integer.", CWE758, Certainty::normal);
152152
}
153153

154-
void Check64BitPortability::returnIntegerError(const Token *tok)
154+
void Check64BitPortabilityImpl::returnIntegerError(const Token *tok)
155155
{
156156
reportError(tok, Severity::portability,
157157
"CastIntegerToAddressAtReturn",
@@ -161,3 +161,20 @@ void Check64BitPortability::returnIntegerError(const Token *tok)
161161
"and Linux they are of different width. In worst case you end up casting 64-bit integer down to 32-bit pointer. "
162162
"The safe way is to always return a pointer.", CWE758, Certainty::normal);
163163
}
164+
165+
166+
/** @brief Run checks against the normal token list */
167+
void Check64BitPortability::runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger)
168+
{
169+
Check64BitPortabilityImpl c(&tokenizer, tokenizer.getSettings(), errorLogger);
170+
c.pointerassignment();
171+
}
172+
173+
void Check64BitPortability::getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) const
174+
{
175+
Check64BitPortabilityImpl c(nullptr, settings, errorLogger);
176+
c.assignmentAddressToIntegerError(nullptr);
177+
c.assignmentIntegerToAddressError(nullptr);
178+
c.returnIntegerError(nullptr);
179+
c.returnPointerError(nullptr);
180+
}

lib/check64bit.h

Lines changed: 17 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
//---------------------------------------------------------------------------
2424

2525
#include "check.h"
26+
#include "checkimpl.h"
2627
#include "config.h"
2728
#include "tokenize.h"
2829

@@ -45,18 +46,26 @@ class CPPCHECKLIB Check64BitPortability : public Check {
4546

4647
public:
4748
/** This constructor is used when registering the Check64BitPortability */
48-
Check64BitPortability() : Check(myName()) {}
49+
Check64BitPortability() : Check("64-bit portability") {}
4950

5051
private:
51-
/** This constructor is used when running checks. */
52-
Check64BitPortability(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger)
53-
: Check(myName(), tokenizer, settings, errorLogger) {}
54-
5552
/** @brief Run checks against the normal token list */
56-
void runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) override {
57-
Check64BitPortability check64BitPortability(&tokenizer, tokenizer.getSettings(), errorLogger);
58-
check64BitPortability.pointerassignment();
53+
void runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) override;
54+
55+
void getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) const override;
56+
57+
std::string classInfo() const override {
58+
return "Check if there is 64-bit portability issues:\n"
59+
"- assign address to/from int/long\n"
60+
"- casting address from/to integer when returning from function\n";
5961
}
62+
};
63+
64+
class Check64BitPortabilityImpl : public CheckImpl {
65+
public:
66+
/** This constructor is used when running checks. */
67+
Check64BitPortabilityImpl(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger)
68+
: CheckImpl(tokenizer, settings, errorLogger) {}
6069

6170
/** Check for pointer assignment */
6271
void pointerassignment();
@@ -65,24 +74,6 @@ class CPPCHECKLIB Check64BitPortability : public Check {
6574
void assignmentIntegerToAddressError(const Token *tok);
6675
void returnIntegerError(const Token *tok);
6776
void returnPointerError(const Token *tok);
68-
69-
void getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) const override {
70-
Check64BitPortability c(nullptr, settings, errorLogger);
71-
c.assignmentAddressToIntegerError(nullptr);
72-
c.assignmentIntegerToAddressError(nullptr);
73-
c.returnIntegerError(nullptr);
74-
c.returnPointerError(nullptr);
75-
}
76-
77-
static std::string myName() {
78-
return "64-bit portability";
79-
}
80-
81-
std::string classInfo() const override {
82-
return "Check if there is 64-bit portability issues:\n"
83-
"- assign address to/from int/long\n"
84-
"- casting address from/to integer when returning from function\n";
85-
}
8677
};
8778
/// @}
8879
//---------------------------------------------------------------------------

lib/checkassert.cpp

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ namespace {
3939
CheckAssert instance;
4040
}
4141

42-
void CheckAssert::assertWithSideEffects()
42+
void CheckAssertImpl::assertWithSideEffects()
4343
{
4444
if (!mSettings->severity.isEnabled(Severity::warning))
4545
return;
@@ -99,7 +99,7 @@ void CheckAssert::assertWithSideEffects()
9999
//---------------------------------------------------------------------------
100100

101101

102-
void CheckAssert::sideEffectInAssertError(const Token *tok, const std::string& functionName)
102+
void CheckAssertImpl::sideEffectInAssertError(const Token *tok, const std::string& functionName)
103103
{
104104
reportError(tok, Severity::warning,
105105
"assertWithSideEffect",
@@ -111,7 +111,7 @@ void CheckAssert::sideEffectInAssertError(const Token *tok, const std::string& f
111111
"builds, this is a bug.", CWE398, Certainty::normal);
112112
}
113113

114-
void CheckAssert::assignmentInAssertError(const Token *tok, const std::string& varname)
114+
void CheckAssertImpl::assignmentInAssertError(const Token *tok, const std::string& varname)
115115
{
116116
reportError(tok, Severity::warning,
117117
"assignmentInAssert",
@@ -124,7 +124,7 @@ void CheckAssert::assignmentInAssertError(const Token *tok, const std::string& v
124124
}
125125

126126
// checks if side effects happen on the variable prior to tmp
127-
void CheckAssert::checkVariableAssignment(const Token* assignTok, const Scope *assertionScope)
127+
void CheckAssertImpl::checkVariableAssignment(const Token* assignTok, const Scope *assertionScope)
128128
{
129129
if (!assignTok->isAssignmentOp() && assignTok->tokType() != Token::eIncDecOp)
130130
return;
@@ -152,8 +152,21 @@ void CheckAssert::checkVariableAssignment(const Token* assignTok, const Scope *a
152152
// TODO: function calls on var
153153
}
154154

155-
bool CheckAssert::inSameScope(const Token* returnTok, const Token* assignTok)
155+
bool CheckAssertImpl::inSameScope(const Token* returnTok, const Token* assignTok)
156156
{
157157
// TODO: even if a return is in the same scope, the assignment might not affect it.
158158
return returnTok->scope() == assignTok->scope();
159159
}
160+
161+
void CheckAssert::runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger)
162+
{
163+
CheckAssertImpl checkAssert(&tokenizer, tokenizer.getSettings(), errorLogger);
164+
checkAssert.assertWithSideEffects();
165+
}
166+
167+
void CheckAssert::getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) const
168+
{
169+
CheckAssertImpl c(nullptr, settings, errorLogger);
170+
c.sideEffectInAssertError(nullptr, "function");
171+
c.assignmentInAssertError(nullptr, "var");
172+
}

lib/checkassert.h

Lines changed: 14 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
//---------------------------------------------------------------------------
2424

2525
#include "check.h"
26+
#include "checkimpl.h"
2627
#include "config.h"
2728
#include "tokenize.h"
2829

@@ -42,17 +43,23 @@ class Token;
4243

4344
class CPPCHECKLIB CheckAssert : public Check {
4445
public:
45-
CheckAssert() : Check(myName()) {}
46+
CheckAssert() : Check("Assert") {}
4647

4748
private:
48-
CheckAssert(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger)
49-
: Check(myName(), tokenizer, settings, errorLogger) {}
50-
5149
/** run checks, the token list is not simplified */
52-
void runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) override {
53-
CheckAssert checkAssert(&tokenizer, tokenizer.getSettings(), errorLogger);
54-
checkAssert.assertWithSideEffects();
50+
void runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) override;
51+
52+
void getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) const override;
53+
54+
std::string classInfo() const override {
55+
return "Warn if there are side effects in assert statements (since this cause different behaviour in debug/release builds).\n";
5556
}
57+
};
58+
59+
class CheckAssertImpl: public CheckImpl {
60+
public:
61+
CheckAssertImpl(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger)
62+
: CheckImpl(tokenizer, settings, errorLogger) {}
5663

5764
void assertWithSideEffects();
5865

@@ -61,20 +68,6 @@ class CPPCHECKLIB CheckAssert : public Check {
6168

6269
void sideEffectInAssertError(const Token *tok, const std::string& functionName);
6370
void assignmentInAssertError(const Token *tok, const std::string &varname);
64-
65-
void getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) const override {
66-
CheckAssert c(nullptr, settings, errorLogger);
67-
c.sideEffectInAssertError(nullptr, "function");
68-
c.assignmentInAssertError(nullptr, "var");
69-
}
70-
71-
static std::string myName() {
72-
return "Assert";
73-
}
74-
75-
std::string classInfo() const override {
76-
return "Warn if there are side effects in assert statements (since this cause different behaviour in debug/release builds).\n";
77-
}
7871
};
7972
/// @}
8073
//---------------------------------------------------------------------------

0 commit comments

Comments
 (0)