Menu ▾ ▴

#530 Accept an arithmetic expression in SET index TO, SET index or pointer UP / DOWN BY (COBOL 2002/2014)

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

cobc refuses an arithmetic expression in SET index-name TO, SET index-name UP BY / DOWN BY and SET data-pointer UP / DOWN BY. A single operand works; any operator is a syntax error. This is a request to accept it; the attached patch implements it.

To reproduce

setexpr.cob (attached):

       IDENTIFICATION DIVISION.
       PROGRAM-ID. SETEXPR.
       DATA DIVISION.
       WORKING-STORAGE SECTION.
       01  N  PIC 9 VALUE 2.
       01  T  VALUE "ABCDEFGHI".
           05  E  PIC X OCCURS 9 TIMES INDEXED BY X Y.
       01  P  USAGE POINTER.
       01  C  PIC X BASED.
       PROCEDURE DIVISION.
           SET X Y TO N + 3
           DISPLAY E (X) E (Y)
           SET X UP BY N * 2
           DISPLAY E (X)
           SET X DOWN BY N - 1
           DISPLAY E (X)
           SET P TO ADDRESS OF T
           SET P UP BY N * 3
           SET ADDRESS OF C TO P
           DISPLAY C
           STOP RUN.
cobc -std=cobol2014 -x setexpr.cob && ./setexpr

What happens

3.2.0 and 3.3-dev r5751 both stop with

setexpr.cob:11: error: syntax error, unexpected +
setexpr.cob:13: error: syntax error, unexpected *
setexpr.cob:15: error: syntax error, unexpected -
setexpr.cob:18: error: syntax error, unexpected *

each followed by its source excerpt. The result is the same with -std=cobol2002, default, ibm and mf. As a workaround, SET X TO FUNCTION INTEGER (N + 3) works on both.

What should happen

Under -std=cobol2002 and -std=cobol2014 the program should print EE, I and H (occurrences 5, 9 and 8), then G (6 bytes into T). ISO/IEC 1989:2023 14.9.39.2 gives Formats 1, 2 and 10 (data-pointer-arithmetic) an arithmetic-expression operand. By general rule 2 a) 1. c. of 14.9.39.4, "index-name-1 is set to a value causing it to refer to the table element that would correspond in occurrence number to that expression"; by general rule 20, the pointer moves by that many bytes. The formats are the same in 2002 (where Format 10 is Format 9) and in the 2014 FCD.

Why it happens

In cobc/parser.y, set_to (target_x_list TO x) and set_up_down (target_x_list up_or_down BY x) take an x, a single operand, not the exp that subscripts and COMPUTE use. The code behind them, cb_emit_set_to (cb_build_move) and cb_emit_set_up_down (cb_build_add / cb_build_sub), already handles an expression.

Proposed fix

The attached n10-set-index-expression.patch (against 3.3-dev r5751) gives both rules a new set_x: an exp, or one of the non-arithmetic forms of x. The grammar stays conflict-free; a single operand compiles to the same C. In typeck.c, the new cb_check_set_arith_expr accepts a non-constant expression only for an index-name, or a data-pointer after UP BY / DOWN BY (syntax rules 1 to 4 and 23), and marks it BOP_RESOLVE_AS_INTEGER, as cb_build_identifier does for a subscript. Two things to weigh: a non-integer result is truncated, as for a subscript or a single operand, instead of raising EC-BOUND-SUBSCRIPT or EC-SIZE-ADDRESS; and one UP BY may still mix index-names and pointers, as it may with a single operand.

Patched, setexpr prints that output. The patch adds the testsuite cases "SET index / pointer by arithmetic expression" to run_misc.at and "SET TO / UP BY arithmetic expression, invalid target" to syn_set.at, with ChangeLog entries. make check: 1374 expected, 9 skipped, 0 failed (1372 unpatched); the new tests fail without the patch. The NIST suite results are unchanged.

bugs #866: SET of an index raises none of the exception conditions of Formats 1 and 2, the truncation above included.
bugs #228: the SET target check accepts any numeric item; the patch leaves single operands as they are.

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.

2 Attachments

Discussion


Log in to post a comment.