ALTER changes the destination of a GO TO statement elsewhere in the program. It complicates the task of eliminating GO TO, especially if you don't notice that the ALTER is present.
If you find an ALTER, replace it with a flag, a case structure, and some ordinary GO TOs. Once the ALTER is gone, you can eliminate the GO TOs by the usual methods.
PERFORM 2100-PROCESS-RECORD THRU 2199-EXIT.
...
2100-PROCESS-RECORD.
GO TO 2110-PROCESS-HEADER.
*
2110-PROCESS-HEADER.
* code to process a file header
ALTER 2100-PROCESS-RECORD TO 2120-PROCESS-DETAIL.
GO TO 2199-EXIT.
*
2120-PROCESS-DETAIL.
* code to process a detail record
GO TO 2199-EXIT.
...
*
2199-EXIT.
EXIT.
The first time we execute the PERFORM, control passes through
2110-PROCESS-HEADER. However, the ALTER at the end of that paragraph
changes the destination of the GO TO in 2100-PROCESS-RECORD. As a
result, on all subsequent executions of the PERFORM, control
does not pass through 2110-PROCESS-HEADER. It passes through
2120-PROCESS-DETAIL instead.
The potential for confusion is obvious. The altered GO TO does not go where it claims to go -- instead, it goes to a place specified in some remote piece of code. To understand how the code works you need to know that the ALTER is present, and you need to know all the circumstances which execute the ALTER.
PERFORM 2100-PROCESS-RECORD THRU 2199-EXIT.
...
2100-PROCESS-RECORD.
GO TO.
*
2110-PROCESS-HEADER.
* code to process a file header
ALTER 2100-PROCESS-RECORD TO 2120-PROCESS-DETAIL.
GO TO 2199-EXIT.
*
2120-PROCESS-DETAIL.
* code to process a detail record
GO TO 2199-EXIT.
...
*
2199-EXIT.
EXIT.
The only difference is in 2100-PROCESS-HEADER. The GO TO has no
destination. The sheer weirdness of this syntax should be enough
to alert you that there is an ALTER involved.
If a GO TO statement has no destination, then it behaves like a CONTINUE statement until an ALTER statement assigns it a destination. In the example: on the first time around, control falls through into 2110-PROCESS-HEADER. On subsequent passes the GO TO will have been assigned a destination of 2120-PROCESS-DETAIL, exactly as in the first example.
If you ever encounter this form of pathology, proceed with extreme caution. You have found either a bizarre and subtle bug or a vicious marauding style of programming. Quite possibly both.
If you determine that this resetting is appropriate rather than accidental, look for a way to preserve the logic while making the resetting visible. Find each spot which causes the reload of the independent segment containing the altered GO TO, and insert an ALTER statement as needed.
This transformation may be tricky if the resetting occurs through code which sometimes causes a reload and sometimes doesn't. As a last resort, you can keep track of which independent segment is currently loaded, if any. Let every paragraph in every independent segment set a flag to indicate which segment is loaded. Then you can check the flag as needed to determine whether to reset a GO TO.
(Any logic this strange is probably just somebody's blunder. Hence it's unlikely that you'll ever need to go to such lengths, but you can do it if you have to.)
Once the new ALTERS have made the resetting explicit, you can eliminate them as described below.
...
WHEN AD-2120-A
GO TO 2120-PROCESS-DETAIL
...