[go: up one dir, main page]

Menu

#1165 Incorrect generated C code when using OCCURS variables as both source and target in STRING operation

GC 3.x
open
nobody
5 - default
2025-12-28
2025-12-08
No

When using a variable from an OCCURS table both as a source and as a target within a STRING operation, GNUCobol generates incorrect C code.
The generated code reuses the same temporary cob_field structure (f0) for multiple fields. As a result, the pointer inside the reused temporary field gets overwritten, causing incorrect behavior at runtime.
This leads to wrong string contents because the temporary field does not represent the correct source and target fields independently.

Example Sourcecode:

MOVE "1234"               TO SYAWDR-SIGMA-TXT (1)
STRING KLAMMER-AUF        DELIMITED SIZE
       SYAWDR-SIGMA-TXT (1) DELIMITED SIZE
   INTO D312-SIGMA-KOPF (1)
END-STRING
DISPLAY 1 " -> " SYAWDR-SIGMA-TXT (1)

Generated (incorrect) C code excerpt:

/* Line: 29        : MOVE               : main.cob */
memcpy (b_17 + 2, "1234", 4);

/* Line: 30        : STRING             : main.cob */
cob_string_init (COB_SET_FLD (f0, 7, b_17 + 6, &a_5), NULL);
cob_string_delimited (NULL);
cob_string_append (&f_18);
cob_string_delimited (NULL);
cob_string_append (COB_SET_FLD (f0, 4, b_17 + 2, &a_5));
cob_string_finish ();

/* Line: 34        : DISPLAY            : main.cob */
cob_display (0, 1, 3, &c_4, &c_5, COB_SET_FLD (f0, 4, b_17 + 2, &a_5));

Here, the same temporary field f0 is used for both the source and the target inside the STRING operation, which causes the internal pointer to be overwritten.

Cause:

Inside codegen.c, function output_stmt(), the variable stack_id is reset to 0 at the beginning of each call.
This forces code generation to reuse the same temporary cob_field (f0) instead of allocating separate temporaries for each field reference.

Working fix (local patch):

Removing the line resetting stack_id inside output_stmt() fixes the issue:
/ in codegen.c, inside function output_stmt() /
// stack_id = 0; // Removing this line fixes incorrect temporary field reuse
With this change, each field occurrence gets its own temporary cob_field, and STRING operations involving OCCURS items work correctly.

Expected behavior

GNUCobol should generate separate temporary field structures for each referenced variable inside a STRING statement, even if the variables originate from the same OCCURS group.

Actual behavior

The generated C reuses the same temporary structure (f0), causing pointer aliasing and incorrect results.

Environment:

GNUCobol version: cobc (GnuCOBOL) 3.3-dev.0
Platform: Windows
Compiler: gcc version 15.1.0 (Rev6, Built by MSYS2 project)

