Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
114 changes: 57 additions & 57 deletions Makefile

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion lib/astutils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2157,7 +2157,7 @@ bool isWithoutSideEffects(const Token* tok, bool checkArrayAccess, bool checkRef
if (tok && tok->varId()) {
const Variable* var = tok->variable();
return var && ((!var->isClass() && (checkReference || !var->isReference())) || var->isPointer() ||
(checkArrayAccess ? var->isArray() || (var->isStlType() && !var->isStlType(CheckClass::stl_containers_not_const)) : var->isStlType()));
(checkArrayAccess ? var->isArray() || (var->isStlType() && !var->isStlType(CheckClassImpl::stl_containers_not_const)) : var->isStlType()));
}
return true;
}
Expand Down
62 changes: 3 additions & 59 deletions lib/check.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@
//---------------------------------------------------------------------------

#include "config.h"
#include "errortypes.h"

#include <list>
#include <string>
Expand All @@ -36,14 +35,8 @@ namespace CTU {
class FileInfo;
}

namespace ValueFlow {
class Value;
}

class Settings;
class Token;
class ErrorLogger;
class ErrorMessage;
class Tokenizer;

/** Use WRONG_DATA in checkers to mark conditions that check that data is correct */
Expand All @@ -59,17 +52,9 @@ class Tokenizer;
class CPPCHECKLIB Check {
public:
/** This constructor is used when registering the CheckClass */
explicit Check(std::string aname);

protected:
/** This constructor is used when running checks. */
Check(std::string aname, const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger)
: mTokenizer(tokenizer), mSettings(settings), mErrorLogger(errorLogger), mName(std::move(aname)) {}

private:
static std::list<Check *> &instances_internal();

public:
explicit Check(std::string aname)
: mName(std::move(aname))
{}
virtual ~Check() = default;

Check(const Check &) = delete;
Expand All @@ -89,13 +74,6 @@ class CPPCHECKLIB Check {
/** get information about this class, used to generate documentation */
virtual std::string classInfo() const = 0;

/**
* Write given error to stdout in xml format.
* This is for for printout out the error list with --errorlist
* @param errmsg Error message to write
*/
static void writeToErrorList(const ErrorMessage &errmsg);

/** Base class used for whole-program analysis */
class CPPCHECKLIB FileInfo {
public:
Expand All @@ -121,40 +99,6 @@ class CPPCHECKLIB Check {
return false;
}

protected:
static std::string getMessageId(const ValueFlow::Value &value, const char id[]);

const Tokenizer* const mTokenizer{};
const Settings* const mSettings{};
ErrorLogger* const mErrorLogger{};

/** report an error */
void reportError(const Token *tok, const Severity severity, const std::string &id, const std::string &msg) {
reportError(tok, severity, id, msg, CWE(0U), Certainty::normal);
}

/** report an error */
void reportError(const Token *tok, const Severity severity, const std::string &id, const std::string &msg, const CWE &cwe, Certainty certainty) {
const std::list<const Token *> callstack(1, tok);
reportError(callstack, severity, id, msg, cwe, certainty);
}

/** report an error */
void reportError(const std::list<const Token *> &callstack, Severity severity, const std::string &id, const std::string &msg, const CWE &cwe, Certainty certainty);

void reportError(ErrorPath errorPath, Severity severity, const char id[], const std::string &msg, const CWE &cwe, Certainty certainty);

/** log checker */
void logChecker(const char id[]);

ErrorPath getErrorPath(const Token* errtok, const ValueFlow::Value* value, std::string bug) const;

/**
* Use WRONG_DATA in checkers when you check for wrong data. That
* will call this method
*/
bool wrongData(const Token *tok, const char *str);

private:
const std::string mName;
};
Expand Down
14 changes: 7 additions & 7 deletions lib/check64bit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ static bool isFunctionPointer(const Token* tok)
return Tokenizer::isFunctionPointer(tok->variable()->nameToken());
}

void Check64BitPortability::pointerassignment()
void Check64BitPortabilityImpl::pointerassignment()
{
if (!mSettings->severity.isEnabled(Severity::portability))
return;
Expand Down Expand Up @@ -139,7 +139,7 @@ void Check64BitPortability::pointerassignment()
}
}

