Store.cpp revision 169077dde4d91270a7495793f1e00b22aa0bc7ca
1c62abc1012feb0b15eff091b02c176649766a347Ted Kremenek//== Store.cpp - Interface for maps from Locations to Values ----*- C++ -*--==//
2c62abc1012feb0b15eff091b02c176649766a347Ted Kremenek//
3c62abc1012feb0b15eff091b02c176649766a347Ted Kremenek//                     The LLVM Compiler Infrastructure
4c62abc1012feb0b15eff091b02c176649766a347Ted Kremenek//
5c62abc1012feb0b15eff091b02c176649766a347Ted Kremenek// This file is distributed under the University of Illinois Open Source
6c62abc1012feb0b15eff091b02c176649766a347Ted Kremenek// License. See LICENSE.TXT for details.
7c62abc1012feb0b15eff091b02c176649766a347Ted Kremenek//
8c62abc1012feb0b15eff091b02c176649766a347Ted Kremenek//===----------------------------------------------------------------------===//
9c62abc1012feb0b15eff091b02c176649766a347Ted Kremenek//
10c62abc1012feb0b15eff091b02c176649766a347Ted Kremenek//  This file defined the types Store and StoreManager.
11c62abc1012feb0b15eff091b02c176649766a347Ted Kremenek//
12c62abc1012feb0b15eff091b02c176649766a347Ted Kremenek//===----------------------------------------------------------------------===//
13c62abc1012feb0b15eff091b02c176649766a347Ted Kremenek
14c62abc1012feb0b15eff091b02c176649766a347Ted Kremenek#include "clang/Analysis/PathSensitive/Store.h"
15c62abc1012feb0b15eff091b02c176649766a347Ted Kremenek#include "clang/Analysis/PathSensitive/GRState.h"
16c62abc1012feb0b15eff091b02c176649766a347Ted Kremenek
17c62abc1012feb0b15eff091b02c176649766a347Ted Kremenekusing namespace clang;
18c62abc1012feb0b15eff091b02c176649766a347Ted Kremenek
1948ce7deb86ffb1e028ac9a8e7cddffc32843c26cTed KremenekStoreManager::StoreManager(GRStateManager &stateMgr, bool useNewCastRegion)
20c62abc1012feb0b15eff091b02c176649766a347Ted Kremenek  : ValMgr(stateMgr.getValueManager()),
21c62abc1012feb0b15eff091b02c176649766a347Ted Kremenek    StateMgr(stateMgr),
2248ce7deb86ffb1e028ac9a8e7cddffc32843c26cTed Kremenek    UseNewCastRegion(useNewCastRegion),
23c62abc1012feb0b15eff091b02c176649766a347Ted Kremenek    MRMgr(ValMgr.getRegionManager()) {}
24c62abc1012feb0b15eff091b02c176649766a347Ted Kremenek
25c62abc1012feb0b15eff091b02c176649766a347Ted KremenekStoreManager::CastResult
26411af40d038947b6d2a8ad9549c85c1c4c52d15aTed KremenekStoreManager::MakeElementRegion(const GRState *state, const MemRegion *region,
27411af40d038947b6d2a8ad9549c85c1c4c52d15aTed Kremenek                                QualType pointeeTy, QualType castToTy) {
28411af40d038947b6d2a8ad9549c85c1c4c52d15aTed Kremenek
29411af40d038947b6d2a8ad9549c85c1c4c52d15aTed Kremenek  // Record the cast type of the region.
30411af40d038947b6d2a8ad9549c85c1c4c52d15aTed Kremenek  state = setCastType(state, region, castToTy);
31411af40d038947b6d2a8ad9549c85c1c4c52d15aTed Kremenek
32411af40d038947b6d2a8ad9549c85c1c4c52d15aTed Kremenek  // Create a new ElementRegion at offset 0.
33411af40d038947b6d2a8ad9549c85c1c4c52d15aTed Kremenek  SVal idx = ValMgr.makeZeroArrayIndex();
34411af40d038947b6d2a8ad9549c85c1c4c52d15aTed Kremenek  return CastResult(state, MRMgr.getElementRegion(pointeeTy, idx, region,
35411af40d038947b6d2a8ad9549c85c1c4c52d15aTed Kremenek                                                  ValMgr.getContext()));
36411af40d038947b6d2a8ad9549c85c1c4c52d15aTed Kremenek}
37411af40d038947b6d2a8ad9549c85c1c4c52d15aTed Kremenek
38169077dde4d91270a7495793f1e00b22aa0bc7caTed Kremenekstatic bool IsCompleteType(ASTContext &Ctx, QualType Ty) {
39169077dde4d91270a7495793f1e00b22aa0bc7caTed Kremenek  if (const RecordType *RT = Ty->getAsRecordType()) {
40169077dde4d91270a7495793f1e00b22aa0bc7caTed Kremenek    const RecordDecl *D = RT->getDecl();
41169077dde4d91270a7495793f1e00b22aa0bc7caTed Kremenek    if (!D->getDefinition(Ctx))
42169077dde4d91270a7495793f1e00b22aa0bc7caTed Kremenek      return false;
43169077dde4d91270a7495793f1e00b22aa0bc7caTed Kremenek  }
44169077dde4d91270a7495793f1e00b22aa0bc7caTed Kremenek
45169077dde4d91270a7495793f1e00b22aa0bc7caTed Kremenek  return true;
46169077dde4d91270a7495793f1e00b22aa0bc7caTed Kremenek}
47169077dde4d91270a7495793f1e00b22aa0bc7caTed Kremenek
48411af40d038947b6d2a8ad9549c85c1c4c52d15aTed KremenekStoreManager::CastResult
4948ce7deb86ffb1e028ac9a8e7cddffc32843c26cTed KremenekStoreManager::NewCastRegion(const GRState *state, const MemRegion* R,
5048ce7deb86ffb1e028ac9a8e7cddffc32843c26cTed Kremenek                            QualType CastToTy) {
5148ce7deb86ffb1e028ac9a8e7cddffc32843c26cTed Kremenek
5248ce7deb86ffb1e028ac9a8e7cddffc32843c26cTed Kremenek  ASTContext& Ctx = StateMgr.getContext();
5348ce7deb86ffb1e028ac9a8e7cddffc32843c26cTed Kremenek
5448ce7deb86ffb1e028ac9a8e7cddffc32843c26cTed Kremenek  // We need to know the real type of CastToTy.
5548ce7deb86ffb1e028ac9a8e7cddffc32843c26cTed Kremenek  QualType ToTy = Ctx.getCanonicalType(CastToTy);
56411af40d038947b6d2a8ad9549c85c1c4c52d15aTed Kremenek
57b9a44250c502cf9f9a2c18ccd50f06158dd7357bTed Kremenek  // Handle casts to Objective-C objects.
58fc8f57c31d8336db0ccb2ce8eb9ebf52228a47c1Ted Kremenek  if (Ctx.isObjCObjectPointerType(CastToTy)) {
59fc8f57c31d8336db0ccb2ce8eb9ebf52228a47c1Ted Kremenek    state = setCastType(state, R, CastToTy);
60145918ca119904b6abe8b41aae0cbbf9a7247905Ted Kremenek    return CastResult(state, R);
61145918ca119904b6abe8b41aae0cbbf9a7247905Ted Kremenek  }
62411af40d038947b6d2a8ad9549c85c1c4c52d15aTed Kremenek
6348ce7deb86ffb1e028ac9a8e7cddffc32843c26cTed Kremenek  // Now assume we are casting from pointer to pointer. Other cases should
6448ce7deb86ffb1e028ac9a8e7cddffc32843c26cTed Kremenek  // already be handled.
65fc8f57c31d8336db0ccb2ce8eb9ebf52228a47c1Ted Kremenek  QualType PointeeTy = CastToTy->getAsPointerType()->getPointeeType();
66169077dde4d91270a7495793f1e00b22aa0bc7caTed Kremenek
6748ce7deb86ffb1e028ac9a8e7cddffc32843c26cTed Kremenek  // Process region cast according to the kind of the region being cast.
68fc8f57c31d8336db0ccb2ce8eb9ebf52228a47c1Ted Kremenek  switch (R->getKind()) {
69fc8f57c31d8336db0ccb2ce8eb9ebf52228a47c1Ted Kremenek    case MemRegion::BEG_TYPED_REGIONS:
70fc8f57c31d8336db0ccb2ce8eb9ebf52228a47c1Ted Kremenek    case MemRegion::MemSpaceRegionKind:
71fc8f57c31d8336db0ccb2ce8eb9ebf52228a47c1Ted Kremenek    case MemRegion::BEG_DECL_REGIONS:
72fc8f57c31d8336db0ccb2ce8eb9ebf52228a47c1Ted Kremenek    case MemRegion::END_DECL_REGIONS:
73fc8f57c31d8336db0ccb2ce8eb9ebf52228a47c1Ted Kremenek    case MemRegion::END_TYPED_REGIONS:
74fc8f57c31d8336db0ccb2ce8eb9ebf52228a47c1Ted Kremenek    case MemRegion::TypedViewRegionKind: {
75fc8f57c31d8336db0ccb2ce8eb9ebf52228a47c1Ted Kremenek      assert(0 && "Invalid region cast");
76fc8f57c31d8336db0ccb2ce8eb9ebf52228a47c1Ted Kremenek      break;
7748ce7deb86ffb1e028ac9a8e7cddffc32843c26cTed Kremenek    }
78fc8f57c31d8336db0ccb2ce8eb9ebf52228a47c1Ted Kremenek
79fc8f57c31d8336db0ccb2ce8eb9ebf52228a47c1Ted Kremenek    case MemRegion::CodeTextRegionKind: {
80fc8f57c31d8336db0ccb2ce8eb9ebf52228a47c1Ted Kremenek      // CodeTextRegion should be cast to only function pointer type.
81fc8f57c31d8336db0ccb2ce8eb9ebf52228a47c1Ted Kremenek      assert(CastToTy->isFunctionPointerType() || CastToTy->isBlockPointerType()
82fc8f57c31d8336db0ccb2ce8eb9ebf52228a47c1Ted Kremenek             || (CastToTy->isPointerType() &&
83fc8f57c31d8336db0ccb2ce8eb9ebf52228a47c1Ted Kremenek                 CastToTy->getAsPointerType()->getPointeeType()->isVoidType()));
84fc8f57c31d8336db0ccb2ce8eb9ebf52228a47c1Ted Kremenek      break;
85fc8f57c31d8336db0ccb2ce8eb9ebf52228a47c1Ted Kremenek    }
86fc8f57c31d8336db0ccb2ce8eb9ebf52228a47c1Ted Kremenek
87fc8f57c31d8336db0ccb2ce8eb9ebf52228a47c1Ted Kremenek    case MemRegion::StringRegionKind:
88fc8f57c31d8336db0ccb2ce8eb9ebf52228a47c1Ted Kremenek      // Handle casts of string literals.
89fc8f57c31d8336db0ccb2ce8eb9ebf52228a47c1Ted Kremenek      return MakeElementRegion(state, R, PointeeTy, CastToTy);
90fc8f57c31d8336db0ccb2ce8eb9ebf52228a47c1Ted Kremenek
91fc8f57c31d8336db0ccb2ce8eb9ebf52228a47c1Ted Kremenek    case MemRegion::ObjCObjectRegionKind:
92fc8f57c31d8336db0ccb2ce8eb9ebf52228a47c1Ted Kremenek    case MemRegion::SymbolicRegionKind:
93fc8f57c31d8336db0ccb2ce8eb9ebf52228a47c1Ted Kremenek      // FIXME: Need to handle arbitrary downcasts.
94fc8f57c31d8336db0ccb2ce8eb9ebf52228a47c1Ted Kremenek    case MemRegion::AllocaRegionKind: {
95fc8f57c31d8336db0ccb2ce8eb9ebf52228a47c1Ted Kremenek      state = setCastType(state, R, CastToTy);
96fc8f57c31d8336db0ccb2ce8eb9ebf52228a47c1Ted Kremenek      break;
97fc8f57c31d8336db0ccb2ce8eb9ebf52228a47c1Ted Kremenek    }
98fc8f57c31d8336db0ccb2ce8eb9ebf52228a47c1Ted Kremenek
99fc8f57c31d8336db0ccb2ce8eb9ebf52228a47c1Ted Kremenek    case MemRegion::CompoundLiteralRegionKind:
100fc8f57c31d8336db0ccb2ce8eb9ebf52228a47c1Ted Kremenek    case MemRegion::ElementRegionKind:
101fc8f57c31d8336db0ccb2ce8eb9ebf52228a47c1Ted Kremenek    case MemRegion::FieldRegionKind:
102fc8f57c31d8336db0ccb2ce8eb9ebf52228a47c1Ted Kremenek    case MemRegion::ObjCIvarRegionKind:
103fc8f57c31d8336db0ccb2ce8eb9ebf52228a47c1Ted Kremenek    case MemRegion::VarRegionKind: {
104db5f266be075aba0f4ca1690e358245a726c9c61Ted Kremenek      // VarRegion, ElementRegion, and FieldRegion has an inherent type.
105db5f266be075aba0f4ca1690e358245a726c9c61Ted Kremenek      // Normally they should not be cast. We only layer an ElementRegion when
106db5f266be075aba0f4ca1690e358245a726c9c61Ted Kremenek      // the cast-to pointee type is of smaller size. In other cases, we return
107db5f266be075aba0f4ca1690e358245a726c9c61Ted Kremenek      // the original VarRegion.
108fc8f57c31d8336db0ccb2ce8eb9ebf52228a47c1Ted Kremenek
109169077dde4d91270a7495793f1e00b22aa0bc7caTed Kremenek      // If the pointee or object type is incomplete, do compute their sizes,
110169077dde4d91270a7495793f1e00b22aa0bc7caTed Kremenek      // and return the original region.
111fc8f57c31d8336db0ccb2ce8eb9ebf52228a47c1Ted Kremenek      QualType ObjTy = cast<TypedRegion>(R)->getValueType(Ctx);
112169077dde4d91270a7495793f1e00b22aa0bc7caTed Kremenek
113169077dde4d91270a7495793f1e00b22aa0bc7caTed Kremenek      if (!IsCompleteType(Ctx, PointeeTy) || !IsCompleteType(Ctx, ObjTy)) {
114169077dde4d91270a7495793f1e00b22aa0bc7caTed Kremenek        state = setCastType(state, R, ToTy);
115169077dde4d91270a7495793f1e00b22aa0bc7caTed Kremenek        break;
116169077dde4d91270a7495793f1e00b22aa0bc7caTed Kremenek      }
117169077dde4d91270a7495793f1e00b22aa0bc7caTed Kremenek
118fc8f57c31d8336db0ccb2ce8eb9ebf52228a47c1Ted Kremenek      uint64_t PointeeTySize = Ctx.getTypeSize(PointeeTy);
119fc8f57c31d8336db0ccb2ce8eb9ebf52228a47c1Ted Kremenek      uint64_t ObjTySize = Ctx.getTypeSize(ObjTy);
120fc8f57c31d8336db0ccb2ce8eb9ebf52228a47c1Ted Kremenek
121fc8f57c31d8336db0ccb2ce8eb9ebf52228a47c1Ted Kremenek      if ((PointeeTySize > 0 && PointeeTySize < ObjTySize) ||
122fc8f57c31d8336db0ccb2ce8eb9ebf52228a47c1Ted Kremenek          (ObjTy->isAggregateType() && PointeeTy->isScalarType()) ||
123fc8f57c31d8336db0ccb2ce8eb9ebf52228a47c1Ted Kremenek          ObjTySize == 0 /* R has 'void*' type. */)
124fc8f57c31d8336db0ccb2ce8eb9ebf52228a47c1Ted Kremenek        return MakeElementRegion(state, R, PointeeTy, ToTy);
125fc8f57c31d8336db0ccb2ce8eb9ebf52228a47c1Ted Kremenek
12648ce7deb86ffb1e028ac9a8e7cddffc32843c26cTed Kremenek      state = setCastType(state, R, ToTy);
127fc8f57c31d8336db0ccb2ce8eb9ebf52228a47c1Ted Kremenek      break;
12848ce7deb86ffb1e028ac9a8e7cddffc32843c26cTed Kremenek    }
12948ce7deb86ffb1e028ac9a8e7cddffc32843c26cTed Kremenek  }
13048ce7deb86ffb1e028ac9a8e7cddffc32843c26cTed Kremenek
131fc8f57c31d8336db0ccb2ce8eb9ebf52228a47c1Ted Kremenek  return CastResult(state, R);
13248ce7deb86ffb1e028ac9a8e7cddffc32843c26cTed Kremenek}
13348ce7deb86ffb1e028ac9a8e7cddffc32843c26cTed Kremenek
13448ce7deb86ffb1e028ac9a8e7cddffc32843c26cTed Kremenek
13548ce7deb86ffb1e028ac9a8e7cddffc32843c26cTed KremenekStoreManager::CastResult
13648ce7deb86ffb1e028ac9a8e7cddffc32843c26cTed KremenekStoreManager::OldCastRegion(const GRState* state, const MemRegion* R,
137fd6b4f3de2ef7bb7b9b33dd252078c53ada43977Ted Kremenek                         QualType CastToTy) {
138c62abc1012feb0b15eff091b02c176649766a347Ted Kremenek
13930d1b99e4429bc27a7801bab7be6c2c04e77a648Ted Kremenek  ASTContext& Ctx = StateMgr.getContext();
14030d1b99e4429bc27a7801bab7be6c2c04e77a648Ted Kremenek
14130d1b99e4429bc27a7801bab7be6c2c04e77a648Ted Kremenek  // We need to know the real type of CastToTy.
14230d1b99e4429bc27a7801bab7be6c2c04e77a648Ted Kremenek  QualType ToTy = Ctx.getCanonicalType(CastToTy);
14330d1b99e4429bc27a7801bab7be6c2c04e77a648Ted Kremenek
144c62abc1012feb0b15eff091b02c176649766a347Ted Kremenek  // Return the same region if the region types are compatible.
145c62abc1012feb0b15eff091b02c176649766a347Ted Kremenek  if (const TypedRegion* TR = dyn_cast<TypedRegion>(R)) {
146ff6978263439e21d795b0602fabcb38488ef8441Zhongxing Xu    QualType Ta = Ctx.getCanonicalType(TR->getLocationType(Ctx));
14730d1b99e4429bc27a7801bab7be6c2c04e77a648Ted Kremenek
14830d1b99e4429bc27a7801bab7be6c2c04e77a648Ted Kremenek    if (Ta == ToTy)
149c62abc1012feb0b15eff091b02c176649766a347Ted Kremenek      return CastResult(state, R);
150c62abc1012feb0b15eff091b02c176649766a347Ted Kremenek  }
151c62abc1012feb0b15eff091b02c176649766a347Ted Kremenek
152fd6b4f3de2ef7bb7b9b33dd252078c53ada43977Ted Kremenek  if (const PointerType* PTy = dyn_cast<PointerType>(ToTy.getTypePtr())) {
153fd6b4f3de2ef7bb7b9b33dd252078c53ada43977Ted Kremenek    // Check if we are casting to 'void*'.
154fd6b4f3de2ef7bb7b9b33dd252078c53ada43977Ted Kremenek    // FIXME: Handle arbitrary upcasts.
155fd6b4f3de2ef7bb7b9b33dd252078c53ada43977Ted Kremenek    QualType Pointee = PTy->getPointeeType();
156fd6b4f3de2ef7bb7b9b33dd252078c53ada43977Ted Kremenek    if (Pointee->isVoidType()) {
157ca4e1b765abd796b07dc6a78a9cb1711f467a8ccTed Kremenek      while (true) {
1584253051c16d0c2a5ae13af3d22383b61071ecb4cTed Kremenek        if (const TypedViewRegion *TR = dyn_cast<TypedViewRegion>(R)) {
1594253051c16d0c2a5ae13af3d22383b61071ecb4cTed Kremenek          // Casts to void* removes TypedViewRegion. This happens when:
1604253051c16d0c2a5ae13af3d22383b61071ecb4cTed Kremenek          //
1614253051c16d0c2a5ae13af3d22383b61071ecb4cTed Kremenek          // void foo(void*);
1624253051c16d0c2a5ae13af3d22383b61071ecb4cTed Kremenek          // ...
1634253051c16d0c2a5ae13af3d22383b61071ecb4cTed Kremenek          // void bar() {
1644253051c16d0c2a5ae13af3d22383b61071ecb4cTed Kremenek          //   int x;
1654253051c16d0c2a5ae13af3d22383b61071ecb4cTed Kremenek          //   foo(&x);
1664253051c16d0c2a5ae13af3d22383b61071ecb4cTed Kremenek          // }
1674253051c16d0c2a5ae13af3d22383b61071ecb4cTed Kremenek          //
1684253051c16d0c2a5ae13af3d22383b61071ecb4cTed Kremenek          R = TR->removeViews();
1694253051c16d0c2a5ae13af3d22383b61071ecb4cTed Kremenek          continue;
1704253051c16d0c2a5ae13af3d22383b61071ecb4cTed Kremenek        }
1714253051c16d0c2a5ae13af3d22383b61071ecb4cTed Kremenek        else if (const ElementRegion *ER = dyn_cast<ElementRegion>(R)) {
1724253051c16d0c2a5ae13af3d22383b61071ecb4cTed Kremenek          // Casts to void* also removes ElementRegions. This happens when:
1734253051c16d0c2a5ae13af3d22383b61071ecb4cTed Kremenek          //
1744253051c16d0c2a5ae13af3d22383b61071ecb4cTed Kremenek          // void foo(void*);
1754253051c16d0c2a5ae13af3d22383b61071ecb4cTed Kremenek          // ...
1764253051c16d0c2a5ae13af3d22383b61071ecb4cTed Kremenek          // void bar() {
1774253051c16d0c2a5ae13af3d22383b61071ecb4cTed Kremenek          //   int x;
1784253051c16d0c2a5ae13af3d22383b61071ecb4cTed Kremenek          //   foo((char*)&x);
1794253051c16d0c2a5ae13af3d22383b61071ecb4cTed Kremenek          // }
1804253051c16d0c2a5ae13af3d22383b61071ecb4cTed Kremenek          //
1814253051c16d0c2a5ae13af3d22383b61071ecb4cTed Kremenek          R = ER->getSuperRegion();
1824253051c16d0c2a5ae13af3d22383b61071ecb4cTed Kremenek          continue;
1834253051c16d0c2a5ae13af3d22383b61071ecb4cTed Kremenek        }
184145918ca119904b6abe8b41aae0cbbf9a7247905Ted Kremenek
185145918ca119904b6abe8b41aae0cbbf9a7247905Ted Kremenek        break;
1864253051c16d0c2a5ae13af3d22383b61071ecb4cTed Kremenek      }
18730d1b99e4429bc27a7801bab7be6c2c04e77a648Ted Kremenek
18830d1b99e4429bc27a7801bab7be6c2c04e77a648Ted Kremenek      return CastResult(state, R);
18930d1b99e4429bc27a7801bab7be6c2c04e77a648Ted Kremenek    }
190fd6b4f3de2ef7bb7b9b33dd252078c53ada43977Ted Kremenek    else if (Pointee->isIntegerType()) {
191fd6b4f3de2ef7bb7b9b33dd252078c53ada43977Ted Kremenek      // FIXME: At some point, it stands to reason that this 'dyn_cast' should
192fd6b4f3de2ef7bb7b9b33dd252078c53ada43977Ted Kremenek      //  become a 'cast' and that 'R' will always be a TypedRegion.
193fd6b4f3de2ef7bb7b9b33dd252078c53ada43977Ted Kremenek      if (const TypedRegion *TR = dyn_cast<TypedRegion>(R)) {
194fd6b4f3de2ef7bb7b9b33dd252078c53ada43977Ted Kremenek        // Check if we are casting to a region with an integer type.  We now
195fd6b4f3de2ef7bb7b9b33dd252078c53ada43977Ted Kremenek        // the types aren't the same, so we construct an ElementRegion.
196cd9392ff7336a2cd5547305ba83a65e63b4f6ff8Ted Kremenek        SVal Idx = ValMgr.makeZeroArrayIndex();
19720bd746306ecdc61125800d53ff7e07321704064Ted Kremenek
19820bd746306ecdc61125800d53ff7e07321704064Ted Kremenek        // If the super region is an element region, strip it away.
19920bd746306ecdc61125800d53ff7e07321704064Ted Kremenek        // FIXME: Is this the right thing to do in all cases?
20019cfa2bde3f5845c22eef2d1b9ee4a0ac9e33f7bTed Kremenek        const MemRegion *Base = isa<ElementRegion>(TR) ? TR->getSuperRegion()
20119cfa2bde3f5845c22eef2d1b9ee4a0ac9e33f7bTed Kremenek                                                       : TR;
202143b2fc6fd3945c250b333383749010c2c8e3a4cZhongxing Xu        ElementRegion* ER = MRMgr.getElementRegion(Pointee, Idx, Base,
20319cfa2bde3f5845c22eef2d1b9ee4a0ac9e33f7bTed Kremenek                                                   StateMgr.getContext());
204fd6b4f3de2ef7bb7b9b33dd252078c53ada43977Ted Kremenek        return CastResult(state, ER);
205fd6b4f3de2ef7bb7b9b33dd252078c53ada43977Ted Kremenek      }
206fd6b4f3de2ef7bb7b9b33dd252078c53ada43977Ted Kremenek    }
207fd6b4f3de2ef7bb7b9b33dd252078c53ada43977Ted Kremenek  }
20830d1b99e4429bc27a7801bab7be6c2c04e77a648Ted Kremenek
209a8607d13c8df25a8c10d46db016d26f9e327418dTed Kremenek  // FIXME: Need to handle arbitrary downcasts.
210a8607d13c8df25a8c10d46db016d26f9e327418dTed Kremenek  // FIXME: Handle the case where a TypedViewRegion (layering a SymbolicRegion
211a8607d13c8df25a8c10d46db016d26f9e327418dTed Kremenek  //         or an AllocaRegion is cast to another view, thus causing the memory
212a8607d13c8df25a8c10d46db016d26f9e327418dTed Kremenek  //         to be re-used for a different purpose.
213a8607d13c8df25a8c10d46db016d26f9e327418dTed Kremenek  if (isa<SymbolicRegion>(R) || isa<AllocaRegion>(R)) {
214a8607d13c8df25a8c10d46db016d26f9e327418dTed Kremenek    const MemRegion* ViewR = MRMgr.getTypedViewRegion(CastToTy, R);
215a8607d13c8df25a8c10d46db016d26f9e327418dTed Kremenek    return CastResult(AddRegionView(state, ViewR, R), ViewR);
216a8607d13c8df25a8c10d46db016d26f9e327418dTed Kremenek  }
217a8607d13c8df25a8c10d46db016d26f9e327418dTed Kremenek
218a8607d13c8df25a8c10d46db016d26f9e327418dTed Kremenek  return CastResult(state, R);
219c62abc1012feb0b15eff091b02c176649766a347Ted Kremenek}
22043e2aafea1cdeca3a3fc849b41a92cc18e001ac0Zhongxing Xu
22143e2aafea1cdeca3a3fc849b41a92cc18e001ac0Zhongxing Xuconst GRState *StoreManager::InvalidateRegion(const GRState *state,
222313b6dab9efcce465b68da0fed7bf422b6e5c375Zhongxing Xu                                              const MemRegion *R,
22343e2aafea1cdeca3a3fc849b41a92cc18e001ac0Zhongxing Xu                                              const Expr *E, unsigned Count) {
224313b6dab9efcce465b68da0fed7bf422b6e5c375Zhongxing Xu  ASTContext& Ctx = StateMgr.getContext();
225313b6dab9efcce465b68da0fed7bf422b6e5c375Zhongxing Xu
22643e2aafea1cdeca3a3fc849b41a92cc18e001ac0Zhongxing Xu  if (!R->isBoundable())
22743e2aafea1cdeca3a3fc849b41a92cc18e001ac0Zhongxing Xu    return state;
22843e2aafea1cdeca3a3fc849b41a92cc18e001ac0Zhongxing Xu
229313b6dab9efcce465b68da0fed7bf422b6e5c375Zhongxing Xu  if (isa<AllocaRegion>(R) || isa<SymbolicRegion>(R)) {
230313b6dab9efcce465b68da0fed7bf422b6e5c375Zhongxing Xu    // Invalidate the alloca region by setting its default value to
231313b6dab9efcce465b68da0fed7bf422b6e5c375Zhongxing Xu    // conjured symbol. The type of the symbol is irrelavant.
232313b6dab9efcce465b68da0fed7bf422b6e5c375Zhongxing Xu    SVal V = ValMgr.getConjuredSymbolVal(E, Ctx.IntTy, Count);
233313b6dab9efcce465b68da0fed7bf422b6e5c375Zhongxing Xu    state = setDefaultValue(state, R, V);
234313b6dab9efcce465b68da0fed7bf422b6e5c375Zhongxing Xu    return state;
235313b6dab9efcce465b68da0fed7bf422b6e5c375Zhongxing Xu  }
236313b6dab9efcce465b68da0fed7bf422b6e5c375Zhongxing Xu
237313b6dab9efcce465b68da0fed7bf422b6e5c375Zhongxing Xu  const TypedRegion *TR = cast<TypedRegion>(R);
238313b6dab9efcce465b68da0fed7bf422b6e5c375Zhongxing Xu
239313b6dab9efcce465b68da0fed7bf422b6e5c375Zhongxing Xu  QualType T = TR->getValueType(Ctx);
24043e2aafea1cdeca3a3fc849b41a92cc18e001ac0Zhongxing Xu
24143e2aafea1cdeca3a3fc849b41a92cc18e001ac0Zhongxing Xu  if (Loc::IsLocType(T) || (T->isIntegerType() && T->isScalarType())) {
24243e2aafea1cdeca3a3fc849b41a92cc18e001ac0Zhongxing Xu    SVal V = ValMgr.getConjuredSymbolVal(E, T, Count);
243313b6dab9efcce465b68da0fed7bf422b6e5c375Zhongxing Xu    return Bind(state, ValMgr.makeLoc(TR), V);
24443e2aafea1cdeca3a3fc849b41a92cc18e001ac0Zhongxing Xu  }
24543e2aafea1cdeca3a3fc849b41a92cc18e001ac0Zhongxing Xu  else if (const RecordType *RT = T->getAsStructureType()) {
24643e2aafea1cdeca3a3fc849b41a92cc18e001ac0Zhongxing Xu    // FIXME: handle structs with default region value.
24743e2aafea1cdeca3a3fc849b41a92cc18e001ac0Zhongxing Xu    const RecordDecl *RD = RT->getDecl()->getDefinition(Ctx);
24843e2aafea1cdeca3a3fc849b41a92cc18e001ac0Zhongxing Xu
24943e2aafea1cdeca3a3fc849b41a92cc18e001ac0Zhongxing Xu    // No record definition.  There is nothing we can do.
25043e2aafea1cdeca3a3fc849b41a92cc18e001ac0Zhongxing Xu    if (!RD)
25143e2aafea1cdeca3a3fc849b41a92cc18e001ac0Zhongxing Xu      return state;
25243e2aafea1cdeca3a3fc849b41a92cc18e001ac0Zhongxing Xu
25343e2aafea1cdeca3a3fc849b41a92cc18e001ac0Zhongxing Xu    // Iterate through the fields and construct new symbols.
25443e2aafea1cdeca3a3fc849b41a92cc18e001ac0Zhongxing Xu    for (RecordDecl::field_iterator FI=RD->field_begin(),
25543e2aafea1cdeca3a3fc849b41a92cc18e001ac0Zhongxing Xu           FE=RD->field_end(); FI!=FE; ++FI) {
25643e2aafea1cdeca3a3fc849b41a92cc18e001ac0Zhongxing Xu
25743e2aafea1cdeca3a3fc849b41a92cc18e001ac0Zhongxing Xu      // For now just handle scalar fields.
25843e2aafea1cdeca3a3fc849b41a92cc18e001ac0Zhongxing Xu      FieldDecl *FD = *FI;
25943e2aafea1cdeca3a3fc849b41a92cc18e001ac0Zhongxing Xu      QualType FT = FD->getType();
260313b6dab9efcce465b68da0fed7bf422b6e5c375Zhongxing Xu      const FieldRegion* FR = MRMgr.getFieldRegion(FD, TR);
26143e2aafea1cdeca3a3fc849b41a92cc18e001ac0Zhongxing Xu
26243e2aafea1cdeca3a3fc849b41a92cc18e001ac0Zhongxing Xu      if (Loc::IsLocType(FT) ||
26343e2aafea1cdeca3a3fc849b41a92cc18e001ac0Zhongxing Xu          (FT->isIntegerType() && FT->isScalarType())) {
26443e2aafea1cdeca3a3fc849b41a92cc18e001ac0Zhongxing Xu        SVal V = ValMgr.getConjuredSymbolVal(E, FT, Count);
26543e2aafea1cdeca3a3fc849b41a92cc18e001ac0Zhongxing Xu        state = state->bindLoc(ValMgr.makeLoc(FR), V);
26643e2aafea1cdeca3a3fc849b41a92cc18e001ac0Zhongxing Xu      }
26743e2aafea1cdeca3a3fc849b41a92cc18e001ac0Zhongxing Xu      else if (FT->isStructureType()) {
26843e2aafea1cdeca3a3fc849b41a92cc18e001ac0Zhongxing Xu        // set the default value of the struct field to conjured
26943e2aafea1cdeca3a3fc849b41a92cc18e001ac0Zhongxing Xu        // symbol. Note that the type of the symbol is irrelavant.
27043e2aafea1cdeca3a3fc849b41a92cc18e001ac0Zhongxing Xu        // We cannot use the type of the struct otherwise ValMgr won't
27143e2aafea1cdeca3a3fc849b41a92cc18e001ac0Zhongxing Xu        // give us the conjured symbol.
27243e2aafea1cdeca3a3fc849b41a92cc18e001ac0Zhongxing Xu        SVal V = ValMgr.getConjuredSymbolVal(E, Ctx.IntTy, Count);
27343e2aafea1cdeca3a3fc849b41a92cc18e001ac0Zhongxing Xu        state = setDefaultValue(state, FR, V);
27443e2aafea1cdeca3a3fc849b41a92cc18e001ac0Zhongxing Xu      }
27543e2aafea1cdeca3a3fc849b41a92cc18e001ac0Zhongxing Xu    }
27643e2aafea1cdeca3a3fc849b41a92cc18e001ac0Zhongxing Xu  } else if (const ArrayType *AT = Ctx.getAsArrayType(T)) {
27743e2aafea1cdeca3a3fc849b41a92cc18e001ac0Zhongxing Xu    // Set the default value of the array to conjured symbol.
27843e2aafea1cdeca3a3fc849b41a92cc18e001ac0Zhongxing Xu    SVal V = ValMgr.getConjuredSymbolVal(E, AT->getElementType(),
27943e2aafea1cdeca3a3fc849b41a92cc18e001ac0Zhongxing Xu                                         Count);
280313b6dab9efcce465b68da0fed7bf422b6e5c375Zhongxing Xu    state = setDefaultValue(state, TR, V);
28143e2aafea1cdeca3a3fc849b41a92cc18e001ac0Zhongxing Xu  } else {
28243e2aafea1cdeca3a3fc849b41a92cc18e001ac0Zhongxing Xu    // Just blast away other values.
283313b6dab9efcce465b68da0fed7bf422b6e5c375Zhongxing Xu    state = Bind(state, ValMgr.makeLoc(TR), UnknownVal());
28443e2aafea1cdeca3a3fc849b41a92cc18e001ac0Zhongxing Xu  }
28543e2aafea1cdeca3a3fc849b41a92cc18e001ac0Zhongxing Xu
28643e2aafea1cdeca3a3fc849b41a92cc18e001ac0Zhongxing Xu  return state;
28743e2aafea1cdeca3a3fc849b41a92cc18e001ac0Zhongxing Xu}
288