clang: lib/Analysis/FlowSensitive/Transfer.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

13

35#include "llvm/Support/Casting.h"

37#include

38

39#define DEBUG_TYPE "dataflow"

40

42namespace dataflow {

43

46 if (Block == nullptr) {

47 assert(false);

48 return nullptr;

49 }

50 if (!ACFG.isBlockReachable(*Block))

51 return nullptr;

52 if (Block->getBlockID() == CurBlockID)

53 return &CurState.Env;

54 const auto &State = BlockToState[Block->getBlockID()];

55 if (!(State))

56 return nullptr;

57 return &State->Env;

58}

59

64

65

66

67 if (LHSValue == RHSValue && LHSValue)

69

70

71

74

75 if (auto *LHSBool = dyn_cast_or_null(LHSValue))

76 if (auto *RHSBool = dyn_cast_or_null(RHSValue))

77 return Env.makeIff(*LHSBool, *RHSBool);

78

79 if (auto *LHSPtr = dyn_cast_or_null(LHSValue))

80 if (auto *RHSPtr = dyn_cast_or_null(RHSValue))

81

82

83

84 if (&LHSPtr->getPointeeLoc() == &RHSPtr->getPointeeLoc())

86

88}

89

91 if (auto *Top = llvm::dyn_cast(&V)) {

93 return A.makeBoolValue(A.makeAtomRef(Top->getAtom()));

94 }

95 return V;

96}

97

98

99

100

103 if (Loc == nullptr)

104 return nullptr;

105 auto *Val = Env.getValue(*Loc);

106

107 auto *B = dyn_cast_or_null(Val);

108 if (B == nullptr)

109 return Val;

110

111 auto &UnpackedVal = unpackValue(*B, Env);

112 if (&UnpackedVal == Val)

113 return Val;

114 Env.setValue(*Loc, UnpackedVal);

115 return &UnpackedVal;

116}

117

120 return;

121 if (auto *Val = Env.getValue(From))

123}

124

130

131

132

133

142

