ProgramPoint.h revision f4be8ee748831bc23e35b542e6c1bb6d1eb49baa
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> 23eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenek 24eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremeneknamespace clang { 2505e14cd46ef44c07385aae96ec2fdcb9bf7e9467Ted Kremenek 2683c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenekclass ProgramPoint { 27eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenekpublic: 28f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek enum Kind { BlockEdgeKind = 0x0, 29f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek BlockEntranceKind = 0x1, 30f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek BlockExitKind = 0x2, 3182bae3f6bf7bc4733d9c87659b266e23ad55f420Ted Kremenek // Keep the following four together and in this order. 32f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek PostStmtKind = 0x3, 33f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek PostLocationChecksSucceedKind = 0x4, 34f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek PostOutOfBoundsCheckFailedKind = 0x5, 35f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek PostNullCheckFailedKind = 0x6, 36f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek PostUndefLocationCheckFailedKind = 0x7, 37f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek PostLoadKind = 0x8, 38f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek PostStoreKind = 0x9, 39f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek PostPurgeDeadSymbolsKind = 0x10, 40f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek PostStmtCustomKind = 0x11, 41f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek MinPostStmtKind = PostStmtKind, 42f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek MaxPostStmtKind = PostStmtCustomKind }; 434c3fbe33194cd9b1bfff773647ed785b403e1ba5Ted Kremenek 44d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenekprivate: 45f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek enum { TwoPointers = 0x1, Custom = 0x2, Mask = 0x3 }; 46f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek 47d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek std::pair<uintptr_t,uintptr_t> Data; 48d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek 49d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenekprotected: 50d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek ProgramPoint(const void* P, Kind k) 51f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek : Data(reinterpret_cast<uintptr_t>(P), 52f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek (uintptr_t) k) {} 53d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek 54d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek ProgramPoint(const void* P1, const void* P2) 55f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek : Data(reinterpret_cast<uintptr_t>(P1) | TwoPointers, 56d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek reinterpret_cast<uintptr_t>(P2)) {} 57f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek 58f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek ProgramPoint(const void* P1, const void* P2, bool) 59f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek : Data(reinterpret_cast<uintptr_t>(P1) | Custom, 60f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek reinterpret_cast<uintptr_t>(P2)) {} 61f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek 62d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenekprotected: 63d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek void* getData1NoMask() const { 64f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek Kind k = getKind(); k = k; 65f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek assert(k == BlockEntranceKind || k == BlockExitKind); 66d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek return reinterpret_cast<void*>(Data.first); 676e5977f0a8a680191fb4b4d8f32bc2c629faf0c2Argyrios Kyrtzidis } 686e5977f0a8a680191fb4b4d8f32bc2c629faf0c2Argyrios Kyrtzidis 69d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek void* getData1() const { 70f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek Kind k = getKind(); k = k; 71f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek assert(k == BlockEdgeKind || (k >= MinPostStmtKind && k < MaxPostStmtKind)); 72f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek return reinterpret_cast<void*>(Data.first & ~Mask); 73d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek } 746e5977f0a8a680191fb4b4d8f32bc2c629faf0c2Argyrios Kyrtzidis 75d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek void* getData2() const { 76f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek Kind k = getKind(); k = k; 77f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek assert(k == BlockEdgeKind || k == PostStmtCustomKind); 78d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek return reinterpret_cast<void*>(Data.second); 794c3fbe33194cd9b1bfff773647ed785b403e1ba5Ted Kremenek } 80f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek 8183c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenekpublic: 82f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek Kind getKind() const { 83f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek switch (Data.first & Mask) { 84f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek case TwoPointers: return BlockEdgeKind; 85f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek case Custom: return PostStmtCustomKind; 86f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek default: return (Kind) Data.second; 87f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek } 88d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek } 89d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek 90d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek // For use with DenseMap. 91d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek unsigned getHashValue() const { 92d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek std::pair<void*,void*> P(reinterpret_cast<void*>(Data.first), 93d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek reinterpret_cast<void*>(Data.second)); 94d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek return llvm::DenseMapInfo<std::pair<void*,void*> >::getHashValue(P); 95d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek } 96eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenek 9783c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek static bool classof(const ProgramPoint*) { return true; } 98d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek 99d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek bool operator==(const ProgramPoint & RHS) const { 100d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek return Data == RHS.Data; 101d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek } 102d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek 103d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek bool operator!=(const ProgramPoint& RHS) const { 104d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek return Data != RHS.Data; 105d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek } 106d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek 107d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek bool operator<(const ProgramPoint& RHS) const { 108d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek return Data < RHS.Data; 109d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek } 1105226755ab5ce6346f98b5f41cdcffbe84c5bb484Ted Kremenek 1115226755ab5ce6346f98b5f41cdcffbe84c5bb484Ted Kremenek void Profile(llvm::FoldingSetNodeID& ID) const { 112d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek ID.AddPointer(reinterpret_cast<void*>(Data.first)); 113d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek ID.AddPointer(reinterpret_cast<void*>(Data.second)); 1145226755ab5ce6346f98b5f41cdcffbe84c5bb484Ted Kremenek } 115eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenek}; 11683c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek 11783c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenekclass BlockEntrance : public ProgramPoint { 118eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenekpublic: 11983c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek BlockEntrance(const CFGBlock* B) : ProgramPoint(B, BlockEntranceKind) {} 12083c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek 12183c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek CFGBlock* getBlock() const { 122d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek return reinterpret_cast<CFGBlock*>(getData1NoMask()); 123bd129696c554fbbcd9405104641e292f0fb4678dTed Kremenek } 124eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenek 12583c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek Stmt* getFirstStmt() const { 12683c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek CFGBlock* B = getBlock(); 12783c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek return B->empty() ? NULL : B->front(); 12883c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek } 129eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenek 13083c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek static bool classof(const ProgramPoint* Location) { 13183c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek return Location->getKind() == BlockEntranceKind; 132bd129696c554fbbcd9405104641e292f0fb4678dTed Kremenek } 133eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenek}; 13483c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek 13583c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenekclass BlockExit : public ProgramPoint { 136eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenekpublic: 13783c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek BlockExit(const CFGBlock* B) : ProgramPoint(B, BlockExitKind) {} 138bd129696c554fbbcd9405104641e292f0fb4678dTed Kremenek 13983c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek CFGBlock* getBlock() const { 140d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek return reinterpret_cast<CFGBlock*>(getData1NoMask()); 141bd129696c554fbbcd9405104641e292f0fb4678dTed Kremenek } 14283c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek 14383c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek Stmt* getLastStmt() const { 14483c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek CFGBlock* B = getBlock(); 14583c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek return B->empty() ? NULL : B->back(); 146bd129696c554fbbcd9405104641e292f0fb4678dTed Kremenek } 147bd129696c554fbbcd9405104641e292f0fb4678dTed Kremenek 14883c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek Stmt* getTerminator() const { 14983c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek return getBlock()->getTerminator(); 150bd129696c554fbbcd9405104641e292f0fb4678dTed Kremenek } 15183c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek 15283c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek static bool classof(const ProgramPoint* Location) { 15383c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek return Location->getKind() == BlockExitKind; 154bd129696c554fbbcd9405104641e292f0fb4678dTed Kremenek } 155bd129696c554fbbcd9405104641e292f0fb4678dTed Kremenek}; 156eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenek 15783c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek 15883c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenekclass PostStmt : public ProgramPoint { 1591b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenekprotected: 160f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek PostStmt(const Stmt* S, Kind k) : ProgramPoint(S, k) {} 161f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek PostStmt(const Stmt* S, const void* data) : ProgramPoint(S, data, true) {} 162f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek 163eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenekpublic: 16483c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek PostStmt(const Stmt* S) : ProgramPoint(S, PostStmtKind) {} 1651b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenek 166f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek Stmt* getStmt() const { return (Stmt*) getData1(); } 16783c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek 16883c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek static bool classof(const ProgramPoint* Location) { 1691b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenek unsigned k = Location->getKind(); 170f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek return k >= MinPostStmtKind && k <= MaxPostStmtKind; 1711b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenek } 1721b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenek}; 1738c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek 1748c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenekclass PostLocationChecksSucceed : public PostStmt { 1758c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenekpublic: 1768c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek PostLocationChecksSucceed(const Stmt* S) 1778c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek : PostStmt(S, PostLocationChecksSucceedKind) {} 1788c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek 1798c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek static bool classof(const ProgramPoint* Location) { 1808c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek return Location->getKind() == PostLocationChecksSucceedKind; 1818c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek } 1828c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek}; 1838c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek 184f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenekclass PostStmtCustom : public PostStmt { 185f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek PostStmtCustom(const Stmt* S, const void* Data) 186f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek : PostStmt(S, Data) { 187f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek assert(getKind() == PostStmtCustomKind); 188f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek } 189f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek 190f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek void* getCustomData() const { return getData2(); } 191f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek 192f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek static bool classof(const ProgramPoint* Location) { 193f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek return Location->getKind() == PostStmtCustomKind; 194f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek } 195f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek}; 196f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek 1978c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenekclass PostOutOfBoundsCheckFailed : public PostStmt { 1988c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenekpublic: 1998c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek PostOutOfBoundsCheckFailed(const Stmt* S) 2008c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek : PostStmt(S, PostOutOfBoundsCheckFailedKind) {} 2018c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek 2028c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek static bool classof(const ProgramPoint* Location) { 2038c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek return Location->getKind() == PostOutOfBoundsCheckFailedKind; 2048c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek } 2058c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek}; 2068c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek 2078c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenekclass PostUndefLocationCheckFailed : public PostStmt { 2088c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenekpublic: 2098c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek PostUndefLocationCheckFailed(const Stmt* S) 2108c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek : PostStmt(S, PostUndefLocationCheckFailedKind) {} 2118c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek 2128c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek static bool classof(const ProgramPoint* Location) { 2138c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek return Location->getKind() == PostUndefLocationCheckFailedKind; 2148c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek } 2158c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek}; 2168c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek 2178c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenekclass PostNullCheckFailed : public PostStmt { 2188c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenekpublic: 2198c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek PostNullCheckFailed(const Stmt* S) 2208c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek : PostStmt(S, PostNullCheckFailedKind) {} 2218c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek 2228c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek static bool classof(const ProgramPoint* Location) { 2238c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek return Location->getKind() == PostNullCheckFailedKind; 2248c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek } 2258c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek}; 2261b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenek 2271b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenekclass PostLoad : public PostStmt { 2281b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenekpublic: 2291b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenek PostLoad(const Stmt* S) : PostStmt(S, PostLoadKind) {} 2301b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenek 2311b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenek static bool classof(const ProgramPoint* Location) { 2321b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenek return Location->getKind() == PostLoadKind; 233bd129696c554fbbcd9405104641e292f0fb4678dTed Kremenek } 234eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenek}; 235b6d2360787e5a0bb5d26f3bc7a83059a8b050dc4Ted Kremenek 23682bae3f6bf7bc4733d9c87659b266e23ad55f420Ted Kremenekclass PostStore : public PostStmt { 23782bae3f6bf7bc4733d9c87659b266e23ad55f420Ted Kremenekpublic: 2388c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek PostStore(const Stmt* S) : PostStmt(S, PostStoreKind) {} 23982bae3f6bf7bc4733d9c87659b266e23ad55f420Ted Kremenek 24082bae3f6bf7bc4733d9c87659b266e23ad55f420Ted Kremenek static bool classof(const ProgramPoint* Location) { 24182bae3f6bf7bc4733d9c87659b266e23ad55f420Ted Kremenek return Location->getKind() == PostStoreKind; 24282bae3f6bf7bc4733d9c87659b266e23ad55f420Ted Kremenek } 24382bae3f6bf7bc4733d9c87659b266e23ad55f420Ted Kremenek}; 24482bae3f6bf7bc4733d9c87659b266e23ad55f420Ted Kremenek 245331b0ac44b9eb0ffcba66b4f3f3f9adb27c2434fTed Kremenekclass PostPurgeDeadSymbols : public PostStmt { 246331b0ac44b9eb0ffcba66b4f3f3f9adb27c2434fTed Kremenekpublic: 247331b0ac44b9eb0ffcba66b4f3f3f9adb27c2434fTed Kremenek PostPurgeDeadSymbols(const Stmt* S) : PostStmt(S, PostPurgeDeadSymbolsKind) {} 248331b0ac44b9eb0ffcba66b4f3f3f9adb27c2434fTed Kremenek 249331b0ac44b9eb0ffcba66b4f3f3f9adb27c2434fTed Kremenek static bool classof(const ProgramPoint* Location) { 250331b0ac44b9eb0ffcba66b4f3f3f9adb27c2434fTed Kremenek return Location->getKind() == PostPurgeDeadSymbolsKind; 251331b0ac44b9eb0ffcba66b4f3f3f9adb27c2434fTed Kremenek } 252331b0ac44b9eb0ffcba66b4f3f3f9adb27c2434fTed Kremenek}; 253331b0ac44b9eb0ffcba66b4f3f3f9adb27c2434fTed Kremenek 25483c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenekclass BlockEdge : public ProgramPoint { 255b6d2360787e5a0bb5d26f3bc7a83059a8b050dc4Ted Kremenekpublic: 256d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek BlockEdge(const CFGBlock* B1, const CFGBlock* B2) 257d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek : ProgramPoint(B1, B2) {} 258d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek 259d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek CFGBlock* getSrc() const { 260d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek return static_cast<CFGBlock*>(getData1()); 261d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek } 262d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek 263d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek CFGBlock* getDst() const { 264d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek return static_cast<CFGBlock*>(getData2()); 265d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek } 266b6d2360787e5a0bb5d26f3bc7a83059a8b050dc4Ted Kremenek 26783c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek static bool classof(const ProgramPoint* Location) { 268d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek return Location->getKind() == BlockEdgeKind; 269b6d2360787e5a0bb5d26f3bc7a83059a8b050dc4Ted Kremenek } 270b6d2360787e5a0bb5d26f3bc7a83059a8b050dc4Ted Kremenek}; 27183c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek 27283c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek 273eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenek} // end namespace clang 2744c3fbe33194cd9b1bfff773647ed785b403e1ba5Ted Kremenek 2754c3fbe33194cd9b1bfff773647ed785b403e1ba5Ted Kremenek 2764c3fbe33194cd9b1bfff773647ed785b403e1ba5Ted Kremeneknamespace llvm { // Traits specialization for DenseMap 2774c3fbe33194cd9b1bfff773647ed785b403e1ba5Ted Kremenek 27883c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenektemplate <> struct DenseMapInfo<clang::ProgramPoint> { 2794c3fbe33194cd9b1bfff773647ed785b403e1ba5Ted Kremenek 280d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenekstatic inline clang::ProgramPoint getEmptyKey() { 281d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek uintptr_t x = 282d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek reinterpret_cast<uintptr_t>(DenseMapInfo<void*>::getEmptyKey()) & ~0x7; 283d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek return clang::BlockEntrance(reinterpret_cast<clang::CFGBlock*>(x)); 284d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek} 285d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek 286d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenekstatic inline clang::ProgramPoint getTombstoneKey() { 287d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek uintptr_t x = 288d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek reinterpret_cast<uintptr_t>(DenseMapInfo<void*>::getTombstoneKey()) & ~0x7; 289d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek return clang::BlockEntrance(reinterpret_cast<clang::CFGBlock*>(x)); 290d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek} 291d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek 292d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenekstatic unsigned getHashValue(const clang::ProgramPoint& Loc) { 293d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek return Loc.getHashValue(); 294d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek} 295d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek 296d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenekstatic bool isEqual(const clang::ProgramPoint& L, 297d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek const clang::ProgramPoint& R) { 298d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek return L == R; 299d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek} 300d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek 301d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenekstatic bool isPod() { 302d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek return true; 303d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek} 3044c3fbe33194cd9b1bfff773647ed785b403e1ba5Ted Kremenek}; 3054c3fbe33194cd9b1bfff773647ed785b403e1ba5Ted Kremenek} // end namespace llvm 3064c3fbe33194cd9b1bfff773647ed785b403e1ba5Ted Kremenek 307eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenek#endif 308