Coverage Report

Created: 2019-07-24 05:18

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