ErrorLogger: Added ErrorPath where each item has token and info
This commit is contained in:
parent
e65d6d3c67
commit
c617851567
23
lib/check.h
23
lib/check.h
|
@ -45,7 +45,6 @@ namespace tinyxml2 {
|
|||
/// @addtogroup Core
|
||||
/// @{
|
||||
|
||||
|
||||
/**
|
||||
* @brief Interface class that cppcheck uses to communicate with the checks.
|
||||
* All checking classes must inherit from this class
|
||||
|
@ -158,19 +157,27 @@ protected:
|
|||
reportError(errmsg);
|
||||
}
|
||||
|
||||
std::list<const Token *> getErrorPath(const Token *errtok, const ValueFlow::Value *value) const {
|
||||
std::list<const Token*> errorPath;
|
||||
void reportError(const ErrorPath &errorPath, Severity::SeverityType severity, const char id[], const std::string &msg, const CWE &cwe, bool inconclusive) {
|
||||
const ErrorLogger::ErrorMessage errmsg(errorPath, _tokenizer ? &_tokenizer->list : nullptr, severity, id, msg, cwe, inconclusive);
|
||||
if (_errorLogger)
|
||||
_errorLogger->reportErr(errmsg);
|
||||
else
|
||||
reportError(errmsg);
|
||||
}
|
||||
|
||||
ErrorPath getErrorPath(const Token *errtok, const ValueFlow::Value *value) const {
|
||||
ErrorPath errorPath;
|
||||
if (!value) {
|
||||
errorPath.push_back(errtok);
|
||||
errorPath.push_back(ErrorPathItem(errtok,""));
|
||||
} else if (_settings->verbose) {
|
||||
errorPath = value->callstack;
|
||||
errorPath.push_back(errtok);
|
||||
errorPath = value->errorPath;
|
||||
errorPath.push_back(ErrorPathItem(errtok,""));
|
||||
} else {
|
||||
if (value->condition)
|
||||
errorPath.push_back(value->condition);
|
||||
errorPath.push_back(ErrorPathItem(value->condition, "condition '" + value->condition->expressionString() + "'"));
|
||||
//else if (!value->isKnown() || value->defaultArg)
|
||||
// errorPath = value->callstack;
|
||||
errorPath.push_back(errtok);
|
||||
errorPath.push_back(ErrorPathItem(errtok,""));
|
||||
}
|
||||
return errorPath;
|
||||
}
|
||||
|
|
|
@ -1780,7 +1780,7 @@ void CheckBufferOverrun::negativeIndexError(const Token *tok, MathLib::bigint in
|
|||
|
||||
void CheckBufferOverrun::negativeIndexError(const Token *tok, const ValueFlow::Value &index)
|
||||
{
|
||||
const std::list<const Token *> errorPath = getErrorPath(tok, &index);
|
||||
const ErrorPath errorPath = getErrorPath(tok, &index);
|
||||
std::ostringstream errmsg;
|
||||
if (index.condition)
|
||||
errmsg << ValueFlow::eitherTheConditionIsRedundant(index.condition)
|
||||
|
|
|
@ -473,7 +473,7 @@ void CheckNullPointer::nullPointerError(const Token *tok, const std::string &var
|
|||
if (!_settings->isEnabled(value, inconclusive))
|
||||
return;
|
||||
|
||||
const std::list<const Token*> errorPath = getErrorPath(tok,value);
|
||||
const ErrorPath errorPath = getErrorPath(tok,value);
|
||||
|
||||
if (value->condition) {
|
||||
reportError(errorPath, Severity::warning, "nullPointerRedundantCheck", errmsgcond, CWE476, inconclusive || value->inconclusive);
|
||||
|
|
|
@ -1656,7 +1656,7 @@ void CheckOther::zerodivError(const Token *tok, const ValueFlow::Value *value)
|
|||
return;
|
||||
}
|
||||
|
||||
const std::list<const Token *> errorPath = getErrorPath(tok, value);
|
||||
const ErrorPath errorPath = getErrorPath(tok, value);
|
||||
|
||||
std::ostringstream errmsg;
|
||||
if (value->condition)
|
||||
|
|
|
@ -111,6 +111,25 @@ ErrorLogger::ErrorMessage::ErrorMessage(const std::list<const Token*>& callstack
|
|||
setmsg(msg);
|
||||
}
|
||||
|
||||
ErrorLogger::ErrorMessage::ErrorMessage(const ErrorPath &errorPath, const TokenList *tokenList, Severity::SeverityType severity, const char id[], const std::string &msg, const CWE &cwe, bool inconclusive)
|
||||
: _id(id), _severity(severity), _cwe(cwe.id), _inconclusive(inconclusive)
|
||||
{
|
||||
// Format callstack
|
||||
for (ErrorPath::const_iterator it = errorPath.begin(); it != errorPath.end(); ++it) {
|
||||
const Token *tok = it->first;
|
||||
const std::string &info = it->second;
|
||||
|
||||
// --errorlist can provide null values here
|
||||
if (tok)
|
||||
_callStack.push_back(ErrorLogger::ErrorMessage::FileLocation(tok, info, tokenList));
|
||||
}
|
||||
|
||||
if (tokenList && !tokenList->getFiles().empty())
|
||||
file0 = tokenList->getFiles()[0];
|
||||
|
||||
setmsg(msg);
|
||||
}
|
||||
|
||||
ErrorLogger::ErrorMessage::ErrorMessage(const tinyxml2::XMLElement * const errmsg)
|
||||
: _id(errmsg->Attribute("id")),
|
||||
_severity(Severity::fromString(errmsg->Attribute("severity"))),
|
||||
|
@ -125,7 +144,10 @@ ErrorLogger::ErrorMessage::ErrorMessage(const tinyxml2::XMLElement * const errms
|
|||
_inconclusive = attr && (std::strcmp(attr, "true") == 0);
|
||||
for (const tinyxml2::XMLElement *e = errmsg->FirstChildElement(); e; e = e->NextSiblingElement()) {
|
||||
if (std::strcmp(e->Name(),"location")==0) {
|
||||
_callStack.push_back(ErrorLogger::ErrorMessage::FileLocation(e->Attribute("file"), std::atoi(e->Attribute("line"))));
|
||||
const char *strfile = e->Attribute("file");
|
||||
const char *strinfo = e->Attribute("info");
|
||||
const char *strline = e->Attribute("line");
|
||||
_callStack.push_back(ErrorLogger::ErrorMessage::FileLocation(strfile, strinfo ? strinfo : "", std::atoi(strline)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -453,6 +475,11 @@ ErrorLogger::ErrorMessage::FileLocation::FileLocation(const Token* tok, const To
|
|||
{
|
||||
}
|
||||
|
||||
ErrorLogger::ErrorMessage::FileLocation::FileLocation(const Token* tok, const std::string &info, const TokenList* list)
|
||||
: line(tok->linenr()), fileNumber(tok->fileIndex()), _file(list->file(tok)), _info(info)
|
||||
{
|
||||
}
|
||||
|
||||
std::string ErrorLogger::ErrorMessage::FileLocation::getfile(bool convert) const
|
||||
{
|
||||
if (convert)
|
||||
|
|
|
@ -160,6 +160,10 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
|
||||
typedef std::pair<const Token *, std::string> ErrorPathItem;
|
||||
typedef std::list<ErrorPathItem> ErrorPath;
|
||||
|
||||
/**
|
||||
* @brief This is an interface, which the class responsible of error logging
|
||||
* should implement.
|
||||
|
@ -190,6 +194,7 @@ public:
|
|||
}
|
||||
|
||||
FileLocation(const Token* tok, const TokenList* list);
|
||||
FileLocation(const Token* tok, const std::string &info, const TokenList* tokenList);
|
||||
|
||||
/**
|
||||
* Return the filename.
|
||||
|
@ -214,12 +219,14 @@ public:
|
|||
|
||||
private:
|
||||
std::string _file;
|
||||
std::string _info;
|
||||
};
|
||||
|
||||
ErrorMessage(const std::list<FileLocation> &callStack, const std::string& file1, Severity::SeverityType severity, const std::string &msg, const std::string &id, bool inconclusive);
|
||||
ErrorMessage(const std::list<FileLocation> &callStack, const std::string& file1, Severity::SeverityType severity, const std::string &msg, const std::string &id, const CWE &cwe, bool inconclusive);
|
||||
ErrorMessage(const std::list<const Token*>& callstack, const TokenList* list, Severity::SeverityType severity, const std::string& id, const std::string& msg, bool inconclusive);
|
||||
ErrorMessage(const std::list<const Token*>& callstack, const TokenList* list, Severity::SeverityType severity, const std::string& id, const std::string& msg, const CWE &cwe, bool inconclusive);
|
||||
ErrorMessage(const ErrorPath &errorPath, const TokenList *tokenList, Severity::SeverityType severity, const char id[], const std::string &msg, const CWE &cwe, bool inconclusive);
|
||||
ErrorMessage();
|
||||
explicit ErrorMessage(const tinyxml2::XMLElement * const errmsg);
|
||||
|
||||
|
|
|
@ -365,7 +365,7 @@ static void setTokenValue(Token* tok, const ValueFlow::Value &value, const Setti
|
|||
result.inconclusive = value1->inconclusive | value2->inconclusive;
|
||||
result.varId = (value1->varId != 0U) ? value1->varId : value2->varId;
|
||||
result.varvalue = (result.varId == value1->varId) ? value1->varvalue : value2->varvalue;
|
||||
result.callstack = (value1->callstack.empty() ? value2 : value1)->callstack;
|
||||
result.errorPath = (value1->errorPath.empty() ? value2 : value1)->errorPath;
|
||||
if (value1->valueKind == value2->valueKind)
|
||||
result.valueKind = value1->valueKind;
|
||||
const float floatValue1 = value1->isIntValue() ? value1->intvalue : value1->floatValue;
|
||||
|
@ -1972,7 +1972,7 @@ static void valueFlowAfterAssign(TokenList *tokenlist, SymbolDatabase* symboldat
|
|||
|
||||
std::list<ValueFlow::Value> values = tok->astOperand2()->values();
|
||||
for (std::list<ValueFlow::Value>::iterator it = values.begin(); it != values.end(); ++it)
|
||||
it->callstack.push_back(tok->astOperand2());
|
||||
it->errorPath.push_back(ErrorPathItem(tok->astOperand2(),"assignment"));
|
||||
const bool constValue = tok->astOperand2()->isNumber();
|
||||
|
||||
if (tokenlist->isCPP() && Token::Match(var->typeStartToken(), "bool|_Bool")) {
|
||||
|
@ -2771,9 +2771,9 @@ static void valueFlowSubFunction(TokenList *tokenlist, ErrorLogger *errorLogger,
|
|||
}
|
||||
}
|
||||
|
||||
// callstack..
|
||||
// Error path..
|
||||
for (std::list<ValueFlow::Value>::iterator it = argvalues.begin(); it != argvalues.end(); ++it)
|
||||
it->callstack.push_back(argtok);
|
||||
it->errorPath.push_back(ErrorPathItem(argtok, "function call argument"));
|
||||
|
||||
// passed values are not "known"..
|
||||
for (std::list<ValueFlow::Value>::iterator it = argvalues.begin(); it != argvalues.end(); ++it) {
|
||||
|
|
|
@ -34,9 +34,12 @@ class Settings;
|
|||
namespace ValueFlow {
|
||||
class CPPCHECKLIB Value {
|
||||
public:
|
||||
typedef std::pair<const Token *, std::string> ErrorPathItem;
|
||||
typedef std::list<ErrorPathItem> ErrorPath;
|
||||
|
||||
explicit Value(long long val = 0) : valueType(INT), intvalue(val), tokvalue(nullptr), floatValue(0.0), moveKind(NonMovedVariable), varvalue(val), condition(0), varId(0U), conditional(false), inconclusive(false), defaultArg(false), valueKind(ValueKind::Possible) {}
|
||||
Value(const Token *c, long long val) : valueType(INT), intvalue(val), tokvalue(nullptr), floatValue(0.0), moveKind(NonMovedVariable), varvalue(val), condition(c), varId(0U), conditional(false), inconclusive(false), defaultArg(false), valueKind(ValueKind::Possible) {
|
||||
callstack.push_back(c);
|
||||
errorPath.push_back(ErrorPathItem(c, "condition"));
|
||||
}
|
||||
|
||||
bool operator==(const Value &rhs) const {
|
||||
|
@ -105,10 +108,10 @@ namespace ValueFlow {
|
|||
/** For calculated values - variable value that calculated value depends on */
|
||||
long long varvalue;
|
||||
|
||||
/** Condition that this value depends on (TODO: replace with a 'callstack') */
|
||||
/** Condition that this value depends on */
|
||||
const Token *condition;
|
||||
|
||||
std::list<const Token *> callstack;
|
||||
ErrorPath errorPath;
|
||||
|
||||
/** For calculated values - varId that calculated value depends on */
|
||||
unsigned int varId;
|
||||
|
|
Loading…
Reference in New Issue