Enable and mitigate readability-else-after-return (#5175)
This commit is contained in:
parent
f96e3c9d84
commit
bb962e2bc3
|
@ -1,5 +1,5 @@
|
|||
---
|
||||
Checks: '*,-abseil-*,-altera-*,-android-*,-boost-*,-cert-*,-cppcoreguidelines-*,-darwin-*,-fuchsia-*,-google-*,-hicpp-*,-linuxkernel-*,-llvm-*,-llvmlibc-*,-mpi-*,-objc-*,-openmp-*,-zircon-*,google-explicit-constructor,-readability-braces-around-statements,-readability-magic-numbers,-bugprone-macro-parentheses,-readability-isolate-declaration,-readability-function-size,-modernize-use-trailing-return-type,-readability-implicit-bool-conversion,-readability-uppercase-literal-suffix,-modernize-use-auto,-readability-else-after-return,-modernize-use-default-member-init,-readability-redundant-member-init,-modernize-avoid-c-arrays,-modernize-use-equals-default,-readability-container-size-empty,-bugprone-branch-clone,-bugprone-narrowing-conversions,-modernize-raw-string-literal,-readability-convert-member-functions-to-static,-modernize-loop-convert,-readability-const-return-type,-modernize-return-braced-init-list,-performance-inefficient-string-concatenation,-misc-throw-by-value-catch-by-reference,-readability-avoid-const-params-in-decls,-misc-non-private-member-variables-in-classes,-clang-analyzer-*,-bugprone-signed-char-misuse,-misc-no-recursion,-readability-use-anyofallof,-performance-no-automatic-move,-readability-function-cognitive-complexity,-readability-redundant-access-specifiers,-concurrency-mt-unsafe,-bugprone-easily-swappable-parameters,-readability-suspicious-call-argument,-readability-identifier-length,-readability-container-data-pointer,-bugprone-assignment-in-if-condition,-misc-const-correctness,-portability-std-allocator-const,-modernize-deprecated-ios-base-aliases,-bugprone-unchecked-optional-access,-modernize-replace-auto-ptr,-readability-identifier-naming,-portability-simd-intrinsics,-misc-use-anonymous-namespace,cert-err34-c'
|
||||
Checks: '*,-abseil-*,-altera-*,-android-*,-boost-*,-cert-*,-cppcoreguidelines-*,-darwin-*,-fuchsia-*,-google-*,-hicpp-*,-linuxkernel-*,-llvm-*,-llvmlibc-*,-mpi-*,-objc-*,-openmp-*,-zircon-*,google-explicit-constructor,-readability-braces-around-statements,-readability-magic-numbers,-bugprone-macro-parentheses,-readability-isolate-declaration,-readability-function-size,-modernize-use-trailing-return-type,-readability-implicit-bool-conversion,-readability-uppercase-literal-suffix,-modernize-use-auto,-modernize-use-default-member-init,-readability-redundant-member-init,-modernize-avoid-c-arrays,-modernize-use-equals-default,-readability-container-size-empty,-bugprone-branch-clone,-bugprone-narrowing-conversions,-modernize-raw-string-literal,-readability-convert-member-functions-to-static,-modernize-loop-convert,-readability-const-return-type,-modernize-return-braced-init-list,-performance-inefficient-string-concatenation,-misc-throw-by-value-catch-by-reference,-readability-avoid-const-params-in-decls,-misc-non-private-member-variables-in-classes,-clang-analyzer-*,-bugprone-signed-char-misuse,-misc-no-recursion,-readability-use-anyofallof,-performance-no-automatic-move,-readability-function-cognitive-complexity,-readability-redundant-access-specifiers,-concurrency-mt-unsafe,-bugprone-easily-swappable-parameters,-readability-suspicious-call-argument,-readability-identifier-length,-readability-container-data-pointer,-bugprone-assignment-in-if-condition,-misc-const-correctness,-portability-std-allocator-const,-modernize-deprecated-ios-base-aliases,-bugprone-unchecked-optional-access,-modernize-replace-auto-ptr,-readability-identifier-naming,-portability-simd-intrinsics,-misc-use-anonymous-namespace,cert-err34-c'
|
||||
WarningsAsErrors: '*'
|
||||
HeaderFilterRegex: '(cli|gui|lib|oss-fuzz|test|triage)\/[a-z]+\.h'
|
||||
CheckOptions:
|
||||
|
|
|
@ -182,7 +182,8 @@ bool CppCheckExecutor::parseFromArgs(Settings &settings, int argc, const char* c
|
|||
if (!ignored.empty())
|
||||
std::cout << "cppcheck: Maybe all paths were ignored?" << std::endl;
|
||||
return false;
|
||||
} else if (!settings.fileFilters.empty() && settings.project.fileSettings.empty()) {
|
||||
}
|
||||
if (!settings.fileFilters.empty() && settings.project.fileSettings.empty()) {
|
||||
std::map<std::string, std::size_t> newMap;
|
||||
for (std::map<std::string, std::size_t>::const_iterator i = mFiles.cbegin(); i != mFiles.cend(); ++i)
|
||||
if (matchglobs(settings.fileFilters, i->first)) {
|
||||
|
|
|
@ -69,8 +69,7 @@ static bool IsAddressOnStack(const void* ptr)
|
|||
char a;
|
||||
if (bStackBelowHeap)
|
||||
return ptr < &a;
|
||||
else
|
||||
return ptr > &a;
|
||||
return ptr > &a;
|
||||
}
|
||||
|
||||
/* (declare this list here, so it may be used in signal handlers in addition to main())
|
||||
|
|
|
@ -218,7 +218,8 @@ bool ProcessExecutor::checkLoadAverage(size_t nchildren)
|
|||
if (getloadavg(&sample, 1) != 1) {
|
||||
// disable load average checking on getloadavg error
|
||||
return true;
|
||||
} else if (sample < mSettings.loadAverage) {
|
||||
}
|
||||
if (sample < mSettings.loadAverage) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
|
|
@ -514,11 +514,9 @@ QString CppcheckLibraryData::open(QIODevice &file)
|
|||
break;
|
||||
}
|
||||
}
|
||||
if (xmlReader.hasError()) {
|
||||
if (xmlReader.hasError())
|
||||
return xmlReader.errorString();
|
||||
} else {
|
||||
return QString();
|
||||
}
|
||||
return QString();
|
||||
}
|
||||
|
||||
static void writeContainerFunctions(QXmlStreamWriter &xmlWriter, const QString &name, int extra, const QList<struct CppcheckLibraryData::Container::Function> &functions)
|
||||
|
|
|
@ -99,9 +99,8 @@ QStringList FileList::getFileList() const
|
|||
names << name;
|
||||
}
|
||||
return names;
|
||||
} else {
|
||||
return applyExcludeList();
|
||||
}
|
||||
return applyExcludeList();
|
||||
}
|
||||
|
||||
void FileList::addExcludeList(const QStringList &paths)
|
||||
|
|
|
@ -2002,7 +2002,7 @@ static int getVersion(const QString& nameWithVersion) {
|
|||
for (const auto c: nameWithVersion) {
|
||||
if (c == '\n' || c == '\r')
|
||||
break;
|
||||
else if (c == ' ') {
|
||||
if (c == ' ') {
|
||||
if (ret > 0 && dot == 1 && nameWithVersion.endsWith(" dev"))
|
||||
return ret * 1000000 + v * 1000 + 500;
|
||||
dot = ret = v = 0;
|
||||
|
|
|
@ -182,10 +182,7 @@ int TranslationHandler::getLanguageIndexByCode(const QString &code) const
|
|||
{
|
||||
int index = -1;
|
||||
for (int i = 0; i < mTranslations.size(); i++) {
|
||||
if (mTranslations[i].mCode == code) {
|
||||
index = i;
|
||||
break;
|
||||
} else if (mTranslations[i].mCode == code.left(2)) {
|
||||
if (mTranslations[i].mCode == code || mTranslations[i].mCode == code.left(2)) {
|
||||
index = i;
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -75,8 +75,8 @@ int XmlReport::determineVersion(const QString &filename)
|
|||
if (attribs.hasAttribute(QString(VersionAttribute))) {
|
||||
const int ver = attribs.value(QString(), VersionAttribute).toString().toInt();
|
||||
return ver;
|
||||
} else
|
||||
return 1;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
|
||||
|
|
|
@ -80,11 +80,10 @@ static int findArgumentPosRecursive(const Token* tok, const Token* tokToFind, b
|
|||
if (res == -1)
|
||||
return -1;
|
||||
return argn + res;
|
||||
} else {
|
||||
if (tokToFind == tok)
|
||||
found = true;
|
||||
return 1;
|
||||
}
|
||||
if (tokToFind == tok)
|
||||
found = true;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int findArgumentPos(const Token* tok, const Token* tokToFind){
|
||||
|
@ -142,8 +141,7 @@ nonneg int astCount(const Token* tok, const char* op, int depth)
|
|||
return 0;
|
||||
if (tok->str() == op)
|
||||
return astCount(tok->astOperand1(), op, depth) + astCount(tok->astOperand2(), op, depth);
|
||||
else
|
||||
return 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
bool astHasToken(const Token* root, const Token * tok)
|
||||
|
@ -439,16 +437,15 @@ bool isTemporary(bool cpp, const Token* tok, const Library* library, bool unknow
|
|||
ftok = tok->previous();
|
||||
if (!ftok)
|
||||
return false;
|
||||
if (const Function * f = ftok->function()) {
|
||||
if (const Function * f = ftok->function())
|
||||
return !Function::returnsReference(f, true);
|
||||
} else if (ftok->type()) {
|
||||
if (ftok->type())
|
||||
return true;
|
||||
} else if (library) {
|
||||
if (library) {
|
||||
std::string returnType = library->returnValueType(ftok);
|
||||
return !returnType.empty() && returnType.back() != '&';
|
||||
} else {
|
||||
return unknown;
|
||||
}
|
||||
return unknown;
|
||||
}
|
||||
if (tok->isCast())
|
||||
return false;
|
||||
|
@ -621,11 +618,9 @@ const Token* getParentLifetime(bool cpp, const Token* tok, const Library* librar
|
|||
// Find the first local variable or temporary
|
||||
auto it = std::find_if(members.crbegin(), members.crend(), [&](const Token* tok2) {
|
||||
const Variable* var = tok2->variable();
|
||||
if (var) {
|
||||
if (var)
|
||||
return var->isLocal() || var->isArgument();
|
||||
} else {
|
||||
return isTemporary(cpp, tok2, library);
|
||||
}
|
||||
return isTemporary(cpp, tok2, library);
|
||||
});
|
||||
if (it == members.rend())
|
||||
return tok;
|
||||
|
@ -688,7 +683,8 @@ std::vector<ValueType> getParentValueTypes(const Token* tok, const Settings* set
|
|||
if (tok->astParent()->astOperand1()->valueType())
|
||||
return {*tok->astParent()->astOperand1()->valueType()};
|
||||
return {};
|
||||
} else if (Token::Match(tok->astParent(), "(|{|,")) {
|
||||
}
|
||||
if (Token::Match(tok->astParent(), "(|{|,")) {
|
||||
int argn = -1;
|
||||
const Token* ftok = getTokenArgumentFunction(tok, argn);
|
||||
const Token* typeTok = nullptr;
|
||||
|
@ -708,7 +704,8 @@ std::vector<ValueType> getParentValueTypes(const Token* tok, const Settings* set
|
|||
*parent = nameTok;
|
||||
}
|
||||
return result;
|
||||
} else if (const Type* t = Token::typeOf(ftok, &typeTok)) {
|
||||
}
|
||||
if (const Type* t = Token::typeOf(ftok, &typeTok)) {
|
||||
if (astIsPointer(typeTok))
|
||||
return {*typeTok->valueType()};
|
||||
const Scope* scope = t->classScope;
|
||||
|
@ -790,11 +787,10 @@ static T* getCondTokFromEndImpl(T* endBlock)
|
|||
T* startBlock = endBlock->link();
|
||||
if (!Token::simpleMatch(startBlock, "{"))
|
||||
return nullptr;
|
||||
if (Token::simpleMatch(startBlock->previous(), ")")) {
|
||||
if (Token::simpleMatch(startBlock->previous(), ")"))
|
||||
return getCondTok(startBlock->previous()->link());
|
||||
} else if (Token::simpleMatch(startBlock->tokAt(-2), "} else {")) {
|
||||
if (Token::simpleMatch(startBlock->tokAt(-2), "} else {"))
|
||||
return getCondTokFromEnd(startBlock->tokAt(-2));
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
@ -1058,7 +1054,8 @@ bool exprDependsOnThis(const Token* expr, bool onVar, nonneg int depth)
|
|||
if (classScope && classScope->isClassOrStruct())
|
||||
return contains(classScope->findAssociatedScopes(), expr->function()->nestedIn);
|
||||
return false;
|
||||
} else if (onVar && expr->variable()) {
|
||||
}
|
||||
if (onVar && expr->variable()) {
|
||||
const Variable* var = expr->variable();
|
||||
return ((var->isPrivate() || var->isPublic() || var->isProtected()) && !var->isStatic());
|
||||
}
|
||||
|
@ -1186,7 +1183,8 @@ SmallVector<ReferenceToken> followAllReferences(const Token* tok,
|
|||
if (var->nameToken() == tok || isStructuredBindingVariable(var)) {
|
||||
refs_result.push_back({tok, std::move(errors)});
|
||||
return refs_result;
|
||||
} else if (var->isReference() || var->isRValueReference()) {
|
||||
}
|
||||
if (var->isReference() || var->isRValueReference()) {
|
||||
const Token * const varDeclEndToken = var->declEndToken();
|
||||
if (!varDeclEndToken) {
|
||||
refs_result.push_back({tok, std::move(errors)});
|
||||
|
@ -1196,7 +1194,8 @@ SmallVector<ReferenceToken> followAllReferences(const Token* tok,
|
|||
errors.emplace_back(varDeclEndToken, "Passed to reference.");
|
||||
refs_result.push_back({tok, std::move(errors)});
|
||||
return refs_result;
|
||||
} else if (Token::simpleMatch(varDeclEndToken, "=")) {
|
||||
}
|
||||
if (Token::simpleMatch(varDeclEndToken, "=")) {
|
||||
if (astHasToken(varDeclEndToken, tok))
|
||||
return refs_result;
|
||||
errors.emplace_back(varDeclEndToken, "Assigned to reference.");
|
||||
|
@ -1826,7 +1825,7 @@ bool isOppositeCond(bool isNot, bool cpp, const Token * const cond1, const Token
|
|||
|
||||
if (op1 == "<" || op1 == "<=")
|
||||
return (op2 == "==" || op2 == ">" || op2 == ">=") && (rhsValue1.intvalue < rhsValue2.intvalue);
|
||||
else if (op1 == ">=" || op1 == ">")
|
||||
if (op1 == ">=" || op1 == ">")
|
||||
return (op2 == "==" || op2 == "<" || op2 == "<=") && (rhsValue1.intvalue > rhsValue2.intvalue);
|
||||
|
||||
return false;
|
||||
|
@ -1903,9 +1902,9 @@ bool isConstFunctionCall(const Token* ftok, const Library& library)
|
|||
return true;
|
||||
}
|
||||
return false;
|
||||
} else if (f->argumentList.empty()) {
|
||||
return f->isConstexpr();
|
||||
}
|
||||
if (f->argumentList.empty())
|
||||
return f->isConstexpr();
|
||||
} else if (Token::Match(ftok->previous(), ". %name% (") && ftok->previous()->originalName() != "->" &&
|
||||
astIsSmartPointer(ftok->previous()->astOperand1())) {
|
||||
return Token::Match(ftok, "get|get_deleter ( )");
|
||||
|
@ -2040,8 +2039,7 @@ static bool isEscaped(const Token* tok, bool functionsScope, const Library* libr
|
|||
return true;
|
||||
if (functionsScope)
|
||||
return Token::simpleMatch(tok, "throw");
|
||||
else
|
||||
return Token::Match(tok, "return|throw");
|
||||
return Token::Match(tok, "return|throw");
|
||||
}
|
||||
|
||||
static bool isEscapedOrJump(const Token* tok, bool functionsScope, const Library* library)
|
||||
|
@ -2050,8 +2048,7 @@ static bool isEscapedOrJump(const Token* tok, bool functionsScope, const Library
|
|||
return true;
|
||||
if (functionsScope)
|
||||
return Token::simpleMatch(tok, "throw");
|
||||
else
|
||||
return Token::Match(tok, "return|goto|throw|continue|break");
|
||||
return Token::Match(tok, "return|goto|throw|continue|break");
|
||||
}
|
||||
|
||||
bool isEscapeFunction(const Token* ftok, const Library* library)
|
||||
|
@ -2093,7 +2090,8 @@ static bool hasNoreturnFunction(const Token* tok, const Library* library, const
|
|||
if (unknownFunc && !function && library && library->functions.count(library->getFunctionName(ftok)) == 0)
|
||||
*unknownFunc = ftok;
|
||||
return false;
|
||||
} else if (tok->isConstOp()) {
|
||||
}
|
||||
if (tok->isConstOp()) {
|
||||
return hasNoreturnFunction(tok->astOperand1(), library, unknownFunc) || hasNoreturnFunction(tok->astOperand2(), library, unknownFunc);
|
||||
}
|
||||
|
||||
|
@ -2273,8 +2271,7 @@ std::vector<const Variable*> getArgumentVars(const Token* tok, int argnr)
|
|||
const Variable* argvar = tok->function()->getArgumentVar(argnr);
|
||||
if (argvar)
|
||||
return {argvar};
|
||||
else
|
||||
return result;
|
||||
return result;
|
||||
}
|
||||
if (tok->variable() || Token::simpleMatch(tok, "{") || Token::Match(tok->previous(), "%type% (|{")) {
|
||||
const Type* type = Token::typeOf(tok);
|
||||
|
@ -2526,18 +2523,20 @@ bool isVariableChanged(const Token *tok, int indirect, const Settings *settings,
|
|||
return true;
|
||||
const Library::Container::Yield yield = c->getYield(ftok->str());
|
||||
// If accessing element check if the element is changed
|
||||
if (contains({Library::Container::Yield::ITEM, Library::Container::Yield::AT_INDEX}, yield)) {
|
||||
if (contains({Library::Container::Yield::ITEM, Library::Container::Yield::AT_INDEX}, yield))
|
||||
return isVariableChanged(ftok->next(), indirect, settings, cpp, depth - 1);
|
||||
} else if (contains({Library::Container::Yield::BUFFER,
|
||||
Library::Container::Yield::BUFFER_NT,
|
||||
Library::Container::Yield::START_ITERATOR,
|
||||
Library::Container::Yield::ITERATOR},
|
||||
yield)) {
|
||||
|
||||
if (contains({Library::Container::Yield::BUFFER,
|
||||
Library::Container::Yield::BUFFER_NT,
|
||||
Library::Container::Yield::START_ITERATOR,
|
||||
Library::Container::Yield::ITERATOR},
|
||||
yield)) {
|
||||
return isVariableChanged(ftok->next(), indirect + 1, settings, cpp, depth - 1);
|
||||
} else if (contains({Library::Container::Yield::SIZE,
|
||||
Library::Container::Yield::EMPTY,
|
||||
Library::Container::Yield::END_ITERATOR},
|
||||
yield)) {
|
||||
}
|
||||
if (contains({Library::Container::Yield::SIZE,
|
||||
Library::Container::Yield::EMPTY,
|
||||
Library::Container::Yield::END_ITERATOR},
|
||||
yield)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -2789,7 +2788,8 @@ bool isThisChanged(const Token* tok, int indirect, const Settings* settings, boo
|
|||
Token::Match(tok->tokAt(-3), "this . %name% (")) {
|
||||
if (tok->previous()->function()) {
|
||||
return (!tok->previous()->function()->isConst() && !tok->previous()->function()->isStatic());
|
||||
} else if (!tok->previous()->isKeyword()) {
|
||||
}
|
||||
if (!tok->previous()->isKeyword()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -3276,17 +3276,20 @@ bool isGlobalData(const Token *expr, bool cpp)
|
|||
// TODO check if pointer points at local data
|
||||
globalData = true;
|
||||
return ChildrenToVisit::none;
|
||||
} else if (Token::Match(tok, "[*[]") && tok->astOperand1() && tok->astOperand1()->variable()) {
|
||||
}
|
||||
if (Token::Match(tok, "[*[]") && tok->astOperand1() && tok->astOperand1()->variable()) {
|
||||
// TODO check if pointer points at local data
|
||||
const Variable *lhsvar = tok->astOperand1()->variable();
|
||||
const ValueType *lhstype = tok->astOperand1()->valueType();
|
||||
if (lhsvar->isPointer()) {
|
||||
globalData = true;
|
||||
return ChildrenToVisit::none;
|
||||
} else if (lhsvar->isArgument() && lhsvar->isArray()) {
|
||||
}
|
||||
if (lhsvar->isArgument() && lhsvar->isArray()) {
|
||||
globalData = true;
|
||||
return ChildrenToVisit::none;
|
||||
} else if (lhsvar->isArgument() && (!lhstype || (lhstype->type <= ValueType::Type::VOID && !lhstype->container))) {
|
||||
}
|
||||
if (lhsvar->isArgument() && (!lhstype || (lhstype->type <= ValueType::Type::VOID && !lhstype->container))) {
|
||||
globalData = true;
|
||||
return ChildrenToVisit::none;
|
||||
}
|
||||
|
|
|
@ -555,7 +555,8 @@ void CheckAutoVariables::checkVarLifetimeScope(const Token * start, const Token
|
|||
isInScope(var->nameToken(), tok->scope())) {
|
||||
errorReturnReference(tok, lt.errorPath, lt.inconclusive);
|
||||
break;
|
||||
} else if (isDeadTemporary(mTokenizer->isCPP(), lt.token, nullptr, &mSettings->library)) {
|
||||
}
|
||||
if (isDeadTemporary(mTokenizer->isCPP(), lt.token, nullptr, &mSettings->library)) {
|
||||
errorReturnTempReference(tok, lt.errorPath, lt.inconclusive);
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -1074,8 +1074,7 @@ void CheckBufferOverrun::objectIndex()
|
|||
if (std::any_of(idxValues.cbegin(), idxValues.cend(), [&](const ValueFlow::Value& vidx) {
|
||||
if (vidx.isImpossible())
|
||||
return (vidx.intvalue == 0);
|
||||
else
|
||||
return (vidx.intvalue != 0);
|
||||
return (vidx.intvalue != 0);
|
||||
})) {
|
||||
objectIndexError(tok, &v, idx->hasKnownIntValue());
|
||||
}
|
||||
|
|
|
@ -585,7 +585,8 @@ bool CheckClass::canNotCopy(const Scope *scope)
|
|||
if (func.type == Function::eCopyConstructor) {
|
||||
publicCopy = true;
|
||||
break;
|
||||
} else if (func.type == Function::eOperatorEqual) {
|
||||
}
|
||||
if (func.type == Function::eOperatorEqual) {
|
||||
publicAssign = true;
|
||||
break;
|
||||
}
|
||||
|
@ -609,10 +610,12 @@ bool CheckClass::canNotMove(const Scope *scope)
|
|||
if (func.type == Function::eCopyConstructor) {
|
||||
publicCopy = true;
|
||||
break;
|
||||
} else if (func.type == Function::eMoveConstructor) {
|
||||
}
|
||||
if (func.type == Function::eMoveConstructor) {
|
||||
publicMove = true;
|
||||
break;
|
||||
} else if (func.type == Function::eOperatorEqual) {
|
||||
}
|
||||
if (func.type == Function::eOperatorEqual) {
|
||||
publicAssign = true;
|
||||
break;
|
||||
}
|
||||
|
@ -874,7 +877,7 @@ void CheckClass::initializeVarList(const Function &func, std::list<const Functio
|
|||
}
|
||||
|
||||
// Ticket #7068
|
||||
else if (Token::Match(ftok, "::| memset ( &| this . %name%")) {
|
||||
if (Token::Match(ftok, "::| memset ( &| this . %name%")) {
|
||||
if (ftok->str() == "::")
|
||||
ftok = ftok->next();
|
||||
int offsetToMember = 4;
|
||||
|
@ -886,7 +889,7 @@ void CheckClass::initializeVarList(const Function &func, std::list<const Functio
|
|||
}
|
||||
|
||||
// Clearing array..
|
||||
else if (Token::Match(ftok, "::| memset ( %name% ,")) {
|
||||
if (Token::Match(ftok, "::| memset ( %name% ,")) {
|
||||
if (ftok->str() == "::")
|
||||
ftok = ftok->next();
|
||||
assignVar(usage, ftok->tokAt(2)->varId());
|
||||
|
@ -895,7 +898,7 @@ void CheckClass::initializeVarList(const Function &func, std::list<const Functio
|
|||
}
|
||||
|
||||
// Calling member function?
|
||||
else if (Token::simpleMatch(ftok, "operator= (")) {
|
||||
if (Token::simpleMatch(ftok, "operator= (")) {
|
||||
if (ftok->function()) {
|
||||
const Function *member = ftok->function();
|
||||
// recursive call
|
||||
|
@ -1164,7 +1167,8 @@ void CheckClass::initializationListUsage()
|
|||
if (var2->scope() == owner && tok2->strAt(-1)!=".") { // Is there a dependency between two member variables?
|
||||
allowed = false;
|
||||
return ChildrenToVisit::done;
|
||||
} else if (var2->isArray() && var2->isLocal()) { // Can't initialize with a local array
|
||||
}
|
||||
if (var2->isArray() && var2->isLocal()) { // Can't initialize with a local array
|
||||
allowed = false;
|
||||
return ChildrenToVisit::done;
|
||||
}
|
||||
|
@ -2158,11 +2162,11 @@ bool CheckClass::isMemberVar(const Scope *scope, const Token *tok) const
|
|||
do {
|
||||
again = false;
|
||||
|
||||
if (tok->str() == "this") {
|
||||
if (tok->str() == "this")
|
||||
return !getFuncTokFromThis(tok); // function calls are handled elsewhere
|
||||
} else if (Token::simpleMatch(tok->tokAt(-3), "( * this )")) {
|
||||
if (Token::simpleMatch(tok->tokAt(-3), "( * this )"))
|
||||
return true;
|
||||
} else if (Token::Match(tok->tokAt(-3), "%name% ) . %name%")) {
|
||||
if (Token::Match(tok->tokAt(-3), "%name% ) . %name%")) {
|
||||
tok = tok->tokAt(-3);
|
||||
again = true;
|
||||
} else if (Token::Match(tok->tokAt(-2), "%name% . %name%")) {
|
||||
|
@ -2394,7 +2398,7 @@ bool CheckClass::checkConstFunc(const Scope *scope, const Function *func, Member
|
|||
if (top->isAssignmentOp()) {
|
||||
if (Token::simpleMatch(top->astOperand2(), "{") && !top->astOperand2()->previous()->function()) // TODO: check usage in init list
|
||||
return false;
|
||||
else if (top->previous()->variable()) {
|
||||
if (top->previous()->variable()) {
|
||||
if (top->previous()->variable()->typeStartToken()->strAt(-1) != "const" && top->previous()->variable()->isPointer())
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -576,9 +576,9 @@ static bool isNonConstFunctionCall(const Token *ftok, const Library &library)
|
|||
obj = obj->astOperand1();
|
||||
if (!obj)
|
||||
return true;
|
||||
else if (obj->variable() && obj->variable()->isConst())
|
||||
if (obj->variable() && obj->variable()->isConst())
|
||||
return false;
|
||||
else if (ftok->function() && ftok->function()->isConst())
|
||||
if (ftok->function() && ftok->function()->isConst())
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
@ -968,8 +968,7 @@ T getvalue3(const T value1, const T value2)
|
|||
const T min = std::min(value1, value2);
|
||||
if (min== std::numeric_limits<T>::max())
|
||||
return min;
|
||||
else
|
||||
return min+1; // see #5895
|
||||
return min + 1; // see #5895
|
||||
}
|
||||
|
||||
template<>
|
||||
|
@ -1145,7 +1144,8 @@ void CheckCondition::checkIncorrectLogicOperator()
|
|||
"The condition '" + cond1VerboseMsg + "' is equivalent to '" + cond2VerboseMsg + "'.";
|
||||
redundantConditionError(tok, msg, false);
|
||||
continue;
|
||||
} else if (isSameExpression(mTokenizer->isCPP(), false, tok->astOperand1(), tok2, mSettings->library, true, true)) {
|
||||
}
|
||||
if (isSameExpression(mTokenizer->isCPP(), false, tok->astOperand1(), tok2, mSettings->library, true, true)) {
|
||||
std::string expr1(tok->astOperand1()->expressionString());
|
||||
std::string expr2(tok->astOperand2()->astOperand1()->expressionString());
|
||||
std::string expr3(tok->astOperand2()->astOperand2()->expressionString());
|
||||
|
|
|
@ -246,19 +246,18 @@ static const Token * functionThrowsRecursive(const Function * function, std::set
|
|||
tok != function->functionScope->bodyEnd; tok = tok->next()) {
|
||||
if (Token::simpleMatch(tok, "try {"))
|
||||
tok = tok->linkAt(1); // skip till start of catch clauses
|
||||
if (tok->str() == "throw") {
|
||||
if (tok->str() == "throw")
|
||||
return tok;
|
||||
} else if (tok->function()) {
|
||||
if (tok->function()) {
|
||||
const Function * called = tok->function();
|
||||
// check if called function has an exception specification
|
||||
if (called->isThrow() && called->throwArg) {
|
||||
if (called->isThrow() && called->throwArg)
|
||||
return tok;
|
||||
} else if (called->isNoExcept() && called->noexceptArg &&
|
||||
called->noexceptArg->str() != "true") {
|
||||
if (called->isNoExcept() && called->noexceptArg &&
|
||||
called->noexceptArg->str() != "true")
|
||||
return tok;
|
||||
} else if (functionThrowsRecursive(called, recursive)) {
|
||||
if (functionThrowsRecursive(called, recursive))
|
||||
return tok;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -330,9 +329,9 @@ void CheckExceptionSafety::unhandledExceptionSpecification()
|
|||
if (scope->function && !scope->function->isThrow() && !mSettings->library.isentrypoint(scope->className)) {
|
||||
for (const Token *tok = scope->function->functionScope->bodyStart->next();
|
||||
tok != scope->function->functionScope->bodyEnd; tok = tok->next()) {
|
||||
if (tok->str() == "try") {
|
||||
if (tok->str() == "try")
|
||||
break;
|
||||
} else if (tok->function()) {
|
||||
if (tok->function()) {
|
||||
const Function * called = tok->function();
|
||||
// check if called function has an exception specification
|
||||
if (called->isThrow() && called->throwArg) {
|
||||
|
|
|
@ -62,7 +62,7 @@ void CheckInternal::checkTokenMatchPatterns()
|
|||
// Check for signs of complex patterns
|
||||
if (pattern.find_first_of("[|") != std::string::npos)
|
||||
continue;
|
||||
else if (pattern.find("!!") != std::string::npos)
|
||||
if (pattern.find("!!") != std::string::npos)
|
||||
continue;
|
||||
|
||||
bool complex = false;
|
||||
|
|
|
@ -97,9 +97,9 @@ static OpenMode getMode(const std::string& str)
|
|||
{
|
||||
if (str.find('+', 1) != std::string::npos)
|
||||
return OpenMode::RW_MODE;
|
||||
else if (str.find('w') != std::string::npos || str.find('a') != std::string::npos)
|
||||
if (str.find('w') != std::string::npos || str.find('a') != std::string::npos)
|
||||
return OpenMode::WRITE_MODE;
|
||||
else if (str.find('r') != std::string::npos)
|
||||
if (str.find('r') != std::string::npos)
|
||||
return OpenMode::READ_MODE;
|
||||
return OpenMode::UNKNOWN_OM;
|
||||
}
|
||||
|
@ -488,13 +488,14 @@ static bool findFormat(nonneg int arg, const Token *firstArg,
|
|||
*formatArgTok = argTok->nextArgument();
|
||||
*formatStringTok = argTok;
|
||||
return true;
|
||||
} else if (Token::Match(argTok, "%var% [,)]") &&
|
||||
argTok->variable() &&
|
||||
Token::Match(argTok->variable()->typeStartToken(), "char|wchar_t") &&
|
||||
(argTok->variable()->isPointer() ||
|
||||
(argTok->variable()->dimensions().size() == 1 &&
|
||||
argTok->variable()->dimensionKnown(0) &&
|
||||
argTok->variable()->dimension(0) != 0))) {
|
||||
}
|
||||
if (Token::Match(argTok, "%var% [,)]") &&
|
||||
argTok->variable() &&
|
||||
Token::Match(argTok->variable()->typeStartToken(), "char|wchar_t") &&
|
||||
(argTok->variable()->isPointer() ||
|
||||
(argTok->variable()->dimensions().size() == 1 &&
|
||||
argTok->variable()->dimensionKnown(0) &&
|
||||
argTok->variable()->dimension(0) != 0))) {
|
||||
*formatArgTok = argTok->nextArgument();
|
||||
if (!argTok->values().empty()) {
|
||||
const std::list<ValueFlow::Value>::const_iterator value = std::find_if(
|
||||
|
@ -1402,11 +1403,12 @@ CheckIO::ArgumentInfo::ArgumentInfo(const Token * arg, const Settings *settings,
|
|||
if (arg->tokType() == Token::eString) {
|
||||
typeToken = arg;
|
||||
return;
|
||||
} else if (arg->str() == "&" || arg->tokType() == Token::eVariable ||
|
||||
arg->tokType() == Token::eFunction || Token::Match(arg, "%type% ::") ||
|
||||
(Token::Match(arg, "static_cast|reinterpret_cast|const_cast <") &&
|
||||
Token::simpleMatch(arg->linkAt(1), "> (") &&
|
||||
Token::Match(arg->linkAt(1)->linkAt(1), ") ,|)"))) {
|
||||
}
|
||||
if (arg->str() == "&" || arg->tokType() == Token::eVariable ||
|
||||
arg->tokType() == Token::eFunction || Token::Match(arg, "%type% ::") ||
|
||||
(Token::Match(arg, "static_cast|reinterpret_cast|const_cast <") &&
|
||||
Token::simpleMatch(arg->linkAt(1), "> (") &&
|
||||
Token::Match(arg->linkAt(1)->linkAt(1), ") ,|)"))) {
|
||||
if (Token::Match(arg, "static_cast|reinterpret_cast|const_cast")) {
|
||||
typeToken = arg->tokAt(2);
|
||||
while (typeToken->str() == "const" || typeToken->str() == "extern")
|
||||
|
@ -1471,7 +1473,8 @@ CheckIO::ArgumentInfo::ArgumentInfo(const Token * arg, const Settings *settings,
|
|||
} else
|
||||
varTok = tok1->previous();
|
||||
break;
|
||||
} else if (tok1->str() == "(" || tok1->str() == "{" || tok1->str() == "[")
|
||||
}
|
||||
if (tok1->str() == "(" || tok1->str() == "{" || tok1->str() == "[")
|
||||
tok1 = tok1->link();
|
||||
else if (tok1->link() && tok1->str() == "<")
|
||||
tok1 = tok1->link();
|
||||
|
@ -1578,7 +1581,8 @@ bool CheckIO::ArgumentInfo::isStdVectorOrString()
|
|||
typeToken = variableInfo->typeStartToken()->tokAt(4);
|
||||
_template = true;
|
||||
return true;
|
||||
} else if (variableInfo->isStlType(stl_string)) {
|
||||
}
|
||||
if (variableInfo->isStlType(stl_string)) {
|
||||
tempToken = new Token();
|
||||
tempToken->fileIndex(variableInfo->typeStartToken()->fileIndex());
|
||||
tempToken->linenr(variableInfo->typeStartToken()->linenr());
|
||||
|
@ -1588,7 +1592,8 @@ bool CheckIO::ArgumentInfo::isStdVectorOrString()
|
|||
tempToken->str("wchar_t");
|
||||
typeToken = tempToken;
|
||||
return true;
|
||||
} else if (variableInfo->type() && !variableInfo->type()->derivedFrom.empty()) {
|
||||
}
|
||||
if (variableInfo->type() && !variableInfo->type()->derivedFrom.empty()) {
|
||||
const std::vector<Type::BaseInfo>& derivedFrom = variableInfo->type()->derivedFrom;
|
||||
for (const Type::BaseInfo & i : derivedFrom) {
|
||||
const Token* nameTok = i.nameTok;
|
||||
|
@ -1596,7 +1601,8 @@ bool CheckIO::ArgumentInfo::isStdVectorOrString()
|
|||
typeToken = nameTok->tokAt(4);
|
||||
_template = true;
|
||||
return true;
|
||||
} else if (Token::Match(nameTok, "std :: string|wstring")) {
|
||||
}
|
||||
if (Token::Match(nameTok, "std :: string|wstring")) {
|
||||
tempToken = new Token();
|
||||
tempToken->fileIndex(variableInfo->typeStartToken()->fileIndex());
|
||||
tempToken->linenr(variableInfo->typeStartToken()->linenr());
|
||||
|
@ -1642,16 +1648,19 @@ bool CheckIO::ArgumentInfo::isStdContainer(const Token *tok)
|
|||
if (variable->isStlType(stl_container)) {
|
||||
typeToken = variable->typeStartToken()->tokAt(4);
|
||||
return true;
|
||||
} else if (variable->isStlType(stl_string)) {
|
||||
}
|
||||
if (variable->isStlType(stl_string)) {
|
||||
typeToken = variable->typeStartToken();
|
||||
return true;
|
||||
} else if (variable->type() && !variable->type()->derivedFrom.empty()) {
|
||||
}
|
||||
if (variable->type() && !variable->type()->derivedFrom.empty()) {
|
||||
for (const Type::BaseInfo &baseInfo : variable->type()->derivedFrom) {
|
||||
const Token* nameTok = baseInfo.nameTok;
|
||||
if (Token::Match(nameTok, "std :: vector|array|bitset|deque|list|forward_list|map|multimap|multiset|priority_queue|queue|set|stack|hash_map|hash_multimap|hash_set|unordered_map|unordered_multimap|unordered_set|unordered_multiset <")) {
|
||||
typeToken = nameTok->tokAt(4);
|
||||
return true;
|
||||
} else if (Token::Match(nameTok, "std :: string|wstring")) {
|
||||
}
|
||||
if (Token::Match(nameTok, "std :: string|wstring")) {
|
||||
typeToken = nameTok;
|
||||
return true;
|
||||
}
|
||||
|
@ -1666,16 +1675,13 @@ bool CheckIO::ArgumentInfo::isArrayOrPointer() const
|
|||
{
|
||||
if (address)
|
||||
return true;
|
||||
else if (variableInfo && !_template) {
|
||||
if (variableInfo && !_template)
|
||||
return variableInfo->isArrayOrPointer();
|
||||
} else {
|
||||
const Token *tok = typeToken;
|
||||
while (Token::Match(tok, "const|struct"))
|
||||
tok = tok->next();
|
||||
if (tok && tok->strAt(1) == "*")
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
||||
const Token *tok = typeToken;
|
||||
while (Token::Match(tok, "const|struct"))
|
||||
tok = tok->next();
|
||||
return tok && tok->strAt(1) == "*";
|
||||
}
|
||||
|
||||
bool CheckIO::ArgumentInfo::isComplexType() const
|
||||
|
@ -1694,7 +1700,7 @@ bool CheckIO::ArgumentInfo::isKnownType() const
|
|||
{
|
||||
if (variableInfo)
|
||||
return (typeToken->isStandardType() || typeToken->next()->isStandardType() || isComplexType());
|
||||
else if (functionInfo)
|
||||
if (functionInfo)
|
||||
return (typeToken->isStandardType() || functionInfo->retType || Token::Match(typeToken, "std :: string|wstring"));
|
||||
|
||||
return typeToken->isStandardType() || Token::Match(typeToken, "std :: string|wstring");
|
||||
|
|
|
@ -509,7 +509,8 @@ bool CheckLeakAutoVar::checkScope(const Token * const startToken,
|
|||
}
|
||||
if (tok3->str() == "(" && Token::Match(tok3->astOperand1(), "UNLIKELY|LIKELY")) {
|
||||
return ChildrenToVisit::op2;
|
||||
} else if (tok3->str() == "(" && tok3->previous()->isName()) {
|
||||
}
|
||||
if (tok3->str() == "(" && tok3->previous()->isName()) {
|
||||
const std::vector<const Token *> params = getArguments(tok3->previous());
|
||||
for (const Token *par : params) {
|
||||
if (!par->isComparisonOp())
|
||||
|
|
|
@ -700,11 +700,10 @@ bool CheckMemoryLeakStructMember::isMalloc(const Variable *variable)
|
|||
const int declarationId(variable->declarationId());
|
||||
bool alloc = false;
|
||||
for (const Token *tok2 = variable->nameToken(); tok2 && tok2 != variable->scope()->bodyEnd; tok2 = tok2->next()) {
|
||||
if (Token::Match(tok2, "= %varid% [;=]", declarationId)) {
|
||||
if (Token::Match(tok2, "= %varid% [;=]", declarationId))
|
||||
return false;
|
||||
} else if (Token::Match(tok2, "%varid% = malloc|kmalloc (", declarationId)) {
|
||||
if (Token::Match(tok2, "%varid% = malloc|kmalloc (", declarationId)) // TODO use library
|
||||
alloc = true;
|
||||
}
|
||||
}
|
||||
return alloc;
|
||||
}
|
||||
|
|
|
@ -508,10 +508,9 @@ static std::string arithmeticTypeString(const Token *tok)
|
|||
{
|
||||
if (tok && tok->str()[0] == '-')
|
||||
return "subtraction";
|
||||
else if (tok && tok->str()[0] == '+')
|
||||
if (tok && tok->str()[0] == '+')
|
||||
return "addition";
|
||||
else
|
||||
return "arithmetic";
|
||||
return "arithmetic";
|
||||
}
|
||||
|
||||
void CheckNullPointer::pointerArithmeticError(const Token* tok, const ValueFlow::Value *value, bool inconclusive)
|
||||
|
|
|
@ -802,9 +802,9 @@ void CheckOther::checkUnreachableCode()
|
|||
if (Token::Match(silencedWarning, "( void ) %name% ;")) {
|
||||
silencedWarning = silencedWarning->tokAt(5);
|
||||
continue;
|
||||
} else if (silencedWarning && silencedWarning == scope->bodyEnd)
|
||||
}
|
||||
if (silencedWarning && silencedWarning == scope->bodyEnd)
|
||||
silencedCompilerWarningOnly = true;
|
||||
|
||||
break;
|
||||
}
|
||||
if (silencedWarning)
|
||||
|
@ -915,7 +915,8 @@ void CheckOther::checkVariableScope()
|
|||
if (tok->str() == "(") {
|
||||
forHead = true;
|
||||
break;
|
||||
} else if (Token::Match(tok, "[;{}]"))
|
||||
}
|
||||
if (Token::Match(tok, "[;{}]"))
|
||||
break;
|
||||
}
|
||||
if (forHead)
|
||||
|
@ -1286,8 +1287,7 @@ static bool canBeConst(const Variable *var, const Settings* settings)
|
|||
const Function* func = tok2->tokAt(2)->function();
|
||||
if (func && (func->isConst() || func->isStatic()))
|
||||
continue;
|
||||
else
|
||||
return false;
|
||||
return false;
|
||||
} else if (isConstRangeBasedFor(tok2))
|
||||
continue;
|
||||
else
|
||||
|
@ -1395,10 +1395,8 @@ static bool isVariableMutableInInitializer(const Token* start, const Token * end
|
|||
if (memberVar->isConst())
|
||||
continue;
|
||||
}
|
||||
return true;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@ -1630,11 +1628,11 @@ void CheckOther::checkConstPointer()
|
|||
int argn = -1;
|
||||
if (Token::Match(parent, "%oror%|%comp%|&&|?|!|-"))
|
||||
continue;
|
||||
else if (Token::simpleMatch(parent, "(") && Token::Match(parent->astOperand1(), "if|while"))
|
||||
if (Token::simpleMatch(parent, "(") && Token::Match(parent->astOperand1(), "if|while"))
|
||||
continue;
|
||||
else if (Token::simpleMatch(parent, "=") && parent->astOperand1() == tok)
|
||||
if (Token::simpleMatch(parent, "=") && parent->astOperand1() == tok)
|
||||
continue;
|
||||
else if (const Token* ftok = getTokenArgumentFunction(tok, argn)) {
|
||||
if (const Token* ftok = getTokenArgumentFunction(tok, argn)) {
|
||||
if (ftok->function() && !parent->isCast()) {
|
||||
const Variable* argVar = ftok->function()->getArgumentVar(argn);
|
||||
if (argVar && argVar->valueType() && argVar->valueType()->isConst(vt->pointer)) {
|
||||
|
@ -1863,22 +1861,21 @@ static bool isConstStatement(const Token *tok, bool cpp)
|
|||
return false;
|
||||
return isWithoutSideEffects(cpp, tok) && isConstStatement(tok->astOperand2(), cpp);
|
||||
}
|
||||
else if (tok->isCast() && tok->next() && tok->next()->isStandardType())
|
||||
if (tok->isCast() && tok->next() && tok->next()->isStandardType())
|
||||
return isWithoutSideEffects(cpp, tok->astOperand1()) && isConstStatement(tok->astOperand1(), cpp);
|
||||
if (Token::simpleMatch(tok, "."))
|
||||
return isConstStatement(tok->astOperand2(), cpp);
|
||||
if (Token::simpleMatch(tok, ",")) {
|
||||
if (tok->astParent()) // warn about const statement on rhs at the top level
|
||||
return isConstStatement(tok->astOperand1(), cpp) && isConstStatement(tok->astOperand2(), cpp);
|
||||
else {
|
||||
const Token* lml = previousBeforeAstLeftmostLeaf(tok); // don't warn about matrix/vector assignment (e.g. Eigen)
|
||||
if (lml)
|
||||
lml = lml->next();
|
||||
const Token* stream = lml;
|
||||
while (stream && Token::Match(stream->astParent(), ".|[|(|*"))
|
||||
stream = stream->astParent();
|
||||
return (!stream || !isLikelyStream(cpp, stream)) && isConstStatement(tok->astOperand2(), cpp);
|
||||
}
|
||||
|
||||
const Token* lml = previousBeforeAstLeftmostLeaf(tok); // don't warn about matrix/vector assignment (e.g. Eigen)
|
||||
if (lml)
|
||||
lml = lml->next();
|
||||
const Token* stream = lml;
|
||||
while (stream && Token::Match(stream->astParent(), ".|[|(|*"))
|
||||
stream = stream->astParent();
|
||||
return (!stream || !isLikelyStream(cpp, stream)) && isConstStatement(tok->astOperand2(), cpp);
|
||||
}
|
||||
if (Token::simpleMatch(tok, "?") && Token::simpleMatch(tok->astOperand2(), ":")) // ternary operator
|
||||
return isConstStatement(tok->astOperand1(), cpp) && isConstStatement(tok->astOperand2()->astOperand1(), cpp) && isConstStatement(tok->astOperand2()->astOperand2(), cpp);
|
||||
|
@ -1916,8 +1913,7 @@ static bool isConstTop(const Token *tok)
|
|||
Token::Match(tok->astTop()->previous(), "for|if (") && Token::simpleMatch(tok->astTop()->astOperand2(), ";")) {
|
||||
if (Token::simpleMatch(tok->astParent()->astParent(), ";"))
|
||||
return tok->astParent()->astOperand2() == tok;
|
||||
else
|
||||
return tok->astParent()->astOperand1() == tok;
|
||||
return tok->astParent()->astOperand1() == tok;
|
||||
}
|
||||
if (Token::simpleMatch(tok, "[")) {
|
||||
const Token* bracTok = tok;
|
||||
|
|
|
@ -428,11 +428,10 @@ static bool isIterator(const Variable *var, bool& inconclusiveType)
|
|||
// look for operator* and operator++
|
||||
const Function* end = var->type()->getFunction("operator*");
|
||||
const Function* incOperator = var->type()->getFunction("operator++");
|
||||
if (!end || end->argCount() > 0 || !incOperator) {
|
||||
if (!end || end->argCount() > 0 || !incOperator)
|
||||
return false;
|
||||
} else {
|
||||
inconclusiveType = true; // heuristics only
|
||||
}
|
||||
|
||||
inconclusiveType = true; // heuristics only
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@ -1619,8 +1618,7 @@ static const Token *findInsertValue(const Token *tok, const Token *containerTok,
|
|||
isSameExpression(true, true, keyTok, ikeyTok, library, true, true)) {
|
||||
if (ivalueTok)
|
||||
return ivalueTok;
|
||||
else
|
||||
return ikeyTok;
|
||||
return ikeyTok;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -2031,7 +2029,8 @@ void CheckStl::string_c_str()
|
|||
search_tok->next()->variable() && search_tok->next()->variable()->isStlStringType()) {
|
||||
is_implicit_std_string = true;
|
||||
break;
|
||||
} else if (Token::Match(search_tok, "+ std :: string|wstring (")) {
|
||||
}
|
||||
if (Token::Match(search_tok, "+ std :: string|wstring (")) {
|
||||
is_implicit_std_string = true;
|
||||
break;
|
||||
}
|
||||
|
@ -2763,8 +2762,7 @@ namespace {
|
|||
return "";
|
||||
if (alwaysTrue)
|
||||
return "std::any_of";
|
||||
else
|
||||
return "std::all_of or std::none_of";
|
||||
return "std::all_of or std::none_of";
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
|
|
@ -457,10 +457,9 @@ bool CheckUninitVar::checkScopeForVariable(const Token *tok, const Variable& var
|
|||
const std::map<nonneg int,VariableValue>::const_iterator it = variableValue.find(condVarTok->varId());
|
||||
if (it != variableValue.cend() && it->second != 0)
|
||||
return true; // this scope is not fully analysed => return true
|
||||
else {
|
||||
condVarId = condVarTok->varId();
|
||||
condVarValue = !VariableValue(0);
|
||||
}
|
||||
|
||||
condVarId = condVarTok->varId();
|
||||
condVarValue = !VariableValue(0);
|
||||
} else if (Token::Match(tok->next()->astOperand2(), "==|!=")) {
|
||||
const Token *condition = tok->next()->astOperand2();
|
||||
const Token *lhs = condition->astOperand1();
|
||||
|
@ -721,7 +720,7 @@ bool CheckUninitVar::checkScopeForVariable(const Token *tok, const Variable& var
|
|||
return true;
|
||||
}
|
||||
|
||||
else if (isSizeOfEtc(tok))
|
||||
if (isSizeOfEtc(tok))
|
||||
tok = tok->linkAt(1);
|
||||
|
||||
else if (tok->str() == "?") {
|
||||
|
@ -802,30 +801,28 @@ bool CheckUninitVar::checkScopeForVariable(const Token *tok, const Variable& var
|
|||
return true;
|
||||
}
|
||||
|
||||
else {
|
||||
const Token *parent = tok;
|
||||
while (parent->astParent() && ((astIsLHS(parent) && parent->astParent()->str() == "[") || parent->astParent()->isUnaryOp("*"))) {
|
||||
parent = parent->astParent();
|
||||
if (parent->str() == "[") {
|
||||
if (const Token *errorToken = checkExpr(parent->astOperand2(), var, *alloc, number_of_if==0)) {
|
||||
if (!suppressErrors)
|
||||
uninitvarError(errorToken, errorToken->expressionString(), *alloc);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (Token::simpleMatch(parent->astParent(), "=") && astIsLHS(parent)) {
|
||||
const Token *eq = parent->astParent();
|
||||
if (const Token *errorToken = checkExpr(eq->astOperand2(), var, *alloc, number_of_if==0)) {
|
||||
const Token *parent = tok;
|
||||
while (parent->astParent() && ((astIsLHS(parent) && parent->astParent()->str() == "[") || parent->astParent()->isUnaryOp("*"))) {
|
||||
parent = parent->astParent();
|
||||
if (parent->str() == "[") {
|
||||
if (const Token *errorToken = checkExpr(parent->astOperand2(), var, *alloc, number_of_if==0)) {
|
||||
if (!suppressErrors)
|
||||
uninitvarError(errorToken, errorToken->expressionString(), *alloc);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// assume that variable is assigned
|
||||
return true;
|
||||
}
|
||||
if (Token::simpleMatch(parent->astParent(), "=") && astIsLHS(parent)) {
|
||||
const Token *eq = parent->astParent();
|
||||
if (const Token *errorToken = checkExpr(eq->astOperand2(), var, *alloc, number_of_if==0)) {
|
||||
if (!suppressErrors)
|
||||
uninitvarError(errorToken, errorToken->expressionString(), *alloc);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// assume that variable is assigned
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -856,7 +853,7 @@ const Token* CheckUninitVar::checkExpr(const Token* tok, const Variable& var, co
|
|||
const Token *errorToken = isVariableUsage(tok, var.isPointer(), alloc);
|
||||
if (errorToken)
|
||||
return errorToken;
|
||||
else if (bailout)
|
||||
if (bailout)
|
||||
*bailout = true;
|
||||
}
|
||||
return nullptr;
|
||||
|
@ -1408,11 +1405,11 @@ bool CheckUninitVar::isMemberVariableAssignment(const Token *tok, const std::str
|
|||
if (Token::Match(tok, "%name% . %name%") && tok->strAt(2) == membervar) {
|
||||
if (Token::Match(tok->tokAt(3), "[=.[]"))
|
||||
return true;
|
||||
else if (Token::Match(tok->tokAt(-2), "[(,=] &"))
|
||||
if (Token::Match(tok->tokAt(-2), "[(,=] &"))
|
||||
return true;
|
||||
else if (isLikelyStreamRead(mTokenizer->isCPP(), tok->previous()))
|
||||
if (isLikelyStreamRead(mTokenizer->isCPP(), tok->previous()))
|
||||
return true;
|
||||
else if ((tok->previous() && tok->previous()->isConstOp()) || Token::Match(tok->previous(), "[|="))
|
||||
if ((tok->previous() && tok->previous()->isConstOp()) || Token::Match(tok->previous(), "[|="))
|
||||
; // member variable usage
|
||||
else if (tok->tokAt(3)->isConstOp())
|
||||
; // member variable usage
|
||||
|
@ -1452,7 +1449,7 @@ bool CheckUninitVar::isMemberVariableAssignment(const Token *tok, const std::str
|
|||
const Library::ArgumentChecks::Direction argDirection = mSettings->library.getArgDirection(ftok, 1 + argumentNumber);
|
||||
if (argDirection == Library::ArgumentChecks::Direction::DIR_IN)
|
||||
return false;
|
||||
else if (argDirection == Library::ArgumentChecks::Direction::DIR_OUT)
|
||||
if (argDirection == Library::ArgumentChecks::Direction::DIR_OUT)
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -1487,25 +1484,26 @@ bool CheckUninitVar::isMemberVariableUsage(const Token *tok, bool isPointer, All
|
|||
if (Token::Match(tok, "%name% . %name%") && tok->strAt(2) == membervar && !(tok->tokAt(-2)->variable() && tok->tokAt(-2)->variable()->isReference())) {
|
||||
const Token *parent = tok->next()->astParent();
|
||||
return !parent || !parent->isUnaryOp("&");
|
||||
} else if (!isPointer && !Token::simpleMatch(tok->astParent(), ".") && Token::Match(tok->previous(), "[(,] %name% [,)]") && isVariableUsage(tok, isPointer, alloc))
|
||||
}
|
||||
if (!isPointer && !Token::simpleMatch(tok->astParent(), ".") && Token::Match(tok->previous(), "[(,] %name% [,)]") && isVariableUsage(tok, isPointer, alloc))
|
||||
return true;
|
||||
|
||||
else if (!isPointer && Token::Match(tok->previous(), "= %name% ;"))
|
||||
if (!isPointer && Token::Match(tok->previous(), "= %name% ;"))
|
||||
return true;
|
||||
|
||||
// = *(&var);
|
||||
else if (!isPointer &&
|
||||
Token::simpleMatch(tok->astParent(),"&") &&
|
||||
Token::simpleMatch(tok->astParent()->astParent(),"*") &&
|
||||
Token::Match(tok->astParent()->astParent()->astParent(), "= * (| &") &&
|
||||
tok->astParent()->astParent()->astParent()->astOperand2() == tok->astParent()->astParent())
|
||||
if (!isPointer &&
|
||||
Token::simpleMatch(tok->astParent(),"&") &&
|
||||
Token::simpleMatch(tok->astParent()->astParent(),"*") &&
|
||||
Token::Match(tok->astParent()->astParent()->astParent(), "= * (| &") &&
|
||||
tok->astParent()->astParent()->astParent()->astOperand2() == tok->astParent()->astParent())
|
||||
return true;
|
||||
|
||||
// TODO: this used to be experimental - enable or remove see #5586
|
||||
else if ((false) && // NOLINT(readability-simplify-boolean-expr)
|
||||
!isPointer &&
|
||||
Token::Match(tok->tokAt(-2), "[(,] & %name% [,)]") &&
|
||||
isVariableUsage(tok, isPointer, alloc))
|
||||
if ((false) && // NOLINT(readability-simplify-boolean-expr)
|
||||
!isPointer &&
|
||||
Token::Match(tok->tokAt(-2), "[(,] & %name% [,)]") &&
|
||||
isVariableUsage(tok, isPointer, alloc))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
|
|
|
@ -444,7 +444,8 @@ void CheckUnusedFunctions::analyseWholeProgram(const Settings &settings, ErrorLo
|
|||
if (std::strcmp(e2->Name(),"functioncall") == 0) {
|
||||
calls.insert(functionName);
|
||||
continue;
|
||||
} else if (std::strcmp(e2->Name(),"functiondecl") == 0) {
|
||||
}
|
||||
if (std::strcmp(e2->Name(),"functiondecl") == 0) {
|
||||
const char* lineNumber = e2->Attribute("lineNumber");
|
||||
if (lineNumber)
|
||||
decls[functionName] = Location(sourcefile, strToInt<int>(lineNumber));
|
||||
|
|
|
@ -832,7 +832,8 @@ void CheckUnusedVar::checkFunctionVariableUsage_iterateScopes(const Scope* const
|
|||
} else if (var->typeEndToken()->str() == ">") // Be careful with types like std::vector
|
||||
tok = tok->previous();
|
||||
break;
|
||||
} else if (Token::Match(tok2, "[;({=]"))
|
||||
}
|
||||
if (Token::Match(tok2, "[;({=]"))
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1496,7 +1496,8 @@ Token * clangimport::AstNode::createTokensVarDecl(TokenList *tokenList)
|
|||
eq->astOperand1(vartok1);
|
||||
eq->astOperand2(children.back()->createTokens(tokenList));
|
||||
return eq;
|
||||
} else if (mExtTokens.back() == "callinit") {
|
||||
}
|
||||
if (mExtTokens.back() == "callinit") {
|
||||
Token *par1 = addtoken(tokenList, "(");
|
||||
par1->astOperand1(vartok1);
|
||||
par1->astOperand2(getChild(0)->createTokens(tokenList));
|
||||
|
@ -1504,7 +1505,8 @@ Token * clangimport::AstNode::createTokensVarDecl(TokenList *tokenList)
|
|||
par1->link(par2);
|
||||
par2->link(par1);
|
||||
return par1;
|
||||
} else if (mExtTokens.back() == "listinit") {
|
||||
}
|
||||
if (mExtTokens.back() == "listinit") {
|
||||
return getChild(0)->createTokens(tokenList);
|
||||
}
|
||||
return vartok1;
|
||||
|
|
|
@ -124,11 +124,12 @@ struct ForwardTraversal {
|
|||
Progress traverseTok(T* tok, F f, bool traverseUnknown, T** out = nullptr) {
|
||||
if (Token::Match(tok, "asm|goto"))
|
||||
return Break(Analyzer::Terminate::Bail);
|
||||
else if (Token::Match(tok, "setjmp|longjmp (")) {
|
||||
if (Token::Match(tok, "setjmp|longjmp (")) {
|
||||
// Traverse the parameters of the function before escaping
|
||||
traverseRecursive(tok->next()->astOperand2(), f, traverseUnknown);
|
||||
return Break(Analyzer::Terminate::Bail);
|
||||
} else if (Token::simpleMatch(tok, "continue")) {
|
||||
}
|
||||
if (Token::simpleMatch(tok, "continue")) {
|
||||
if (loopEnds.empty())
|
||||
return Break(Analyzer::Terminate::Escape);
|
||||
// If we are in a loop then jump to the end
|
||||
|
|
|
@ -48,7 +48,7 @@ static bool isUnchanged(const Token *startToken, const Token *endToken, const st
|
|||
if (parent->astParent()) {
|
||||
if (parent->astParent()->tokType() == Token::Type::eIncDecOp)
|
||||
return false;
|
||||
else if (parent->astParent()->isAssignmentOp() && parent == parent->astParent()->astOperand1())
|
||||
if (parent->astParent()->isAssignmentOp() && parent == parent->astParent()->astOperand1())
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -321,15 +321,18 @@ struct FwdAnalysis::Result FwdAnalysis::checkRecursive(const Token *expr, const
|
|||
if (reassign)
|
||||
return Result(Result::Type::WRITE, parent->astParent());
|
||||
return Result(Result::Type::READ);
|
||||
} else if (mWhat == What::Reassign && parent->valueType() && parent->valueType()->pointer && Token::Match(parent->astParent(), "%assign%") && parent == parent->astParent()->astOperand1()) {
|
||||
}
|
||||
if (mWhat == What::Reassign && parent->valueType() && parent->valueType()->pointer && Token::Match(parent->astParent(), "%assign%") && parent == parent->astParent()->astOperand1())
|
||||
return Result(Result::Type::READ);
|
||||
} else if (Token::Match(parent->astParent(), "%assign%") && !parent->astParent()->astParent() && parent == parent->astParent()->astOperand1()) {
|
||||
|
||||
if (Token::Match(parent->astParent(), "%assign%") && !parent->astParent()->astParent() && parent == parent->astParent()->astOperand1()) {
|
||||
if (mWhat == What::Reassign)
|
||||
return Result(Result::Type::BAILOUT, parent->astParent());
|
||||
if (mWhat == What::UnusedValue && (!parent->valueType() || parent->valueType()->reference != Reference::None))
|
||||
return Result(Result::Type::BAILOUT, parent->astParent());
|
||||
continue;
|
||||
} else if (mWhat == What::UnusedValue && parent->isUnaryOp("&") && Token::Match(parent->astParent(), "[,(]")) {
|
||||
}
|
||||
if (mWhat == What::UnusedValue && parent->isUnaryOp("&") && Token::Match(parent->astParent(), "[,(]")) {
|
||||
// Pass variable to function the writes it
|
||||
const Token *ftok = parent->astParent();
|
||||
while (Token::simpleMatch(ftok, ","))
|
||||
|
@ -349,10 +352,9 @@ struct FwdAnalysis::Result FwdAnalysis::checkRecursive(const Token *expr, const
|
|||
}
|
||||
}
|
||||
return Result(Result::Type::BAILOUT, parent->astParent());
|
||||
} else {
|
||||
// TODO: this is a quick bailout
|
||||
return Result(Result::Type::BAILOUT, parent->astParent());
|
||||
}
|
||||
// TODO: this is a quick bailout
|
||||
return Result(Result::Type::BAILOUT, parent->astParent());
|
||||
}
|
||||
|
||||
if (Token::Match(tok, ")|do {")) {
|
||||
|
|
|
@ -227,8 +227,7 @@ struct Interval {
|
|||
if (!eq.empty()) {
|
||||
if (eq.front() == 0)
|
||||
return {1, -1};
|
||||
else
|
||||
return {0};
|
||||
return {0};
|
||||
}
|
||||
if (diff.isGreaterThan(-1, ref))
|
||||
return {0, 1};
|
||||
|
|
|
@ -138,59 +138,56 @@ Library::Error Library::load(const char exename[], const char path[])
|
|||
|
||||
if (error == tinyxml2::XML_ERROR_FILE_NOT_FOUND)
|
||||
return Error(ErrorCode::FILE_NOT_FOUND);
|
||||
else {
|
||||
doc.PrintError();
|
||||
return Error(ErrorCode::BAD_XML);
|
||||
}
|
||||
|
||||
doc.PrintError();
|
||||
return Error(ErrorCode::BAD_XML);
|
||||
}
|
||||
|
||||
Library::Container::Yield Library::Container::yieldFrom(const std::string& yieldName)
|
||||
{
|
||||
if (yieldName == "at_index")
|
||||
return Container::Yield::AT_INDEX;
|
||||
else if (yieldName == "item")
|
||||
if (yieldName == "item")
|
||||
return Container::Yield::ITEM;
|
||||
else if (yieldName == "buffer")
|
||||
if (yieldName == "buffer")
|
||||
return Container::Yield::BUFFER;
|
||||
else if (yieldName == "buffer-nt")
|
||||
if (yieldName == "buffer-nt")
|
||||
return Container::Yield::BUFFER_NT;
|
||||
else if (yieldName == "start-iterator")
|
||||
if (yieldName == "start-iterator")
|
||||
return Container::Yield::START_ITERATOR;
|
||||
else if (yieldName == "end-iterator")
|
||||
if (yieldName == "end-iterator")
|
||||
return Container::Yield::END_ITERATOR;
|
||||
else if (yieldName == "iterator")
|
||||
if (yieldName == "iterator")
|
||||
return Container::Yield::ITERATOR;
|
||||
else if (yieldName == "size")
|
||||
if (yieldName == "size")
|
||||
return Container::Yield::SIZE;
|
||||
else if (yieldName == "empty")
|
||||
if (yieldName == "empty")
|
||||
return Container::Yield::EMPTY;
|
||||
else
|
||||
return Container::Yield::NO_YIELD;
|
||||
return Container::Yield::NO_YIELD;
|
||||
}
|
||||
Library::Container::Action Library::Container::actionFrom(const std::string& actionName)
|
||||
{
|
||||
if (actionName == "resize")
|
||||
return Container::Action::RESIZE;
|
||||
else if (actionName == "clear")
|
||||
if (actionName == "clear")
|
||||
return Container::Action::CLEAR;
|
||||
else if (actionName == "push")
|
||||
if (actionName == "push")
|
||||
return Container::Action::PUSH;
|
||||
else if (actionName == "pop")
|
||||
if (actionName == "pop")
|
||||
return Container::Action::POP;
|
||||
else if (actionName == "find")
|
||||
if (actionName == "find")
|
||||
return Container::Action::FIND;
|
||||
else if (actionName == "insert")
|
||||
if (actionName == "insert")
|
||||
return Container::Action::INSERT;
|
||||
else if (actionName == "erase")
|
||||
if (actionName == "erase")
|
||||
return Container::Action::ERASE;
|
||||
else if (actionName == "change-content")
|
||||
if (actionName == "change-content")
|
||||
return Container::Action::CHANGE_CONTENT;
|
||||
else if (actionName == "change-internal")
|
||||
if (actionName == "change-internal")
|
||||
return Container::Action::CHANGE_INTERNAL;
|
||||
else if (actionName == "change")
|
||||
if (actionName == "change")
|
||||
return Container::Action::CHANGE;
|
||||
else
|
||||
return Container::Action::NO_ACTION;
|
||||
return Container::Action::NO_ACTION;
|
||||
}
|
||||
|
||||
// cppcheck-suppress unusedFunction - only used in unit tests
|
||||
|
@ -882,10 +879,10 @@ Library::Error Library::loadFunction(const tinyxml2::XMLElement * const node, co
|
|||
}
|
||||
} else {
|
||||
const char * const message = functionnode->GetText();
|
||||
if (!message) {
|
||||
if (!message)
|
||||
return Error(ErrorCode::MISSING_ATTRIBUTE, "\"reason\" and \"alternatives\" or some text.");
|
||||
} else
|
||||
wi.message = message;
|
||||
|
||||
wi.message = message;
|
||||
}
|
||||
|
||||
functionwarn[name] = wi;
|
||||
|
@ -924,7 +921,7 @@ bool Library::isIntArgValid(const Token *ftok, int argnr, const MathLib::bigint
|
|||
const ArgumentChecks *ac = getarg(ftok, argnr);
|
||||
if (!ac || ac->valid.empty())
|
||||
return true;
|
||||
else if (ac->valid.find('.') != std::string::npos)
|
||||
if (ac->valid.find('.') != std::string::npos)
|
||||
return isFloatArgValid(ftok, argnr, argvalue);
|
||||
TokenList tokenList(nullptr);
|
||||
gettokenlistfromvalid(ac->valid, tokenList);
|
||||
|
@ -1463,8 +1460,7 @@ Library::ArgumentChecks::Direction Library::getArgDirection(const Token* ftok, i
|
|||
if (fs_argno >= 0 && argnr >= fs_argno) {
|
||||
if (formatstr_scan(ftok))
|
||||
return ArgumentChecks::Direction::DIR_OUT;
|
||||
else
|
||||
return ArgumentChecks::Direction::DIR_IN;
|
||||
return ArgumentChecks::Direction::DIR_IN;
|
||||
}
|
||||
}
|
||||
return ArgumentChecks::Direction::DIR_UNKNOWN;
|
||||
|
|
|
@ -335,8 +335,8 @@ MathLib::biguint MathLib::toULongNumber(const std::string & str)
|
|||
const double doubleval = toDoubleNumber(str);
|
||||
if (doubleval > (double)std::numeric_limits<biguint>::max())
|
||||
return std::numeric_limits<biguint>::max();
|
||||
else // cast to bigint to avoid UBSAN warning about negative double being out-of-range
|
||||
return static_cast<biguint>(static_cast<bigint>(doubleval));
|
||||
// cast to bigint to avoid UBSAN warning about negative double being out-of-range
|
||||
return static_cast<biguint>(static_cast<bigint>(doubleval));
|
||||
}
|
||||
|
||||
if (isCharLiteral(str))
|
||||
|
@ -414,10 +414,9 @@ MathLib::bigint MathLib::toLongNumber(const std::string & str)
|
|||
const double doubleval = toDoubleNumber(str);
|
||||
if (doubleval > (double)std::numeric_limits<bigint>::max())
|
||||
return std::numeric_limits<bigint>::max();
|
||||
else if (doubleval < (double)std::numeric_limits<bigint>::min())
|
||||
if (doubleval < (double)std::numeric_limits<bigint>::min())
|
||||
return std::numeric_limits<bigint>::min();
|
||||
else
|
||||
return static_cast<bigint>(doubleval);
|
||||
return static_cast<bigint>(doubleval);
|
||||
}
|
||||
|
||||
if (isCharLiteral(str))
|
||||
|
@ -463,14 +462,12 @@ static double myStod(const std::string& str, std::string::const_iterator from, s
|
|||
auto digitval = [&](char c) {
|
||||
if ((10 < base) && (c > '9'))
|
||||
return 10 + std::tolower(c) - 'a';
|
||||
else
|
||||
return c - '0';
|
||||
return c - '0';
|
||||
};
|
||||
for (; it!=to; ++it) {
|
||||
if ('.' == *it)
|
||||
continue;
|
||||
else
|
||||
--distance;
|
||||
--distance;
|
||||
result += digitval(*it)* std::pow(base, distance);
|
||||
}
|
||||
return positivesign ? result : -result;
|
||||
|
@ -1036,7 +1033,7 @@ std::string MathLib::getSuffix(const std::string& value)
|
|||
return isUnsigned ? "UL" : "L";
|
||||
if (longState == 2)
|
||||
return isUnsigned ? "ULL" : "LL";
|
||||
else return "";
|
||||
return "";
|
||||
}
|
||||
|
||||
static std::string intsuffix(const std::string & first, const std::string & second)
|
||||
|
@ -1117,7 +1114,8 @@ std::string MathLib::divide(const std::string &first, const std::string &second)
|
|||
if (a == std::numeric_limits<bigint>::min() && std::abs(b)<=1)
|
||||
throw InternalError(nullptr, "Internal Error: Division overflow");
|
||||
return toString(toLongNumber(first) / b) + intsuffix(first, second);
|
||||
} else if (isNullValue(second)) {
|
||||
}
|
||||
if (isNullValue(second)) {
|
||||
if (isNullValue(first))
|
||||
return "nan.0";
|
||||
return isPositive(first) == isPositive(second) ? "inf.0" : "-inf.0";
|
||||
|
@ -1287,32 +1285,31 @@ bool MathLib::isDigitSeparator(const std::string& iCode, std::string::size_type
|
|||
return true; // Only xdigits before '
|
||||
--i;
|
||||
}
|
||||
if (i == iPos - 1) { // No xdigit before '
|
||||
if (i == iPos - 1) // No xdigit before '
|
||||
return false;
|
||||
|
||||
switch (iCode[i]) {
|
||||
case ' ':
|
||||
case '.':
|
||||
case ',':
|
||||
case 'x':
|
||||
case '(':
|
||||
case '{':
|
||||
case '+':
|
||||
case '-':
|
||||
case '*':
|
||||
case '%':
|
||||
case '/':
|
||||
case '&':
|
||||
case '|':
|
||||
case '^':
|
||||
case '~':
|
||||
case '=':
|
||||
return true;
|
||||
case '\'':
|
||||
return isDigitSeparator(iCode, i);
|
||||
default:
|
||||
return false;
|
||||
} else {
|
||||
switch (iCode[i]) {
|
||||
case ' ':
|
||||
case '.':
|
||||
case ',':
|
||||
case 'x':
|
||||
case '(':
|
||||
case '{':
|
||||
case '+':
|
||||
case '-':
|
||||
case '*':
|
||||
case '%':
|
||||
case '/':
|
||||
case '&':
|
||||
case '|':
|
||||
case '^':
|
||||
case '~':
|
||||
case '=':
|
||||
return true;
|
||||
case '\'':
|
||||
return isDigitSeparator(iCode, i);
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -185,7 +185,7 @@ std::string Path::getRelativePath(const std::string& absolutePath, const std::ve
|
|||
|
||||
if (endsWith(bp,'/'))
|
||||
return absolutePath.substr(bp.length());
|
||||
else if (absolutePath.size() > bp.size() && absolutePath[bp.length()] == '/')
|
||||
if (absolutePath.size() > bp.size() && absolutePath[bp.length()] == '/')
|
||||
return absolutePath.substr(bp.length() + 1);
|
||||
}
|
||||
return absolutePath;
|
||||
|
|
|
@ -87,11 +87,12 @@ PathAnalysis::Progress PathAnalysis::forwardRange(const Token* startToken, const
|
|||
for (const Token *tok = startToken; precedes(tok, endToken); tok = tok->next()) {
|
||||
if (Token::Match(tok, "asm|goto|break|continue"))
|
||||
return Progress::Break;
|
||||
else if (Token::Match(tok, "return|throw")) {
|
||||
if (Token::Match(tok, "return|throw")) {
|
||||
forwardRecursive(tok, info, f);
|
||||
return Progress::Break;
|
||||
// Evaluate RHS of assignment before LHS
|
||||
} else if (const Token* assignTok = assignExpr(tok)) {
|
||||
}
|
||||
if (const Token* assignTok = assignExpr(tok)) {
|
||||
if (forwardRecursive(assignTok->astOperand2(), info, f) == Progress::Break)
|
||||
return Progress::Break;
|
||||
if (forwardRecursive(assignTok->astOperand1(), info, f) == Progress::Break)
|
||||
|
|
|
@ -72,8 +72,7 @@ const ValueFlow::Value* ProgramMemory::getValue(nonneg int exprid, bool impossib
|
|||
const bool found = it != mValues.cend() && (impossible || !it->second.isImpossible());
|
||||
if (found)
|
||||
return &it->second;
|
||||
else
|
||||
return nullptr;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// cppcheck-suppress unusedFunction
|
||||
|
@ -1162,23 +1161,25 @@ static ValueFlow::Value executeImpl(const Token* expr, ProgramMemory& pm, const
|
|||
const ValueFlow::Value* value = nullptr;
|
||||
if (!expr)
|
||||
return unknown;
|
||||
else if (expr->hasKnownIntValue() && !expr->isAssignmentOp() && expr->str() != ",") {
|
||||
if (expr->hasKnownIntValue() && !expr->isAssignmentOp() && expr->str() != ",")
|
||||
return expr->values().front();
|
||||
} else if ((value = expr->getKnownValue(ValueFlow::Value::ValueType::FLOAT)) ||
|
||||
(value = expr->getKnownValue(ValueFlow::Value::ValueType::ITERATOR_START)) ||
|
||||
(value = expr->getKnownValue(ValueFlow::Value::ValueType::ITERATOR_END)) ||
|
||||
(value = expr->getKnownValue(ValueFlow::Value::ValueType::CONTAINER_SIZE))) {
|
||||
if ((value = expr->getKnownValue(ValueFlow::Value::ValueType::FLOAT)) ||
|
||||
(value = expr->getKnownValue(ValueFlow::Value::ValueType::ITERATOR_START)) ||
|
||||
(value = expr->getKnownValue(ValueFlow::Value::ValueType::ITERATOR_END)) ||
|
||||
(value = expr->getKnownValue(ValueFlow::Value::ValueType::CONTAINER_SIZE))) {
|
||||
return *value;
|
||||
} else if (expr->isNumber()) {
|
||||
}
|
||||
if (expr->isNumber()) {
|
||||
if (MathLib::isFloat(expr->str()))
|
||||
return unknown;
|
||||
MathLib::bigint i = MathLib::toLongNumber(expr->str());
|
||||
if (i < 0 && astIsUnsigned(expr))
|
||||
return unknown;
|
||||
return ValueFlow::Value{i};
|
||||
} else if (expr->isBoolean()) {
|
||||
}
|
||||
if (expr->isBoolean())
|
||||
return ValueFlow::Value{ expr->str() == "true" };
|
||||
} else if (Token::Match(expr->tokAt(-2), ". %name% (") && astIsContainer(expr->tokAt(-2)->astOperand1())) {
|
||||
if (Token::Match(expr->tokAt(-2), ". %name% (") && astIsContainer(expr->tokAt(-2)->astOperand1())) {
|
||||
const Token* containerTok = expr->tokAt(-2)->astOperand1();
|
||||
const Library::Container::Yield yield = containerTok->valueType()->container->getYield(expr->strAt(-1));
|
||||
if (yield == Library::Container::Yield::SIZE) {
|
||||
|
@ -1187,13 +1188,14 @@ static ValueFlow::Value executeImpl(const Token* expr, ProgramMemory& pm, const
|
|||
return unknown;
|
||||
v.valueType = ValueFlow::Value::ValueType::INT;
|
||||
return v;
|
||||
} else if (yield == Library::Container::Yield::EMPTY) {
|
||||
}
|
||||
if (yield == Library::Container::Yield::EMPTY) {
|
||||
ValueFlow::Value v = execute(containerTok, pm);
|
||||
if (!v.isContainerSizeValue())
|
||||
return unknown;
|
||||
if (v.isImpossible() && v.intvalue == 0)
|
||||
return ValueFlow::Value{0};
|
||||
else if (!v.isImpossible())
|
||||
if (!v.isImpossible())
|
||||
return ValueFlow::Value{v.intvalue == 0};
|
||||
}
|
||||
} else if (expr->isAssignmentOp() && expr->astOperand1() && expr->astOperand2() && expr->astOperand1()->exprId() > 0) {
|
||||
|
@ -1212,10 +1214,9 @@ static ValueFlow::Value executeImpl(const Token* expr, ProgramMemory& pm, const
|
|||
else
|
||||
return unknown;
|
||||
return lhs;
|
||||
} else {
|
||||
pm.setValue(expr->astOperand1(), rhs);
|
||||
return rhs;
|
||||
}
|
||||
pm.setValue(expr->astOperand1(), rhs);
|
||||
return rhs;
|
||||
} else if (expr->str() == "&&" && expr->astOperand1() && expr->astOperand2()) {
|
||||
ValueFlow::Value lhs = execute(expr->astOperand1(), pm);
|
||||
if (!lhs.isIntValue())
|
||||
|
@ -1273,7 +1274,7 @@ static ValueFlow::Value executeImpl(const Token* expr, ProgramMemory& pm, const
|
|||
const MathLib::bigint index = rhs.intvalue;
|
||||
if (index >= 0 && index < strValue.size())
|
||||
return ValueFlow::Value{strValue[index]};
|
||||
else if (index == strValue.size())
|
||||
if (index == strValue.size())
|
||||
return ValueFlow::Value{};
|
||||
} else if (Token::Match(expr, "%cop%") && expr->astOperand1() && expr->astOperand2()) {
|
||||
ValueFlow::Value lhs = execute(expr->astOperand1(), pm);
|
||||
|
@ -1324,15 +1325,14 @@ static ValueFlow::Value executeImpl(const Token* expr, ProgramMemory& pm, const
|
|||
const Token* child = expr->astOperand2();
|
||||
if (isFalse(cond))
|
||||
return execute(child->astOperand2(), pm);
|
||||
else if (isTrue(cond))
|
||||
if (isTrue(cond))
|
||||
return execute(child->astOperand1(), pm);
|
||||
else
|
||||
return unknown;
|
||||
|
||||
return unknown;
|
||||
} else if (expr->str() == "(" && expr->isCast()) {
|
||||
if (Token::simpleMatch(expr->previous(), ">") && expr->previous()->link())
|
||||
return execute(expr->astOperand2(), pm);
|
||||
else
|
||||
return execute(expr->astOperand1(), pm);
|
||||
return execute(expr->astOperand1(), pm);
|
||||
}
|
||||
if (expr->exprId() > 0 && pm.hasValue(expr->exprId())) {
|
||||
ValueFlow::Value result = pm.at(expr->exprId());
|
||||
|
@ -1354,20 +1354,18 @@ static ValueFlow::Value executeImpl(const Token* expr, ProgramMemory& pm, const
|
|||
return execute(tok, pm, settings);
|
||||
});
|
||||
BuiltinLibraryFunction lf = getBuiltinLibraryFunction(ftok->str());
|
||||
if (lf) {
|
||||
if (lf)
|
||||
return lf(args);
|
||||
} else {
|
||||
const std::string& returnValue = settings->library.returnValue(ftok);
|
||||
if (!returnValue.empty()) {
|
||||
std::unordered_map<nonneg int, ValueFlow::Value> arg_map;
|
||||
int argn = 0;
|
||||
for (const ValueFlow::Value& result : args) {
|
||||
if (!result.isUninitValue())
|
||||
arg_map[argn] = result;
|
||||
argn++;
|
||||
}
|
||||
return evaluateLibraryFunction(arg_map, returnValue, settings);
|
||||
const std::string& returnValue = settings->library.returnValue(ftok);
|
||||
if (!returnValue.empty()) {
|
||||
std::unordered_map<nonneg int, ValueFlow::Value> arg_map;
|
||||
int argn = 0;
|
||||
for (const ValueFlow::Value& result : args) {
|
||||
if (!result.isUninitValue())
|
||||
arg_map[argn] = result;
|
||||
argn++;
|
||||
}
|
||||
return evaluateLibraryFunction(arg_map, returnValue, settings);
|
||||
}
|
||||
}
|
||||
// Check if function modifies argument
|
||||
|
@ -1435,9 +1433,10 @@ std::vector<ValueFlow::Value> execute(const Scope* scope, ProgramMemory& pm, con
|
|||
if (!top)
|
||||
return unknown;
|
||||
|
||||
if (Token::simpleMatch(top, "return") && top->astOperand1()) {
|
||||
if (Token::simpleMatch(top, "return") && top->astOperand1())
|
||||
return {execute(top->astOperand1(), pm, settings)};
|
||||
} else if (Token::Match(top, "%op%")) {
|
||||
|
||||
if (Token::Match(top, "%op%")) {
|
||||
if (execute(top, pm, settings).isUninitValue())
|
||||
return unknown;
|
||||
const Token* next = nextAfterAstRightmostLeaf(top);
|
||||
|
|
|
@ -114,8 +114,7 @@ struct ReverseTraversal {
|
|||
continueB &= update(tok);
|
||||
if (continueB)
|
||||
return ChildrenToVisit::op1_and_op2;
|
||||
else
|
||||
return ChildrenToVisit::done;
|
||||
return ChildrenToVisit::done;
|
||||
});
|
||||
return continueB;
|
||||
}
|
||||
|
@ -302,7 +301,7 @@ struct ReverseTraversal {
|
|||
}
|
||||
if (thenAction.isModified() && inLoop)
|
||||
break;
|
||||
else if (thenAction.isModified() && !elseAction.isModified())
|
||||
if (thenAction.isModified() && !elseAction.isModified())
|
||||
analyzer->assume(condTok, hasElse);
|
||||
else if (elseAction.isModified() && !thenAction.isModified())
|
||||
analyzer->assume(condTok, !hasElse);
|
||||
|
|
|
@ -171,8 +171,7 @@ std::string Settings::parseEnabled(const std::string &str, std::tuple<SimpleEnab
|
|||
// the actual option is prepending in the applyEnabled() call
|
||||
if (str.empty())
|
||||
return " parameter is empty";
|
||||
else
|
||||
return " parameter with the unknown name '" + str + "'";
|
||||
return " parameter with the unknown name '" + str + "'";
|
||||
}
|
||||
|
||||
return "";
|
||||
|
|
|
@ -918,7 +918,7 @@ void SymbolDatabase::createSymbolDatabaseNeedInitialization()
|
|||
}
|
||||
|
||||
/** check for arguments with default values */
|
||||
else if (func.argCount() == func.initializedArgCount()) {
|
||||
if (func.argCount() == func.initializedArgCount()) {
|
||||
hasDefaultConstructor = true;
|
||||
break;
|
||||
}
|
||||
|
@ -1744,7 +1744,7 @@ void SymbolDatabase::setArrayDimensionsUsingValueFlow()
|
|||
continue;
|
||||
}
|
||||
|
||||
else if (dimension.tok->valueType() && dimension.tok->valueType()->pointer == 0) {
|
||||
if (dimension.tok->valueType() && dimension.tok->valueType()->pointer == 0) {
|
||||
int bits = 0;
|
||||
switch (dimension.tok->valueType()->type) {
|
||||
case ValueType::Type::CHAR:
|
||||
|
@ -1811,7 +1811,8 @@ bool SymbolDatabase::isFunction(const Token *tok, const Scope* outerScope, const
|
|||
*argStart = argStartTok;
|
||||
*declEnd = Token::findmatch(tok2->link()->next(), "{|;");
|
||||
return true;
|
||||
} else if (tok2 && tok2->str() == "[") {
|
||||
}
|
||||
if (tok2 && tok2->str() == "[") {
|
||||
while (tok2 && tok2->str() == "[")
|
||||
tok2 = tok2->link()->next();
|
||||
if (Token::Match(tok2, "{|;|const|=")) {
|
||||
|
@ -2759,8 +2760,7 @@ bool Function::argsMatch(const Scope *scope, const Token *first, const Token *se
|
|||
else if (first->str() == ")") {
|
||||
if (openParen == 1)
|
||||
return true;
|
||||
else
|
||||
--openParen;
|
||||
--openParen;
|
||||
}
|
||||
|
||||
// skip optional type information
|
||||
|
@ -3495,9 +3495,9 @@ const std::string& Type::name() const
|
|||
const Token* next = classDef->next();
|
||||
if (classScope && classScope->enumClass && isEnumType())
|
||||
return next->strAt(1);
|
||||
else if (next->str() == "class")
|
||||
if (next->str() == "class")
|
||||
return next->strAt(1);
|
||||
else if (next->isName())
|
||||
if (next->isName())
|
||||
return next->str();
|
||||
return emptyString;
|
||||
}
|
||||
|
@ -3543,15 +3543,14 @@ bool Type::hasCircularDependencies(std::set<BaseInfo>* ancestors) const
|
|||
for (std::vector<BaseInfo>::const_iterator parent=derivedFrom.cbegin(); parent!=derivedFrom.cend(); ++parent) {
|
||||
if (!parent->type)
|
||||
continue;
|
||||
else if (this==parent->type)
|
||||
if (this==parent->type)
|
||||
return true;
|
||||
else if (ancestors->find(*parent)!=ancestors->end())
|
||||
if (ancestors->find(*parent)!=ancestors->end())
|
||||
return true;
|
||||
|
||||
ancestors->insert(*parent);
|
||||
if (parent->type->hasCircularDependencies(ancestors))
|
||||
return true;
|
||||
else {
|
||||
ancestors->insert(*parent);
|
||||
if (parent->type->hasCircularDependencies(ancestors))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@ -4567,13 +4566,13 @@ void Scope::getVariableList(const Settings* settings, const Token* start, const
|
|||
break;
|
||||
|
||||
// Is it a function?
|
||||
else if (tok->str() == "{") {
|
||||
if (tok->str() == "{") {
|
||||
tok = tok->link();
|
||||
continue;
|
||||
}
|
||||
|
||||
// Is it a nested class or structure?
|
||||
else if (tok->isKeyword() && Token::Match(tok, "class|struct|union|namespace %type% :|{")) {
|
||||
if (tok->isKeyword() && Token::Match(tok, "class|struct|union|namespace %type% :|{")) {
|
||||
tok = tok->tokAt(2);
|
||||
while (tok && tok->str() != "{")
|
||||
tok = tok->next();
|
||||
|
@ -4581,13 +4580,15 @@ void Scope::getVariableList(const Settings* settings, const Token* start, const
|
|||
// skip implementation
|
||||
tok = tok->link();
|
||||
continue;
|
||||
} else
|
||||
break;
|
||||
} else if (tok->isKeyword() && Token::Match(tok, "struct|union {")) {
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (tok->isKeyword() && Token::Match(tok, "struct|union {")) {
|
||||
if (Token::Match(tok->next()->link(), "} %name% ;|[")) {
|
||||
tok = tok->next()->link()->tokAt(2);
|
||||
continue;
|
||||
} else if (Token::simpleMatch(tok->next()->link(), "} ;")) {
|
||||
}
|
||||
if (Token::simpleMatch(tok->next()->link(), "} ;")) {
|
||||
tok = tok->next();
|
||||
continue;
|
||||
}
|
||||
|
@ -4604,8 +4605,7 @@ void Scope::getVariableList(const Settings* settings, const Token* start, const
|
|||
}
|
||||
if (tok)
|
||||
continue;
|
||||
else
|
||||
break;
|
||||
break;
|
||||
}
|
||||
|
||||
// "private:" "public:" "protected:" etc
|
||||
|
@ -4648,9 +4648,9 @@ void Scope::getVariableList(const Settings* settings, const Token* start, const
|
|||
}
|
||||
|
||||
// Search for start of statement..
|
||||
else if (tok->previous() && !Token::Match(tok->previous(), ";|{|}|public:|protected:|private:"))
|
||||
if (tok->previous() && !Token::Match(tok->previous(), ";|{|}|public:|protected:|private:"))
|
||||
continue;
|
||||
else if (tok->str() == ";")
|
||||
if (tok->str() == ";")
|
||||
continue;
|
||||
|
||||
tok = checkVariable(tok, varaccess, settings);
|
||||
|
@ -4981,13 +4981,11 @@ const Enumerator * SymbolDatabase::findEnumerator(const Token * tok, std::set<st
|
|||
if (enumerator) // enum class
|
||||
return enumerator;
|
||||
// enum
|
||||
else {
|
||||
for (std::vector<Scope *>::const_iterator it = scope->nestedList.cbegin(), end = scope->nestedList.cend(); it != end; ++it) {
|
||||
enumerator = (*it)->findEnumerator(tokStr);
|
||||
for (std::vector<Scope *>::const_iterator it = scope->nestedList.cbegin(), end = scope->nestedList.cend(); it != end; ++it) {
|
||||
enumerator = (*it)->findEnumerator(tokStr);
|
||||
|
||||
if (enumerator && !(enumerator->scope && enumerator->scope->enumClass))
|
||||
return enumerator;
|
||||
}
|
||||
if (enumerator && !(enumerator->scope && enumerator->scope->enumClass))
|
||||
return enumerator;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -5152,17 +5150,17 @@ const Type* SymbolDatabase::findVariableType(const Scope *start, const Token *ty
|
|||
while (scope) {
|
||||
if (scope->className == tok1->str())
|
||||
break;
|
||||
else {
|
||||
const Scope *scope1 = scope->findRecordInNestedList(tok1->str());
|
||||
|
||||
if (scope1) {
|
||||
scope = scope1;
|
||||
break;
|
||||
} else if (scope->type == Scope::eFunction && scope->functionOf)
|
||||
scope = scope->functionOf;
|
||||
else
|
||||
scope = scope->nestedIn;
|
||||
const Scope *scope1 = scope->findRecordInNestedList(tok1->str());
|
||||
|
||||
if (scope1) {
|
||||
scope = scope1;
|
||||
break;
|
||||
}
|
||||
if (scope->type == Scope::eFunction && scope->functionOf)
|
||||
scope = scope->functionOf;
|
||||
else
|
||||
scope = scope->nestedIn;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -5648,15 +5646,14 @@ const Function* SymbolDatabase::findFunction(const Token* const tok) const
|
|||
while (currScope) {
|
||||
if (currScope->className == tok1->str())
|
||||
break;
|
||||
else {
|
||||
const Scope *scope = currScope->findRecordInNestedList(tok1->str());
|
||||
|
||||
if (scope) {
|
||||
currScope = scope;
|
||||
break;
|
||||
} else
|
||||
currScope = currScope->nestedIn;
|
||||
const Scope *scope = currScope->findRecordInNestedList(tok1->str());
|
||||
|
||||
if (scope) {
|
||||
currScope = scope;
|
||||
break;
|
||||
}
|
||||
currScope = currScope->nestedIn;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -5690,10 +5687,10 @@ const Function* SymbolDatabase::findFunction(const Token* const tok) const
|
|||
// check for member function
|
||||
else if (Token::Match(tok->tokAt(-2), "!!this .")) {
|
||||
const Token* tok1 = tok->previous()->astOperand1();
|
||||
if (tok1 && tok1->valueType() && tok1->valueType()->typeScope) {
|
||||
if (tok1 && tok1->valueType() && tok1->valueType()->typeScope)
|
||||
return tok1->valueType()->typeScope->findFunction(tok, tok1->valueType()->constness == 1);
|
||||
} else if (tok1 && Token::Match(tok1->previous(), "%name% (") && tok1->previous()->function() &&
|
||||
tok1->previous()->function()->retDef) {
|
||||
if (tok1 && Token::Match(tok1->previous(), "%name% (") && tok1->previous()->function() &&
|
||||
tok1->previous()->function()->retDef) {
|
||||
ValueType vt = ValueType::parseDecl(tok1->previous()->function()->retDef, mSettings, mIsCpp);
|
||||
if (vt.typeScope)
|
||||
return vt.typeScope->findFunction(tok, vt.constness == 1);
|
||||
|
@ -5972,7 +5969,7 @@ const Type* SymbolDatabase::findType(const Token *startTok, const Scope *startSc
|
|||
const Type * type = scope->findType(tok->str());
|
||||
if (type)
|
||||
return type;
|
||||
else if (const Scope *scope1 = scope->findRecordInBase(tok->str())) {
|
||||
if (const Scope *scope1 = scope->findRecordInBase(tok->str())) {
|
||||
type = scope1->definedType;
|
||||
if (type)
|
||||
return type;
|
||||
|
@ -6032,11 +6029,10 @@ const Type* SymbolDatabase::findTypeInNested(const Token *startTok, const Scope
|
|||
const Type * type = scope->findType(tok->str());
|
||||
if (hasPath || type)
|
||||
return type;
|
||||
else {
|
||||
scope = scope->nestedIn;
|
||||
if (!scope)
|
||||
break;
|
||||
}
|
||||
|
||||
scope = scope->nestedIn;
|
||||
if (!scope)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -6052,7 +6048,7 @@ const Scope * SymbolDatabase::findNamespace(const Token * tok, const Scope * sco
|
|||
|
||||
if (s)
|
||||
return s;
|
||||
else if (scope->nestedIn)
|
||||
if (scope->nestedIn)
|
||||
return findNamespace(tok, scope->nestedIn);
|
||||
|
||||
return nullptr;
|
||||
|
@ -6100,10 +6096,8 @@ bool SymbolDatabase::isReservedName(const std::string& iName) const
|
|||
static const auto& cpp_keywords = Keywords::getAll(Standards::cppstd_t::CPPLatest);
|
||||
return cpp_keywords.find(iName) != cpp_keywords.cend();
|
||||
}
|
||||
else {
|
||||
static const auto& c_keywords = Keywords::getAll(Standards::cstd_t::CLatest);
|
||||
return c_keywords.find(iName) != c_keywords.cend();
|
||||
}
|
||||
static const auto& c_keywords = Keywords::getAll(Standards::cstd_t::CLatest);
|
||||
return c_keywords.find(iName) != c_keywords.cend();
|
||||
}
|
||||
|
||||
nonneg int SymbolDatabase::sizeOfType(const Token *type) const
|
||||
|
@ -6720,7 +6714,8 @@ static const Token* parsedecl(const Token* type,
|
|||
valuetype->reference = vt2->reference;
|
||||
type = type->linkAt(1)->next();
|
||||
continue;
|
||||
} else if (type->isSigned())
|
||||
}
|
||||
if (type->isSigned())
|
||||
valuetype->sign = ValueType::Sign::SIGNED;
|
||||
else if (type->isUnsigned())
|
||||
valuetype->sign = ValueType::Sign::UNSIGNED;
|
||||
|
@ -7391,7 +7386,8 @@ bool ValueType::fromLibraryType(const std::string &typestr, const Settings &sett
|
|||
type = ValueType::Type::UNKNOWN_INT;
|
||||
sign = (podtype->sign == 'u') ? ValueType::UNSIGNED : ValueType::SIGNED;
|
||||
return true;
|
||||
} else if (podtype && podtype->stdtype == Library::PodType::Type::NO) {
|
||||
}
|
||||
if (podtype && podtype->stdtype == Library::PodType::Type::NO) {
|
||||
type = ValueType::Type::POD;
|
||||
sign = ValueType::UNKNOWN_SIGN;
|
||||
return true;
|
||||
|
@ -7420,7 +7416,8 @@ bool ValueType::fromLibraryType(const std::string &typestr, const Settings &sett
|
|||
if (platformType->mConstPtr)
|
||||
constness = 1;
|
||||
return true;
|
||||
} else if (!podtype && (typestr == "size_t" || typestr == "std::size_t")) {
|
||||
}
|
||||
if (!podtype && (typestr == "size_t" || typestr == "std::size_t")) {
|
||||
originalTypeName = "size_t";
|
||||
sign = ValueType::UNSIGNED;
|
||||
if (settings.platform.sizeof_size_t == settings.platform.sizeof_long)
|
||||
|
@ -7690,11 +7687,11 @@ ValueType::MatchResult ValueType::matchParameter(const ValueType *call, const Va
|
|||
return call->type < func->type ?
|
||||
ValueType::MatchResult::FALLBACK1 :
|
||||
ValueType::MatchResult::FALLBACK2;
|
||||
else if (call->isFloat() && func->isFloat())
|
||||
if (call->isFloat() && func->isFloat())
|
||||
return ValueType::MatchResult::FALLBACK1;
|
||||
else if (call->isIntegral() && func->isFloat())
|
||||
if (call->isIntegral() && func->isFloat())
|
||||
return ValueType::MatchResult::FALLBACK2;
|
||||
else if (call->isFloat() && func->isIntegral())
|
||||
if (call->isFloat() && func->isIntegral())
|
||||
return ValueType::MatchResult::FALLBACK2;
|
||||
return ValueType::MatchResult::UNKNOWN; // TODO
|
||||
}
|
||||
|
|
|
@ -944,11 +944,9 @@ public:
|
|||
static std::vector<const Token*> findReturns(const Function* f);
|
||||
|
||||
const Token* returnDefEnd() const {
|
||||
if (this->hasTrailingReturnType()) {
|
||||
if (this->hasTrailingReturnType())
|
||||
return Token::findmatch(retDef, "{|;");
|
||||
} else {
|
||||
return tokenDef;
|
||||
}
|
||||
return tokenDef;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -420,7 +420,7 @@ unsigned int TemplateSimplifier::templateParameters(const Token *tok)
|
|||
syntaxError(tok);
|
||||
if (Token::Match(tok, ">|>>|>>="))
|
||||
return numberOfParameters;
|
||||
else if (tok->str() == ",") {
|
||||
if (tok->str() == ",") {
|
||||
++numberOfParameters;
|
||||
tok = tok->next();
|
||||
continue;
|
||||
|
@ -479,9 +479,9 @@ unsigned int TemplateSimplifier::templateParameters(const Token *tok)
|
|||
return 0;
|
||||
if (tok->str() == ">" && level == 0)
|
||||
return numberOfParameters;
|
||||
else if ((tok->str() == ">>" || tok->str() == ">>=") && level == 1)
|
||||
if ((tok->str() == ">>" || tok->str() == ">>=") && level == 1)
|
||||
return numberOfParameters;
|
||||
else if (tok->str() == ",") {
|
||||
if (tok->str() == ",") {
|
||||
if (level == 0)
|
||||
++numberOfParameters;
|
||||
tok = tok->next();
|
||||
|
@ -989,42 +989,41 @@ void TemplateSimplifier::getTemplateInstantiations()
|
|||
// full name matches
|
||||
addInstantiation(tok, it->scope());
|
||||
break;
|
||||
} else {
|
||||
// full name doesn't match so try with using namespaces if available
|
||||
bool found = false;
|
||||
for (const auto & nameSpace : tok->scopeInfo()->usingNamespaces) {
|
||||
std::string fullNameSpace = scopeName + (scopeName.empty()?"":" :: ") +
|
||||
nameSpace + (qualification.empty()?"":" :: ") + qualification;
|
||||
std::string newFullName = fullNameSpace + " :: " + tok->str();
|
||||
const std::list<TokenAndName>::const_iterator it1 = std::find_if(mTemplateDeclarations.cbegin(), mTemplateDeclarations.cend(), FindFullName(newFullName));
|
||||
if (it1 != mTemplateDeclarations.end()) {
|
||||
// insert using namespace into token stream
|
||||
std::string::size_type offset = 0;
|
||||
std::string::size_type pos = 0;
|
||||
while ((pos = nameSpace.find(' ', offset)) != std::string::npos) {
|
||||
qualificationTok->insertToken(nameSpace.substr(offset, pos - offset), emptyString, true);
|
||||
offset = pos + 1;
|
||||
}
|
||||
qualificationTok->insertToken(nameSpace.substr(offset), emptyString, true);
|
||||
qualificationTok->insertToken("::", emptyString, true);
|
||||
addInstantiation(tok, it1->scope());
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (found)
|
||||
break;
|
||||
|
||||
if (scopeName.empty()) {
|
||||
if (!qualification.empty())
|
||||
addInstantiation(tok, qualification);
|
||||
else
|
||||
addInstantiation(tok, tok->scopeInfo()->name);
|
||||
break;
|
||||
}
|
||||
const std::string::size_type pos = scopeName.rfind(" :: ");
|
||||
scopeName = (pos == std::string::npos) ? std::string() : scopeName.substr(0,pos);
|
||||
}
|
||||
// full name doesn't match so try with using namespaces if available
|
||||
bool found = false;
|
||||
for (const auto & nameSpace : tok->scopeInfo()->usingNamespaces) {
|
||||
std::string fullNameSpace = scopeName + (scopeName.empty()?"":" :: ") +
|
||||
nameSpace + (qualification.empty()?"":" :: ") + qualification;
|
||||
std::string newFullName = fullNameSpace + " :: " + tok->str();
|
||||
const std::list<TokenAndName>::const_iterator it1 = std::find_if(mTemplateDeclarations.cbegin(), mTemplateDeclarations.cend(), FindFullName(newFullName));
|
||||
if (it1 != mTemplateDeclarations.end()) {
|
||||
// insert using namespace into token stream
|
||||
std::string::size_type offset = 0;
|
||||
std::string::size_type pos = 0;
|
||||
while ((pos = nameSpace.find(' ', offset)) != std::string::npos) {
|
||||
qualificationTok->insertToken(nameSpace.substr(offset, pos - offset), emptyString, true);
|
||||
offset = pos + 1;
|
||||
}
|
||||
qualificationTok->insertToken(nameSpace.substr(offset), emptyString, true);
|
||||
qualificationTok->insertToken("::", emptyString, true);
|
||||
addInstantiation(tok, it1->scope());
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (found)
|
||||
break;
|
||||
|
||||
if (scopeName.empty()) {
|
||||
if (!qualification.empty())
|
||||
addInstantiation(tok, qualification);
|
||||
else
|
||||
addInstantiation(tok, tok->scopeInfo()->name);
|
||||
break;
|
||||
}
|
||||
const std::string::size_type pos = scopeName.rfind(" :: ");
|
||||
scopeName = (pos == std::string::npos) ? std::string() : scopeName.substr(0,pos);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1092,8 +1091,8 @@ void TemplateSimplifier::useDefaultArgumentValues(TokenAndName &declaration)
|
|||
if (!eq.empty())
|
||||
eq.back().end = tok;
|
||||
break;
|
||||
} else
|
||||
--templateParmDepth;
|
||||
}
|
||||
--templateParmDepth;
|
||||
}
|
||||
|
||||
// map type parameter name to index
|
||||
|
@ -1423,7 +1422,7 @@ bool TemplateSimplifier::getTemplateNamePositionTemplateFunction(const Token *to
|
|||
if (Token::Match(tok->next(), ";|{"))
|
||||
return false;
|
||||
// skip decltype(...)
|
||||
else if (Token::simpleMatch(tok->next(), "decltype (")) {
|
||||
if (Token::simpleMatch(tok->next(), "decltype (")) {
|
||||
const Token * end = tok->linkAt(2)->previous();
|
||||
while (tok->next() && tok != end) {
|
||||
tok = tok->next();
|
||||
|
@ -1455,7 +1454,7 @@ bool TemplateSimplifier::getTemplateNamePositionTemplateVariable(const Token *to
|
|||
if (Token::Match(tok->next(), ";|{|(|using"))
|
||||
return false;
|
||||
// skip decltype(...)
|
||||
else if (Token::simpleMatch(tok->next(), "decltype (")) {
|
||||
if (Token::simpleMatch(tok->next(), "decltype (")) {
|
||||
const Token * end = tok->linkAt(2);
|
||||
while (tok->next() && tok != end) {
|
||||
tok = tok->next();
|
||||
|
@ -2155,9 +2154,10 @@ void TemplateSimplifier::expandTemplate(
|
|||
eraseTokens(tok3, closingBracket->next());
|
||||
}
|
||||
continue;
|
||||
} else if (!templateDeclaration.scope().empty() &&
|
||||
!alreadyHasNamespace(templateDeclaration, tok3) &&
|
||||
!Token::Match(closingBracket->next(), "(|::")) {
|
||||
}
|
||||
if (!templateDeclaration.scope().empty() &&
|
||||
!alreadyHasNamespace(templateDeclaration, tok3) &&
|
||||
!Token::Match(closingBracket->next(), "(|::")) {
|
||||
if (copy)
|
||||
addNamespace(templateDeclaration, tok3);
|
||||
}
|
||||
|
@ -2354,8 +2354,9 @@ bool TemplateSimplifier::simplifyNumericCalculations(Token *tok, bool isTemplate
|
|||
|
||||
// Don't simplify "%num% / 0"
|
||||
if (Token::Match(op, "[/%] 0")) {
|
||||
if (isTemplate) throw InternalError(op, "Instantiation error: Divide by zero in template instantiation.", InternalError::INSTANTIATION);
|
||||
else return ret;
|
||||
if (isTemplate)
|
||||
throw InternalError(op, "Instantiation error: Divide by zero in template instantiation.", InternalError::INSTANTIATION);
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Integer operations
|
||||
|
@ -3316,28 +3317,25 @@ static bool matchTemplateParameters(const Token *nameTok, const std::list<std::s
|
|||
if (tok->isUnsigned()) {
|
||||
if (*it != "unsigned")
|
||||
return false;
|
||||
else {
|
||||
++it;
|
||||
if (it == strings.cend())
|
||||
return false;
|
||||
}
|
||||
|
||||
++it;
|
||||
if (it == strings.cend())
|
||||
return false;
|
||||
} else if (tok->isSigned()) {
|
||||
if (*it != "signed")
|
||||
return false;
|
||||
else {
|
||||
++it;
|
||||
if (it == strings.cend())
|
||||
return false;
|
||||
}
|
||||
|
||||
++it;
|
||||
if (it == strings.cend())
|
||||
return false;
|
||||
}
|
||||
if (tok->isLong()) {
|
||||
if (*it != "long")
|
||||
return false;
|
||||
else {
|
||||
++it;
|
||||
if (it == strings.cend())
|
||||
return false;
|
||||
}
|
||||
|
||||
++it;
|
||||
if (it == strings.cend())
|
||||
return false;
|
||||
}
|
||||
if (*it != tok->str())
|
||||
return false;
|
||||
|
@ -3396,9 +3394,8 @@ void TemplateSimplifier::replaceTemplateUsage(
|
|||
if (ti->token() == tok) {
|
||||
ti = mTemplateInstantiations.erase(ti);
|
||||
break;
|
||||
} else {
|
||||
++ti;
|
||||
}
|
||||
++ti;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3854,7 +3851,7 @@ void TemplateSimplifier::simplifyTemplates(
|
|||
for (const Token* tok = arg; tok; tok = tok->next()) {
|
||||
if (tok->str() == ",")
|
||||
return i;
|
||||
else if (tok->link() && Token::Match(tok, "(|{|["))
|
||||
if (tok->link() && Token::Match(tok, "(|{|["))
|
||||
tok = tok->link();
|
||||
else if (tok->str() == "<") {
|
||||
const Token* temp = tok->findClosingBracket();
|
||||
|
|
|
@ -465,11 +465,11 @@ static int multiComparePercent(const Token *tok, const char*& haystack, nonneg i
|
|||
if (haystack[3] == '%') { // %any%
|
||||
haystack += 4;
|
||||
return 1;
|
||||
} else { // %assign%
|
||||
haystack += 7;
|
||||
if (tok->isAssignmentOp())
|
||||
return 1;
|
||||
}
|
||||
// %assign%
|
||||
haystack += 7;
|
||||
if (tok->isAssignmentOp())
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
case 'n':
|
||||
|
@ -646,9 +646,9 @@ bool Token::simpleMatch(const Token *tok, const char pattern[], size_t pattern_l
|
|||
bool Token::firstWordEquals(const char *str, const char *word)
|
||||
{
|
||||
for (;;) {
|
||||
if (*str != *word) {
|
||||
if (*str != *word)
|
||||
return (*str == ' ' && *word == 0);
|
||||
} else if (*str == 0)
|
||||
if (*str == 0)
|
||||
break;
|
||||
|
||||
++str;
|
||||
|
@ -841,7 +841,7 @@ const Token* Token::nextArgument() const
|
|||
for (const Token* tok = this; tok; tok = tok->next()) {
|
||||
if (tok->str() == ",")
|
||||
return tok->next();
|
||||
else if (tok->link() && Token::Match(tok, "(|{|[|<"))
|
||||
if (tok->link() && Token::Match(tok, "(|{|[|<"))
|
||||
tok = tok->link();
|
||||
else if (Token::Match(tok, ")|;"))
|
||||
return nullptr;
|
||||
|
@ -854,7 +854,7 @@ const Token* Token::nextArgumentBeforeCreateLinks2() const
|
|||
for (const Token* tok = this; tok; tok = tok->next()) {
|
||||
if (tok->str() == ",")
|
||||
return tok->next();
|
||||
else if (tok->link() && Token::Match(tok, "(|{|["))
|
||||
if (tok->link() && Token::Match(tok, "(|{|["))
|
||||
tok = tok->link();
|
||||
else if (tok->str() == "<") {
|
||||
const Token* temp = tok->findClosingBracket();
|
||||
|
@ -871,7 +871,7 @@ const Token* Token::nextTemplateArgument() const
|
|||
for (const Token* tok = this; tok; tok = tok->next()) {
|
||||
if (tok->str() == ",")
|
||||
return tok->next();
|
||||
else if (tok->link() && Token::Match(tok, "(|{|[|<"))
|
||||
if (tok->link() && Token::Match(tok, "(|{|[|<"))
|
||||
tok = tok->link();
|
||||
else if (Token::Match(tok, ">|;"))
|
||||
return nullptr;
|
||||
|
@ -1944,16 +1944,15 @@ static bool removeContradiction(std::list<ValueFlow::Value>& values)
|
|||
if (removey)
|
||||
values.remove(y);
|
||||
return true;
|
||||
} else {
|
||||
result = removex || removey;
|
||||
bool bail = false;
|
||||
if (removex && removePointValue(values, x))
|
||||
bail = true;
|
||||
if (removey && removePointValue(values, y))
|
||||
bail = true;
|
||||
if (bail)
|
||||
return true;
|
||||
}
|
||||
result = removex || removey;
|
||||
bool bail = false;
|
||||
if (removex && removePointValue(values, x))
|
||||
bail = true;
|
||||
if (removey && removePointValue(values, y))
|
||||
bail = true;
|
||||
if (bail)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
|
@ -2203,13 +2202,13 @@ const ::Type* Token::typeOf(const Token* tok, const Token** typeTok)
|
|||
if (typeTok != nullptr)
|
||||
*typeTok = tok;
|
||||
const Token* lhsVarTok{};
|
||||
if (tok->type()) {
|
||||
if (tok->type())
|
||||
return tok->type();
|
||||
} else if (tok->variable()) {
|
||||
if (tok->variable())
|
||||
return tok->variable()->type();
|
||||
} else if (tok->function()) {
|
||||
if (tok->function())
|
||||
return tok->function()->retType;
|
||||
} else if (Token::simpleMatch(tok, "return")) {
|
||||
if (Token::simpleMatch(tok, "return")) {
|
||||
const Scope *scope = tok->scope();
|
||||
if (!scope)
|
||||
return nullptr;
|
||||
|
@ -2217,15 +2216,16 @@ const ::Type* Token::typeOf(const Token* tok, const Token** typeTok)
|
|||
if (!function)
|
||||
return nullptr;
|
||||
return function->retType;
|
||||
} else if (Token::Match(tok->previous(), "%type%|= (|{")) {
|
||||
}
|
||||
if (Token::Match(tok->previous(), "%type%|= (|{"))
|
||||
return typeOf(tok->previous(), typeTok);
|
||||
} else if (Token::simpleMatch(tok, "=") && (lhsVarTok = getLHSVariableToken(tok)) != tok->next()) {
|
||||
if (Token::simpleMatch(tok, "=") && (lhsVarTok = getLHSVariableToken(tok)) != tok->next())
|
||||
return Token::typeOf(lhsVarTok, typeTok);
|
||||
} else if (Token::simpleMatch(tok, ".")) {
|
||||
if (Token::simpleMatch(tok, "."))
|
||||
return Token::typeOf(tok->astOperand2(), typeTok);
|
||||
} else if (Token::simpleMatch(tok, "[")) {
|
||||
if (Token::simpleMatch(tok, "["))
|
||||
return Token::typeOf(tok->astOperand1(), typeTok);
|
||||
} else if (Token::simpleMatch(tok, "{")) {
|
||||
if (Token::simpleMatch(tok, "{")) {
|
||||
int argnr;
|
||||
const Token* ftok = getTokenArgumentFunction(tok, argnr);
|
||||
if (argnr < 0)
|
||||
|
@ -2251,9 +2251,9 @@ std::pair<const Token*, const Token*> Token::typeDecl(const Token* tok, bool poi
|
|||
{
|
||||
if (!tok)
|
||||
return {};
|
||||
else if (tok->type()) {
|
||||
if (tok->type())
|
||||
return {tok, tok->next()};
|
||||
} else if (tok->variable()) {
|
||||
if (tok->variable()) {
|
||||
const Variable *var = tok->variable();
|
||||
if (!var->typeStartToken() || !var->typeEndToken())
|
||||
return {};
|
||||
|
@ -2321,7 +2321,8 @@ std::pair<const Token*, const Token*> Token::typeDecl(const Token* tok, bool poi
|
|||
if (result.first)
|
||||
return result;
|
||||
return {var->typeStartToken(), var->typeEndToken()->next()};
|
||||
} else if (Token::simpleMatch(tok, "return")) {
|
||||
}
|
||||
if (Token::simpleMatch(tok, "return")) {
|
||||
const Scope* scope = tok->scope();
|
||||
if (!scope)
|
||||
return {};
|
||||
|
@ -2329,19 +2330,20 @@ std::pair<const Token*, const Token*> Token::typeDecl(const Token* tok, bool poi
|
|||
if (!function)
|
||||
return {};
|
||||
return { function->retDef, function->returnDefEnd() };
|
||||
} else if (tok->previous() && tok->previous()->function()) {
|
||||
}
|
||||
if (tok->previous() && tok->previous()->function()) {
|
||||
const Function *function = tok->previous()->function();
|
||||
return {function->retDef, function->returnDefEnd()};
|
||||
} else if (Token::simpleMatch(tok, "=")) {
|
||||
return Token::typeDecl(tok->astOperand1());
|
||||
} else if (Token::simpleMatch(tok, ".")) {
|
||||
return Token::typeDecl(tok->astOperand2());
|
||||
} else {
|
||||
const ::Type * t = typeOf(tok);
|
||||
if (!t || !t->classDef)
|
||||
return {};
|
||||
return {t->classDef->next(), t->classDef->tokAt(2)};
|
||||
}
|
||||
if (Token::simpleMatch(tok, "="))
|
||||
return Token::typeDecl(tok->astOperand1());
|
||||
if (Token::simpleMatch(tok, "."))
|
||||
return Token::typeDecl(tok->astOperand2());
|
||||
|
||||
const ::Type * t = typeOf(tok);
|
||||
if (!t || !t->classDef)
|
||||
return {};
|
||||
return {t->classDef->next(), t->classDef->tokAt(2)};
|
||||
}
|
||||
std::string Token::typeStr(const Token* tok)
|
||||
{
|
||||
|
|
|
@ -1411,7 +1411,7 @@ public:
|
|||
return nullptr;
|
||||
if (this == astParent()->astOperand1())
|
||||
return astParent()->astOperand2();
|
||||
else if (this == astParent()->astOperand2())
|
||||
if (this == astParent()->astOperand2())
|
||||
return astParent()->astOperand1();
|
||||
return nullptr;
|
||||
|
||||
|
@ -1421,7 +1421,7 @@ public:
|
|||
return nullptr;
|
||||
if (this == astParent()->astOperand1())
|
||||
return astParent()->astOperand2();
|
||||
else if (this == astParent()->astOperand2())
|
||||
if (this == astParent()->astOperand2())
|
||||
return astParent()->astOperand1();
|
||||
return nullptr;
|
||||
|
||||
|
|
161
lib/tokenize.cpp
161
lib/tokenize.cpp
|
@ -212,10 +212,11 @@ nonneg int Tokenizer::sizeOfType(const Token *type) const
|
|||
return 0;
|
||||
|
||||
return podtype->size;
|
||||
} else if (type->isLong()) {
|
||||
}
|
||||
if (type->isLong()) {
|
||||
if (type->str() == "double")
|
||||
return mSettings->platform.sizeof_long_double;
|
||||
else if (type->str() == "long")
|
||||
if (type->str() == "long")
|
||||
return mSettings->platform.sizeof_long_long;
|
||||
}
|
||||
|
||||
|
@ -250,15 +251,15 @@ bool Tokenizer::duplicateTypedef(Token **tokPtr, const Token *name, const Token
|
|||
if (end)
|
||||
end = end->next();
|
||||
} else if (end->str() == "(") {
|
||||
if (tok->previous()->str().compare(0, 8, "operator") == 0) {
|
||||
if (tok->previous()->str().compare(0, 8, "operator") == 0)
|
||||
// conversion operator
|
||||
return false;
|
||||
} else if (tok->previous()->str() == "typedef") {
|
||||
if (tok->previous()->str() == "typedef")
|
||||
// typedef of function returning this type
|
||||
return false;
|
||||
} else if (Token::Match(tok->previous(), "public:|private:|protected:")) {
|
||||
if (Token::Match(tok->previous(), "public:|private:|protected:"))
|
||||
return false;
|
||||
} else if (tok->previous()->str() == ">") {
|
||||
if (tok->previous()->str() == ">") {
|
||||
if (!Token::Match(tok->tokAt(-2), "%type%"))
|
||||
return false;
|
||||
|
||||
|
@ -313,17 +314,16 @@ bool Tokenizer::duplicateTypedef(Token **tokPtr, const Token *name, const Token
|
|||
typeDef->strAt(3) != "{") {
|
||||
// declaration after forward declaration
|
||||
return true;
|
||||
} else if (tok->next()->str() == "{") {
|
||||
return true;
|
||||
} else if (Token::Match(tok->next(), ")|*")) {
|
||||
return true;
|
||||
} else if (tok->next()->str() == name->str()) {
|
||||
return true;
|
||||
} else if (tok->next()->str() != ";") {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
if (tok->next()->str() == "{")
|
||||
return true;
|
||||
if (Token::Match(tok->next(), ")|*"))
|
||||
return true;
|
||||
if (tok->next()->str() == name->str())
|
||||
return true;
|
||||
if (tok->next()->str() != ";")
|
||||
return true;
|
||||
return false;
|
||||
} else if (tok->previous()->str() == "union") {
|
||||
return tok->next()->str() != ";";
|
||||
} else if (isCPP() && tok->previous()->str() == "class") {
|
||||
|
@ -354,7 +354,7 @@ void Tokenizer::unsupportedTypedef(const Token *tok) const
|
|||
while (tok) {
|
||||
if (level == 0 && tok->str() == ";")
|
||||
break;
|
||||
else if (tok->str() == "{")
|
||||
if (tok->str() == "{")
|
||||
++level;
|
||||
else if (tok->str() == "}") {
|
||||
if (level == 0)
|
||||
|
@ -383,7 +383,8 @@ Token * Tokenizer::deleteInvalidTypedef(Token *typeDef)
|
|||
if (typeDef->next()->str() == ";") {
|
||||
typeDef->deleteNext();
|
||||
break;
|
||||
} else if (typeDef->next()->str() == "{")
|
||||
}
|
||||
if (typeDef->next()->str() == "{")
|
||||
Token::eraseTokens(typeDef, typeDef->linkAt(1));
|
||||
else if (typeDef->next()->str() == "}")
|
||||
break;
|
||||
|
@ -466,20 +467,19 @@ static Token *splitDefinitionFromTypedef(Token *tok, nonneg int *unnamedCount)
|
|||
tok->deleteThis();
|
||||
tok1->deleteThis();
|
||||
return nullptr;
|
||||
} else {
|
||||
tok1->insertToken("typedef");
|
||||
tok1 = tok1->next();
|
||||
Token * tok3 = tok1;
|
||||
if (isConst) {
|
||||
tok1->insertToken("const");
|
||||
tok1 = tok1->next();
|
||||
}
|
||||
tok1->insertToken(tok->next()->str()); // struct, union or enum
|
||||
tok1 = tok1->next();
|
||||
tok1->insertToken(name);
|
||||
tok->deleteThis();
|
||||
tok = tok3;
|
||||
}
|
||||
tok1->insertToken("typedef");
|
||||
tok1 = tok1->next();
|
||||
Token * tok3 = tok1;
|
||||
if (isConst) {
|
||||
tok1->insertToken("const");
|
||||
tok1 = tok1->next();
|
||||
}
|
||||
tok1->insertToken(tok->next()->str()); // struct, union or enum
|
||||
tok1 = tok1->next();
|
||||
tok1->insertToken(name);
|
||||
tok->deleteThis();
|
||||
tok = tok3;
|
||||
|
||||
return tok;
|
||||
}
|
||||
|
@ -1374,7 +1374,7 @@ void Tokenizer::simplifyTypedefCpp()
|
|||
}
|
||||
|
||||
// function pointer
|
||||
else if (Token::Match(tokOffset2, "* %name% ) (")) {
|
||||
if (Token::Match(tokOffset2, "* %name% ) (")) {
|
||||
// name token wasn't a name, it was part of the type
|
||||
typeEnd = typeEnd->next();
|
||||
functionPtr = true;
|
||||
|
@ -2313,12 +2313,11 @@ void Tokenizer::simplifyTypedefCpp()
|
|||
|
||||
if (!tokOffset->next())
|
||||
return; // invalid input
|
||||
else if (tokOffset->next()->str() == ";")
|
||||
if (tokOffset->next()->str() == ";")
|
||||
break;
|
||||
else if (tokOffset->str() == "]")
|
||||
if (tokOffset->str() == "]")
|
||||
break;
|
||||
else
|
||||
tokOffset = tokOffset->next();
|
||||
tokOffset = tokOffset->next();
|
||||
}
|
||||
|
||||
arrayEnd = tokOffset;
|
||||
|
@ -2410,11 +2409,10 @@ namespace {
|
|||
for (const auto & child : children) {
|
||||
if (child.type == Record && (child.name == scope || child.fullName == scope))
|
||||
return &child;
|
||||
else {
|
||||
const ScopeInfo3 * temp = child.findInChildren(scope);
|
||||
if (temp)
|
||||
return temp;
|
||||
}
|
||||
|
||||
const ScopeInfo3 * temp = child.findInChildren(scope);
|
||||
if (temp)
|
||||
return temp;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -2764,7 +2762,7 @@ namespace {
|
|||
while (end) {
|
||||
if (end->str() == "{" && !Token::Match(end->tokAt(-2), ":|, %name%"))
|
||||
return end;
|
||||
else if (end->str() == ";")
|
||||
if (end->str() == ";")
|
||||
break;
|
||||
end = end->next();
|
||||
}
|
||||
|
@ -3058,7 +3056,8 @@ bool Tokenizer::simplifyUsing()
|
|||
}
|
||||
}
|
||||
continue;
|
||||
} else if (inMemberFunc && memberFuncScope) {
|
||||
}
|
||||
if (inMemberFunc && memberFuncScope) {
|
||||
if (!usingMatch(nameToken, scope, &tok1, scope1, currentScope1, memberFuncScope))
|
||||
continue;
|
||||
} else if (!usingMatch(nameToken, scope, &tok1, scope1, currentScope1, nullptr))
|
||||
|
@ -3079,19 +3078,18 @@ bool Tokenizer::simplifyUsing()
|
|||
tok1->deletePrevious();
|
||||
tok1->deletePrevious();
|
||||
break;
|
||||
} else {
|
||||
const std::string::size_type idx = fullScope.rfind("::");
|
||||
|
||||
if (idx == std::string::npos)
|
||||
break;
|
||||
|
||||
if (tok1->strAt(-2) == fullScope.substr(idx + 3)) {
|
||||
tok1->deletePrevious();
|
||||
tok1->deletePrevious();
|
||||
fullScope.resize(idx - 1);
|
||||
} else
|
||||
break;
|
||||
}
|
||||
const std::string::size_type idx = fullScope.rfind("::");
|
||||
|
||||
if (idx == std::string::npos)
|
||||
break;
|
||||
|
||||
if (tok1->strAt(-2) == fullScope.substr(idx + 3)) {
|
||||
tok1->deletePrevious();
|
||||
tok1->deletePrevious();
|
||||
fullScope.resize(idx - 1);
|
||||
} else
|
||||
break;
|
||||
}
|
||||
|
||||
// remove global namespace if present
|
||||
|
@ -4719,8 +4717,7 @@ void Tokenizer::setVarIdPass1()
|
|||
if (tok->previous() && tok->previous()->str() == "::") {
|
||||
if (Token::Match(tok->tokAt(-2), ")|]|%name%"))
|
||||
continue;
|
||||
else
|
||||
globalNamespace = true;
|
||||
globalNamespace = true;
|
||||
}
|
||||
if (tok->next() && tok->next()->str() == "::")
|
||||
continue;
|
||||
|
@ -4903,7 +4900,8 @@ void Tokenizer::setVarIdPass2()
|
|||
usingnamespaces.push_back(tok->tokAt(2));
|
||||
tok = endtok;
|
||||
continue;
|
||||
} else if (Token::Match(tok, "namespace %name% {")) {
|
||||
}
|
||||
if (Token::Match(tok, "namespace %name% {")) {
|
||||
scope.push_back(tok->strAt(1));
|
||||
endOfScope[tok->linkAt(2)] = tok->strAt(1);
|
||||
}
|
||||
|
@ -6546,7 +6544,7 @@ void Tokenizer::simplifyFunctionParameters()
|
|||
for (const Token* tok2 = tok1; tok2; tok2 = tok2->next()) {
|
||||
if (Token::simpleMatch(tok2, "; {"))
|
||||
break;
|
||||
else if (tok2->str() == "{") {
|
||||
if (tok2->str() == "{") {
|
||||
bailOut = true;
|
||||
break;
|
||||
}
|
||||
|
@ -6704,7 +6702,7 @@ void Tokenizer::simplifyFunctionPointers()
|
|||
}
|
||||
|
||||
// check for start of statement
|
||||
else if (tok->previous() && !Token::Match(tok->previous(), "{|}|;|,|(|public:|protected:|private:"))
|
||||
if (tok->previous() && !Token::Match(tok->previous(), "{|}|;|,|(|public:|protected:|private:"))
|
||||
continue;
|
||||
|
||||
if (Token::Match(tok, "delete|else|return|throw|typedef"))
|
||||
|
@ -7031,7 +7029,7 @@ void Tokenizer::simplifyVarDecl(Token * tokBegin, const Token * const tokEnd, co
|
|||
continue;
|
||||
}
|
||||
//non-VLA case
|
||||
else if (Token::Match(varName, "%name% ,|=")) {
|
||||
if (Token::Match(varName, "%name% ,|=")) {
|
||||
if (varName->str() != "operator") {
|
||||
tok2 = varName->next(); // The ',' or '=' token
|
||||
|
||||
|
@ -7419,7 +7417,7 @@ Token * Tokenizer::initVar(Token * tok)
|
|||
// check initializer..
|
||||
if (tok->tokAt(2)->isStandardType() || tok->strAt(2) == "void")
|
||||
return tok;
|
||||
else if (!tok->tokAt(2)->isNumber() && !Token::Match(tok->tokAt(2), "%type% (") && tok->strAt(2) != "&" && tok->tokAt(2)->varId() == 0)
|
||||
if (!tok->tokAt(2)->isNumber() && !Token::Match(tok->tokAt(2), "%type% (") && tok->strAt(2) != "&" && tok->tokAt(2)->varId() == 0)
|
||||
return tok;
|
||||
|
||||
// insert '; var ='
|
||||
|
@ -8019,9 +8017,9 @@ static bool isAlignAttribute(const Token * tok)
|
|||
template<typename T>
|
||||
static T* skipCPPOrAlignAttribute(T * tok)
|
||||
{
|
||||
if (isCPPAttribute(tok)) {
|
||||
if (isCPPAttribute(tok))
|
||||
return tok->link();
|
||||
} else if (isAlignAttribute(tok)) {
|
||||
if (isAlignAttribute(tok)) {
|
||||
return tok->next()->link();
|
||||
}
|
||||
return tok;
|
||||
|
@ -8762,9 +8760,9 @@ Token* Tokenizer::getAttributeFuncTok(Token* tok, bool gccattr) const {
|
|||
prev = prev->previous();
|
||||
if (Token::simpleMatch(prev, ")") && Token::Match(prev->link()->previous(), "%name% ("))
|
||||
return prev->link()->previous();
|
||||
else if (Token::simpleMatch(prev, ")") && Token::Match(prev->link()->tokAt(-2), "operator %op% (") && isCPP())
|
||||
if (Token::simpleMatch(prev, ")") && Token::Match(prev->link()->tokAt(-2), "operator %op% (") && isCPP())
|
||||
return prev->link()->tokAt(-2);
|
||||
else if ((!prev || Token::Match(prev, "[;{}*]")) && Token::Match(tok->previous(), "%name%"))
|
||||
if ((!prev || Token::Match(prev, "[;{}*]")) && Token::Match(tok->previous(), "%name%"))
|
||||
return tok->previous();
|
||||
}
|
||||
return nullptr;
|
||||
|
@ -9855,9 +9853,9 @@ void Tokenizer::simplifyOverloadedOperators()
|
|||
for (const Token *tok2 = tok->next(); tok2; tok2 = tok2->next()) {
|
||||
if (tok2->str() == "}")
|
||||
break;
|
||||
else if (indent == 0 && tok2->str() == ";")
|
||||
if (indent == 0 && tok2->str() == ";")
|
||||
break;
|
||||
else if (tok2->str() == "{") {
|
||||
if (tok2->str() == "{") {
|
||||
if (indent == 0)
|
||||
++indent;
|
||||
else
|
||||
|
@ -10297,21 +10295,20 @@ void Tokenizer::simplifyNamespaceAliases()
|
|||
// delete duplicate
|
||||
tok2 = deleteAlias(tok2->previous());
|
||||
continue;
|
||||
} else {
|
||||
// conflicting declaration (syntax error)
|
||||
// cppcheck-suppress duplicateBranch - remove when TODO below is addressed
|
||||
if (endScope == scope) {
|
||||
// delete conflicting declaration
|
||||
tok2 = deleteAlias(tok2->previous());
|
||||
}
|
||||
|
||||
// new declaration
|
||||
else {
|
||||
// TODO: use the new alias in this scope
|
||||
tok2 = deleteAlias(tok2->previous());
|
||||
}
|
||||
continue;
|
||||
}
|
||||
// conflicting declaration (syntax error)
|
||||
// cppcheck-suppress duplicateBranch - remove when TODO below is addressed
|
||||
if (endScope == scope) {
|
||||
// delete conflicting declaration
|
||||
tok2 = deleteAlias(tok2->previous());
|
||||
}
|
||||
|
||||
// new declaration
|
||||
else {
|
||||
// TODO: use the new alias in this scope
|
||||
tok2 = deleteAlias(tok2->previous());
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
if (tok2->strAt(1) == "::" && !alreadyHasNamespace(tokNameStart, tokNameEnd, tok2)) {
|
||||
|
|
|
@ -1717,7 +1717,7 @@ void TokenList::validateAst() const
|
|||
if (tok->str() == "?") {
|
||||
if (!tok->astOperand1() || !tok->astOperand2())
|
||||
throw InternalError(tok, "AST broken, ternary operator missing operand(s)", InternalError::AST);
|
||||
else if (tok->astOperand2()->str() != ":")
|
||||
if (tok->astOperand2()->str() != ":")
|
||||
throw InternalError(tok, "Syntax Error: AST broken, ternary operator lacks ':'.", InternalError::AST);
|
||||
}
|
||||
|
||||
|
|
|
@ -518,7 +518,8 @@ static Library::Container::Yield getContainerYield(Token* tok, const Settings* s
|
|||
if (parent)
|
||||
*parent = tok->astParent();
|
||||
return c ? c->getYield(tok->strAt(1)) : Library::Container::Yield::NO_YIELD;
|
||||
} else if (Token::Match(tok->previous(), "%name% (")) {
|
||||
}
|
||||
if (Token::Match(tok->previous(), "%name% (")) {
|
||||
if (parent)
|
||||
*parent = tok;
|
||||
if (const Library::Function* f = settings->library.getFunction(tok->previous())) {
|
||||
|
@ -1450,7 +1451,7 @@ static void valueFlowArray(TokenList *tokenlist, const Settings *settings)
|
|||
continue;
|
||||
}
|
||||
|
||||
else if (Token::Match(tok, "const char %var% [ %num%| ] = %str% ;")) {
|
||||
if (Token::Match(tok, "const char %var% [ %num%| ] = %str% ;")) {
|
||||
Token *vartok = tok->tokAt(2);
|
||||
Token *strtok = vartok->next()->link()->tokAt(2);
|
||||
constantArrays[vartok->varId()] = strtok;
|
||||
|
@ -2175,8 +2176,7 @@ static const std::string& invertAssign(const std::string& assign)
|
|||
if (it == lookup.end()) {
|
||||
return emptyString;
|
||||
}
|
||||
else
|
||||
return it->second;
|
||||
return it->second;
|
||||
}
|
||||
|
||||
static std::string removeAssign(const std::string& assign) {
|
||||
|
@ -2488,11 +2488,13 @@ struct ValueFlowAnalyzer : Analyzer {
|
|||
result.dependent = true;
|
||||
result.unknown = false;
|
||||
return result;
|
||||
} else if (tok->hasKnownIntValue() || tok->isLiteral()) {
|
||||
}
|
||||
if (tok->hasKnownIntValue() || tok->isLiteral()) {
|
||||
result.dependent = false;
|
||||
result.unknown = false;
|
||||
return result;
|
||||
} else if (Token::Match(tok, "%cop%")) {
|
||||
}
|
||||
if (Token::Match(tok, "%cop%")) {
|
||||
if (isLikelyStream(isCPP(), tok->astOperand1())) {
|
||||
result.dependent = false;
|
||||
return result;
|
||||
|
@ -2509,7 +2511,8 @@ struct ValueFlowAnalyzer : Analyzer {
|
|||
result.dependent = lhs.dependent || rhs.dependent;
|
||||
result.unknown = lhs.unknown || rhs.unknown;
|
||||
return result;
|
||||
} else if (Token::Match(tok->previous(), "%name% (")) {
|
||||
}
|
||||
if (Token::Match(tok->previous(), "%name% (")) {
|
||||
std::vector<const Token*> args = getArguments(tok->previous());
|
||||
if (Token::Match(tok->tokAt(-2), ". %name% (")) {
|
||||
args.push_back(tok->tokAt(-2)->astOperand1());
|
||||
|
@ -2524,23 +2527,23 @@ struct ValueFlowAnalyzer : Analyzer {
|
|||
result.unknown = false;
|
||||
}
|
||||
return result;
|
||||
} else {
|
||||
std::unordered_map<nonneg int, const Token*> symbols = getSymbols(tok);
|
||||
result.dependent = false;
|
||||
for (auto&& p : symbols) {
|
||||
const Token* arg = p.second;
|
||||
ConditionState cs = analyzeCondition(arg, depth - 1);
|
||||
result.dependent = cs.dependent;
|
||||
if (result.dependent)
|
||||
break;
|
||||
}
|
||||
if (result.dependent) {
|
||||
// Check if we can evaluate the token
|
||||
if (!evaluate(Evaluate::Integral, tok).empty())
|
||||
result.unknown = false;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
std::unordered_map<nonneg int, const Token*> symbols = getSymbols(tok);
|
||||
result.dependent = false;
|
||||
for (auto&& p : symbols) {
|
||||
const Token* arg = p.second;
|
||||
ConditionState cs = analyzeCondition(arg, depth - 1);
|
||||
result.dependent = cs.dependent;
|
||||
if (result.dependent)
|
||||
break;
|
||||
}
|
||||
if (result.dependent) {
|
||||
// Check if we can evaluate the token
|
||||
if (!evaluate(Evaluate::Integral, tok).empty())
|
||||
result.unknown = false;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
virtual Action isModified(const Token* tok) const {
|
||||
|
@ -2624,8 +2627,7 @@ struct ValueFlowAnalyzer : Analyzer {
|
|||
{
|
||||
if (d == Direction::Forward)
|
||||
return tok->str();
|
||||
else
|
||||
return invertAssign(tok->str());
|
||||
return invertAssign(tok->str());
|
||||
}
|
||||
|
||||
virtual Action isWritable(const Token* tok, Direction d) const {
|
||||
|
@ -2831,11 +2833,11 @@ struct ValueFlowAnalyzer : Analyzer {
|
|||
Action a = isAliasModified(tok);
|
||||
if (inconclusive && a.isModified())
|
||||
return Action::Inconclusive;
|
||||
else
|
||||
return a;
|
||||
} else if (isSameSymbolicValue(ref)) {
|
||||
return Action::Read | Action::SymbolicMatch;
|
||||
return a;
|
||||
}
|
||||
if (isSameSymbolicValue(ref))
|
||||
return Action::Read | Action::SymbolicMatch;
|
||||
|
||||
return Action::None;
|
||||
}
|
||||
|
||||
|
@ -2901,7 +2903,8 @@ struct ValueFlowAnalyzer : Analyzer {
|
|||
return evaluateInt(tok, [&] {
|
||||
return pms.get(tok, ctx, getProgramState());
|
||||
});
|
||||
} else if (e == Evaluate::ContainerEmpty) {
|
||||
}
|
||||
if (e == Evaluate::ContainerEmpty) {
|
||||
const ValueFlow::Value* value = ValueFlow::findValue(tok->values(), nullptr, [](const ValueFlow::Value& v) {
|
||||
return v.isKnown() && v.isContainerSizeValue();
|
||||
});
|
||||
|
@ -2912,9 +2915,8 @@ struct ValueFlowAnalyzer : Analyzer {
|
|||
if (pm.getContainerEmptyValue(tok->exprId(), out))
|
||||
return {static_cast<int>(out)};
|
||||
return {};
|
||||
} else {
|
||||
return {};
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
void assume(const Token* tok, bool state, unsigned int flags) override {
|
||||
|
@ -3099,10 +3101,10 @@ struct SingleValueFlowAnalyzer : ValueFlowAnalyzer {
|
|||
const Scope* scope = endBlock->scope();
|
||||
if (!scope)
|
||||
return false;
|
||||
if (scope->type == Scope::eLambda) {
|
||||
if (scope->type == Scope::eLambda)
|
||||
return value.isLifetimeValue();
|
||||
} else if (scope->type == Scope::eIf || scope->type == Scope::eElse || scope->type == Scope::eWhile ||
|
||||
scope->type == Scope::eFor) {
|
||||
if (scope->type == Scope::eIf || scope->type == Scope::eElse || scope->type == Scope::eWhile ||
|
||||
scope->type == Scope::eFor) {
|
||||
if (value.isKnown() || value.isImpossible())
|
||||
return true;
|
||||
if (value.isLifetimeValue())
|
||||
|
@ -3472,7 +3474,8 @@ static std::vector<ValueFlow::LifetimeToken> getLifetimeTokens(const Token* tok,
|
|||
if (var->isArgument()) {
|
||||
errorPath.emplace_back(varDeclEndToken, "Passed to reference.");
|
||||
return {{tok, true, std::move(errorPath)}};
|
||||
} else if (Token::simpleMatch(varDeclEndToken, "=")) {
|
||||
}
|
||||
if (Token::simpleMatch(varDeclEndToken, "=")) {
|
||||
errorPath.emplace_back(varDeclEndToken, "Assigned to reference.");
|
||||
const Token *vartok = varDeclEndToken->astOperand2();
|
||||
const bool temporary = isTemporary(true, vartok, nullptr, true);
|
||||
|
@ -3492,8 +3495,7 @@ static std::vector<ValueFlow::LifetimeToken> getLifetimeTokens(const Token* tok,
|
|||
const Token* contok = var->nameToken()->astParent()->astOperand2();
|
||||
if (astIsContainer(contok))
|
||||
return getLifetimeTokens(contok, escape, std::move(errorPath), pred, depth - 1);
|
||||
else
|
||||
return std::vector<ValueFlow::LifetimeToken>{};
|
||||
return std::vector<ValueFlow::LifetimeToken>{};
|
||||
} else {
|
||||
return std::vector<ValueFlow::LifetimeToken> {};
|
||||
}
|
||||
|
@ -3541,7 +3543,8 @@ static std::vector<ValueFlow::LifetimeToken> getLifetimeTokens(const Token* tok,
|
|||
}
|
||||
}
|
||||
return result;
|
||||
} else if (Token::Match(tok->tokAt(-2), ". %name% (") && tok->tokAt(-2)->originalName() != "->" && astIsContainer(tok->tokAt(-2)->astOperand1())) {
|
||||
}
|
||||
if (Token::Match(tok->tokAt(-2), ". %name% (") && tok->tokAt(-2)->originalName() != "->" && astIsContainer(tok->tokAt(-2)->astOperand1())) {
|
||||
const Library::Container* library = getLibraryContainer(tok->tokAt(-2)->astOperand1());
|
||||
const Library::Container::Yield y = library->getYield(tok->previous()->str());
|
||||
if (y == Library::Container::Yield::AT_INDEX || y == Library::Container::Yield::ITEM) {
|
||||
|
@ -4855,9 +4858,9 @@ static void valueFlowLifetime(TokenList *tokenlist, SymbolDatabase* /*db*/, Erro
|
|||
auto isImplicitCapturingThis = [&](const Token* tok2) {
|
||||
if (capturedThis)
|
||||
return false;
|
||||
if (Token::simpleMatch(tok2, "this")) {
|
||||
if (Token::simpleMatch(tok2, "this"))
|
||||
return true;
|
||||
} else if (tok2->variable()) {
|
||||
if (tok2->variable()) {
|
||||
if (Token::simpleMatch(tok2->previous(), "."))
|
||||
return false;
|
||||
const Variable* var = tok2->variable();
|
||||
|
@ -4866,9 +4869,9 @@ static void valueFlowLifetime(TokenList *tokenlist, SymbolDatabase* /*db*/, Erro
|
|||
if (var->isArgument())
|
||||
return false;
|
||||
return exprDependsOnThis(tok2);
|
||||
} else if (Token::simpleMatch(tok2, "(")) {
|
||||
return exprDependsOnThis(tok2);
|
||||
}
|
||||
if (Token::simpleMatch(tok2, "("))
|
||||
return exprDependsOnThis(tok2);
|
||||
return false;
|
||||
};
|
||||
|
||||
|
@ -6559,7 +6562,8 @@ struct ConditionHandler {
|
|||
"valueFlowAfterCondition: " + cond.vartok->expressionString() +
|
||||
" is changed in conditional block");
|
||||
return;
|
||||
} else if (bailBlock >= 0) {
|
||||
}
|
||||
if (bailBlock >= 0) {
|
||||
if (settings->debugwarnings)
|
||||
bailout(tokenlist,
|
||||
errorLogger,
|
||||
|
@ -7042,7 +7046,7 @@ static void valueFlowForLoopSimplify(Token* const bodyStart,
|
|||
getProgramMemory(tok2->astTop(), expr, ValueFlow::Value(value), settings))))
|
||||
break;
|
||||
|
||||
else if (Token::simpleMatch(tok2, ") {")) {
|
||||
if (Token::simpleMatch(tok2, ") {")) {
|
||||
if (vartok->varId() && Token::findmatch(tok2->link(), "%varid%", tok2, vartok->varId())) {
|
||||
if (Token::findmatch(tok2, "continue|break|return", tok2->linkAt(1), vartok->varId())) {
|
||||
if (settings->debugwarnings)
|
||||
|
@ -7278,8 +7282,9 @@ struct MultiValueFlowAnalyzer : ValueFlowAnalyzer {
|
|||
return std::all_of(values.cbegin(), values.cend(), [](const std::pair<nonneg int, ValueFlow::Value>& p) {
|
||||
return p.second.isLifetimeValue();
|
||||
});
|
||||
} else if (scope->type == Scope::eIf || scope->type == Scope::eElse || scope->type == Scope::eWhile ||
|
||||
scope->type == Scope::eFor) {
|
||||
}
|
||||
if (scope->type == Scope::eIf || scope->type == Scope::eElse || scope->type == Scope::eWhile ||
|
||||
scope->type == Scope::eFor) {
|
||||
auto pred = [](const ValueFlow::Value& value) {
|
||||
if (value.isKnown())
|
||||
return true;
|
||||
|
|
|
@ -214,8 +214,7 @@ private:
|
|||
|
||||
if (tokenizer.tokens())
|
||||
return tokenizer.tokens()->stringifyList(false, expand, false, true, false, nullptr, nullptr);
|
||||
else
|
||||
return "";
|
||||
return "";
|
||||
}
|
||||
|
||||
#define tokenizeDebugListing(...) tokenizeDebugListing_(__FILE__, __LINE__, __VA_ARGS__)
|
||||
|
|
|
@ -477,8 +477,7 @@ private:
|
|||
|
||||
if (tokenizer.tokens())
|
||||
return tokenizer.tokens()->stringifyList(false, expand, false, true, false, nullptr, nullptr);
|
||||
else
|
||||
return "";
|
||||
return "";
|
||||
}
|
||||
|
||||
#define tokenizeAndStringifyWindows(...) tokenizeAndStringifyWindows_(__FILE__, __LINE__, __VA_ARGS__)
|
||||
|
@ -504,8 +503,7 @@ private:
|
|||
|
||||
if (tokenizer.tokens())
|
||||
return tokenizer.tokens()->stringifyList(false, expand, false, true, false, nullptr, nullptr);
|
||||
else
|
||||
return "";
|
||||
return "";
|
||||
}
|
||||
|
||||
std::string tokenizeAndStringify_(const char* file, int line, const char code[], const Settings &settings, const char filename[] = "test.cpp") {
|
||||
|
|
Loading…
Reference in New Issue