56     mValues[expr] = value;
 
   60         [&](
const Token* 
tok) -> std::vector<MathLib::bigint> {
 
   62             return {tok->values().front().intvalue};
 
   70         mValues[subexpr] = std::move(subvalue);
 
   74     const ProgramMemory::Map::const_iterator it = mValues.find(
exprid);
 
   75     const bool found = it != mValues.cend() && (impossible || !it->second.isImpossible());
 
  151     return mValues.find(
exprid) != mValues.end();
 
  155     return mValues.at(
exprid);
 
  158     return mValues.at(
exprid);
 
  163     for (
auto it = mValues.begin(); it != mValues.end();) {
 
  165             it = mValues.erase(it);
 
  183     return mValues.empty();
 
  189         mValues[p.first] = std::move(p.second);
 
  208     return !
error && result == r;
 
  221 static bool frontIs(
const std::vector<MathLib::bigint>& v, 
bool i)
 
  276     auto eval = [&](
const Token* t) -> std::vector<MathLib::bigint> {
 
  278             return std::vector<MathLib::bigint>{};
 
  279         if (t->hasKnownIntValue())
 
  280             return {t->values().front().intvalue};
 
  286         return std::vector<MathLib::bigint>{};
 
  294         if (vartok->
exprId() == 0)
 
  300         const bool impossible = (
tok->
str() == 
"==" && !then) || (
tok->
str() == 
"!=" && then);
 
  317         if (lhs.empty() || rhs.empty()) {
 
  365             tok2->astOperand2()) {
 
  368             for (
const auto& p:vars) {
 
  369                 if (p.first != vartok->
exprId())
 
  382         } 
else if (tok2->exprId() > 0 && 
Token::Match(tok2, 
".|(|[|*|%var%") && !pm.
hasValue(tok2->exprId()) &&
 
  387         if (tok2->str() == 
"{") {
 
  388             if (indentlevel <= 0) {
 
  397                 tok2 = tok2->linkAt(-2)->previous();
 
  399         if (tok2->str() == 
"}" && !
Token::Match(tok2->link()->previous(), 
"%var% {")) {
 
  410                         tok2 = tok2->link()->tokAt(-2);
 
  451             origins.insert(std::make_pair(p.first.getExpressionId(), origin));
 
  458         for (
const auto& p : pm)
 
  459             origins[p.first.getExpressionId()] = origin;
 
  465     for (
const auto& p:vars) {
 
  489     const Token* origin = tok;
 
  492         origin = top->
link()->next();
 
  493         if (!b && origin->
link()) {
 
  494             origin = origin->
link();
 
  497     replace(std::move(pm), origin);
 
  503     auto eval = [&](
const Token* cond) -> std::vector<MathLib::bigint> {
 
  545     programMemory.
setValue(expr, value);
 
  548     return programMemory;
 
  561     return std::string{assign.cbegin(), assign.cend() - 1};
 
  566         template<
class T, 
class U>
 
  567         void operator()(T& x, 
const U& y)
 const 
  587         if (
contains({
"%", 
"/", 
"&", 
"|"}, op))
 
  607     const bool compareOp = 
contains({
"==", 
"!=", 
"<", 
">", 
">=", 
"<="}, op);
 
  650     std::unordered_map<std::string, BuiltinLibraryFunction> functions;
 
  651     functions[
"strlen"] = [](
const std::vector<ValueFlow::Value>& args) {
 
  652         if (args.size() != 1)
 
  662     functions[
"strcmp"] = [](
const std::vector<ValueFlow::Value>& args) {
 
  663         if (args.size() != 2)
 
  675     functions[
"strncmp"] = [](
const std::vector<ValueFlow::Value>& args) {
 
  676         if (args.size() != 3)
 
  692     functions[
"sin"] = [](
const std::vector<ValueFlow::Value>& args) {
 
  693         if (args.size() != 1)
 
  698         const double value = args[0].
isFloatValue() ? args[0].floatValue : args[0].intvalue;
 
  703     functions[
"lgamma"] = [](
const std::vector<ValueFlow::Value>& args) {
 
  704         if (args.size() != 1)
 
  709         const double value = args[0].
isFloatValue() ? args[0].floatValue : args[0].intvalue;
 
  714     functions[
"cos"] = [](
const std::vector<ValueFlow::Value>& args) {
 
  715         if (args.size() != 1)
 
  720         const double value = args[0].
isFloatValue() ? args[0].floatValue : args[0].intvalue;
 
  725     functions[
"tan"] = [](
const std::vector<ValueFlow::Value>& args) {
 
  726         if (args.size() != 1)
 
  731         const double value = args[0].
isFloatValue() ? args[0].floatValue : args[0].intvalue;
 
  736     functions[
"asin"] = [](
const std::vector<ValueFlow::Value>& args) {
 
  737         if (args.size() != 1)
 
  742         const double value = args[0].
isFloatValue() ? args[0].floatValue : args[0].intvalue;
 
  747     functions[
"acos"] = [](
const std::vector<ValueFlow::Value>& args) {
 
  748         if (args.size() != 1)
 
  753         const double value = args[0].
isFloatValue() ? args[0].floatValue : args[0].intvalue;
 
  758     functions[
"atan"] = [](
const std::vector<ValueFlow::Value>& args) {
 
  759         if (args.size() != 1)
 
  764         const double value = args[0].
isFloatValue() ? args[0].floatValue : args[0].intvalue;
 
  769     functions[
"atan2"] = [](
const std::vector<ValueFlow::Value>& args) {
 
  770         if (args.size() != 2 || !std::all_of(args.cbegin(), args.cend(), [](
const ValueFlow::Value& v) {
 
  771             return v.isFloatValue() || v.isIntValue();
 
  774         const double value = args[0].
isFloatValue() ? args[0].floatValue : args[0].intvalue;
 
  777         v.
floatValue = std::atan2(value, args[1].isFloatValue() ? args[1].floatValue : args[1].intvalue);
 
  781     functions[
"remainder"] = [](
const std::vector<ValueFlow::Value>& args) {
 
  782         if (args.size() != 2 || !std::all_of(args.cbegin(), args.cend(), [](
const ValueFlow::Value& v) {
 
  783             return v.isFloatValue() || v.isIntValue();
 
  786         const double value = args[0].
isFloatValue() ? args[0].floatValue : args[0].intvalue;
 
  789         v.
floatValue = std::remainder(value, args[1].isFloatValue() ? args[1].floatValue : args[1].intvalue);
 
  793     functions[
"nextafter"] = [](
const std::vector<ValueFlow::Value>& args) {
 
  794         if (args.size() != 2 || !std::all_of(args.cbegin(), args.cend(), [](
const ValueFlow::Value& v) {
 
  795             return v.isFloatValue() || v.isIntValue();
 
  798         const double value = args[0].
isFloatValue() ? args[0].floatValue : args[0].intvalue;
 
  801         v.
floatValue = std::nextafter(value, args[1].isFloatValue() ? args[1].floatValue : args[1].intvalue);
 
  805     functions[
"nexttoward"] = [](
const std::vector<ValueFlow::Value>& args) {
 
  806         if (args.size() != 2 || !std::all_of(args.cbegin(), args.cend(), [](
const ValueFlow::Value& v) {
 
  807             return v.isFloatValue() || v.isIntValue();
 
  810         const double value = args[0].
isFloatValue() ? args[0].floatValue : args[0].intvalue;
 
  813         v.
floatValue = std::nexttoward(value, args[1].isFloatValue() ? args[1].floatValue : args[1].intvalue);
 
  817     functions[
"hypot"] = [](
const std::vector<ValueFlow::Value>& args) {
 
  818         if (args.size() != 2 || !std::all_of(args.cbegin(), args.cend(), [](
const ValueFlow::Value& v) {
 
  819             return v.isFloatValue() || v.isIntValue();
 
  822         const double value = args[0].
isFloatValue() ? args[0].floatValue : args[0].intvalue;
 
  825         v.
floatValue = std::hypot(value, args[1].isFloatValue() ? args[1].floatValue : args[1].intvalue);
 
  829     functions[
"fdim"] = [](
const std::vector<ValueFlow::Value>& args) {
 
  830         if (args.size() != 2 || !std::all_of(args.cbegin(), args.cend(), [](
const ValueFlow::Value& v) {
 
  831             return v.isFloatValue() || v.isIntValue();
 
  834         const double value = args[0].
isFloatValue() ? args[0].floatValue : args[0].intvalue;
 
  837         v.
floatValue = std::fdim(value, args[1].isFloatValue() ? args[1].floatValue : args[1].intvalue);
 
  841     functions[
"fmax"] = [](
const std::vector<ValueFlow::Value>& args) {
 
  842         if (args.size() != 2 || !std::all_of(args.cbegin(), args.cend(), [](
const ValueFlow::Value& v) {
 
  843             return v.isFloatValue() || v.isIntValue();
 
  846         const double value = args[0].
isFloatValue() ? args[0].floatValue : args[0].intvalue;
 
  849         v.
floatValue = std::fmax(value, args[1].isFloatValue() ? args[1].floatValue : args[1].intvalue);
 
  853     functions[
"fmin"] = [](
const std::vector<ValueFlow::Value>& args) {
 
  854         if (args.size() != 2 || !std::all_of(args.cbegin(), args.cend(), [](
const ValueFlow::Value& v) {
 
  855             return v.isFloatValue() || v.isIntValue();
 
  858         const double value = args[0].
isFloatValue() ? args[0].floatValue : args[0].intvalue;
 
  861         v.
floatValue = std::fmin(value, args[1].isFloatValue() ? args[1].floatValue : args[1].intvalue);
 
  865     functions[
"fmod"] = [](
const std::vector<ValueFlow::Value>& args) {
 
  866         if (args.size() != 2 || !std::all_of(args.cbegin(), args.cend(), [](
const ValueFlow::Value& v) {
 
  867             return v.isFloatValue() || v.isIntValue();
 
  870         const double value = args[0].
isFloatValue() ? args[0].floatValue : args[0].intvalue;
 
  873         v.
floatValue = std::fmod(value, args[1].isFloatValue() ? args[1].floatValue : args[1].intvalue);
 
  877     functions[
"pow"] = [](
const std::vector<ValueFlow::Value>& args) {
 
  878         if (args.size() != 2 || !std::all_of(args.cbegin(), args.cend(), [](
const ValueFlow::Value& v) {
 
  879             return v.isFloatValue() || v.isIntValue();
 
  882         const double value = args[0].
isFloatValue() ? args[0].floatValue : args[0].intvalue;
 
  885         v.
floatValue = std::pow(value, args[1].isFloatValue() ? args[1].floatValue : args[1].intvalue);
 
  889     functions[
"scalbln"] = [](
const std::vector<ValueFlow::Value>& args) {
 
  890         if (args.size() != 2 || !std::all_of(args.cbegin(), args.cend(), [](
const ValueFlow::Value& v) {
 
  891             return v.isFloatValue() || v.isIntValue();
 
  894         const double value = args[0].
isFloatValue() ? args[0].floatValue : args[0].intvalue;
 
  897         v.
floatValue = std::scalbln(value, args[1].isFloatValue() ? args[1].floatValue : args[1].intvalue);
 
  901     functions[
"ldexp"] = [](
const std::vector<ValueFlow::Value>& args) {
 
  902         if (args.size() != 2 || !std::all_of(args.cbegin(), args.cend(), [](
const ValueFlow::Value& v) {
 
  903             return v.isFloatValue() || v.isIntValue();
 
  906         const double value = args[0].
isFloatValue() ? args[0].floatValue : args[0].intvalue;
 
  909         v.
floatValue = std::ldexp(value, args[1].isFloatValue() ? args[1].floatValue : args[1].intvalue);
 
  913     functions[
"ilogb"] = [](
const std::vector<ValueFlow::Value>& args) {
 
  914         if (args.size() != 1)
 
  919         const double value = args[0].
isFloatValue() ? args[0].floatValue : args[0].intvalue;
 
  924     functions[
"erf"] = [](
const std::vector<ValueFlow::Value>& args) {
 
  925         if (args.size() != 1)
 
  930         const double value = args[0].
isFloatValue() ? args[0].floatValue : args[0].intvalue;
 
  935     functions[
"erfc"] = [](
const std::vector<ValueFlow::Value>& args) {
 
  936         if (args.size() != 1)
 
  941         const double value = args[0].
isFloatValue() ? args[0].floatValue : args[0].intvalue;
 
  946     functions[
"floor"] = [](
const std::vector<ValueFlow::Value>& args) {
 
  947         if (args.size() != 1)
 
  952         const double value = args[0].
isFloatValue() ? args[0].floatValue : args[0].intvalue;
 
  957     functions[
"sqrt"] = [](
const std::vector<ValueFlow::Value>& args) {
 
  958         if (args.size() != 1)
 
  963         const double value = args[0].
isFloatValue() ? args[0].floatValue : args[0].intvalue;
 
  968     functions[
"cbrt"] = [](
const std::vector<ValueFlow::Value>& args) {
 
  969         if (args.size() != 1)
 
  974         const double value = args[0].
isFloatValue() ? args[0].floatValue : args[0].intvalue;
 
  979     functions[
"ceil"] = [](
const std::vector<ValueFlow::Value>& args) {
 
  980         if (args.size() != 1)
 
  985         const double value = args[0].
isFloatValue() ? args[0].floatValue : args[0].intvalue;
 
  990     functions[
"exp"] = [](
const std::vector<ValueFlow::Value>& args) {
 
  991         if (args.size() != 1)
 
  996         const double value = args[0].
isFloatValue() ? args[0].floatValue : args[0].intvalue;
 
 1001     functions[
"exp2"] = [](
const std::vector<ValueFlow::Value>& args) {
 
 1002         if (args.size() != 1)
 
 1007         const double value = args[0].
isFloatValue() ? args[0].floatValue : args[0].intvalue;
 
 1012     functions[
"expm1"] = [](
const std::vector<ValueFlow::Value>& args) {
 
 1013         if (args.size() != 1)
 
 1018         const double value = args[0].
isFloatValue() ? args[0].floatValue : args[0].intvalue;
 
 1023     functions[
"fabs"] = [](
const std::vector<ValueFlow::Value>& args) {
 
 1024         if (args.size() != 1)
 
 1029         const double value = args[0].
isFloatValue() ? args[0].floatValue : args[0].intvalue;
 
 1034     functions[
"log"] = [](
const std::vector<ValueFlow::Value>& args) {
 
 1035         if (args.size() != 1)
 
 1040         const double value = args[0].
isFloatValue() ? args[0].floatValue : args[0].intvalue;
 
 1045     functions[
"log10"] = [](
const std::vector<ValueFlow::Value>& args) {
 
 1046         if (args.size() != 1)
 
 1051         const double value = args[0].
isFloatValue() ? args[0].floatValue : args[0].intvalue;
 
 1056     functions[
"log1p"] = [](
const std::vector<ValueFlow::Value>& args) {
 
 1057         if (args.size() != 1)
 
 1062         const double value = args[0].
isFloatValue() ? args[0].floatValue : args[0].intvalue;
 
 1067     functions[
"log2"] = [](
const std::vector<ValueFlow::Value>& args) {
 
 1068         if (args.size() != 1)
 
 1073         const double value = args[0].
isFloatValue() ? args[0].floatValue : args[0].intvalue;
 
 1078     functions[
"logb"] = [](
const std::vector<ValueFlow::Value>& args) {
 
 1079         if (args.size() != 1)
 
 1084         const double value = args[0].
isFloatValue() ? args[0].floatValue : args[0].intvalue;
 
 1089     functions[
"nearbyint"] = [](
const std::vector<ValueFlow::Value>& args) {
 
 1090         if (args.size() != 1)
 
 1095         const double value = args[0].
isFloatValue() ? args[0].floatValue : args[0].intvalue;
 
 1100     functions[
"sinh"] = [](
const std::vector<ValueFlow::Value>& args) {
 
 1101         if (args.size() != 1)
 
 1106         const double value = args[0].
isFloatValue() ? args[0].floatValue : args[0].intvalue;
 
 1111     functions[
"cosh"] = [](
const std::vector<ValueFlow::Value>& args) {
 
 1112         if (args.size() != 1)
 
 1117         const double value = args[0].
isFloatValue() ? args[0].floatValue : args[0].intvalue;
 
 1122     functions[
"tanh"] = [](
const std::vector<ValueFlow::Value>& args) {
 
 1123         if (args.size() != 1)
 
 1128         const double value = args[0].
isFloatValue() ? args[0].floatValue : args[0].intvalue;
 
 1133     functions[
"asinh"] = [](
const std::vector<ValueFlow::Value>& args) {
 
 1134         if (args.size() != 1)
 
 1139         const double value = args[0].
isFloatValue() ? args[0].floatValue : args[0].intvalue;
 
 1144     functions[
"acosh"] = [](
const std::vector<ValueFlow::Value>& args) {
 
 1145         if (args.size() != 1)
 
 1150         const double value = args[0].
isFloatValue() ? args[0].floatValue : args[0].intvalue;
 
 1155     functions[
"atanh"] = [](
const std::vector<ValueFlow::Value>& args) {
 
 1156         if (args.size() != 1)
 
 1161         const double value = args[0].
isFloatValue() ? args[0].floatValue : args[0].intvalue;
 
 1166     functions[
"round"] = [](
const std::vector<ValueFlow::Value>& args) {
 
 1167         if (args.size() != 1)
 
 1172         const double value = args[0].
isFloatValue() ? args[0].floatValue : args[0].intvalue;
 
 1177     functions[
"tgamma"] = [](
const std::vector<ValueFlow::Value>& args) {
 
 1178         if (args.size() != 1)
 
 1183         const double value = args[0].
isFloatValue() ? args[0].floatValue : args[0].intvalue;
 
 1188     functions[
"trunc"] = [](
const std::vector<ValueFlow::Value>& args) {
 
 1189         if (args.size() != 1)
 
 1194         const double value = args[0].
isFloatValue() ? args[0].floatValue : args[0].intvalue;
 
 1205     auto it = functions.find(name);
 
 1206     if (it == functions.end())
 
 1217 static std::vector<const Token*> 
setDifference(
const std::vector<const Token*>& v1, 
const std::vector<const Token*>& v2)
 
 1219     std::vector<const Token*> result;
 
 1220     std::set_difference(v1.begin(), v1.end(), v2.begin(), v2.end(), std::back_inserter(result), &
TokenExprIdCompare);
 
 1225                               const Token* storedValue,
 
 1239                             const std::unordered_map<nonneg int, ValueFlow::Value>& state)
 
 1241     conds.erase(std::remove_if(conds.begin(),
 
 1243                                [&](
const Token* cond) {
 
 1244         if (cond->exprId() == 0)
 
 1246         auto it = state.find(cond->exprId());
 
 1247         if (it == state.end())
 
 1249         const ValueFlow::Value& v = it->second;
 
 1250         return isTrueOrFalse(v, !b);
 
 1258         const Settings* settings = 
nullptr;
 
 1264             assert(settings != 
nullptr);
 
 1271         std::unordered_map<nonneg int, ValueFlow::Value> executeAll(
const std::vector<const Token*>& toks,
 
 1272                                                                     const bool* b = 
nullptr)
 const 
 1274             std::unordered_map<nonneg int, ValueFlow::Value> result;
 
 1276             for (
const Token* tok : toks) {
 
 1281                 result.emplace(tok->
exprId(), std::move(r));
 
 1289         static std::vector<const Token*> flattenConditions(
const Token* tok)
 
 1293         static bool sortConditions(std::vector<const Token*>& conditions)
 
 1295             if (std::any_of(conditions.begin(), conditions.end(), [](
const Token* child) {
 
 1296                 return Token::Match(child, 
"&&|%oror%");
 
 1300             conditions.erase(std::unique(conditions.begin(), conditions.end(), &
TokenExprIdCompare), conditions.end());
 
 1301             return !conditions.empty() && conditions.front()->exprId() != 0;
 
 1329             std::vector<const Token*> conditions1 = flattenConditions(expr);
 
 1330             if (conditions1.empty())
 
 1332             std::unordered_map<nonneg int, ValueFlow::Value> condValues = executeAll(conditions1, &b);
 
 1333             bool allNegated = 
true;
 
 1335             for (
const auto& p : condValues) {
 
 1343             if (condValues.size() == conditions1.size() && allNegated)
 
 1344                 return negatedValue;
 
 1347             if (!sortConditions(conditions1))
 
 1350             for (
const auto& p : *pm) {
 
 1351                 const Token* tok = p.first.tok;
 
 1360                     std::vector<const Token*> conditions2 = flattenConditions(tok);
 
 1361                     if (!sortConditions(conditions2))
 
 1363                     if (conditions1.size() == conditions2.size() &&
 
 1364                         std::equal(conditions1.begin(), conditions1.end(), conditions2.begin(), &
TokenExprIdEqual))
 
 1366                     std::vector<const Token*> diffConditions1 = 
setDifference(conditions1, conditions2);
 
 1367                     std::vector<const Token*> diffConditions2 = 
setDifference(conditions2, conditions1);
 
 1370                     if (diffConditions1.size() != diffConditions2.size())
 
 1372                     if (diffConditions1.size() == conditions1.size())
 
 1374                     for (
const Token* cond1 : diffConditions1) {
 
 1375                         auto it = std::find_if(diffConditions2.begin(), diffConditions2.end(), [&](
const Token* cond2) {
 
 1376                             return evalSameCondition(*pm, cond2, cond1, *settings);
 
 1378                         if (it == diffConditions2.end())
 
 1380                         diffConditions2.erase(it);
 
 1382                     if (diffConditions2.empty())
 
 1395                 return expr->
values().front();
 
 1437                 if (expr->
str() != 
"=") {
 
 1446                                                      std::bind(assign{}, std::ref(lhs.
floatValue), std::placeholders::_1));
 
 1454                 return executeMultiCondition(
false, expr);
 
 1456                 return executeMultiCondition(
true, expr);
 
 1470                 if (expr->
str() == 
"++")
 
 1476                 const Token* tokvalue = 
nullptr;
 
 1477                 if (!pm->getTokValue(expr->
astOperand1()->exprId(), tokvalue)) {
 
 1478                     auto tokvalue_it = std::find_if(expr->
astOperand1()->values().cbegin(),
 
 1481                     if (tokvalue_it == expr->
astOperand1()->values().cend() || !tokvalue_it->isKnown()) {
 
 1484                     tokvalue = tokvalue_it->tokvalue;
 
 1486                 if (!tokvalue || !tokvalue->
isLiteral()) {
 
 1489                 const std::string strValue = tokvalue->
strValue();
 
 1494                 if (index >= 0 && index < strValue.size())
 
 1496                 if (index == strValue.size())
 
 1506                         std::vector<ValueFlow::Value> result =
 
 1508                         if (!result.empty() && result.front().isKnown())
 
 1509                             return result.front();
 
 1512                         std::vector<ValueFlow::Value> result =
 
 1514                         if (!result.empty() && result.front().isKnown())
 
 1515                             return result.front();
 
 1526                 if (expr->
str() == 
"!") {
 
 1537                 if (expr->
str() == 
"-")
 
 1551             } 
else if (expr->
str() == 
"(" && expr->
isCast()) {
 
 1556             if (expr->
exprId() > 0 && pm->hasValue(expr->
exprId())) {
 
 1569                 if (settings && expr->
str() == 
"(") {
 
 1570                     std::vector<const Token*> tokArgs = 
getArguments(expr);
 
 1571                     std::vector<ValueFlow::Value> args(tokArgs.size());
 
 1573                         tokArgs.cbegin(), tokArgs.cend(), args.begin(), [&](
const Token* tok) {
 
 1574                         return execute(tok);
 
 1579                             for (std::size_t i = 0; i < args.size(); ++i) {
 
 1586                             ex.pm = &functionState;
 
 1598                         if (!returnValue.empty()) {
 
 1599                             std::unordered_map<nonneg int, ValueFlow::Value> arg_map;
 
 1612                     if (child->exprId() > 0 && pm->hasValue(child->exprId())) {
 
 1613                         ValueFlow::Value& v = pm->at(child->exprId());
 
 1614                         assert(settings != nullptr);
 
 1615                         if (v.valueType == ValueFlow::Value::ValueType::CONTAINER_SIZE) {
 
 1616                             if (ValueFlow::isContainerSizeChanged(child, v.indirect, *settings))
 
 1618                         } else if (v.valueType != ValueFlow::Value::ValueType::UNINIT) {
 
 1619                             if (isVariableChanged(child, v.indirect, *settings))
 
 1634             std::vector<const ValueFlow::Value*> values;
 
 1639                     values.push_back(std::addressof(v));
 
 1644                 return x->intvalue < y->intvalue;
 
 1646             if (it == values.end())
 
 1668             if (updateValue(v, executeImpl(expr)))
 
 1672             if (expr->
exprId() > 0 && pm->hasValue(expr->
exprId())) {
 
 1673                 if (updateValue(v, pm->at(expr->
exprId())))
 
 1697         std::vector<ValueFlow::Value> 
execute(
const Scope* scope)
 
 1712                     if (
execute(top).isUninitValue())
 
 1723                     const Token* thenStart = top->
link()->next();
 
 1725                     const Token* elseStart = 
nullptr;
 
 1727                         elseStart = thenStart->
link()->tokAt(2);
 
 1728                         next = elseStart->
link();
 
 1730                     std::vector<ValueFlow::Value> result;
 
 1739                     if (!result.empty())
 
 1754     return ex.execute(expr);
 
 1760     return ex.execute(scope);
 
 1764                                          const std::string& returnValue,
 
 1768     thread_local 
static std::unordered_map<std::string,
 
 1769                                            std::function<
ValueFlow::Value(
const std::unordered_map<nonneg int, ValueFlow::Value>& arg)>>
 
 1771     if (functions.count(returnValue) == 0) {
 
 1773         std::unordered_map<nonneg int, const Token*> lookupVarId;
 
 1776         functions[returnValue] =
 
 1777             [lookupVarId, expr, settings](
const std::unordered_map<nonneg int, ValueFlow::Value>& xargs) {
 
 1781             for (
const auto& p : xargs) {
 
 1782                 auto it = lookupVarId.find(p.first);
 
 1783                 if (it != lookupVarId.end())
 
 1786             return execute(expr.get(), pm, settings);
 
 1789     return functions.at(returnValue)(args);
 
bool astIsContainer(const Token *tok)
 
std::vector< const Token * > getArguments(const Token *ftok)
Get arguments (AST)
 
bool precedes(const Token *tok1, const Token *tok2)
If tok2 comes after tok1.
 
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.
 
const Token * findExpressionChanged(const Token *expr, const Token *start, const Token *end, const Settings &settings, int depth)
 
bool astHasExpr(const Token *tok, nonneg int exprid)
 
std::vector< const Token * > astFlatten(const Token *tok, const char *op)
 
Token * getCondTokFromEnd(Token *endBlock)
 
const Token * nextAfterAstRightmostLeaf(const Token *tok)
 
bool astIsUnsigned(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)
 
nonneg int astCount(const Token *tok, const char *op, int depth)
 
bool isVariableChanged(const Token *tok, int indirect, const Settings &settings, int depth)
 
void visitAstNodes(T *ast, const TFunc &visitor)
Visit AST nodes recursively.
 
R calculate(const std::string &s, const T &x, const T &y, bool *error=nullptr)
 
This class will take a list of filenames and settings and check then all files using threads.
 
Executor(const std::list< FileWithDetails > &files, const std::list< FileSettings > &fileSettings, const Settings &settings, SuppressionList &suppressions, ErrorLogger &errorLogger)
 
const Scope * functionScope
scope of function body
 
const Variable * getArgumentVar(nonneg int num) const
 
bool isImplicitlyVirtual(bool defaultVal=false) const
check if this function is virtual in the base classes
 
Yield getYield(const std::string &function) const
 
const Token * getContainerFromYield(const Token *tok, Container::Yield yield) const
 
const std::string & returnValue(const Token *ftok) const
 
static bigint toBigNumber(const std::string &str)
for conversion of numeric literals - for atoi-like conversions please use strToInt()
 
static bool isFloat(const std::string &str)
 
const Token * bodyStart
'{' token
 
const Token * bodyEnd
'}' token
 
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.
 
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 hasKnownIntValue() const
 
static nonneg int getStrLength(const Token *tok)
 
const ValueFlow::Value * getKnownValue(ValueFlow::Value::ValueType t) const
 
const ValueType * valueType() const
 
const std::string & strAt(int index) const
 
void astOperand1(Token *tok)
 
void function(const Function *f)
Associate this token with given function.
 
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
 
std::string strValue() const
This can be called only for tokens that are strings, else the assert() is called.
 
bool isAssignmentOp() const
 
bool isComparisonOp() const
 
const std::list< ValueFlow::Value > & values() const
 
static bool simpleMatch(const Token *tok, const char(&pattern)[count])
Match given token (or list of tokens) to a pattern list.
 
void astParent(Token *tok)
 
bool isSymbolicValue() const
 
Bound bound
The value bound
 
enum ValueFlow::Value::ValueType valueType
 
bool isIteratorValue() const
 
bool isFloatValue() const
 
@ Impossible
Listed values are impossible.
 
bool isImpossible() const
 
double floatValue
float value
 
bool isUninitValue() const
 
static void visitValue(T &self, F f)
 
const Token * condition
Condition that this value depends on.
 
const Token * tokvalue
token value - the token that has the value.
 
long long intvalue
int value (or sometimes bool value?)
 
enum ValueFlow::Value::ValueKind valueKind
 
bool isContainerSizeValue() const
 
const Library::Container * container
If the type is a container defined in a cfg file, this is the used.
 
Information about a member variable.
 
const Token * nameToken() const
Get name token.
 
std::shared_ptr< Token > createTokenFromExpression(const std::string &returnValue, const Settings &settings, bool cpp, std::unordered_map< nonneg int, const Token * > *lookupVarId)
 
@ error
Programming error.
 
std::vector< ValueFlow::Value > infer(const ValuePtr< InferModel > &model, const std::string &op, std::list< ValueFlow::Value > lhsValues, std::list< ValueFlow::Value > rhsValues)
 
const Token * parseCompareInt(const Token *tok, Value &true_value, Value &false_value, const std::function< std::vector< MathLib::bigint >(const Token *)> &evaluate)
 
CPPCHECKLIB ValuePtr< InferModel > makeIntegralInferModel()
 
void combineValueProperties(const Value &value1, const Value &value2, Value &result)
 
Value asImpossible(Value v)
 
static BuiltinLibraryFunction getBuiltinLibraryFunction(const std::string &name)
 
bool conditionIsFalse(const Token *condition, ProgramMemory pm, const Settings &settings)
Is condition always false when variable has given value?
 
static bool frontIs(const std::vector< MathLib::bigint > &v, bool i)
 
static bool isTrueOrFalse(const ValueFlow::Value &v, bool b)
 
static ValueFlow::Value execute(const Token *expr, ProgramMemory &pm, const Settings &settings)
 
static bool isFalse(const ValueFlow::Value &v)
 
static ValueFlow::Value evaluate(const std::string &op, const ValueFlow::Value &lhs, const ValueFlow::Value &rhs)
 
static void programMemoryParseCondition(ProgramMemory &pm, const Token *tok, const Token *endTok, const Settings &settings, bool then)
 
static bool evalSameCondition(const ProgramMemory &state, const Token *storedValue, const Token *cond, const Settings &settings)
 
static bool isNumericValue(const ValueFlow::Value &value)
 
static bool isTrue(const ValueFlow::Value &v)
 
static std::string removeAssign(const std::string &assign)
 
static std::vector< const Token * > setDifference(const std::vector< const Token * > &v1, const std::vector< const Token * > &v2)
 
ProgramMemory getProgramMemory(const Token *tok, const Token *expr, const ValueFlow::Value &value, const Settings &settings)
Get program memory by looking backwards from given token.
 
static bool isIntegralValue(const ValueFlow::Value &value)
 
static bool evaluateCondition(MathLib::bigint r, const Token *condition, ProgramMemory &pm, const Settings &settings)
 
ValueFlow::Value evaluateLibraryFunction(const std::unordered_map< nonneg int, ValueFlow::Value > &args, const std::string &returnValue, const Settings &settings, bool cpp)
 
static void removeModifiedVars(ProgramMemory &pm, const Token *tok, const Token *origin, const Settings &settings)
 
static bool isBasicForLoop(const Token *tok)
 
static void fillProgramMemoryFromConditions(ProgramMemory &pm, const Scope *scope, const Token *endTok, const Settings &settings)
 
static bool TokenExprIdCompare(const Token *tok1, const Token *tok2)
 
static void addVars(ProgramMemory &pm, const ProgramMemory::Map &vars)
 
static std::unordered_map< std::string, BuiltinLibraryFunction > createBuiltinLibraryFunctions()
 
std::function< ValueFlow::Value(const std::vector< ValueFlow::Value > &)> BuiltinLibraryFunction
 
bool conditionIsTrue(const Token *condition, ProgramMemory pm, const Settings &settings)
Is condition always true when variable has given value?
 
static bool TokenExprIdEqual(const Token *tok1, const Token *tok2)
 
static void pruneConditions(std::vector< const Token * > &conds, bool b, const std::unordered_map< nonneg int, ValueFlow::Value > &state)
 
static double asFloat(const ValueFlow::Value &value)
 
static void fillProgramMemoryFromAssignments(ProgramMemory &pm, const Token *tok, const Settings &settings, const ProgramMemory &state, const ProgramMemory::Map &vars)
 
static ProgramMemory getInitialProgramState(const Token *tok, const Token *origin, const Settings &settings, const ProgramMemory::Map &vars=ProgramMemory::Map {})
 
std::size_t operator()(ExprIdToken etok) const
 
nonneg int getExpressionId() const
 
ProgramMemoryState(const Settings *s)
 
void assume(const Token *tok, bool b, bool isEmpty=false)
 
std::map< nonneg int, const Token * > origins
 
void replace(ProgramMemory pm, const Token *origin=nullptr)
 
void removeModifiedVars(const Token *tok)
 
ProgramMemory get(const Token *tok, const Token *ctx, const ProgramMemory::Map &vars) const
 
void insert(const ProgramMemory &pm, const Token *origin=nullptr)
 
void addState(const Token *tok, const ProgramMemory::Map &vars)
 
const Settings * settings
 
void setValue(const Token *expr, const ValueFlow::Value &value)
 
bool getIntValue(nonneg int exprid, MathLib::bigint &result) const
 
void insert(const ProgramMemory &pm)
 
bool getTokValue(nonneg int exprid, const Token *&result) const
 
void setUnknown(const Token *expr)
 
const ValueFlow::Value * getValue(nonneg int exprid, bool impossible=false) const
 
void erase_if(const std::function< bool(const ExprIdToken &)> &pred)
 
bool getContainerEmptyValue(nonneg int exprid, MathLib::bigint &result) const
 
bool getContainerSizeValue(nonneg int exprid, MathLib::bigint &result) const
 
const ValueFlow::Value & at(nonneg int exprid) const
 
void setContainerSizeValue(const Token *expr, MathLib::bigint value, bool isEqual=true)
 
std::unordered_map< ExprIdToken, ValueFlow::Value, ExprIdToken::Hash > Map
 
void replace(ProgramMemory pm)
 
bool hasValue(nonneg int exprid)
 
void swap(ProgramMemory &pm)
 
void setIntValue(const Token *expr, MathLib::bigint value, bool impossible=false)
 
static std::string getStringLiteral(const std::string &str)
 
bool contains(const Range &r, const T &x)
 
static const Token * solveExprValue(const Token *expr, ValueFlow::Value &value)