clang: lib/StaticAnalyzer/Core/Store.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

31#include "llvm/ADT/APSInt.h"

32#include "llvm/ADT/STLExtras.h"

33#include "llvm/Support/ErrorHandling.h"

34#include

35#include

36#include

37

38using namespace clang;

39using namespace ento;

40

44

48

50 Call.getInitialStackFrameContents(LCtx, InitialBindings);

51

52 for (const auto &[Location, Val] : InitialBindings) {

53 Store S = Result.ResultingStore.getStore();

57 }

58

60}

61

68

72 assert(T.isNull());

73 return MRMgr.getElementRegion(T, idx, R, Ctx);

74}

75

79

80

83

85

86

87

88

90 return R;

91

92

93

94 return std::nullopt;

95 }

96

97

98

100 QualType CanonPointeeTy = Ctx.getCanonicalType(PointeeTy);

102

103

104 if (CanonPointeeTy == Ctx.VoidTy)

105 return R;

106

108 if (const auto *TR = dyn_cast(R)) {

109 QualType ObjTy = Ctx.getCanonicalType(TR->getValueType());

111 return true;

112 }

113 return false;

114 };

115

116

117 if (R->isBoundable() && IsSameRegionType(R, CanonPointeeTy))

118 return R;

119

120

122 case MemRegion::CXXThisRegionKind:

123 case MemRegion::CodeSpaceRegionKind:

124 case MemRegion::StackLocalsSpaceRegionKind:

125 case MemRegion::StackArgumentsSpaceRegionKind:

126 case MemRegion::HeapSpaceRegionKind:

127 case MemRegion::UnknownSpaceRegionKind:

128 case MemRegion::StaticGlobalSpaceRegionKind:

129 case MemRegion::GlobalInternalSpaceRegionKind:

130 case MemRegion::GlobalSystemSpaceRegionKind:

131 case MemRegion::GlobalImmutableSpaceRegionKind: {

132 llvm_unreachable("Invalid region cast");

133 }

134

135 case MemRegion::FunctionCodeRegionKind:

136 case MemRegion::BlockCodeRegionKind:

137 case MemRegion::BlockDataRegionKind:

138 case MemRegion::StringRegionKind:

139

140 case MemRegion::SymbolicRegionKind:

141 case MemRegion::AllocaRegionKind:

142 case MemRegion::CompoundLiteralRegionKind:

143 case MemRegion::FieldRegionKind:

144 case MemRegion::ObjCIvarRegionKind:

145 case MemRegion::ObjCStringRegionKind:

146 case MemRegion::NonParamVarRegionKind:

147 case MemRegion::ParamVarRegionKind:

148 case MemRegion::CXXTempObjectRegionKind:

149 case MemRegion::CXXLifetimeExtendedObjectRegionKind:

150 case MemRegion::CXXBaseObjectRegionKind:

151 case MemRegion::CXXDerivedObjectRegionKind:

153

154 case MemRegion::ElementRegionKind: {

155

156

157

158

159

160

161

162

163

164

165

166

167

168

169

170

171

172

173

177

178

179

180 if (!baseR)

181 return std::nullopt;

182

184

186

187

188

189 if (IsSameRegionType(baseR, CanonPointeeTy))

190 return baseR;

191

193 }

194

195

196

197

198

199

200

201

202 int64_t newIndex = 0;

203 const MemRegion *newSuperR = nullptr;

204

205

207

208 CharUnits pointeeTySize = Ctx.getTypeSizeInChars(PointeeTy);

209 if (!pointeeTySize.isZero()) {

210

211

212

214 newIndex = off / pointeeTySize;

215 newSuperR = baseR;

216 }

217 }

218 }

219

220 if (!newSuperR) {

221

222

225 }

226

228 }

229 }

230

231 llvm_unreachable("unreachable");

232}

233

235 const MemRegion *MR = V.getAsRegion();

236 if (!MR)

237 return true;

238

239 const auto *TVR = dyn_cast(MR);

240 if (!TVR)

241 return true;

242

243 const CXXRecordDecl *RD = TVR->getValueType()->getAsCXXRecordDecl();

244 if (!RD)

245 return true;

246

250

252}

253

255

256

259

260

264 }

266}

267

269

271 for (const auto &I : Path)

273 I.Base->isVirtual());

275}

276

