================ @@ -393,6 +401,173 @@ ProgramStateRef CStringChecker::checkNonNull(CheckerContext &C, return stateNonNull; } +static std::optional<NonLoc> getIndex(ProgramStateRef State, + const ElementRegion *ER, CharKind CK) { + SValBuilder &SValBuilder = State->getStateManager().getSValBuilder(); + ASTContext &Ctx = SValBuilder.getContext(); + + if (CK == CharKind::Regular) { + if (ER->getValueType() != Ctx.CharTy) + return {}; + return ER->getIndex(); + } + + if (ER->getValueType() != Ctx.WideCharTy) + return {}; + + QualType SizeTy = Ctx.getSizeType(); + NonLoc WideSize = + SValBuilder + .makeIntVal(Ctx.getTypeSizeInChars(Ctx.WideCharTy).getQuantity(), + SizeTy) + .castAs<NonLoc>(); + SVal Offset = + SValBuilder.evalBinOpNN(State, BO_Mul, ER->getIndex(), WideSize, SizeTy); + if (Offset.isUnknown()) + return {}; + return Offset.castAs<NonLoc>(); +} + +// Try to get hold of the origin regin (e.g. the actual array region from an +// element region). +static const TypedValueRegion *getOriginRegion(const ElementRegion *ER) { + const MemRegion *MR = ER->getSuperRegion(); + const MemRegion *Ret = MR; + assert(MR); + if (const auto *sym = MR->getAs<SymbolicRegion>()) { + SymbolRef sym2 = sym->getSymbol(); + if (!sym2) + return nullptr; + Ret = sym2->getOriginRegion(); + } + if (const auto *element = MR->getAs<ElementRegion>()) { + Ret = element->getBaseRegion(); + } + return dyn_cast_or_null<TypedValueRegion>(Ret); +} + +// Basically 1 -> 1st, 12 -> 12th, etc. +static void printIdxWithOrdinalSuffix(llvm::raw_ostream &Os, unsigned Idx) { + Os << Idx << llvm::getOrdinalSuffix(Idx); +} + +ProgramStateRef CStringChecker::checkInit(CheckerContext &C, + ProgramStateRef State, + AnyArgExpr Buffer, SVal Element, + SVal Size) const { + + // If a previous check has failed, propagate the failure. + if (!State) + return nullptr; + + const MemRegion *R = Element.getAsRegion(); + if (!R) + return State; + + const auto *ER = dyn_cast<ElementRegion>(R); + if (!ER) + return State; + + const TypedValueRegion *Orig = getOriginRegion(ER); + if (!Orig) + return State; + + SValBuilder &SValBuilder = State->getStateManager().getSValBuilder(); + ASTContext &Ctx = SValBuilder.getContext(); + + // FIXME: We ought to able to check objects as well. Maybe + // UninitializedObjectChecker could help? + if (!Orig->getValueType()->isArrayType()) + return State; ---------------- NagyDonat wrote:
Perhaps move this above the definition of `SValBuilder` and `Ctx` to keep it together with all the other early return statements. https://github.com/llvm/llvm-project/pull/95408 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits