@@ -5857,6 +5857,60 @@ static bool checkAssignedAndUsed(const BoundsAttributedAssignmentGroup &Group,
58575857 return IsGroupSafe;
58585858}
58595859
5860+ // Checks if each assignment to count-attributed pointer in the group is safe.
5861+ static bool
5862+ checkAssignmentPatterns (const BoundsAttributedAssignmentGroup &Group,
5863+ UnsafeBufferUsageHandler &Handler, ASTContext &Ctx) {
5864+ // Collect dependent values.
5865+ DependentValuesTy DependentValues;
5866+ for (size_t I = 0 , N = Group.AssignedObjects .size (); I < N; ++I) {
5867+ const ValueDecl *VD = Group.AssignedObjects [I].Decl ;
5868+ const auto *Attr = VD->getAttr <DependerDeclsAttr>();
5869+ if (!Attr)
5870+ continue ;
5871+
5872+ const BinaryOperator *Assign = Group.Assignments [I];
5873+ const Expr *Value = Assign->getRHS ();
5874+
5875+ [[maybe_unused]] bool Inserted =
5876+ DependentValues.insert ({{VD, Attr->getIsDeref ()}, Value}).second ;
5877+ // Previous checks in `checkBoundsAttributedGroup` should have validated
5878+ // that we have only a single assignment.
5879+ assert (Inserted);
5880+ }
5881+
5882+ bool IsGroupSafe = true ;
5883+
5884+ // Check every pointer in the group.
5885+ for (size_t I = 0 , N = Group.AssignedObjects .size (); I < N; ++I) {
5886+ const ValueDecl *VD = Group.AssignedObjects [I].Decl ;
5887+
5888+ QualType Ty = VD->getType ();
5889+ const auto *CAT = Ty->getAs <CountAttributedType>();
5890+ if (!CAT && Ty->isPointerType ())
5891+ CAT = Ty->getPointeeType ()->getAs <CountAttributedType>();
5892+ if (!CAT)
5893+ continue ;
5894+
5895+ const BinaryOperator *Assign = Group.Assignments [I];
5896+
5897+ // TODO: Move this logic to isCountAttributedPointerArgumentSafeImpl.
5898+ const Expr *CountArg =
5899+ DependentValues.size () == 1 ? DependentValues.begin ()->second : nullptr ;
5900+
5901+ bool IsSafe = isCountAttributedPointerArgumentSafeImpl (
5902+ Ctx, Assign->getRHS (), CountArg, CAT, CAT->getCountExpr (),
5903+ CAT->isCountInBytes (), CAT->isOrNull (), &DependentValues);
5904+ if (!IsSafe) {
5905+ Handler.handleUnsafeCountAttributedPointerAssignment (
5906+ Assign, /* IsRelatedToDecl=*/ false , Ctx);
5907+ IsGroupSafe = false ;
5908+ }
5909+ }
5910+
5911+ return IsGroupSafe;
5912+ }
5913+
58605914// Checks if the bounds-attributed group is safe. This function returns false
58615915// iff the assignment group is unsafe and diagnostics have been emitted.
58625916static bool
@@ -5868,8 +5922,7 @@ checkBoundsAttributedGroup(const BoundsAttributedAssignmentGroup &Group,
58685922 return false ;
58695923 if (!checkAssignedAndUsed (Group, Handler, Ctx))
58705924 return false ;
5871- // TODO: Add more checks.
5872- return true ;
5925+ return checkAssignmentPatterns (Group, Handler, Ctx);
58735926}
58745927
58755928static void
0 commit comments