clang: lib/StaticAnalyzer/Checkers/DynamicTypePropagation.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
34#include "llvm/ADT/STLExtras.h"
35#include
36
37using namespace clang;
38using namespace ento;
39
40
41
42
43
44
45
46
47
50
51namespace {
52class DynamicTypePropagation
53 : public CheckerFamily<check::PreCall, check::PostCall, check::DeadSymbols,
54 check::PostStmt,
55 check::PostStmt, check::PreObjCMessage,
56 check::PostObjCMessage> {
57public:
58
59
60
63
64private:
65
68
72
74 public:
75 GenericsBugVisitor(SymbolRef S) : Sym(S) {}
76
77 void Profile(llvm::FoldingSetNodeID &ID) const override {
78 static int X = 0;
79 ID.AddPointer(&X);
80 ID.AddPointer(Sym);
81 }
82
86
87 private:
88
90 };
91
95 const Stmt *ReportedNode = nullptr) const;
96
97public:
105
106
107 StringRef getDebugTag() const override { return "DynamicTypePropagation"; }
108};
109
111 if (const auto *PointerType = dyn_cast(Type)) {
112 return PointerType->getObjectType()->isObjCClass();
113 }
114 return false;
115}
116
117struct RuntimeType {
119 bool Precise = false;
120
121 operator bool() const { return Type != nullptr; }
122};
123
124RuntimeType inferReceiverType(const ObjCMethodCall &Message,
126 const ObjCMessageExpr *MessageExpr = Message.getOriginExpr();
127
128
129
130
131
132
133
136 true};
137 }
138
139
140
141
142
143
146 true};
147 }
148
149
150
151
152
153
155 if (const auto *ObjTy =
157 return {ObjTy->getObjectType(), true};
158 }
159
161
162 if (!RecE)
163 return {};
164
165
166
168 SVal ReceiverSVal = C.getSVal(RecE);
170
174 }
175 }
176
178 if (InferredType.isNull()) {
179 InferredType = ReceiverSymbol->getType();
180 }
181
182
183
184 if (isObjCClassType(InferredType)) {
185
188
189
191 }
192
193 SVal SelfSVal = State->getSelfSVal(C.getLocationContext());
194
195
196
197 if (ReceiverSVal == SelfSVal) {
198
199
201 dyn_cast(C.getStackFrame()->getDecl()))
202 if (const ObjCObjectType *ObjTy = dyn_cast(
203 MD->getClassInterface()->getTypeForDecl()))
204 return {ObjTy};
205 }
206 }
207 }
208
209
210 if (InferredType.isNull()) {
211 return {};
212 }
213
214
215
216 if (const auto *ReceiverInferredType =
217 dyn_cast(InferredType)) {
218 return {ReceiverInferredType->getObjectType()};
219 }
220
221
222 return {};
223}
224}
225
226void DynamicTypePropagation::checkDeadSymbols(SymbolReaper &SR,
230
231 MostSpecializedTypeArgsMapTy TyArgMap =
232 State->get();
233 for (SymbolRef Sym : llvm::make_first_range(TyArgMap)) {
234 if (SR.isDead(Sym)) {
235 State = State->remove(Sym);
236 }
237 }
238
239 C.addTransition(State);
240}
241
244 assert(Region);
245 assert(MD);
246
249
251 State = setDynamicTypeInfo(State, Region, Ty, false);
252 C.addTransition(State);
253}
254
255void DynamicTypePropagation::checkPreCall(const CallEvent &Call,
258
259
260
261
262
263
264
265
266 switch (Ctor->getOriginExpr()->getConstructionKind()) {
269
270 return;
273 if (const MemRegion *Target = Ctor->getCXXThisVal().getAsRegion())
275 return;
276 }
277
278 return;
279 }
280
282
283 if (!Dtor->isBaseDestructor())
284 return;
285
286 const MemRegion *Target = Dtor->getCXXThisVal().getAsRegion();
288 return;
289
290 const Decl *D = Dtor->getDecl();
291 if (!D)
292 return;
293
295 return;
296 }
297}
298
299void DynamicTypePropagation::checkPostCall(const CallEvent &Call,
301
303
304
305 const MemRegion *RetReg = Call.getReturnValue().getAsRegion();
306 if (!RetReg)
307 return;
308
311
313 switch (Msg->getMethodFamily()) {
314 default:
315 break;
316
317
318
319
322
323 RuntimeType ObjTy = inferReceiverType(*Msg, C);
324
325 if (!ObjTy)
326 return;
327
329 C.getASTContext().getObjCObjectPointerType(QualType(ObjTy.Type, 0));
330
331
332
333
334
335
336
337
339 break;
340 }
342
343
344 const MemRegion *RecReg = Msg->getReceiverSVal().getAsRegion();
345 if (!RecReg)
346 return;
349 break;
350 }
351 }
352 }
353 return;
354 }
355
357
358 switch (Ctor->getOriginExpr()->getConstructionKind()) {
361
362
363
364
365
366 return;
369 if (const MemRegion *Target = Ctor->getCXXThisVal().getAsRegion()) {
370
371
373
374
375
376
377
378
379
380 if (isa_and_nonnull<InitListExpr, CXXParenListInitExpr>(
382 return;
383
385 }
386 return;
387 }
388 }
389}
390
391
392
393
394
395ExplodedNode *DynamicTypePropagation::dynamicTypePropagationOnCasts(
397
398 const MemRegion *ToR = C.getSVal(CE).getAsRegion();
399 if (!ToR)
400 return C.getPredecessor();
401
403 return C.getPredecessor();
404
405 if (const Type *NewTy = getBetterObjCType(CE, C)) {
407 return C.addTransition(State);
408 }
409 return C.getPredecessor();
410}
411
412void DynamicTypePropagation::checkPostStmt(const CXXNewExpr *NewE,
415 return;
416
417
418 const MemRegion *MR = C.getSVal(NewE).getAsRegion();
419 if (!MR)
420 return;
421
423 false));
424}
425
426
427
428
430DynamicTypePropagation::getBetterObjCType(const Expr *CastE,
432 const MemRegion *ToR = C.getSVal(CastE).getAsRegion();
433 assert(ToR);
434
435
438 if (!NewTy)
439 return nullptr;
441 if (OldDTy.isNull()) {
442 return NewTy;
443 }
446 if (!OldTy)
447 return nullptr;
448
449
451 return NewTy;
452
453
457 return NewTy;
458
459 return nullptr;
460}
461
465
469 assert(MostInformativeCandidate->isSpecialized());
470 return MostInformativeCandidate;
471 }
472 return From;
473 }
474
475 if (To->getObjectType()->getSuperClassType().isNull()) {
476
477
478
479 return From;
480 }
481
482 const auto *SuperOfTo =
484 assert(SuperOfTo);
486 C.getObjCObjectPointerType(QualType(SuperOfTo, 0));
490 C);
491 else
493 MostInformativeCandidate, C);
494}
495
496
497
498
499
500
501
502
503
504
505
506
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533static bool
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
560
561
562 if (!Current) {
564 State = State->set(Sym, StaticLowerBound);
565 return true;
566 }
567
570 State = State->set(Sym, WithMostInfo);
571 return true;
572 }
573
574
575 if (C.canAssignObjCInterfaces(StaticLowerBound, *Current)) {
576 return false;
577 }
578
579
580 if (C.canAssignObjCInterfaces(*Current, StaticUpperBound)) {
581
584 WithMostInfo =
586 if (WithMostInfo == *Current)
587 return false;
588 State = State->set(Sym, WithMostInfo);
589 return true;
590 }
591
592
595 if (WithMostInfo != *Current) {
596 State = State->set(Sym, WithMostInfo);
597 return true;
598 }
599
600 return false;
601}
602
603
604
605
606void DynamicTypePropagation::checkPostStmt(const CastExpr *CE,
609 return;
610
613
616
617 if (!OrigObjectPtrType || !DestObjectPtrType)
618 return;
619
621 ExplodedNode *AfterTypeProp = dynamicTypePropagationOnCasts(CE, State, C);
622
624
625
626
627
628
629
630 OrigObjectPtrType = OrigObjectPtrType->stripObjCKindOfTypeAndQuals(ASTCtxt);
632
633 if (OrigObjectPtrType->isUnspecialized() &&
635 return;
636
637 SymbolRef Sym = C.getSVal(CE).getAsSymbol();
638 if (!Sym)
639 return;
640
642 State->get(Sym);
643
645
646
647
648
649
650
651
652
653 if (TrackedType) {
654 State = State->remove(Sym);
655 C.addTransition(State, AfterTypeProp);
656 }
657 return;
658 }
659
660
661 bool OrigToDest =
663 bool DestToOrig =
665
666
667
668
669
670 if (TrackedType &&
673
674
675
676
678 "IllegalConversion");
680 C.generateNonFatalErrorNode(State, AfterTypeProp, &IllegalConv);
681 if (N)
682 reportGenericsBug(*TrackedType, DestObjectPtrType, N, Sym, C);
683 return;
684 }
685
686
687
690 if (OrigToDest && !DestToOrig)
691 std::swap(LowerBound, UpperBound);
692
693
694 LowerBound = LowerBound->isObjCIdType() ? UpperBound : LowerBound;
695 UpperBound = UpperBound->isObjCIdType() ? LowerBound : UpperBound;
696
698 ASTCtxt)) {
699 C.addTransition(State, AfterTypeProp);
700 }
701}
702
711
713
714
715
716 class IsObjCTypeParamDependentTypeVisitor
718 public:
719 IsObjCTypeParamDependentTypeVisitor() = default;
720 bool VisitObjCTypeParamType(ObjCTypeParamType *Type) override {
722 Result = true;
723 return false;
724 }
725 return true;
726 }
727
728 bool Result = false;
729 };
730
731 IsObjCTypeParamDependentTypeVisitor Visitor;
732 Visitor.TraverseType(Type);
733 return Visitor.Result;
734}
735
736
737
738
739
740
745
747
748
749
752
753
754
759
762 if (!Method)
764 }
765 }
766
767
768
769 return Method ? Method : MessageExpr->getMethodDecl();
770}
771
772
773
774
778 QualType StaticResultType = Method->getReturnType();
779
780
781 if (StaticResultType == C.getObjCInstanceType())
782 return QualType(SelfType, 0);
783
784
787
790
791 return ResultType;
792}
793
794
795
796void DynamicTypePropagation::checkPreObjCMessage(const ObjCMethodCall &M,
800 if (!Sym)
801 return;
802
804 State->get(Sym);
805 if (!TrackedType)
806 return;
807
808
809
810
815
816
817 if (!Method)
818 return;
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
840 return;
841
843 if (!TypeParams)
844 return;
845
848 return;
849 }
850
851 std::optional<ArrayRef> TypeArgs =
852 (*TrackedType)->getObjCSubstitutions(Method->getDeclContext());
853
854
855 if (!TypeArgs)
856 return;
857
858 for (unsigned i = 0; i < Method->param_size(); i++) {
859 const Expr *Arg = MessageExpr->getArg(i);
860 const ParmVarDecl *Param = Method->parameters()[i];
861
862 QualType OrigParamType = Param->getType();
864 continue;
865
868
870 const auto *ArgObjectPtrType =
872 if (!ParamObjectPtrType || !ArgObjectPtrType)
873 continue;
874
875
876
879 if (ArgSym) {
881 State->get(ArgSym);
882 if (TrackedArgType &&
884 ArgObjectPtrType = *TrackedArgType;
885 }
886 }
887
888
890 ArgObjectPtrType)) {
891 ExplodedNode *N = C.generateNonFatalErrorNode(State);
892 reportGenericsBug(ArgObjectPtrType, ParamObjectPtrType, N, Sym, C, Arg);
893 return;
894 }
895 }
896}
897
898
899
900
901
902
903
904
905void DynamicTypePropagation::checkPostObjCMessage(const ObjCMethodCall &M,
908
910 if (!RetSym)
911 return;
912
915
916
918
919 if (RuntimeType ReceiverRuntimeType = inferReceiverType(M, C)) {
920
921 ReceiverRuntimeType.Type->getSuperClassType();
922 QualType ReceiverClassType(ReceiverRuntimeType.Type, 0);
923
924
925 if (ReceiverRuntimeType.Type->isSpecialized() &&
926 ReceiverRuntimeType.Precise) {
927 QualType ReceiverClassPointerType =
928 C.getASTContext().getObjCObjectPointerType(ReceiverClassType);
929 const auto *InferredType =
931 State = State->set(RetSym, InferredType);
932 }
933
934
936 !ReceiverRuntimeType.Precise);
937
938 C.addTransition(State);
939 return;
940 }
941 }
942
944
945
946 if (RuntimeType ReceiverRuntimeType = inferReceiverType(M, C)) {
947
948
949 QualType ReceiversSuperClass =
950 ReceiverRuntimeType.Type->getSuperClassType();
951
952
953
954
955
956 if (!ReceiversSuperClass.isNull()) {
957
959 State, RetSym, ReceiversSuperClass, !ReceiverRuntimeType.Precise);
960
961 C.addTransition(State);
962 }
963 return;
964 }
965 }
966
967
969 if (!RecSym)
970 return;
971
973 State->get(RecSym);
974 if (!TrackedType)
975 return;
976
980 if (!Method)
981 return;
982
983 std::optional<ArrayRef> TypeArgs =
984 (*TrackedType)->getObjCSubstitutions(Method->getDeclContext());
985 if (!TypeArgs)
986 return;
987
990
991 if (ResultType.isNull())
992 return;
993
996
997
998
1000
1001
1002
1004 true);
1005 Pred = C.addTransition(State);
1006 }
1007
1009
1010 if (!ResultPtrType || ResultPtrType->isUnspecialized())
1011 return;
1012
1013
1014
1015 if (!State->get(RetSym)) {
1016 State = State->set(RetSym, ResultPtrType);
1017 C.addTransition(State, Pred);
1018 }
1019}
1020
1021void DynamicTypePropagation::reportGenericsBug(
1024 const Stmt *ReportedNode) const {
1025 if (!ObjCGenericsChecker.isEnabled())
1026 return;
1027
1029 llvm::raw_svector_ostream OS(Buf);
1030 OS << "Conversion from value of type '";
1032 OS << "' to incompatible type '";
1034 OS << "'";
1035 auto R = std::make_unique(ObjCGenericsChecker,
1036 OS.str(), N);
1037 R->markInteresting(Sym);
1038 R->addVisitor(std::make_unique(Sym));
1039 if (ReportedNode)
1041 C.emitReport(std::move(R));
1042}
1043
1049
1051 state->get(Sym);
1053 statePrev->get(Sym);
1054 if (!TrackedType)
1055 return nullptr;
1056
1057 if (TrackedTypePrev && *TrackedTypePrev == *TrackedType)
1058 return nullptr;
1059
1060
1062 if (!S)
1063 return nullptr;
1064
1066
1068 llvm::raw_svector_ostream OS(Buf);
1069 OS << "Type '";
1071 OS << "' is inferred from ";
1072
1073 if (const auto *ExplicitCast = dyn_cast(S)) {
1074 OS << "explicit cast (from '";
1075 QualType::print(ExplicitCast->getSubExpr()->getType().getTypePtr(),
1077 OS << "' to '";
1079 LangOpts, llvm::Twine());
1080 OS << "')";
1081 } else if (const auto *ImplicitCast = dyn_cast(S)) {
1082 OS << "implicit cast (from '";
1083 QualType::print(ImplicitCast->getSubExpr()->getType().getTypePtr(),
1085 OS << "' to '";
1087 LangOpts, llvm::Twine());
1088 OS << "')";
1089 } else {
1090 OS << "this context";
1091 }
1092
1093
1096 return std::make_shared(Pos, OS.str(), true);
1097}
1098
1099
1100void ento::registerObjCGenericsChecker(CheckerManager &Mgr) {
1101 Mgr.getChecker()->ObjCGenericsChecker.enable(Mgr);
1102}
1103
1104bool ento::shouldRegisterObjCGenericsChecker(const CheckerManager &) {
1105 return true;
1106}
1107
1108void ento::registerDynamicTypePropagation(CheckerManager &Mgr) {
1109
1110
1111
1112
1113 Mgr.getChecker();
1114}
1115
1116bool ento::shouldRegisterDynamicTypePropagation(const CheckerManager &) {
1117 return true;
1118}
Defines enum values for all the target-independent builtin functions.
static QualType getReturnTypeForMethod(const ObjCMethodDecl *Method, ArrayRef< QualType > TypeArgs, const ObjCObjectPointerType *SelfType, ASTContext &C)
Get the returned ObjCObjectPointerType by a method based on the tracked type information,...
Definition DynamicTypePropagation.cpp:775
static void recordFixedType(const MemRegion *Region, const CXXMethodDecl *MD, CheckerContext &C)
Definition DynamicTypePropagation.cpp:242
static const ObjCObjectPointerType * getMostInformativeDerivedClassImpl(const ObjCObjectPointerType *From, const ObjCObjectPointerType *To, const ObjCObjectPointerType *MostInformativeCandidate, ASTContext &C)
Definition DynamicTypePropagation.cpp:462
static const ObjCMethodDecl * findMethodDecl(const ObjCMessageExpr *MessageExpr, const ObjCObjectPointerType *TrackedType, ASTContext &ASTCtxt)
A method might not be available in the interface indicated by the static type.
Definition DynamicTypePropagation.cpp:742
static bool isObjCTypeParamDependent(QualType Type)
Definition DynamicTypePropagation.cpp:712
static const Expr * stripCastsAndSugar(const Expr *E)
Definition DynamicTypePropagation.cpp:703
static const ObjCObjectPointerType * getMostInformativeDerivedClass(const ObjCObjectPointerType *From, const ObjCObjectPointerType *To, ASTContext &C)
A downcast may loose specialization information.
Definition DynamicTypePropagation.cpp:508
static bool storeWhenMoreInformative(ProgramStateRef &State, SymbolRef Sym, const ObjCObjectPointerType *const *Current, const ObjCObjectPointerType *StaticLowerBound, const ObjCObjectPointerType *StaticUpperBound, ASTContext &C)
Inputs:
Definition DynamicTypePropagation.cpp:534
llvm::MachO::Target Target
#define REGISTER_MAP_WITH_PROGRAMSTATE(Name, Key, Value)
Declares an immutable map of type NameTy, suitable for placement into the ProgramState.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
QualType getPointerType(QualType T) const
Return the uniqued reference to the type for a pointer to the specified type.
bool canAssignObjCInterfaces(const ObjCObjectPointerType *LHSOPT, const ObjCObjectPointerType *RHSOPT)
canAssignObjCInterfaces - Return true if the two interface types are compatible for assignment from R...
const LangOptions & getLangOpts() const
CanQualType getCanonicalTagType(const TagDecl *TD) const
Represents a static or instance method of a struct/union/class.
const CXXRecordDecl * getParent() const
Return the parent of this method declaration, which is the class in which this method is defined.
Represents a new-expression for memory allocation and constructor calls, e.g: "new CXXNewExpr(foo)".
CastExpr - Base class for type casts, including both implicit casts (ImplicitCastExpr) and explicit c...
CastKind getCastKind() const
Decl - This represents one declaration (or definition), e.g.
This represents one expression.
Expr * IgnoreParenImpCasts() LLVM_READONLY
Skip past any parentheses and implicit casts which might surround this expression until reaching a fi...
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
It wraps the AnalysisDeclContext to represent both the call stack with the help of StackFrameContext ...
const Decl * getDecl() const
const ParentMap & getParentMap() const
Represents an ObjC class declaration.
ObjCMethodDecl * lookupClassMethod(Selector Sel) const
Lookup a class method for a given selector.
ObjCMethodDecl * lookupInstanceMethod(Selector Sel) const
Lookup an instance method for a given selector.
ObjCInterfaceDecl * getCanonicalDecl() override
Retrieves the canonical declaration of this Objective-C class.
bool isSuperClassOf(const ObjCInterfaceDecl *I) const
isSuperClassOf - Return true if this class is the specified class or is a super class of the specifie...
An expression that sends a message to the given Objective-C object or class.
Expr * getArg(unsigned Arg)
getArg - Return the specified argument.
Expr * getInstanceReceiver()
Returns the object expression (receiver) for an instance message, or null for a message that is not a...
Selector getSelector() const
@ SuperInstance
The receiver is the instance of the superclass object.
@ Instance
The receiver is an object instance.
@ SuperClass
The receiver is a superclass.
@ Class
The receiver is a class.
QualType getClassReceiver() const
Returns the type of a class message send, or NULL if the message is not a class message.
QualType getSuperType() const
Retrieve the type referred to by 'super'.
const ObjCMethodDecl * getMethodDecl() const
ReceiverKind getReceiverKind() const
Determine the kind of receiver that this message is being sent to.
QualType getReceiverType() const
Retrieve the receiver type to which this message is being directed.
ObjCMethodDecl - Represents an instance or class method declaration.
bool hasRelatedResultType() const
Determine whether this method has a result type that is related to the message receiver's type.
Represents a pointer to an Objective C object.
bool isSpecialized() const
Whether this type is specialized, meaning that it has type arguments.
const ObjCObjectPointerType * stripObjCKindOfTypeAndQuals(const ASTContext &ctx) const
Strip off the Objective-C "kindof" type and (with it) any protocol qualifiers.
const ObjCObjectType * getObjectType() const
Gets the type pointed to by this ObjC pointer.
bool isUnspecialized() const
Whether this type is unspecialized, meaning that is has no type arguments.
bool isObjCIdType() const
True if this is equivalent to the 'id' type, i.e.
ObjCInterfaceDecl * getInterfaceDecl() const
If this pointer points to an Objective @interface type, gets the declaration for that interface.
Represents the declaration of an Objective-C type parameter.
Stores a list of Objective-C type parameters for a parameterized class or a category/extension thereo...
OpaqueValueExpr - An expression referring to an opaque object of a fixed type and value class.
Stmt * getParent(Stmt *) const
Represents a parameter to a function.
PointerType - C99 6.7.5.1 - Pointer Declarators.
virtual StringRef getDebugTag() const =0
The description of this program point which will be dumped for debugging purposes.
PseudoObjectExpr - An expression which accesses a pseudo-object l-value.
A (possibly-)qualified type.
bool isNull() const
Return true if this QualType doesn't point to a type yet.
void print(raw_ostream &OS, const PrintingPolicy &Policy, const Twine &PlaceHolder=Twine(), unsigned Indentation=0) const
QualType getCanonicalType() const
QualType substObjCTypeArgs(ASTContext &ctx, ArrayRef< QualType > typeArgs, ObjCSubstitutionContext context) const
Substitute type arguments for the Objective-C type parameters used in the subject type.
The collection of all-type qualifiers we support.
Smart pointer class that efficiently represents Objective-C method names.
std::string getAsString() const
Derive the full selector name (e.g.
Stmt - This represents one statement.
SourceRange getSourceRange() const LLVM_READONLY
SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...
The base class of the type hierarchy.
const T * castAs() const
Member-template castAs.
bool isObjCIdType() const
bool isObjCClassType() const
const T * getAs() const
Member-template getAs'.
ASTContext & getASTContext() const
const SourceManager & getSourceManager() const
BugReporterVisitors are used to add custom diagnostics along a path.
Represents a call to a C++ constructor.
Represents an implicit call to a C++ destructor.
Represents an abstract call to a function or method along a particular path.
virtual SVal getArgSVal(unsigned Index) const
Returns the value of a given argument at the time of the call.
SVal getReturnValue() const
Returns the return value of the call.
Checker families (where a single backend class implements multiple related frontends) should derive f...
Trivial convenience class for the common case when a certain checker frontend always uses the same bu...
CHECKER * getChecker(AT &&...Args)
If the the singleton instance of a checker class is not yet constructed, then construct it (with the ...
Stores the currently inferred strictest bound on the runtime type of a region in a given state along ...
QualType getType() const
Returns the currently inferred upper bound on the runtime type.
const ProgramStateRef & getState() const
const Stmt * getStmtForDiagnostics() const
If the node's program point corresponds to a statement, retrieve that statement.
const LocationContext * getLocationContext() const
ExplodedNode * getFirstPred()
MemRegion - The root abstract class for all memory regions.
Represents any expression that calls an Objective-C method.
const ObjCMessageExpr * getOriginExpr() const override
Returns the expression whose value will be the result of this call.
SVal getReceiverSVal() const
Returns the value of the receiver at the time of this call.
SVal - This represents a symbolic expression, which can be either an L-value or an R-value.
SymbolRef getAsSymbol(bool IncludeBaseRegions=false) const
If this SVal wraps a symbol return that SymbolRef.
const MemRegion * getAsRegion() const
A class responsible for cleaning up unused symbols.
bool isDead(SymbolRef sym)
Returns whether or not a symbol has been confirmed dead.
const char *const CoreFoundationObjectiveC
IntrusiveRefCntPtr< const ProgramState > ProgramStateRef
const SymExpr * SymbolRef
ProgramStateRef setClassObjectDynamicTypeInfo(ProgramStateRef State, SymbolRef Sym, DynamicTypeInfo NewTy)
Set constraint on a type contained in a class object; return the new state.
@ OS
Indicates that the tracking object is a descendant of a referenced-counted OSObject,...
ProgramStateRef removeDeadClassObjectTypes(ProgramStateRef State, SymbolReaper &SR)
Removes the dead Class object type informations from State.
DynamicTypeInfo getDynamicTypeInfo(ProgramStateRef State, const MemRegion *MR)
Get dynamic type information for the region MR.
const DynamicTypeInfo * getRawDynamicTypeInfo(ProgramStateRef State, const MemRegion *MR)
Get raw dynamic type information for the region MR.
ProgramStateRef setDynamicTypeInfo(ProgramStateRef State, const MemRegion *MR, DynamicTypeInfo NewTy)
Set dynamic type information of the region; return the new state.
std::shared_ptr< PathDiagnosticPiece > PathDiagnosticPieceRef
ProgramStateRef removeDeadTypes(ProgramStateRef State, SymbolReaper &SR)
Removes the dead type informations from State.
DynamicTypeInfo getClassObjectDynamicTypeInfo(ProgramStateRef State, SymbolRef Sym)
Get dynamic type information stored in a class object represented by Sym.
The JSON file list parser is used to communicate input to InstallAPI.
CanQual< Type > CanQualType
Represents a canonical, potentially-qualified type.
bool isa(CodeGen::Address addr)
@ Parameter
The parameter type of a method or function.
@ Result
The result type of a method or function.
DynamicRecursiveASTVisitorBase< false > DynamicRecursiveASTVisitor
@ Invariant
The parameter is invariant: must match exactly.
U cast(CodeGen::Address addr)
@ Interface
The "__interface" keyword introduces the elaborated-type-specifier.