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;

82 ID.AddPointer(&X);

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 (D)

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.