Index: clang/lib/StaticAnalyzer/Checkers/DebugIteratorModeling.cpp =================================================================== --- clang/lib/StaticAnalyzer/Checkers/DebugIteratorModeling.cpp +++ clang/lib/StaticAnalyzer/Checkers/DebugIteratorModeling.cpp @@ -55,6 +55,9 @@ bool evalCall(const CallEvent &Call, CheckerContext &C) const; }; +bool contains(const SourceManager &SM, const SourceRange Outer, + SourceRange Inner); + } //namespace DebugIteratorModeling::DebugIteratorModeling() { @@ -95,7 +98,18 @@ } else { State = State->BindExpr(CE, C.getLocationContext(), Default); } - C.addTransition(State); + + const auto &SM = C.getSourceManager(); + const NoteTag *InterestingTag = + C.getNoteTag([V, CE, &SM](BugReport &BR) -> std::string { + auto *PSBR = dyn_cast(&BR); + if (PSBR && contains(SM, PSBR->getRanges()[0], CE->getSourceRange())) { + PSBR->markInteresting(V); + } + return ""; + }); + + C.addTransition(State, InterestingTag); } void DebugIteratorModeling::analyzerIteratorPosition(const CallExpr *CE, @@ -135,6 +149,18 @@ return N; } +namespace { + +bool contains(const SourceManager &SM, const SourceRange Outer, + SourceRange Inner) { + SourceLocation OB = Outer.getBegin(), OE = Outer.getEnd(), + IB = Inner.getBegin(), IE = Inner.getEnd(); + return (OB == IB || SM.isBeforeInTranslationUnit(OB, IB)) && + (IE == OE || SM.isBeforeInTranslationUnit(IE, OE)); +} + +} // namespace + void ento::registerDebugIteratorModeling(CheckerManager &mgr) { mgr.registerChecker(); } Index: clang/lib/StaticAnalyzer/Checkers/IteratorModeling.cpp =================================================================== --- clang/lib/StaticAnalyzer/Checkers/IteratorModeling.cpp +++ clang/lib/StaticAnalyzer/Checkers/IteratorModeling.cpp @@ -93,24 +93,27 @@ SymbolRef Sym1, SymbolRef Sym2, const SVal &RetVal, OverloadedOperatorKind Op) const; void handleIncrement(CheckerContext &C, const SVal &RetVal, const SVal &Iter, - bool Postfix) const; + const Expr *ItE, bool Postfix) const; void handleDecrement(CheckerContext &C, const SVal &RetVal, const SVal &Iter, - bool Postfix) const; + const Expr *ItE, bool Postfix) const; void handleRandomIncrOrDecr(CheckerContext &C, const Expr *CE, OverloadedOperatorKind Op, const SVal &RetVal, - const SVal &LHS, const SVal &RHS) const; + const SVal &LHS, const SVal &RHS, + const Expr *ItE) const; void assignToContainer(CheckerContext &C, const Expr *CE, const SVal &RetVal, const MemRegion *Cont) const; + const NoteTag *getChangeTag(CheckerContext &C, StringRef Text, + const Expr *ItE, SVal It1, int64_t Amount = 0, + SVal It2 = UndefinedVal()) const; + const NoteTag *getInterestingnessPropagationTag(CheckerContext &C, SVal It1, + SVal It2) const; void printState(raw_ostream &Out, ProgramStateRef State, const char *NL, const char *Sep) const override; - public: IteratorModeling() {} void checkPostCall(const CallEvent &Call, CheckerContext &C) const; void checkBind(SVal Loc, SVal Val, const Stmt *S, CheckerContext &C) const; - void checkPostStmt(const CXXConstructExpr *CCE, CheckerContext &C) const; - void checkPostStmt(const DeclStmt *DS, CheckerContext &C) const; void checkPostStmt(const MaterializeTemporaryExpr *MTE, CheckerContext &C) const; void checkLiveSymbols(ProgramStateRef State, SymbolReaper &SR) const; @@ -159,7 +162,8 @@ Call.getArgExpr(0)->getType()->isIntegralOrEnumerationType()) { handleRandomIncrOrDecr(C, OrigExpr, Func->getOverloadedOperator(), Call.getReturnValue(), - InstCall->getCXXThisVal(), Call.getArgSVal(0)); + InstCall->getCXXThisVal(), Call.getArgSVal(0), + InstCall->getCXXThisExpr()); return; } } else { @@ -167,29 +171,29 @@ Call.getArgExpr(1)->getType()->isIntegralOrEnumerationType()) { handleRandomIncrOrDecr(C, OrigExpr, Func->getOverloadedOperator(), Call.getReturnValue(), Call.getArgSVal(0), - Call.getArgSVal(1)); + Call.getArgSVal(1), Call.getArgExpr(0)); return; } } } else if (isIncrementOperator(Func->getOverloadedOperator())) { if (const auto *InstCall = dyn_cast(&Call)) { handleIncrement(C, Call.getReturnValue(), InstCall->getCXXThisVal(), - Call.getNumArgs()); + InstCall->getCXXThisExpr(), Call.getNumArgs()); return; } handleIncrement(C, Call.getReturnValue(), Call.getArgSVal(0), - Call.getNumArgs()); + Call.getArgExpr(0), Call.getNumArgs()); return; } else if (isDecrementOperator(Func->getOverloadedOperator())) { if (const auto *InstCall = dyn_cast(&Call)) { handleDecrement(C, Call.getReturnValue(), InstCall->getCXXThisVal(), - Call.getNumArgs()); + InstCall->getCXXThisExpr(), Call.getNumArgs()); return; } handleDecrement(C, Call.getReturnValue(), Call.getArgSVal(0), - Call.getNumArgs()); + Call.getArgExpr(0), Call.getNumArgs()); return; } } else { @@ -213,7 +217,10 @@ if (cast(Func)->isMoveConstructor()) { State = removeIteratorPosition(State, Call.getArgSVal(0)); } - C.addTransition(State); + const NoteTag *InterestingTag = + getInterestingnessPropagationTag(C, Call.getArgSVal(0), + Call.getReturnValue()); + C.addTransition(State, InterestingTag); return; } } @@ -241,7 +248,9 @@ const auto *Pos = getIteratorPosition(State, Val); if (Pos) { State = setIteratorPosition(State, Loc, *Pos); - C.addTransition(State); + const NoteTag *InterestingTag = + getInterestingnessPropagationTag(C, Val, Loc); + C.addTransition(State, InterestingTag); } else { const auto *OldPos = getIteratorPosition(State, Loc); if (OldPos) { @@ -255,11 +264,15 @@ CheckerContext &C) const { /* Transfer iterator state to temporary objects */ auto State = C.getState(); - const auto *Pos = getIteratorPosition(State, C.getSVal(MTE->getSubExpr())); + SVal OldVal = C.getSVal(MTE->getSubExpr()); + SVal NewVal = C.getSVal(MTE); + const auto *Pos = getIteratorPosition(State, OldVal); if (!Pos) return; - State = setIteratorPosition(State, C.getSVal(MTE), *Pos); - C.addTransition(State); + State = setIteratorPosition(State, NewVal, *Pos); + const NoteTag *InterestingTag = + getInterestingnessPropagationTag(C, OldVal, NewVal); + C.addTransition(State, InterestingTag); } void IteratorModeling::checkLiveSymbols(ProgramStateRef State, @@ -394,7 +407,8 @@ } void IteratorModeling::handleIncrement(CheckerContext &C, const SVal &RetVal, - const SVal &Iter, bool Postfix) const { + const SVal &Iter, const Expr *ItE, + bool Postfix) const { // Increment the symbolic expressions which represents the position of the // iterator auto State = C.getState(); @@ -414,13 +428,17 @@ assert(NewPos && "Iterator should have position after successful advancement"); + const NoteTag *ChangeTag = + getChangeTag(C, "incremented", ItE, Iter, 1, + Postfix ? UndefinedVal() : RetVal); State = setIteratorPosition(State, Iter, *NewPos); State = setIteratorPosition(State, RetVal, Postfix ? *Pos : *NewPos); - C.addTransition(State); + C.addTransition(State, ChangeTag); } void IteratorModeling::handleDecrement(CheckerContext &C, const SVal &RetVal, - const SVal &Iter, bool Postfix) const { + const SVal &Iter, const Expr *ItE, + bool Postfix) const { // Decrement the symbolic expressions which represents the position of the // iterator auto State = C.getState(); @@ -440,9 +458,12 @@ assert(NewPos && "Iterator should have position after successful advancement"); + const NoteTag *ChangeTag = + getChangeTag(C, "decremented", ItE, Iter, 1, + Postfix ? UndefinedVal() : RetVal); State = setIteratorPosition(State, Iter, *NewPos); State = setIteratorPosition(State, RetVal, Postfix ? *Pos : *NewPos); - C.addTransition(State); + C.addTransition(State, ChangeTag); } void IteratorModeling::handleRandomIncrOrDecr(CheckerContext &C, @@ -450,7 +471,8 @@ OverloadedOperatorKind Op, const SVal &RetVal, const SVal &LHS, - const SVal &RHS) const { + const SVal &RHS, + const Expr *ItE) const { // Increment or decrement the symbolic expressions which represents the // position of the iterator auto State = C.getState(); @@ -474,8 +496,14 @@ assert(NewPos && "Iterator should have position after successful advancement"); + auto &SVB = State->getStateManager().getSValBuilder(); + const NoteTag *ChangeTag = + getChangeTag(C, ((Op == OO_Plus || Op == OO_PlusEqual) ? + "incremented" : "decremented"), ItE, LHS, + SVB.getKnownValue(State, *value)->getExtValue(), + (TgtVal == RetVal) ? RetVal : UndefinedVal()); State = setIteratorPosition(NewState, TgtVal, *NewPos); - C.addTransition(State); + C.addTransition(State, ChangeTag); } else { assignToContainer(C, CE, TgtVal, Pos->getContainer()); } @@ -493,6 +521,80 @@ C.addTransition(State); } +const NoteTag *IteratorModeling::getChangeTag(CheckerContext &C, StringRef Text, + const Expr *ItE, SVal It1, + int64_t Amount, SVal It2) const { + StringRef Name; + if (const auto *DRE = dyn_cast(ItE->IgnoreParenCasts()))) { + Name = DRE->getDecl()->getName(); + } + + return C.getNoteTag([Text, Name, Amount, It1, It2](BugReport &BR) + -> std::string { + auto *PSBR = dyn_cast(&BR); + if (!PSBR) + return ""; + + if (PSBR->isInteresting(It2)) { + PSBR->markInteresting(It1); + if (const auto &LCV1 = It1.getAs()) { + PSBR->markInteresting(LCV1->getRegion()); + } + } else if (const auto &LCV2 = It2.getAs()) { + if (PSBR->isInteresting(LCV2->getRegion())) { + PSBR->markInteresting(It1); + if (const auto &LCV1 = It1.getAs()) { + PSBR->markInteresting(LCV1->getRegion()); + } + } + } + + if (!PSBR->isInteresting(It1)) { + const auto &LCV1 = It1.getAs(); + if (!LCV1) + return ""; + if (!PSBR->isInteresting(LCV1->getRegion())) + return ""; + } + + SmallString<256> Msg; + llvm::raw_svector_ostream Out(Msg); + Out << "Iterator " << (!Name.empty() ? ("'" + Name.str() + "' ") : "" ) + << Text; + if (Amount) { + Out << " by " << Amount; + } + return std::string(Out.str()); + }); +} + +const NoteTag * +IteratorModeling::getInterestingnessPropagationTag(CheckerContext &C, + SVal It1, SVal It2) const { + return C.getNoteTag([It1, It2](BugReport &BR) + -> std::string { + auto *PSBR = dyn_cast(&BR); + if (!PSBR) + return ""; + + if (PSBR->isInteresting(It2)) { + PSBR->markInteresting(It1); + if (const auto &LCV1 = It1.getAs()) { + PSBR->markInteresting(LCV1->getRegion()); + } + } else if (const auto &LCV2 = It2.getAs()) { + if (PSBR->isInteresting(LCV2->getRegion())) { + PSBR->markInteresting(It1); + if (const auto &LCV1 = It1.getAs()) { + PSBR->markInteresting(LCV1->getRegion()); + } + } + } + + return ""; + }); +} + void IteratorModeling::printState(raw_ostream &Out, ProgramStateRef State, const char *NL, const char *Sep) const { auto SymbolMap = State->get(); Index: clang/test/Analysis/iterator-modelling.cpp =================================================================== --- clang/test/Analysis/iterator-modelling.cpp +++ clang/test/Analysis/iterator-modelling.cpp @@ -1,6 +1,6 @@ -// RUN: %clang_analyze_cc1 -std=c++11 -analyzer-checker=core,cplusplus,debug.DebugIteratorModeling,debug.ExprInspection -analyzer-config aggressive-binary-operation-simplification=true -analyzer-config c++-container-inlining=false %s -verify +// RUN: %clang_analyze_cc1 -std=c++11 -analyzer-checker=core,cplusplus,debug.DebugIteratorModeling,debug.ExprInspection -analyzer-config aggressive-binary-operation-simplification=true -analyzer-config c++-container-inlining=false -analyzer-output=text %s -verify -// RUN: %clang_analyze_cc1 -std=c++11 -analyzer-checker=core,cplusplus,debug.DebugIteratorModeling,debug.ExprInspection -analyzer-config aggressive-binary-operation-simplification=true -analyzer-config c++-container-inlining=true -DINLINE=1 %s -verify +// RUN: %clang_analyze_cc1 -std=c++11 -analyzer-checker=core,cplusplus,debug.DebugIteratorModeling,debug.ExprInspection -analyzer-config aggressive-binary-operation-simplification=true -analyzer-config c++-container-inlining=true -DINLINE=1 -analyzer-output=text %s -verify // RUN: %clang_analyze_cc1 -std=c++11 -analyzer-checker=core,cplusplus,alpha.cplusplus.IteratorModeling,debug.ExprInspection -analyzer-config aggressive-binary-operation-simplification=true %s 2>&1 | FileCheck %s @@ -26,8 +26,10 @@ auto i = v.begin(); clang_analyzer_eval(clang_analyzer_iterator_container(i) == &v); // expected-warning{{TRUE}} + // expected-note@-1{{TRUE}} clang_analyzer_denote(clang_analyzer_container_begin(v), "$v.begin()"); clang_analyzer_express(clang_analyzer_iterator_position(i)); //expected-warning{{$v.begin()}} + //expected-note@-1{{$v.begin()}} if (i != v.begin()) { clang_analyzer_warnIfReached(); @@ -38,8 +40,10 @@ auto i = v.end(); clang_analyzer_eval(clang_analyzer_iterator_container(i) == &v); // expected-warning{{TRUE}} + // expected-note@-1{{TRUE}} clang_analyzer_denote(clang_analyzer_container_end(v), "$v.end()"); clang_analyzer_express(clang_analyzer_iterator_position(i)); //expected-warning{{$v.end()}} + //expected-note@-1{{$v.end()}} if (i != v.end()) { clang_analyzer_warnIfReached(); @@ -51,10 +55,13 @@ clang_analyzer_denote(clang_analyzer_container_begin(v), "$v.begin()"); - auto j = ++i; + auto j = ++i; // expected-note{{Iterator 'i' incremented by 1}} + // expected-note@-1{{Iterator 'i' incremented by 1}} clang_analyzer_express(clang_analyzer_iterator_position(i)); //expected-warning{{$v.begin() + 1}} + //expected-note@-1{{$v.begin() + 1}} clang_analyzer_express(clang_analyzer_iterator_position(j)); //expected-warning{{$v.begin() + 1}} + //expected-note@-1{{$v.begin() + 1}} } void prefix_decrement(const std::vector &v) { @@ -62,10 +69,13 @@ clang_analyzer_denote(clang_analyzer_container_end(v), "$v.end()"); - auto j = --i; + auto j = --i; // expected-note{{Iterator 'i' decremented by 1}} + // expected-note@-1{{Iterator 'i' decremented by 1}} clang_analyzer_express(clang_analyzer_iterator_position(i)); //expected-warning{{$v.end() - 1}} + //expected-note@-1{{$v.end() - 1}} clang_analyzer_express(clang_analyzer_iterator_position(j)); //expected-warning{{$v.end() - 1}} + //expected-note@-1{{$v.end() - 1}} } void postfix_increment(const std::vector &v) { @@ -73,10 +83,12 @@ clang_analyzer_denote(clang_analyzer_container_begin(v), "$v.begin()"); - auto j = i++; + auto j = i++; // expected-note{{Iterator 'i' incremented by 1}} clang_analyzer_express(clang_analyzer_iterator_position(i)); //expected-warning{{$v.begin() + 1}} + //expected-note@-1{{$v.begin() + 1}} clang_analyzer_express(clang_analyzer_iterator_position(j)); //expected-warning{{$v.begin()}} + //expected-note@-1{{$v.begin()}} } void postfix_decrement(const std::vector &v) { @@ -84,10 +96,12 @@ clang_analyzer_denote(clang_analyzer_container_end(v), "$v.end()"); - auto j = i--; + auto j = i--; // expected-note{{Iterator 'i' decremented by 1}} clang_analyzer_express(clang_analyzer_iterator_position(i)); //expected-warning{{$v.end() - 1}} + //expected-note@-1{{$v.end() - 1}} clang_analyzer_express(clang_analyzer_iterator_position(j)); //expected-warning{{$v.end()}} + //expected-note@-1{{$v.end()}} } void plus_equal(const std::vector &v) { @@ -95,9 +109,10 @@ clang_analyzer_denote(clang_analyzer_container_begin(v), "$v.begin()"); - i += 2; + i += 2; // expected-note{{Iterator 'i' incremented by 2}} clang_analyzer_express(clang_analyzer_iterator_position(i)); //expected-warning{{$v.begin() + 2}} + //expected-note@-1{{$v.begin() + 2}} } void minus_equal(const std::vector &v) { @@ -105,9 +120,10 @@ clang_analyzer_denote(clang_analyzer_container_end(v), "$v.end()"); - i -= 2; + i -= 2; // expected-note{{Iterator 'i' decremented by 2}} clang_analyzer_express(clang_analyzer_iterator_position(i)); //expected-warning{{$v.end() - 2}} + //expected-note@-1{{$v.end() - 2}} } void copy(const std::vector &v) { @@ -118,7 +134,9 @@ auto i2 = i1; clang_analyzer_eval(clang_analyzer_iterator_container(i2) == &v); // expected-warning{{TRUE}} + // expected-note@-1{{TRUE}} clang_analyzer_express(clang_analyzer_iterator_position(i2)); //expected-warning{{$v.end()}} + //expected-note@-1{{$v.end()}} } void plus(const std::vector &v) { @@ -126,10 +144,13 @@ clang_analyzer_denote(clang_analyzer_container_begin(v), "$v.begin()"); - auto i2 = i1 + 2; + auto i2 = i1 + 2; // expected-note{{Iterator 'i1' incremented by 2}} + // expected-note@-1{{Iterator 'i1' incremented by 2}} clang_analyzer_eval(clang_analyzer_iterator_container(i2) == &v); // expected-warning{{TRUE}} + // expected-note@-1{{TRUE}} clang_analyzer_express(clang_analyzer_iterator_position(i2)); //expected-warning{{$v.begin() + 2}} + //expected-note@-1{{$v.begin() + 2}} } void minus(const std::vector &v) { @@ -137,10 +158,13 @@ clang_analyzer_denote(clang_analyzer_container_end(v), "$v.end()"); - auto i2 = i1 - 2; + auto i2 = i1 - 2; // expected-note{{Iterator 'i1' decremented by 2}} + // expected-note@-1{{Iterator 'i1' decremented by 2}} clang_analyzer_eval(clang_analyzer_iterator_container(i2) == &v); // expected-warning{{TRUE}} + // expected-note@-1{{TRUE}} clang_analyzer_express(clang_analyzer_iterator_position(i2)); //expected-warning{{$v.end() - 2}} + //expected-note@-1{{$v.end() - 2}} } void copy_and_increment1(const std::vector &v) { @@ -149,10 +173,12 @@ clang_analyzer_denote(clang_analyzer_container_begin(v), "$v.begin()"); auto i2 = i1; - ++i1; + ++i1; // expected-note{{Iterator 'i1' incremented by 1}} clang_analyzer_express(clang_analyzer_iterator_position(i1)); //expected-warning{{$v.begin() + 1}} + //expected-note@-1{{$v.begin() + 1}} clang_analyzer_express(clang_analyzer_iterator_position(i2)); //expected-warning{{$v.begin()}} + //expected-note@-1{{$v.begin()}} } void copy_and_increment2(const std::vector &v) { @@ -161,10 +187,12 @@ clang_analyzer_denote(clang_analyzer_container_begin(v), "$v.begin()"); auto i2 = i1; - ++i2; + ++i2; // expected-note{{Iterator 'i2' incremented by 1}} clang_analyzer_express(clang_analyzer_iterator_position(i1)); //expected-warning{{$v.begin()}} + //expected-note@-1{{$v.begin()}} clang_analyzer_express(clang_analyzer_iterator_position(i2)); //expected-warning{{$v.begin() + 1}} + //expected-note@-1{{$v.begin() + 1}} } void copy_and_decrement1(const std::vector &v) { @@ -173,10 +201,12 @@ clang_analyzer_denote(clang_analyzer_container_end(v), "$v.end()"); auto i2 = i1; - --i1; + --i1; // expected-note{{Iterator 'i1' decremented by 1}} clang_analyzer_express(clang_analyzer_iterator_position(i1)); //expected-warning{{$v.end() - 1}} + //expected-note@-1{{$v.end() - 1}} clang_analyzer_express(clang_analyzer_iterator_position(i2)); //expected-warning{{$v.end()}} + //expected-note@-1{{$v.end()}} } void copy_and_decrement2(const std::vector &v) { @@ -185,10 +215,12 @@ clang_analyzer_denote(clang_analyzer_container_end(v), "$v.end()"); auto i2 = i1; - --i2; + --i2; // expected-note{{Iterator 'i2' decremented by 1}} clang_analyzer_express(clang_analyzer_iterator_position(i1)); //expected-warning{{$v.end()}} + //expected-note@-1{{$v.end()}} clang_analyzer_express(clang_analyzer_iterator_position(i2)); //expected-warning{{$v.end() - 1}} + //expected-note@-1{{$v.end() - 1}} } //////////////////////////////////////////////////////////////////////////////// @@ -202,36 +234,46 @@ void list_copy_assignment(std::list &L1, const std::list &L2) { auto i0 = L1.cbegin(); clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{TRUE}} + //expected-note@-1{{TRUE}} L1 = L2; clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{FALSE}} + //expected-note@-1{{FALSE}} } void vector_copy_assignment(std::vector &V1, const std::vector &V2) { auto i0 = V1.cbegin(); clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{TRUE}} + //expected-note@-1{{TRUE}} V1 = V2; clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{FALSE}} + //expected-note@-1{{FALSE}} } void deque_copy_assignment(std::deque &D1, const std::deque &D2) { auto i0 = D1.cbegin(); clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{TRUE}} + //expected-note@-1{{TRUE}} D1 = D2; clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{FALSE}} + //expected-note@-1{{FALSE}} } void forward_list_copy_assignment(std::forward_list &FL1, const std::forward_list &FL2) { auto i0 = FL1.cbegin(); clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{TRUE}} + //expected-note@-1{{TRUE}} FL1 = FL2; clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{FALSE}} + //expected-note@-1{{FALSE}} } // Move void list_move_assignment(std::list &L1, std::list &L2) { auto i0 = L1.cbegin(), i1 = L2.cbegin(), i2 = --L2.cend(), i3 = L2.cend(); + // expected-note@-1{{Iterator decremented by 1}} + // expected-note@-2{{Iterator decremented by 1}} clang_analyzer_denote(clang_analyzer_container_begin(L2), "$L2.begin()"); clang_analyzer_denote(clang_analyzer_container_end(L2), "$L2.end()"); @@ -239,50 +281,75 @@ L1 = std::move(L2); clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{FALSE}} + //expected-note@-1{{FALSE}} clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{TRUE}} + //expected-note@-1{{TRUE}} clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{TRUE}} + //expected-note@-1{{TRUE}} clang_analyzer_eval(clang_analyzer_iterator_validity(i3)); //expected-warning{{TRUE}} FIXME: Should be FALSE. + //expected-note@-1{{TRUE}} FIXME: Should be FALSE. clang_analyzer_eval(clang_analyzer_iterator_container(i1) == &L1); // expected-warning{{TRUE}} + // expected-note@-1{{TRUE}} clang_analyzer_eval(clang_analyzer_iterator_container(i2) == &L1); // expected-warning{{TRUE}} + // expected-note@-1{{TRUE}} clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning{{$L2.begin()}} + // expected-note@-1{{$L2.begin()}} } void vector_move_assignment(std::vector &V1, std::vector &V2) { auto i0 = V1.cbegin(), i1 = V2.cbegin(), i2 = --V2.cend(), i3 = V2.cend(); + // expected-note@-1{{Iterator decremented by 1}} + // expected-note@-2{{Iterator decremented by 1}} clang_analyzer_denote(clang_analyzer_container_begin(V2), "$V2.begin()"); V1 = std::move(V2); clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{FALSE}} + //expected-note@-1{{FALSE}} clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{TRUE}} + //expected-note@-1{{TRUE}} clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{TRUE}} + //expected-note@-1{{TRUE}} clang_analyzer_eval(clang_analyzer_iterator_validity(i3)); //expected-warning{{TRUE}} FIXME: Should be FALSE. + //expected-note@-1{{TRUE}} FIXME: Should be FALSE. clang_analyzer_eval(clang_analyzer_iterator_container(i1) == &V1); // expected-warning{{TRUE}} + // expected-note@-1{{TRUE}} clang_analyzer_eval(clang_analyzer_iterator_container(i2) == &V1); // expected-warning{{TRUE}} + // expected-note@-1{{TRUE}} clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning{{$V2.begin()}} + // expected-note@-1{{$V2.begin()}} } void deque_move_assignment(std::deque &D1, std::deque &D2) { auto i0 = D1.cbegin(), i1 = D2.cbegin(), i2 = --D2.cend(), i3 = D2.cend(); + // expected-note@-1{{Iterator decremented by 1}} + // expected-note@-2{{Iterator decremented by 1}} clang_analyzer_denote(clang_analyzer_container_begin(D2), "$D2.begin()"); D1 = std::move(D2); clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{FALSE}} + //expected-note@-1{{FALSE}} clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{TRUE}} + //expected-note@-1{{TRUE}} clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{TRUE}} + //expected-note@-1{{TRUE}} clang_analyzer_eval(clang_analyzer_iterator_validity(i3)); //expected-warning{{TRUE}} FIXME: Should be FALSE. + //expected-note@-1{{TRUE}} FIXME: Should be FALSE. clang_analyzer_eval(clang_analyzer_iterator_container(i1) == &D1); // expected-warning{{TRUE}} + // expected-note@-1{{TRUE}} clang_analyzer_eval(clang_analyzer_iterator_container(i2) == &D1); // expected-warning{{TRUE}} + // expected-note@-1{{TRUE}} clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning{{$D2.begin()}} + // expected-note@-1{{$D2.begin()}} } void forward_list_move_assignment(std::forward_list &FL1, @@ -294,12 +361,17 @@ FL1 = std::move(FL2); clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{FALSE}} + //expected-note@-1{{FALSE}} clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{TRUE}} + //expected-note@-1{{TRUE}} clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{TRUE}} FIXME: Should be FALSE. + //expected-note@-1{{TRUE}} FIXME: Should be FALSE. clang_analyzer_eval(clang_analyzer_iterator_container(i1) == &FL1); // expected-warning{{TRUE}} + // expected-note@-1{{TRUE}} clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning{{$FL2.begin()}} + // expected-note@-1{{$FL2.begin()}} } @@ -318,28 +390,36 @@ auto i0 = L.cbegin(), i1 = L.cend(); L.assign(10, n); clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{FALSE}} + //expected-note@-1{{FALSE}} clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{FALSE}} + //expected-note@-1{{FALSE}} } void vector_assign(std::vector &V, int n) { auto i0 = V.cbegin(), i1 = V.cend(); V.assign(10, n); clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{FALSE}} + //expected-note@-1{{FALSE}} clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{FALSE}} + //expected-note@-1{{FALSE}} } void deque_assign(std::deque &D, int n) { auto i0 = D.cbegin(), i1 = D.cend(); D.assign(10, n); clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{FALSE}} + //expected-note@-1{{FALSE}} clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{FALSE}} + //expected-note@-1{{FALSE}} } void forward_list_assign(std::forward_list &FL, int n) { auto i0 = FL.cbegin(), i1 = FL.cend(); FL.assign(10, n); clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{FALSE}} + //expected-note@-1{{FALSE}} clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{FALSE}} + //expected-note@-1{{FALSE}} } /// clear() @@ -350,29 +430,37 @@ void list_clear(std::list &L) { auto i0 = L.cbegin(), i1 = L.cend(); clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{TRUE}} + //expected-note@-1{{TRUE}} L.clear(); clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{FALSE}} + //expected-note@-1{{FALSE}} } void vector_clear(std::vector &V) { auto i0 = V.cbegin(), i1 = V.cend(); clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{TRUE}} + //expected-note@-1{{TRUE}} V.clear(); clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{FALSE}} + //expected-note@-1{{FALSE}} } void deque_clear(std::deque &D) { auto i0 = D.cbegin(), i1 = D.cend(); clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{TRUE}} + //expected-note@-1{{TRUE}} D.clear(); clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{FALSE}} + //expected-note@-1{{FALSE}} } void forward_list_clear(std::forward_list &FL) { auto i0 = FL.cbegin(), i1 = FL.cend(); clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{TRUE}} + //expected-note@-1{{TRUE}} FL.clear(); clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{FALSE}} + //expected-note@-1{{FALSE}} } /// push_back() @@ -386,6 +474,8 @@ void list_push_back(std::list &L, int n) { auto i0 = L.cbegin(), i1 = --L.cend(), i2 = L.cend(); + // expected-note@-1{{Iterator decremented by 1}} + // expected-note@-2{{Iterator decremented by 1}} clang_analyzer_denote(clang_analyzer_container_begin(L), "$L.begin()"); clang_analyzer_denote(clang_analyzer_container_end(L), "$L.end()"); @@ -393,18 +483,26 @@ L.push_back(n); clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{TRUE}} + //expected-note@-1{{TRUE}} clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{TRUE}} + //expected-note@-1{{TRUE}} clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{TRUE}} + //expected-note@-1{{TRUE}} clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning{{$L.begin()}} + // expected-note@-1{{$L.begin()}} clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning{{$L.end() - 1}} + // expected-note@-1{{$L.end() - 1}} clang_analyzer_express(clang_analyzer_iterator_position(i2)); // expected-warning{{$L.end()}} FIXME: Should be $L.end() + 1 + // expected-note@-1{{$L.end()}} FIXME: Should be $L.end() + 1 } /// std::vector-like containers: The past-the-end iterator is invalidated. void vector_push_back(std::vector &V, int n) { auto i0 = V.cbegin(), i1 = --V.cend(), i2 = V.cend(); + // expected-note@-1{{Iterator decremented by 1}} + // expected-note@-2{{Iterator decremented by 1}} clang_analyzer_denote(clang_analyzer_container_begin(V), "$V.begin()"); clang_analyzer_denote(clang_analyzer_container_end(V), "$V.end()"); @@ -412,11 +510,16 @@ V.push_back(n); clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{TRUE}} + //expected-note@-1{{TRUE}} clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{TRUE}} + //expected-note@-1{{TRUE}} clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{FALSE}} + //expected-note@-1{{FALSE}} clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning{{$V.begin()}} + // expected-note@-1{{$V.begin()}} clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning{{$V.end() - 1}} + // expected-note@-1{{$V.end() - 1}} } /// std::deque-like containers: All iterators, including the past-the-end @@ -424,6 +527,7 @@ void deque_push_back(std::deque &D, int n) { auto i0 = D.cbegin(), i1 = --D.cend(), i2 = D.cend(); + // expected-note@-1{{Iterator decremented by 1}} clang_analyzer_denote(clang_analyzer_container_begin(D), "$D.begin()"); clang_analyzer_denote(clang_analyzer_container_end(D), "$D.end()"); @@ -431,8 +535,11 @@ D.push_back(n); clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{FALSE}} + //expected-note@-1{{FALSE}} clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{FALSE}} + //expected-note@-1{{FALSE}} clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{FALSE}} + //expected-note@-1{{FALSE}} } /// emplace_back() @@ -446,6 +553,8 @@ void list_emplace_back(std::list &L, int n) { auto i0 = L.cbegin(), i1 = --L.cend(), i2 = L.cend(); + // expected-note@-1{{Iterator decremented by 1}} + // expected-note@-2{{Iterator decremented by 1}} clang_analyzer_denote(clang_analyzer_container_begin(L), "$L.begin()"); clang_analyzer_denote(clang_analyzer_container_end(L), "$L.end()"); @@ -453,18 +562,26 @@ L.emplace_back(n); clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{TRUE}} + //expected-note@-1{{TRUE}} clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{TRUE}} + //expected-note@-1{{TRUE}} clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{TRUE}} + //expected-note@-1{{TRUE}} clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning{{$L.begin()}} + // expected-note@-1{{$L.begin()}} clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning{{$L.end()}} + // expected-note@-1{{$L.end()}} clang_analyzer_express(clang_analyzer_iterator_position(i2)); // expected-warning{{$L.end()}} FIXME: Should be $L.end() + 1 + // expected-note@-1{{$L.end()}} FIXME: Should be $L.end() + 1 } /// std::vector-like containers: The past-the-end iterator is invalidated. void vector_emplace_back(std::vector &V, int n) { auto i0 = V.cbegin(), i1 = --V.cend(), i2 = V.cend(); + // expected-note@-1{{Iterator decremented by 1}} + // expected-note@-2{{Iterator decremented by 1}} clang_analyzer_denote(clang_analyzer_container_begin(V), "$V.begin()"); clang_analyzer_denote(clang_analyzer_container_end(V), "$V.end()"); @@ -472,11 +589,16 @@ V.emplace_back(n); clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{TRUE}} + //expected-note@-1{{TRUE}} clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{TRUE}} + //expected-note@-1{{TRUE}} clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{FALSE}} + //expected-note@-1{{FALSE}} clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning{{$V.begin()}} + // expected-note@-1{{$V.begin()}} clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning{{$V.end() - 1}} + // expected-note@-1{{$V.end() - 1}} } /// std::deque-like containers: All iterators, including the past-the-end @@ -484,6 +606,7 @@ void deque_emplace_back(std::deque &D, int n) { auto i0 = D.cbegin(), i1 = --D.cend(), i2 = D.cend(); + // expected-note@-1{{Iterator decremented by 1}} clang_analyzer_denote(clang_analyzer_container_begin(D), "$D.begin()"); clang_analyzer_denote(clang_analyzer_container_end(D), "$D.end()"); @@ -491,8 +614,11 @@ D.emplace_back(n); clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{FALSE}} + //expected-note@-1{{FALSE}} clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{FALSE}} + //expected-note@-1{{FALSE}} clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{FALSE}} + //expected-note@-1{{FALSE}} } /// pop_back() @@ -506,6 +632,7 @@ void list_pop_back(std::list &L, int n) { auto i0 = L.cbegin(), i1 = --L.cend(), i2 = L.cend(); + // expected-note@-1{{Iterator decremented by 1}} clang_analyzer_denote(clang_analyzer_container_begin(L), "$L.begin()"); clang_analyzer_denote(clang_analyzer_container_end(L), "$L.end()"); @@ -513,11 +640,16 @@ L.pop_back(); clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{TRUE}} + //expected-note@-1{{TRUE}} clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{FALSE}} + //expected-note@-1{{FALSE}} clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{TRUE}} + //expected-note@-1{{TRUE}} clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning{{$L.begin()}} + // expected-note@-1{{$L.begin()}} clang_analyzer_express(clang_analyzer_iterator_position(i2)); // expected-warning{{$L.end()}} FIXME: Should be $L.end() - 1 + // expected-note@-1{{$L.end()}} FIXME: Should be $L.end() - 1 } /// std::vector-like containers: Iterators to the last element, as well as the @@ -525,6 +657,7 @@ void vector_pop_back(std::vector &V, int n) { auto i0 = V.cbegin(), i1 = --V.cend(), i2 = V.cend(); + // expected-note@-1{{Iterator decremented by 1}} clang_analyzer_denote(clang_analyzer_container_begin(V), "$V.begin()"); clang_analyzer_denote(clang_analyzer_container_end(V), "$V.end()"); @@ -532,10 +665,14 @@ V.pop_back(); clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{TRUE}} + //expected-note@-1{{TRUE}} clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{FALSE}} + //expected-note@-1{{FALSE}} clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{FALSE}} + //expected-note@-1{{FALSE}} clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning{{$V.begin()}} + // expected-note@-1{{$V.begin()}} } /// std::deque-like containers: Iterators to the last element are invalidated. @@ -544,6 +681,7 @@ void deque_pop_back(std::deque &D, int n) { auto i0 = D.cbegin(), i1 = --D.cend(), i2 = D.cend(); + // expected-note@-1{{Iterator decremented by 1}} clang_analyzer_denote(clang_analyzer_container_begin(D), "$D.begin()"); clang_analyzer_denote(clang_analyzer_container_end(D), "$D.end()"); @@ -551,10 +689,14 @@ D.pop_back(); clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{TRUE}} + //expected-note@-1{{TRUE}} clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{FALSE}} + //expected-note@-1{{FALSE}} clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{FALSE}} + //expected-note@-1{{FALSE}} clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning{{$D.begin()}} + // expected-note@-1{{$D.begin()}} } /// push_front() @@ -575,10 +717,14 @@ L.push_front(n); clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{TRUE}} + //expected-note@-1{{TRUE}} clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{TRUE}} + //expected-note@-1{{TRUE}} clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning{{$L.begin()}} + // expected-note@-1{{$L.begin()}} clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning{{$L.end()}} + // expected-note@-1{{$L.end()}} } /// std::deque-like containers: All iterators, including the past-the-end @@ -586,6 +732,7 @@ void deque_push_front(std::deque &D, int n) { auto i0 = D.cbegin(), i1 = --D.cend(), i2 = D.cend(); + // expected-note@-1{{Iterator decremented by 1}} clang_analyzer_denote(clang_analyzer_container_begin(D), "$D.begin()"); clang_analyzer_denote(clang_analyzer_container_end(D), "$D.end()"); @@ -593,8 +740,11 @@ D.push_front(n); clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{FALSE}} + //expected-note@-1{{FALSE}} clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{FALSE}} + //expected-note@-1{{FALSE}} clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{FALSE}} + //expected-note@-1{{FALSE}} } /// std::forward_list-like containers: No iterators are invalidated. @@ -608,10 +758,14 @@ FL.push_front(n); clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{TRUE}} + //expected-note@-1{{TRUE}} clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{TRUE}} + //expected-note@-1{{TRUE}} clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning{{$FL.begin()}} + // expected-note@-1{{$FL.begin()}} clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning{{$FL.end()}} + // expected-note@-1{{$FL.end()}} } /// emplace_front() @@ -632,10 +786,14 @@ L.emplace_front(n); clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{TRUE}} + //expected-note@-1{{TRUE}} clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{TRUE}} + //expected-note@-1{{TRUE}} clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning{{$L.begin()}} + // expected-note@-1{{$L.begin()}} clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning{{$L.end()}} + // expected-note@-1{{$L.end()}} } /// std::deque-like containers: All iterators, including the past-the-end @@ -643,6 +801,7 @@ void deque_emplace_front(std::deque &D, int n) { auto i0 = D.cbegin(), i1 = --D.cend(), i2 = D.cend(); + // expected-note@-1{{Iterator decremented by 1}} clang_analyzer_denote(clang_analyzer_container_begin(D), "$D.begin()"); clang_analyzer_denote(clang_analyzer_container_end(D), "$D.end()"); @@ -650,8 +809,11 @@ D.emplace_front(n); clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{FALSE}} + //expected-note@-1{{FALSE}} clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{FALSE}} + //expected-note@-1{{FALSE}} clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{FALSE}} + //expected-note@-1{{FALSE}} } /// std::forward_list-like containers: No iterators are invalidated. @@ -665,10 +827,14 @@ FL.emplace_front(n); clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{TRUE}} + //expected-note@-1{{TRUE}} clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{TRUE}} + //expected-note@-1{{TRUE}} clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning{{$FL.begin()}} + // expected-note@-1{{$FL.begin()}} clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning{{$FL.end()}} + // expected-note@-1{{$FL.end()}} } /// pop_front() @@ -682,6 +848,8 @@ void list_pop_front(std::list &L, int n) { auto i0 = L.cbegin(), i1 = ++L.cbegin(), i2 = L.cend(); + // expected-note@-1{{Iterator incremented by 1}} + // expected-note@-2{{Iterator incremented by 1}} clang_analyzer_denote(clang_analyzer_container_begin(L), "$L.begin()"); clang_analyzer_denote(clang_analyzer_container_end(L), "$L.end()"); @@ -689,11 +857,16 @@ L.pop_front(); clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{FALSE}} + //expected-note@-1{{FALSE}} clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{TRUE}} + //expected-note@-1{{TRUE}} clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{TRUE}} + //expected-note@-1{{TRUE}} clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning{{$L.begin() + 1}} + // expected-note@-1{{$L.begin() + 1}} clang_analyzer_express(clang_analyzer_iterator_position(i2)); // expected-warning{{$L.end()}} + // expected-note@-1{{$L.end()}} } /// std::deque-like containers: Iterators to the first element are invalidated. @@ -701,6 +874,8 @@ void deque_pop_front(std::deque &D, int n) { auto i0 = D.cbegin(), i1 = ++D.cbegin(), i2 = D.cend(); + // expected-note@-1{{Iterator incremented by 1}} + // expected-note@-2{{Iterator incremented by 1}} clang_analyzer_denote(clang_analyzer_container_begin(D), "$D.begin()"); clang_analyzer_denote(clang_analyzer_container_end(D), "$D.end()"); @@ -708,11 +883,16 @@ D.pop_front(); clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{FALSE}} + //expected-note@-1{{FALSE}} clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{TRUE}} + //expected-note@-1{{TRUE}} clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{TRUE}} + //expected-note@-1{{TRUE}} clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning{{$D.begin() + 1}} + // expected-note@-1{{$D.begin() + 1}} clang_analyzer_express(clang_analyzer_iterator_position(i2)); // expected-warning{{$D.end()}} + // expected-note@-1{{$D.end()}} } /// std::forward_list-like containers: Iterators to the first element are @@ -720,6 +900,8 @@ void forward_list_pop_front(std::list &FL, int n) { auto i0 = FL.cbegin(), i1 = ++FL.cbegin(), i2 = FL.cend(); + // expected-note@-1{{Iterator incremented by 1}} + // expected-note@-2{{Iterator incremented by 1}} clang_analyzer_denote(clang_analyzer_container_begin(FL), "$FL.begin()"); clang_analyzer_denote(clang_analyzer_container_end(FL), "$FL.end()"); @@ -727,11 +909,16 @@ FL.pop_front(); clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{FALSE}} + //expected-note@-1{{FALSE}} clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{TRUE}} + //expected-note@-1{{TRUE}} clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{TRUE}} + //expected-note@-1{{TRUE}} clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning{{$FL.begin() + 1}} + // expected-note@-1{{$FL.begin() + 1}} clang_analyzer_express(clang_analyzer_iterator_position(i2)); // expected-warning{{$FL.end()}} + // expected-note@-1{{$FL.end()}} } /// insert() @@ -755,15 +942,21 @@ auto i2 = L.insert(i0, n); clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{TRUE}} + //expected-note@-1{{TRUE}} clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{TRUE}} + //expected-note@-1{{TRUE}} clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning{{$L.begin()}} + // expected-note@-1{{$L.begin()}} // clang_analyzer_express(clang_analyzer_iterator_position(i2)); FIXME: expect warning $L.begin() - 1 clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning{{$L.end()}} + // expected-note@-1{{$L.end()}} } void list_insert_behind_begin(std::list &L, int n) { auto i0 = L.cbegin(), i1 = ++L.cbegin(), i2 = L.cend(); + // expected-note@-1{{Iterator incremented by 1}} + // expected-note@-2{{Iterator incremented by 1}} clang_analyzer_denote(clang_analyzer_container_begin(L), "$L.begin()"); clang_analyzer_denote(clang_analyzer_container_end(L), "$L.end()"); @@ -771,13 +964,19 @@ auto i3 = L.insert(i1, n); clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{TRUE}} + //expected-note@-1{{TRUE}} clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{TRUE}} + //expected-note@-1{{TRUE}} clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{TRUE}} + //expected-note@-1{{TRUE}} clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning{{$L.begin()}} FIXME: Should be $L.begin() - 1 + // expected-note@-1{{$L.begin()}} FIXME: Should be $L.begin() - 1 clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning{{$L.begin() + 1}} + // expected-note@-1{{$L.begin() + 1}} // clang_analyzer_express(clang_analyzer_iterator_position(i3)); FIXME: expect warning $L.begin() clang_analyzer_express(clang_analyzer_iterator_position(i2)); // expected-warning{{$L.end()}} + // expected-note@-1{{$L.end()}} } template Iter return_any_iterator(const Iter &It); @@ -792,17 +991,25 @@ auto i3 = L.insert(i1, n); clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{TRUE}} + //expected-note@-1{{TRUE}} clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{TRUE}} + //expected-note@-1{{TRUE}} clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{TRUE}} + //expected-note@-1{{TRUE}} clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning{{$L.begin()}} + // expected-note@-1{{$L.begin()}} clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning{{$i1}} + // expected-note@-1{{$i1}} // clang_analyzer_express(clang_analyzer_iterator_position(i3)); FIXME: expect warning $i - 1 clang_analyzer_express(clang_analyzer_iterator_position(i2)); // expected-warning{{$L.end()}} + // expected-note@-1{{$L.end()}} } void list_insert_ahead_of_end(std::list &L, int n) { auto i0 = L.cbegin(), i1 = --L.cend(), i2 = L.cend(); + // expected-note@-1{{Iterator decremented by 1}} + // expected-note@-2{{Iterator decremented by 1}} clang_analyzer_denote(clang_analyzer_container_begin(L), "$L.begin()"); clang_analyzer_denote(clang_analyzer_container_end(L), "$L.end()"); @@ -810,17 +1017,25 @@ auto i3 = L.insert(i1, n); clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{TRUE}} + //expected-note@-1{{TRUE}} clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{TRUE}} + //expected-note@-1{{TRUE}} clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{TRUE}} + //expected-note@-1{{TRUE}} clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning{{$L.begin()}} + // expected-note@-1{{$L.begin()}} clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning{{$L.end() - 1}} + // expected-note@-1{{$L.end() - 1}} clang_analyzer_express(clang_analyzer_iterator_position(i2)); // expected-warning{{$L.end()}} + // expected-note@-1{{$L.end()}} // clang_analyzer_express(clang_analyzer_iterator_position(i3)); FIXME: expect warning $L.end() - 2 } void list_insert_end(std::list &L, int n) { auto i0 = L.cbegin(), i1 = --L.cend(), i2 = L.cend(); + // expected-note@-1{{Iterator decremented by 1}} + // expected-note@-2{{Iterator decremented by 1}} clang_analyzer_denote(clang_analyzer_container_begin(L), "$L.begin()"); clang_analyzer_denote(clang_analyzer_container_end(L), "$L.end()"); @@ -828,12 +1043,18 @@ auto i3 = L.insert(i2, n); clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{TRUE}} + //expected-note@-1{{TRUE}} clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{TRUE}} + //expected-note@-1{{TRUE}} clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{TRUE}} + //expected-note@-1{{TRUE}} clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning{{$L.begin()}} + // expected-note@-1{{$L.begin()}} clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning{{$L.end() - 1}} FIXME: should be $L.end() - 2 + // expected-note@-1{{$L.end() - 1}} FIXME: should be $L.end() - 2 clang_analyzer_express(clang_analyzer_iterator_position(i2)); // expected-warning{{$L.end()}} + // expected-note@-1{{$L.end()}} // clang_analyzer_express(clang_analyzer_iterator_position(i3)); FIXME: expect warning $L.end() - 1 } @@ -850,13 +1071,16 @@ auto i2 = V.insert(i0, n); clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{FALSE}} + //expected-note@-1{{FALSE}} clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{FALSE}} + //expected-note@-1{{FALSE}} // clang_analyzer_express(clang_analyzer_iterator_position(i2)); FIXME: expect warning $V.begin() - 1 } void vector_insert_behind_begin(std::vector &V, int n) { auto i0 = V.cbegin(), i1 = ++V.cbegin(), i2 = V.cend(); + // expected-note@-1{{Iterator incremented by 1}} clang_analyzer_denote(clang_analyzer_container_begin(V), "$V.begin()"); clang_analyzer_denote(clang_analyzer_container_end(V), "$V.end()"); @@ -864,10 +1088,14 @@ auto i3 = V.insert(i1, n); clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{TRUE}} + //expected-note@-1{{TRUE}} clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{FALSE}} + //expected-note@-1{{FALSE}} clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{FALSE}} + //expected-note@-1{{FALSE}} clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning{{$V.begin()}} FIXME: Should be $V.begin() - 1 + // expected-note@-1{{$V.begin()}} FIXME: Should be $V.begin() - 1 // clang_analyzer_express(clang_analyzer_iterator_position(i3)); // FIXME: expect -warning $V.begin() } @@ -881,15 +1109,20 @@ auto i3 = V.insert(i1, n); clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{TRUE}} + //expected-note@-1{{TRUE}} clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{FALSE}} + //expected-note@-1{{FALSE}} clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{FALSE}} + //expected-note@-1{{FALSE}} clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning{{$V.begin()}} + // expected-note@-1{{$V.begin()}} // clang_analyzer_express(clang_analyzer_iterator_position(i3)); FIXME: expecte warning $i1 - 1 } void vector_insert_ahead_of_end(std::vector &V, int n) { auto i0 = V.cbegin(), i1 = --V.cend(), i2 = V.cend(); + // expected-note@-1{{Iterator decremented by 1}} clang_analyzer_denote(clang_analyzer_container_begin(V), "$V.begin()"); clang_analyzer_denote(clang_analyzer_container_end(V), "$V.end()"); @@ -897,15 +1130,21 @@ auto i3 = V.insert(i1, n); clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{TRUE}} + //expected-note@-1{{TRUE}} clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{FALSE}} + //expected-note@-1{{FALSE}} clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{FALSE}} + //expected-note@-1{{FALSE}} clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning{{$V.begin()}} + // expected-note@-1{{$V.begin()}} // clang_analyzer_express(clang_analyzer_iterator_position(i3)); FIXME: expect warning $V.end() - 2 } void vector_insert_end(std::vector &V, int n) { auto i0 = V.cbegin(), i1 = --V.cend(), i2 = V.cend(); + // expected-note@-1{{Iterator decremented by 1}} + // expected-note@-2{{Iterator decremented by 1}} clang_analyzer_denote(clang_analyzer_container_begin(V), "$V.begin()"); clang_analyzer_denote(clang_analyzer_container_end(V), "$V.end()"); @@ -913,11 +1152,16 @@ auto i3 = V.insert(i2, n); clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{TRUE}} + //expected-note@-1{{TRUE}} clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{TRUE}} + //expected-note@-1{{TRUE}} clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{FALSE}} + //expected-note@-1{{FALSE}} clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning{{$V.begin()}} + // expected-note@-1{{$V.begin()}} clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning{{$V.end() - 1}} FIXME: Should be $V.end() - 2 + // expected-note@-1{{$V.end() - 1}} FIXME: Should be $V.end() - 2 // clang_analyzer_express(clang_analyzer_iterator_position(i3)); FIXME: expect warning $V.end() - 1 } @@ -933,13 +1177,16 @@ auto i2 = D.insert(i0, n); clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{FALSE}} + //expected-note@-1{{FALSE}} clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{FALSE}} + //expected-note@-1{{FALSE}} // clang_analyzer_express(clang_analyzer_iterator_position(i2)); FIXME: expect warning $D.begin() - 1 } void deque_insert_behind_begin(std::deque &D, int n) { auto i0 = D.cbegin(), i1 = ++D.cbegin(), i2 = D.cend(); + // expected-note@-1{{Iterator incremented by 1}} clang_analyzer_denote(clang_analyzer_container_begin(D), "$D.begin()"); clang_analyzer_denote(clang_analyzer_container_end(D), "$D.end()"); @@ -947,8 +1194,11 @@ auto i3 = D.insert(i1, n); clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{FALSE}} + //expected-note@-1{{FALSE}} clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{FALSE}} + //expected-note@-1{{FALSE}} clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{FALSE}} + //expected-note@-1{{FALSE}} // clang_analyzer_express(clang_analyzer_iterator_position(i3)); FIXME: expect warning $D.begin() - 1 } @@ -963,14 +1213,18 @@ auto i3 = D.insert(i1, n); clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{FALSE}} + //expected-note@-1{{FALSE}} clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{FALSE}} + //expected-note@-1{{FALSE}} clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{FALSE}} + //expected-note@-1{{FALSE}} // clang_analyzer_express(clang_analyzer_iterator_position(i3)); FIXME: expect warning $i1 - 1 } void deque_insert_ahead_of_end(std::deque &D, int n) { auto i0 = D.cbegin(), i1 = --D.cend(), i2 = D.cend(); + // expected-note@-1{{Iterator decremented by 1}} clang_analyzer_denote(clang_analyzer_container_begin(D), "$D.begin()"); clang_analyzer_denote(clang_analyzer_container_end(D), "$D.end()"); @@ -978,14 +1232,18 @@ auto i3 = D.insert(i1, n); clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{FALSE}} + //expected-note@-1{{FALSE}} clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{FALSE}} + //expected-note@-1{{FALSE}} clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{FALSE}} + //expected-note@-1{{FALSE}} // clang_analyzer_express(clang_analyzer_iterator_position(i3)); FIXME: expect warning $D.end() - 2 } void deque_insert_end(std::deque &D, int n) { auto i0 = D.cbegin(), i1 = --D.cend(), i2 = D.cend(); + // expected-note@-1{{Iterator decremented by 1}} clang_analyzer_denote(clang_analyzer_container_begin(D), "$D.begin()"); clang_analyzer_denote(clang_analyzer_container_end(D), "$D.end()"); @@ -993,8 +1251,11 @@ auto i3 = D.insert(i2, n); clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{FALSE}} + //expected-note@-1{{FALSE}} clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{FALSE}} + //expected-note@-1{{FALSE}} clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{FALSE}} + //expected-note@-1{{FALSE}} // clang_analyzer_express(clang_analyzer_iterator_position(i3)); FIXME: expect warning $D.end() - 1 } @@ -1018,15 +1279,21 @@ auto i2 = FL.insert_after(i0, n); clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{TRUE}} + //expected-note@-1{{TRUE}} clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{TRUE}} + //expected-note@-1{{TRUE}} clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning{{$FL.begin()}} + // expected-note@-1{{$FL.begin()}} // clang_analyzer_express(clang_analyzer_iterator_position(i2)); FIXME: expect warning $FL.begin() + 1 clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning{{$FL.end()}} + // expected-note@-1{{$FL.end()}} } void forward_list_insert_after_behind_begin(std::forward_list &FL, int n) { auto i0 = FL.cbegin(), i1 = ++FL.cbegin(), i2 = FL.cend(); + // expected-note@-1{{Iterator incremented by 1}} + // expected-note@-2{{Iterator incremented by 1}} clang_analyzer_denote(clang_analyzer_container_begin(FL), "$FL.begin()"); clang_analyzer_denote(clang_analyzer_container_end(FL), "$FL.end()"); @@ -1034,13 +1301,19 @@ auto i3 = FL.insert_after(i1, n); clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{TRUE}} + //expected-note@-1{{TRUE}} clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{TRUE}} + //expected-note@-1{{TRUE}} clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{TRUE}} + //expected-note@-1{{TRUE}} clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning{{$FL.begin()}} + // expected-note@-1{{$FL.begin()}} clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning{{$FL.begin() + 1}} + // expected-note@-1{{$FL.begin() + 1}} // clang_analyzer_express(clang_analyzer_iterator_position(i3)); FIXME: expect warning $FL.begin() + 2 clang_analyzer_express(clang_analyzer_iterator_position(i2)); // expected-warning{{$FL.end()}} + // expected-note@-1{{$FL.end()}} } void forward_list_insert_after_unknown(std::forward_list &FL, int n) { @@ -1053,13 +1326,19 @@ auto i3 = FL.insert_after(i1, n); clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{TRUE}} + //expected-note@-1{{TRUE}} clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{TRUE}} + //expected-note@-1{{TRUE}} clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{TRUE}} + //expected-note@-1{{TRUE}} clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning{{$FL.begin()}} + // expected-note@-1{{$FL.begin()}} clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning{{$i1}} + // expected-note@-1{{$i1}} // clang_analyzer_express(clang_analyzer_iterator_position(i3)); FIXME: expect warning $i1 + 1 clang_analyzer_express(clang_analyzer_iterator_position(i2)); // expected-warning{{$FL.end()}} + // expected-note@-1{{$FL.end()}} } /// emplace() @@ -1083,15 +1362,21 @@ auto i2 = L.emplace(i0, n); clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{TRUE}} + //expected-note@-1{{TRUE}} clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{TRUE}} + //expected-note@-1{{TRUE}} clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning{{$L.begin()}} + // expected-note@-1{{$L.begin()}} // clang_analyzer_express(clang_analyzer_iterator_position(i2)); FIXME: expect warning $L.begin() - 1 clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning{{$L.end()}} + // expected-note@-1{{$L.end()}} } void list_emplace_behind_begin(std::list &L, int n) { auto i0 = L.cbegin(), i1 = ++L.cbegin(), i2 = L.cend(); + // expected-note@-1{{Iterator incremented by 1}} + // expected-note@-2{{Iterator incremented by 1}} clang_analyzer_denote(clang_analyzer_container_begin(L), "$L.begin()"); clang_analyzer_denote(clang_analyzer_container_end(L), "$L.end()"); @@ -1099,13 +1384,19 @@ auto i3 = L.emplace(i1, n); clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{TRUE}} + //expected-note@-1{{TRUE}} clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{TRUE}} + //expected-note@-1{{TRUE}} clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{TRUE}} + //expected-note@-1{{TRUE}} clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning{{$L.begin()}} FIXME: Should be $L.begin() - 1 + // expected-note@-1{{$L.begin()}} FIXME: Should be $L.begin() - 1 clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning{{$L.begin() + 1}} + // expected-note@-1{{$L.begin() + 1}} // clang_analyzer_express(clang_analyzer_iterator_position(i3)); FIXME: expect warning $L.begin() clang_analyzer_express(clang_analyzer_iterator_position(i2)); // expected-warning{{$L.end()}} + // expected-note@-1{{$L.end()}} } template Iter return_any_iterator(const Iter &It); @@ -1120,17 +1411,25 @@ auto i3 = L.emplace(i1, n); clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{TRUE}} + //expected-note@-1{{TRUE}} clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{TRUE}} + //expected-note@-1{{TRUE}} clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{TRUE}} + //expected-note@-1{{TRUE}} clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning{{$L.begin()}} + // expected-note@-1{{$L.begin()}} clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning{{$i1}} + // expected-note@-1{{$i1}} // clang_analyzer_express(clang_analyzer_iterator_position(i3)); FIXME: expect warning $i - 1 clang_analyzer_express(clang_analyzer_iterator_position(i2)); // expected-warning{{$L.end()}} + // expected-note@-1{{$L.end()}} } void list_emplace_ahead_of_end(std::list &L, int n) { auto i0 = L.cbegin(), i1 = --L.cend(), i2 = L.cend(); + // expected-note@-1{{Iterator decremented by 1}} + // expected-note@-2{{Iterator decremented by 1}} clang_analyzer_denote(clang_analyzer_container_begin(L), "$L.begin()"); clang_analyzer_denote(clang_analyzer_container_end(L), "$L.end()"); @@ -1138,17 +1437,25 @@ auto i3 = L.emplace(i1, n); clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{TRUE}} + //expected-note@-1{{TRUE}} clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{TRUE}} + //expected-note@-1{{TRUE}} clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{TRUE}} + //expected-note@-1{{TRUE}} clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning{{$L.begin()}} + // expected-note@-1{{$L.begin()}} clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning{{$L.end() - 1}} + // expected-note@-1{{$L.end() - 1}} clang_analyzer_express(clang_analyzer_iterator_position(i2)); // expected-warning{{$L.end()}} + // expected-note@-1{{$L.end()}} // clang_analyzer_express(clang_analyzer_iterator_position(i3)); FIXME: expect warning $L.end() - 2 } void list_emplace_end(std::list &L, int n) { auto i0 = L.cbegin(), i1 = --L.cend(), i2 = L.cend(); + // expected-note@-1{{Iterator decremented by 1}} + // expected-note@-2{{Iterator decremented by 1}} clang_analyzer_denote(clang_analyzer_container_begin(L), "$L.begin()"); clang_analyzer_denote(clang_analyzer_container_end(L), "$L.end()"); @@ -1156,12 +1463,18 @@ auto i3 = L.emplace(i2, n); clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{TRUE}} + //expected-note@-1{{TRUE}} clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{TRUE}} + //expected-note@-1{{TRUE}} clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{TRUE}} + //expected-note@-1{{TRUE}} clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning{{$L.begin()}} + // expected-note@-1{{$L.begin()}} clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning{{$L.end() - 1}} FIXME: should be $L.end() - 2 + // expected-note@-1{{$L.end() - 1}} FIXME: should be $L.end() - 2 clang_analyzer_express(clang_analyzer_iterator_position(i2)); // expected-warning{{$L.end()}} + // expected-note@-1{{$L.end()}} // clang_analyzer_express(clang_analyzer_iterator_position(i3)); FIXME: expect warning $L.end() - 1 } @@ -1178,12 +1491,15 @@ auto i2 = V.emplace(i0, n); clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{FALSE}} + //expected-note@-1{{FALSE}} clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{FALSE}} + //expected-note@-1{{FALSE}} // clang_analyzer_express(clang_analyzer_iterator_position(i2)); FIXME: expect warning $V.begin() - 1 } void vector_emplace_behind_begin(std::vector &V, int n) { auto i0 = V.cbegin(), i1 = ++V.cbegin(), i2 = V.cend(); + // expected-note@-1{{Iterator incremented by 1}} clang_analyzer_denote(clang_analyzer_container_begin(V), "$V.begin()"); clang_analyzer_denote(clang_analyzer_container_end(V), "$V.end()"); @@ -1191,10 +1507,14 @@ auto i3 = V.emplace(i1, n); clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{TRUE}} + //expected-note@-1{{TRUE}} clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{FALSE}} + //expected-note@-1{{FALSE}} clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{FALSE}} + //expected-note@-1{{FALSE}} clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning{{$V.begin()}} FIXME: Should be $V.begin() - 1 + // expected-note@-1{{$V.begin()}} FIXME: Should be $V.begin() - 1 // clang_analyzer_express(clang_analyzer_iterator_position(i3)); // FIXME: expect -warning $V.begin() } @@ -1208,15 +1528,20 @@ auto i3 = V.emplace(i1, n); clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{TRUE}} + //expected-note@-1{{TRUE}} clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{FALSE}} + //expected-note@-1{{FALSE}} clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{FALSE}} + //expected-note@-1{{FALSE}} clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning{{$V.begin()}} + // expected-note@-1{{$V.begin()}} // clang_analyzer_express(clang_analyzer_iterator_position(i3)); FIXME: expecte warning $i1 - 1 } void vector_emplace_ahead_of_end(std::vector &V, int n) { auto i0 = V.cbegin(), i1 = --V.cend(), i2 = V.cend(); + // expected-note@-1{{Iterator decremented by 1}} clang_analyzer_denote(clang_analyzer_container_begin(V), "$V.begin()"); clang_analyzer_denote(clang_analyzer_container_end(V), "$V.end()"); @@ -1224,15 +1549,21 @@ auto i3 = V.emplace(i1, n); clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{TRUE}} + //expected-note@-1{{TRUE}} clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{FALSE}} + //expected-note@-1{{FALSE}} clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{FALSE}} + //expected-note@-1{{FALSE}} clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning{{$V.begin()}} + // expected-note@-1{{$V.begin()}} // clang_analyzer_express(clang_analyzer_iterator_position(i3)); FIXME: expect warning $V.end() - 2 } void vector_emplace_end(std::vector &V, int n) { auto i0 = V.cbegin(), i1 = --V.cend(), i2 = V.cend(); + // expected-note@-1{{Iterator decremented by 1}} + // expected-note@-2{{Iterator decremented by 1}} clang_analyzer_denote(clang_analyzer_container_begin(V), "$V.begin()"); clang_analyzer_denote(clang_analyzer_container_end(V), "$V.end()"); @@ -1240,11 +1571,16 @@ auto i3 = V.emplace(i2, n); clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{TRUE}} + //expected-note@-1{{TRUE}} clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{TRUE}} + //expected-note@-1{{TRUE}} clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{FALSE}} + //expected-note@-1{{FALSE}} clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning{{$V.begin()}} + // expected-note@-1{{$V.begin()}} clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning{{$V.end() - 1}} FIXME: Should be $V.end() - 2 + // expected-note@-1{{$V.end() - 1}} FIXME: Should be $V.end() - 2 // clang_analyzer_express(clang_analyzer_iterator_position(i3)); FIXME: expect warning $V.end() - 1 } @@ -1260,12 +1596,15 @@ auto i2 = D.emplace(i0, n); clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{FALSE}} + //expected-note@-1{{FALSE}} clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{FALSE}} + //expected-note@-1{{FALSE}} // clang_analyzer_express(clang_analyzer_iterator_position(i2)); FIXME: expect warning $D.begin() - 1 } void deque_emplace_behind_begin(std::deque &D, int n) { auto i0 = D.cbegin(), i1 = ++D.cbegin(), i2 = D.cend(); + // expected-note@-1{{Iterator incremented by 1}} clang_analyzer_denote(clang_analyzer_container_begin(D), "$D.begin()"); clang_analyzer_denote(clang_analyzer_container_end(D), "$D.end()"); @@ -1273,8 +1612,11 @@ auto i3 = D.emplace(i1, n); clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{FALSE}} + //expected-note@-1{{FALSE}} clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{FALSE}} + //expected-note@-1{{FALSE}} clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{FALSE}} + //expected-note@-1{{FALSE}} // clang_analyzer_express(clang_analyzer_iterator_position(i3)); FIXME: expect warning $D.begin() - 1 } @@ -1288,14 +1630,18 @@ auto i3 = D.emplace(i1, n); clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{FALSE}} + //expected-note@-1{{FALSE}} clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{FALSE}} + //expected-note@-1{{FALSE}} clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{FALSE}} + //expected-note@-1{{FALSE}} // clang_analyzer_express(clang_analyzer_iterator_position(i3)); FIXME: expect warning $i1 - 1 } void deque_emplace_ahead_of_end(std::deque &D, int n) { auto i0 = D.cbegin(), i1 = --D.cend(), i2 = D.cend(); + // expected-note@-1{{Iterator decremented by 1}} clang_analyzer_denote(clang_analyzer_container_begin(D), "$D.begin()"); clang_analyzer_denote(clang_analyzer_container_end(D), "$D.end()"); @@ -1303,14 +1649,18 @@ auto i3 = D.emplace(i1, n); clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{FALSE}} + //expected-note@-1{{FALSE}} clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{FALSE}} + //expected-note@-1{{FALSE}} clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{FALSE}} + //expected-note@-1{{FALSE}} // clang_analyzer_express(clang_analyzer_iterator_position(i3)); FIXME: expect warning $D.end() - 2 } void deque_emplace_end(std::deque &D, int n) { auto i0 = D.cbegin(), i1 = --D.cend(), i2 = D.cend(); + // expected-note@-1{{Iterator decremented by 1}} clang_analyzer_denote(clang_analyzer_container_begin(D), "$D.begin()"); clang_analyzer_denote(clang_analyzer_container_end(D), "$D.end()"); @@ -1318,8 +1668,11 @@ auto i3 = D.emplace(i2, n); clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{FALSE}} + //expected-note@-1{{FALSE}} clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{FALSE}} + //expected-note@-1{{FALSE}} clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{FALSE}} + //expected-note@-1{{FALSE}} // clang_analyzer_express(clang_analyzer_iterator_position(i3)); FIXME: expect warning $D.end() - 1 } @@ -1343,16 +1696,22 @@ auto i2 = FL.emplace_after(i0, n); clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{TRUE}} + //expected-note@-1{{TRUE}} clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{TRUE}} + //expected-note@-1{{TRUE}} clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning{{$FL.begin()}} + // expected-note@-1{{$FL.begin()}} // clang_analyzer_express(clang_analyzer_iterator_position(i2)); FIXME: expect warning $FL.begin() + 1 clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning{{$FL.end()}} + // expected-note@-1{{$FL.end()}} } void forward_list_emplace_after_behind_begin(std::forward_list &FL, int n) { auto i0 = FL.cbegin(), i1 = ++FL.cbegin(), i2 = FL.cend(); + // expected-note@-1{{Iterator incremented by 1}} + // expected-note@-2{{Iterator incremented by 1}} clang_analyzer_denote(clang_analyzer_container_begin(FL), "$FL.begin()"); clang_analyzer_denote(clang_analyzer_container_end(FL), "$FL.end()"); @@ -1360,13 +1719,19 @@ auto i3 = FL.emplace_after(i1, n); clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{TRUE}} + //expected-note@-1{{TRUE}} clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{TRUE}} + //expected-note@-1{{TRUE}} clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{TRUE}} + //expected-note@-1{{TRUE}} clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning{{$FL.begin()}} + // expected-note@-1{{$FL.begin()}} clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning{{$FL.begin() + 1}} + // expected-note@-1{{$FL.begin() + 1}} // clang_analyzer_express(clang_analyzer_iterator_position(i3)); FIXME: expect warning $FL.begin() + 2 clang_analyzer_express(clang_analyzer_iterator_position(i2)); // expected-warning{{$FL.end()}} + // expected-note@-1{{$FL.end()}} } void forward_list_emplace_after_unknown(std::forward_list &FL, int n) { @@ -1379,13 +1744,19 @@ auto i3 = FL.emplace_after(i1, n); clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{TRUE}} + //expected-note@-1{{TRUE}} clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{TRUE}} + //expected-note@-1{{TRUE}} clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{TRUE}} + //expected-note@-1{{TRUE}} clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning{{$FL.begin()}} + // expected-note@-1{{$FL.begin()}} clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning{{$i1}} + // expected-note@-1{{$i1}} // clang_analyzer_express(clang_analyzer_iterator_position(i3)); FIXME: expect warning $i1 + 1 clang_analyzer_express(clang_analyzer_iterator_position(i2)); // expected-warning{{$FL.end()}} + // expected-note@-1{{$FL.end()}} } /// erase() @@ -1403,6 +1774,8 @@ void list_erase_begin(std::list &L) { auto i0 = L.cbegin(), i1 = ++L.cbegin(), i2 = L.cend(); + // expected-note@-1{{Iterator incremented by 1}} + // expected-note@-2{{Iterator incremented by 1}} clang_analyzer_denote(clang_analyzer_container_begin(L), "$L.begin()"); clang_analyzer_denote(clang_analyzer_container_end(L), "$L.end()"); @@ -1410,16 +1783,22 @@ auto i3 = L.erase(i0); clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{FALSE}} + //expected-note@-1{{FALSE}} clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{TRUE}} + //expected-note@-1{{TRUE}} clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{TRUE}} + //expected-note@-1{{TRUE}} clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning{{$L.begin() + 1}} + // expected-note@-1{{$L.begin() + 1}} // clang_analyzer_express(clang_analyzer_iterator_position(i3)); FIXME: expect warning $L.begin() + 1 clang_analyzer_express(clang_analyzer_iterator_position(i2)); // expected-warning{{$L.end()}} + // expected-note@-1{{$L.end()}} } void list_erase_behind_begin(std::list &L, int n) { auto i0 = L.cbegin(), i1 = ++L.cbegin(), i2 = L.cend(); + // expected-note@-1{{Iterator incremented by 1}} clang_analyzer_denote(clang_analyzer_container_begin(L), "$L.begin()"); clang_analyzer_denote(clang_analyzer_container_end(L), "$L.end()"); @@ -1427,12 +1806,17 @@ auto i3 = L.erase(i1); clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{TRUE}} + //expected-note@-1{{TRUE}} clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{FALSE}} + //expected-note@-1{{FALSE}} clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{TRUE}} + //expected-note@-1{{TRUE}} clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning{{$L.begin()}} FIXME: Should be $L.begin() + 1 + // expected-note@-1{{$L.begin()}} FIXME: Should be $L.begin() + 1 // clang_analyzer_express(clang_analyzer_iterator_position(i3)); FIXME: expect warning $L.begin() + 2 clang_analyzer_express(clang_analyzer_iterator_position(i2)); // expected-warning{{$L.end()}} + // expected-note@-1{{$L.end()}} } void list_erase_unknown(std::list &L) { @@ -1445,16 +1829,22 @@ auto i3 = L.erase(i1); clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{TRUE}} + //expected-note@-1{{TRUE}} clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{FALSE}} + //expected-note@-1{{FALSE}} clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{TRUE}} + //expected-note@-1{{TRUE}} clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning{{$L.begin()}} + // expected-note@-1{{$L.begin()}} // clang_analyzer_express(clang_analyzer_iterator_position(i3)); FIXME: expect warning $i1 + 1 clang_analyzer_express(clang_analyzer_iterator_position(i2)); // expected-warning{{$L.end()}} + // expected-note@-1{{$L.end()}} } void list_erase_ahead_of_end(std::list &L) { auto i0 = L.cbegin(), i1 = --L.cend(), i2 = L.cend(); + // expected-note@-1{{Iterator decremented by 1}} clang_analyzer_denote(clang_analyzer_container_begin(L), "$L.begin()"); clang_analyzer_denote(clang_analyzer_container_end(L), "$L.end()"); @@ -1462,11 +1852,16 @@ auto i3 = L.erase(i1); clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{TRUE}} + //expected-note@-1{{TRUE}} clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{FALSE}} + //expected-note@-1{{FALSE}} clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{TRUE}} + //expected-note@-1{{TRUE}} clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning{{$L.begin()}} + // expected-note@-1{{$L.begin()}} clang_analyzer_express(clang_analyzer_iterator_position(i2)); // expected-warning{{$L.end()}} + // expected-note@-1{{$L.end()}} // clang_analyzer_express(clang_analyzer_iterator_position(i3)); FIXME: expect warning $L.end() } @@ -1475,6 +1870,7 @@ void vector_erase_begin(std::vector &V) { auto i0 = V.cbegin(), i1 = ++V.cbegin(), i2 = V.cend(); + // expected-note@-1{{Iterator incremented by 1}} clang_analyzer_denote(clang_analyzer_container_begin(V), "$V.begin()"); clang_analyzer_denote(clang_analyzer_container_end(V), "$V.end()"); @@ -1482,14 +1878,18 @@ auto i3 = V.erase(i0); clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{FALSE}} + //expected-note@-1{{FALSE}} clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{FALSE}} + //expected-note@-1{{FALSE}} clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{FALSE}} + //expected-note@-1{{FALSE}} // clang_analyzer_express(clang_analyzer_iterator_position(i3)); FIXME: expect warning $V.begin() + 1 } void vector_erase_behind_begin(std::vector &V, int n) { auto i0 = V.cbegin(), i1 = ++V.cbegin(), i2 = V.cend(); + // expected-note@-1{{Iterator incremented by 1}} clang_analyzer_denote(clang_analyzer_container_begin(V), "$V.begin()"); clang_analyzer_denote(clang_analyzer_container_end(V), "$V.end()"); @@ -1497,10 +1897,14 @@ auto i3 = V.erase(i1); clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{TRUE}} + //expected-note@-1{{TRUE}} clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{FALSE}} + //expected-note@-1{{FALSE}} clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{FALSE}} + //expected-note@-1{{FALSE}} clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning{{$V.begin()}} FIXME: Should be $V.begin() + 1 + // expected-note@-1{{$V.begin()}} FIXME: Should be $V.begin() + 1 // clang_analyzer_express(clang_analyzer_iterator_position(i3)); FIXME: expect warning $V.begin() + 2 } @@ -1514,15 +1918,20 @@ auto i3 = V.erase(i1); clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{TRUE}} + //expected-note@-1{{TRUE}} clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{FALSE}} + //expected-note@-1{{FALSE}} clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{FALSE}} + //expected-note@-1{{FALSE}} clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning{{$V.begin()}} + // expected-note@-1{{$V.begin()}} // clang_analyzer_express(clang_analyzer_iterator_position(i3)); FIXME: expect warning $i1 + 1 } void vector_erase_ahead_of_end(std::vector &V) { auto i0 = V.cbegin(), i1 = --V.cend(), i2 = V.cend(); + // expected-note@-1{{Iterator decremented by 1}} clang_analyzer_denote(clang_analyzer_container_begin(V), "$V.begin()"); clang_analyzer_denote(clang_analyzer_container_end(V), "$V.end()"); @@ -1530,10 +1939,14 @@ auto i3 = V.erase(i1); clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{TRUE}} + //expected-note@-1{{TRUE}} clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{FALSE}} + //expected-note@-1{{FALSE}} clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{FALSE}} + //expected-note@-1{{FALSE}} clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning{{$V.begin()}} + // expected-note@-1{{$V.begin()}} // clang_analyzer_express(clang_analyzer_iterator_position(i3)); FIXME: expect warning $V.end() } @@ -1547,6 +1960,7 @@ void deque_erase_begin(std::deque &D) { auto i0 = D.cbegin(), i1 = ++D.cbegin(), i2 = D.cend(); + // expected-note@-1{{Iterator incremented by 1}} clang_analyzer_denote(clang_analyzer_container_begin(D), "$D.begin()"); clang_analyzer_denote(clang_analyzer_container_end(D), "$D.end()"); @@ -1554,14 +1968,18 @@ auto i3 = D.erase(i0); clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{FALSE}} + //expected-note@-1{{FALSE}} clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{FALSE}} + //expected-note@-1{{FALSE}} clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{FALSE}} + //expected-note@-1{{FALSE}} // clang_analyzer_express(clang_analyzer_iterator_position(i3)); FIXME: expect warning $D.begin() + 1 } void deque_erase_behind_begin(std::deque &D, int n) { auto i0 = D.cbegin(), i1 = ++D.cbegin(), i2 = D.cend(); + // expected-note@-1{{Iterator incremented by 1}} clang_analyzer_denote(clang_analyzer_container_begin(D), "$D.begin()"); clang_analyzer_denote(clang_analyzer_container_end(D), "$D.end()"); @@ -1569,8 +1987,11 @@ auto i3 = D.erase(i1); clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{FALSE}} + //expected-note@-1{{FALSE}} clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{FALSE}} + //expected-note@-1{{FALSE}} clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{FALSE}} + //expected-note@-1{{FALSE}} // clang_analyzer_express(clang_analyzer_iterator_position(i3)); FIXME: expect warning $D.begin() + 2 } @@ -1585,14 +2006,18 @@ auto i3 = D.erase(i1); clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{FALSE}} + //expected-note@-1{{FALSE}} clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{FALSE}} + //expected-note@-1{{FALSE}} clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{FALSE}} + //expected-note@-1{{FALSE}} // clang_analyzer_express(clang_analyzer_iterator_position(i3)); FIXME: expect warning $i1 + 1 } void deque_erase_ahead_of_end(std::deque &D) { auto i0 = D.cbegin(), i1 = --D.cend(), i2 = D.cend(); + // expected-note@-1{{Iterator decremented by 1}} clang_analyzer_denote(clang_analyzer_container_begin(D), "$D.begin()"); clang_analyzer_denote(clang_analyzer_container_end(D), "$D.end()"); @@ -1600,8 +2025,11 @@ auto i3 = D.erase(i1); clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{FALSE}} + //expected-note@-1{{FALSE}} clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{FALSE}} + //expected-note@-1{{FALSE}} clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{FALSE}} + //expected-note@-1{{FALSE}} // clang_analyzer_express(clang_analyzer_iterator_position(i3)); FIXME: expect warning $D.end() } @@ -1621,7 +2049,12 @@ void forward_list_erase_after_begin(std::forward_list &FL) { auto i0 = FL.cbegin(), i1 = ++FL.cbegin(), i2 = i1, i3 = FL.cend(); + // expected-note@-1{{Iterator incremented by 1}} + // expected-note@-2{{Iterator incremented by 1}} + // expected-note@-3{{Iterator incremented by 1}} ++i2; + // expected-note@-1{{Iterator 'i2' incremented by 1}} + // expected-note@-2{{Iterator 'i2' incremented by 1}} clang_analyzer_denote(clang_analyzer_container_begin(FL), "$FL.begin()"); clang_analyzer_denote(clang_analyzer_container_end(FL), "$FL.end()"); @@ -1629,22 +2062,34 @@ auto i4 = FL.erase_after(i0); clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{TRUE}} + //expected-note@-1{{TRUE}} clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{FALSE}} + //expected-note@-1{{FALSE}} clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{TRUE}} + //expected-note@-1{{TRUE}} clang_analyzer_eval(clang_analyzer_iterator_validity(i3)); //expected-warning{{TRUE}} + //expected-note@-1{{TRUE}} clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning{{$FL.begin()}} + // expected-note@-1{{$FL.begin()}} clang_analyzer_express(clang_analyzer_iterator_position(i2)); // expected-warning{{$FL.begin() + 2}} FIXME: Should be $FL.begin() + 1 + // expected-note@-1{{$FL.begin() + 2}} FIXME: Should be $FL.begin() + 1 // clang_analyzer_express(clang_analyzer_iterator_position(i4)); FIXME: expect warning $FL.begin() + 1 clang_analyzer_express(clang_analyzer_iterator_position(i3)); // expected-warning{{$FL.end()}} + // expected-note@-1{{$FL.end()}} } void forward_list_erase_after_unknown(std::forward_list &FL) { auto i0 = FL.cbegin(), i1 = return_any_iterator(FL.cbegin()), i2 = i1, i3 = i1, i4 = FL.cend(); ++i2; + // expected-note@-1{{Iterator 'i2' incremented by 1}} ++i3; + // expected-note@-1{{Iterator 'i3' incremented by 1}} + // expected-note@-2{{Iterator 'i3' incremented by 1}} ++i3; + // expected-note@-1{{Iterator 'i3' incremented by 1}} + // expected-note@-2{{Iterator 'i3' incremented by 1}} clang_analyzer_denote(clang_analyzer_container_begin(FL), "$FL.begin()"); clang_analyzer_denote(clang_analyzer_container_end(FL), "$FL.end()"); @@ -1653,16 +2098,25 @@ auto i5 = FL.erase_after(i1); clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{TRUE}} + //expected-note@-1{{TRUE}} clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{TRUE}} + //expected-note@-1{{TRUE}} clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{FALSE}} + //expected-note@-1{{FALSE}} clang_analyzer_eval(clang_analyzer_iterator_validity(i3)); //expected-warning{{TRUE}} + //expected-note@-1{{TRUE}} clang_analyzer_eval(clang_analyzer_iterator_validity(i4)); //expected-warning{{TRUE}} + //expected-note@-1{{TRUE}} clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning{{$FL.begin()}} + // expected-note@-1{{$FL.begin()}} clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning{{$i1}} + // expected-note@-1{{$i1}} clang_analyzer_express(clang_analyzer_iterator_position(i3)); // expected-warning{{$i1 + 2}} FIXME: Should be $i1 + 1 + // expected-note@-1{{$i1 + 2}} FIXME: Should be $i1 + 1 // clang_analyzer_express(clang_analyzer_iterator_position(i5)); FIXME: expect warning $i1 + 1 clang_analyzer_express(clang_analyzer_iterator_position(i4)); // expected-warning{{$FL.end()}} + // expected-note@-1{{$FL.end()}} } struct simple_iterator_base { @@ -1710,21 +2164,24 @@ void deferred_assumption(std::vector &V, int e) { const auto first = V.begin(); const auto comp1 = (first != V.end()), comp2 = (first == V.end()); - if (comp1) { + if (comp1) { // expected-note{{'comp1' is true}} + // expected-note@-1{{Taking true branch}} clang_analyzer_eval(clang_analyzer_container_end(V) == clang_analyzer_iterator_position(first)); // expected-warning@-1{{FALSE}} + // expected-note@-2{{FALSE}} } } void loop(std::vector &V, int e) { auto start = V.begin(); - while (true) { + while (true) { // expected-note{{Loop condition is true. Entering loop body}} auto item = std::find(start, V.end(), e); - if (item == V.end()) + if (item == V.end()) // expected-note{{Taking false branch}} break; clang_analyzer_eval(clang_analyzer_container_end(V) == clang_analyzer_iterator_position(item)); // expected-warning@-1{{FALSE}} + // expected-note@-2{{FALSE}} } } @@ -1743,12 +2200,47 @@ auto first = nonStdFind(V.begin(), V.end(), e); clang_analyzer_eval(clang_analyzer_container_end(V) == clang_analyzer_iterator_position(first)); // expected-warning@-1{{FALSE}} expected-warning@-1{{TRUE}} - if (V.end() != first) { + // expected-note@-2{{FALSE}} expected-note@-2{{TRUE}} + // expected-note@-3{{Assuming the condition is false}} + // expected-note@-4{{Assuming the condition is false}} + // expected-note@-5{{Assuming the condition is true}} + if (V.end() != first) { // expected-note{{Taking true branch}} + clang_analyzer_eval(clang_analyzer_container_end(V) == clang_analyzer_iterator_position(first)); // expected-warning@-1{{FALSE}} + // expected-note@-2{{FALSE}} } } +/// Track the right iterators only + +void prefix_increment2(const std::vector &v) { + auto i = v.begin(), j = v.begin(); + + clang_analyzer_denote(clang_analyzer_container_begin(v), "$v.begin()"); + + auto k = ++j; // expected-note{{Iterator 'j' incremented by 1}} + + clang_analyzer_express(clang_analyzer_iterator_position(i)); //expected-warning{{$v.begin()}} + //expected-note@-1{{$v.begin()}} + + clang_analyzer_express(clang_analyzer_iterator_position(k)); //expected-warning{{$v.begin() + 1}} + //expected-note@-1{{$v.begin() + 1}} +} + +void prefix_increment3(const std::vector &v) { + auto i = v.begin(), j = v.begin(); + + clang_analyzer_denote(clang_analyzer_container_begin(v), "$v.begin()"); + + auto k = ++j; // no note expected + + clang_analyzer_express(clang_analyzer_iterator_position(i)); //expected-warning{{$v.begin()}} + //expected-note@-1{{$v.begin()}} +} + +/// Print State + void clang_analyzer_printState(); void print_state(std::vector &V) { Index: clang/test/Analysis/iterator-range.cpp =================================================================== --- clang/test/Analysis/iterator-range.cpp +++ clang/test/Analysis/iterator-range.cpp @@ -1,5 +1,5 @@ -// RUN: %clang_analyze_cc1 -std=c++11 -analyzer-checker=core,cplusplus,alpha.cplusplus.IteratorRange -analyzer-config aggressive-binary-operation-simplification=true -analyzer-config c++-container-inlining=false %s -verify -// RUN: %clang_analyze_cc1 -std=c++11 -analyzer-checker=core,cplusplus,alpha.cplusplus.IteratorRange -analyzer-config aggressive-binary-operation-simplification=true -analyzer-config c++-container-inlining=true -DINLINE=1 %s -verify +// RUN: %clang_analyze_cc1 -std=c++11 -analyzer-checker=core,cplusplus,alpha.cplusplus.IteratorRange -analyzer-config aggressive-binary-operation-simplification=true -analyzer-config c++-container-inlining=false -analyzer-output=text %s -verify +// RUN: %clang_analyze_cc1 -std=c++11 -analyzer-checker=core,cplusplus,alpha.cplusplus.IteratorRange -analyzer-config aggressive-binary-operation-simplification=true -analyzer-config c++-container-inlining=true -DINLINE=1 -analyzer-output=text %s -verify #include "Inputs/system-header-simulator-cxx.h" @@ -32,6 +32,7 @@ void deref_end(const std::vector &V) { auto i = V.end(); *i; // expected-warning{{Past-the-end iterator dereferenced}} + // expected-note@-1{{Past-the-end iterator dereferenced}} } // Prefix increment - operator++() @@ -59,6 +60,7 @@ void incr_end(const std::vector &V) { auto i = V.end(); ++i; // expected-warning{{Iterator incremented behind the past-the-end iterator}} + // expected-note@-1{{Iterator incremented behind the past-the-end iterator}} } // Postfix increment - operator++(int) @@ -86,6 +88,7 @@ void end_incr(const std::vector &V) { auto i = V.end(); i++; // expected-warning{{Iterator incremented behind the past-the-end iterator}} + // expected-note@-1{{Iterator incremented behind the past-the-end iterator}} } // Prefix decrement - operator--() @@ -93,6 +96,7 @@ void decr_begin(const std::vector &V) { auto i = V.begin(); --i; // expected-warning{{Iterator decremented ahead of its valid range}} + // expected-note@-1{{Iterator decremented ahead of its valid range}} } void decr_behind_begin(const std::vector &V) { @@ -120,6 +124,7 @@ void begin_decr(const std::vector &V) { auto i = V.begin(); i--; // expected-warning{{Iterator decremented ahead of its valid range}} + // expected-note@-1{{Iterator decremented ahead of its valid range}} } void behind_begin_decr(const std::vector &V) { @@ -166,13 +171,15 @@ } void incr_by_2_ahead_of_end(const std::vector &V) { - auto i = --V.end(); + auto i = --V.end(); // expected-note{{Iterator decremented by 1}} i += 2; // expected-warning{{Iterator incremented behind the past-the-end iterator}} + // expected-note@-1{{Iterator incremented behind the past-the-end iterator}} } void incr_by_2_end(const std::vector &V) { auto i = V.end(); i += 2; // expected-warning{{Iterator incremented behind the past-the-end iterator}} + // expected-note@-1{{Iterator incremented behind the past-the-end iterator}} } // Addition - operator+(int) @@ -199,13 +206,15 @@ } void incr_by_2_copy_ahead_of_end(const std::vector &V) { - auto i = --V.end(); + auto i = --V.end(); // expected-note{{Iterator decremented by 1}} auto j = i + 2; // expected-warning{{Iterator incremented behind the past-the-end iterator}} + // expected-note@-1{{Iterator incremented behind the past-the-end iterator}} } void incr_by_2_copy_end(const std::vector &V) { auto i = V.end(); auto j = i + 2; // expected-warning{{Iterator incremented behind the past-the-end iterator}} + // expected-note@-1{{Iterator incremented behind the past-the-end iterator}} } // Subtraction assignment - operator-=(int) @@ -213,11 +222,13 @@ void decr_by_2_begin(const std::vector &V) { auto i = V.begin(); i -= 2; // expected-warning{{Iterator decremented ahead of its valid range}} + // expected-note@-1{{Iterator decremented ahead of its valid range}} } void decr_by_2_behind_begin(const std::vector &V) { - auto i = ++V.begin(); + auto i = ++V.begin(); // expected-note{{Iterator incremented by 1}} i -= 2; // expected-warning{{Iterator decremented ahead of its valid range}} + // expected-note@-1{{Iterator decremented ahead of its valid range}} } void decr_by_2_behind_begin_by_2(const std::vector &V) { @@ -246,11 +257,13 @@ void decr_by_2_copy_begin(const std::vector &V) { auto i = V.begin(); auto j = i - 2; // expected-warning{{Iterator decremented ahead of its valid range}} + // expected-note@-1{{Iterator decremented ahead of its valid range}} } void decr_by_2_copy_behind_begin(const std::vector &V) { - auto i = ++V.begin(); + auto i = ++V.begin(); // expected-note{{Iterator incremented by 1}} auto j = i - 2; // expected-warning{{Iterator decremented ahead of its valid range}} + // expected-note@-1{{Iterator decremented ahead of its valid range}} } void decr_by_2_copy_behind_begin_by_2(const std::vector &V) { @@ -303,6 +316,7 @@ void subscript_zero_end(const std::vector &V) { auto i = V.end(); auto j = i[0]; // expected-warning{{Past-the-end iterator dereferenced}} + // expected-note@-1{{Past-the-end iterator dereferenced}} } // By negative number @@ -329,7 +343,8 @@ void subscript_negative_end(const std::vector &V) { auto i = V.end(); - auto j = i[-1]; // // expected-warning{{Past-the-end iterator dereferenced}} FIXME: expect no warning + auto j = i[-1]; // expected-warning{{Past-the-end iterator dereferenced}} FIXME: expect no warning + // expected-note@-1{{Past-the-end iterator dereferenced}} } // By positive number @@ -357,6 +372,7 @@ void subscript_positive_end(const std::vector &V) { auto i = V.end(); auto j = i[1]; // expected-warning{{Past-the-end iterator dereferenced}} FIXME: expect warning Iterator incremented behind the past-the-end iterator + // expected-note@-1{{Past-the-end iterator dereferenced}} FIXME: expect note@-1 Iterator incremented behind the past-the-end iterator } // @@ -376,5 +392,15 @@ void arrow_deref_end(const std::vector &V) { auto i = V.end(); - int n = i->n; // expected-warning{{Past-the-end iterator dereferenced}} + int n = i->n; // expected-warning{{Past-the-end iterator dereferenced}} + // expected-note@-1{{Past-the-end iterator dereferenced}} +} + +// Path notes + +void deref_end2(const std::vector &V) { + auto i = --V.end(); // expected-note{{Iterator decremented by 1}} + ++i; // expected-note{{Iterator 'i' incremented by 1}} + *i; // expected-warning{{Past-the-end iterator dereferenced}} + // expected-note@-1{{Past-the-end iterator dereferenced}} }