BugReporter.h revision 18c66fdc3c4008d335885695fe36fb5353c5f672
1db0e15ae3e2b5e180541eec35e2bce54359ca7d8Zhongxing Xu//===--- BugReporter.h - Generate PathDiagnostics --------------*- C++ -*-===// 261f3e058056ab519d249aa67e3d52b0ead57c63eTed Kremenek// 361f3e058056ab519d249aa67e3d52b0ead57c63eTed Kremenek// The LLVM Compiler Infrastructure 461f3e058056ab519d249aa67e3d52b0ead57c63eTed Kremenek// 561f3e058056ab519d249aa67e3d52b0ead57c63eTed Kremenek// This file is distributed under the University of Illinois Open Source 661f3e058056ab519d249aa67e3d52b0ead57c63eTed Kremenek// License. See LICENSE.TXT for details. 761f3e058056ab519d249aa67e3d52b0ead57c63eTed Kremenek// 861f3e058056ab519d249aa67e3d52b0ead57c63eTed Kremenek//===----------------------------------------------------------------------===// 961f3e058056ab519d249aa67e3d52b0ead57c63eTed Kremenek// 1061f3e058056ab519d249aa67e3d52b0ead57c63eTed Kremenek// This file defines BugReporter, a utility class for generating 1118c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek// PathDiagnostics for analyses based on ProgramState. 1261f3e058056ab519d249aa67e3d52b0ead57c63eTed Kremenek// 1361f3e058056ab519d249aa67e3d52b0ead57c63eTed Kremenek//===----------------------------------------------------------------------===// 1461f3e058056ab519d249aa67e3d52b0ead57c63eTed Kremenek 155a4f98ff943e6a501b0fe47ade007c9bbf96cb88Argyrios Kyrtzidis#ifndef LLVM_CLANG_GR_BUGREPORTER 165a4f98ff943e6a501b0fe47ade007c9bbf96cb88Argyrios Kyrtzidis#define LLVM_CLANG_GR_BUGREPORTER 1761f3e058056ab519d249aa67e3d52b0ead57c63eTed Kremenek 18d2f642b56e87493edfc3b0dab359b5e32d5f8a5eTed Kremenek#include "clang/Basic/SourceLocation.h" 1918c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h" 201b431023814196f87515a540ebcb9e9f1a9176a1Ted Kremenek#include "llvm/ADT/FoldingSet.h" 211b431023814196f87515a540ebcb9e9f1a9176a1Ted Kremenek#include "llvm/ADT/ImmutableList.h" 221b431023814196f87515a540ebcb9e9f1a9176a1Ted Kremenek#include "llvm/ADT/ImmutableSet.h" 23f377fc85488f4799ced714ac60e65a0e3f8f69cbTed Kremenek#include "llvm/ADT/SmallSet.h" 24e207558e9dbed963eebf5cf31fdb02616f1545a3Ted Kremenek#include <list> 25e207558e9dbed963eebf5cf31fdb02616f1545a3Ted Kremenek 2661f3e058056ab519d249aa67e3d52b0ead57c63eTed Kremeneknamespace clang { 271eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 285a4f98ff943e6a501b0fe47ade007c9bbf96cb88Argyrios Kyrtzidisclass ASTContext; 295a4f98ff943e6a501b0fe47ade007c9bbf96cb88Argyrios Kyrtzidisclass Diagnostic; 305a4f98ff943e6a501b0fe47ade007c9bbf96cb88Argyrios Kyrtzidisclass Stmt; 315a4f98ff943e6a501b0fe47ade007c9bbf96cb88Argyrios Kyrtzidisclass ParentMap; 325a4f98ff943e6a501b0fe47ade007c9bbf96cb88Argyrios Kyrtzidis 339ef6537a894c33003359b1f9b9676e9178e028b7Ted Kremeneknamespace ento { 345a4f98ff943e6a501b0fe47ade007c9bbf96cb88Argyrios Kyrtzidis 3561f3e058056ab519d249aa67e3d52b0ead57c63eTed Kremenekclass PathDiagnostic; 3661f3e058056ab519d249aa67e3d52b0ead57c63eTed Kremenekclass PathDiagnosticPiece; 3761f3e058056ab519d249aa67e3d52b0ead57c63eTed Kremenekclass PathDiagnosticClient; 385e2d2c2ee3cf410643e0f9a5701708e51409d973Benjamin Kramerclass ExplodedNode; 395e2d2c2ee3cf410643e0f9a5701708e51409d973Benjamin Kramerclass ExplodedGraph; 4050a6d0ce344c02782e0207574005c3b2aaa5077cTed Kremenekclass BugReporter; 418966bc1c8ce271c09936c0eaf6c841aef4a0af1bTed Kremenekclass BugReporterContext; 42d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidisclass ExprEngine; 4318c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenekclass ProgramState; 44cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenekclass BugType; 451eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 46cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek//===----------------------------------------------------------------------===// 47cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek// Interface for individual bug reports. 48cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek//===----------------------------------------------------------------------===// 498966bc1c8ce271c09936c0eaf6c841aef4a0af1bTed Kremenek 501b431023814196f87515a540ebcb9e9f1a9176a1Ted Kremenekclass BugReporterVisitor : public llvm::FoldingSetNode { 518966bc1c8ce271c09936c0eaf6c841aef4a0af1bTed Kremenekpublic: 528966bc1c8ce271c09936c0eaf6c841aef4a0af1bTed Kremenek virtual ~BugReporterVisitor(); 539c378f705405d37f49795d5e915989de774fe11fTed Kremenek virtual PathDiagnosticPiece *VisitNode(const ExplodedNode *N, 549c378f705405d37f49795d5e915989de774fe11fTed Kremenek const ExplodedNode *PrevN, 559c378f705405d37f49795d5e915989de774fe11fTed Kremenek BugReporterContext &BRC) = 0; 561eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 578966bc1c8ce271c09936c0eaf6c841aef4a0af1bTed Kremenek virtual bool isOwnedByReporterContext() { return true; } 581b431023814196f87515a540ebcb9e9f1a9176a1Ted Kremenek virtual void Profile(llvm::FoldingSetNodeID &ID) const = 0; 598966bc1c8ce271c09936c0eaf6c841aef4a0af1bTed Kremenek}; 601eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 61cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek// FIXME: Combine this with RangedBugReport and remove RangedBugReport. 628966bc1c8ce271c09936c0eaf6c841aef4a0af1bTed Kremenekclass BugReport : public BugReporterVisitor { 637a9bb52171f962d51ab13c1e012d2236feb9558dTed Kremenekprotected: 64cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek BugType& BT; 65d49967f8764135ae65658e354b6d38e3637c9de3Ted Kremenek std::string ShortDescription; 66cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek std::string Description; 67212f6d3b5fb3fa55ba1e40671cfc336430abc8ddTom Care const ExplodedNode *ErrorNode; 68640ccf071076e684713cc3c3276bb51982bff607Argyrios Kyrtzidis mutable SourceRange R; 691eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 70cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenekprotected: 71cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek friend class BugReporter; 72cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek friend class BugReportEquivClass; 73cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek 74cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek virtual void Profile(llvm::FoldingSetNodeID& hash) const { 75404fc3ad6bd844bf8ce70cbf9974ab297704a122Argyrios Kyrtzidis hash.AddPointer(&BT); 76cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek hash.AddInteger(getLocation().getRawEncoding()); 771a0c8b9183fde84982aea9190a55fde1541c432dTed Kremenek hash.AddString(Description); 78072192bcbb05a0fee7ec3061750b27e8d2004952Ted Kremenek } 791eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 8050a6d0ce344c02782e0207574005c3b2aaa5077cTed Kremenekpublic: 81fe9e543a2a363df7fcaa899367d3b2580b63b27cTed Kremenek class NodeResolver { 82fe9e543a2a363df7fcaa899367d3b2580b63b27cTed Kremenek public: 83fe9e543a2a363df7fcaa899367d3b2580b63b27cTed Kremenek virtual ~NodeResolver() {} 84c5619d901a68dc27a9e310a6a831f03efebcd950Zhongxing Xu virtual const ExplodedNode* 859c378f705405d37f49795d5e915989de774fe11fTed Kremenek getOriginalNode(const ExplodedNode *N) = 0; 86fe9e543a2a363df7fcaa899367d3b2580b63b27cTed Kremenek }; 871eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 88686775deca8b8685eb90801495880e3abdd844c2Chris Lattner BugReport(BugType& bt, StringRef desc, const ExplodedNode *errornode) 89212f6d3b5fb3fa55ba1e40671cfc336430abc8ddTom Care : BT(bt), Description(desc), ErrorNode(errornode) {} 901eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 91686775deca8b8685eb90801495880e3abdd844c2Chris Lattner BugReport(BugType& bt, StringRef shortDesc, StringRef desc, 92212f6d3b5fb3fa55ba1e40671cfc336430abc8ddTom Care const ExplodedNode *errornode) 93212f6d3b5fb3fa55ba1e40671cfc336430abc8ddTom Care : BT(bt), ShortDescription(shortDesc), Description(desc), 94212f6d3b5fb3fa55ba1e40671cfc336430abc8ddTom Care ErrorNode(errornode) {} 95d49967f8764135ae65658e354b6d38e3637c9de3Ted Kremenek 9650a6d0ce344c02782e0207574005c3b2aaa5077cTed Kremenek virtual ~BugReport(); 971eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 988966bc1c8ce271c09936c0eaf6c841aef4a0af1bTed Kremenek virtual bool isOwnedByReporterContext() { return false; } 99cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek 100cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek const BugType& getBugType() const { return BT; } 101cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek BugType& getBugType() { return BT; } 1021eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 103cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek // FIXME: Perhaps this should be moved into a subclass? 1049c378f705405d37f49795d5e915989de774fe11fTed Kremenek const ExplodedNode *getErrorNode() const { return ErrorNode; } 1051eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 106cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek // FIXME: Do we need this? Maybe getLocation() should return a ProgramPoint 107cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek // object. 1088966bc1c8ce271c09936c0eaf6c841aef4a0af1bTed Kremenek // FIXME: If we do need it, we can probably just make it private to 1098966bc1c8ce271c09936c0eaf6c841aef4a0af1bTed Kremenek // BugReporter. 1109c378f705405d37f49795d5e915989de774fe11fTed Kremenek const Stmt *getStmt() const; 1111eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 112686775deca8b8685eb90801495880e3abdd844c2Chris Lattner const StringRef getDescription() const { return Description; } 113d49967f8764135ae65658e354b6d38e3637c9de3Ted Kremenek 114686775deca8b8685eb90801495880e3abdd844c2Chris Lattner const StringRef getShortDescription() const { 115d49967f8764135ae65658e354b6d38e3637c9de3Ted Kremenek return ShortDescription.empty() ? Description : ShortDescription; 116d49967f8764135ae65658e354b6d38e3637c9de3Ted Kremenek } 1171eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 118cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek // FIXME: Is this needed? 119072192bcbb05a0fee7ec3061750b27e8d2004952Ted Kremenek virtual std::pair<const char**,const char**> getExtraDescriptiveText() { 120cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek return std::make_pair((const char**)0,(const char**)0); 121072192bcbb05a0fee7ec3061750b27e8d2004952Ted Kremenek } 1221eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 123cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek // FIXME: Perhaps move this into a subclass. 1249c378f705405d37f49795d5e915989de774fe11fTed Kremenek virtual PathDiagnosticPiece *getEndPath(BugReporterContext &BRC, 1259c378f705405d37f49795d5e915989de774fe11fTed Kremenek const ExplodedNode *N); 1261eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 127cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek /// getLocation - Return the "definitive" location of the reported bug. 128cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek /// While a bug can span an entire path, usually there is a specific 129fc8f0e14ad142ed811e90fbd9a30e419e301c717Chris Lattner /// location that can be used to identify where the key issue occurred. 130cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek /// This location is used by clients rendering diagnostics. 131cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek virtual SourceLocation getLocation() const; 1321eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 133640ccf071076e684713cc3c3276bb51982bff607Argyrios Kyrtzidis typedef const SourceRange *ranges_iterator; 134640ccf071076e684713cc3c3276bb51982bff607Argyrios Kyrtzidis 135cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek /// getRanges - Returns the source ranges associated with this bug. 136640ccf071076e684713cc3c3276bb51982bff607Argyrios Kyrtzidis virtual std::pair<ranges_iterator, ranges_iterator> getRanges() const; 137cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek 1389c378f705405d37f49795d5e915989de774fe11fTed Kremenek virtual PathDiagnosticPiece *VisitNode(const ExplodedNode *N, 1399c378f705405d37f49795d5e915989de774fe11fTed Kremenek const ExplodedNode *PrevN, 1409c378f705405d37f49795d5e915989de774fe11fTed Kremenek BugReporterContext &BR); 1411eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1429c378f705405d37f49795d5e915989de774fe11fTed Kremenek virtual void registerInitialVisitors(BugReporterContext &BRC, 1439c378f705405d37f49795d5e915989de774fe11fTed Kremenek const ExplodedNode *N) {} 1446837faa083bebad39aa342f84c2b450fb6410eafTed Kremenek}; 145cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek 146cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek//===----------------------------------------------------------------------===// 147cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek// BugTypes (collections of related reports). 148cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek//===----------------------------------------------------------------------===// 1491eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 150cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenekclass BugReportEquivClass : public llvm::FoldingSetNode { 151cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek // List of *owned* BugReport objects. 152cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek std::list<BugReport*> Reports; 1531eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 154cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek friend class BugReporter; 155cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek void AddReport(BugReport* R) { Reports.push_back(R); } 156cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenekpublic: 157cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek BugReportEquivClass(BugReport* R) { Reports.push_back(R); } 158cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek ~BugReportEquivClass(); 159cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek 160cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek void Profile(llvm::FoldingSetNodeID& ID) const { 161cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek assert(!Reports.empty()); 162cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek (*Reports.begin())->Profile(ID); 163cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek } 164cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek 165cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek class iterator { 166cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek std::list<BugReport*>::iterator impl; 167cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek public: 168cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek iterator(std::list<BugReport*>::iterator i) : impl(i) {} 1699c378f705405d37f49795d5e915989de774fe11fTed Kremenek iterator &operator++() { ++impl; return *this; } 1709c378f705405d37f49795d5e915989de774fe11fTed Kremenek bool operator==(const iterator &I) const { return I.impl == impl; } 1719c378f705405d37f49795d5e915989de774fe11fTed Kremenek bool operator!=(const iterator &I) const { return I.impl != impl; } 172cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek BugReport* operator*() const { return *impl; } 173cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek BugReport* operator->() const { return *impl; } 174cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek }; 1751eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1763aa1ab27c14d16c853ccb61f17a4a75d8e366806Ted Kremenek class const_iterator { 1773aa1ab27c14d16c853ccb61f17a4a75d8e366806Ted Kremenek std::list<BugReport*>::const_iterator impl; 1783aa1ab27c14d16c853ccb61f17a4a75d8e366806Ted Kremenek public: 1793aa1ab27c14d16c853ccb61f17a4a75d8e366806Ted Kremenek const_iterator(std::list<BugReport*>::const_iterator i) : impl(i) {} 1809c378f705405d37f49795d5e915989de774fe11fTed Kremenek const_iterator &operator++() { ++impl; return *this; } 1819c378f705405d37f49795d5e915989de774fe11fTed Kremenek bool operator==(const const_iterator &I) const { return I.impl == impl; } 1829c378f705405d37f49795d5e915989de774fe11fTed Kremenek bool operator!=(const const_iterator &I) const { return I.impl != impl; } 1833aa1ab27c14d16c853ccb61f17a4a75d8e366806Ted Kremenek const BugReport* operator*() const { return *impl; } 1843aa1ab27c14d16c853ccb61f17a4a75d8e366806Ted Kremenek const BugReport* operator->() const { return *impl; } 1853aa1ab27c14d16c853ccb61f17a4a75d8e366806Ted Kremenek }; 1861eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 187cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek iterator begin() { return iterator(Reports.begin()); } 188cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek iterator end() { return iterator(Reports.end()); } 1891eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1903aa1ab27c14d16c853ccb61f17a4a75d8e366806Ted Kremenek const_iterator begin() const { return const_iterator(Reports.begin()); } 1913aa1ab27c14d16c853ccb61f17a4a75d8e366806Ted Kremenek const_iterator end() const { return const_iterator(Reports.end()); } 192cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek}; 1931eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1941eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 195cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek//===----------------------------------------------------------------------===// 196cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek// Specialized subclasses of BugReport. 197cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek//===----------------------------------------------------------------------===// 1981eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 199cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek// FIXME: Collapse this with the default BugReport class. 200d2f642b56e87493edfc3b0dab359b5e32d5f8a5eTed Kremenekclass RangedBugReport : public BugReport { 201686775deca8b8685eb90801495880e3abdd844c2Chris Lattner SmallVector<SourceRange, 4> Ranges; 2025e55cda64f4452fa65d83f66390c7126a8b248bbTed Kremenekpublic: 203686775deca8b8685eb90801495880e3abdd844c2Chris Lattner RangedBugReport(BugType& D, StringRef description, 204212f6d3b5fb3fa55ba1e40671cfc336430abc8ddTom Care ExplodedNode *errornode) 205212f6d3b5fb3fa55ba1e40671cfc336430abc8ddTom Care : BugReport(D, description, errornode) {} 2061eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 207686775deca8b8685eb90801495880e3abdd844c2Chris Lattner RangedBugReport(BugType& D, StringRef shortDescription, 208686775deca8b8685eb90801495880e3abdd844c2Chris Lattner StringRef description, ExplodedNode *errornode) 209212f6d3b5fb3fa55ba1e40671cfc336430abc8ddTom Care : BugReport(D, shortDescription, description, errornode) {} 2101eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 211cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek ~RangedBugReport(); 21222bda887aacd0e591978541a799aa43835652ec9Ted Kremenek 213cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek // FIXME: Move this out of line. 21494fd0b8c88db9b1cd99457d3cd8cd333341dd39cTed Kremenek void addRange(SourceRange R) { 215a5083e6ab51b031241152e81457240497ab9bff9Ted Kremenek assert(R.isValid()); 216a5083e6ab51b031241152e81457240497ab9bff9Ted Kremenek Ranges.push_back(R); 217a5083e6ab51b031241152e81457240497ab9bff9Ted Kremenek } 2181eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 219640ccf071076e684713cc3c3276bb51982bff607Argyrios Kyrtzidis virtual std::pair<ranges_iterator, ranges_iterator> getRanges() const { 220640ccf071076e684713cc3c3276bb51982bff607Argyrios Kyrtzidis return std::make_pair(Ranges.begin(), Ranges.end()); 2215e55cda64f4452fa65d83f66390c7126a8b248bbTed Kremenek } 2229fc90c1bf7498dc53862156205ab95868b8b849fTed Kremenek 2239fc90c1bf7498dc53862156205ab95868b8b849fTed Kremenek virtual void Profile(llvm::FoldingSetNodeID& hash) const { 2249fc90c1bf7498dc53862156205ab95868b8b849fTed Kremenek BugReport::Profile(hash); 225686775deca8b8685eb90801495880e3abdd844c2Chris Lattner for (SmallVectorImpl<SourceRange>::const_iterator I = 2269fc90c1bf7498dc53862156205ab95868b8b849fTed Kremenek Ranges.begin(), E = Ranges.end(); I != E; ++I) { 2279fc90c1bf7498dc53862156205ab95868b8b849fTed Kremenek const SourceRange range = *I; 2289fc90c1bf7498dc53862156205ab95868b8b849fTed Kremenek if (!range.isValid()) 2299fc90c1bf7498dc53862156205ab95868b8b849fTed Kremenek continue; 2309fc90c1bf7498dc53862156205ab95868b8b849fTed Kremenek hash.AddInteger(range.getBegin().getRawEncoding()); 2319fc90c1bf7498dc53862156205ab95868b8b849fTed Kremenek hash.AddInteger(range.getEnd().getRawEncoding()); 2329fc90c1bf7498dc53862156205ab95868b8b849fTed Kremenek } 2339fc90c1bf7498dc53862156205ab95868b8b849fTed Kremenek } 2345e55cda64f4452fa65d83f66390c7126a8b248bbTed Kremenek}; 2351eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 236592362b46ad69db0db0988e7f9d8cbe647510bddTed Kremenekclass EnhancedBugReport : public RangedBugReport { 237592362b46ad69db0db0988e7f9d8cbe647510bddTed Kremenekpublic: 238592362b46ad69db0db0988e7f9d8cbe647510bddTed Kremenek typedef void (*VisitorCreator)(BugReporterContext &BRcC, const void *data, 239592362b46ad69db0db0988e7f9d8cbe647510bddTed Kremenek const ExplodedNode *N); 2401eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 241592362b46ad69db0db0988e7f9d8cbe647510bddTed Kremenekprivate: 242592362b46ad69db0db0988e7f9d8cbe647510bddTed Kremenek typedef std::vector<std::pair<VisitorCreator, const void*> > Creators; 243592362b46ad69db0db0988e7f9d8cbe647510bddTed Kremenek Creators creators; 2441eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 245592362b46ad69db0db0988e7f9d8cbe647510bddTed Kremenekpublic: 246686775deca8b8685eb90801495880e3abdd844c2Chris Lattner EnhancedBugReport(BugType& D, StringRef description, 247212f6d3b5fb3fa55ba1e40671cfc336430abc8ddTom Care ExplodedNode *errornode) 248212f6d3b5fb3fa55ba1e40671cfc336430abc8ddTom Care : RangedBugReport(D, description, errornode) {} 2491eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 250686775deca8b8685eb90801495880e3abdd844c2Chris Lattner EnhancedBugReport(BugType& D, StringRef shortDescription, 251686775deca8b8685eb90801495880e3abdd844c2Chris Lattner StringRef description, ExplodedNode *errornode) 252212f6d3b5fb3fa55ba1e40671cfc336430abc8ddTom Care : RangedBugReport(D, shortDescription, description, errornode) {} 2531eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 254592362b46ad69db0db0988e7f9d8cbe647510bddTed Kremenek ~EnhancedBugReport() {} 2551eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 2569c378f705405d37f49795d5e915989de774fe11fTed Kremenek void registerInitialVisitors(BugReporterContext &BRC, const ExplodedNode *N) { 257592362b46ad69db0db0988e7f9d8cbe647510bddTed Kremenek for (Creators::iterator I = creators.begin(), E = creators.end(); I!=E; ++I) 258592362b46ad69db0db0988e7f9d8cbe647510bddTed Kremenek I->first(BRC, I->second, N); 259592362b46ad69db0db0988e7f9d8cbe647510bddTed Kremenek } 2601eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 261592362b46ad69db0db0988e7f9d8cbe647510bddTed Kremenek void addVisitorCreator(VisitorCreator creator, const void *data) { 262592362b46ad69db0db0988e7f9d8cbe647510bddTed Kremenek creators.push_back(std::make_pair(creator, data)); 263592362b46ad69db0db0988e7f9d8cbe647510bddTed Kremenek } 264592362b46ad69db0db0988e7f9d8cbe647510bddTed Kremenek}; 2651eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 266cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek//===----------------------------------------------------------------------===// 267cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek// BugReporter and friends. 268cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek//===----------------------------------------------------------------------===// 269cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek 270c095997b853270d8adb6fe55209a4dbc42803d16Ted Kremenekclass BugReporterData { 271c095997b853270d8adb6fe55209a4dbc42803d16Ted Kremenekpublic: 272c095997b853270d8adb6fe55209a4dbc42803d16Ted Kremenek virtual ~BugReporterData(); 2731eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump virtual Diagnostic& getDiagnostic() = 0; 2741eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump virtual PathDiagnosticClient* getPathDiagnosticClient() = 0; 2759c378f705405d37f49795d5e915989de774fe11fTed Kremenek virtual ASTContext &getASTContext() = 0; 276c095997b853270d8adb6fe55209a4dbc42803d16Ted Kremenek virtual SourceManager& getSourceManager() = 0; 277c095997b853270d8adb6fe55209a4dbc42803d16Ted Kremenek}; 2781eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 27961f3e058056ab519d249aa67e3d52b0ead57c63eTed Kremenekclass BugReporter { 280c095997b853270d8adb6fe55209a4dbc42803d16Ted Kremenekpublic: 281c095997b853270d8adb6fe55209a4dbc42803d16Ted Kremenek enum Kind { BaseBRKind, GRBugReporterKind }; 282c095997b853270d8adb6fe55209a4dbc42803d16Ted Kremenek 283cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenekprivate: 284cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek typedef llvm::ImmutableSet<BugType*> BugTypesTy; 285cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek BugTypesTy::Factory F; 286cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek BugTypesTy BugTypes; 287cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek 2881eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump const Kind kind; 289c095997b853270d8adb6fe55209a4dbc42803d16Ted Kremenek BugReporterData& D; 2901eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 291cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek void FlushReport(BugReportEquivClass& EQ); 292cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek 293404fc3ad6bd844bf8ce70cbf9974ab297704a122Argyrios Kyrtzidis llvm::FoldingSet<BugReportEquivClass> EQClasses; 294404fc3ad6bd844bf8ce70cbf9974ab297704a122Argyrios Kyrtzidis 295cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenekprotected: 2963baf672378f105602d2b12f03f00277ae1936fe9Ted Kremenek BugReporter(BugReporterData& d, Kind k) : BugTypes(F.getEmptySet()), kind(k), 297212f6d3b5fb3fa55ba1e40671cfc336430abc8ddTom Care D(d) {} 298cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek 29961f3e058056ab519d249aa67e3d52b0ead57c63eTed Kremenekpublic: 3003baf672378f105602d2b12f03f00277ae1936fe9Ted Kremenek BugReporter(BugReporterData& d) : BugTypes(F.getEmptySet()), kind(BaseBRKind), 301212f6d3b5fb3fa55ba1e40671cfc336430abc8ddTom Care D(d) {} 302c095997b853270d8adb6fe55209a4dbc42803d16Ted Kremenek virtual ~BugReporter(); 3031eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 304cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek void FlushReports(); 3051eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 306c095997b853270d8adb6fe55209a4dbc42803d16Ted Kremenek Kind getKind() const { return kind; } 3071eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 308c095997b853270d8adb6fe55209a4dbc42803d16Ted Kremenek Diagnostic& getDiagnostic() { 309c095997b853270d8adb6fe55209a4dbc42803d16Ted Kremenek return D.getDiagnostic(); 310c095997b853270d8adb6fe55209a4dbc42803d16Ted Kremenek } 3111eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 312c095997b853270d8adb6fe55209a4dbc42803d16Ted Kremenek PathDiagnosticClient* getPathDiagnosticClient() { 313c095997b853270d8adb6fe55209a4dbc42803d16Ted Kremenek return D.getPathDiagnosticClient(); 314c095997b853270d8adb6fe55209a4dbc42803d16Ted Kremenek } 3151eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 3163aa1ab27c14d16c853ccb61f17a4a75d8e366806Ted Kremenek typedef BugTypesTy::iterator iterator; 3173aa1ab27c14d16c853ccb61f17a4a75d8e366806Ted Kremenek iterator begin() { return BugTypes.begin(); } 3183aa1ab27c14d16c853ccb61f17a4a75d8e366806Ted Kremenek iterator end() { return BugTypes.end(); } 3191eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 320404fc3ad6bd844bf8ce70cbf9974ab297704a122Argyrios Kyrtzidis typedef llvm::FoldingSet<BugReportEquivClass>::iterator EQClasses_iterator; 321404fc3ad6bd844bf8ce70cbf9974ab297704a122Argyrios Kyrtzidis EQClasses_iterator EQClasses_begin() { return EQClasses.begin(); } 322404fc3ad6bd844bf8ce70cbf9974ab297704a122Argyrios Kyrtzidis EQClasses_iterator EQClasses_end() { return EQClasses.end(); } 323404fc3ad6bd844bf8ce70cbf9974ab297704a122Argyrios Kyrtzidis 3249c378f705405d37f49795d5e915989de774fe11fTed Kremenek ASTContext &getContext() { return D.getASTContext(); } 3251eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 326cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek SourceManager& getSourceManager() { return D.getSourceManager(); } 3271eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 32840406fe63df2b932d6e9fd021f77f097f9d33afbTed Kremenek virtual void GeneratePathDiagnostic(PathDiagnostic& pathDiagnostic, 329686775deca8b8685eb90801495880e3abdd844c2Chris Lattner SmallVectorImpl<BugReport *> &bugReports) {} 33061f3e058056ab519d249aa67e3d52b0ead57c63eTed Kremenek 331cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek void Register(BugType *BT); 3321eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 333cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek void EmitReport(BugReport *R); 3341eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 335686775deca8b8685eb90801495880e3abdd844c2Chris Lattner void EmitBasicReport(StringRef BugName, StringRef BugStr, 3368f2698621f5090db1dea691059bd0ebd79fb7f14Ted Kremenek SourceLocation Loc, 3378f2698621f5090db1dea691059bd0ebd79fb7f14Ted Kremenek SourceRange* RangeBeg, unsigned NumRanges); 3388f2698621f5090db1dea691059bd0ebd79fb7f14Ted Kremenek 339686775deca8b8685eb90801495880e3abdd844c2Chris Lattner void EmitBasicReport(StringRef BugName, StringRef BugCategory, 340686775deca8b8685eb90801495880e3abdd844c2Chris Lattner StringRef BugStr, SourceLocation Loc, 3418c036c7f77d69f96df49219ed0bdbade200d52ebTed Kremenek SourceRange* RangeBeg, unsigned NumRanges); 3421eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 3431eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 344686775deca8b8685eb90801495880e3abdd844c2Chris Lattner void EmitBasicReport(StringRef BugName, StringRef BugStr, 3458f2698621f5090db1dea691059bd0ebd79fb7f14Ted Kremenek SourceLocation Loc) { 3468f2698621f5090db1dea691059bd0ebd79fb7f14Ted Kremenek EmitBasicReport(BugName, BugStr, Loc, 0, 0); 3478f2698621f5090db1dea691059bd0ebd79fb7f14Ted Kremenek } 3481eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 349686775deca8b8685eb90801495880e3abdd844c2Chris Lattner void EmitBasicReport(StringRef BugName, StringRef BugCategory, 350686775deca8b8685eb90801495880e3abdd844c2Chris Lattner StringRef BugStr, SourceLocation Loc) { 35162059e809596a419e6fc3e751b2f0b57b7cc51e7Ted Kremenek EmitBasicReport(BugName, BugCategory, BugStr, Loc, 0, 0); 35262059e809596a419e6fc3e751b2f0b57b7cc51e7Ted Kremenek } 3531eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 354686775deca8b8685eb90801495880e3abdd844c2Chris Lattner void EmitBasicReport(StringRef BugName, StringRef BugStr, 3558f2698621f5090db1dea691059bd0ebd79fb7f14Ted Kremenek SourceLocation Loc, SourceRange R) { 3568f2698621f5090db1dea691059bd0ebd79fb7f14Ted Kremenek EmitBasicReport(BugName, BugStr, Loc, &R, 1); 3578f2698621f5090db1dea691059bd0ebd79fb7f14Ted Kremenek } 3581eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 359686775deca8b8685eb90801495880e3abdd844c2Chris Lattner void EmitBasicReport(StringRef BugName, StringRef Category, 360686775deca8b8685eb90801495880e3abdd844c2Chris Lattner StringRef BugStr, SourceLocation Loc, 361f0171732efb4647772ad2a45c0f31978b0e34f71Benjamin Kramer SourceRange R) { 3628c036c7f77d69f96df49219ed0bdbade200d52ebTed Kremenek EmitBasicReport(BugName, Category, BugStr, Loc, &R, 1); 3638c036c7f77d69f96df49219ed0bdbade200d52ebTed Kremenek } 3641eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 365c095997b853270d8adb6fe55209a4dbc42803d16Ted Kremenek static bool classof(const BugReporter* R) { return true; } 366404fc3ad6bd844bf8ce70cbf9974ab297704a122Argyrios Kyrtzidis 367404fc3ad6bd844bf8ce70cbf9974ab297704a122Argyrios Kyrtzidisprivate: 368404fc3ad6bd844bf8ce70cbf9974ab297704a122Argyrios Kyrtzidis llvm::StringMap<BugType *> StrBugTypes; 369404fc3ad6bd844bf8ce70cbf9974ab297704a122Argyrios Kyrtzidis 370404fc3ad6bd844bf8ce70cbf9974ab297704a122Argyrios Kyrtzidis /// \brief Returns a BugType that is associated with the given name and 371404fc3ad6bd844bf8ce70cbf9974ab297704a122Argyrios Kyrtzidis /// category. 372686775deca8b8685eb90801495880e3abdd844c2Chris Lattner BugType *getBugTypeForName(StringRef name, StringRef category); 373c095997b853270d8adb6fe55209a4dbc42803d16Ted Kremenek}; 3748966bc1c8ce271c09936c0eaf6c841aef4a0af1bTed Kremenek 375cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek// FIXME: Get rid of GRBugReporter. It's the wrong abstraction. 376c095997b853270d8adb6fe55209a4dbc42803d16Ted Kremenekclass GRBugReporter : public BugReporter { 377d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis ExprEngine& Eng; 3782dabd4372c50019fa00aae223ce634e0e754a3f2Ted Kremenek llvm::SmallSet<SymbolRef, 10> NotableSymbols; 3791eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumppublic: 380d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis GRBugReporter(BugReporterData& d, ExprEngine& eng) 381c095997b853270d8adb6fe55209a4dbc42803d16Ted Kremenek : BugReporter(d, GRBugReporterKind), Eng(eng) {} 3821eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 383c095997b853270d8adb6fe55209a4dbc42803d16Ted Kremenek virtual ~GRBugReporter(); 3841eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 385cfdf9b4edf1172728be97d1ae2d95171975f812bTed Kremenek /// getEngine - Return the analysis engine used to analyze a given 386cfdf9b4edf1172728be97d1ae2d95171975f812bTed Kremenek /// function or method. 387d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis ExprEngine &getEngine() { return Eng; } 388c095997b853270d8adb6fe55209a4dbc42803d16Ted Kremenek 389cfdf9b4edf1172728be97d1ae2d95171975f812bTed Kremenek /// getGraph - Get the exploded graph created by the analysis engine 390cfdf9b4edf1172728be97d1ae2d95171975f812bTed Kremenek /// for the analyzed method or function. 39138b02b912e1a55c912f603c4369431264d36a381Zhongxing Xu ExplodedGraph &getGraph(); 3921eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 393cfdf9b4edf1172728be97d1ae2d95171975f812bTed Kremenek /// getStateManager - Return the state manager used by the analysis 394cfdf9b4edf1172728be97d1ae2d95171975f812bTed Kremenek /// engine. 39518c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek ProgramStateManager &getStateManager(); 3961eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 39740406fe63df2b932d6e9fd021f77f097f9d33afbTed Kremenek virtual void GeneratePathDiagnostic(PathDiagnostic &pathDiagnostic, 398686775deca8b8685eb90801495880e3abdd844c2Chris Lattner SmallVectorImpl<BugReport*> &bugReports); 399c095997b853270d8adb6fe55209a4dbc42803d16Ted Kremenek 4002dabd4372c50019fa00aae223ce634e0e754a3f2Ted Kremenek void addNotableSymbol(SymbolRef Sym) { 401c095997b853270d8adb6fe55209a4dbc42803d16Ted Kremenek NotableSymbols.insert(Sym); 402c095997b853270d8adb6fe55209a4dbc42803d16Ted Kremenek } 4031eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 4042dabd4372c50019fa00aae223ce634e0e754a3f2Ted Kremenek bool isNotable(SymbolRef Sym) const { 405c095997b853270d8adb6fe55209a4dbc42803d16Ted Kremenek return (bool) NotableSymbols.count(Sym); 406c095997b853270d8adb6fe55209a4dbc42803d16Ted Kremenek } 4071eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 408cfdf9b4edf1172728be97d1ae2d95171975f812bTed Kremenek /// classof - Used by isa<>, cast<>, and dyn_cast<>. 409c095997b853270d8adb6fe55209a4dbc42803d16Ted Kremenek static bool classof(const BugReporter* R) { 410c095997b853270d8adb6fe55209a4dbc42803d16Ted Kremenek return R->getKind() == GRBugReporterKind; 411c095997b853270d8adb6fe55209a4dbc42803d16Ted Kremenek } 41261f3e058056ab519d249aa67e3d52b0ead57c63eTed Kremenek}; 4131eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 4148966bc1c8ce271c09936c0eaf6c841aef4a0af1bTed Kremenekclass BugReporterContext { 4158966bc1c8ce271c09936c0eaf6c841aef4a0af1bTed Kremenek GRBugReporter &BR; 4166493b8153a56cbff9f89c1a53f04b6af424b383aTed Kremenek // Not the most efficient data structure, but we use an ImmutableList for the 4176493b8153a56cbff9f89c1a53f04b6af424b383aTed Kremenek // Callbacks because it is safe to make additions to list during iteration. 4186493b8153a56cbff9f89c1a53f04b6af424b383aTed Kremenek llvm::ImmutableList<BugReporterVisitor*>::Factory F; 4196493b8153a56cbff9f89c1a53f04b6af424b383aTed Kremenek llvm::ImmutableList<BugReporterVisitor*> Callbacks; 4201b431023814196f87515a540ebcb9e9f1a9176a1Ted Kremenek llvm::FoldingSet<BugReporterVisitor> CallbacksSet; 4218966bc1c8ce271c09936c0eaf6c841aef4a0af1bTed Kremenekpublic: 4223baf672378f105602d2b12f03f00277ae1936fe9Ted Kremenek BugReporterContext(GRBugReporter& br) : BR(br), Callbacks(F.getEmptyList()) {} 4238966bc1c8ce271c09936c0eaf6c841aef4a0af1bTed Kremenek virtual ~BugReporterContext(); 4241eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 4251b431023814196f87515a540ebcb9e9f1a9176a1Ted Kremenek void addVisitor(BugReporterVisitor* visitor); 4261eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 4276493b8153a56cbff9f89c1a53f04b6af424b383aTed Kremenek typedef llvm::ImmutableList<BugReporterVisitor*>::iterator visitor_iterator; 4288966bc1c8ce271c09936c0eaf6c841aef4a0af1bTed Kremenek visitor_iterator visitor_begin() { return Callbacks.begin(); } 4291eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump visitor_iterator visitor_end() { return Callbacks.end(); } 4301eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 4311eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump GRBugReporter& getBugReporter() { return BR; } 4321eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 43338b02b912e1a55c912f603c4369431264d36a381Zhongxing Xu ExplodedGraph &getGraph() { return BR.getGraph(); } 4341eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 4358966bc1c8ce271c09936c0eaf6c841aef4a0af1bTed Kremenek void addNotableSymbol(SymbolRef Sym) { 4368966bc1c8ce271c09936c0eaf6c841aef4a0af1bTed Kremenek // FIXME: For now forward to GRBugReporter. 4378966bc1c8ce271c09936c0eaf6c841aef4a0af1bTed Kremenek BR.addNotableSymbol(Sym); 4388966bc1c8ce271c09936c0eaf6c841aef4a0af1bTed Kremenek } 4391eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 4408966bc1c8ce271c09936c0eaf6c841aef4a0af1bTed Kremenek bool isNotable(SymbolRef Sym) const { 4418966bc1c8ce271c09936c0eaf6c841aef4a0af1bTed Kremenek // FIXME: For now forward to GRBugReporter. 4428966bc1c8ce271c09936c0eaf6c841aef4a0af1bTed Kremenek return BR.isNotable(Sym); 4438966bc1c8ce271c09936c0eaf6c841aef4a0af1bTed Kremenek } 4441eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 44518c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek ProgramStateManager& getStateManager() { 4468966bc1c8ce271c09936c0eaf6c841aef4a0af1bTed Kremenek return BR.getStateManager(); 4478966bc1c8ce271c09936c0eaf6c841aef4a0af1bTed Kremenek } 4481eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 449c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek SValBuilder& getSValBuilder() { 450c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek return getStateManager().getSValBuilder(); 451dd986cc9989f665370cef0917ba8ba3b4871e3e6Ted Kremenek } 4521eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 4539c378f705405d37f49795d5e915989de774fe11fTed Kremenek ASTContext &getASTContext() { 4548966bc1c8ce271c09936c0eaf6c841aef4a0af1bTed Kremenek return BR.getContext(); 4558966bc1c8ce271c09936c0eaf6c841aef4a0af1bTed Kremenek } 4561eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 4578966bc1c8ce271c09936c0eaf6c841aef4a0af1bTed Kremenek SourceManager& getSourceManager() { 4588966bc1c8ce271c09936c0eaf6c841aef4a0af1bTed Kremenek return BR.getSourceManager(); 4598966bc1c8ce271c09936c0eaf6c841aef4a0af1bTed Kremenek } 4601eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 4611eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump virtual BugReport::NodeResolver& getNodeResolver() = 0; 4628966bc1c8ce271c09936c0eaf6c841aef4a0af1bTed Kremenek}; 463e207558e9dbed963eebf5cf31fdb02616f1545a3Ted Kremenek 464e207558e9dbed963eebf5cf31fdb02616f1545a3Ted Kremenekclass DiagBugReport : public RangedBugReport { 465e207558e9dbed963eebf5cf31fdb02616f1545a3Ted Kremenek std::list<std::string> Strs; 466e207558e9dbed963eebf5cf31fdb02616f1545a3Ted Kremenek FullSourceLoc L; 467e207558e9dbed963eebf5cf31fdb02616f1545a3Ted Kremenekpublic: 468686775deca8b8685eb90801495880e3abdd844c2Chris Lattner DiagBugReport(BugType& D, StringRef desc, FullSourceLoc l) : 469cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek RangedBugReport(D, desc, 0), L(l) {} 4701eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 471e207558e9dbed963eebf5cf31fdb02616f1545a3Ted Kremenek virtual ~DiagBugReport() {} 4721eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 473cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek // FIXME: Move out-of-line (virtual function). 474cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek SourceLocation getLocation() const { return L; } 4751eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 476686775deca8b8685eb90801495880e3abdd844c2Chris Lattner void addString(StringRef s) { Strs.push_back(s); } 4771eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 478e207558e9dbed963eebf5cf31fdb02616f1545a3Ted Kremenek typedef std::list<std::string>::const_iterator str_iterator; 479e207558e9dbed963eebf5cf31fdb02616f1545a3Ted Kremenek str_iterator str_begin() const { return Strs.begin(); } 480e207558e9dbed963eebf5cf31fdb02616f1545a3Ted Kremenek str_iterator str_end() const { return Strs.end(); } 481e207558e9dbed963eebf5cf31fdb02616f1545a3Ted Kremenek}; 4821eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 4835350066e7b19d17a5b137caa6c039ab9626dbfa5Ted Kremenek//===----------------------------------------------------------------------===// 4845350066e7b19d17a5b137caa6c039ab9626dbfa5Ted Kremenek//===----------------------------------------------------------------------===// 4851eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 4865350066e7b19d17a5b137caa6c039ab9626dbfa5Ted Kremeneknamespace bugreporter { 4871eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 488c5619d901a68dc27a9e310a6a831f03efebcd950Zhongxing Xuconst Stmt *GetDerefExpr(const ExplodedNode *N); 489c5619d901a68dc27a9e310a6a831f03efebcd950Zhongxing Xuconst Stmt *GetDenomExpr(const ExplodedNode *N); 490c5619d901a68dc27a9e310a6a831f03efebcd950Zhongxing Xuconst Stmt *GetCalleeExpr(const ExplodedNode *N); 491c5619d901a68dc27a9e310a6a831f03efebcd950Zhongxing Xuconst Stmt *GetRetValExpr(const ExplodedNode *N); 4925350066e7b19d17a5b137caa6c039ab9626dbfa5Ted Kremenek 493993124ecdd44ec1430a3b7f01b22f65bbaadb586Ted Kremenekvoid registerConditionVisitor(BugReporterContext &BRC); 494993124ecdd44ec1430a3b7f01b22f65bbaadb586Ted Kremenek 4959c378f705405d37f49795d5e915989de774fe11fTed Kremenekvoid registerTrackNullOrUndefValue(BugReporterContext &BRC, const void *stmt, 4969c378f705405d37f49795d5e915989de774fe11fTed Kremenek const ExplodedNode *N); 4975350066e7b19d17a5b137caa6c039ab9626dbfa5Ted Kremenek 4989c378f705405d37f49795d5e915989de774fe11fTed Kremenekvoid registerFindLastStore(BugReporterContext &BRC, const void *memregion, 49994fd0b8c88db9b1cd99457d3cd8cd333341dd39cTed Kremenek const ExplodedNode *N); 50094fd0b8c88db9b1cd99457d3cd8cd333341dd39cTed Kremenek 501993124ecdd44ec1430a3b7f01b22f65bbaadb586Ted Kremenekvoid registerNilReceiverVisitor(BugReporterContext &BRC); 50294fd0b8c88db9b1cd99457d3cd8cd333341dd39cTed Kremenek 5032bbbe50dbaa0bf231c16333b335304655deeb26bTom Carevoid registerVarDeclsLastStore(BugReporterContext &BRC, const void *stmt, 5042bbbe50dbaa0bf231c16333b335304655deeb26bTom Care const ExplodedNode *N); 5052bbbe50dbaa0bf231c16333b335304655deeb26bTom Care 5065350066e7b19d17a5b137caa6c039ab9626dbfa5Ted Kremenek} // end namespace clang::bugreporter 5071eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 5085350066e7b19d17a5b137caa6c039ab9626dbfa5Ted Kremenek//===----------------------------------------------------------------------===// 509e207558e9dbed963eebf5cf31fdb02616f1545a3Ted Kremenek 5105a4f98ff943e6a501b0fe47ade007c9bbf96cb88Argyrios Kyrtzidis} // end GR namespace 5115a4f98ff943e6a501b0fe47ade007c9bbf96cb88Argyrios Kyrtzidis 51261f3e058056ab519d249aa67e3d52b0ead57c63eTed Kremenek} // end clang namespace 51361f3e058056ab519d249aa67e3d52b0ead57c63eTed Kremenek 51461f3e058056ab519d249aa67e3d52b0ead57c63eTed Kremenek#endif 515