278 bool IsVirtual) {

280 if (!DerivedReg)

281 return Derived;

282

283 const CXXRecordDecl *BaseDecl = BaseType->getPointeeCXXRecordDecl();

284 if (!BaseDecl)

285 BaseDecl = BaseType->getAsCXXRecordDecl();

286 assert(BaseDecl && "not a C++ object?");

287

288 if (const auto *AlreadyDerivedReg =

289 dyn_cast(DerivedReg)) {

290 if (const auto *SR =

291 dyn_cast(AlreadyDerivedReg->getSuperRegion()))

292 if (SR->getSymbol()->getType()->getPointeeCXXRecordDecl() == BaseDecl)

294

295 DerivedReg = AlreadyDerivedReg->getSuperRegion();

296 }

297

298 const MemRegion *BaseReg = MRMgr.getCXXBaseObjectRegion(

300

302}

303

304

305

306

307

308

309

311 if (const auto *TVR = dyn_cast(MR))

312 return TVR->getValueType()->getAsCXXRecordDecl();

313 if (const auto *SR = dyn_cast(MR))

314 return SR->getSymbol()->getType()->getPointeeCXXRecordDecl();

315 return nullptr;

316}

317

321 if (!MR)

323

324

326 assert(!TargetType.isNull());

328 if (!TargetClass && !TargetType->isVoidType())

330

331

332

334

335 if (MRClass == TargetClass)

337

338

339

340

341 if (!TargetType->isVoidType() && MRClass->hasDefinition()) {

342

343

344 CXXBasePaths Paths(false, true,

345 false);

346 if (MRClass->isDerivedFrom(TargetClass, Paths))

348 }

349

350 if (const auto *BaseR = dyn_cast(MR)) {

351

352 MR = BaseR->getSuperRegion();

353 continue;

354 }

355

356

359

360

361

362

363

364

365

366

367

369 if (Uncasted == MR) {

370

371

372

373 break;

374 }

375

376 MR = Uncasted;

377 }

378

379

380

381

382

383

384 if (const auto *SR = dyn_cast(MR)) {

385 QualType T = SR->getSymbol()->getType();

386 const CXXRecordDecl *SourceClass = T->getPointeeCXXRecordDecl();

387 if (TargetClass && SourceClass && TargetClass->isDerivedFrom(SourceClass))

389 MRMgr.getCXXDerivedObjectRegion(TargetClass, SR));

391 }

392

393

395 return std::nullopt;

396

398}

399

400SVal StoreManager::getLValueFieldOrIvar(const Decl *D, SVal Base) {

401 if (Base.isUnknownOrUndef())

403

405 const SubRegion* BaseR = nullptr;

406

407 switch (BaseL.getKind()) {

408 case loc::MemRegionValKind:

410 break;

411

412 case loc::GotoLabelKind:

413

415

416 case loc::ConcreteIntKind:

417

418

419

420

421

422

423

424

425

426

428

429 default:

430 llvm_unreachable("Unhandled Base.");

431 }

432

433

434

435 if (const auto *ID = dyn_cast(D))

437

439}

440

442 return getLValueFieldOrIvar(decl, base);

443}

444

447

448

449

450 if (Offset.isZeroConstant()) {

454 if (!PointeeTy.isNull() &&

457 }

458 }

459

460

461

462

463

466

469

472

473

474 const auto *ElemR = dyn_cast(BaseRegion);

475

476

477 auto Off = svalBuilder.convertToArrayIndex(Offset).getAs<NonLoc>();

478 if (!Off) {

479

480

481

482

483

485 }

486

487 Offset = Off.value();

488

489 if (!ElemR) {

490

491

492

493

494

495

496

498 BaseRegion, Ctx));

499 }

500

501 SVal BaseIdx = ElemR->getIndex();

502

505

506 const llvm::APSInt &BaseIdxI =

508

509

510

511

514 elementType, Offset, cast(ElemR->getSuperRegion()), Ctx));

515

516 const llvm::APSInt& OffI = Offset.castAs<nonloc::ConcreteInt>().getValue();

517 assert(BaseIdxI.isSigned());

518

519

521 OffI));

522

523

527}

528

530

536 if (!SymV || SymV != Sym)

537 return true;

538

539 if (Binding) {

540 First = false;

541 return false;

542 }

543 else

544 Binding = R;

545

546 return true;

547}

Defines the clang::ASTContext interface.

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

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

static bool regionMatchesCXXRecordType(SVal V, QualType Ty)

Definition Store.cpp:234

static const CXXRecordDecl * getCXXRecordType(const MemRegion *MR)

Returns the static type of the given region, if it represents a C++ class object.

Definition Store.cpp:310

C Language Family Type Representation.

Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...

Represents a path from a specific derived class (which is not represented as part of the path) to a p...

BasePaths - Represents the set of paths from a derived class to one of its (direct or indirect) bases...

Represents a base class of a C++ class.

Represents a C++ struct/union/class.

CXXRecordDecl * getCanonicalDecl() override

Retrieves the "canonical" declaration of the given declaration.

bool isDerivedFrom(const CXXRecordDecl *Base) const

Determine whether this class is derived from the class Base.

CastExpr - Base class for type casts, including both implicit casts (ImplicitCastExpr) and explicit c...

CharUnits - This is an opaque type for sizes expressed in character units.

bool isZero() const

isZero - Test whether the quantity equals zero.

QuantityType getQuantity() const

