DefinedOrUnknownSVal TypedValueRegion::getExtent(SValBuilder &svalBuilder) const { ASTContext &Ctx = svalBuilder.getContext(); QualType T = getDesugaredValueType(Ctx); if (isa<VariableArrayType>(T)) return nonloc::SymbolVal(svalBuilder.getSymbolManager().getExtentSymbol(this)); if (isa<IncompleteArrayType>(T)) return UnknownVal(); CharUnits size = Ctx.getTypeSizeInChars(T); QualType sizeTy = svalBuilder.getArrayIndexType(); return svalBuilder.makeIntVal(size.getQuantity(), sizeTy); }
DefinedOrUnknownSVal FieldRegion::getExtent(SValBuilder &svalBuilder) const { DefinedOrUnknownSVal Extent = DeclRegion::getExtent(svalBuilder); // A zero-length array at the end of a struct often stands for dynamically- // allocated extra memory. if (Extent.isZeroConstant()) { QualType T = getDesugaredValueType(svalBuilder.getContext()); if (isa<ConstantArrayType>(T)) return UnknownVal(); } return Extent; }
/// Compute a raw byte offset from a base region. Used for array bounds /// checking. RegionRawOffsetV2 RegionRawOffsetV2::computeOffset(ProgramStateRef state, SValBuilder &svalBuilder, SVal location) { const MemRegion *region = location.getAsRegion(); SVal offset = UndefinedVal(); while (region) { switch (region->getKind()) { default: { if (const SubRegion *subReg = dyn_cast<SubRegion>(region)) { offset = getValue(offset, svalBuilder); if (!offset.isUnknownOrUndef()) return RegionRawOffsetV2(subReg, offset); } return RegionRawOffsetV2(); } case MemRegion::ElementRegionKind: { const ElementRegion *elemReg = cast<ElementRegion>(region); SVal index = elemReg->getIndex(); if (!isa<NonLoc>(index)) return RegionRawOffsetV2(); QualType elemType = elemReg->getElementType(); // If the element is an incomplete type, go no further. ASTContext &astContext = svalBuilder.getContext(); if (!IsCompleteType(astContext, elemType)) return RegionRawOffsetV2(); // Update the offset. offset = addValue(state, getValue(offset, svalBuilder), scaleValue(state, cast<NonLoc>(index), astContext.getTypeSizeInChars(elemType), svalBuilder), svalBuilder); if (offset.isUnknownOrUndef()) return RegionRawOffsetV2(); region = elemReg->getSuperRegion(); continue; } } } return RegionRawOffsetV2(); }