150bbc165b063155cc23c360deb7b865502e068e2Anna Zaks//===--- BugReporterVisitor.h - Generate PathDiagnostics -------*- C++ -*-===// 250bbc165b063155cc23c360deb7b865502e068e2Anna Zaks// 350bbc165b063155cc23c360deb7b865502e068e2Anna Zaks// The LLVM Compiler Infrastructure 450bbc165b063155cc23c360deb7b865502e068e2Anna Zaks// 550bbc165b063155cc23c360deb7b865502e068e2Anna Zaks// This file is distributed under the University of Illinois Open Source 650bbc165b063155cc23c360deb7b865502e068e2Anna Zaks// License. See LICENSE.TXT for details. 750bbc165b063155cc23c360deb7b865502e068e2Anna Zaks// 850bbc165b063155cc23c360deb7b865502e068e2Anna Zaks//===----------------------------------------------------------------------===// 950bbc165b063155cc23c360deb7b865502e068e2Anna Zaks// 1050bbc165b063155cc23c360deb7b865502e068e2Anna Zaks// This file declares BugReporterVisitors, which are used to generate enhanced 1150bbc165b063155cc23c360deb7b865502e068e2Anna Zaks// diagnostic traces. 1250bbc165b063155cc23c360deb7b865502e068e2Anna Zaks// 1350bbc165b063155cc23c360deb7b865502e068e2Anna Zaks//===----------------------------------------------------------------------===// 1450bbc165b063155cc23c360deb7b865502e068e2Anna Zaks 1550bbc165b063155cc23c360deb7b865502e068e2Anna Zaks#ifndef LLVM_CLANG_GR_BUGREPORTERVISITOR 1650bbc165b063155cc23c360deb7b865502e068e2Anna Zaks#define LLVM_CLANG_GR_BUGREPORTERVISITOR 1750bbc165b063155cc23c360deb7b865502e068e2Anna Zaks 1850bbc165b063155cc23c360deb7b865502e068e2Anna Zaks#include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h" 1950bbc165b063155cc23c360deb7b865502e068e2Anna Zaks#include "llvm/ADT/FoldingSet.h" 2050bbc165b063155cc23c360deb7b865502e068e2Anna Zaks 2150bbc165b063155cc23c360deb7b865502e068e2Anna Zaksnamespace clang { 2250bbc165b063155cc23c360deb7b865502e068e2Anna Zaks 2350bbc165b063155cc23c360deb7b865502e068e2Anna Zaksnamespace ento { 2450bbc165b063155cc23c360deb7b865502e068e2Anna Zaks 2550bbc165b063155cc23c360deb7b865502e068e2Anna Zaksclass BugReport; 2650bbc165b063155cc23c360deb7b865502e068e2Anna Zaksclass BugReporterContext; 2750bbc165b063155cc23c360deb7b865502e068e2Anna Zaksclass ExplodedNode; 2850bbc165b063155cc23c360deb7b865502e068e2Anna Zaksclass MemRegion; 2950bbc165b063155cc23c360deb7b865502e068e2Anna Zaksclass PathDiagnosticPiece; 3050bbc165b063155cc23c360deb7b865502e068e2Anna Zaks 3150bbc165b063155cc23c360deb7b865502e068e2Anna Zaksclass BugReporterVisitor : public llvm::FoldingSetNode { 3250bbc165b063155cc23c360deb7b865502e068e2Anna Zakspublic: 3350bbc165b063155cc23c360deb7b865502e068e2Anna Zaks virtual ~BugReporterVisitor(); 3450bbc165b063155cc23c360deb7b865502e068e2Anna Zaks 3550bbc165b063155cc23c360deb7b865502e068e2Anna Zaks /// \brief Return a diagnostic piece which should be associated with the 3650bbc165b063155cc23c360deb7b865502e068e2Anna Zaks /// given node. 3750bbc165b063155cc23c360deb7b865502e068e2Anna Zaks /// 3850bbc165b063155cc23c360deb7b865502e068e2Anna Zaks /// The last parameter can be used to register a new visitor with the given 3950bbc165b063155cc23c360deb7b865502e068e2Anna Zaks /// BugReport while processing a node. 4050bbc165b063155cc23c360deb7b865502e068e2Anna Zaks virtual PathDiagnosticPiece *VisitNode(const ExplodedNode *N, 4150bbc165b063155cc23c360deb7b865502e068e2Anna Zaks const ExplodedNode *PrevN, 4250bbc165b063155cc23c360deb7b865502e068e2Anna Zaks BugReporterContext &BRC, 4350bbc165b063155cc23c360deb7b865502e068e2Anna Zaks BugReport &BR) = 0; 4450bbc165b063155cc23c360deb7b865502e068e2Anna Zaks 4523f395ee1bf4e4aa76b310d896a951799eaca94aAnna Zaks /// \brief Provide custom definition for the final diagnostic piece on the 4623f395ee1bf4e4aa76b310d896a951799eaca94aAnna Zaks /// path - the piece, which is displayed before the path is expanded. 4723f395ee1bf4e4aa76b310d896a951799eaca94aAnna Zaks /// 4823f395ee1bf4e4aa76b310d896a951799eaca94aAnna Zaks /// If returns NULL the default implementation will be used. 4923f395ee1bf4e4aa76b310d896a951799eaca94aAnna Zaks /// Also note that at most one visitor of a BugReport should generate a 5023f395ee1bf4e4aa76b310d896a951799eaca94aAnna Zaks /// non-NULL end of path diagnostic piece. 5123f395ee1bf4e4aa76b310d896a951799eaca94aAnna Zaks virtual PathDiagnosticPiece *getEndPath(BugReporterContext &BRC, 5223f395ee1bf4e4aa76b310d896a951799eaca94aAnna Zaks const ExplodedNode *N, 5323f395ee1bf4e4aa76b310d896a951799eaca94aAnna Zaks BugReport &BR); 5423f395ee1bf4e4aa76b310d896a951799eaca94aAnna Zaks 5550bbc165b063155cc23c360deb7b865502e068e2Anna Zaks virtual void Profile(llvm::FoldingSetNodeID &ID) const = 0; 5623f395ee1bf4e4aa76b310d896a951799eaca94aAnna Zaks 5723f395ee1bf4e4aa76b310d896a951799eaca94aAnna Zaks /// \brief Generates the default final diagnostic piece. 5823f395ee1bf4e4aa76b310d896a951799eaca94aAnna Zaks static PathDiagnosticPiece *getDefaultEndPath(BugReporterContext &BRC, 5923f395ee1bf4e4aa76b310d896a951799eaca94aAnna Zaks const ExplodedNode *N, 6023f395ee1bf4e4aa76b310d896a951799eaca94aAnna Zaks BugReport &BR); 6123f395ee1bf4e4aa76b310d896a951799eaca94aAnna Zaks 6250bbc165b063155cc23c360deb7b865502e068e2Anna Zaks}; 6350bbc165b063155cc23c360deb7b865502e068e2Anna Zaks 6450bbc165b063155cc23c360deb7b865502e068e2Anna Zaksclass FindLastStoreBRVisitor : public BugReporterVisitor { 6550bbc165b063155cc23c360deb7b865502e068e2Anna Zaks const MemRegion *R; 6650bbc165b063155cc23c360deb7b865502e068e2Anna Zaks SVal V; 6750bbc165b063155cc23c360deb7b865502e068e2Anna Zaks bool satisfied; 6850bbc165b063155cc23c360deb7b865502e068e2Anna Zaks const ExplodedNode *StoreSite; 6950bbc165b063155cc23c360deb7b865502e068e2Anna Zaks 7050bbc165b063155cc23c360deb7b865502e068e2Anna Zakspublic: 7150bbc165b063155cc23c360deb7b865502e068e2Anna Zaks /// \brief Convenience method to create a visitor given only the MemRegion. 7250bbc165b063155cc23c360deb7b865502e068e2Anna Zaks /// Returns NULL if the visitor cannot be created. For example, when the 7350bbc165b063155cc23c360deb7b865502e068e2Anna Zaks /// corresponding value is unknown. 7450bbc165b063155cc23c360deb7b865502e068e2Anna Zaks static BugReporterVisitor *createVisitorObject(const ExplodedNode *N, 7550bbc165b063155cc23c360deb7b865502e068e2Anna Zaks const MemRegion *R); 7650bbc165b063155cc23c360deb7b865502e068e2Anna Zaks 7750bbc165b063155cc23c360deb7b865502e068e2Anna Zaks /// Creates a visitor for every VarDecl inside a Stmt and registers it with 7850bbc165b063155cc23c360deb7b865502e068e2Anna Zaks /// the BugReport. 7950bbc165b063155cc23c360deb7b865502e068e2Anna Zaks static void registerStatementVarDecls(BugReport &BR, const Stmt *S); 8050bbc165b063155cc23c360deb7b865502e068e2Anna Zaks 8150bbc165b063155cc23c360deb7b865502e068e2Anna Zaks FindLastStoreBRVisitor(SVal v, const MemRegion *r) 8250bbc165b063155cc23c360deb7b865502e068e2Anna Zaks : R(r), V(v), satisfied(false), StoreSite(0) { 8350bbc165b063155cc23c360deb7b865502e068e2Anna Zaks assert (!V.isUnknown() && "Cannot track unknown value."); 8450bbc165b063155cc23c360deb7b865502e068e2Anna Zaks 8550bbc165b063155cc23c360deb7b865502e068e2Anna Zaks // TODO: Does it make sense to allow undef values here? 8650bbc165b063155cc23c360deb7b865502e068e2Anna Zaks // (If not, also see UndefCapturedBlockVarChecker)? 8750bbc165b063155cc23c360deb7b865502e068e2Anna Zaks } 8850bbc165b063155cc23c360deb7b865502e068e2Anna Zaks 8950bbc165b063155cc23c360deb7b865502e068e2Anna Zaks void Profile(llvm::FoldingSetNodeID &ID) const; 9050bbc165b063155cc23c360deb7b865502e068e2Anna Zaks 9150bbc165b063155cc23c360deb7b865502e068e2Anna Zaks PathDiagnosticPiece *VisitNode(const ExplodedNode *N, 9250bbc165b063155cc23c360deb7b865502e068e2Anna Zaks const ExplodedNode *PrevN, 9350bbc165b063155cc23c360deb7b865502e068e2Anna Zaks BugReporterContext &BRC, 9450bbc165b063155cc23c360deb7b865502e068e2Anna Zaks BugReport &BR); 9550bbc165b063155cc23c360deb7b865502e068e2Anna Zaks}; 9650bbc165b063155cc23c360deb7b865502e068e2Anna Zaks 9750bbc165b063155cc23c360deb7b865502e068e2Anna Zaksclass TrackConstraintBRVisitor : public BugReporterVisitor { 9850bbc165b063155cc23c360deb7b865502e068e2Anna Zaks DefinedSVal Constraint; 9950bbc165b063155cc23c360deb7b865502e068e2Anna Zaks const bool Assumption; 10050bbc165b063155cc23c360deb7b865502e068e2Anna Zaks bool isSatisfied; 10150bbc165b063155cc23c360deb7b865502e068e2Anna Zaks 10250bbc165b063155cc23c360deb7b865502e068e2Anna Zakspublic: 10350bbc165b063155cc23c360deb7b865502e068e2Anna Zaks TrackConstraintBRVisitor(DefinedSVal constraint, bool assumption) 10450bbc165b063155cc23c360deb7b865502e068e2Anna Zaks : Constraint(constraint), Assumption(assumption), isSatisfied(false) {} 10550bbc165b063155cc23c360deb7b865502e068e2Anna Zaks 10650bbc165b063155cc23c360deb7b865502e068e2Anna Zaks void Profile(llvm::FoldingSetNodeID &ID) const; 10750bbc165b063155cc23c360deb7b865502e068e2Anna Zaks 10850bbc165b063155cc23c360deb7b865502e068e2Anna Zaks PathDiagnosticPiece *VisitNode(const ExplodedNode *N, 10950bbc165b063155cc23c360deb7b865502e068e2Anna Zaks const ExplodedNode *PrevN, 11050bbc165b063155cc23c360deb7b865502e068e2Anna Zaks BugReporterContext &BRC, 11150bbc165b063155cc23c360deb7b865502e068e2Anna Zaks BugReport &BR); 11250bbc165b063155cc23c360deb7b865502e068e2Anna Zaks}; 11350bbc165b063155cc23c360deb7b865502e068e2Anna Zaks 11450bbc165b063155cc23c360deb7b865502e068e2Anna Zaksclass NilReceiverBRVisitor : public BugReporterVisitor { 11550bbc165b063155cc23c360deb7b865502e068e2Anna Zakspublic: 11650bbc165b063155cc23c360deb7b865502e068e2Anna Zaks void Profile(llvm::FoldingSetNodeID &ID) const { 11750bbc165b063155cc23c360deb7b865502e068e2Anna Zaks static int x = 0; 11850bbc165b063155cc23c360deb7b865502e068e2Anna Zaks ID.AddPointer(&x); 11950bbc165b063155cc23c360deb7b865502e068e2Anna Zaks } 12050bbc165b063155cc23c360deb7b865502e068e2Anna Zaks 12150bbc165b063155cc23c360deb7b865502e068e2Anna Zaks PathDiagnosticPiece *VisitNode(const ExplodedNode *N, 12250bbc165b063155cc23c360deb7b865502e068e2Anna Zaks const ExplodedNode *PrevN, 12350bbc165b063155cc23c360deb7b865502e068e2Anna Zaks BugReporterContext &BRC, 12450bbc165b063155cc23c360deb7b865502e068e2Anna Zaks BugReport &BR); 12550bbc165b063155cc23c360deb7b865502e068e2Anna Zaks}; 12650bbc165b063155cc23c360deb7b865502e068e2Anna Zaks 12750bbc165b063155cc23c360deb7b865502e068e2Anna Zaks/// Visitor that tries to report interesting diagnostics from conditions. 12850bbc165b063155cc23c360deb7b865502e068e2Anna Zaksclass ConditionBRVisitor : public BugReporterVisitor { 12950bbc165b063155cc23c360deb7b865502e068e2Anna Zakspublic: 13050bbc165b063155cc23c360deb7b865502e068e2Anna Zaks void Profile(llvm::FoldingSetNodeID &ID) const { 13150bbc165b063155cc23c360deb7b865502e068e2Anna Zaks static int x = 0; 13250bbc165b063155cc23c360deb7b865502e068e2Anna Zaks ID.AddPointer(&x); 13350bbc165b063155cc23c360deb7b865502e068e2Anna Zaks } 13450bbc165b063155cc23c360deb7b865502e068e2Anna Zaks 13550bbc165b063155cc23c360deb7b865502e068e2Anna Zaks virtual PathDiagnosticPiece *VisitNode(const ExplodedNode *N, 13650bbc165b063155cc23c360deb7b865502e068e2Anna Zaks const ExplodedNode *Prev, 13750bbc165b063155cc23c360deb7b865502e068e2Anna Zaks BugReporterContext &BRC, 13850bbc165b063155cc23c360deb7b865502e068e2Anna Zaks BugReport &BR); 13950bbc165b063155cc23c360deb7b865502e068e2Anna Zaks 14050bbc165b063155cc23c360deb7b865502e068e2Anna Zaks PathDiagnosticPiece *VisitTerminator(const Stmt *Term, 141220ac8c175cb1bf9b18d82eefe036995d7a2164dAnna Zaks const ExplodedNode *N, 14250bbc165b063155cc23c360deb7b865502e068e2Anna Zaks const CFGBlock *srcBlk, 14350bbc165b063155cc23c360deb7b865502e068e2Anna Zaks const CFGBlock *dstBlk, 14450bbc165b063155cc23c360deb7b865502e068e2Anna Zaks BugReporterContext &BRC); 14550bbc165b063155cc23c360deb7b865502e068e2Anna Zaks 14650bbc165b063155cc23c360deb7b865502e068e2Anna Zaks PathDiagnosticPiece *VisitTrueTest(const Expr *Cond, 14750bbc165b063155cc23c360deb7b865502e068e2Anna Zaks bool tookTrue, 148220ac8c175cb1bf9b18d82eefe036995d7a2164dAnna Zaks BugReporterContext &BRC, 149220ac8c175cb1bf9b18d82eefe036995d7a2164dAnna Zaks const LocationContext *LC); 15050bbc165b063155cc23c360deb7b865502e068e2Anna Zaks 15150bbc165b063155cc23c360deb7b865502e068e2Anna Zaks PathDiagnosticPiece *VisitTrueTest(const Expr *Cond, 15250bbc165b063155cc23c360deb7b865502e068e2Anna Zaks const DeclRefExpr *DR, 15350bbc165b063155cc23c360deb7b865502e068e2Anna Zaks const bool tookTrue, 154220ac8c175cb1bf9b18d82eefe036995d7a2164dAnna Zaks BugReporterContext &BRC, 155220ac8c175cb1bf9b18d82eefe036995d7a2164dAnna Zaks const LocationContext *LC); 15650bbc165b063155cc23c360deb7b865502e068e2Anna Zaks 15750bbc165b063155cc23c360deb7b865502e068e2Anna Zaks PathDiagnosticPiece *VisitTrueTest(const Expr *Cond, 15850bbc165b063155cc23c360deb7b865502e068e2Anna Zaks const BinaryOperator *BExpr, 15950bbc165b063155cc23c360deb7b865502e068e2Anna Zaks const bool tookTrue, 160220ac8c175cb1bf9b18d82eefe036995d7a2164dAnna Zaks BugReporterContext &BRC, 161220ac8c175cb1bf9b18d82eefe036995d7a2164dAnna Zaks const LocationContext *LC); 16250bbc165b063155cc23c360deb7b865502e068e2Anna Zaks 16350bbc165b063155cc23c360deb7b865502e068e2Anna Zaks bool patternMatch(const Expr *Ex, 16450bbc165b063155cc23c360deb7b865502e068e2Anna Zaks llvm::raw_ostream &Out, 16550bbc165b063155cc23c360deb7b865502e068e2Anna Zaks BugReporterContext &BRC); 16650bbc165b063155cc23c360deb7b865502e068e2Anna Zaks}; 16750bbc165b063155cc23c360deb7b865502e068e2Anna Zaks 16850bbc165b063155cc23c360deb7b865502e068e2Anna Zaksnamespace bugreporter { 16950bbc165b063155cc23c360deb7b865502e068e2Anna Zaks 17050bbc165b063155cc23c360deb7b865502e068e2Anna ZaksBugReporterVisitor *getTrackNullOrUndefValueVisitor(const ExplodedNode *N, 17150bbc165b063155cc23c360deb7b865502e068e2Anna Zaks const Stmt *S); 17250bbc165b063155cc23c360deb7b865502e068e2Anna Zaks 17350bbc165b063155cc23c360deb7b865502e068e2Anna Zaksconst Stmt *GetDerefExpr(const ExplodedNode *N); 17450bbc165b063155cc23c360deb7b865502e068e2Anna Zaksconst Stmt *GetDenomExpr(const ExplodedNode *N); 17550bbc165b063155cc23c360deb7b865502e068e2Anna Zaksconst Stmt *GetCalleeExpr(const ExplodedNode *N); 17650bbc165b063155cc23c360deb7b865502e068e2Anna Zaksconst Stmt *GetRetValExpr(const ExplodedNode *N); 17750bbc165b063155cc23c360deb7b865502e068e2Anna Zaks 17850bbc165b063155cc23c360deb7b865502e068e2Anna Zaks} // end namespace clang 17950bbc165b063155cc23c360deb7b865502e068e2Anna Zaks} // end namespace ento 18050bbc165b063155cc23c360deb7b865502e068e2Anna Zaks} // end namespace bugreporter 18150bbc165b063155cc23c360deb7b865502e068e2Anna Zaks 18250bbc165b063155cc23c360deb7b865502e068e2Anna Zaks 18350bbc165b063155cc23c360deb7b865502e068e2Anna Zaks#endif //LLVM_CLANG_GR__BUGREPORTERVISITOR 184