Menu ▾ ▴

#1269 Boolean items (PIC 1) refused: IF flag / EVALUATE flag WHEN TRUE, B-AND operands, ALIGNED order

GC 3.x
open
nobody
None
5 - default
2026-10-30
2026-10-30
No

cobc refuses three kinds of legal COBOL 2002 and 2014 source that use boolean items (PIC 1, USAGE BIT). It rejects a one-position boolean item used as a condition, rejects a boolean COMPUTE with B-AND, B-OR or B-XOR, and rejects the ALIGNED clause unless it comes directly after USAGE BIT. A program that uses any of these cannot be compiled, and the user has to rewrite it. The attached patch fixes the third case; the first two need boolean support that cobc does not have yet.

Cases

  1. A boolean item of length 1 is refused as a condition (evb.cob, evb2.cob).
  2. A boolean COMPUTE over PIC 1 items is refused (bcmp.cob).
  3. The ALIGNED clause is accepted only directly after USAGE BIT (algn.cob, algn-x.cob).

1. A boolean item of length 1 is refused as a condition

To reproduce

evb.cob:

IDENTIFICATION DIVISION.
PROGRAM-ID. EVB.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 FLAG PIC 1 VALUE B"1".
PROCEDURE DIVISION.
EVALUATE FLAG
WHEN TRUE DISPLAY "T"
WHEN FALSE DISPLAY "F"
END-EVALUATE
STOP RUN.
cobc -std=cobol2014 -fformat=free -fno-diagnostics-show-caret -x evb.cob

What happens

3.2.0 exits 1:

evb.cob:7: error: incomplete expression
evb.cob:7: error: invalid expression: boolean expected with logical operator

3.3-dev r5751 gives the same output, byte for byte, exit 1.

evb2.cob uses the same item as the condition of an IF and as a WHEN object of EVALUATE TRUE:

IDENTIFICATION DIVISION.
PROGRAM-ID. EVB2.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 FLAG PIC 1 VALUE B"1".
PROCEDURE DIVISION.
IF FLAG DISPLAY "T" ELSE DISPLAY "F" END-IF
EVALUATE TRUE
WHEN FLAG DISPLAY "T2"
WHEN OTHER DISPLAY "F2"
END-EVALUATE
STOP RUN.

With cobc -std=cobol2014 -fformat=free -fno-diagnostics-show-caret -x evb2.cob, 3.2.0 exits 1:

evb2.cob:7: error: incomplete expression
evb2.cob:9: error: incomplete expression

3.3-dev r5751 gives the same output, exit 1.

The relation forms compile and run on both versions. With the procedure division IF FLAG = B"1" DISPLAY "T" ELSE DISPLAY "F" END-IF and EVALUATE FLAG WHEN B"1" DISPLAY "T1" WHEN OTHER DISPLAY "F1" END-EVALUATE, the program prints T and T1, exit 0.

What should happen

evb.cob compiles and prints T. evb2.cob prints T and T2. FLAG is a boolean item of one boolean position, so it is a boolean condition. ISO/IEC 1989:2023 says:

  • §8.8.4.3.2, general format of the simple boolean condition: [ NOT ] boolean-expression-1. §8.8.2 says a boolean expression may be "an identifier referencing a boolean data item".
  • §8.8.4.3.3 syntax rule 1: "Boolean-expression-1 shall reference only boolean items of length 1."
  • §8.8.4.3.4 general rule 1: "Boolean-expression-1 evaluates true if the result of the expression is 1 and evaluates false if the result of the expression is 0."
  • For EVALUATE FLAG WHEN TRUE, §14.9.13.3 syntax rule 6 b): "If the selection object is TRUE or FALSE and the selection subject is a boolean expression that results in one boolean character, the selection subject is treated as a boolean condition and therefore condition-1." §14.9.13.4 general rule 4 a) 4.: "If the selection object is either TRUE or FALSE, the selection subject is condition-1. If the truth value of the selection subject and selection object match, the result of the analysis is true."

Boolean items, the boolean condition, the boolean COMPUTE and the ALIGNED clause came in with ISO/IEC 1989:2002. The 2014 edition has the same rules.

2. A boolean COMPUTE over PIC 1 items is refused

To reproduce

bcmp.cob:

IDENTIFICATION DIVISION.
PROGRAM-ID. BCMP.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 A PIC 1(4) VALUE B"1100".
01 B PIC 1(4) VALUE B"1010".
01 R PIC 1(4).
PROCEDURE DIVISION.
COMPUTE R = A B-AND B
DISPLAY R
STOP RUN.
cobc -std=cobol2014 -fformat=free -fno-diagnostics-show-caret -x bcmp.cob

What happens

3.2.0 exits 1:

bcmp.cob:9: error: A should be COMP-X/COMP-5 for logical operator

3.3-dev r5751 gives the same output, exit 1.

With B-OR or B-XOR in place of B-AND the error is the same on both versions. The PICTURE 1 entries and the boolean literals draw no diagnostic.

What should happen

bcmp.cob compiles and displays 1000, because 1100 B-AND 1010 is 1000.

  • §14.9.8.2 format 2 is the boolean COMPUTE, COMPUTE { identifier-2 } ... = boolean-expression-1. §14.9.8.3 syntax rule 2: "Identifier-2 shall reference an elementary boolean data item."
  • §8.7.2 lists B-AND as "AND operation (boolean conjunction)". B-OR and B-XOR are listed the same way.
  • §8.8.2 rule 9: "Binary boolean operations shall be performed without regard for the usage of the operands."
  • §14.9.8.4 general rule 3: "The number of boolean positions in the value resulting from the evaluation of boolean-expression-1 is the number of boolean positions in the largest boolean item referenced in the expression."

No rule requires COMP-X or COMP-5 for the operands of a boolean operator.

3. The ALIGNED clause is accepted only directly after USAGE BIT

To reproduce

algn.cob:

IDENTIFICATION DIVISION.
PROGRAM-ID. ALGN.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 G.
   05 G1 USAGE BIT PIC 1(4).
   05 G2 USAGE BIT PIC 1(4) ALIGNED.
PROCEDURE DIVISION.
DISPLAY FUNCTION BYTE-LENGTH(G)
STOP RUN.
cobc -std=cobol2014 -fformat=free -fno-diagnostics-show-caret -x algn.cob

What happens

3.2.0 exits 1:

algn.cob:6: warning: USAGE BIT is not implemented [-Wpending]
algn.cob:7: warning: USAGE BIT is not implemented [-Wpending]
algn.cob:7: error: syntax error, unexpected ALIGNED

3.3-dev r5751 gives the same output, exit 1.

With line 7 written 05 G2 ALIGNED USAGE BIT PIC 1(4). (saved as algn-x.cob), both versions print, exit 1:

algn-x.cob:6: warning: USAGE BIT is not implemented [-Wpending]
algn-x.cob:7: error: syntax error, unexpected ALIGNED

With line 7 written 05 G2 PIC 1(4) USAGE BIT ALIGNED., both versions compile with the two -Wpending warnings, and the program prints 2, exit 0.

The -Wpending warning for USAGE BIT itself is understood. This report is about the syntax error, which PIC 1(4) USAGE BIT ALIGNED avoids.

What should happen

algn.cob compiles and prints 2.

  • §13.16.2: [ ALIGNED ] is its own clause in the format of a data description entry, separate from the USAGE clause. §13.16.3 syntax rule 4: "The remaining clauses may be written in any order."
  • §13.18.1.3 syntax rule 1: "The ALIGNED clause may be specified only for a bit group item or an elementary bit data item." §13.18.60.4 general rule 5: "A data item described with USAGE BIT is a bit data item."
  • §13.18.1.4 general rule 1: "An ALIGNED clause causes the subject of the entry to be aligned on the first bit of the first available byte boundary." G1 takes bits 1-4 of byte 1, and G2 starts at byte 2. §8.5.1.6.3 adds trailing filler "as needed to increase the number of bits to fill an integral number of characters". So BYTE-LENGTH(G) is 2 (§15.14.4: "the length of argument-1 in number of bytes").

Why it happens

In cobc/parser.y the ALIGNED token was accepted only in the usage rule's BIT ALIGNED alternative. A comment there says "ALIGNED actually is a separate clause but at least for now we simplify it".

Proposed fix

