MemRegion.h revision d17da2b99f323fa91b01e1dd119cc32e0ee8197d
19e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenek//== MemRegion.h - Abstract memory regions for static analysis --*- C++ -*--==// 29e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenek// 39e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenek// The LLVM Compiler Infrastructure 49e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenek// 59e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenek// This file is distributed under the University of Illinois Open Source 69e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenek// License. See LICENSE.TXT for details. 79e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenek// 89e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenek//===----------------------------------------------------------------------===// 99e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenek// 109e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenek// This file defines MemRegion and its subclasses. MemRegion defines a 119e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenek// partially-typed abstraction of memory useful for path-sensitive dataflow 129e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenek// analyses. 139e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenek// 149e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenek//===----------------------------------------------------------------------===// 159e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenek 169e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenek#ifndef LLVM_CLANG_ANALYSIS_MEMREGION_H 179e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenek#define LLVM_CLANG_ANALYSIS_MEMREGION_H 189e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenek 19993f1c72913417be7c534ec7a634363cdfc84fa5Ted Kremenek#include "clang/AST/Decl.h" 20993f1c72913417be7c534ec7a634363cdfc84fa5Ted Kremenek#include "clang/AST/DeclObjC.h" 21993f1c72913417be7c534ec7a634363cdfc84fa5Ted Kremenek#include "clang/Analysis/PathSensitive/SymbolManager.h" 2222ab7a4d900ed53285fd0b6720e7b43af84724d8Zhongxing Xu#include "clang/Analysis/PathSensitive/SVals.h" 23a693d4fa7a6dc31b23837cf38cba7aa2af8f00f3Ted Kremenek#include "clang/AST/ASTContext.h" 249e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenek#include "llvm/Support/Casting.h" 259e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenek#include "llvm/ADT/FoldingSet.h" 26dc0a25d9bff956cdbe54ea0bfc8fbbe3ceb4eb92Zhongxing Xu#include "llvm/ADT/ImmutableList.h" 27dc0a25d9bff956cdbe54ea0bfc8fbbe3ceb4eb92Zhongxing Xu#include "llvm/ADT/ImmutableMap.h" 289e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenek#include "llvm/Support/Allocator.h" 299e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenek#include <string> 309e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenek 319e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremeneknamespace llvm { class raw_ostream; } 329e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenek 339e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremeneknamespace clang { 349e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenek 359e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenekclass MemRegionManager; 36d17da2b99f323fa91b01e1dd119cc32e0ee8197dTed Kremenekclass MemSpaceRegion; 37d17da2b99f323fa91b01e1dd119cc32e0ee8197dTed Kremenekclass LocationContext; 389e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenek 3919e1f0ba5cec738ce6cebe3fe0e1edc782206494Ted Kremenek//===----------------------------------------------------------------------===// 4019e1f0ba5cec738ce6cebe3fe0e1edc782206494Ted Kremenek// Base region classes. 4119e1f0ba5cec738ce6cebe3fe0e1edc782206494Ted Kremenek//===----------------------------------------------------------------------===// 4219e1f0ba5cec738ce6cebe3fe0e1edc782206494Ted Kremenek 439e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenek/// MemRegion - The root abstract class for all memory regions. 449e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenekclass MemRegion : public llvm::FoldingSetNode { 459e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenekpublic: 46026c66395b88a09437319139a43b090093f7e1ddZhongxing Xu enum Kind { MemSpaceRegionKind, 47e8e86482da4c1872673bbb9c237649229d19793bTed Kremenek SymbolicRegionKind, 4882bd99f4db2454cc6e1b7bfaac6db25cb3444ddcTed Kremenek AllocaRegionKind, 499e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenek // Typed regions. 509e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenek BEG_TYPED_REGIONS, 51369f447eded97e6048ced02c0c2be3842f61fc1cZhongxing Xu CodeTextRegionKind, 5277cfac623178d0c16e16e2f171d20b0fea8fde30Zhongxing Xu CompoundLiteralRegionKind, 53329d6fde79254503b14724e1231a9d70fa6b387fTed Kremenek StringRegionKind, ElementRegionKind, 54329d6fde79254503b14724e1231a9d70fa6b387fTed Kremenek // Decl Regions. 55329d6fde79254503b14724e1231a9d70fa6b387fTed Kremenek BEG_DECL_REGIONS, 56329d6fde79254503b14724e1231a9d70fa6b387fTed Kremenek VarRegionKind, FieldRegionKind, 57329d6fde79254503b14724e1231a9d70fa6b387fTed Kremenek ObjCIvarRegionKind, ObjCObjectRegionKind, 58329d6fde79254503b14724e1231a9d70fa6b387fTed Kremenek END_DECL_REGIONS, 599e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenek END_TYPED_REGIONS }; 609e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenekprivate: 619e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenek const Kind kind; 629e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenek 639e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenekprotected: 649e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenek MemRegion(Kind k) : kind(k) {} 659e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenek virtual ~MemRegion(); 669e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenek 679e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenekpublic: 68a6275a534da701f37d19a068e6361e5f10f983a1Ted Kremenek ASTContext &getContext() const; 69a6275a534da701f37d19a068e6361e5f10f983a1Ted Kremenek 709e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenek virtual void Profile(llvm::FoldingSetNodeID& ID) const = 0; 71a43484afda4c4fb4b23a53a2dc91d985d39dc2c4Ted Kremenek 72a43484afda4c4fb4b23a53a2dc91d985d39dc2c4Ted Kremenek virtual MemRegionManager* getMemRegionManager() const = 0; 73a43484afda4c4fb4b23a53a2dc91d985d39dc2c4Ted Kremenek 749e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenek std::string getString() const; 75bb7c96f290453104ec35ca17111a5165f68a4697Ted Kremenek 76bb7c96f290453104ec35ca17111a5165f68a4697Ted Kremenek const MemSpaceRegion *getMemorySpace() const; 770e3ec3ff2477e60f0ceda922cc2e3a25a59d81f2Ted Kremenek 780e3ec3ff2477e60f0ceda922cc2e3a25a59d81f2Ted Kremenek const MemRegion *getBaseRegion() const; 79ea20cd74793d257679267032419a9ff7fc89dc05Ted Kremenek 80ea20cd74793d257679267032419a9ff7fc89dc05Ted Kremenek bool hasStackStorage() const; 81ea20cd74793d257679267032419a9ff7fc89dc05Ted Kremenek 821508636e99faddf569a57fce82c0fb3aa2124396Ted Kremenek bool hasParametersStorage() const; 831508636e99faddf569a57fce82c0fb3aa2124396Ted Kremenek 841508636e99faddf569a57fce82c0fb3aa2124396Ted Kremenek bool hasGlobalsStorage() const; 851508636e99faddf569a57fce82c0fb3aa2124396Ted Kremenek 861508636e99faddf569a57fce82c0fb3aa2124396Ted Kremenek bool hasGlobalsOrParametersStorage() const; 871508636e99faddf569a57fce82c0fb3aa2124396Ted Kremenek 88ea20cd74793d257679267032419a9ff7fc89dc05Ted Kremenek bool hasHeapStorage() const; 89bb7c96f290453104ec35ca17111a5165f68a4697Ted Kremenek 90bb7c96f290453104ec35ca17111a5165f68a4697Ted Kremenek bool hasHeapOrStackStorage() const; 91b21ff77c8126ea628b66d2ffb931fdaa7884f5d2Zhongxing Xu 928800ad4eaa1621f6d23c8264971063b9f8da6a2eTed Kremenek virtual void dumpToStream(llvm::raw_ostream& os) const; 937f39d29cb69e7488f994870800d548008e50e1cbTed Kremenek 948800ad4eaa1621f6d23c8264971063b9f8da6a2eTed Kremenek void dump() const; 959e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenek 969e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenek Kind getKind() const { return kind; } 9741168eac256fed59ec5406a75fce91c59cd5dd91Ted Kremenek 98ed65d3d97132fbcdd124aef4d2478e348dfbd36bTed Kremenek template<typename RegionTy> const RegionTy* getAs() const; 99ed65d3d97132fbcdd124aef4d2478e348dfbd36bTed Kremenek 100f0f0605c87739c906861f73d4287798a4969b1e0Zhongxing Xu virtual bool isBoundable() const { return false; } 101b21ff77c8126ea628b66d2ffb931fdaa7884f5d2Zhongxing Xu 1029e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenek static bool classof(const MemRegion*) { return true; } 1039e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenek}; 1049e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenek 1059e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenek/// MemSpaceRegion - A memory region that represents and "memory space"; 1069e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenek/// for example, the set of global variables, the stack frame, etc. 1079e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenekclass MemSpaceRegion : public MemRegion { 1089e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenek friend class MemRegionManager; 109a43484afda4c4fb4b23a53a2dc91d985d39dc2c4Ted Kremenek 110a43484afda4c4fb4b23a53a2dc91d985d39dc2c4Ted Kremenekprotected: 111a43484afda4c4fb4b23a53a2dc91d985d39dc2c4Ted Kremenek MemRegionManager *Mgr; 112a43484afda4c4fb4b23a53a2dc91d985d39dc2c4Ted Kremenek 113a43484afda4c4fb4b23a53a2dc91d985d39dc2c4Ted Kremenek MemSpaceRegion(MemRegionManager *mgr) : MemRegion(MemSpaceRegionKind), 114a43484afda4c4fb4b23a53a2dc91d985d39dc2c4Ted Kremenek Mgr(mgr) {} 1159e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenek 116a43484afda4c4fb4b23a53a2dc91d985d39dc2c4Ted Kremenek MemRegionManager* getMemRegionManager() const { 117a43484afda4c4fb4b23a53a2dc91d985d39dc2c4Ted Kremenek return Mgr; 118a43484afda4c4fb4b23a53a2dc91d985d39dc2c4Ted Kremenek } 119a43484afda4c4fb4b23a53a2dc91d985d39dc2c4Ted Kremenek 1209e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenekpublic: 1219e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenek void Profile(llvm::FoldingSetNodeID& ID) const; 1229e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenek 123a43484afda4c4fb4b23a53a2dc91d985d39dc2c4Ted Kremenek bool isBoundable() const { return false; } 12441168eac256fed59ec5406a75fce91c59cd5dd91Ted Kremenek 1259e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenek static bool classof(const MemRegion* R) { 1269e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenek return R->getKind() == MemSpaceRegionKind; 1279e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenek } 1289e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenek}; 1299e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenek 130993f1c72913417be7c534ec7a634363cdfc84fa5Ted Kremenek/// SubRegion - A region that subsets another larger region. Most regions 131993f1c72913417be7c534ec7a634363cdfc84fa5Ted Kremenek/// are subclasses of SubRegion. 132993f1c72913417be7c534ec7a634363cdfc84fa5Ted Kremenekclass SubRegion : public MemRegion { 1339e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenekprotected: 134993f1c72913417be7c534ec7a634363cdfc84fa5Ted Kremenek const MemRegion* superRegion; 135993f1c72913417be7c534ec7a634363cdfc84fa5Ted Kremenek SubRegion(const MemRegion* sReg, Kind k) : MemRegion(k), superRegion(sReg) {} 1369e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenekpublic: 1379e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenek const MemRegion* getSuperRegion() const { 1389e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenek return superRegion; 1399e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenek } 140a43484afda4c4fb4b23a53a2dc91d985d39dc2c4Ted Kremenek 141a43484afda4c4fb4b23a53a2dc91d985d39dc2c4Ted Kremenek MemRegionManager* getMemRegionManager() const; 14219e1f0ba5cec738ce6cebe3fe0e1edc782206494Ted Kremenek 1437e5d6ed47dcedce35043de59ee00464b681bc786Zhongxing Xu bool isSubRegionOf(const MemRegion* R) const; 14419e1f0ba5cec738ce6cebe3fe0e1edc782206494Ted Kremenek 1459e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenek static bool classof(const MemRegion* R) { 146026c66395b88a09437319139a43b090093f7e1ddZhongxing Xu return R->getKind() > MemSpaceRegionKind; 147993f1c72913417be7c534ec7a634363cdfc84fa5Ted Kremenek } 148993f1c72913417be7c534ec7a634363cdfc84fa5Ted Kremenek}; 14919e1f0ba5cec738ce6cebe3fe0e1edc782206494Ted Kremenek 15019e1f0ba5cec738ce6cebe3fe0e1edc782206494Ted Kremenek//===----------------------------------------------------------------------===// 15119e1f0ba5cec738ce6cebe3fe0e1edc782206494Ted Kremenek// Auxillary data classes for use with MemRegions. 15219e1f0ba5cec738ce6cebe3fe0e1edc782206494Ted Kremenek//===----------------------------------------------------------------------===// 15319e1f0ba5cec738ce6cebe3fe0e1edc782206494Ted Kremenek 15419e1f0ba5cec738ce6cebe3fe0e1edc782206494Ted Kremenekclass ElementRegion; 15519e1f0ba5cec738ce6cebe3fe0e1edc782206494Ted Kremenek 15619e1f0ba5cec738ce6cebe3fe0e1edc782206494Ted Kremenekclass RegionRawOffset : public std::pair<const MemRegion*, int64_t> { 15719e1f0ba5cec738ce6cebe3fe0e1edc782206494Ted Kremenekprivate: 15819e1f0ba5cec738ce6cebe3fe0e1edc782206494Ted Kremenek friend class ElementRegion; 15919e1f0ba5cec738ce6cebe3fe0e1edc782206494Ted Kremenek 16019e1f0ba5cec738ce6cebe3fe0e1edc782206494Ted Kremenek RegionRawOffset(const MemRegion* reg, int64_t offset = 0) 16119e1f0ba5cec738ce6cebe3fe0e1edc782206494Ted Kremenek : std::pair<const MemRegion*, int64_t>(reg, offset) {} 16219e1f0ba5cec738ce6cebe3fe0e1edc782206494Ted Kremenek 16319e1f0ba5cec738ce6cebe3fe0e1edc782206494Ted Kremenekpublic: 16419e1f0ba5cec738ce6cebe3fe0e1edc782206494Ted Kremenek // FIXME: Eventually support symbolic offsets. 16519e1f0ba5cec738ce6cebe3fe0e1edc782206494Ted Kremenek int64_t getByteOffset() const { return second; } 16619e1f0ba5cec738ce6cebe3fe0e1edc782206494Ted Kremenek const MemRegion *getRegion() const { return first; } 16719e1f0ba5cec738ce6cebe3fe0e1edc782206494Ted Kremenek 16819e1f0ba5cec738ce6cebe3fe0e1edc782206494Ted Kremenek void dumpToStream(llvm::raw_ostream& os) const; 16919e1f0ba5cec738ce6cebe3fe0e1edc782206494Ted Kremenek void dump() const; 17019e1f0ba5cec738ce6cebe3fe0e1edc782206494Ted Kremenek}; 17119e1f0ba5cec738ce6cebe3fe0e1edc782206494Ted Kremenek 17219e1f0ba5cec738ce6cebe3fe0e1edc782206494Ted Kremenek//===----------------------------------------------------------------------===// 17319e1f0ba5cec738ce6cebe3fe0e1edc782206494Ted Kremenek// MemRegion subclasses. 17419e1f0ba5cec738ce6cebe3fe0e1edc782206494Ted Kremenek//===----------------------------------------------------------------------===// 175ec13d9206645af07ef7c571405893b8d901de151Zhongxing Xu 17682bd99f4db2454cc6e1b7bfaac6db25cb3444ddcTed Kremenek/// AllocaRegion - A region that represents an untyped blob of bytes created 17782bd99f4db2454cc6e1b7bfaac6db25cb3444ddcTed Kremenek/// by a call to 'alloca'. 17882bd99f4db2454cc6e1b7bfaac6db25cb3444ddcTed Kremenekclass AllocaRegion : public SubRegion { 17982bd99f4db2454cc6e1b7bfaac6db25cb3444ddcTed Kremenek friend class MemRegionManager; 18082bd99f4db2454cc6e1b7bfaac6db25cb3444ddcTed Kremenekprotected: 18182bd99f4db2454cc6e1b7bfaac6db25cb3444ddcTed Kremenek unsigned Cnt; // Block counter. Used to distinguish different pieces of 18282bd99f4db2454cc6e1b7bfaac6db25cb3444ddcTed Kremenek // memory allocated by alloca at the same call site. 18382bd99f4db2454cc6e1b7bfaac6db25cb3444ddcTed Kremenek const Expr* Ex; 18482bd99f4db2454cc6e1b7bfaac6db25cb3444ddcTed Kremenek 1857ae7ad9951f032d0a33b64c964f7cdcb9cc6f59bTed Kremenek AllocaRegion(const Expr* ex, unsigned cnt, const MemRegion *superRegion) 18682bd99f4db2454cc6e1b7bfaac6db25cb3444ddcTed Kremenek : SubRegion(superRegion, AllocaRegionKind), Cnt(cnt), Ex(ex) {} 18782bd99f4db2454cc6e1b7bfaac6db25cb3444ddcTed Kremenek 18882bd99f4db2454cc6e1b7bfaac6db25cb3444ddcTed Kremenekpublic: 18982bd99f4db2454cc6e1b7bfaac6db25cb3444ddcTed Kremenek 19082bd99f4db2454cc6e1b7bfaac6db25cb3444ddcTed Kremenek const Expr* getExpr() const { return Ex; } 1919852b5bf94d4934de63da6356c651c61e81f58d9Zhongxing Xu 1929852b5bf94d4934de63da6356c651c61e81f58d9Zhongxing Xu bool isBoundable() const { return true; } 1939852b5bf94d4934de63da6356c651c61e81f58d9Zhongxing Xu 19482bd99f4db2454cc6e1b7bfaac6db25cb3444ddcTed Kremenek void Profile(llvm::FoldingSetNodeID& ID) const; 19582bd99f4db2454cc6e1b7bfaac6db25cb3444ddcTed Kremenek 19682bd99f4db2454cc6e1b7bfaac6db25cb3444ddcTed Kremenek static void ProfileRegion(llvm::FoldingSetNodeID& ID, const Expr* Ex, 1977ae7ad9951f032d0a33b64c964f7cdcb9cc6f59bTed Kremenek unsigned Cnt, const MemRegion *superRegion); 19882bd99f4db2454cc6e1b7bfaac6db25cb3444ddcTed Kremenek 1998800ad4eaa1621f6d23c8264971063b9f8da6a2eTed Kremenek void dumpToStream(llvm::raw_ostream& os) const; 20082bd99f4db2454cc6e1b7bfaac6db25cb3444ddcTed Kremenek 20182bd99f4db2454cc6e1b7bfaac6db25cb3444ddcTed Kremenek static bool classof(const MemRegion* R) { 20282bd99f4db2454cc6e1b7bfaac6db25cb3444ddcTed Kremenek return R->getKind() == AllocaRegionKind; 20382bd99f4db2454cc6e1b7bfaac6db25cb3444ddcTed Kremenek } 20482bd99f4db2454cc6e1b7bfaac6db25cb3444ddcTed Kremenek}; 20582bd99f4db2454cc6e1b7bfaac6db25cb3444ddcTed Kremenek 206993f1c72913417be7c534ec7a634363cdfc84fa5Ted Kremenek/// TypedRegion - An abstract class representing regions that are typed. 207993f1c72913417be7c534ec7a634363cdfc84fa5Ted Kremenekclass TypedRegion : public SubRegion { 208993f1c72913417be7c534ec7a634363cdfc84fa5Ted Kremenekprotected: 209993f1c72913417be7c534ec7a634363cdfc84fa5Ted Kremenek TypedRegion(const MemRegion* sReg, Kind k) : SubRegion(sReg, k) {} 210993f1c72913417be7c534ec7a634363cdfc84fa5Ted Kremenek 211993f1c72913417be7c534ec7a634363cdfc84fa5Ted Kremenekpublic: 212a82d8aa5b3b3d24998b4d98b9f45a43cc84cac6fZhongxing Xu virtual QualType getValueType(ASTContext &C) const = 0; 2136eddeb153415049c7b62de4b45385a759a6906c6Ted Kremenek 214ff6978263439e21d795b0602fabcb38488ef8441Zhongxing Xu virtual QualType getLocationType(ASTContext& C) const { 2156eddeb153415049c7b62de4b45385a759a6906c6Ted Kremenek // FIXME: We can possibly optimize this later to cache this value. 216a82d8aa5b3b3d24998b4d98b9f45a43cc84cac6fZhongxing Xu return C.getPointerType(getValueType(C)); 2176eddeb153415049c7b62de4b45385a759a6906c6Ted Kremenek } 21814553abd17d303b0b310b3ab1523eb0d30d8121cTed Kremenek 219a82d8aa5b3b3d24998b4d98b9f45a43cc84cac6fZhongxing Xu QualType getDesugaredValueType(ASTContext& C) const { 220a82d8aa5b3b3d24998b4d98b9f45a43cc84cac6fZhongxing Xu QualType T = getValueType(C); 2211b9b883a95215e38e153d253a46a2a2fcac25896Ted Kremenek return T.getTypePtr() ? T->getDesugaredType() : T; 22214553abd17d303b0b310b3ab1523eb0d30d8121cTed Kremenek } 22314553abd17d303b0b310b3ab1523eb0d30d8121cTed Kremenek 224ff6978263439e21d795b0602fabcb38488ef8441Zhongxing Xu QualType getDesugaredLocationType(ASTContext& C) const { 225ff6978263439e21d795b0602fabcb38488ef8441Zhongxing Xu return getLocationType(C)->getDesugaredType(); 22614553abd17d303b0b310b3ab1523eb0d30d8121cTed Kremenek } 2271b9b883a95215e38e153d253a46a2a2fcac25896Ted Kremenek 228a43484afda4c4fb4b23a53a2dc91d985d39dc2c4Ted Kremenek bool isBoundable() const { 229a43484afda4c4fb4b23a53a2dc91d985d39dc2c4Ted Kremenek return !getValueType(getContext()).isNull(); 23041168eac256fed59ec5406a75fce91c59cd5dd91Ted Kremenek } 2316eddeb153415049c7b62de4b45385a759a6906c6Ted Kremenek 232993f1c72913417be7c534ec7a634363cdfc84fa5Ted Kremenek static bool classof(const MemRegion* R) { 2339e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenek unsigned k = R->getKind(); 2349e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenek return k > BEG_TYPED_REGIONS && k < END_TYPED_REGIONS; 2359e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenek } 2369e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenek}; 2379e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenek 238ec13d9206645af07ef7c571405893b8d901de151Zhongxing Xu/// CodeTextRegion - A region that represents code texts of a function. It wraps 239ec13d9206645af07ef7c571405893b8d901de151Zhongxing Xu/// two kinds of code texts: real function and symbolic function. Real function 240ec13d9206645af07ef7c571405893b8d901de151Zhongxing Xu/// is a function declared in the program. Symbolic function is a function 241ec13d9206645af07ef7c571405893b8d901de151Zhongxing Xu/// pointer that we don't know which function it points to. 242ec13d9206645af07ef7c571405893b8d901de151Zhongxing Xuclass CodeTextRegion : public TypedRegion { 243ec13d9206645af07ef7c571405893b8d901de151Zhongxing Xupublic: 244ec13d9206645af07ef7c571405893b8d901de151Zhongxing Xu enum CodeKind { Declared, Symbolic }; 245ec13d9206645af07ef7c571405893b8d901de151Zhongxing Xu 246ec13d9206645af07ef7c571405893b8d901de151Zhongxing Xuprivate: 247ec13d9206645af07ef7c571405893b8d901de151Zhongxing Xu // The function pointer kind that this CodeTextRegion represents. 248ec13d9206645af07ef7c571405893b8d901de151Zhongxing Xu CodeKind codekind; 249ec13d9206645af07ef7c571405893b8d901de151Zhongxing Xu 250ec13d9206645af07ef7c571405893b8d901de151Zhongxing Xu // Data may be a SymbolRef or FunctionDecl*. 251ec13d9206645af07ef7c571405893b8d901de151Zhongxing Xu const void* Data; 252ec13d9206645af07ef7c571405893b8d901de151Zhongxing Xu 253ec13d9206645af07ef7c571405893b8d901de151Zhongxing Xu // Cached function pointer type. 254ec13d9206645af07ef7c571405893b8d901de151Zhongxing Xu QualType LocationType; 255ec13d9206645af07ef7c571405893b8d901de151Zhongxing Xu 256ec13d9206645af07ef7c571405893b8d901de151Zhongxing Xupublic: 257ec13d9206645af07ef7c571405893b8d901de151Zhongxing Xu 258ec13d9206645af07ef7c571405893b8d901de151Zhongxing Xu CodeTextRegion(const FunctionDecl* fd, QualType t, const MemRegion* sreg) 259ec13d9206645af07ef7c571405893b8d901de151Zhongxing Xu : TypedRegion(sreg, CodeTextRegionKind), 260ec13d9206645af07ef7c571405893b8d901de151Zhongxing Xu codekind(Declared), 261ec13d9206645af07ef7c571405893b8d901de151Zhongxing Xu Data(fd), 262ec13d9206645af07ef7c571405893b8d901de151Zhongxing Xu LocationType(t) {} 263ec13d9206645af07ef7c571405893b8d901de151Zhongxing Xu 264ec13d9206645af07ef7c571405893b8d901de151Zhongxing Xu CodeTextRegion(SymbolRef sym, QualType t, const MemRegion* sreg) 265ec13d9206645af07ef7c571405893b8d901de151Zhongxing Xu : TypedRegion(sreg, CodeTextRegionKind), 266ec13d9206645af07ef7c571405893b8d901de151Zhongxing Xu codekind(Symbolic), 267ec13d9206645af07ef7c571405893b8d901de151Zhongxing Xu Data(sym), 268ec13d9206645af07ef7c571405893b8d901de151Zhongxing Xu LocationType(t) {} 269ec13d9206645af07ef7c571405893b8d901de151Zhongxing Xu 270a82d8aa5b3b3d24998b4d98b9f45a43cc84cac6fZhongxing Xu QualType getValueType(ASTContext &C) const { 271ec13d9206645af07ef7c571405893b8d901de151Zhongxing Xu // Do not get the object type of a CodeTextRegion. 272ec13d9206645af07ef7c571405893b8d901de151Zhongxing Xu assert(0); 273ec13d9206645af07ef7c571405893b8d901de151Zhongxing Xu return QualType(); 274ec13d9206645af07ef7c571405893b8d901de151Zhongxing Xu } 275ec13d9206645af07ef7c571405893b8d901de151Zhongxing Xu 276ff6978263439e21d795b0602fabcb38488ef8441Zhongxing Xu QualType getLocationType(ASTContext &C) const { 277ec13d9206645af07ef7c571405893b8d901de151Zhongxing Xu return LocationType; 278ec13d9206645af07ef7c571405893b8d901de151Zhongxing Xu } 279369f447eded97e6048ced02c0c2be3842f61fc1cZhongxing Xu 280369f447eded97e6048ced02c0c2be3842f61fc1cZhongxing Xu bool isDeclared() const { return codekind == Declared; } 281264e93799c891c03d60cf0b09a032b0a9935d3b5Zhongxing Xu bool isSymbolic() const { return codekind == Symbolic; } 282369f447eded97e6048ced02c0c2be3842f61fc1cZhongxing Xu 283369f447eded97e6048ced02c0c2be3842f61fc1cZhongxing Xu const FunctionDecl* getDecl() const { 284369f447eded97e6048ced02c0c2be3842f61fc1cZhongxing Xu assert(codekind == Declared); 285369f447eded97e6048ced02c0c2be3842f61fc1cZhongxing Xu return static_cast<const FunctionDecl*>(Data); 286369f447eded97e6048ced02c0c2be3842f61fc1cZhongxing Xu } 2878ec3d7dbff9d526fcdce4fbea683830192340c90Ted Kremenek 28872e032004b0d2c2c298e8e4f7027f23a21c0cc7dTed Kremenek SymbolRef getSymbol() const { 28972e032004b0d2c2c298e8e4f7027f23a21c0cc7dTed Kremenek assert(codekind == Symbolic); 29072e032004b0d2c2c298e8e4f7027f23a21c0cc7dTed Kremenek return const_cast<SymbolRef>(static_cast<const SymbolRef>(Data)); 29172e032004b0d2c2c298e8e4f7027f23a21c0cc7dTed Kremenek } 29272e032004b0d2c2c298e8e4f7027f23a21c0cc7dTed Kremenek 293a43484afda4c4fb4b23a53a2dc91d985d39dc2c4Ted Kremenek bool isBoundable() const { return false; } 29472e032004b0d2c2c298e8e4f7027f23a21c0cc7dTed Kremenek 2958800ad4eaa1621f6d23c8264971063b9f8da6a2eTed Kremenek virtual void dumpToStream(llvm::raw_ostream& os) const; 296ec13d9206645af07ef7c571405893b8d901de151Zhongxing Xu 297ec13d9206645af07ef7c571405893b8d901de151Zhongxing Xu void Profile(llvm::FoldingSetNodeID& ID) const; 298ec13d9206645af07ef7c571405893b8d901de151Zhongxing Xu 299ec13d9206645af07ef7c571405893b8d901de151Zhongxing Xu static void ProfileRegion(llvm::FoldingSetNodeID& ID, 3000dea5241bca707789d706ed1fda3a29a8fedc4c0Zhongxing Xu const void* data, QualType t, const MemRegion*); 301ec13d9206645af07ef7c571405893b8d901de151Zhongxing Xu 302ec13d9206645af07ef7c571405893b8d901de151Zhongxing Xu static bool classof(const MemRegion* R) { 303ec13d9206645af07ef7c571405893b8d901de151Zhongxing Xu return R->getKind() == CodeTextRegionKind; 304ec13d9206645af07ef7c571405893b8d901de151Zhongxing Xu } 305ec13d9206645af07ef7c571405893b8d901de151Zhongxing Xu}; 306ec13d9206645af07ef7c571405893b8d901de151Zhongxing Xu 307026c66395b88a09437319139a43b090093f7e1ddZhongxing Xu/// SymbolicRegion - A special, "non-concrete" region. Unlike other region 308026c66395b88a09437319139a43b090093f7e1ddZhongxing Xu/// clases, SymbolicRegion represents a region that serves as an alias for 309026c66395b88a09437319139a43b090093f7e1ddZhongxing Xu/// either a real region, a NULL pointer, etc. It essentially is used to 310026c66395b88a09437319139a43b090093f7e1ddZhongxing Xu/// map the concept of symbolic values into the domain of regions. Symbolic 311026c66395b88a09437319139a43b090093f7e1ddZhongxing Xu/// regions do not need to be typed. 312e8e86482da4c1872673bbb9c237649229d19793bTed Kremenekclass SymbolicRegion : public SubRegion { 313026c66395b88a09437319139a43b090093f7e1ddZhongxing Xuprotected: 314026c66395b88a09437319139a43b090093f7e1ddZhongxing Xu const SymbolRef sym; 315026c66395b88a09437319139a43b090093f7e1ddZhongxing Xu 316026c66395b88a09437319139a43b090093f7e1ddZhongxing Xupublic: 317e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek SymbolicRegion(const SymbolRef s, const MemRegion* sreg) 318e8e86482da4c1872673bbb9c237649229d19793bTed Kremenek : SubRegion(sreg, SymbolicRegionKind), sym(s) {} 319026c66395b88a09437319139a43b090093f7e1ddZhongxing Xu 320026c66395b88a09437319139a43b090093f7e1ddZhongxing Xu SymbolRef getSymbol() const { 321026c66395b88a09437319139a43b090093f7e1ddZhongxing Xu return sym; 322026c66395b88a09437319139a43b090093f7e1ddZhongxing Xu } 323026c66395b88a09437319139a43b090093f7e1ddZhongxing Xu 3249852b5bf94d4934de63da6356c651c61e81f58d9Zhongxing Xu bool isBoundable() const { return true; } 3259852b5bf94d4934de63da6356c651c61e81f58d9Zhongxing Xu 326026c66395b88a09437319139a43b090093f7e1ddZhongxing Xu void Profile(llvm::FoldingSetNodeID& ID) const; 327026c66395b88a09437319139a43b090093f7e1ddZhongxing Xu 328250101353b711a409b075f1bc11070dddec7100bTed Kremenek static void ProfileRegion(llvm::FoldingSetNodeID& ID, 329250101353b711a409b075f1bc11070dddec7100bTed Kremenek SymbolRef sym, 330250101353b711a409b075f1bc11070dddec7100bTed Kremenek const MemRegion* superRegion); 331026c66395b88a09437319139a43b090093f7e1ddZhongxing Xu 3328800ad4eaa1621f6d23c8264971063b9f8da6a2eTed Kremenek void dumpToStream(llvm::raw_ostream& os) const; 333026c66395b88a09437319139a43b090093f7e1ddZhongxing Xu 334026c66395b88a09437319139a43b090093f7e1ddZhongxing Xu static bool classof(const MemRegion* R) { 335026c66395b88a09437319139a43b090093f7e1ddZhongxing Xu return R->getKind() == SymbolicRegionKind; 336026c66395b88a09437319139a43b090093f7e1ddZhongxing Xu } 337026c66395b88a09437319139a43b090093f7e1ddZhongxing Xu}; 338026c66395b88a09437319139a43b090093f7e1ddZhongxing Xu 339e9f4e5420895a75dd788e9891921e7781c1823b9Zhongxing Xu/// StringRegion - Region associated with a StringLiteral. 340e9f4e5420895a75dd788e9891921e7781c1823b9Zhongxing Xuclass StringRegion : public TypedRegion { 341e9f4e5420895a75dd788e9891921e7781c1823b9Zhongxing Xu friend class MemRegionManager; 342e9f4e5420895a75dd788e9891921e7781c1823b9Zhongxing Xu const StringLiteral* Str; 343e9f4e5420895a75dd788e9891921e7781c1823b9Zhongxing Xuprotected: 344e9f4e5420895a75dd788e9891921e7781c1823b9Zhongxing Xu 345250101353b711a409b075f1bc11070dddec7100bTed Kremenek StringRegion(const StringLiteral* str, const MemRegion* sreg) 346e9f4e5420895a75dd788e9891921e7781c1823b9Zhongxing Xu : TypedRegion(sreg, StringRegionKind), Str(str) {} 347e9f4e5420895a75dd788e9891921e7781c1823b9Zhongxing Xu 348e9f4e5420895a75dd788e9891921e7781c1823b9Zhongxing Xu static void ProfileRegion(llvm::FoldingSetNodeID& ID, 349e9f4e5420895a75dd788e9891921e7781c1823b9Zhongxing Xu const StringLiteral* Str, 350e9f4e5420895a75dd788e9891921e7781c1823b9Zhongxing Xu const MemRegion* superRegion); 351e9f4e5420895a75dd788e9891921e7781c1823b9Zhongxing Xu 352e9f4e5420895a75dd788e9891921e7781c1823b9Zhongxing Xupublic: 3536613d08a19aa6ce9b6330487f3bfac841d4b8a4dZhongxing Xu 3546613d08a19aa6ce9b6330487f3bfac841d4b8a4dZhongxing Xu const StringLiteral* getStringLiteral() const { return Str; } 3556eddeb153415049c7b62de4b45385a759a6906c6Ted Kremenek 356a82d8aa5b3b3d24998b4d98b9f45a43cc84cac6fZhongxing Xu QualType getValueType(ASTContext& C) const { 357ff6978263439e21d795b0602fabcb38488ef8441Zhongxing Xu return Str->getType(); 358ff6978263439e21d795b0602fabcb38488ef8441Zhongxing Xu } 359e9f4e5420895a75dd788e9891921e7781c1823b9Zhongxing Xu 3600a51f1c6cec6032bcf64ce205bc4edfdc3cb3a2fZhongxing Xu bool isBoundable() const { return false; } 3610a51f1c6cec6032bcf64ce205bc4edfdc3cb3a2fZhongxing Xu 362e9f4e5420895a75dd788e9891921e7781c1823b9Zhongxing Xu void Profile(llvm::FoldingSetNodeID& ID) const { 363e9f4e5420895a75dd788e9891921e7781c1823b9Zhongxing Xu ProfileRegion(ID, Str, superRegion); 364e9f4e5420895a75dd788e9891921e7781c1823b9Zhongxing Xu } 365e9f4e5420895a75dd788e9891921e7781c1823b9Zhongxing Xu 3668800ad4eaa1621f6d23c8264971063b9f8da6a2eTed Kremenek void dumpToStream(llvm::raw_ostream& os) const; 367cc128b32429494fe04ed36d7ba30c011cb4e173aZhongxing Xu 368e9f4e5420895a75dd788e9891921e7781c1823b9Zhongxing Xu static bool classof(const MemRegion* R) { 369e9f4e5420895a75dd788e9891921e7781c1823b9Zhongxing Xu return R->getKind() == StringRegionKind; 370e9f4e5420895a75dd788e9891921e7781c1823b9Zhongxing Xu } 371e9f4e5420895a75dd788e9891921e7781c1823b9Zhongxing Xu}; 372e9f4e5420895a75dd788e9891921e7781c1823b9Zhongxing Xu 373329d6fde79254503b14724e1231a9d70fa6b387fTed Kremenek/// CompoundLiteralRegion - A memory region representing a compound literal. 374329d6fde79254503b14724e1231a9d70fa6b387fTed Kremenek/// Compound literals are essentially temporaries that are stack allocated 375329d6fde79254503b14724e1231a9d70fa6b387fTed Kremenek/// or in the global constant pool. 37677cfac623178d0c16e16e2f171d20b0fea8fde30Zhongxing Xuclass CompoundLiteralRegion : public TypedRegion { 377329d6fde79254503b14724e1231a9d70fa6b387fTed Kremenekprivate: 378329d6fde79254503b14724e1231a9d70fa6b387fTed Kremenek friend class MemRegionManager; 379329d6fde79254503b14724e1231a9d70fa6b387fTed Kremenek const CompoundLiteralExpr* CL; 380329d6fde79254503b14724e1231a9d70fa6b387fTed Kremenek 381329d6fde79254503b14724e1231a9d70fa6b387fTed Kremenek CompoundLiteralRegion(const CompoundLiteralExpr* cl, const MemRegion* sReg) 38277cfac623178d0c16e16e2f171d20b0fea8fde30Zhongxing Xu : TypedRegion(sReg, CompoundLiteralRegionKind), CL(cl) {} 383329d6fde79254503b14724e1231a9d70fa6b387fTed Kremenek 384329d6fde79254503b14724e1231a9d70fa6b387fTed Kremenek static void ProfileRegion(llvm::FoldingSetNodeID& ID, 385329d6fde79254503b14724e1231a9d70fa6b387fTed Kremenek const CompoundLiteralExpr* CL, 386329d6fde79254503b14724e1231a9d70fa6b387fTed Kremenek const MemRegion* superRegion); 387329d6fde79254503b14724e1231a9d70fa6b387fTed Kremenekpublic: 388a82d8aa5b3b3d24998b4d98b9f45a43cc84cac6fZhongxing Xu QualType getValueType(ASTContext& C) const { 38977cfac623178d0c16e16e2f171d20b0fea8fde30Zhongxing Xu return C.getCanonicalType(CL->getType()); 39077cfac623178d0c16e16e2f171d20b0fea8fde30Zhongxing Xu } 3910a51f1c6cec6032bcf64ce205bc4edfdc3cb3a2fZhongxing Xu 3929a08fee80a34938b8c11c7166e009a89ced4c2b4Zhongxing Xu bool isBoundable() const { return !CL->isFileScope(); } 3939a08fee80a34938b8c11c7166e009a89ced4c2b4Zhongxing Xu 394329d6fde79254503b14724e1231a9d70fa6b387fTed Kremenek void Profile(llvm::FoldingSetNodeID& ID) const; 395329d6fde79254503b14724e1231a9d70fa6b387fTed Kremenek 3968800ad4eaa1621f6d23c8264971063b9f8da6a2eTed Kremenek void dumpToStream(llvm::raw_ostream& os) const; 397329d6fde79254503b14724e1231a9d70fa6b387fTed Kremenek 39811a83dc7a9a5738cc0bc76180b508eae896eefa9Ted Kremenek const CompoundLiteralExpr* getLiteralExpr() const { return CL; } 39911a83dc7a9a5738cc0bc76180b508eae896eefa9Ted Kremenek 400329d6fde79254503b14724e1231a9d70fa6b387fTed Kremenek static bool classof(const MemRegion* R) { 401329d6fde79254503b14724e1231a9d70fa6b387fTed Kremenek return R->getKind() == CompoundLiteralRegionKind; 402329d6fde79254503b14724e1231a9d70fa6b387fTed Kremenek } 403329d6fde79254503b14724e1231a9d70fa6b387fTed Kremenek}; 404178927517fa09ddbb04dc8ef725b5716c18aae21Zhongxing Xu 4059e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenekclass DeclRegion : public TypedRegion { 4069e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenekprotected: 4079e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenek const Decl* D; 4089e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenek 409993f1c72913417be7c534ec7a634363cdfc84fa5Ted Kremenek DeclRegion(const Decl* d, const MemRegion* sReg, Kind k) 4109e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenek : TypedRegion(sReg, k), D(d) {} 4119e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenek 4129e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenek static void ProfileRegion(llvm::FoldingSetNodeID& ID, const Decl* D, 4139e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenek const MemRegion* superRegion, Kind k); 4149e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenek 415bfb6582ef46dfb33672d9621f879fc262339d704Zhongxing Xupublic: 416bfb6582ef46dfb33672d9621f879fc262339d704Zhongxing Xu const Decl* getDecl() const { return D; } 4179e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenek void Profile(llvm::FoldingSetNodeID& ID) const; 4186eddeb153415049c7b62de4b45385a759a6906c6Ted Kremenek 419e9f4e5420895a75dd788e9891921e7781c1823b9Zhongxing Xu static bool classof(const MemRegion* R) { 420e9f4e5420895a75dd788e9891921e7781c1823b9Zhongxing Xu unsigned k = R->getKind(); 421e9f4e5420895a75dd788e9891921e7781c1823b9Zhongxing Xu return k > BEG_DECL_REGIONS && k < END_DECL_REGIONS; 422e9f4e5420895a75dd788e9891921e7781c1823b9Zhongxing Xu } 4239e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenek}; 4249e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenek 4259e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenekclass VarRegion : public DeclRegion { 4269e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenek friend class MemRegionManager; 427d17da2b99f323fa91b01e1dd119cc32e0ee8197dTed Kremenek 428d17da2b99f323fa91b01e1dd119cc32e0ee8197dTed Kremenek // Data. 429d17da2b99f323fa91b01e1dd119cc32e0ee8197dTed Kremenek const LocationContext *LC; 4309e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenek 431d17da2b99f323fa91b01e1dd119cc32e0ee8197dTed Kremenek // Constructors and private methods. 432d17da2b99f323fa91b01e1dd119cc32e0ee8197dTed Kremenek VarRegion(const VarDecl* vd, const LocationContext *lC, const MemRegion* sReg) 433d17da2b99f323fa91b01e1dd119cc32e0ee8197dTed Kremenek : DeclRegion(vd, sReg, VarRegionKind), LC(lC) {} 4349e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenek 435250101353b711a409b075f1bc11070dddec7100bTed Kremenek static void ProfileRegion(llvm::FoldingSetNodeID& ID, const VarDecl* VD, 436d17da2b99f323fa91b01e1dd119cc32e0ee8197dTed Kremenek const LocationContext *LC, 437d17da2b99f323fa91b01e1dd119cc32e0ee8197dTed Kremenek const MemRegion *superRegion) { 4389e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenek DeclRegion::ProfileRegion(ID, VD, superRegion, VarRegionKind); 439d17da2b99f323fa91b01e1dd119cc32e0ee8197dTed Kremenek ID.AddPointer(LC); 4409e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenek } 4419e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenek 442d17da2b99f323fa91b01e1dd119cc32e0ee8197dTed Kremenek void Profile(llvm::FoldingSetNodeID& ID) const; 443d17da2b99f323fa91b01e1dd119cc32e0ee8197dTed Kremenek 4449e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenekpublic: 445d17da2b99f323fa91b01e1dd119cc32e0ee8197dTed Kremenek const VarDecl *getDecl() const { return cast<VarDecl>(D); } 446d17da2b99f323fa91b01e1dd119cc32e0ee8197dTed Kremenek 447d17da2b99f323fa91b01e1dd119cc32e0ee8197dTed Kremenek const LocationContext *getLocationContext() const { return LC; } 4489e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenek 449a82d8aa5b3b3d24998b4d98b9f45a43cc84cac6fZhongxing Xu QualType getValueType(ASTContext& C) const { 4506eddeb153415049c7b62de4b45385a759a6906c6Ted Kremenek // FIXME: We can cache this if needed. 4516eddeb153415049c7b62de4b45385a759a6906c6Ted Kremenek return C.getCanonicalType(getDecl()->getType()); 4526eddeb153415049c7b62de4b45385a759a6906c6Ted Kremenek } 4536eddeb153415049c7b62de4b45385a759a6906c6Ted Kremenek 4548800ad4eaa1621f6d23c8264971063b9f8da6a2eTed Kremenek void dumpToStream(llvm::raw_ostream& os) const; 4559e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenek 4569e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenek static bool classof(const MemRegion* R) { 4579e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenek return R->getKind() == VarRegionKind; 4589e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenek } 4599e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenek}; 4609e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenek 4619e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenekclass FieldRegion : public DeclRegion { 4629e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenek friend class MemRegionManager; 4639e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenek 464993f1c72913417be7c534ec7a634363cdfc84fa5Ted Kremenek FieldRegion(const FieldDecl* fd, const MemRegion* sReg) 4659e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenek : DeclRegion(fd, sReg, FieldRegionKind) {} 4669e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenek 4674bd1eefd48c70ebef185e524d0484c00f16000cfTed Kremenekpublic: 4684bd1eefd48c70ebef185e524d0484c00f16000cfTed Kremenek 4698800ad4eaa1621f6d23c8264971063b9f8da6a2eTed Kremenek void dumpToStream(llvm::raw_ostream& os) const; 4704bd1eefd48c70ebef185e524d0484c00f16000cfTed Kremenek 4714bd1eefd48c70ebef185e524d0484c00f16000cfTed Kremenek const FieldDecl* getDecl() const { return cast<FieldDecl>(D); } 4726eddeb153415049c7b62de4b45385a759a6906c6Ted Kremenek 473a82d8aa5b3b3d24998b4d98b9f45a43cc84cac6fZhongxing Xu QualType getValueType(ASTContext& C) const { 4746eddeb153415049c7b62de4b45385a759a6906c6Ted Kremenek // FIXME: We can cache this if needed. 475e70559fd25bfd1970a82086c5f99cf9ef181b1aeZhongxing Xu return C.getCanonicalType(getDecl()->getType()); 4766eddeb153415049c7b62de4b45385a759a6906c6Ted Kremenek } 4774bd1eefd48c70ebef185e524d0484c00f16000cfTed Kremenek 4786304b08daee27b25ae2e2bdb8bffd67dfad74b3cTed Kremenek static void ProfileRegion(llvm::FoldingSetNodeID& ID, const FieldDecl* FD, 4796304b08daee27b25ae2e2bdb8bffd67dfad74b3cTed Kremenek const MemRegion* superRegion) { 4809e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenek DeclRegion::ProfileRegion(ID, FD, superRegion, FieldRegionKind); 4819e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenek } 4829e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenek 4839e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenek static bool classof(const MemRegion* R) { 4849e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenek return R->getKind() == FieldRegionKind; 4859e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenek } 4869e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenek}; 4879e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenek 488a7f1b9e8804012ed8df25d93f5a06cb26c9bbd2bTed Kremenekclass ObjCObjectRegion : public DeclRegion { 489a7f1b9e8804012ed8df25d93f5a06cb26c9bbd2bTed Kremenek 490a7f1b9e8804012ed8df25d93f5a06cb26c9bbd2bTed Kremenek friend class MemRegionManager; 491a7f1b9e8804012ed8df25d93f5a06cb26c9bbd2bTed Kremenek 492a7f1b9e8804012ed8df25d93f5a06cb26c9bbd2bTed Kremenek ObjCObjectRegion(const ObjCInterfaceDecl* ivd, const MemRegion* sReg) 493a7f1b9e8804012ed8df25d93f5a06cb26c9bbd2bTed Kremenek : DeclRegion(ivd, sReg, ObjCObjectRegionKind) {} 494a7f1b9e8804012ed8df25d93f5a06cb26c9bbd2bTed Kremenek 4956304b08daee27b25ae2e2bdb8bffd67dfad74b3cTed Kremenek static void ProfileRegion(llvm::FoldingSetNodeID& ID, 4966304b08daee27b25ae2e2bdb8bffd67dfad74b3cTed Kremenek const ObjCInterfaceDecl* ivd, 497a7f1b9e8804012ed8df25d93f5a06cb26c9bbd2bTed Kremenek const MemRegion* superRegion) { 498a7f1b9e8804012ed8df25d93f5a06cb26c9bbd2bTed Kremenek DeclRegion::ProfileRegion(ID, ivd, superRegion, ObjCObjectRegionKind); 499a7f1b9e8804012ed8df25d93f5a06cb26c9bbd2bTed Kremenek } 500a7f1b9e8804012ed8df25d93f5a06cb26c9bbd2bTed Kremenek 501a7f1b9e8804012ed8df25d93f5a06cb26c9bbd2bTed Kremenekpublic: 502a7f1b9e8804012ed8df25d93f5a06cb26c9bbd2bTed Kremenek const ObjCInterfaceDecl* getInterface() const { 503a7f1b9e8804012ed8df25d93f5a06cb26c9bbd2bTed Kremenek return cast<ObjCInterfaceDecl>(D); 504a7f1b9e8804012ed8df25d93f5a06cb26c9bbd2bTed Kremenek } 505a7f1b9e8804012ed8df25d93f5a06cb26c9bbd2bTed Kremenek 506a82d8aa5b3b3d24998b4d98b9f45a43cc84cac6fZhongxing Xu QualType getValueType(ASTContext& C) const { 5073b3a45858c6b2a45114e91902c3bf3c4b7f5f302Daniel Dunbar return C.getObjCInterfaceType(getInterface()); 508a7f1b9e8804012ed8df25d93f5a06cb26c9bbd2bTed Kremenek } 509a7f1b9e8804012ed8df25d93f5a06cb26c9bbd2bTed Kremenek 510a7f1b9e8804012ed8df25d93f5a06cb26c9bbd2bTed Kremenek static bool classof(const MemRegion* R) { 511a7f1b9e8804012ed8df25d93f5a06cb26c9bbd2bTed Kremenek return R->getKind() == ObjCObjectRegionKind; 512a7f1b9e8804012ed8df25d93f5a06cb26c9bbd2bTed Kremenek } 513a7f1b9e8804012ed8df25d93f5a06cb26c9bbd2bTed Kremenek}; 514a7f1b9e8804012ed8df25d93f5a06cb26c9bbd2bTed Kremenek 5159e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenekclass ObjCIvarRegion : public DeclRegion { 5169e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenek 5179e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenek friend class MemRegionManager; 5189e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenek 519993f1c72913417be7c534ec7a634363cdfc84fa5Ted Kremenek ObjCIvarRegion(const ObjCIvarDecl* ivd, const MemRegion* sReg) 5209e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenek : DeclRegion(ivd, sReg, ObjCIvarRegionKind) {} 5219e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenek 5226304b08daee27b25ae2e2bdb8bffd67dfad74b3cTed Kremenek static void ProfileRegion(llvm::FoldingSetNodeID& ID, const ObjCIvarDecl* ivd, 5236304b08daee27b25ae2e2bdb8bffd67dfad74b3cTed Kremenek const MemRegion* superRegion) { 5249e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenek DeclRegion::ProfileRegion(ID, ivd, superRegion, ObjCIvarRegionKind); 5259e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenek } 5269e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenek 5279e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenekpublic: 5289e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenek const ObjCIvarDecl* getDecl() const { return cast<ObjCIvarDecl>(D); } 529a82d8aa5b3b3d24998b4d98b9f45a43cc84cac6fZhongxing Xu QualType getValueType(ASTContext&) const { return getDecl()->getType(); } 5309e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenek 531bcfe03a0beb61082fa2f40887216d8dbca19a024Ted Kremenek void dumpToStream(llvm::raw_ostream& os) const; 532bcfe03a0beb61082fa2f40887216d8dbca19a024Ted Kremenek 5339e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenek static bool classof(const MemRegion* R) { 5349e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenek return R->getKind() == ObjCIvarRegionKind; 5359e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenek } 5369e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenek}; 537511191ce8920160525611be2be754c32a0724c3eZhongxing Xu 53827b57063d83b00474d7563fb5d608544e2364862Zhongxing Xuclass ElementRegion : public TypedRegion { 539511191ce8920160525611be2be754c32a0724c3eZhongxing Xu friend class MemRegionManager; 540511191ce8920160525611be2be754c32a0724c3eZhongxing Xu 541f936f4568700d799e7d92eecef67b0e2b822ae7eTed Kremenek QualType ElementType; 542511191ce8920160525611be2be754c32a0724c3eZhongxing Xu SVal Index; 543511191ce8920160525611be2be754c32a0724c3eZhongxing Xu 544f936f4568700d799e7d92eecef67b0e2b822ae7eTed Kremenek ElementRegion(QualType elementType, SVal Idx, const MemRegion* sReg) 545f936f4568700d799e7d92eecef67b0e2b822ae7eTed Kremenek : TypedRegion(sReg, ElementRegionKind), 546f936f4568700d799e7d92eecef67b0e2b822ae7eTed Kremenek ElementType(elementType), Index(Idx) { 5473d8173c1c68f451c7492f92023d829c626845925Chris Lattner assert((!isa<nonloc::ConcreteInt>(&Idx) || 5483d8173c1c68f451c7492f92023d829c626845925Chris Lattner cast<nonloc::ConcreteInt>(&Idx)->getValue().isSigned()) && 54943b28d07019bc78447ecbbb721526de4ffd83f20Chris Lattner "The index must be signed"); 5500395b5d4987fe5baa818015e9d294c128619e4ecZhongxing Xu } 551abb042f33ea8e6107a7dc8efc51d2ace329f9f48Ted Kremenek 552f936f4568700d799e7d92eecef67b0e2b822ae7eTed Kremenek static void ProfileRegion(llvm::FoldingSetNodeID& ID, QualType elementType, 553f936f4568700d799e7d92eecef67b0e2b822ae7eTed Kremenek SVal Idx, const MemRegion* superRegion); 554511191ce8920160525611be2be754c32a0724c3eZhongxing Xu 555511191ce8920160525611be2be754c32a0724c3eZhongxing Xupublic: 556511191ce8920160525611be2be754c32a0724c3eZhongxing Xu 5576e78e1b22f3b16bb2ef76950b9b75f060bdba7bfZhongxing Xu SVal getIndex() const { return Index; } 5586e78e1b22f3b16bb2ef76950b9b75f060bdba7bfZhongxing Xu 559a82d8aa5b3b3d24998b4d98b9f45a43cc84cac6fZhongxing Xu QualType getValueType(ASTContext&) const { 560f936f4568700d799e7d92eecef67b0e2b822ae7eTed Kremenek return ElementType; 561f936f4568700d799e7d92eecef67b0e2b822ae7eTed Kremenek } 562f936f4568700d799e7d92eecef67b0e2b822ae7eTed Kremenek 563f936f4568700d799e7d92eecef67b0e2b822ae7eTed Kremenek QualType getElementType() const { 564f936f4568700d799e7d92eecef67b0e2b822ae7eTed Kremenek return ElementType; 565abb042f33ea8e6107a7dc8efc51d2ace329f9f48Ted Kremenek } 566abb042f33ea8e6107a7dc8efc51d2ace329f9f48Ted Kremenek 56719e1f0ba5cec738ce6cebe3fe0e1edc782206494Ted Kremenek RegionRawOffset getAsRawOffset() const; 56819e1f0ba5cec738ce6cebe3fe0e1edc782206494Ted Kremenek 5698800ad4eaa1621f6d23c8264971063b9f8da6a2eTed Kremenek void dumpToStream(llvm::raw_ostream& os) const; 570b21ff77c8126ea628b66d2ffb931fdaa7884f5d2Zhongxing Xu 571511191ce8920160525611be2be754c32a0724c3eZhongxing Xu void Profile(llvm::FoldingSetNodeID& ID) const; 572511191ce8920160525611be2be754c32a0724c3eZhongxing Xu 573511191ce8920160525611be2be754c32a0724c3eZhongxing Xu static bool classof(const MemRegion* R) { 574511191ce8920160525611be2be754c32a0724c3eZhongxing Xu return R->getKind() == ElementRegionKind; 575511191ce8920160525611be2be754c32a0724c3eZhongxing Xu } 576511191ce8920160525611be2be754c32a0724c3eZhongxing Xu}; 57719e1f0ba5cec738ce6cebe3fe0e1edc782206494Ted Kremenek 578ed65d3d97132fbcdd124aef4d2478e348dfbd36bTed Kremenektemplate<typename RegionTy> 579ed65d3d97132fbcdd124aef4d2478e348dfbd36bTed Kremenekconst RegionTy* MemRegion::getAs() const { 580f7a0cf426eddae76e1a71dd2295631a2cf0560afTed Kremenek if (const RegionTy* RT = dyn_cast<RegionTy>(this)) 581f7a0cf426eddae76e1a71dd2295631a2cf0560afTed Kremenek return RT; 582ed65d3d97132fbcdd124aef4d2478e348dfbd36bTed Kremenek 583f7a0cf426eddae76e1a71dd2295631a2cf0560afTed Kremenek return NULL; 584ed65d3d97132fbcdd124aef4d2478e348dfbd36bTed Kremenek} 585511191ce8920160525611be2be754c32a0724c3eZhongxing Xu 5869e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenek//===----------------------------------------------------------------------===// 5879e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenek// MemRegionManager - Factory object for creating regions. 5889e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenek//===----------------------------------------------------------------------===// 5899e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenek 5909e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenekclass MemRegionManager { 591a43484afda4c4fb4b23a53a2dc91d985d39dc2c4Ted Kremenek ASTContext &C; 5929e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenek llvm::BumpPtrAllocator& A; 5939e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenek llvm::FoldingSet<MemRegion> Regions; 5949e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenek 595d05552a21377f493c882298c59e8829040b01d34Ted Kremenek MemSpaceRegion *globals; 596d05552a21377f493c882298c59e8829040b01d34Ted Kremenek MemSpaceRegion *stack; 597d05552a21377f493c882298c59e8829040b01d34Ted Kremenek MemSpaceRegion *stackArguments; 598d05552a21377f493c882298c59e8829040b01d34Ted Kremenek MemSpaceRegion *heap; 599d05552a21377f493c882298c59e8829040b01d34Ted Kremenek MemSpaceRegion *unknown; 600d05552a21377f493c882298c59e8829040b01d34Ted Kremenek MemSpaceRegion *code; 601dc0a25d9bff956cdbe54ea0bfc8fbbe3ceb4eb92Zhongxing Xu 6029e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenekpublic: 603a43484afda4c4fb4b23a53a2dc91d985d39dc2c4Ted Kremenek MemRegionManager(ASTContext &c, llvm::BumpPtrAllocator& a) 604d05552a21377f493c882298c59e8829040b01d34Ted Kremenek : C(c), A(a), globals(0), stack(0), stackArguments(0), heap(0), 605d05552a21377f493c882298c59e8829040b01d34Ted Kremenek unknown(0), code(0) {} 6069e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenek 6079e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenek ~MemRegionManager() {} 6089e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenek 609a43484afda4c4fb4b23a53a2dc91d985d39dc2c4Ted Kremenek ASTContext &getContext() { return C; } 610a43484afda4c4fb4b23a53a2dc91d985d39dc2c4Ted Kremenek 6119e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenek /// getStackRegion - Retrieve the memory region associated with the 6129e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenek /// current stack frame. 613d05552a21377f493c882298c59e8829040b01d34Ted Kremenek MemSpaceRegion *getStackRegion(); 614d05552a21377f493c882298c59e8829040b01d34Ted Kremenek 615d05552a21377f493c882298c59e8829040b01d34Ted Kremenek /// getStackArgumentsRegion - Retrieve the memory region associated with 616d05552a21377f493c882298c59e8829040b01d34Ted Kremenek /// function/method arguments of the current stack frame. 617d05552a21377f493c882298c59e8829040b01d34Ted Kremenek MemSpaceRegion *getStackArgumentsRegion(); 6189e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenek 6199e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenek /// getGlobalsRegion - Retrieve the memory region associated with 6209e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenek /// all global variables. 621d05552a21377f493c882298c59e8829040b01d34Ted Kremenek MemSpaceRegion *getGlobalsRegion(); 6229e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenek 6239e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenek /// getHeapRegion - Retrieve the memory region associated with the 6249e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenek /// generic "heap". 625d05552a21377f493c882298c59e8829040b01d34Ted Kremenek MemSpaceRegion *getHeapRegion(); 626178927517fa09ddbb04dc8ef725b5716c18aae21Zhongxing Xu 627178927517fa09ddbb04dc8ef725b5716c18aae21Zhongxing Xu /// getUnknownRegion - Retrieve the memory region associated with unknown 628178927517fa09ddbb04dc8ef725b5716c18aae21Zhongxing Xu /// memory space. 629d05552a21377f493c882298c59e8829040b01d34Ted Kremenek MemSpaceRegion *getUnknownRegion(); 630c540b261ac553b91840146eaa3fee3f11b1013a7Zhongxing Xu 631d05552a21377f493c882298c59e8829040b01d34Ted Kremenek MemSpaceRegion *getCodeRegion(); 632ec13d9206645af07ef7c571405893b8d901de151Zhongxing Xu 6337090ae1a984eb446a5fb4da7b1f2573830653799Ted Kremenek /// getAllocaRegion - Retrieve a region associated with a call to alloca(). 634d05552a21377f493c882298c59e8829040b01d34Ted Kremenek AllocaRegion *getAllocaRegion(const Expr* Ex, unsigned Cnt); 6357090ae1a984eb446a5fb4da7b1f2573830653799Ted Kremenek 636329d6fde79254503b14724e1231a9d70fa6b387fTed Kremenek /// getCompoundLiteralRegion - Retrieve the region associated with a 637329d6fde79254503b14724e1231a9d70fa6b387fTed Kremenek /// given CompoundLiteral. 638329d6fde79254503b14724e1231a9d70fa6b387fTed Kremenek CompoundLiteralRegion* 639329d6fde79254503b14724e1231a9d70fa6b387fTed Kremenek getCompoundLiteralRegion(const CompoundLiteralExpr* CL); 640329d6fde79254503b14724e1231a9d70fa6b387fTed Kremenek 641993f1c72913417be7c534ec7a634363cdfc84fa5Ted Kremenek /// getSymbolicRegion - Retrieve or create a "symbolic" memory region. 642e0e4ebf6bfca5a71b2344d8a1b748b852509279cTed Kremenek SymbolicRegion* getSymbolicRegion(SymbolRef sym); 643e9f4e5420895a75dd788e9891921e7781c1823b9Zhongxing Xu 644e9f4e5420895a75dd788e9891921e7781c1823b9Zhongxing Xu StringRegion* getStringRegion(const StringLiteral* Str); 645e9f4e5420895a75dd788e9891921e7781c1823b9Zhongxing Xu 6469e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenek /// getVarRegion - Retrieve or create the memory region associated with 647d17da2b99f323fa91b01e1dd119cc32e0ee8197dTed Kremenek /// a specified VarDecl and LocationContext. 648d17da2b99f323fa91b01e1dd119cc32e0ee8197dTed Kremenek VarRegion* getVarRegion(const VarDecl *D, const LocationContext *LC); 649329d6fde79254503b14724e1231a9d70fa6b387fTed Kremenek 650f936f4568700d799e7d92eecef67b0e2b822ae7eTed Kremenek /// getElementRegion - Retrieve the memory region associated with the 651f936f4568700d799e7d92eecef67b0e2b822ae7eTed Kremenek /// associated element type, index, and super region. 652a5e81f1240bcc5b9b0721fc6275075ad7cadaf5eTed Kremenek ElementRegion *getElementRegion(QualType elementType, SVal Idx, 653d17da2b99f323fa91b01e1dd119cc32e0ee8197dTed Kremenek const MemRegion *superRegion, 654d17da2b99f323fa91b01e1dd119cc32e0ee8197dTed Kremenek ASTContext &Ctx); 655a5e81f1240bcc5b9b0721fc6275075ad7cadaf5eTed Kremenek 656a5e81f1240bcc5b9b0721fc6275075ad7cadaf5eTed Kremenek ElementRegion *getElementRegionWithSuper(const ElementRegion *ER, 657a5e81f1240bcc5b9b0721fc6275075ad7cadaf5eTed Kremenek const MemRegion *superRegion) { 658a5e81f1240bcc5b9b0721fc6275075ad7cadaf5eTed Kremenek return getElementRegion(ER->getElementType(), ER->getIndex(), 659a5e81f1240bcc5b9b0721fc6275075ad7cadaf5eTed Kremenek superRegion, ER->getContext()); 660a5e81f1240bcc5b9b0721fc6275075ad7cadaf5eTed Kremenek } 661511191ce8920160525611be2be754c32a0724c3eZhongxing Xu 6629e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenek /// getFieldRegion - Retrieve or create the memory region associated with 6639e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenek /// a specified FieldDecl. 'superRegion' corresponds to the containing 6649e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenek /// memory region (which typically represents the memory representing 6659e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenek /// a structure or class). 666a5e81f1240bcc5b9b0721fc6275075ad7cadaf5eTed Kremenek FieldRegion *getFieldRegion(const FieldDecl* fd, 667abb042f33ea8e6107a7dc8efc51d2ace329f9f48Ted Kremenek const MemRegion* superRegion); 6689e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenek 669a5e81f1240bcc5b9b0721fc6275075ad7cadaf5eTed Kremenek FieldRegion *getFieldRegionWithSuper(const FieldRegion *FR, 670a5e81f1240bcc5b9b0721fc6275075ad7cadaf5eTed Kremenek const MemRegion *superRegion) { 671a5e81f1240bcc5b9b0721fc6275075ad7cadaf5eTed Kremenek return getFieldRegion(FR->getDecl(), superRegion); 672a5e81f1240bcc5b9b0721fc6275075ad7cadaf5eTed Kremenek } 673a5e81f1240bcc5b9b0721fc6275075ad7cadaf5eTed Kremenek 674a7f1b9e8804012ed8df25d93f5a06cb26c9bbd2bTed Kremenek /// getObjCObjectRegion - Retrieve or create the memory region associated with 675a7f1b9e8804012ed8df25d93f5a06cb26c9bbd2bTed Kremenek /// the instance of a specified Objective-C class. 676a7f1b9e8804012ed8df25d93f5a06cb26c9bbd2bTed Kremenek ObjCObjectRegion* getObjCObjectRegion(const ObjCInterfaceDecl* ID, 677a7f1b9e8804012ed8df25d93f5a06cb26c9bbd2bTed Kremenek const MemRegion* superRegion); 678a7f1b9e8804012ed8df25d93f5a06cb26c9bbd2bTed Kremenek 6799e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenek /// getObjCIvarRegion - Retrieve or create the memory region associated with 6809e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenek /// a specified Objective-c instance variable. 'superRegion' corresponds 6819e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenek /// to the containing region (which typically represents the Objective-C 6829e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenek /// object). 6839e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenek ObjCIvarRegion* getObjCIvarRegion(const ObjCIvarDecl* ivd, 684993f1c72913417be7c534ec7a634363cdfc84fa5Ted Kremenek const MemRegion* superRegion); 68519e1f0ba5cec738ce6cebe3fe0e1edc782206494Ted Kremenek 686ec13d9206645af07ef7c571405893b8d901de151Zhongxing Xu CodeTextRegion* getCodeTextRegion(SymbolRef sym, QualType t); 687ec13d9206645af07ef7c571405893b8d901de151Zhongxing Xu CodeTextRegion* getCodeTextRegion(const FunctionDecl* fd, QualType t); 688250101353b711a409b075f1bc11070dddec7100bTed Kremenek 689250101353b711a409b075f1bc11070dddec7100bTed Kremenek template <typename RegionTy, typename A1> 690250101353b711a409b075f1bc11070dddec7100bTed Kremenek RegionTy* getRegion(const A1 a1); 6916304b08daee27b25ae2e2bdb8bffd67dfad74b3cTed Kremenek 6926304b08daee27b25ae2e2bdb8bffd67dfad74b3cTed Kremenek template <typename RegionTy, typename A1> 693eeea45611d45238c34474c183cee96d47ae79e24Ted Kremenek RegionTy* getSubRegion(const A1 a1, const MemRegion* superRegion); 6947ae7ad9951f032d0a33b64c964f7cdcb9cc6f59bTed Kremenek 6957ae7ad9951f032d0a33b64c964f7cdcb9cc6f59bTed Kremenek template <typename RegionTy, typename A1, typename A2> 6967ae7ad9951f032d0a33b64c964f7cdcb9cc6f59bTed Kremenek RegionTy* getRegion(const A1 a1, const A2 a2); 697dc0a25d9bff956cdbe54ea0bfc8fbbe3ceb4eb92Zhongxing Xu 698dd198f04897df87c52fef66398035cbf67fdc33dZhongxing Xu bool isGlobalsRegion(const MemRegion* R) { 699dd198f04897df87c52fef66398035cbf67fdc33dZhongxing Xu assert(R); 700dd198f04897df87c52fef66398035cbf67fdc33dZhongxing Xu return R == globals; 701dd198f04897df87c52fef66398035cbf67fdc33dZhongxing Xu } 702dd198f04897df87c52fef66398035cbf67fdc33dZhongxing Xu 7039e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenekprivate: 7049e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenek MemSpaceRegion* LazyAllocate(MemSpaceRegion*& region); 705ed65d3d97132fbcdd124aef4d2478e348dfbd36bTed Kremenek}; 706250101353b711a409b075f1bc11070dddec7100bTed Kremenek 707250101353b711a409b075f1bc11070dddec7100bTed Kremenek//===----------------------------------------------------------------------===// 708a43484afda4c4fb4b23a53a2dc91d985d39dc2c4Ted Kremenek// Out-of-line member definitions. 709250101353b711a409b075f1bc11070dddec7100bTed Kremenek//===----------------------------------------------------------------------===// 710250101353b711a409b075f1bc11070dddec7100bTed Kremenek 711a43484afda4c4fb4b23a53a2dc91d985d39dc2c4Ted Kremenekinline ASTContext& MemRegion::getContext() const { 712a43484afda4c4fb4b23a53a2dc91d985d39dc2c4Ted Kremenek return getMemRegionManager()->getContext(); 713a43484afda4c4fb4b23a53a2dc91d985d39dc2c4Ted Kremenek} 714a43484afda4c4fb4b23a53a2dc91d985d39dc2c4Ted Kremenek 715250101353b711a409b075f1bc11070dddec7100bTed Kremenektemplate<typename RegionTy> struct MemRegionManagerTrait; 716250101353b711a409b075f1bc11070dddec7100bTed Kremenek 717250101353b711a409b075f1bc11070dddec7100bTed Kremenektemplate <typename RegionTy, typename A1> 718250101353b711a409b075f1bc11070dddec7100bTed KremenekRegionTy* MemRegionManager::getRegion(const A1 a1) { 719250101353b711a409b075f1bc11070dddec7100bTed Kremenek 720250101353b711a409b075f1bc11070dddec7100bTed Kremenek const typename MemRegionManagerTrait<RegionTy>::SuperRegionTy *superRegion = 721250101353b711a409b075f1bc11070dddec7100bTed Kremenek MemRegionManagerTrait<RegionTy>::getSuperRegion(*this, a1); 722250101353b711a409b075f1bc11070dddec7100bTed Kremenek 723250101353b711a409b075f1bc11070dddec7100bTed Kremenek llvm::FoldingSetNodeID ID; 724250101353b711a409b075f1bc11070dddec7100bTed Kremenek RegionTy::ProfileRegion(ID, a1, superRegion); 725250101353b711a409b075f1bc11070dddec7100bTed Kremenek void* InsertPos; 726250101353b711a409b075f1bc11070dddec7100bTed Kremenek RegionTy* R = cast_or_null<RegionTy>(Regions.FindNodeOrInsertPos(ID, 727250101353b711a409b075f1bc11070dddec7100bTed Kremenek InsertPos)); 728250101353b711a409b075f1bc11070dddec7100bTed Kremenek 729250101353b711a409b075f1bc11070dddec7100bTed Kremenek if (!R) { 7306304b08daee27b25ae2e2bdb8bffd67dfad74b3cTed Kremenek R = (RegionTy*) A.Allocate<RegionTy>(); 7316304b08daee27b25ae2e2bdb8bffd67dfad74b3cTed Kremenek new (R) RegionTy(a1, superRegion); 7326304b08daee27b25ae2e2bdb8bffd67dfad74b3cTed Kremenek Regions.InsertNode(R, InsertPos); 7336304b08daee27b25ae2e2bdb8bffd67dfad74b3cTed Kremenek } 7346304b08daee27b25ae2e2bdb8bffd67dfad74b3cTed Kremenek 7356304b08daee27b25ae2e2bdb8bffd67dfad74b3cTed Kremenek return R; 7366304b08daee27b25ae2e2bdb8bffd67dfad74b3cTed Kremenek} 7376304b08daee27b25ae2e2bdb8bffd67dfad74b3cTed Kremenek 7386304b08daee27b25ae2e2bdb8bffd67dfad74b3cTed Kremenektemplate <typename RegionTy, typename A1> 739eeea45611d45238c34474c183cee96d47ae79e24Ted KremenekRegionTy* MemRegionManager::getSubRegion(const A1 a1, 740eeea45611d45238c34474c183cee96d47ae79e24Ted Kremenek const MemRegion *superRegion) { 7416304b08daee27b25ae2e2bdb8bffd67dfad74b3cTed Kremenek llvm::FoldingSetNodeID ID; 7426304b08daee27b25ae2e2bdb8bffd67dfad74b3cTed Kremenek RegionTy::ProfileRegion(ID, a1, superRegion); 7436304b08daee27b25ae2e2bdb8bffd67dfad74b3cTed Kremenek void* InsertPos; 7446304b08daee27b25ae2e2bdb8bffd67dfad74b3cTed Kremenek RegionTy* R = cast_or_null<RegionTy>(Regions.FindNodeOrInsertPos(ID, 7456304b08daee27b25ae2e2bdb8bffd67dfad74b3cTed Kremenek InsertPos)); 7466304b08daee27b25ae2e2bdb8bffd67dfad74b3cTed Kremenek 7476304b08daee27b25ae2e2bdb8bffd67dfad74b3cTed Kremenek if (!R) { 748250101353b711a409b075f1bc11070dddec7100bTed Kremenek R = (RegionTy*) A.Allocate<RegionTy>(); 749250101353b711a409b075f1bc11070dddec7100bTed Kremenek new (R) RegionTy(a1, superRegion); 750250101353b711a409b075f1bc11070dddec7100bTed Kremenek Regions.InsertNode(R, InsertPos); 751250101353b711a409b075f1bc11070dddec7100bTed Kremenek } 752250101353b711a409b075f1bc11070dddec7100bTed Kremenek 753250101353b711a409b075f1bc11070dddec7100bTed Kremenek return R; 754250101353b711a409b075f1bc11070dddec7100bTed Kremenek} 755250101353b711a409b075f1bc11070dddec7100bTed Kremenek 7567ae7ad9951f032d0a33b64c964f7cdcb9cc6f59bTed Kremenektemplate <typename RegionTy, typename A1, typename A2> 7577ae7ad9951f032d0a33b64c964f7cdcb9cc6f59bTed KremenekRegionTy* MemRegionManager::getRegion(const A1 a1, const A2 a2) { 7587ae7ad9951f032d0a33b64c964f7cdcb9cc6f59bTed Kremenek 7597ae7ad9951f032d0a33b64c964f7cdcb9cc6f59bTed Kremenek const typename MemRegionManagerTrait<RegionTy>::SuperRegionTy *superRegion = 7607ae7ad9951f032d0a33b64c964f7cdcb9cc6f59bTed Kremenek MemRegionManagerTrait<RegionTy>::getSuperRegion(*this, a1, a2); 7617ae7ad9951f032d0a33b64c964f7cdcb9cc6f59bTed Kremenek 7627ae7ad9951f032d0a33b64c964f7cdcb9cc6f59bTed Kremenek llvm::FoldingSetNodeID ID; 7637ae7ad9951f032d0a33b64c964f7cdcb9cc6f59bTed Kremenek RegionTy::ProfileRegion(ID, a1, a2, superRegion); 7647ae7ad9951f032d0a33b64c964f7cdcb9cc6f59bTed Kremenek void* InsertPos; 7657ae7ad9951f032d0a33b64c964f7cdcb9cc6f59bTed Kremenek RegionTy* R = cast_or_null<RegionTy>(Regions.FindNodeOrInsertPos(ID, 7667ae7ad9951f032d0a33b64c964f7cdcb9cc6f59bTed Kremenek InsertPos)); 7677ae7ad9951f032d0a33b64c964f7cdcb9cc6f59bTed Kremenek 7687ae7ad9951f032d0a33b64c964f7cdcb9cc6f59bTed Kremenek if (!R) { 7697ae7ad9951f032d0a33b64c964f7cdcb9cc6f59bTed Kremenek R = (RegionTy*) A.Allocate<RegionTy>(); 7707ae7ad9951f032d0a33b64c964f7cdcb9cc6f59bTed Kremenek new (R) RegionTy(a1, a2, superRegion); 7717ae7ad9951f032d0a33b64c964f7cdcb9cc6f59bTed Kremenek Regions.InsertNode(R, InsertPos); 7727ae7ad9951f032d0a33b64c964f7cdcb9cc6f59bTed Kremenek } 7737ae7ad9951f032d0a33b64c964f7cdcb9cc6f59bTed Kremenek 7747ae7ad9951f032d0a33b64c964f7cdcb9cc6f59bTed Kremenek return R; 7757ae7ad9951f032d0a33b64c964f7cdcb9cc6f59bTed Kremenek} 7767ae7ad9951f032d0a33b64c964f7cdcb9cc6f59bTed Kremenek 777250101353b711a409b075f1bc11070dddec7100bTed Kremenek//===----------------------------------------------------------------------===// 778250101353b711a409b075f1bc11070dddec7100bTed Kremenek// Traits for constructing regions. 779250101353b711a409b075f1bc11070dddec7100bTed Kremenek//===----------------------------------------------------------------------===// 780250101353b711a409b075f1bc11070dddec7100bTed Kremenek 7817ae7ad9951f032d0a33b64c964f7cdcb9cc6f59bTed Kremenektemplate <> struct MemRegionManagerTrait<AllocaRegion> { 7827ae7ad9951f032d0a33b64c964f7cdcb9cc6f59bTed Kremenek typedef MemRegion SuperRegionTy; 7837ae7ad9951f032d0a33b64c964f7cdcb9cc6f59bTed Kremenek static const SuperRegionTy* getSuperRegion(MemRegionManager& MRMgr, 7847ae7ad9951f032d0a33b64c964f7cdcb9cc6f59bTed Kremenek const Expr *, unsigned) { 7857ae7ad9951f032d0a33b64c964f7cdcb9cc6f59bTed Kremenek return MRMgr.getStackRegion(); 7867ae7ad9951f032d0a33b64c964f7cdcb9cc6f59bTed Kremenek } 7877ae7ad9951f032d0a33b64c964f7cdcb9cc6f59bTed Kremenek}; 7887ae7ad9951f032d0a33b64c964f7cdcb9cc6f59bTed Kremenek 789250101353b711a409b075f1bc11070dddec7100bTed Kremenektemplate <> struct MemRegionManagerTrait<CompoundLiteralRegion> { 790250101353b711a409b075f1bc11070dddec7100bTed Kremenek typedef MemRegion SuperRegionTy; 791250101353b711a409b075f1bc11070dddec7100bTed Kremenek static const SuperRegionTy* getSuperRegion(MemRegionManager& MRMgr, 792250101353b711a409b075f1bc11070dddec7100bTed Kremenek const CompoundLiteralExpr *CL) { 793250101353b711a409b075f1bc11070dddec7100bTed Kremenek 794250101353b711a409b075f1bc11070dddec7100bTed Kremenek return CL->isFileScope() ? MRMgr.getGlobalsRegion() 795250101353b711a409b075f1bc11070dddec7100bTed Kremenek : MRMgr.getStackRegion(); 796250101353b711a409b075f1bc11070dddec7100bTed Kremenek } 797250101353b711a409b075f1bc11070dddec7100bTed Kremenek}; 798250101353b711a409b075f1bc11070dddec7100bTed Kremenek 799250101353b711a409b075f1bc11070dddec7100bTed Kremenektemplate <> struct MemRegionManagerTrait<StringRegion> { 800250101353b711a409b075f1bc11070dddec7100bTed Kremenek typedef MemSpaceRegion SuperRegionTy; 801250101353b711a409b075f1bc11070dddec7100bTed Kremenek static const SuperRegionTy* getSuperRegion(MemRegionManager& MRMgr, 802250101353b711a409b075f1bc11070dddec7100bTed Kremenek const StringLiteral*) { 803250101353b711a409b075f1bc11070dddec7100bTed Kremenek return MRMgr.getGlobalsRegion(); 804250101353b711a409b075f1bc11070dddec7100bTed Kremenek } 805250101353b711a409b075f1bc11070dddec7100bTed Kremenek}; 806250101353b711a409b075f1bc11070dddec7100bTed Kremenek 807250101353b711a409b075f1bc11070dddec7100bTed Kremenektemplate <> struct MemRegionManagerTrait<VarRegion> { 808250101353b711a409b075f1bc11070dddec7100bTed Kremenek typedef MemRegion SuperRegionTy; 809d17da2b99f323fa91b01e1dd119cc32e0ee8197dTed Kremenek static const SuperRegionTy* getSuperRegion(MemRegionManager &MRMgr, 810d17da2b99f323fa91b01e1dd119cc32e0ee8197dTed Kremenek const VarDecl *D, 811d17da2b99f323fa91b01e1dd119cc32e0ee8197dTed Kremenek const LocationContext *LC) { 812d17da2b99f323fa91b01e1dd119cc32e0ee8197dTed Kremenek 813d17da2b99f323fa91b01e1dd119cc32e0ee8197dTed Kremenek // FIXME: Make stack regions have a location context? 814d17da2b99f323fa91b01e1dd119cc32e0ee8197dTed Kremenek 815d17da2b99f323fa91b01e1dd119cc32e0ee8197dTed Kremenek if (D->hasLocalStorage()) { 816d17da2b99f323fa91b01e1dd119cc32e0ee8197dTed Kremenek return isa<ParmVarDecl>(D) || isa<ImplicitParamDecl>(D) 817d05552a21377f493c882298c59e8829040b01d34Ted Kremenek ? MRMgr.getStackArgumentsRegion() : MRMgr.getStackRegion(); 818d05552a21377f493c882298c59e8829040b01d34Ted Kremenek } 819d05552a21377f493c882298c59e8829040b01d34Ted Kremenek 820d05552a21377f493c882298c59e8829040b01d34Ted Kremenek return MRMgr.getGlobalsRegion(); 821250101353b711a409b075f1bc11070dddec7100bTed Kremenek } 822250101353b711a409b075f1bc11070dddec7100bTed Kremenek}; 823250101353b711a409b075f1bc11070dddec7100bTed Kremenek 824250101353b711a409b075f1bc11070dddec7100bTed Kremenektemplate <> struct MemRegionManagerTrait<SymbolicRegion> { 825250101353b711a409b075f1bc11070dddec7100bTed Kremenek typedef MemRegion SuperRegionTy; 826250101353b711a409b075f1bc11070dddec7100bTed Kremenek static const SuperRegionTy* getSuperRegion(MemRegionManager& MRMgr, 827250101353b711a409b075f1bc11070dddec7100bTed Kremenek SymbolRef) { 828250101353b711a409b075f1bc11070dddec7100bTed Kremenek return MRMgr.getUnknownRegion(); 829250101353b711a409b075f1bc11070dddec7100bTed Kremenek } 830250101353b711a409b075f1bc11070dddec7100bTed Kremenek}; 8310dea5241bca707789d706ed1fda3a29a8fedc4c0Zhongxing Xu 8320dea5241bca707789d706ed1fda3a29a8fedc4c0Zhongxing Xutemplate<> struct MemRegionManagerTrait<CodeTextRegion> { 8330dea5241bca707789d706ed1fda3a29a8fedc4c0Zhongxing Xu typedef MemSpaceRegion SuperRegionTy; 8340dea5241bca707789d706ed1fda3a29a8fedc4c0Zhongxing Xu static const SuperRegionTy* getSuperRegion(MemRegionManager& MRMgr, 8350dea5241bca707789d706ed1fda3a29a8fedc4c0Zhongxing Xu const FunctionDecl*, QualType) { 8360dea5241bca707789d706ed1fda3a29a8fedc4c0Zhongxing Xu return MRMgr.getCodeRegion(); 8370dea5241bca707789d706ed1fda3a29a8fedc4c0Zhongxing Xu } 8380dea5241bca707789d706ed1fda3a29a8fedc4c0Zhongxing Xu static const SuperRegionTy* getSuperRegion(MemRegionManager& MRMgr, 8390dea5241bca707789d706ed1fda3a29a8fedc4c0Zhongxing Xu SymbolRef, QualType) { 8400dea5241bca707789d706ed1fda3a29a8fedc4c0Zhongxing Xu return MRMgr.getCodeRegion(); 8410dea5241bca707789d706ed1fda3a29a8fedc4c0Zhongxing Xu } 8420dea5241bca707789d706ed1fda3a29a8fedc4c0Zhongxing Xu}; 843250101353b711a409b075f1bc11070dddec7100bTed Kremenek 844be91224894e1501133e224934285ba6440bf5b59Ted Kremenek} // end clang namespace 8459e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenek 846250101353b711a409b075f1bc11070dddec7100bTed Kremenek//===----------------------------------------------------------------------===// 847250101353b711a409b075f1bc11070dddec7100bTed Kremenek// Pretty-printing regions. 848250101353b711a409b075f1bc11070dddec7100bTed Kremenek//===----------------------------------------------------------------------===// 849250101353b711a409b075f1bc11070dddec7100bTed Kremenek 850be91224894e1501133e224934285ba6440bf5b59Ted Kremeneknamespace llvm { 8518800ad4eaa1621f6d23c8264971063b9f8da6a2eTed Kremenekstatic inline raw_ostream& operator<<(raw_ostream& os, 852be91224894e1501133e224934285ba6440bf5b59Ted Kremenek const clang::MemRegion* R) { 8538800ad4eaa1621f6d23c8264971063b9f8da6a2eTed Kremenek R->dumpToStream(os); 8548800ad4eaa1621f6d23c8264971063b9f8da6a2eTed Kremenek return os; 855be91224894e1501133e224934285ba6440bf5b59Ted Kremenek} 856be91224894e1501133e224934285ba6440bf5b59Ted Kremenek} // end llvm namespace 8579e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenek 8589e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenek#endif 859