When a numeric item is COMP-5 or COMP-X and a statement has only a NOT ON SIZE ERROR phrase, cobc does not treat an overflow as a size error. The NOT ON SIZE ERROR phrase runs, and the item is left holding the truncated bytes. For DISPLAY and BINARY items the same statement detects the overflow, keeps the old value and skips the phrase. The same COMP-5 overflow is detected when the statement also has an ON SIZE ERROR phrase, so the result depends on which phrases are written.
keept.cob (attached) adds 200 to a COMP-5 item and to a DISPLAY item, both PIC 99 holding 99, with only NOT ON SIZE ERROR:
IDENTIFICATION DIVISION.
PROGRAM-ID. KEEPT.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 X5 PIC 99 COMP-5 VALUE 99.
01 XD PIC 99 VALUE 99.
PROCEDURE DIVISION.
ADD 200 TO X5 NOT ON SIZE ERROR DISPLAY "NOT X5" END-ADD
ADD 200 TO XD NOT ON SIZE ERROR DISPLAY "NOT XD" END-ADD
DISPLAY "X5=" X5
DISPLAY "XD=" XD
STOP RUN.
cobc -x keept.cob && ./keept
COMP-5 and COMP-X are not available under -std=cobol2014, so both programs use the default dialect.
Output of keept (run exit 0):
NOT X5
X5=043
XD=99
The result 299 does not fit X5 (PIC 99, one byte), and 043 is the byte residue, but the NOT ON SIZE ERROR phrase runs. The DISPLAY item XD in the same kind of statement keeps 99 and its NOT phrase does not run. The output is the same when compiled with -debug or with -fec=EC-SIZE. GnuCOBOL 3.2.0 and 3.3-dev r5751 give byte-identical output.
keepb.cob (attached) uses COMP-5 with both phrases, and COMP-X and BINARY with NOT ON SIZE ERROR only:
IDENTIFICATION DIVISION.
PROGRAM-ID. KEEPB.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 X5 PIC 99 COMP-5 VALUE 99.
01 XX PIC 99 COMP-X VALUE 99.
01 XB PIC 99 BINARY VALUE 99.
PROCEDURE DIVISION.
ADD 200 TO X5 ON SIZE ERROR DISPLAY "SE X5"
NOT ON SIZE ERROR DISPLAY "NOT X5" END-ADD
ADD 200 TO XX NOT ON SIZE ERROR DISPLAY "NOT XX" END-ADD
ADD 200 TO XB NOT ON SIZE ERROR DISPLAY "NOT XB" END-ADD
DISPLAY "X5=" X5 " XX=" XX " XB=" XB
STOP RUN.
Output of cobc -x keepb.cob && ./keepb (run exit 0, byte-identical on 3.2.0 and 3.3-dev r5751):
SE X5
NOT XX
X5=099 XX=43 XB=99
With an ON SIZE ERROR phrase, the COMP-5 overflow is detected: the SIZE ERROR phrase runs and X5 keeps 99. COMP-X behaves like COMP-5, and BINARY behaves like DISPLAY.
NOT X5 and NOT XX should not be displayed. Whether the size error condition exists does not depend on the phrases. Only the handling does. ISO/IEC 1989:2023 §14.7.5 says (the 2014 and 2002 editions have the same text):
The value left in the receiver is the implementor's choice here (§14.6.13.1.3 rule 8: "If checking for the exception condition is not enabled, the implementor defines whether or not execution will continue, how it will continue, and how any receiving operands are affected."), so 043 by itself is not the problem. But cobc keeps the receiver for DISPLAY and BINARY in the same statement, and keeping it for COMP-5 and COMP-X too makes the usages consistent.
The attached size-error-receiver-kept.patch (against 3.3-dev r5751, applies with patch -p1 at the top of the tree) changes build_store_option in cobc/typeck.c. That function has a special case for CB_USAGE_COMP_5, CB_USAGE_COMP_X and CB_USAGE_COMP_N: it sets COB_STORE_KEEP_ON_OVERFLOW only when an ON SIZE ERROR handler exists. The patch removes the special case, so these usages take the same handler_type != NO_HANDLER test as every other usage. With only NOT ON SIZE ERROR, the store then detects the overflow, keeps the receiver and skips the NOT phrase, as it already does for DISPLAY and BINARY. Statements with neither phrase are unchanged: no flag is set, and the optimized cb_build_optim_add and cb_build_optim_sub paths are still taken for them.
With the patch, cobc -x keept.cob && ./keept gives this (run exit 0; the same with -debug and with -fec=EC-SIZE):
X5=099
XD=99
cobc -x keepb.cob && ./keepb (run exit 0):
SE X5
X5=099 XX=99 XB=99
make check on 3.3-dev r5751 with the patch: 1373 behaved as expected, 9 skipped, 0 failed, as unpatched (1372) plus the new test 608, which passes; unpatched it prints SIZE ERROR not set for COMP-5: 043. The patch adds the test "NOT ON SIZE ERROR with COMP-5 / COMP-X" to tests/testsuite.src/run_fundamental.at (after "Numeric operations (5) COMP-5") and a cobc/ChangeLog entry.
GnuCOBOL 3.2.0 (Ubuntu gnucobol3 3.2-4build1) and 3.3-dev r5751 (CI snapshot 3.3-dev.138 of 2026-10-29), x86_64 Linux, both re-run 2026-10-30. Both programs are fixed format. Every compile exits 0 with no cobc diagnostic. On 3.2.0 the Ubuntu C compiler step also prints <command-line>: warning: ‘_FORTIFY_SOURCE’ redefined and its note; that is the distribution's build setting.