ProgramPoint.h revision 2680b5f926fad29c1a2b2723a70d189f4b637979
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 1805e14cd46ef44c07385aae96ec2fdcb9bf7e9467Ted Kremenek#include "clang/AST/CFG.h" 19eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenek#include "llvm/Support/DataTypes.h" 204c3fbe33194cd9b1bfff773647ed785b403e1ba5Ted Kremenek#include "llvm/ADT/DenseMap.h" 215226755ab5ce6346f98b5f41cdcffbe84c5bb484Ted Kremenek#include "llvm/ADT/FoldingSet.h" 224c3fbe33194cd9b1bfff773647ed785b403e1ba5Ted Kremenek#include <cassert> 2359753441b6391a9843eff287f0adb2614153b7c8Ted Kremenek#include <utility> 24eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenek 25eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremeneknamespace clang { 2605e14cd46ef44c07385aae96ec2fdcb9bf7e9467Ted Kremenek 2783c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenekclass ProgramPoint { 28eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenekpublic: 29f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek enum Kind { BlockEdgeKind = 0x0, 30f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek BlockEntranceKind = 0x1, 31f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek BlockExitKind = 0x2, 3282bae3f6bf7bc4733d9c87659b266e23ad55f420Ted Kremenek // Keep the following four together and in this order. 33f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek PostStmtKind = 0x3, 34f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek PostLocationChecksSucceedKind = 0x4, 35f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek PostOutOfBoundsCheckFailedKind = 0x5, 36f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek PostNullCheckFailedKind = 0x6, 37f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek PostUndefLocationCheckFailedKind = 0x7, 38f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek PostLoadKind = 0x8, 39f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek PostStoreKind = 0x9, 40f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek PostPurgeDeadSymbolsKind = 0x10, 41f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek PostStmtCustomKind = 0x11, 42f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek MinPostStmtKind = PostStmtKind, 43f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek MaxPostStmtKind = PostStmtCustomKind }; 444c3fbe33194cd9b1bfff773647ed785b403e1ba5Ted Kremenek 45d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenekprivate: 46f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek enum { TwoPointers = 0x1, Custom = 0x2, Mask = 0x3 }; 47f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek 48d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek std::pair<uintptr_t,uintptr_t> Data; 49d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek 50d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenekprotected: 51d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek ProgramPoint(const void* P, Kind k) 52f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek : Data(reinterpret_cast<uintptr_t>(P), 53f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek (uintptr_t) k) {} 54d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek 55d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek ProgramPoint(const void* P1, const void* P2) 56f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek : Data(reinterpret_cast<uintptr_t>(P1) | TwoPointers, 57d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek reinterpret_cast<uintptr_t>(P2)) {} 58f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek 59f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek ProgramPoint(const void* P1, const void* P2, bool) 60f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek : Data(reinterpret_cast<uintptr_t>(P1) | Custom, 61f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek reinterpret_cast<uintptr_t>(P2)) {} 62f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek 63d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenekprotected: 64d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek void* getData1NoMask() const { 65f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek Kind k = getKind(); k = k; 66f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek assert(k == BlockEntranceKind || k == BlockExitKind); 67d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek return reinterpret_cast<void*>(Data.first); 686e5977f0a8a680191fb4b4d8f32bc2c629faf0c2Argyrios Kyrtzidis } 696e5977f0a8a680191fb4b4d8f32bc2c629faf0c2Argyrios Kyrtzidis 70d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek void* getData1() const { 71f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek Kind k = getKind(); k = k; 722680b5f926fad29c1a2b2723a70d189f4b637979Ted Kremenek assert(k == BlockEdgeKind ||(k >= MinPostStmtKind && k <= MaxPostStmtKind)); 73f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek return reinterpret_cast<void*>(Data.first & ~Mask); 74d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek } 756e5977f0a8a680191fb4b4d8f32bc2c629faf0c2Argyrios Kyrtzidis 76d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek void* getData2() const { 77f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek Kind k = getKind(); k = k; 78f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek assert(k == BlockEdgeKind || k == PostStmtCustomKind); 79d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek return reinterpret_cast<void*>(Data.second); 804c3fbe33194cd9b1bfff773647ed785b403e1ba5Ted Kremenek } 81f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek 8283c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenekpublic: 83f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek Kind getKind() const { 84f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek switch (Data.first & Mask) { 85f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek case TwoPointers: return BlockEdgeKind; 86f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek case Custom: return PostStmtCustomKind; 87f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek default: return (Kind) Data.second; 88f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek } 89d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek } 90d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek 91d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek // For use with DenseMap. 92d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek unsigned getHashValue() const { 93d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek std::pair<void*,void*> P(reinterpret_cast<void*>(Data.first), 94d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek reinterpret_cast<void*>(Data.second)); 95d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek return llvm::DenseMapInfo<std::pair<void*,void*> >::getHashValue(P); 96d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek } 97eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenek 9883c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek static bool classof(const ProgramPoint*) { return true; } 99d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek 100d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek bool operator==(const ProgramPoint & RHS) const { 101d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek return Data == RHS.Data; 102d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek } 103d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek 104d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek bool operator!=(const ProgramPoint& RHS) const { 105d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek return Data != RHS.Data; 106d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek } 107d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek 108d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek bool operator<(const ProgramPoint& RHS) const { 109d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek return Data < RHS.Data; 110d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek } 1115226755ab5ce6346f98b5f41cdcffbe84c5bb484Ted Kremenek 1125226755ab5ce6346f98b5f41cdcffbe84c5bb484Ted Kremenek void Profile(llvm::FoldingSetNodeID& ID) const { 113d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek ID.AddPointer(reinterpret_cast<void*>(Data.first)); 1142680b5f926fad29c1a2b2723a70d189f4b637979Ted Kremenek if (getKind() != PostStmtCustomKind) 1152680b5f926fad29c1a2b2723a70d189f4b637979Ted Kremenek ID.AddPointer(reinterpret_cast<void*>(Data.second)); 1162680b5f926fad29c1a2b2723a70d189f4b637979Ted Kremenek else { 1172680b5f926fad29c1a2b2723a70d189f4b637979Ted Kremenek const std::pair<const void*, const void*> *P = 1182680b5f926fad29c1a2b2723a70d189f4b637979Ted Kremenek reinterpret_cast<std::pair<const void*, const void*>*>(Data.second); 1192680b5f926fad29c1a2b2723a70d189f4b637979Ted Kremenek ID.AddPointer(P->first); 1202680b5f926fad29c1a2b2723a70d189f4b637979Ted Kremenek ID.AddPointer(P->second); 1212680b5f926fad29c1a2b2723a70d189f4b637979Ted Kremenek } 1222680b5f926fad29c1a2b2723a70d189f4b637979Ted Kremenek } 123eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenek}; 12483c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek 12583c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenekclass BlockEntrance : public ProgramPoint { 126eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenekpublic: 12783c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek BlockEntrance(const CFGBlock* B) : ProgramPoint(B, BlockEntranceKind) {} 12883c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek 12983c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek CFGBlock* getBlock() const { 130d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek return reinterpret_cast<CFGBlock*>(getData1NoMask()); 131bd129696c554fbbcd9405104641e292f0fb4678dTed Kremenek } 132eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenek 13383c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek Stmt* getFirstStmt() const { 13483c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek CFGBlock* B = getBlock(); 13583c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek return B->empty() ? NULL : B->front(); 13683c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek } 137eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenek 13883c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek static bool classof(const ProgramPoint* Location) { 13983c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek return Location->getKind() == BlockEntranceKind; 140bd129696c554fbbcd9405104641e292f0fb4678dTed Kremenek } 141eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenek}; 14283c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek 14383c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenekclass BlockExit : public ProgramPoint { 144eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenekpublic: 14583c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek BlockExit(const CFGBlock* B) : ProgramPoint(B, BlockExitKind) {} 146bd129696c554fbbcd9405104641e292f0fb4678dTed Kremenek 14783c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek CFGBlock* getBlock() const { 148d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek return reinterpret_cast<CFGBlock*>(getData1NoMask()); 149bd129696c554fbbcd9405104641e292f0fb4678dTed Kremenek } 15083c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek 15183c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek Stmt* getLastStmt() const { 15283c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek CFGBlock* B = getBlock(); 15383c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek return B->empty() ? NULL : B->back(); 154bd129696c554fbbcd9405104641e292f0fb4678dTed Kremenek } 155bd129696c554fbbcd9405104641e292f0fb4678dTed Kremenek 15683c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek Stmt* getTerminator() const { 15783c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek return getBlock()->getTerminator(); 158bd129696c554fbbcd9405104641e292f0fb4678dTed Kremenek } 15983c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek 16083c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek static bool classof(const ProgramPoint* Location) { 16183c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek return Location->getKind() == BlockExitKind; 162bd129696c554fbbcd9405104641e292f0fb4678dTed Kremenek } 163bd129696c554fbbcd9405104641e292f0fb4678dTed Kremenek}; 164eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenek 16583c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek 16683c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenekclass PostStmt : public ProgramPoint { 1671b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenekprotected: 168f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek PostStmt(const Stmt* S, Kind k) : ProgramPoint(S, k) {} 169f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek PostStmt(const Stmt* S, const void* data) : ProgramPoint(S, data, true) {} 170f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek 171eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenekpublic: 17283c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek PostStmt(const Stmt* S) : ProgramPoint(S, PostStmtKind) {} 1731b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenek 174f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek Stmt* getStmt() const { return (Stmt*) getData1(); } 17583c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek 17683c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek static bool classof(const ProgramPoint* Location) { 1771b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenek unsigned k = Location->getKind(); 178f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek return k >= MinPostStmtKind && k <= MaxPostStmtKind; 1791b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenek } 1801b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenek}; 1818c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek 1828c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenekclass PostLocationChecksSucceed : public PostStmt { 1838c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenekpublic: 1848c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek PostLocationChecksSucceed(const Stmt* S) 1858c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek : PostStmt(S, PostLocationChecksSucceedKind) {} 1868c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek 1878c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek static bool classof(const ProgramPoint* Location) { 1888c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek return Location->getKind() == PostLocationChecksSucceedKind; 1898c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek } 1908c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek}; 1918c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek 192f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenekclass PostStmtCustom : public PostStmt { 1932680b5f926fad29c1a2b2723a70d189f4b637979Ted Kremenekpublic: 19459753441b6391a9843eff287f0adb2614153b7c8Ted Kremenek PostStmtCustom(const Stmt* S, 19559753441b6391a9843eff287f0adb2614153b7c8Ted Kremenek const std::pair<const void*, const void*>* TaggedData) 19659753441b6391a9843eff287f0adb2614153b7c8Ted Kremenek : PostStmt(S, TaggedData) { 197f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek assert(getKind() == PostStmtCustomKind); 198f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek } 19959753441b6391a9843eff287f0adb2614153b7c8Ted Kremenek 20059753441b6391a9843eff287f0adb2614153b7c8Ted Kremenek const std::pair<const void*, const void*>& getTaggedPair() const { 20159753441b6391a9843eff287f0adb2614153b7c8Ted Kremenek return *reinterpret_cast<std::pair<const void*, const void*>*>(getData2()); 20259753441b6391a9843eff287f0adb2614153b7c8Ted Kremenek } 20359753441b6391a9843eff287f0adb2614153b7c8Ted Kremenek 20459753441b6391a9843eff287f0adb2614153b7c8Ted Kremenek const void* getTag() const { return getTaggedPair().first; } 205f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek 20659753441b6391a9843eff287f0adb2614153b7c8Ted Kremenek const void* getTaggedData() const { return getTaggedPair().second; } 207f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek 208f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek static bool classof(const ProgramPoint* Location) { 209f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek return Location->getKind() == PostStmtCustomKind; 210f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek } 211f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek}; 212f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek 2138c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenekclass PostOutOfBoundsCheckFailed : public PostStmt { 2148c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenekpublic: 2158c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek PostOutOfBoundsCheckFailed(const Stmt* S) 2168c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek : PostStmt(S, PostOutOfBoundsCheckFailedKind) {} 2178c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek 2188c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek static bool classof(const ProgramPoint* Location) { 2198c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek return Location->getKind() == PostOutOfBoundsCheckFailedKind; 2208c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek } 2218c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek}; 2228c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek 2238c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenekclass PostUndefLocationCheckFailed : public PostStmt { 2248c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenekpublic: 2258c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek PostUndefLocationCheckFailed(const Stmt* S) 2268c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek : PostStmt(S, PostUndefLocationCheckFailedKind) {} 2278c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek 2288c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek static bool classof(const ProgramPoint* Location) { 2298c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek return Location->getKind() == PostUndefLocationCheckFailedKind; 2308c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek } 2318c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek}; 2328c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek 2338c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenekclass PostNullCheckFailed : public PostStmt { 2348c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenekpublic: 2358c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek PostNullCheckFailed(const Stmt* S) 2368c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek : PostStmt(S, PostNullCheckFailedKind) {} 2378c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek 2388c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek static bool classof(const ProgramPoint* Location) { 2398c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek return Location->getKind() == PostNullCheckFailedKind; 2408c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek } 2418c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek}; 2421b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenek 2431b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenekclass PostLoad : public PostStmt { 2441b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenekpublic: 2451b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenek PostLoad(const Stmt* S) : PostStmt(S, PostLoadKind) {} 2461b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenek 2471b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenek static bool classof(const ProgramPoint* Location) { 2481b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenek return Location->getKind() == PostLoadKind; 249bd129696c554fbbcd9405104641e292f0fb4678dTed Kremenek } 250eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenek}; 251b6d2360787e5a0bb5d26f3bc7a83059a8b050dc4Ted Kremenek 25282bae3f6bf7bc4733d9c87659b266e23ad55f420Ted Kremenekclass PostStore : public PostStmt { 25382bae3f6bf7bc4733d9c87659b266e23ad55f420Ted Kremenekpublic: 2548c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek PostStore(const Stmt* S) : PostStmt(S, PostStoreKind) {} 25582bae3f6bf7bc4733d9c87659b266e23ad55f420Ted Kremenek 25682bae3f6bf7bc4733d9c87659b266e23ad55f420Ted Kremenek static bool classof(const ProgramPoint* Location) { 25782bae3f6bf7bc4733d9c87659b266e23ad55f420Ted Kremenek return Location->getKind() == PostStoreKind; 25882bae3f6bf7bc4733d9c87659b266e23ad55f420Ted Kremenek } 25982bae3f6bf7bc4733d9c87659b266e23ad55f420Ted Kremenek}; 26082bae3f6bf7bc4733d9c87659b266e23ad55f420Ted Kremenek 261331b0ac44b9eb0ffcba66b4f3f3f9adb27c2434fTed Kremenekclass PostPurgeDeadSymbols : public PostStmt { 262331b0ac44b9eb0ffcba66b4f3f3f9adb27c2434fTed Kremenekpublic: 263331b0ac44b9eb0ffcba66b4f3f3f9adb27c2434fTed Kremenek PostPurgeDeadSymbols(const Stmt* S) : PostStmt(S, PostPurgeDeadSymbolsKind) {} 264331b0ac44b9eb0ffcba66b4f3f3f9adb27c2434fTed Kremenek 265331b0ac44b9eb0ffcba66b4f3f3f9adb27c2434fTed Kremenek static bool classof(const ProgramPoint* Location) { 266331b0ac44b9eb0ffcba66b4f3f3f9adb27c2434fTed Kremenek return Location->getKind() == PostPurgeDeadSymbolsKind; 267331b0ac44b9eb0ffcba66b4f3f3f9adb27c2434fTed Kremenek } 268331b0ac44b9eb0ffcba66b4f3f3f9adb27c2434fTed Kremenek}; 269331b0ac44b9eb0ffcba66b4f3f3f9adb27c2434fTed Kremenek 27083c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenekclass BlockEdge : public ProgramPoint { 271b6d2360787e5a0bb5d26f3bc7a83059a8b050dc4Ted Kremenekpublic: 272d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek BlockEdge(const CFGBlock* B1, const CFGBlock* B2) 273d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek : ProgramPoint(B1, B2) {} 274d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek 275d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek CFGBlock* getSrc() const { 276d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek return static_cast<CFGBlock*>(getData1()); 277d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek } 278d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek 279d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek CFGBlock* getDst() const { 280d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek return static_cast<CFGBlock*>(getData2()); 281d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek } 282b6d2360787e5a0bb5d26f3bc7a83059a8b050dc4Ted Kremenek 28383c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek static bool classof(const ProgramPoint* Location) { 284d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek return Location->getKind() == BlockEdgeKind; 285b6d2360787e5a0bb5d26f3bc7a83059a8b050dc4Ted Kremenek } 286b6d2360787e5a0bb5d26f3bc7a83059a8b050dc4Ted Kremenek}; 28783c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek 28883c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek 289eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenek} // end namespace clang 2904c3fbe33194cd9b1bfff773647ed785b403e1ba5Ted Kremenek 2914c3fbe33194cd9b1bfff773647ed785b403e1ba5Ted Kremenek 2924c3fbe33194cd9b1bfff773647ed785b403e1ba5Ted Kremeneknamespace llvm { // Traits specialization for DenseMap 2934c3fbe33194cd9b1bfff773647ed785b403e1ba5Ted Kremenek 29483c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenektemplate <> struct DenseMapInfo<clang::ProgramPoint> { 2954c3fbe33194cd9b1bfff773647ed785b403e1ba5Ted Kremenek 296d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenekstatic inline clang::ProgramPoint getEmptyKey() { 297d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek uintptr_t x = 298d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek reinterpret_cast<uintptr_t>(DenseMapInfo<void*>::getEmptyKey()) & ~0x7; 299d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek return clang::BlockEntrance(reinterpret_cast<clang::CFGBlock*>(x)); 300d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek} 301d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek 302d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenekstatic inline clang::ProgramPoint getTombstoneKey() { 303d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek uintptr_t x = 304d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek reinterpret_cast<uintptr_t>(DenseMapInfo<void*>::getTombstoneKey()) & ~0x7; 305d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek return clang::BlockEntrance(reinterpret_cast<clang::CFGBlock*>(x)); 306d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek} 307d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek 308d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenekstatic unsigned getHashValue(const clang::ProgramPoint& Loc) { 309d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek return Loc.getHashValue(); 310d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek} 311d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek 312d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenekstatic bool isEqual(const clang::ProgramPoint& L, 313d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek const clang::ProgramPoint& R) { 314d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek return L == R; 315d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek} 316d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek 317d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenekstatic bool isPod() { 318d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek return true; 319d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek} 3204c3fbe33194cd9b1bfff773647ed785b403e1ba5Ted Kremenek}; 3214c3fbe33194cd9b1bfff773647ed785b403e1ba5Ted Kremenek} // end namespace llvm 3224c3fbe33194cd9b1bfff773647ed785b403e1ba5Ted Kremenek 323eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenek#endif 324