avoid some unchecked pointer dereferences (#4811)

This commit is contained in:
Oliver Stöneberg 2023-03-02 22:05:41 +01:00 committed by GitHub
parent 215124461e
commit b70e1d5461
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
32 changed files with 292 additions and 290 deletions

View File

@ -81,7 +81,7 @@ static bool addFilesToList(const std::string& fileList, std::vector<std::string>
return true;
}
static bool addIncludePathsToList(const std::string& fileList, std::list<std::string>* pathNames)
static bool addIncludePathsToList(const std::string& fileList, std::list<std::string>& pathNames)
{
std::ifstream files(fileList);
if (files) {
@ -96,7 +96,7 @@ static bool addIncludePathsToList(const std::string& fileList, std::list<std::st
if (!endsWith(pathName, '/'))
pathName += '/';
pathNames->emplace_back(std::move(pathName));
pathNames.emplace_back(std::move(pathName));
}
}
return true;
@ -104,12 +104,12 @@ static bool addIncludePathsToList(const std::string& fileList, std::list<std::st
return false;
}
static bool addPathsToSet(const std::string& fileName, std::set<std::string>* set)
static bool addPathsToSet(const std::string& fileName, std::set<std::string>& set)
{
std::list<std::string> templist;
if (!addIncludePathsToList(fileName, &templist))
if (!addIncludePathsToList(fileName, templist))
return false;
set->insert(templist.cbegin(), templist.cend());
set.insert(templist.cbegin(), templist.cend());
return true;
}
@ -279,7 +279,7 @@ bool CmdLineParser::parseFromArgs(int argc, const char* const argv[])
else if (std::strncmp(argv[i], "--config-excludes-file=", 23) == 0) {
// open this file and read every input file (1 file name per line)
const std::string cfgExcludesFile(23 + argv[i]);
if (!addPathsToSet(cfgExcludesFile, &mSettings->configExcludePaths)) {
if (!addPathsToSet(cfgExcludesFile, mSettings->configExcludePaths)) {
printError("unable to open config excludes file at '" + cfgExcludesFile + "'");
return false;
}
@ -468,7 +468,7 @@ bool CmdLineParser::parseFromArgs(int argc, const char* const argv[])
else if (std::strncmp(argv[i], "--includes-file=", 16) == 0) {
// open this file and read every input file (1 file name per line)
const std::string includesFile(16 + argv[i]);
if (!addIncludePathsToList(includesFile, &mSettings->includePaths)) {
if (!addIncludePathsToList(includesFile, mSettings->includePaths)) {
printError("unable to open includes file at '" + includesFile + "'");
return false;
}

View File

@ -568,9 +568,9 @@ bool CppCheckExecutor::tryLoadLibrary(Library& destination, const std::string& b
*/
// cppcheck-suppress passedByValue - used as callback so we need to preserve the signature
// NOLINTNEXTLINE(performance-unnecessary-value-param) - used as callback so we need to preserve the signature
bool CppCheckExecutor::executeCommand(std::string exe, std::vector<std::string> args, std::string redirect, std::string *output_)
bool CppCheckExecutor::executeCommand(std::string exe, std::vector<std::string> args, std::string redirect, std::string &output_)
{
output_->clear();
output_.clear();
std::string joinedArgs;
for (const std::string &arg : args) {
@ -596,7 +596,7 @@ bool CppCheckExecutor::executeCommand(std::string exe, std::vector<std::string>
return false;
char buffer[1024];
while (fgets(buffer, sizeof(buffer), pipe.get()) != nullptr)
*output_ += buffer;
output_ += buffer;
return true;
}

View File

@ -114,7 +114,7 @@ public:
/**
* Execute a shell command and read the output from it. Returns true if command terminated successfully.
*/
static bool executeCommand(std::string exe, std::vector<std::string> args, std::string redirect, std::string *output_);
static bool executeCommand(std::string exe, std::vector<std::string> args, std::string redirect, std::string &output_);
static bool reportSuppressions(const Settings &settings, bool unusedFunctionCheckEnabled, const std::map<std::string, std::size_t> &files, ErrorLogger& errorLogger);

View File

@ -45,9 +45,9 @@
#include <QSettings>
// NOLINTNEXTLINE(performance-unnecessary-value-param) - used as callback so we need to preserve the signature
static bool executeCommand(std::string exe, std::vector<std::string> args, std::string redirect, std::string *output)
static bool executeCommand(std::string exe, std::vector<std::string> args, std::string redirect, std::string &output)
{
output->clear();
output.clear();
QStringList args2;
for (const std::string &arg: args)
@ -60,9 +60,9 @@ static bool executeCommand(std::string exe, std::vector<std::string> args, std::
if (redirect == "2>&1") {
QString s1 = process.readAllStandardOutput();
QString s2 = process.readAllStandardError();
*output = (s1 + "\n" + s2).toStdString();
output = (s1 + "\n" + s2).toStdString();
} else
*output = process.readAllStandardOutput().toStdString();
output = process.readAllStandardOutput().toStdString();
if (redirect.compare(0,3,"2> ") == 0) {
std::ofstream fout(redirect.substr(3));

View File

@ -72,7 +72,7 @@ void AnalyzerInformation::close()
}
}
static bool skipAnalysis(const std::string &analyzerInfoFile, std::size_t hash, std::list<ErrorMessage> *errors)
static bool skipAnalysis(const std::string &analyzerInfoFile, std::size_t hash, std::list<ErrorMessage> &errors)
{
tinyxml2::XMLDocument doc;
const tinyxml2::XMLError error = doc.LoadFile(analyzerInfoFile.c_str());
@ -89,7 +89,7 @@ static bool skipAnalysis(const std::string &analyzerInfoFile, std::size_t hash,
for (const tinyxml2::XMLElement *e = rootNode->FirstChildElement(); e; e = e->NextSiblingElement()) {
if (std::strcmp(e->Name(), "error") == 0)
errors->emplace_back(e);
errors.emplace_back(e);
}
return true;
@ -127,7 +127,7 @@ std::string AnalyzerInformation::getAnalyzerInfoFile(const std::string &buildDir
return Path::join(buildDir, filename) + ".analyzerinfo";
}
bool AnalyzerInformation::analyzeFile(const std::string &buildDir, const std::string &sourcefile, const std::string &cfg, std::size_t hash, std::list<ErrorMessage> *errors)
bool AnalyzerInformation::analyzeFile(const std::string &buildDir, const std::string &sourcefile, const std::string &cfg, std::size_t hash, std::list<ErrorMessage> &errors)
{
if (buildDir.empty() || sourcefile.empty())
return true;

View File

@ -55,7 +55,7 @@ public:
/** Close current TU.analyzerinfo file */
void close();
bool analyzeFile(const std::string &buildDir, const std::string &sourcefile, const std::string &cfg, std::size_t hash, std::list<ErrorMessage> *errors);
bool analyzeFile(const std::string &buildDir, const std::string &sourcefile, const std::string &cfg, std::size_t hash, std::list<ErrorMessage> &errors);
void reportErr(const ErrorMessage &msg);
void setFileInfo(const std::string &check, const std::string &fileInfo);
static std::string getAnalyzerInfoFile(const std::string &buildDir, const std::string &sourcefile, const std::string &cfg);

View File

@ -109,7 +109,7 @@ static int getArgumentPos(const Token* ftok, const Token* tokToFind){
}
template<class T, REQUIRES("T must be a Token class", std::is_convertible<T*, const Token*> )>
static void astFlattenRecursive(T* tok, std::vector<T*>* result, const char* op, nonneg int depth = 0)
static void astFlattenRecursive(T* tok, std::vector<T*>& result, const char* op, nonneg int depth = 0)
{
++depth;
if (!tok || depth >= 100)
@ -118,21 +118,21 @@ static void astFlattenRecursive(T* tok, std::vector<T*>* result, const char* op,
astFlattenRecursive(tok->astOperand1(), result, op, depth);
astFlattenRecursive(tok->astOperand2(), result, op, depth);
} else {
result->push_back(tok);
result.push_back(tok);
}
}
std::vector<const Token*> astFlatten(const Token* tok, const char* op)
{
std::vector<const Token*> result;
astFlattenRecursive(tok, &result, op);
astFlattenRecursive(tok, result, op);
return result;
}
std::vector<Token*> astFlatten(Token* tok, const char* op)
{
std::vector<Token*> result;
astFlattenRecursive(tok, &result, op);
astFlattenRecursive(tok, result, op);
return result;
}
@ -865,12 +865,12 @@ const Token *findNextTokenFromBreak(const Token *breakToken)
}
bool extractForLoopValues(const Token *forToken,
nonneg int * const varid,
bool * const knownInitValue,
MathLib::bigint * const initValue,
bool * const partialCond,
MathLib::bigint * const stepValue,
MathLib::bigint * const lastValue)
nonneg int &varid,
bool &knownInitValue,
MathLib::bigint &initValue,
bool &partialCond,
MathLib::bigint &stepValue,
MathLib::bigint &lastValue)
{
if (!Token::simpleMatch(forToken, "for (") || !Token::simpleMatch(forToken->next()->astOperand2(), ";"))
return false;
@ -880,28 +880,28 @@ bool extractForLoopValues(const Token *forToken,
if (!initExpr || !initExpr->isBinaryOp() || initExpr->str() != "=" || !Token::Match(initExpr->astOperand1(), "%var%"))
return false;
std::vector<MathLib::bigint> minInitValue = getMinValue(ValueFlow::makeIntegralInferModel(), initExpr->astOperand2()->values());
*varid = initExpr->astOperand1()->varId();
*knownInitValue = initExpr->astOperand2()->hasKnownIntValue();
*initValue = minInitValue.empty() ? 0 : minInitValue.front();
*partialCond = Token::Match(condExpr, "%oror%|&&");
varid = initExpr->astOperand1()->varId();
knownInitValue = initExpr->astOperand2()->hasKnownIntValue();
initValue = minInitValue.empty() ? 0 : minInitValue.front();
partialCond = Token::Match(condExpr, "%oror%|&&");
visitAstNodes(condExpr, [varid, &condExpr](const Token *tok) {
if (Token::Match(tok, "%oror%|&&"))
return ChildrenToVisit::op1_and_op2;
if (Token::Match(tok, "<|<=") && tok->isBinaryOp() && tok->astOperand1()->varId() == *varid && tok->astOperand2()->hasKnownIntValue()) {
if (Token::Match(tok, "<|<=") && tok->isBinaryOp() && tok->astOperand1()->varId() == varid && tok->astOperand2()->hasKnownIntValue()) {
if (Token::Match(condExpr, "%oror%|&&") || tok->astOperand2()->getKnownIntValue() < condExpr->astOperand2()->getKnownIntValue())
condExpr = tok;
}
return ChildrenToVisit::none;
});
if (!Token::Match(condExpr, "<|<=") || !condExpr->isBinaryOp() || condExpr->astOperand1()->varId() != *varid || !condExpr->astOperand2()->hasKnownIntValue())
if (!Token::Match(condExpr, "<|<=") || !condExpr->isBinaryOp() || condExpr->astOperand1()->varId() != varid || !condExpr->astOperand2()->hasKnownIntValue())
return false;
if (!incExpr || !incExpr->isUnaryOp("++") || incExpr->astOperand1()->varId() != *varid)
if (!incExpr || !incExpr->isUnaryOp("++") || incExpr->astOperand1()->varId() != varid)
return false;
*stepValue = 1;
stepValue = 1;
if (condExpr->str() == "<")
*lastValue = condExpr->astOperand2()->getKnownIntValue() - 1;
lastValue = condExpr->astOperand2()->getKnownIntValue() - 1;
else
*lastValue = condExpr->astOperand2()->getKnownIntValue();
lastValue = condExpr->astOperand2()->getKnownIntValue();
return true;
}

View File

@ -216,12 +216,12 @@ const Token *findNextTokenFromBreak(const Token *breakToken);
* Extract for loop values: loopvar varid, init value, step value, last value (inclusive)
*/
bool extractForLoopValues(const Token *forToken,
nonneg int * const varid,
bool * const knownInitValue,
long long * const initValue,
bool * const partialCond,
long long * const stepValue,
long long * const lastValue);
nonneg int &varid,
bool &knownInitValue,
long long &initValue,
bool &partialCond,
long long &stepValue,
long long &lastValue);
bool precedes(const Token * tok1, const Token * tok2);
bool succeeds(const Token* tok1, const Token* tok2);

View File

@ -183,37 +183,36 @@ static int getMinFormatStringOutputLength(const std::vector<const Token*> &param
//---------------------------------------------------------------------------
static bool getDimensionsEtc(const Token * const arrayToken, const Settings *settings, std::vector<Dimension> * const dimensions, ErrorPath * const errorPath, bool * const mightBeLarger, MathLib::bigint* path)
static bool getDimensionsEtc(const Token * const arrayToken, const Settings *settings, std::vector<Dimension> &dimensions, ErrorPath &errorPath, bool &mightBeLarger, MathLib::bigint &path)
{
const Token *array = arrayToken;
while (Token::Match(array, ".|::"))
array = array->astOperand2();
if (array->variable() && array->variable()->isArray() && !array->variable()->dimensions().empty()) {
*dimensions = array->variable()->dimensions();
if (dimensions->size() >= 1 && ((*dimensions)[0].num <= 1 || !(*dimensions)[0].tok)) {
dimensions = array->variable()->dimensions();
if (dimensions[0].num <= 1 || !dimensions[0].tok) {
visitAstNodes(arrayToken,
[&](const Token *child) {
if (child->originalName() == "->") {
*mightBeLarger = true;
mightBeLarger = true;
return ChildrenToVisit::none;
}
return ChildrenToVisit::op1_and_op2;
});
}
} else if (const Token *stringLiteral = array->getValueTokenMinStrSize(settings, path)) {
} else if (const Token *stringLiteral = array->getValueTokenMinStrSize(settings, &path)) {
Dimension dim;
dim.tok = nullptr;
dim.num = Token::getStrArraySize(stringLiteral);
dim.known = array->hasKnownValue();
dimensions->emplace_back(dim);
dimensions.emplace_back(dim);
} else if (array->valueType() && array->valueType()->pointer >= 1 && (array->valueType()->isIntegral() || array->valueType()->isFloat())) {
const ValueFlow::Value *value = getBufferSizeValue(array);
if (!value)
return false;
if (path)
*path = value->path;
*errorPath = value->errorPath;
path = value->path;
errorPath = value->errorPath;
Dimension dim;
dim.known = value->isKnown();
dim.tok = nullptr;
@ -221,9 +220,9 @@ static bool getDimensionsEtc(const Token * const arrayToken, const Settings *set
if (typeSize == 0)
return false;
dim.num = value->intvalue / typeSize;
dimensions->emplace_back(dim);
dimensions.emplace_back(dim);
}
return !dimensions->empty();
return !dimensions.empty();
}
static ValueFlow::Value makeSizeValue(MathLib::bigint size, MathLib::bigint path)
@ -314,7 +313,7 @@ void CheckBufferOverrun::arrayIndex()
ErrorPath errorPath;
bool mightBeLarger = false;
MathLib::bigint path = 0;
if (!getDimensionsEtc(tok->astOperand1(), mSettings, &dimensions, &errorPath, &mightBeLarger, &path))
if (!getDimensionsEtc(tok->astOperand1(), mSettings, dimensions, errorPath, mightBeLarger, path))
continue;
const Variable* const var = array->variable();
@ -486,7 +485,7 @@ void CheckBufferOverrun::pointerArithmetic()
ErrorPath errorPath;
bool mightBeLarger = false;
MathLib::bigint path = 0;
if (!getDimensionsEtc(arrayToken, mSettings, &dimensions, &errorPath, &mightBeLarger, &path))
if (!getDimensionsEtc(arrayToken, mSettings, dimensions, errorPath, mightBeLarger, path))
continue;
if (tok->str() == "+") {
@ -881,6 +880,8 @@ std::string CheckBufferOverrun::MyFileInfo::toString() const
bool CheckBufferOverrun::isCtuUnsafeBufferUsage(const Check *check, const Token *argtok, MathLib::bigint *offset, int type)
{
if (!offset)
return false;
const CheckBufferOverrun *c = dynamic_cast<const CheckBufferOverrun *>(check);
if (!c)
return false;
@ -897,8 +898,6 @@ bool CheckBufferOverrun::isCtuUnsafeBufferUsage(const Check *check, const Token
return false;
if (!indexTok->hasKnownIntValue())
return false;
if (!offset)
return false;
*offset = indexTok->getKnownIntValue() * argtok->valueType()->typeSize(*c->mSettings);
return true;
}

View File

@ -1004,11 +1004,11 @@ static inline T getvalue(const int test, const T value1, const T value2)
return 0;
}
static bool parseComparison(const Token *comp, bool *not1, std::string *op, std::string *value, const Token **expr, bool* inconclusive)
static bool parseComparison(const Token *comp, bool &not1, std::string &op, std::string &value, const Token *&expr, bool &inconclusive)
{
*not1 = false;
not1 = false;
while (comp && comp->str() == "!") {
*not1 = !(*not1);
not1 = !(not1);
comp = comp->astOperand1();
}
@ -1018,37 +1018,37 @@ static bool parseComparison(const Token *comp, bool *not1, std::string *op, std:
const Token* op1 = comp->astOperand1();
const Token* op2 = comp->astOperand2();
if (!comp->isComparisonOp() || !op1 || !op2) {
*op = "!=";
*value = "0";
*expr = comp;
op = "!=";
value = "0";
expr = comp;
} else if (op1->isLiteral()) {
if (op1->isExpandedMacro())
return false;
*op = invertOperatorForOperandSwap(comp->str());
op = invertOperatorForOperandSwap(comp->str());
if (op1->enumerator() && op1->enumerator()->value_known)
*value = MathLib::toString(op1->enumerator()->value);
value = MathLib::toString(op1->enumerator()->value);
else
*value = op1->str();
*expr = op2;
value = op1->str();
expr = op2;
} else if (comp->astOperand2()->isLiteral()) {
if (op2->isExpandedMacro())
return false;
*op = comp->str();
op = comp->str();
if (op2->enumerator() && op2->enumerator()->value_known)
*value = MathLib::toString(op2->enumerator()->value);
value = MathLib::toString(op2->enumerator()->value);
else
*value = op2->str();
*expr = op1;
value = op2->str();
expr = op1;
} else {
*op = "!=";
*value = "0";
*expr = comp;
op = "!=";
value = "0";
expr = comp;
}
*inconclusive = *inconclusive || ((*value)[0] == '\'' && !(*op == "!=" || *op == "=="));
inconclusive = inconclusive || ((value)[0] == '\'' && !(op == "!=" || op == "=="));
// Only float and int values are currently handled
if (!MathLib::isInt(*value) && !MathLib::isFloat(*value) && (*value)[0] != '\'')
if (!MathLib::isInt(value) && !MathLib::isFloat(value) && (value)[0] != '\'')
return false;
return true;
@ -1076,7 +1076,7 @@ static std::string conditionString(const Token * tok)
bool not_;
std::string op, value;
const Token *expr;
if (parseComparison(tok, &not_, &op, &value, &expr, &inconclusive) && expr->isName()) {
if (parseComparison(tok, not_, op, value, expr, inconclusive) && expr->isName()) {
return conditionString(not_, expr, op, value);
}
}
@ -1192,13 +1192,13 @@ void CheckCondition::checkIncorrectLogicOperator()
bool not1;
std::string op1, value1;
const Token *expr1 = nullptr;
parseable &= (parseComparison(comp1, &not1, &op1, &value1, &expr1, &inconclusive));
parseable &= (parseComparison(comp1, not1, op1, value1, expr1, inconclusive));
// Parse RHS
bool not2;
std::string op2, value2;
const Token *expr2 = nullptr;
parseable &= (parseComparison(comp2, &not2, &op2, &value2, &expr2, &inconclusive));
parseable &= (parseComparison(comp2, not2, op2, value2, expr2, inconclusive));
if (inconclusive && !printInconclusive)
continue;

View File

@ -208,7 +208,7 @@ void CheckLeakAutoVar::check()
// Empty variable info
VarInfo varInfo;
checkScope(scope->bodyStart, &varInfo, notzero, 0);
checkScope(scope->bodyStart, varInfo, notzero, 0);
}
}
@ -287,7 +287,7 @@ static const Token * isFunctionCall(const Token * nameToken)
}
bool CheckLeakAutoVar::checkScope(const Token * const startToken,
VarInfo *varInfo,
VarInfo &varInfo,
std::set<int> notzero,
nonneg int recursiveCount)
{
@ -299,9 +299,9 @@ bool CheckLeakAutoVar::checkScope(const Token * const startToken,
if (++recursiveCount > recursiveLimit) // maximum number of "else if ()"
throw InternalError(startToken, "Internal limit: CheckLeakAutoVar::checkScope() Maximum recursive count of 1000 reached.", InternalError::LIMIT);
std::map<int, VarInfo::AllocInfo> &alloctype = varInfo->alloctype;
std::map<int, std::string> &possibleUsage = varInfo->possibleUsage;
const std::set<int> conditionalAlloc(varInfo->conditionalAlloc);
std::map<int, VarInfo::AllocInfo> &alloctype = varInfo.alloctype;
std::map<int, std::string> &possibleUsage = varInfo.possibleUsage;
const std::set<int> conditionalAlloc(varInfo.conditionalAlloc);
// Parse all tokens
const Token * const endToken = startToken->link();
@ -372,7 +372,7 @@ bool CheckLeakAutoVar::checkScope(const Token * const startToken,
if (Token::Match(tokAssignOp, "= %var% [+;]")) {
if (varTok->tokAt(2)->varId() != varTok->varId()) {
// If variable points at allocated memory => error
leakIfAllocated(varTok, *varInfo);
leakIfAllocated(varTok, varInfo);
// no multivariable checking currently => bail out for rhs variables
for (const Token *tok2 = varTok; tok2; tok2 = tok2->next()) {
@ -380,7 +380,7 @@ bool CheckLeakAutoVar::checkScope(const Token * const startToken,
break;
}
if (tok2->varId()) {
varInfo->erase(tok2->varId());
varInfo.erase(tok2->varId());
}
}
}
@ -397,8 +397,8 @@ bool CheckLeakAutoVar::checkScope(const Token * const startToken,
// Variable has already been allocated => error
if (conditionalAlloc.find(varTok->varId()) == conditionalAlloc.end())
leakIfAllocated(varTok, *varInfo);
varInfo->erase(varTok->varId());
leakIfAllocated(varTok, varInfo);
varInfo.erase(varTok->varId());
if (!isLocalVarNoAutoDealloc(varTok, mTokenizer->isCPP()))
continue;
@ -488,8 +488,8 @@ bool CheckLeakAutoVar::checkScope(const Token * const startToken,
}
if (Token::simpleMatch(closingParenthesis, ") {")) {
VarInfo varInfo1(*varInfo); // VarInfo for if code
VarInfo varInfo2(*varInfo); // VarInfo for else code
VarInfo varInfo1(varInfo); // VarInfo for if code
VarInfo varInfo2(varInfo); // VarInfo for else code
// Skip expressions before commas
const Token * astOperand2AfterCommas = tok->next()->astOperand2();
@ -535,13 +535,13 @@ bool CheckLeakAutoVar::checkScope(const Token * const startToken,
return ChildrenToVisit::none;
});
if (!checkScope(closingParenthesis->next(), &varInfo1, notzero, recursiveCount)) {
varInfo->clear();
if (!checkScope(closingParenthesis->next(), varInfo1, notzero, recursiveCount)) {
varInfo.clear();
continue;
}
closingParenthesis = closingParenthesis->linkAt(1);
if (Token::simpleMatch(closingParenthesis, "} else {")) {
if (!checkScope(closingParenthesis->tokAt(2), &varInfo2, notzero, recursiveCount))
if (!checkScope(closingParenthesis->tokAt(2), varInfo2, notzero, recursiveCount))
continue;
tok = closingParenthesis->linkAt(2)->previous();
} else {
@ -549,7 +549,7 @@ bool CheckLeakAutoVar::checkScope(const Token * const startToken,
}
VarInfo old;
old.swap(*varInfo);
old.swap(varInfo);
std::map<int, VarInfo::AllocInfo>::const_iterator it;
@ -568,7 +568,7 @@ bool CheckLeakAutoVar::checkScope(const Token * const startToken,
for (it = varInfo1.alloctype.cbegin(); it != varInfo1.alloctype.cend(); ++it) {
if (varInfo2.alloctype.find(it->first) == varInfo2.alloctype.end() &&
old.alloctype.find(it->first) == old.alloctype.end()) {
varInfo->conditionalAlloc.insert(it->first);
varInfo.conditionalAlloc.insert(it->first);
}
}
@ -576,20 +576,20 @@ bool CheckLeakAutoVar::checkScope(const Token * const startToken,
for (it = varInfo2.alloctype.cbegin(); it != varInfo2.alloctype.cend(); ++it) {
if (varInfo1.alloctype.find(it->first) == varInfo1.alloctype.end() &&
old.alloctype.find(it->first) == old.alloctype.end()) {
varInfo->conditionalAlloc.insert(it->first);
varInfo.conditionalAlloc.insert(it->first);
}
}
// Conditional allocation/deallocation
for (it = varInfo1.alloctype.cbegin(); it != varInfo1.alloctype.cend(); ++it) {
if (it->second.managed() && conditionalAlloc.find(it->first) != conditionalAlloc.end()) {
varInfo->conditionalAlloc.erase(it->first);
varInfo.conditionalAlloc.erase(it->first);
varInfo2.erase(it->first);
}
}
for (it = varInfo2.alloctype.cbegin(); it != varInfo2.alloctype.cend(); ++it) {
if (it->second.managed() && conditionalAlloc.find(it->first) != conditionalAlloc.end()) {
varInfo->conditionalAlloc.erase(it->first);
varInfo.conditionalAlloc.erase(it->first);
varInfo1.erase(it->first);
}
}
@ -604,14 +604,14 @@ bool CheckLeakAutoVar::checkScope(const Token * const startToken,
// unknown control.. (TODO: handle loops)
else if ((Token::Match(tok, "%type% (") && Token::simpleMatch(tok->linkAt(1), ") {")) || Token::simpleMatch(tok, "do {")) {
varInfo->clear();
varInfo.clear();
break;
}
// return
else if (tok->str() == "return") {
ret(tok, *varInfo);
varInfo->clear();
ret(tok, varInfo);
varInfo.clear();
}
// throw
@ -625,8 +625,8 @@ bool CheckLeakAutoVar::checkScope(const Token * const startToken,
}
// If the execution leaves the function then treat it as return
if (!tryFound)
ret(tok, *varInfo);
varInfo->clear();
ret(tok, varInfo);
varInfo.clear();
}
// delete
@ -670,9 +670,9 @@ bool CheckLeakAutoVar::checkScope(const Token * const startToken,
bool unknown = false;
if (mTokenizer->isScopeNoReturn(tok->tokAt(2), &unknown)) {
if (!unknown)
varInfo->clear();
varInfo.clear();
else if (!mSettings->library.isLeakIgnore(functionName) && !mSettings->library.isUse(functionName))
varInfo->possibleUsageAll(functionName);
varInfo.possibleUsageAll(functionName);
}
}
@ -681,13 +681,13 @@ bool CheckLeakAutoVar::checkScope(const Token * const startToken,
// goto => weird execution path
else if (tok->str() == "goto") {
varInfo->clear();
varInfo.clear();
return false;
}
// continue/break
else if (Token::Match(tok, "continue|break ;")) {
varInfo->clear();
varInfo.clear();
}
// Check smart pointer
@ -761,7 +761,7 @@ bool CheckLeakAutoVar::checkScope(const Token * const startToken,
break;
}
} else { // there is a deleter, but we can't check it -> assume that it deallocates correctly
varInfo->clear();
varInfo.clear();
continue;
}
}
@ -772,23 +772,23 @@ bool CheckLeakAutoVar::checkScope(const Token * const startToken,
changeAllocStatus(varInfo, allocation, vtok, vtok);
}
}
ret(endToken, *varInfo, true);
ret(endToken, varInfo, true);
return true;
}
const Token * CheckLeakAutoVar::checkTokenInsideExpression(const Token * const tok, VarInfo *varInfo)
const Token * CheckLeakAutoVar::checkTokenInsideExpression(const Token * const tok, VarInfo &varInfo)
{
// Deallocation and then dereferencing pointer..
if (tok->varId() > 0) {
// TODO : Write a separate checker for this that uses valueFlowForward.
const std::map<int, VarInfo::AllocInfo>::const_iterator var = varInfo->alloctype.find(tok->varId());
if (var != varInfo->alloctype.end()) {
const std::map<int, VarInfo::AllocInfo>::const_iterator var = varInfo.alloctype.find(tok->varId());
if (var != varInfo.alloctype.end()) {
bool unknown = false;
if (var->second.status == VarInfo::DEALLOC && CheckNullPointer::isPointerDeRef(tok, unknown, mSettings) && !unknown) {
deallocUseError(tok, tok->str());
} else if (Token::simpleMatch(tok->tokAt(-2), "= &")) {
varInfo->erase(tok->varId());
varInfo.erase(tok->varId());
} else {
// check if tok is assigned into another variable
const Token *rhs = tok;
@ -802,7 +802,7 @@ const Token * CheckLeakAutoVar::checkTokenInsideExpression(const Token * const t
}
if (rhs->varId() == tok->varId()) {
// simple assignment
varInfo->erase(tok->varId());
varInfo.erase(tok->varId());
} else if (rhs->str() == "(" && !mSettings->library.returnValue(rhs->astOperand1()).empty()) {
// #9298, assignment through return value of a function
const std::string &returnValue = mSettings->library.returnValue(rhs->astOperand1());
@ -812,14 +812,14 @@ const Token * CheckLeakAutoVar::checkTokenInsideExpression(const Token * const t
if (func) {
const std::string arg = "arg" + std::to_string(argn + 1);
if (returnValue == arg) {
varInfo->erase(tok->varId());
varInfo.erase(tok->varId());
}
}
}
}
}
} else if (Token::Match(tok->previous(), "& %name% = %var% ;")) {
varInfo->referenced.insert(tok->tokAt(2)->varId());
varInfo.referenced.insert(tok->tokAt(2)->varId());
}
}
@ -863,23 +863,23 @@ void CheckLeakAutoVar::changeAllocStatusIfRealloc(std::map<int, VarInfo::AllocIn
}
void CheckLeakAutoVar::changeAllocStatus(VarInfo *varInfo, const VarInfo::AllocInfo& allocation, const Token* tok, const Token* arg)
void CheckLeakAutoVar::changeAllocStatus(VarInfo &varInfo, const VarInfo::AllocInfo& allocation, const Token* tok, const Token* arg)
{
std::map<int, VarInfo::AllocInfo> &alloctype = varInfo->alloctype;
std::map<int, VarInfo::AllocInfo> &alloctype = varInfo.alloctype;
const std::map<int, VarInfo::AllocInfo>::iterator var = alloctype.find(arg->varId());
if (var != alloctype.end()) {
if (allocation.status == VarInfo::NOALLOC) {
// possible usage
varInfo->possibleUsage[arg->varId()] = tok->str();
varInfo.possibleUsage[arg->varId()] = tok->str();
if (var->second.status == VarInfo::DEALLOC && arg->previous()->str() == "&")
varInfo->erase(arg->varId());
varInfo.erase(arg->varId());
} else if (var->second.managed()) {
doubleFreeError(tok, var->second.allocTok, arg->str(), allocation.type);
var->second.status = allocation.status;
} else if (var->second.type != allocation.type && var->second.type != 0) {
// mismatching allocation and deallocation
mismatchError(tok, var->second.allocTok, arg->str());
varInfo->erase(arg->varId());
varInfo.erase(arg->varId());
} else {
// deallocation
var->second.status = allocation.status;
@ -892,7 +892,7 @@ void CheckLeakAutoVar::changeAllocStatus(VarInfo *varInfo, const VarInfo::AllocI
}
}
void CheckLeakAutoVar::functionCall(const Token *tokName, const Token *tokOpeningPar, VarInfo *varInfo, const VarInfo::AllocInfo& allocation, const Library::AllocFunc* af)
void CheckLeakAutoVar::functionCall(const Token *tokName, const Token *tokOpeningPar, VarInfo &varInfo, const VarInfo::AllocInfo& allocation, const Library::AllocFunc* af)
{
// Ignore function call?
if (mSettings->library.isLeakIgnore(mSettings->library.getFunctionName(tokName)))

View File

@ -126,7 +126,7 @@ private:
/** check for leaks in a function scope */
bool checkScope(const Token * const startToken,
VarInfo *varInfo,
VarInfo &varInfo,
std::set<int> notzero,
nonneg int recursiveCount);
@ -135,13 +135,13 @@ private:
* @param varInfo Variable info
* @return next token to process (if no other checks needed for this token). NULL if other checks could be performed.
*/
const Token * checkTokenInsideExpression(const Token * const tok, VarInfo *varInfo);
const Token * checkTokenInsideExpression(const Token * const tok, VarInfo &varInfo);
/** parse function call */
void functionCall(const Token *tokName, const Token *tokOpeningPar, VarInfo *varInfo, const VarInfo::AllocInfo& allocation, const Library::AllocFunc* af);
void functionCall(const Token *tokName, const Token *tokOpeningPar, VarInfo &varInfo, const VarInfo::AllocInfo& allocation, const Library::AllocFunc* af);
/** parse changes in allocation status */
void changeAllocStatus(VarInfo *varInfo, const VarInfo::AllocInfo& allocation, const Token* tok, const Token* arg);
void changeAllocStatus(VarInfo &varInfo, const VarInfo::AllocInfo& allocation, const Token* tok, const Token* arg);
/** update allocation status if reallocation function */
void changeAllocStatusIfRealloc(std::map<int, VarInfo::AllocInfo> &alloctype, const Token *fTok, const Token *retTok);

View File

@ -728,6 +728,8 @@ void CheckMemoryLeakStructMember::check()
bool CheckMemoryLeakStructMember::isMalloc(const Variable *variable)
{
if (!variable)
return false;
const int declarationId(variable->declarationId());
bool alloc = false;
for (const Token *tok2 = variable->nameToken(); tok2 && tok2 != variable->scope()->bodyEnd; tok2 = tok2->next()) {
@ -742,6 +744,8 @@ bool CheckMemoryLeakStructMember::isMalloc(const Variable *variable)
void CheckMemoryLeakStructMember::checkStructVariable(const Variable * const variable)
{
if (!variable)
return;
// Is struct variable a pointer?
if (variable->isArrayOrPointer()) {
// Check that variable is allocated with malloc

View File

@ -387,22 +387,19 @@ void CheckType::checkFloatToIntegerOverflow()
{
for (const Token *tok = mTokenizer->tokens(); tok; tok = tok->next()) {
const ValueType *vtint, *vtfloat;
const std::list<ValueFlow::Value> *floatValues;
// Explicit cast
if (Token::Match(tok, "( %name%") && tok->astOperand1() && !tok->astOperand2()) {
vtint = tok->valueType();
vtfloat = tok->astOperand1()->valueType();
floatValues = &tok->astOperand1()->values();
checkFloatToIntegerOverflow(tok, vtint, vtfloat, floatValues);
checkFloatToIntegerOverflow(tok, vtint, vtfloat, tok->astOperand1()->values());
}
// Assignment
else if (tok->str() == "=" && tok->astOperand1() && tok->astOperand2()) {
vtint = tok->astOperand1()->valueType();
vtfloat = tok->astOperand2()->valueType();
floatValues = &tok->astOperand2()->values();
checkFloatToIntegerOverflow(tok, vtint, vtfloat, floatValues);
checkFloatToIntegerOverflow(tok, vtint, vtfloat, tok->astOperand2()->values());
}
else if (tok->str() == "return" && tok->astOperand1() && tok->astOperand1()->valueType() && tok->astOperand1()->valueType()->isFloat()) {
@ -412,14 +409,13 @@ void CheckType::checkFloatToIntegerOverflow()
if (scope && scope->type == Scope::ScopeType::eFunction && scope->function && scope->function->retDef) {
const ValueType &valueType = ValueType::parseDecl(scope->function->retDef, mSettings, mTokenizer->isCPP());
vtfloat = tok->astOperand1()->valueType();
floatValues = &tok->astOperand1()->values();
checkFloatToIntegerOverflow(tok, &valueType, vtfloat, floatValues);
checkFloatToIntegerOverflow(tok, &valueType, vtfloat, tok->astOperand1()->values());
}
}
}
}
void CheckType::checkFloatToIntegerOverflow(const Token *tok, const ValueType *vtint, const ValueType *vtfloat, const std::list<ValueFlow::Value> *floatValues)
void CheckType::checkFloatToIntegerOverflow(const Token *tok, const ValueType *vtint, const ValueType *vtfloat, const std::list<ValueFlow::Value> &floatValues)
{
// Conversion of float to integer?
if (!vtint || !vtint->isIntegral())
@ -427,7 +423,7 @@ void CheckType::checkFloatToIntegerOverflow(const Token *tok, const ValueType *v
if (!vtfloat || !vtfloat->isFloat())
return;
for (const ValueFlow::Value &f : *floatValues) {
for (const ValueFlow::Value &f : floatValues) {
if (f.valueType != ValueFlow::Value::ValueType::FLOAT)
continue;
if (!mSettings->isEnabled(&f, false))

View File

@ -75,7 +75,7 @@ public:
/** @brief %Check for float to integer overflow */
void checkFloatToIntegerOverflow();
void checkFloatToIntegerOverflow(const Token *tok, const ValueType *vtint, const ValueType *vtfloat, const std::list<ValueFlow::Value> *floatValues);
void checkFloatToIntegerOverflow(const Token *tok, const ValueType *vtint, const ValueType *vtfloat, const std::list<ValueFlow::Value> &floatValues);
private:

View File

@ -317,7 +317,7 @@ static std::string executeAddon(const AddonInfo &addonInfo,
const std::string &defaultPythonExe,
const std::string &file,
const std::string &premiumArgs,
const std::function<bool(std::string,std::vector<std::string>,std::string,std::string*)> &executeCommand)
const std::function<bool(std::string,std::vector<std::string>,std::string,std::string&)> &executeCommand)
{
const std::string redirect = "2>&1";
@ -337,7 +337,7 @@ static std::string executeAddon(const AddonInfo &addonInfo,
#endif
for (const char* py_exe : py_exes) {
std::string out;
if (executeCommand(py_exe, split("--version"), redirect, &out) && out.compare(0, 7, "Python ") == 0 && std::isdigit(out[7])) {
if (executeCommand(py_exe, split("--version"), redirect, out) && out.compare(0, 7, "Python ") == 0 && std::isdigit(out[7])) {
pythonExe = py_exe;
break;
}
@ -357,7 +357,7 @@ static std::string executeAddon(const AddonInfo &addonInfo,
args += fileArg;
std::string result;
if (!executeCommand(pythonExe, split(args), redirect, &result)) {
if (!executeCommand(pythonExe, split(args), redirect, result)) {
std::string message("Failed to execute addon (command: '" + pythonExe + " " + args + "'). Exitcode is nonzero.");
if (result.size() > 2) {
message = message + "\n" + message + "\nOutput:\n" + result;
@ -390,7 +390,7 @@ static std::string getDefinesFlags(const std::string &semicolonSeparatedString)
CppCheck::CppCheck(ErrorLogger &errorLogger,
bool useGlobalSuppressions,
std::function<bool(std::string,std::vector<std::string>,std::string,std::string*)> executeCommand)
std::function<bool(std::string,std::vector<std::string>,std::string,std::string&)> executeCommand)
: mErrorLogger(errorLogger)
, mExitCode(0)
, mUseGlobalSuppressions(useGlobalSuppressions)
@ -423,7 +423,7 @@ const char * CppCheck::extraVersion()
return ExtraVersion;
}
static bool reportClangErrors(std::istream &is, const std::function<void(const ErrorMessage&)>& reportErr, std::vector<ErrorMessage> *warnings)
static bool reportClangErrors(std::istream &is, const std::function<void(const ErrorMessage&)>& reportErr, std::vector<ErrorMessage> &warnings)
{
std::string line;
while (std::getline(is, line)) {
@ -433,7 +433,7 @@ static bool reportClangErrors(std::istream &is, const std::function<void(const E
std::string::size_type pos3 = line.find(": error: ");
if (pos3 == std::string::npos)
pos3 = line.find(": fatal error:");
if (warnings && pos3 == std::string::npos)
if (pos3 == std::string::npos)
pos3 = line.find(": warning:");
if (pos3 == std::string::npos)
continue;
@ -463,7 +463,7 @@ static bool reportClangErrors(std::istream &is, const std::function<void(const E
Certainty::normal);
if (line.compare(pos3, 10, ": warning:") == 0) {
warnings->push_back(std::move(errmsg));
warnings.push_back(std::move(errmsg));
continue;
}
@ -512,7 +512,7 @@ unsigned int CppCheck::check(const std::string &path)
}
std::string output2;
if (!mExecuteCommand(exe,split(args2),redirect2,&output2) || output2.find("TranslationUnitDecl") == std::string::npos) {
if (!mExecuteCommand(exe,split(args2),redirect2,output2) || output2.find("TranslationUnitDecl") == std::string::npos) {
std::cerr << "Failed to execute '" << exe << " " << args2 << " " << redirect2 << "'" << std::endl;
return 0;
}
@ -524,14 +524,14 @@ unsigned int CppCheck::check(const std::string &path)
auto reportError = [this](const ErrorMessage& errorMessage) {
reportErr(errorMessage);
};
if (reportClangErrors(fin, reportError, &compilerWarnings))
if (reportClangErrors(fin, reportError, compilerWarnings))
return 0;
} else {
std::istringstream istr(output2);
auto reportError = [this](const ErrorMessage& errorMessage) {
reportErr(errorMessage);
};
if (reportClangErrors(istr, reportError, &compilerWarnings))
if (reportClangErrors(istr, reportError, compilerWarnings))
return 0;
}
@ -762,7 +762,7 @@ unsigned int CppCheck::checkFile(const std::string& filename, const std::string
// Calculate hash so it can be compared with old hash / future hashes
const std::size_t hash = preprocessor.calculateHash(tokens1, toolinfo.str());
std::list<ErrorMessage> errors;
if (!mAnalyzerInformation.analyzeFile(mSettings.buildDir, filename, cfgname, hash, &errors)) {
if (!mAnalyzerInformation.analyzeFile(mSettings.buildDir, filename, cfgname, hash, errors)) {
while (!errors.empty()) {
reportErr(errors.front());
errors.pop_front();
@ -1699,7 +1699,7 @@ void CppCheck::analyseClangTidy(const ImportProject::FileSettings &fileSettings)
const std::string args = "-quiet -checks=*,-clang-analyzer-*,-llvm* \"" + fileSettings.filename + "\" -- " + allIncludes + allDefines;
std::string output;
if (!mExecuteCommand(exe, split(args), emptyString, &output)) {
if (!mExecuteCommand(exe, split(args), emptyString, output)) {
std::cerr << "Failed to execute '" << exe << "'" << std::endl;
return;
}

View File

@ -55,7 +55,7 @@ public:
*/
CppCheck(ErrorLogger &errorLogger,
bool useGlobalSuppressions,
std::function<bool(std::string,std::vector<std::string>,std::string,std::string*)> executeCommand);
std::function<bool(std::string,std::vector<std::string>,std::string,std::string&)> executeCommand);
/**
* @brief Destructor.
@ -240,7 +240,7 @@ private:
AnalyzerInformation mAnalyzerInformation;
/** Callback for executing a shell command (exe, args, output) */
std::function<bool(std::string,std::vector<std::string>,std::string,std::string*)> mExecuteCommand;
std::function<bool(std::string,std::vector<std::string>,std::string,std::string&)> mExecuteCommand;
std::ofstream mPlistFile;
};

View File

@ -626,7 +626,7 @@ static std::list<std::string> toStringList(const std::string &s)
return ret;
}
static void importPropertyGroup(const tinyxml2::XMLElement *node, std::map<std::string,std::string,cppcheck::stricmp> *variables, std::string *includePath, bool *useOfMfc)
static void importPropertyGroup(const tinyxml2::XMLElement *node, std::map<std::string,std::string,cppcheck::stricmp> &variables, std::string &includePath, bool *useOfMfc)
{
if (useOfMfc) {
for (const tinyxml2::XMLElement *e = node->FirstChildElement(); e; e = e->NextSiblingElement()) {
@ -642,7 +642,7 @@ static void importPropertyGroup(const tinyxml2::XMLElement *node, std::map<std::
for (const tinyxml2::XMLElement *propertyGroup = node->FirstChildElement(); propertyGroup; propertyGroup = propertyGroup->NextSiblingElement()) {
const std::string name(propertyGroup->Name());
const char *text = propertyGroup->GetText();
(*variables)[name] = std::string(text ? text : "");
variables[name] = std::string(text ? text : "");
}
} else if (!labelAttribute) {
@ -655,22 +655,22 @@ static void importPropertyGroup(const tinyxml2::XMLElement *node, std::map<std::
std::string path(text);
const std::string::size_type pos = path.find("$(IncludePath)");
if (pos != std::string::npos)
path.replace(pos, 14U, *includePath);
*includePath = path;
path.replace(pos, 14U, includePath);
includePath = path;
}
}
}
static void loadVisualStudioProperties(const std::string &props, std::map<std::string,std::string,cppcheck::stricmp> *variables, std::string *includePath, const std::string &additionalIncludeDirectories, std::list<ItemDefinitionGroup> &itemDefinitionGroupList)
static void loadVisualStudioProperties(const std::string &props, std::map<std::string,std::string,cppcheck::stricmp> &variables, std::string &includePath, const std::string &additionalIncludeDirectories, std::list<ItemDefinitionGroup> &itemDefinitionGroupList)
{
std::string filename(props);
// variables can't be resolved
if (!simplifyPathWithVariables(filename, *variables))
if (!simplifyPathWithVariables(filename, variables))
return;
// prepend project dir (if it exists) to transform relative paths into absolute ones
if (!Path::isAbsolute(filename) && variables->count("ProjectDir") > 0)
filename = Path::getAbsoluteFilePath(variables->at("ProjectDir") + filename);
if (!Path::isAbsolute(filename) && variables.count("ProjectDir") > 0)
filename = Path::getAbsoluteFilePath(variables.at("ProjectDir") + filename);
tinyxml2::XMLDocument doc;
if (doc.LoadFile(filename.c_str()) != tinyxml2::XML_SUCCESS)
@ -750,7 +750,7 @@ bool ImportProject::importVcxproj(const std::string &filename, std::map<std::str
} else if (std::strcmp(node->Name(), "ItemDefinitionGroup") == 0) {
itemDefinitionGroupList.emplace_back(node, additionalIncludeDirectories);
} else if (std::strcmp(node->Name(), "PropertyGroup") == 0) {
importPropertyGroup(node, &variables, &includePath, &useOfMfc);
importPropertyGroup(node, variables, includePath, &useOfMfc);
} else if (std::strcmp(node->Name(), "ImportGroup") == 0) {
const char *labelAttribute = node->Attribute("Label");
if (labelAttribute && std::strcmp(labelAttribute, "PropertySheets") == 0) {
@ -758,7 +758,7 @@ bool ImportProject::importVcxproj(const std::string &filename, std::map<std::str
if (std::strcmp(e->Name(), "Import") == 0) {
const char *projectAttribute = e->Attribute("Project");
if (projectAttribute)
loadVisualStudioProperties(projectAttribute, &variables, &includePath, additionalIncludeDirectories, itemDefinitionGroupList);
loadVisualStudioProperties(projectAttribute, variables, includePath, additionalIncludeDirectories, itemDefinitionGroupList);
}
}
}

View File

@ -953,10 +953,10 @@ bool Library::isFloatArgValid(const Token *ftok, int argnr, double argvalue) con
return false;
}
std::string Library::getFunctionName(const Token *ftok, bool *error) const
std::string Library::getFunctionName(const Token *ftok, bool &error) const
{
if (!ftok) {
*error = true;
error = true;
return "";
}
if (ftok->isName()) {
@ -980,13 +980,13 @@ std::string Library::getFunctionName(const Token *ftok, bool *error) const
if (ftok->str() == "." && ftok->astOperand1()) {
const std::string type = astCanonicalType(ftok->astOperand1());
if (type.empty()) {
*error = true;
error = true;
return "";
}
return type + "::" + getFunctionName(ftok->astOperand2(),error);
}
*error = true;
error = true;
return "";
}
@ -999,7 +999,7 @@ std::string Library::getFunctionName(const Token *ftok) const
if (ftok->astParent()) {
bool error = false;
const Token * tok = ftok->astParent()->isUnaryOp("&") ? ftok->astParent()->astOperand1() : ftok->next()->astOperand1();
const std::string ret = getFunctionName(tok, &error);
const std::string ret = getFunctionName(tok, error);
return error ? std::string() : ret;
}

View File

@ -154,7 +154,7 @@ public:
return ((id > 0) && ((id & 1) == 0));
}
static bool ismemory(const AllocFunc* const func) {
return ((func->groupId > 0) && ((func->groupId & 1) == 0));
return func && (func->groupId > 0) && ((func->groupId & 1) == 0);
}
/** is allocation type resource? */
@ -162,7 +162,7 @@ public:
return ((id > 0) && ((id & 1) == 1));
}
static bool isresource(const AllocFunc* const func) {
return ((func->groupId > 0) && ((func->groupId & 1) == 1));
return func && (func->groupId > 0) && ((func->groupId & 1) == 1);
}
bool formatstr_function(const Token* ftok) const;
@ -652,7 +652,7 @@ private:
const ArgumentChecks * getarg(const Token *ftok, int argnr) const;
std::string getFunctionName(const Token *ftok, bool *error) const;
std::string getFunctionName(const Token *ftok, bool &error) const;
static const AllocFunc* getAllocDealloc(const std::map<std::string, AllocFunc> &data, const std::string &name) {
const std::map<std::string, AllocFunc>::const_iterator it = data.find(name);

View File

@ -84,7 +84,7 @@ namespace {
};
}
static bool parseInlineSuppressionCommentToken(const simplecpp::Token *tok, std::list<Suppressions::Suppression> &inlineSuppressions, std::list<BadInlineSuppression> *bad)
static bool parseInlineSuppressionCommentToken(const simplecpp::Token *tok, std::list<Suppressions::Suppression> &inlineSuppressions, std::list<BadInlineSuppression> &bad)
{
const std::string cppchecksuppress("cppcheck-suppress");
@ -110,7 +110,7 @@ static bool parseInlineSuppressionCommentToken(const simplecpp::Token *tok, std:
std::vector<Suppressions::Suppression> suppressions = Suppressions::parseMultiSuppressComment(comment, &errmsg);
if (!errmsg.empty())
bad->emplace_back(tok->location, std::move(errmsg));
bad.emplace_back(tok->location, std::move(errmsg));
std::copy_if(suppressions.cbegin(), suppressions.cend(), std::back_inserter(inlineSuppressions), [](const Suppressions::Suppression& s) {
return !s.errorId.empty();
@ -126,13 +126,13 @@ static bool parseInlineSuppressionCommentToken(const simplecpp::Token *tok, std:
inlineSuppressions.push_back(std::move(s));
if (!errmsg.empty())
bad->emplace_back(tok->location, std::move(errmsg));
bad.emplace_back(tok->location, std::move(errmsg));
}
return true;
}
static void addinlineSuppressions(const simplecpp::TokenList &tokens, Settings &mSettings, std::list<BadInlineSuppression> *bad)
static void addinlineSuppressions(const simplecpp::TokenList &tokens, Settings &mSettings, std::list<BadInlineSuppression> &bad)
{
for (const simplecpp::Token *tok = tokens.cfront(); tok; tok = tok->next) {
if (!tok->comment)
@ -192,10 +192,10 @@ void Preprocessor::inlineSuppressions(const simplecpp::TokenList &tokens)
if (!mSettings.inlineSuppressions)
return;
std::list<BadInlineSuppression> err;
::addinlineSuppressions(tokens, mSettings, &err);
::addinlineSuppressions(tokens, mSettings, err);
for (std::map<std::string,simplecpp::TokenList*>::const_iterator it = mTokenLists.cbegin(); it != mTokenLists.cend(); ++it) {
if (it->second)
::addinlineSuppressions(*it->second, mSettings, &err);
::addinlineSuppressions(*it->second, mSettings, err);
}
for (const BadInlineSuppression &bad : err) {
error(bad.location.file(), bad.location.line, bad.errmsg);

View File

@ -58,7 +58,7 @@ void ProgramMemory::setValue(const Token* expr, const ValueFlow::Value& value) {
if (tok->hasKnownIntValue())
return {tok->values().front().intvalue};
MathLib::bigint result = 0;
if (getIntValue(tok->exprId(), &result))
if (getIntValue(tok->exprId(), result))
return {result};
return {};
},
@ -77,11 +77,11 @@ const ValueFlow::Value* ProgramMemory::getValue(nonneg int exprid, bool impossib
}
// cppcheck-suppress unusedFunction
bool ProgramMemory::getIntValue(nonneg int exprid, MathLib::bigint* result) const
bool ProgramMemory::getIntValue(nonneg int exprid, MathLib::bigint& result) const
{
const ValueFlow::Value* value = getValue(exprid);
if (value && value->isIntValue()) {
*result = value->intvalue;
result = value->intvalue;
return true;
}
return false;
@ -106,25 +106,25 @@ bool ProgramMemory::getTokValue(nonneg int exprid, const Token** result) const
}
// cppcheck-suppress unusedFunction
bool ProgramMemory::getContainerSizeValue(nonneg int exprid, MathLib::bigint* result) const
bool ProgramMemory::getContainerSizeValue(nonneg int exprid, MathLib::bigint& result) const
{
const ValueFlow::Value* value = getValue(exprid);
if (value && value->isContainerSizeValue()) {
*result = value->intvalue;
result = value->intvalue;
return true;
}
return false;
}
bool ProgramMemory::getContainerEmptyValue(nonneg int exprid, MathLib::bigint* result) const
bool ProgramMemory::getContainerEmptyValue(nonneg int exprid, MathLib::bigint& result) const
{
const ValueFlow::Value* value = getValue(exprid, true);
if (value && value->isContainerSizeValue()) {
if (value->isImpossible() && value->intvalue == 0) {
*result = false;
result = false;
return true;
}
if (!value->isImpossible()) {
*result = (value->intvalue == 0);
result = (value->intvalue == 0);
return true;
}
}
@ -210,7 +210,7 @@ static bool evaluateCondition(const std::string& op,
}
MathLib::bigint result = 0;
bool error = false;
execute(condition, &pm, &result, &error, settings);
execute(condition, pm, &result, &error, settings);
return !error && result == r;
}
@ -259,7 +259,7 @@ void programMemoryParseCondition(ProgramMemory& pm, const Token* tok, const Toke
return {t->values().front().intvalue};
MathLib::bigint result = 0;
bool error = false;
execute(t, &pm, &result, &error);
execute(t, pm, &result, &error);
if (!error)
return {result};
return std::vector<MathLib::bigint>{};
@ -323,7 +323,7 @@ static void fillProgramMemoryFromConditions(ProgramMemory& pm, const Scope* scop
return;
MathLib::bigint result = 0;
bool error = false;
execute(condTok, &pm, &result, &error);
execute(condTok, pm, &result, &error);
if (error)
programMemoryParseCondition(pm, condTok, endTok, settings, scope->type != Scope::eElse);
}
@ -719,7 +719,7 @@ static std::unordered_map<std::string, BuiltinLibraryFunction> createBuiltinLibr
return ValueFlow::Value::unknown();
const double value = args[0].isFloatValue() ? args[0].floatValue : args[0].intvalue;
ValueFlow::Value v;
combineValueProperties(args[0], args[1], &v);
combineValueProperties(args[0], args[1], v);
v.floatValue = std::atan2(value, args[1].isFloatValue() ? args[1].floatValue : args[1].intvalue);
v.valueType = ValueFlow::Value::ValueType::FLOAT;
return v;
@ -731,7 +731,7 @@ static std::unordered_map<std::string, BuiltinLibraryFunction> createBuiltinLibr
return ValueFlow::Value::unknown();
const double value = args[0].isFloatValue() ? args[0].floatValue : args[0].intvalue;
ValueFlow::Value v;
combineValueProperties(args[0], args[1], &v);
combineValueProperties(args[0], args[1], v);
v.floatValue = std::remainder(value, args[1].isFloatValue() ? args[1].floatValue : args[1].intvalue);
v.valueType = ValueFlow::Value::ValueType::FLOAT;
return v;
@ -743,7 +743,7 @@ static std::unordered_map<std::string, BuiltinLibraryFunction> createBuiltinLibr
return ValueFlow::Value::unknown();
const double value = args[0].isFloatValue() ? args[0].floatValue : args[0].intvalue;
ValueFlow::Value v;
combineValueProperties(args[0], args[1], &v);
combineValueProperties(args[0], args[1], v);
v.floatValue = std::nextafter(value, args[1].isFloatValue() ? args[1].floatValue : args[1].intvalue);
v.valueType = ValueFlow::Value::ValueType::FLOAT;
return v;
@ -755,7 +755,7 @@ static std::unordered_map<std::string, BuiltinLibraryFunction> createBuiltinLibr
return ValueFlow::Value::unknown();
const double value = args[0].isFloatValue() ? args[0].floatValue : args[0].intvalue;
ValueFlow::Value v;
combineValueProperties(args[0], args[1], &v);
combineValueProperties(args[0], args[1], v);
v.floatValue = std::nexttoward(value, args[1].isFloatValue() ? args[1].floatValue : args[1].intvalue);
v.valueType = ValueFlow::Value::ValueType::FLOAT;
return v;
@ -767,7 +767,7 @@ static std::unordered_map<std::string, BuiltinLibraryFunction> createBuiltinLibr
return ValueFlow::Value::unknown();
const double value = args[0].isFloatValue() ? args[0].floatValue : args[0].intvalue;
ValueFlow::Value v;
combineValueProperties(args[0], args[1], &v);
combineValueProperties(args[0], args[1], v);
v.floatValue = std::hypot(value, args[1].isFloatValue() ? args[1].floatValue : args[1].intvalue);
v.valueType = ValueFlow::Value::ValueType::FLOAT;
return v;
@ -779,7 +779,7 @@ static std::unordered_map<std::string, BuiltinLibraryFunction> createBuiltinLibr
return ValueFlow::Value::unknown();
const double value = args[0].isFloatValue() ? args[0].floatValue : args[0].intvalue;
ValueFlow::Value v;
combineValueProperties(args[0], args[1], &v);
combineValueProperties(args[0], args[1], v);
v.floatValue = std::fdim(value, args[1].isFloatValue() ? args[1].floatValue : args[1].intvalue);
v.valueType = ValueFlow::Value::ValueType::FLOAT;
return v;
@ -791,7 +791,7 @@ static std::unordered_map<std::string, BuiltinLibraryFunction> createBuiltinLibr
return ValueFlow::Value::unknown();
const double value = args[0].isFloatValue() ? args[0].floatValue : args[0].intvalue;
ValueFlow::Value v;
combineValueProperties(args[0], args[1], &v);
combineValueProperties(args[0], args[1], v);
v.floatValue = std::fmax(value, args[1].isFloatValue() ? args[1].floatValue : args[1].intvalue);
v.valueType = ValueFlow::Value::ValueType::FLOAT;
return v;
@ -803,7 +803,7 @@ static std::unordered_map<std::string, BuiltinLibraryFunction> createBuiltinLibr
return ValueFlow::Value::unknown();
const double value = args[0].isFloatValue() ? args[0].floatValue : args[0].intvalue;
ValueFlow::Value v;
combineValueProperties(args[0], args[1], &v);
combineValueProperties(args[0], args[1], v);
v.floatValue = std::fmin(value, args[1].isFloatValue() ? args[1].floatValue : args[1].intvalue);
v.valueType = ValueFlow::Value::ValueType::FLOAT;
return v;
@ -815,7 +815,7 @@ static std::unordered_map<std::string, BuiltinLibraryFunction> createBuiltinLibr
return ValueFlow::Value::unknown();
const double value = args[0].isFloatValue() ? args[0].floatValue : args[0].intvalue;
ValueFlow::Value v;
combineValueProperties(args[0], args[1], &v);
combineValueProperties(args[0], args[1], v);
v.floatValue = std::fmod(value, args[1].isFloatValue() ? args[1].floatValue : args[1].intvalue);
v.valueType = ValueFlow::Value::ValueType::FLOAT;
return v;
@ -827,7 +827,7 @@ static std::unordered_map<std::string, BuiltinLibraryFunction> createBuiltinLibr
return ValueFlow::Value::unknown();
const double value = args[0].isFloatValue() ? args[0].floatValue : args[0].intvalue;
ValueFlow::Value v;
combineValueProperties(args[0], args[1], &v);
combineValueProperties(args[0], args[1], v);
v.floatValue = std::pow(value, args[1].isFloatValue() ? args[1].floatValue : args[1].intvalue);
v.valueType = ValueFlow::Value::ValueType::FLOAT;
return v;
@ -839,7 +839,7 @@ static std::unordered_map<std::string, BuiltinLibraryFunction> createBuiltinLibr
return ValueFlow::Value::unknown();
const double value = args[0].isFloatValue() ? args[0].floatValue : args[0].intvalue;
ValueFlow::Value v;
combineValueProperties(args[0], args[1], &v);
combineValueProperties(args[0], args[1], v);
v.floatValue = std::scalbln(value, args[1].isFloatValue() ? args[1].floatValue : args[1].intvalue);
v.valueType = ValueFlow::Value::ValueType::FLOAT;
return v;
@ -851,7 +851,7 @@ static std::unordered_map<std::string, BuiltinLibraryFunction> createBuiltinLibr
return ValueFlow::Value::unknown();
const double value = args[0].isFloatValue() ? args[0].floatValue : args[0].intvalue;
ValueFlow::Value v;
combineValueProperties(args[0], args[1], &v);
combineValueProperties(args[0], args[1], v);
v.floatValue = std::ldexp(value, args[1].isFloatValue() ? args[1].floatValue : args[1].intvalue);
v.valueType = ValueFlow::Value::ValueType::FLOAT;
return v;
@ -1408,12 +1408,12 @@ ValueFlow::Value evaluateLibraryFunction(const std::unordered_map<nonneg int, Va
}
void execute(const Token* expr,
ProgramMemory* const programMemory,
ProgramMemory& programMemory,
MathLib::bigint* result,
bool* error,
const Settings* settings)
{
ValueFlow::Value v = execute(expr, *programMemory, settings);
ValueFlow::Value v = execute(expr, programMemory, settings);
if (!v.isIntValue() || v.isImpossible()) {
if (error)
*error = true;

View File

@ -74,11 +74,11 @@ struct ProgramMemory {
void setValue(const Token* expr, const ValueFlow::Value& value);
const ValueFlow::Value* getValue(nonneg int exprid, bool impossible = false) const;
bool getIntValue(nonneg int exprid, MathLib::bigint* result) const;
bool getIntValue(nonneg int exprid, MathLib::bigint& result) const;
void setIntValue(const Token* expr, MathLib::bigint value, bool impossible = false);
bool getContainerSizeValue(nonneg int exprid, MathLib::bigint* result) const;
bool getContainerEmptyValue(nonneg int exprid, MathLib::bigint* result) const;
bool getContainerSizeValue(nonneg int exprid, MathLib::bigint& result) const;
bool getContainerEmptyValue(nonneg int exprid, MathLib::bigint& result) const;
void setContainerSizeValue(const Token* expr, MathLib::bigint value, bool isEqual = true);
void setUnknown(const Token* expr);
@ -143,7 +143,7 @@ struct ProgramMemoryState {
};
void execute(const Token* expr,
ProgramMemory* const programMemory,
ProgramMemory& programMemory,
MathLib::bigint* result,
bool* error,
const Settings* settings = nullptr);

View File

@ -2167,7 +2167,7 @@ void Variable::evaluate(const Settings* settings)
bool isContainer = false;
if (mNameToken)
setFlag(fIsArray, arrayDimensions(settings, &isContainer));
setFlag(fIsArray, arrayDimensions(settings, isContainer));
if (mTypeStartToken)
setValueType(ValueType::parseDecl(mTypeStartToken,settings, true)); // TODO: set isCpp
@ -2238,7 +2238,7 @@ void Variable::evaluate(const Settings* settings)
tok = tok->link()->previous();
// add array dimensions if present
if (tok && tok->next()->str() == "[")
setFlag(fIsArray, arrayDimensions(settings, &isContainer));
setFlag(fIsArray, arrayDimensions(settings, isContainer));
}
if (!tok)
return;
@ -3502,14 +3502,14 @@ bool Type::isDerivedFrom(const std::string & ancestor) const
return false;
}
bool Variable::arrayDimensions(const Settings* settings, bool* isContainer)
bool Variable::arrayDimensions(const Settings* settings, bool& isContainer)
{
*isContainer = false;
isContainer = false;
const Library::Container* container = settings->library.detectContainer(mTypeStartToken);
if (container && container->arrayLike_indexOp && container->size_templateArgNo > 0) {
const Token* tok = Token::findsimplematch(mTypeStartToken, "<");
if (tok) {
*isContainer = true;
isContainer = true;
Dimension dimension_;
tok = tok->next();
for (int i = 0; i < container->size_templateArgNo && tok; i++) {

View File

@ -226,7 +226,7 @@ class CPPCHECKLIB Variable {
* @param isContainer Is the array container-like?
* @return true if array, false if not
*/
bool arrayDimensions(const Settings* settings, bool* isContainer);
bool arrayDimensions(const Settings* settings, bool& isContainer);
public:
Variable(const Token *name_, const Token *start_, const Token *end_,

View File

@ -2496,13 +2496,13 @@ void TokenImpl::setCppcheckAttribute(TokenImpl::CppcheckAttributes::Type type, M
}
}
bool TokenImpl::getCppcheckAttribute(TokenImpl::CppcheckAttributes::Type type, MathLib::bigint *value) const
bool TokenImpl::getCppcheckAttribute(TokenImpl::CppcheckAttributes::Type type, MathLib::bigint &value) const
{
struct CppcheckAttributes *attr = mCppcheckAttributes;
while (attr && attr->type != type)
attr = attr->next;
if (attr)
*value = attr->value;
value = attr->value;
return attr != nullptr;
}

View File

@ -132,7 +132,7 @@ struct TokenImpl {
TokenDebug mDebug;
void setCppcheckAttribute(CppcheckAttributes::Type type, MathLib::bigint value);
bool getCppcheckAttribute(CppcheckAttributes::Type type, MathLib::bigint *value) const;
bool getCppcheckAttribute(CppcheckAttributes::Type type, MathLib::bigint &value) const;
TokenImpl()
: mVarId(0),
@ -559,7 +559,7 @@ public:
void setCppcheckAttribute(TokenImpl::CppcheckAttributes::Type type, MathLib::bigint value) {
mImpl->setCppcheckAttribute(type, value);
}
bool getCppcheckAttribute(TokenImpl::CppcheckAttributes::Type type, MathLib::bigint *value) const {
bool getCppcheckAttribute(TokenImpl::CppcheckAttributes::Type type, MathLib::bigint &value) const {
return mImpl->getCppcheckAttribute(type, value);
}
bool hasCppcheckAttributes() const {

View File

@ -3483,8 +3483,11 @@ public:
const std::map<std::string, nonneg int>& map(bool global) const {
return global ? mVariableId_global : mVariableId;
}
nonneg int* getVarId() const {
return &mVarId;
nonneg int getVarId() const {
return mVarId;
}
nonneg int& getVarId() {
return mVarId;
}
};
@ -3661,7 +3664,7 @@ static bool setVarIdParseDeclaration(const Token **tok, const VariableMap& varia
void Tokenizer::setVarIdStructMembers(Token **tok1,
std::map<nonneg int, std::map<std::string, nonneg int>>& structMembers,
nonneg int *varId) const
nonneg int &varId) const
{
Token *tok = *tok1;
@ -3680,8 +3683,8 @@ void Tokenizer::setVarIdStructMembers(Token **tok1,
tok = tok->next();
const std::map<std::string, nonneg int>::iterator it = members.find(tok->str());
if (it == members.end()) {
members[tok->str()] = ++(*varId);
tok->varId(*varId);
members[tok->str()] = ++varId;
tok->varId(varId);
} else {
tok->varId(it->second);
}
@ -3714,8 +3717,8 @@ void Tokenizer::setVarIdStructMembers(Token **tok1,
std::map<std::string, nonneg int>& members = structMembers[struct_varid];
const std::map<std::string, nonneg int>::iterator it = members.find(tok->str());
if (it == members.end()) {
members[tok->str()] = ++(*varId);
tok->varId(*varId);
members[tok->str()] = ++varId;
tok->varId(varId);
} else {
tok->varId(it->second);
}
@ -3726,7 +3729,7 @@ void Tokenizer::setVarIdStructMembers(Token **tok1,
void Tokenizer::setVarIdClassDeclaration(const Token * const startToken,
const VariableMap &variableMap,
VariableMap &variableMap,
const nonneg int scopeStartVarId,
std::map<nonneg int, std::map<std::string, nonneg int>>& structMembers)
{
@ -3808,7 +3811,7 @@ void Tokenizer::setVarIdClassFunction(const std::string &classname,
const Token * const endToken,
const std::map<std::string, nonneg int> &varlist,
std::map<nonneg int, std::map<std::string, nonneg int>>& structMembers,
nonneg int *varId_)
nonneg int &varId_)
{
for (Token *tok2 = startToken; tok2 && tok2 != endToken; tok2 = tok2->next()) {
if (tok2->varId() != 0 || !tok2->isName())
@ -3889,7 +3892,7 @@ void Tokenizer::setVarIdPass1()
if (!variableMap.leaveScope())
cppcheckError(tok);
} else if (tok->str() == "{") {
scopeStack.emplace(true, scopeStack.top().isStructInit || tok->strAt(-1) == "=", /*isEnum=*/ false, *variableMap.getVarId());
scopeStack.emplace(true, scopeStack.top().isStructInit || tok->strAt(-1) == "=", /*isEnum=*/ false, variableMap.getVarId());
// check if this '{' is a start of an "if" body
const Token * ifToken = tok->previous();
@ -3951,7 +3954,7 @@ void Tokenizer::setVarIdPass1()
variableMap.enterScope();
}
initlist = false;
scopeStack.emplace(isExecutable, scopeStack.top().isStructInit || tok->strAt(-1) == "=", isEnumStart(tok), *variableMap.getVarId());
scopeStack.emplace(isExecutable, scopeStack.top().isStructInit || tok->strAt(-1) == "=", isEnumStart(tok), variableMap.getVarId());
} else { /* if (tok->str() == "}") */
bool isNamespace = false;
for (const Token *tok1 = tok->link()->previous(); tok1 && tok1->isName(); tok1 = tok1->previous()) {
@ -4212,7 +4215,7 @@ void Tokenizer::setVarIdPass1()
}
}
mVarId = *variableMap.getVarId();
mVarId = variableMap.getVarId();
}
namespace {
@ -4460,14 +4463,14 @@ void Tokenizer::setVarIdPass2()
if (tok2->str() == "(") {
Token *funcstart = const_cast<Token*>(isFunctionHead(tok2, "{"));
if (funcstart) {
setVarIdClassFunction(scopeName2 + classname, funcstart, funcstart->link(), thisClassVars, structMembers, &mVarId);
setVarIdClassFunction(scopeName2 + classname, funcstart, funcstart->link(), thisClassVars, structMembers, mVarId);
tok2 = funcstart->link();
continue;
}
}
if (tok2->str() == "{") {
if (tok2->strAt(-1) == ")")
setVarIdClassFunction(scopeName2 + classname, tok2, tok2->link(), thisClassVars, structMembers, &mVarId);
setVarIdClassFunction(scopeName2 + classname, tok2, tok2->link(), thisClassVars, structMembers, mVarId);
tok2 = tok2->link();
} else if (Token::Match(tok2, "( %name%|)") && !Token::Match(tok2->link(), "(|[")) {
tok2 = tok2->link();
@ -4513,7 +4516,7 @@ void Tokenizer::setVarIdPass2()
// If this is a function implementation.. add it to funclist
Token * start = const_cast<Token *>(isFunctionHead(tok2, "{"));
if (start) {
setVarIdClassFunction(classname, start, start->link(), thisClassVars, structMembers, &mVarId);
setVarIdClassFunction(classname, start, start->link(), thisClassVars, structMembers, mVarId);
}
if (Token::Match(tok2, ") %name% ("))
@ -4547,7 +4550,7 @@ void Tokenizer::setVarIdPass2()
tok3 = tok3->linkAt(1);
}
if (Token::Match(tok3, ")|} {")) {
setVarIdClassFunction(classname, tok2, tok3->next()->link(), thisClassVars, structMembers, &mVarId);
setVarIdClassFunction(classname, tok2, tok3->next()->link(), thisClassVars, structMembers, mVarId);
}
}
}

View File

@ -587,20 +587,20 @@ private:
void unsupportedTypedef(const Token *tok) const;
void setVarIdClassDeclaration(const Token * const startToken,
const VariableMap &variableMap,
VariableMap &variableMap,
const nonneg int scopeStartVarId,
std::map<nonneg int, std::map<std::string, nonneg int>>& structMembers);
void setVarIdStructMembers(Token **tok1,
std::map<nonneg int, std::map<std::string, nonneg int>>& structMembers,
nonneg int *varId) const;
nonneg int &varId) const;
void setVarIdClassFunction(const std::string &classname,
Token * const startToken,
const Token * const endToken,
const std::map<std::string, nonneg int> &varlist,
std::map<nonneg int, std::map<std::string, nonneg int>>& structMembers,
nonneg int *varId_);
nonneg int &varId_);
/**
* Output list of unknown types.

View File

@ -418,47 +418,47 @@ static bool isNumeric(const ValueFlow::Value& value) {
return value.isIntValue() || value.isFloatValue();
}
void ValueFlow::combineValueProperties(const ValueFlow::Value &value1, const ValueFlow::Value &value2, ValueFlow::Value *result)
void ValueFlow::combineValueProperties(const ValueFlow::Value &value1, const ValueFlow::Value &value2, ValueFlow::Value &result)
{
if (value1.isKnown() && value2.isKnown())
result->setKnown();
result.setKnown();
else if (value1.isImpossible() || value2.isImpossible())
result->setImpossible();
result.setImpossible();
else if (value1.isInconclusive() || value2.isInconclusive())
result->setInconclusive();
result.setInconclusive();
else
result->setPossible();
result.setPossible();
if (value1.tokvalue)
result->tokvalue = value1.tokvalue;
result.tokvalue = value1.tokvalue;
else if (value2.tokvalue)
result->tokvalue = value2.tokvalue;
result.tokvalue = value2.tokvalue;
if (value1.isSymbolicValue()) {
result->valueType = value1.valueType;
result->tokvalue = value1.tokvalue;
result.valueType = value1.valueType;
result.tokvalue = value1.tokvalue;
}
if (value2.isSymbolicValue()) {
result->valueType = value2.valueType;
result->tokvalue = value2.tokvalue;
result.valueType = value2.valueType;
result.tokvalue = value2.tokvalue;
}
if (value1.isIteratorValue())
result->valueType = value1.valueType;
result.valueType = value1.valueType;
if (value2.isIteratorValue())
result->valueType = value2.valueType;
result->condition = value1.condition ? value1.condition : value2.condition;
result->varId = (value1.varId != 0) ? value1.varId : value2.varId;
result->varvalue = (result->varId == value1.varId) ? value1.varvalue : value2.varvalue;
result->errorPath = (value1.errorPath.empty() ? value2 : value1).errorPath;
result->safe = value1.safe || value2.safe;
result.valueType = value2.valueType;
result.condition = value1.condition ? value1.condition : value2.condition;
result.varId = (value1.varId != 0) ? value1.varId : value2.varId;
result.varvalue = (result.varId == value1.varId) ? value1.varvalue : value2.varvalue;
result.errorPath = (value1.errorPath.empty() ? value2 : value1).errorPath;
result.safe = value1.safe || value2.safe;
if (value1.bound == ValueFlow::Value::Bound::Point || value2.bound == ValueFlow::Value::Bound::Point) {
if (value1.bound == ValueFlow::Value::Bound::Upper || value2.bound == ValueFlow::Value::Bound::Upper)
result->bound = ValueFlow::Value::Bound::Upper;
result.bound = ValueFlow::Value::Bound::Upper;
if (value1.bound == ValueFlow::Value::Bound::Lower || value2.bound == ValueFlow::Value::Bound::Lower)
result->bound = ValueFlow::Value::Bound::Lower;
result.bound = ValueFlow::Value::Bound::Lower;
}
if (value1.path != value2.path)
result->path = -1;
result.path = -1;
else
result->path = value1.path;
result.path = value1.path;
}
static const Token *getCastTypeStartToken(const Token *parent, const Settings* settings)
@ -652,7 +652,7 @@ static void setTokenValue(Token* tok,
else
continue;
combineValueProperties(value1, value2, &result);
combineValueProperties(value1, value2, result);
if (Token::simpleMatch(parent, "==") && result.intvalue)
continue;
@ -854,7 +854,7 @@ static void setTokenValue(Token* tok,
if (!isCompatibleValues(value1, value2))
continue;
ValueFlow::Value result(0);
combineValueProperties(value1, value2, &result);
combineValueProperties(value1, value2, result);
if (astIsFloat(parent, false)) {
if (!result.isIntValue() && !result.isFloatValue())
continue;
@ -1097,7 +1097,7 @@ size_t ValueFlow::getSizeOf(const ValueType &vt, const Settings *settings)
}
static bool getMinMaxValues(const ValueType* vt, const cppcheck::Platform& platform, MathLib::bigint* minValue, MathLib::bigint* maxValue);
static bool getMinMaxValues(const ValueType* vt, const cppcheck::Platform& platform, MathLib::bigint& minValue, MathLib::bigint& maxValue);
// Handle various constants..
static Token * valueFlowSetConstantValue(Token *tok, const Settings *settings, bool cpp)
@ -1108,7 +1108,7 @@ static Token * valueFlowSetConstantValue(Token *tok, const Settings *settings, b
const ValueType* vt = tok->valueType();
if (vt && vt->sign == ValueType::UNSIGNED && signedValue < 0 && ValueFlow::getSizeOf(*vt, settings) < sizeof(MathLib::bigint)) {
MathLib::bigint minValue{}, maxValue{};
if (getMinMaxValues(tok->valueType(), *settings, &minValue, &maxValue))
if (getMinMaxValues(tok->valueType(), *settings, minValue, maxValue))
signedValue += maxValue + 1;
}
ValueFlow::Value value(signedValue);
@ -2817,7 +2817,7 @@ struct ValueFlowAnalyzer : Analyzer {
} else {
MathLib::bigint out = 0;
bool error = false;
execute(tok, &pm, &out, &error, getSettings());
execute(tok, pm, &out, &error, getSettings());
if (!error)
result.push_back(out);
}
@ -2844,7 +2844,7 @@ struct ValueFlowAnalyzer : Analyzer {
return {value->intvalue == 0};
ProgramMemory pm = pms.get(tok, ctx, getProgramState());
MathLib::bigint out = 0;
if (pm.getContainerEmptyValue(tok->exprId(), &out))
if (pm.getContainerEmptyValue(tok->exprId(), out))
return {static_cast<int>(out)};
return {};
} else {
@ -6344,9 +6344,9 @@ struct ConditionHandler {
ProgramMemory pm;
fillFromPath(pm, initTok, path);
fillFromPath(pm, condTok, path);
execute(initTok, &pm, nullptr, nullptr);
execute(initTok, pm, nullptr, nullptr);
MathLib::bigint result = 1;
execute(condTok, &pm, &result, nullptr);
execute(condTok, pm, &result, nullptr);
if (result == 0)
return;
// Remove condition since for condition is not redundant
@ -6762,10 +6762,10 @@ static bool valueFlowForLoop2(const Token *tok,
ProgramMemory programMemory;
MathLib::bigint result(0);
bool error = false;
execute(firstExpression, &programMemory, &result, &error);
execute(firstExpression, programMemory, &result, &error);
if (error)
return false;
execute(secondExpression, &programMemory, &result, &error);
execute(secondExpression, programMemory, &result, &error);
if (result == 0) // 2nd expression is false => no looping
return false;
if (error) {
@ -6788,9 +6788,9 @@ static bool valueFlowForLoop2(const Token *tok,
int maxcount = 10000;
while (result != 0 && !error && --maxcount > 0) {
endMemory = programMemory;
execute(thirdExpression, &programMemory, &result, &error);
execute(thirdExpression, programMemory, &result, &error);
if (!error)
execute(secondExpression, &programMemory, &result, &error);
execute(secondExpression, programMemory, &result, &error);
}
if (memory1)
@ -6954,7 +6954,7 @@ static void valueFlowForLoop(TokenList *tokenlist, SymbolDatabase* symboldatabas
bool knownInitValue, partialCond;
MathLib::bigint initValue, stepValue, lastValue;
if (extractForLoopValues(tok, &varid, &knownInitValue, &initValue, &partialCond, &stepValue, &lastValue)) {
if (extractForLoopValues(tok, varid, knownInitValue, initValue, partialCond, stepValue, lastValue)) {
const bool executeBody = !knownInitValue || initValue <= lastValue;
const Token* vartok = Token::findmatch(tok, "%varid%", bodyStart, varid);
if (executeBody && vartok) {
@ -7556,7 +7556,7 @@ static void valueFlowFunctionReturn(TokenList *tokenlist, ErrorLogger *errorLogg
MathLib::bigint result = 0;
bool error = false;
execute(functionScope->bodyStart->next()->astOperand1(),
&programMemory,
programMemory,
&result,
&error);
if (!error) {
@ -8631,7 +8631,7 @@ static void valueFlowDynamicBufferSize(TokenList* tokenlist, SymbolDatabase* sym
}
}
static bool getMinMaxValues(const ValueType *vt, const cppcheck::Platform &platform, MathLib::bigint *minValue, MathLib::bigint *maxValue)
static bool getMinMaxValues(const ValueType *vt, const cppcheck::Platform &platform, MathLib::bigint &minValue, MathLib::bigint &maxValue)
{
if (!vt || !vt->isIntegral() || vt->pointer)
return false;
@ -8661,23 +8661,23 @@ static bool getMinMaxValues(const ValueType *vt, const cppcheck::Platform &platf
}
if (bits == 1) {
*minValue = 0;
*maxValue = 1;
minValue = 0;
maxValue = 1;
} else if (bits < 62) {
if (vt->sign == ValueType::Sign::UNSIGNED) {
*minValue = 0;
*maxValue = (1LL << bits) - 1;
minValue = 0;
maxValue = (1LL << bits) - 1;
} else {
*minValue = -(1LL << (bits - 1));
*maxValue = (1LL << (bits - 1)) - 1;
minValue = -(1LL << (bits - 1));
maxValue = (1LL << (bits - 1)) - 1;
}
} else if (bits == 64) {
if (vt->sign == ValueType::Sign::UNSIGNED) {
*minValue = 0;
*maxValue = LLONG_MAX; // todo max unsigned value
minValue = 0;
maxValue = LLONG_MAX; // todo max unsigned value
} else {
*minValue = LLONG_MIN;
*maxValue = LLONG_MAX;
minValue = LLONG_MIN;
maxValue = LLONG_MAX;
}
} else {
return false;
@ -8686,7 +8686,7 @@ static bool getMinMaxValues(const ValueType *vt, const cppcheck::Platform &platf
return true;
}
static bool getMinMaxValues(const std::string &typestr, const Settings *settings, MathLib::bigint *minvalue, MathLib::bigint *maxvalue)
static bool getMinMaxValues(const std::string &typestr, const Settings *settings, MathLib::bigint &minvalue, MathLib::bigint &maxvalue)
{
TokenList typeTokens(settings);
std::istringstream istr(typestr+";");
@ -8732,8 +8732,8 @@ static void valueFlowSafeFunctions(TokenList* tokenlist, SymbolDatabase* symbold
}
MathLib::bigint low, high;
bool isLow = arg.nameToken()->getCppcheckAttribute(TokenImpl::CppcheckAttributes::Type::LOW, &low);
bool isHigh = arg.nameToken()->getCppcheckAttribute(TokenImpl::CppcheckAttributes::Type::HIGH, &high);
bool isLow = arg.nameToken()->getCppcheckAttribute(TokenImpl::CppcheckAttributes::Type::LOW, low);
bool isHigh = arg.nameToken()->getCppcheckAttribute(TokenImpl::CppcheckAttributes::Type::HIGH, high);
if (!isLow && !isHigh && !all)
continue;
@ -8743,7 +8743,7 @@ static void valueFlowSafeFunctions(TokenList* tokenlist, SymbolDatabase* symbold
if ((!isLow || !isHigh) && all) {
MathLib::bigint minValue, maxValue;
if (getMinMaxValues(arg.valueType(), *settings, &minValue, &maxValue)) {
if (getMinMaxValues(arg.valueType(), *settings, minValue, maxValue)) {
if (!isLow)
low = minValue;
if (!isHigh)
@ -8808,7 +8808,7 @@ static void valueFlowUnknownFunctionReturn(TokenList *tokenlist, const Settings
// Get min/max values for return type
const std::string &typestr = settings->library.returnValueType(tok->previous());
MathLib::bigint minvalue, maxvalue;
if (!getMinMaxValues(typestr, settings, &minvalue, &maxvalue))
if (!getMinMaxValues(typestr, settings, minvalue, maxvalue))
continue;
for (MathLib::bigint value : unknownValues) {

View File

@ -126,7 +126,7 @@ namespace ValueFlow {
const Token* getEndOfExprScope(const Token* tok, const Scope* defaultScope = nullptr, bool smallest = true);
void combineValueProperties(const Value& value1, const Value& value2, Value* result);
void combineValueProperties(const Value& value1, const Value& value2, Value& result);
}
#endif // valueflowH

View File

@ -662,10 +662,10 @@ private:
ASSERT(library.loadxmldata(xmldata, sizeof(xmldata)));
ASSERT(library.functions.empty());
ASSERT(Library::ismemory(library.getAllocFuncInfo("CreateX")));
ASSERT_EQUALS(library.allocId("CreateX"), library.deallocId("DeleteX"));
const Library::AllocFunc* af = library.getAllocFuncInfo("CreateX");
ASSERT(af && af->arg == -1);
ASSERT(Library::ismemory(af));
ASSERT_EQUALS(library.allocId("CreateX"), library.deallocId("DeleteX"));
const Library::AllocFunc* df = library.getDeallocFuncInfo("DeleteX");
ASSERT(df && df->arg == 1);
}