boolean-items-bugs.patch, against 3.3-dev r5751, fixes this case only.

  • It adds an aligned_clause alternative to data_description_clause, with the duplicate-clause check the other clauses have, and removes the BIT ALIGNED alternative. ALIGNED may now stand anywhere in the entry.
  • The grammar no longer ties ALIGNED to USAGE BIT, so the data_description rule now reports "ALIGNED clause requires USAGE BIT" at the end of an entry that has ALIGNED but not USAGE BIT (§13.18.1.3 rule 1). cobc has no GROUP-USAGE BIT, so an item with USAGE BIT, written or inherited from its group, is the only bit item it can describe.
  • ALIGNED still has no other effect, as before. USAGE BIT is not implemented, and each USAGE BIT item takes a whole byte, so BYTE-LENGTH(G) is 2 with or without ALIGNED.

With the patch, cobc -std=cobol2014 -fformat=free -fno-diagnostics-show-caret -x algn.cob && ./algn gives compile exit 0 and run exit 0:

algn.cob:6: warning: USAGE BIT is not implemented [-Wpending]
algn.cob:7: warning: USAGE BIT is not implemented [-Wpending]
2

algn-x.cob (ALIGNED before USAGE BIT), the same command, compile exit 0, run exit 0:

algn-x.cob:6: warning: USAGE BIT is not implemented [-Wpending]
algn-x.cob:7: warning: USAGE BIT is not implemented [-Wpending]
2

make check on 3.3-dev r5751 with the patch passes: 1373 behaved as expected, 9 skipped, 0 failed (unpatched: 1372, 9 skipped, 0 failed). The patch adds the test "ALIGNED clause" to tests/testsuite.src/syn_definition.at (after "SYNCHRONIZED clause"), which covers ALIGNED in four positions, ALIGNED on a PIC X item, and a repeated ALIGNED; the unpatched compiler gives "syntax error, unexpected ALIGNED" on it. The new test 115 passes, the VALIDATE example in syn_misc.at (which writes PIC 1(8) USAGE BIT ALIGNED) still passes, and the patch adds entries to cobc/ChangeLog and tests/ChangeLog.

Where the fix for cases 1 and 2 belongs

This comes from reading the 3.3-dev source; no debugger was used. We did not attempt a patch, because both cases need boolean support that cobc does not have yet.

A PIC 1 item is compiled as a numeric item. cb_build_picture in cobc/tree.c handles the symbol 1 with category |= PIC_NUMERIC; /* FIXME: this is WRONG */, and scan_b in cobc/scanner.l builds B"..." as a numeric literal holding the binary value ("FIXME: we should really build a boolean literal..."). One visible effect: 01 A PIC 1(4) VALUE B"1100". followed by DISPLAY A prints 0012 on 3.3-dev r5751.

  • Case 1: with FLAG numeric, cb_build_cond in cobc/typeck.c has no case for it. Its CB_TAG_REFERENCE arm makes a condition only of a level-88 item or a non-field, so a numeric field falls through to "incomplete expression". A boolean-condition arm (the item compared with 1) belongs there and in evaluate_test for a TRUE or FALSE object, but it needs a boolean category to test for. CB_CATEGORY_BOOLEAN maps to CB_CLASS_BOOLEAN, the class cobc also gives to conditions. Once PIC 1 items get that category, they would pass the logical-operator checks in cb_build_binary_op as if they were conditions, so the two need to be kept apart.
  • Case 2: cb_build_binary_op in cobc/tree.c, in the arm for the bit-wise operators ('a', 'o', 'e'), sends every operand through the integer path and refuses a field that is not COMP-5 or COMP-X. A boolean operand needs its own evaluation path, position by position, which in turn needs the boolean category and a boolean literal.
  • feature-requests #303: boolean class and category for USAGE BIT / PIC 1 items and boolean literals. It does not report these three refusals.
  • feature-requests #172: the boolean picture. It does not report these three refusals either.
  • feature-requests #235: added the numeric bit-wise operators that carry the COMP-X/COMP-5 check.

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 re-run 2026-10-30. Every command above was also run without -std=cobol2014 (default dialect), with the same output and exit code. -fno-diagnostics-show-caret only removes the source-context lines. All programs are free format.

Attached: evb.cob and evb2.cob, bcmp.cob, algn.cob, and boolean-items-bugs.patch (the fix for case 3, against 3.3-dev r5751). The quoted ISO text is from ISO/IEC 1989:2023.

5 Attachments

Discussion


Log in to post a comment.