143namespace {

144

145class TransferVisitor : public ConstStmtVisitor {

146public:

147 TransferVisitor(const StmtToEnvMap &StmtToEnv, Environment &Env,

148 Environment::ValueModel &Model)

149 : StmtToEnv(StmtToEnv), Env(Env), Model(Model) {}

150

151 void VisitBinaryOperator(const BinaryOperator *S) {

152 const Expr *LHS = S->getLHS();

153 assert(LHS != nullptr);

154

155 const Expr *RHS = S->getRHS();

156 assert(RHS != nullptr);

157

158

159

160

161

162 if (S->isCompoundAssignmentOp())

164

165 switch (S->getOpcode()) {

166 case BO_Assign: {

167 auto *LHSLoc = Env.getStorageLocation(*LHS);

168 if (LHSLoc == nullptr)

169 break;

170

171 auto *RHSVal = Env.getValue(*RHS);

172 if (RHSVal == nullptr)

173 break;

174

175

176 Env.setValue(*LHSLoc, *RHSVal);

177

178

179 Env.setStorageLocation(*S, *LHSLoc);

180 break;

181 }

182 case BO_LAnd:

183 case BO_LOr: {

184 BoolValue &LHSVal = getLogicOperatorSubExprValue(*LHS);

185 BoolValue &RHSVal = getLogicOperatorSubExprValue(*RHS);

186

187 if (S->getOpcode() == BO_LAnd)

188 Env.setValue(*S, Env.makeAnd(LHSVal, RHSVal));

189 else

190 Env.setValue(*S, Env.makeOr(LHSVal, RHSVal));

191 break;

192 }

193 case BO_NE:

194 case BO_EQ: {

196 Env.setValue(*S, S->getOpcode() == BO_EQ ? LHSEqRHSValue

197 : Env.makeNot(LHSEqRHSValue));

198 break;

199 }

200 case BO_Comma: {

202 break;

203 }

204 default:

205 break;

206 }

207 }

208

209 void VisitDeclRefExpr(const DeclRefExpr *S) {

210 const ValueDecl *VD = S->getDecl();

211 assert(VD != nullptr);

212

213

214

215

216

217

218

219

220

221

222 if (!S->isGLValue())

223 return;

224

225 auto *DeclLoc = Env.getStorageLocation(*VD);

226 if (DeclLoc == nullptr)

227 return;

228

229 Env.setStorageLocation(*S, *DeclLoc);

230 }

231

232 void VisitDeclStmt(const DeclStmt *S) {

233

234

235 const auto &D = *cast(S->getSingleDecl());

236

237 ProcessVarDecl(D);

238 }

239

240 void ProcessVarDecl(const VarDecl &D) {

241

242 if (D.hasGlobalStorage())

243 return;

244

245

246

247

248 if (D.getType()->isReferenceType() && Env.getStorageLocation(D) != nullptr)

249 return;

250

251 assert(Env.getStorageLocation(D) == nullptr);

252

253 Env.setStorageLocation(D, Env.createObject(D));

254

255

256

257

258 if (const auto *Decomp = dyn_cast(&D)) {

259

260

261

262

263

264 for (const auto *B : Decomp->bindings()) {

265 if (auto *ME = dyn_cast_or_null(B->getBinding())) {

266 auto *DE = dyn_cast_or_null(ME->getBase());

267 if (DE == nullptr)

268 continue;

269

270

271

272 VisitDeclRefExpr(DE);

273 VisitMemberExpr(ME);

274

275 if (auto *Loc = Env.getStorageLocation(*ME))

276 Env.setStorageLocation(*B, *Loc);

277 } else if (auto *VD = B->getHoldingVar()) {

278

279

280

281

282

283

284 ProcessVarDecl(*VD);

285 auto *VDLoc = Env.getStorageLocation(*VD);

286 assert(VDLoc != nullptr);

287 Env.setStorageLocation(*B, *VDLoc);

288 }

289 }

290 }

291 }

292

293 void VisitCastExpr(const CastExpr *S) {

294 const Expr *SubExpr = S->getSubExpr();

295 assert(SubExpr != nullptr);

296

297 switch (S->getCastKind()) {

298 case CK_IntegralToBoolean: {

299

300

301

302 if (auto *SubExprVal =

303 dyn_cast_or_null(Env.getValue(*SubExpr)))

304 Env.setValue(*S, *SubExprVal);

305 else

306

307

308 Env.setValue(*S, Env.makeAtomicBoolValue());

309 break;

310 }

311

312 case CK_LValueToRValue: {

313

314

316 if (SubExprVal == nullptr)

317 break;

318

319 Env.setValue(*S, *SubExprVal);

320 break;

321 }

322

323 case CK_BaseToDerived: {

324

325

326

327

328 RecordStorageLocation *Loc = nullptr;

329 if (S->getType()->isPointerType()) {

330 auto *PV = Env.get(*SubExpr);

331 assert(PV != nullptr);

332 if (PV == nullptr)

333 break;

335 } else {

336 assert(S->getType()->isRecordType());

337 if (SubExpr->isGLValue()) {

338 Loc = Env.get(*SubExpr);

339 } else {

340 Loc = &Env.getResultObjectLocation(*SubExpr);

341 }

342 }

343 if (!Loc) {

344

345 break;

346 }

347

348

349 QualType Derived = S->getType().getNonReferenceType();

350 if (Derived->isPointerType()) {

351 Derived = Derived->getPointeeType();

352 }

353

354

355

356 for (const FieldDecl *Field :

357 Env.getDataflowAnalysisContext().getModeledFields(Derived)) {

358 assert(Field != nullptr);

359 QualType FieldType = Field->getType();

360 if (FieldType->isReferenceType()) {

361 Loc->addChild(*Field, nullptr);

362 } else {

363 Loc->addChild(*Field, &Env.createStorageLocation(FieldType));

364 }

365

366 for (const auto &Entry :

367 Env.getDataflowAnalysisContext().getSyntheticFields(Derived)) {

368 Loc->addSyntheticField(Entry.getKey(),

369 Env.createStorageLocation(Entry.getValue()));

370 }

371 }

372 Env.initializeFieldsWithValues(*Loc, Derived);

373

374

375 [[fallthrough]];

376 }

377 case CK_IntegralCast:

378

379

380

381

382

383 case CK_UncheckedDerivedToBase:

384 case CK_DerivedToBase:

385 case CK_ConstructorConversion:

386 case CK_UserDefinedConversion:

387 case CK_NoOp: {

388

389

390

392 break;

393 }

394 case CK_NullToPointer: {

395 auto &NullPointerVal =

396 Env.getOrCreateNullPointerValue(S->getType()->getPointeeType());

397 Env.setValue(*S, NullPointerVal);

398 break;

399 }

400 case CK_NullToMemberPointer:

401

402

403 break;

404 case CK_FunctionToPointerDecay: {

405 StorageLocation *PointeeLoc = Env.getStorageLocation(*SubExpr);

406 if (PointeeLoc == nullptr)

407 break;

408

409 Env.setValue(*S, Env.create(*PointeeLoc));

410 break;

411 }

412 case CK_BuiltinFnToFnPtr:

413

414

415

416

417 break;

418 default:

419 break;

420 }

421 }

422

423 void VisitUnaryOperator(const UnaryOperator *S) {

424 const Expr *SubExpr = S->getSubExpr();

425 assert(SubExpr != nullptr);

426

427 switch (S->getOpcode()) {

428 case UO_Deref: {

429 const auto *SubExprVal = Env.get(*SubExpr);

430 if (SubExprVal == nullptr)

431 break;

432

433 Env.setStorageLocation(*S, SubExprVal->getPointeeLoc());

434 break;

435 }

436 case UO_AddrOf: {

437

438 if (S->getType()->isMemberPointerType())

439 break;

440

441 if (StorageLocation *PointeeLoc = Env.getStorageLocation(*SubExpr))

442 Env.setValue(*S, Env.create(*PointeeLoc));

443 break;

444 }

445 case UO_LNot: {

446 auto *SubExprVal = dyn_cast_or_null(Env.getValue(*SubExpr));

447 if (SubExprVal == nullptr)

448 break;

449

450 Env.setValue(*S, Env.makeNot(*SubExprVal));

451 break;

452 }

453 case UO_PreInc:

454 case UO_PreDec:

455

456

457

458

460 if (StorageLocation *Loc = Env.getStorageLocation(*S->getSubExpr()))

461 Env.clearValue(*Loc);

462 break;

463 case UO_PostInc:

464 case UO_PostDec:

465

466

467

469 if (StorageLocation *Loc = Env.getStorageLocation(*S->getSubExpr()))

470 Env.clearValue(*Loc);

471 break;

472 default:

473 break;

474 }

475 }

476

477 void VisitCXXThisExpr(const CXXThisExpr *S) {

478 auto *ThisPointeeLoc = Env.getThisPointeeStorageLocation();

479 if (ThisPointeeLoc == nullptr)

480

481

482 return;

483

484 Env.setValue(*S, Env.create(*ThisPointeeLoc));

485 }

486

487 void VisitCXXNewExpr(const CXXNewExpr *S) {

488 if (Value *Val = Env.createValue(S->getType()))

489 Env.setValue(*S, *Val);

490 }

491

492 void VisitCXXDeleteExpr(const CXXDeleteExpr *S) {

493

494

495

496

497 }

498

499 void VisitReturnStmt(const ReturnStmt *S) {

500 if (!Env.getDataflowAnalysisContext().getOptions().ContextSensitiveOpts)

501 return;

502

503 auto *Ret = S->getRetValue();

504 if (Ret == nullptr)

505 return;

506

507 if (Ret->isPRValue()) {

508 if (Ret->getType()->isRecordType())

509 return;

510

511 auto *Val = Env.getValue(*Ret);

512 if (Val == nullptr)

513 return;

514

515

516 Env.setReturnValue(Val);

517 } else {

518 auto *Loc = Env.getStorageLocation(*Ret);

519 if (Loc == nullptr)

520 return;

521

522

523 Env.setReturnStorageLocation(Loc);

524 }

525 }

526

527 void VisitMemberExpr(const MemberExpr *S) {

528 ValueDecl *Member = S->getMemberDecl();

529 assert(Member != nullptr);

530

531

532 if (Member->isFunctionOrFunctionTemplate())

533 return;

534

535

537 return;

538

539 if (auto *D = dyn_cast(Member)) {

540 if (D->hasGlobalStorage()) {

541 auto *VarDeclLoc = Env.getStorageLocation(*D);

542 if (VarDeclLoc == nullptr)

543 return;

544

545 Env.setStorageLocation(*S, *VarDeclLoc);

546 return;

547 }

548 }

549

551 if (BaseLoc == nullptr)

552 return;

553

554 auto *MemberLoc = BaseLoc->getChild(*Member);

555 if (MemberLoc == nullptr)

556 return;

557 Env.setStorageLocation(*S, *MemberLoc);

558 }

559

560 void VisitCXXDefaultArgExpr(const CXXDefaultArgExpr *S) {

561 const Expr *ArgExpr = S->getExpr();

562 assert(ArgExpr != nullptr);

564

565 if (S->isPRValue() && S->getType()->isRecordType()) {

566 auto &Loc = Env.getResultObjectLocation(*S);

567 Env.initializeFieldsWithValues(Loc);

568 }

569 }

570

571 void VisitCXXDefaultInitExpr(const CXXDefaultInitExpr *S) {

572 const Expr *InitExpr = S->getExpr();

573 assert(InitExpr != nullptr);

574

575

576

577

578 if (S->getType()->isRecordType() && S->isPRValue())

579 return;

580

582 }

583

584 void VisitCXXConstructExpr(const CXXConstructExpr *S) {

585 const CXXConstructorDecl *ConstructorDecl = S->getConstructor();

586 assert(ConstructorDecl != nullptr);

587

588

589

590

591 if (!S->getType()->isRecordType()) {

592 transferInlineCall(S, ConstructorDecl);

593 return;

594 }

595

596 RecordStorageLocation &Loc = Env.getResultObjectLocation(*S);

597

598 if (ConstructorDecl->isCopyOrMoveConstructor()) {

599

600

601 assert(S->getNumArgs() != 0);

602

603 const Expr *Arg = S->getArg(0);

604 assert(Arg != nullptr);

605

606 auto *ArgLoc = Env.get(*Arg);

607 if (ArgLoc == nullptr)

608 return;

609

610

611

612

613

614

615

616

617

618

619

620

621 copyRecord(*ArgLoc, Loc, Env, S->getType());

622 return;

623 }

624

625 Env.initializeFieldsWithValues(Loc, S->getType());

626

627 transferInlineCall(S, ConstructorDecl);

628 }

629

630 void VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *S) {

631 if (S->getOperator() == OO_Equal) {

632 assert(S->getNumArgs() == 2);

633

634 const Expr *Arg0 = S->getArg(0);

635 assert(Arg0 != nullptr);

636

637 const Expr *Arg1 = S->getArg(1);

638 assert(Arg1 != nullptr);

639

640

642 dyn_cast_or_null(S->getDirectCallee());

644 return;

645 if (Method->isCopyAssignmentOperator() &&

646 Method->isMoveAssignmentOperator())

647 return;

648

649 RecordStorageLocation *LocSrc = nullptr;

650 if (Arg1->isPRValue()) {

651 LocSrc = &Env.getResultObjectLocation(*Arg1);

652 } else {

653 LocSrc = Env.get(*Arg1);

654 }

655 auto *LocDst = Env.get(*Arg0);

656

657 if (LocSrc == nullptr || LocDst == nullptr)

658 return;

659

660

661

662

663

664

665 copyRecord(*LocSrc, *LocDst, Env, Arg0->getType());

666

667

668

669

670 if (S->getType().getCanonicalType().getUnqualifiedType() !=

671 LocDst->getType().getCanonicalType().getUnqualifiedType()) {

672 auto ReturnDecl = S->getType()->getAsCXXRecordDecl();

673 auto DstDecl = LocDst->getType()->getAsCXXRecordDecl();

674 if (ReturnDecl == nullptr || DstDecl == nullptr)

675 return;

676 if (!DstDecl->isDerivedFrom(ReturnDecl))

677 return;

678 }

679

680 if (S->isGLValue())

681 Env.setStorageLocation(*S, *LocDst);

682 else

683 copyRecord(*LocDst, Env.getResultObjectLocation(*S), Env);

684

685 return;

686 }

687

688

689

690 VisitCallExpr(S);

691 }

692

693 void VisitCXXRewrittenBinaryOperator(const CXXRewrittenBinaryOperator *RBO) {

695 }

696

697 void VisitCallExpr(const CallExpr *S) {

698

699

700

701 if (S->isCallToStdMove()) {

702 assert(S->getNumArgs() == 1);

703

704 const Expr *Arg = S->getArg(0);

705 assert(Arg != nullptr);

706

707 auto *ArgLoc = Env.getStorageLocation(*Arg);

708 if (ArgLoc == nullptr)

709 return;

710

711 Env.setStorageLocation(*S, *ArgLoc);

712 } else if (S->getDirectCallee() != nullptr &&

713 S->getDirectCallee()->getBuiltinID() ==

714 Builtin::BI__builtin_expect) {

715 assert(S->getNumArgs() > 0);

716 assert(S->getArg(0) != nullptr);

717 auto *ArgVal = Env.getValue(*S->getArg(0));

718 if (ArgVal == nullptr)

719 return;

720 Env.setValue(*S, *ArgVal);

721 } else if (const FunctionDecl *F = S->getDirectCallee()) {

722 transferInlineCall(S, F);

723

724

725

726 if (S->getType()->isRecordType() && S->isPRValue()) {

727 RecordStorageLocation &Loc = Env.getResultObjectLocation(*S);

728 Env.initializeFieldsWithValues(Loc);

729 }

730 }

731 }

732

733 void VisitMaterializeTemporaryExpr(const MaterializeTemporaryExpr *S) {

734 const Expr *SubExpr = S->getSubExpr();

735 assert(SubExpr != nullptr);

736

737 StorageLocation &Loc = Env.createStorageLocation(*S);

738 Env.setStorageLocation(*S, Loc);

739

740 if (SubExpr->getType()->isRecordType())

741

742

743 return;

744

745 if (Value *SubExprVal = Env.getValue(*SubExpr))

746 Env.setValue(Loc, *SubExprVal);

747 }

748

749 void VisitCXXBindTemporaryExpr(const CXXBindTemporaryExpr *S) {

750 const Expr *SubExpr = S->getSubExpr();

751 assert(SubExpr != nullptr);

752

754 }

755

756 void VisitConditionalOperator(const ConditionalOperator *S) {

757 const Environment *TrueEnv = StmtToEnv.getEnvironment(*S->getTrueExpr());

758 const Environment *FalseEnv = StmtToEnv.getEnvironment(*S->getFalseExpr());

759

760 if (TrueEnv == nullptr || FalseEnv == nullptr) {

761

762

763

764

765 return;

766 }

767

768 if (S->isGLValue()) {

769 StorageLocation *TrueLoc = TrueEnv->getStorageLocation(*S->getTrueExpr());

770 StorageLocation *FalseLoc =

771 FalseEnv->getStorageLocation(*S->getFalseExpr());

772 if (TrueLoc == FalseLoc && TrueLoc != nullptr) {

773 Env.setStorageLocation(*S, *TrueLoc);

774 } else if (!S->getType()->isRecordType()) {

775

776

777

778

779

780

781

782

783

784

785

787 S->getType(), TrueEnv->getValue(*S->getTrueExpr()), *TrueEnv,

788 FalseEnv->getValue(*S->getFalseExpr()), *FalseEnv, Env,

789 Model)) {

790 StorageLocation &Loc = Env.createStorageLocation(*S);

791 Env.setStorageLocation(*S, Loc);

792 Env.setValue(Loc, *Val);

793 }

794 }

795 } else if (!S->getType()->isRecordType()) {

796

797

798

799

800

801

802

803

804

805

806

807

808

809

810

812 S->getType(), TrueEnv->getValue(*S->getTrueExpr()), *TrueEnv,

813 FalseEnv->getValue(*S->getFalseExpr()), *FalseEnv, Env, Model))

