https://gcc.gnu.org/bugzilla/show_bug.cgi?id=126525
Bug ID: 126525
Summary: EXIT SECTION is a no-op when the section is entered by
fall-through rather than PERFORM
Product: gcc
Version: 17.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: cobol
Assignee: unassigned at gcc dot gnu.org
Reporter: peeterjoot at protonmail dot com
Target Milestone: ---
Created attachment 65185
--> https://gcc.gnu.org/bugzilla/attachment.cgi?id=65185&action=edit
exit-section-fallthrough.cob (also inline in the report remarks)
# Summary
`EXIT SECTION` is a no-op when the section was **not** entered by a `PERFORM`.
gcobol implements it as the PERFORM-return mechanism only, so in a section
reached
by ordinary fall-through the statement does nothing and execution continues
into
the section's remaining paragraphs.
The same program run under GnuCOBOL `cobc` skips the rest of the section, which
is
what the Language Reference requires.
# Environment
- Compiler: gcobol from GCC trunk (`gcobol (GCC) 17.0.0 20260717
(experimental)`)
- Contrast: GnuCOBOL 3.2-rc2 `cobc` — correct
- Platform: Linux aarch64 (expected elsewhere too)
- Options: `-ffixed-form` only
# Reproducer
`exit-section-fallthrough.cob` (in this directory):
```cobol
IDENTIFICATION DIVISION.
PROGRAM-ID. EXITSECT.
PROCEDURE DIVISION.
DRIVER-SECT SECTION.
D1.
PERFORM P-SECT.
DISPLAY "BACK".
FALL-SECT SECTION.
F1.
DISPLAY "F1".
EXIT SECTION.
F2.
DISPLAY "F2-SHOULD-NOT-RUN".
LAST-SECT SECTION.
L1.
DISPLAY "L1".
STOP RUN.
P-SECT SECTION.
P1.
DISPLAY "P1".
EXIT SECTION.
P2.
DISPLAY "P2-SHOULD-NOT-RUN".
```
The program exercises both entry paths to a section holding `EXIT SECTION`:
- `P-SECT` is entered by `PERFORM` — gcobol handles this one correctly
(`P2-SHOULD-NOT-RUN` does not print).
- `FALL-SECT` is entered by falling out of `DRIVER-SECT` — this is the failing
case.
```sh
gcobol -ffixed-form -o exit-section-fallthrough exit-section-fallthrough.cob \
-Wl,-rpath,/opt/gcc-trunk-20260717/lib64
./exit-section-fallthrough
```
# Observed (gcobol)
```
P1
BACK
F1
F2-SHOULD-NOT-RUN
L1
```
`F2-SHOULD-NOT-RUN` executes: the `EXIT SECTION` in `F1` had no effect.
That `P2-SHOULD-NOT-RUN` is absent is what localizes the bug — `EXIT SECTION`
works when it is unwinding a `PERFORM` and does nothing otherwise, so it
appears to
be implemented as the PERFORM-return path rather than as a transfer to the
section
end.
# Expected (and cobc behavior)
```
P1
BACK
F1
L1
```
```sh
cobc -std=cobol85 -x -o exit-section-fallthrough-cobc
exit-section-fallthrough.cob
./exit-section-fallthrough-cobc
```
# Language Reference
IBM Enterprise COBOL for z/OS 6.5 Language Reference (SC27-8713-04), *EXIT
statement*, Format 6 (`EXIT SECTION`):
> The EXIT SECTION statement controls the exit from a section without executing
> any following statements within the section.
and:
> When an EXIT SECTION statement is executed, control is passed to an unnamed
> empty paragraph that immediately follows the last paragraph of the current
> section. This return mechanism **supersedes any other return mechanisms** that
> are associated with language elements, such as PERFORM, SORT, and USE for that
> section.
Neither sentence conditions the transfer on the section having been entered by
a
`PERFORM`. "Supersedes any other return mechanisms" is the opposite reading:
the
transfer to the section end is the primary behaviour, and a `PERFORM` return is
one
of the things it overrides.
# Notes
- Found while validating a control-flow transformation that relocates a
paragraph
to the end of its section and fences the previous last paragraph with `EXIT
SECTION` — a rewrite that is sound under the rule quoted above, and that this
divergence silently breaks.
- Any `EXIT SECTION` in a section reached by fall-through is affected, so a
program
can be miscompiled without using `PERFORM` at all.
- Independent of `EXIT PARAGRAPH`, which is a separate format of the same
statement
and is not exercised here.