| 807 | } |
| 808 | |
| 809 | void CheckStlImpl::mismatchingContainers() |
| 810 | { |
| 811 | logChecker("CheckStl::misMatchingContainers"); |
| 812 | |
| 813 | // Check if different containers are used in various calls of standard functions |
| 814 | const SymbolDatabase *symbolDatabase = mTokenizer->getSymbolDatabase(); |
| 815 | for (const Scope * scope : symbolDatabase->functionScopes) { |
| 816 | for (const Token* tok = scope->bodyStart->next(); tok != scope->bodyEnd; tok = tok->next()) { |
| 817 | if (Token::Match(tok, "%comp%|-")) { |
| 818 | if (checkIteratorPair(tok->astOperand1(), tok->astOperand2())) |
| 819 | continue; |
| 820 | } |
| 821 | if (!Token::Match(tok, "%name% ( !!)")) |
| 822 | continue; |
| 823 | const Token * const ftok = tok; |
| 824 | |
| 825 | const std::vector<const Token *> args = getArguments(ftok); |
| 826 | if (args.size() < 2) |
| 827 | continue; |
| 828 | |
| 829 | // Group args together by container |
| 830 | std::map<int, std::vector<ArgIteratorInfo>> containers; |
| 831 | for (int argnr = 1; argnr <= args.size(); ++argnr) { |
| 832 | const Library::ArgumentChecks::IteratorInfo *i = mSettings.library.getArgIteratorInfo(ftok, argnr); |
| 833 | if (!i) |
| 834 | continue; |
| 835 | const Token * const argTok = args[argnr - 1]; |
| 836 | containers[i->container].emplace_back(ArgIteratorInfo{argTok, i}); |
| 837 | } |
| 838 | |
| 839 | // Lambda is used to escape the nested loops |
| 840 | [&] { |
| 841 | for (const auto& p : containers) |
| 842 | { |
| 843 | const std::vector<ArgIteratorInfo>& cargs = p.second; |
| 844 | for (ArgIteratorInfo iter1 : cargs) { |
| 845 | for (ArgIteratorInfo iter2 : cargs) { |
| 846 | if (iter1.tok == iter2.tok) |
| 847 | continue; |
| 848 | if (iter1.info->first && iter2.info->last && |
| 849 | isSameExpression(false, iter1.tok, iter2.tok, mSettings, false, false)) |
| 850 | sameIteratorExpressionError(iter1.tok); |
| 851 | if (checkIteratorPair(iter1.tok, iter2.tok)) |
| 852 | return; |
| 853 | } |
| 854 | } |
| 855 | } |
| 856 | }(); |
| 857 | } |
| 858 | } |
| 859 | for (const Variable *var : symbolDatabase->variableList()) { |
| 860 | if (var && var->isStlStringType() && Token::Match(var->nameToken(), "%var% (") && |
| 861 | Token::Match(var->nameToken()->tokAt(2), "%name% . begin|cbegin|rbegin|crbegin ( ) , %name% . end|cend|rend|crend ( ) ,|)")) { |
| 862 | if (var->nameToken()->strAt(2) != var->nameToken()->strAt(8)) { |
| 863 | mismatchingContainersError(var->nameToken(), var->nameToken()->tokAt(2)); |
| 864 | } |
| 865 | } |
| 866 | } |
no test coverage detected