814 Env.setValue(*S, *Val);

815 }

816 }

817

818 void VisitInitListExpr(const InitListExpr *S) {

819 QualType Type = S->getType();

820

821 if (Type->isRecordType()) {

822

823

824 if (Type->isArrayType() && S->getNumInits() == 1)

826 return;

827 }

828

829

830 if (S->isSemanticForm() && S->isTransparent())

831 return;

832

833 RecordStorageLocation &Loc = Env.getResultObjectLocation(*S);

834

835

836

837

838

839

840 RecordInitListHelper InitListHelper(S);

841

842 for (auto [Field, Init] : InitListHelper.field_inits()) {

843 if (Field->getType()->isRecordType())

844 continue;

845 if (Field->getType()->isReferenceType()) {

846 assert(Field->getType().getCanonicalType()->getPointeeType() ==

847 Init->getType().getCanonicalType());

848 Loc.setChild(*Field, &Env.createObject(Field->getType(), Init));

849 continue;

850 }

851 assert(Field->getType().getCanonicalType().getUnqualifiedType() ==

852 Init->getType().getCanonicalType().getUnqualifiedType());

853 StorageLocation *FieldLoc = Loc.getChild(*Field);

854

855 assert(FieldLoc != nullptr);

856 Value *Val = Env.getValue(*Init);

858 Init->getType()->isPointerType())

859 Val =

860 &Env.getOrCreateNullPointerValue(Init->getType()->getPointeeType());

861 if (Val == nullptr)

862 Val = Env.createValue(Field->getType());

863 if (Val != nullptr)

864 Env.setValue(*FieldLoc, *Val);

865 }

