As far as I know the gap lock is used to prevent phantom read, and I found gap lock is set by locking read in most articles via Google search.
A gap lock is a lock on a gap between index records, or a lock on the gap before the first or after the last index record. For example, SELECT c1 FROM t WHERE c1 BETWEEN 10 and 20 FOR UPDATE; prevents other transactions from inserting a value of 15 into column t.c1, whether or not there was already any such value in the column, because the gaps between all existing values in the range are locked.
https://dev.mysql.com/doc/refman/8.0/en/innodb-locking.html#innodb-gap-locks
I guess this (set gap lock on locking read) is sufficient. Why update, delete also set gap lock.
UPDATE ... WHERE ... sets an exclusive next-key lock on every record the search encounters. However, only an index record lock is required for statements that lock rows using a unique index to search for a unique row.
https://dev.mysql.com/doc/refman/8.0/en/innodb-locks-set.html
And another issue is what happened if there is no suitable index where gap lock can be attached? Does fall back to lock on the entire table?
Here we assumed that using the default transaction isolation level Repeatable Read.