@@ -6020,6 +6020,60 @@ static bool checkAssignedAndUsed(const BoundsAttributedAssignmentGroup &Group,
60206020 return IsGroupSafe;
60216021}
60226022
6023+ // Checks if each assignment to count-attributed pointer in the group is safe.
6024+ static bool
6025+ checkAssignmentPatterns (const BoundsAttributedAssignmentGroup &Group,
6026+ UnsafeBufferUsageHandler &Handler, ASTContext &Ctx) {
6027+ // Collect dependent values.
6028+ DependentValuesTy DependentValues;
6029+ for (size_t I = 0 , N = Group.AssignedObjects .size (); I < N; ++I) {
6030+ const ValueDecl *VD = Group.AssignedObjects [I].Decl ;
6031+ const auto *Attr = VD->getAttr <DependerDeclsAttr>();
6032+ if (!Attr)
6033+ continue ;
6034+
6035+ const BinaryOperator *Assign = Group.Assignments [I];
6036+ const Expr *Value = Assign->getRHS ();
6037+
6038+ [[maybe_unused]] bool Inserted =
6039+ DependentValues.insert ({{VD, Attr->getIsDeref ()}, Value}).second ;
6040+ // Previous checks in `checkBoundsAttributedGroup` should have validated
6041+ // that we have only a single assignment.
6042+ assert (Inserted);
6043+ }
6044+
6045+ bool IsGroupSafe = true ;
6046+
6047+ // Check every pointer in the group.
6048+ for (size_t I = 0 , N = Group.AssignedObjects .size (); I < N; ++I) {
6049+ const ValueDecl *VD = Group.AssignedObjects [I].Decl ;
6050+
6051+ QualType Ty = VD->getType ();
6052+ const auto *CAT = Ty->getAs <CountAttributedType>();
6053+ if (!CAT && Ty->isPointerType ())
6054+ CAT = Ty->getPointeeType ()->getAs <CountAttributedType>();
6055+ if (!CAT)
6056+ continue ;
6057+
6058+ const BinaryOperator *Assign = Group.Assignments [I];
6059+
6060+ // TODO: Move this logic to isCountAttributedPointerArgumentSafeImpl.
6061+ const Expr *CountArg =
6062+ DependentValues.size () == 1 ? DependentValues.begin ()->second : nullptr ;
6063+
6064+ bool IsSafe = isCountAttributedPointerArgumentSafeImpl (
6065+ Ctx, Assign->getRHS (), CountArg, CAT, CAT->getCountExpr (),
6066+ CAT->isCountInBytes (), CAT->isOrNull (), &DependentValues);
6067+ if (!IsSafe) {
6068+ Handler.handleUnsafeCountAttributedPointerAssignment (
6069+ Assign, /* IsRelatedToDecl=*/ false , Ctx);
6070+ IsGroupSafe = false ;
6071+ }
6072+ }
6073+
6074+ return IsGroupSafe;
6075+ }
6076+
60236077// Checks if the bounds-attributed group is safe. This function returns false
60246078// iff the assignment group is unsafe and diagnostics have been emitted.
60256079static bool
@@ -6031,8 +6085,7 @@ checkBoundsAttributedGroup(const BoundsAttributedAssignmentGroup &Group,
60316085 return false ;
60326086 if (!checkAssignedAndUsed (Group, Handler, Ctx))
60336087 return false ;
6034- // TODO: Add more checks.
6035- return true ;
6088+ return checkAssignmentPatterns (Group, Handler, Ctx);
60366089}
60376090
60386091static void
0 commit comments