ProgramPoint.h revision 7090d5465de7ca620da16211cf886edf1edc1f1f
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, 427090d5465de7ca620da16211cf886edf1edc1f1fTed Kremenek PostLValueKind = 0x12, 43f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek MinPostStmtKind = PostStmtKind, 447090d5465de7ca620da16211cf886edf1edc1f1fTed Kremenek MaxPostStmtKind = PostLValueKind }; 454c3fbe33194cd9b1bfff773647ed785b403e1ba5Ted Kremenek 46d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenekprivate: 47f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek enum { TwoPointers = 0x1, Custom = 0x2, Mask = 0x3 }; 48f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek 49d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek std::pair<uintptr_t,uintptr_t> Data; 50e8063ae53bd241de10ba1053054d06867a5c56abTed Kremenek const void *Tag; 51d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek 52d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenekprotected: 53e8063ae53bd241de10ba1053054d06867a5c56abTed Kremenek ProgramPoint(const void* P, Kind k, const void *tag = 0) 54f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek : Data(reinterpret_cast<uintptr_t>(P), 55e8063ae53bd241de10ba1053054d06867a5c56abTed Kremenek (uintptr_t) k), Tag(tag) {} 56d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek 57e8063ae53bd241de10ba1053054d06867a5c56abTed Kremenek ProgramPoint(const void* P1, const void* P2, const void *tag = 0) 58f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek : Data(reinterpret_cast<uintptr_t>(P1) | TwoPointers, 59e8063ae53bd241de10ba1053054d06867a5c56abTed Kremenek reinterpret_cast<uintptr_t>(P2)), Tag(tag) {} 60f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek 611670e403c48f3af4fceff3f6773a0e1cfc6c4eb3Ted Kremenek ProgramPoint(const void* P1, const void* P2, bool, const void *tag = 0) 62f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek : Data(reinterpret_cast<uintptr_t>(P1) | Custom, 631670e403c48f3af4fceff3f6773a0e1cfc6c4eb3Ted Kremenek reinterpret_cast<uintptr_t>(P2)), Tag(tag) {} 64f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek 65d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenekprotected: 66d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek void* getData1NoMask() const { 67f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek Kind k = getKind(); k = k; 68f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek assert(k == BlockEntranceKind || k == BlockExitKind); 69d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek return reinterpret_cast<void*>(Data.first); 706e5977f0a8a680191fb4b4d8f32bc2c629faf0c2Argyrios Kyrtzidis } 716e5977f0a8a680191fb4b4d8f32bc2c629faf0c2Argyrios Kyrtzidis 72d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek void* getData1() const { 73f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek Kind k = getKind(); k = k; 742680b5f926fad29c1a2b2723a70d189f4b637979Ted Kremenek assert(k == BlockEdgeKind ||(k >= MinPostStmtKind && k <= MaxPostStmtKind)); 75f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek return reinterpret_cast<void*>(Data.first & ~Mask); 76d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek } 776e5977f0a8a680191fb4b4d8f32bc2c629faf0c2Argyrios Kyrtzidis 78d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek void* getData2() const { 79f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek Kind k = getKind(); k = k; 80f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek assert(k == BlockEdgeKind || k == PostStmtCustomKind); 81d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek return reinterpret_cast<void*>(Data.second); 824c3fbe33194cd9b1bfff773647ed785b403e1ba5Ted Kremenek } 83e8063ae53bd241de10ba1053054d06867a5c56abTed Kremenek 84e8063ae53bd241de10ba1053054d06867a5c56abTed Kremenek const void *getTag() const { return Tag; } 85f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek 8683c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenekpublic: 87f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek Kind getKind() const { 88f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek switch (Data.first & Mask) { 89f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek case TwoPointers: return BlockEdgeKind; 90f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek case Custom: return PostStmtCustomKind; 91f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek default: return (Kind) Data.second; 92f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek } 93d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek } 94d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek 95e8063ae53bd241de10ba1053054d06867a5c56abTed Kremenek // For use with DenseMap. This hash is probably slow. 96d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek unsigned getHashValue() const { 97e8063ae53bd241de10ba1053054d06867a5c56abTed Kremenek llvm::FoldingSetNodeID ID; 98e8063ae53bd241de10ba1053054d06867a5c56abTed Kremenek ID.AddPointer(reinterpret_cast<void*>(Data.first)); 99e8063ae53bd241de10ba1053054d06867a5c56abTed Kremenek ID.AddPointer(reinterpret_cast<void*>(Data.second)); 100e8063ae53bd241de10ba1053054d06867a5c56abTed Kremenek ID.AddPointer(Tag); 101e8063ae53bd241de10ba1053054d06867a5c56abTed Kremenek return ID.ComputeHash(); 102d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek } 103eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenek 10483c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek static bool classof(const ProgramPoint*) { return true; } 105d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek 106d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek bool operator==(const ProgramPoint & RHS) const { 107e8063ae53bd241de10ba1053054d06867a5c56abTed Kremenek return Data == RHS.Data && Tag == RHS.Tag; 108d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek } 109d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek 110d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek bool operator!=(const ProgramPoint& RHS) const { 111e8063ae53bd241de10ba1053054d06867a5c56abTed Kremenek return Data != RHS.Data || Tag != RHS.Tag; 112d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek } 113d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek 114d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek bool operator<(const ProgramPoint& RHS) const { 115e8063ae53bd241de10ba1053054d06867a5c56abTed Kremenek return Data < RHS.Data && Tag < RHS.Tag; 116d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek } 1175226755ab5ce6346f98b5f41cdcffbe84c5bb484Ted Kremenek 1185226755ab5ce6346f98b5f41cdcffbe84c5bb484Ted Kremenek void Profile(llvm::FoldingSetNodeID& ID) const { 119d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek ID.AddPointer(reinterpret_cast<void*>(Data.first)); 1202680b5f926fad29c1a2b2723a70d189f4b637979Ted Kremenek if (getKind() != PostStmtCustomKind) 1212680b5f926fad29c1a2b2723a70d189f4b637979Ted Kremenek ID.AddPointer(reinterpret_cast<void*>(Data.second)); 1222680b5f926fad29c1a2b2723a70d189f4b637979Ted Kremenek else { 1232680b5f926fad29c1a2b2723a70d189f4b637979Ted Kremenek const std::pair<const void*, const void*> *P = 1242680b5f926fad29c1a2b2723a70d189f4b637979Ted Kremenek reinterpret_cast<std::pair<const void*, const void*>*>(Data.second); 1252680b5f926fad29c1a2b2723a70d189f4b637979Ted Kremenek ID.AddPointer(P->first); 1262680b5f926fad29c1a2b2723a70d189f4b637979Ted Kremenek ID.AddPointer(P->second); 1272680b5f926fad29c1a2b2723a70d189f4b637979Ted Kremenek } 128e8063ae53bd241de10ba1053054d06867a5c56abTed Kremenek ID.AddPointer(Tag); 1292680b5f926fad29c1a2b2723a70d189f4b637979Ted Kremenek } 130eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenek}; 13183c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek 13283c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenekclass BlockEntrance : public ProgramPoint { 133eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenekpublic: 13483c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek BlockEntrance(const CFGBlock* B) : ProgramPoint(B, BlockEntranceKind) {} 13583c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek 13683c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek CFGBlock* getBlock() const { 137d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek return reinterpret_cast<CFGBlock*>(getData1NoMask()); 138bd129696c554fbbcd9405104641e292f0fb4678dTed Kremenek } 139eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenek 14083c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek Stmt* getFirstStmt() const { 14183c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek CFGBlock* B = getBlock(); 14283c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek return B->empty() ? NULL : B->front(); 14383c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek } 144eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenek 14583c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek static bool classof(const ProgramPoint* Location) { 14683c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek return Location->getKind() == BlockEntranceKind; 147bd129696c554fbbcd9405104641e292f0fb4678dTed Kremenek } 148eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenek}; 14983c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek 15083c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenekclass BlockExit : public ProgramPoint { 151eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenekpublic: 15283c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek BlockExit(const CFGBlock* B) : ProgramPoint(B, BlockExitKind) {} 153bd129696c554fbbcd9405104641e292f0fb4678dTed Kremenek 15483c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek CFGBlock* getBlock() const { 155d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek return reinterpret_cast<CFGBlock*>(getData1NoMask()); 156bd129696c554fbbcd9405104641e292f0fb4678dTed Kremenek } 15783c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek 15883c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek Stmt* getLastStmt() const { 15983c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek CFGBlock* B = getBlock(); 16083c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek return B->empty() ? NULL : B->back(); 161bd129696c554fbbcd9405104641e292f0fb4678dTed Kremenek } 162bd129696c554fbbcd9405104641e292f0fb4678dTed Kremenek 16383c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek Stmt* getTerminator() const { 16483c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek return getBlock()->getTerminator(); 165bd129696c554fbbcd9405104641e292f0fb4678dTed Kremenek } 16683c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek 16783c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek static bool classof(const ProgramPoint* Location) { 16883c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek return Location->getKind() == BlockExitKind; 169bd129696c554fbbcd9405104641e292f0fb4678dTed Kremenek } 170bd129696c554fbbcd9405104641e292f0fb4678dTed Kremenek}; 171eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenek 17283c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenekclass PostStmt : public ProgramPoint { 1731b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenekprotected: 174e8063ae53bd241de10ba1053054d06867a5c56abTed Kremenek PostStmt(const Stmt* S, Kind k,const void *tag = 0) 175e8063ae53bd241de10ba1053054d06867a5c56abTed Kremenek : ProgramPoint(S, k, tag) {} 176e8063ae53bd241de10ba1053054d06867a5c56abTed Kremenek 1771670e403c48f3af4fceff3f6773a0e1cfc6c4eb3Ted Kremenek PostStmt(const Stmt* S, const void* data, bool, const void *tag =0) 1781670e403c48f3af4fceff3f6773a0e1cfc6c4eb3Ted Kremenek : ProgramPoint(S, data, true, tag) {} 179f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek 180eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenekpublic: 1811670e403c48f3af4fceff3f6773a0e1cfc6c4eb3Ted Kremenek PostStmt(const Stmt* S, const void *tag = 0) 1821670e403c48f3af4fceff3f6773a0e1cfc6c4eb3Ted Kremenek : ProgramPoint(S, PostStmtKind, tag) {} 1831670e403c48f3af4fceff3f6773a0e1cfc6c4eb3Ted Kremenek 1841b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenek 185f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek Stmt* getStmt() const { return (Stmt*) getData1(); } 18683c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek 18783c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek static bool classof(const ProgramPoint* Location) { 1881b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenek unsigned k = Location->getKind(); 189f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek return k >= MinPostStmtKind && k <= MaxPostStmtKind; 1901b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenek } 1911b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenek}; 1928c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek 1938c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenekclass PostLocationChecksSucceed : public PostStmt { 1948c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenekpublic: 195e8063ae53bd241de10ba1053054d06867a5c56abTed Kremenek PostLocationChecksSucceed(const Stmt* S, const void *tag = 0) 196e8063ae53bd241de10ba1053054d06867a5c56abTed Kremenek : PostStmt(S, PostLocationChecksSucceedKind, tag) {} 1978c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek 1988c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek static bool classof(const ProgramPoint* Location) { 1998c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek return Location->getKind() == PostLocationChecksSucceedKind; 2008c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek } 2018c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek}; 2028c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek 203f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenekclass PostStmtCustom : public PostStmt { 2042680b5f926fad29c1a2b2723a70d189f4b637979Ted Kremenekpublic: 20559753441b6391a9843eff287f0adb2614153b7c8Ted Kremenek PostStmtCustom(const Stmt* S, 20659753441b6391a9843eff287f0adb2614153b7c8Ted Kremenek const std::pair<const void*, const void*>* TaggedData) 2071670e403c48f3af4fceff3f6773a0e1cfc6c4eb3Ted Kremenek : PostStmt(S, TaggedData, true) { 208f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek assert(getKind() == PostStmtCustomKind); 209f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek } 21059753441b6391a9843eff287f0adb2614153b7c8Ted Kremenek 21159753441b6391a9843eff287f0adb2614153b7c8Ted Kremenek const std::pair<const void*, const void*>& getTaggedPair() const { 21259753441b6391a9843eff287f0adb2614153b7c8Ted Kremenek return *reinterpret_cast<std::pair<const void*, const void*>*>(getData2()); 21359753441b6391a9843eff287f0adb2614153b7c8Ted Kremenek } 21459753441b6391a9843eff287f0adb2614153b7c8Ted Kremenek 21559753441b6391a9843eff287f0adb2614153b7c8Ted Kremenek const void* getTag() const { return getTaggedPair().first; } 216f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek 21759753441b6391a9843eff287f0adb2614153b7c8Ted Kremenek const void* getTaggedData() const { return getTaggedPair().second; } 218f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek 219f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek static bool classof(const ProgramPoint* Location) { 220f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek return Location->getKind() == PostStmtCustomKind; 221f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek } 222f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek}; 223f4be8ee748831bc23e35b542e6c1bb6d1eb49baaTed Kremenek 2248c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenekclass PostOutOfBoundsCheckFailed : public PostStmt { 2258c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenekpublic: 2261670e403c48f3af4fceff3f6773a0e1cfc6c4eb3Ted Kremenek PostOutOfBoundsCheckFailed(const Stmt* S, const void *tag = 0) 2271670e403c48f3af4fceff3f6773a0e1cfc6c4eb3Ted Kremenek : PostStmt(S, PostOutOfBoundsCheckFailedKind, tag) {} 2288c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek 2298c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek static bool classof(const ProgramPoint* Location) { 2308c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek return Location->getKind() == PostOutOfBoundsCheckFailedKind; 2318c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek } 2328c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek}; 2338c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek 2348c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenekclass PostUndefLocationCheckFailed : public PostStmt { 2358c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenekpublic: 2361670e403c48f3af4fceff3f6773a0e1cfc6c4eb3Ted Kremenek PostUndefLocationCheckFailed(const Stmt* S, const void *tag = 0) 2371670e403c48f3af4fceff3f6773a0e1cfc6c4eb3Ted Kremenek : PostStmt(S, PostUndefLocationCheckFailedKind, tag) {} 2388c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek 2398c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek static bool classof(const ProgramPoint* Location) { 2408c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek return Location->getKind() == PostUndefLocationCheckFailedKind; 2418c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek } 2428c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek}; 2438c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek 2448c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenekclass PostNullCheckFailed : public PostStmt { 2458c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenekpublic: 2461670e403c48f3af4fceff3f6773a0e1cfc6c4eb3Ted Kremenek PostNullCheckFailed(const Stmt* S, const void *tag = 0) 2471670e403c48f3af4fceff3f6773a0e1cfc6c4eb3Ted Kremenek : PostStmt(S, PostNullCheckFailedKind, tag) {} 2488c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek 2498c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek static bool classof(const ProgramPoint* Location) { 2508c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek return Location->getKind() == PostNullCheckFailedKind; 2518c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek } 2528c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek}; 2531b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenek 2541b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenekclass PostLoad : public PostStmt { 2551b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenekpublic: 256e8063ae53bd241de10ba1053054d06867a5c56abTed Kremenek PostLoad(const Stmt* S, const void *tag = 0) 257e8063ae53bd241de10ba1053054d06867a5c56abTed Kremenek : PostStmt(S, PostLoadKind, tag) {} 2581b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenek 2591b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenek static bool classof(const ProgramPoint* Location) { 2601b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenek return Location->getKind() == PostLoadKind; 261bd129696c554fbbcd9405104641e292f0fb4678dTed Kremenek } 262eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenek}; 263b6d2360787e5a0bb5d26f3bc7a83059a8b050dc4Ted Kremenek 26482bae3f6bf7bc4733d9c87659b266e23ad55f420Ted Kremenekclass PostStore : public PostStmt { 26582bae3f6bf7bc4733d9c87659b266e23ad55f420Ted Kremenekpublic: 266e8063ae53bd241de10ba1053054d06867a5c56abTed Kremenek PostStore(const Stmt* S, const void *tag = 0) 267e8063ae53bd241de10ba1053054d06867a5c56abTed Kremenek : PostStmt(S, PostStoreKind, tag) {} 26882bae3f6bf7bc4733d9c87659b266e23ad55f420Ted Kremenek 26982bae3f6bf7bc4733d9c87659b266e23ad55f420Ted Kremenek static bool classof(const ProgramPoint* Location) { 27082bae3f6bf7bc4733d9c87659b266e23ad55f420Ted Kremenek return Location->getKind() == PostStoreKind; 27182bae3f6bf7bc4733d9c87659b266e23ad55f420Ted Kremenek } 27282bae3f6bf7bc4733d9c87659b266e23ad55f420Ted Kremenek}; 2737090d5465de7ca620da16211cf886edf1edc1f1fTed Kremenek 2747090d5465de7ca620da16211cf886edf1edc1f1fTed Kremenekclass PostLValue : public PostStmt { 2757090d5465de7ca620da16211cf886edf1edc1f1fTed Kremenekpublic: 2767090d5465de7ca620da16211cf886edf1edc1f1fTed Kremenek PostLValue(const Stmt* S, const void *tag = 0) 2777090d5465de7ca620da16211cf886edf1edc1f1fTed Kremenek : PostStmt(S, PostLValueKind, tag) {} 2787090d5465de7ca620da16211cf886edf1edc1f1fTed Kremenek 2797090d5465de7ca620da16211cf886edf1edc1f1fTed Kremenek static bool classof(const ProgramPoint* Location) { 2807090d5465de7ca620da16211cf886edf1edc1f1fTed Kremenek return Location->getKind() == PostLValueKind; 2817090d5465de7ca620da16211cf886edf1edc1f1fTed Kremenek } 2827090d5465de7ca620da16211cf886edf1edc1f1fTed Kremenek}; 28382bae3f6bf7bc4733d9c87659b266e23ad55f420Ted Kremenek 284331b0ac44b9eb0ffcba66b4f3f3f9adb27c2434fTed Kremenekclass PostPurgeDeadSymbols : public PostStmt { 285331b0ac44b9eb0ffcba66b4f3f3f9adb27c2434fTed Kremenekpublic: 2861670e403c48f3af4fceff3f6773a0e1cfc6c4eb3Ted Kremenek PostPurgeDeadSymbols(const Stmt* S, const void *tag = 0) 2871670e403c48f3af4fceff3f6773a0e1cfc6c4eb3Ted Kremenek : PostStmt(S, PostPurgeDeadSymbolsKind, tag) {} 288331b0ac44b9eb0ffcba66b4f3f3f9adb27c2434fTed Kremenek 289331b0ac44b9eb0ffcba66b4f3f3f9adb27c2434fTed Kremenek static bool classof(const ProgramPoint* Location) { 290331b0ac44b9eb0ffcba66b4f3f3f9adb27c2434fTed Kremenek return Location->getKind() == PostPurgeDeadSymbolsKind; 291331b0ac44b9eb0ffcba66b4f3f3f9adb27c2434fTed Kremenek } 292331b0ac44b9eb0ffcba66b4f3f3f9adb27c2434fTed Kremenek}; 293331b0ac44b9eb0ffcba66b4f3f3f9adb27c2434fTed Kremenek 29483c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenekclass BlockEdge : public ProgramPoint { 295b6d2360787e5a0bb5d26f3bc7a83059a8b050dc4Ted Kremenekpublic: 296d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek BlockEdge(const CFGBlock* B1, const CFGBlock* B2) 297d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek : ProgramPoint(B1, B2) {} 298d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek 299d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek CFGBlock* getSrc() const { 300d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek return static_cast<CFGBlock*>(getData1()); 301d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek } 302d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek 303d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek CFGBlock* getDst() const { 304d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek return static_cast<CFGBlock*>(getData2()); 305d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek } 306b6d2360787e5a0bb5d26f3bc7a83059a8b050dc4Ted Kremenek 30783c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek static bool classof(const ProgramPoint* Location) { 308d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek return Location->getKind() == BlockEdgeKind; 309b6d2360787e5a0bb5d26f3bc7a83059a8b050dc4Ted Kremenek } 310b6d2360787e5a0bb5d26f3bc7a83059a8b050dc4Ted Kremenek}; 31183c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek 31283c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek 313eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenek} // end namespace clang 3144c3fbe33194cd9b1bfff773647ed785b403e1ba5Ted Kremenek 3154c3fbe33194cd9b1bfff773647ed785b403e1ba5Ted Kremenek 3164c3fbe33194cd9b1bfff773647ed785b403e1ba5Ted Kremeneknamespace llvm { // Traits specialization for DenseMap 3174c3fbe33194cd9b1bfff773647ed785b403e1ba5Ted Kremenek 31883c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenektemplate <> struct DenseMapInfo<clang::ProgramPoint> { 3194c3fbe33194cd9b1bfff773647ed785b403e1ba5Ted Kremenek 320d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenekstatic inline clang::ProgramPoint getEmptyKey() { 321d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek uintptr_t x = 322d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek reinterpret_cast<uintptr_t>(DenseMapInfo<void*>::getEmptyKey()) & ~0x7; 323d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek return clang::BlockEntrance(reinterpret_cast<clang::CFGBlock*>(x)); 324d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek} 325d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek 326d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenekstatic inline clang::ProgramPoint getTombstoneKey() { 327d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek uintptr_t x = 328d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek reinterpret_cast<uintptr_t>(DenseMapInfo<void*>::getTombstoneKey()) & ~0x7; 329d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek return clang::BlockEntrance(reinterpret_cast<clang::CFGBlock*>(x)); 330d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek} 331d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek 332d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenekstatic unsigned getHashValue(const clang::ProgramPoint& Loc) { 333d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek return Loc.getHashValue(); 334d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek} 335d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek 336d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenekstatic bool isEqual(const clang::ProgramPoint& L, 337d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek const clang::ProgramPoint& R) { 338d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek return L == R; 339d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek} 340d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek 341d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenekstatic bool isPod() { 342d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek return true; 343d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek} 3444c3fbe33194cd9b1bfff773647ed785b403e1ba5Ted Kremenek}; 3454c3fbe33194cd9b1bfff773647ed785b403e1ba5Ted Kremenek} // end namespace llvm 3464c3fbe33194cd9b1bfff773647ed785b403e1ba5Ted Kremenek 347eb19188e668d0ad2c968fc0286a6922f9194deb4Ted Kremenek#endif 348