866

867 for (const auto &[FieldName, FieldLoc] : Loc.synthetic_fields()) {

868 QualType FieldType = FieldLoc->getType();

869 if (FieldType->isRecordType()) {

871 } else {

872 if (Value *Val = Env.createValue(FieldType))

873 Env.setValue(*FieldLoc, *Val);

874 }

875 }

876

877

878 }

879

880 void VisitCXXBoolLiteralExpr(const CXXBoolLiteralExpr *S) {

881 Env.setValue(*S, Env.getBoolLiteralValue(S->getValue()));

882 }

883

884 void VisitIntegerLiteral(const IntegerLiteral *S) {

885 Env.setValue(*S, Env.getIntLiteralValue(S->getValue()));

886 }

887

888 void VisitParenExpr(const ParenExpr *S) {

889

890

891

892 auto *SubExpr = S->getSubExpr();

893 assert(SubExpr != nullptr);

894 Visit(SubExpr);

895 }

896

897 void VisitExprWithCleanups(const ExprWithCleanups *S) {

898

899

900

901 auto *SubExpr = S->getSubExpr();

902 assert(SubExpr != nullptr);

903 Visit(SubExpr);

904 }

905

906private:

907

908 BoolValue &getLogicOperatorSubExprValue(const Expr &SubExpr) {

909

910

911

912 if (const Environment *SubExprEnv = StmtToEnv.getEnvironment(SubExpr))

913 if (auto *Val =

914 dyn_cast_or_null(SubExprEnv->getValue(SubExpr)))

915 return *Val;

916

917

918

919

920

921

922 if (Env.getValue(SubExpr) == nullptr)

923 Visit(&SubExpr);

924 if (auto *Val = dyn_cast_or_null(Env.getValue(SubExpr)))

925 return *Val;

926

927

928

929 return Env.makeAtomicBoolValue();

930 }

