ProgramPoint.h revision 5f85e17df3f5b0a8021443f2b590daecfb2cbd17
183c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek//==- ProgramPoint.h - Program Points for Path-Sensitive Analysis --*- C++ -*-// 2eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenek// 3eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenek// The LLVM Compiler Infrastructure 4eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenek// 50bc735ffcfb223c0186419547abaa5c84482663eChris Lattner// This file is distributed under the University of Illinois Open Source 60bc735ffcfb223c0186419547abaa5c84482663eChris Lattner// License. See LICENSE.TXT for details. 7eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenek// 8eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenek//===----------------------------------------------------------------------===// 9eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenek// 1083c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek// This file defines the interface ProgramPoint, which identifies a 1183c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek// distinct location in a function. 12eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenek// 13eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenek//===----------------------------------------------------------------------===// 14eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenek 1583c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek#ifndef LLVM_CLANG_ANALYSIS_PROGRAM_POINT 1683c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek#define LLVM_CLANG_ANALYSIS_PROGRAM_POINT 17eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenek 18e41611aa2237d06a0ef61db4528fb2883a8defcdTed Kremenek#include "clang/Analysis/CFG.h" 19eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenek#include "llvm/Support/DataTypes.h" 204c3fbe33194cd9b1bfff773647ed785b403e1ba5Ted Kremenek#include "llvm/ADT/DenseMap.h" 215226755ab5ce6346f98b5f41cdcffbe84c5bb484Ted Kremenek#include "llvm/ADT/FoldingSet.h" 226bad354120ce0d35901e86ca63e5534b7b9ed092Ted Kremenek#include "llvm/Support/Casting.h" 234c3fbe33194cd9b1bfff773647ed785b403e1ba5Ted Kremenek#include <cassert> 2459753441b6391a9843eff287f0adb2614153b7c8Ted Kremenek#include <utility> 25eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenek 26eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremeneknamespace clang { 2705e14cd46ef44c07385aae96ec2fdcb9bf7e9467Ted Kremenek 2883c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenekclass ProgramPoint { 29eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenekpublic: 30cdd4f1783da7c7565be2376d14ca6ab2625aa4b6Ted Kremenek enum Kind { BlockEdgeKind, 31cdd4f1783da7c7565be2376d14ca6ab2625aa4b6Ted Kremenek BlockEntranceKind, 32cdd4f1783da7c7565be2376d14ca6ab2625aa4b6Ted Kremenek BlockExitKind, 33cdd4f1783da7c7565be2376d14ca6ab2625aa4b6Ted Kremenek PreStmtKind, 34cdd4f1783da7c7565be2376d14ca6ab2625aa4b6Ted Kremenek // Keep the following together and in this order. 35cdd4f1783da7c7565be2376d14ca6ab2625aa4b6Ted Kremenek PostStmtKind, 36cdd4f1783da7c7565be2376d14ca6ab2625aa4b6Ted Kremenek PostLocationChecksSucceedKind, 37cdd4f1783da7c7565be2376d14ca6ab2625aa4b6Ted Kremenek PostOutOfBoundsCheckFailedKind, 38cdd4f1783da7c7565be2376d14ca6ab2625aa4b6Ted Kremenek PostNullCheckFailedKind, 39cdd4f1783da7c7565be2376d14ca6ab2625aa4b6Ted Kremenek PostUndefLocationCheckFailedKind, 40cdd4f1783da7c7565be2376d14ca6ab2625aa4b6Ted Kremenek PostLoadKind, 41cdd4f1783da7c7565be2376d14ca6ab2625aa4b6Ted Kremenek PostStoreKind, 42cdd4f1783da7c7565be2376d14ca6ab2625aa4b6Ted Kremenek PostPurgeDeadSymbolsKind, 43cdd4f1783da7c7565be2376d14ca6ab2625aa4b6Ted Kremenek PostStmtCustomKind, 44cdd4f1783da7c7565be2376d14ca6ab2625aa4b6Ted Kremenek PostLValueKind, 45f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek MinPostStmtKind = PostStmtKind, 467090d5465de7ca620da16211cf886edf1edc1f1fTed Kremenek MaxPostStmtKind = PostLValueKind }; 474c3fbe33194cd9b1bfff773647ed785b403e1ba5Ted Kremenek 48d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenekprivate: 49d6b9e37311013bdf24fd709f7e9962e3b141e6fbTed Kremenek std::pair<const void *, const void *> Data; 50d6b9e37311013bdf24fd709f7e9962e3b141e6fbTed Kremenek Kind K; 51e8063ae53bd241de10ba1053054d06867a5c56abTed Kremenek const void *Tag; 52d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek 53d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenekprotected: 54e8063ae53bd241de10ba1053054d06867a5c56abTed Kremenek ProgramPoint(const void* P, Kind k, const void *tag = 0) 55d6b9e37311013bdf24fd709f7e9962e3b141e6fbTed Kremenek : Data(P, NULL), K(k), Tag(tag) {} 56d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek 57d6b9e37311013bdf24fd709f7e9962e3b141e6fbTed Kremenek ProgramPoint(const void* P1, const void* P2, Kind k, const void *tag = 0) 58d6b9e37311013bdf24fd709f7e9962e3b141e6fbTed Kremenek : Data(P1, P2), K(k), Tag(tag) {} 59f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek 60d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenekprotected: 61d6b9e37311013bdf24fd709f7e9962e3b141e6fbTed Kremenek const void* getData1() const { return Data.first; } 62d6b9e37311013bdf24fd709f7e9962e3b141e6fbTed Kremenek const void* getData2() const { return Data.second; } 63e8063ae53bd241de10ba1053054d06867a5c56abTed Kremenek const void *getTag() const { return Tag; } 64f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek 6583c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenekpublic: 66d6b9e37311013bdf24fd709f7e9962e3b141e6fbTed Kremenek Kind getKind() const { return K; } 67d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek 68e8063ae53bd241de10ba1053054d06867a5c56abTed Kremenek // For use with DenseMap. This hash is probably slow. 69d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek unsigned getHashValue() const { 70e8063ae53bd241de10ba1053054d06867a5c56abTed Kremenek llvm::FoldingSetNodeID ID; 71d6b9e37311013bdf24fd709f7e9962e3b141e6fbTed Kremenek Profile(ID); 72e8063ae53bd241de10ba1053054d06867a5c56abTed Kremenek return ID.ComputeHash(); 73d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek } 74eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenek 7583c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek static bool classof(const ProgramPoint*) { return true; } 76d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek 77d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek bool operator==(const ProgramPoint & RHS) const { 78d6b9e37311013bdf24fd709f7e9962e3b141e6fbTed Kremenek return K == RHS.K && Data == RHS.Data && Tag == RHS.Tag; 79d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek } 80d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek 81d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek bool operator!=(const ProgramPoint& RHS) const { 82d6b9e37311013bdf24fd709f7e9962e3b141e6fbTed Kremenek return K != RHS.K || Data != RHS.Data || Tag != RHS.Tag; 83d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek } 84d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek 855226755ab5ce6346f98b5f41cdcffbe84c5bb484Ted Kremenek void Profile(llvm::FoldingSetNodeID& ID) const { 86d6b9e37311013bdf24fd709f7e9962e3b141e6fbTed Kremenek ID.AddInteger((unsigned) K); 87d6b9e37311013bdf24fd709f7e9962e3b141e6fbTed Kremenek ID.AddPointer(Data.first); 88d6b9e37311013bdf24fd709f7e9962e3b141e6fbTed Kremenek ID.AddPointer(Data.second); 89e8063ae53bd241de10ba1053054d06867a5c56abTed Kremenek ID.AddPointer(Tag); 902680b5f926fad29c1a2b2723a70d189f4b637979Ted Kremenek } 91eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenek}; 9283c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek 9383c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenekclass BlockEntrance : public ProgramPoint { 94eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenekpublic: 95ab422d17dce198f2af9851340ea7384771a2a8c5Ted Kremenek BlockEntrance(const CFGBlock* B, const void *tag = 0) 96ab422d17dce198f2af9851340ea7384771a2a8c5Ted Kremenek : ProgramPoint(B, BlockEntranceKind, tag) {} 9783c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek 9883c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek CFGBlock* getBlock() const { 99d6b9e37311013bdf24fd709f7e9962e3b141e6fbTed Kremenek return const_cast<CFGBlock*>(reinterpret_cast<const CFGBlock*>(getData1())); 100bd129696c554fbbcd9405104641e292f0fb4678dTed Kremenek } 101eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenek 10283c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek Stmt* getFirstStmt() const { 103d6b9e37311013bdf24fd709f7e9962e3b141e6fbTed Kremenek const CFGBlock* B = getBlock(); 10483c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek return B->empty() ? NULL : B->front(); 10583c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek } 106eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenek 10783c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek static bool classof(const ProgramPoint* Location) { 10883c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek return Location->getKind() == BlockEntranceKind; 109bd129696c554fbbcd9405104641e292f0fb4678dTed Kremenek } 110eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenek}; 11183c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek 11283c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenekclass BlockExit : public ProgramPoint { 113eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenekpublic: 11483c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek BlockExit(const CFGBlock* B) : ProgramPoint(B, BlockExitKind) {} 115bd129696c554fbbcd9405104641e292f0fb4678dTed Kremenek 11683c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek CFGBlock* getBlock() const { 117d6b9e37311013bdf24fd709f7e9962e3b141e6fbTed Kremenek return const_cast<CFGBlock*>(reinterpret_cast<const CFGBlock*>(getData1())); 118bd129696c554fbbcd9405104641e292f0fb4678dTed Kremenek } 11983c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek 12083c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek Stmt* getLastStmt() const { 121d6b9e37311013bdf24fd709f7e9962e3b141e6fbTed Kremenek const CFGBlock* B = getBlock(); 12283c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek return B->empty() ? NULL : B->back(); 123bd129696c554fbbcd9405104641e292f0fb4678dTed Kremenek } 124bd129696c554fbbcd9405104641e292f0fb4678dTed Kremenek 12583c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek Stmt* getTerminator() const { 12683c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek return getBlock()->getTerminator(); 127bd129696c554fbbcd9405104641e292f0fb4678dTed Kremenek } 12883c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek 12983c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek static bool classof(const ProgramPoint* Location) { 13083c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek return Location->getKind() == BlockExitKind; 131bd129696c554fbbcd9405104641e292f0fb4678dTed Kremenek } 132bd129696c554fbbcd9405104641e292f0fb4678dTed Kremenek}; 1335f85e17df3f5b0a8021443f2b590daecfb2cbd17Ted Kremenek 1345f85e17df3f5b0a8021443f2b590daecfb2cbd17Ted Kremenekclass StmtPoint : public ProgramPoint { 1355f85e17df3f5b0a8021443f2b590daecfb2cbd17Ted Kremenekpublic: 1365f85e17df3f5b0a8021443f2b590daecfb2cbd17Ted Kremenek StmtPoint(const Stmt *S, const void *p2, Kind k, const void *tag) 1375f85e17df3f5b0a8021443f2b590daecfb2cbd17Ted Kremenek : ProgramPoint(S, p2, k, tag) {} 1385f85e17df3f5b0a8021443f2b590daecfb2cbd17Ted Kremenek 1395f85e17df3f5b0a8021443f2b590daecfb2cbd17Ted Kremenek const Stmt *getStmt() const { return (const Stmt*) getData1(); } 1405f85e17df3f5b0a8021443f2b590daecfb2cbd17Ted Kremenek 1415f85e17df3f5b0a8021443f2b590daecfb2cbd17Ted Kremenek template <typename T> 1425f85e17df3f5b0a8021443f2b590daecfb2cbd17Ted Kremenek const T* getStmtAs() const { return llvm::dyn_cast<T>(getStmt()); } 1435f85e17df3f5b0a8021443f2b590daecfb2cbd17Ted Kremenek 1445f85e17df3f5b0a8021443f2b590daecfb2cbd17Ted Kremenek static bool classof(const ProgramPoint* Location) { 1455f85e17df3f5b0a8021443f2b590daecfb2cbd17Ted Kremenek unsigned k = Location->getKind(); 1465f85e17df3f5b0a8021443f2b590daecfb2cbd17Ted Kremenek return k >= PreStmtKind && k <= MaxPostStmtKind; 1475f85e17df3f5b0a8021443f2b590daecfb2cbd17Ted Kremenek } 1485f85e17df3f5b0a8021443f2b590daecfb2cbd17Ted Kremenek}; 149eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenek 1505f85e17df3f5b0a8021443f2b590daecfb2cbd17Ted Kremenek 1515f85e17df3f5b0a8021443f2b590daecfb2cbd17Ted Kremenekclass PreStmt : public StmtPoint { 152cdd4f1783da7c7565be2376d14ca6ab2625aa4b6Ted Kremenekpublic: 153cdd4f1783da7c7565be2376d14ca6ab2625aa4b6Ted Kremenek PreStmt(const Stmt *S, const void *tag, const Stmt *SubStmt = 0) 1545f85e17df3f5b0a8021443f2b590daecfb2cbd17Ted Kremenek : StmtPoint(S, SubStmt, PreStmtKind, tag) {} 155cdd4f1783da7c7565be2376d14ca6ab2625aa4b6Ted Kremenek 156cdd4f1783da7c7565be2376d14ca6ab2625aa4b6Ted Kremenek const Stmt *getSubStmt() const { return (const Stmt*) getData2(); } 157cdd4f1783da7c7565be2376d14ca6ab2625aa4b6Ted Kremenek 158cdd4f1783da7c7565be2376d14ca6ab2625aa4b6Ted Kremenek static bool classof(const ProgramPoint* Location) { 159cdd4f1783da7c7565be2376d14ca6ab2625aa4b6Ted Kremenek return Location->getKind() == PreStmtKind; 160cdd4f1783da7c7565be2376d14ca6ab2625aa4b6Ted Kremenek } 161cdd4f1783da7c7565be2376d14ca6ab2625aa4b6Ted Kremenek}; 162cdd4f1783da7c7565be2376d14ca6ab2625aa4b6Ted Kremenek 1635f85e17df3f5b0a8021443f2b590daecfb2cbd17Ted Kremenekclass PostStmt : public StmtPoint { 1641b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenekprotected: 165cdd4f1783da7c7565be2376d14ca6ab2625aa4b6Ted Kremenek PostStmt(const Stmt* S, Kind k, const void *tag = 0) 1665f85e17df3f5b0a8021443f2b590daecfb2cbd17Ted Kremenek : StmtPoint(S, NULL, k, tag) {} 167e8063ae53bd241de10ba1053054d06867a5c56abTed Kremenek 168d6b9e37311013bdf24fd709f7e9962e3b141e6fbTed Kremenek PostStmt(const Stmt* S, const void* data, Kind k, const void *tag =0) 1695f85e17df3f5b0a8021443f2b590daecfb2cbd17Ted Kremenek : StmtPoint(S, data, k, tag) {} 170f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek 171eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenekpublic: 1725f85e17df3f5b0a8021443f2b590daecfb2cbd17Ted Kremenek explicit PostStmt(const Stmt* S, const void *tag = 0) 1735f85e17df3f5b0a8021443f2b590daecfb2cbd17Ted Kremenek : StmtPoint(S, NULL, PostStmtKind, tag) {} 17483c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek 17583c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek static bool classof(const ProgramPoint* Location) { 1761b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenek unsigned k = Location->getKind(); 177f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek return k >= MinPostStmtKind && k <= MaxPostStmtKind; 1781b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenek } 1791b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenek}; 1808c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek 1818c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenekclass PostLocationChecksSucceed : public PostStmt { 1828c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenekpublic: 183e8063ae53bd241de10ba1053054d06867a5c56abTed Kremenek PostLocationChecksSucceed(const Stmt* S, const void *tag = 0) 184e8063ae53bd241de10ba1053054d06867a5c56abTed Kremenek : PostStmt(S, PostLocationChecksSucceedKind, tag) {} 1858c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek 1868c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek static bool classof(const ProgramPoint* Location) { 1878c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek return Location->getKind() == PostLocationChecksSucceedKind; 1888c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek } 1898c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek}; 1908c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek 191f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenekclass PostStmtCustom : public PostStmt { 1922680b5f926fad29c1a2b2723a70d189f4b637979Ted Kremenekpublic: 19359753441b6391a9843eff287f0adb2614153b7c8Ted Kremenek PostStmtCustom(const Stmt* S, 19459753441b6391a9843eff287f0adb2614153b7c8Ted Kremenek const std::pair<const void*, const void*>* TaggedData) 195d6b9e37311013bdf24fd709f7e9962e3b141e6fbTed Kremenek : PostStmt(S, TaggedData, PostStmtCustomKind) {} 19659753441b6391a9843eff287f0adb2614153b7c8Ted Kremenek 19759753441b6391a9843eff287f0adb2614153b7c8Ted Kremenek const std::pair<const void*, const void*>& getTaggedPair() const { 198d6b9e37311013bdf24fd709f7e9962e3b141e6fbTed Kremenek return 199d6b9e37311013bdf24fd709f7e9962e3b141e6fbTed Kremenek *reinterpret_cast<const std::pair<const void*, const void*>*>(getData2()); 20059753441b6391a9843eff287f0adb2614153b7c8Ted Kremenek } 20159753441b6391a9843eff287f0adb2614153b7c8Ted Kremenek 20259753441b6391a9843eff287f0adb2614153b7c8Ted Kremenek const void* getTag() const { return getTaggedPair().first; } 203f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek 20459753441b6391a9843eff287f0adb2614153b7c8Ted Kremenek const void* getTaggedData() const { return getTaggedPair().second; } 205f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek 206f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek static bool classof(const ProgramPoint* Location) { 207f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek return Location->getKind() == PostStmtCustomKind; 208f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek } 209f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek}; 210f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek 2118c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenekclass PostOutOfBoundsCheckFailed : public PostStmt { 2128c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenekpublic: 2131670e403c48f3af4fceff3f6773a0e1cfc6c4eb3Ted Kremenek PostOutOfBoundsCheckFailed(const Stmt* S, const void *tag = 0) 2141670e403c48f3af4fceff3f6773a0e1cfc6c4eb3Ted Kremenek : PostStmt(S, PostOutOfBoundsCheckFailedKind, tag) {} 2158c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek 2168c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek static bool classof(const ProgramPoint* Location) { 2178c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek return Location->getKind() == PostOutOfBoundsCheckFailedKind; 2188c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek } 2198c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek}; 2208c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek 2218c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenekclass PostUndefLocationCheckFailed : public PostStmt { 2228c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenekpublic: 2231670e403c48f3af4fceff3f6773a0e1cfc6c4eb3Ted Kremenek PostUndefLocationCheckFailed(const Stmt* S, const void *tag = 0) 2241670e403c48f3af4fceff3f6773a0e1cfc6c4eb3Ted Kremenek : PostStmt(S, PostUndefLocationCheckFailedKind, tag) {} 2258c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek 2268c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek static bool classof(const ProgramPoint* Location) { 2278c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek return Location->getKind() == PostUndefLocationCheckFailedKind; 2288c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek } 2298c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek}; 2308c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek 2318c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenekclass PostNullCheckFailed : public PostStmt { 2328c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenekpublic: 2331670e403c48f3af4fceff3f6773a0e1cfc6c4eb3Ted Kremenek PostNullCheckFailed(const Stmt* S, const void *tag = 0) 2341670e403c48f3af4fceff3f6773a0e1cfc6c4eb3Ted Kremenek : PostStmt(S, PostNullCheckFailedKind, tag) {} 2358c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek 2368c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek static bool classof(const ProgramPoint* Location) { 2378c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek return Location->getKind() == PostNullCheckFailedKind; 2388c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek } 2398c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek}; 2401b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenek 2411b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenekclass PostLoad : public PostStmt { 2421b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenekpublic: 243e8063ae53bd241de10ba1053054d06867a5c56abTed Kremenek PostLoad(const Stmt* S, const void *tag = 0) 244e8063ae53bd241de10ba1053054d06867a5c56abTed Kremenek : PostStmt(S, PostLoadKind, tag) {} 2451b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenek 2461b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenek static bool classof(const ProgramPoint* Location) { 2471b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenek return Location->getKind() == PostLoadKind; 248bd129696c554fbbcd9405104641e292f0fb4678dTed Kremenek } 249eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenek}; 250b6d2360787e5a0bb5d26f3bc7a83059a8b050dc4Ted Kremenek 25182bae3f6bf7bc4733d9c87659b266e23ad55f420Ted Kremenekclass PostStore : public PostStmt { 25282bae3f6bf7bc4733d9c87659b266e23ad55f420Ted Kremenekpublic: 253e8063ae53bd241de10ba1053054d06867a5c56abTed Kremenek PostStore(const Stmt* S, const void *tag = 0) 254e8063ae53bd241de10ba1053054d06867a5c56abTed Kremenek : PostStmt(S, PostStoreKind, tag) {} 25582bae3f6bf7bc4733d9c87659b266e23ad55f420Ted Kremenek 25682bae3f6bf7bc4733d9c87659b266e23ad55f420Ted Kremenek static bool classof(const ProgramPoint* Location) { 25782bae3f6bf7bc4733d9c87659b266e23ad55f420Ted Kremenek return Location->getKind() == PostStoreKind; 25882bae3f6bf7bc4733d9c87659b266e23ad55f420Ted Kremenek } 25982bae3f6bf7bc4733d9c87659b266e23ad55f420Ted Kremenek}; 2607090d5465de7ca620da16211cf886edf1edc1f1fTed Kremenek 2617090d5465de7ca620da16211cf886edf1edc1f1fTed Kremenekclass PostLValue : public PostStmt { 2627090d5465de7ca620da16211cf886edf1edc1f1fTed Kremenekpublic: 2637090d5465de7ca620da16211cf886edf1edc1f1fTed Kremenek PostLValue(const Stmt* S, const void *tag = 0) 2647090d5465de7ca620da16211cf886edf1edc1f1fTed Kremenek : PostStmt(S, PostLValueKind, tag) {} 2657090d5465de7ca620da16211cf886edf1edc1f1fTed Kremenek 2667090d5465de7ca620da16211cf886edf1edc1f1fTed Kremenek static bool classof(const ProgramPoint* Location) { 2677090d5465de7ca620da16211cf886edf1edc1f1fTed Kremenek return Location->getKind() == PostLValueKind; 2687090d5465de7ca620da16211cf886edf1edc1f1fTed Kremenek } 2697090d5465de7ca620da16211cf886edf1edc1f1fTed Kremenek}; 27082bae3f6bf7bc4733d9c87659b266e23ad55f420Ted Kremenek 271331b0ac44b9eb0ffcba66b4f3f3f9adb27c2434fTed Kremenekclass PostPurgeDeadSymbols : public PostStmt { 272331b0ac44b9eb0ffcba66b4f3f3f9adb27c2434fTed Kremenekpublic: 2731670e403c48f3af4fceff3f6773a0e1cfc6c4eb3Ted Kremenek PostPurgeDeadSymbols(const Stmt* S, const void *tag = 0) 2741670e403c48f3af4fceff3f6773a0e1cfc6c4eb3Ted Kremenek : PostStmt(S, PostPurgeDeadSymbolsKind, tag) {} 275331b0ac44b9eb0ffcba66b4f3f3f9adb27c2434fTed Kremenek 276331b0ac44b9eb0ffcba66b4f3f3f9adb27c2434fTed Kremenek static bool classof(const ProgramPoint* Location) { 277331b0ac44b9eb0ffcba66b4f3f3f9adb27c2434fTed Kremenek return Location->getKind() == PostPurgeDeadSymbolsKind; 278331b0ac44b9eb0ffcba66b4f3f3f9adb27c2434fTed Kremenek } 279331b0ac44b9eb0ffcba66b4f3f3f9adb27c2434fTed Kremenek}; 280331b0ac44b9eb0ffcba66b4f3f3f9adb27c2434fTed Kremenek 28183c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenekclass BlockEdge : public ProgramPoint { 282b6d2360787e5a0bb5d26f3bc7a83059a8b050dc4Ted Kremenekpublic: 283d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek BlockEdge(const CFGBlock* B1, const CFGBlock* B2) 284d6b9e37311013bdf24fd709f7e9962e3b141e6fbTed Kremenek : ProgramPoint(B1, B2, BlockEdgeKind) {} 285d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek 286d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek CFGBlock* getSrc() const { 287d6b9e37311013bdf24fd709f7e9962e3b141e6fbTed Kremenek return const_cast<CFGBlock*>(static_cast<const CFGBlock*>(getData1())); 288d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek } 289d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek 290d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek CFGBlock* getDst() const { 291d6b9e37311013bdf24fd709f7e9962e3b141e6fbTed Kremenek return const_cast<CFGBlock*>(static_cast<const CFGBlock*>(getData2())); 292d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek } 293b6d2360787e5a0bb5d26f3bc7a83059a8b050dc4Ted Kremenek 29483c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek static bool classof(const ProgramPoint* Location) { 295d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek return Location->getKind() == BlockEdgeKind; 296b6d2360787e5a0bb5d26f3bc7a83059a8b050dc4Ted Kremenek } 297b6d2360787e5a0bb5d26f3bc7a83059a8b050dc4Ted Kremenek}; 29883c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek 29983c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek 300eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenek} // end namespace clang 3014c3fbe33194cd9b1bfff773647ed785b403e1ba5Ted Kremenek 3024c3fbe33194cd9b1bfff773647ed785b403e1ba5Ted Kremenek 3034c3fbe33194cd9b1bfff773647ed785b403e1ba5Ted Kremeneknamespace llvm { // Traits specialization for DenseMap 3044c3fbe33194cd9b1bfff773647ed785b403e1ba5Ted Kremenek 30583c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenektemplate <> struct DenseMapInfo<clang::ProgramPoint> { 3064c3fbe33194cd9b1bfff773647ed785b403e1ba5Ted Kremenek 307d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenekstatic inline clang::ProgramPoint getEmptyKey() { 308d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek uintptr_t x = 309d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek reinterpret_cast<uintptr_t>(DenseMapInfo<void*>::getEmptyKey()) & ~0x7; 310d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek return clang::BlockEntrance(reinterpret_cast<clang::CFGBlock*>(x)); 311d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek} 312d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek 313d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenekstatic inline clang::ProgramPoint getTombstoneKey() { 314d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek uintptr_t x = 315d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek reinterpret_cast<uintptr_t>(DenseMapInfo<void*>::getTombstoneKey()) & ~0x7; 316d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek return clang::BlockEntrance(reinterpret_cast<clang::CFGBlock*>(x)); 317d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek} 318d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek 319d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenekstatic unsigned getHashValue(const clang::ProgramPoint& Loc) { 320d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek return Loc.getHashValue(); 321d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek} 322d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek 323d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenekstatic bool isEqual(const clang::ProgramPoint& L, 324d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek const clang::ProgramPoint& R) { 325d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek return L == R; 326d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek} 327d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek 328d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenekstatic bool isPod() { 329d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek return true; 330d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek} 3314c3fbe33194cd9b1bfff773647ed785b403e1ba5Ted Kremenek}; 3324c3fbe33194cd9b1bfff773647ed785b403e1ba5Ted Kremenek} // end namespace llvm 3334c3fbe33194cd9b1bfff773647ed785b403e1ba5Ted Kremenek 334eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenek#endif 335