Coverage Report

Created: 2020-09-22 08:39

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