931

932

933

934 template

935 void transferInlineCall(const E *S, const FunctionDecl *F) {

936 const auto &Options = Env.getDataflowAnalysisContext().getOptions();

937 if (!(Options.ContextSensitiveOpts &&

938 Env.canDescend(Options.ContextSensitiveOpts->Depth, F)))

939 return;

940

941 const AdornedCFG *ACFG = Env.getDataflowAnalysisContext().getAdornedCFG(F);

942 if (!ACFG)

943 return;

944

945

946

947

948

949 auto ExitBlock = ACFG->getCFG().getExit().getBlockID();

950

951 auto CalleeEnv = Env.pushCall(S);

952

953

954

955

956 auto Analysis = NoopAnalysis(ACFG->getDecl().getASTContext(),

957 DataflowAnalysisOptions{Options});

958

959 auto BlockToOutputState =

961 assert(BlockToOutputState);

962 assert(ExitBlock < BlockToOutputState->size());

963

964 auto &ExitState = (*BlockToOutputState)[ExitBlock];

965 assert(ExitState);

966

967 Env.popCall(S, ExitState->Env);

968 }

969

970 const StmtToEnvMap &StmtToEnv;

971 Environment &Env;

972 Environment::ValueModel &Model;

973};

974

975}

976

979 TransferVisitor(StmtToEnv, Env, Model).Visit(&S);

