| 365 | } |
| 366 | |
| 367 | const Token * astIsVariableComparison(const Token *tok, const std::string &comp, const std::string &rhs, const Token **vartok) |
| 368 | { |
| 369 | if (!tok) |
| 370 | return nullptr; |
| 371 | |
| 372 | const Token *ret = nullptr; |
| 373 | if (tok->isComparisonOp()) { |
| 374 | if (tok->astOperand1() && match(tok->astOperand1(), rhs)) { |
| 375 | // Invert comparator |
| 376 | std::string s = tok->str(); |
| 377 | if (s[0] == '>') |
| 378 | s[0] = '<'; |
| 379 | else if (s[0] == '<') |
| 380 | s[0] = '>'; |
| 381 | if (s == comp) { |
| 382 | ret = tok->astOperand2(); |
| 383 | } |
| 384 | } else if (tok->str() == comp && tok->astOperand2() && match(tok->astOperand2(), rhs)) { |
| 385 | ret = tok->astOperand1(); |
| 386 | } |
| 387 | } else if (comp == "!=" && rhs == "0") { |
| 388 | if (tok->str() == "!") { |
| 389 | ret = tok->astOperand1(); |
| 390 | // handle (!(x==0)) as (x!=0) |
| 391 | astIsVariableComparison(ret, "==", "0", &ret); |
| 392 | } else |
| 393 | ret = tok; |
| 394 | } else if (comp == "==" && rhs == "0") { |
| 395 | if (tok->str() == "!") { |
| 396 | ret = tok->astOperand1(); |
| 397 | // handle (!(x!=0)) as (x==0) |
| 398 | astIsVariableComparison(ret, "!=", "0", &ret); |
| 399 | } |
| 400 | } |
| 401 | while (ret && ret->str() == ".") |
| 402 | ret = ret->astOperand2(); |
| 403 | while (ret && ret->isCast()) |
| 404 | ret = ret->astOperand2() ? ret->astOperand2() : ret->astOperand1(); |
| 405 | if (ret && ret->str() == "=" && ret->astOperand1() && ret->astOperand1()->varId()) |
| 406 | ret = ret->astOperand1(); |
| 407 | else if (ret && ret->varId() == 0U) |
| 408 | ret = nullptr; |
| 409 | if (vartok) |
| 410 | *vartok = ret; |
| 411 | return ret; |
| 412 | } |
| 413 | |
| 414 | bool isVariableDecl(const Token* tok) |
| 415 | { |
no test coverage detected