1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
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 | |
48 | |
49 | |
50 | void SValBuilder::anchor() {} |
51 | |
52 | DefinedOrUnknownSVal SValBuilder::makeZeroVal(QualType type) { |
53 | if (Loc::isLocType(type)) |
54 | return makeNull(); |
55 | |
56 | if (type->isIntegralOrEnumerationType()) |
57 | return makeIntVal(0, type); |
58 | |
59 | if (type->isArrayType() || type->isRecordType() || type->isVectorType() || |
60 | type->isAnyComplexType()) |
61 | return makeCompoundVal(type, BasicVals.getEmptySValList()); |
62 | |
63 | |
64 | return UnknownVal(); |
65 | } |
66 | |
67 | NonLoc SValBuilder::makeNonLoc(const SymExpr *lhs, BinaryOperator::Opcode op, |
68 | const llvm::APSInt& rhs, QualType type) { |
69 | |
70 | |
71 | |
72 | assert(lhs); |
73 | assert(!Loc::isLocType(type)); |
74 | return nonloc::SymbolVal(SymMgr.getSymIntExpr(lhs, op, rhs, type)); |
75 | } |
76 | |
77 | NonLoc SValBuilder::makeNonLoc(const llvm::APSInt& lhs, |
78 | BinaryOperator::Opcode op, const SymExpr *rhs, |
79 | QualType type) { |
80 | assert(rhs); |
81 | assert(!Loc::isLocType(type)); |
82 | return nonloc::SymbolVal(SymMgr.getIntSymExpr(lhs, op, rhs, type)); |
83 | } |
84 | |
85 | NonLoc SValBuilder::makeNonLoc(const SymExpr *lhs, BinaryOperator::Opcode op, |
86 | const SymExpr *rhs, QualType type) { |
87 | assert(lhs && rhs); |
88 | assert(!Loc::isLocType(type)); |
89 | return nonloc::SymbolVal(SymMgr.getSymSymExpr(lhs, op, rhs, type)); |
90 | } |
91 | |
92 | NonLoc SValBuilder::makeNonLoc(const SymExpr *operand, |
93 | QualType fromTy, QualType toTy) { |
94 | assert(operand); |
95 | assert(!Loc::isLocType(toTy)); |
96 | return nonloc::SymbolVal(SymMgr.getCastSymbol(operand, fromTy, toTy)); |
97 | } |
98 | |
99 | SVal SValBuilder::convertToArrayIndex(SVal val) { |
100 | if (val.isUnknownOrUndef()) |
101 | return val; |
102 | |
103 | |
104 | if (Optional<nonloc::ConcreteInt> CI = val.getAs<nonloc::ConcreteInt>()) { |
105 | const llvm::APSInt& I = CI->getValue(); |
106 | if (I.getBitWidth() == ArrayIndexWidth && I.isSigned()) |
107 | return val; |
108 | } |
109 | |
110 | return evalCastFromNonLoc(val.castAs<NonLoc>(), ArrayIndexTy); |
111 | } |
112 | |
113 | nonloc::ConcreteInt SValBuilder::makeBoolVal(const CXXBoolLiteralExpr *boolean){ |
114 | return makeTruthVal(boolean->getValue()); |
115 | } |
116 | |
117 | DefinedOrUnknownSVal |
118 | SValBuilder::getRegionValueSymbolVal(const TypedValueRegion *region) { |
119 | QualType T = region->getValueType(); |
120 | |
121 | if (T->isNullPtrType()) |
122 | return makeZeroVal(T); |
123 | |
124 | if (!SymbolManager::canSymbolicate(T)) |
125 | return UnknownVal(); |
126 | |
127 | SymbolRef sym = SymMgr.getRegionValueSymbol(region); |
128 | |
129 | if (Loc::isLocType(T)) |
130 | return loc::MemRegionVal(MemMgr.getSymbolicRegion(sym)); |
131 | |
132 | return nonloc::SymbolVal(sym); |
133 | } |
134 | |
135 | DefinedOrUnknownSVal SValBuilder::conjureSymbolVal(const void *SymbolTag, |
136 | const Expr *Ex, |
137 | const LocationContext *LCtx, |
138 | unsigned Count) { |
139 | QualType T = Ex->getType(); |
140 | |
141 | if (T->isNullPtrType()) |
142 | return makeZeroVal(T); |
143 | |
144 | |
145 | |
146 | QualType ExType = Ex->getType(); |
147 | if (Ex->isGLValue()) |
148 | T = LCtx->getAnalysisDeclContext()->getASTContext().getPointerType(ExType); |
149 | |
150 | return conjureSymbolVal(SymbolTag, Ex, LCtx, T, Count); |
151 | } |
152 | |
153 | DefinedOrUnknownSVal SValBuilder::conjureSymbolVal(const void *symbolTag, |
154 | const Expr *expr, |
155 | const LocationContext *LCtx, |
156 | QualType type, |
157 | unsigned count) { |
158 | if (type->isNullPtrType()) |
159 | return makeZeroVal(type); |
160 | |
161 | if (!SymbolManager::canSymbolicate(type)) |
162 | return UnknownVal(); |
163 | |
164 | SymbolRef sym = SymMgr.conjureSymbol(expr, LCtx, type, count, symbolTag); |
165 | |
166 | if (Loc::isLocType(type)) |
167 | return loc::MemRegionVal(MemMgr.getSymbolicRegion(sym)); |
168 | |
169 | return nonloc::SymbolVal(sym); |
170 | } |
171 | |
172 | DefinedOrUnknownSVal SValBuilder::conjureSymbolVal(const Stmt *stmt, |
173 | const LocationContext *LCtx, |
174 | QualType type, |
175 | unsigned visitCount) { |
176 | if (type->isNullPtrType()) |
177 | return makeZeroVal(type); |
178 | |
179 | if (!SymbolManager::canSymbolicate(type)) |
180 | return UnknownVal(); |
181 | |
182 | SymbolRef sym = SymMgr.conjureSymbol(stmt, LCtx, type, visitCount); |
183 | |
184 | if (Loc::isLocType(type)) |
185 | return loc::MemRegionVal(MemMgr.getSymbolicRegion(sym)); |
186 | |
187 | return nonloc::SymbolVal(sym); |
188 | } |
189 | |
190 | DefinedOrUnknownSVal |
191 | SValBuilder::getConjuredHeapSymbolVal(const Expr *E, |
192 | const LocationContext *LCtx, |
193 | unsigned VisitCount) { |
194 | QualType T = E->getType(); |
195 | assert(Loc::isLocType(T)); |
196 | assert(SymbolManager::canSymbolicate(T)); |
197 | if (T->isNullPtrType()) |
198 | return makeZeroVal(T); |
199 | |
200 | SymbolRef sym = SymMgr.conjureSymbol(E, LCtx, T, VisitCount); |
201 | return loc::MemRegionVal(MemMgr.getSymbolicHeapRegion(sym)); |
202 | } |
203 | |
204 | DefinedSVal SValBuilder::getMetadataSymbolVal(const void *symbolTag, |
205 | const MemRegion *region, |
206 | const Expr *expr, QualType type, |
207 | const LocationContext *LCtx, |
208 | unsigned count) { |
209 | (0) . __assert_fail ("SymbolManager..canSymbolicate(type) && \"Invalid metadata symbol type\"", "/home/seafit/code_projects/clang_source/clang/lib/StaticAnalyzer/Core/SValBuilder.cpp", 209, __PRETTY_FUNCTION__))" file_link="../../../../include/assert.h.html#88" macro="true">assert(SymbolManager::canSymbolicate(type) && "Invalid metadata symbol type"); |
210 | |
211 | SymbolRef sym = |
212 | SymMgr.getMetadataSymbol(region, expr, type, LCtx, count, symbolTag); |
213 | |
214 | if (Loc::isLocType(type)) |
215 | return loc::MemRegionVal(MemMgr.getSymbolicRegion(sym)); |
216 | |
217 | return nonloc::SymbolVal(sym); |
218 | } |
219 | |
220 | DefinedOrUnknownSVal |
221 | SValBuilder::getDerivedRegionValueSymbolVal(SymbolRef parentSymbol, |
222 | const TypedValueRegion *region) { |
223 | QualType T = region->getValueType(); |
224 | |
225 | if (T->isNullPtrType()) |
226 | return makeZeroVal(T); |
227 | |
228 | if (!SymbolManager::canSymbolicate(T)) |
229 | return UnknownVal(); |
230 | |
231 | SymbolRef sym = SymMgr.getDerivedSymbol(parentSymbol, region); |
232 | |
233 | if (Loc::isLocType(T)) |
234 | return loc::MemRegionVal(MemMgr.getSymbolicRegion(sym)); |
235 | |
236 | return nonloc::SymbolVal(sym); |
237 | } |
238 | |
239 | DefinedSVal SValBuilder::getMemberPointer(const DeclaratorDecl *DD) { |
240 | (DD) || isa(DD)", "/home/seafit/code_projects/clang_source/clang/lib/StaticAnalyzer/Core/SValBuilder.cpp", 240, __PRETTY_FUNCTION__))" file_link="../../../../include/assert.h.html#88" macro="true">assert(!DD || isa<CXXMethodDecl>(DD) || isa<FieldDecl>(DD)); |
241 | |
242 | if (const auto *MD = dyn_cast_or_null<CXXMethodDecl>(DD)) { |
243 | |
244 | |
245 | |
246 | |
247 | |
248 | if (MD->isStatic()) |
249 | return getFunctionPointer(MD); |
250 | } |
251 | |
252 | return nonloc::PointerToMember(DD); |
253 | } |
254 | |
255 | DefinedSVal SValBuilder::getFunctionPointer(const FunctionDecl *func) { |
256 | return loc::MemRegionVal(MemMgr.getFunctionCodeRegion(func)); |
257 | } |
258 | |
259 | DefinedSVal SValBuilder::getBlockPointer(const BlockDecl *block, |
260 | CanQualType locTy, |
261 | const LocationContext *locContext, |
262 | unsigned blockCount) { |
263 | const BlockCodeRegion *BC = |
264 | MemMgr.getBlockCodeRegion(block, locTy, locContext->getAnalysisDeclContext()); |
265 | const BlockDataRegion *BD = MemMgr.getBlockDataRegion(BC, locContext, |
266 | blockCount); |
267 | return loc::MemRegionVal(BD); |
268 | } |
269 | |
270 | |
271 | loc::MemRegionVal SValBuilder::getCXXThis(const CXXMethodDecl *D, |
272 | const StackFrameContext *SFC) { |
273 | return loc::MemRegionVal( |
274 | getRegionManager().getCXXThisRegion(D->getThisType(), SFC)); |
275 | } |
276 | |
277 | |
278 | loc::MemRegionVal SValBuilder::getCXXThis(const CXXRecordDecl *D, |
279 | const StackFrameContext *SFC) { |
280 | const Type *T = D->getTypeForDecl(); |
281 | QualType PT = getContext().getPointerType(QualType(T, 0)); |
282 | return loc::MemRegionVal(getRegionManager().getCXXThisRegion(PT, SFC)); |
283 | } |
284 | |
285 | Optional<SVal> SValBuilder::getConstantVal(const Expr *E) { |
286 | E = E->IgnoreParens(); |
287 | |
288 | switch (E->getStmtClass()) { |
289 | |
290 | |
291 | case Stmt::AddrLabelExprClass: |
292 | return makeLoc(cast<AddrLabelExpr>(E)); |
293 | |
294 | case Stmt::CXXScalarValueInitExprClass: |
295 | case Stmt::ImplicitValueInitExprClass: |
296 | return makeZeroVal(E->getType()); |
297 | |
298 | case Stmt::ObjCStringLiteralClass: { |
299 | const auto *SL = cast<ObjCStringLiteral>(E); |
300 | return makeLoc(getRegionManager().getObjCStringRegion(SL)); |
301 | } |
302 | |
303 | case Stmt::StringLiteralClass: { |
304 | const auto *SL = cast<StringLiteral>(E); |
305 | return makeLoc(getRegionManager().getStringRegion(SL)); |
306 | } |
307 | |
308 | |
309 | |
310 | case Stmt::CharacterLiteralClass: { |
311 | const auto *C = cast<CharacterLiteral>(E); |
312 | return makeIntVal(C->getValue(), C->getType()); |
313 | } |
314 | |
315 | case Stmt::CXXBoolLiteralExprClass: |
316 | return makeBoolVal(cast<CXXBoolLiteralExpr>(E)); |
317 | |
318 | case Stmt::TypeTraitExprClass: { |
319 | const auto *TE = cast<TypeTraitExpr>(E); |
320 | return makeTruthVal(TE->getValue(), TE->getType()); |
321 | } |
322 | |
323 | case Stmt::IntegerLiteralClass: |
324 | return makeIntVal(cast<IntegerLiteral>(E)); |
325 | |
326 | case Stmt::ObjCBoolLiteralExprClass: |
327 | return makeBoolVal(cast<ObjCBoolLiteralExpr>(E)); |
328 | |
329 | case Stmt::CXXNullPtrLiteralExprClass: |
330 | return makeNull(); |
331 | |
332 | case Stmt::CStyleCastExprClass: |
333 | case Stmt::CXXFunctionalCastExprClass: |
334 | case Stmt::CXXConstCastExprClass: |
335 | case Stmt::CXXReinterpretCastExprClass: |
336 | case Stmt::CXXStaticCastExprClass: |
337 | case Stmt::ImplicitCastExprClass: { |
338 | const auto *CE = cast<CastExpr>(E); |
339 | switch (CE->getCastKind()) { |
340 | default: |
341 | break; |
342 | case CK_ArrayToPointerDecay: |
343 | case CK_IntegralToPointer: |
344 | case CK_NoOp: |
345 | case CK_BitCast: { |
346 | const Expr *SE = CE->getSubExpr(); |
347 | Optional<SVal> Val = getConstantVal(SE); |
348 | if (!Val) |
349 | return None; |
350 | return evalCast(*Val, CE->getType(), SE->getType()); |
351 | } |
352 | } |
353 | |
354 | LLVM_FALLTHROUGH; |
355 | } |
356 | |
357 | |
358 | default: { |
359 | |
360 | if (E->isGLValue()) |
361 | return None; |
362 | |
363 | ASTContext &Ctx = getContext(); |
364 | Expr::EvalResult Result; |
365 | if (E->EvaluateAsInt(Result, Ctx)) |
366 | return makeIntVal(Result.Val.getInt()); |
367 | |
368 | if (Loc::isLocType(E->getType())) |
369 | if (E->isNullPointerConstant(Ctx, Expr::NPC_ValueDependentIsNotNull)) |
370 | return makeNull(); |
371 | |
372 | return None; |
373 | } |
374 | } |
375 | } |
376 | |
377 | SVal SValBuilder::makeSymExprValNN(BinaryOperator::Opcode Op, |
378 | NonLoc LHS, NonLoc RHS, |
379 | QualType ResultTy) { |
380 | const SymExpr *symLHS = LHS.getAsSymExpr(); |
381 | const SymExpr *symRHS = RHS.getAsSymExpr(); |
382 | |
383 | |
384 | |
385 | const unsigned MaxComp = StateMgr.getOwningEngine() |
386 | .getAnalysisManager() |
387 | .options.MaxSymbolComplexity; |
388 | |
389 | if (symLHS && symRHS && |
390 | (symLHS->computeComplexity() + symRHS->computeComplexity()) < MaxComp) |
391 | return makeNonLoc(symLHS, Op, symRHS, ResultTy); |
392 | |
393 | if (symLHS && symLHS->computeComplexity() < MaxComp) |
394 | if (Optional<nonloc::ConcreteInt> rInt = RHS.getAs<nonloc::ConcreteInt>()) |
395 | return makeNonLoc(symLHS, Op, rInt->getValue(), ResultTy); |
396 | |
397 | if (symRHS && symRHS->computeComplexity() < MaxComp) |
398 | if (Optional<nonloc::ConcreteInt> lInt = LHS.getAs<nonloc::ConcreteInt>()) |
399 | return makeNonLoc(lInt->getValue(), Op, symRHS, ResultTy); |
400 | |
401 | return UnknownVal(); |
402 | } |
403 | |
404 | SVal SValBuilder::evalBinOp(ProgramStateRef state, BinaryOperator::Opcode op, |
405 | SVal lhs, SVal rhs, QualType type) { |
406 | if (lhs.isUndef() || rhs.isUndef()) |
407 | return UndefinedVal(); |
408 | |
409 | if (lhs.isUnknown() || rhs.isUnknown()) |
410 | return UnknownVal(); |
411 | |
412 | if (lhs.getAs<nonloc::LazyCompoundVal>() || |
413 | rhs.getAs<nonloc::LazyCompoundVal>()) { |
414 | return UnknownVal(); |
415 | } |
416 | |
417 | if (Optional<Loc> LV = lhs.getAs<Loc>()) { |
418 | if (Optional<Loc> RV = rhs.getAs<Loc>()) |
419 | return evalBinOpLL(state, op, *LV, *RV, type); |
420 | |
421 | return evalBinOpLN(state, op, *LV, rhs.castAs<NonLoc>(), type); |
422 | } |
423 | |
424 | if (Optional<Loc> RV = rhs.getAs<Loc>()) { |
425 | |
426 | |
427 | assert(op == BO_Add); |
428 | |
429 | |
430 | return evalBinOpLN(state, op, *RV, lhs.castAs<NonLoc>(), type); |
431 | } |
432 | |
433 | return evalBinOpNN(state, op, lhs.castAs<NonLoc>(), rhs.castAs<NonLoc>(), |
434 | type); |
435 | } |
436 | |
437 | ConditionTruthVal SValBuilder::areEqual(ProgramStateRef state, SVal lhs, |
438 | SVal rhs) { |
439 | return state->isNonNull(evalEQ(state, lhs, rhs)); |
440 | } |
441 | |
442 | SVal SValBuilder::evalEQ(ProgramStateRef state, SVal lhs, SVal rhs) { |
443 | return evalBinOp(state, BO_EQ, lhs, rhs, getConditionType()); |
444 | } |
445 | |
446 | DefinedOrUnknownSVal SValBuilder::evalEQ(ProgramStateRef state, |
447 | DefinedOrUnknownSVal lhs, |
448 | DefinedOrUnknownSVal rhs) { |
449 | return evalEQ(state, static_cast<SVal>(lhs), static_cast<SVal>(rhs)) |
450 | .castAs<DefinedOrUnknownSVal>(); |
451 | } |
452 | |
453 | |
454 | |
455 | |
456 | static bool shouldBeModeledWithNoOp(ASTContext &Context, QualType ToTy, |
457 | QualType FromTy) { |
458 | while (Context.UnwrapSimilarTypes(ToTy, FromTy)) { |
459 | Qualifiers Quals1, Quals2; |
460 | ToTy = Context.getUnqualifiedArrayType(ToTy, Quals1); |
461 | FromTy = Context.getUnqualifiedArrayType(FromTy, Quals2); |
462 | |
463 | |
464 | |
465 | Quals1.removeCVRQualifiers(); |
466 | Quals2.removeCVRQualifiers(); |
467 | if (Quals1 != Quals2) |
468 | return false; |
469 | } |
470 | |
471 | |
472 | |
473 | |
474 | |
475 | |
476 | |
477 | if (ToTy->isVoidType()) |
478 | return true; |
479 | |
480 | if (ToTy != FromTy) |
481 | return false; |
482 | |
483 | return true; |
484 | } |
485 | |
486 | |
487 | |
488 | |
489 | SVal SValBuilder::evalIntegralCast(ProgramStateRef state, SVal val, |
490 | QualType castTy, QualType originalTy) { |
491 | |
492 | if (getContext().getTypeSize(castTy) >= getContext().getTypeSize(originalTy)) |
493 | return evalCast(val, castTy, originalTy); |
494 | |
495 | const SymExpr *se = val.getAsSymbolicExpression(); |
496 | if (!se) |
497 | return evalCast(val, castTy, originalTy); |
498 | |
499 | |
500 | APSIntType ToType(getContext().getTypeSize(castTy), |
501 | castTy->isUnsignedIntegerType()); |
502 | llvm::APSInt ToTypeMax = ToType.getMaxValue(); |
503 | NonLoc ToTypeMaxVal = |
504 | makeIntVal(ToTypeMax.isUnsigned() ? ToTypeMax.getZExtValue() |
505 | : ToTypeMax.getSExtValue(), |
506 | castTy) |
507 | .castAs<NonLoc>(); |
508 | |
509 | |
510 | NonLoc FromVal = val.castAs<NonLoc>(); |
511 | QualType CmpTy = getConditionType(); |
512 | NonLoc CompVal = |
513 | evalBinOpNN(state, BO_LE, FromVal, ToTypeMaxVal, CmpTy).castAs<NonLoc>(); |
514 | ProgramStateRef IsNotTruncated, IsTruncated; |
515 | std::tie(IsNotTruncated, IsTruncated) = state->assume(CompVal); |
516 | if (!IsNotTruncated && IsTruncated) { |
517 | |
518 | NonLoc CastVal = makeNonLoc(se, originalTy, castTy); |
519 | return CastVal; |
520 | } |
521 | return evalCast(val, castTy, originalTy); |
522 | } |
523 | |
524 | |
525 | SVal SValBuilder::evalCast(SVal val, QualType castTy, QualType originalTy) { |
526 | castTy = Context.getCanonicalType(castTy); |
527 | originalTy = Context.getCanonicalType(originalTy); |
528 | if (val.isUnknownOrUndef() || castTy == originalTy) |
529 | return val; |
530 | |
531 | if (castTy->isBooleanType()) { |
532 | if (val.isUnknownOrUndef()) |
533 | return val; |
534 | if (val.isConstant()) |
535 | return makeTruthVal(!val.isZeroConstant(), castTy); |
536 | if (!Loc::isLocType(originalTy) && |
537 | !originalTy->isIntegralOrEnumerationType() && |
538 | !originalTy->isMemberPointerType()) |
539 | return UnknownVal(); |
540 | if (SymbolRef Sym = val.getAsSymbol(true)) { |
541 | BasicValueFactory &BVF = getBasicValueFactory(); |
542 | |
543 | |
544 | return makeNonLoc(Sym, BO_NE, BVF.getValue(0, Sym->getType()), castTy); |
545 | } |
546 | |
547 | if (Optional<Loc> L = val.getAs<Loc>()) |
548 | return evalCastFromLoc(*L, castTy); |
549 | |
550 | Loc L = val.castAs<nonloc::LocAsInteger>().getLoc(); |
551 | return evalCastFromLoc(L, castTy); |
552 | } |
553 | |
554 | |
555 | if (!castTy->isVariableArrayType() && !originalTy->isVariableArrayType()) |
556 | if (shouldBeModeledWithNoOp(Context, Context.getPointerType(castTy), |
557 | Context.getPointerType(originalTy))) |
558 | return val; |
559 | |
560 | |
561 | if (castTy->isIntegralOrEnumerationType() && Loc::isLocType(originalTy)) |
562 | return evalCastFromLoc(val.castAs<Loc>(), castTy); |
563 | |
564 | |
565 | if (Loc::isLocType(castTy) && originalTy->isIntegralOrEnumerationType()) { |
566 | if (Optional<nonloc::LocAsInteger> LV = val.getAs<nonloc::LocAsInteger>()) { |
567 | if (const MemRegion *R = LV->getLoc().getAsRegion()) { |
568 | StoreManager &storeMgr = StateMgr.getStoreManager(); |
569 | R = storeMgr.castRegion(R, castTy); |
570 | return R ? SVal(loc::MemRegionVal(R)) : UnknownVal(); |
571 | } |
572 | return LV->getLoc(); |
573 | } |
574 | return dispatchCast(val, castTy); |
575 | } |
576 | |
577 | |
578 | if (originalTy->isBlockPointerType() || originalTy->isFunctionPointerType()) { |
579 | assert(Loc::isLocType(castTy)); |
580 | return val; |
581 | } |
582 | |
583 | |
584 | if (const auto *arrayT = |
585 | dyn_cast<ArrayType>(originalTy.getCanonicalType())) { |
586 | |
587 | QualType elemTy = arrayT->getElementType(); |
588 | val = StateMgr.ArrayToPointer(val.castAs<Loc>(), elemTy); |
589 | |
590 | |
591 | |
592 | if (castTy->isPointerType() || castTy->isReferenceType()) |
593 | return val; |
594 | |
595 | |
596 | |
597 | isIntegralOrEnumerationType()", "/home/seafit/code_projects/clang_source/clang/lib/StaticAnalyzer/Core/SValBuilder.cpp", 597, __PRETTY_FUNCTION__))" file_link="../../../../include/assert.h.html#88" macro="true">assert(castTy->isIntegralOrEnumerationType()); |
598 | |
599 | |
600 | |
601 | |
602 | |
603 | return evalCastFromLoc(val.castAs<Loc>(), castTy); |
604 | } |
605 | |
606 | |
607 | if (const MemRegion *R = val.getAsRegion()) { |
608 | |
609 | if (castTy->isIntegralOrEnumerationType()) |
610 | return evalCastFromLoc(loc::MemRegionVal(R), castTy); |
611 | |
612 | |
613 | |
614 | if (!Loc::isLocType(castTy)) { |
615 | |
616 | |
617 | |
618 | |
619 | |
620 | |
621 | |
622 | |
623 | return UnknownVal(); |
624 | } |
625 | |
626 | |
627 | |
628 | |
629 | |
630 | |
631 | |
632 | |
633 | |
634 | |
635 | |
636 | |
637 | |
638 | |
639 | |
640 | |
641 | isFunctionType() || originalTy->isBlockPointerType() || castTy->isReferenceType()", "/home/seafit/code_projects/clang_source/clang/lib/StaticAnalyzer/Core/SValBuilder.cpp", 642, __PRETTY_FUNCTION__))" file_link="../../../../include/assert.h.html#88" macro="true">assert(Loc::isLocType(originalTy) || originalTy->isFunctionType() || |
642 | isFunctionType() || originalTy->isBlockPointerType() || castTy->isReferenceType()", "/home/seafit/code_projects/clang_source/clang/lib/StaticAnalyzer/Core/SValBuilder.cpp", 642, __PRETTY_FUNCTION__))" file_link="../../../../include/assert.h.html#88" macro="true"> originalTy->isBlockPointerType() || castTy->isReferenceType()); |
643 | |
644 | StoreManager &storeMgr = StateMgr.getStoreManager(); |
645 | |
646 | |
647 | |
648 | |
649 | R = storeMgr.castRegion(R, castTy); |
650 | return R ? SVal(loc::MemRegionVal(R)) : UnknownVal(); |
651 | } |
652 | |
653 | return dispatchCast(val, castTy); |
654 | } |
655 | |