To quote the current standard (F2018 6.2.5):
Any statement that is not part of another statement, and that is not preceded by a semicolon in fixed form, may begin with a statement label
A DO statement like this is not part of another statement: yes it may be labelled.
That said, as you are using it as a go to target, you can consider that there are better ways than labelling the DO statement.
And also, you should try to avoid that 15 label as well. Not only is it redundant (the labelled statement is an end do) but the "labelled DO statement") is obsolescent and may be deleted from the standard. (The "nonblock DO construct", where the labelled statement is something other than end do, was deleted in Fortran 2018, so deletion isn't an empty threat.)
These points together give the program without any labels and with no go to:
implicit none
integer :: b, i
b=20
do
do i = 1, 5
b = b + i
end do
if (b .ne. 35) exit ! or /= instead of .ne.
end do
print *, b
end
(I've also used implicit none and used an assignment for b instead of initialization.)
In general, while you can put labels in many places, there are very, very few places where you should use the labels.
"Part of another statement" makes lines like the following line bad:
if (.true.) 10 print *, "Hello"
The PRINT statement here is an action statement which is part of the IF statement. While the IF statement as a whole may be labelled, the PRINT statement is part of that statement and so may not be labelled.