| 2479 | |
| 2480 | |
| 2481 | void CheckStlImpl::checkDereferenceInvalidIterator2() |
| 2482 | { |
| 2483 | const bool printInconclusive = (mSettings.certainty.isEnabled(Certainty::inconclusive)); |
| 2484 | |
| 2485 | logChecker("CheckStl::checkDereferenceInvalidIterator2"); |
| 2486 | |
| 2487 | for (const Token *tok = mTokenizer->tokens(); tok; tok = tok->next()) { |
| 2488 | if (Token::Match(tok, "sizeof|decltype|typeid|typeof (")) { |
| 2489 | tok = tok->linkAt(1); |
| 2490 | continue; |
| 2491 | } |
| 2492 | |
| 2493 | if (Token::Match(tok, "%assign%")) |
| 2494 | continue; |
| 2495 | |
| 2496 | std::vector<ValueFlow::Value> contValues; |
| 2497 | std::copy_if(tok->values().cbegin(), tok->values().cend(), std::back_inserter(contValues), [&](const ValueFlow::Value& value) { |
| 2498 | if (value.isImpossible()) |
| 2499 | return false; |
| 2500 | if (!printInconclusive && value.isInconclusive()) |
| 2501 | return false; |
| 2502 | return value.isContainerSizeValue(); |
| 2503 | }); |
| 2504 | |
| 2505 | |
| 2506 | // Can iterator point to END or before START? |
| 2507 | for (const ValueFlow::Value& value:tok->values()) { |
| 2508 | if (value.isImpossible()) |
| 2509 | continue; |
| 2510 | if (!printInconclusive && value.isInconclusive()) |
| 2511 | continue; |
| 2512 | if (!value.isIteratorValue()) |
| 2513 | continue; |
| 2514 | bool isInvalidIterator = false; |
| 2515 | const ValueFlow::Value* cValue = nullptr; |
| 2516 | if (value.isIteratorEndValue() && value.intvalue >= 0) { |
| 2517 | isInvalidIterator = value.intvalue > 0; |
| 2518 | } else if (value.isIteratorStartValue() && value.intvalue < 0) { |
| 2519 | isInvalidIterator = true; |
| 2520 | } else { |
| 2521 | auto it = std::find_if(contValues.cbegin(), contValues.cend(), [&](const ValueFlow::Value& c) { |
| 2522 | if (value.path != c.path) |
| 2523 | return false; |
| 2524 | if (value.isIteratorStartValue() && value.intvalue >= c.intvalue) |
| 2525 | return true; |
| 2526 | if (value.isIteratorEndValue() && -value.intvalue > c.intvalue) |
| 2527 | return true; |
| 2528 | return false; |
| 2529 | }); |
| 2530 | if (it == contValues.end()) |
| 2531 | continue; |
| 2532 | cValue = &*it; |
| 2533 | if (value.isIteratorStartValue() && value.intvalue > cValue->intvalue) |
| 2534 | isInvalidIterator = true; |
| 2535 | } |
| 2536 | bool inconclusive = false; |
| 2537 | bool unknown = false; |
| 2538 | const Token* emptyAdvance = nullptr; |
no test coverage detected