| 739 | } |
| 740 | |
| 741 | static void valueFlowArrayElement(TokenList& tokenlist, const Settings& settings) |
| 742 | { |
| 743 | for (Token* tok = tokenlist.front(); tok; tok = tok->next()) { |
| 744 | if (tok->hasKnownIntValue()) |
| 745 | continue; |
| 746 | const Token* indexTok = nullptr; |
| 747 | const Token* arrayTok = nullptr; |
| 748 | if (Token::simpleMatch(tok, "[") && tok->isBinaryOp()) { |
| 749 | indexTok = tok->astOperand2(); |
| 750 | arrayTok = tok->astOperand1(); |
| 751 | } else if (Token::Match(tok->tokAt(-2), ". %name% (") && astIsContainer(tok->tokAt(-2)->astOperand1())) { |
| 752 | arrayTok = tok->tokAt(-2)->astOperand1(); |
| 753 | const Library::Container* container = getLibraryContainer(arrayTok); |
| 754 | if (!container || container->stdAssociativeLike) |
| 755 | continue; |
| 756 | const Library::Container::Yield yield = container->getYield(tok->strAt(-1)); |
| 757 | if (yield != Library::Container::Yield::AT_INDEX) |
| 758 | continue; |
| 759 | indexTok = tok->astOperand2(); |
| 760 | } |
| 761 | |
| 762 | if (!indexTok || !arrayTok) |
| 763 | continue; |
| 764 | |
| 765 | for (const ValueFlow::Value& arrayValue : arrayTok->values()) { |
| 766 | if (!arrayValue.isTokValue()) |
| 767 | continue; |
| 768 | if (arrayValue.isImpossible()) |
| 769 | continue; |
| 770 | for (const ValueFlow::Value& indexValue : indexTok->values()) { |
| 771 | if (!indexValue.isIntValue()) |
| 772 | continue; |
| 773 | if (indexValue.isImpossible()) |
| 774 | continue; |
| 775 | if (!arrayValue.isKnown() && !indexValue.isKnown() && arrayValue.varId != 0 && indexValue.varId != 0 && |
| 776 | !(arrayValue.varId == indexValue.varId && arrayValue.varvalue == indexValue.varvalue)) |
| 777 | continue; |
| 778 | |
| 779 | ValueFlow::Value result(0); |
| 780 | result.condition = arrayValue.condition ? arrayValue.condition : indexValue.condition; |
| 781 | result.setInconclusive(arrayValue.isInconclusive() || indexValue.isInconclusive()); |
| 782 | result.varId = (arrayValue.varId != 0) ? arrayValue.varId : indexValue.varId; |
| 783 | result.varvalue = (result.varId == arrayValue.varId) ? arrayValue.intvalue : indexValue.intvalue; |
| 784 | if (arrayValue.valueKind == indexValue.valueKind) |
| 785 | result.valueKind = arrayValue.valueKind; |
| 786 | |
| 787 | result.errorPath.insert(result.errorPath.end(), |
| 788 | arrayValue.errorPath.cbegin(), |
| 789 | arrayValue.errorPath.cend()); |
| 790 | result.errorPath.insert(result.errorPath.end(), |
| 791 | indexValue.errorPath.cbegin(), |
| 792 | indexValue.errorPath.cend()); |
| 793 | |
| 794 | const MathLib::bigint index = indexValue.intvalue; |
| 795 | |
| 796 | if (arrayValue.tokvalue->tokType() == Token::eString) { |
| 797 | const std::string s = arrayValue.tokvalue->strValue(); |
| 798 | if (index == s.size()) { |
no test coverage detected