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.