@@ -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