typedef SmallVector<std::unique_ptr<BugReporterVisitor>, 8> VisitorList;
typedef VisitorList::iterator visitor_iterator;
typedef SmallVector<StringRef, 2> ExtraTextList;
- typedef SmallVector<llvm::IntrusiveRefCntPtr<PathDiagnosticNotePiece>, 4>
- NoteList;
+ typedef SmallVector<std::shared_ptr<PathDiagnosticNotePiece>, 4> NoteList;
protected:
friend class BugReporter;
/// the extra note should appear.
void addNote(StringRef Msg, const PathDiagnosticLocation &Pos,
ArrayRef<SourceRange> Ranges) {
- PathDiagnosticNotePiece *P = new PathDiagnosticNotePiece(Pos, Msg);
+ auto P = std::make_shared<PathDiagnosticNotePiece>(Pos, Msg);
for (const auto &R : Ranges)
P->addRange(R);
- Notes.push_back(P);
+ Notes.push_back(std::move(P));
}
// FIXME: Instead of making an override, we could have default-initialized
///
/// The last parameter can be used to register a new visitor with the given
/// BugReport while processing a node.
- virtual PathDiagnosticPiece *VisitNode(const ExplodedNode *Succ,
- const ExplodedNode *Pred,
- BugReporterContext &BRC,
- BugReport &BR) = 0;
+ virtual std::shared_ptr<PathDiagnosticPiece>
+ VisitNode(const ExplodedNode *Succ, const ExplodedNode *Pred,
+ BugReporterContext &BRC, BugReport &BR) = 0;
/// \brief Provide custom definition for the final diagnostic piece on the
/// path - the piece, which is displayed before the path is expanded.
void Profile(llvm::FoldingSetNodeID &ID) const override;
- PathDiagnosticPiece *VisitNode(const ExplodedNode *N,
- const ExplodedNode *PrevN,
- BugReporterContext &BRC,
- BugReport &BR) override;
+ std::shared_ptr<PathDiagnosticPiece> VisitNode(const ExplodedNode *N,
+ const ExplodedNode *PrevN,
+ BugReporterContext &BRC,
+ BugReport &BR) override;
};
class TrackConstraintBRVisitor final
/// to make all PathDiagnosticPieces created by this visitor.
static const char *getTag();
- PathDiagnosticPiece *VisitNode(const ExplodedNode *N,
- const ExplodedNode *PrevN,
- BugReporterContext &BRC,
- BugReport &BR) override;
+ std::shared_ptr<PathDiagnosticPiece> VisitNode(const ExplodedNode *N,
+ const ExplodedNode *PrevN,
+ BugReporterContext &BRC,
+ BugReport &BR) override;
private:
/// Checks if the constraint is valid in the current state.
ID.AddPointer(&x);
}
- PathDiagnosticPiece *VisitNode(const ExplodedNode *N,
- const ExplodedNode *PrevN,
- BugReporterContext &BRC,
- BugReport &BR) override;
+ std::shared_ptr<PathDiagnosticPiece> VisitNode(const ExplodedNode *N,
+ const ExplodedNode *PrevN,
+ BugReporterContext &BRC,
+ BugReport &BR) override;
/// If the statement is a message send expression with nil receiver, returns
/// the receiver expression. Returns NULL otherwise.
/// to make all PathDiagnosticPieces created by this visitor.
static const char *getTag();
- PathDiagnosticPiece *VisitNode(const ExplodedNode *N,
- const ExplodedNode *Prev,
- BugReporterContext &BRC,
- BugReport &BR) override;
+ std::shared_ptr<PathDiagnosticPiece> VisitNode(const ExplodedNode *N,
+ const ExplodedNode *Prev,
+ BugReporterContext &BRC,
+ BugReport &BR) override;
- PathDiagnosticPiece *VisitNodeImpl(const ExplodedNode *N,
- const ExplodedNode *Prev,
- BugReporterContext &BRC,
- BugReport &BR);
-
- PathDiagnosticPiece *VisitTerminator(const Stmt *Term,
- const ExplodedNode *N,
- const CFGBlock *srcBlk,
- const CFGBlock *dstBlk,
- BugReport &R,
- BugReporterContext &BRC);
-
- PathDiagnosticPiece *VisitTrueTest(const Expr *Cond,
- bool tookTrue,
- BugReporterContext &BRC,
- BugReport &R,
- const ExplodedNode *N);
-
- PathDiagnosticPiece *VisitTrueTest(const Expr *Cond,
- const DeclRefExpr *DR,
- const bool tookTrue,
- BugReporterContext &BRC,
- BugReport &R,
- const ExplodedNode *N);
-
- PathDiagnosticPiece *VisitTrueTest(const Expr *Cond,
- const BinaryOperator *BExpr,
- const bool tookTrue,
- BugReporterContext &BRC,
- BugReport &R,
- const ExplodedNode *N);
-
- PathDiagnosticPiece *VisitConditionVariable(StringRef LhsString,
- const Expr *CondVarExpr,
- const bool tookTrue,
- BugReporterContext &BRC,
- BugReport &R,
- const ExplodedNode *N);
+ std::shared_ptr<PathDiagnosticPiece> VisitNodeImpl(const ExplodedNode *N,
+ const ExplodedNode *Prev,
+ BugReporterContext &BRC,
+ BugReport &BR);
+
+ std::shared_ptr<PathDiagnosticPiece>
+ VisitTerminator(const Stmt *Term, const ExplodedNode *N,
+ const CFGBlock *srcBlk, const CFGBlock *dstBlk, BugReport &R,
+ BugReporterContext &BRC);
+
+ std::shared_ptr<PathDiagnosticPiece>
+ VisitTrueTest(const Expr *Cond, bool tookTrue, BugReporterContext &BRC,
+ BugReport &R, const ExplodedNode *N);
+
+ std::shared_ptr<PathDiagnosticPiece>
+ VisitTrueTest(const Expr *Cond, const DeclRefExpr *DR, const bool tookTrue,
+ BugReporterContext &BRC, BugReport &R, const ExplodedNode *N);
+
+ std::shared_ptr<PathDiagnosticPiece>
+ VisitTrueTest(const Expr *Cond, const BinaryOperator *BExpr,
+ const bool tookTrue, BugReporterContext &BRC, BugReport &R,
+ const ExplodedNode *N);
+
+ std::shared_ptr<PathDiagnosticPiece>
+ VisitConditionVariable(StringRef LhsString, const Expr *CondVarExpr,
+ const bool tookTrue, BugReporterContext &BRC,
+ BugReport &R, const ExplodedNode *N);
bool patternMatch(const Expr *Ex,
const Expr *ParentEx,
ID.AddPointer(getTag());
}
- PathDiagnosticPiece *VisitNode(const ExplodedNode *N,
- const ExplodedNode *Prev,
- BugReporterContext &BRC,
- BugReport &BR) override {
+ std::shared_ptr<PathDiagnosticPiece> VisitNode(const ExplodedNode *N,
+ const ExplodedNode *Prev,
+ BugReporterContext &BRC,
+ BugReport &BR) override {
return nullptr;
}
ID.AddPointer(R);
}
- PathDiagnosticPiece *VisitNode(const ExplodedNode *N,
- const ExplodedNode *PrevN,
- BugReporterContext &BRC,
- BugReport &BR) override;
+ std::shared_ptr<PathDiagnosticPiece> VisitNode(const ExplodedNode *N,
+ const ExplodedNode *PrevN,
+ BugReporterContext &BRC,
+ BugReport &BR) override;
};
class SuppressInlineDefensiveChecksVisitor final
/// to make all PathDiagnosticPieces created by this visitor.
static const char *getTag();
- PathDiagnosticPiece *VisitNode(const ExplodedNode *Succ,
- const ExplodedNode *Pred,
- BugReporterContext &BRC,
- BugReport &BR) override;
+ std::shared_ptr<PathDiagnosticPiece> VisitNode(const ExplodedNode *Succ,
+ const ExplodedNode *Pred,
+ BugReporterContext &BRC,
+ BugReport &BR) override;
};
class CXXSelfAssignmentBRVisitor final
void Profile(llvm::FoldingSetNodeID &ID) const override {}
- PathDiagnosticPiece *VisitNode(const ExplodedNode *Succ,
- const ExplodedNode *Pred,
- BugReporterContext &BRC,
- BugReport &BR) override;
+ std::shared_ptr<PathDiagnosticPiece> VisitNode(const ExplodedNode *Succ,
+ const ExplodedNode *Pred,
+ BugReporterContext &BRC,
+ BugReport &BR) override;
};
namespace bugreporter {
// Path "pieces" for path-sensitive diagnostics.
//===----------------------------------------------------------------------===//
-class PathDiagnosticPiece : public RefCountedBase<PathDiagnosticPiece> {
+class PathDiagnosticPiece {
public:
enum Kind { ControlFlow, Event, Macro, Call, Note };
enum DisplayHint { Above, Below };
virtual void dump() const = 0;
};
-
-
-class PathPieces : public std::list<IntrusiveRefCntPtr<PathDiagnosticPiece> > {
+
+class PathPieces : public std::list<std::shared_ptr<PathDiagnosticPiece>> {
void flattenTo(PathPieces &Primary, PathPieces &Current,
bool ShouldFlattenMacros) const;
public:
PathDiagnosticLocation getLocation() const override {
return callEnter;
}
-
- IntrusiveRefCntPtr<PathDiagnosticEventPiece> getCallEnterEvent() const;
- IntrusiveRefCntPtr<PathDiagnosticEventPiece>
- getCallEnterWithinCallerEvent() const;
- IntrusiveRefCntPtr<PathDiagnosticEventPiece> getCallExitEvent() const;
+
+ std::shared_ptr<PathDiagnosticEventPiece> getCallEnterEvent() const;
+ std::shared_ptr<PathDiagnosticEventPiece>
+ getCallEnterWithinCallerEvent() const;
+ std::shared_ptr<PathDiagnosticEventPiece> getCallExitEvent() const;
void flattenLocations() override {
callEnter.flatten();
for (PathPieces::iterator I = path.begin(),
E = path.end(); I != E; ++I) (*I)->flattenLocations();
}
-
- static PathDiagnosticCallPiece *construct(const ExplodedNode *N,
- const CallExitEnd &CE,
- const SourceManager &SM);
-
+
+ static std::shared_ptr<PathDiagnosticCallPiece>
+ construct(const ExplodedNode *N, const CallExitEnd &CE,
+ const SourceManager &SM);
+
static PathDiagnosticCallPiece *construct(PathPieces &pieces,
const Decl *caller);
assert(!Loc.isValid() && "End location already set!");
Loc = EndPiece->getLocation();
assert(Loc.isValid() && "Invalid location for end-of-path piece");
- getActivePath().push_back(EndPiece.release());
+ getActivePath().push_back(std::move(EndPiece));
}
void appendToDesc(StringRef S) {
ID.AddPointer(Reg);
}
- PathDiagnosticPiece *VisitNode(const ExplodedNode *N,
- const ExplodedNode *PrevN,
- BugReporterContext &BRC,
- BugReport &BR) override;
+ std::shared_ptr<PathDiagnosticPiece> VisitNode(const ExplodedNode *N,
+ const ExplodedNode *PrevN,
+ BugReporterContext &BRC,
+ BugReport &BR) override;
private:
// The tracked region.
C.emitReport(std::move(R));
}
-PathDiagnosticPiece *DynamicTypeChecker::DynamicTypeBugVisitor::VisitNode(
- const ExplodedNode *N, const ExplodedNode *PrevN, BugReporterContext &BRC,
- BugReport &BR) {
+std::shared_ptr<PathDiagnosticPiece>
+DynamicTypeChecker::DynamicTypeBugVisitor::VisitNode(const ExplodedNode *N,
+ const ExplodedNode *PrevN,
+ BugReporterContext &BRC,
+ BugReport &BR) {
ProgramStateRef State = N->getState();
ProgramStateRef StatePrev = PrevN->getState();
// Generate the extra diagnostic.
PathDiagnosticLocation Pos(S, BRC.getSourceManager(),
N->getLocationContext());
- return new PathDiagnosticEventPiece(Pos, OS.str(), true, nullptr);
+ return std::make_shared<PathDiagnosticEventPiece>(Pos, OS.str(), true,
+ nullptr);
}
static bool hasDefinition(const ObjCObjectPointerType *ObjPtr) {
ID.AddPointer(Sym);
}
- PathDiagnosticPiece *VisitNode(const ExplodedNode *N,
- const ExplodedNode *PrevN,
- BugReporterContext &BRC,
- BugReport &BR) override;
+ std::shared_ptr<PathDiagnosticPiece> VisitNode(const ExplodedNode *N,
+ const ExplodedNode *PrevN,
+ BugReporterContext &BRC,
+ BugReport &BR) override;
private:
// The tracked symbol.
C.emitReport(std::move(R));
}
-PathDiagnosticPiece *DynamicTypePropagation::GenericsBugVisitor::VisitNode(
- const ExplodedNode *N, const ExplodedNode *PrevN, BugReporterContext &BRC,
- BugReport &BR) {
+std::shared_ptr<PathDiagnosticPiece>
+DynamicTypePropagation::GenericsBugVisitor::VisitNode(const ExplodedNode *N,
+ const ExplodedNode *PrevN,
+ BugReporterContext &BRC,
+ BugReport &BR) {
ProgramStateRef state = N->getState();
ProgramStateRef statePrev = PrevN->getState();
// Generate the extra diagnostic.
PathDiagnosticLocation Pos(S, BRC.getSourceManager(),
N->getLocationContext());
- return new PathDiagnosticEventPiece(Pos, OS.str(), true, nullptr);
+ return std::make_shared<PathDiagnosticEventPiece>(Pos, OS.str(), true,
+ nullptr);
}
/// Register checkers.
assert(NonLocalizedString);
}
- PathDiagnosticPiece *VisitNode(const ExplodedNode *Succ,
- const ExplodedNode *Pred,
- BugReporterContext &BRC,
- BugReport &BR) override;
+ std::shared_ptr<PathDiagnosticPiece> VisitNode(const ExplodedNode *Succ,
+ const ExplodedNode *Pred,
+ BugReporterContext &BRC,
+ BugReport &BR) override;
void Profile(llvm::FoldingSetNodeID &ID) const override {
ID.Add(NonLocalizedString);
setNonLocalizedState(sv, C);
}
-PathDiagnosticPiece *
+std::shared_ptr<PathDiagnosticPiece>
NonLocalizedStringBRVisitor::VisitNode(const ExplodedNode *Succ,
const ExplodedNode *Pred,
BugReporterContext &BRC, BugReport &BR) {
if (!L.isValid() || !L.asLocation().isValid())
return nullptr;
- auto *Piece = new PathDiagnosticEventPiece(L,
- "Non-localized string literal here");
+ auto Piece = std::make_shared<PathDiagnosticEventPiece>(
+ L, "Non-localized string literal here");
Piece->addRange(LiteralExpr->getSourceRange());
- return Piece;
+ return std::move(Piece);
}
namespace {
BReporter.emitReport(std::move(Report));
}
-PathDiagnosticPiece *MPIBugReporter::RequestNodeVisitor::VisitNode(
- const ExplodedNode *N, const ExplodedNode *PrevN, BugReporterContext &BRC,
- BugReport &BR) {
+std::shared_ptr<PathDiagnosticPiece>
+MPIBugReporter::RequestNodeVisitor::VisitNode(const ExplodedNode *N,
+ const ExplodedNode *PrevN,
+ BugReporterContext &BRC,
+ BugReport &BR) {
if (IsNodeFound)
return nullptr;
PathDiagnosticLocation L =
PathDiagnosticLocation::create(P, BRC.getSourceManager());
- return new PathDiagnosticEventPiece(L, ErrorText);
+ return std::make_shared<PathDiagnosticEventPiece>(L, ErrorText);
}
return nullptr;
ID.AddPointer(RequestRegion);
}
- PathDiagnosticPiece *VisitNode(const ExplodedNode *N,
- const ExplodedNode *PrevN,
- BugReporterContext &BRC,
- BugReport &BR) override;
+ std::shared_ptr<PathDiagnosticPiece> VisitNode(const ExplodedNode *N,
+ const ExplodedNode *PrevN,
+ BugReporterContext &BRC,
+ BugReport &BR) override;
private:
const MemRegion *const RequestRegion;
ID.AddPointer(Sym);
}
- PathDiagnosticPiece *VisitNode(const ExplodedNode *N,
- const ExplodedNode *PrevN,
- BugReporterContext &BRC,
- BugReport &BR) override;
+ std::shared_ptr<PathDiagnosticPiece> VisitNode(const ExplodedNode *N,
+ const ExplodedNode *PrevN,
+ BugReporterContext &BRC,
+ BugReport &BR) override;
};
};
}
C.addTransition(State, N);
}
-
-PathDiagnosticPiece *MacOSKeychainAPIChecker::SecKeychainBugVisitor::VisitNode(
- const ExplodedNode *N,
- const ExplodedNode *PrevN,
- BugReporterContext &BRC,
- BugReport &BR) {
+std::shared_ptr<PathDiagnosticPiece>
+MacOSKeychainAPIChecker::SecKeychainBugVisitor::VisitNode(
+ const ExplodedNode *N, const ExplodedNode *PrevN, BugReporterContext &BRC,
+ BugReport &BR) {
const AllocationState *AS = N->getState()->get<AllocatedData>(Sym);
if (!AS)
return nullptr;
const Expr *ArgExpr = CE->getArg(FunctionsToTrack[Idx].Param);
PathDiagnosticLocation Pos(ArgExpr, BRC.getSourceManager(),
N->getLocationContext());
- return new PathDiagnosticEventPiece(Pos, "Data is allocated here.");
+ return std::make_shared<PathDiagnosticEventPiece>(Pos,
+ "Data is allocated here.");
}
void ento::registerMacOSKeychainAPIChecker(CheckerManager &mgr) {
SPrev->isAllocatedOfSizeZero())));
}
- PathDiagnosticPiece *VisitNode(const ExplodedNode *N,
- const ExplodedNode *PrevN,
- BugReporterContext &BRC,
- BugReport &BR) override;
+ std::shared_ptr<PathDiagnosticPiece> VisitNode(const ExplodedNode *N,
+ const ExplodedNode *PrevN,
+ BugReporterContext &BRC,
+ BugReport &BR) override;
std::unique_ptr<PathDiagnosticPiece>
getEndPath(BugReporterContext &BRC, const ExplodedNode *EndPathNode,
return nullptr;
}
-PathDiagnosticPiece *
-MallocChecker::MallocBugVisitor::VisitNode(const ExplodedNode *N,
- const ExplodedNode *PrevN,
- BugReporterContext &BRC,
- BugReport &BR) {
+std::shared_ptr<PathDiagnosticPiece> MallocChecker::MallocBugVisitor::VisitNode(
+ const ExplodedNode *N, const ExplodedNode *PrevN, BugReporterContext &BRC,
+ BugReport &BR) {
ProgramStateRef state = N->getState();
ProgramStateRef statePrev = PrevN->getState();
// Generate the extra diagnostic.
PathDiagnosticLocation Pos(S, BRC.getSourceManager(),
N->getLocationContext());
- return new PathDiagnosticEventPiece(Pos, Msg, true, StackHint);
+ return std::make_shared<PathDiagnosticEventPiece>(Pos, Msg, true, StackHint);
}
void MallocChecker::printState(raw_ostream &Out, ProgramStateRef State,
ID.AddPointer(Region);
}
- PathDiagnosticPiece *VisitNode(const ExplodedNode *N,
- const ExplodedNode *PrevN,
- BugReporterContext &BRC,
- BugReport &BR) override;
+ std::shared_ptr<PathDiagnosticPiece> VisitNode(const ExplodedNode *N,
+ const ExplodedNode *PrevN,
+ BugReporterContext &BRC,
+ BugReport &BR) override;
private:
// The tracked region.
return dyn_cast<SymbolicRegion>(Region);
}
-PathDiagnosticPiece *NullabilityChecker::NullabilityBugVisitor::VisitNode(
- const ExplodedNode *N, const ExplodedNode *PrevN, BugReporterContext &BRC,
- BugReport &BR) {
+std::shared_ptr<PathDiagnosticPiece>
+NullabilityChecker::NullabilityBugVisitor::VisitNode(const ExplodedNode *N,
+ const ExplodedNode *PrevN,
+ BugReporterContext &BRC,
+ BugReport &BR) {
ProgramStateRef State = N->getState();
ProgramStateRef StatePrev = PrevN->getState();
// Generate the extra diagnostic.
PathDiagnosticLocation Pos(S, BRC.getSourceManager(),
N->getLocationContext());
- return new PathDiagnosticEventPiece(Pos, InfoText, true, nullptr);
+ return std::make_shared<PathDiagnosticEventPiece>(Pos, InfoText, true,
+ nullptr);
}
static Nullability getNullabilityAnnotation(QualType Type) {
: ReceiverSymbol(ReceiverSymbol),
Satisfied(false) {}
- PathDiagnosticPiece *VisitNode(const ExplodedNode *Succ,
- const ExplodedNode *Pred,
- BugReporterContext &BRC,
- BugReport &BR) override;
+ std::shared_ptr<PathDiagnosticPiece> VisitNode(const ExplodedNode *Succ,
+ const ExplodedNode *Pred,
+ BugReporterContext &BRC,
+ BugReport &BR) override;
void Profile(llvm::FoldingSetNodeID &ID) const override {
ID.Add(ReceiverSymbol);
return M.getSelector() == SELdealloc;
}
-PathDiagnosticPiece *SuperDeallocBRVisitor::VisitNode(const ExplodedNode *Succ,
- const ExplodedNode *Pred,
- BugReporterContext &BRC,
- BugReport &BR) {
+std::shared_ptr<PathDiagnosticPiece>
+SuperDeallocBRVisitor::VisitNode(const ExplodedNode *Succ,
+ const ExplodedNode *Pred,
+ BugReporterContext &BRC, BugReport &BR) {
if (Satisfied)
return nullptr;
if (!L.isValid() || !L.asLocation().isValid())
return nullptr;
- return new PathDiagnosticEventPiece(
+ return std::make_shared<PathDiagnosticEventPiece>(
L, "[super dealloc] called here");
}
ID.AddPointer(Sym);
}
- PathDiagnosticPiece *VisitNode(const ExplodedNode *N,
- const ExplodedNode *PrevN,
- BugReporterContext &BRC,
- BugReport &BR) override;
+ std::shared_ptr<PathDiagnosticPiece> VisitNode(const ExplodedNode *N,
+ const ExplodedNode *PrevN,
+ BugReporterContext &BRC,
+ BugReport &BR) override;
std::unique_ptr<PathDiagnosticPiece> getEndPath(BugReporterContext &BRC,
const ExplodedNode *N,
return SFC->getAnalysisDeclContext()->isBodyAutosynthesized();
}
-PathDiagnosticPiece *CFRefReportVisitor::VisitNode(const ExplodedNode *N,
- const ExplodedNode *PrevN,
- BugReporterContext &BRC,
- BugReport &BR) {
+std::shared_ptr<PathDiagnosticPiece>
+CFRefReportVisitor::VisitNode(const ExplodedNode *N, const ExplodedNode *PrevN,
+ BugReporterContext &BRC, BugReport &BR) {
// FIXME: We will eventually need to handle non-statement-based events
// (__attribute__((cleanup))).
if (!N->getLocation().getAs<StmtPoint>())
PathDiagnosticLocation Pos(S, BRC.getSourceManager(),
N->getLocationContext());
- return new PathDiagnosticEventPiece(Pos, os.str());
+ return std::make_shared<PathDiagnosticEventPiece>(Pos, os.str());
}
// Gather up the effects that were performed on the object at this
const Stmt *S = N->getLocation().castAs<StmtPoint>().getStmt();
PathDiagnosticLocation Pos(S, BRC.getSourceManager(),
N->getLocationContext());
- PathDiagnosticPiece *P = new PathDiagnosticEventPiece(Pos, os.str());
+ auto P = std::make_shared<PathDiagnosticEventPiece>(Pos, os.str());
// Add the range by scanning the children of the statement for any bindings
// to Sym.
break;
}
- return P;
+ return std::move(P);
}
namespace {
ID.Add(SFC);
}
- PathDiagnosticPiece *VisitNode(const ExplodedNode *Succ,
- const ExplodedNode *Pred,
- BugReporterContext &BRC,
- BugReport &BR) override;
+ std::shared_ptr<PathDiagnosticPiece> VisitNode(const ExplodedNode *Succ,
+ const ExplodedNode *Pred,
+ BugReporterContext &BRC,
+ BugReport &BR) override;
};
class TestAfterDivZeroChecker
REGISTER_SET_WITH_PROGRAMSTATE(DivZeroMap, ZeroState)
-PathDiagnosticPiece *DivisionBRVisitor::VisitNode(const ExplodedNode *Succ,
- const ExplodedNode *Pred,
- BugReporterContext &BRC,
- BugReport &BR) {
+std::shared_ptr<PathDiagnosticPiece>
+DivisionBRVisitor::VisitNode(const ExplodedNode *Succ, const ExplodedNode *Pred,
+ BugReporterContext &BRC, BugReport &BR) {
if (Satisfied)
return nullptr;
if (!L.isValid() || !L.asLocation().isValid())
return nullptr;
- return new PathDiagnosticEventPiece(
+ return std::make_shared<PathDiagnosticEventPiece>(
L, "Division with compared value made here");
}
return llvm::make_unique<PathDiagnosticEventPiece>(L, BR.getDescription(),
false);
}
- PathDiagnosticPiece *VisitNode(const ExplodedNode *N,
- const ExplodedNode *PrevN,
- BugReporterContext &BRC,
- BugReport &BR) override;
+ std::shared_ptr<PathDiagnosticPiece> VisitNode(const ExplodedNode *N,
+ const ExplodedNode *PrevN,
+ BugReporterContext &BRC,
+ BugReport &BR) override;
private:
const MemRegion *Reg;
C.addTransition(State);
}
-PathDiagnosticPiece *ValistChecker::ValistBugVisitor::VisitNode(
+std::shared_ptr<PathDiagnosticPiece> ValistChecker::ValistBugVisitor::VisitNode(
const ExplodedNode *N, const ExplodedNode *PrevN, BugReporterContext &BRC,
BugReport &BR) {
ProgramStateRef State = N->getState();
PathDiagnosticLocation Pos(S, BRC.getSourceManager(),
N->getLocationContext());
- return new PathDiagnosticEventPiece(Pos, Msg, true);
+ return std::make_shared<PathDiagnosticEventPiece>(Pos, Msg, true);
}
#define REGISTER_CHECKER(name) \
// grabbing the front, processing it, and if we decide to keep it append
// it to the end of the path. The entire path is processed in this way.
for (unsigned i = 0; i < N; ++i) {
- IntrusiveRefCntPtr<PathDiagnosticPiece> piece(path.front());
+ auto piece = std::move(path.front());
path.pop_front();
switch (piece->getKind()) {
case PathDiagnosticPiece::Call:
- removeRedundantMsgs(cast<PathDiagnosticCallPiece>(piece)->path);
+ removeRedundantMsgs(cast<PathDiagnosticCallPiece>(*piece).path);
break;
case PathDiagnosticPiece::Macro:
- removeRedundantMsgs(cast<PathDiagnosticMacroPiece>(piece)->subPieces);
+ removeRedundantMsgs(cast<PathDiagnosticMacroPiece>(*piece).subPieces);
break;
case PathDiagnosticPiece::ControlFlow:
break;
if (PathDiagnosticEventPiece *nextEvent =
dyn_cast<PathDiagnosticEventPiece>(path.front().get())) {
PathDiagnosticEventPiece *event =
- cast<PathDiagnosticEventPiece>(piece);
+ cast<PathDiagnosticEventPiece>(piece.get());
// Check to see if we should keep one of the two pieces. If we
// come up with a preference, record which piece to keep, and consume
// another piece from the path.
- if (PathDiagnosticEventPiece *pieceToKeep =
- eventsDescribeSameCondition(event, nextEvent)) {
- piece = pieceToKeep;
+ if (auto *pieceToKeep =
+ eventsDescribeSameCondition(event, nextEvent)) {
+ piece = std::move(pieceToKeep == event ? piece : path.front());
path.pop_front();
++i;
}
case PathDiagnosticPiece::Note:
break;
}
- path.push_back(piece);
+ path.push_back(std::move(piece));
}
}
for (unsigned i = 0 ; i < N ; ++i) {
// Remove the front piece from the path. If it is still something we
// want to keep once we are done, we will push it back on the end.
- IntrusiveRefCntPtr<PathDiagnosticPiece> piece(pieces.front());
+ auto piece = std::move(pieces.front());
pieces.pop_front();
switch (piece->getKind()) {
case PathDiagnosticPiece::Call: {
- PathDiagnosticCallPiece *call = cast<PathDiagnosticCallPiece>(piece);
+ auto &call = cast<PathDiagnosticCallPiece>(*piece);
// Check if the location context is interesting.
- assert(LCM.count(&call->path));
- if (R->isInteresting(LCM[&call->path])) {
+ assert(LCM.count(&call.path));
+ if (R->isInteresting(LCM[&call.path])) {
containsSomethingInteresting = true;
break;
}
- if (!removeUnneededCalls(call->path, R, LCM))
+ if (!removeUnneededCalls(call.path, R, LCM))
continue;
containsSomethingInteresting = true;
break;
}
case PathDiagnosticPiece::Macro: {
- PathDiagnosticMacroPiece *macro = cast<PathDiagnosticMacroPiece>(piece);
- if (!removeUnneededCalls(macro->subPieces, R, LCM))
+ auto ¯o = cast<PathDiagnosticMacroPiece>(*piece);
+ if (!removeUnneededCalls(macro.subPieces, R, LCM))
continue;
containsSomethingInteresting = true;
break;
}
case PathDiagnosticPiece::Event: {
- PathDiagnosticEventPiece *event = cast<PathDiagnosticEventPiece>(piece);
+ auto &event = cast<PathDiagnosticEventPiece>(*piece);
// We never throw away an event, but we do throw it away wholesale
// as part of a path if we throw the entire path away.
- containsSomethingInteresting |= !event->isPrunable();
+ containsSomethingInteresting |= !event.isPrunable();
break;
}
case PathDiagnosticPiece::ControlFlow:
break;
}
- pieces.push_back(piece);
+ pieces.push_back(std::move(piece));
}
return containsSomethingInteresting;
adjustCallLocations(PathPieces &Pieces,
PathDiagnosticLocation *LastCallLocation = nullptr) {
for (PathPieces::iterator I = Pieces.begin(), E = Pieces.end(); I != E; ++I) {
- PathDiagnosticCallPiece *Call = dyn_cast<PathDiagnosticCallPiece>(*I);
+ PathDiagnosticCallPiece *Call = dyn_cast<PathDiagnosticCallPiece>(I->get());
if (!Call) {
assert((*I)->getLocation().asLocation().isValid());
/// explicitly in a constructor or braced list.
static void removeEdgesToDefaultInitializers(PathPieces &Pieces) {
for (PathPieces::iterator I = Pieces.begin(), E = Pieces.end(); I != E;) {
- if (PathDiagnosticCallPiece *C = dyn_cast<PathDiagnosticCallPiece>(*I))
+ if (auto *C = dyn_cast<PathDiagnosticCallPiece>(I->get()))
removeEdgesToDefaultInitializers(C->path);
- if (PathDiagnosticMacroPiece *M = dyn_cast<PathDiagnosticMacroPiece>(*I))
+ if (auto *M = dyn_cast<PathDiagnosticMacroPiece>(I->get()))
removeEdgesToDefaultInitializers(M->subPieces);
- if (PathDiagnosticControlFlowPiece *CF =
- dyn_cast<PathDiagnosticControlFlowPiece>(*I)) {
+ if (auto *CF = dyn_cast<PathDiagnosticControlFlowPiece>(I->get())) {
const Stmt *Start = CF->getStartLocation().asStmt();
const Stmt *End = CF->getEndLocation().asStmt();
if (Start && isa<CXXDefaultInitExpr>(Start)) {
} else if (End && isa<CXXDefaultInitExpr>(End)) {
PathPieces::iterator Next = std::next(I);
if (Next != E) {
- if (PathDiagnosticControlFlowPiece *NextCF =
- dyn_cast<PathDiagnosticControlFlowPiece>(*Next)) {
+ if (auto *NextCF =
+ dyn_cast<PathDiagnosticControlFlowPiece>(Next->get())) {
NextCF->setStartLocation(CF->getStartLocation());
}
}
/// Farm generated functions.
static void removePiecesWithInvalidLocations(PathPieces &Pieces) {
for (PathPieces::iterator I = Pieces.begin(), E = Pieces.end(); I != E;) {
- if (PathDiagnosticCallPiece *C = dyn_cast<PathDiagnosticCallPiece>(*I))
+ if (auto *C = dyn_cast<PathDiagnosticCallPiece>(I->get()))
removePiecesWithInvalidLocations(C->path);
- if (PathDiagnosticMacroPiece *M = dyn_cast<PathDiagnosticMacroPiece>(*I))
+ if (auto *M = dyn_cast<PathDiagnosticMacroPiece>(I->get()))
removePiecesWithInvalidLocations(M->subPieces);
if (!(*I)->getLocation().isValid() ||
BugReport *R = PDB.getBugReport();
while (const ExplodedNode *Pred = N->getFirstPred()) {
- for (auto &V : visitors) {
+ for (auto &V : visitors)
// Visit all the node pairs, but throw the path pieces away.
- PathDiagnosticPiece *Piece = V->VisitNode(N, Pred, PDB, *R);
- delete Piece;
- }
+ V->VisitNode(N, Pred, PDB, *R);
N = Pred;
}
typedef std::pair<PathDiagnosticCallPiece*, const ExplodedNode*> StackDiagPair;
typedef SmallVector<StackDiagPair, 6> StackDiagVector;
-static void updateStackPiecesWithMessage(PathDiagnosticPiece *P,
+static void updateStackPiecesWithMessage(PathDiagnosticPiece &P,
StackDiagVector &CallStack) {
// If the piece contains a special message, add it to all the call
// pieces on the active stack.
- if (PathDiagnosticEventPiece *ep =
- dyn_cast<PathDiagnosticEventPiece>(P)) {
+ if (PathDiagnosticEventPiece *ep = dyn_cast<PathDiagnosticEventPiece>(&P)) {
if (ep->hasCallStackHint())
for (StackDiagVector::iterator I = CallStack.begin(),
do {
if (Optional<CallExitEnd> CE = P.getAs<CallExitEnd>()) {
- PathDiagnosticCallPiece *C =
- PathDiagnosticCallPiece::construct(N, *CE, SMgr);
+ auto C = PathDiagnosticCallPiece::construct(N, *CE, SMgr);
// Record the mapping from call piece to LocationContext.
LCM[&C->path] = CE->getCalleeContext();
- PD.getActivePath().push_front(C);
- PD.pushActivePath(&C->path);
- CallStack.push_back(StackDiagPair(C, N));
+ auto *P = C.get();
+ PD.getActivePath().push_front(std::move(C));
+ PD.pushActivePath(&P->path);
+ CallStack.push_back(StackDiagPair(P, N));
break;
}
// a new PathDiagnosticCallPiece.
PathDiagnosticCallPiece *C;
if (VisitedEntireCall) {
- C = cast<PathDiagnosticCallPiece>(PD.getActivePath().front());
+ C = cast<PathDiagnosticCallPiece>(PD.getActivePath().front().get());
} else {
const Decl *Caller = CE->getLocationContext()->getDecl();
C = PathDiagnosticCallPiece::construct(PD.getActivePath(), Caller);
os << "Control jumps to line "
<< End.asLocation().getExpansionLineNumber();
- PD.getActivePath().push_front(new PathDiagnosticControlFlowPiece(
- Start, End, os.str()));
+ PD.getActivePath().push_front(
+ std::make_shared<PathDiagnosticControlFlowPiece>(Start, End,
+ os.str()));
break;
}
break;
}
}
- PD.getActivePath().push_front(new PathDiagnosticControlFlowPiece(
- Start, End, os.str()));
+ PD.getActivePath().push_front(
+ std::make_shared<PathDiagnosticControlFlowPiece>(Start, End,
+ os.str()));
}
else {
os << "'Default' branch taken. ";
const PathDiagnosticLocation &End = PDB.ExecutionContinues(os, N);
- PD.getActivePath().push_front(new PathDiagnosticControlFlowPiece(
- Start, End, os.str()));
+ PD.getActivePath().push_front(
+ std::make_shared<PathDiagnosticControlFlowPiece>(Start, End,
+ os.str()));
}
break;
std::string sbuf;
llvm::raw_string_ostream os(sbuf);
PathDiagnosticLocation End = PDB.ExecutionContinues(os, N);
- PD.getActivePath().push_front(new PathDiagnosticControlFlowPiece(
- Start, End, os.str()));
+ PD.getActivePath().push_front(
+ std::make_shared<PathDiagnosticControlFlowPiece>(Start, End,
+ os.str()));
break;
}
if (const Stmt *S = End.asStmt())
End = PDB.getEnclosingStmtLocation(S);
- PD.getActivePath().push_front(new PathDiagnosticControlFlowPiece(
- Start, End, os.str()));
+ PD.getActivePath().push_front(
+ std::make_shared<PathDiagnosticControlFlowPiece>(Start, End,
+ os.str()));
break;
}
PathDiagnosticLocation End(B->getLHS(), SMgr, LC);
PathDiagnosticLocation Start =
PathDiagnosticLocation::createOperatorLoc(B, SMgr);
- PD.getActivePath().push_front(new PathDiagnosticControlFlowPiece(
- Start, End, os.str()));
+ PD.getActivePath().push_front(
+ std::make_shared<PathDiagnosticControlFlowPiece>(Start, End,
+ os.str()));
}
else {
os << "true";
PathDiagnosticLocation Start(B->getLHS(), SMgr, LC);
PathDiagnosticLocation End = PDB.ExecutionContinues(N);
- PD.getActivePath().push_front(new PathDiagnosticControlFlowPiece(
- Start, End, os.str()));
+ PD.getActivePath().push_front(
+ std::make_shared<PathDiagnosticControlFlowPiece>(Start, End,
+ os.str()));
}
}
else {
os << "false";
PathDiagnosticLocation Start(B->getLHS(), SMgr, LC);
PathDiagnosticLocation End = PDB.ExecutionContinues(N);
- PD.getActivePath().push_front(new PathDiagnosticControlFlowPiece(
- Start, End, os.str()));
+ PD.getActivePath().push_front(
+ std::make_shared<PathDiagnosticControlFlowPiece>(Start, End,
+ os.str()));
}
else {
os << "true";
PathDiagnosticLocation End(B->getLHS(), SMgr, LC);
PathDiagnosticLocation Start =
PathDiagnosticLocation::createOperatorLoc(B, SMgr);
- PD.getActivePath().push_front(new PathDiagnosticControlFlowPiece(
- Start, End, os.str()));
+ PD.getActivePath().push_front(
+ std::make_shared<PathDiagnosticControlFlowPiece>(Start, End,
+ os.str()));
}
}
if (const Stmt *S = End.asStmt())
End = PDB.getEnclosingStmtLocation(S);
- PD.getActivePath().push_front(new PathDiagnosticControlFlowPiece(
- Start, End, os.str()));
+ PD.getActivePath().push_front(
+ std::make_shared<PathDiagnosticControlFlowPiece>(Start, End,
+ os.str()));
}
else {
PathDiagnosticLocation End = PDB.ExecutionContinues(N);
if (const Stmt *S = End.asStmt())
End = PDB.getEnclosingStmtLocation(S);
- PD.getActivePath().push_front(new PathDiagnosticControlFlowPiece(
- Start, End, "Loop condition is false. Exiting loop"));
+ PD.getActivePath().push_front(
+ std::make_shared<PathDiagnosticControlFlowPiece>(
+ Start, End, "Loop condition is false. Exiting loop"));
}
break;
if (const Stmt *S = End.asStmt())
End = PDB.getEnclosingStmtLocation(S);
- PD.getActivePath().push_front(new PathDiagnosticControlFlowPiece(
- Start, End, os.str()));
+ PD.getActivePath().push_front(
+ std::make_shared<PathDiagnosticControlFlowPiece>(Start, End,
+ os.str()));
}
else {
PathDiagnosticLocation End = PDB.ExecutionContinues(N);
if (const Stmt *S = End.asStmt())
End = PDB.getEnclosingStmtLocation(S);
- PD.getActivePath().push_front(new PathDiagnosticControlFlowPiece(
- Start, End, "Loop condition is true. Entering loop body"));
+ PD.getActivePath().push_front(
+ std::make_shared<PathDiagnosticControlFlowPiece>(
+ Start, End, "Loop condition is true. Entering loop body"));
}
break;
End = PDB.getEnclosingStmtLocation(S);
if (*(Src->succ_begin()+1) == Dst)
- PD.getActivePath().push_front(new PathDiagnosticControlFlowPiece(
- Start, End, "Taking false branch"));
+ PD.getActivePath().push_front(
+ std::make_shared<PathDiagnosticControlFlowPiece>(
+ Start, End, "Taking false branch"));
else
- PD.getActivePath().push_front(new PathDiagnosticControlFlowPiece(
- Start, End, "Taking true branch"));
+ PD.getActivePath().push_front(
+ std::make_shared<PathDiagnosticControlFlowPiece>(
+ Start, End, "Taking true branch"));
break;
}
// Add diagnostic pieces from custom visitors.
BugReport *R = PDB.getBugReport();
for (auto &V : visitors) {
- if (PathDiagnosticPiece *p = V->VisitNode(N, NextNode, PDB, *R)) {
- PD.getActivePath().push_front(p);
- updateStackPiecesWithMessage(p, CallStack);
+ if (auto p = V->VisitNode(N, NextNode, PDB, *R)) {
+ updateStackPiecesWithMessage(*p, CallStack);
+ PD.getActivePath().push_front(std::move(p));
}
}
}
PrevLocClean.asLocation().getExpansionLoc())
return;
- PD.getActivePath().push_front(new PathDiagnosticControlFlowPiece(NewLocClean, PrevLocClean));
+ PD.getActivePath().push_front(
+ std::make_shared<PathDiagnosticControlFlowPiece>(NewLocClean,
+ PrevLocClean));
PrevLoc = NewLoc;
}
N->getLocationContext());
}
- PathDiagnosticCallPiece *C =
- PathDiagnosticCallPiece::construct(N, *CE, SM);
+ auto C = PathDiagnosticCallPiece::construct(N, *CE, SM);
LCM[&C->path] = CE->getCalleeContext();
EB.addEdge(C->callReturn, /*AlwaysAdd=*/true, /*IsPostJump=*/true);
EB.flushLocations();
- PD.getActivePath().push_front(C);
- PD.pushActivePath(&C->path);
- CallStack.push_back(StackDiagPair(C, N));
+ auto *P = C.get();
+ PD.getActivePath().push_front(std::move(C));
+ PD.pushActivePath(&P->path);
+ CallStack.push_back(StackDiagPair(P, N));
break;
}
// a new PathDiagnosticCallPiece.
PathDiagnosticCallPiece *C;
if (VisitedEntireCall) {
- C = cast<PathDiagnosticCallPiece>(PD.getActivePath().front());
+ C = cast<PathDiagnosticCallPiece>(PD.getActivePath().front().get());
} else {
const Decl *Caller = CE->getLocationContext()->getDecl();
C = PathDiagnosticCallPiece::construct(PD.getActivePath(), Caller);
else if (const WhileStmt *WS = dyn_cast<WhileStmt>(Loop))
CS = dyn_cast<CompoundStmt>(WS->getBody());
- PathDiagnosticEventPiece *p =
- new PathDiagnosticEventPiece(L,
- "Looping back to the head of the loop");
+ auto p = std::make_shared<PathDiagnosticEventPiece>(
+ L, "Looping back to the head of the loop");
p->setPrunable(true);
EB.addEdge(p->getLocation(), true);
- PD.getActivePath().push_front(p);
+ PD.getActivePath().push_front(std::move(p));
if (CS) {
PathDiagnosticLocation BL =
N),
Term)) {
PathDiagnosticLocation L(Term, SM, PDB.LC);
- PathDiagnosticEventPiece *PE =
- new PathDiagnosticEventPiece(L, "Loop body executed 0 times");
+ auto PE = std::make_shared<PathDiagnosticEventPiece>(
+ L, "Loop body executed 0 times");
PE->setPrunable(true);
EB.addEdge(PE->getLocation(), true);
- PD.getActivePath().push_front(PE);
+ PD.getActivePath().push_front(std::move(PE));
}
// In any case, add the terminator as the current statement
// Add pieces from custom visitors.
BugReport *R = PDB.getBugReport();
for (auto &V : visitors) {
- if (PathDiagnosticPiece *p = V->VisitNode(N, NextNode, PDB, *R)) {
+ if (auto p = V->VisitNode(N, NextNode, PDB, *R)) {
const PathDiagnosticLocation &Loc = p->getLocation();
EB.addEdge(Loc, true);
- PD.getActivePath().push_front(p);
- updateStackPiecesWithMessage(p, CallStack);
+ updateStackPiecesWithMessage(*p, CallStack);
+ PD.getActivePath().push_front(std::move(p));
if (const Stmt *S = Loc.asStmt())
EB.addExtendedContext(PDB.getEnclosingStmtLocation(S).asStmt());
if (NewLoc.asStmt() && NewLoc.asStmt() == PrevLoc.asStmt())
return;
- path.push_front(new PathDiagnosticControlFlowPiece(NewLoc,
- PrevLoc));
+ path.push_front(
+ std::make_shared<PathDiagnosticControlFlowPiece>(NewLoc, PrevLoc));
PrevLoc = NewLoc;
}
// Since we just transferred the path over to the call piece,
// reset the mapping from active to location context.
assert(PD.getActivePath().size() == 1 &&
- PD.getActivePath().front() == C);
+ PD.getActivePath().front().get() == C);
LCM[&PD.getActivePath()] = nullptr;
// Record the location context mapping for the path within
// We are descending into a call (backwards). Construct
// a new call piece to contain the path pieces for that call.
- PathDiagnosticCallPiece *C =
- PathDiagnosticCallPiece::construct(N, *CE, SM);
+ auto C = PathDiagnosticCallPiece::construct(N, *CE, SM);
// Record the location context for this call piece.
LCM[&C->path] = CE->getCalleeContext();
// Add the edge to the return site.
addEdgeToPath(PD.getActivePath(), PrevLoc, C->callReturn, PDB.LC);
- PD.getActivePath().push_front(C);
+ auto *P = C.get();
+ PD.getActivePath().push_front(std::move(C));
PrevLoc.invalidate();
// Make the contents of the call the active path for now.
- PD.pushActivePath(&C->path);
- CallStack.push_back(StackDiagPair(C, N));
+ PD.pushActivePath(&P->path);
+ CallStack.push_back(StackDiagPair(P, N));
break;
}
}
// do-while statements are explicitly excluded here
- PathDiagnosticEventPiece *p =
- new PathDiagnosticEventPiece(L, "Looping back to the head "
- "of the loop");
+ auto p = std::make_shared<PathDiagnosticEventPiece>(
+ L, "Looping back to the head "
+ "of the loop");
p->setPrunable(true);
addEdgeToPath(PD.getActivePath(), PrevLoc, p->getLocation(), PDB.LC);
- PD.getActivePath().push_front(p);
+ PD.getActivePath().push_front(std::move(p));
if (const CompoundStmt *CS = dyn_cast_or_null<CompoundStmt>(Body)) {
addEdgeToPath(PD.getActivePath(), PrevLoc,
if (str) {
PathDiagnosticLocation L(TermCond ? TermCond : Term, SM, PDB.LC);
- PathDiagnosticEventPiece *PE =
- new PathDiagnosticEventPiece(L, str);
+ auto PE = std::make_shared<PathDiagnosticEventPiece>(L, str);
PE->setPrunable(true);
addEdgeToPath(PD.getActivePath(), PrevLoc,
PE->getLocation(), PDB.LC);
- PD.getActivePath().push_front(PE);
+ PD.getActivePath().push_front(std::move(PE));
}
} else if (isa<BreakStmt>(Term) || isa<ContinueStmt>(Term) ||
isa<GotoStmt>(Term)) {
// Add pieces from custom visitors.
for (auto &V : visitors) {
- if (PathDiagnosticPiece *p = V->VisitNode(N, NextNode, PDB, *report)) {
+ if (auto p = V->VisitNode(N, NextNode, PDB, *report)) {
addEdgeToPath(PD.getActivePath(), PrevLoc, p->getLocation(), PDB.LC);
- PD.getActivePath().push_front(p);
- updateStackPiecesWithMessage(p, CallStack);
+ updateStackPiecesWithMessage(*p, CallStack);
+ PD.getActivePath().push_front(std::move(p));
}
}
}
for (PathPieces::iterator I = pieces.begin(), E = Prev; I != E;
Prev = I, ++I) {
PathDiagnosticControlFlowPiece *Piece =
- dyn_cast<PathDiagnosticControlFlowPiece>(*I);
+ dyn_cast<PathDiagnosticControlFlowPiece>(I->get());
if (!Piece)
continue;
// Try to extend the previous edge if it's at the same level as the source
// context.
if (Prev != E) {
- PathDiagnosticControlFlowPiece *PrevPiece =
- dyn_cast<PathDiagnosticControlFlowPiece>(*Prev);
+ auto *PrevPiece = dyn_cast<PathDiagnosticControlFlowPiece>(Prev->get());
if (PrevPiece) {
if (const Stmt *PrevSrc = getLocStmt(PrevPiece->getStartLocation())) {
// Otherwise, split the current edge into a context edge and a
// subexpression edge. Note that the context statement may itself have
// context.
- Piece = new PathDiagnosticControlFlowPiece(SrcLoc, DstContext);
- I = pieces.insert(I, Piece);
+ auto P =
+ std::make_shared<PathDiagnosticControlFlowPiece>(SrcLoc, DstContext);
+ Piece = P.get();
+ I = pieces.insert(I, std::move(P));
}
}
}
static void simplifySimpleBranches(PathPieces &pieces) {
for (PathPieces::iterator I = pieces.begin(), E = pieces.end(); I != E; ++I) {
- PathDiagnosticControlFlowPiece *PieceI =
- dyn_cast<PathDiagnosticControlFlowPiece>(*I);
+ auto *PieceI = dyn_cast<PathDiagnosticControlFlowPiece>(I->get());
if (!PieceI)
continue;
if (NextI == E)
break;
- PathDiagnosticEventPiece *EV = dyn_cast<PathDiagnosticEventPiece>(*NextI);
+ auto *EV = dyn_cast<PathDiagnosticEventPiece>(NextI->get());
if (EV) {
StringRef S = EV->getString();
if (S == StrEnteringLoop || S == StrLoopBodyZero ||
break;
}
- PieceNextI = dyn_cast<PathDiagnosticControlFlowPiece>(*NextI);
+ PieceNextI = dyn_cast<PathDiagnosticControlFlowPiece>(NextI->get());
break;
}
for (PathPieces::iterator I = Path.begin(), E = Path.end(); I != E; ) {
// Pattern match the current piece and its successor.
PathDiagnosticControlFlowPiece *PieceI =
- dyn_cast<PathDiagnosticControlFlowPiece>(*I);
+ dyn_cast<PathDiagnosticControlFlowPiece>(I->get());
if (!PieceI) {
++I;
break;
PathDiagnosticControlFlowPiece *PieceNextI =
- dyn_cast<PathDiagnosticControlFlowPiece>(*NextI);
+ dyn_cast<PathDiagnosticControlFlowPiece>(NextI->get());
if (!PieceNextI) {
- if (isa<PathDiagnosticEventPiece>(*NextI)) {
+ if (isa<PathDiagnosticEventPiece>(NextI->get())) {
++NextI;
if (NextI == E)
break;
- PieceNextI = dyn_cast<PathDiagnosticControlFlowPiece>(*NextI);
+ PieceNextI = dyn_cast<PathDiagnosticControlFlowPiece>(NextI->get());
}
if (!PieceNextI) {
erased = false;
- PathDiagnosticControlFlowPiece *PieceI =
- dyn_cast<PathDiagnosticControlFlowPiece>(*I);
+ auto *PieceI = dyn_cast<PathDiagnosticControlFlowPiece>(I->get());
if (!PieceI)
continue;
static void removeIdenticalEvents(PathPieces &path) {
for (PathPieces::iterator I = path.begin(), E = path.end(); I != E; ++I) {
- PathDiagnosticEventPiece *PieceI =
- dyn_cast<PathDiagnosticEventPiece>(*I);
+ auto *PieceI = dyn_cast<PathDiagnosticEventPiece>(I->get());
if (!PieceI)
continue;
if (NextI == E)
return;
- PathDiagnosticEventPiece *PieceNextI =
- dyn_cast<PathDiagnosticEventPiece>(*NextI);
+ auto *PieceNextI = dyn_cast<PathDiagnosticEventPiece>(NextI->get());
if (!PieceNextI)
continue;
for (PathPieces::iterator I = path.begin(), E = path.end(); I != E; ) {
// Optimize subpaths.
- if (PathDiagnosticCallPiece *CallI = dyn_cast<PathDiagnosticCallPiece>(*I)){
+ if (auto *CallI = dyn_cast<PathDiagnosticCallPiece>(I->get())) {
// Record the fact that a call has been optimized so we only do the
// effort once.
if (!OCS.count(CallI)) {
}
// Pattern match the current piece and its successor.
- PathDiagnosticControlFlowPiece *PieceI =
- dyn_cast<PathDiagnosticControlFlowPiece>(*I);
+ auto *PieceI = dyn_cast<PathDiagnosticControlFlowPiece>(I->get());
if (!PieceI) {
++I;
if (NextI == E)
break;
- PathDiagnosticControlFlowPiece *PieceNextI =
- dyn_cast<PathDiagnosticControlFlowPiece>(*NextI);
+ auto *PieceNextI = dyn_cast<PathDiagnosticControlFlowPiece>(NextI->get());
if (!PieceNextI) {
++I;
static void dropFunctionEntryEdge(PathPieces &Path,
LocationContextMap &LCM,
SourceManager &SM) {
- const PathDiagnosticControlFlowPiece *FirstEdge =
- dyn_cast<PathDiagnosticControlFlowPiece>(Path.front());
+ const auto *FirstEdge =
+ dyn_cast<PathDiagnosticControlFlowPiece>(Path.front().get());
if (!FirstEdge)
return;
/// CompactPathDiagnostic - This function postprocesses a PathDiagnostic object
/// and collapses PathDiagosticPieces that are expanded by macros.
static void CompactPathDiagnostic(PathPieces &path, const SourceManager& SM) {
- typedef std::vector<std::pair<IntrusiveRefCntPtr<PathDiagnosticMacroPiece>,
- SourceLocation> > MacroStackTy;
+ typedef std::vector<
+ std::pair<std::shared_ptr<PathDiagnosticMacroPiece>, SourceLocation>>
+ MacroStackTy;
- typedef std::vector<IntrusiveRefCntPtr<PathDiagnosticPiece> >
- PiecesTy;
+ typedef std::vector<std::shared_ptr<PathDiagnosticPiece>> PiecesTy;
MacroStackTy MacroStack;
PiecesTy Pieces;
for (PathPieces::const_iterator I = path.begin(), E = path.end();
I!=E; ++I) {
- PathDiagnosticPiece *piece = I->get();
+ auto &piece = *I;
// Recursively compact calls.
- if (PathDiagnosticCallPiece *call=dyn_cast<PathDiagnosticCallPiece>(piece)){
+ if (auto *call = dyn_cast<PathDiagnosticCallPiece>(&*piece)) {
CompactPathDiagnostic(call->path, SM);
}
// We aren't in the same group. Are we descending into a new macro
// or are part of an old one?
- IntrusiveRefCntPtr<PathDiagnosticMacroPiece> MacroGroup;
+ std::shared_ptr<PathDiagnosticMacroPiece> MacroGroup;
SourceLocation ParentInstantiationLoc = InstantiationLoc.isMacroID() ?
SM.getExpansionLoc(Loc) :
if (!MacroGroup || ParentInstantiationLoc == MacroStack.back().second) {
// Create a new macro group and add it to the stack.
- PathDiagnosticMacroPiece *NewGroup =
- new PathDiagnosticMacroPiece(
+ auto NewGroup = std::make_shared<PathDiagnosticMacroPiece>(
PathDiagnosticLocation::createSingleLocation(piece->getLocation()));
if (MacroGroup)
for (auto I = exampleReport->getNotes().rbegin(),
E = exampleReport->getNotes().rend(); I != E; ++I) {
PathDiagnosticNotePiece *Piece = I->get();
- PathDiagnosticEventPiece *ConvertedPiece =
- new PathDiagnosticEventPiece(Piece->getLocation(),
- Piece->getString());
+ auto ConvertedPiece = std::make_shared<PathDiagnosticEventPiece>(
+ Piece->getLocation(), Piece->getString());
for (const auto &R: Piece->getRanges())
ConvertedPiece->addRange(R);
- Pieces.push_front(ConvertedPiece);
+ Pieces.push_front(std::move(ConvertedPiece));
}
} else {
for (auto I = exampleReport->getNotes().rbegin(),
return Options.shouldAvoidSuppressingNullArgumentPaths();
}
- PathDiagnosticPiece *visitNodeInitial(const ExplodedNode *N,
- const ExplodedNode *PrevN,
- BugReporterContext &BRC,
- BugReport &BR) {
+ std::shared_ptr<PathDiagnosticPiece>
+ visitNodeInitial(const ExplodedNode *N, const ExplodedNode *PrevN,
+ BugReporterContext &BRC, BugReport &BR) {
// Only print a message at the interesting return statement.
if (N->getLocationContext() != StackFrame)
return nullptr;
if (!L.isValid() || !L.asLocation().isValid())
return nullptr;
- return new PathDiagnosticEventPiece(L, Out.str());
+ return std::make_shared<PathDiagnosticEventPiece>(L, Out.str());
}
- PathDiagnosticPiece *visitNodeMaybeUnsuppress(const ExplodedNode *N,
- const ExplodedNode *PrevN,
- BugReporterContext &BRC,
- BugReport &BR) {
+ std::shared_ptr<PathDiagnosticPiece>
+ visitNodeMaybeUnsuppress(const ExplodedNode *N, const ExplodedNode *PrevN,
+ BugReporterContext &BRC, BugReport &BR) {
#ifndef NDEBUG
ExprEngine &Eng = BRC.getBugReporter().getEngine();
AnalyzerOptions &Options = Eng.getAnalysisManager().options;
return nullptr;
}
- PathDiagnosticPiece *VisitNode(const ExplodedNode *N,
- const ExplodedNode *PrevN,
- BugReporterContext &BRC,
- BugReport &BR) override {
+ std::shared_ptr<PathDiagnosticPiece> VisitNode(const ExplodedNode *N,
+ const ExplodedNode *PrevN,
+ BugReporterContext &BRC,
+ BugReport &BR) override {
switch (Mode) {
case Initial:
return visitNodeInitial(N, PrevN, BRC, BR);
return FrameSpace->getStackFrame() == LCtx->getCurrentStackFrame();
}
-PathDiagnosticPiece *FindLastStoreBRVisitor::VisitNode(const ExplodedNode *Succ,
- const ExplodedNode *Pred,
- BugReporterContext &BRC,
- BugReport &BR) {
+std::shared_ptr<PathDiagnosticPiece>
+FindLastStoreBRVisitor::VisitNode(const ExplodedNode *Succ,
+ const ExplodedNode *Pred,
+ BugReporterContext &BRC, BugReport &BR) {
if (Satisfied)
return nullptr;
if (!L.isValid() || !L.asLocation().isValid())
return nullptr;
- return new PathDiagnosticEventPiece(L, os.str());
+ return std::make_shared<PathDiagnosticEventPiece>(L, os.str());
}
void TrackConstraintBRVisitor::Profile(llvm::FoldingSetNodeID &ID) const {
return (bool)N->getState()->assume(Constraint, !Assumption);
}
-PathDiagnosticPiece *
+std::shared_ptr<PathDiagnosticPiece>
TrackConstraintBRVisitor::VisitNode(const ExplodedNode *N,
const ExplodedNode *PrevN,
- BugReporterContext &BRC,
- BugReport &BR) {
+ BugReporterContext &BRC, BugReport &BR) {
if (IsSatisfied)
return nullptr;
if (!L.isValid())
return nullptr;
- PathDiagnosticEventPiece *X = new PathDiagnosticEventPiece(L, os.str());
+ auto X = std::make_shared<PathDiagnosticEventPiece>(L, os.str());
X->setTag(getTag());
- return X;
+ return std::move(X);
}
return nullptr;
return "IDCVisitor";
}
-PathDiagnosticPiece *
+std::shared_ptr<PathDiagnosticPiece>
SuppressInlineDefensiveChecksVisitor::VisitNode(const ExplodedNode *Succ,
const ExplodedNode *Pred,
BugReporterContext &BRC,
return nullptr;
}
-PathDiagnosticPiece *NilReceiverBRVisitor::VisitNode(const ExplodedNode *N,
- const ExplodedNode *PrevN,
- BugReporterContext &BRC,
- BugReport &BR) {
+std::shared_ptr<PathDiagnosticPiece>
+NilReceiverBRVisitor::VisitNode(const ExplodedNode *N,
+ const ExplodedNode *PrevN,
+ BugReporterContext &BRC, BugReport &BR) {
Optional<PreStmt> P = N->getLocationAs<PreStmt>();
if (!P)
return nullptr;
// Issue a message saying that the method was skipped.
PathDiagnosticLocation L(Receiver, BRC.getSourceManager(),
N->getLocationContext());
- return new PathDiagnosticEventPiece(L, OS.str());
+ return std::make_shared<PathDiagnosticEventPiece>(L, OS.str());
}
// Registers every VarDecl inside a Stmt with a last store visitor.
return "ConditionBRVisitor";
}
-PathDiagnosticPiece *ConditionBRVisitor::VisitNode(const ExplodedNode *N,
- const ExplodedNode *Prev,
- BugReporterContext &BRC,
- BugReport &BR) {
- PathDiagnosticPiece *piece = VisitNodeImpl(N, Prev, BRC, BR);
+std::shared_ptr<PathDiagnosticPiece>
+ConditionBRVisitor::VisitNode(const ExplodedNode *N, const ExplodedNode *Prev,
+ BugReporterContext &BRC, BugReport &BR) {
+ auto piece = VisitNodeImpl(N, Prev, BRC, BR);
if (piece) {
piece->setTag(getTag());
- if (PathDiagnosticEventPiece *ev=dyn_cast<PathDiagnosticEventPiece>(piece))
+ if (auto *ev = dyn_cast<PathDiagnosticEventPiece>(piece.get()))
ev->setPrunable(true, /* override */ false);
}
return piece;
}
-PathDiagnosticPiece *ConditionBRVisitor::VisitNodeImpl(const ExplodedNode *N,
- const ExplodedNode *Prev,
- BugReporterContext &BRC,
- BugReport &BR) {
+std::shared_ptr<PathDiagnosticPiece>
+ConditionBRVisitor::VisitNodeImpl(const ExplodedNode *N,
+ const ExplodedNode *Prev,
+ BugReporterContext &BRC, BugReport &BR) {
ProgramPoint progPoint = N->getLocation();
ProgramStateRef CurrentState = N->getState();
return nullptr;
}
-PathDiagnosticPiece *
-ConditionBRVisitor::VisitTerminator(const Stmt *Term,
- const ExplodedNode *N,
- const CFGBlock *srcBlk,
- const CFGBlock *dstBlk,
- BugReport &R,
- BugReporterContext &BRC) {
+std::shared_ptr<PathDiagnosticPiece> ConditionBRVisitor::VisitTerminator(
+ const Stmt *Term, const ExplodedNode *N, const CFGBlock *srcBlk,
+ const CFGBlock *dstBlk, BugReport &R, BugReporterContext &BRC) {
const Expr *Cond = nullptr;
// In the code below, Term is a CFG terminator and Cond is a branch condition
return VisitTrueTest(Cond, tookTrue, BRC, R, N);
}
-PathDiagnosticPiece *
-ConditionBRVisitor::VisitTrueTest(const Expr *Cond,
- bool tookTrue,
- BugReporterContext &BRC,
- BugReport &R,
+std::shared_ptr<PathDiagnosticPiece>
+ConditionBRVisitor::VisitTrueTest(const Expr *Cond, bool tookTrue,
+ BugReporterContext &BRC, BugReport &R,
const ExplodedNode *N) {
// These will be modified in code below, but we need to preserve the original
// values in case we want to throw the generic message.
default:
break;
case Stmt::BinaryOperatorClass:
- if (PathDiagnosticPiece *P = VisitTrueTest(
- Cond, cast<BinaryOperator>(CondTmp), tookTrueTmp, BRC, R, N))
+ if (auto P = VisitTrueTest(Cond, cast<BinaryOperator>(CondTmp),
+ tookTrueTmp, BRC, R, N))
return P;
break;
case Stmt::DeclRefExprClass:
- if (PathDiagnosticPiece *P = VisitTrueTest(
- Cond, cast<DeclRefExpr>(CondTmp), tookTrueTmp, BRC, R, N))
+ if (auto P = VisitTrueTest(Cond, cast<DeclRefExpr>(CondTmp),
+ tookTrueTmp, BRC, R, N))
return P;
break;
case Stmt::UnaryOperatorClass: {
if (!Loc.isValid() || !Loc.asLocation().isValid())
return nullptr;
- PathDiagnosticEventPiece *Event = new PathDiagnosticEventPiece(
+ return std::make_shared<PathDiagnosticEventPiece>(
Loc, tookTrue ? GenericTrueMessage : GenericFalseMessage);
- return Event;
}
bool ConditionBRVisitor::patternMatch(const Expr *Ex,
return false;
}
-PathDiagnosticPiece *
-ConditionBRVisitor::VisitTrueTest(const Expr *Cond,
- const BinaryOperator *BExpr,
- const bool tookTrue,
- BugReporterContext &BRC,
- BugReport &R,
- const ExplodedNode *N) {
+std::shared_ptr<PathDiagnosticPiece>
+ConditionBRVisitor::VisitTrueTest(const Expr *Cond, const BinaryOperator *BExpr,
+ const bool tookTrue, BugReporterContext &BRC,
+ BugReport &R, const ExplodedNode *N) {
bool shouldInvert = false;
Optional<bool> shouldPrune;
Out << (shouldInvert ? LhsString : RhsString);
const LocationContext *LCtx = N->getLocationContext();
PathDiagnosticLocation Loc(Cond, BRC.getSourceManager(), LCtx);
- PathDiagnosticEventPiece *event =
- new PathDiagnosticEventPiece(Loc, Out.str());
+ auto event = std::make_shared<PathDiagnosticEventPiece>(Loc, Out.str());
if (shouldPrune.hasValue())
event->setPrunable(shouldPrune.getValue());
return event;
}
-PathDiagnosticPiece *
-ConditionBRVisitor::VisitConditionVariable(StringRef LhsString,
- const Expr *CondVarExpr,
- const bool tookTrue,
- BugReporterContext &BRC,
- BugReport &report,
- const ExplodedNode *N) {
+std::shared_ptr<PathDiagnosticPiece> ConditionBRVisitor::VisitConditionVariable(
+ StringRef LhsString, const Expr *CondVarExpr, const bool tookTrue,
+ BugReporterContext &BRC, BugReport &report, const ExplodedNode *N) {
// FIXME: If there's already a constraint tracker for this variable,
// we shouldn't emit anything here (c.f. the double note in
// test/Analysis/inlining/path-notes.c)
const LocationContext *LCtx = N->getLocationContext();
PathDiagnosticLocation Loc(CondVarExpr, BRC.getSourceManager(), LCtx);
- PathDiagnosticEventPiece *event =
- new PathDiagnosticEventPiece(Loc, Out.str());
+ auto event = std::make_shared<PathDiagnosticEventPiece>(Loc, Out.str());
if (const DeclRefExpr *DR = dyn_cast<DeclRefExpr>(CondVarExpr)) {
if (const VarDecl *VD = dyn_cast<VarDecl>(DR->getDecl())) {
return event;
}
-PathDiagnosticPiece *
-ConditionBRVisitor::VisitTrueTest(const Expr *Cond,
- const DeclRefExpr *DR,
- const bool tookTrue,
- BugReporterContext &BRC,
- BugReport &report,
- const ExplodedNode *N) {
+std::shared_ptr<PathDiagnosticPiece>
+ConditionBRVisitor::VisitTrueTest(const Expr *Cond, const DeclRefExpr *DR,
+ const bool tookTrue, BugReporterContext &BRC,
+ BugReport &report, const ExplodedNode *N) {
const VarDecl *VD = dyn_cast<VarDecl>(DR->getDecl());
if (!VD)
const LocationContext *LCtx = N->getLocationContext();
PathDiagnosticLocation Loc(Cond, BRC.getSourceManager(), LCtx);
- PathDiagnosticEventPiece *event =
- new PathDiagnosticEventPiece(Loc, Out.str());
+ auto event = std::make_shared<PathDiagnosticEventPiece>(Loc, Out.str());
const ProgramState *state = N->getState().get();
if (const MemRegion *R = state->getLValue(VD, LCtx).getAsRegion()) {
event->setPrunable(false);
}
}
- return event;
+ return std::move(event);
}
const char *const ConditionBRVisitor::GenericTrueMessage =
return nullptr;
}
-PathDiagnosticPiece *
+std::shared_ptr<PathDiagnosticPiece>
UndefOrNullArgVisitor::VisitNode(const ExplodedNode *N,
- const ExplodedNode *PrevN,
- BugReporterContext &BRC,
- BugReport &BR) {
+ const ExplodedNode *PrevN,
+ BugReporterContext &BRC, BugReport &BR) {
ProgramStateRef State = N->getState();
ProgramPoint ProgLoc = N->getLocation();
return nullptr;
}
-PathDiagnosticPiece *
+std::shared_ptr<PathDiagnosticPiece>
CXXSelfAssignmentBRVisitor::VisitNode(const ExplodedNode *Succ,
const ExplodedNode *Pred,
BugReporterContext &BRC, BugReport &BR) {
Out << "Assuming " << Met->getParamDecl(0)->getName() <<
((Param == This) ? " == " : " != ") << "*this";
- auto *Piece = new PathDiagnosticEventPiece(L, Out.str());
+ auto Piece = std::make_shared<PathDiagnosticEventPiece>(L, Out.str());
Piece->addRange(Met->getSourceRange());
- return Piece;
+ return std::move(Piece);
}
unsigned TotalPieces = path.size();
unsigned TotalNotePieces =
std::count_if(path.begin(), path.end(),
- [](const IntrusiveRefCntPtr<PathDiagnosticPiece> &p) {
- return isa<PathDiagnosticNotePiece>(p.get());
+ [](const std::shared_ptr<PathDiagnosticPiece> &p) {
+ return isa<PathDiagnosticNotePiece>(*p);
});
unsigned TotalRegularPieces = TotalPieces - TotalNotePieces;
I!=E; ++I) {
if (const PathDiagnosticMacroPiece *MP =
- dyn_cast<PathDiagnosticMacroPiece>(*I)) {
+ dyn_cast<PathDiagnosticMacroPiece>(I->get())) {
num = ProcessMacroPiece(os, *MP, num);
continue;
}
- if (PathDiagnosticEventPiece *EP = dyn_cast<PathDiagnosticEventPiece>(*I)) {
+ if (PathDiagnosticEventPiece *EP =
+ dyn_cast<PathDiagnosticEventPiece>(I->get())) {
os << "<div class=\"msg msgEvent\" style=\"width:94%; "
"margin-left:5px\">"
"<table class=\"msgT\"><tr>"
using namespace ento;
bool PathDiagnosticMacroPiece::containsEvent() const {
- for (PathPieces::const_iterator I = subPieces.begin(), E = subPieces.end();
- I!=E; ++I) {
- if (isa<PathDiagnosticEventPiece>(*I))
+ for (auto &P : subPieces) {
+ if (isa<PathDiagnosticEventPiece>(*P))
return true;
- if (PathDiagnosticMacroPiece *MP = dyn_cast<PathDiagnosticMacroPiece>(*I))
+ if (auto *MP = dyn_cast<PathDiagnosticMacroPiece>(P.get()))
if (MP->containsEvent())
return true;
}
void PathPieces::flattenTo(PathPieces &Primary, PathPieces &Current,
bool ShouldFlattenMacros) const {
- for (PathPieces::const_iterator I = begin(), E = end(); I != E; ++I) {
- PathDiagnosticPiece *Piece = I->get();
-
+ for (auto &Piece : *this) {
switch (Piece->getKind()) {
case PathDiagnosticPiece::Call: {
- PathDiagnosticCallPiece *Call = cast<PathDiagnosticCallPiece>(Piece);
- IntrusiveRefCntPtr<PathDiagnosticEventPiece> CallEnter =
- Call->getCallEnterEvent();
- if (CallEnter)
- Current.push_back(CallEnter);
- Call->path.flattenTo(Primary, Primary, ShouldFlattenMacros);
- IntrusiveRefCntPtr<PathDiagnosticEventPiece> callExit =
- Call->getCallExitEvent();
- if (callExit)
- Current.push_back(callExit);
+ auto &Call = cast<PathDiagnosticCallPiece>(*Piece);
+ if (auto CallEnter = Call.getCallEnterEvent())
+ Current.push_back(std::move(CallEnter));
+ Call.path.flattenTo(Primary, Primary, ShouldFlattenMacros);
+ if (auto callExit = Call.getCallExitEvent())
+ Current.push_back(std::move(callExit));
break;
}
case PathDiagnosticPiece::Macro: {
- PathDiagnosticMacroPiece *Macro = cast<PathDiagnosticMacroPiece>(Piece);
+ auto &Macro = cast<PathDiagnosticMacroPiece>(*Piece);
if (ShouldFlattenMacros) {
- Macro->subPieces.flattenTo(Primary, Primary, ShouldFlattenMacros);
+ Macro.subPieces.flattenTo(Primary, Primary, ShouldFlattenMacros);
} else {
Current.push_back(Piece);
PathPieces NewPath;
- Macro->subPieces.flattenTo(Primary, NewPath, ShouldFlattenMacros);
+ Macro.subPieces.flattenTo(Primary, NewPath, ShouldFlattenMacros);
// FIXME: This probably shouldn't mutate the original path piece.
- Macro->subPieces = NewPath;
+ Macro.subPieces = NewPath;
}
break;
}
// Check if the last piece in the callee path is a call to a function outside
// of the main file.
if (PathDiagnosticCallPiece *CPInner =
- dyn_cast<PathDiagnosticCallPiece>(Path.back())) {
+ dyn_cast<PathDiagnosticCallPiece>(Path.back().get())) {
return getFirstStackedCallToHeaderFile(CPInner, SMgr);
}
// Manipulation of PathDiagnosticCallPieces.
//===----------------------------------------------------------------------===//
-PathDiagnosticCallPiece *
-PathDiagnosticCallPiece::construct(const ExplodedNode *N,
- const CallExitEnd &CE,
+std::shared_ptr<PathDiagnosticCallPiece>
+PathDiagnosticCallPiece::construct(const ExplodedNode *N, const CallExitEnd &CE,
const SourceManager &SM) {
const Decl *caller = CE.getLocationContext()->getDecl();
PathDiagnosticLocation pos = getLocationForCaller(CE.getCalleeContext(),
CE.getLocationContext(),
SM);
- return new PathDiagnosticCallPiece(caller, pos);
+ return std::shared_ptr<PathDiagnosticCallPiece>(
+ new PathDiagnosticCallPiece(caller, pos));
}
PathDiagnosticCallPiece *
PathDiagnosticCallPiece::construct(PathPieces &path,
const Decl *caller) {
- PathDiagnosticCallPiece *C = new PathDiagnosticCallPiece(path, caller);
+ std::shared_ptr<PathDiagnosticCallPiece> C(
+ new PathDiagnosticCallPiece(path, caller));
path.clear();
- path.push_front(C);
- return C;
+ auto *R = C.get();
+ path.push_front(std::move(C));
+ return R;
}
void PathDiagnosticCallPiece::setCallee(const CallEnter &CE,
return true;
}
-IntrusiveRefCntPtr<PathDiagnosticEventPiece>
+std::shared_ptr<PathDiagnosticEventPiece>
PathDiagnosticCallPiece::getCallEnterEvent() const {
if (!Callee)
return nullptr;
describeCodeDecl(Out, Callee, /*ExtendedDescription=*/true);
assert(callEnter.asLocation().isValid());
- return new PathDiagnosticEventPiece(callEnter, Out.str());
+ return std::make_shared<PathDiagnosticEventPiece>(callEnter, Out.str());
}
-IntrusiveRefCntPtr<PathDiagnosticEventPiece>
+std::shared_ptr<PathDiagnosticEventPiece>
PathDiagnosticCallPiece::getCallEnterWithinCallerEvent() const {
if (!callEnterWithin.asLocation().isValid())
return nullptr;
Out << "Entered call";
describeCodeDecl(Out, Caller, /*ExtendedDescription=*/false, " from ");
- return new PathDiagnosticEventPiece(callEnterWithin, Out.str());
+ return std::make_shared<PathDiagnosticEventPiece>(callEnterWithin, Out.str());
}
-IntrusiveRefCntPtr<PathDiagnosticEventPiece>
+std::shared_ptr<PathDiagnosticEventPiece>
PathDiagnosticCallPiece::getCallExitEvent() const {
if (NoExit)
return nullptr;
}
assert(callReturn.asLocation().isValid());
- return new PathDiagnosticEventPiece(callReturn, Out.str());
+ return std::make_shared<PathDiagnosticEventPiece>(callReturn, Out.str());
}
static void compute_path_size(const PathPieces &pieces, unsigned &size) {
unsigned indent,
unsigned depth) {
- IntrusiveRefCntPtr<PathDiagnosticEventPiece> callEnter =
- P.getCallEnterEvent();
-
- if (callEnter)
+ if (auto callEnter = P.getCallEnterEvent())
ReportPiece(o, *callEnter, FM, SM, LangOpts, indent, depth, true,
P.isLastInMainSourceFile());
- IntrusiveRefCntPtr<PathDiagnosticEventPiece> callEnterWithinCaller =
- P.getCallEnterWithinCallerEvent();
++depth;
- if (callEnterWithinCaller)
+ if (auto callEnterWithinCaller = P.getCallEnterWithinCallerEvent())
ReportPiece(o, *callEnterWithinCaller, FM, SM, LangOpts,
indent, depth, true);
--depth;
- IntrusiveRefCntPtr<PathDiagnosticEventPiece> callExit =
- P.getCallExitEvent();
-
- if (callExit)
+ if (auto callExit = P.getCallExitEvent())
ReportPiece(o, *callExit, FM, SM, LangOpts, indent, depth, true);
}
if (!Diags.empty())
SM = &Diags.front()->path.front()->getLocation().getManager();
-
- auto AddPieceFID = [&FM, &Fids, SM](const PathDiagnosticPiece *Piece)->void {
- AddFID(FM, Fids, *SM, Piece->getLocation().asLocation());
- ArrayRef<SourceRange> Ranges = Piece->getRanges();
+ auto AddPieceFID = [&FM, &Fids, SM](const PathDiagnosticPiece &Piece) {
+ AddFID(FM, Fids, *SM, Piece.getLocation().asLocation());
+ ArrayRef<SourceRange> Ranges = Piece.getRanges();
for (const SourceRange &Range : Ranges) {
AddFID(FM, Fids, *SM, Range.getBegin());
AddFID(FM, Fids, *SM, Range.getEnd());
const PathPieces &Path = *WorkList.pop_back_val();
for (const auto &Iter : Path) {
- const PathDiagnosticPiece *Piece = Iter.get();
+ const PathDiagnosticPiece &Piece = *Iter;
AddPieceFID(Piece);
if (const PathDiagnosticCallPiece *Call =
- dyn_cast<PathDiagnosticCallPiece>(Piece)) {
- if (IntrusiveRefCntPtr<PathDiagnosticEventPiece>
- CallEnterWithin = Call->getCallEnterWithinCallerEvent())
- AddPieceFID(CallEnterWithin.get());
+ dyn_cast<PathDiagnosticCallPiece>(&Piece)) {
+ if (auto CallEnterWithin = Call->getCallEnterWithinCallerEvent())
+ AddPieceFID(*CallEnterWithin);
- if (IntrusiveRefCntPtr<PathDiagnosticEventPiece>
- CallEnterEvent = Call->getCallEnterEvent())
- AddPieceFID(CallEnterEvent.get());
+ if (auto CallEnterEvent = Call->getCallEnterEvent())
+ AddPieceFID(*CallEnterEvent);
WorkList.push_back(&Call->path);
- }
- else if (const PathDiagnosticMacroPiece *Macro =
- dyn_cast<PathDiagnosticMacroPiece>(Piece)) {
+ } else if (const PathDiagnosticMacroPiece *Macro =
+ dyn_cast<PathDiagnosticMacroPiece>(&Piece)) {
WorkList.push_back(&Macro->subPieces);
}
}