Discussion

  • Arnold Trembley

    Arnold Trembley - 2025-12-08

    I don't understand this bug description.

    Could you please provide the complete data definitions with PICTURE clauses for SYAWDR-SIGMA-TXT, KLAMMER-AUF, and D312-SIGMA-KOPF, along with the initial contents or VALUE of KLAMMER-AUF?

    Then could you also please provide what results you actually received in D312-SIGMA-KOPF, versus what you expected to find in D312-SIGMA-KOPF?

    Kind regards,

     
  • Michael Plumbohm

    Hi Arnold,
    I’m sorry if my previous bug description wasn’t clear enough.
    The complete source code I used is:

           IDENTIFICATION DIVISION.
           PROGRAM-ID. "c_main".
           DATA DIVISION.
           WORKING-STORAGE SECTION.
           01  STRUKTUR.
               05 KLAMMER-AUF               PIC X     VALUE "(".
               05 KLAMMER-ZU                PIC X     VALUE ")".
               05 SYAWDR-SIGMA-TABELLE.
                  10 SYAWDR-SIGMA-TXT       OCCURS 1 PIC X(04).
               05 AUSGABE.
                  10 D312-SORT-TAB OCCURS 1.
                     15 D312-SIGMA-KOPF     PIC X(07).
           LINKAGE SECTION.
           PROCEDURE DIVISION.
           HAUPT.
               MOVE "1234" TO SYAWDR-SIGMA-TXT (1)
               STRING KLAMMER-AUF        DELIMITED SIZE
                      SYAWDR-SIGMA-TXT (1) DELIMITED SIZE
                 INTO D312-SIGMA-KOPF (1)
               END-STRING
               DISPLAY 1 " -> " SYAWDR-SIGMA-TXT (1)
               .
    

    I expect the output to be:

    (1234
    

    but instead I get:

    1123
    

    The reason becomes clear when looking at the generated C code:
    f0 is used as the temporary structure for the target field but is overwritten when processing the second source operand. This changes the field, pointed to (as string target) and leads to the incorrect result.

     
  • Arnold Trembley

    Arnold Trembley - 2025-12-08

    Thank you very much for the additional information.

    I think you may have a minor error in your sample program. The following statement:

    DISPLAY 1 " -> " SYAWDR-SIGMA-TXT (1)

    Should be replaced by one of these examples:

    DISPLAY 1 " -> " AUSGABE (or)
    DISPLAY 1 " -> " D312-SORT-TAB (or)
    DISPLAY 1 " -> " D312-SIGMA-KOPF (1)

    I do not have a very current version of GnuCOBOL 3.3 DEV. Mine comes from Chuck Haatvedt and has the following version:

      Microsoft Windows [Version 10.0.26200.7309]  2025-12-08  16:57:01
    C:\cobol>cobc --info
    cobc (GnuCOBOL) 3.3-dev.0
    Copyright (C) 2024 Free Software Foundation, Inc.
    License GPLv3+: GNU GPL version 3 or later <https://gnu.org/licenses/gpl.html>
    This is free software; see the source for copying conditions.  There is NO
    warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
    Written by Keisuke Nishida, Roger While, Ron Norman, Simon Sobisch, Edward Hart
    Built     Jun 19 2024 18:16:23
    Packaged  Jun 19 2024 23:16:03 UTC
    C version (MinGW) "14.1.0"
    

    I am unable to replicate your results. I have created a modified version of your sample program with two additional DISPLAY statements at the end (see attachments) and these are the results I get:

    Microsoft Windows [Version 10.0.26200.7309]  2025-12-08  16:58:35
    C:\cobol>
    Microsoft Windows [Version 10.0.26200.7309]  2025-12-08  17:06:20
    C:\cobol>bug1165v01
    1 -> 1234
    SYAWDR-SIGMA-TABELLE = 1234
    AUSGABE              = (1234
    

    I have also tested the modified program with a 32-bit MinGW version of GnuCOBOL 3.2, and I get the same results:

    Microsoft Windows [Version 10.0.26200.7309]  2025-12-08  17:08:40
    C:\cobol>cobc --info
    cobc (GnuCOBOL) 3.2.0
    Copyright (C) 2023 Free Software Foundation, Inc.
    License GPLv3+: GNU GPL version 3 or later <https://gnu.org/licenses/gpl.html>
    This is free software; see the source for copying conditions.  There is NO
    warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
    Written by Keisuke Nishida, Roger While, Ron Norman, Simon Sobisch, Edward Hart
    Built     Jul 28 2023 19:10:09
    Packaged  Jul 28 2023 17:02:56 UTC
    C version (MinGW) "9.2.0"
    
    
    cobc.exe -x -Wall -fnotrunc -Xref -t C:\Users\Arnold\AppData\Local\Temp\bug1165v01.lst -o C:\Users\Arnold\AppData\Local\Temp\bug1165v01.exe bug1165v01.cbl
    
    Microsoft Windows [Version 10.0.26200.7309]  2025-12-08  17:10:00
    C:\cobol>bug1165v01
    1 -> 1234
    SYAWDR-SIGMA-TABELLE = 1234
    AUSGABE              = (1234
    

    If there is a more up-to-date build of GnuCOBOL 3.3 DEV 0 that will make the source field SYAWDR-SIGMA-TXT (1) have the corrupted value "1123" I would definitely call that a bug.

    Kind regards,

     
    👍
    1

    Last edit: Arnold Trembley 2025-12-08
  • Michael Plumbohm

    Hi,

    I recently updated to GNUCobol 4.0, and the issue no longer persists.
    For me, the problem is resolved and this ticket can be closed.

    Thank you very much for your time and for maintaining and improving GNUCobol — it is greatly appreciated.

     
    👍
    1
    • Simon Sobisch

      Simon Sobisch - 2025-12-18

      We'd really like to fix it for GnuCOBOL 3.3 if it is reproducible there - is this possible for you?

       
      • Michael Del Solio

        I tested it on macOS 15.7.1 (ARM) with the latest 3.3 updates:

        svn info
        Pfad: .
        Wurzelpfad der Arbeitskopie: /Users/mds/cobol/gnucobol-3.x
        URL: svn://svn.code.sf.net/p/gnucobol/code/branches/gnucobol-3.x
        Letzter Autor: sf-mensch
        Letzte geänderte Rev: 5626
        Letztes Änderungsdatum: 2025-12-06 02:59:21 +0100 (Sa, 06. Dez 2025)
        
        cobc -v               
        cobc (GnuCOBOL) 3.3-dev.0
        Built     Dec 12 2025 23:14:12  Packaged  Dec 12 2025 22:14:04 UTC
        C version "Apple LLVM 17.0.0 (clang-1700.3.19.1)"
        
        cobc -x bug1165v01.cbl 
        ./bug1165v01 
        1 -> 1234
        SYAWDR-SIGMA-TABELLE = 1234
        AUSGABE              = (1234  
        
        cobc -x c_main.cob
        ./c_main 
        1 -> 1234
        
         
        • Arnold Trembley

          Arnold Trembley - 2025-12-28

          To be clear, I never checked the generated C code, because I am not well versed in C. I don't believe I can determine if there is a defect in the generation of the intermediate C code.

          But I believe that the COBOL results are correct in all cases, using either c_main.cob or the similar bug1165v01.cbl (with extra display statements).

           

Log in to post a comment.