diff --git a/lib/astutils.cpp b/lib/astutils.cpp index 1e75552ec4d..7ec19bedaf1 100644 --- a/lib/astutils.cpp +++ b/lib/astutils.cpp @@ -409,22 +409,22 @@ bool isStlStringType(const Token* tok) (Token::simpleMatch(tok, "std :: basic_string <") && !Token::simpleMatch(tok->linkAt(3), "> ::")); } -bool isTemporary(bool cpp, const Token* tok, const Library* library, bool unknown) +bool isTemporary(const Token* tok, const Library* library, bool unknown) { if (!tok) return false; if (Token::simpleMatch(tok, ".")) - return (tok->originalName() != "->" && isTemporary(cpp, tok->astOperand1(), library)) || - isTemporary(cpp, tok->astOperand2(), library); + return (tok->originalName() != "->" && isTemporary(tok->astOperand1(), library)) || + isTemporary(tok->astOperand2(), library); if (Token::Match(tok, ",|::")) - return isTemporary(cpp, tok->astOperand2(), library); - if (tok->isCast() || (cpp && isCPPCast(tok))) - return isTemporary(cpp, tok->astOperand2(), library); + return isTemporary(tok->astOperand2(), library); + if (tok->isCast() || (tok->isCpp() && isCPPCast(tok))) + return isTemporary(tok->astOperand2(), library); if (Token::Match(tok, ".|[|++|--|%name%|%assign%")) return false; if (tok->isUnaryOp("*")) return false; - if (Token::Match(tok, "&|<<|>>") && isLikelyStream(cpp, tok->astOperand1())) + if (Token::Match(tok, "&|<<|>>") && isLikelyStream(tok->astOperand1())) return false; if (Token::simpleMatch(tok, "?")) { const Token* branchTok = tok->astOperand2(); @@ -473,7 +473,7 @@ bool isTemporary(bool cpp, const Token* tok, const Library* library, bool unknow return unknown; if (Token::simpleMatch(tok, "{") && Token::simpleMatch(tok->astParent(), "return") && tok->astOperand1() && !tok->astOperand2()) - return isTemporary(cpp, tok->astOperand1(), library); + return isTemporary(tok->astOperand1(), library); return true; } @@ -629,7 +629,7 @@ static std::vector getParentMembers(const Token* tok) return result; } -const Token* getParentLifetime(bool cpp, const Token* tok, const Library* library) +const Token* getParentLifetime(const Token* tok, const Library* library) { std::vector members = getParentMembers(tok); if (members.size() < 2) @@ -639,7 +639,7 @@ const Token* getParentLifetime(bool cpp, const Token* tok, const Library* librar const Variable* var = tok2->variable(); if (var) return var->isLocal() || var->isArgument(); - return isTemporary(cpp, tok2, library); + return isTemporary(tok2, library); }); if (it == members.rend()) return tok; @@ -1137,7 +1137,7 @@ bool isStructuredBindingVariable(const Variable* var) /// This takes a token that refers to a variable and it will return the token /// to the expression that the variable is assigned to. If its not valid to /// make such substitution then it will return the original token. -static const Token * followVariableExpression(const Token * tok, bool cpp, const Token * end = nullptr) +static const Token * followVariableExpression(const Token * tok, const Token * end = nullptr) { if (!tok) return tok; @@ -1175,7 +1175,7 @@ static const Token * followVariableExpression(const Token * tok, bool cpp, const const Token * lastTok = precedes(tok, end) ? end : tok; // If this is in a loop then check if variables are modified in the entire scope const Token * endToken = (isInLoopCondition(tok) || isInLoopCondition(varTok) || var->scope() != tok->scope()) ? var->scope()->bodyEnd : lastTok; - if (!var->isConst() && (!precedes(varTok, endToken) || isVariableChanged(varTok, endToken, tok->varId(), false, nullptr, cpp))) + if (!var->isConst() && (!precedes(varTok, endToken) || isVariableChanged(varTok, endToken, tok->varId(), false, nullptr))) return tok; if (precedes(varTok, endToken) && isAliased(varTok, endToken, tok->varId())) return tok; @@ -1187,7 +1187,7 @@ static const Token * followVariableExpression(const Token * tok, bool cpp, const return tok; } else if (!precedes(startToken, endToken)) { return tok; - } else if (findExpressionChanged(varTok, startToken, endToken, nullptr, cpp)) { + } else if (findExpressionChanged(varTok, startToken, endToken, nullptr)) { return tok; } return varTok; @@ -1250,7 +1250,7 @@ SmallVector followAllReferences(const Token* tok, return {}; errors.emplace_back(varDeclEndToken, "Assigned to reference."); const Token *vartok = varDeclEndToken->astOperand2(); - if (vartok == tok || (!temporary && isTemporary(true, vartok, nullptr, true) && + if (vartok == tok || (!temporary && isTemporary(vartok, nullptr, true) && (var->isConst() || var->isRValueReference()))) { SmallVector refs_result; refs_result.push_back({tok, std::move(errors)}); @@ -1527,13 +1527,14 @@ static bool astIsBoolLike(const Token* tok) return astIsBool(tok) || isUsedAsBool(tok); } -bool isSameExpression(bool cpp, bool macro, const Token *tok1, const Token *tok2, const Library& library, bool pure, bool followVar, ErrorPath* errors) +bool isSameExpression(bool macro, const Token *tok1, const Token *tok2, const Library& library, bool pure, bool followVar, ErrorPath* errors) { if (tok1 == nullptr && tok2 == nullptr) return true; if (tok1 == nullptr || tok2 == nullptr) return false; - if (cpp) { + // tokens needs to be from the same TokenList so no need check standard on both of them + if (tok1->isCpp()) { if (tok1->str() == "." && tok1->astOperand1() && tok1->astOperand1()->str() == "this") tok1 = tok1->astOperand2(); if (tok2->str() == "." && tok2->astOperand1() && tok2->astOperand1()->str() == "this") @@ -1541,10 +1542,10 @@ bool isSameExpression(bool cpp, bool macro, const Token *tok1, const Token *tok2 } // Skip double not if (Token::simpleMatch(tok1, "!") && Token::simpleMatch(tok1->astOperand1(), "!") && !Token::simpleMatch(tok1->astParent(), "=") && astIsBoolLike(tok2)) { - return isSameExpression(cpp, macro, tok1->astOperand1()->astOperand1(), tok2, library, pure, followVar, errors); + return isSameExpression(macro, tok1->astOperand1()->astOperand1(), tok2, library, pure, followVar, errors); } if (Token::simpleMatch(tok2, "!") && Token::simpleMatch(tok2->astOperand1(), "!") && !Token::simpleMatch(tok2->astParent(), "=") && astIsBoolLike(tok1)) { - return isSameExpression(cpp, macro, tok1, tok2->astOperand1()->astOperand1(), library, pure, followVar, errors); + return isSameExpression(macro, tok1, tok2->astOperand1()->astOperand1(), library, pure, followVar, errors); } const bool tok_str_eq = tok1->str() == tok2->str(); if (!tok_str_eq && isDifferentKnownValues(tok1, tok2)) @@ -1560,20 +1561,20 @@ bool isSameExpression(bool cpp, bool macro, const Token *tok1, const Token *tok2 // Follow variable if (followVar && !tok_str_eq && (followTok1->varId() || followTok2->varId() || followTok1->enumerator() || followTok2->enumerator())) { - const Token * varTok1 = followVariableExpression(followTok1, cpp, followTok2); + const Token * varTok1 = followVariableExpression(followTok1, followTok2); if ((varTok1->str() == followTok2->str()) || isSameConstantValue(macro, varTok1, followTok2)) { followVariableExpressionError(followTok1, varTok1, errors); - return isSameExpression(cpp, macro, varTok1, followTok2, library, true, followVar, errors); + return isSameExpression(macro, varTok1, followTok2, library, true, followVar, errors); } - const Token * varTok2 = followVariableExpression(followTok2, cpp, followTok1); + const Token * varTok2 = followVariableExpression(followTok2, followTok1); if ((followTok1->str() == varTok2->str()) || isSameConstantValue(macro, followTok1, varTok2)) { followVariableExpressionError(followTok2, varTok2, errors); - return isSameExpression(cpp, macro, followTok1, varTok2, library, true, followVar, errors); + return isSameExpression(macro, followTok1, varTok2, library, true, followVar, errors); } if ((varTok1->str() == varTok2->str()) || isSameConstantValue(macro, varTok1, varTok2)) { followVariableExpressionError(tok1, varTok1, errors); followVariableExpressionError(tok2, varTok2, errors); - return isSameExpression(cpp, macro, varTok1, varTok2, library, true, followVar, errors); + return isSameExpression(macro, varTok1, varTok2, library, true, followVar, errors); } } // Follow references @@ -1585,17 +1586,17 @@ bool isSameExpression(bool cpp, bool macro, const Token *tok1, const Token *tok2 const Token *start = refTok1, *end = refTok2; if (!precedes(start, end)) std::swap(start, end); - if (findExpressionChanged(start, start, end, nullptr, cpp)) + if (findExpressionChanged(start, start, end, nullptr)) return false; } - return isSameExpression(cpp, macro, refTok1, refTok2, library, pure, followVar, errors); + return isSameExpression(macro, refTok1, refTok2, library, pure, followVar, errors); } } if (tok1->varId() != tok2->varId() || !tok_str_eq || tok1->originalName() != tok2->originalName()) { if ((Token::Match(tok1,"<|>") && Token::Match(tok2,"<|>")) || (Token::Match(tok1,"<=|>=") && Token::Match(tok2,"<=|>="))) { - return isSameExpression(cpp, macro, tok1->astOperand1(), tok2->astOperand2(), library, pure, followVar, errors) && - isSameExpression(cpp, macro, tok1->astOperand2(), tok2->astOperand1(), library, pure, followVar, errors); + return isSameExpression(macro, tok1->astOperand1(), tok2->astOperand2(), library, pure, followVar, errors) && + isSameExpression(macro, tok1->astOperand2(), tok2->astOperand1(), library, pure, followVar, errors); } const Token* condTok = nullptr; const Token* exprTok = nullptr; @@ -1633,7 +1634,7 @@ bool isSameExpression(bool cpp, bool macro, const Token *tok1, const Token *tok2 } } if (compare && astIsBoolLike(varTok1) && astIsBoolLike(varTok2)) - return isSameExpression(cpp, macro, varTok1, varTok2, library, pure, followVar, errors); + return isSameExpression(macro, varTok1, varTok2, library, pure, followVar, errors); } return false; @@ -1714,15 +1715,15 @@ bool isSameExpression(bool cpp, bool macro, const Token *tok1, const Token *tok2 return false; } bool noncommutativeEquals = - isSameExpression(cpp, macro, tok1->astOperand1(), tok2->astOperand1(), library, pure, followVar, errors); + isSameExpression(macro, tok1->astOperand1(), tok2->astOperand1(), library, pure, followVar, errors); noncommutativeEquals = noncommutativeEquals && - isSameExpression(cpp, macro, tok1->astOperand2(), tok2->astOperand2(), library, pure, followVar, errors); + isSameExpression(macro, tok1->astOperand2(), tok2->astOperand2(), library, pure, followVar, errors); if (noncommutativeEquals) return true; // in c++, a+b might be different to b+a, depending on the type of a and b - if (cpp && tok1->str() == "+" && tok1->isBinaryOp()) { + if (tok1->isCpp() && tok1->str() == "+" && tok1->isBinaryOp()) { const ValueType* vt1 = tok1->astOperand1()->valueType(); const ValueType* vt2 = tok1->astOperand2()->valueType(); if (!(vt1 && (vt1->type >= ValueType::VOID || vt1->pointer) && vt2 && (vt2->type >= ValueType::VOID || vt2->pointer))) @@ -1731,9 +1732,9 @@ bool isSameExpression(bool cpp, bool macro, const Token *tok1, const Token *tok2 const bool commutative = tok1->isBinaryOp() && Token::Match(tok1, "%or%|%oror%|+|*|&|&&|^|==|!="); bool commutativeEquals = commutative && - isSameExpression(cpp, macro, tok1->astOperand2(), tok2->astOperand1(), library, pure, followVar, errors); + isSameExpression(macro, tok1->astOperand2(), tok2->astOperand1(), library, pure, followVar, errors); commutativeEquals = commutativeEquals && - isSameExpression(cpp, macro, tok1->astOperand1(), tok2->astOperand2(), library, pure, followVar, errors); + isSameExpression(macro, tok1->astOperand1(), tok2->astOperand2(), library, pure, followVar, errors); return commutativeEquals; @@ -1757,12 +1758,12 @@ static bool isZeroBoundCond(const Token * const cond) return false; } -bool isOppositeCond(bool isNot, bool cpp, const Token * const cond1, const Token * const cond2, const Library& library, bool pure, bool followVar, ErrorPath* errors) +bool isOppositeCond(bool isNot, const Token * const cond1, const Token * const cond2, const Library& library, bool pure, bool followVar, ErrorPath* errors) { if (!cond1 || !cond2) return false; - if (isSameExpression(cpp, true, cond1, cond2, library, pure, followVar, errors)) + if (isSameExpression(true, cond1, cond2, library, pure, followVar, errors)) return false; if (!isNot && cond1->str() == "&&" && cond2->str() == "&&") { @@ -1772,8 +1773,8 @@ bool isOppositeCond(bool isNot, bool cpp, const Token * const cond1, const Token for (const Token* tok2: { cond2->astOperand1(), cond2->astOperand2() }) { - if (isSameExpression(cpp, true, tok1, tok2, library, pure, followVar, errors)) { - if (isOppositeCond(isNot, cpp, tok1->astSibling(), tok2->astSibling(), library, pure, followVar, errors)) + if (isSameExpression(true, tok1, tok2, library, pure, followVar, errors)) { + if (isOppositeCond(isNot, tok1->astSibling(), tok2->astSibling(), library, pure, followVar, errors)) return true; } } @@ -1791,37 +1792,36 @@ bool isOppositeCond(bool isNot, bool cpp, const Token * const cond1, const Token orCond = cond2; otherCond = cond1; } - return isOppositeCond(isNot, cpp, orCond->astOperand1(), otherCond, library, pure, followVar, errors) && - isOppositeCond(isNot, cpp, orCond->astOperand2(), otherCond, library, pure, followVar, errors); + return isOppositeCond(isNot, orCond->astOperand1(), otherCond, library, pure, followVar, errors) && + isOppositeCond(isNot, orCond->astOperand2(), otherCond, library, pure, followVar, errors); } if (cond1->str() == "!") { if (cond2->str() == "!=") { if (cond2->astOperand1() && cond2->astOperand1()->str() == "0") - return isSameExpression(cpp, true, cond1->astOperand1(), cond2->astOperand2(), library, pure, followVar, errors); + return isSameExpression(true, cond1->astOperand1(), cond2->astOperand2(), library, pure, followVar, errors); if (cond2->astOperand2() && cond2->astOperand2()->str() == "0") - return isSameExpression(cpp, true, cond1->astOperand1(), cond2->astOperand1(), library, pure, followVar, errors); + return isSameExpression(true, cond1->astOperand1(), cond2->astOperand1(), library, pure, followVar, errors); } if (!isUsedAsBool(cond2)) return false; - return isSameExpression(cpp, true, cond1->astOperand1(), cond2, library, pure, followVar, errors); + return isSameExpression(true, cond1->astOperand1(), cond2, library, pure, followVar, errors); } if (cond2->str() == "!") - return isOppositeCond(isNot, cpp, cond2, cond1, library, pure, followVar, errors); + return isOppositeCond(isNot, cond2, cond1, library, pure, followVar, errors); if (!isNot) { if (cond1->str() == "==" && cond2->str() == "==") { - if (isSameExpression(cpp, true, cond1->astOperand1(), cond2->astOperand1(), library, pure, followVar, errors)) + if (isSameExpression(true, cond1->astOperand1(), cond2->astOperand1(), library, pure, followVar, errors)) return isDifferentKnownValues(cond1->astOperand2(), cond2->astOperand2()); - if (isSameExpression(cpp, true, cond1->astOperand2(), cond2->astOperand2(), library, pure, followVar, errors)) + if (isSameExpression(true, cond1->astOperand2(), cond2->astOperand2(), library, pure, followVar, errors)) return isDifferentKnownValues(cond1->astOperand1(), cond2->astOperand1()); } // TODO: Handle reverse conditions if (Library::isContainerYield(cond1, Library::Container::Yield::EMPTY, "empty") && Library::isContainerYield(cond2->astOperand1(), Library::Container::Yield::SIZE, "size") && - isSameExpression(cpp, - true, + isSameExpression(true, cond1->astOperand1()->astOperand1(), cond2->astOperand1()->astOperand1()->astOperand1(), library, @@ -1833,8 +1833,7 @@ bool isOppositeCond(bool isNot, bool cpp, const Token * const cond1, const Token if (Library::isContainerYield(cond2, Library::Container::Yield::EMPTY, "empty") && Library::isContainerYield(cond1->astOperand1(), Library::Container::Yield::SIZE, "size") && - isSameExpression(cpp, - true, + isSameExpression(true, cond2->astOperand1()->astOperand1(), cond1->astOperand1()->astOperand1()->astOperand1(), library, @@ -1853,11 +1852,11 @@ bool isOppositeCond(bool isNot, bool cpp, const Token * const cond1, const Token // condition found .. get comparator std::string comp2; - if (isSameExpression(cpp, true, cond1->astOperand1(), cond2->astOperand1(), library, pure, followVar, errors) && - isSameExpression(cpp, true, cond1->astOperand2(), cond2->astOperand2(), library, pure, followVar, errors)) { + if (isSameExpression(true, cond1->astOperand1(), cond2->astOperand1(), library, pure, followVar, errors) && + isSameExpression(true, cond1->astOperand2(), cond2->astOperand2(), library, pure, followVar, errors)) { comp2 = cond2->str(); - } else if (isSameExpression(cpp, true, cond1->astOperand1(), cond2->astOperand2(), library, pure, followVar, errors) && - isSameExpression(cpp, true, cond1->astOperand2(), cond2->astOperand1(), library, pure, followVar, errors)) { + } else if (isSameExpression(true, cond1->astOperand1(), cond2->astOperand2(), library, pure, followVar, errors) && + isSameExpression(true, cond1->astOperand2(), cond2->astOperand1(), library, pure, followVar, errors)) { comp2 = cond2->str(); if (comp2[0] == '>') comp2[0] = '<'; @@ -1893,7 +1892,7 @@ bool isOppositeCond(bool isNot, bool cpp, const Token * const cond1, const Token if (!expr1 || !value1 || !expr2 || !value2) { return false; } - if (!isSameExpression(cpp, true, expr1, expr2, library, pure, followVar, errors)) + if (!isSameExpression(true, expr1, expr2, library, pure, followVar, errors)) return false; const ValueFlow::Value &rhsValue1 = value1->values().front(); @@ -1921,16 +1920,16 @@ bool isOppositeCond(bool isNot, bool cpp, const Token * const cond1, const Token ))); } -bool isOppositeExpression(bool cpp, const Token * const tok1, const Token * const tok2, const Library& library, bool pure, bool followVar, ErrorPath* errors) +bool isOppositeExpression(const Token * const tok1, const Token * const tok2, const Library& library, bool pure, bool followVar, ErrorPath* errors) { if (!tok1 || !tok2) return false; - if (isOppositeCond(true, cpp, tok1, tok2, library, pure, followVar, errors)) + if (isOppositeCond(true, tok1, tok2, library, pure, followVar, errors)) return true; if (tok1->isUnaryOp("-") && !(tok2->astParent() && tok2->astParent()->tokType() == Token::eBitOp)) - return isSameExpression(cpp, true, tok1->astOperand1(), tok2, library, pure, followVar, errors); + return isSameExpression(true, tok1->astOperand1(), tok2, library, pure, followVar, errors); if (tok2->isUnaryOp("-") && !(tok2->astParent() && tok2->astParent()->tokType() == Token::eBitOp)) - return isSameExpression(cpp, true, tok2->astOperand1(), tok1, library, pure, followVar, errors); + return isSameExpression(true, tok2->astOperand1(), tok1, library, pure, followVar, errors); return false; } @@ -2023,7 +2022,7 @@ bool isConstFunctionCall(const Token* ftok, const Library& library) return true; } -bool isConstExpression(const Token *tok, const Library& library, bool cpp) +bool isConstExpression(const Token *tok, const Library& library) { if (!tok) return true; @@ -2037,17 +2036,19 @@ bool isConstExpression(const Token *tok, const Library& library, bool cpp) return false; if (tok->isAssignmentOp()) return false; - if (isLikelyStreamRead(cpp, tok)) + if (isLikelyStreamRead(tok)) return false; // bailout when we see ({..}) if (tok->str() == "{") return false; - return isConstExpression(tok->astOperand1(), library, cpp) && isConstExpression(tok->astOperand2(), library, cpp); + return isConstExpression(tok->astOperand1(), library) && isConstExpression(tok->astOperand2(), library); } -bool isWithoutSideEffects(bool cpp, const Token* tok, bool checkArrayAccess, bool checkReference) +bool isWithoutSideEffects(const Token* tok, bool checkArrayAccess, bool checkReference) { - if (!cpp) + if (!tok) + return true; + if (!tok->isCpp()) return true; while (tok && tok->astOperand2() && tok->astOperand2()->str() != "(") @@ -2520,7 +2521,7 @@ bool isVariableChangedByFunctionCall(const Token *tok, int indirect, const Setti return false; } -bool isVariableChanged(const Token *tok, int indirect, const Settings *settings, bool cpp, int depth) +bool isVariableChanged(const Token *tok, int indirect, const Settings *settings, int depth) { if (!tok) return false; @@ -2577,7 +2578,7 @@ bool isVariableChanged(const Token *tok, int indirect, const Settings *settings, const Variable * var = getLHSVariable(tok2->astParent()); if (var && var->isReference() && !var->isConst() && ((var->nameToken() && var->nameToken()->next() == tok2->astParent()) || var->isPointer())) { - if (!var->isLocal() || isVariableChanged(var, settings, cpp, depth - 1)) + if (!var->isLocal() || isVariableChanged(var, settings, depth - 1)) return true; } } @@ -2586,7 +2587,7 @@ bool isVariableChanged(const Token *tok, int indirect, const Settings *settings, // Check addressof if (tok2->astParent() && tok2->astParent()->isUnaryOp("&")) { - if (isVariableChanged(tok2->astParent(), indirect + 1, settings, cpp, depth - 1)) + if (isVariableChanged(tok2->astParent(), indirect + 1, settings, depth - 1)) return true; } else { // If its already const then it cant be modified @@ -2594,10 +2595,10 @@ bool isVariableChanged(const Token *tok, int indirect, const Settings *settings, return false; } - if (cpp && Token::Match(tok2->astParent(), ">>|&") && astIsRHS(tok2) && isLikelyStreamRead(cpp, tok2->astParent())) + if (tok2->isCpp() && Token::Match(tok2->astParent(), ">>|&") && astIsRHS(tok2) && isLikelyStreamRead(tok2->astParent())) return true; - if (isLikelyStream(cpp, tok2)) + if (isLikelyStream(tok2)) return true; // Member function call @@ -2626,14 +2627,14 @@ bool isVariableChanged(const Token *tok, int indirect, const Settings *settings, 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)) - return isVariableChanged(ftok->next(), indirect, settings, cpp, depth - 1); + return isVariableChanged(ftok->next(), indirect, settings, depth - 1); 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); + return isVariableChanged(ftok->next(), indirect + 1, settings, depth - 1); } if (contains({Library::Container::Yield::SIZE, Library::Container::Yield::EMPTY, @@ -2716,7 +2717,7 @@ bool isVariableChanged(const Token *tok, int indirect, const Settings *settings, const Variable * loopVar = varTok->variable(); if (!loopVar) return false; - if (!loopVar->isConst() && loopVar->isReference() && isVariableChanged(loopVar, settings, cpp, depth - 1)) + if (!loopVar->isConst() && loopVar->isReference() && isVariableChanged(loopVar, settings, depth - 1)) return true; return false; } @@ -2738,14 +2739,14 @@ bool isVariableChanged(const Token *tok, int indirect, const Settings *settings, return false; } -bool isVariableChanged(const Token *start, const Token *end, const nonneg int exprid, bool globalvar, const Settings *settings, bool cpp, int depth) +bool isVariableChanged(const Token *start, const Token *end, const nonneg int exprid, bool globalvar, const Settings *settings, int depth) { - return findVariableChanged(start, end, 0, exprid, globalvar, settings, cpp, depth) != nullptr; + return findVariableChanged(start, end, 0, exprid, globalvar, settings, depth) != nullptr; } -bool isVariableChanged(const Token *start, const Token *end, int indirect, const nonneg int exprid, bool globalvar, const Settings *settings, bool cpp, int depth) +bool isVariableChanged(const Token *start, const Token *end, int indirect, const nonneg int exprid, bool globalvar, const Settings *settings, int depth) { - return findVariableChanged(start, end, indirect, exprid, globalvar, settings, cpp, depth) != nullptr; + return findVariableChanged(start, end, indirect, exprid, globalvar, settings, depth) != nullptr; } const Token* findExpression(const Token* start, const nonneg int exprid) @@ -2788,7 +2789,6 @@ static bool isExpressionChangedAt(const F& getExprTok, const nonneg int exprid, bool globalvar, const Settings* settings, - bool cpp, int depth) { if (depth < 0) @@ -2809,14 +2809,14 @@ static bool isExpressionChangedAt(const F& getExprTok, aliased = isAliasOf(tok, expr, &i); if (!aliased) return false; - if (isVariableChanged(tok, indirect + i, settings, cpp, depth)) + if (isVariableChanged(tok, indirect + i, settings, depth)) return true; // TODO: Try to traverse the lambda function if (Token::Match(tok, "%var% (")) return true; return false; } - return (isVariableChanged(tok, indirect, settings, cpp, depth)); + return (isVariableChanged(tok, indirect, settings, depth)); } bool isExpressionChangedAt(const Token* expr, @@ -2824,15 +2824,14 @@ bool isExpressionChangedAt(const Token* expr, int indirect, bool globalvar, const Settings* settings, - bool cpp, int depth) { return isExpressionChangedAt([&] { return expr; - }, tok, indirect, expr->exprId(), globalvar, settings, cpp, depth); + }, tok, indirect, expr->exprId(), globalvar, settings, depth); } -Token* findVariableChanged(Token *start, const Token *end, int indirect, const nonneg int exprid, bool globalvar, const Settings *settings, bool cpp, int depth) +Token* findVariableChanged(Token *start, const Token *end, int indirect, const nonneg int exprid, bool globalvar, const Settings *settings, int depth) { if (!precedes(start, end)) return nullptr; @@ -2842,18 +2841,18 @@ Token* findVariableChanged(Token *start, const Token *end, int indirect, const n return findExpression(start, exprid); }); for (Token *tok = start; tok != end; tok = tok->next()) { - if (isExpressionChangedAt(getExprTok, tok, indirect, exprid, globalvar, settings, cpp, depth)) + if (isExpressionChangedAt(getExprTok, tok, indirect, exprid, globalvar, settings, depth)) return tok; } return nullptr; } -const Token* findVariableChanged(const Token *start, const Token *end, int indirect, const nonneg int exprid, bool globalvar, const Settings *settings, bool cpp, int depth) +const Token* findVariableChanged(const Token *start, const Token *end, int indirect, const nonneg int exprid, bool globalvar, const Settings *settings, int depth) { - return findVariableChanged(const_cast(start), end, indirect, exprid, globalvar, settings, cpp, depth); + return findVariableChanged(const_cast(start), end, indirect, exprid, globalvar, settings, depth); } -bool isVariableChanged(const Variable * var, const Settings *settings, bool cpp, int depth) +bool isVariableChanged(const Variable * var, const Settings *settings, int depth) { if (!var) return false; @@ -2869,15 +2868,14 @@ bool isVariableChanged(const Variable * var, const Settings *settings, bool cpp, if (next) start = next; } - return findExpressionChanged(var->nameToken(), start->next(), var->scope()->bodyEnd, settings, cpp, depth); + return findExpressionChanged(var->nameToken(), start->next(), var->scope()->bodyEnd, settings, depth); } bool isVariablesChanged(const Token* start, const Token* end, int indirect, const std::vector &vars, - const Settings* settings, - bool cpp) + const Settings* settings) { std::set varids; std::transform(vars.cbegin(), vars.cend(), std::inserter(varids, varids.begin()), [](const Variable* var) { @@ -2893,13 +2891,13 @@ bool isVariablesChanged(const Token* start, return true; continue; } - if (isVariableChanged(tok, indirect, settings, cpp)) + if (isVariableChanged(tok, indirect, settings)) return true; } return false; } -bool isThisChanged(const Token* tok, int indirect, const Settings* settings, bool cpp) +bool isThisChanged(const Token* tok, int indirect, const Settings* settings) { if ((Token::Match(tok->previous(), "%name% (") && !Token::simpleMatch(tok->astOperand1(), ".")) || Token::Match(tok->tokAt(-3), "this . %name% (")) { @@ -2910,19 +2908,19 @@ bool isThisChanged(const Token* tok, int indirect, const Settings* settings, boo return true; } } - if (isVariableChanged(tok, indirect, settings, cpp)) + if (isVariableChanged(tok, indirect, settings)) return true; return false; } -const Token* findThisChanged(const Token* start, const Token* end, int indirect, const Settings* settings, bool cpp) +const Token* findThisChanged(const Token* start, const Token* end, int indirect, const Settings* settings) { if (!precedes(start, end)) return nullptr; for (const Token* tok = start; tok != end; tok = tok->next()) { if (!exprDependsOnThis(tok)) continue; - if (isThisChanged(tok, indirect, settings, cpp)) + if (isThisChanged(tok, indirect, settings)) return tok; } return nullptr; @@ -2933,7 +2931,6 @@ static const Token* findExpressionChangedImpl(const Token* expr, const Token* start, const Token* end, const Settings* settings, - bool cpp, int depth, Find find) { @@ -2944,7 +2941,7 @@ static const Token* findExpressionChangedImpl(const Token* expr, const Token* result = nullptr; findAstNode(expr, [&](const Token* tok) { if (exprDependsOnThis(tok)) { - result = findThisChanged(start, end, /*indirect*/ 0, settings, cpp); + result = findThisChanged(start, end, /*indirect*/ 0, settings); if (result) return true; } @@ -2967,7 +2964,7 @@ static const Token* findExpressionChangedImpl(const Token* expr, ++indirect; } for (int i = 0; i <= indirect; ++i) - if (isExpressionChangedAt(tok, tok2, i, global, settings, cpp, depth)) + if (isExpressionChangedAt(tok, tok2, i, global, settings, depth)) return true; return false; }); @@ -3009,22 +3006,20 @@ const Token* findExpressionChanged(const Token* expr, const Token* start, const Token* end, const Settings* settings, - bool cpp, int depth) { - return findExpressionChangedImpl(expr, start, end, settings, cpp, depth, ExpressionChangedSimpleFind{}); + return findExpressionChangedImpl(expr, start, end, settings, depth, ExpressionChangedSimpleFind{}); } const Token* findExpressionChangedSkipDeadCode(const Token* expr, const Token* start, const Token* end, const Settings* settings, - bool cpp, const std::function(const Token* tok)>& evaluate, int depth) { return findExpressionChangedImpl( - expr, start, end, settings, cpp, depth, ExpressionChangedSkipDeadCode{&settings->library, evaluate}); + expr, start, end, settings, depth, ExpressionChangedSkipDeadCode{&settings->library, evaluate}); } const Token* getArgumentStart(const Token* ftok) @@ -3183,12 +3178,12 @@ Token* findLambdaEndToken(Token* first) return findLambdaEndTokenGeneric(first); } -bool isLikelyStream(bool cpp, const Token *stream) +bool isLikelyStream(const Token *stream) { - if (!cpp) + if (!stream) return false; - if (!stream) + if (!stream->isCpp()) return false; if (!Token::Match(stream->astParent(), "&|<<|>>") || !stream->astParent()->isBinaryOp()) @@ -3200,9 +3195,12 @@ bool isLikelyStream(bool cpp, const Token *stream) return !astIsIntegral(stream, false); } -bool isLikelyStreamRead(bool cpp, const Token *op) +bool isLikelyStreamRead(const Token *op) { - if (!cpp) + if (!op) + return false; + + if (!op->isCpp()) return false; if (!Token::Match(op, "&|>>") || !op->isBinaryOp()) @@ -3324,7 +3322,7 @@ bool isLeafDot(const Token* tok) return isLeafDot(parent); } -ExprUsage getExprUsage(const Token* tok, int indirect, const Settings* settings, bool cpp) +ExprUsage getExprUsage(const Token* tok, int indirect, const Settings* settings) { const Token* parent = tok->astParent(); if (indirect > 0 && parent) { @@ -3339,12 +3337,12 @@ ExprUsage getExprUsage(const Token* tok, int indirect, const Settings* settings, if (parent->isCast()) return ExprUsage::NotUsed; if (Token::simpleMatch(parent, ":") && Token::simpleMatch(parent->astParent(), "?")) - return getExprUsage(parent->astParent(), indirect, settings, cpp); + return getExprUsage(parent->astParent(), indirect, settings); } if (indirect == 0) { if (Token::Match(parent, "%cop%|%assign%|++|--") && parent->str() != "=" && !parent->isUnaryOp("&") && - !(astIsRHS(tok) && isLikelyStreamRead(cpp, parent))) + !(astIsRHS(tok) && isLikelyStreamRead(parent))) return ExprUsage::Used; if (isLeafDot(tok)) { const Token* op = parent->astParent(); @@ -3478,7 +3476,7 @@ bool isNullOperand(const Token *expr) return Token::Match(castOp, "NULL|nullptr") || (MathLib::isInt(castOp->str()) && MathLib::isNullValue(castOp->str())); } -bool isGlobalData(const Token *expr, bool cpp) +bool isGlobalData(const Token *expr) { // function call that returns reference => assume global data if (expr && expr->str() == "(" && expr->valueType() && expr->valueType()->reference != Reference::None) { @@ -3491,7 +3489,7 @@ bool isGlobalData(const Token *expr, bool cpp) bool globalData = false; bool var = false; visitAstNodes(expr, - [expr, cpp, &globalData, &var](const Token *tok) { + [expr, &globalData, &var](const Token *tok) { if (tok->varId()) var = true; if (tok->varId() && !tok->variable()) { @@ -3549,7 +3547,7 @@ bool isGlobalData(const Token *expr, bool cpp) } } // Unknown argument type => it might be some reference type.. - if (cpp && tok->str() == "." && tok->astOperand1() && tok->astOperand1()->variable() && !tok->astOperand1()->valueType()) { + if (tok->isCpp() && tok->str() == "." && tok->astOperand1() && tok->astOperand1()->variable() && !tok->astOperand1()->valueType()) { globalData = true; return ChildrenToVisit::none; } diff --git a/lib/astutils.h b/lib/astutils.h index e39b61b33d6..10699f8de61 100644 --- a/lib/astutils.h +++ b/lib/astutils.h @@ -194,7 +194,7 @@ const Token * astIsVariableComparison(const Token *tok, const std::string &comp, bool isVariableDecl(const Token* tok); bool isStlStringType(const Token* tok); -bool isTemporary(bool cpp, const Token* tok, const Library* library, bool unknown = false); +bool isTemporary(const Token* tok, const Library* library, bool unknown = false); const Token* previousBeforeAstLeftmostLeaf(const Token* tok); Token* previousBeforeAstLeftmostLeaf(Token* tok); @@ -208,7 +208,7 @@ const Token* astParentSkipParens(const Token* tok); const Token* getParentMember(const Token * tok); const Token* getParentLifetime(const Token* tok); -const Token* getParentLifetime(bool cpp, const Token* tok, const Library* library); +const Token* getParentLifetime(const Token* tok, const Library* library); std::vector getParentValueTypes(const Token* tok, const Settings* settings = nullptr, @@ -261,7 +261,7 @@ SmallVector followAllReferences(const Token* tok, int depth = 20); const Token* followReferences(const Token* tok, ErrorPath* errors = nullptr); -CPPCHECKLIB bool isSameExpression(bool cpp, bool macro, const Token *tok1, const Token *tok2, const Library& library, bool pure, bool followVar, ErrorPath* errors=nullptr); +CPPCHECKLIB bool isSameExpression(bool macro, const Token *tok1, const Token *tok2, const Library& library, bool pure, bool followVar, ErrorPath* errors=nullptr); bool isEqualKnownValue(const Token * const tok1, const Token * const tok2); @@ -282,21 +282,20 @@ bool compareTokenFlags(const Token* tok1, const Token* tok2, bool macro); /** * Are two conditions opposite * @param isNot do you want to know if cond1 is !cond2 or if cond1 and cond2 are non-overlapping. true: cond1==!cond2 false: cond1==true => cond2==false - * @param cpp c++ file * @param cond1 condition1 * @param cond2 condition2 * @param library files data * @param pure boolean */ -bool isOppositeCond(bool isNot, bool cpp, const Token * const cond1, const Token * const cond2, const Library& library, bool pure, bool followVar, ErrorPath* errors=nullptr); +bool isOppositeCond(bool isNot, const Token * const cond1, const Token * const cond2, const Library& library, bool pure, bool followVar, ErrorPath* errors=nullptr); -bool isOppositeExpression(bool cpp, const Token * const tok1, const Token * const tok2, const Library& library, bool pure, bool followVar, ErrorPath* errors=nullptr); +bool isOppositeExpression(const Token * const tok1, const Token * const tok2, const Library& library, bool pure, bool followVar, ErrorPath* errors=nullptr); bool isConstFunctionCall(const Token* ftok, const Library& library); -bool isConstExpression(const Token *tok, const Library& library, bool cpp); +bool isConstExpression(const Token *tok, const Library& library); -bool isWithoutSideEffects(bool cpp, const Token* tok, bool checkArrayAccess = false, bool checkReference = true); +bool isWithoutSideEffects(const Token* tok, bool checkArrayAccess = false, bool checkReference = true); bool isUniqueExpression(const Token* tok); @@ -341,38 +340,35 @@ bool isVariableChangedByFunctionCall(const Token *tok, int indirect, nonneg int CPPCHECKLIB bool isVariableChangedByFunctionCall(const Token *tok, int indirect, const Settings *settings, bool *inconclusive); /** Is variable changed in block of code? */ -CPPCHECKLIB bool isVariableChanged(const Token *start, const Token *end, const nonneg int exprid, bool globalvar, const Settings *settings, bool cpp, int depth = 20); -bool isVariableChanged(const Token *start, const Token *end, int indirect, const nonneg int exprid, bool globalvar, const Settings *settings, bool cpp, int depth = 20); +CPPCHECKLIB bool isVariableChanged(const Token *start, const Token *end, const nonneg int exprid, bool globalvar, const Settings *settings, int depth = 20); +bool isVariableChanged(const Token *start, const Token *end, int indirect, const nonneg int exprid, bool globalvar, const Settings *settings, int depth = 20); -bool isVariableChanged(const Token *tok, int indirect, const Settings *settings, bool cpp, int depth = 20); +bool isVariableChanged(const Token *tok, int indirect, const Settings *settings, int depth = 20); -bool isVariableChanged(const Variable * var, const Settings *settings, bool cpp, int depth = 20); +bool isVariableChanged(const Variable * var, const Settings *settings, int depth = 20); bool isVariablesChanged(const Token* start, const Token* end, int indirect, const std::vector &vars, - const Settings* settings, - bool cpp); + const Settings* settings); -bool isThisChanged(const Token* tok, int indirect, const Settings* settings, bool cpp); -const Token* findThisChanged(const Token* start, const Token* end, int indirect, const Settings* settings, bool cpp); +bool isThisChanged(const Token* tok, int indirect, const Settings* settings); +const Token* findThisChanged(const Token* start, const Token* end, int indirect, const Settings* settings); -const Token* findVariableChanged(const Token *start, const Token *end, int indirect, const nonneg int exprid, bool globalvar, const Settings *settings, bool cpp, int depth = 20); -Token* findVariableChanged(Token *start, const Token *end, int indirect, const nonneg int exprid, bool globalvar, const Settings *settings, bool cpp, int depth = 20); +const Token* findVariableChanged(const Token *start, const Token *end, int indirect, const nonneg int exprid, bool globalvar, const Settings *settings, int depth = 20); +Token* findVariableChanged(Token *start, const Token *end, int indirect, const nonneg int exprid, bool globalvar, const Settings *settings, int depth = 20); CPPCHECKLIB const Token* findExpressionChanged(const Token* expr, const Token* start, const Token* end, const Settings* settings, - bool cpp, int depth = 20); const Token* findExpressionChangedSkipDeadCode(const Token* expr, const Token* start, const Token* end, const Settings* settings, - bool cpp, const std::function(const Token* tok)>& evaluate, int depth = 20); @@ -381,7 +377,6 @@ bool isExpressionChangedAt(const Token* expr, int indirect, bool globalvar, const Settings* settings, - bool cpp, int depth = 20); /// If token is an alias if another variable @@ -426,14 +421,14 @@ CPPCHECKLIB const Token *findLambdaStartToken(const Token *last); CPPCHECKLIB const Token *findLambdaEndToken(const Token *first); CPPCHECKLIB Token* findLambdaEndToken(Token* first); -bool isLikelyStream(bool cpp, const Token *stream); +bool isLikelyStream(const Token *stream); /** * do we see a likely write of rhs through overloaded operator * s >> x; * a & x; */ -bool isLikelyStreamRead(bool cpp, const Token *op); +bool isLikelyStreamRead(const Token *op); bool isCPPCast(const Token* tok); @@ -443,7 +438,7 @@ bool isLeafDot(const Token* tok); enum class ExprUsage { None, NotUsed, PassedByReference, Used, Inconclusive }; -ExprUsage getExprUsage(const Token* tok, int indirect, const Settings* settings, bool cpp); +ExprUsage getExprUsage(const Token* tok, int indirect, const Settings* settings); const Variable *getLHSVariable(const Token *tok); @@ -458,7 +453,7 @@ bool isScopeBracket(const Token* tok); CPPCHECKLIB bool isNullOperand(const Token *expr); -bool isGlobalData(const Token *expr, bool cpp); +bool isGlobalData(const Token *expr); bool isUnevaluated(const Token *tok); diff --git a/lib/checkautovariables.cpp b/lib/checkautovariables.cpp index 766cc185ade..7434fb3be3a 100644 --- a/lib/checkautovariables.cpp +++ b/lib/checkautovariables.cpp @@ -296,7 +296,7 @@ void CheckAutoVariables::autoVariables() } // Invalid pointer deallocation else if ((Token::Match(tok, "%name% ( %var%|%str% ) ;") && mSettings->library.getDeallocFuncInfo(tok)) || - (mTokenizer->isCPP() && Token::Match(tok, "delete [| ]| (| %var%|%str% !!["))) { + (tok->isCpp() && Token::Match(tok, "delete [| ]| (| %var%|%str% !!["))) { tok = Token::findmatch(tok->next(), "%var%|%str%"); if (Token::simpleMatch(tok->astParent(), ".")) continue; @@ -314,7 +314,7 @@ void CheckAutoVariables::autoVariables() } } } else if ((Token::Match(tok, "%name% ( & %var% ) ;") && mSettings->library.getDeallocFuncInfo(tok)) || - (mTokenizer->isCPP() && Token::Match(tok, "delete [| ]| (| & %var% !!["))) { + (tok->isCpp() && Token::Match(tok, "delete [| ]| (| & %var% !!["))) { tok = Token::findmatch(tok->next(), "%var%"); if (isAutoVar(tok)) errorInvalidDeallocation(tok, nullptr); @@ -463,9 +463,9 @@ static int getPointerDepth(const Token *tok) return n; } -static bool isDeadTemporary(bool cpp, const Token* tok, const Token* expr, const Library* library) +static bool isDeadTemporary(const Token* tok, const Token* expr, const Library* library) { - if (!isTemporary(cpp, tok, library)) + if (!isTemporary(tok, library)) return false; if (expr) { if (!precedes(nextAfterAstRightmostLeaf(tok->astTop()), nextAfterAstRightmostLeaf(expr->astTop()))) @@ -495,7 +495,7 @@ static bool isEscapedReference(const Variable* var) if (!Token::simpleMatch(varDeclEndToken, "=")) return false; const Token* vartok = varDeclEndToken->astOperand2(); - return !isTemporary(true, vartok, nullptr, false); + return !isTemporary(vartok, nullptr, false); } static bool isDanglingSubFunction(const Token* tokvalue, const Token* tok) @@ -562,7 +562,7 @@ void CheckAutoVariables::checkVarLifetimeScope(const Token * start, const Token errorReturnReference(tok, lt.errorPath, lt.inconclusive); break; } - if (isDeadTemporary(mTokenizer->isCPP(), lt.token, nullptr, &mSettings->library)) { + if (isDeadTemporary(lt.token, nullptr, &mSettings->library)) { errorReturnTempReference(tok, lt.errorPath, lt.inconclusive); break; } @@ -584,7 +584,7 @@ void CheckAutoVariables::checkVarLifetimeScope(const Token * start, const Token if (!printInconclusive && lt.inconclusive) continue; const Token * tokvalue = lt.token; - if (isDeadTemporary(mTokenizer->isCPP(), tokvalue, tok, &mSettings->library)) { + if (isDeadTemporary(tokvalue, tok, &mSettings->library)) { errorDanglingTempReference(tok, lt.errorPath, lt.inconclusive); break; } @@ -598,7 +598,7 @@ void CheckAutoVariables::checkVarLifetimeScope(const Token * start, const Token continue; if (!printInconclusive && val.isInconclusive()) continue; - const Token* parent = getParentLifetime(mTokenizer->isCPP(), val.tokvalue, &mSettings->library); + const Token* parent = getParentLifetime(val.tokvalue, &mSettings->library); if (!exprs.insert(parent).second) continue; for (const ValueFlow::LifetimeToken& lt : ValueFlow::getLifetimeTokens(parent, escape || isAssignedToNonLocal(tok))) { @@ -614,7 +614,7 @@ void CheckAutoVariables::checkVarLifetimeScope(const Token * start, const Token continue; if ((tokvalue->variable() && !isEscapedReference(tokvalue->variable()) && isInScope(tokvalue->variable()->nameToken(), scope)) || - isDeadTemporary(mTokenizer->isCPP(), tokvalue, nullptr, &mSettings->library)) { + isDeadTemporary(tokvalue, nullptr, &mSettings->library)) { errorReturnDanglingLifetime(tok, &val); break; } @@ -622,7 +622,7 @@ void CheckAutoVariables::checkVarLifetimeScope(const Token * start, const Token errorInvalidLifetime(tok, &val); break; } else if (!tokvalue->variable() && - isDeadTemporary(mTokenizer->isCPP(), tokvalue, tok, &mSettings->library)) { + isDeadTemporary(tokvalue, tok, &mSettings->library)) { if (!diag(tokvalue)) errorDanglingTemporaryLifetime(tok, &val, tokvalue); break; @@ -650,8 +650,7 @@ void CheckAutoVariables::checkVarLifetimeScope(const Token * start, const Token tok->scope()->bodyEnd, var->declarationId(), var->isGlobal(), - mSettings, - mTokenizer->isCPP())) { + mSettings)) { errorDanglngLifetime(tok2, &val); break; } diff --git a/lib/checkbool.cpp b/lib/checkbool.cpp index 16e1471db07..609fc4c701a 100644 --- a/lib/checkbool.cpp +++ b/lib/checkbool.cpp @@ -122,7 +122,7 @@ void CheckBool::checkBitwiseOnBoolean() if (tok->str() == "|" && !isConvertedToBool(tok) && !(isBoolOp1 && isBoolOp2)) continue; // first operand will always be evaluated - if (!isConstExpression(tok->astOperand2(), mSettings->library, mTokenizer->isCPP())) + if (!isConstExpression(tok->astOperand2(), mSettings->library)) continue; if (tok->astOperand2()->variable() && tok->astOperand2()->variable()->nameToken() == tok->astOperand2()) continue; diff --git a/lib/checkbufferoverrun.cpp b/lib/checkbufferoverrun.cpp index 49cb2036ff3..5c5cc5e0c81 100644 --- a/lib/checkbufferoverrun.cpp +++ b/lib/checkbufferoverrun.cpp @@ -327,7 +327,7 @@ void CheckBufferOverrun::arrayIndex() const Token* changeTok = var->scope()->bodyStart; bool isChanged = false; while ((changeTok = findVariableChanged(changeTok->next(), var->scope()->bodyEnd, /*indirect*/ 0, var->declarationId(), - /*globalvar*/ false, mSettings, mTokenizer->isCPP()))) { + /*globalvar*/ false, mSettings))) { if (!Token::simpleMatch(changeTok->astParent(), "[")) { isChanged = true; break; @@ -793,7 +793,7 @@ void CheckBufferOverrun::stringNotZeroTerminated() const Token *rhs = tok2->next()->astOperand2(); if (!rhs || !rhs->hasKnownIntValue() || rhs->getKnownIntValue() != 0) continue; - if (isSameExpression(mTokenizer->isCPP(), false, args[0], tok2->link()->astOperand1(), mSettings->library, false, false)) + if (isSameExpression(false, args[0], tok2->link()->astOperand1(), mSettings->library, false, false)) isZeroTerminated = true; } if (isZeroTerminated) @@ -1090,7 +1090,7 @@ void CheckBufferOverrun::objectIndex() if (var->valueType()->pointer > obj->valueType()->pointer) continue; } - if (obj->valueType() && var->valueType() && (obj->isCast() || (mTokenizer->isCPP() && isCPPCast(obj)) || obj->valueType()->pointer)) { // allow cast to a different type + if (obj->valueType() && var->valueType() && (obj->isCast() || (obj->isCpp() && isCPPCast(obj)) || obj->valueType()->pointer)) { // allow cast to a different type const auto varSize = var->valueType()->typeSize(mSettings->platform); if (varSize == 0) continue; diff --git a/lib/checkclass.cpp b/lib/checkclass.cpp index 7e4d4adc443..627f15574b7 100644 --- a/lib/checkclass.cpp +++ b/lib/checkclass.cpp @@ -503,7 +503,7 @@ void CheckClass::copyconstructors() } } for (tok = func.functionScope->bodyStart; tok != func.functionScope->bodyEnd; tok = tok->next()) { - if ((mTokenizer->isCPP() && Token::Match(tok, "%var% = new")) || + if ((tok->isCpp() && Token::Match(tok, "%var% = new")) || (Token::Match(tok, "%var% = %name% (") && (mSettings->library.getAllocFuncInfo(tok->tokAt(2)) || mSettings->library.getReallocFuncInfo(tok->tokAt(2))))) { allocatedVars.erase(tok->varId()); } else if (Token::Match(tok, "%var% = %name% . %name% ;") && allocatedVars.find(tok->varId()) != allocatedVars.end()) { @@ -817,7 +817,7 @@ void CheckClass::initializeVarList(const Function &func, std::list>|& %name%") && isLikelyStreamRead(true, ftok)) { + if (Token::Match(ftok, ">>|& %name%") && isLikelyStreamRead(ftok)) { assignVar(usage, ftok->next()->varId()); } @@ -1771,7 +1771,7 @@ bool CheckClass::hasAllocation(const Function *func, const Scope* scope, const T if (!end) end = func->functionScope->bodyEnd; for (const Token *tok = start; tok && (tok != end); tok = tok->next()) { - if (((mTokenizer->isCPP() && Token::Match(tok, "%var% = new")) || + if (((tok->isCpp() && Token::Match(tok, "%var% = new")) || (Token::Match(tok, "%var% = %name% (") && mSettings->library.getAllocFuncInfo(tok->tokAt(2)))) && isMemberVar(scope, tok)) return true; @@ -1780,9 +1780,9 @@ bool CheckClass::hasAllocation(const Function *func, const Scope* scope, const T const Token *var; if (Token::Match(tok, "%name% ( %var%") && mSettings->library.getDeallocFuncInfo(tok)) var = tok->tokAt(2); - else if (mTokenizer->isCPP() && Token::Match(tok, "delete [ ] %var%")) + else if (tok->isCpp() && Token::Match(tok, "delete [ ] %var%")) var = tok->tokAt(3); - else if (mTokenizer->isCPP() && Token::Match(tok, "delete %var%")) + else if (tok->isCpp() && Token::Match(tok, "delete %var%")) var = tok->next(); else continue; @@ -2552,7 +2552,7 @@ bool CheckClass::checkConstFunc(const Scope *scope, const Function *func, Member // Streaming else if (end->strAt(1) == "<<" && tok1->strAt(-1) != "<<") return false; - else if (isLikelyStreamRead(true, tok1->previous())) + else if (isLikelyStreamRead(tok1->previous())) return false; // ++/-- @@ -2581,7 +2581,7 @@ bool CheckClass::checkConstFunc(const Scope *scope, const Function *func, Member } // streaming: >> *this - else if (Token::simpleMatch(tok1, ">> * this") && isLikelyStreamRead(true, tok1)) { + else if (Token::simpleMatch(tok1, ">> * this") && isLikelyStreamRead(tok1)) { return false; } diff --git a/lib/checkcondition.cpp b/lib/checkcondition.cpp index b39b69cbd40..f5e250a0cd8 100644 --- a/lib/checkcondition.cpp +++ b/lib/checkcondition.cpp @@ -200,7 +200,7 @@ bool CheckCondition::assignIfParseScope(const Token * const assignTok, // is variable changed in loop? const Token *bodyStart = tok2->linkAt(1)->next(); const Token *bodyEnd = bodyStart ? bodyStart->link() : nullptr; - if (!bodyEnd || bodyEnd->str() != "}" || isVariableChanged(bodyStart, bodyEnd, varid, !islocal, mSettings, mTokenizer->isCPP())) + if (!bodyEnd || bodyEnd->str() != "}" || isVariableChanged(bodyStart, bodyEnd, varid, !islocal, mSettings)) continue; } @@ -435,7 +435,7 @@ bool CheckCondition::isOverlappingCond(const Token * const cond1, const Token * return false; // same expressions - if (isSameExpression(mTokenizer->isCPP(), true, cond1, cond2, mSettings->library, pure, false)) + if (isSameExpression(true, cond1, cond2, mSettings->library, pure, false)) return true; // bitwise overlap for example 'x&7' and 'x==1' @@ -458,7 +458,7 @@ bool CheckCondition::isOverlappingCond(const Token * const cond1, const Token * if (!num2->isNumber() || MathLib::isNegative(num2->str())) return false; - if (!isSameExpression(mTokenizer->isCPP(), true, expr1, expr2, mSettings->library, pure, false)) + if (!isSameExpression(true, expr1, expr2, mSettings->library, pure, false)) return false; const MathLib::bigint value1 = MathLib::toBigNumber(num1->str()); @@ -503,8 +503,8 @@ void CheckCondition::duplicateCondition() continue; ErrorPath errorPath; - if (!findExpressionChanged(cond1, scope.classDef->next(), cond2, mSettings, mTokenizer->isCPP()) && - isSameExpression(mTokenizer->isCPP(), true, cond1, cond2, mSettings->library, true, true, &errorPath)) + if (!findExpressionChanged(cond1, scope.classDef->next(), cond2, mSettings) && + isSameExpression(true, cond1, cond2, mSettings->library, true, true, &errorPath)) duplicateConditionError(cond1, cond2, std::move(errorPath)); } } @@ -553,11 +553,11 @@ void CheckCondition::multiCondition() if (tok2->astOperand2()) { ErrorPath errorPath; if (isOverlappingCond(cond1, tok2->astOperand2(), true) && - !findExpressionChanged(cond1, cond1, tok2->astOperand2(), mSettings, mTokenizer->isCPP())) + !findExpressionChanged(cond1, cond1, tok2->astOperand2(), mSettings)) overlappingElseIfConditionError(tok2->astOperand2(), cond1->linenr()); else if (isOppositeCond( - true, mTokenizer->isCPP(), cond1, tok2->astOperand2(), mSettings->library, true, true, &errorPath) && - !findExpressionChanged(cond1, cond1, tok2->astOperand2(), mSettings, mTokenizer->isCPP())) + true, cond1, tok2->astOperand2(), mSettings->library, true, true, &errorPath) && + !findExpressionChanged(cond1, cond1, tok2->astOperand2(), mSettings)) oppositeElseIfConditionError(cond1, tok2->astOperand2(), std::move(errorPath)); } } @@ -665,7 +665,7 @@ void CheckCondition::multiCondition2() } } else if (!nonlocal && cond->isName()) { // varid is 0. this is possibly a nonlocal variable.. - nonlocal = Token::Match(cond->astParent(), "%cop%|(|[") || Token::Match(cond, "%name% .") || (mTokenizer->isCPP() && cond->str() == "this"); + nonlocal = Token::Match(cond->astParent(), "%cop%|(|[") || Token::Match(cond, "%name% .") || (cond->isCpp() && cond->str() == "this"); } else { return ChildrenToVisit::op1_and_op2; } @@ -703,13 +703,13 @@ void CheckCondition::multiCondition2() const Token * const endToken = tok->scope()->bodyEnd; for (; tok && tok != endToken; tok = tok->next()) { - if (isExpressionChangedAt(cond1, tok, 0, false, mSettings, mTokenizer->isCPP())) + if (isExpressionChangedAt(cond1, tok, 0, false, mSettings)) break; if (Token::Match(tok, "if|return")) { const Token * condStartToken = tok->str() == "if" ? tok->next() : tok; const Token * condEndToken = tok->str() == "if" ? condStartToken->link() : Token::findsimplematch(condStartToken, ";"); // Does condition modify tracked variables? - if (findExpressionChanged(cond1, condStartToken, condEndToken, mSettings, mTokenizer->isCPP())) + if (findExpressionChanged(cond1, condStartToken, condEndToken, mSettings)) break; // Condition.. @@ -723,14 +723,14 @@ void CheckCondition::multiCondition2() if (!firstCondition) return ChildrenToVisit::none; if (firstCondition->str() == "&&") { - if (!isOppositeCond(false, mTokenizer->isCPP(), firstCondition, cond2, mSettings->library, true, true)) + if (!isOppositeCond(false, firstCondition, cond2, mSettings->library, true, true)) return ChildrenToVisit::op1_and_op2; } if (!firstCondition->hasKnownIntValue()) { - if (!isReturnVar && isOppositeCond(false, mTokenizer->isCPP(), firstCondition, cond2, mSettings->library, true, true, &errorPath)) { + if (!isReturnVar && isOppositeCond(false, firstCondition, cond2, mSettings->library, true, true, &errorPath)) { if (!isAliased(vars)) oppositeInnerConditionError(firstCondition, cond2, errorPath); - } else if (!isReturnVar && isSameExpression(mTokenizer->isCPP(), true, firstCondition, cond2, mSettings->library, true, true, &errorPath)) { + } else if (!isReturnVar && isSameExpression(true, firstCondition, cond2, mSettings->library, true, true, &errorPath)) { identicalInnerConditionError(firstCondition, cond2, errorPath); } } @@ -742,7 +742,7 @@ void CheckCondition::multiCondition2() return ChildrenToVisit::op1_and_op2; if ((!cond1->hasKnownIntValue() || !secondCondition->hasKnownIntValue()) && - isSameExpression(mTokenizer->isCPP(), true, cond1, secondCondition, mSettings->library, true, true, &errorPath)) { + isSameExpression(true, cond1, secondCondition, mSettings->library, true, true, &errorPath)) { if (!isAliased(vars) && !mTokenizer->hasIfdef(cond1, secondCondition)) { identicalConditionAfterEarlyExitError(cond1, secondCondition, errorPath); return ChildrenToVisit::done; @@ -753,7 +753,7 @@ void CheckCondition::multiCondition2() } } if (Token::Match(tok, "%name% (") && - isVariablesChanged(tok, tok->linkAt(1), 0, varsInCond, mSettings, mTokenizer->isCPP())) { + isVariablesChanged(tok, tok->linkAt(1), 0, varsInCond, mSettings)) { break; } if (Token::Match(tok, "%type% (") && nonlocal && isNonConstFunctionCall(tok, mSettings->library)) // non const function call -> bailout if there are nonlocal variables @@ -782,7 +782,7 @@ void CheckCondition::multiCondition2() break; } const bool changed = std::any_of(vars.cbegin(), vars.cend(), [&](int varid) { - return isVariableChanged(tok1, tok2, varid, nonlocal, mSettings, mTokenizer->isCPP()); + return isVariableChanged(tok1, tok2, varid, nonlocal, mSettings); }); if (changed) break; @@ -799,9 +799,9 @@ void CheckCondition::multiCondition2() if (Token::Match(parent->astParent(), "%assign%|++|--")) break; } - if (mTokenizer->isCPP() && Token::Match(tok, "%name% <<") && (!tok->valueType() || !tok->valueType()->isIntegral())) + if (tok->isCpp() && Token::Match(tok, "%name% <<") && (!tok->valueType() || !tok->valueType()->isIntegral())) break; - if (isLikelyStreamRead(mTokenizer->isCPP(), tok->next()) || isLikelyStreamRead(mTokenizer->isCPP(), tok->previous())) + if (isLikelyStreamRead(tok->next()) || isLikelyStreamRead(tok->previous())) break; if (Token::Match(tok, "%name% [")) { const Token *tok2 = tok->linkAt(1); @@ -1145,7 +1145,7 @@ void CheckCondition::checkIncorrectLogicOperator() ((tok->str() == "||" && tok->astOperand2()->str() == "&&") || (tok->str() == "&&" && tok->astOperand2()->str() == "||"))) { const Token* tok2 = tok->astOperand2()->astOperand1(); - if (isOppositeCond(true, mTokenizer->isCPP(), tok->astOperand1(), tok2, mSettings->library, true, false)) { + if (isOppositeCond(true, tok->astOperand1(), tok2, mSettings->library, true, false)) { std::string expr1(tok->astOperand1()->expressionString()); std::string expr2(tok->astOperand2()->astOperand1()->expressionString()); std::string expr3(tok->astOperand2()->astOperand2()->expressionString()); @@ -1177,7 +1177,7 @@ void CheckCondition::checkIncorrectLogicOperator() redundantConditionError(tok, msg, false); continue; } - if (isSameExpression(mTokenizer->isCPP(), false, tok->astOperand1(), tok2, mSettings->library, true, true)) { + if (isSameExpression(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()); @@ -1242,7 +1242,7 @@ void CheckCondition::checkIncorrectLogicOperator() // Opposite comparisons around || or && => always true or always false const bool isLogicalOr(tok->str() == "||"); - if (!isfloat && isOppositeCond(isLogicalOr, mTokenizer->isCPP(), tok->astOperand1(), tok->astOperand2(), mSettings->library, true, true, &errorPath)) { + if (!isfloat && isOppositeCond(isLogicalOr, tok->astOperand1(), tok->astOperand2(), mSettings->library, true, true, &errorPath)) { if (!isIfConstexpr(tok)) { const bool alwaysTrue(isLogicalOr); incorrectLogicOperatorError(tok, conditionString(tok), alwaysTrue, inconclusive, errorPath); @@ -1253,9 +1253,9 @@ void CheckCondition::checkIncorrectLogicOperator() if (!parseable) continue; - if (isSameExpression(mTokenizer->isCPP(), true, comp1, comp2, mSettings->library, true, true)) + if (isSameExpression(true, comp1, comp2, mSettings->library, true, true)) continue; // same expressions => only report that there are same expressions - if (!isSameExpression(mTokenizer->isCPP(), true, expr1, expr2, mSettings->library, true, true)) + if (!isSameExpression(true, expr1, expr2, mSettings->library, true, true)) continue; @@ -1555,9 +1555,8 @@ void CheckCondition::alwaysTrueFalse() continue; if (Token::Match(tok->astOperand1(), "%name% (") && Token::simpleMatch(tok->astParent(), "return")) continue; - if (tok->isComparisonOp() && isWithoutSideEffects(mTokenizer->isCPP(), tok->astOperand1()) && - isSameExpression(mTokenizer->isCPP(), - true, + if (tok->isComparisonOp() && isWithoutSideEffects(tok->astOperand1()) && + isSameExpression(true, tok->astOperand1(), tok->astOperand2(), mSettings->library, @@ -1685,8 +1684,7 @@ void CheckCondition::checkInvalidTestForOverflow() if (expr->hasKnownIntValue()) continue; - if (!isSameExpression(mTokenizer->isCPP(), - true, + if (!isSameExpression(true, expr, lhs->astSibling(), mSettings->library, @@ -1836,10 +1834,10 @@ void CheckCondition::checkDuplicateConditionalAssign() isRedundant = (isNegation && val == 0) || (!isNegation && val == 1); } else { // comparison if (!isSameExpression( - mTokenizer->isCPP(), true, condTok->astOperand1(), assignTok->astOperand1(), mSettings->library, true, true)) + true, condTok->astOperand1(), assignTok->astOperand1(), mSettings->library, true, true)) continue; if (!isSameExpression( - mTokenizer->isCPP(), true, condTok->astOperand2(), assignTok->astOperand2(), mSettings->library, true, true)) + true, condTok->astOperand2(), assignTok->astOperand2(), mSettings->library, true, true)) continue; } duplicateConditionalAssignError(condTok, assignTok, isRedundant); diff --git a/lib/checkfunctions.cpp b/lib/checkfunctions.cpp index 7c2a58eb0d4..98e8e340bc6 100644 --- a/lib/checkfunctions.cpp +++ b/lib/checkfunctions.cpp @@ -148,7 +148,7 @@ void CheckFunctions::invalidFunctionUsage() // Is non-null terminated local variable of type char (e.g. char buf[] = {'x'};) ? if (variable && variable->isLocal() && valueType && (valueType->type == ValueType::Type::CHAR || valueType->type == ValueType::Type::WCHAR_T) - && !isVariablesChanged(variable->declEndToken(), functionToken, 0 /*indirect*/, { variable }, mSettings, mTokenizer->isCPP())) { + && !isVariablesChanged(variable->declEndToken(), functionToken, 0 /*indirect*/, { variable }, mSettings)) { const Token* varTok = variable->declEndToken(); auto count = -1; // Find out explicitly set count, e.g.: char buf[3] = {...}. Variable 'count' is set to 3 then. if (varTok && Token::simpleMatch(varTok->astOperand1(), "[")) @@ -756,10 +756,10 @@ void CheckFunctions::useStandardLibrary() const auto& secondOp = condToken->str(); const bool isLess = "<" == secondOp && - isConstExpression(condToken->astOperand2(), mSettings->library, mTokenizer->isCPP()) && + isConstExpression(condToken->astOperand2(), mSettings->library) && condToken->astOperand1()->varId() == idxVarId; const bool isMore = ">" == secondOp && - isConstExpression(condToken->astOperand1(), mSettings->library, mTokenizer->isCPP()) && + isConstExpression(condToken->astOperand1(), mSettings->library) && condToken->astOperand2()->varId() == idxVarId; if (!(isLess || isMore)) @@ -776,7 +776,7 @@ void CheckFunctions::useStandardLibrary() // technically using void* here is not correct but some compilers could allow it const Token *tok = scope.bodyStart; - const std::string memcpyName = mTokenizer->isCPP() ? "std::memcpy" : "memcpy"; + const std::string memcpyName = tok->isCpp() ? "std::memcpy" : "memcpy"; // (reinterpret_cast(dest))[i] = (reinterpret_cast(src))[i]; if (Token::Match(tok, "{ (| reinterpret_cast < uint8_t|int8_t|char|void * > ( %var% ) )| [ %varid% ] = " "(| reinterpret_cast < const| uint8_t|int8_t|char|void * > ( %var% ) )| [ %varid% ] ; }", idxVarId)) { @@ -792,7 +792,7 @@ void CheckFunctions::useStandardLibrary() } - const static std::string memsetName = mTokenizer->isCPP() ? "std::memset" : "memset"; + const static std::string memsetName = tok->isCpp() ? "std::memset" : "memset"; // ((char*)dst)[i] = 0; if (Token::Match(tok, "{ ( ( uint8_t|int8_t|char|void * ) (| %var% ) )| [ %varid% ] = %char%|%num% ; }", idxVarId)) { useStandardLibraryError(tok->next(), memsetName); diff --git a/lib/checkleakautovar.cpp b/lib/checkleakautovar.cpp index 7ac325ac567..92eb6fae960 100644 --- a/lib/checkleakautovar.cpp +++ b/lib/checkleakautovar.cpp @@ -254,7 +254,7 @@ static bool isPointerReleased(const Token *startToken, const Token *endToken, no return false; } -static bool isLocalVarNoAutoDealloc(const Token *varTok, const bool isCpp) +static bool isLocalVarNoAutoDealloc(const Token *varTok) { // not a local variable nor argument? const Variable *var = varTok->variable(); @@ -268,7 +268,7 @@ static bool isLocalVarNoAutoDealloc(const Token *varTok, const bool isCpp) return false; // non-pod variable - if (isCpp) { + if (varTok->isCpp()) { // Possibly automatically deallocated memory if (isAutoDealloc(var) && Token::Match(varTok, "%var% [=({] new")) return false; @@ -432,7 +432,7 @@ bool CheckLeakAutoVar::checkScope(const Token * const startToken, leakIfAllocated(varTok, varInfo); varInfo.erase(varTok->varId()); - if (!isLocalVarNoAutoDealloc(varTok, mTokenizer->isCPP())) + if (!isLocalVarNoAutoDealloc(varTok)) continue; // allocation? @@ -447,7 +447,7 @@ bool CheckLeakAutoVar::checkScope(const Token * const startToken, } changeAllocStatusIfRealloc(alloctype, fTok, varTok); - } else if (mTokenizer->isCPP() && Token::Match(varTok->tokAt(2), "new !!(")) { + } else if (varTok->isCpp() && Token::Match(varTok->tokAt(2), "new !!(")) { const Token* tok2 = varTok->tokAt(2)->astOperand1(); const bool arrayNew = (tok2 && (tok2->str() == "[" || (Token::Match(tok2, "(|{") && tok2->astOperand1() && tok2->astOperand1()->str() == "["))); VarInfo::AllocInfo& varAlloc = alloctype[varTok->varId()]; @@ -481,7 +481,7 @@ bool CheckLeakAutoVar::checkScope(const Token * const startToken, if (!openingPar) checkTokenInsideExpression(innerTok, varInfo); - if (!isLocalVarNoAutoDealloc(innerTok, mTokenizer->isCPP())) + if (!isLocalVarNoAutoDealloc(innerTok)) continue; // Check assignments in the if-statement. Skip multiple assignments since we don't track those @@ -505,7 +505,7 @@ bool CheckLeakAutoVar::checkScope(const Token * const startToken, alloctype.erase(innerTok->varId()); } changeAllocStatusIfRealloc(alloctype, fTok, varTok); - } else if (mTokenizer->isCPP() && Token::Match(innerTok->tokAt(2), "new !!(")) { + } else if (innerTok->isCpp() && Token::Match(innerTok->tokAt(2), "new !!(")) { const Token* tok2 = innerTok->tokAt(2)->astOperand1(); const bool arrayNew = (tok2 && (tok2->str() == "[" || (tok2->str() == "(" && tok2->astOperand1() && tok2->astOperand1()->str() == "["))); VarInfo::AllocInfo& varAlloc = alloctype[innerTok->varId()]; @@ -656,7 +656,7 @@ bool CheckLeakAutoVar::checkScope(const Token * const startToken, } // throw - else if (mTokenizer->isCPP() && tok->str() == "throw") { + else if (tok->isCpp() && tok->str() == "throw") { bool tryFound = false; const Scope* scope = tok->scope(); while (scope && scope->isExecutable()) { @@ -671,7 +671,7 @@ bool CheckLeakAutoVar::checkScope(const Token * const startToken, } // delete - else if (mTokenizer->isCPP() && tok->str() == "delete") { + else if (tok->isCpp() && tok->str() == "delete") { const Token * delTok = tok; if (Token::simpleMatch(delTok->astOperand1(), ".")) continue; @@ -962,7 +962,7 @@ void CheckLeakAutoVar::functionCall(const Token *tokName, const Token *tokOpenin int argNr = 1; for (const Token *funcArg = tokFirstArg; funcArg; funcArg = funcArg->nextArgument()) { const Token* arg = funcArg; - if (mTokenizer->isCPP()) { + if (arg->isCpp()) { int tokAdvance = 0; if (arg->str() == "new") tokAdvance = 1; diff --git a/lib/checkmemoryleak.cpp b/lib/checkmemoryleak.cpp index 28542238444..bc8cdd9e50a 100644 --- a/lib/checkmemoryleak.cpp +++ b/lib/checkmemoryleak.cpp @@ -76,7 +76,7 @@ CheckMemoryLeak::AllocType CheckMemoryLeak::getAllocationType(const Token *tok2, if (reallocType != No) return reallocType; - if (mTokenizer_->isCPP() && tok2->str() == "new") { + if (tok2->isCpp() && tok2->str() == "new") { if (tok2->strAt(1) == "(" && !Token::Match(tok2->next(),"( std| ::| nothrow )")) return No; if (tok2->astOperand1() && (tok2->astOperand1()->str() == "[" || (tok2->astOperand1()->astOperand1() && tok2->astOperand1()->astOperand1()->str() == "["))) @@ -187,7 +187,7 @@ CheckMemoryLeak::AllocType CheckMemoryLeak::getReallocationType(const Token *tok CheckMemoryLeak::AllocType CheckMemoryLeak::getDeallocationType(const Token *tok, nonneg int varid) const { - if (mTokenizer_->isCPP() && tok->str() == "delete" && tok->astOperand1()) { + if (tok->isCpp() && tok->str() == "delete" && tok->astOperand1()) { const Token* vartok = tok->astOperand1(); if (Token::Match(vartok, ".|::")) vartok = vartok->astOperand2(); @@ -973,7 +973,7 @@ void CheckMemoryLeakNoVar::checkForUnreleasedInputArgument(const Scope *scope) continue; const std::string& functionName = tok->str(); - if ((mTokenizer->isCPP() && functionName == "delete") || + if ((tok->isCpp() && functionName == "delete") || functionName == "return") continue; @@ -989,7 +989,7 @@ void CheckMemoryLeakNoVar::checkForUnreleasedInputArgument(const Scope *scope) if (arg->isOp() && !(tok->isKeyword() && arg->str() == "*")) // e.g. switch (*new int) continue; while (arg->astOperand1()) { - if (mTokenizer->isCPP() && Token::simpleMatch(arg, "new")) + if (arg->isCpp() && Token::simpleMatch(arg, "new")) break; arg = arg->astOperand1(); } @@ -1031,7 +1031,7 @@ void CheckMemoryLeakNoVar::checkForUnreleasedInputArgument(const Scope *scope) void CheckMemoryLeakNoVar::checkForUnusedReturnValue(const Scope *scope) { for (const Token *tok = scope->bodyStart; tok != scope->bodyEnd; tok = tok->next()) { - const bool isNew = mTokenizer->isCPP() && tok->str() == "new"; + const bool isNew = tok->isCpp() && tok->str() == "new"; if (!isNew && !Token::Match(tok, "%name% (")) continue; diff --git a/lib/checkother.cpp b/lib/checkother.cpp index 1e5b719271c..47b78729d67 100644 --- a/lib/checkother.cpp +++ b/lib/checkother.cpp @@ -92,7 +92,7 @@ void CheckOther::checkCastIntToCharAndBack() const SymbolDatabase *symbolDatabase = mTokenizer->getSymbolDatabase(); for (const Scope * scope : symbolDatabase->functionScopes) { std::map vars; - for (const Token* tok = scope->bodyStart->next(); tok != scope->bodyEnd; tok = tok->next()) { + for (const Token* tok = scope->bodyStart->next(); tok && tok != scope->bodyEnd; tok = tok->next()) { // Quick check to see if any of the matches below have any chances if (!Token::Match(tok, "%var%|EOF %comp%|=")) continue; @@ -107,13 +107,13 @@ void CheckOther::checkCastIntToCharAndBack() if (var && var->typeEndToken()->str() == "char" && !var->typeEndToken()->isSigned()) { checkCastIntToCharAndBackError(tok, tok->strAt(2)); } - } else if (mTokenizer->isCPP() && (Token::Match(tok, "EOF %comp% ( %var% = std :: cin . get (") || Token::Match(tok, "EOF %comp% ( %var% = cin . get ("))) { + } else if (tok->isCpp() && (Token::Match(tok, "EOF %comp% ( %var% = std :: cin . get (") || Token::Match(tok, "EOF %comp% ( %var% = cin . get ("))) { tok = tok->tokAt(3); const Variable *var = tok->variable(); if (var && var->typeEndToken()->str() == "char" && !var->typeEndToken()->isSigned()) { checkCastIntToCharAndBackError(tok, "cin.get"); } - } else if (mTokenizer->isCPP() && (Token::Match(tok, "%var% = std :: cin . get (") || Token::Match(tok, "%var% = cin . get ("))) { + } else if (tok->isCpp() && (Token::Match(tok, "%var% = std :: cin . get (") || Token::Match(tok, "%var% = cin . get ("))) { const Variable *var = tok->variable(); if (var && var->typeEndToken()->str() == "char" && !var->typeEndToken()->isSigned()) { vars[tok->varId()] = "cin.get"; @@ -482,7 +482,7 @@ void CheckOther::checkRedundantAssignment() continue; bool inconclusive = false; - if (mTokenizer->isCPP() && tok->astOperand1()->valueType()) { + if (tok->isCpp() && tok->astOperand1()->valueType()) { // If there is a custom assignment operator => this is inconclusive if (tok->astOperand1()->valueType()->typeScope) { const std::string op = "operator" + tok->str(); @@ -498,7 +498,7 @@ void CheckOther::checkRedundantAssignment() if (inconclusive && !mSettings->certainty.isEnabled(Certainty::inconclusive)) continue; - FwdAnalysis fwdAnalysis(mTokenizer->isCPP(), mSettings->library); + FwdAnalysis fwdAnalysis(mSettings->library); if (fwdAnalysis.hasOperand(tok->astOperand2(), tok->astOperand1())) continue; @@ -917,7 +917,7 @@ static bool isSimpleExpr(const Token* tok, const Variable* var, const Settings* ((ftok->function() && ftok->function()->isConst()) || settings->library.isFunctionConst(ftok->str(), /*pure*/ true))) needsCheck = true; } - return (needsCheck && !findExpressionChanged(tok, tok->astParent(), var->scope()->bodyEnd, settings, true)); + return (needsCheck && !findExpressionChanged(tok, tok->astParent(), var->scope()->bodyEnd, settings)); } //--------------------------------------------------------------------------- @@ -1305,7 +1305,7 @@ void CheckOther::checkPassByReference() if (!isRangeBasedFor && (!var->scope() || var->scope()->function->isImplicitlyVirtual())) continue; - if (!isVariableChanged(var, mSettings, mTokenizer->isCPP())) { + if (!isVariableChanged(var, mSettings)) { passedByValueError(var, inconclusive, isRangeBasedFor); } } @@ -1421,7 +1421,7 @@ void CheckOther::checkConstVariable() continue; if (isStructuredBindingVariable(var)) // TODO: check all bound variables continue; - if (isVariableChanged(var, mSettings, mTokenizer->isCPP())) + if (isVariableChanged(var, mSettings)) continue; const bool hasFunction = function != nullptr; if (!hasFunction) { @@ -1630,7 +1630,7 @@ void CheckOther::checkConstPointer() if (std::find(nonConstPointers.cbegin(), nonConstPointers.cend(), p) == nonConstPointers.cend()) { const Token *start = getVariableChangedStart(p); const int indirect = p->isArray() ? p->dimensions().size() : 1; - if (isVariableChanged(start, p->scope()->bodyEnd, indirect, p->declarationId(), false, mSettings, mTokenizer->isCPP())) + if (isVariableChanged(start, p->scope()->bodyEnd, indirect, p->declarationId(), false, mSettings)) continue; if (p->typeStartToken() && p->typeStartToken()->isSimplifiedTypedef() && !(Token::simpleMatch(p->typeEndToken(), "*") && !p->typeEndToken()->isSimplifiedTypedef())) continue; @@ -1809,7 +1809,7 @@ static bool isConstant(const Token* tok) { return tok && (tok->isEnumerator() || Token::Match(tok, "%bool%|%num%|%str%|%char%|nullptr|NULL")); } -static bool isConstStatement(const Token *tok, bool cpp) +static bool isConstStatement(const Token *tok) { if (!tok) return false; @@ -1831,7 +1831,7 @@ static bool isConstStatement(const Token *tok, bool cpp) tok2 = tok2->astParent(); } if (Token::Match(tok, "&&|%oror%")) - return isConstStatement(tok->astOperand1(), cpp) && isConstStatement(tok->astOperand2(), cpp); + return isConstStatement(tok->astOperand1()) && isConstStatement(tok->astOperand2()); if (Token::Match(tok, "!|~|%cop%") && (tok->astOperand1() || tok->astOperand2())) return true; if (Token::simpleMatch(tok->previous(), "sizeof (")) @@ -1839,15 +1839,15 @@ static bool isConstStatement(const Token *tok, bool cpp) if (isCPPCast(tok)) { if (Token::simpleMatch(tok->astOperand1(), "dynamic_cast") && Token::simpleMatch(tok->astOperand1()->linkAt(1)->previous(), "& >")) return false; - return isWithoutSideEffects(cpp, tok) && isConstStatement(tok->astOperand2(), cpp); + return isWithoutSideEffects(tok) && isConstStatement(tok->astOperand2()); } if (tok->isCast() && tok->next() && tok->next()->isStandardType()) - return isWithoutSideEffects(cpp, tok->astOperand1()) && isConstStatement(tok->astOperand1(), cpp); + return isWithoutSideEffects(tok->astOperand1()) && isConstStatement(tok->astOperand1()); if (Token::simpleMatch(tok, ".")) - return isConstStatement(tok->astOperand2(), cpp); + return isConstStatement(tok->astOperand2()); 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); + return isConstStatement(tok->astOperand1()) && isConstStatement(tok->astOperand2()); const Token* lml = previousBeforeAstLeftmostLeaf(tok); // don't warn about matrix/vector assignment (e.g. Eigen) if (lml) @@ -1855,14 +1855,14 @@ static bool isConstStatement(const Token *tok, bool cpp) const Token* stream = lml; while (stream && Token::Match(stream->astParent(), ".|[|(|*")) stream = stream->astParent(); - return (!stream || !isLikelyStream(cpp, stream)) && isConstStatement(tok->astOperand2(), cpp); + return (!stream || !isLikelyStream(stream)) && isConstStatement(tok->astOperand2()); } 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); - if (isBracketAccess(tok) && isWithoutSideEffects(cpp, tok->astOperand1(), /*checkArrayAccess*/ true, /*checkReference*/ false)) { + return isConstStatement(tok->astOperand1()) && isConstStatement(tok->astOperand2()->astOperand1()) && isConstStatement(tok->astOperand2()->astOperand2()); + if (isBracketAccess(tok) && isWithoutSideEffects(tok->astOperand1(), /*checkArrayAccess*/ true, /*checkReference*/ false)) { if (Token::simpleMatch(tok->astParent(), "[")) - return isConstStatement(tok->astOperand2(), cpp) && isConstStatement(tok->astParent(), cpp); - return isConstStatement(tok->astOperand2(), cpp); + return isConstStatement(tok->astOperand2()) && isConstStatement(tok->astParent()); + return isConstStatement(tok->astOperand2()); } return false; } @@ -1946,7 +1946,7 @@ void CheckOther::checkIncompleteStatement() const Token *rtok = nextAfterAstRightmostLeaf(tok); if (!Token::simpleMatch(tok->astParent(), ";") && !Token::simpleMatch(rtok, ";") && !Token::Match(tok->previous(), ";|}|{ %any% ;") && - !(mTokenizer->isCPP() && tok->isCast() && !tok->astParent()) && + !(tok->isCpp() && tok->isCast() && !tok->astParent()) && !Token::simpleMatch(tok->tokAt(-2), "for (") && !Token::Match(tok->tokAt(-1), "%var% [") && !(tok->str() == "," && tok->astParent() && tok->astParent()->isAssignmentOp())) @@ -1954,11 +1954,11 @@ void CheckOther::checkIncompleteStatement() // Skip statement expressions if (Token::simpleMatch(rtok, "; } )")) continue; - if (!isConstStatement(tok, mTokenizer->isCPP())) + if (!isConstStatement(tok)) continue; if (isVoidStmt(tok)) continue; - if (mTokenizer->isCPP() && tok->str() == "&" && !(tok->astOperand1() && tok->astOperand1()->valueType() && tok->astOperand1()->valueType()->isIntegral())) + if (tok->isCpp() && tok->str() == "&" && !(tok->astOperand1() && tok->astOperand1()->valueType() && tok->astOperand1()->valueType()->isIntegral())) // Possible archive continue; const bool inconclusive = tok->isConstOp(); @@ -2143,7 +2143,7 @@ void CheckOther::checkMisusedScopedObject() if (Token::simpleMatch(parTok, "<") && parTok->link()) parTok = parTok->link()->next(); if (const Token* arg = parTok->astOperand2()) { - if (!isConstStatement(arg, mTokenizer->isCPP())) + if (!isConstStatement(arg)) continue; if (parTok->str() == "(") { if (arg->varId() && !(arg->variable() && arg->variable()->nameToken() != arg)) @@ -2266,8 +2266,8 @@ void CheckOther::checkDuplicateBranch() if (branchTop1->str() != branchTop2->str()) continue; ErrorPath errorPath; - if (isSameExpression(mTokenizer->isCPP(), false, branchTop1->astOperand1(), branchTop2->astOperand1(), mSettings->library, true, true, &errorPath) && - isSameExpression(mTokenizer->isCPP(), false, branchTop1->astOperand2(), branchTop2->astOperand2(), mSettings->library, true, true, &errorPath)) + if (isSameExpression(false, branchTop1->astOperand1(), branchTop2->astOperand1(), mSettings->library, true, true, &errorPath) && + isSameExpression(false, branchTop1->astOperand2(), branchTop2->astOperand2(), mSettings->library, true, true, &errorPath)) duplicateBranchError(scope.classDef, scope.bodyEnd->next(), std::move(errorPath)); } } @@ -2300,10 +2300,10 @@ void CheckOther::checkInvalidFree() const bool printInconclusive = mSettings->certainty.isEnabled(Certainty::inconclusive); const SymbolDatabase* symbolDatabase = mTokenizer->getSymbolDatabase(); for (const Scope * scope : symbolDatabase->functionScopes) { - for (const Token* tok = scope->bodyStart->next(); tok != scope->bodyEnd; tok = tok->next()) { + for (const Token* tok = scope->bodyStart->next(); tok && tok != scope->bodyEnd; tok = tok->next()) { // Keep track of which variables were assigned addresses to newly-allocated memory - if ((mTokenizer->isCPP() && Token::Match(tok, "%var% = new")) || + if ((tok->isCpp() && Token::Match(tok, "%var% = new")) || (Token::Match(tok, "%var% = %name% (") && mSettings->library.getAllocFuncInfo(tok->tokAt(2)))) { allocation.insert(std::make_pair(tok->varId(), tok->strAt(2))); inconclusive.insert(std::make_pair(tok->varId(), false)); @@ -2431,8 +2431,6 @@ void CheckOther::checkDuplicateExpression() std::list constFunctions; getConstFunctions(symbolDatabase, constFunctions); - const bool cpp = mTokenizer->isCPP(); - for (const Scope *scope : symbolDatabase->functionScopes) { for (const Token *tok = scope->bodyStart; tok != scope->bodyEnd; tok = tok->next()) { if (tok->str() == "=" && Token::Match(tok->astOperand1(), "%var%")) { @@ -2457,8 +2455,8 @@ void CheckOther::checkDuplicateExpression() Token::Match(tok->astOperand2()->previous(), "%name% (") ) && tok->next()->tokType() != Token::eType && - isSameExpression(cpp, true, tok->next(), nextAssign->next(), mSettings->library, true, false) && - isSameExpression(cpp, true, tok->astOperand2(), nextAssign->astOperand2(), mSettings->library, true, false) && + isSameExpression(true, tok->next(), nextAssign->next(), mSettings->library, true, false) && + isSameExpression(true, tok->astOperand2(), nextAssign->astOperand2(), mSettings->library, true, false) && tok->astOperand2()->expressionString() == nextAssign->astOperand2()->expressionString()) { bool differentDomain = false; const Scope * varScope = var1->scope() ? var1->scope() : scope; @@ -2472,8 +2470,7 @@ void CheckOther::checkDuplicateExpression() if (assignTok->astOperand1()->varId() != var1->varId() && assignTok->astOperand1()->varId() != var2->varId() && - !isSameExpression(cpp, - true, + !isSameExpression(true, tok->astOperand2(), assignTok->astOperand1(), mSettings->library, @@ -2482,8 +2479,7 @@ void CheckOther::checkDuplicateExpression() continue; if (assignTok->astOperand2()->varId() != var1->varId() && assignTok->astOperand2()->varId() != var2->varId() && - !isSameExpression(cpp, - true, + !isSameExpression(true, tok->astOperand2(), assignTok->astOperand2(), mSettings->library, @@ -2513,24 +2509,23 @@ void CheckOther::checkDuplicateExpression() const bool pointerDereference = (tok->astOperand1() && tok->astOperand1()->isUnaryOp("*")) || (tok->astOperand2() && tok->astOperand2()->isUnaryOp("*")); const bool followVar = (!isConstVarExpression(tok) || Token::Match(tok, "%comp%|%oror%|&&")) && !pointerDereference; - if (isSameExpression(cpp, - true, + if (isSameExpression(true, tok->astOperand1(), tok->astOperand2(), mSettings->library, true, followVar, &errorPath)) { - if (isWithoutSideEffects(cpp, tok->astOperand1())) { + if (isWithoutSideEffects(tok->astOperand1())) { const Token* loopTok = isInLoopCondition(tok); if (!loopTok || - !findExpressionChanged(tok, tok, loopTok->link()->next()->link(), mSettings, cpp)) { + !findExpressionChanged(tok, tok, loopTok->link()->next()->link(), mSettings)) { const bool isEnum = tok->scope()->type == Scope::eEnum; const bool assignment = !isEnum && tok->str() == "="; if (assignment) selfAssignmentError(tok, tok->astOperand1()->expressionString()); else if (!isEnum) { - if (cpp && mSettings->standards.cpp >= Standards::CPP11 && tok->str() == "==") { + if (tok->isCpp() && mSettings->standards.cpp >= Standards::CPP11 && tok->str() == "==") { const Token* parent = tok->astParent(); while (parent && parent->astParent()) { parent = parent->astParent(); @@ -2544,43 +2539,40 @@ void CheckOther::checkDuplicateExpression() } } } else if (tok->str() == "=" && Token::simpleMatch(tok->astOperand2(), "=") && - isSameExpression(cpp, - false, + isSameExpression(false, tok->astOperand1(), tok->astOperand2()->astOperand1(), mSettings->library, true, false)) { - if (isWithoutSideEffects(cpp, tok->astOperand1())) { + if (isWithoutSideEffects(tok->astOperand1())) { selfAssignmentError(tok, tok->astOperand1()->expressionString()); } - } else if (isOppositeExpression(cpp, - tok->astOperand1(), + } else if (isOppositeExpression(tok->astOperand1(), tok->astOperand2(), mSettings->library, false, true, &errorPath) && !Token::Match(tok, "=|-|-=|/|/=") && - isWithoutSideEffects(cpp, tok->astOperand1())) { + isWithoutSideEffects(tok->astOperand1())) { oppositeExpressionError(tok, std::move(errorPath)); } else if (!Token::Match(tok, "[-/%]")) { // These operators are not associative if (tok->astOperand2() && tok->str() == tok->astOperand1()->str() && - isSameExpression(cpp, - true, + isSameExpression(true, tok->astOperand2(), tok->astOperand1()->astOperand2(), mSettings->library, true, followVar, &errorPath) && - isWithoutSideEffects(cpp, tok->astOperand2())) + isWithoutSideEffects(tok->astOperand2())) duplicateExpressionError(tok->astOperand2(), tok->astOperand1()->astOperand2(), tok, errorPath); - else if (tok->astOperand2() && isConstExpression(tok->astOperand1(), mSettings->library, cpp)) { + else if (tok->astOperand2() && isConstExpression(tok->astOperand1(), mSettings->library)) { auto checkDuplicate = [&](const Token* exp1, const Token* exp2, const Token* ast1) { - if (isSameExpression(cpp, true, exp1, exp2, mSettings->library, true, true, &errorPath) && - isWithoutSideEffects(cpp, exp1) && - isWithoutSideEffects(cpp, ast1->astOperand2())) + if (isSameExpression(true, exp1, exp2, mSettings->library, true, true, &errorPath) && + isWithoutSideEffects(exp1) && + isWithoutSideEffects(ast1->astOperand2())) duplicateExpressionError(exp1, exp2, tok, errorPath, /*hasMultipleExpr*/ true); }; const Token *ast1 = tok->astOperand1(); @@ -2594,10 +2586,10 @@ void CheckOther::checkDuplicateExpression() } } else if (tok->astOperand1() && tok->astOperand2() && tok->str() == ":" && tok->astParent() && tok->astParent()->str() == "?") { if (!tok->astOperand1()->values().empty() && !tok->astOperand2()->values().empty() && isEqualKnownValue(tok->astOperand1(), tok->astOperand2()) && - !isVariableChanged(tok->astParent(), /*indirect*/ 0, mSettings, cpp) && - isConstStatement(tok->astOperand1(), cpp) && isConstStatement(tok->astOperand2(), cpp)) + !isVariableChanged(tok->astParent(), /*indirect*/ 0, mSettings) && + isConstStatement(tok->astOperand1()) && isConstStatement(tok->astOperand2())) duplicateValueTernaryError(tok); - else if (isSameExpression(cpp, true, tok->astOperand1(), tok->astOperand2(), mSettings->library, false, true, &errorPath)) + else if (isSameExpression(true, tok->astOperand1(), tok->astOperand2(), mSettings->library, false, true, &errorPath)) duplicateExpressionTernaryError(tok, std::move(errorPath)); } } @@ -2874,7 +2866,7 @@ void CheckOther::checkRedundantCopy() for (const Variable* var : symbolDatabase->variableList()) { if (!var || var->isReference() || var->isPointer() || (!var->type() && !var->isStlType()) || // bailout if var is of standard type, if it is a pointer or non-const - (!var->isConst() && isVariableChanged(var, mSettings, mTokenizer->isCPP()))) + (!var->isConst() && isVariableChanged(var, mSettings))) continue; const Token* startTok = var->nameToken(); @@ -2899,9 +2891,9 @@ void CheckOther::checkRedundantCopy() const Token* dot = tok->astOperand1(); if (Token::simpleMatch(dot, ".")) { - if (dot->astOperand1() && isVariableChanged(dot->astOperand1()->variable(), mSettings, mTokenizer->isCPP())) + if (dot->astOperand1() && isVariableChanged(dot->astOperand1()->variable(), mSettings)) continue; - if (isTemporary(/*cpp*/ true, dot, &mSettings->library, /*unknown*/ true)) + if (isTemporary(dot, &mSettings->library, /*unknown*/ true)) continue; } if (exprDependsOnThis(tok->previous())) @@ -2955,7 +2947,7 @@ void CheckOther::checkNegativeBitwiseShift() continue; // don't warn if lhs is a class. this is an overloaded operator then - if (mTokenizer->isCPP()) { + if (tok->isCpp()) { const ValueType * lhsType = tok->astOperand1()->valueType(); if (!lhsType || !lhsType->isIntegral()) continue; @@ -3333,9 +3325,9 @@ void CheckOther::checkEvaluationOrder() if (tok2 == tok && tok->str() == "=" && parent->str() == "=" && - isSameExpression(mTokenizer->isCPP(), false, tok->astOperand1(), parent->astOperand1(), mSettings->library, true, false)) { + isSameExpression(false, tok->astOperand1(), parent->astOperand1(), mSettings->library, true, false)) { if (mSettings->severity.isEnabled(Severity::warning) && - isSameExpression(mTokenizer->isCPP(), true, tok->astOperand1(), parent->astOperand1(), mSettings->library, true, false)) + isSameExpression(true, tok->astOperand1(), parent->astOperand1(), mSettings->library, true, false)) selfAssignmentError(parent, tok->astOperand1()->expressionString()); break; } @@ -3348,7 +3340,7 @@ void CheckOther::checkEvaluationOrder() return ChildrenToVisit::none; // don't handle address-of for now if (tok3->str() == "(" && Token::simpleMatch(tok3->previous(), "sizeof")) return ChildrenToVisit::none; // don't care about sizeof usage - if (isSameExpression(mTokenizer->isCPP(), false, tok->astOperand1(), tok3, mSettings->library, true, false)) + if (isSameExpression(false, tok->astOperand1(), tok3, mSettings->library, true, false)) foundError = true; return foundError ? ChildrenToVisit::done : ChildrenToVisit::op1_and_op2; }); @@ -3399,7 +3391,7 @@ void CheckOther::checkAccessOfMovedVariable() else inconclusive = true; } else { - const ExprUsage usage = getExprUsage(tok, 0, mSettings, mTokenizer->isCPP()); + const ExprUsage usage = getExprUsage(tok, 0, mSettings); if (usage == ExprUsage::Used) accessOfMoved = true; if (usage == ExprUsage::PassedByReference) @@ -3705,7 +3697,7 @@ void CheckOther::checkKnownArgument() continue; if (tok->isComparisonOp() && isSameExpression( - mTokenizer->isCPP(), true, tok->astOperand1(), tok->astOperand2(), mSettings->library, true, true)) + true, tok->astOperand1(), tok->astOperand2(), mSettings->library, true, true)) continue; // ensure that there is a integer variable in expression with unknown value const Token* vartok = nullptr; @@ -3838,10 +3830,10 @@ void CheckOther::checkComparePointers() continue; if (var1->isRValueReference() || var2->isRValueReference()) continue; - if (const Token* parent2 = getParentLifetime(mTokenizer->isCPP(), v2.tokvalue, &mSettings->library)) + if (const Token* parent2 = getParentLifetime(v2.tokvalue, &mSettings->library)) if (var1 == parent2->variable()) continue; - if (const Token* parent1 = getParentLifetime(mTokenizer->isCPP(), v1.tokvalue, &mSettings->library)) + if (const Token* parent1 = getParentLifetime(v1.tokvalue, &mSettings->library)) if (var2 == parent1->variable()) continue; comparePointersError(tok, &v1, &v2); @@ -3998,7 +3990,7 @@ void CheckOther::checkOverlappingWrite() constexpr bool macro = true; constexpr bool pure = true; constexpr bool follow = true; - if (!isSameExpression(mTokenizer->isCPP(), macro, ptr1, ptr2, mSettings->library, pure, follow, &errorPath)) + if (!isSameExpression(macro, ptr1, ptr2, mSettings->library, pure, follow, &errorPath)) continue; overlappingWriteFunction(tok); } @@ -4023,7 +4015,7 @@ void CheckOther::checkOverlappingWrite() constexpr bool macro = true; constexpr bool pure = true; constexpr bool follow = true; - if (!isSameExpression(mTokenizer->isCPP(), macro, buf1, buf2, mSettings->library, pure, follow, &errorPath)) + if (!isSameExpression(macro, buf1, buf2, mSettings->library, pure, follow, &errorPath)) continue; overlappingWriteFunction(tok); } diff --git a/lib/checkstl.cpp b/lib/checkstl.cpp index 3f740c2a98f..5eca694028f 100644 --- a/lib/checkstl.cpp +++ b/lib/checkstl.cpp @@ -283,7 +283,7 @@ bool CheckStl::isContainerSize(const Token *containerToken, const Token *expr) c return false; if (!Token::Match(expr->astOperand1(), ". %name% (")) return false; - if (!isSameExpression(mTokenizer->isCPP(), false, containerToken, expr->astOperand1()->astOperand1(), mSettings->library, false, false)) + if (!isSameExpression(false, containerToken, expr->astOperand1()->astOperand1(), mSettings->library, false, false)) return false; return containerToken->valueType()->container->getYield(expr->previous()->str()) == Library::Container::Yield::SIZE; } @@ -708,8 +708,8 @@ static bool isSameIteratorContainerExpression(const Token* tok1, const Library& library, ValueFlow::Value::LifetimeKind kind = ValueFlow::Value::LifetimeKind::Iterator) { - if (isSameExpression(true, false, tok1, tok2, library, false, false)) { - return !astIsContainerOwned(tok1) || !isTemporary(true, tok1, &library); + if (isSameExpression(false, tok1, tok2, library, false, false)) { + return !astIsContainerOwned(tok1) || !isTemporary(tok1, &library); } if (astContainerYield(tok2) == Library::Container::Yield::ITEM) return true; @@ -718,7 +718,7 @@ static bool isSameIteratorContainerExpression(const Token* tok1, const auto address2 = getAddressContainer(tok2); return std::any_of(address1.begin(), address1.end(), [&](const Token* tok1) { return std::any_of(address2.begin(), address2.end(), [&](const Token* tok2) { - return isSameExpression(true, false, tok1, tok2, library, false, false); + return isSameExpression(false, tok1, tok2, library, false, false); }); }); } @@ -826,7 +826,7 @@ void CheckStl::mismatchingContainers() if (iter1.tok == iter2.tok) continue; if (iter1.info->first && iter2.info->last && - isSameExpression(true, false, iter1.tok, iter2.tok, mSettings->library, false, false)) + isSameExpression(false, iter1.tok, iter2.tok, mSettings->library, false, false)) sameIteratorExpressionError(iter1.tok); if (checkIteratorPair(iter1.tok, iter2.tok)) return; @@ -1662,8 +1662,8 @@ static const Token *findInsertValue(const Token *tok, const Token *containerTok, } if (!ikeyTok || !icontainerTok) return nullptr; - if (isSameExpression(true, true, containerTok, icontainerTok, library, true, false) && - isSameExpression(true, true, keyTok, ikeyTok, library, true, true)) { + if (isSameExpression(true, containerTok, icontainerTok, library, true, false) && + isSameExpression(true, keyTok, ikeyTok, library, true, true)) { if (ivalueTok) return ivalueTok; return ikeyTok; @@ -1707,7 +1707,7 @@ void CheckStl::checkFindInsert() findInsertValue(thenTok->link()->tokAt(2), containerTok, keyTok, mSettings->library); if (!valueTok2) continue; - if (isSameExpression(true, true, valueTok, valueTok2, mSettings->library, true, true)) { + if (isSameExpression(true, valueTok, valueTok2, mSettings->library, true, true)) { checkFindInsertError(valueTok); } } else { @@ -2585,9 +2585,9 @@ static const Token *singleAssignInScope(const Token *start, nonneg int varid, bo if (!Token::Match(start->next(), "%var% %assign%")) return nullptr; const Token *assignTok = start->tokAt(2); - if (isVariableChanged(assignTok->next(), endStatement, assignTok->astOperand1()->varId(), /*globalvar*/ false, settings, /*cpp*/ true)) + if (isVariableChanged(assignTok->next(), endStatement, assignTok->astOperand1()->varId(), /*globalvar*/ false, settings)) return nullptr; - if (isVariableChanged(assignTok->next(), endStatement, varid, /*globalvar*/ false, settings, /*cpp*/ true)) + if (isVariableChanged(assignTok->next(), endStatement, varid, /*globalvar*/ false, settings)) return nullptr; input = Token::findmatch(assignTok->next(), "%varid%", endStatement, varid) || !Token::Match(start->next(), "%var% ="); hasBreak = Token::simpleMatch(endStatement->previous(), "break"); @@ -2611,7 +2611,7 @@ static const Token *singleMemberCallInScope(const Token *start, nonneg int varid if (!Token::findmatch(dotTok->tokAt(2), "%varid%", endStatement, varid)) return nullptr; input = Token::Match(start->next(), "%var% . %name% ( %varid% )", varid); - if (isVariableChanged(dotTok->next(), endStatement, dotTok->astOperand1()->varId(), /*globalvar*/ false, settings, /*cpp*/ true)) + if (isVariableChanged(dotTok->next(), endStatement, dotTok->astOperand1()->varId(), /*globalvar*/ false, settings)) return nullptr; return dotTok; } @@ -2648,7 +2648,7 @@ static const Token *singleConditionalInScope(const Token *start, nonneg int vari return nullptr; if (!Token::findmatch(start, "%varid%", bodyTok, varid)) return nullptr; - if (isVariableChanged(start, bodyTok, varid, /*globalvar*/ false, settings, /*cpp*/ true)) + if (isVariableChanged(start, bodyTok, varid, /*globalvar*/ false, settings)) return nullptr; return bodyTok; } @@ -2763,7 +2763,7 @@ namespace { return true; if (inconclusive) return true; - if (isVariableChanged(tok, i, settings, true)) + if (isVariableChanged(tok, i, settings)) return true; } return false; @@ -2881,7 +2881,7 @@ void CheckStl::useStlAlgorithm() auto isConditionWithoutSideEffects = [this](const Token* tok) -> bool { if (!Token::simpleMatch(tok, "{") || !Token::simpleMatch(tok->previous(), ")")) return false; - return isConstExpression(tok->previous()->link()->astOperand2(), mSettings->library, true); + return isConstExpression(tok->previous()->link()->astOperand2(), mSettings->library); }; for (const Scope *function : mTokenizer->getSymbolDatabase()->functionScopes) { diff --git a/lib/checkstring.cpp b/lib/checkstring.cpp index cc9a5939896..1c51fa5d8b9 100644 --- a/lib/checkstring.cpp +++ b/lib/checkstring.cpp @@ -189,7 +189,7 @@ void CheckString::checkSuspiciousStringCompare() continue; const ValueType* varType = varTok->valueType(); - if (mTokenizer->isCPP() && (!varType || !varType->isIntegral())) + if (varTok->isCpp() && (!varType || !varType->isIntegral())) continue; if (litTok->tokType() == Token::eString) { @@ -396,7 +396,7 @@ void CheckString::overlappingStrcmp() if (args1[1]->isLiteral() && args2[1]->isLiteral() && args1[1]->str() != args2[1]->str() && - isSameExpression(mTokenizer->isCPP(), true, args1[0], args2[0], mSettings->library, true, false)) + isSameExpression(true, args1[0], args2[0], mSettings->library, true, false)) overlappingStrcmpError(eq0, ne0); } } @@ -444,8 +444,7 @@ void CheckString::sprintfOverlappingData() while (arg->isCast()) arg = arg->astOperand2() ? arg->astOperand2() : arg->astOperand1(); - const bool same = isSameExpression(mTokenizer->isCPP(), - false, + const bool same = isSameExpression(false, dest, arg, mSettings->library, diff --git a/lib/checktype.cpp b/lib/checktype.cpp index 344f752f96d..8a23b8e4f41 100644 --- a/lib/checktype.cpp +++ b/lib/checktype.cpp @@ -68,7 +68,7 @@ void CheckType::checkTooBigBitwiseShift() for (const Token *tok = mTokenizer->tokens(); tok; tok = tok->next()) { // C++ and macro: OUT(x<isCPP() && Token::Match(tok, "[;{}] %name% (") && Token::simpleMatch(tok->linkAt(2), ") ;") && tok->next()->isUpperCaseName() && !tok->next()->function()) + if (tok->isCpp() && Token::Match(tok, "[;{}] %name% (") && Token::simpleMatch(tok->linkAt(2), ") ;") && tok->next()->isUpperCaseName() && !tok->next()->function()) tok = tok->linkAt(2); if (!tok->astOperand1() || !tok->astOperand2()) diff --git a/lib/checkuninitvar.cpp b/lib/checkuninitvar.cpp index e12e8047ed9..0cb2065760b 100644 --- a/lib/checkuninitvar.cpp +++ b/lib/checkuninitvar.cpp @@ -725,7 +725,7 @@ bool CheckUninitVar::checkScopeForVariable(const Token *tok, const Variable& var if (!membervar.empty()) { if (!suppressErrors && Token::Match(tok, "%name% . %name%") && tok->strAt(2) == membervar && Token::Match(tok->next()->astParent(), "%cop%|return|throw|?")) uninitStructMemberError(tok, tok->str() + "." + membervar); - else if (mTokenizer->isCPP() && !suppressErrors && Token::Match(tok, "%name%") && Token::Match(tok->astParent(), "return|throw|?")) { + else if (tok->isCpp() && !suppressErrors && Token::Match(tok, "%name%") && Token::Match(tok->astParent(), "return|throw|?")) { if (std::any_of(tok->values().cbegin(), tok->values().cend(), [](const ValueFlow::Value& v) { return v.isUninitValue() && !v.isInconclusive(); })) @@ -1306,7 +1306,7 @@ const Token* CheckUninitVar::isVariableUsage(const Token *vartok, const Library& // Stream read/write // FIXME this code is a hack!! if (cpp && Token::Match(valueExpr->astParent(), "<<|>>")) { - if (isLikelyStreamRead(cpp, vartok->previous())) + if (isLikelyStreamRead(vartok->previous())) return nullptr; if (const auto* vt = valueExpr->valueType()) { @@ -1317,7 +1317,7 @@ const Token* CheckUninitVar::isVariableUsage(const Token *vartok, const Library& return nullptr; } } - if (astIsRhs(derefValue) && isLikelyStreamRead(cpp, derefValue->astParent())) + if (astIsRhs(derefValue) && isLikelyStreamRead(derefValue->astParent())) return nullptr; // Assignment with overloaded & @@ -1428,7 +1428,7 @@ bool CheckUninitVar::isMemberVariableAssignment(const Token *tok, const std::str return true; if (Token::Match(tok->tokAt(-2), "[(,=] &")) return true; - if (isLikelyStreamRead(mTokenizer->isCPP(), tok->previous())) + if (isLikelyStreamRead(tok->previous())) return true; if ((tok->previous() && tok->previous()->isConstOp()) || Token::Match(tok->previous(), "[|=")) ; // member variable usage @@ -1647,7 +1647,7 @@ void CheckUninitVar::valueFlowUninit() if (!isleaf && Token::Match(tok->astParent(), ". %name%") && (tok->astParent()->next()->varId() || tok->astParent()->next()->isEnumerator())) continue; } - const ExprUsage usage = getExprUsage(tok, v->indirect, mSettings, mTokenizer->isCPP()); + const ExprUsage usage = getExprUsage(tok, v->indirect, mSettings); if (usage == ExprUsage::NotUsed || usage == ExprUsage::Inconclusive) continue; if (!v->subexpressions.empty() && usage == ExprUsage::PassedByReference) @@ -1658,7 +1658,7 @@ void CheckUninitVar::valueFlowUninit() continue; if (usage != ExprUsage::Used) { if (!(Token::Match(tok->astParent(), ". %name% (|[") && uninitderef) && - isVariableChanged(tok, v->indirect, mSettings, mTokenizer->isCPP())) + isVariableChanged(tok, v->indirect, mSettings)) continue; if (isVariableChangedByFunctionCall(tok, v->indirect, mSettings, &inconclusive) || inconclusive) continue; diff --git a/lib/checkunusedvar.cpp b/lib/checkunusedvar.cpp index d7e4f4bf55e..7d7ccd7b023 100644 --- a/lib/checkunusedvar.cpp +++ b/lib/checkunusedvar.cpp @@ -837,7 +837,7 @@ void CheckUnusedVar::checkFunctionVariableUsage_iterateScopes(const Scope* const } // Freeing memory (not considered "using" the pointer if it was also allocated in this function) if ((Token::Match(tok, "%name% ( %var% )") && mSettings->library.getDeallocFuncInfo(tok)) || - (mTokenizer->isCPP() && (Token::Match(tok, "delete %var% ;") || Token::Match(tok, "delete [ ] %var% ;")))) { + (tok->isCpp() && (Token::Match(tok, "delete %var% ;") || Token::Match(tok, "delete [ ] %var% ;")))) { nonneg int varid = 0; if (tok->str() != "delete") { const Token *varTok = tok->tokAt(2); @@ -953,8 +953,8 @@ void CheckUnusedVar::checkFunctionVariableUsage_iterateScopes(const Scope* const const Token *type = allocFuncCallToken->next(); // skip nothrow - if (mTokenizer->isCPP() && (Token::simpleMatch(type, "( nothrow )") || - Token::simpleMatch(type, "( std :: nothrow )"))) + if (type->isCpp() && (Token::simpleMatch(type, "( nothrow )") || + Token::simpleMatch(type, "( std :: nothrow )"))) type = type->link()->next(); // is it a user defined type? @@ -1026,7 +1026,7 @@ void CheckUnusedVar::checkFunctionVariableUsage_iterateScopes(const Scope* const if (var) { // Consider allocating memory separately because allocating/freeing alone does not constitute using the variable if (var->mType == Variables::pointer && - ((mTokenizer->isCPP() && Token::simpleMatch(skipBrackets(tok->next()), "= new")) || + ((tok->isCpp() && Token::simpleMatch(skipBrackets(tok->next()), "= new")) || (Token::Match(skipBrackets(tok->next()), "= %name% (") && mSettings->library.getAllocFuncInfo(tok->tokAt(2))))) { variables.allocateMemory(varid, tok); } else if (var->mType == Variables::pointer || var->mType == Variables::reference) { @@ -1039,7 +1039,7 @@ void CheckUnusedVar::checkFunctionVariableUsage_iterateScopes(const Scope* const } } - else if (mTokenizer->isCPP() && Token::Match(tok, "[;{}] %var% <<")) { + else if (tok->isCpp() && Token::Match(tok, "[;{}] %var% <<")) { variables.erase(tok->next()->varId()); } @@ -1049,13 +1049,13 @@ void CheckUnusedVar::checkFunctionVariableUsage_iterateScopes(const Scope* const } else // addressof variables.use(tok->next()->varId(), tok); // use = read + write } else if (Token::Match(tok, ">>|>>= %name%")) { - if (isLikelyStreamRead(mTokenizer->isCPP(), tok)) + if (isLikelyStreamRead(tok)) variables.use(tok->next()->varId(), tok); // use = read + write else variables.read(tok->next()->varId(), tok); } else if (Token::Match(tok, "%var% >>|&") && Token::Match(tok->previous(), "[{};:]")) { variables.read(tok->varId(), tok); - } else if (isLikelyStreamRead(mTokenizer->isCPP(),tok->previous())) { + } else if (isLikelyStreamRead(tok->previous())) { variables.use(tok->varId(), tok); } @@ -1205,13 +1205,13 @@ void CheckUnusedVar::checkFunctionVariableUsage() if (isIncrementOrDecrement && tok->astParent() && precedes(tok, tok->astOperand1())) continue; - if (tok->str() == "=" && !(tok->valueType() && tok->valueType()->pointer) && isRaiiClass(tok->valueType(), mTokenizer->isCPP(), false)) + if (tok->str() == "=" && !(tok->valueType() && tok->valueType()->pointer) && isRaiiClass(tok->valueType(), tok->isCpp(), false)) continue; const bool isPointer = tok->valueType() && (tok->valueType()->pointer || tok->valueType()->type == ValueType::SMART_POINTER); if (tok->isName()) { - if (isRaiiClass(tok->valueType(), mTokenizer->isCPP(), false)) + if (isRaiiClass(tok->valueType(), tok->isCpp(), false)) continue; tok = tok->next(); } @@ -1298,7 +1298,7 @@ void CheckUnusedVar::checkFunctionVariableUsage() if (tok->previous() && tok->previous()->variable() && tok->previous()->variable()->nameToken()->scope()->type == Scope::eUnion) continue; - FwdAnalysis fwdAnalysis(mTokenizer->isCPP(), mSettings->library); + FwdAnalysis fwdAnalysis(mSettings->library); const Token* scopeEnd = ValueFlow::getEndOfExprScope(expr, scope, /*smallest*/ false); if (fwdAnalysis.unusedValue(expr, start, scopeEnd)) { if (!bailoutTypeName.empty()) { @@ -1688,7 +1688,7 @@ bool CheckUnusedVar::isFunctionWithoutSideEffects(const Function& func, const To // check if global variable is changed if (bodyVariable->isGlobal() || (pointersToGlobals.find(bodyVariable) != pointersToGlobals.end())) { const int indirect = bodyVariable->isArray() ? bodyVariable->dimensions().size() : bodyVariable->isPointer(); - if (isVariableChanged(bodyToken, indirect, mSettings, mTokenizer->isCPP())) { + if (isVariableChanged(bodyToken, indirect, mSettings)) { return false; } // check if pointer to global variable assigned to another variable (another_var = &global_var) diff --git a/lib/checkvaarg.cpp b/lib/checkvaarg.cpp index 3606a4f3432..d78f8121114 100644 --- a/lib/checkvaarg.cpp +++ b/lib/checkvaarg.cpp @@ -150,7 +150,7 @@ void CheckVaarg::va_list_usage() tok = findNextTokenFromBreak(tok); if (!tok) return; - } else if (tok->str() == "goto" || (mTokenizer->isCPP() && tok->str() == "try")) { + } else if (tok->str() == "goto" || (tok->isCpp() && tok->str() == "try")) { open = false; break; } else if (!open && tok->varId() == var->declarationId()) diff --git a/lib/ctu.cpp b/lib/ctu.cpp index 9dd4369f533..a98e7e80943 100644 --- a/lib/ctu.cpp +++ b/lib/ctu.cpp @@ -436,7 +436,7 @@ CTU::FileInfo *CTU::getFileInfo(const Tokenizer *tokenizer) return fileInfo; } -static std::list> getUnsafeFunction(const Tokenizer *tokenizer, const Settings *settings, const Scope *scope, int argnr, bool (*isUnsafeUsage)(const Settings *settings, const Token *argtok, MathLib::bigint *value)) +static std::list> getUnsafeFunction(const Settings *settings, const Scope *scope, int argnr, bool (*isUnsafeUsage)(const Settings *settings, const Token *argtok, MathLib::bigint *value)) { std::list> ret; const Variable * const argvar = scope->function->getArgumentVar(argnr); @@ -450,7 +450,7 @@ static std::list> getUnsafeFunction(co int indirect = 0; if (argvar->valueType()) indirect = argvar->valueType()->pointer; - if (isVariableChanged(tok2->link(), tok2, indirect, argvar->declarationId(), false, settings, tokenizer->isCPP())) + if (isVariableChanged(tok2->link(), tok2, indirect, argvar->declarationId(), false, settings)) return ret; } if (Token::Match(tok2, "%oror%|&&|?")) { @@ -482,7 +482,7 @@ std::list CTU::getUnsafeUsage(const Tokenizer *token // "Unsafe" functions unconditionally reads data before it is written.. for (int argnr = 0; argnr < function->argCount(); ++argnr) { - for (const std::pair &v : getUnsafeFunction(tokenizer, settings, &scope, argnr, isUnsafeUsage)) { + for (const std::pair &v : getUnsafeFunction(settings, &scope, argnr, isUnsafeUsage)) { const Token *tok = v.first; const MathLib::bigint val = v.second; unsafeUsage.emplace_back(CTU::getFunctionId(tokenizer, function), argnr+1, tok->str(), CTU::FileInfo::Location(tokenizer,tok), val); diff --git a/lib/forwardanalyzer.cpp b/lib/forwardanalyzer.cpp index 0dfe80895f8..4385e393cb8 100644 --- a/lib/forwardanalyzer.cpp +++ b/lib/forwardanalyzer.cpp @@ -383,13 +383,13 @@ namespace { std::pair exprToks = stepTok->findExpressionStartEndTokens(); if (exprToks.first != nullptr && exprToks.second != nullptr) stepChangesCond |= - findExpressionChanged(condTok, exprToks.first, exprToks.second->next(), &settings, true) != nullptr; + findExpressionChanged(condTok, exprToks.first, exprToks.second->next(), &settings) != nullptr; } - const bool bodyChangesCond = findExpressionChanged(condTok, endBlock->link(), endBlock, &settings, true); + const bool bodyChangesCond = findExpressionChanged(condTok, endBlock->link(), endBlock, &settings); // Check for mutation in the condition const bool condChanged = nullptr != findAstNode(condTok, [&](const Token* tok) { - return isVariableChanged(tok, 0, &settings, true); + return isVariableChanged(tok, 0, &settings); }); const bool changed = stepChangesCond || bodyChangesCond || condChanged; if (!changed) diff --git a/lib/fwdanalysis.cpp b/lib/fwdanalysis.cpp index e0b3074ff0d..264153d1fd0 100644 --- a/lib/fwdanalysis.cpp +++ b/lib/fwdanalysis.cpp @@ -272,12 +272,12 @@ FwdAnalysis::Result FwdAnalysis::checkRecursive(const Token *expr, const Token * if (exprVarIds.find(tok->varId()) != exprVarIds.end()) { const Token *parent = tok; bool other = false; - bool same = tok->astParent() && isSameExpression(mCpp, false, expr, tok, mLibrary, true, false, nullptr); + bool same = tok->astParent() && isSameExpression(false, expr, tok, mLibrary, true, false, nullptr); while (!same && Token::Match(parent->astParent(), "*|.|::|[|(|%cop%")) { parent = parent->astParent(); if (parent->str() == "(" && !parent->isCast()) break; - if (isSameExpression(mCpp, false, expr, parent, mLibrary, true, false, nullptr)) { + if (isSameExpression(false, expr, parent, mLibrary, true, false, nullptr)) { same = true; if (mWhat == What::ValueFlow) { KnownAndToken v; @@ -287,7 +287,7 @@ FwdAnalysis::Result FwdAnalysis::checkRecursive(const Token *expr, const Token * } } if (Token::Match(parent, ". %var%") && parent->next()->varId() && exprVarIds.find(parent->next()->varId()) == exprVarIds.end() && - isSameExpression(mCpp, false, expr->astOperand1(), parent->astOperand1(), mLibrary, true, false, nullptr)) { + isSameExpression(false, expr->astOperand1(), parent->astOperand1(), mLibrary, true, false, nullptr)) { other = true; break; } @@ -317,7 +317,7 @@ FwdAnalysis::Result FwdAnalysis::checkRecursive(const Token *expr, const Token * if (hasGccCompoundStatement(parent->astParent()->astOperand2())) return Result(Result::Type::BAILOUT); // cppcheck-suppress shadowFunction - TODO: fix this - const bool reassign = isSameExpression(mCpp, false, expr, parent, mLibrary, false, false, nullptr); + const bool reassign = isSameExpression(false, expr, parent, mLibrary, false, false, nullptr); if (reassign) return Result(Result::Type::WRITE, parent->astParent()); return Result(Result::Type::READ); @@ -395,11 +395,6 @@ FwdAnalysis::Result FwdAnalysis::checkRecursive(const Token *expr, const Token * return Result(Result::Type::NONE); } -bool FwdAnalysis::isGlobalData(const Token *expr) const -{ - return ::isGlobalData(expr, mCpp); -} - std::set FwdAnalysis::getExprVarIds(const Token* expr, bool* localOut, bool* unknownVarIdOut) const { // all variable ids in expr. @@ -469,7 +464,7 @@ bool FwdAnalysis::hasOperand(const Token *tok, const Token *lhs) const { if (!tok) return false; - if (isSameExpression(mCpp, false, tok, lhs, mLibrary, false, false, nullptr)) + if (isSameExpression(false, tok, lhs, mLibrary, false, false, nullptr)) return true; return hasOperand(tok->astOperand1(), lhs) || hasOperand(tok->astOperand2(), lhs); } @@ -517,7 +512,7 @@ bool FwdAnalysis::possiblyAliased(const Token *expr, const Token *startToken) co if (tok->function() && tok->function()->getArgumentVar(argnr) && !tok->function()->getArgumentVar(argnr)->isReference() && !tok->function()->isConst()) continue; for (const Token *subexpr = expr; subexpr; subexpr = subexpr->astOperand1()) { - if (isSameExpression(mCpp, macro, subexpr, args[argnr], mLibrary, pure, followVar)) { + if (isSameExpression(macro, subexpr, args[argnr], mLibrary, pure, followVar)) { const Scope* scope = expr->scope(); // if there is no other variable, assume no aliasing if (scope->varlist.size() > 1) return true; @@ -542,7 +537,7 @@ bool FwdAnalysis::possiblyAliased(const Token *expr, const Token *startToken) co continue; for (const Token *subexpr = expr; subexpr; subexpr = subexpr->astOperand1()) { - if (subexpr != addrOf && isSameExpression(mCpp, macro, subexpr, addrOf, mLibrary, pure, followVar)) + if (subexpr != addrOf && isSameExpression(macro, subexpr, addrOf, mLibrary, pure, followVar)) return true; } } diff --git a/lib/fwdanalysis.h b/lib/fwdanalysis.h index bc87ff2a597..17fc29f7b42 100644 --- a/lib/fwdanalysis.h +++ b/lib/fwdanalysis.h @@ -37,7 +37,7 @@ class Library; */ class FwdAnalysis { public: - FwdAnalysis(bool cpp, const Library &library) : mCpp(cpp), mLibrary(library) {} + explicit FwdAnalysis(const Library &library) : mLibrary(library) {} bool hasOperand(const Token *tok, const Token *lhs) const; @@ -82,10 +82,6 @@ class FwdAnalysis { Result check(const Token *expr, const Token *startToken, const Token *endToken); Result checkRecursive(const Token *expr, const Token *startToken, const Token *endToken, const std::set &exprVarIds, bool local, bool inInnerClass, int depth=0); - // Is expression a l-value global data? - bool isGlobalData(const Token *expr) const; - - const bool mCpp; const Library &mLibrary; enum class What { Reassign, UnusedValue, ValueFlow } mWhat = What::Reassign; std::vector mValueFlow; diff --git a/lib/programmemory.cpp b/lib/programmemory.cpp index 12b53c0acb3..e00075b0118 100644 --- a/lib/programmemory.cpp +++ b/lib/programmemory.cpp @@ -295,7 +295,7 @@ void programMemoryParseCondition(ProgramMemory& pm, const Token* tok, const Toke return; if (!truevalue.isIntValue()) return; - if (endTok && findExpressionChanged(vartok, tok->next(), endTok, settings, true)) + if (endTok && findExpressionChanged(vartok, tok->next(), endTok, settings)) return; const bool impossible = (tok->str() == "==" && !then) || (tok->str() == "!=" && then); const ValueFlow::Value& v = then ? truevalue : falsevalue; @@ -323,7 +323,7 @@ void programMemoryParseCondition(ProgramMemory& pm, const Token* tok, const Toke pm.setIntValue(tok, 0, then); } } else if (tok && tok->exprId() > 0) { - if (endTok && findExpressionChanged(tok, tok->next(), endTok, settings, true)) + if (endTok && findExpressionChanged(tok, tok->next(), endTok, settings)) return; pm.setIntValue(tok, 0, then); assert(settings); @@ -381,7 +381,7 @@ static void fillProgramMemoryFromAssignments(ProgramMemory& pm, const Token* tok } } } else if (tok2->exprId() > 0 && Token::Match(tok2, ".|(|[|*|%var%") && !pm.hasValue(tok2->exprId()) && - isVariableChanged(tok2, 0, settings, true)) { + isVariableChanged(tok2, 0, settings)) { pm.setUnknown(tok2); } @@ -421,7 +421,7 @@ static void fillProgramMemoryFromAssignments(ProgramMemory& pm, const Token* tok static void removeModifiedVars(ProgramMemory& pm, const Token* tok, const Token* origin) { pm.erase_if([&](const ExprIdToken& e) { - return isVariableChanged(origin, tok, e.getExpressionId(), false, nullptr, true); + return isVariableChanged(origin, tok, e.getExpressionId(), false, nullptr); }); } @@ -508,7 +508,7 @@ void ProgramMemoryState::removeModifiedVars(const Token* tok) state.erase_if([&](const ExprIdToken& e) { const Token* start = origins[e.getExpressionId()]; const Token* expr = e.tok; - if (!expr || findExpressionChangedSkipDeadCode(expr, start, tok, settings, true, eval)) { + if (!expr || findExpressionChangedSkipDeadCode(expr, start, tok, settings, eval)) { origins.erase(e.getExpressionId()); return true; } @@ -1610,7 +1610,7 @@ namespace { if (ValueFlow::isContainerSizeChanged(child, v.indirect, *settings)) v = unknown(); } else if (v.valueType != ValueFlow::Value::ValueType::UNINIT) { - if (isVariableChanged(child, v.indirect, settings, true)) + if (isVariableChanged(child, v.indirect, settings)) v = unknown(); } } diff --git a/lib/reverseanalyzer.cpp b/lib/reverseanalyzer.cpp index 213061e5044..a94e1679bb7 100644 --- a/lib/reverseanalyzer.cpp +++ b/lib/reverseanalyzer.cpp @@ -248,7 +248,7 @@ namespace { // Assignment to } else if (lhsAction.matches() && !assignTok->astOperand2()->hasKnownIntValue() && assignTok->astOperand2()->exprId() > 0 && - isConstExpression(assignTok->astOperand2(), settings.library, true)) { + isConstExpression(assignTok->astOperand2(), settings.library)) { const std::string info = "Assignment to '" + assignTok->expressionString() + "'"; ValuePtr a = analyzer->reanalyze(assignTok->astOperand2(), info); if (a) { diff --git a/lib/symboldatabase.cpp b/lib/symboldatabase.cpp index 4c056626ef1..793ef1375be 100644 --- a/lib/symboldatabase.cpp +++ b/lib/symboldatabase.cpp @@ -58,8 +58,6 @@ SymbolDatabase::SymbolDatabase(Tokenizer& tokenizer, const Settings& settings, E if (!mTokenizer.tokens()) return; - mIsCpp = isCPP(); - if (mSettings.platform.defaultSign == 's' || mSettings.platform.defaultSign == 'S') mDefaultSignedness = ValueType::SIGNED; else if (mSettings.platform.defaultSign == 'u' || mSettings.platform.defaultSign == 'U') @@ -162,7 +160,7 @@ void SymbolDatabase::createSymbolDatabaseFindAllScopes() "SymbolDatabase", tok->progressValue()); // Locate next class - if ((mTokenizer.isCPP() && tok->isKeyword() && + if ((tok->isCpp() && tok->isKeyword() && ((Token::Match(tok, "class|struct|union|namespace ::| %name% final| {|:|::|<") && !Token::Match(tok->previous(), "new|friend|const|enum|typedef|mutable|volatile|using|)|(|<")) || (Token::Match(tok, "enum class| %name% {") || @@ -172,7 +170,7 @@ void SymbolDatabase::createSymbolDatabaseFindAllScopes() if (tok->strAt(1) == "::") tok2 = tok2->next(); - else if (mTokenizer.isCPP() && tok->strAt(1) == "class") + else if (tok->isCpp() && tok->strAt(1) == "class") tok2 = tok2->next(); while (Token::Match(tok2, ":: %name%")) @@ -188,7 +186,7 @@ void SymbolDatabase::createSymbolDatabaseFindAllScopes() } // skip over final - if (mTokenizer.isCPP() && Token::simpleMatch(tok2, "final")) + if (tok2 && tok2->isCpp() && Token::simpleMatch(tok2, "final")) tok2 = tok2->next(); // make sure we have valid code @@ -256,7 +254,7 @@ void SymbolDatabase::createSymbolDatabaseFindAllScopes() } // definition may be different than declaration - if (mTokenizer.isCPP() && tok->str() == "class") { + if (tok->isCpp() && tok->str() == "class") { access[new_scope] = AccessControl::Private; new_scope->type = Scope::eClass; } else if (tok->str() == "struct") { @@ -315,7 +313,7 @@ void SymbolDatabase::createSymbolDatabaseFindAllScopes() } if (new_scope->type == Scope::eEnum) { - tok2 = new_scope->addEnum(tok, mTokenizer.isCPP()); + tok2 = new_scope->addEnum(tok); scope->nestedList.push_back(new_scope); if (!tok2) @@ -331,7 +329,7 @@ void SymbolDatabase::createSymbolDatabaseFindAllScopes() } // Namespace and unknown macro (#3854) - else if (mTokenizer.isCPP() && tok->isKeyword() && + else if (tok->isCpp() && tok->isKeyword() && Token::Match(tok, "namespace %name% %type% (") && tok->tokAt(2)->isUpperCaseName() && Token::simpleMatch(tok->linkAt(3), ") {")) { @@ -370,7 +368,7 @@ void SymbolDatabase::createSymbolDatabaseFindAllScopes() } // using namespace - else if (mTokenizer.isCPP() && tok->isKeyword() && Token::Match(tok, "using namespace ::| %type% ;|::")) { + else if (tok->isCpp() && tok->isKeyword() && Token::Match(tok, "using namespace ::| %type% ;|::")) { Scope::UsingInfo using_info; using_info.start = tok; // save location @@ -390,7 +388,7 @@ void SymbolDatabase::createSymbolDatabaseFindAllScopes() } // using type alias - else if (mTokenizer.isCPP() && tok->isKeyword() && Token::Match(tok, "using %name% =") && !tok->tokAt(2)->isSimplifiedTypedef()) { + else if (tok->isCpp() && tok->isKeyword() && Token::Match(tok, "using %name% =") && !tok->tokAt(2)->isSimplifiedTypedef()) { if (tok->strAt(-1) != ">" && !findType(tok->next(), scope)) { // fill typeList.. typeList.emplace_back(tok, nullptr, scope); @@ -603,7 +601,7 @@ void SymbolDatabase::createSymbolDatabaseFindAllScopes() } // friend class declaration? - else if (mTokenizer.isCPP() && tok->isKeyword() && Token::Match(tok, "friend class|struct| ::| %any% ;|::")) { + else if (tok->isCpp() && tok->isKeyword() && Token::Match(tok, "friend class|struct| ::| %any% ;|::")) { Type::FriendInfo friendInfo; // save the name start @@ -1141,7 +1139,7 @@ void SymbolDatabase::createSymbolDatabaseSetFunctionPointers(bool firstPass) inTemplateArg = tok->link(); if (inTemplateArg == tok) inTemplateArg = nullptr; - if (tok->isName() && !tok->function() && tok->varId() == 0 && ((tok->astParent() && tok->astParent()->isComparisonOp()) || Token::Match(tok, "%name% [{(,)>;]")) && !isReservedName(tok->str())) { + if (tok->isName() && !tok->function() && tok->varId() == 0 && ((tok->astParent() && tok->astParent()->isComparisonOp()) || Token::Match(tok, "%name% [{(,)>;]")) && !isReservedName(tok)) { if (tok->next()->str() == ">" && !tok->next()->link()) continue; @@ -1550,7 +1548,7 @@ void SymbolDatabase::createSymbolDatabaseIncompleteVars() } if (mSettings.library.functions.find(fstr) != mSettings.library.functions.end()) continue; - if (mTokenizer.isCPP()) { + if (tok->isCpp()) { const Token* parent = tok->astParent(); while (Token::Match(parent, "::|[|{")) parent = parent->astParent(); @@ -1615,7 +1613,7 @@ namespace { } }; using ExprIdMap = std::map; - void setParentExprId(Token* tok, bool cpp, ExprIdMap& exprIdMap, nonneg int &id) { + void setParentExprId(Token* tok, ExprIdMap& exprIdMap, nonneg int &id) { if (!tok->astParent() || tok->astParent()->isControlFlowKeyword()) return; const Token* op1 = tok->astParent()->astOperand1(); @@ -1632,7 +1630,7 @@ namespace { if (tok->astParent()->isExpandedMacro() || Token::Match(tok->astParent(), "++|--")) { tok->astParent()->exprId(id); ++id; - setParentExprId(tok->astParent(), cpp, exprIdMap, id); + setParentExprId(tok->astParent(), exprIdMap, id); return; } @@ -1674,7 +1672,7 @@ namespace { if (key.operand1 > key.operand2 && key.operand2 && Token::Match(tok->astParent(), "%or%|%oror%|+|*|&|&&|^|==|!=")) { // In C++ the order of operands of + might matter - if (!cpp || + if (!tok->isCpp() || key.parentOp != "+" || !tok->astParent()->valueType() || tok->astParent()->valueType()->isIntegral() || @@ -1691,7 +1689,7 @@ namespace { } else { tok->astParent()->exprId(it->second); } - setParentExprId(tok->astParent(), cpp, exprIdMap, id); + setParentExprId(tok->astParent(), exprIdMap, id); } } @@ -1766,7 +1764,7 @@ void SymbolDatabase::createSymbolDatabaseExprIds() if (tok->varId() > 0) { tok->exprId(tok->varId()); if (tok->astParent() && tok->astParent()->exprId() == 0) - setParentExprId(tok, mTokenizer.isCPP(), exprIdMap, id); + setParentExprId(tok, exprIdMap, id); } else if (tok->astParent() && !tok->astOperand1() && !tok->astOperand2()) { if (tok->tokType() == Token::Type::eBracket) continue; @@ -1789,7 +1787,7 @@ void SymbolDatabase::createSymbolDatabaseExprIds() } } - setParentExprId(tok, mTokenizer.isCPP(), exprIdMap, id); + setParentExprId(tok, exprIdMap, id); } } for (Token* tok = const_cast(scope->bodyStart); tok != scope->bodyEnd; tok = tok->next()) { @@ -1978,7 +1976,7 @@ bool SymbolDatabase::isFunction(const Token *tok, const Scope* outerScope, const return false; // regular function? - else if (Token::Match(tok, "%name% (") && !isReservedName(tok->str()) && tok->previous() && + else if (Token::Match(tok, "%name% (") && !isReservedName(tok) && tok->previous() && (Token::Match(tok->previous(), "%name%|>|&|&&|*|::|~") || // Either a return type or scope qualifier in front of tok outerScope->isClassOrStructOrUnion())) { // or a ctor/dtor const Token* tok1 = tok->previous(); @@ -2020,7 +2018,7 @@ bool SymbolDatabase::isFunction(const Token *tok, const Scope* outerScope, const // done if constructor or destructor if (!Token::Match(tok1, "{|}|;|public:|protected:|private:") && tok1) { // skip over pointers and references - while (Token::Match(tok1, "%type%|*|&|&&") && !endsWith(tok1->str(), ':') && (!isReservedName(tok1->str()) || tok1->str() == "const")) + while (Token::Match(tok1, "%type%|*|&|&&") && !endsWith(tok1->str(), ':') && (!isReservedName(tok1) || tok1->str() == "const")) tok1 = tok1->previous(); // skip over decltype @@ -2063,7 +2061,7 @@ bool SymbolDatabase::isFunction(const Token *tok, const Scope* outerScope, const // skip over modifiers and other stuff while (Token::Match(tok1, "const|static|extern|template|virtual|struct|class|enum|%name%")) { // friend type func(); is not a function - if (isCPP() && tok1->str() == "friend" && tok2->str() == ";") + if (tok1->isCpp() && tok1->str() == "friend" && tok2->str() == ";") return false; tok1 = tok1->previous(); } @@ -2113,7 +2111,7 @@ bool SymbolDatabase::isFunction(const Token *tok, const Scope* outerScope, const } // regular C function with missing return or invalid C++ ? - else if (Token::Match(tok, "%name% (") && !isReservedName(tok->str()) && + else if (Token::Match(tok, "%name% (") && !isReservedName(tok) && Token::simpleMatch(tok->linkAt(1), ") {") && (!tok->previous() || Token::Match(tok->previous(), ";|}"))) { if (tok->isC()) { @@ -2843,8 +2841,7 @@ static bool typesMatch( bool Function::argsMatch(const Scope *scope, const Token *first, const Token *second, const std::string &path, nonneg int path_length) const { - const bool isCPP = scope->check->isCPP(); - if (!isCPP) // C does not support overloads + if (!first->isCpp()) // C does not support overloads return true; int arg_path_length = path_length; @@ -4759,7 +4756,7 @@ Scope::Scope(const SymbolDatabase *check_, const Token *classDef_, const Scope * const Token *nameTok = classDef; if (!classDef) { type = Scope::eGlobal; - } else if (classDef->str() == "class" && check && check->isCPP()) { + } else if (classDef->str() == "class" && classDef->isCpp()) { type = Scope::eClass; nameTok = nameTok->next(); } else if (classDef->str() == "struct") { @@ -5070,7 +5067,7 @@ bool Scope::isVariableDeclaration(const Token* const tok, const Token*& vartok, if (!tok) return false; - const bool isCPP = check && check->mTokenizer.isCPP(); + const bool isCPP = tok->isCpp(); if (isCPP && Token::Match(tok, "throw|new")) return false; @@ -5138,12 +5135,12 @@ bool Scope::isVariableDeclaration(const Token* const tok, const Token*& vartok, return nullptr != vartok; } -const Token * Scope::addEnum(const Token * tok, bool isCpp) +const Token * Scope::addEnum(const Token * tok) { const Token * tok2 = tok->next(); // skip over class if present - if (isCpp && tok2->str() == "class") + if (tok2->isCpp() && tok2->str() == "class") tok2 = tok2->next(); // skip over name @@ -5204,7 +5201,7 @@ const Token * Scope::addEnum(const Token * tok, bool isCpp) if (tok2 == end) { tok2 = tok2->next(); - if (tok2 && tok2->str() != ";" && (isCpp || tok2->str() != ")")) + if (tok2 && tok2->str() != ";" && (tok2->isCpp() || tok2->str() != ")")) tok2 = nullptr; } else tok2 = nullptr; @@ -5830,7 +5827,7 @@ const Function* Scope::findFunction(const Token *tok, bool requireConst) const fallback2++; // Try to evaluate the apparently more complex expression - else if (check->isCPP()) { + else if (arguments[j]->isCpp()) { const Token *vartok = arguments[j]; if (vartok->str() == ".") { const Token* rml = nextAfterAstRightmostLeaf(vartok); @@ -6206,13 +6203,6 @@ const Function *Scope::getDestructor() const //--------------------------------------------------------------------------- -bool SymbolDatabase::isCPP() const -{ - return mTokenizer.isCPP(); -} - -//--------------------------------------------------------------------------- - const Scope *SymbolDatabase::findScope(const Token *tok, const Scope *startScope) const { const Scope *scope = nullptr; @@ -6461,9 +6451,10 @@ Function * SymbolDatabase::findFunctionInScope(const Token *func, const Scope *n //--------------------------------------------------------------------------- -bool SymbolDatabase::isReservedName(const std::string& iName) const +bool SymbolDatabase::isReservedName(const Token* tok) { - if (isCPP()) { + const std::string& iName = tok->str(); + if (tok->isCpp()) { static const auto& cpp_keywords = Keywords::getAll(Standards::cppstd_t::CPPLatest); return cpp_keywords.find(iName) != cpp_keywords.cend(); } @@ -6489,7 +6480,6 @@ static const Token* parsedecl(const Token* type, ValueType* const valuetype, ValueType::Sign defaultSignedness, const Settings& settings, - bool isCpp, SourceLocation loc = SourceLocation::current()); void SymbolDatabase::setValueType(Token* tok, const Variable& var, const SourceLocation &loc) @@ -6511,7 +6501,7 @@ void SymbolDatabase::setValueType(Token* tok, const Variable& var, const SourceL valuetype.containerTypeToken = var.valueType()->containerTypeToken; } valuetype.smartPointerType = var.smartPointerType(); - if (parsedecl(var.typeStartToken(), &valuetype, mDefaultSignedness, mSettings, mIsCpp)) { + if (parsedecl(var.typeStartToken(), &valuetype, mDefaultSignedness, mSettings)) { if (tok->str() == "." && tok->astOperand1()) { const ValueType * const vt = tok->astOperand1()->valueType(); if (vt && (vt->constness & 1) != 0) @@ -6590,7 +6580,7 @@ void SymbolDatabase::setValueType(Token* tok, const ValueType& valuetype, const const ValueType *vt2 = parent->astOperand2() ? parent->astOperand2()->valueType() : nullptr; if (vt1 && Token::Match(parent, "<<|>>")) { - if (!mIsCpp || (vt2 && vt2->isIntegral())) { + if (!parent->isCpp() || (vt2 && vt2->isIntegral())) { if (vt1->type < ValueType::Type::BOOL || vt1->type >= ValueType::Type::INT) { ValueType vt(*vt1); vt.reference = Reference::None; @@ -6610,7 +6600,7 @@ void SymbolDatabase::setValueType(Token* tok, const ValueType& valuetype, const if (vt1 && vt1->container && vt1->containerTypeToken && Token::Match(parent, ". %name% (") && isContainerYieldElement(vt1->container->getYield(parent->next()->str()))) { ValueType item; - if (parsedecl(vt1->containerTypeToken, &item, mDefaultSignedness, mSettings, mIsCpp)) { + if (parsedecl(vt1->containerTypeToken, &item, mDefaultSignedness, mSettings)) { if (item.constness == 0) item.constness = vt1->constness; if (item.volatileness == 0) @@ -6635,8 +6625,8 @@ void SymbolDatabase::setValueType(Token* tok, const ValueType& valuetype, const auto vt = *vt1; vt.reference = Reference::None; setValueType(parent, vt); - } else if (mIsCpp && ((Token::Match(parent->tokAt(-3), "%var% ; %var% =") && parent->strAt(-3) == parent->strAt(-1)) || - Token::Match(parent->tokAt(-1), "%var% ="))) { + } else if (parent->isCpp() && ((Token::Match(parent->tokAt(-3), "%var% ; %var% =") && parent->strAt(-3) == parent->strAt(-1)) || + Token::Match(parent->tokAt(-1), "%var% ="))) { Token *var1Tok = parent->strAt(-2) == ";" ? parent->tokAt(-3) : parent->tokAt(-1); Token *autoTok = nullptr; if (Token::simpleMatch(var1Tok->tokAt(-1), "auto")) @@ -6693,7 +6683,7 @@ void SymbolDatabase::setValueType(Token* tok, const ValueType& valuetype, const return; } - if (parent->str() == "[" && (!mIsCpp || parent->astOperand1() == tok) && valuetype.pointer > 0U && !Token::Match(parent->previous(), "[{,]")) { + if (parent->str() == "[" && (!parent->isCpp() || parent->astOperand1() == tok) && valuetype.pointer > 0U && !Token::Match(parent->previous(), "[{,]")) { const Token *op1 = parent->astOperand1(); while (op1 && op1->str() == "[") op1 = op1->astOperand1(); @@ -6728,7 +6718,7 @@ void SymbolDatabase::setValueType(Token* tok, const ValueType& valuetype, const if (parent->str() == "*" && !parent->astOperand2() && valuetype.type == ValueType::Type::ITERATOR && valuetype.containerTypeToken) { ValueType vt; - if (parsedecl(valuetype.containerTypeToken, &vt, mDefaultSignedness, mSettings, mIsCpp)) { + if (parsedecl(valuetype.containerTypeToken, &vt, mDefaultSignedness, mSettings)) { if (vt.constness == 0) vt.constness = valuetype.constness; if (vt.volatileness == 0) @@ -6742,7 +6732,7 @@ void SymbolDatabase::setValueType(Token* tok, const ValueType& valuetype, const if (parent->str() == "*" && !parent->astOperand2() && valuetype.type == ValueType::Type::SMART_POINTER && valuetype.smartPointerTypeToken) { ValueType vt; - if (parsedecl(valuetype.smartPointerTypeToken, &vt, mDefaultSignedness, mSettings, mIsCpp)) { + if (parsedecl(valuetype.smartPointerTypeToken, &vt, mDefaultSignedness, mSettings)) { if (vt.constness == 0) vt.constness = valuetype.constness; if (vt.volatileness == 0) @@ -6875,7 +6865,7 @@ void SymbolDatabase::setValueType(Token* tok, const ValueType& valuetype, const autovt.type = ValueType::Type::NONSTD; } } - } else if (parsedecl(vt2->containerTypeToken, &autovt, mDefaultSignedness, mSettings, mIsCpp)) { + } else if (parsedecl(vt2->containerTypeToken, &autovt, mDefaultSignedness, mSettings)) { setType = true; templateArgType = vt2->containerTypeToken->type(); if (Token::simpleMatch(autoToken->next(), "&")) @@ -6923,19 +6913,19 @@ void SymbolDatabase::setValueType(Token* tok, const ValueType& valuetype, const if (vt1 && vt1->containerTypeToken && parent->str() == "[") { ValueType vtParent; - if (parsedecl(vt1->containerTypeToken, &vtParent, mDefaultSignedness, mSettings, mIsCpp)) { + if (parsedecl(vt1->containerTypeToken, &vtParent, mDefaultSignedness, mSettings)) { setValueType(parent, vtParent); return; } } - if (mIsCpp && vt2 && Token::simpleMatch(parent->previous(), "decltype (")) { + if (parent->isCpp() && vt2 && Token::simpleMatch(parent->previous(), "decltype (")) { setValueType(parent, *vt2); return; } // c++17 auto type deduction of braced init list - if (mIsCpp && mSettings.standards.cpp >= Standards::CPP17 && vt2 && Token::Match(parent->tokAt(-2), "auto %var% {")) { + if (parent->isCpp() && mSettings.standards.cpp >= Standards::CPP17 && vt2 && Token::Match(parent->tokAt(-2), "auto %var% {")) { Token *autoTok = parent->tokAt(-2); setValueType(autoTok, *vt2); setAutoTokenProperties(autoTok); @@ -7102,7 +7092,6 @@ static const Token* parsedecl(const Token* type, ValueType* const valuetype, ValueType::Sign defaultSignedness, const Settings& settings, - bool isCpp, SourceLocation loc) { if (settings.debugnormal || settings.debugwarnings) @@ -7164,7 +7153,7 @@ static const Token* parsedecl(const Token* type, if (valuetype->type == ValueType::Type::UNKNOWN_TYPE && type->type() && type->type()->isTypeAlias() && type->type()->typeStart && type->type()->typeStart->str() != type->str() && type->type()->typeStart != previousType) - parsedecl(type->type()->typeStart, valuetype, defaultSignedness, settings, isCpp); + parsedecl(type->type()->typeStart, valuetype, defaultSignedness, settings); else if (Token::Match(type, "const|constexpr")) valuetype->constness |= (1 << (valuetype->pointer - pointer0)); else if (Token::simpleMatch(type, "volatile")) @@ -7196,7 +7185,7 @@ static const Token* parsedecl(const Token* type, if (valuetype->typeScope) valuetype->type = (scope->type == Scope::ScopeType::eClass) ? ValueType::Type::RECORD : ValueType::Type::NONSTD; } - } else if (const Library::Container* container = (isCpp ? settings.library.detectContainerOrIterator(type, &isIterator) : nullptr)) { + } else if (const Library::Container* container = (type->isCpp() ? settings.library.detectContainerOrIterator(type, &isIterator) : nullptr)) { if (isIterator) valuetype->type = ValueType::Type::ITERATOR; else @@ -7218,7 +7207,7 @@ static const Token* parsedecl(const Token* type, // we are past the end of the type type = type->previous(); continue; - } else if (const Library::SmartPointer* smartPointer = (isCpp ? settings.library.detectSmartPointer(type) : nullptr)) { + } else if (const Library::SmartPointer* smartPointer = (type->isCpp() ? settings.library.detectSmartPointer(type) : nullptr)) { const Token* argTok = Token::findsimplematch(type, "<"); if (!argTok) break; @@ -7425,11 +7414,11 @@ void SymbolDatabase::setValueTypeInTokenList(bool reportDebugWarnings, Token *to setValueType(tok, ValueType(sign, type, 0U)); } } else if (tok->isComparisonOp() || tok->tokType() == Token::eLogicalOp) { - if (mIsCpp && tok->isComparisonOp() && (getClassScope(tok->astOperand1()) || getClassScope(tok->astOperand2()))) { + if (tok->isCpp() && tok->isComparisonOp() && (getClassScope(tok->astOperand1()) || getClassScope(tok->astOperand2()))) { const Function *function = getOperatorFunction(tok); if (function) { ValueType vt; - parsedecl(function->retDef, &vt, mDefaultSignedness, mSettings, mIsCpp); + parsedecl(function->retDef, &vt, mDefaultSignedness, mSettings); setValueType(tok, vt); continue; } @@ -7443,7 +7432,7 @@ void SymbolDatabase::setValueTypeInTokenList(bool reportDebugWarnings, Token *to nonneg int const volatileness = 0U; ValueType valuetype(ValueType::Sign::UNKNOWN_SIGN, ValueType::Type::CHAR, pointer, constness, volatileness); - if (mIsCpp && mSettings.standards.cpp >= Standards::CPP20 && tok->isUtf8()) { + if (tok->isCpp() && mSettings.standards.cpp >= Standards::CPP20 && tok->isUtf8()) { valuetype.originalTypeName = "char8_t"; valuetype.fromLibraryType(valuetype.originalTypeName, mSettings); } else if (tok->isUtf16()) { @@ -7455,7 +7444,7 @@ void SymbolDatabase::setValueTypeInTokenList(bool reportDebugWarnings, Token *to } else if (tok->isLong()) { valuetype.originalTypeName = "wchar_t"; valuetype.type = ValueType::Type::WCHAR_T; - } else if ((tok->tokType() == Token::eChar) && ((tok->isCChar() && !mIsCpp) || (tok->isCMultiChar()))) { + } else if ((tok->tokType() == Token::eChar) && ((!tok->isCpp() && tok->isCChar()) || (tok->isCMultiChar()))) { valuetype.type = ValueType::Type::INT; valuetype.sign = ValueType::Sign::SIGNED; } @@ -7465,21 +7454,21 @@ void SymbolDatabase::setValueTypeInTokenList(bool reportDebugWarnings, Token *to // cast if (tok->isCast() && !tok->astOperand2() && Token::Match(tok, "( %name%")) { ValueType valuetype; - if (Token::simpleMatch(parsedecl(tok->next(), &valuetype, mDefaultSignedness, mSettings, mIsCpp), ")")) + if (Token::simpleMatch(parsedecl(tok->next(), &valuetype, mDefaultSignedness, mSettings), ")")) setValueType(tok, valuetype); } // C++ cast else if (tok->astOperand2() && Token::Match(tok->astOperand1(), "static_cast|const_cast|dynamic_cast|reinterpret_cast < %name%") && tok->astOperand1()->linkAt(1)) { ValueType valuetype; - if (Token::simpleMatch(parsedecl(tok->astOperand1()->tokAt(2), &valuetype, mDefaultSignedness, mSettings, mIsCpp), ">")) + if (Token::simpleMatch(parsedecl(tok->astOperand1()->tokAt(2), &valuetype, mDefaultSignedness, mSettings), ">")) setValueType(tok, valuetype); } // Construct smart pointer - else if (mIsCpp && mSettings.library.isSmartPointer(start)) { + else if (start && start->isCpp() && mSettings.library.isSmartPointer(start)) { ValueType valuetype; - if (parsedecl(start, &valuetype, mDefaultSignedness, mSettings, mIsCpp)) { + if (parsedecl(start, &valuetype, mDefaultSignedness, mSettings)) { setValueType(tok, valuetype); setValueType(tok->astOperand1(), valuetype); } @@ -7489,7 +7478,7 @@ void SymbolDatabase::setValueTypeInTokenList(bool reportDebugWarnings, Token *to // function or lambda else if (const Function* f = getFunction(tok->previous())) { ValueType valuetype; - if (parsedecl(f->retDef, &valuetype, mDefaultSignedness, mSettings, mIsCpp)) + if (parsedecl(f->retDef, &valuetype, mDefaultSignedness, mSettings)) setValueType(tok, valuetype); } @@ -7503,7 +7492,7 @@ void SymbolDatabase::setValueTypeInTokenList(bool reportDebugWarnings, Token *to if (Token::Match(tok, "( %type% %type%| *| *| )")) { ValueType vt; - if (parsedecl(tok->next(), &vt, mDefaultSignedness, mSettings, mIsCpp)) { + if (parsedecl(tok->next(), &vt, mDefaultSignedness, mSettings)) { setValueType(tok->next(), vt); } } @@ -7545,21 +7534,21 @@ void SymbolDatabase::setValueTypeInTokenList(bool reportDebugWarnings, Token *to // Aggregate constructor if (Token::Match(tok->previous(), "%name%")) { ValueType valuetype; - if (parsedecl(tok->previous(), &valuetype, mDefaultSignedness, mSettings, mIsCpp)) { + if (parsedecl(tok->previous(), &valuetype, mDefaultSignedness, mSettings)) { if (valuetype.typeScope) { setValueType(tok, valuetype); continue; } } } - if (mIsCpp && tok->astParent() && Token::Match(tok->astOperand1(), "%name%|::")) { + if (tok->isCpp() && tok->astParent() && Token::Match(tok->astOperand1(), "%name%|::")) { const Token *typeStartToken = tok->astOperand1(); while (typeStartToken && typeStartToken->str() == "::") typeStartToken = typeStartToken->astOperand1(); if (mSettings.library.detectContainerOrIterator(typeStartToken) || mSettings.library.detectSmartPointer(typeStartToken)) { ValueType vt; - if (parsedecl(typeStartToken, &vt, mDefaultSignedness, mSettings, mIsCpp)) { + if (parsedecl(typeStartToken, &vt, mDefaultSignedness, mSettings)) { setValueType(tok, vt); continue; } @@ -7569,7 +7558,7 @@ void SymbolDatabase::setValueTypeInTokenList(bool reportDebugWarnings, Token *to if ((e == "std::make_shared" || e == "std::make_unique") && Token::Match(tok->astOperand1(), ":: %name% < %name%")) { ValueType vt; - parsedecl(tok->astOperand1()->tokAt(3), &vt, mDefaultSignedness, mSettings, mIsCpp); + parsedecl(tok->astOperand1()->tokAt(3), &vt, mDefaultSignedness, mSettings); if (vt.typeScope) { vt.smartPointerType = vt.typeScope->definedType; vt.typeScope = nullptr; @@ -7598,7 +7587,7 @@ void SymbolDatabase::setValueTypeInTokenList(bool reportDebugWarnings, Token *to std::istringstream istr(typestr+";"); tokenList.createTokens(istr, tok->isCpp() ? Standards::Language::CPP : Standards::Language::C); tokenList.simplifyStdType(); - if (parsedecl(tokenList.front(), &valuetype, mDefaultSignedness, mSettings, mIsCpp)) { + if (parsedecl(tokenList.front(), &valuetype, mDefaultSignedness, mSettings)) { valuetype.originalTypeName = typestr; setValueType(tok, valuetype); } @@ -7690,7 +7679,7 @@ void SymbolDatabase::setValueTypeInTokenList(bool reportDebugWarnings, Token *to ValueType vt; tokenList.simplifyPlatformTypes(); tokenList.simplifyStdType(); - if (parsedecl(tokenList.front(), &vt, mDefaultSignedness, mSettings, mIsCpp)) { + if (parsedecl(tokenList.front(), &vt, mDefaultSignedness, mSettings)) { vt.originalTypeName = typestr; setValueType(tok, vt); } @@ -7763,7 +7752,7 @@ void SymbolDatabase::setValueTypeInTokenList(bool reportDebugWarnings, Token *to fscope = fscope->nestedIn; if (fscope && fscope->function && fscope->function->retDef) { ValueType vt; - parsedecl(fscope->function->retDef, &vt, mDefaultSignedness, mSettings, mIsCpp); + parsedecl(fscope->function->retDef, &vt, mDefaultSignedness, mSettings); setValueType(tok, vt); } } else if (tok->isKeyword() && tok->str() == "this" && tok->scope()->isExecutable()) { @@ -7805,7 +7794,7 @@ void SymbolDatabase::setValueTypeInTokenList(bool reportDebugWarnings, Token *to ValueType ValueType::parseDecl(const Token *type, const Settings &settings) { ValueType vt; - parsedecl(type, &vt, settings.platform.defaultSign == 'u' ? Sign::UNSIGNED : Sign::SIGNED, settings, type->isCpp()); + parsedecl(type, &vt, settings.platform.defaultSign == 'u' ? Sign::UNSIGNED : Sign::SIGNED, settings); return vt; } diff --git a/lib/symboldatabase.h b/lib/symboldatabase.h index f718e695842..1395caed76d 100644 --- a/lib/symboldatabase.h +++ b/lib/symboldatabase.h @@ -1176,7 +1176,7 @@ class CPPCHECKLIB Scope { */ const Variable *getVariable(const std::string &varname) const; - const Token * addEnum(const Token * tok, bool isCpp); + const Token * addEnum(const Token * tok); const Scope *findRecordInBase(const std::string &name) const; @@ -1387,8 +1387,6 @@ class CPPCHECKLIB SymbolDatabase { void printVariable(const Variable *var, const char *indent) const; void printXml(std::ostream &out) const; - bool isCPP() const; - /* * @brief Do a sanity check */ @@ -1458,8 +1456,8 @@ class CPPCHECKLIB SymbolDatabase { void fixVarId(VarIdMap & varIds, const Token * vartok, Token * membertok, const Variable * membervar); - /** Whether iName is a keyword as defined in http://en.cppreference.com/w/c/keyword and http://en.cppreference.com/w/cpp/keyword*/ - bool isReservedName(const std::string& iName) const; + /** Whether the token is a keyword as defined in http://en.cppreference.com/w/c/keyword and http://en.cppreference.com/w/cpp/keyword*/ + static bool isReservedName(const Token* tok); const Enumerator * findEnumerator(const Token * tok, std::set& tokensThatAreNotEnumeratorValues) const; @@ -1477,7 +1475,6 @@ class CPPCHECKLIB SymbolDatabase { /** list for missing types */ std::list mBlankTypes; - bool mIsCpp; ValueType::Sign mDefaultSignedness; }; diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index da1a6fd0456..9760903f1b3 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -313,7 +313,7 @@ bool Tokenizer::duplicateTypedef(Token **tokPtr, const Token *name, const Token return false; } else if (tok->previous()->str() == "union") { return tok->next()->str() != ";"; - } else if (isCPP() && tok->previous()->str() == "class") { + } else if (tok->isCpp() && tok->previous()->str() == "class") { return tok->next()->str() != ";"; } if (tok) @@ -1697,7 +1697,7 @@ void Tokenizer::simplifyTypedefCpp() } // check for member functions - else if (isCPP() && tok2->str() == "(" && isFunctionHead(tok2, "{:")) { + else if (tok2->isCpp() && tok2->str() == "(" && isFunctionHead(tok2, "{:")) { const Token *func = tok2->previous(); /** @todo add support for multi-token operators */ @@ -1724,7 +1724,7 @@ void Tokenizer::simplifyTypedefCpp() // check for entering a new scope else if (tok2->str() == "{") { // check for entering a new namespace - if (isCPP()) { + if (tok2->isCpp()) { if (tok2->strAt(-2) == "namespace") { if (classLevel < spaceInfo.size() && spaceInfo[classLevel].isNamespace && @@ -1753,7 +1753,7 @@ void Tokenizer::simplifyTypedefCpp() // check for operator typedef /** @todo add support for multi-token operators */ - else if (isCPP() && + else if (tok2->isCpp() && tok2->str() == "operator" && tok2->next() && tok2->next()->str() == typeName->str() && @@ -4528,7 +4528,7 @@ void Tokenizer::setVarIdPass1() for (Token *tok = list.front(); tok; tok = tok->next()) { if (tok->isOp()) continue; - if (isCPP() && Token::simpleMatch(tok, "template <")) { + if (tok->isCpp() && Token::simpleMatch(tok, "template <")) { Token* closingBracket = tok->next()->findClosingBracket(); if (closingBracket) tok = closingBracket; @@ -4722,7 +4722,7 @@ void Tokenizer::setVarIdPass1() ; else if (Token::Match(prev2, "%type% ( !!)") && Token::simpleMatch(tok2->link(), ") ;")) { // In C++ , a variable can't be called operator+ or something like that. - if (isCPP() && + if (prev2->isCpp() && prev2->isOperatorKeyword()) continue; @@ -4804,7 +4804,7 @@ void Tokenizer::setVarIdPass1() if (tok->isName() && !tok->isKeyword() && !tok->isStandardType()) { // don't set variable id after a struct|enum|union - if (Token::Match(tok->previous(), "struct|enum|union") || (isCPP() && tok->strAt(-1) == "class")) + if (Token::Match(tok->previous(), "struct|enum|union") || (tok->isCpp() && tok->strAt(-1) == "class")) continue; bool globalNamespace = false; @@ -6153,7 +6153,7 @@ void Tokenizer::simplifyHeadersAndUnusedTemplates() // functions and types to keep std::set keep; for (const Token *tok = list.front(); tok; tok = tok->next()) { - if (isCPP() && Token::simpleMatch(tok, "template <")) { + if (tok->isCpp() && Token::simpleMatch(tok, "template <")) { const Token *closingBracket = tok->next()->findClosingBracket(); if (Token::Match(closingBracket, "> class|struct %name% {")) tok = closingBracket->linkAt(3); @@ -6884,7 +6884,7 @@ void Tokenizer::simplifyFunctionPointers() Token::Match(tok, "static_cast < %type% %type%| *| *| ( * ) (")) { Token *tok1 = tok; - if (isCPP() && tok1->str() == "static_cast") + if (tok1->isCpp() && tok1->str() == "static_cast") tok1 = tok1->next(); tok1 = tok1->next(); @@ -7085,7 +7085,7 @@ void Tokenizer::simplifyVarDecl(Token * tokBegin, const Token * const tokEnd, co continue; if (isCPP11 && type0->str() == "using") continue; - if (isCPP() && type0->str() == "namespace") + if (type0->isCpp() && type0->str() == "namespace") continue; bool isconst = false; @@ -7744,7 +7744,7 @@ bool Tokenizer::simplifyRedundantParentheses() if (tok->str() != "(") continue; - if (isCPP() && Token::simpleMatch(tok->previous(), "} (")) { + if (tok->isCpp() && Token::simpleMatch(tok->previous(), "} (")) { const Token* plp = tok->previous()->link()->previous(); if (Token::Match(plp, "%name%|>|] {") || (Token::simpleMatch(plp, ")") && Token::simpleMatch(plp->link()->previous(), "]"))) continue; diff --git a/lib/tokenlist.cpp b/lib/tokenlist.cpp index 7039c72ef7e..6cd58a78573 100644 --- a/lib/tokenlist.cpp +++ b/lib/tokenlist.cpp @@ -1424,7 +1424,7 @@ const Token* findLambdaEndTokenWithoutAST(const Token* tok) { return tok->link()->next(); } -static Token * createAstAtToken(Token *tok, bool cpp); +static Token * createAstAtToken(Token *tok); // Compile inner expressions inside inner ({..}) and lambda bodies static void createAstAtTokenInner(Token * const tok1, const Token *endToken, bool cpp) @@ -1445,7 +1445,7 @@ static void createAstAtTokenInner(Token * const tok1, const Token *endToken, boo } if (!hasAst) { for (; tok && tok != endToken && tok != endToken2; tok = tok ? tok->next() : nullptr) - tok = createAstAtToken(tok, cpp); + tok = createAstAtToken(tok); } } else if (cpp && tok->str() == "[") { if (isLambdaCaptureList(tok)) { @@ -1455,7 +1455,7 @@ static void createAstAtTokenInner(Token * const tok1, const Token *endToken, boo const Token * const endToken2 = tok->link(); tok = tok->next(); for (; tok && tok != endToken && tok != endToken2; tok = tok ? tok->next() : nullptr) - tok = createAstAtToken(tok, cpp); + tok = createAstAtToken(tok); } } else if (Token::simpleMatch(tok, "( * ) [")) { @@ -1497,8 +1497,9 @@ static Token * findAstTop(Token *tok1, const Token *tok2) return nullptr; } -static Token * createAstAtToken(Token *tok, bool cpp) +static Token * createAstAtToken(Token *tok) { + const bool cpp = tok->isCpp(); // skip function pointer declaration if (Token::Match(tok, "%type% %type%") && !Token::Match(tok, "return|throw|new|delete")) { Token* tok2 = tok->tokAt(2); @@ -1754,7 +1755,7 @@ static Token * createAstAtToken(Token *tok, bool cpp) void TokenList::createAst() const { for (Token *tok = mTokensFrontBack.front; tok; tok = tok ? tok->next() : nullptr) { - tok = createAstAtToken(tok, isCPP()); + tok = createAstAtToken(tok); } } diff --git a/lib/valueflow.cpp b/lib/valueflow.cpp index 2c734df9925..5a3833419b0 100644 --- a/lib/valueflow.cpp +++ b/lib/valueflow.cpp @@ -1210,7 +1210,7 @@ size_t ValueFlow::getSizeOf(const ValueType &vt, const Settings &settings) static bool getMinMaxValues(const ValueType* vt, const Platform& platform, MathLib::bigint& minValue, MathLib::bigint& maxValue); // Handle various constants.. -static Token * valueFlowSetConstantValue(Token *tok, const Settings &settings, bool cpp) +static Token * valueFlowSetConstantValue(Token *tok, const Settings &settings) { if ((tok->isNumber() && MathLib::isInt(tok->str())) || (tok->tokType() == Token::eChar)) { try { @@ -1240,7 +1240,7 @@ static Token * valueFlowSetConstantValue(Token *tok, const Settings &settings, b if (!tok->isTemplateArg()) value.setKnown(); setTokenValue(tok, std::move(value), settings); - } else if (tok->str() == "NULL" || (cpp && tok->str() == "nullptr")) { + } else if (tok->str() == "NULL" || (tok->isCpp() && tok->str() == "nullptr")) { ValueFlow::Value value(0); if (!tok->isTemplateArg()) value.setKnown(); @@ -1359,7 +1359,7 @@ static Token * valueFlowSetConstantValue(Token *tok, const Settings &settings, b } } else if (tok2->tokType() == Token::eChar) { nonneg int sz = 0; - if (cpp && settings.standards.cpp >= Standards::CPP20 && tok2->isUtf8()) + if (tok2->isCpp() && settings.standards.cpp >= Standards::CPP20 && tok2->isUtf8()) sz = 1; else if (tok2->isUtf16()) sz = 2; @@ -1367,7 +1367,7 @@ static Token * valueFlowSetConstantValue(Token *tok, const Settings &settings, b sz = 4; else if (tok2->isLong()) sz = settings.platform.sizeof_wchar_t; - else if ((tok2->isCChar() && !cpp) || (tok2->isCMultiChar())) + else if ((!tok2->isCpp() && tok2->isCChar()) || (tok2->isCMultiChar())) sz = settings.platform.sizeof_int; else sz = 1; @@ -1427,7 +1427,7 @@ static Token * valueFlowSetConstantValue(Token *tok, const Settings &settings, b static void valueFlowNumber(TokenList &tokenlist, const Settings& settings) { for (Token *tok = tokenlist.front(); tok;) { - tok = valueFlowSetConstantValue(tok, settings, tokenlist.isCPP()); + tok = valueFlowSetConstantValue(tok, settings); } if (tokenlist.isCPP()) { @@ -1738,7 +1738,7 @@ static void valueFlowSameExpressions(TokenList &tokenlist, const Settings& setti if (!val.isKnown()) continue; - if (isSameExpression(tokenlist.isCPP(), false, tok->astOperand1(), tok->astOperand2(), settings.library, true, true, &val.errorPath)) { + if (isSameExpression(false, tok->astOperand1(), tok->astOperand2(), settings.library, true, true, &val.errorPath)) { setTokenValue(tok, std::move(val), settings); } } @@ -2087,9 +2087,9 @@ static void valueFlowGlobalStaticVar(TokenList &tokenList, const Settings &setti else if (tok->astParent()->isAssignmentOp()) { if (tok == tok->astParent()->astOperand1()) vars.erase(tok->variable()); - else if (tokenList.isCPP() && Token::Match(tok->astParent()->tokAt(-2), "& %name% =")) + else if (tok->isCpp() && Token::Match(tok->astParent()->tokAt(-2), "& %name% =")) vars.erase(tok->variable()); - } else if (isLikelyStreamRead(tokenList.isCPP(), tok->astParent())) { + } else if (isLikelyStreamRead(tok->astParent())) { vars.erase(tok->variable()); } else if (Token::Match(tok->astParent(), "[(,]")) vars.erase(tok->variable()); @@ -2417,7 +2417,7 @@ static bool bifurcateVariableChanged(const Variable* var, bool result = false; const Token* tok = start; while ((tok = findVariableChanged( - tok->next(), end, var->isPointer(), var->declarationId(), var->isGlobal(), &settings, true))) { + tok->next(), end, var->isPointer(), var->declarationId(), var->isGlobal(), &settings))) { if (Token::Match(tok->astParent(), "%assign%")) { if (!bifurcate(tok->astParent()->astOperand2(), varids, settings, depth - 1)) return true; @@ -2572,7 +2572,7 @@ struct ValueFlowAnalyzer : Analyzer { return result; } if (Token::Match(tok, "%cop%")) { - if (isLikelyStream(isCPP(), tok->astOperand1())) { + if (isLikelyStream(tok->astOperand1())) { result.dependent = false; return result; } @@ -2643,7 +2643,7 @@ struct ValueFlowAnalyzer : Analyzer { return read | Action::Invalid; if (inconclusive) return read | Action::Inconclusive; - if (isVariableChanged(tok, getIndirect(tok), &getSettings(), isCPP())) { + if (isVariableChanged(tok, getIndirect(tok), &getSettings())) { if (Token::Match(tok->astParent(), "*|[|.|++|--")) return read | Action::Invalid; // Check if its assigned to the same value @@ -2672,13 +2672,13 @@ struct ValueFlowAnalyzer : Analyzer { } } for (int i = 0; i <= indirect; ++i) - if (isVariableChanged(tok, i, &getSettings(), isCPP())) + if (isVariableChanged(tok, i, &getSettings())) return Action::Invalid; return Action::None; } virtual Action isThisModified(const Token* tok) const { - if (isThisChanged(tok, 0, &getSettings(), isCPP())) + if (isThisChanged(tok, 0, &getSettings())) return Action::Invalid; return Action::None; } @@ -3237,7 +3237,7 @@ struct ExpressionAnalyzer : SingleValueFlowAnalyzer { setupExprVarIds(value.tokvalue); } uniqueExprId = - expr->isUniqueExprId() && (Token::Match(expr, "%cop%") || !isVariableChanged(expr, 0, &s, t.isCPP())); + expr->isUniqueExprId() && (Token::Match(expr, "%cop%") || !isVariableChanged(expr, 0, &s)); } static bool nonLocal(const Variable* var, bool deref) { @@ -3275,7 +3275,7 @@ struct ExpressionAnalyzer : SingleValueFlowAnalyzer { if (!Token::simpleMatch(tok->previous(), ".")) { const Variable* var = tok->variable(); if (var && var->isReference() && var->isLocal() && Token::Match(var->nameToken(), "%var% [=(]") && - !isGlobalData(var->nameToken()->next()->astOperand2(), isCPP())) + !isGlobalData(var->nameToken()->next()->astOperand2())) return ChildrenToVisit::none; const bool deref = tok->astParent() && (tok->astParent()->isUnaryOp("*") || @@ -3337,7 +3337,7 @@ struct SameExpressionAnalyzer : ExpressionAnalyzer { bool match(const Token* tok) const override { - return isSameExpression(isCPP(), true, expr, tok, getSettings().library, true, true); + return isSameExpression(true, expr, tok, getSettings().library, true, true); } }; @@ -3353,7 +3353,7 @@ struct OppositeExpressionAnalyzer : ExpressionAnalyzer { } bool match(const Token* tok) const override { - return isOppositeCond(isNot, isCPP(), expr, tok, getSettings().library, true, true); + return isOppositeCond(isNot, expr, tok, getSettings().library, true, true); } }; @@ -3561,7 +3561,7 @@ static std::vector getLifetimeTokens(const Token* tok, if (Token::Match(varDeclEndToken, "=|{")) { errorPath.emplace_back(varDeclEndToken, "Assigned to reference."); const Token *vartok = varDeclEndToken->astOperand2(); - const bool temporary = isTemporary(true, vartok, nullptr, true); + const bool temporary = isTemporary(vartok, nullptr, true); const bool nonlocal = var->isStatic() || var->isGlobal(); if (vartok == tok || (nonlocal && temporary) || (!escape && (var->isConst() || var->isRValueReference()) && temporary)) @@ -4012,7 +4012,7 @@ static void valueFlowForwardLifetime(Token * tok, TokenList &tokenlist, ErrorLog // TODO: handle `[` if (Token::simpleMatch(parent->astOperand1(), ".")) { const Token* parentLifetime = - getParentLifetime(tokenlist.isCPP(), parent->astOperand1()->astOperand2(), &settings.library); + getParentLifetime(parent->astOperand1()->astOperand2(), &settings.library); if (parentLifetime && parentLifetime->exprId() > 0) { valueFlowForward(nextExpression, endOfVarScope, parentLifetime, std::move(values), tokenlist, errorLogger, settings); } @@ -4527,7 +4527,7 @@ static void valueFlowLifetimeFunction(Token *tok, TokenList &tokenlist, ErrorLog if (returnTok == tok) continue; const Variable *returnVar = ValueFlow::getLifetimeVariable(returnTok); - if (returnVar && returnVar->isArgument() && (returnVar->isConst() || !isVariableChanged(returnVar, &settings, tokenlist.isCPP()))) { + if (returnVar && returnVar->isArgument() && (returnVar->isConst() || !isVariableChanged(returnVar, &settings))) { LifetimeStore ls = LifetimeStore::fromFunctionArg(f, tok, returnVar, tokenlist, settings, errorLogger); ls.inconclusive = inconclusive; ls.forward = false; @@ -5356,7 +5356,7 @@ static void valueFlowConditionExpressions(const TokenList &tokenlist, const Symb continue; if (condTok->hasKnownIntValue()) continue; - if (!isConstExpression(condTok, settings.library, tokenlist.isCPP())) + if (!isConstExpression(condTok, settings.library)) continue; const bool is1 = (condTok->isComparisonOp() || condTok->tokType() == Token::eLogicalOp || astIsBool(condTok)); @@ -5483,7 +5483,7 @@ static void valueFlowSymbolic(const TokenList& tokenlist, const SymbolDatabase& continue; if (tok->astOperand2()->exprId() == 0) continue; - if (!isConstExpression(tok->astOperand2(), settings.library, tokenlist.isCPP())) + if (!isConstExpression(tok->astOperand2(), settings.library)) continue; if (tok->astOperand1()->valueType() && tok->astOperand2()->valueType()) { if (isTruncated( @@ -5782,7 +5782,7 @@ static ValueFlow::Value::Bound findVarBound(const Variable* var, ValueFlow::Value::Bound result = ValueFlow::Value::Bound::Point; const Token* next = start; while ((next = findExpressionChangedSkipDeadCode( - var->nameToken(), next->next(), end, settings, true, &evaluateKnownValues))) { + var->nameToken(), next->next(), end, settings, &evaluateKnownValues))) { ValueFlow::Value::Bound b = ValueFlow::Value::Bound::Point; if (next->varId() != var->declarationId()) return ValueFlow::Value::Bound::Point; @@ -6322,8 +6322,7 @@ struct ConditionHandler { valueFlowReverse(start, endToken, exprTok, values, tokenlist, errorLogger, settings, loc); } - void traverseCondition(const TokenList& tokenlist, - const SymbolDatabase& symboldatabase, + void traverseCondition(const SymbolDatabase& symboldatabase, const Settings& settings, const std::set& skippedFunctions, const std::function& f) const @@ -6352,7 +6351,7 @@ struct ConditionHandler { continue; if (cond.true_values.empty() || cond.false_values.empty()) continue; - if (!isConstExpression(cond.vartok, settings.library, tokenlist.isCPP())) + if (!isConstExpression(cond.vartok, settings.library)) continue; f(cond, tok, scope); } @@ -6365,7 +6364,7 @@ struct ConditionHandler { ErrorLogger* errorLogger, const Settings& settings, const std::set& skippedFunctions) const { - traverseCondition(tokenlist, symboldatabase, settings, skippedFunctions, [&](const Condition& cond, Token* tok, const Scope*) { + traverseCondition(symboldatabase, settings, skippedFunctions, [&](const Condition& cond, Token* tok, const Scope*) { if (cond.vartok->exprId() == 0) return; @@ -6423,7 +6422,7 @@ struct ConditionHandler { if (Token::simpleMatch(top->previous(), "for (")) { if (top->astOperand2() && top->astOperand2()->astOperand2() && findExpressionChanged( - cond.vartok, top->astOperand2()->astOperand2(), top->link(), &settings, tokenlist.isCPP())) { + cond.vartok, top->astOperand2()->astOperand2(), top->link(), &settings)) { if (settings.debugwarnings) bailout(tokenlist, errorLogger, @@ -6438,7 +6437,7 @@ struct ConditionHandler { const Token* const block = top->link()->next(); const Token* const end = block->link(); - if (findExpressionChanged(cond.vartok, start, end, &settings, tokenlist.isCPP())) { + if (findExpressionChanged(cond.vartok, start, end, &settings)) { // If its reassigned in loop then analyze from the end if (!Token::Match(tok, "%assign%|++|--") && findExpression(cond.vartok->exprId(), start, end, [&](const Token* tok2) { @@ -6513,7 +6512,7 @@ struct ConditionHandler { ErrorLogger* errorLogger, const Settings& settings, const std::set& skippedFunctions) const { - traverseCondition(tokenlist, symboldatabase, settings, skippedFunctions, [&](const Condition& cond, Token* condTok, const Scope* scope) { + traverseCondition(symboldatabase, settings, skippedFunctions, [&](const Condition& cond, Token* condTok, const Scope* scope) { Token* top = condTok->astTop(); const MathLib::bigint path = cond.getPath(); @@ -6664,8 +6663,7 @@ struct ConditionHandler { startBlock->link(), cond.vartok->varId(), cond.vartok->variable()->isGlobal(), - &settings, - tokenlist.isCPP())) + &settings)) return; // Check if condition in for loop is always false const Token* initTok = getInitTok(top); @@ -7039,7 +7037,7 @@ struct SymbolicConditionHandler : SimpleConditionHandler { return {}; if (!tok->astOperand2() || tok->astOperand2()->hasKnownIntValue() || tok->astOperand2()->isLiteral()) return {}; - if (!isConstExpression(tok, settings.library, true)) + if (!isConstExpression(tok, settings.library)) return {}; std::vector result; @@ -7147,7 +7145,7 @@ static void valueFlowForLoopSimplify(Token* const bodyStart, const Token * const bodyEnd = bodyStart->link(); // Is variable modified inside for loop - if (isVariableChanged(bodyStart, bodyEnd, expr->varId(), globalvar, &settings, tokenlist.isCPP())) + if (isVariableChanged(bodyStart, bodyEnd, expr->varId(), globalvar, &settings)) return; for (Token *tok2 = bodyStart->next(); tok2 != bodyEnd; tok2 = tok2->next()) { @@ -7934,7 +7932,7 @@ static void valueFlowFunctionReturn(TokenList &tokenlist, ErrorLogger *errorLogg } } -static bool needsInitialization(const Variable* var, bool cpp) +static bool needsInitialization(const Variable* var) { if (!var) return false; @@ -7944,7 +7942,7 @@ static bool needsInitialization(const Variable* var, bool cpp) return true; if (var->type() && var->type()->isUnionType()) return false; - if (!cpp) + if (!var->nameToken()->isCpp()) return true; if (var->type() && var->type()->needInitialization == Type::NeedInitialization::True) return true; @@ -8057,7 +8055,7 @@ static void valueFlowUninit(TokenList& tokenlist, ErrorLogger* const errorLogger continue; if (var->nameToken() != tok || var->isInit()) continue; - if (!needsInitialization(var, tokenlist.isCPP())) + if (!needsInitialization(var)) continue; if (!var->isLocal() || var->isStatic() || var->isExtern() || var->isReference() || var->isThrow()) continue; @@ -8083,7 +8081,7 @@ static void valueFlowUninit(TokenList& tokenlist, ErrorLogger* const errorLogger // Skip array since we can't track partial initialization from nested subexpressions if (memVar.isArray()) continue; - if (!needsInitialization(&memVar, tokenlist.isCPP())) { + if (!needsInitialization(&memVar)) { if (!var->isPointer()) partial = true; continue; @@ -8286,7 +8284,7 @@ struct ContainerExpressionAnalyzer : ExpressionAnalyzer { return read; if (Token::Match(tok->astParent(), "%assign%") && astIsLHS(tok)) return Action::Invalid; - if (isLikelyStreamRead(isCPP(), tok->astParent())) + if (isLikelyStreamRead(tok->astParent())) return Action::Invalid; if (astIsContainer(tok) && ValueFlow::isContainerSizeChanged(tok, getIndirect(tok), getSettings())) return read | Action::Invalid; @@ -8845,7 +8843,7 @@ static void valueFlowContainerSize(TokenList& tokenlist, continue; } if (nameToken->astTop() && Token::Match(nameToken->astTop()->previous(), "for|while")) - known = !isVariableChanged(var, &settings, true); + known = !isVariableChanged(var, &settings); std::vector values{ValueFlow::Value{size}}; values.back().valueType = ValueFlow::Value::ValueType::CONTAINER_SIZE; if (known) @@ -9108,7 +9106,7 @@ static void valueFlowDynamicBufferSize(const TokenList& tokenlist, const SymbolD if (!rhs) continue; - const bool isNew = symboldatabase.isCPP() && rhs->str() == "new"; + const bool isNew = rhs->isCpp() && rhs->str() == "new"; if (!isNew && !Token::Match(rhs->previous(), "%name% (")) continue; @@ -9343,7 +9341,7 @@ const ValueFlow::Value *ValueFlow::valueFlowConstantFoldAST(Token *expr, const S if (expr && expr->values().empty()) { valueFlowConstantFoldAST(expr->astOperand1(), settings); valueFlowConstantFoldAST(expr->astOperand2(), settings); - valueFlowSetConstantValue(expr, settings, true /* TODO: this is a guess */); + valueFlowSetConstantValue(expr, settings); } return expr && expr->hasKnownValue() ? &expr->values().front() : nullptr; } diff --git a/test/testastutils.cpp b/test/testastutils.cpp index 0d05b90072d..9140b16e561 100644 --- a/test/testastutils.cpp +++ b/test/testastutils.cpp @@ -181,7 +181,7 @@ class TestAstUtils : public TestFixture { ASSERT_LOC(tokenizer.tokenize(istr, cpp ? "test.cpp" : "test.c"), file, line); const Token * const tok1 = Token::findsimplematch(tokenizer.tokens(), tokStr1, strlen(tokStr1)); const Token * const tok2 = Token::findsimplematch(tok1->next(), tokStr2, strlen(tokStr2)); - return (isSameExpression)(cpp, false, tok1, tok2, library, false, true, nullptr); + return (isSameExpression)(false, tok1, tok2, library, false, true, nullptr); } void isSameExpressionTestInternal(bool cpp) { @@ -229,7 +229,7 @@ class TestAstUtils : public TestFixture { ASSERT_LOC(tokenizer.tokenize(istr, "test.cpp"), file, line); const Token * const tok1 = Token::findsimplematch(tokenizer.tokens(), startPattern, strlen(startPattern)); const Token * const tok2 = Token::findsimplematch(tokenizer.tokens(), endPattern, strlen(endPattern)); - return (isVariableChanged)(tok1, tok2, 1, false, &settingsDefault, /*cpp*/ true); + return (isVariableChanged)(tok1, tok2, 1, false, &settingsDefault); } void isVariableChangedTest() { @@ -407,7 +407,7 @@ class TestAstUtils : public TestFixture { const Token* const start = Token::findsimplematch(tokenizer.tokens(), startPattern, strlen(startPattern)); const Token* const end = Token::findsimplematch(start, endPattern, strlen(endPattern)); const Token* const expr = Token::findsimplematch(tokenizer.tokens(), var, strlen(var)); - return (findExpressionChanged)(expr, start, end, &settings, /*cpp*/ true); + return (findExpressionChanged)(expr, start, end, &settings); } void isExpressionChangedTest()