| 1614 | } |
| 1615 | |
| 1616 | void CheckUninitVarImpl::valueFlowUninit() |
| 1617 | { |
| 1618 | logChecker("CheckUninitVar::valueFlowUninit"); |
| 1619 | |
| 1620 | const SymbolDatabase *symbolDatabase = mTokenizer->getSymbolDatabase(); |
| 1621 | |
| 1622 | std::unordered_set<nonneg int> ids; |
| 1623 | for (const bool subfunction : {false, true}) { |
| 1624 | // check every executable scope |
| 1625 | for (const Scope* scope : symbolDatabase->functionScopes) { |
| 1626 | for (const Token* tok = scope->bodyStart; tok != scope->bodyEnd; tok = tok->next()) { |
| 1627 | if (isUnevaluated(tok)) { |
| 1628 | tok = tok->linkAt(1); |
| 1629 | continue; |
| 1630 | } |
| 1631 | if (ids.count(tok->exprId()) > 0) |
| 1632 | continue; |
| 1633 | if (!tok->variable() && !tok->isUnaryOp("*") && !tok->isUnaryOp("&")) |
| 1634 | continue; |
| 1635 | if (Token::Match(tok, "%name% (")) |
| 1636 | continue; |
| 1637 | const Token* parent = tok->astParent(); |
| 1638 | while (Token::simpleMatch(parent, ".")) |
| 1639 | parent = parent->astParent(); |
| 1640 | if (parent && parent->isUnaryOp("&")) |
| 1641 | continue; |
| 1642 | if (isVoidCast(parent)) |
| 1643 | continue; |
| 1644 | auto v = std::find_if( |
| 1645 | tok->values().cbegin(), tok->values().cend(), std::mem_fn(&ValueFlow::Value::isUninitValue)); |
| 1646 | if (v == tok->values().cend()) |
| 1647 | continue; |
| 1648 | if (v->tokvalue && ids.count(v->tokvalue->exprId()) > 0) |
| 1649 | continue; |
| 1650 | if (subfunction == (v->path == 0)) |
| 1651 | continue; |
| 1652 | if (v->isInconclusive()) |
| 1653 | continue; |
| 1654 | if (v->indirect > 1 || v->indirect < 0) |
| 1655 | continue; |
| 1656 | bool uninitderef = false; |
| 1657 | if (tok->variable()) { |
| 1658 | bool unknown; |
| 1659 | const bool isarray = tok->variable()->isArray(); |
| 1660 | if (isarray && tok->variable()->isMember()) |
| 1661 | continue; // Todo: this is a bailout |
| 1662 | if (isarray && tok->variable()->isStlType() && Token::simpleMatch(tok->astParent(), ".")) { |
| 1663 | const auto yield = astContainerYield(tok, mSettings.library); |
| 1664 | if (yield != Library::Container::Yield::AT_INDEX && yield != Library::Container::Yield::ITEM) |
| 1665 | continue; |
| 1666 | } |
| 1667 | const bool deref = CheckNullPointerImpl::isPointerDeRef(tok, unknown, mSettings); |
| 1668 | uninitderef = deref && v->indirect == 0; |
| 1669 | const bool isleaf = isLeafDot(tok) || uninitderef; |
| 1670 | if (!isleaf && Token::Match(tok->astParent(), ". %name%") && |
| 1671 | (tok->astParent()->next()->variable() || tok->astParent()->next()->isEnumerator())) |
| 1672 | continue; |
| 1673 | } |
no test coverage detected