Coverage Report

Created: 2023-09-30 09:22

/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/Analysis/AnalysisDeclContext.h"
23
#include "clang/Basic/LLVM.h"
24
#include "clang/StaticAnalyzer/Core/PathSensitive/APSIntType.h"
25
#include "clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.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/SValVisitor.h"
32
#include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h"
33
#include "clang/StaticAnalyzer/Core/PathSensitive/Store.h"
34
#include "clang/StaticAnalyzer/Core/PathSensitive/SymExpr.h"
35
#include "clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h"
36
#include "llvm/ADT/APSInt.h"
37
#include "llvm/Support/Casting.h"
38
#include "llvm/Support/Compiler.h"
39
#include <cassert>
40
#include <optional>
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
SValBuilder::SValBuilder(llvm::BumpPtrAllocator &alloc, ASTContext &context,
53
                         ProgramStateManager &stateMgr)
54
16.2k
    : Context(context), BasicVals(context, alloc),
55
16.2k
      SymMgr(context, BasicVals, alloc), MemMgr(context, alloc),
56
16.2k
      StateMgr(stateMgr),
57
      AnOpts(
58
16.2k
          stateMgr.getOwningEngine().getAnalysisManager().getAnalyzerOptions()),
59
16.2k
      ArrayIndexTy(context.LongLongTy),
60
16.2k
      ArrayIndexWidth(context.getTypeSize(ArrayIndexTy)) {}