980}

981

982}

983}

Defines enum values for all the target-independent builtin functions.

Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate....

Defines the clang::Expr interface and subclasses for C++ expressions.

Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified.

Defines an enumeration for C++ overloaded operators.

C Language Family Type Representation.

Represents a single basic block in a source-level CFG.

ConstStmtVisitor - This class implements a simple visitor for Stmt subclasses.

This represents one expression.

Stmt - This represents one statement.

bool isNullPtrType() const

bool isRecordType() const

BoolValue & makeBoolValue(const Formula &)

Creates a BoolValue wrapping a particular formula.

Supplements Environment with non-standard comparison and join operations.

Holds the state of the program (store and heap) at a given program point.

BoolValue & makeIff(BoolValue &LHS, BoolValue &RHS) const

Returns a boolean value represents LHS <=> RHS.

StorageLocation * getStorageLocation(const ValueDecl &D) const

Returns the storage location assigned to D in the environment, or null if D isn't assigned a storage ...

BoolValue & makeAtomicBoolValue() const

Returns an atomic boolean value.

Value * getValue(const StorageLocation &Loc) const

Returns the value assigned to Loc in the environment or null if Loc isn't assigned a value in the env...

BoolValue & getBoolLiteralValue(bool Value) const

Returns a symbolic boolean value that models a boolean literal equal to Value

