Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix decimal constant bug occuring when several programs in a COBOL file #113

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions cobc/ChangeLog
Original file line number Diff line number Diff line change
@@ -1,4 +1,11 @@

2023-10-17 David Declerck <david.declerck@ocamlpro.com>

* codegen.c (codegen_internal, codegen_finalize): move declaration
of decimal constants from global storage to local storage to
fix bug #917 (segfault on decimal constant after CANCEL on
subprogram)

2023-07-26 Simon Sobisch <simonsobisch@gnu.org>

* typeck.c (search_set_keys): improving SEARCH ALL syntax checks
Expand Down
45 changes: 23 additions & 22 deletions cobc/codegen.c
Original file line number Diff line number Diff line change
Expand Up @@ -13926,6 +13926,29 @@ codegen_internal (struct cb_program *prog, const int subsequent_call)
/* Switch to main storage file */
output_target = cb_storage_file;
}

/* Decimal constants */
{
struct literal_list* m = literal_cache;
int comment_gen = 0;
for (; m; m = m->next) {
if (CB_TREE_CLASS (m->x) == CB_CLASS_NUMERIC
ddeclerck marked this conversation as resolved.
Show resolved Hide resolved
&& m->make_decimal) {
if (!comment_gen) {
comment_gen = 1;
output_local ("\n/* Decimal constants */\n");
}
output_local ("static\tcob_decimal\t%s%d;\n",
CB_PREFIX_DEC_FIELD, m->id);
output_local ("static\tcob_decimal\t*%s%d = NULL;\n",
CB_PREFIX_DEC_CONST, m->id);
}
}
if (comment_gen) {
output_local ("\n");
}
}

}

void
Expand Down Expand Up @@ -13965,28 +13988,6 @@ codegen_finalize (void)
}
}

/* Decimal constants */
{
struct literal_list* m;
int comment_gen = 0;
for (m = literal_cache; m; m = m->next) {
if (CB_TREE_CLASS (m->x) == CB_CLASS_NUMERIC
&& m->make_decimal) {
if (!comment_gen) {
comment_gen = 1;
output_storage ("\n/* Decimal constants */\n");
}
output_storage ("static\tcob_decimal\t%s%d;\n",
CB_PREFIX_DEC_FIELD, m->id);
output_storage ("static\tcob_decimal\t*%s%d = NULL;\n",
CB_PREFIX_DEC_CONST, m->id);
}
}
if (comment_gen) {
output_storage ("\n");
}
}

/* Clean up by clearing these */
attr_cache = NULL;
literal_cache = NULL;
Expand Down
60 changes: 60 additions & 0 deletions tests/testsuite.src/run_misc.at
Original file line number Diff line number Diff line change
Expand Up @@ -14570,3 +14570,63 @@ TST-DECIMAL IS < ZERO-DECIMAL


AT_CLEANUP


AT_SETUP([Decimal constants and programs in same source])
AT_KEYWORDS([runmisc INITIAL CANCEL CALL])

# this used to cause a SIGSEGV, see bug #917

AT_DATA([prog.cpy], [
IDENTIFICATION DIVISION.
PROGRAM-ID. :PROG-NAME: :PROG-KIND:.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 X PIC 9(2) VALUE 42.
01 Y PIC 9v9 VALUE 0.1.
PROCEDURE DIVISION.
MAIN.
* ensure that cobc cannot optimize the expression away
IF FUNCTION CURRENT-DATE = 0
ADD 1 TO Y.
IF (X + Y) / 42.1 = 1
DISPLAY "OK" WITH NO ADVANCING.
EXIT PROGRAM.
END PROGRAM :PROG-NAME:.
])

AT_DATA([prog.cob], [
IDENTIFICATION DIVISION.
PROGRAM-ID. prog.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 X PIC 9(2) VALUE 0.
01 Y PIC 9v9 VALUE 0.1.
PROCEDURE DIVISION.
MAIN.
* ensure that cobc cannot optimize the expression away
IF FUNCTION CURRENT-DATE = 0
ADD 1 TO Y.
CALL "nested_init"
CALL "nonnested_init"
CALL "nested_noninit"
CANCEL "nested_noninit"
CALL "nonnested_noninit"
CANCEL "nonnested_noninit"
IF X + Y + 42.1 <> 0
DISPLAY "OK" WITH NO ADVANCING.
STOP RUN.
COPY prog REPLACING ==:PROG-NAME:== BY ==nested_init==
==:PROG-KIND:== BY ==INITIAL==.
COPY prog REPLACING ==:PROG-NAME:== BY ==nested_noninit==
==:PROG-KIND:== BY ====.
END PROGRAM prog.
COPY prog REPLACING ==:PROG-NAME:== BY ==nonnested_init==
==:PROG-KIND:== BY ==INITIAL==.
COPY prog REPLACING ==:PROG-NAME:== BY ==nonnested_noninit==
==:PROG-KIND:== BY ====.
])

AT_CHECK([$COMPILE_MODULE prog.cob], [0], [], [])
AT_CHECK([$COBCRUN prog], [0], [OKOKOKOKOK], [])
AT_CLEANUP
Loading