42 #include <initializer_list>
46 #include <type_traits>
47 #include <unordered_map>
53 const std::function<
bool(
const Token*)>& pred)
59 for (
const Token* tok = start; tok != end; tok = tok->
next()) {
60 if (tok->exprId() != exprid)
71 if (!tok || depth >= 100)
73 if (tok->
str() ==
",") {
99 const Token* tok = ftok;
105 if (!startTok && tok->
next() != tok->
link())
112 std::vector<const Token*> result;
119 std::vector<Token*> result;
127 if (!tok || depth < 0)
129 if (tok->
str() == op)
147 if (tok->
varId() == varid)
156 if (tok->
exprId() == exprid)
168 return valueType->
type == ValueType::Type::CHAR && valueType->
pointer == 0U && valueType->
sign ==
sign;
212 return vt->
type >= ValueType::Type::FLOAT && vt->
pointer == 0U;
282 return parent->
next();
318 return function->containerYield;
330 std::pair<const Token*, const Token*> decl =
Token::typeDecl(expr, pointedToType);
331 if (decl.first && decl.second) {
333 for (
const Token *type = decl.first;
Token::Match(type,
"%name%|::") && type != decl.second; type = type->next()) {
344 if (tok->
str() == rhs)
356 const Token *ret =
nullptr;
360 std::string s = tok->
str();
363 else if (s[0] ==
'<')
371 }
else if (comp ==
"!=" && rhs ==
"0") {
372 if (tok->
str() ==
"!") {
378 }
else if (comp ==
"==" && rhs ==
"0") {
379 if (tok->
str() ==
"!") {
385 while (ret && ret->
str() ==
".")
389 else if (ret && ret->
varId() == 0U)
406 return Token::Match(varDeclEndToken,
"; %var%") && varDeclEndToken->
next() == tok;
411 return Token::Match(tok,
"std :: string|wstring|u16string|u32string !!::") ||
455 const Token* ftok =
nullptr;
468 return !returnType.empty() && returnType.back() !=
'&';
496 for (
const Token * tok2 = startTok; tok2 != stopTok; tok2 = tok2->
next()) {
503 template<
class T,
REQUIRES(
"T must be a Token class", std::is_convertible<T*, const Token*> )>
508 T* leftmostLeaf = tok;
509 while (leftmostLeaf->astOperand1())
510 leftmostLeaf = leftmostLeaf->astOperand1();
511 return leftmostLeaf->previous();
523 template<
class T,
REQUIRES(
"T must be a Token class", std::is_convertible<T*, const Token*> )>
526 T * rightmostLeaf = tok;
527 if (!rightmostLeaf || !rightmostLeaf->astOperand1())
534 if (rightmostLeaf->astOperand2() &&
precedes(rightmostLeaf, rightmostLeaf->astOperand2()))
535 rightmostLeaf = rightmostLeaf->astOperand2();
536 else if (rightmostLeaf->astOperand1() &&
precedes(rightmostLeaf, rightmostLeaf->astOperand1()))
537 rightmostLeaf = rightmostLeaf->astOperand1();
540 }
while (rightmostLeaf->astOperand1() || rightmostLeaf->astOperand2());
541 while (
Token::Match(rightmostLeaf->next(),
"]|)") && !
hasToken(rightmostLeaf->next()->link(), rightmostLeaf->next(), tok))
542 rightmostLeaf = rightmostLeaf->next();
543 if (
Token::Match(rightmostLeaf,
"{|(|[") && rightmostLeaf->link())
544 rightmostLeaf = rightmostLeaf->link();
545 return rightmostLeaf->next();
624 std::vector<const Token*> result;
628 result.insert(result.end(), sub.cbegin(), sub.cend());
630 result.push_back(tok2);
645 if (members.size() < 2)
648 auto it = std::find_if(members.crbegin(), members.crend(), [&](
const Token* tok2) {
649 const Variable* var = tok2->variable();
651 return var->isLocal() || var->isArgument();
652 if (Token::simpleMatch(tok2,
"["))
654 return isTemporary(tok2, &library);
656 if (it == members.rend())
659 if (std::any_of(it.base() - 1, members.cend() - 1, [&](
const Token* tok2) {
660 const Token* obj = getParentLifetimeObject(tok2);
661 const Variable* var = obj->variable();
663 if (var && var->isArray())
665 if (astIsPointer(obj) || astIsContainerView(obj) || astIsIterator(obj))
667 if (!astIsUniqueSmartPointer(obj)) {
668 if (astIsSmartPointer(obj))
670 const Token* dotTok = obj->next();
671 if (!Token::simpleMatch(dotTok,
".")) {
672 const Token* endTok = nextAfterAstRightmostLeaf(obj);
674 dotTok = obj->next();
675 else if (Token::simpleMatch(endTok,
"."))
677 else if (Token::simpleMatch(endTok->next(),
"."))
678 dotTok = endTok->next();
681 if (Token::simpleMatch(dotTok,
".") && dotTok->originalName() ==
"->")
684 return var && var->isReference();
720 *parent = tok->
astParent()->astOperand1();
721 if (tok->
astParent()->astOperand1()->valueType())
722 return {*tok->
astParent()->astOperand1()->valueType()};
725 const Token* ftok =
nullptr;
729 const Token* typeTok =
nullptr;
730 if (ftok && argn >= 0) {
732 std::vector<ValueType> result;
733 const Token* nameTok =
nullptr;
737 if (!var->valueType())
739 nameTok = var->nameToken();
740 result.push_back(*var->valueType());
742 if (result.size() == 1 && nameTok && parent) {
750 const Scope* scope = t->classScope;
755 assert(argn < scope->varlist.size());
756 auto it = std::next(scope->
varlist.cbegin(), argn);
758 return {*it->valueType()};
765 const Token* contTok = tok->
astParent()->tokAt(-2)->astOperand1();
770 return {std::move(vtParent)};
811 template<
class T,
REQUIRES(
"T must be a Token class", std::is_convertible<T*, const Token*> )>
819 tok->next()->astOperand2()->astOperand2())
820 return tok->next()->astOperand2()->astOperand2()->astOperand1();
822 return tok->next()->astOperand2()->astOperand1();
823 return tok->next()->astOperand2();
826 template<
class T,
REQUIRES(
"T must be a Token class", std::is_convertible<T*, const Token*> )>
831 T* startBlock = endBlock->link();
835 return getCondTok(startBlock->previous()->link());
841 template<
class T,
REQUIRES(
"T must be a Token class", std::is_convertible<T*, const Token*> )>
848 if (tok->str() !=
"(")
854 return tok->astOperand2()->astOperand1();
857 template<
class T,
REQUIRES(
"T must be a Token class", std::is_convertible<T*, const Token*> )>
864 if (tok->str() !=
"(")
870 return tok->astOperand2()->astOperand2()->astOperand2();
909 if (scope->
isLoopScope() || scope->
type == Scope::ScopeType::eSwitch) {
921 bool &knownInitValue,
935 if (minInitValue.empty()) {
938 minInitValue.push_back(v->
intvalue);
940 if (minInitValue.empty())
943 knownInitValue = initExpr->
astOperand2()->hasKnownIntValue();
944 initValue = minInitValue.front();
950 if (Token::Match(condExpr,
"%oror%|&&") || tok->astOperand2()->getKnownIntValue() < condExpr->astOperand2()->getKnownIntValue())
960 if (condExpr->
str() ==
"<")
961 lastValue = condExpr->
astOperand2()->getKnownIntValue() - 1;
963 lastValue = condExpr->
astOperand2()->getKnownIntValue();
973 if (!varDeclEndToken)
1012 if (tok->
varId() == varid)
1016 if (!val.isLocalLifetimeValue())
1018 if (val.tokvalue->varId() == varid) {
1019 if (val.isInconclusive()) {
1034 const Token* r =
nullptr;
1040 if (childTok->
exprId() == 0)
1042 if (ref.token != tok && expr->
exprId() == childTok->
exprId()) {
1048 if (val.isImpossible())
1050 if (val.isLocalLifetimeValue() || (pointer && val.isSymbolicValue() && val.intvalue == 0)) {
1051 if (findAstNode(val.tokvalue,
1052 [&](const Token* aliasTok) {
1053 return aliasTok != childTok && aliasTok->exprId() == childTok->exprId();
1055 if (val.isInconclusive() && inconclusive != nullptr) {
1068 if (!r && value && inconclusive)
1077 for (
const Token *tok = startTok; tok != endTok; tok = tok->
next()) {
1102 if (expr->
str() ==
"this")
1117 if (classScope && classScope->
function)
1135 bool result =
false;
1139 return ChildrenToVisit::done;
1203 startToken = varTok;
1204 if (varTok->
exprId() == 0) {
1207 }
else if (!
precedes(startToken, endToken)) {
1224 if (std::find(errors->cbegin(), errors->cend(), item) != errors->cend())
1226 errors->push_back(std::move(item));
1235 struct ReferenceTokenLess {
1244 refs_result.push_back({tok, std::move(errors)});
1251 refs_result.push_back({tok, std::move(errors)});
1256 if (!varDeclEndToken) {
1258 refs_result.push_back({tok, std::move(errors)});
1262 errors.emplace_back(varDeclEndToken,
"Passed to reference.");
1264 refs_result.push_back({tok, std::move(errors)});
1270 errors.emplace_back(varDeclEndToken,
"Assigned to reference.");
1272 if (vartok == tok || (!temporary &&
isTemporary(vartok,
nullptr,
true) &&
1275 refs_result.push_back({tok, std::move(errors)});
1283 std::set<ReferenceToken, ReferenceTokenLess> result;
1287 result.insert(refs.cbegin(), refs.cend());
1289 result.insert(refs.cbegin(), refs.cend());
1293 refs_result.push_back({tok, std::move(errors)});
1297 if (!result.empty()) {
1299 refs_result.insert(refs_result.end(), result.cbegin(), result.cend());
1307 refs_result.push_back({tok, std::move(errors)});
1310 std::set<ReferenceToken, ReferenceTokenLess> result;
1312 for (
const Token* returnTok : returns) {
1313 if (returnTok == tok)
1317 const Variable* argvar = rt.token->variable();
1320 refs_result.push_back({tok, std::move(errors)});
1327 refs_result.push_back({tok, std::move(errors)});
1331 if (n >= args.size()) {
1333 refs_result.push_back({tok, std::move(errors)});
1336 const Token* argTok = args[n];
1338 er.emplace_back(returnTok,
"Return reference.");
1342 result.insert(refs.cbegin(), refs.cend());
1345 refs_result.push_back({tok, std::move(errors)});
1351 if (!result.empty()) {
1353 refs_result.insert(refs_result.end(), result.cbegin(), result.cend());
1358 refs_result.push_back({tok, std::move(errors)});
1367 if (refs.size() == 1) {
1369 *errors = std::move(refs.front().errors);
1370 return refs.front().token;
1390 const auto v1 = std::find_if(tok1->
values().cbegin(), tok1->
values().cend(), isKnownFn);
1391 if (v1 == tok1->
values().end()) {
1394 if (v1->isNonValue() || v1->isContainerSizeValue() || v1->isSymbolicValue())
1396 const auto v2 = std::find_if(tok2->
values().cbegin(), tok2->
values().cend(), isKnownFn);
1397 if (v2 == tok2->
values().end()) {
1400 if (v1->valueType != v2->valueType) {
1404 return compare(*v1, *v2, sameLifetime);
1431 if (tok1 ==
nullptr || tok2 ==
nullptr)
1434 auto adjustForCast = [](
const Token* tok) {
1435 if (tok->astOperand2() &&
Token::Match(tok->previous(),
"%type% (|{") && tok->previous()->isStandardType())
1436 return tok->astOperand2();
1440 tok1 = adjustForCast(tok1);
1443 tok2 = adjustForCast(tok2);
1468 parent->
astParent()->astParent()->astOperand1()->str() ==
"for";
1479 parent->
astParent()->astParent()->astOperand1()->str() ==
"for";
1523 return std::any_of(vtParents.cbegin(), vtParents.cend(), [&](
const ValueType& vt) {
1524 return vt.pointer == 0 && vt.type == ValueType::BOOL;
1553 if (tok1 ==
nullptr || tok2 ==
nullptr)
1556 if (tok1->
isCpp()) {
1569 const bool tok_str_eq = tok1->
str() == tok2->
str();
1573 const Token *followTok1 = tok1, *followTok2 = tok2;
1577 followTok2 = followTok2->astOperand2();
1582 if (followVar && !tok_str_eq && (followTok1->
varId() || followTok2->varId() || followTok1->
enumerator() || followTok2->enumerator())) {
1586 return isSameExpression(macro, varTok1, followTok2, settings,
true, followVar, errors);
1591 return isSameExpression(macro, followTok1, varTok2, settings,
true, followVar, errors);
1596 return isSameExpression(macro, varTok1, varTok2, settings,
true, followVar, errors);
1603 if (refTok1 != tok1 || refTok2 != tok2) {
1604 if (refTok1 && !refTok1->
varId() && refTok2 && !refTok2->
varId()) {
1605 const Token *start = refTok1, *end = refTok2;
1607 std::swap(start, end);
1611 return isSameExpression(macro, refTok1, refTok2, settings, pure, followVar, errors);
1620 const Token* condTok =
nullptr;
1621 const Token* exprTok =
nullptr;
1630 const Token* varTok1 =
nullptr;
1631 const Token* varTok2 = exprTok;
1634 value = &condTok->
astOperand1()->values().front();
1636 }
else if (condTok->
astOperand2()->hasKnownIntValue()) {
1637 value = &condTok->
astOperand2()->values().front();
1643 bool compare =
false;
1656 return isSameExpression(macro, varTok1, varTok2, settings, pure, followVar, errors);
1679 const Token * ftok = tok1;
1686 if (!tok1->
function()->isConst() && !tok1->
function()->isAttributeConst() &&
1687 !tok1->
function()->isAttributePure())
1698 tok1->
str() !=
"dynamic_cast")
1706 while (t1 && t2 && t1 != end1 && t2 != end2) {
1712 if (t1 != end1 || t2 != end2)
1718 if (tok1->
str() ==
"{")
1727 t1->
str() == t2->
str() &&
1733 if (!t1 || !t2 || t1->
str() !=
")" || t2->
str() !=
")")
1736 bool noncommutativeEquals =
1738 noncommutativeEquals = noncommutativeEquals &&
1741 if (noncommutativeEquals)
1753 bool commutativeEquals = commutative &&
1755 commutativeEquals = commutativeEquals &&
1759 return commutativeEquals;
1764 if (cond ==
nullptr)
1769 if (cond->
str() ==
"==" || cond->
str() ==
">=")
1771 if (cond->
str() ==
"<=")
1773 if (cond->
str() ==
"<")
1775 if (cond->
str() ==
">")
1782 if (!cond1 || !cond2)
1785 if (
isSameExpression(
true, cond1, cond2, settings, pure, followVar, errors))
1788 if (!isNot && cond1->
str() ==
"&&" && cond2->
str() ==
"&&") {
1789 for (
const Token* tok1: {
1792 for (
const Token* tok2: {
1795 if (
isSameExpression(
true, tok1, tok2, settings, pure, followVar, errors)) {
1803 if (cond1->
str() != cond2->
str() && (cond1->
str() ==
"||" || cond2->
str() ==
"||")) {
1804 const Token* orCond =
nullptr;
1805 const Token* otherCond =
nullptr;
1806 if (cond1->
str() ==
"||") {
1810 if (cond2->
str() ==
"||") {
1818 if (cond1->
str() ==
"!") {
1819 if (cond2->
str() ==
"!=") {
1830 if (cond2->
str() ==
"!")
1831 return isOppositeCond(isNot, cond2, cond1, settings, pure, followVar, errors);
1834 if (cond1->
str() ==
"==" && cond2->
str() ==
"==") {
1845 cond2->
astOperand1()->astOperand1()->astOperand1(),
1857 cond1->
astOperand1()->astOperand1()->astOperand1(),
1870 const std::string &comp1 = cond1->
str();
1876 comp2 = cond2->
str();
1879 comp2 = cond2->
str();
1880 if (comp2[0] ==
'>')
1882 else if (comp2[0] ==
'<')
1886 if (!isNot && comp2.empty()) {
1887 const Token *expr1 =
nullptr, *value1 =
nullptr, *expr2 =
nullptr, *value2 =
nullptr;
1892 }
else if (cond1->
astOperand1()->hasKnownIntValue()) {
1897 else if (
op1[0] ==
'<')
1903 }
else if (cond2->
astOperand1()->hasKnownIntValue()) {
1908 else if (
op2[0] ==
'<')
1911 if (!expr1 || !value1 || !expr2 || !value2) {
1914 if (!
isSameExpression(
true, expr1, expr2, settings, pure, followVar, errors))
1920 if (
op1 ==
"<" ||
op1 ==
"<=")
1922 if (
op1 ==
">=" ||
op1 ==
">")
1929 return ((comp1 ==
"==" && comp2 ==
"!=") ||
1930 (comp1 ==
"!=" && comp2 ==
"==") ||
1931 (comp1 ==
"<" && comp2 ==
">=") ||
1932 (comp1 ==
"<=" && comp2 ==
">") ||
1933 (comp1 ==
">" && comp2 ==
"<=") ||
1934 (comp1 ==
">=" && comp2 ==
"<") ||
1935 (!isNot && ((comp1 ==
"<" && comp2 ==
">") ||
1936 (comp1 ==
">" && comp2 ==
"<") ||
1937 (comp1 ==
"==" && (comp2 ==
"!=" || comp2 ==
">" || comp2 ==
"<")) ||
1938 ((comp1 ==
"!=" || comp1 ==
">" || comp1 ==
"<") && comp2 ==
"==")
1946 if (
isOppositeCond(
true, tok1, tok2, settings, pure, followVar, errors))
1958 if (var.isReference() || var.isPointer())
1959 return !var.isConst();
1971 if (f->isAttributePure() || f->isAttributeConst())
1984 std::vector<const Function*> fs = f->getOverloadedFunctions();
1985 if (std::any_of(fs.cbegin(), fs.cend(), [&](
const Function* g) {
1988 if (f->argumentList.size() != g->argumentList.size())
1990 if (functionModifiesArguments(g))
1992 if (g->isConst() && Function::returnsConst(g))
2000 if (f->argumentList.empty())
2001 return f->isConstexpr();
2024 bool constMember = !memberFunction;
2034 return constMember && std::all_of(args.cbegin(), args.cend(), [](
const Token* tok) {
2035 const Variable* var = tok->variable();
2037 return var->isConst();
2061 if (tok->
str() ==
"{")
2075 if (tok && tok->
varId()) {
2093 if (f.type != Function::eFunction)
2096 const std::string freturnType = f.retType ? f.retType->name() : f.retDef->stringifyList(f.returnDefEnd());
2097 return f.argumentList.size() != fun->argumentList.size() || returnType != freturnType || f.name() == fun->name();
2105 const Type * varType = var->
type();
2109 auto pred = [=](
const Variable& v) {
2111 return v.
type() && v.
type()->name() == varType->
name() && v.name() != var->
name();
2114 v.isClass() == var->
isClass() &&
2115 v.isArray() == var->
isArray() &&
2117 v.name() != var->
name();
2119 if (std::any_of(scope->
varlist.cbegin(), scope->
varlist.cend(), pred))
2147 return Token::Match(tok,
"return|goto|throw|continue|break");
2156 if (function->isEscapeFunction())
2158 if (function->isAttributeNoreturn())
2160 }
else if (library) {
2177 if (function->isEscapeFunction())
2179 if (function->isAttributeNoreturn())
2187 *unknownFunc = ftok;
2199 if (!endToken || endToken->
str() !=
"}")
2210 return isReturnScope(prev, library, unknownFunc, functionScope) &&
2216 return isReturnScope(prev, library, unknownFunc, functionScope);
2218 if (
isEscaped(prev->
link()->astTop(), functionScope, library))
2221 return isReturnScope(prev, library, unknownFunc, functionScope);
2240 return prev && prev->
isName();
2250 while (scope && scope != var->
scope()) {
2251 if (scope->
type == type)
2262 if (tok->
varId() == varid)
2274 if (tok->
str() ==
"{")
2275 return tok->
scope()->bodyStart == tok;
2276 if (tok->
str() ==
"}")
2277 return tok->
scope()->bodyEnd == tok;
2281 template<
class T,
REQUIRES(
"T must be a Token class", std::is_convertible<T*, const Token*> )>
2286 T* parent = tok->astParent();
2287 if (parent && (parent->isUnaryOp(
"&") || parent->isIncDecOp()))
2288 parent = parent->astParent();
2289 while (parent && parent->isCast())
2290 parent = parent->astParent();
2291 if (
Token::Match(parent,
"[+-]") && parent->valueType() && parent->valueType()->pointer)
2292 parent = parent->astParent();
2299 parent = parent->astParent();
2301 parent = parent->astParent();
2302 if (!parent || parent->str() !=
"(")
2309 while (argtok && argtok->astParent() && (!
Token::Match(argtok->astParent(),
",|(|{") || argtok->astParent()->isCast())) {
2310 argtok = argtok->astParent();
2315 argtok = argtok->astOperand1();
2318 tok = tok->astParent();
2327 if (tok->astOperand2())
2328 tok = tok->astOperand1();
2329 while (tok && (tok->isUnaryOp(
"*") || tok->str() ==
"["))
2330 tok = tok->astOperand1();
2332 return tok->tokAt(2);
2334 tok = tok->astOperand2();
2337 if (!tok->astOperand2() && tok->astOperand1()) {
2338 tok = tok->astOperand1();
2341 tok = tok->astOperand2();
2343 tok = tok->astOperand1();
2345 if (tok && tok->link() && tok->str() ==
">")
2346 tok = tok->link()->previous();
2365 std::vector<const Variable*> result;
2383 if (tokIsBrace && typeScope->
numConstructors == 0 && argnr < typeScope->varlist.size()) {
2384 auto it = std::next(typeScope->
varlist.cbegin(), argnr);
2388 const bool constructor = tokIsBrace || (tok->
variable() && tok->
variable()->nameToken() == tok);
2390 if (
function.argCount() < argCount)
2392 if (constructor && !
function.isConstructor())
2396 const Variable* argvar =
function.getArgumentVar(argnr);
2398 result.push_back(argvar);
2413 const Token* typeTok =
nullptr;
2441 const Token *
const tok1 = tok;
2449 if (deref && indirect > 0)
2468 parenTok = parenTok->
link()->next();
2469 const bool possiblyPassedByReference = (parenTok->
next() == tok1 ||
Token::Match(tok1->
previous(),
", %name% [,)}]"));
2480 if (indirect == 0 &&
isArray(tok1))
2484 if (indirect > 0 && requireInit && requireNonNull)
2491 if (indirect == 0 && requireNonNull)
2494 if (possiblyPassedByReference) {
2504 if (tok == var->nameToken() && (!var->isReference() || var->isConst()) && (!var->isClass() || (var->valueType() && var->valueType()->container)))
2509 bool conclusive =
false;
2515 if (arg->isPointer() && !(arg->valueType() && arg->valueType()->isConst(indirect)))
2517 if (indirect > 1 && addressOf && arg->isPointer() && (!arg->valueType() || !arg->valueType()->isConst(indirect-1)))
2519 if (arg->isArray() || (!arg->isPointer() && (!arg->valueType() || arg->valueType()->type ==
ValueType::UNKNOWN_TYPE)))
2522 if (!arg->isConst() && arg->isReference())
2525 if (addressOf && tok1->
astParent()->isUnaryOp(
"&")) {
2527 while (castToken->
astParent()->isCast())
2549 const Token *tok2 = tok;
2557 if (derefs > indirect)
2579 auto skipRedundantPtrOp = [](
const Token* tok,
const Token* parent) {
2581 while (parent && gparent && ((parent->isUnaryOp(
"*") && gparent->
isUnaryOp(
"&")) || (parent->isUnaryOp(
"&") && gparent->
isUnaryOp(
"*")))) {
2589 tok2 = skipRedundantPtrOp(tok2, tok2->
astParent());
2592 if (((indirect == 0 || tok2 != tok) || (indirect == 1 && tok2->
str() ==
".")) && tok2 == tok2->
astParent()->astOperand1())
2611 if (vt && vt->
isConst(indirect))
2623 tok2->
astParent()->astOperand1() == tok2) {
2685 const Token *ftok = tok2;
2692 const Token * ptok = tok2;
2695 int pindirect = indirect;
2713 const Token *typeStart = tok2->
astParent()->previous()->link()->previous();
2717 for (
const Token *vartok = typeStart->
tokAt(2); vartok != tok2; vartok = vartok->
next()) {
2718 if (vartok->varId()) {
2719 const Variable* refvar = vartok->variable();
2750 (parent->
astParent()->astOperand1() == parent)) {
2766 return findVariableChanged(start, end, indirect, exprid, globalvar, settings, depth) !=
nullptr;
2778 if (tok->exprId() != exprid)
2786 template<class F, class R=decltype(std::declval<F>()())>
2791 return [=]()
mutable -> R {
2801 REQUIRES(
"F must be a function that returns a Token class",
2802 std::is_convertible<decltype(std::declval<F>()()),
const Token*> )>
2820 bool aliased =
false;
2822 auto expr = getExprTok();
2848 }, tok, indirect, expr->
exprId(), globalvar, settings, depth);
2857 auto getExprTok =
memoize([&] {
2860 for (
Token *tok = start; tok != end; tok = tok->
next()) {
2882 start = start->
tokAt(2);
2894 const std::vector<const Variable*> &vars,
2897 std::set<int> varids;
2898 std::transform(vars.cbegin(), vars.cend(), std::inserter(varids, varids.begin()), [](
const Variable* var) {
2899 return var->declarationId();
2901 const bool globalvar = std::any_of(vars.cbegin(), vars.cend(), [](
const Variable* var) {
2902 return var->isGlobal();
2904 for (
const Token* tok = start; tok != end; tok = tok->
next()) {
2905 if (tok->varId() == 0 || varids.count(tok->varId()) == 0) {
2937 for (
const Token* tok = start; tok != end; tok = tok->
next()) {
2946 template<
class Find>
2958 const Token* result =
nullptr;
2965 bool global =
false;
2975 if (tok->
exprId() > 0 || global) {
2976 const Token* modifedTok = find(start, end, [&](
const Token* tok2) {
2979 indirect = vt->pointer;
2980 if (vt->type == ValueType::ITERATOR)
2983 for (
int i = 0; i <= indirect; ++i) {
2990 result = modifedTok;
3000 struct ExpressionChangedSimpleFind {
3002 const Token* operator()(
const Token* start,
const Token* end, F f)
const
3008 struct ExpressionChangedSkipDeadCode {
3010 const std::function<std::vector<MathLib::bigint>(
const Token* tok)>*
evaluate;
3011 ExpressionChangedSkipDeadCode(
const Library& library,
3012 const std::function<std::vector<MathLib::bigint>(
const Token* tok)>&
evaluate)
3016 const Token* operator()(
const Token* start,
const Token* end, F f)
const
3036 const std::function<std::vector<MathLib::bigint>(
const Token* tok)>&
evaluate,
3040 expr, start, end, settings, depth, ExpressionChangedSkipDeadCode{settings.
library,
evaluate});
3045 const Token* tok = ftok;
3053 if (!startTok && tok->
next() != tok->
link())
3065 const Token* openBracket = start->
next();
3067 openBracket = openBracket->
next();
3068 if (openBracket && openBracket->
str()==
"(" && openBracket->
next() && openBracket->
next()->
str()!=
")") {
3069 const Token* argument=openBracket->
next();
3085 return v.nameToken() == var->nameToken();
3089 return std::distance(f->
argumentList.cbegin(), arg_it);
3102 if (tok->
str() ==
"(")
3107 }
else if (
Token::Match(tok,
"begin|cbegin|rbegin|crbegin|end|cend|rend|crend (")) {
3119 if (args.size() != 2)
3124 const Token* tok1 =
nullptr;
3125 const Token* tok2 =
nullptr;
3137 return tok1 || tok2;
3142 if (!last || !last->
isCpp() || last->
str() !=
"}")
3152 template<
class T,
REQUIRES(
"T must be a Token class", std::is_convertible<T*, const Token*> )>
3155 auto maybeLambda = [](T* tok) ->
bool {
3158 tok = tok->link()->previous();
3160 if (tok->str() ==
">")
3162 if (tok->str() ==
"new")
3164 tok = tok->previous();
3170 if (!first || !first->isCpp() || first->str() !=
"[")
3172 if (!maybeLambda(first->previous()))
3176 const Token* roundOrCurly = first->
link()->next();
3177 if (roundOrCurly->
link() && roundOrCurly->
str() ==
"<")
3178 roundOrCurly = roundOrCurly->
link()->next();
3179 if (first->astOperand1() != roundOrCurly)
3183 if (tok->astOperand1() && tok->astOperand1()->str() ==
"(")
3184 tok = tok->astOperand1();
3185 if (tok->astOperand1() && tok->astOperand1()->str() ==
"{")
3186 return tok->astOperand1()->link();
3204 if (!stream->
isCpp())
3210 if (stream->
astParent()->astOperand1() != stream)
3230 const Token *parent = op;
3253 if (skipPredicate && skipPredicate(tok))
3263 return !args.empty() && std::all_of(args.cbegin(), args.cend(), [&](
const Token* t) {
3264 return isConstVarExpression(t, skipPredicate);
3281 if (
Token::Match(tok,
"%bool%|%num%|%str%|%char%|nullptr|NULL"))
3286 return tok->
variable()->isConst() && tok->
variable()->nameToken() && tok->
variable()->nameToken()->hasKnownValue();
3303 if (arg->isReference() || (arg->isPointer() && indirect == 1)) {
3306 for (
const Token* bodytok = ftok->
function()->functionScope->bodyStart; bodytok != ftok->
function()->functionScope->bodyEnd; bodytok = bodytok->next()) {
3307 if (bodytok->variable() == arg) {
3308 if (arg->isReference())
3318 if (!args.empty() && indirect == 0 && !addressOf)
3322 }
else if (ftok->
str() ==
"{") {
3325 if (ftok->
variable()->type() && ftok->
variable()->type()->classScope && ftok->
variable()->type()->classScope->numConstructors == 0)
3331 if (indirect == 0 &&
astIsPointer(tok) && !addressOf && isnullbad)
3333 bool hasIndirect =
false;
3335 if (isuninitbad && (!addressOf || isnullbad))
3356 if (indirect > 0 && parent) {
3372 if (indirect == 0) {
3373 if (
Token::Match(parent,
"%cop%|%assign%|++|--") && parent->
str() !=
"=" &&
3382 if (op->
str() ==
"=") {
3426 std::vector<const Variable*> result;
3475 if (vartok && vartok->
variable() && vartok->
variable()->nameToken() == vartok)
3499 if (expr->
isCpp() &&
Token::Match(expr,
"static_cast|const_cast|dynamic_cast|reinterpret_cast <"))
3501 else if (!expr->
isCast())
3519 bool globalData =
false;
3522 [expr, &globalData, &var](
const Token *tok) {
3528 return ChildrenToVisit::none;
3533 return ChildrenToVisit::none;
3537 const Variable *lhsvar = tok->astOperand1()->variable();
3538 const ValueType *lhstype = tok->astOperand1()->valueType();
3539 if (lhsvar->isPointer()) {
3541 return ChildrenToVisit::none;
3543 if (lhsvar->isArgument() && lhsvar->isArray()) {
3545 return ChildrenToVisit::none;
3547 if (lhsvar->isArgument() && (!lhstype || (lhstype->type <= ValueType::Type::VOID && !lhstype->container))) {
3549 return ChildrenToVisit::none;
3554 return ChildrenToVisit::none;
3558 if (tok->variable()->isReference() && tok != tok->variable()->nameToken()) {
3560 return ChildrenToVisit::none;
3564 return ChildrenToVisit::none;
3568 return ChildrenToVisit::none;
3570 if (tok->
variable()->isArgument() && tok->
variable()->isPointer() && tok != expr) {
3572 return ChildrenToVisit::none;
3574 if (tok->
variable()->isPointerArray()) {
3576 return ChildrenToVisit::none;
3582 return ChildrenToVisit::none;
3588 return globalData || !var;
3593 return Token::Match(tok,
"alignof|_Alignof|_alignof|__alignof|__alignof__|decltype|offsetof|sizeof|typeid|typeof|__typeof__ (");
const Token * astIsVariableComparison(const Token *tok, const std::string &comp, const std::string &rhs, const Token **vartok)
Is given syntax tree a variable comparison against value.
int numberOfArgumentsWithoutAst(const Token *start)
Get number of arguments without using AST.
static bool compareKnownValue(const Token *const tok1, const Token *const tok2, const std::function< bool(const ValueFlow::Value &, const ValueFlow::Value &, bool)> &compare)
bool astIsContainer(const Token *tok)
static bool isCPPCastKeyword(const Token *tok)
const Token * getIteratorExpression(const Token *tok)
static T * getTokenArgumentFunctionImpl(T *tok, int &argn)
static bool isArray(const Token *tok)
std::vector< const Token * > getArguments(const Token *ftok)
Get arguments (AST)
static bool astIsCharWithSign(const Token *tok, ValueType::Sign sign)
static bool astIsBoolLike(const Token *tok, const Settings &settings)
bool isOppositeExpression(const Token *const tok1, const Token *const tok2, const Settings &settings, bool pure, bool followVar, ErrorPath *errors)
static bool isExpressionChangedAt(const F &getExprTok, const Token *tok, int indirect, const nonneg int exprid, bool globalvar, const Settings &settings, int depth)
bool isSameExpression(bool macro, const Token *tok1, const Token *tok2, const Settings &settings, bool pure, bool followVar, ErrorPath *errors)
bool astIsPrimitive(const Token *tok)
bool astIsContainerView(const Token *tok)
bool astIsIntegral(const Token *tok, bool unknown)
Is expression of integral type?
static T * getCondTokImpl(T *tok)
static T * getStepTokImpl(T *tok)
static const Token * getLHSVariableRecursive(const Token *tok)
bool exprDependsOnThis(const Token *expr, bool onVar, nonneg int depth)
bool isTemporary(const Token *tok, const Library *library, bool unknown)
const Token * followReferences(const Token *tok, ErrorPath *errors)
bool astIsRangeBasedForDecl(const Token *tok)
Is given token a range-declaration in a range-based for loop.
bool precedes(const Token *tok1, const Token *tok2)
If tok2 comes after tok1.
const Token * getTokenArgumentFunction(const Token *tok, int &argn)
Return the token to the function and the argument number.
bool astHasVar(const Token *tok, nonneg int varid)
static void getLHSVariablesRecursive(std::vector< const Variable * > &vars, const Token *tok)
bool isUsedAsBool(const Token *const tok, const Settings &settings)
Is token used as boolean, that is to say cast to a bool, or used as a condition in a if/while/for.
static void followVariableExpressionError(const Token *tok1, const Token *tok2, ErrorPath *errors)
bool extractForLoopValues(const Token *forToken, nonneg int &varid, bool &knownInitValue, MathLib::bigint &initValue, bool &partialCond, MathLib::bigint &stepValue, MathLib::bigint &lastValue)
Extract for loop values: loopvar varid, init value, step value, last value (inclusive)
static bool hasNoreturnFunction(const Token *tok, const Library &library, const Token **unknownFunc)
bool astIsPointer(const Token *tok)
bool compareTokenFlags(const Token *tok1, const Token *tok2, bool macro)
Are the tokens' flags equal?
const Token * isInLoopCondition(const Token *tok)
static const Token * getParentLifetimeObject(const Token *tok)
static T * findLambdaEndTokenGeneric(T *first)
bool isStlStringType(const Token *tok)
bool isLikelyStreamRead(const Token *op)
do we see a likely write of rhs through overloaded operator s >> x; a & x;
bool isUniqueExpression(const Token *tok)
bool astIsContainerOwned(const Token *tok)
const Token * findExpressionChanged(const Token *expr, const Token *start, const Token *end, const Settings &settings, int depth)
const Token * findAllocFuncCallToken(const Token *expr, const Library &library)
Find a allocation function call in expression, so result of expression is allocated memory/resource.
bool astIsLHS(const Token *tok)
bool isGlobalData(const Token *expr)
bool isConstFunctionCall(const Token *ftok, const Library &library)
static bool isTrivialConstructor(const Token *tok)
bool astIsBool(const Token *tok)
Is expression of boolean type?
const Token * getArgumentStart(const Token *ftok)
bool isScopeBracket(const Token *tok)
static ExprUsage getFunctionUsage(const Token *tok, int indirect, const Settings &settings)
bool isEscapeFunction(const Token *ftok, const Library *library)
bool isVariableDecl(const Token *tok)
static bool isFunctionCall(const Token *tok)
static bool isInConstructorList(const Token *tok)
static bool hasToken(const Token *startTok, const Token *stopTok, const Token *tok)
static bool match(const Token *tok, const std::string &rhs)
static int getArgumentPos(const Token *ftok, const Token *tokToFind)
bool astIsGenericChar(const Token *tok)
Is expression a char according to valueType?
bool astHasExpr(const Token *tok, nonneg int exprid)
bool isStructuredBindingVariable(const Variable *var)
Token * getInitTok(Token *tok)
const Token * findNextTokenFromBreak(const Token *breakToken)
For a "break" token, locate the next token to execute.
bool isLeafDot(const Token *tok)
bool astIsUniqueSmartPointer(const Token *tok)
static bool isEscaped(const Token *tok, bool functionsScope, const Library &library)
Library::Container::Action astContainerAction(const Token *tok, const Token **ftok)
Library::Container::Yield astFunctionYield(const Token *tok, const Settings &settings, const Token **ftok)
static bool isDifferentKnownValues(const Token *const tok1, const Token *const tok2)
std::vector< const Token * > astFlatten(const Token *tok, const char *op)
bool astIsSmartPointer(const Token *tok)
Token * getCondTokFromEnd(Token *endBlock)
bool isNullOperand(const Token *expr)
const Token * findLambdaStartToken(const Token *last)
bool astHasToken(const Token *root, const Token *tok)
const Token * astParentSkipParens(const Token *tok)
bool isOppositeCond(bool isNot, const Token *const cond1, const Token *const cond2, const Settings &settings, bool pure, bool followVar, ErrorPath *errors)
Are two conditions opposite.
bool astIsContainerString(const Token *tok)
static bool isForLoopCondition(const Token *const tok)
Token * getCondTok(Token *tok)
bool astIsRHS(const Token *tok)
bool isWithinScope(const Token *tok, const Variable *var, Scope::ScopeType type)
Is tok within a scope of the given type, nested within var's scope?
static std::function< R()> memoize(F f)
static bool functionModifiesArguments(const Function *f)
std::vector< ValueType > getParentValueTypes(const Token *tok, const Settings &settings, const Token **parent)
const Variable * getLHSVariable(const Token *tok)
bool astIsSignedChar(const Token *tok)
Is expression a 'signed char' if no promotion is used.
bool isConstVarExpression(const Token *tok, const std::function< bool(const Token *)> &skipPredicate)
bool isWithoutSideEffects(const Token *tok, bool checkArrayAccess, bool checkReference)
bool astIsFloat(const Token *tok, bool unknown)
Is expression of floating point type?
const Token * findLambdaEndToken(const Token *first)
find lambda function end token
const Token * nextAfterAstRightmostLeaf(const Token *tok)
ExprUsage getExprUsage(const Token *tok, int indirect, const Settings &settings)
bool isThisChanged(const Token *tok, int indirect, const Settings &settings)
static const Token * getVariableInitExpression(const Variable *var)
bool astIsNonStringContainer(const Token *tok)
static std::vector< const Token * > getParentMembers(const Token *tok)
static bool isZeroBoundCond(const Token *const cond)
Token * getStepTok(Token *tok)
bool isVariablesChanged(const Token *start, const Token *end, int indirect, const std::vector< const Variable * > &vars, const Settings &settings)
bool isIteratorPair(const std::vector< const Token * > &args)
Are the arguments a pair of iterators/pointers?
bool isAliasOf(const Token *tok, nonneg int varid, bool *inconclusive)
If token is an alias if another variable.
static const Token * getContainerFunction(const Token *tok)
const Token * getParentMember(const Token *tok)
bool isVariableChangedByFunctionCall(const Token *tok, int indirect, nonneg int varid, const Settings &settings, bool *inconclusive)
Is variable changed by function call? In case the answer of the question is inconclusive,...
bool isReturnScope(const Token *const endToken, const Library &library, const Token **unknownFunc, bool functionScope)
Is scope a return scope (scope will unconditionally return)
Token * findVariableChanged(Token *start, const Token *end, int indirect, const nonneg int exprid, bool globalvar, const Settings &settings, int depth)
static bool hasUnknownVars(const Token *startTok)
static bool isEscapedOrJump(const Token *tok, bool functionsScope, const Library &library)
static const Token * followVariableExpression(const Settings &settings, const Token *tok, const Token *end=nullptr)
This takes a token that refers to a variable and it will return the token to the expression that the ...
static bool isSameConstantValue(bool macro, const Token *tok1, const Token *tok2)
bool astIsUnsigned(const Token *tok)
static bool isSameLifetime(const Token *const tok1, const Token *const tok2)
static int findArgumentPosRecursive(const Token *tok, const Token *tokToFind, bool &found, nonneg int depth=0)
bool astIsIterator(const Token *tok)
const Token * previousBeforeAstLeftmostLeaf(const Token *tok)
const Token * findExpressionChangedSkipDeadCode(const Token *expr, const Token *start, const Token *end, const Settings &settings, const std::function< std::vector< MathLib::bigint >(const Token *tok)> &evaluate, int depth)
bool isCPPCast(const Token *tok)
bool isEqualKnownValue(const Token *const tok1, const Token *const tok2)
std::vector< const Variable * > getLHSVariables(const Token *tok)
bool isConstExpression(const Token *tok, const Library &library)
std::vector< const Variable * > getArgumentVars(const Token *tok, int argnr)
static bool isForLoopIncrement(const Token *const tok)
bool isUnevaluated(const Token *tok)
const Token * getLHSVariableToken(const Token *tok)
const Token * getParentLifetime(const Token *tok)
SmallVector< ReferenceToken > followAllReferences(const Token *tok, bool temporary, bool inconclusive, ErrorPath errors, int depth)
static bool isAliased(const Token *startTok, const Token *endTok, nonneg int varid)
bool isLikelyStream(const Token *stream)
std::string astCanonicalType(const Token *expr, bool pointedToType)
Get canonical type of expression.
Library::Container::Yield astContainerYield(const Token *tok, const Token **ftok)
static T * getCondTokFromEndImpl(T *endBlock)
static const Token * findThisChanged(const Token *start, const Token *end, int indirect, const Settings &settings)
static int findArgumentPos(const Token *tok, const Token *tokToFind)
bool astIsUnknownSignChar(const Token *tok)
Is expression a 'char' if no promotion is used?
static const Token * findExpressionChangedImpl(const Token *expr, const Token *start, const Token *end, const Settings &settings, int depth, Find find)
static T * getInitTokImpl(T *tok)
bool succeeds(const Token *tok1, const Token *tok2)
If tok1 comes after tok2.
static T * previousBeforeAstLeftmostLeafGeneric(T *tok)
int numberOfArguments(const Token *ftok)
Determines the number of arguments - if token is a function call or macro.
nonneg int astCount(const Token *tok, const char *op, int depth)
const Token * findExpression(const nonneg int exprid, const Token *start, const Token *end, const std::function< bool(const Token *)> &pred)
bool isVariableChanged(const Token *tok, int indirect, const Settings &settings, int depth)
static T * nextAfterAstRightmostLeafGeneric(T *tok)
void visitAstNodes(T *ast, const TFunc &visitor)
Visit AST nodes recursively.
void astFlattenCopy(T *tok, const char *op, OuputIterator out, nonneg int depth=100)
const Token * findAstNode(const Token *ast, const TFunc &pred)
static int sign(const T v)
static const std::set< std::string > stl_containers_not_const
Set of the STL types whose operator[] is not const.
static std::vector< const Token * > findReturns(const Function *f)
const Scope * functionScope
scope of function body
static bool returnsConst(const Function *function, bool unknown=false)
Type type
constructor, destructor, ...
static bool returnsReference(const Function *function, bool unknown=false, bool includeRValueRef=false)
const Token * retDef
function return type token
const Token * token
function name token in implementation
const ::Type * retType
function return type
const Scope * nestedIn
Scope the function is declared in.
const Token * tokenDef
function name token in class definition
std::list< Variable > argumentList
argument list, must remain list due to clangimport usage!
static bool returnsVoid(const Function *function, bool unknown=false)
Action getAction(const std::string &function) const
Yield getYield(const std::string &function) const
Library definitions handling.
ArgumentChecks::Direction getArgDirection(const Token *ftok, int argnr) const
bool isuninitargbad(const Token *ftok, int argnr, int indirect=0, bool *hasIndirect=nullptr) const
static bool isContainerYield(const Token *const cond, Library::Container::Yield y, const std::string &fallback=emptyString)
bool isnullargbad(const Token *ftok, int argnr) const
bool isnoreturn(const Token *ftok) const
const AllocFunc * getAllocFuncInfo(const Token *tok) const
get allocation info for function
const Function * getFunction(const Token *ftok) const
std::string getFunctionName(const Token *ftok) const
Get function name for function call.
const std::string & returnValueType(const Token *ftok) const
std::unordered_map< std::string, Function > functions
bool isFunctionConst(const std::string &functionName, bool pure) const
static bool isNullValue(const std::string &str)
Does the string represent the numerical value of 0? In case leading or trailing white space is provid...
static bool isInt(const std::string &str)
std::list< Function > functionList
std::list< Variable > varlist
static Function * nestedInFunction(const Scope *scope)
Function * function
function info for this function
const Token * bodyStart
'{' token
const Token * bodyEnd
'}' token
nonneg int numConstructors
const Scope * functionOf
scope this function belongs to
std::vector< const Scope * > findAssociatedScopes() const
bool isClassOrStruct() const
This is just a container for general settings so that we don't need to pass individual values to func...
The token list that the TokenList generates is a linked-list of this class.
bool hasKnownValue() const
static bool Match(const Token *tok, const char pattern[], nonneg int varid=0)
Match given token (or list of tokens) to a pattern list.
nonneg int exprId() const
bool isEnumerator() const
const std::string & originalName() const
bool hasKnownIntValue() const
bool isExpandedMacro() const
bool isTemplateArg() const
Is current token a template argument?
static std::pair< const Token *, const Token * > typeDecl(const Token *tok, bool pointedToType=false)
bool isArithmeticalOp() const
std::string stringifyList(const stringifyOptions &options, const std::vector< std::string > *fileNames=nullptr, const Token *end=nullptr) const
bool isIncompleteVar() const
bool isControlFlowKeyword() const
static const ::Type * typeOf(const Token *tok, const Token **typeTok=nullptr)
const ValueType * valueType() const
const Enumerator * enumerator() const
void astOperand1(Token *tok)
void function(const Function *f)
Associate this token with given function.
std::string expressionString() const
bool isUnaryOp(const std::string &s) const
bool isIncompleteConstant() const
static const Token * findsimplematch(const Token *const startTok, const char(&pattern)[count])
const Token * tokAt(int index) const
Token::Type tokType() const
void astOperand2(Token *tok)
void scope(const Scope *s)
Associate this token with given scope.
void link(Token *linkToToken)
Create link to given token.
const Token * linkAt(int index) const
void type(const ::Type *t)
Associate this token with given type.
bool isAssignmentOp() const
bool isStandardType() const
void variable(const Variable *v)
Associate this token with given variable.
bool isComparisonOp() const
const std::list< ValueFlow::Value > & values() const
bool isAttributeConst() const
const Token * nextArgument() const
static bool simpleMatch(const Token *tok, const char(&pattern)[count])
Match given token (or list of tokens) to a pattern list.
nonneg int fileIndex() const
bool isAttributePure() const
void astParent(Token *tok)
Information about a class type.
const std::string & type() const
bool isIteratorValue() const
bool isLifetimeValue() const
const Token * tokvalue
token value - the token that has the value.
long long intvalue
int value (or sometimes bool value?)
bool equalValue(const ValueFlow::Value &rhs) const
enum ValueType::Type type
const Library::Container * container
If the type is a container defined in a cfg file, this is the used.
bool isConst(nonneg int indirect=0) const
nonneg int constness
bit 0=data, bit 1=*, bit 2=**
Reference reference
Is the outermost indirection of this type a reference or rvalue.
const Library::SmartPointer * smartPointer
Smart pointer.
nonneg int pointer
0=>not pointer, 1=>*, 2=>**, 3=>***, etc
const Token * smartPointerTypeToken
Smart pointer type token.
const Token * containerTypeToken
The container type token.
static ValueType parseDecl(const Token *type, const Settings &settings)
enum ValueType::Sign sign
Information about a member variable.
bool isArgument() const
Is variable a function argument.
bool isEnumType() const
Determine whether it's an enumeration type.
bool isClass() const
Is variable a user defined (or unknown) type.
bool isProtected() const
Is variable protected.
bool isReference() const
Is reference variable.
bool isFloatingType() const
Determine whether it's a floating number type.
bool isRValueReference() const
Is reference variable.
bool isStlType() const
Checks if the variable is an STL type ('std::') E.g.
bool isLocal() const
Is variable local.
const Token * declEndToken() const
Get end token of variable declaration E.g.
const Type * type() const
Get Type pointer of known type.
const Scope * scope() const
Get Scope pointer of enclosing scope.
bool isPublic() const
Is variable public.
const std::string & name() const
Get name string.
bool isConst() const
Is variable const.
bool isArray() const
Is variable an array.
const Token * nameToken() const
Get name token.
bool isPrivate() const
Is variable private.
nonneg int declarationId() const
Get declaration ID (varId used for variable in its declaration).
bool isVolatile() const
Is variable volatile.
bool isPointer() const
Is pointer variable.
bool isStatic() const
Is variable static.
const ValueType * valueType() const
#define REQUIRES(msg,...)
T * findToken(T *start, const Token *end, const Predicate &pred)
T * findTokenSkipDeadCode(const Library &library, T *start, const Token *end, const Predicate &pred, const Evaluate &evaluate)
std::pair< const Token *, std::string > ErrorPathItem
const Library::Container * getLibraryContainer(const Token *tok)
std::list< ErrorPathItem > ErrorPath
std::vector< MathLib::bigint > getMinValue(const ValuePtr< InferModel > &model, const std::list< ValueFlow::Value > &values)
CPPCHECKLIB Value getLifetimeObjValue(const Token *tok, bool inconclusive=false)
CPPCHECKLIB ValuePtr< InferModel > makeIntegralInferModel()
static ValueFlow::Value evaluate(const std::string &op, const ValueFlow::Value &lhs, const ValueFlow::Value &rhs)
@ DIR_IN
Input to called function. Data is treated as read-only.
@ DIR_OUT
Output to caller. Data is passed by reference or address and is potentially written.
@ DIR_INOUT
Input to called function, and output to caller. Data is passed by reference or address and is potenti...
bool startsWith(const std::string &str, const char start[], std::size_t startlen)
bool endsWith(const std::string &str, char c)
bool contains(const Range &r, const T &x)