DataflowAnalysisContext & getDataflowAnalysisContext() const

Returns the DataflowAnalysisContext used by the environment.

static Value * joinValues(QualType Ty, Value *Val1, const Environment &Env1, Value *Val2, const Environment &Env2, Environment &JoinedEnv, Environment::ValueModel &Model)

Returns a value that approximates both Val1 and Val2, or null if no such value can be produced.

void setStorageLocation(const ValueDecl &D, StorageLocation &Loc)

Assigns Loc as the storage location of D in the environment.

void setValue(const StorageLocation &Loc, Value &Val)

Assigns Val as the value of Loc in the environment.

Maps statements to the environments of basic blocks that contain them.

const Environment * getEnvironment(const Stmt &S) const

Returns the environment of the basic block that contains S.

Definition Transfer.cpp:44

Base class for all values computed by abstract interpretation.

void transfer(const StmtToEnvMap &StmtToEnv, const Stmt &S, Environment &Env, Environment::ValueModel &Model)

Evaluates S and updates Env accordingly.

Definition Transfer.cpp:977

static void propagateValueOrStorageLocation(const Expr &From, const Expr &To, Environment &Env)

Definition Transfer.cpp:134

static void propagateStorageLocation(const Expr &From, const Expr &To, Environment &Env)

Definition Transfer.cpp:125

void copyRecord(RecordStorageLocation &Src, RecordStorageLocation &Dst, Environment &Env, QualType TypeToCopy=QualType())

Copies a record (struct, class, or union) from Src to Dst.

static void propagateValue(const Expr &From, const Expr &To, Environment &Env)

Definition Transfer.cpp:118

static Value * maybeUnpackLValueExpr(const Expr &E, Environment &Env)

Definition Transfer.cpp:101

static BoolValue & unpackValue(BoolValue &V, Environment &Env)

Definition Transfer.cpp:90

static BoolValue & evaluateBooleanEquality(const Expr &LHS, const Expr &RHS, Environment &Env)

Definition Transfer.cpp:60

RecordStorageLocation * getBaseObjectLocation(const MemberExpr &ME, const Environment &Env)

Returns the storage location for the base object of a MemberExpr, or null if none is defined in the e...

llvm::Expected< std::vector< std::optional< DataflowAnalysisState< typename AnalysisT::Lattice > > > > runDataflowAnalysis(const AdornedCFG &ACFG, AnalysisT &Analysis, const Environment &InitEnv, CFGEltCallbacks< AnalysisT > PostAnalysisCallbacks={}, std::int32_t MaxBlockVisits=kDefaultMaxBlockVisits)

Performs dataflow analysis and returns a mapping from basic block IDs to dataflow analysis states tha...

bool Ret(InterpState &S, CodePtr &PC)

The JSON file list parser is used to communicate input to InstallAPI.

bool isa(CodeGen::Address addr)

@ Type

The name was classified as a type.

U cast(CodeGen::Address addr)