void Check64BitPortability::assignmentAddressToIntegerError(const Token *tok)
void Check64BitPortabilityImpl::assignmentAddressToIntegerError(const Token *tok)
{
reportError(tok, Severity::portability,
"AssignmentAddressToInteger",
Expand All @@ -150,7 +150,7 @@ void Check64BitPortability::assignmentAddressToIntegerError(const Token *tok)
"way is to store addresses only in pointer types (or typedefs like uintptr_t).", CWE758, Certainty::normal);
}

void Check64BitPortability::assignmentIntegerToAddressError(const Token *tok)
void Check64BitPortabilityImpl::assignmentIntegerToAddressError(const Token *tok)
{
reportError(tok, Severity::portability,
"AssignmentIntegerToAddress",
Expand All @@ -161,7 +161,7 @@ void Check64BitPortability::assignmentIntegerToAddressError(const Token *tok)
"way is to store addresses only in pointer types (or typedefs like uintptr_t).", CWE758, Certainty::normal);
}

void Check64BitPortability::returnPointerError(const Token *tok)
void Check64BitPortabilityImpl::returnPointerError(const Token *tok)
{
reportError(tok, Severity::portability,
"CastAddressToIntegerAtReturn",
Expand All @@ -172,7 +172,7 @@ void Check64BitPortability::returnPointerError(const Token *tok)
"to 32-bit integer. The safe way is to return a type such as intptr_t.", CWE758, Certainty::normal);
}

void Check64BitPortability::returnIntegerError(const Token *tok)
void Check64BitPortabilityImpl::returnIntegerError(const Token *tok)
{
reportError(tok, Severity::portability,
"CastIntegerToAddressAtReturn",
Expand All @@ -185,13 +185,13 @@ void Check64BitPortability::returnIntegerError(const Token *tok)

void Check64BitPortability::runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger)
{
Check64BitPortability check64BitPortability(&tokenizer, &tokenizer.getSettings(), errorLogger);
Check64BitPortabilityImpl check64BitPortability(&tokenizer, &tokenizer.getSettings(), errorLogger);
check64BitPortability.pointerassignment();
}

void Check64BitPortability::getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) const
{
Check64BitPortability c(nullptr, settings, errorLogger);
Check64BitPortabilityImpl c(nullptr, settings, errorLogger);
c.assignmentAddressToIntegerError(nullptr);
c.assignmentIntegerToAddressError(nullptr);
c.returnIntegerError(nullptr);
Expand Down
34 changes: 17 additions & 17 deletions lib/check64bit.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
//---------------------------------------------------------------------------

#include "check.h"
#include "checkimpl.h"
#include "config.h"

#include <string>
Expand All @@ -44,36 +45,35 @@ class CPPCHECKLIB Check64BitPortability : public Check {

public:
/** This constructor is used when registering the Check64BitPortability */
Check64BitPortability() : Check(myName()) {}
Check64BitPortability() : Check("64-bit portability") {}

private:
/** This constructor is used when running checks. */
Check64BitPortability(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger)
: Check(myName(), tokenizer, settings, errorLogger) {}

/** @brief Run checks against the normal token list */
void runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) override;

/** Check for pointer assignment */
void pointerassignment();

void assignmentAddressToIntegerError(const Token *tok);
void assignmentIntegerToAddressError(const Token *tok);
void returnIntegerError(const Token *tok);
void returnPointerError(const Token *tok);

void getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) const override;

static std::string myName() {
return "64-bit portability";
}

std::string classInfo() const override {
return "Check if there is 64-bit portability issues:\n"
"- assign address to/from int/long\n"
"- casting address from/to integer when returning from function\n";
}
};

class CPPCHECKLIB Check64BitPortabilityImpl : public CheckImpl {
public:
/** This constructor is used when running checks. */
Check64BitPortabilityImpl(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger)
: CheckImpl(tokenizer, settings, errorLogger) {}

/** Check for pointer assignment */
void pointerassignment();

void assignmentAddressToIntegerError(const Token *tok);
void assignmentIntegerToAddressError(const Token *tok);
void returnIntegerError(const Token *tok);
void returnPointerError(const Token *tok);
};
/// @}
//---------------------------------------------------------------------------
#endif // check64bitH
14 changes: 7 additions & 7 deletions lib/checkassert.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
// CWE ids used
static const CWE CWE398(398U); // Indicator of Poor Code Quality

