Menu ▾ ▴

#1290 SEARCH VARYING sets the VARYING item to the search index's value instead of incrementing it

unclassified
open
nobody
None
5 - default
2026-11-04
2026-11-04
No

When a serial SEARCH has a VARYING phrase that names an integer data item, an index data item, or an index-name of another table, cobc does not increment that item.

To reproduce

srchvary.cob (attached) starts the search index X at 2 and the VARYING item N at 10. The WHEN is true at occurrence 4:

       IDENTIFICATION DIVISION.
       PROGRAM-ID. SRCHVARY.
       DATA DIVISION.
       WORKING-STORAGE SECTION.
       01  T  VALUE "ABCDE".
           05  E  PIC X OCCURS 5 TIMES INDEXED BY X.
       01  N  PIC 99.
       PROCEDURE DIVISION.
           SET X TO 2
           MOVE 10 TO N
           SEARCH E VARYING N
               AT END DISPLAY "NOT FOUND"
               WHEN E (X) = "D"
                   DISPLAY "FOUND D, N = " N
           END-SEARCH
           STOP RUN.
cobc -std=cobol2014 -x srchvary.cob && ./srchvary

What happens

3.2.0 and 3.3-dev r5751 both print

FOUND D, N = 04

srchend.cob and srchidx.cob, attached, show the same at AT END (FOUND N=03, AT END N=04) and for an index-name of another table and a USAGE INDEX item (04 for each).

What should happen

N goes up by one each time X does, 10, 11, 12, so the program should print FOUND D, N = 12. ISO/IEC 1989:2023 14.9.37.4 general rule 3 b) 2.: "If identifier-2 references an integer data item, that data item is incremented by the value one at the same time as the search index is incremented." Rules 3 b) 1. and 3 c) 2. give an index data item and an index-name the same step; the same in 2002 and in the 2014 FCD.

Why it happens

In cobc/codegen.c, output_search_whens increments the search index and then generates a MOVE of it to the VARYING item (output_move (idx, var)), so the item's own starting value is lost, with no message.

Proposed fix

The attached n10-search-varying.patch (against 3.3-dev r5751) replaces that MOVE with output_stmt (cb_build_add (var, cb_int1, cb_high)), the call cb_build_perform_varying uses for the PERFORM VARYING step. A SEARCH without VARYING, or VARYING one of the table's own indexes, generates the same code as before. With the patch srchvary prints FOUND D, N = 12, srchend FOUND N=12 and AT END N=15, and srchidx 07 for each.

The patch also enforces syntax rule 5 (14.9.37.3), which cobc did not check: cb_emit_search in cobc/typeck.c now calls cb_check_integer_value on the VARYING item, so a non-integer item, floating-point included, is now refused at the SEARCH; srchbad.cob, attached, varies a PIC XX item and printed FOUND [00], and now stops with 'V' is not an integer. A boolean PIC 1 item still passes, because cobc compiles PIC 1 as numeric (bugs #1269).

It adds the testsuite cases "SEARCH VARYING checks" to syn_misc.at and "SEARCH VARYING data item / other index" to run_misc.at, with ChangeLog entries. make check: 1374 expected, 9 skipped, 0 failed (1372 unpatched); the new tests fail without the patch. The NIST suite gives the same results with and without it.

  • bugs #1269: cobc compiles PIC 1 items as numeric.
  • bugs #313: runtime subscript checks inside the WHEN of SEARCH and SEARCH ALL; the same code generation, a different problem.

Details

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 run 2026-11-04.

5 Attachments

Discussion


Log in to post a comment.