@@ -5947,6 +5947,60 @@ static bool checkMissingAndDuplicatedAssignments(
59475947  return  IsGroupSafe;
59485948}
59495949
5950+ //  Checks if each assignment to count-attributed pointer in the group is safe.
5951+ static  bool 
5952+ checkAssignmentPatterns (const  BoundsAttributedAssignmentGroup &Group,
5953+                         UnsafeBufferUsageHandler &Handler, ASTContext &Ctx) {
5954+   //  Collect dependent values.
5955+   DependentValuesTy DependentValues;
5956+   for  (size_t  I = 0 , N = Group.AssignedObjects .size (); I < N; ++I) {
5957+     const  ValueDecl *VD = Group.AssignedObjects [I].Decl ;
5958+     const  auto  *Attr = VD->getAttr <DependerDeclsAttr>();
5959+     if  (!Attr)
5960+       continue ;
5961+ 
5962+     const  BinaryOperator *Assign = Group.Assignments [I];
5963+     const  Expr *Value = Assign->getRHS ();
5964+ 
5965+     [[maybe_unused]] bool  Inserted =
5966+         DependentValues.insert ({{VD, Attr->getIsDeref ()}, Value}).second ;
5967+     //  Previous checks in `checkBoundsAttributedGroup` should have validated
5968+     //  that we have only a single assignment.
5969+     assert (Inserted);
5970+   }
5971+ 
5972+   bool  IsGroupSafe = true ;
5973+ 
5974+   //  Check every pointer in the group.
5975+   for  (size_t  I = 0 , N = Group.AssignedObjects .size (); I < N; ++I) {
5976+     const  ValueDecl *VD = Group.AssignedObjects [I].Decl ;
5977+ 
5978+     QualType Ty = VD->getType ();
5979+     const  auto  *CAT = Ty->getAs <CountAttributedType>();
5980+     if  (!CAT && Ty->isPointerType ())
5981+       CAT = Ty->getPointeeType ()->getAs <CountAttributedType>();
5982+     if  (!CAT)
5983+       continue ;
5984+ 
5985+     const  BinaryOperator *Assign = Group.Assignments [I];
5986+ 
5987+     //  TODO: Move this logic to isCountAttributedPointerArgumentSafeImpl.
5988+     const  Expr *CountArg =
5989+         DependentValues.size () == 1  ? DependentValues.begin ()->second  : nullptr ;
5990+ 
5991+     bool  IsSafe = isCountAttributedPointerArgumentSafeImpl (
5992+         Ctx, Assign->getRHS (), CountArg, CAT, CAT->getCountExpr (),
5993+         CAT->isCountInBytes (), CAT->isOrNull (), &DependentValues);
5994+     if  (!IsSafe) {
5995+       Handler.handleUnsafeCountAttributedPointerAssignment (
5996+           Assign, /* IsRelatedToDecl=*/ false , Ctx);
5997+       IsGroupSafe = false ;
5998+     }
5999+   }
6000+ 
6001+   return  IsGroupSafe;
6002+ }
6003+ 
59506004//  Checks if the bounds-attributed group is safe. This function returns false
59516005//  iff the assignment group is unsafe and diagnostics have been emitted.
59526006static  bool 
@@ -5956,8 +6010,7 @@ checkBoundsAttributedGroup(const BoundsAttributedAssignmentGroup &Group,
59566010    return  false ;
59576011  if  (!checkMissingAndDuplicatedAssignments (Group, Handler, Ctx))
59586012    return  false ;
5959-   //  TODO: Add more checks.
5960-   return  true ;
6013+   return  checkAssignmentPatterns (Group, Handler, Ctx);
59616014}
59626015
59636016static  void 
0 commit comments