Store.cpp revision bf0fe6c5b7bd7bc67b6b3ef0acb22bf4811f2a1b
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//== Store.cpp - Interface for maps from Locations to Values ----*- C++ -*--==// 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The LLVM Compiler Infrastructure 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This file is distributed under the University of Illinois Open Source 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// License. See LICENSE.TXT for details. 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//===----------------------------------------------------------------------===// 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 10a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// This file defined the types Store and StoreManager. 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//===----------------------------------------------------------------------===// 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "clang/Analysis/PathSensitive/Store.h" 155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "clang/Analysis/PathSensitive/GRState.h" 167d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using namespace clang; 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)StoreManager::StoreManager(GRStateManager &stateMgr) 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : ValMgr(stateMgr.getValueManager()), StateMgr(stateMgr), 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MRMgr(ValMgr.getRegionManager()) {} 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const MemRegion *StoreManager::MakeElementRegion(const MemRegion *Base, 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) QualType EleTy, uint64_t index) { 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SVal idx = ValMgr.makeArrayIndex(index); 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return MRMgr.getElementRegion(EleTy, idx, Base, ValMgr.getContext()); 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// FIXME: Merge with the implementation of the same method in MemRegion.cpp 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static bool IsCompleteType(ASTContext &Ctx, QualType Ty) { 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (const RecordType *RT = Ty->getAs<RecordType>()) { 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const RecordDecl *D = RT->getDecl(); 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!D->getDefinition(Ctx)) 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const MemRegion *StoreManager::CastRegion(const MemRegion *R, QualType CastToTy) { 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASTContext& Ctx = StateMgr.getContext(); 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Handle casts to Objective-C objects. 457d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if (CastToTy->isObjCObjectPointerType()) 467d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return R->StripCasts(); 477d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 487d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if (CastToTy->isBlockPointerType()) { 497d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // FIXME: We may need different solutions, depending on the symbol 50f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // involved. Blocks can be casted to/from 'id', as they can be treated 517d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // as Objective-C objects. This could possibly be handled by enhancing 52f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // our reasoning of downcasts of symbolic objects. 53f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (isa<CodeTextRegion>(R) || isa<SymbolicRegion>(R)) 547d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return R; 557d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 567d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // We don't know what to make of it. Return a NULL region, which 577d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // will be interpretted as UnknownVal. 587d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return NULL; 597d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) } 607d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 61f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Now assume we are casting from pointer to pointer. Other cases should 62f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // already be handled. 63f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) QualType PointeeTy = CastToTy->getAs<PointerType>()->getPointeeType(); 64f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) QualType CanonPointeeTy = Ctx.getCanonicalType(PointeeTy); 65f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 66f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Handle casts to void*. We just pass the region through. 67f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (CanonPointeeTy.getLocalUnqualifiedType() == Ctx.VoidTy) 68f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return R; 69f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 707d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // Handle casts from compatible types. 71f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (R->isBoundable()) 72f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (const TypedRegion *TR = dyn_cast<TypedRegion>(R)) { 73f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) QualType ObjTy = Ctx.getCanonicalType(TR->getValueType(Ctx)); 74f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (CanonPointeeTy == ObjTy) 75f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return R; 76f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 77f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 78f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Process region cast according to the kind of the region being cast. 79f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) switch (R->getKind()) { 80f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) case MemRegion::BEG_TYPED_REGIONS: 81f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) case MemRegion::MemSpaceRegionKind: 827d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) case MemRegion::BEG_DECL_REGIONS: 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case MemRegion::END_DECL_REGIONS: 84f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) case MemRegion::END_TYPED_REGIONS: { 85f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) assert(0 && "Invalid region cast"); 86f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) break; 87f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case MemRegion::FunctionTextRegionKind: 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case MemRegion::BlockTextRegionKind: 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case MemRegion::BlockDataRegionKind: { 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // CodeTextRegion should be cast to only a function or block pointer type, 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // although they can in practice be casted to anything, e.g, void*, char*, 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // etc. 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Just return the region. 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return R; 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 984e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case MemRegion::StringRegionKind: 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case MemRegion::ObjCObjectRegionKind: 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // FIXME: Need to handle arbitrary downcasts. 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case MemRegion::SymbolicRegionKind: 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case MemRegion::AllocaRegionKind: 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case MemRegion::CompoundLiteralRegionKind: 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case MemRegion::FieldRegionKind: 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case MemRegion::ObjCIvarRegionKind: 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case MemRegion::VarRegionKind: 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return MakeElementRegion(R, PointeeTy); 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case MemRegion::ElementRegionKind: { 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If we are casting from an ElementRegion to another type, the 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // algorithm is as follows: 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // (1) Compute the "raw offset" of the ElementRegion from the 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // base region. This is done by calling 'getAsRawOffset()'. 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // (2a) If we get a 'RegionRawOffset' after calling 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 'getAsRawOffset()', determine if the absolute offset 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // can be exactly divided into chunks of the size of the 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // casted-pointee type. If so, create a new ElementRegion with 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the pointee-cast type as the new ElementType and the index 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // being the offset divded by the chunk size. If not, create 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // a new ElementRegion at offset 0 off the raw offset region. 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // (2b) If we don't a get a 'RegionRawOffset' after calling 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 'getAsRawOffset()', it means that we are at offset 0. 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // FIXME: Handle symbolic raw offsets. 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ElementRegion *elementR = cast<ElementRegion>(R); 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const RegionRawOffset &rawOff = elementR->getAsRawOffset(); 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const MemRegion *baseR = rawOff.getRegion(); 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If we cannot compute a raw offset, throw up our hands and return 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // a NULL MemRegion*. 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!baseR) 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int64_t off = rawOff.getByteOffset(); 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (off == 0) { 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Edge case: we are at 0 bytes off the beginning of baseR. We 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // check to see if type we are casting to is the same as the base 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // region. If so, just return the base region. 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (const TypedRegion *TR = dyn_cast<TypedRegion>(baseR)) { 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) QualType ObjTy = Ctx.getCanonicalType(TR->getValueType(Ctx)); 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) QualType CanonPointeeTy = Ctx.getCanonicalType(PointeeTy); 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (CanonPointeeTy == ObjTy) 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return baseR; 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Otherwise, create a new ElementRegion at offset 0. 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return MakeElementRegion(baseR, PointeeTy); 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We have a non-zero offset from the base region. We want to determine 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // if the offset can be evenly divided by sizeof(PointeeTy). If so, 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // we create an ElementRegion whose index is that value. Otherwise, we 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // create two ElementRegions, one that reflects a raw offset and the other 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // that reflects the cast. 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Compute the index for the new ElementRegion. 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int64_t newIndex = 0; 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const MemRegion *newSuperR = 0; 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We can only compute sizeof(PointeeTy) if it is a complete type. 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (IsCompleteType(Ctx, PointeeTy)) { 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Compute the size in **bytes**. 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int64_t pointeeTySize = (int64_t) (Ctx.getTypeSize(PointeeTy) / 8); 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Is the offset a multiple of the size? If so, we can layer the 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // ElementRegion (with elementType == PointeeTy) directly on top of 173a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // the base region. 1745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (off % pointeeTySize == 0) { 1755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) newIndex = off / pointeeTySize; 1765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) newSuperR = baseR; 1775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 1785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 179a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 1805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!newSuperR) { 1815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Create an intermediate ElementRegion to represent the raw byte. 1825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // This will be the super region of the final ElementRegion. 1835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) newSuperR = MakeElementRegion(baseR, Ctx.CharTy, off); 1845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 185a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 186a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return MakeElementRegion(newSuperR, PointeeTy, newIndex); 187a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 1885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 1891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci assert(0 && "unreachable"); 1911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return 0; 1921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 1931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci/// CastRetrievedVal - Used by subclasses of StoreManager to implement 1961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci/// implicit casts that arise from loads from regions that are reinterpreted 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// as another region. 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SVal StoreManager::CastRetrievedVal(SVal V, const TypedRegion *R, 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) QualType castTy) { 200 if (castTy.isNull()) 201 return V; 202 203 assert(ValMgr.getContext().hasSameUnqualifiedType(castTy, 204 R->getValueType(ValMgr.getContext()))); 205 return V; 206} 207 208