| 285 | } |
| 286 | |
| 287 | static void conditionAlwaysTrueOrFalse(const Token *tok, const std::map<nonneg int, VariableValue> &variableValue, bool *alwaysTrue, bool *alwaysFalse) |
| 288 | { |
| 289 | if (!tok) |
| 290 | return; |
| 291 | |
| 292 | if (const ValueFlow::Value* v = tok->getKnownValue(ValueFlow::Value::ValueType::INT)) { |
| 293 | if (v->intvalue == 0) |
| 294 | *alwaysFalse = true; |
| 295 | else |
| 296 | *alwaysTrue = true; |
| 297 | return; |
| 298 | } |
| 299 | |
| 300 | if (tok->isName() || tok->str() == ".") { |
| 301 | while (tok && tok->str() == ".") |
| 302 | tok = tok->astOperand2(); |
| 303 | const auto it = tok ? variableValue.find(tok->varId()) : variableValue.end(); |
| 304 | if (it != variableValue.end()) { |
| 305 | *alwaysTrue = (it->second != 0LL); |
| 306 | *alwaysFalse = (it->second == 0LL); |
| 307 | } |
| 308 | } |
| 309 | |
| 310 | else if (tok->isComparisonOp()) { |
| 311 | if (variableValue.empty()) { |
| 312 | return; |
| 313 | } |
| 314 | |
| 315 | const Token *vartok, *numtok; |
| 316 | if (tok->astOperand2() && tok->astOperand2()->isNumber()) { |
| 317 | vartok = tok->astOperand1(); |
| 318 | numtok = tok->astOperand2(); |
| 319 | } else if (tok->astOperand1() && tok->astOperand1()->isNumber()) { |
| 320 | vartok = tok->astOperand2(); |
| 321 | numtok = tok->astOperand1(); |
| 322 | } else { |
| 323 | return; |
| 324 | } |
| 325 | |
| 326 | while (vartok && vartok->str() == ".") |
| 327 | vartok = vartok->astOperand2(); |
| 328 | |
| 329 | const auto it = vartok ? variableValue.find(vartok->varId()) : variableValue.end(); |
| 330 | if (it == variableValue.end()) |
| 331 | return; |
| 332 | |
| 333 | if (tok->str() == "==") |
| 334 | *alwaysTrue = (it->second == MathLib::toBigNumber(numtok)); |
| 335 | else if (tok->str() == "!=") |
| 336 | *alwaysTrue = (it->second != MathLib::toBigNumber(numtok)); |
| 337 | else |
| 338 | return; |
| 339 | *alwaysFalse = !(*alwaysTrue); |
| 340 | } |
| 341 | |
| 342 | else if (tok->str() == "!") { |
| 343 | bool t=false,f=false; |
| 344 | conditionAlwaysTrueOrFalse(tok->astOperand1(), variableValue, &t, &f); |
no test coverage detected