getQuantity - Get the raw integer representation of this quantity.

bool isMultipleOf(CharUnits N) const

Test whether this is a multiple of the other value.

Decl - This represents one declaration (or definition), e.g.

ObjCIvarDecl - Represents an ObjC instance variable.

A (possibly-)qualified type.

QualType getLocalUnqualifiedType() const

Return this type with all of the instance-specific qualifiers removed, but without removing any quali...

bool isNull() const

Return true if this QualType doesn't point to a type yet.

QualType getCanonicalType() const

It represents a stack frame of the call stack (based on CallEvent).

bool isBlockPointerType() const

CXXRecordDecl * getAsCXXRecordDecl() const

Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...

const CXXRecordDecl * getPointeeCXXRecordDecl() const

If this is a pointer or reference to a RecordType, return the CXXRecordDecl that the type refers to.

QualType getPointeeType() const

If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.

bool isIncompleteType(NamedDecl **Def=nullptr) const

Types are partitioned into 3 broad categories (C99 6.2.5p1): object types, function types,...

bool isObjCObjectPointerType() const

Represents an abstract call to a function or method along a particular path.

ElementRegion is used to represent both array elements and casts.

RegionRawOffset getAsArrayOffset() const

Compute the offset within the array. The array might also be a subobject.

const FieldRegion * getFieldRegion(const FieldDecl *FD, const SubRegion *SuperRegion)

getFieldRegion - Retrieve or create the memory region associated with a specified FieldDecl.

const ObjCIvarRegion * getObjCIvarRegion(const ObjCIvarDecl *ivd, const SubRegion *superRegion)

getObjCIvarRegion - Retrieve or create the memory region associated with a specified Objective-c inst...

MemRegion - The root abstract class for all memory regions.

virtual bool isBoundable() const

LLVM_ATTRIBUTE_RETURNS_NONNULL const MemRegion * StripCasts(bool StripBaseAndDerivedCasts=true) const

CharUnits getOffset() const

const MemRegion * getRegion() const

SVal - This represents a symbolic expression, which can be either an L-value or an R-value.

SymbolRef getAsLocSymbol(bool IncludeBaseRegions=false) const

If this SVal is a location and wraps a symbol, return that SymbolRef.

const MemRegion * getAsRegion() const

T castAs() const

Convert to the specified SVal type, asserting that this SVal is of the desired type.

virtual ~BindingsHandler()

bool HandleBinding(StoreManager &SMgr, Store store, const MemRegion *R, SVal val) override

Definition Store.cpp:531

SVal evalDerivedToBase(SVal Derived, const CastExpr *Cast)

Evaluates a chain of derived-to-base casts through the path specified in Cast.

Definition Store.cpp:254

ProgramStateManager & StateMgr

SValBuilder & getSValBuilder()

MemRegionManager & getRegionManager()

getRegionManager - Returns the internal RegionManager object that is used to query and manipulate Mem...

std::optional< SVal > evalBaseToDerived(SVal Base, QualType DerivedPtrType)

Attempts to do a down cast.

Definition Store.cpp:318

BindResult enterStackFrame(Store store, const CallEvent &Call, const StackFrameContext *CalleeCtx)

enterStackFrame - Let the StoreManager to do something when execution engine is about to execute into...

Definition Store.cpp:45

const ElementRegion * MakeElementRegion(const SubRegion *baseRegion, QualType pointeeTy, uint64_t index=0)

Definition Store.cpp:62

MemRegionManager & MRMgr

MRMgr - Manages region objects associated with this StoreManager.

SValBuilder & svalBuilder

virtual SVal getLValueIvar(const ObjCIvarDecl *decl, SVal base)

Definition Store.cpp:441

StoreManager(ProgramStateManager &stateMgr)

Definition Store.cpp:41

const ElementRegion * GetElementZeroRegion(const SubRegion *R, QualType T)

Definition Store.cpp:69

virtual SVal getLValueElement(QualType elementType, NonLoc offset, SVal Base)

Definition Store.cpp:445

std::optional< const MemRegion * > castRegion(const MemRegion *region, QualType CastToTy)

castRegion - Used by ExprEngine::VisitCast to handle casts from a MemRegion* to a specific location t...

Definition Store.cpp:76

SubRegion - A region that subsets another larger region.

LLVM_ATTRIBUTE_RETURNS_NONNULL const MemRegion * getRegion() const

Get the underlining region.

Value representing integer constant.

const internal::VariadicAllOfMatcher< Decl > decl

Matches declarations.

const SymExpr * SymbolRef

const void * Store

Store - This opaque type encapsulates an immutable mapping from locations to values.

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

bool isa(CodeGen::Address addr)

@ Bind

'bind' clause, allowed on routine constructs.

@ Result

The result type of a method or function.

const FunctionProtoType * T

U cast(CodeGen::Address addr)

llvm::SmallVector< SVal, 0 > FailedToBindValues