| 588 | } |
| 589 | |
| 590 | Action analyzeToken(const Token* ref, const Token* tok, Direction d, bool inconclusiveRef) const { |
| 591 | if (!ref) |
| 592 | return Action::None; |
| 593 | // If its an inconclusiveRef then ref != tok |
| 594 | assert(!inconclusiveRef || ref != tok); |
| 595 | bool inconclusive = false; |
| 596 | if (match(ref)) { |
| 597 | if (inconclusiveRef) { |
| 598 | Action a = isModified(tok); |
| 599 | if (a.isModified() || a.isInconclusive()) |
| 600 | return Action::Inconclusive; |
| 601 | } else { |
| 602 | return analyzeMatch(tok, d) | Action::Match; |
| 603 | } |
| 604 | } else if (isDereferenceOp(ref) && !match(ref->astOperand1())) { |
| 605 | const Token* lifeTok = nullptr; |
| 606 | for (const ValueFlow::Value& v:ref->astOperand1()->values()) { |
| 607 | if (!v.isLocalLifetimeValue()) |
| 608 | continue; |
| 609 | if (v.conditional) |
| 610 | continue; |
| 611 | if (lifeTok) |
| 612 | return Action::None; |
| 613 | lifeTok = v.tokvalue; |
| 614 | } |
| 615 | if (!lifeTok) |
| 616 | return Action::None; |
| 617 | Action la = analyzeLifetime(lifeTok); |
| 618 | if (la.matches()) { |
| 619 | Action a = Action::Read; |
| 620 | if (isModified(tok).isModified()) |
| 621 | a = Action::Invalid; |
| 622 | if (Token::Match(tok->astParent(), "%assign%") && astIsLHS(tok)) |
| 623 | a |= Action::Invalid; |
| 624 | if (inconclusiveRef && a.isModified()) |
| 625 | return Action::Inconclusive; |
| 626 | return a; |
| 627 | } |
| 628 | if (la.isRead()) { |
| 629 | return isAliasModified(tok); |
| 630 | } |
| 631 | return Action::None; |
| 632 | |
| 633 | } else if (isAlias(ref, inconclusive)) { |
| 634 | inconclusive |= inconclusiveRef; |
| 635 | Action a = isAliasModified(tok); |
| 636 | if (inconclusive && a.isModified()) |
| 637 | return Action::Inconclusive; |
| 638 | return a; |
| 639 | } |
| 640 | if (isSameSymbolicValue(ref)) |
| 641 | return Action::Read | Action::SymbolicMatch; |
| 642 | |
| 643 | return Action::None; |
| 644 | } |
| 645 | |
| 646 | Action analyze(const Token* tok, Direction d) const override { |
| 647 | if (invalid()) |
no test coverage detected