================
@@ -447,16 +448,105 @@ static void printIdxWithOrdinalSuffix(llvm::raw_ostream 
&Os, unsigned Idx) {
   Os << Idx << llvm::getOrdinalSuffix(Idx);
 }
 
+static const FieldRegion *findUninitializedField(ProgramStateRef State,
+                                                 const TypedValueRegion *R) {
+  QualType Ty = R->getValueType();
+  SValBuilder &SVB = State->getStateManager().getSValBuilder();
+  ASTContext &Ctx = SVB.getContext();
+  MemRegionManager &MRMgr = SVB.getRegionManager();
+
+  if (R->getValueType()->isUnionType())
+    return nullptr;
+
+  if (Ty->isArrayType()) {
+    const auto *First = R;
+    const auto *Last = R;
+
+    while (const auto *AT = Ctx.getAsConstantArrayType(Ty)) {
+      if (AT->getSize().isZero())
+        return nullptr;
+
+      Ty = AT->getElementType();
+      First = MRMgr.getElementRegion(Ty, SVB.makeZeroArrayIndex(), First, Ctx);
+      Last = MRMgr.getElementRegion(
+          Ty, SVB.makeArrayIndex(AT->getSize().getZExtValue() - 1), Last, Ctx);
+    }
+
+    if (!Ty->isStructureType())
+      return nullptr;
+
+    if (const auto *FR = findUninitializedField(State, First))
+      return FR;
+
+    return First == Last ? nullptr : findUninitializedField(State, Last);
+  }
+
+  const auto *RT = Ty->getAsStructureType();
+  if (!RT)
+    return nullptr;
+  const auto *RD = RT->getDecl()->getDefinition();
+  if (!RD)
+    return nullptr;
+
+  for (const auto *FD : RD->fields()) {
+    if (!FD->getIdentifier())
+      continue;
+
+    const auto *FR = MRMgr.getFieldRegion(FD, R);
+    if (FD->getType()->isStructureType()) {
+      if (const auto *Uninit = findUninitializedField(State, FR))
+        return Uninit;
+    } else if (!FD->getType()->isAggregateType() &&
+               State->getSVal(FR).isUndef())
+      return FR;
+  }
+  return nullptr;
+}
+
 ProgramStateRef CStringChecker::checkInit(CheckerContext &C,
                                           ProgramStateRef State,
                                           AnyArgExpr Buffer, SVal Element,
-                                          SVal Size) const {
+                                          SVal Size, CharKind CK) const {
 
   // If a previous check has failed, propagate the failure.
   if (!State)
     return nullptr;
 
   SVal BufVal = C.getSVal(Buffer.Expression);
+  SValBuilder &SVB = C.getSValBuilder();
+  ASTContext &Ctx = SVB.getContext();
+
+  // Field initialization is meaningful only when the entire source object is
+  // read. Do not widen partial copies or nonzero offsets to their base object
+  if (UninitializedRead.isEnabled()) {
+    const auto *BufR = BufVal.getAsRegion();
+    const auto *Object = llvm::dyn_cast_or_null<TypedValueRegion>(
+        BufR ? BufR->StripCasts(false) : nullptr);
+
+    if (Object && !isa<ElementRegion>(Object)) {
+      QualType Ty = Object->getValueType();
+      const llvm::APSInt *Length = SVB.getKnownValue(State, Size);
+      CharUnits CharSize = Ctx.getTypeSizeInChars(
+          CK == CharKind::Regular ? Ctx.CharTy : Ctx.WideCharTy);
+
+      if (Ctx.getBaseElementType(Ty)->isStructureType() &&
+          !Ty->isIncompleteType() && !Ty->isVariablyModifiedType() && Length &&
+          Ctx.getTypeSizeInChars(Ty).isMultipleOf(CharSize) &&
+          *Length == Ctx.getTypeSizeInChars(Ty) / CharSize) {
----------------
bozicrHT wrote:

You're right, I added that.

https://github.com/llvm/llvm-project/pull/232824
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to