clang: lib/StaticAnalyzer/Core/Store.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
31#include "llvm/ADT/APSInt.h"
32#include "llvm/ADT/STLExtras.h"
33#include "llvm/Support/ErrorHandling.h"
34#include
35#include
36#include
37
38using namespace clang;
39using namespace ento;
40
44
48
50 Call.getInitialStackFrameContents(LCtx, InitialBindings);
51
52 for (const auto &[Location, Val] : InitialBindings) {
53 Store S = Result.ResultingStore.getStore();
57 }
58
60}
61
68
72 assert(.isNull());
73 return MRMgr.getElementRegion(T, idx, R, Ctx);
74}
75
79
80
83
85
86
87
88
90 return R;
91
92
93
94 return std::nullopt;
95 }
96
97
98
100 QualType CanonPointeeTy = Ctx.getCanonicalType(PointeeTy);
102
103
104 if (CanonPointeeTy == Ctx.VoidTy)
105 return R;
106
108 if (const auto *TR = dyn_cast(R)) {
109 QualType ObjTy = Ctx.getCanonicalType(TR->getValueType());
111 return true;
112 }
113 return false;
114 };
115
116
117 if (R->isBoundable() && IsSameRegionType(R, CanonPointeeTy))
118 return R;
119
120
122 case MemRegion::CXXThisRegionKind:
123 case MemRegion::CodeSpaceRegionKind:
124 case MemRegion::StackLocalsSpaceRegionKind:
125 case MemRegion::StackArgumentsSpaceRegionKind:
126 case MemRegion::HeapSpaceRegionKind:
127 case MemRegion::UnknownSpaceRegionKind:
128 case MemRegion::StaticGlobalSpaceRegionKind:
129 case MemRegion::GlobalInternalSpaceRegionKind:
130 case MemRegion::GlobalSystemSpaceRegionKind:
131 case MemRegion::GlobalImmutableSpaceRegionKind: {
132 llvm_unreachable("Invalid region cast");
133 }
134
135 case MemRegion::FunctionCodeRegionKind:
136 case MemRegion::BlockCodeRegionKind:
137 case MemRegion::BlockDataRegionKind:
138 case MemRegion::StringRegionKind:
139
140 case MemRegion::SymbolicRegionKind:
141 case MemRegion::AllocaRegionKind:
142 case MemRegion::CompoundLiteralRegionKind:
143 case MemRegion::FieldRegionKind:
144 case MemRegion::ObjCIvarRegionKind:
145 case MemRegion::ObjCStringRegionKind:
146 case MemRegion::NonParamVarRegionKind:
147 case MemRegion::ParamVarRegionKind:
148 case MemRegion::CXXTempObjectRegionKind:
149 case MemRegion::CXXLifetimeExtendedObjectRegionKind:
150 case MemRegion::CXXBaseObjectRegionKind:
151 case MemRegion::CXXDerivedObjectRegionKind:
153
154 case MemRegion::ElementRegionKind: {
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
177
178
179
180 if (!baseR)
181 return std::nullopt;
182
184
186
187
188
189 if (IsSameRegionType(baseR, CanonPointeeTy))
190 return baseR;
191
193 }
194
195
196
197
198
199
200
201
202 int64_t newIndex = 0;
203 const MemRegion *newSuperR = nullptr;
204
205
207
208 CharUnits pointeeTySize = Ctx.getTypeSizeInChars(PointeeTy);
209 if (!pointeeTySize.isZero()) {
210
211
212
214 newIndex = off / pointeeTySize;
215 newSuperR = baseR;
216 }
217 }
218 }
219
220 if (!newSuperR) {
221
222
225 }
226
228 }
229 }
230
231 llvm_unreachable("unreachable");
232}
233
235 const MemRegion *MR = V.getAsRegion();
236 if (!MR)
237 return true;
238
239 const auto *TVR = dyn_cast(MR);
240 if (!TVR)
241 return true;
242
243 const CXXRecordDecl *RD = TVR->getValueType()->getAsCXXRecordDecl();
244 if (!RD)
245 return true;
246
250
252}
253
255
256
259
260
264 }
266}
267
269
271 for (const auto &I : Path)
273 I.Base->isVirtual());
275}
276
278 bool IsVirtual) {
280 if (!DerivedReg)
281 return Derived;
282
283 const CXXRecordDecl *BaseDecl = BaseType->getPointeeCXXRecordDecl();
284 if (!BaseDecl)
285 BaseDecl = BaseType->getAsCXXRecordDecl();
286 assert(BaseDecl && "not a C++ object?");
287
288 if (const auto *AlreadyDerivedReg =
289 dyn_cast(DerivedReg)) {
290 if (const auto *SR =
291 dyn_cast(AlreadyDerivedReg->getSuperRegion()))
292 if (SR->getSymbol()->getType()->getPointeeCXXRecordDecl() == BaseDecl)
294
295 DerivedReg = AlreadyDerivedReg->getSuperRegion();
296 }
297
298 const MemRegion *BaseReg = MRMgr.getCXXBaseObjectRegion(
300
302}
303
304
305
306
307
308
309
311 if (const auto *TVR = dyn_cast(MR))
312 return TVR->getValueType()->getAsCXXRecordDecl();
313 if (const auto *SR = dyn_cast(MR))
314 return SR->getSymbol()->getType()->getPointeeCXXRecordDecl();
315 return nullptr;
316}
317
321 if (!MR)
323
324
326 assert(!TargetType.isNull());
328 if (!TargetClass && !TargetType->isVoidType())
330
331
332
334
335 if (MRClass == TargetClass)
337
338
339
340
341 if (!TargetType->isVoidType() && MRClass->hasDefinition()) {
342
343
344 CXXBasePaths Paths(false, true,
345 false);
346 if (MRClass->isDerivedFrom(TargetClass, Paths))
348 }
349
350 if (const auto *BaseR = dyn_cast(MR)) {
351
352 MR = BaseR->getSuperRegion();
353 continue;
354 }
355
356
359
360
361
362
363
364
365
366
367
369 if (Uncasted == MR) {
370
371
372
373 break;
374 }
375
376 MR = Uncasted;
377 }
378
379
380
381
382
383
384 if (const auto *SR = dyn_cast(MR)) {
385 QualType T = SR->getSymbol()->getType();
386 const CXXRecordDecl *SourceClass = T->getPointeeCXXRecordDecl();
387 if (TargetClass && SourceClass && TargetClass->isDerivedFrom(SourceClass))
389 MRMgr.getCXXDerivedObjectRegion(TargetClass, SR));
391 }
392
393
395 return std::nullopt;
396
398}
399
400SVal StoreManager::getLValueFieldOrIvar(const Decl *D, SVal Base) {
401 if (Base.isUnknownOrUndef())
403
405 const SubRegion* BaseR = nullptr;
406
407 switch (BaseL.getKind()) {
408 case loc::MemRegionValKind:
410 break;
411
412 case loc::GotoLabelKind:
413
415
416 case loc::ConcreteIntKind:
417
418
419
420
421
422
423
424
425
426
428
429 default:
430 llvm_unreachable("Unhandled Base.");
431 }
432
433
434
435 if (const auto *ID = dyn_cast(D))
437
439}
440
442 return getLValueFieldOrIvar(decl, base);
443}
444
447
448
449
450 if (Offset.isZeroConstant()) {
454 if (!PointeeTy.isNull() &&
457 }
458 }
459
460
461
462
463
466
469
472
473
474 const auto *ElemR = dyn_cast(BaseRegion);
475
476
477 auto Off = svalBuilder.convertToArrayIndex(Offset).getAs<NonLoc>();
478 if (!Off) {
479
480
481
482
483
485 }
486
487 Offset = Off.value();
488
489 if (!ElemR) {
490
491
492
493
494
495
496
498 BaseRegion, Ctx));
499 }
500
501 SVal BaseIdx = ElemR->getIndex();
502
505
506 const llvm::APSInt &BaseIdxI =
508
509
510
511
514 elementType, Offset, cast(ElemR->getSuperRegion()), Ctx));
515
516 const llvm::APSInt& OffI = Offset.castAs<nonloc::ConcreteInt>().getValue();
517 assert(BaseIdxI.isSigned());
518
519
521 OffI));
522
523
527}
528
530
536 if (!SymV || SymV != Sym)
537 return true;
538
539 if (Binding) {
540 First = false;
541 return false;
542 }
543 else
544 Binding = R;
545
546 return true;
547}
Defines the clang::ASTContext interface.
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate....
Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified.
static bool regionMatchesCXXRecordType(SVal V, QualType Ty)
Definition Store.cpp:234
static const CXXRecordDecl * getCXXRecordType(const MemRegion *MR)
Returns the static type of the given region, if it represents a C++ class object.
Definition Store.cpp:310
C Language Family Type Representation.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Represents a path from a specific derived class (which is not represented as part of the path) to a p...
BasePaths - Represents the set of paths from a derived class to one of its (direct or indirect) bases...
Represents a base class of a C++ class.
Represents a C++ struct/union/class.
CXXRecordDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
bool isDerivedFrom(const CXXRecordDecl *Base) const
Determine whether this class is derived from the class Base.
CastExpr - Base class for type casts, including both implicit casts (ImplicitCastExpr) and explicit c...
CharUnits - This is an opaque type for sizes expressed in character units.
bool isZero() const
isZero - Test whether the quantity equals zero.
QuantityType getQuantity() const
getQuantity - Get the raw integer representation of this quantity.
bool isMultipleOf(CharUnits N) const
Test whether this is a multiple of the other value.
Decl - This represents one declaration (or definition), e.g.
ObjCIvarDecl - Represents an ObjC instance variable.
A (possibly-)qualified type.
QualType getLocalUnqualifiedType() const
Return this type with all of the instance-specific qualifiers removed, but without removing any quali...
bool isNull() const
Return true if this QualType doesn't point to a type yet.
QualType getCanonicalType() const
It represents a stack frame of the call stack (based on CallEvent).
bool isBlockPointerType() const
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
const CXXRecordDecl * getPointeeCXXRecordDecl() const
If this is a pointer or reference to a RecordType, return the CXXRecordDecl that the type refers to.
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
bool isIncompleteType(NamedDecl **Def=nullptr) const
Types are partitioned into 3 broad categories (C99 6.2.5p1): object types, function types,...
bool isObjCObjectPointerType() const
Represents an abstract call to a function or method along a particular path.
ElementRegion is used to represent both array elements and casts.
RegionRawOffset getAsArrayOffset() const
Compute the offset within the array. The array might also be a subobject.
const FieldRegion * getFieldRegion(const FieldDecl *FD, const SubRegion *SuperRegion)
getFieldRegion - Retrieve or create the memory region associated with a specified FieldDecl.
const ObjCIvarRegion * getObjCIvarRegion(const ObjCIvarDecl *ivd, const SubRegion *superRegion)
getObjCIvarRegion - Retrieve or create the memory region associated with a specified Objective-c inst...
MemRegion - The root abstract class for all memory regions.
virtual bool isBoundable() const
LLVM_ATTRIBUTE_RETURNS_NONNULL const MemRegion * StripCasts(bool StripBaseAndDerivedCasts=true) const
CharUnits getOffset() const
const MemRegion * getRegion() const
SVal - This represents a symbolic expression, which can be either an L-value or an R-value.
SymbolRef getAsLocSymbol(bool IncludeBaseRegions=false) const
If this SVal is a location and wraps a symbol, return that SymbolRef.
const MemRegion * getAsRegion() const
T castAs() const
Convert to the specified SVal type, asserting that this SVal is of the desired type.
virtual ~BindingsHandler()
bool HandleBinding(StoreManager &SMgr, Store store, const MemRegion *R, SVal val) override
Definition Store.cpp:531
SVal evalDerivedToBase(SVal Derived, const CastExpr *Cast)
Evaluates a chain of derived-to-base casts through the path specified in Cast.
Definition Store.cpp:254
ProgramStateManager & StateMgr
SValBuilder & getSValBuilder()
MemRegionManager & getRegionManager()
getRegionManager - Returns the internal RegionManager object that is used to query and manipulate Mem...
std::optional< SVal > evalBaseToDerived(SVal Base, QualType DerivedPtrType)
Attempts to do a down cast.
Definition Store.cpp:318
BindResult enterStackFrame(Store store, const CallEvent &Call, const StackFrameContext *CalleeCtx)
enterStackFrame - Let the StoreManager to do something when execution engine is about to execute into...
Definition Store.cpp:45
const ElementRegion * MakeElementRegion(const SubRegion *baseRegion, QualType pointeeTy, uint64_t index=0)
Definition Store.cpp:62
MemRegionManager & MRMgr
MRMgr - Manages region objects associated with this StoreManager.
SValBuilder & svalBuilder
virtual SVal getLValueIvar(const ObjCIvarDecl *decl, SVal base)
Definition Store.cpp:441
StoreManager(ProgramStateManager &stateMgr)
Definition Store.cpp:41
const ElementRegion * GetElementZeroRegion(const SubRegion *R, QualType T)
Definition Store.cpp:69
virtual SVal getLValueElement(QualType elementType, NonLoc offset, SVal Base)
Definition Store.cpp:445
std::optional< const MemRegion * > castRegion(const MemRegion *region, QualType CastToTy)
castRegion - Used by ExprEngine::VisitCast to handle casts from a MemRegion* to a specific location t...
Definition Store.cpp:76
SubRegion - A region that subsets another larger region.
LLVM_ATTRIBUTE_RETURNS_NONNULL const MemRegion * getRegion() const
Get the underlining region.
Value representing integer constant.
const internal::VariadicAllOfMatcher< Decl > decl
Matches declarations.
const SymExpr * SymbolRef
const void * Store
Store - This opaque type encapsulates an immutable mapping from locations to values.
The JSON file list parser is used to communicate input to InstallAPI.
bool isa(CodeGen::Address addr)
@ Bind
'bind' clause, allowed on routine constructs.
@ Result
The result type of a method or function.
const FunctionProtoType * T
U cast(CodeGen::Address addr)
llvm::SmallVector< SVal, 0 > FailedToBindValues