| 450 | } |
| 451 | |
| 452 | void CheckStlImpl::iterators() |
| 453 | { |
| 454 | logChecker("CheckStl::iterators"); |
| 455 | |
| 456 | const SymbolDatabase *symbolDatabase = mTokenizer->getSymbolDatabase(); |
| 457 | |
| 458 | // Filling map of iterators id and their scope begin |
| 459 | std::map<int, const Token*> iteratorScopeBeginInfo; |
| 460 | for (const Variable* var : symbolDatabase->variableList()) { |
| 461 | bool inconclusiveType=false; |
| 462 | if (!isIterator(var, inconclusiveType)) |
| 463 | continue; |
| 464 | const int iteratorId = var->declarationId(); |
| 465 | if (iteratorId != 0) |
| 466 | iteratorScopeBeginInfo[iteratorId] = var->nameToken(); |
| 467 | } |
| 468 | |
| 469 | for (const Variable* var : symbolDatabase->variableList()) { |
| 470 | bool inconclusiveType=false; |
| 471 | if (!isIterator(var, inconclusiveType)) |
| 472 | continue; |
| 473 | if (inconclusiveType && !mSettings.certainty.isEnabled(Certainty::inconclusive)) |
| 474 | continue; |
| 475 | |
| 476 | const int iteratorId = var->declarationId(); |
| 477 | |
| 478 | // the validIterator flag says if the iterator has a valid value or not |
| 479 | bool validIterator = Token::Match(var->nameToken()->next(), "[(=:{[]"); |
| 480 | const Scope* invalidationScope = nullptr; |
| 481 | |
| 482 | // The container this iterator can be used with |
| 483 | const Token* containerToken = nullptr; |
| 484 | const Scope* containerAssignScope = nullptr; |
| 485 | |
| 486 | // When "validatingToken" is reached the validIterator is set to true |
| 487 | const Token* validatingToken = nullptr; |
| 488 | |
| 489 | const Token* eraseToken = nullptr; |
| 490 | |
| 491 | // Scan through the rest of the code and see if the iterator is |
| 492 | // used against other containers. |
| 493 | for (const Token *tok2 = var->nameToken(); tok2 && tok2 != var->scope()->bodyEnd; tok2 = tok2->next()) { |
| 494 | if (invalidationScope && tok2 == invalidationScope->bodyEnd) |
| 495 | validIterator = true; // Assume that the iterator becomes valid again |
| 496 | if (containerAssignScope && tok2 == containerAssignScope->bodyEnd) |
| 497 | containerToken = nullptr; // We don't know which containers might be used with the iterator |
| 498 | |
| 499 | if (tok2 == validatingToken) { |
| 500 | validIterator = true; |
| 501 | eraseToken = nullptr; |
| 502 | invalidationScope = nullptr; |
| 503 | } |
| 504 | |
| 505 | // Is the iterator used in a insert/erase operation? |
| 506 | if (Token::Match(tok2, "%name% . insert|erase ( *| %varid% )|,", iteratorId) && !isVector(tok2)) { |
| 507 | const Token* itTok = tok2->tokAt(4); |
| 508 | if (itTok->str() == "*") { |
| 509 | if (tok2->strAt(2) == "insert") |
no test coverage detected