Bug Summary

File:build/llvm-toolchain-snapshot-15~++20220420111733+e13d2efed663/clang/lib/StaticAnalyzer/Core/SValBuilder.cpp
Warning:line 487, column 10
Called C++ object pointer is null

Annotated Source Code

Press '?' to see keyboard shortcuts

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