BugReporter.h revision 62059e809596a419e6fc3e751b2f0b57b7cc51e7
161f3e058056ab519d249aa67e3d52b0ead57c63eTed Kremenek// 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 114adc81e540b874bafa15715fd2c5cb662463debdTed Kremenek// PathDiagnostics for analyses based on GRState. 1261f3e058056ab519d249aa67e3d52b0ead57c63eTed Kremenek// 1361f3e058056ab519d249aa67e3d52b0ead57c63eTed Kremenek//===----------------------------------------------------------------------===// 1461f3e058056ab519d249aa67e3d52b0ead57c63eTed Kremenek 1561f3e058056ab519d249aa67e3d52b0ead57c63eTed Kremenek#ifndef LLVM_CLANG_ANALYSIS_BUGREPORTER 1661f3e058056ab519d249aa67e3d52b0ead57c63eTed Kremenek#define LLVM_CLANG_ANALYSIS_BUGREPORTER 1761f3e058056ab519d249aa67e3d52b0ead57c63eTed Kremenek 18e207558e9dbed963eebf5cf31fdb02616f1545a3Ted Kremenek#include "clang/Basic/Diagnostic.h" 19d2f642b56e87493edfc3b0dab359b5e32d5f8a5eTed Kremenek#include "clang/Basic/SourceLocation.h" 204adc81e540b874bafa15715fd2c5cb662463debdTed Kremenek#include "clang/Analysis/PathSensitive/GRState.h" 2161f3e058056ab519d249aa67e3d52b0ead57c63eTed Kremenek#include "clang/Analysis/PathSensitive/ExplodedGraph.h" 2261f3e058056ab519d249aa67e3d52b0ead57c63eTed Kremenek#include "llvm/ADT/SmallPtrSet.h" 23f377fc85488f4799ced714ac60e65a0e3f8f69cbTed Kremenek#include "llvm/ADT/SmallSet.h" 24cb61292aeafc1dc1bc4064fb3d2733717d1d50e5Ted Kremenek#include <vector> 25e207558e9dbed963eebf5cf31fdb02616f1545a3Ted Kremenek#include <list> 26e207558e9dbed963eebf5cf31fdb02616f1545a3Ted Kremenek 2761f3e058056ab519d249aa67e3d52b0ead57c63eTed Kremeneknamespace clang { 2861f3e058056ab519d249aa67e3d52b0ead57c63eTed Kremenek 2961f3e058056ab519d249aa67e3d52b0ead57c63eTed Kremenekclass PathDiagnostic; 3061f3e058056ab519d249aa67e3d52b0ead57c63eTed Kremenekclass PathDiagnosticPiece; 3161f3e058056ab519d249aa67e3d52b0ead57c63eTed Kremenekclass PathDiagnosticClient; 3261f3e058056ab519d249aa67e3d52b0ead57c63eTed Kremenekclass ASTContext; 3361f3e058056ab519d249aa67e3d52b0ead57c63eTed Kremenekclass Diagnostic; 3450a6d0ce344c02782e0207574005c3b2aaa5077cTed Kremenekclass BugReporter; 3550a6d0ce344c02782e0207574005c3b2aaa5077cTed Kremenekclass GRExprEngine; 364adc81e540b874bafa15715fd2c5cb662463debdTed Kremenekclass GRState; 37d2f642b56e87493edfc3b0dab359b5e32d5f8a5eTed Kremenekclass Stmt; 3895cc1bae89ac68626d6f4d389e189ce1ef3aa7f6Ted Kremenekclass BugReport; 391a654b60ef40e84f3943cdb581795c4d4dae1e45Ted Kremenekclass ParentMap; 4050a6d0ce344c02782e0207574005c3b2aaa5077cTed Kremenek 4150a6d0ce344c02782e0207574005c3b2aaa5077cTed Kremenekclass BugType { 4261f3e058056ab519d249aa67e3d52b0ead57c63eTed Kremenekpublic: 4350a6d0ce344c02782e0207574005c3b2aaa5077cTed Kremenek BugType() {} 4450a6d0ce344c02782e0207574005c3b2aaa5077cTed Kremenek virtual ~BugType(); 4561f3e058056ab519d249aa67e3d52b0ead57c63eTed Kremenek 4661f3e058056ab519d249aa67e3d52b0ead57c63eTed Kremenek virtual const char* getName() const = 0; 4750a6d0ce344c02782e0207574005c3b2aaa5077cTed Kremenek virtual const char* getDescription() const { return getName(); } 488c036c7f77d69f96df49219ed0bdbade200d52ebTed Kremenek virtual const char* getCategory() const { return ""; } 49072192bcbb05a0fee7ec3061750b27e8d2004952Ted Kremenek 50072192bcbb05a0fee7ec3061750b27e8d2004952Ted Kremenek virtual std::pair<const char**,const char**> getExtraDescriptiveText() { 51072192bcbb05a0fee7ec3061750b27e8d2004952Ted Kremenek return std::pair<const char**, const char**>(0, 0); 52072192bcbb05a0fee7ec3061750b27e8d2004952Ted Kremenek } 5350a6d0ce344c02782e0207574005c3b2aaa5077cTed Kremenek 5450a6d0ce344c02782e0207574005c3b2aaa5077cTed Kremenek virtual void EmitWarnings(BugReporter& BR) {} 554adc81e540b874bafa15715fd2c5cb662463debdTed Kremenek virtual void GetErrorNodes(std::vector<ExplodedNode<GRState>*>& Nodes) {} 5695cc1bae89ac68626d6f4d389e189ce1ef3aa7f6Ted Kremenek 5795cc1bae89ac68626d6f4d389e189ce1ef3aa7f6Ted Kremenek virtual bool isCached(BugReport& R) = 0; 5895cc1bae89ac68626d6f4d389e189ce1ef3aa7f6Ted Kremenek}; 5995cc1bae89ac68626d6f4d389e189ce1ef3aa7f6Ted Kremenek 6095cc1bae89ac68626d6f4d389e189ce1ef3aa7f6Ted Kremenekclass BugTypeCacheLocation : public BugType { 61d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek llvm::SmallSet<ProgramPoint,10> CachedErrors; 6295cc1bae89ac68626d6f4d389e189ce1ef3aa7f6Ted Kremenekpublic: 6395cc1bae89ac68626d6f4d389e189ce1ef3aa7f6Ted Kremenek BugTypeCacheLocation() {} 6495cc1bae89ac68626d6f4d389e189ce1ef3aa7f6Ted Kremenek virtual ~BugTypeCacheLocation() {} 6595cc1bae89ac68626d6f4d389e189ce1ef3aa7f6Ted Kremenek virtual bool isCached(BugReport& R); 6676d90c8bf83d071fd1bdbffa6d9f2af87c6bb7b5Ted Kremenek bool isCached(ProgramPoint P); 6750a6d0ce344c02782e0207574005c3b2aaa5077cTed Kremenek}; 6861f3e058056ab519d249aa67e3d52b0ead57c63eTed Kremenek 6995cc1bae89ac68626d6f4d389e189ce1ef3aa7f6Ted Kremenek 7050a6d0ce344c02782e0207574005c3b2aaa5077cTed Kremenekclass BugReport { 7195cc1bae89ac68626d6f4d389e189ce1ef3aa7f6Ted Kremenek BugType& Desc; 724adc81e540b874bafa15715fd2c5cb662463debdTed Kremenek ExplodedNode<GRState> *EndNode; 73bb77e9b908658b354b058509d3801f3aed052becTed Kremenek SourceRange R; 7450a6d0ce344c02782e0207574005c3b2aaa5077cTed Kremenekpublic: 754adc81e540b874bafa15715fd2c5cb662463debdTed Kremenek BugReport(BugType& D, ExplodedNode<GRState> *n) : Desc(D), EndNode(n) {} 7650a6d0ce344c02782e0207574005c3b2aaa5077cTed Kremenek virtual ~BugReport(); 7750a6d0ce344c02782e0207574005c3b2aaa5077cTed Kremenek 7850a6d0ce344c02782e0207574005c3b2aaa5077cTed Kremenek const BugType& getBugType() const { return Desc; } 7995cc1bae89ac68626d6f4d389e189ce1ef3aa7f6Ted Kremenek BugType& getBugType() { return Desc; } 80d2f642b56e87493edfc3b0dab359b5e32d5f8a5eTed Kremenek 814adc81e540b874bafa15715fd2c5cb662463debdTed Kremenek ExplodedNode<GRState>* getEndNode() const { return EndNode; } 82d2f642b56e87493edfc3b0dab359b5e32d5f8a5eTed Kremenek 83bb77e9b908658b354b058509d3801f3aed052becTed Kremenek Stmt* getStmt(BugReporter& BR) const; 8450a6d0ce344c02782e0207574005c3b2aaa5077cTed Kremenek 8550a6d0ce344c02782e0207574005c3b2aaa5077cTed Kremenek const char* getName() const { return getBugType().getName(); } 864d35dacf85fc9fb257baa1a846abef2361a1c426Ted Kremenek 874d35dacf85fc9fb257baa1a846abef2361a1c426Ted Kremenek virtual const char* getDescription() const { 884d35dacf85fc9fb257baa1a846abef2361a1c426Ted Kremenek return getBugType().getDescription(); 894d35dacf85fc9fb257baa1a846abef2361a1c426Ted Kremenek } 9061f3e058056ab519d249aa67e3d52b0ead57c63eTed Kremenek 918c036c7f77d69f96df49219ed0bdbade200d52ebTed Kremenek virtual const char* getCategory() const { 928c036c7f77d69f96df49219ed0bdbade200d52ebTed Kremenek return getBugType().getCategory(); 938c036c7f77d69f96df49219ed0bdbade200d52ebTed Kremenek } 948c036c7f77d69f96df49219ed0bdbade200d52ebTed Kremenek 95072192bcbb05a0fee7ec3061750b27e8d2004952Ted Kremenek virtual std::pair<const char**,const char**> getExtraDescriptiveText() { 96072192bcbb05a0fee7ec3061750b27e8d2004952Ted Kremenek return getBugType().getExtraDescriptiveText(); 97072192bcbb05a0fee7ec3061750b27e8d2004952Ted Kremenek } 98072192bcbb05a0fee7ec3061750b27e8d2004952Ted Kremenek 99bd7efa8ca27ed9676acf00abf31d5e1cd54651ccTed Kremenek virtual PathDiagnosticPiece* getEndPath(BugReporter& BR, 1004adc81e540b874bafa15715fd2c5cb662463debdTed Kremenek ExplodedNode<GRState>* N); 101d2f642b56e87493edfc3b0dab359b5e32d5f8a5eTed Kremenek 102d2f642b56e87493edfc3b0dab359b5e32d5f8a5eTed Kremenek virtual FullSourceLoc getLocation(SourceManager& Mgr); 103f1ae705460552655fe7275327804444c62e86baeTed Kremenek 104bb77e9b908658b354b058509d3801f3aed052becTed Kremenek virtual void getRanges(BugReporter& BR,const SourceRange*& beg, 105bb77e9b908658b354b058509d3801f3aed052becTed Kremenek const SourceRange*& end); 1066837faa083bebad39aa342f84c2b450fb6410eafTed Kremenek 1074adc81e540b874bafa15715fd2c5cb662463debdTed Kremenek virtual PathDiagnosticPiece* VisitNode(ExplodedNode<GRState>* N, 1084adc81e540b874bafa15715fd2c5cb662463debdTed Kremenek ExplodedNode<GRState>* PrevN, 1094adc81e540b874bafa15715fd2c5cb662463debdTed Kremenek ExplodedGraph<GRState>& G, 1108dd564630c901d6d62dd2ffd4110b613d0055078Ted Kremenek BugReporter& BR); 1116837faa083bebad39aa342f84c2b450fb6410eafTed Kremenek}; 1126837faa083bebad39aa342f84c2b450fb6410eafTed Kremenek 113d2f642b56e87493edfc3b0dab359b5e32d5f8a5eTed Kremenekclass RangedBugReport : public BugReport { 1145e55cda64f4452fa65d83f66390c7126a8b248bbTed Kremenek std::vector<SourceRange> Ranges; 11522bda887aacd0e591978541a799aa43835652ec9Ted Kremenek const char* desc; 1165e55cda64f4452fa65d83f66390c7126a8b248bbTed Kremenekpublic: 1174adc81e540b874bafa15715fd2c5cb662463debdTed Kremenek RangedBugReport(BugType& D, ExplodedNode<GRState> *n, 11822bda887aacd0e591978541a799aa43835652ec9Ted Kremenek const char* description = 0) 11922bda887aacd0e591978541a799aa43835652ec9Ted Kremenek : BugReport(D, n), desc(description) {} 120d2f642b56e87493edfc3b0dab359b5e32d5f8a5eTed Kremenek 1215e55cda64f4452fa65d83f66390c7126a8b248bbTed Kremenek virtual ~RangedBugReport(); 12222bda887aacd0e591978541a799aa43835652ec9Ted Kremenek 12322bda887aacd0e591978541a799aa43835652ec9Ted Kremenek virtual const char* getDescription() const { 12422bda887aacd0e591978541a799aa43835652ec9Ted Kremenek return desc ? desc : BugReport::getDescription(); 12522bda887aacd0e591978541a799aa43835652ec9Ted Kremenek } 1265e55cda64f4452fa65d83f66390c7126a8b248bbTed Kremenek 1275e55cda64f4452fa65d83f66390c7126a8b248bbTed Kremenek void addRange(SourceRange R) { Ranges.push_back(R); } 1285e55cda64f4452fa65d83f66390c7126a8b248bbTed Kremenek 12922bda887aacd0e591978541a799aa43835652ec9Ted Kremenek 130bb77e9b908658b354b058509d3801f3aed052becTed Kremenek virtual void getRanges(BugReporter& BR,const SourceRange*& beg, 131bb77e9b908658b354b058509d3801f3aed052becTed Kremenek const SourceRange*& end) { 1325e55cda64f4452fa65d83f66390c7126a8b248bbTed Kremenek 1335e55cda64f4452fa65d83f66390c7126a8b248bbTed Kremenek if (Ranges.empty()) { 1345e55cda64f4452fa65d83f66390c7126a8b248bbTed Kremenek beg = NULL; 1355e55cda64f4452fa65d83f66390c7126a8b248bbTed Kremenek end = NULL; 1365e55cda64f4452fa65d83f66390c7126a8b248bbTed Kremenek } 1375e55cda64f4452fa65d83f66390c7126a8b248bbTed Kremenek else { 1385e55cda64f4452fa65d83f66390c7126a8b248bbTed Kremenek beg = &Ranges[0]; 1395e55cda64f4452fa65d83f66390c7126a8b248bbTed Kremenek end = beg + Ranges.size(); 1405e55cda64f4452fa65d83f66390c7126a8b248bbTed Kremenek } 1415e55cda64f4452fa65d83f66390c7126a8b248bbTed Kremenek } 1425e55cda64f4452fa65d83f66390c7126a8b248bbTed Kremenek}; 1435e55cda64f4452fa65d83f66390c7126a8b248bbTed Kremenek 144c095997b853270d8adb6fe55209a4dbc42803d16Ted Kremenekclass BugReporterData { 145c095997b853270d8adb6fe55209a4dbc42803d16Ted Kremenekpublic: 146c095997b853270d8adb6fe55209a4dbc42803d16Ted Kremenek virtual ~BugReporterData(); 147c095997b853270d8adb6fe55209a4dbc42803d16Ted Kremenek virtual Diagnostic& getDiagnostic() = 0; 148c095997b853270d8adb6fe55209a4dbc42803d16Ted Kremenek virtual PathDiagnosticClient* getPathDiagnosticClient() = 0; 149c095997b853270d8adb6fe55209a4dbc42803d16Ted Kremenek virtual ASTContext& getContext() = 0; 150c095997b853270d8adb6fe55209a4dbc42803d16Ted Kremenek virtual SourceManager& getSourceManager() = 0; 1517032f460fc9828f386056e75933da5af61e88638Ted Kremenek virtual CFG* getCFG() = 0; 152c095997b853270d8adb6fe55209a4dbc42803d16Ted Kremenek virtual ParentMap& getParentMap() = 0; 1537032f460fc9828f386056e75933da5af61e88638Ted Kremenek virtual LiveVariables* getLiveVariables() = 0; 154c095997b853270d8adb6fe55209a4dbc42803d16Ted Kremenek}; 155c095997b853270d8adb6fe55209a4dbc42803d16Ted Kremenek 15661f3e058056ab519d249aa67e3d52b0ead57c63eTed Kremenekclass BugReporter { 157c095997b853270d8adb6fe55209a4dbc42803d16Ted Kremenekpublic: 158c095997b853270d8adb6fe55209a4dbc42803d16Ted Kremenek enum Kind { BaseBRKind, GRBugReporterKind }; 159c095997b853270d8adb6fe55209a4dbc42803d16Ted Kremenek 160c095997b853270d8adb6fe55209a4dbc42803d16Ted Kremenekprotected: 161c095997b853270d8adb6fe55209a4dbc42803d16Ted Kremenek Kind kind; 162c095997b853270d8adb6fe55209a4dbc42803d16Ted Kremenek BugReporterData& D; 163c095997b853270d8adb6fe55209a4dbc42803d16Ted Kremenek 164c095997b853270d8adb6fe55209a4dbc42803d16Ted Kremenek BugReporter(BugReporterData& d, Kind k) : kind(k), D(d) {} 16561f3e058056ab519d249aa67e3d52b0ead57c63eTed Kremenek 16661f3e058056ab519d249aa67e3d52b0ead57c63eTed Kremenekpublic: 167c095997b853270d8adb6fe55209a4dbc42803d16Ted Kremenek BugReporter(BugReporterData& d) : kind(BaseBRKind), D(d) {} 168c095997b853270d8adb6fe55209a4dbc42803d16Ted Kremenek virtual ~BugReporter(); 16950a6d0ce344c02782e0207574005c3b2aaa5077cTed Kremenek 170c095997b853270d8adb6fe55209a4dbc42803d16Ted Kremenek Kind getKind() const { return kind; } 17161f3e058056ab519d249aa67e3d52b0ead57c63eTed Kremenek 172c095997b853270d8adb6fe55209a4dbc42803d16Ted Kremenek Diagnostic& getDiagnostic() { 173c095997b853270d8adb6fe55209a4dbc42803d16Ted Kremenek return D.getDiagnostic(); 174c095997b853270d8adb6fe55209a4dbc42803d16Ted Kremenek } 17550a6d0ce344c02782e0207574005c3b2aaa5077cTed Kremenek 176c095997b853270d8adb6fe55209a4dbc42803d16Ted Kremenek PathDiagnosticClient* getPathDiagnosticClient() { 177c095997b853270d8adb6fe55209a4dbc42803d16Ted Kremenek return D.getPathDiagnosticClient(); 178c095997b853270d8adb6fe55209a4dbc42803d16Ted Kremenek } 17961f3e058056ab519d249aa67e3d52b0ead57c63eTed Kremenek 180c095997b853270d8adb6fe55209a4dbc42803d16Ted Kremenek ASTContext& getContext() { 181c095997b853270d8adb6fe55209a4dbc42803d16Ted Kremenek return D.getContext(); 182c095997b853270d8adb6fe55209a4dbc42803d16Ted Kremenek } 18361f3e058056ab519d249aa67e3d52b0ead57c63eTed Kremenek 184c095997b853270d8adb6fe55209a4dbc42803d16Ted Kremenek SourceManager& getSourceManager() { 185e207558e9dbed963eebf5cf31fdb02616f1545a3Ted Kremenek return D.getSourceManager(); 186c095997b853270d8adb6fe55209a4dbc42803d16Ted Kremenek } 187c9fa2f7bcc3061aa8bcdbe0df26d2c7cf7281539Ted Kremenek 1887032f460fc9828f386056e75933da5af61e88638Ted Kremenek CFG* getCFG() { 189c095997b853270d8adb6fe55209a4dbc42803d16Ted Kremenek return D.getCFG(); 190c095997b853270d8adb6fe55209a4dbc42803d16Ted Kremenek } 191c095997b853270d8adb6fe55209a4dbc42803d16Ted Kremenek 192c095997b853270d8adb6fe55209a4dbc42803d16Ted Kremenek ParentMap& getParentMap() { 193c095997b853270d8adb6fe55209a4dbc42803d16Ted Kremenek return D.getParentMap(); 194c095997b853270d8adb6fe55209a4dbc42803d16Ted Kremenek } 195c095997b853270d8adb6fe55209a4dbc42803d16Ted Kremenek 1967032f460fc9828f386056e75933da5af61e88638Ted Kremenek LiveVariables* getLiveVariables() { 197c095997b853270d8adb6fe55209a4dbc42803d16Ted Kremenek return D.getLiveVariables(); 198c095997b853270d8adb6fe55209a4dbc42803d16Ted Kremenek } 199c095997b853270d8adb6fe55209a4dbc42803d16Ted Kremenek 200c095997b853270d8adb6fe55209a4dbc42803d16Ted Kremenek virtual void GeneratePathDiagnostic(PathDiagnostic& PD, BugReport& R) {} 20161f3e058056ab519d249aa67e3d52b0ead57c63eTed Kremenek 202c095997b853270d8adb6fe55209a4dbc42803d16Ted Kremenek void EmitWarning(BugReport& R); 20350a6d0ce344c02782e0207574005c3b2aaa5077cTed Kremenek 20457202071e477530e9348bc76671ee369b2399b92Ted Kremenek void EmitBasicReport(const char* BugName, const char* BugStr, 2058f2698621f5090db1dea691059bd0ebd79fb7f14Ted Kremenek SourceLocation Loc, 2068f2698621f5090db1dea691059bd0ebd79fb7f14Ted Kremenek SourceRange* RangeBeg, unsigned NumRanges); 2078f2698621f5090db1dea691059bd0ebd79fb7f14Ted Kremenek 2088c036c7f77d69f96df49219ed0bdbade200d52ebTed Kremenek void EmitBasicReport(const char* BugName, const char* BugCategory, 2098c036c7f77d69f96df49219ed0bdbade200d52ebTed Kremenek const char* BugStr, SourceLocation Loc, 2108c036c7f77d69f96df49219ed0bdbade200d52ebTed Kremenek SourceRange* RangeBeg, unsigned NumRanges); 2118c036c7f77d69f96df49219ed0bdbade200d52ebTed Kremenek 2128c036c7f77d69f96df49219ed0bdbade200d52ebTed Kremenek 2138f2698621f5090db1dea691059bd0ebd79fb7f14Ted Kremenek void EmitBasicReport(const char* BugName, const char* BugStr, 2148f2698621f5090db1dea691059bd0ebd79fb7f14Ted Kremenek SourceLocation Loc) { 2158f2698621f5090db1dea691059bd0ebd79fb7f14Ted Kremenek EmitBasicReport(BugName, BugStr, Loc, 0, 0); 2168f2698621f5090db1dea691059bd0ebd79fb7f14Ted Kremenek } 2178f2698621f5090db1dea691059bd0ebd79fb7f14Ted Kremenek 21862059e809596a419e6fc3e751b2f0b57b7cc51e7Ted Kremenek void EmitBasicReport(const char* BugName, const char* BugCategory, 21962059e809596a419e6fc3e751b2f0b57b7cc51e7Ted Kremenek const char* BugStr, SourceLocation Loc) { 22062059e809596a419e6fc3e751b2f0b57b7cc51e7Ted Kremenek EmitBasicReport(BugName, BugCategory, BugStr, Loc, 0, 0); 22162059e809596a419e6fc3e751b2f0b57b7cc51e7Ted Kremenek } 22262059e809596a419e6fc3e751b2f0b57b7cc51e7Ted Kremenek 2238f2698621f5090db1dea691059bd0ebd79fb7f14Ted Kremenek void EmitBasicReport(const char* BugName, const char* BugStr, 2248f2698621f5090db1dea691059bd0ebd79fb7f14Ted Kremenek SourceLocation Loc, SourceRange R) { 2258f2698621f5090db1dea691059bd0ebd79fb7f14Ted Kremenek EmitBasicReport(BugName, BugStr, Loc, &R, 1); 2268f2698621f5090db1dea691059bd0ebd79fb7f14Ted Kremenek } 22757202071e477530e9348bc76671ee369b2399b92Ted Kremenek 2288c036c7f77d69f96df49219ed0bdbade200d52ebTed Kremenek void EmitBasicReport(const char* BugName, const char* Category, 2298c036c7f77d69f96df49219ed0bdbade200d52ebTed Kremenek const char* BugStr, SourceLocation Loc, SourceRange R) { 2308c036c7f77d69f96df49219ed0bdbade200d52ebTed Kremenek EmitBasicReport(BugName, Category, BugStr, Loc, &R, 1); 2318c036c7f77d69f96df49219ed0bdbade200d52ebTed Kremenek } 2328c036c7f77d69f96df49219ed0bdbade200d52ebTed Kremenek 233c095997b853270d8adb6fe55209a4dbc42803d16Ted Kremenek static bool classof(const BugReporter* R) { return true; } 234c095997b853270d8adb6fe55209a4dbc42803d16Ted Kremenek}; 235f377fc85488f4799ced714ac60e65a0e3f8f69cbTed Kremenek 236c095997b853270d8adb6fe55209a4dbc42803d16Ted Kremenekclass GRBugReporter : public BugReporter { 237c095997b853270d8adb6fe55209a4dbc42803d16Ted Kremenek GRExprEngine& Eng; 238c095997b853270d8adb6fe55209a4dbc42803d16Ted Kremenek llvm::SmallSet<SymbolID, 10> NotableSymbols; 239c095997b853270d8adb6fe55209a4dbc42803d16Ted Kremenekpublic: 240bd7efa8ca27ed9676acf00abf31d5e1cd54651ccTed Kremenek 241c095997b853270d8adb6fe55209a4dbc42803d16Ted Kremenek GRBugReporter(BugReporterData& d, GRExprEngine& eng) 242c095997b853270d8adb6fe55209a4dbc42803d16Ted Kremenek : BugReporter(d, GRBugReporterKind), Eng(eng) {} 2431a654b60ef40e84f3943cdb581795c4d4dae1e45Ted Kremenek 244c095997b853270d8adb6fe55209a4dbc42803d16Ted Kremenek virtual ~GRBugReporter(); 245c095997b853270d8adb6fe55209a4dbc42803d16Ted Kremenek 246cfdf9b4edf1172728be97d1ae2d95171975f812bTed Kremenek /// getEngine - Return the analysis engine used to analyze a given 247cfdf9b4edf1172728be97d1ae2d95171975f812bTed Kremenek /// function or method. 248c095997b853270d8adb6fe55209a4dbc42803d16Ted Kremenek GRExprEngine& getEngine() { 249c095997b853270d8adb6fe55209a4dbc42803d16Ted Kremenek return Eng; 250c095997b853270d8adb6fe55209a4dbc42803d16Ted Kremenek } 251c095997b853270d8adb6fe55209a4dbc42803d16Ted Kremenek 252cfdf9b4edf1172728be97d1ae2d95171975f812bTed Kremenek /// getGraph - Get the exploded graph created by the analysis engine 253cfdf9b4edf1172728be97d1ae2d95171975f812bTed Kremenek /// for the analyzed method or function. 2544adc81e540b874bafa15715fd2c5cb662463debdTed Kremenek ExplodedGraph<GRState>& getGraph(); 25561f3e058056ab519d249aa67e3d52b0ead57c63eTed Kremenek 256cfdf9b4edf1172728be97d1ae2d95171975f812bTed Kremenek /// getStateManager - Return the state manager used by the analysis 257cfdf9b4edf1172728be97d1ae2d95171975f812bTed Kremenek /// engine. 2584adc81e540b874bafa15715fd2c5cb662463debdTed Kremenek GRStateManager& getStateManager(); 259f377fc85488f4799ced714ac60e65a0e3f8f69cbTed Kremenek 260c095997b853270d8adb6fe55209a4dbc42803d16Ted Kremenek virtual void GeneratePathDiagnostic(PathDiagnostic& PD, BugReport& R); 261c095997b853270d8adb6fe55209a4dbc42803d16Ted Kremenek 262c095997b853270d8adb6fe55209a4dbc42803d16Ted Kremenek void addNotableSymbol(SymbolID Sym) { 263c095997b853270d8adb6fe55209a4dbc42803d16Ted Kremenek NotableSymbols.insert(Sym); 264c095997b853270d8adb6fe55209a4dbc42803d16Ted Kremenek } 265c095997b853270d8adb6fe55209a4dbc42803d16Ted Kremenek 266c095997b853270d8adb6fe55209a4dbc42803d16Ted Kremenek bool isNotable(SymbolID Sym) const { 267c095997b853270d8adb6fe55209a4dbc42803d16Ted Kremenek return (bool) NotableSymbols.count(Sym); 268c095997b853270d8adb6fe55209a4dbc42803d16Ted Kremenek } 269cfdf9b4edf1172728be97d1ae2d95171975f812bTed Kremenek 270cfdf9b4edf1172728be97d1ae2d95171975f812bTed Kremenek /// classof - Used by isa<>, cast<>, and dyn_cast<>. 271c095997b853270d8adb6fe55209a4dbc42803d16Ted Kremenek static bool classof(const BugReporter* R) { 272c095997b853270d8adb6fe55209a4dbc42803d16Ted Kremenek return R->getKind() == GRBugReporterKind; 273c095997b853270d8adb6fe55209a4dbc42803d16Ted Kremenek } 27461f3e058056ab519d249aa67e3d52b0ead57c63eTed Kremenek}; 27561f3e058056ab519d249aa67e3d52b0ead57c63eTed Kremenek 276e207558e9dbed963eebf5cf31fdb02616f1545a3Ted Kremenek 277e207558e9dbed963eebf5cf31fdb02616f1545a3Ted Kremenekclass DiagBugReport : public RangedBugReport { 278e207558e9dbed963eebf5cf31fdb02616f1545a3Ted Kremenek std::list<std::string> Strs; 279e207558e9dbed963eebf5cf31fdb02616f1545a3Ted Kremenek FullSourceLoc L; 280e207558e9dbed963eebf5cf31fdb02616f1545a3Ted Kremenek const char* description; 281e207558e9dbed963eebf5cf31fdb02616f1545a3Ted Kremenekpublic: 282e207558e9dbed963eebf5cf31fdb02616f1545a3Ted Kremenek DiagBugReport(const char* desc, BugType& D, FullSourceLoc l) : 283e207558e9dbed963eebf5cf31fdb02616f1545a3Ted Kremenek RangedBugReport(D, NULL), L(l), description(desc) {} 284e207558e9dbed963eebf5cf31fdb02616f1545a3Ted Kremenek 285e207558e9dbed963eebf5cf31fdb02616f1545a3Ted Kremenek virtual ~DiagBugReport() {} 286e207558e9dbed963eebf5cf31fdb02616f1545a3Ted Kremenek virtual FullSourceLoc getLocation(SourceManager&) { return L; } 287e207558e9dbed963eebf5cf31fdb02616f1545a3Ted Kremenek 288e207558e9dbed963eebf5cf31fdb02616f1545a3Ted Kremenek virtual const char* getDescription() const { 289e207558e9dbed963eebf5cf31fdb02616f1545a3Ted Kremenek return description; 290e207558e9dbed963eebf5cf31fdb02616f1545a3Ted Kremenek } 291e207558e9dbed963eebf5cf31fdb02616f1545a3Ted Kremenek 292e207558e9dbed963eebf5cf31fdb02616f1545a3Ted Kremenek void addString(const std::string& s) { Strs.push_back(s); } 293e207558e9dbed963eebf5cf31fdb02616f1545a3Ted Kremenek 294e207558e9dbed963eebf5cf31fdb02616f1545a3Ted Kremenek typedef std::list<std::string>::const_iterator str_iterator; 295e207558e9dbed963eebf5cf31fdb02616f1545a3Ted Kremenek str_iterator str_begin() const { return Strs.begin(); } 296e207558e9dbed963eebf5cf31fdb02616f1545a3Ted Kremenek str_iterator str_end() const { return Strs.end(); } 297e207558e9dbed963eebf5cf31fdb02616f1545a3Ted Kremenek}; 298e207558e9dbed963eebf5cf31fdb02616f1545a3Ted Kremenek 299e207558e9dbed963eebf5cf31fdb02616f1545a3Ted Kremenekclass DiagCollector : public DiagnosticClient { 300e207558e9dbed963eebf5cf31fdb02616f1545a3Ted Kremenek std::list<DiagBugReport> Reports; 301e207558e9dbed963eebf5cf31fdb02616f1545a3Ted Kremenek BugType& D; 302e207558e9dbed963eebf5cf31fdb02616f1545a3Ted Kremenekpublic: 303e207558e9dbed963eebf5cf31fdb02616f1545a3Ted Kremenek DiagCollector(BugType& d) : D(d) {} 304e207558e9dbed963eebf5cf31fdb02616f1545a3Ted Kremenek 305e207558e9dbed963eebf5cf31fdb02616f1545a3Ted Kremenek virtual ~DiagCollector() {} 306e207558e9dbed963eebf5cf31fdb02616f1545a3Ted Kremenek 307e207558e9dbed963eebf5cf31fdb02616f1545a3Ted Kremenek virtual void HandleDiagnostic(Diagnostic &Diags, 308e207558e9dbed963eebf5cf31fdb02616f1545a3Ted Kremenek Diagnostic::Level DiagLevel, 309e207558e9dbed963eebf5cf31fdb02616f1545a3Ted Kremenek FullSourceLoc Pos, 310e207558e9dbed963eebf5cf31fdb02616f1545a3Ted Kremenek diag::kind ID, 311e207558e9dbed963eebf5cf31fdb02616f1545a3Ted Kremenek const std::string *Strs, 312e207558e9dbed963eebf5cf31fdb02616f1545a3Ted Kremenek unsigned NumStrs, 313e207558e9dbed963eebf5cf31fdb02616f1545a3Ted Kremenek const SourceRange *Ranges, 314e207558e9dbed963eebf5cf31fdb02616f1545a3Ted Kremenek unsigned NumRanges) { 315e207558e9dbed963eebf5cf31fdb02616f1545a3Ted Kremenek 316e207558e9dbed963eebf5cf31fdb02616f1545a3Ted Kremenek // FIXME: Use a map from diag::kind to BugType, instead of having just 317e207558e9dbed963eebf5cf31fdb02616f1545a3Ted Kremenek // one BugType. 318e207558e9dbed963eebf5cf31fdb02616f1545a3Ted Kremenek 319e207558e9dbed963eebf5cf31fdb02616f1545a3Ted Kremenek Reports.push_back(DiagBugReport(Diags.getDescription(ID), D, Pos)); 320e207558e9dbed963eebf5cf31fdb02616f1545a3Ted Kremenek DiagBugReport& R = Reports.back(); 321e207558e9dbed963eebf5cf31fdb02616f1545a3Ted Kremenek 322e207558e9dbed963eebf5cf31fdb02616f1545a3Ted Kremenek for ( ; NumRanges ; --NumRanges, ++Ranges) 323e207558e9dbed963eebf5cf31fdb02616f1545a3Ted Kremenek R.addRange(*Ranges); 324e207558e9dbed963eebf5cf31fdb02616f1545a3Ted Kremenek 325e207558e9dbed963eebf5cf31fdb02616f1545a3Ted Kremenek for ( ; NumStrs ; --NumStrs, ++Strs) 326e207558e9dbed963eebf5cf31fdb02616f1545a3Ted Kremenek R.addString(*Strs); 327e207558e9dbed963eebf5cf31fdb02616f1545a3Ted Kremenek } 328e207558e9dbed963eebf5cf31fdb02616f1545a3Ted Kremenek 329e207558e9dbed963eebf5cf31fdb02616f1545a3Ted Kremenek // Iterators. 330e207558e9dbed963eebf5cf31fdb02616f1545a3Ted Kremenek 331e207558e9dbed963eebf5cf31fdb02616f1545a3Ted Kremenek typedef std::list<DiagBugReport>::iterator iterator; 332e207558e9dbed963eebf5cf31fdb02616f1545a3Ted Kremenek iterator begin() { return Reports.begin(); } 333e207558e9dbed963eebf5cf31fdb02616f1545a3Ted Kremenek iterator end() { return Reports.end(); } 334e207558e9dbed963eebf5cf31fdb02616f1545a3Ted Kremenek}; 335e207558e9dbed963eebf5cf31fdb02616f1545a3Ted Kremenek 336db09a4dee28a4515438af60f2d2b4a83e4965c31Ted Kremenekclass SimpleBugType : public BugTypeCacheLocation { 337584def7364f51e35bfcaf5c3c64673096533addaTed Kremenek const char* name; 3388c036c7f77d69f96df49219ed0bdbade200d52ebTed Kremenek const char* category; 339584def7364f51e35bfcaf5c3c64673096533addaTed Kremenek const char* desc; 340db09a4dee28a4515438af60f2d2b4a83e4965c31Ted Kremenekpublic: 3418c036c7f77d69f96df49219ed0bdbade200d52ebTed Kremenek SimpleBugType(const char* n) : name(n), category(""), desc(0) {} 3428c036c7f77d69f96df49219ed0bdbade200d52ebTed Kremenek SimpleBugType(const char* n, const char* c, const char* d) 3438c036c7f77d69f96df49219ed0bdbade200d52ebTed Kremenek : name(n), category(c), desc(d) {} 344db09a4dee28a4515438af60f2d2b4a83e4965c31Ted Kremenek 345db09a4dee28a4515438af60f2d2b4a83e4965c31Ted Kremenek virtual const char* getName() const { return name; } 3468c036c7f77d69f96df49219ed0bdbade200d52ebTed Kremenek virtual const char* getDescription() const { return desc ? desc : name; } 3478c036c7f77d69f96df49219ed0bdbade200d52ebTed Kremenek virtual const char* getCategory() const { return category; } 348db09a4dee28a4515438af60f2d2b4a83e4965c31Ted Kremenek}; 349db09a4dee28a4515438af60f2d2b4a83e4965c31Ted Kremenek 35061f3e058056ab519d249aa67e3d52b0ead57c63eTed Kremenek} // end clang namespace 35161f3e058056ab519d249aa67e3d52b0ead57c63eTed Kremenek 35261f3e058056ab519d249aa67e3d52b0ead57c63eTed Kremenek#endif 353