void CheckAssert::assertWithSideEffects()
void CheckAssertImpl::assertWithSideEffects()
{
if (!mSettings->severity.isEnabled(Severity::warning))
return;
Expand Down Expand Up @@ -117,7 +117,7 @@ void CheckAssert::assertWithSideEffects()
//---------------------------------------------------------------------------


void CheckAssert::sideEffectInAssertError(const Token *tok, const std::string& functionName)
void CheckAssertImpl::sideEffectInAssertError(const Token *tok, const std::string& functionName)
{
reportError(tok, Severity::warning,
"assertWithSideEffect",
Expand All @@ -129,7 +129,7 @@ void CheckAssert::sideEffectInAssertError(const Token *tok, const std::string& f
"builds, this is a bug.", CWE398, Certainty::normal);
}

void CheckAssert::assignmentInAssertError(const Token *tok, const std::string& varname)
void CheckAssertImpl::assignmentInAssertError(const Token *tok, const std::string& varname)
{
reportError(tok, Severity::warning,
"assignmentInAssert",
Expand All @@ -142,7 +142,7 @@ void CheckAssert::assignmentInAssertError(const Token *tok, const std::string& v
}

// checks if side effects happen on the variable prior to tmp
void CheckAssert::checkVariableAssignment(const Token* assignTok, const Scope *assertionScope)
void CheckAssertImpl::checkVariableAssignment(const Token* assignTok, const Scope *assertionScope)
{
if (!assignTok->isAssignmentOp() && assignTok->tokType() != Token::eIncDecOp)
return;
Expand Down Expand Up @@ -172,21 +172,21 @@ void CheckAssert::checkVariableAssignment(const Token* assignTok, const Scope *a
// TODO: function calls on var
}

bool CheckAssert::inSameScope(const Token* returnTok, const Token* assignTok)
bool CheckAssertImpl::inSameScope(const Token* returnTok, const Token* assignTok)
{
// TODO: even if a return is in the same scope, the assignment might not affect it.
return returnTok->scope() == assignTok->scope();
}

void CheckAssert::runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger)
{
CheckAssert checkAssert(&tokenizer, &tokenizer.getSettings(), errorLogger);
CheckAssertImpl checkAssert(&tokenizer, &tokenizer.getSettings(), errorLogger);
checkAssert.assertWithSideEffects();
}

void CheckAssert::getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) const
{
CheckAssert c(nullptr, settings, errorLogger);
CheckAssertImpl c(nullptr, settings, errorLogger);
c.sideEffectInAssertError(nullptr, "function");
c.assignmentInAssertError(nullptr, "var");
}
27 changes: 13 additions & 14 deletions lib/checkassert.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
//---------------------------------------------------------------------------

#include "check.h"
#include "checkimpl.h"
#include "config.h"

#include <string>
Expand All @@ -42,14 +43,22 @@ class Tokenizer;

class CPPCHECKLIB CheckAssert : public Check {
public:
CheckAssert() : Check(myName()) {}
CheckAssert() : Check("Assert") {}

private:
CheckAssert(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger)
: Check(myName(), tokenizer, settings, errorLogger) {}

/** run checks, the token list is not simplified */
void runChecks(const Tokenizer &tokenizer, ErrorLogger *errorLogger) override;
void getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) const override;

std::string classInfo() const override {
return "Warn if there are side effects in assert statements (since this cause different behaviour in debug/release builds).\n";
}
};

class CPPCHECKLIB CheckAssertImpl : public CheckImpl {
public:
CheckAssertImpl(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger)
: CheckImpl(tokenizer, settings, errorLogger) {}

void assertWithSideEffects();

Expand All @@ -58,16 +67,6 @@ class CPPCHECKLIB CheckAssert : public Check {

void sideEffectInAssertError(const Token *tok, const std::string& functionName);
void assignmentInAssertError(const Token *tok, const std::string &varname);

void getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) const override;

static std::string myName() {
return "Assert";
}

std::string classInfo() const override {
return "Warn if there are side effects in assert statements (since this cause different behaviour in debug/release builds).\n";
}
};
/// @}
//---------------------------------------------------------------------------
Expand Down
Loading
Loading