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 Checker< check::PreCall,
54 check::PostCall,
55 check::DeadSymbols,
56 check::PostStmt,
57 check::PostStmt,
58 check::PreObjCMessage,
59 check::PostObjCMessage > {
60
61
64
68
69 mutable std::unique_ptr ObjCGenericsBugType;
70 void initBugType() const {
71 if (!ObjCGenericsBugType)
72 ObjCGenericsBugType.reset(new BugType(
74 }
75
77 public:
78 GenericsBugVisitor(SymbolRef S) : Sym(S) {}
79
80 void Profile(llvm::FoldingSetNodeID &ID) const override {
81 static int X = 0;
83 ID.AddPointer(Sym);
84 }
85
89
90 private:
91
93 };
94
98 const Stmt *ReportedNode = nullptr) const;
99
100public:
108
109
110 bool CheckGenerics = false;
112};
113
115 if (const auto *PointerType = dyn_cast(Type)) {
116 return PointerType->getObjectType()->isObjCClass();
117 }
118 return false;
119}
120
121struct RuntimeType {
123 bool Precise = false;
124
125 operator bool() const { return Type != nullptr; }
126};
127
128RuntimeType inferReceiverType(const ObjCMethodCall &Message,
130 const ObjCMessageExpr *MessageExpr = Message.getOriginExpr();
131
132
133
134
135
136
137
140 true};
141 }
142
143
144
145
146
147
150 true};
151 }
152
153
154
155
156
157
159 if (const auto *ObjTy =
161 return {ObjTy->getObjectType(), true};
162 }
163
165
166 if (!RecE)
167 return {};
168
169
170
172 SVal ReceiverSVal = C.getSVal(RecE);
174
178 }
179 }
180
182 if (InferredType.isNull()) {
183 InferredType = ReceiverSymbol->getType();
184 }
185
186
187
188 if (isObjCClassType(InferredType)) {
189
192
193
194 return {cast(DTI.getType()), !DTI.canBeASubClass()};
195 }
196
197 SVal SelfSVal = State->getSelfSVal(C.getLocationContext());
198
199
200
201 if (ReceiverSVal == SelfSVal) {
202
203
205 dyn_cast(C.getStackFrame()->getDecl()))
206 if (const ObjCObjectType *ObjTy = dyn_cast(
207 MD->getClassInterface()->getTypeForDecl()))
208 return {ObjTy};
209 }
210 }
211 }
212
213
214 if (InferredType.isNull()) {
215 return {};
216 }
217
218
219
220 if (const auto *ReceiverInferredType =
221 dyn_cast(InferredType)) {
222 return {ReceiverInferredType->getObjectType()};
223 }
224
225
226 return {};
227}
228}
229
230void DynamicTypePropagation::checkDeadSymbols(SymbolReaper &SR,
234
235 MostSpecializedTypeArgsMapTy TyArgMap =
236 State->get();
237 for (SymbolRef Sym : llvm::make_first_range(TyArgMap)) {
238 if (SR.isDead(Sym)) {
239 State = State->remove(Sym);
240 }
241 }
242
243 C.addTransition(State);
244}
245
248 assert(Region);
249 assert(MD);
250
253
255 State = setDynamicTypeInfo(State, Region, Ty, false);
256 C.addTransition(State);
257}
258
259void DynamicTypePropagation::checkPreCall(const CallEvent &Call,
262
263
264
265
266
267
268
269
270 switch (Ctor->getOriginExpr()->getConstructionKind()) {
271 case CXXConstructionKind::Complete:
272 case CXXConstructionKind::Delegating:
273
274 return;
275 case CXXConstructionKind::NonVirtualBase:
276 case CXXConstructionKind::VirtualBase:
277 if (const MemRegion *Target = Ctor->getCXXThisVal().getAsRegion())
279 return;
280 }
281
282 return;
283 }
284
286
287 if (!Dtor->isBaseDestructor())
288 return;
289
290 const MemRegion *Target = Dtor->getCXXThisVal().getAsRegion();
292 return;
293
294 const Decl *D = Dtor->getDecl();
295 if ()
296 return;
297
299 return;
300 }
301}
302
303void DynamicTypePropagation::checkPostCall(const CallEvent &Call,
305
307
308
309 const MemRegion *RetReg = Call.getReturnValue().getAsRegion();
310 if (!RetReg)
311 return;
312
315
316 if (D && D->hasRelatedResultType()) {
317 switch (Msg->getMethodFamily()) {
318 default:
319 break;
320
321
322
323
326
327 RuntimeType ObjTy = inferReceiverType(*Msg, C);
328
329 if (!ObjTy)
330 return;
331
333 C.getASTContext().getObjCObjectPointerType(QualType(ObjTy.Type, 0));
334
335
336
337
338
339
340
341
343 break;
344 }
346
347
348 const MemRegion *RecReg = Msg->getReceiverSVal().getAsRegion();
349 if (!RecReg)
350 return;
353 break;
354 }
355 }
356 }
357 return;
358 }
359
361
362 switch (Ctor->getOriginExpr()->getConstructionKind()) {
363 case CXXConstructionKind::Complete:
364 case CXXConstructionKind::Delegating:
365
366
367
368
369
370 return;
371 case CXXConstructionKind::NonVirtualBase:
372 case CXXConstructionKind::VirtualBase:
373 if (const MemRegion *Target = Ctor->getCXXThisVal().getAsRegion()) {
374
375
377
378
379
380
381
382
383
384 if (isa_and_nonnull(
386 return;
387
389 }
390 return;
391 }
392 }
393}
394
395
396
397
398
399ExplodedNode *DynamicTypePropagation::dynamicTypePropagationOnCasts(
401
402 const MemRegion *ToR = C.getSVal(CE).getAsRegion();
403 if (!ToR)
404 return C.getPredecessor();
405
406 if (isa(CE))
407 return C.getPredecessor();
408
409 if (const Type *NewTy = getBetterObjCType(CE, C)) {
411 return C.addTransition(State);
412 }
413 return C.getPredecessor();
414}
415
416void DynamicTypePropagation::checkPostStmt(const CXXNewExpr *NewE,
419 return;
420
421
422 const MemRegion *MR = C.getSVal(NewE).getAsRegion();
423 if (!MR)
424 return;
425
427 false));
428}
429
430
431
432
434DynamicTypePropagation::getBetterObjCType(const Expr *CastE,
436 const MemRegion *ToR = C.getSVal(CastE).getAsRegion();
437 assert(ToR);
438
439
442 if (!NewTy)
443 return nullptr;
445 if (OldDTy.isNull()) {
446 return NewTy;
447 }
450 if (!OldTy)
451 return nullptr;
452
453
455 return NewTy;
456
457
461 return NewTy;
462
463 return nullptr;
464}
465
469
473 assert(MostInformativeCandidate->isSpecialized());
474 return MostInformativeCandidate;
475 }
476 return From;
477 }
478
480
481
482
483 return From;
484 }
485
486 const auto *SuperOfTo =
488 assert(SuperOfTo);
490 C.getObjCObjectPointerType(QualType(SuperOfTo, 0));
494 C);
495 else
497 MostInformativeCandidate, C);
498}
499
500
501
502
503
504
505
506
507
508
509
510
515}
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537static bool
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
563 assert(!Current || (*Current)->isSpecialized());
564
565
566 if (!Current) {
568 State = State->set(Sym, StaticLowerBound);
569 return true;
570 }
571
574 State = State->set(Sym, WithMostInfo);
575 return true;
576 }
577
578
579 if (C.canAssignObjCInterfaces(StaticLowerBound, *Current)) {
580 return false;
581 }
582
583
584 if (C.canAssignObjCInterfaces(*Current, StaticUpperBound)) {
585
588 WithMostInfo =
590 if (WithMostInfo == *Current)
591 return false;
592 State = State->set(Sym, WithMostInfo);
593 return true;
594 }
595
596
599 if (WithMostInfo != *Current) {
600 State = State->set(Sym, WithMostInfo);
601 return true;
602 }
603
604 return false;
605}
606
607
608
609
610void DynamicTypePropagation::checkPostStmt(const CastExpr *CE,
613 return;
614
617
620
621 if (!OrigObjectPtrType || !DestObjectPtrType)
622 return;
623
625 ExplodedNode *AfterTypeProp = dynamicTypePropagationOnCasts(CE, State, C);
626
628
629
630
631
632
633
634 OrigObjectPtrType = OrigObjectPtrType->stripObjCKindOfTypeAndQuals(ASTCtxt);
636
637 if (OrigObjectPtrType->isUnspecialized() &&
639 return;
640
641 SymbolRef Sym = C.getSVal(CE).getAsSymbol();
642 if (!Sym)
643 return;
644
646 State->get(Sym);
647
648 if (isa(CE)) {
649
650
651
652
653
654
655
656
657 if (TrackedType) {
658 State = State->remove(Sym);
659 C.addTransition(State, AfterTypeProp);
660 }
661 return;
662 }
663
664
665 bool OrigToDest =
667 bool DestToOrig =
669
670
671
672
673
674 if (TrackedType &&
678 ExplodedNode *N = C.addTransition(State, AfterTypeProp, &IllegalConv);
679 reportGenericsBug(*TrackedType, DestObjectPtrType, N, Sym, C);
680 return;
681 }
682
683
684
687 if (OrigToDest && !DestToOrig)
688 std::swap(LowerBound, UpperBound);
689
690
691 LowerBound = LowerBound->isObjCIdType() ? UpperBound : LowerBound;
692 UpperBound = UpperBound->isObjCIdType() ? LowerBound : UpperBound;
693
695 ASTCtxt)) {
696 C.addTransition(State, AfterTypeProp);
697 }
698}
699
704 if (const OpaqueValueExpr *OVE = dyn_cast(E))
706 return E;
707}
708
710
711
712
713 class IsObjCTypeParamDependentTypeVisitor
715 public:
716 IsObjCTypeParamDependentTypeVisitor() = default;
718 if (isa(Type->getDecl())) {
719 Result = true;
720 return false;
721 }
722 return true;
723 }
724
725 bool Result = false;
726 };
727
728 IsObjCTypeParamDependentTypeVisitor Visitor;
729 Visitor.TraverseType(Type);
730 return Visitor.Result;
731}
732
733
734
735
736
737
742
744
745
746
749
750
751
756
759 if (!Method)
761 }
762 }
763
764
765
766 return Method ? Method : MessageExpr->getMethodDecl();
767}
768
769
770
771
776
777
778 if (StaticResultType == C.getObjCInstanceType())
779 return QualType(SelfType, 0);
780
781
784
786 C, TypeArgs, ObjCSubstitutionContext::Result);
787
788 return ResultType;
789}
790
791
792
793void DynamicTypePropagation::checkPreObjCMessage(const ObjCMethodCall &M,
797 if (!Sym)
798 return;
799
801 State->get(Sym);
802 if (!TrackedType)
803 return;
804
805
806
807
812
813
814 if (!Method)
815 return;
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
837 return;
838
840 if (!TypeParams)
841 return;
842
844 if (TypeParam->getVariance() != ObjCTypeParamVariance::Invariant)
845 return;
846 }
847
848 std::optional<ArrayRef> TypeArgs =
849 (*TrackedType)->getObjCSubstitutions(Method->getDeclContext());
850
851
852 if (!TypeArgs)
853 return;
854
855 for (unsigned i = 0; i < Method->param_size(); i++) {
856 const Expr *Arg = MessageExpr->getArg(i);
858
861 continue;
862
864 ASTCtxt, *TypeArgs, ObjCSubstitutionContext::Parameter);
865
867 const auto *ArgObjectPtrType =
869 if (!ParamObjectPtrType || !ArgObjectPtrType)
870 continue;
871
872
873
876 if (ArgSym) {
878 State->get(ArgSym);
879 if (TrackedArgType &&
881 ArgObjectPtrType = *TrackedArgType;
882 }
883 }
884
885
887 ArgObjectPtrType)) {
890 reportGenericsBug(ArgObjectPtrType, ParamObjectPtrType, N, Sym, C, Arg);
891 return;
892 }
893 }
894}
895
896
897
898
899
900
901
902
903void DynamicTypePropagation::checkPostObjCMessage(const ObjCMethodCall &M,
906
908 if (!RetSym)
909 return;
910
913
914
916
917 if (RuntimeType ReceiverRuntimeType = inferReceiverType(M, C)) {
918
919 ReceiverRuntimeType.Type->getSuperClassType();
920 QualType ReceiverClassType(ReceiverRuntimeType.Type, 0);
921
922
923 if (ReceiverRuntimeType.Type->isSpecialized() &&
924 ReceiverRuntimeType.Precise) {
925 QualType ReceiverClassPointerType =
926 C.getASTContext().getObjCObjectPointerType(ReceiverClassType);
927 const auto *InferredType =
929 State = State->set(RetSym, InferredType);
930 }
931
932
934 !ReceiverRuntimeType.Precise);
935
936 C.addTransition(State);
937 return;
938 }
939 }
940
942
943
944 if (RuntimeType ReceiverRuntimeType = inferReceiverType(M, C)) {
945
946
947 QualType ReceiversSuperClass =
948 ReceiverRuntimeType.Type->getSuperClassType();
949
950
951
952
953
954 if (!ReceiversSuperClass.isNull()) {
955
957 State, RetSym, ReceiversSuperClass, !ReceiverRuntimeType.Precise);
958
959 C.addTransition(State);
960 }
961 return;
962 }
963 }
964
965
967 if (!RecSym)
968 return;
969
971 State->get(RecSym);
972 if (!TrackedType)
973 return;
974
978 if (!Method)
979 return;
980
981 std::optional<ArrayRef> TypeArgs =
982 (*TrackedType)->getObjCSubstitutions(Method->getDeclContext());
983 if (!TypeArgs)
984 return;
985
988
989 if (ResultType.isNull())
990 return;
991
994
995
996
998
999
1000
1002 true);
1003 Pred = C.addTransition(State);
1004 }
1005
1007
1008 if (!ResultPtrType || ResultPtrType->isUnspecialized())
1009 return;
1010
1011
1012
1013 if (!State->get(RetSym)) {
1014 State = State->set(RetSym, ResultPtrType);
1015 C.addTransition(State, Pred);
1016 }
1017}
1018
1019void DynamicTypePropagation::reportGenericsBug(
1022 const Stmt *ReportedNode) const {
1023 if (!CheckGenerics)
1024 return;
1025
1026 initBugType();
1028 llvm::raw_svector_ostream OS(Buf);
1029 OS << "Conversion from value of type '";
1031 OS << "' to incompatible type '";
1033 OS << "'";
1034 auto R = std::make_unique(*ObjCGenericsBugType,
1035 OS.str(), N);
1036 R->markInteresting(Sym);
1037 R->addVisitor(std::make_unique(Sym));
1038 if (ReportedNode)
1040 C.emitReport(std::move(R));
1041}
1042
1048
1050 state->get(Sym);
1052 statePrev->get(Sym);
1053 if (!TrackedType)
1054 return nullptr;
1055
1056 if (TrackedTypePrev && *TrackedTypePrev == *TrackedType)
1057 return nullptr;
1058
1059
1061 if (!S)
1062 return nullptr;
1063
1065
1067 llvm::raw_svector_ostream OS(Buf);
1068 OS << "Type '";
1070 OS << "' is inferred from ";
1071
1072 if (const auto *ExplicitCast = dyn_cast(S)) {
1073 OS << "explicit cast (from '";
1074 QualType::print(ExplicitCast->getSubExpr()->getType().getTypePtr(),
1075 Qualifiers(), OS, LangOpts, llvm::Twine());
1076 OS << "' to '";
1078 LangOpts, llvm::Twine());
1079 OS << "')";
1080 } else if (const auto *ImplicitCast = dyn_cast(S)) {
1081 OS << "implicit cast (from '";
1082 QualType::print(ImplicitCast->getSubExpr()->getType().getTypePtr(),
1083 Qualifiers(), OS, LangOpts, llvm::Twine());
1084 OS << "' to '";
1086 LangOpts, llvm::Twine());
1087 OS << "')";
1088 } else {
1089 OS << "this context";
1090 }
1091
1092
1095 return std::make_shared(Pos, OS.str(), true);
1096}
1097
1098
1099void ento::registerObjCGenericsChecker(CheckerManager &mgr) {
1100 DynamicTypePropagation *checker = mgr.getChecker();
1101 checker->CheckGenerics = true;
1103}
1104
1105bool ento::shouldRegisterObjCGenericsChecker(const CheckerManager &mgr) {
1106 return true;
1107}
1108
1109void ento::registerDynamicTypePropagation(CheckerManager &mgr) {
1111}
1112
1113bool ento::shouldRegisterDynamicTypePropagation(const CheckerManager &mgr) {
1114 return true;
1115}
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,...
static void recordFixedType(const MemRegion *Region, const CXXMethodDecl *MD, CheckerContext &C)
static const ObjCObjectPointerType * getMostInformativeDerivedClassImpl(const ObjCObjectPointerType *From, const ObjCObjectPointerType *To, const ObjCObjectPointerType *MostInformativeCandidate, ASTContext &C)
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. However it might be av...
static bool isObjCTypeParamDependent(QualType Type)
static const Expr * stripCastsAndSugar(const Expr *E)
static const ObjCObjectPointerType * getMostInformativeDerivedClass(const ObjCObjectPointerType *From, const ObjCObjectPointerType *To, ASTContext &C)
A downcast may loose specialization information. E. g.: MutableMap<T, U> : Map The downcast to Mutabl...
static bool storeWhenMoreInformative(ProgramStateRef &State, SymbolRef Sym, const ObjCObjectPointerType *const *Current, const ObjCObjectPointerType *StaticLowerBound, const ObjCObjectPointerType *StaticUpperBound, ASTContext &C)
Inputs:
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 getRecordType(const RecordDecl *Decl) const
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
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.
DeclContext * getDeclContext()
Recursive AST visitor that supports extension via dynamic dispatch.
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.
ArrayRef< ParmVarDecl * > parameters() const
unsigned param_size() const
QualType getReturnType() const
ObjCInterfaceDecl * getClassInterface()
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 a class type in Objective C.
QualType getSuperClassType() const
Retrieve the type of the superclass of this object type.
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...
Represents a type parameter type in Objective C.
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.
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 * registerChecker(AT &&... Args)
Used to register checkers.
CheckerNameRef getCurrentCheckerName() const
This wrapper is used to ensure that only StringRefs originating from the CheckerRegistry are used as ...
Tag that can use a checker name as a message provider (see SimpleProgramPointTag).
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
ProgramStateRef setClassObjectDynamicTypeInfo(ProgramStateRef State, SymbolRef Sym, DynamicTypeInfo NewTy)
Set constraint on a type contained in a class object; return the new state.
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.
ProgramStateRef removeDeadTypes(ProgramStateRef State, SymbolReaper &SR)
Removes the dead type informations from State.
std::shared_ptr< PathDiagnosticPiece > PathDiagnosticPieceRef
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.
@ Interface
The "__interface" keyword introduces the elaborated-type-specifier.