61
62
11.4k
DefinedOrUnknownSVal SValBuilder::makeZeroVal(QualType type) {
63
11.4k
  if (Loc::isLocType(type))
64
5.03k
    return makeNullWithType(type);
65
66
6.45k
  if (type->isIntegralOrEnumerationType())
67
6.40k
    return makeIntVal(0, type);
68
69
48
  if (type->isArrayType() || 
type->isRecordType()12
||
type->isVectorType()7
||
70
48
      
type->isAnyComplexType()7
)
71
41
    return makeCompoundVal(type, BasicVals.getEmptySValList());
72
73
  // FIXME: Handle floats.
74
7
  return UnknownVal();
75
48
}
76
77
nonloc::SymbolVal SValBuilder::makeNonLoc(const SymExpr *lhs,
78
                                          BinaryOperator::Opcode op,
79
                                          const llvm::APSInt &rhs,
80
221k
                                          QualType type) {
81
  // The Environment ensures we always get a persistent APSInt in
82
  // BasicValueFactory, so we don't need to get the APSInt from
83
  // BasicValueFactory again.
84
221k
  assert(lhs);
85
221k
  assert(!Loc::isLocType(type));
86
221k
  return nonloc::SymbolVal(SymMgr.getSymIntExpr(lhs, op, rhs, type));
87
221k
}
88
89
nonloc::SymbolVal SValBuilder::makeNonLoc(const llvm::APSInt &lhs,
90
                                          BinaryOperator::Opcode op,
91
1.41k
                                          const SymExpr *rhs, QualType type) {
92
1.41k
  assert(rhs);
93
1.41k
  assert(!Loc::isLocType(type));
94
1.41k
  return nonloc::SymbolVal(SymMgr.getIntSymExpr(lhs, op, rhs, type));
95
1.41k
}
96
97
nonloc::SymbolVal SValBuilder::makeNonLoc(const SymExpr *lhs,
98
                                          BinaryOperator::Opcode op,
99
45.0k
                                          const SymExpr *rhs, QualType type) {
100
45.0k
  assert(lhs && rhs);
101
45.0k
  assert(!Loc::isLocType(type));
102
45.0k
  return nonloc::SymbolVal(SymMgr.getSymSymExpr(lhs, op, rhs, type));
103
45.0k
}
104
105
NonLoc SValBuilder::makeNonLoc(const SymExpr *operand, UnaryOperator::Opcode op,
106
70
                               QualType type) {
107
70
  assert(operand);
108
70
  assert(!Loc::isLocType(type));
109
70
  return nonloc::SymbolVal(SymMgr.getUnarySymExpr(operand, op, type));
110
70
}
111
112
nonloc::SymbolVal SValBuilder::makeNonLoc(const SymExpr *operand,
113
5.08k
                                          QualType fromTy, QualType toTy) {
114
5.08k
  assert(operand);
115
5.08k
  assert(!Loc::isLocType(toTy));
116
5.08k
  if (fromTy == toTy)
117
61
    return operand;
118
5.02k
  return nonloc::SymbolVal(SymMgr.getCastSymbol(operand, fromTy, toTy));
119
5.08k
}
120
121
29.2k
SVal SValBuilder::convertToArrayIndex(SVal val) {
122
29.2k
  if (val.isUnknownOrUndef())
123
0
    return val;
124
125
  // Common case: we have an appropriately sized integer.
126
29.2k
  if (std::optional<nonloc::ConcreteInt> CI =
127
29.2k
          val.getAs<nonloc::ConcreteInt>()) {
128
9.77k
    const llvm::APSInt& I = CI->getValue();
129
9.77k
    if (I.getBitWidth() == ArrayIndexWidth && 
I.isSigned()3.91k
)
130
2.04k
      return val;
131
9.77k
  }
132
133
27.1k
  return evalCast(val, ArrayIndexTy, QualType{});
134
29.2k
}
135
136
2.35k
nonloc::ConcreteInt SValBuilder::makeBoolVal(const CXXBoolLiteralExpr *boolean){
137
2.35k
  return makeTruthVal(boolean->getValue());
138
2.35k
}
139
140
DefinedOrUnknownSVal
141
166k
SValBuilder::getRegionValueSymbolVal(const TypedValueRegion *region) {
142
166k
  QualType T = region->getValueType();
143
144
166k
  if (T->isNullPtrType())
145
0
    return makeZeroVal(T);
146
147
166k
  if (!SymbolManager::canSymbolicate(T))
148
2.22k
    return UnknownVal();
149
150
164k
  SymbolRef sym = SymMgr.getRegionValueSymbol(region);
151
152
164k
  if (Loc::isLocType(T))
153
65.9k
    return loc::MemRegionVal(MemMgr.getSymbolicRegion(sym));
154
155
98.7k
  return nonloc::SymbolVal(sym);
156
164k
}
157
158
DefinedOrUnknownSVal SValBuilder::conjureSymbolVal(const void *SymbolTag,
159
                                                   const Expr *Ex,
160
                                                   const LocationContext *LCtx,
161
4.52k
                                                   unsigned Count) {
162
4.52k
  QualType T = Ex->getType();
163
164
4.52k
  if (T->isNullPtrType())
165
0
    return makeZeroVal(T);
166
167
  // Compute the type of the result. If the expression is not an R-value, the
168
  // result should be a location.
169
4.52k
  QualType ExType = Ex->getType();
170
4.52k
  if (Ex->isGLValue())
171
2
    T = LCtx->getAnalysisDeclContext()->getASTContext().getPointerType(ExType);
172
173
4.52k
  return conjureSymbolVal(SymbolTag, Ex, LCtx, T, Count);
174
4.52k
}
175
176
DefinedOrUnknownSVal SValBuilder::conjureSymbolVal(const void *symbolTag,
177
                                                   const Expr *expr,
178
                                                   const LocationContext *LCtx,
179
                                                   QualType type,
180
140k
                                                   unsigned count) {
181
140k
  if (type->isNullPtrType())
182
1
    return makeZeroVal(type);
183
184
140k
  if (!SymbolManager::canSymbolicate(type))
185
8.23k
    return UnknownVal();
186
187
131k
  SymbolRef sym = SymMgr.conjureSymbol(expr, LCtx, type, count, symbolTag);
188
189
131k
  if (Loc::isLocType(type))
190
7.08k
    return loc::MemRegionVal(MemMgr.getSymbolicRegion(sym));
191
192
124k
  return nonloc::SymbolVal(sym);
193
131k
}
194
195
DefinedOrUnknownSVal SValBuilder::conjureSymbolVal(const Stmt *stmt,
196
                                                   const LocationContext *LCtx,
197
                                                   QualType type,
198
637
                                                   unsigned visitCount) {
199
637
  if (type->isNullPtrType())
200
0
    return makeZeroVal(type);
201
202
637
  if (!SymbolManager::canSymbolicate(type))
203
35
    return UnknownVal();
204
205
602
  SymbolRef sym = SymMgr.conjureSymbol(stmt, LCtx, type, visitCount);
206
207
602
  if (Loc::isLocType(type))
208
90
    return loc::MemRegionVal(MemMgr.getSymbolicRegion(sym));
209
210
512
  return nonloc::SymbolVal(sym);
211
602
}
212
213
DefinedOrUnknownSVal
214
SValBuilder::getConjuredHeapSymbolVal(const Expr *E,
215
                                      const LocationContext *LCtx,
216
1.72k
                                      unsigned VisitCount) {
217
1.72k
  QualType T = E->getType();
218
1.72k
  return getConjuredHeapSymbolVal(E, LCtx, T, VisitCount);
219
1.72k
}
220
221
DefinedOrUnknownSVal
222
SValBuilder::getConjuredHeapSymbolVal(const Expr *E,
223
                                      const LocationContext *LCtx,
224
1.72k
                                      QualType type, unsigned VisitCount) {
225
1.72k
  assert(Loc::isLocType(type));
226
1.72k
  assert(SymbolManager::canSymbolicate(type));
227
1.72k
  if (type->isNullPtrType())
228
0
    return makeZeroVal(type);
229
230
1.72k
  SymbolRef sym = SymMgr.conjureSymbol(E, LCtx, type, VisitCount);
231
1.72k
  return loc::MemRegionVal(MemMgr.getSymbolicHeapRegion(sym));
232
1.72k
}
233
234
DefinedSVal SValBuilder::getMetadataSymbolVal(const void *symbolTag,
235
                                              const MemRegion *region,
236
                                              const Expr *expr, QualType type,
237
                                              const LocationContext *LCtx,
238
694
                                              unsigned count) {
239
694
  assert(SymbolManager::canSymbolicate(type) && "Invalid metadata symbol type");
240
241
694
  SymbolRef sym =
242
694
      SymMgr.getMetadataSymbol(region, expr, type, LCtx, count, symbolTag);
243
244
694
  if (Loc::isLocType(type))
245
0
    return loc::MemRegionVal(MemMgr.getSymbolicRegion(sym));
246
247
694
  return nonloc::SymbolVal(sym);
248
694
}
249
250
DefinedOrUnknownSVal
251
SValBuilder::getDerivedRegionValueSymbolVal(SymbolRef parentSymbol,
252
15.9k
                                             const TypedValueRegion *region) {
253
15.9k
  QualType T = region->getValueType();
254
255
15.9k
  if (T->isNullPtrType())
256
10
    return makeZeroVal(T);
257
258
15.9k
  if (!SymbolManager::canSymbolicate(T))
259
104
    return UnknownVal();
260
261
15.8k
  SymbolRef sym = SymMgr.getDerivedSymbol(parentSymbol, region);
262
263
15.8k
  if (Loc::isLocType(T))
264
8.73k
    return loc::MemRegionVal(MemMgr.getSymbolicRegion(sym));
265
266
7.09k
  return nonloc::SymbolVal(sym);
267
15.8k
}
268
269
67
DefinedSVal SValBuilder::getMemberPointer(const NamedDecl *ND) {
270
67
  assert(!ND || (isa<CXXMethodDecl, FieldDecl, IndirectFieldDecl>(ND)));
271
272
67
  if (const auto *MD = dyn_cast_or_null<CXXMethodDecl>(ND)) {
273
    // Sema treats pointers to static member functions as have function pointer
274
    // type, so return a function pointer for the method.
275
    // We don't need to play a similar trick for static member fields
276
    // because these are represented as plain VarDecls and not FieldDecls
277
    // in the AST.
278
26
    if (MD->isStatic())
279
1
      return getFunctionPointer(MD);
280
26
  }
281
282
66
  return nonloc::PointerToMember(ND);
283
67
}
284
285
81.0k
DefinedSVal SValBuilder::getFunctionPointer(const FunctionDecl *func) {
286
81.0k
  return loc::MemRegionVal(MemMgr.getFunctionCodeRegion(func));
287
81.0k
}
288
289
DefinedSVal SValBuilder::getBlockPointer(const BlockDecl *block,
290
                                         CanQualType locTy,
291
                                         const LocationContext *locContext,
292
398
                                         unsigned blockCount) {
293
398
  const BlockCodeRegion *BC =
294
398
    MemMgr.getBlockCodeRegion(block, locTy, locContext->getAnalysisDeclContext());
295
398
  const BlockDataRegion *BD = MemMgr.getBlockDataRegion(BC, locContext,
296
398
                                                        blockCount);
297
398
  return loc::MemRegionVal(BD);
298
398
}
299
300
std::optional<loc::MemRegionVal>
301
67.6k
SValBuilder::getCastedMemRegionVal(const MemRegion *R, QualType Ty) {
302
67.6k
  if (auto OptR = StateMgr.getStoreManager().castRegion(R, Ty))
303
67.6k
    return loc::MemRegionVal(*OptR);
304
14
  return std::nullopt;
305
67.6k
}
306
307
/// Return a memory region for the 'this' object reference.
308
loc::MemRegionVal SValBuilder::getCXXThis(const CXXMethodDecl *D,
309
61.3k
                                          const StackFrameContext *SFC) {
310
61.3k
  return loc::MemRegionVal(
311
61.3k
      getRegionManager().getCXXThisRegion(D->getThisType(), SFC));
312
61.3k
}
313
314
/// Return a memory region for the 'this' object reference.
315
loc::MemRegionVal SValBuilder::getCXXThis(const CXXRecordDecl *D,
316
9.51k
                                          const StackFrameContext *SFC) {
317
9.51k
  const Type *T = D->getTypeForDecl();
318
9.51k
  QualType PT = getContext().getPointerType(QualType(T, 0));
319
9.51k
  return loc::MemRegionVal(getRegionManager().getCXXThisRegion(PT, SFC));
320
9.51k
}
321
322
117k
std::optional<SVal> SValBuilder::getConstantVal(const Expr *E) {
323
117k
  E = E->IgnoreParens();
324
325
117k
  switch (E->getStmtClass()) {
326
  // Handle expressions that we treat differently from the AST's constant
327
  // evaluator.
328
164
  case Stmt::AddrLabelExprClass:
329
164
    return makeLoc(cast<AddrLabelExpr>(E));
330
331
114
  case Stmt::CXXScalarValueInitExprClass:
332
335
  case Stmt::ImplicitValueInitExprClass:
333
335
    return makeZeroVal(E->getType());
334
335
1.12k
  case Stmt::ObjCStringLiteralClass: {
336
1.12k
    const auto *SL = cast<ObjCStringLiteral>(E);
337
1.12k
    return makeLoc(getRegionManager().getObjCStringRegion(SL));
338
114
  }
339
340
10.7k
  case Stmt::StringLiteralClass: {
341
10.7k
    const auto *SL = cast<StringLiteral>(E);
342
10.7k
    return makeLoc(getRegionManager().getStringRegion(SL));
343
114
  }
344
345
1.14k
  case Stmt::PredefinedExprClass: {
346
1.14k
    const auto *PE = cast<PredefinedExpr>(E);
347
1.14k
    assert(PE->getFunctionName() &&
348
1.14k
           "Since we analyze only instantiated functions, PredefinedExpr "
349
1.14k
           "should have a function name.");
350
1.14k
    return makeLoc(getRegionManager().getStringRegion(PE->getFunctionName()));
351
1.14k
  }
352
353
  // Fast-path some expressions to avoid the overhead of going through the AST's
354
  // constant evaluator
355
1.24k
  case Stmt::CharacterLiteralClass: {
356
1.24k
    const auto *C = cast<CharacterLiteral>(E);
357
1.24k
    return makeIntVal(C->getValue(), C->getType());
358
1.14k
  }
359
360
2.35k
  case Stmt::CXXBoolLiteralExprClass:
361
2.35k
    return makeBoolVal(cast<CXXBoolLiteralExpr>(E));
362
363
9
  case Stmt::TypeTraitExprClass: {
364
9
    const auto *TE = cast<TypeTraitExpr>(E);
365
9
    return makeTruthVal(TE->getValue(), TE->getType());
366
1.14k
  }
367
368
96.7k
  case Stmt::IntegerLiteralClass:
369
96.7k
    return makeIntVal(cast<IntegerLiteral>(E));
370
371
244
  case Stmt::ObjCBoolLiteralExprClass:
372
244
    return makeBoolVal(cast<ObjCBoolLiteralExpr>(E));
373
374
302
  case Stmt::CXXNullPtrLiteralExprClass:
375
302
    return makeNullWithType(E->getType());
376
377
235
  case Stmt::CStyleCastExprClass:
378
270
  case Stmt::CXXFunctionalCastExprClass:
379
305
  case Stmt::CXXConstCastExprClass:
380
340
  case Stmt::CXXReinterpretCastExprClass:
381
377
  case Stmt::CXXStaticCastExprClass:
382
904
  case Stmt::ImplicitCastExprClass: {
383
904
    const auto *CE = cast<CastExpr>(E);
384
904
    switch (CE->getCastKind()) {
385
431
    default:
386
431
      break;
387
431
    case CK_ArrayToPointerDecay:
388
337
    case CK_IntegralToPointer:
389
471
    case CK_NoOp:
390
473
    case CK_BitCast: {
391
473
      const Expr *SE = CE->getSubExpr();
392
473
      std::optional<SVal> Val = getConstantVal(SE);
393
473
      if (!Val)
394
61
        return std::nullopt;
395
412
      return evalCast(*Val, CE->getType(), SE->getType());
396
473
    }
397
904
    }
398
904
    [[fallthrough]];
399
431
  }
400
401
  // If we don't have a special case, fall back to the AST's constant evaluator.
402
2.40k
  default: {
403
    // Don't try to come up with a value for materialized temporaries.
404
2.40k
    if (E->isGLValue())
405
3
      return std::nullopt;
406
407
2.39k
    ASTContext &Ctx = getContext();
408
2.39k
    Expr::EvalResult Result;
409
2.39k
    if (E->EvaluateAsInt(Result, Ctx))
410
645
      return makeIntVal(Result.Val.getInt());
411
412
1.75k
    if (Loc::isLocType(E->getType()))
413
190
      if (E->isNullPointerConstant(Ctx, Expr::NPC_ValueDependentIsNotNull))
414
177
        return makeNullWithType(E->getType());
415
416
1.57k
    return std::nullopt;
417
1.75k
  }
418
117k
  }
419
117k
}
420
421
SVal SValBuilder::makeSymExprValNN(BinaryOperator::Opcode Op,
422
                                   NonLoc LHS, NonLoc RHS,
423
45.9k
                                   QualType ResultTy) {
424
45.9k
  SymbolRef symLHS = LHS.getAsSymbol();
425
45.9k
  SymbolRef symRHS = RHS.getAsSymbol();
426
427
  // TODO: When the Max Complexity is reached, we should conjure a symbol
428
  // instead of generating an Unknown value and propagate the taint info to it.
429
45.9k
  const unsigned MaxComp = AnOpts.MaxSymbolComplexity;
430
431
45.9k
  if (symLHS && 
symRHS44.5k
&&
432
45.9k
      
(symLHS->computeComplexity() + symRHS->computeComplexity()) < MaxComp44.5k
)
433
44.3k
    return makeNonLoc(symLHS, Op, symRHS, ResultTy);
434
435
1.57k
  if (symLHS && 
symLHS->computeComplexity() < MaxComp159
)
436
159
    if (std::optional<nonloc::ConcreteInt> rInt =
437
159
            RHS.getAs<nonloc::ConcreteInt>())
438
0
      return makeNonLoc(symLHS, Op, rInt->getValue(), ResultTy);
439
440
1.57k
  if (symRHS && 
symRHS->computeComplexity() < MaxComp1.56k
)
441
1.56k
    if (std::optional<nonloc::ConcreteInt> lInt =
442
1.56k
            LHS.getAs<nonloc::ConcreteInt>())
443
1.41k
      return makeNonLoc(lInt->getValue(), Op, symRHS, ResultTy);
444
445
160
  return UnknownVal();
446
1.57k
}
447
448
5.33k
SVal SValBuilder::evalMinus(NonLoc X) {
449
5.33k
  switch (X.getSubKind()) {
450
5.28k
  case nonloc::ConcreteIntKind:
451
5.28k
    return makeIntVal(-X.castAs<nonloc::ConcreteInt>().getValue());
452
53
  case nonloc::SymbolValKind:
453
53
    return makeNonLoc(X.castAs<nonloc::SymbolVal>().getSymbol(), UO_Minus,
454
53
                      X.getType(Context));
455
0
  default:
456
0
    return UnknownVal();
457
5.33k
  }
458
5.33k
}
459
460
2.50k
SVal SValBuilder::evalComplement(NonLoc X) {
461
2.50k
  switch (X.getSubKind()) {
462
2.48k
  case nonloc::ConcreteIntKind:
463
2.48k
    return makeIntVal(~X.castAs<nonloc::ConcreteInt>().getValue());
464
17
  case nonloc::SymbolValKind:
465
17
    return makeNonLoc(X.castAs<nonloc::SymbolVal>().getSymbol(), UO_Not,
466
17
                      X.getType(Context));
467
0
  default:
468
0
    return UnknownVal();
469
2.50k
  }
470
2.50k
}
471
472
SVal SValBuilder::evalUnaryOp(ProgramStateRef state, UnaryOperator::Opcode opc,
473
4
                 SVal operand, QualType type) {
474
4
  auto OpN = operand.getAs<NonLoc>();
475
4
  if (!OpN)
476
0
    return UnknownVal();
477
478
4
  if (opc == UO_Minus)
479
4
    return evalMinus(*OpN);
480
0
  if (opc == UO_Not)
481
0
    return evalComplement(*OpN);
482
0
  llvm_unreachable("Unexpected unary operator");
483
0
}
484
485
SVal SValBuilder::evalBinOp(ProgramStateRef state, BinaryOperator::Opcode op,
486
192k
                            SVal lhs, SVal rhs, QualType type) {
487
192k
  if (lhs.isUndef() || 
rhs.isUndef()185k
)
488
6.43k
    return UndefinedVal();
489
490
185k
  if (lhs.isUnknown() || 
rhs.isUnknown()178k
)
491
8.35k
    return UnknownVal();
492
493
177k
  if (isa<nonloc::LazyCompoundVal>(lhs) || 
isa<nonloc::LazyCompoundVal>(rhs)176k
) {
494
390
    return UnknownVal();
495
390
  }
496
497
176k
  if (op == BinaryOperatorKind::BO_Cmp) {
498
    // We can't reason about C++20 spaceship operator yet.
499
    //
500
    // FIXME: Support C++20 spaceship operator.
501
    //        The main problem here is that the result is not integer.
502
1
    return UnknownVal();
503
1
  }
504
505
176k
  if (std::optional<Loc> LV = lhs.getAs<Loc>()) {
506
36.2k
    if (std::optional<Loc> RV = rhs.getAs<Loc>())
507
25.0k
      return evalBinOpLL(state, op, *LV, *RV, type);
508
509
11.1k
    return evalBinOpLN(state, op, *LV, rhs.castAs<NonLoc>(), type);
510
36.2k
  }
511
512
140k
  if (const std::optional<Loc> RV = rhs.getAs<Loc>()) {
513
59
    const auto IsCommutative = [](BinaryOperatorKind Op) {
514
59
      return Op == BO_Mul || Op == BO_Add || 
Op == BO_And32
||
Op == BO_Xor32
||
515
59
             
Op == BO_Or32
;
516
59
    };
517
518
59
    if (IsCommutative(op)) {
519
      // Swap operands.
520
27
      return evalBinOpLN(state, op, *RV, lhs.castAs<NonLoc>(), type);
521
27
    }
522
523
    // If the right operand is a concrete int location then we have nothing
524
    // better but to treat it as a simple nonloc.
525
32
    if (auto RV = rhs.getAs<loc::ConcreteInt>()) {
526
32
      const nonloc::ConcreteInt RhsAsLoc = makeIntVal(RV->getValue());
527
32
      return evalBinOpNN(state, op, lhs.castAs<NonLoc>(), RhsAsLoc, type);
528
32
    }
529
32
  }
530
531
140k
  return evalBinOpNN(state, op, lhs.castAs<NonLoc>(), rhs.castAs<NonLoc>(),
532
140k
                     type);
533
140k
}
534
535
ConditionTruthVal SValBuilder::areEqual(ProgramStateRef state, SVal lhs,
536
26.3k
                                        SVal rhs) {
537
26.3k
  return state->isNonNull(evalEQ(state, lhs, rhs));
538
26.3k
}
539
540
34.4k
SVal SValBuilder::evalEQ(ProgramStateRef state, SVal lhs, SVal rhs) {
541
34.4k
  return evalBinOp(state, BO_EQ, lhs, rhs, getConditionType());
542
34.4k
}
543
544
DefinedOrUnknownSVal SValBuilder::evalEQ(ProgramStateRef state,
545
                                         DefinedOrUnknownSVal lhs,
546
8.06k
                                         DefinedOrUnknownSVal rhs) {
547
8.06k
  return evalEQ(state, static_cast<SVal>(lhs), static_cast<SVal>(rhs))
548
8.06k
      .castAs<DefinedOrUnknownSVal>();
549
8.06k
}
550
551
/// Recursively check if the pointer types are equal modulo const, volatile,
552
/// and restrict qualifiers. Also, assume that all types are similar to 'void'.
553
/// Assumes the input types are canonical.
554
static bool shouldBeModeledWithNoOp(ASTContext &Context, QualType ToTy,
555
912k
                                                         QualType FromTy) {
556
1.83M
  while (Context.UnwrapSimilarTypes(ToTy, FromTy)) {
557
925k
    Qualifiers Quals1, Quals2;
558
925k
    ToTy = Context.getUnqualifiedArrayType(ToTy, Quals1);
559
925k
    FromTy = Context.getUnqualifiedArrayType(FromTy, Quals2);
560
561
    // Make sure that non-cvr-qualifiers the other qualifiers (e.g., address
562
    // spaces) are identical.
563
925k
    Quals1.removeCVRQualifiers();
564
925k
    Quals2.removeCVRQualifiers();
565
925k
    if (Quals1 != Quals2)
566
3
      return false;
567
925k
  }
568
569
  // If we are casting to void, the 'From' value can be used to represent the
570
  // 'To' value.
571
  //
572
  // FIXME: Doing this after unwrapping the types doesn't make any sense. A
573
  // cast from 'int**' to 'void**' is not special in the way that a cast from
574
  // 'int*' to 'void*' is.
575
912k
  if (ToTy->isVoidType())
576
3.58k
    return true;
577
578
909k
  if (ToTy != FromTy)
579
909k
    return false;
580
581
112
  return true;
582
909k
}
583
584
// Handles casts of type CK_IntegralCast.
585
// At the moment, this function will redirect to evalCast, except when the range
586
// of the original value is known to be greater than the max of the target type.
587
SVal SValBuilder::evalIntegralCast(ProgramStateRef state, SVal val,
588
46.7k
                                   QualType castTy, QualType originalTy) {
589
  // No truncations if target type is big enough.
590
46.7k
  if (getContext().getTypeSize(castTy) >= getContext().getTypeSize(originalTy))
591
43.1k
    return evalCast(val, castTy, originalTy);
592
593
3.59k
  SymbolRef se = val.getAsSymbol();
594
3.59k
  if (!se) // Let evalCast handle non symbolic expressions.
595
2.23k
    return evalCast(val, castTy, originalTy);
596
597
  // Find the maximum value of the target type.
598
1.35k
  APSIntType ToType(getContext().getTypeSize(castTy),
599
1.35k
                    castTy->isUnsignedIntegerType());
600
1.35k
  llvm::APSInt ToTypeMax = ToType.getMaxValue();
601
602
1.35k
  NonLoc ToTypeMaxVal = makeIntVal(ToTypeMax);
603
604
  // Check the range of the symbol being casted against the maximum value of the
605
  // target type.
606
1.35k
  NonLoc FromVal = val.castAs<NonLoc>();
607
1.35k
  QualType CmpTy = getConditionType();
608
1.35k
  NonLoc CompVal =
609
1.35k
      evalBinOpNN(state, BO_LE, FromVal, ToTypeMaxVal, CmpTy).castAs<NonLoc>();
610
1.35k
  ProgramStateRef IsNotTruncated, IsTruncated;
611
1.35k
  std::tie(IsNotTruncated, IsTruncated) = state->assume(CompVal);
612
1.35k
  if (!IsNotTruncated && 
IsTruncated21
) {
613
    // Symbol is truncated so we evaluate it as a cast.
614
21
    return makeNonLoc(se, originalTy, castTy);
615
21
  }
616
1.33k
  return evalCast(val, castTy, originalTy);
617
1.35k
}
618
619
//===----------------------------------------------------------------------===//
620
// Cast method.
621
// `evalCast` and its helper `EvalCastVisitor`
622
//===----------------------------------------------------------------------===//
623
624
namespace {
625
class EvalCastVisitor : public SValVisitor<EvalCastVisitor, SVal> {
626
private:
627
  SValBuilder &VB;
628
  ASTContext &Context;
629
  QualType CastTy, OriginalTy;
630
631
public:
632
  EvalCastVisitor(SValBuilder &VB, QualType CastTy, QualType OriginalTy)
633
1.53M
      : VB(VB), Context(VB.getContext()), CastTy(CastTy),
634
1.53M
        OriginalTy(OriginalTy) {}
635
636
1.53M
  SVal Visit(SVal V) {
637
1.53M
    if (CastTy.isNull())
638
0
      return V;
639
640
1.53M
    CastTy = Context.getCanonicalType(CastTy);
641
642
1.53M
    const bool IsUnknownOriginalType = OriginalTy.isNull();
643
1.53M
    if (!IsUnknownOriginalType) {
644
918k
      OriginalTy = Context.getCanonicalType(OriginalTy);
645
646
918k
      if (CastTy == OriginalTy)
647
5.48k
        return V;
648
649
      // FIXME: Move this check to the most appropriate
650
      // evalCastKind/evalCastSubKind function. For const casts, casts to void,
651
      // just propagate the value.
652
912k
      if (!CastTy->isVariableArrayType() && !OriginalTy->isVariableArrayType())
653
912k
        if (shouldBeModeledWithNoOp(Context, Context.getPointerType(CastTy),
654
912k
                                    Context.getPointerType(OriginalTy)))
655
3.69k
          return V;
656
912k
    }
657
1.52M
    return SValVisitor::Visit(V);
658
1.53M
  }
659
105k
  SVal VisitUndefinedVal(UndefinedVal V) { return V; }
660
19.0k
  SVal VisitUnknownVal(UnknownVal V) { return V; }
661
52.8k
  SVal VisitLocConcreteInt(loc::ConcreteInt V) {
662
    // Pointer to bool.
663
52.8k
    if (CastTy->isBooleanType())
664
3.33k
      return VB.makeTruthVal(V.getValue().getBoolValue(), CastTy);
665
666
    // Pointer to integer.
667
49.5k
    if (CastTy->isIntegralOrEnumerationType()) {
668
86
      llvm::APSInt Value = V.getValue();
669
86
      VB.getBasicValueFactory().getAPSIntType(CastTy).apply(Value);
670
86
      return VB.makeIntVal(Value);
671
86
    }
672
673
    // Pointer to any pointer.
674
49.4k
    if (Loc::isLocType(CastTy)) {
675
49.4k
      llvm::APSInt Value = V.getValue();
676
49.4k
      VB.getBasicValueFactory().getAPSIntType(CastTy).apply(Value);
677
49.4k
      return loc::ConcreteInt(VB.getBasicValueFactory().getValue(Value));
678
49.4k
    }
679
680
    // Pointer to whatever else.
681
8
    return UnknownVal();
682
49.4k
  }
683
56
  SVal VisitLocGotoLabel(loc::GotoLabel V) {
684
    // Pointer to bool.
685
56
    if (CastTy->isBooleanType())
686
      // Labels are always true.
687
14
      return VB.makeTruthVal(true, CastTy);
688
689
    // Pointer to integer.
690
42
    if (CastTy->isIntegralOrEnumerationType()) {
691
0
      const unsigned BitWidth = Context.getIntWidth(CastTy);
692
0
      return VB.makeLocAsInteger(V, BitWidth);
693
0
    }
694
695
42
    const bool IsUnknownOriginalType = OriginalTy.isNull();
696
42
    if (!IsUnknownOriginalType) {
697
      // Array to pointer.
698
40
      if (isa<ArrayType>(OriginalTy))
699
0
        if (CastTy->isPointerType() || CastTy->isReferenceType())
700
0
          return UnknownVal();
701
40
    }
702
703
    // Pointer to any pointer.
704
42
    if (Loc::isLocType(CastTy))
705
42
      return V;
706
707
    // Pointer to whatever else.
708
0
    return UnknownVal();
709
42
  }
710
1.01M
  SVal VisitLocMemRegionVal(loc::MemRegionVal V) {
711
    // Pointer to bool.
712
1.01M
    if (CastTy->isBooleanType()) {
713
807k
      const MemRegion *R = V.getRegion();
714
807k
      if (const FunctionCodeRegion *FTR = dyn_cast<FunctionCodeRegion>(R))
715
144k
        if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(FTR->getDecl()))
716
144k
          if (FD->isWeak())
717
            // FIXME: Currently we are using an extent symbol here,
718
            // because there are no generic region address metadata
719
            // symbols to use, only content metadata.
720
27
            return nonloc::SymbolVal(
721
27
                VB.getSymbolManager().getExtentSymbol(FTR));
722
723
807k
      if (const SymbolicRegion *SymR = R->getSymbolicBase()) {
724
128k
        SymbolRef Sym = SymR->getSymbol();
725
128k
        QualType Ty = Sym->getType();
726
        // This change is needed for architectures with varying
727
        // pointer widths. See the amdgcn opencl reproducer with
728
        // this change as an example: solver-sym-simplification-ptr-bool.cl
729
128k
        if (!Ty->isReferenceType())
730
112k
          return VB.makeNonLoc(
731
112k
              Sym, BO_NE, VB.getBasicValueFactory().getZeroWithTypeSize(Ty),
732
112k
              CastTy);
733
128k
      }
734
      // Non-symbolic memory regions are always true.
735
695k
      return VB.makeTruthVal(true, CastTy);
736
807k
    }
737
738
210k
    const bool IsUnknownOriginalType = OriginalTy.isNull();
739
    // Try to cast to array
740
210k
    const auto *ArrayTy =
741
210k
        IsUnknownOriginalType
742
210k
            ? 
nullptr187k
743
210k
            : 
dyn_cast<ArrayType>(OriginalTy.getCanonicalType())22.7k
;
744
745
    // Pointer to integer.
746
210k
    if (CastTy->isIntegralOrEnumerationType()) {
747
417
      SVal Val = V;
748
      // Array to integer.
749
417
      if (ArrayTy) {
750
        // We will always decay to a pointer.
751
0
        QualType ElemTy = ArrayTy->getElementType();
752
0
        Val = VB.getStateManager().ArrayToPointer(V, ElemTy);
753
        // FIXME: Keep these here for now in case we decide soon that we
754
        // need the original decayed type.
755
        //    QualType elemTy = cast<ArrayType>(originalTy)->getElementType();
756
        //    QualType pointerTy = C.getPointerType(elemTy);
757
0
      }
758
417
      const unsigned BitWidth = Context.getIntWidth(CastTy);
759
417
      return VB.makeLocAsInteger(Val.castAs<Loc>(), BitWidth);
760
417
    }
761
762
    // Pointer to pointer.
763
209k
    if (Loc::isLocType(CastTy)) {
764
765
209k
      if (IsUnknownOriginalType) {
766
        // When retrieving symbolic pointer and expecting a non-void pointer,
767
        // wrap them into element regions of the expected type if necessary.
768
        // It is necessary to make sure that the retrieved value makes sense,
769
        // because there's no other cast in the AST that would tell us to cast
770
        // it to the correct pointer type. We might need to do that for non-void
771
        // pointers as well.
772
        // FIXME: We really need a single good function to perform casts for us
773
        // correctly every time we need it.
774
187k
        const MemRegion *R = V.getRegion();
775
187k
        if (CastTy->isPointerType() && 
!CastTy->isVoidPointerType()139k
) {
776
133k
          if (const auto *SR = dyn_cast<SymbolicRegion>(R)) {
777
64.7k
            QualType SRTy = SR->getSymbol()->getType();
778
779
64.7k
            auto HasSameUnqualifiedPointeeType = [](QualType ty1,
780
64.7k
                                                    QualType ty2) {
781
64.7k
              return ty1->getPointeeType().getCanonicalType().getTypePtr() ==
782
64.7k
                     ty2->getPointeeType().getCanonicalType().getTypePtr();
783
64.7k
            };
784
64.7k
            if (!HasSameUnqualifiedPointeeType(SRTy, CastTy)) {
785
17
              if (auto OptMemRegV = VB.getCastedMemRegionVal(SR, CastTy))
786
17
                return *OptMemRegV;
787
17
            }
788
64.7k
          }
789
133k
        }
790
        // Next fixes pointer dereference using type different from its initial
791
        // one. See PR37503 and PR49007 for details.
792
187k
        if (const auto *ER = dyn_cast<ElementRegion>(R)) {
793
58.7k
          if (auto OptMemRegV = VB.getCastedMemRegionVal(ER, CastTy))
794
58.7k
            return *OptMemRegV;
795
58.7k
        }
796
797
128k
        return V;
798
187k
      }
799
800
22.3k
      if (OriginalTy->isIntegralOrEnumerationType() ||
801
22.3k
          OriginalTy->isBlockPointerType() ||
802
22.3k
          
OriginalTy->isFunctionPointerType()22.2k
)
803
118
        return V;
804
805
      // Array to pointer.
806
22.2k
      if (ArrayTy) {
807
        // Are we casting from an array to a pointer?  If so just pass on
808
        // the decayed value.
809
13.3k
        if (CastTy->isPointerType() || 
CastTy->isReferenceType()0
) {
810
          // We will always decay to a pointer.
811
13.3k
          QualType ElemTy = ArrayTy->getElementType();
812
13.3k
          return VB.getStateManager().ArrayToPointer(V, ElemTy);
813
13.3k
        }
814
        // Are we casting from an array to an integer?  If so, cast the decayed
815
        // pointer value to an integer.
816
0
        assert(CastTy->isIntegralOrEnumerationType());
817
0
      }
818
819
      // Other pointer to pointer.
820
8.84k
      assert(Loc::isLocType(OriginalTy) || OriginalTy->isFunctionType() ||
821
8.84k
             CastTy->isReferenceType());
822
823
      // We get a symbolic function pointer for a dereference of a function
824
      // pointer, but it is of function type. Example:
825
826
      //  struct FPRec {
827
      //    void (*my_func)(int * x);
828
      //  };
829
      //
830
      //  int bar(int x);
831
      //
832
      //  int f1_a(struct FPRec* foo) {
833
      //    int x;
834
      //    (*foo->my_func)(&x);
835
      //    return bar(x)+1; // no-warning
836
      //  }
837
838
      // Get the result of casting a region to a different type.
839
8.84k
      const MemRegion *R = V.getRegion();
840
8.84k
      if (auto OptMemRegV = VB.getCastedMemRegionVal(R, CastTy))
841
8.83k
        return *OptMemRegV;
842
8.84k
    }
843
844
    // Pointer to whatever else.
845
    // FIXME: There can be gross cases where one casts the result of a
846
    // function (that returns a pointer) to some other value that happens to
847
    // fit within that pointer value.  We currently have no good way to model
848
    // such operations.  When this happens, the underlying operation is that
849
    // the caller is reasoning about bits.  Conceptually we are layering a
850
    // "view" of a location on top of those bits.  Perhaps we need to be more
851
    // lazy about mutual possible views, even on an SVal?  This may be
852
    // necessary for bit-level reasoning as well.
853
24
    return UnknownVal();
854
209k
  }
855
13
  SVal VisitNonLocCompoundVal(nonloc::CompoundVal V) {
856
    // Compound to whatever.
857
13
    return UnknownVal();
858
13
  }
859
89.1k
  SVal VisitNonLocConcreteInt(nonloc::ConcreteInt V) {
860
89.1k
    auto CastedValue = [V, this]() {
861
87.0k
      llvm::APSInt Value = V.getValue();
862
87.0k
      VB.getBasicValueFactory().getAPSIntType(CastTy).apply(Value);
863
87.0k
      return Value;
864
87.0k
    };
865
866
    // Integer to bool.
867
89.1k
    if (CastTy->isBooleanType())
868
1.92k
      return VB.makeTruthVal(V.getValue().getBoolValue(), CastTy);
869
870
    // Integer to pointer.
871
87.2k
    if (CastTy->isIntegralOrEnumerationType())
872
86.4k
      return VB.makeIntVal(CastedValue());
873
874
    // Integer to pointer.
875
780
    if (Loc::isLocType(CastTy))
876
555
      return VB.makeIntLocVal(CastedValue());
877
878
    // Pointer to whatever else.
879
225
    return UnknownVal();
880
780
  }
881
0
  SVal VisitNonLocLazyCompoundVal(nonloc::LazyCompoundVal V) {
882
    // LazyCompound to whatever.
883
0
    return UnknownVal();
884
0
  }
885
661
  SVal VisitNonLocLocAsInteger(nonloc::LocAsInteger V) {
886
661
    Loc L = V.getLoc();
887
888
    // Pointer as integer to bool.
889
661
    if (CastTy->isBooleanType())
890
      // Pass to Loc function.
891
1
      return Visit(L);
892
893
660
    const bool IsUnknownOriginalType = OriginalTy.isNull();
894
    // Pointer as integer to pointer.
895
660
    if (!IsUnknownOriginalType && 
Loc::isLocType(CastTy)84
&&
896
660
        
OriginalTy->isIntegralOrEnumerationType()30
) {
897
30
      if (const MemRegion *R = L.getAsRegion())
898
30
        if (auto OptMemRegV = VB.getCastedMemRegionVal(R, CastTy))
899
30
          return *OptMemRegV;
900
0
      return L;
901
30
    }
902
903
    // Pointer as integer with region to integer/pointer.
904
630
    const MemRegion *R = L.getAsRegion();
905
630
    if (!IsUnknownOriginalType && 
R54
) {
906
54
      if (CastTy->isIntegralOrEnumerationType())
907
52
        return VisitLocMemRegionVal(loc::MemRegionVal(R));
908
909
2
      if (Loc::isLocType(CastTy)) {
910
0
        assert(Loc::isLocType(OriginalTy) || OriginalTy->isFunctionType() ||
911
0
               CastTy->isReferenceType());
912
        // Delegate to store manager to get the result of casting a region to a
913
        // different type. If the MemRegion* returned is NULL, this expression
914
        // Evaluates to UnknownVal.
915
0
        if (auto OptMemRegV = VB.getCastedMemRegionVal(R, CastTy))
916
0
          return *OptMemRegV;
917
0
      }
918
576
    } else {
919
576
      if (Loc::isLocType(CastTy)) {
920
18
        if (IsUnknownOriginalType)
921
18
          return VisitLocMemRegionVal(loc::MemRegionVal(R));
922
0
        return L;
923
18
      }
924
925
558
      SymbolRef SE = nullptr;
926
558
      if (R) {
927
558
        if (const SymbolicRegion *SR =
928
558
                dyn_cast<SymbolicRegion>(R->StripCasts())) {
929
518
          SE = SR->getSymbol();
930
518
        }
931
558
      }
932
933
558
      if (!CastTy->isFloatingType() || 
!SE0
||
SE->getType()->isFloatingType()0
) {
934
        // FIXME: Correctly support promotions/truncations.
935
558
        const unsigned CastSize = Context.getIntWidth(CastTy);
936
558
        if (CastSize == V.getNumBits())
937
557
          return V;
938
939
1
        return VB.makeLocAsInteger(L, CastSize);
940
558
      }
941
558
    }
942
943
    // Pointer as integer to whatever else.
944
2
    return UnknownVal();
945
630
  }
946
241k
  SVal VisitNonLocSymbolVal(nonloc::SymbolVal V) {
947
241k
    SymbolRef SE = V.getSymbol();
948
949
241k
    const bool IsUnknownOriginalType = OriginalTy.isNull();
950
    // Symbol to bool.
951
241k
    if (!IsUnknownOriginalType && 
CastTy->isBooleanType()54.1k
) {
952
      // Non-float to bool.
953
23.3k
      if (Loc::isLocType(OriginalTy) ||
954
23.3k
          OriginalTy->isIntegralOrEnumerationType() ||
955
23.3k
          
OriginalTy->isMemberPointerType()2
) {
956
23.3k
        BasicValueFactory &BVF = VB.getBasicValueFactory();
957
23.3k
        return VB.makeNonLoc(SE, BO_NE, BVF.getValue(0, SE->getType()), CastTy);
958
23.3k
      }
959
217k
    } else {
960
      // Symbol to integer, float.
961
217k
      QualType T = Context.getCanonicalType(SE->getType());
962
963
      // Produce SymbolCast if CastTy and T are different integers.
964
      // NOTE: In the end the type of SymbolCast shall be equal to CastTy.
965
217k
      if (T->isIntegralOrUnscopedEnumerationType() &&
966
217k
          
CastTy->isIntegralOrUnscopedEnumerationType()217k
) {
967
217k
        AnalyzerOptions &Opts = VB.getStateManager()
968
217k
                                    .getOwningEngine()
969
217k
                                    .getAnalysisManager()
970
217k
                                    .getAnalyzerOptions();
971
        // If appropriate option is disabled, ignore the cast.
972
        // NOTE: ShouldSupportSymbolicIntegerCasts is `false` by default.
973
217k
        if (!Opts.ShouldSupportSymbolicIntegerCasts)
974
208k
          return V;
975
9.27k
        return simplifySymbolCast(V, CastTy);
976
217k
      }
977
189
      if (!Loc::isLocType(CastTy))
978
119
        if (!IsUnknownOriginalType || 
!CastTy->isFloatingType()70
||
979
119
            
T->isFloatingType()60
)
980
111
          return VB.makeNonLoc(SE, T, CastTy);
981
189
    }
982
983
    // Symbol to pointer and whatever else.
984
80
    return UnknownVal();
985
241k
  }
986
89
  SVal VisitNonLocPointerToMember(nonloc::PointerToMember V) {
987
    // Member pointer to whatever.
988
89
    return V;
989
89
  }
990
991
  /// Reduce cast expression by removing redundant intermediate casts.
992
  /// E.g.
993
  /// - (char)(short)(int x) -> (char)(int x)
994
  /// - (int)(int x) -> int x
995
  ///
996
  /// \param V -- SymbolVal, which pressumably contains SymbolCast or any symbol
997
  /// that is applicable for cast operation.
998
  /// \param CastTy -- QualType, which `V` shall be cast to.
999
  /// \return SVal with simplified cast expression.
1000
  /// \note: Currently only support integral casts.
1001
9.27k
  nonloc::SymbolVal simplifySymbolCast(nonloc::SymbolVal V, QualType CastTy) {
1002
    // We use seven conditions to recognize a simplification case.
1003
    // For the clarity let `CastTy` be `C`, SE->getType() - `T`, root type -
1004
    // `R`, prefix `u` for unsigned, `s` for signed, no prefix - any sign: E.g.
1005
    // (char)(short)(uint x)
1006
    //      ( sC )( sT  )( uR  x)
1007
    //
1008
    // C === R (the same type)
1009
    //  (char)(char x) -> (char x)
1010
    //  (long)(long x) -> (long x)
1011
    // Note: Comparisons operators below are for bit width.
1012
    // C == T
1013
    //  (short)(short)(int x) -> (short)(int x)
1014
    //  (int)(long)(char x) -> (int)(char x) (sizeof(long) == sizeof(int))
1015
    //  (long)(ullong)(char x) -> (long)(char x) (sizeof(long) ==
1016
    //  sizeof(ullong))
1017
    // C < T
1018
    //  (short)(int)(char x) -> (short)(char x)
1019
    //  (char)(int)(short x) -> (char)(short x)
1020
    //  (short)(int)(short x) -> (short x)
1021
    // C > T > uR
1022
    //  (int)(short)(uchar x) -> (int)(uchar x)
1023
    //  (uint)(short)(uchar x) -> (uint)(uchar x)
1024
    //  (int)(ushort)(uchar x) -> (int)(uchar x)
1025
    // C > sT > sR
1026
    //  (int)(short)(char x) -> (int)(char x)
1027
    //  (uint)(short)(char x) -> (uint)(char x)
1028
    // C > sT == sR
1029
    //  (int)(char)(char x) -> (int)(char x)
1030
    //  (uint)(short)(short x) -> (uint)(short x)
1031
    // C > uT == uR
1032
    //  (int)(uchar)(uchar x) -> (int)(uchar x)
1033
    //  (uint)(ushort)(ushort x) -> (uint)(ushort x)
1034
    //  (llong)(ulong)(uint x) -> (llong)(uint x) (sizeof(ulong) ==
1035
    //  sizeof(uint))
1036
1037
9.27k
    SymbolRef SE = V.getSymbol();
1038
9.27k
    QualType T = Context.getCanonicalType(SE->getType());
1039
1040
9.27k
    if (T == CastTy)
1041
4.18k
      return V;
1042
1043
5.08k
    if (!isa<SymbolCast>(SE))
1044
2.88k
      return VB.makeNonLoc(SE, T, CastTy);
1045
1046
2.20k
    SymbolRef RootSym = cast<SymbolCast>(SE)->getOperand();
1047
2.20k
    QualType RT = RootSym->getType().getCanonicalType();
1048
1049
    // FIXME support simplification from non-integers.
1050
2.20k
    if (!RT->isIntegralOrEnumerationType())
1051
1
      return VB.makeNonLoc(SE, T, CastTy);
1052
1053
2.20k
    BasicValueFactory &BVF = VB.getBasicValueFactory();
1054
2.20k
    APSIntType CTy = BVF.getAPSIntType(CastTy);
1055
2.20k
    APSIntType TTy = BVF.getAPSIntType(T);
1056
1057
2.20k
    const auto WC = CTy.getBitWidth();
1058
2.20k
    const auto WT = TTy.getBitWidth();
1059
1060
2.20k
    if (WC <= WT) {
1061
1.32k
      const bool isSameType = (RT == CastTy);
1062
1.32k
      if (isSameType)
1063
132
        return nonloc::SymbolVal(RootSym);
1064
1.18k
      return VB.makeNonLoc(RootSym, RT, CastTy);
1065
1.32k
    }
1066
1067
884
    APSIntType RTy = BVF.getAPSIntType(RT);
1068
884
    const auto WR = RTy.getBitWidth();
1069
884
    const bool UT = TTy.isUnsigned();
1070
884
    const bool UR = RTy.isUnsigned();
1071
1072
884
    if (((WT > WR) && 
(152
UR152
||
!UT96
)) ||
(780
(WT == WR)780
&&
(UT == UR)152
))
1073
144
      return VB.makeNonLoc(RootSym, RT, CastTy);
1074
1075
740
    return VB.makeNonLoc(SE, T, CastTy);
1076
884
  }
1077
};
1078
} // end anonymous namespace
1079
1080
/// Cast a given SVal to another SVal using given QualType's.
1081
/// \param V -- SVal that should be casted.
1082
/// \param CastTy -- QualType that V should be casted according to.
1083
/// \param OriginalTy -- QualType which is associated to V. It provides
1084
/// additional information about what type the cast performs from.
1085
/// \returns the most appropriate casted SVal.
1086
/// Note: Many cases don't use an exact OriginalTy. It can be extracted
1087
/// from SVal or the cast can performs unconditionaly. Always pass OriginalTy!
1088
/// It can be crucial in certain cases and generates different results.
1089
/// FIXME: If `OriginalTy.isNull()` is true, then cast performs based on CastTy
1090
/// only. This behavior is uncertain and should be improved.
1091
1.53M
SVal SValBuilder::evalCast(SVal V, QualType CastTy, QualType OriginalTy) {
1092
1.53M
  EvalCastVisitor TRV{*this, CastTy, OriginalTy};
1093
1.53M
  return TRV.Visit(V);
1094
1.53M
}