1//===- SValBuilder.cpp - Basic class for all SValBuilder implementations --===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9//  This file defines SValBuilder, the base class for all (complete) SValBuilder
10//  implementations.
11//
12//===----------------------------------------------------------------------===//
13
14#include "clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h"
15#include "clang/AST/ASTContext.h"
16#include "clang/AST/Decl.h"
17#include "clang/AST/DeclCXX.h"
18#include "clang/AST/ExprCXX.h"
19#include "clang/AST/ExprObjC.h"
20#include "clang/AST/Stmt.h"
21#include "clang/AST/Type.h"
22#include "clang/Basic/LLVM.h"
23#include "clang/Analysis/AnalysisDeclContext.h"
24#include "clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h"
25#include "clang/StaticAnalyzer/Core/PathSensitive/APSIntType.h"
26#include "clang/StaticAnalyzer/Core/PathSensitive/BasicValueFactory.h"
27#include "clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h"
28#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h"
29#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState_Fwd.h"
30#include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h"
31#include "clang/StaticAnalyzer/Core/PathSensitive/Store.h"
32#include "clang/StaticAnalyzer/Core/PathSensitive/SubEngine.h"
33#include "clang/StaticAnalyzer/Core/PathSensitive/SymExpr.h"
34#include "clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h"
35#include "llvm/ADT/APSInt.h"
36#include "llvm/ADT/None.h"
37#include "llvm/ADT/Optional.h"
38#include "llvm/Support/Casting.h"
39#include "llvm/Support/Compiler.h"
40#include <cassert>
41#include <tuple>
42
43using namespace clang;
44using namespace ento;
45
46//===----------------------------------------------------------------------===//
47// Basic SVal creation.
48//===----------------------------------------------------------------------===//
49
50void SValBuilder::anchor() {}
51
52DefinedOrUnknownSVal SValBuilder::makeZeroVal(QualType type) {
53  if (Loc::isLocType(type))
54    return makeNull();
55
56  if (type->isIntegralOrEnumerationType())
57    return makeIntVal(0, type);
58
59  if (type->isArrayType() || type->isRecordType() || type->isVectorType() ||
60      type->isAnyComplexType())
61    return makeCompoundVal(type, BasicVals.getEmptySValList());
62
63  // FIXME: Handle floats.
64  return UnknownVal();
65}
66
67NonLoc SValBuilder::makeNonLoc(const SymExpr *lhs, BinaryOperator::Opcode op,
68                                const llvm::APSInt& rhs, QualType type) {
69  // The Environment ensures we always get a persistent APSInt in
70  // BasicValueFactory, so we don't need to get the APSInt from
71  // BasicValueFactory again.
72  assert(lhs);
73  assert(!Loc::isLocType(type));
74  return nonloc::SymbolVal(SymMgr.getSymIntExpr(lhs, op, rhs, type));
75}
76
77NonLoc SValBuilder::makeNonLoc(const llvm::APSInt& lhs,
78                               BinaryOperator::Opcode op, const SymExpr *rhs,
79                               QualType type) {
80  assert(rhs);
81  assert(!Loc::isLocType(type));
82  return nonloc::SymbolVal(SymMgr.getIntSymExpr(lhs, op, rhs, type));
83}
84
85NonLoc SValBuilder::makeNonLoc(const SymExpr *lhs, BinaryOperator::Opcode op,
86                               const SymExpr *rhs, QualType type) {
87  assert(lhs && rhs);
88  assert(!Loc::isLocType(type));
89  return nonloc::SymbolVal(SymMgr.getSymSymExpr(lhs, op, rhs, type));
90}
91
92NonLoc SValBuilder::makeNonLoc(const SymExpr *operand,
93                               QualType fromTy, QualType toTy) {
94  assert(operand);
95  assert(!Loc::isLocType(toTy));
96  return nonloc::SymbolVal(SymMgr.getCastSymbol(operand, fromTy, toTy));
97}
98
99SVal SValBuilder::convertToArrayIndex(SVal val) {
100  if (val.isUnknownOrUndef())
101    return val;
102
103  // Common case: we have an appropriately sized integer.
104  if (Optional<nonloc::ConcreteInt> CI = val.getAs<nonloc::ConcreteInt>()) {
105    const llvm::APSInt& I = CI->getValue();
106    if (I.getBitWidth() == ArrayIndexWidth && I.isSigned())
107      return val;
108  }
109
110  return evalCastFromNonLoc(val.castAs<NonLoc>(), ArrayIndexTy);
111}
112
113nonloc::ConcreteInt SValBuilder::makeBoolVal(const CXXBoolLiteralExpr *boolean){
114  return makeTruthVal(boolean->getValue());
115}
116
117DefinedOrUnknownSVal
118SValBuilder::getRegionValueSymbolVal(const TypedValueRegion *region) {
119  QualType T = region->getValueType();
120
121  if (T->isNullPtrType())
122    return makeZeroVal(T);
123
124  if (!SymbolManager::canSymbolicate(T))
125    return UnknownVal();
126
127  SymbolRef sym = SymMgr.getRegionValueSymbol(region);
128
129  if (Loc::isLocType(T))
130    return loc::MemRegionVal(MemMgr.getSymbolicRegion(sym));
131
132  return nonloc::SymbolVal(sym);
133}
134
135DefinedOrUnknownSVal SValBuilder::conjureSymbolVal(const void *SymbolTag,
136                                                   const Expr *Ex,
137                                                   const LocationContext *LCtx,
138                                                   unsigned Count) {
139  QualType T = Ex->getType();
140
141  if (T->isNullPtrType())
142    return makeZeroVal(T);
143
144  // Compute the type of the result. If the expression is not an R-value, the
145  // result should be a location.
146  QualType ExType = Ex->getType();
147  if (Ex->isGLValue())
148    T = LCtx->getAnalysisDeclContext()->getASTContext().getPointerType(ExType);
149
150  return conjureSymbolVal(SymbolTag, Ex, LCtx, T, Count);
151}
152
153DefinedOrUnknownSVal SValBuilder::conjureSymbolVal(const void *symbolTag,
154                                                   const Expr *expr,
155                                                   const LocationContext *LCtx,
156                                                   QualType type,
157                                                   unsigned count) {
158  if (type->isNullPtrType())
159    return makeZeroVal(type);
160
161  if (!SymbolManager::canSymbolicate(type))
162    return UnknownVal();
163
164  SymbolRef sym = SymMgr.conjureSymbol(expr, LCtx, type, count, symbolTag);
165
166  if (Loc::isLocType(type))
167    return loc::MemRegionVal(MemMgr.getSymbolicRegion(sym));
168
169  return nonloc::SymbolVal(sym);
170}
171
172DefinedOrUnknownSVal SValBuilder::conjureSymbolVal(const Stmt *stmt,
173                                                   const LocationContext *LCtx,
174                                                   QualType type,
175                                                   unsigned visitCount) {
176  if (type->isNullPtrType())
177    return makeZeroVal(type);
178
179  if (!SymbolManager::canSymbolicate(type))
180    return UnknownVal();
181
182  SymbolRef sym = SymMgr.conjureSymbol(stmt, LCtx, type, visitCount);
183
184  if (Loc::isLocType(type))
185    return loc::MemRegionVal(MemMgr.getSymbolicRegion(sym));
186
187  return nonloc::SymbolVal(sym);
188}
189
190DefinedOrUnknownSVal
191SValBuilder::getConjuredHeapSymbolVal(const Expr *E,
192                                      const LocationContext *LCtx,
193                                      unsigned VisitCount) {
194  QualType T = E->getType();
195  assert(Loc::isLocType(T));
196  assert(SymbolManager::canSymbolicate(T));
197  if (T->isNullPtrType())
198    return makeZeroVal(T);
199
200  SymbolRef sym = SymMgr.conjureSymbol(E, LCtx, T, VisitCount);
201  return loc::MemRegionVal(MemMgr.getSymbolicHeapRegion(sym));
202}
203
204DefinedSVal SValBuilder::getMetadataSymbolVal(const void *symbolTag,
205                                              const MemRegion *region,
206                                              const Expr *expr, QualType type,
207                                              const LocationContext *LCtx,
208                                              unsigned count) {
209  assert(SymbolManager::canSymbolicate(type) && "Invalid metadata symbol type");
210
211  SymbolRef sym =
212      SymMgr.getMetadataSymbol(region, expr, type, LCtx, count, symbolTag);
213
214  if (Loc::isLocType(type))
215    return loc::MemRegionVal(MemMgr.getSymbolicRegion(sym));
216
217  return nonloc::SymbolVal(sym);
218}
219
220DefinedOrUnknownSVal
221SValBuilder::getDerivedRegionValueSymbolVal(SymbolRef parentSymbol,
222                                             const TypedValueRegion *region) {
223  QualType T = region->getValueType();
224
225  if (T->isNullPtrType())
226    return makeZeroVal(T);
227
228  if (!SymbolManager::canSymbolicate(T))
229    return UnknownVal();
230
231  SymbolRef sym = SymMgr.getDerivedSymbol(parentSymbol, region);
232
233  if (Loc::isLocType(T))
234    return loc::MemRegionVal(MemMgr.getSymbolicRegion(sym));
235
236  return nonloc::SymbolVal(sym);
237}
238
239DefinedSVal SValBuilder::getMemberPointer(const DeclaratorDecl *DD) {
240  assert(!DD || isa<CXXMethodDecl>(DD) || isa<FieldDecl>(DD));
241
242  if (const auto *MD = dyn_cast_or_null<CXXMethodDecl>(DD)) {
243    // Sema treats pointers to static member functions as have function pointer
244    // type, so return a function pointer for the method.
245    // We don't need to play a similar trick for static member fields
246    // because these are represented as plain VarDecls and not FieldDecls
247    // in the AST.
248    if (MD->isStatic())
249      return getFunctionPointer(MD);
250  }
251
252  return nonloc::PointerToMember(DD);
253}
254
255DefinedSVal SValBuilder::getFunctionPointer(const FunctionDecl *func) {
256  return loc::MemRegionVal(MemMgr.getFunctionCodeRegion(func));
257}
258
259DefinedSVal SValBuilder::getBlockPointer(const BlockDecl *block,
260                                         CanQualType locTy,
261                                         const LocationContext *locContext,
262                                         unsigned blockCount) {
263  const BlockCodeRegion *BC =
264    MemMgr.getBlockCodeRegion(block, locTy, locContext->getAnalysisDeclContext());
265  const BlockDataRegion *BD = MemMgr.getBlockDataRegion(BC, locContext,
266                                                        blockCount);
267  return loc::MemRegionVal(BD);
268}
269
270/// Return a memory region for the 'this' object reference.
271loc::MemRegionVal SValBuilder::getCXXThis(const CXXMethodDecl *D,
272                                          const StackFrameContext *SFC) {
273  return loc::MemRegionVal(
274      getRegionManager().getCXXThisRegion(D->getThisType(), SFC));
275}
276
277/// Return a memory region for the 'this' object reference.
278loc::MemRegionVal SValBuilder::getCXXThis(const CXXRecordDecl *D,
279                                          const StackFrameContext *SFC) {
280  const Type *T = D->getTypeForDecl();
281  QualType PT = getContext().getPointerType(QualType(T, 0));
282  return loc::MemRegionVal(getRegionManager().getCXXThisRegion(PT, SFC));
283}
284
285Optional<SVal> SValBuilder::getConstantVal(const Expr *E) {
286  E = E->IgnoreParens();
287
288  switch (E->getStmtClass()) {
289  // Handle expressions that we treat differently from the AST's constant
290  // evaluator.
291  case Stmt::AddrLabelExprClass:
292    return makeLoc(cast<AddrLabelExpr>(E));
293
294  case Stmt::CXXScalarValueInitExprClass:
295  case Stmt::ImplicitValueInitExprClass:
296    return makeZeroVal(E->getType());
297
298  case Stmt::ObjCStringLiteralClass: {
299    const auto *SL = cast<ObjCStringLiteral>(E);
300    return makeLoc(getRegionManager().getObjCStringRegion(SL));
301  }
302
303  case Stmt::StringLiteralClass: {
304    const auto *SL = cast<StringLiteral>(E);
305    return makeLoc(getRegionManager().getStringRegion(SL));
306  }
307
308  // Fast-path some expressions to avoid the overhead of going through the AST's
309  // constant evaluator
310  case Stmt::CharacterLiteralClass: {
311    const auto *C = cast<CharacterLiteral>(E);
312    return makeIntVal(C->getValue(), C->getType());
313  }
314
315  case Stmt::CXXBoolLiteralExprClass:
316    return makeBoolVal(cast<CXXBoolLiteralExpr>(E));
317
318  case Stmt::TypeTraitExprClass: {
319    const auto *TE = cast<TypeTraitExpr>(E);
320    return makeTruthVal(TE->getValue(), TE->getType());
321  }
322
323  case Stmt::IntegerLiteralClass:
324    return makeIntVal(cast<IntegerLiteral>(E));
325
326  case Stmt::ObjCBoolLiteralExprClass:
327    return makeBoolVal(cast<ObjCBoolLiteralExpr>(E));
328
329  case Stmt::CXXNullPtrLiteralExprClass:
330    return makeNull();
331
332  case Stmt::CStyleCastExprClass:
333  case Stmt::CXXFunctionalCastExprClass:
334  case Stmt::CXXConstCastExprClass:
335  case Stmt::CXXReinterpretCastExprClass:
336  case Stmt::CXXStaticCastExprClass:
337  case Stmt::ImplicitCastExprClass: {
338    const auto *CE = cast<CastExpr>(E);
339    switch (CE->getCastKind()) {
340    default:
341      break;
342    case CK_ArrayToPointerDecay:
343    case CK_IntegralToPointer:
344    case CK_NoOp:
345    case CK_BitCast: {
346      const Expr *SE = CE->getSubExpr();
347      Optional<SVal> Val = getConstantVal(SE);
348      if (!Val)
349        return None;
350      return evalCast(*Val, CE->getType(), SE->getType());
351    }
352    }
353    // FALLTHROUGH
354    LLVM_FALLTHROUGH;
355  }
356
357  // If we don't have a special case, fall back to the AST's constant evaluator.
358  default: {
359    // Don't try to come up with a value for materialized temporaries.
360    if (E->isGLValue())
361      return None;
362
363    ASTContext &Ctx = getContext();
364    Expr::EvalResult Result;
365    if (E->EvaluateAsInt(Result, Ctx))
366      return makeIntVal(Result.Val.getInt());
367
368    if (Loc::isLocType(E->getType()))
369      if (E->isNullPointerConstant(Ctx, Expr::NPC_ValueDependentIsNotNull))
370        return makeNull();
371
372    return None;
373  }
374  }
375}
376
377SVal SValBuilder::makeSymExprValNN(BinaryOperator::Opcode Op,
378                                   NonLoc LHS, NonLoc RHS,
379                                   QualType ResultTy) {
380  const SymExpr *symLHS = LHS.getAsSymExpr();
381  const SymExpr *symRHS = RHS.getAsSymExpr();
382
383  // TODO: When the Max Complexity is reached, we should conjure a symbol
384  // instead of generating an Unknown value and propagate the taint info to it.
385  const unsigned MaxComp = StateMgr.getOwningEngine()
386                               .getAnalysisManager()
387                               .options.MaxSymbolComplexity;
388
389  if (symLHS && symRHS &&
390      (symLHS->computeComplexity() + symRHS->computeComplexity()) <  MaxComp)
391    return makeNonLoc(symLHS, Op, symRHS, ResultTy);
392
393  if (symLHS && symLHS->computeComplexity() < MaxComp)
394    if (Optional<nonloc::ConcreteInt> rInt = RHS.getAs<nonloc::ConcreteInt>())
395      return makeNonLoc(symLHS, Op, rInt->getValue(), ResultTy);
396
397  if (symRHS && symRHS->computeComplexity() < MaxComp)
398    if (Optional<nonloc::ConcreteInt> lInt = LHS.getAs<nonloc::ConcreteInt>())
399      return makeNonLoc(lInt->getValue(), Op, symRHS, ResultTy);
400
401  return UnknownVal();
402}
403
404SVal SValBuilder::evalBinOp(ProgramStateRef state, BinaryOperator::Opcode op,
405                            SVal lhs, SVal rhs, QualType type) {
406  if (lhs.isUndef() || rhs.isUndef())
407    return UndefinedVal();
408
409  if (lhs.isUnknown() || rhs.isUnknown())
410    return UnknownVal();
411
412  if (lhs.getAs<nonloc::LazyCompoundVal>() ||
413      rhs.getAs<nonloc::LazyCompoundVal>()) {
414    return UnknownVal();
415  }
416
417  if (Optional<Loc> LV = lhs.getAs<Loc>()) {
418    if (Optional<Loc> RV = rhs.getAs<Loc>())
419      return evalBinOpLL(state, op, *LV, *RV, type);
420
421    return evalBinOpLN(state, op, *LV, rhs.castAs<NonLoc>(), type);
422  }
423
424  if (Optional<Loc> RV = rhs.getAs<Loc>()) {
425    // Support pointer arithmetic where the addend is on the left
426    // and the pointer on the right.
427    assert(op == BO_Add);
428
429    // Commute the operands.
430    return evalBinOpLN(state, op, *RV, lhs.castAs<NonLoc>(), type);
431  }
432
433  return evalBinOpNN(state, op, lhs.castAs<NonLoc>(), rhs.castAs<NonLoc>(),
434                     type);
435}
436
437ConditionTruthVal SValBuilder::areEqual(ProgramStateRef state, SVal lhs,
438                                        SVal rhs) {
439  return state->isNonNull(evalEQ(state, lhs, rhs));
440}
441
442SVal SValBuilder::evalEQ(ProgramStateRef state, SVal lhs, SVal rhs) {
443  return evalBinOp(state, BO_EQ, lhs, rhs, getConditionType());
444}
445
446DefinedOrUnknownSVal SValBuilder::evalEQ(ProgramStateRef state,
447                                         DefinedOrUnknownSVal lhs,
448                                         DefinedOrUnknownSVal rhs) {
449  return evalEQ(state, static_cast<SVal>(lhs), static_cast<SVal>(rhs))
450      .castAs<DefinedOrUnknownSVal>();
451}
452
453/// Recursively check if the pointer types are equal modulo const, volatile,
454/// and restrict qualifiers. Also, assume that all types are similar to 'void'.
455/// Assumes the input types are canonical.
456static bool shouldBeModeledWithNoOp(ASTContext &Context, QualType ToTy,
457                                                         QualType FromTy) {
458  while (Context.UnwrapSimilarTypes(ToTy, FromTy)) {
459    Qualifiers Quals1, Quals2;
460    ToTy = Context.getUnqualifiedArrayType(ToTy, Quals1);
461    FromTy = Context.getUnqualifiedArrayType(FromTy, Quals2);
462
463    // Make sure that non-cvr-qualifiers the other qualifiers (e.g., address
464    // spaces) are identical.
465    Quals1.removeCVRQualifiers();
466    Quals2.removeCVRQualifiers();
467    if (Quals1 != Quals2)
468      return false;
469  }
470
471  // If we are casting to void, the 'From' value can be used to represent the
472  // 'To' value.
473  //
474  // FIXME: Doing this after unwrapping the types doesn't make any sense. A
475  // cast from 'int**' to 'void**' is not special in the way that a cast from
476  // 'int*' to 'void*' is.
477  if (ToTy->isVoidType())
478    return true;
479
480  if (ToTy != FromTy)
481    return false;
482
483  return true;
484}
485
486// Handles casts of type CK_IntegralCast.
487// At the moment, this function will redirect to evalCast, except when the range
488// of the original value is known to be greater than the max of the target type.
489SVal SValBuilder::evalIntegralCast(ProgramStateRef state, SVal val,
490                                   QualType castTy, QualType originalTy) {
491  // No truncations if target type is big enough.
492  if (getContext().getTypeSize(castTy) >= getContext().getTypeSize(originalTy))
493    return evalCast(val, castTy, originalTy);
494
495  const SymExpr *se = val.getAsSymbolicExpression();
496  if (!se) // Let evalCast handle non symbolic expressions.
497    return evalCast(val, castTy, originalTy);
498
499  // Find the maximum value of the target type.
500  APSIntType ToType(getContext().getTypeSize(castTy),
501                    castTy->isUnsignedIntegerType());
502  llvm::APSInt ToTypeMax = ToType.getMaxValue();
503  NonLoc ToTypeMaxVal =
504      makeIntVal(ToTypeMax.isUnsigned() ? ToTypeMax.getZExtValue()
505                                        : ToTypeMax.getSExtValue(),
506                 castTy)
507          .castAs<NonLoc>();
508  // Check the range of the symbol being casted against the maximum value of the
509  // target type.
510  NonLoc FromVal = val.castAs<NonLoc>();
511  QualType CmpTy = getConditionType();
512  NonLoc CompVal =
513      evalBinOpNN(state, BO_LE, FromVal, ToTypeMaxVal, CmpTy).castAs<NonLoc>();
514  ProgramStateRef IsNotTruncated, IsTruncated;
515  std::tie(IsNotTruncated, IsTruncated) = state->assume(CompVal);
516  if (!IsNotTruncated && IsTruncated) {
517    // Symbol is truncated so we evaluate it as a cast.
518    NonLoc CastVal = makeNonLoc(se, originalTy, castTy);
519    return CastVal;
520  }
521  return evalCast(val, castTy, originalTy);
522}
523
524// FIXME: should rewrite according to the cast kind.
525SVal SValBuilder::evalCast(SVal val, QualType castTy, QualType originalTy) {
526  castTy = Context.getCanonicalType(castTy);
527  originalTy = Context.getCanonicalType(originalTy);
528  if (val.isUnknownOrUndef() || castTy == originalTy)
529    return val;
530
531  if (castTy->isBooleanType()) {
532    if (val.isUnknownOrUndef())
533      return val;
534    if (val.isConstant())
535      return makeTruthVal(!val.isZeroConstant(), castTy);
536    if (!Loc::isLocType(originalTy) &&
537        !originalTy->isIntegralOrEnumerationType() &&
538        !originalTy->isMemberPointerType())
539      return UnknownVal();
540    if (SymbolRef Sym = val.getAsSymbol(true)) {
541      BasicValueFactory &BVF = getBasicValueFactory();
542      // FIXME: If we had a state here, we could see if the symbol is known to
543      // be zero, but we don't.
544      return makeNonLoc(Sym, BO_NE, BVF.getValue(0, Sym->getType()), castTy);
545    }
546    // Loc values are not always true, they could be weakly linked functions.
547    if (Optional<Loc> L = val.getAs<Loc>())
548      return evalCastFromLoc(*L, castTy);
549
550    Loc L = val.castAs<nonloc::LocAsInteger>().getLoc();
551    return evalCastFromLoc(L, castTy);
552  }
553
554  // For const casts, casts to void, just propagate the value.
555  if (!castTy->isVariableArrayType() && !originalTy->isVariableArrayType())
556    if (shouldBeModeledWithNoOp(Context, Context.getPointerType(castTy),
557                                         Context.getPointerType(originalTy)))
558      return val;
559
560  // Check for casts from pointers to integers.
561  if (castTy->isIntegralOrEnumerationType() && Loc::isLocType(originalTy))
562    return evalCastFromLoc(val.castAs<Loc>(), castTy);
563
564  // Check for casts from integers to pointers.
565  if (Loc::isLocType(castTy) && originalTy->isIntegralOrEnumerationType()) {
566    if (Optional<nonloc::LocAsInteger> LV = val.getAs<nonloc::LocAsInteger>()) {
567      if (const MemRegion *R = LV->getLoc().getAsRegion()) {
568        StoreManager &storeMgr = StateMgr.getStoreManager();
569        R = storeMgr.castRegion(R, castTy);
570        return R ? SVal(loc::MemRegionVal(R)) : UnknownVal();
571      }
572      return LV->getLoc();
573    }
574    return dispatchCast(val, castTy);
575  }
576
577  // Just pass through function and block pointers.
578  if (originalTy->isBlockPointerType() || originalTy->isFunctionPointerType()) {
579    assert(Loc::isLocType(castTy));
580    return val;
581  }
582
583  // Check for casts from array type to another type.
584  if (const auto *arrayT =
585          dyn_cast<ArrayType>(originalTy.getCanonicalType())) {
586    // We will always decay to a pointer.
587    QualType elemTy = arrayT->getElementType();
588    val = StateMgr.ArrayToPointer(val.castAs<Loc>(), elemTy);
589
590    // Are we casting from an array to a pointer?  If so just pass on
591    // the decayed value.
592    if (castTy->isPointerType() || castTy->isReferenceType())
593      return val;
594
595    // Are we casting from an array to an integer?  If so, cast the decayed
596    // pointer value to an integer.
597    assert(castTy->isIntegralOrEnumerationType());
598
599    // FIXME: Keep these here for now in case we decide soon that we
600    // need the original decayed type.
601    //    QualType elemTy = cast<ArrayType>(originalTy)->getElementType();
602    //    QualType pointerTy = C.getPointerType(elemTy);
603    return evalCastFromLoc(val.castAs<Loc>(), castTy);
604  }
605
606  // Check for casts from a region to a specific type.
607  if (const MemRegion *R = val.getAsRegion()) {
608    // Handle other casts of locations to integers.
609    if (castTy->isIntegralOrEnumerationType())
610      return evalCastFromLoc(loc::MemRegionVal(R), castTy);
611
612    // FIXME: We should handle the case where we strip off view layers to get
613    //  to a desugared type.
614    if (!Loc::isLocType(castTy)) {
615      // FIXME: There can be gross cases where one casts the result of a function
616      // (that returns a pointer) to some other value that happens to fit
617      // within that pointer value.  We currently have no good way to
618      // model such operations.  When this happens, the underlying operation
619      // is that the caller is reasoning about bits.  Conceptually we are
620      // layering a "view" of a location on top of those bits.  Perhaps
621      // we need to be more lazy about mutual possible views, even on an
622      // SVal?  This may be necessary for bit-level reasoning as well.
623      return UnknownVal();
624    }
625
626    // We get a symbolic function pointer for a dereference of a function
627    // pointer, but it is of function type. Example:
628
629    //  struct FPRec {
630    //    void (*my_func)(int * x);
631    //  };
632    //
633    //  int bar(int x);
634    //
635    //  int f1_a(struct FPRec* foo) {
636    //    int x;
637    //    (*foo->my_func)(&x);
638    //    return bar(x)+1; // no-warning
639    //  }
640
641    assert(Loc::isLocType(originalTy) || originalTy->isFunctionType() ||
642           originalTy->isBlockPointerType() || castTy->isReferenceType());
643
644    StoreManager &storeMgr = StateMgr.getStoreManager();
645
646    // Delegate to store manager to get the result of casting a region to a
647    // different type.  If the MemRegion* returned is NULL, this expression
648    // Evaluates to UnknownVal.
649    R = storeMgr.castRegion(R, castTy);
650    return R ? SVal(loc::MemRegionVal(R)) : UnknownVal();
651  }
652
653  return dispatchCast(val, castTy);
654}
655