diff --git a/ChangeLog b/ChangeLog index f944cbe7e..8eb60544f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,4 +1,8 @@ +2023-01-16 Simon Sobisch + + * configure.ac: adjusted hack for AIX 64bit OBJECT_MODE + 2023-01-14 Simon Sobisch * configure.ac: fix to use pdcurses when libcurses was verified diff --git a/NEWS b/NEWS index 90b3bed5d..c2158c9a4 100644 --- a/NEWS +++ b/NEWS @@ -229,12 +229,15 @@ NEWS - user visible changes -*- outline -*- affected programs (with OCCURS DEPENDING ON) or compile with additional -fno-odoslide to get the same results as with older GnuCOBOL versions -** the compile flag -fdefaultbyte was moved to a dialect configuration, +** the compile flag -fdefaultbyte (initializarion for data-items without + an explicit VALUE) was moved to a dialect configuration; while -fdefaultbyte still works as before it is now implied as binary - zero with -std=ibm/mvs/bs2000, space for -std=mf/acu/rm/realia, and + zero with -std=ibm/mvs/bs2000/realia, space for -std=mf/acu/rm, and no defined initialization for -std=cobol85/cobol2002/cobol2014/xopen, - it is unchanged for -std=default (initialize to PICTURE/USAGE) - for compatibility to previous behavior compile with -fdefaultbyte=init + it is unchanged for -std=default (initialize to PICTURE/USAGE); + for compatibility to previous behavior compile with -fdefaultbyte=init; + note that initialization for INDEXED BY items honors the defaultbyte + configuration now, too ** the dialect configuration option larger-redefines-ok was changed to a support option larger-redefines; if specified on the command-line diff --git a/build_windows/ChangeLog.txt b/build_windows/ChangeLog.txt index ef71e758f..6424414c5 100644 --- a/build_windows/ChangeLog.txt +++ b/build_windows/ChangeLog.txt @@ -1,4 +1,8 @@ +2023-01-16 Simon Sobisch + + * version_cobc.rc, version_libcob.rc: updated date + rev + 2022-12-17 Simon Sobisch * general for libcob+cobc: handle move of cconv module @@ -25,7 +29,7 @@ 2021-11-06 Simon Sobisch - * config.h.in: moved references to PACKACAGE_defines after the define, + * config.h.in: moved references to PACKAGE_defines after the define, fixing dist builds since 2020-10-27 * makedist.cmd: explicit search for "define PACKAGE_define" which fixes the multiple results @@ -306,7 +310,7 @@ version_libcob.rc, version_cobcrun.rc provided by Simon) -Copyright 2014-2020 Free Software Foundation, Inc. +Copyright 2014-2023 Free Software Foundation, Inc. Copying and distribution of this file, with or without modification, are permitted provided the copyright notice and this notice are preserved. diff --git a/build_windows/version_cobc.rc b/build_windows/version_cobc.rc index 26dc98a58..6237f7e9e 100644 --- a/build_windows/version_cobc.rc +++ b/build_windows/version_cobc.rc @@ -4,7 +4,7 @@ #include "config.h" #include "../libcob/version.h" -#define VCS_REF 4776 +#define VCS_REF 4935 #define STRINGIZE_DETAIL_(v) #v #define STRINGIZE(v) STRINGIZE_DETAIL_(v) @@ -44,7 +44,7 @@ VS_VERSION_INFO VERSIONINFO VALUE "FileDescription", PACKAGE_NAME " compiler, supporting most COBOL dialects with lots of extensions" VALUE "FileVersion", STRINGIZE(__LIBCOB_VERSION)"."STRINGIZE(__LIBCOB_VERSION_MINOR)"."STRINGIZE(__LIBCOB_VERSION_PATCHLEVEL)"."STRINGIZE(VCS_REF) VALUE "InternalName", "cobc" - VALUE "LegalCopyright", "Copyright (C) 2001-2022 Free Software Foundation, Inc." + VALUE "LegalCopyright", "Copyright (C) 2001-2023 Free Software Foundation, Inc." VALUE "LegalTrademarks", "Compiler: GNU General Public License v3 - see COPYING,\x0ADocumentation: GNU Free Documentation License." VALUE "OriginalFilename", "cobc.exe" VALUE "ProductName", PACKAGE_NAME " compiler" @@ -55,7 +55,7 @@ VS_VERSION_INFO VERSIONINFO VALUE "SpecialBuild", "" /* Non-Standard entries */ - VALUE "Build", "Oct 2022" + VALUE "Build", "Jan 2023" VALUE "Developer", "Keisuke Nishida, Roger While, Ron Norman, Simon Sobisch, Edward Hart and many others (see AUTHORS and THANKS)" VALUE "Support", "https://www.gnu.org/software/gnucobol/" VALUE "Users", "Unlimited." diff --git a/build_windows/version_libcob.rc b/build_windows/version_libcob.rc index 0bb8e4cff..aece84196 100644 --- a/build_windows/version_libcob.rc +++ b/build_windows/version_libcob.rc @@ -4,7 +4,7 @@ #include "config.h" #include "../libcob/version.h" -#define VCS_REF 4776 +#define VCS_REF 4935 #define STRINGIZE_DETAIL_(v) #v #define STRINGIZE(v) STRINGIZE_DETAIL_(v) @@ -44,7 +44,7 @@ VS_VERSION_INFO VERSIONINFO VALUE "FileDescription", PACKAGE_NAME " runtime, supporting most COBOL dialects with lots of extensions" VALUE "FileVersion", STRINGIZE(__LIBCOB_VERSION)"."STRINGIZE(__LIBCOB_VERSION_MINOR)"."STRINGIZE(__LIBCOB_VERSION_PATCHLEVEL)"."STRINGIZE(VCS_REF) VALUE "InternalName", "libcob" - VALUE "LegalCopyright", "Copyright (C) 2001-2022 Free Software Foundation, Inc." + VALUE "LegalCopyright", "Copyright (C) 2001-2023 Free Software Foundation, Inc." VALUE "LegalTrademarks", "Runtime: GNU Lesser General Public License v3 - see COPYING.LESSER,\x0ADocumentation: GNU Free Documentation License." VALUE "OriginalFilename", "libcob.dll" VALUE "ProductName", PACKAGE_NAME " runtime library" @@ -55,7 +55,7 @@ VS_VERSION_INFO VERSIONINFO VALUE "SpecialBuild", "" /* Non-Standard entries */ - VALUE "Build", "Oct 2022" + VALUE "Build", "Jan 2023" VALUE "Developer", "Keisuke Nishida, Roger While, Ron Norman, Simon Sobisch, Edward Hart and many others (see AUTHORS and THANKS)" VALUE "Support", "https://www.gnu.org/software/gnucobol/" VALUE "Users", "Unlimited." diff --git a/cobc/ChangeLog b/cobc/ChangeLog index 40212df96..385df1ef2 100644 --- a/cobc/ChangeLog +++ b/cobc/ChangeLog @@ -1,4 +1,21 @@ +2023-01-16 Simon Sobisch + + * parser.y (occurs_index): only set VALUE 1 for defaultbyte == INIT + * tree.h (CB_DEFAULT_BYTE_INIT, CB_DEFAULT_BYTE_NONE), config.c, field.c, + codegen.c: explicit defines instead of "only magic numbers" + * tree.c (cb_build_initialize), tree.h (struct cb_initialize), codegen.c + (output_initialize_to_value): replaced flag_init_statement with statement + * parser.y (setup_occurs_min_max): validate occurs_max limit + * codegen.c (output_initialize_uniform): pass code-field instead of + re-evaluating it + * codegen.c (output_initialize_multi_values): removed variable + "total_occurs" fixing Wunused-but-set-variable + * codegen.c (output_stmt): dropped unused msgid + * typeck.c (cb_build_index): add internal index variables in LINKAGE to + internal WORKING-STORAGE or internal LOCAL-STORAGE items depending on + program->flag_recursive + 2023-01-05 Simon Sobisch * cobc.c, flag.def, help.c: added option --coverage internally setting diff --git a/cobc/codegen.c b/cobc/codegen.c index 1382b7a3d..7d11b049c 100644 --- a/cobc/codegen.c +++ b/cobc/codegen.c @@ -1,5 +1,5 @@ /* - Copyright (C) 2003-2022 Free Software Foundation, Inc. + Copyright (C) 2003-2023 Free Software Foundation, Inc. Written by Keisuke Nishida, Roger While, Ron Norman, Simon Sobisch, Edward Hart @@ -2324,7 +2324,7 @@ output_local_field_cache (struct cb_program *prog) f = field->f; if (!f->flag_local && !f->flag_external) { - if (f->storage == CB_STORAGE_REPORT + if (f->storage == CB_STORAGE_REPORT && f->flag_occurs && f->occurs_max > 1) { /* generate sub-fields and a comment each */ @@ -2363,7 +2363,7 @@ output_local_field_cache (struct cb_program *prog) for (f = rep->records; f; f = f->sister) { if (f->storage == CB_STORAGE_WORKING && !(f->report_flag & COB_REPORT_REF_EMITTED)) { - output_emit_field(cb_build_field_reference (f, NULL), NULL); + output_emit_field (cb_build_field_reference (f, NULL), NULL); } } } @@ -4380,11 +4380,11 @@ deduce_initialize_type (struct cb_initialize *p, struct cb_field *f, return INITIALIZE_ONE; } - if (f->flag_external && !p->flag_init_statement) { + if (f->flag_external && p->statement == STMT_INIT_STORAGE) { return INITIALIZE_NONE; } - if (f->redefines && (!topfield || !p->flag_init_statement)) { + if (f->redefines && (!topfield || p->statement != STMT_INITIALIZE)) { return INITIALIZE_NONE; } @@ -4425,7 +4425,7 @@ deduce_initialize_type (struct cb_initialize *p, struct cb_field *f, } if (p->flag_default) { - if (cb_default_byte >= 0 && !p->flag_init_statement) { + if (p->statement == STMT_INIT_STORAGE && cb_default_byte >= 0) { return INITIALIZE_DEFAULT; } switch (f->usage) { @@ -4531,7 +4531,7 @@ static int initialize_uniform_char (const struct cb_field *f, const struct cb_initialize *p) { - if (cb_default_byte >= 0 && !p->flag_init_statement) { + if (p->statement == STMT_INIT_STORAGE && cb_default_byte >= 0) { return cb_default_byte; } @@ -4741,10 +4741,9 @@ output_initialize_fp (cb_tree x, struct cb_field *f) } static void -output_initialize_uniform (cb_tree x, const unsigned char cc, const int size) +output_initialize_uniform (cb_tree x, struct cb_field *f, + const unsigned char cc, const int size) { - struct cb_field *f = cb_code_field (x); - /* REPORT lines are cleared to SPACES */ if (f->storage == CB_STORAGE_REPORT && cc == ' ') { @@ -4805,7 +4804,7 @@ static void output_initialize_chaining (struct cb_field *f, struct cb_initialize *p) { /* only handle CHAINING for program initialization */ - if (p->flag_init_statement) { + if (p->statement == STMT_INITIALIZE) { return; } /* Note: CHAINING must be an extra initialization step as parameters not passed @@ -4821,7 +4820,7 @@ output_initialize_chaining (struct cb_field *f, struct cb_initialize *p) static void output_initialize_to_value (struct cb_field *f, cb_tree x, - const int flag_init_statement) + const enum cob_statement statement) { cb_tree value; struct cb_literal *l; @@ -4850,7 +4849,7 @@ output_initialize_to_value (struct cb_field *f, cb_tree x, } /* Check for non-standard OCCURS */ if ((f->level == 1 || f->level == 77) - && f->flag_occurs && !flag_init_statement) { + && f->flag_occurs && statement == STMT_INIT_STORAGE) { init_occurs = 1; } else { init_occurs = 0; @@ -5125,13 +5124,11 @@ output_initialize_to_default (struct cb_field *f, cb_tree x) static void output_initialize_one (struct cb_initialize *p, cb_tree x) { - struct cb_field *f; - - f = cb_code_field (x); + struct cb_field *f = cb_code_field (x); /* Initialize TO VALUE */ if (p->val && f->values) { - output_initialize_to_value (f, x, p->flag_init_statement); + output_initialize_to_value (f, x, p->statement); return; } @@ -5214,7 +5211,7 @@ output_initialize_multi_values (struct cb_initialize *p, cb_tree x, struct cb_fi struct cb_field *pftbl[COB_MAX_SUBSCRIPTS+1] = { NULL }; int idxtbl[COB_MAX_SUBSCRIPTS+1] = { 0 }; int occtbl[COB_MAX_SUBSCRIPTS+1] = { 0 }; - int idx, idx_clr, total_occurs; + int idx, idx_clr; #if 0 /* CHECKME: the init above should be fine */ for (idx=0; idx <= COB_MAX_SUBSCRIPTS; idx++) { @@ -5222,14 +5219,12 @@ output_initialize_multi_values (struct cb_initialize *p, cb_tree x, struct cb_fi pftbl[idx] = NULL; } #endif - total_occurs = 1; idx_clr = 0; for (idx = 0, pf = f; pf; pf = pf->parent) { if (pf->flag_occurs && pf->occurs_max > 1) { pftbl [idx] = pf; occtbl[idx] = pf->occurs_max; - total_occurs *= pf->occurs_max; idx++; } } @@ -5346,7 +5341,7 @@ output_initialize_compound (struct cb_initialize *p, cb_tree x) } else { size = ff->offset + ff->size - last_field->offset; } - output_initialize_uniform (c, (unsigned char)last_char, size); + output_initialize_uniform (c, last_field, (unsigned char)last_char, size); } break; } @@ -5472,7 +5467,7 @@ static void output_initialize_values_table_format (struct cb_initialize *p) { if (needs_table_format_value - && (!p->flag_init_statement || p->val == cb_true)) { + && (p->statement == STMT_INIT_STORAGE || p->val == cb_true)) { struct cb_field *f = cb_code_field (p->var); const cb_tree c = cb_build_field_reference (f, NULL); @@ -5495,7 +5490,7 @@ output_initialize_values_table_format (struct cb_initialize *p) static void output_initialize (struct cb_initialize *p) { - struct cb_field *f = cb_code_field (p->var); + struct cb_field *f = cb_code_field (p->var); int c; const enum cobc_init_type type @@ -5518,15 +5513,15 @@ output_initialize (struct cb_initialize *p) /* TODO: if cb_default_byte >= 0 do a huge memset first, then only emit setting for fields that need it (VALUE clause or special category - in general: not matching cb_default_byte); - similar for cb_default_byte == -2 (just without the - initial huge memset) */ + similar for cb_default_byte == CB_DEFAULT_BYTE_NONE (-2), + just without the initial huge memset */ needs_table_format_value = 0; /* Check for non-standard OCCURS */ if ((f->level == 1 || f->level == 77) && f->flag_occurs - && !p->flag_init_statement) { + && p->statement == STMT_INIT_STORAGE) { cb_tree x; switch (type) { case INITIALIZE_ONE: @@ -5537,7 +5532,7 @@ output_initialize (struct cb_initialize *p) case INITIALIZE_DEFAULT: c = initialize_uniform_char (f, p); if (c != -1) { - output_initialize_uniform (p->var, (unsigned char)c, f->occurs_max); + output_initialize_uniform (p->var, f, (unsigned char)c, f->size * f->occurs_max); output_initialize_chaining (f, p); return; } @@ -5582,7 +5577,7 @@ output_initialize (struct cb_initialize *p) case INITIALIZE_DEFAULT: c = initialize_uniform_char (f, p); if (c != -1) { - output_initialize_uniform (p->var, (unsigned char)c, f->size); + output_initialize_uniform (p->var, f, (unsigned char)c, f->size); output_initialize_chaining (f, p); return; } @@ -8200,7 +8195,7 @@ output_source_reference (cb_tree tree, const enum cob_statement statement) tree->source_file); /* Output source location as code */ - if (cb_flag_c_line_directives && tree->source_file) { + if (cb_flag_c_line_directives && tree->source_line) { output_cobol_info (tree); if (cb_flag_source_location) { output_line ("module->statement = %s;", stmnt_enum); @@ -8210,7 +8205,7 @@ output_source_reference (cb_tree tree, const enum cob_statement statement) output_c_info (); } if (cb_flag_source_location) { - if (!(cb_flag_c_line_directives && tree->source_file)) { + if (!(cb_flag_c_line_directives && tree->source_line)) { output_line ("module->statement = %s;", stmnt_enum); } if (statement == STMT_UNTIL) { @@ -8674,7 +8669,8 @@ output_stmt (cb_tree x) } /* LCOV_EXCL_START */ if (unlikely(x == cb_error_node)) { - cobc_err_msg (_("unexpected error_node parameter")); + /* untranslated as unexpected */ + cobc_err_msg ("unexpected error_node parameter"); COBC_ABORT (); } /* LCOV_EXCL_STOP */ @@ -9529,7 +9525,7 @@ output_report_data (struct cb_field *p) report_col_pos = p->report_column + p->size; } } - output_emit_field(cb_build_field_reference (p, NULL), NULL); + output_emit_field (cb_build_field_reference (p, NULL), NULL); if (p->report_sum_counter) { output_emit_field (p->report_sum_counter, "SUM"); } @@ -10441,9 +10437,22 @@ output_initial_values (struct cb_field *f) if (p->flag_no_init && !p->count) { continue; } + /* note: the initial value of INDEXED BY items is undefined per standard, + but earlier versions always set this explict to 1 on first entry; + we now make this depending on its value, set depending on cb_init_indexed_by + and on cb_implicit_init */ + if (p->flag_indexed_by && cb_default_byte == CB_DEFAULT_BYTE_NONE) { + continue; + } x = cb_build_field_reference (p, NULL); + /* output comment and source location for each 01/77 */ output_line ("/* initialize field %s */", p->name); - output_stmt (cb_build_initialize (x, cb_true, NULL, 1, 0, 0)); + if (cb_flag_c_line_directives && p->common.source_line) { + output_cobol_info (CB_TREE (p)); + output_line ("cob_nop ();"); + output_c_info (); + } + output_stmt (cb_build_initialize (x, cb_true, NULL, 1, STMT_INIT_STORAGE, 0)); output_newline (); } } @@ -12311,7 +12320,7 @@ output_internal_function (struct cb_program *prog, cb_tree parameter_list) } output_line ("%s%d = &%s%d;", CB_PREFIX_DEC_CONST, m->id, CB_PREFIX_DEC_FIELD, m->id); - output_line ("cob_decimal_init(%s%d);", CB_PREFIX_DEC_CONST, m->id); + output_line ("cob_decimal_init (%s%d);", CB_PREFIX_DEC_CONST, m->id); output_line ("cob_decimal_set_field (%s%d, (cob_field *)&%s%d);", CB_PREFIX_DEC_CONST, m->id, CB_PREFIX_CONST, m->id); diff --git a/cobc/config.c b/cobc/config.c index d9b661d73..017dbc0a6 100644 --- a/cobc/config.c +++ b/cobc/config.c @@ -1,5 +1,5 @@ /* - Copyright (C) 2003-2012, 2014-2017, 2019-2022 Free Software Foundation, Inc. + Copyright (C) 2003-2012, 2014-2017, 2019-2023 Free Software Foundation, Inc. Written by Keisuke Nishida, Roger While, Simon Sobisch This file is part of GnuCOBOL. @@ -773,11 +773,11 @@ cb_config_entry (char *buff, const char *fname, const int line) } else if (strcmp (name, "defaultbyte") == 0) { if (strcmp (val, "init") == 0) { /* generate default initialization per INITIALIZE rules */ - cb_default_byte = -1; + cb_default_byte = CB_DEFAULT_BYTE_INIT; break; } if (strcmp (val, "none") == 0) { - cb_default_byte = -2; + cb_default_byte = CB_DEFAULT_BYTE_NONE; #if 1 /* TODO: do not generate any default initialization for fields without VALUE, only the storage (best performance, least reproducibility); for now warn if specified on command line (allowing config files be correct already) */ diff --git a/cobc/field.c b/cobc/field.c index 08afaf61d..9301e26b8 100644 --- a/cobc/field.c +++ b/cobc/field.c @@ -3018,7 +3018,7 @@ cleanup_field_value (struct cb_field* f, cb_tree *val) } if (*val == cb_zero && !f->flag_internal_register - && cb_default_byte == -1 + && cb_default_byte == CB_DEFAULT_BYTE_INIT && ( f->storage == CB_STORAGE_WORKING || f->storage == CB_STORAGE_LOCAL) && !f->flag_sign_separate) { @@ -3039,7 +3039,8 @@ cleanup_field_value (struct cb_field* f, cb_tree *val) } if (*val == cb_space && !f->flag_internal_register - && (cb_default_byte == -1 || cb_default_byte == ' ') + && ( cb_default_byte == CB_DEFAULT_BYTE_INIT + || cb_default_byte == ' ') && ( f->storage == CB_STORAGE_WORKING || f->storage == CB_STORAGE_LOCAL) && !f->children) { diff --git a/cobc/parser.y b/cobc/parser.y index 3c5cf4211..e313e49d6 100644 --- a/cobc/parser.y +++ b/cobc/parser.y @@ -38,6 +38,7 @@ #define COB_IN_PARSER 1 #include "cobc.h" #include "tree.h" +#include "libcob/coblocal.h" #define _PARSER_H /* work around bad Windows SDK header */ @@ -789,9 +790,10 @@ setup_occurs_min_max (cb_tree occurs_min, cb_tree occurs_max) } if (current_field->occurs_max <= current_field->occurs_min) { cb_error (_("OCCURS TO must be greater than OCCURS FROM")); + current_field->occurs_max = current_field->occurs_min; } } else { - current_field->occurs_max = 0; + current_field->occurs_max = 0; /* UNBOUNDED */ } } else { current_field->occurs_min = 1; /* CHECKME: why using 1 ? */ @@ -800,6 +802,17 @@ setup_occurs_min_max (cb_tree occurs_min, cb_tree occurs_max) cb_verify (cb_odo_without_to, _("OCCURS DEPENDING ON without TO phrase")); } } + /* LCOV_EXCL_START */ + if (current_field->occurs_max > COB_MAX_FIELD_SIZE) { + /* testing here to give an early error; unlikely to be reached + with 64bit compilers so no own msgid for now; should be added + when the maximum field size is changed to be configurable */ + cb_error_x (CB_TREE (current_field), + _("'%s' cannot be larger than %d bytes"), + current_field->name, COB_MAX_FIELD_SIZE); + current_field->occurs_min = current_field->occurs_max = 1; + } + /* LCOV_EXCL_STOP */ } static void @@ -7837,6 +7850,7 @@ usage: } | INDEX { + /* TODO: second type which is 0-based, depending on dialect option */ check_and_set_usage (CB_USAGE_INDEX); } | PACKED_DECIMAL @@ -8279,7 +8293,9 @@ occurs_index: unqualified_word { const enum cb_storage storage = current_field->storage; - $$ = cb_build_index ($1, cb_int1, 1U, current_field); + const cb_tree init_val = cb_default_byte == CB_DEFAULT_BYTE_INIT + ? cb_int1 : NULL; + $$ = cb_build_index ($1, init_val, 1U, current_field); if (storage == CB_STORAGE_LOCAL) { CB_FIELD_PTR ($$)->index_type = CB_INT_INDEX; } else { diff --git a/cobc/tree.c b/cobc/tree.c index c7f13b73a..a444eee77 100644 --- a/cobc/tree.c +++ b/cobc/tree.c @@ -1,5 +1,5 @@ /* - Copyright (C) 2001-2022 Free Software Foundation, Inc. + Copyright (C) 2001-2023 Free Software Foundation, Inc. Written by Keisuke Nishida, Roger While, Simon Sobisch, Ron Norman, Edward Hart @@ -6464,7 +6464,7 @@ cb_build_assign (const cb_tree var, const cb_tree val) cb_tree cb_build_initialize (const cb_tree var, const cb_tree val, const cb_tree rep, const unsigned int def, - const unsigned int is_statement, + const enum cob_statement statement, const unsigned int no_filler_init) { struct cb_initialize *p; @@ -6475,7 +6475,7 @@ cb_build_initialize (const cb_tree var, const cb_tree val, const cb_tree rep, p->val = val; p->rep = rep; p->flag_default = (cob_u8_t)def; - p->flag_init_statement = (cob_u8_t)is_statement; + p->statement = statement; p->flag_no_filler_init = (cob_u8_t)no_filler_init; return CB_TREE (p); } diff --git a/cobc/tree.h b/cobc/tree.h index 2bfbd1ac0..f7f7e45fd 100644 --- a/cobc/tree.h +++ b/cobc/tree.h @@ -1,5 +1,5 @@ /* - Copyright (C) 2001-2012, 2014-2022 Free Software Foundation, Inc. + Copyright (C) 2001-2012, 2014-2023 Free Software Foundation, Inc. Written by Keisuke Nishida, Roger While, Simon Sobisch, Ron Norman This file is part of GnuCOBOL. @@ -997,6 +997,10 @@ struct cb_field { #define CB_FIELD_PTR(x) \ (CB_REFERENCE_P (x) ? CB_FIELD (cb_ref (x)) : CB_FIELD (x)) +/* special values for cb_default_byte */ +#define CB_DEFAULT_BYTE_INIT -1 /* init by PICTURE/USAGE; INDEXED BY as 1 */ +#define CB_DEFAULT_BYTE_NONE -2 /* no explicit init at all */ + /* Index */ #define CB_INDEX_OR_HANDLE_P(x) cb_check_index_or_handle_p (x) @@ -1337,8 +1341,8 @@ struct cb_initialize { cb_tree var; /* Field */ cb_tree val; /* ALL (cb_true) or category (cb_int) TO VALUE */ cb_tree rep; /* Replacing */ + enum cob_statement statement; /* INITIALIZE statement */ unsigned char flag_default; /* Default */ - unsigned char flag_init_statement; /* INITIALIZE statement */ unsigned char flag_no_filler_init; /* No FILLER initialize */ unsigned char padding; /* Padding */ }; @@ -2198,7 +2202,7 @@ extern cb_tree cb_build_schema_name (cb_tree); extern cb_tree cb_build_initialize (const cb_tree, const cb_tree, const cb_tree, const unsigned int, - const unsigned int, + const enum cob_statement, const unsigned int); struct cb_literal *build_literal (enum cb_category, diff --git a/cobc/typeck.c b/cobc/typeck.c index ac33d4115..0d2b9c274 100644 --- a/cobc/typeck.c +++ b/cobc/typeck.c @@ -1,5 +1,5 @@ /* - Copyright (C) 2001-2022 Free Software Foundation, Inc. + Copyright (C) 2001-2023 Free Software Foundation, Inc. Written by Keisuke Nishida, Roger While, Simon Sobisch, Ron Norman, Edward Hart @@ -2281,6 +2281,8 @@ cb_build_index (cb_tree x, cb_tree values, const unsigned int indexed_by, enum cb_storage storage = CB_STORAGE_WORKING; struct cb_field *f = CB_FIELD (cb_build_field (x)); + /* TODO: possibly second type which is 0-based, depending on dialect option, + see FR #428 */ f->usage = CB_USAGE_INDEX; cb_validate_field (f); f->values = values; @@ -2294,10 +2296,17 @@ cb_build_index (cb_tree x, cb_tree values, const unsigned int indexed_by, } switch (storage) { case CB_STORAGE_FILE: - case CB_STORAGE_LINKAGE: /* explicit: not passed -> program local -> WS */ case CB_STORAGE_WORKING: CB_FIELD_ADD (current_program->working_storage, f); break; + case CB_STORAGE_LINKAGE: + /* explicit: not passed -> program local -> WS / LO */ + if (current_program->flag_recursive) { + CB_FIELD_ADD (current_program->local_storage, f); + } else { + CB_FIELD_ADD (current_program->working_storage, f); + } + break; case CB_STORAGE_SCREEN: CB_FIELD_ADD (current_program->screen_storage, f); break; @@ -8344,7 +8353,7 @@ cb_emit_allocate_identifier (cb_tree allocate_identifier, cb_tree returning, con INITIALIZE identifier WITH FILLER ALL TO VALUE THEN TO DEFAULT */ if (init_flag) { current_statement->not_ex_handler = - cb_build_initialize (allocate_identifier, cb_true, NULL, 1, 0, 0); + cb_build_initialize (allocate_identifier, cb_true, NULL, 1, STMT_ALLOCATE, 0); } } @@ -9886,7 +9895,7 @@ cb_emit_initialize (cb_tree vars, cb_tree fillinit, cb_tree value, CB_REFERENCE (x)->length = temp; } cb_emit (cb_build_initialize (x , value, replacing, - def_init, 1, no_fill_init)); + def_init, STMT_INITIALIZE, no_fill_init)); } } diff --git a/config/ChangeLog b/config/ChangeLog index e0a5c2e5d..1ad29e507 100644 --- a/config/ChangeLog +++ b/config/ChangeLog @@ -1,4 +1,8 @@ +2023-01-16 Simon Sobisch + + * realia-strict.conf: change defaultbyte from space to zero + 2022-12-07 Nicolas Berthier * general: rename partial-replacing-with-literal into @@ -721,7 +725,7 @@ * default.inc, Makefile.am: New files. -Copyright 2003,2005-2007-2010,2014-2022 Free Software Foundation, Inc. +Copyright 2003,2005-2007-2010,2014-2023 Free Software Foundation, Inc. Copying and distribution of this file, with or without modification, are permitted provided the copyright notice and this notice are preserved. diff --git a/config/cobol2002.conf b/config/cobol2002.conf index 20f8d841b..e3651b557 100644 --- a/config/cobol2002.conf +++ b/config/cobol2002.conf @@ -271,7 +271,7 @@ assign-disk-from: unconformable vsam-status: unconformable self-call-recursive: skip record-contains-depending-clause: unconformable -defaultbyte: none # "undefined" +defaultbyte: none # initial storage is undefined picture-l: unconformable # archaic in COBOL2002 and currently not available as dialect features: diff --git a/config/cobol2014.conf b/config/cobol2014.conf index d0b9293ec..392a992b4 100644 --- a/config/cobol2014.conf +++ b/config/cobol2014.conf @@ -271,7 +271,7 @@ assign-disk-from: unconformable vsam-status: unconformable self-call-recursive: skip record-contains-depending-clause: unconformable -defaultbyte: none # "undefined" +defaultbyte: none # initial storage is undefined picture-l: unconformable # use fixed word list, synonyms and exceptions specified there diff --git a/config/cobol85.conf b/config/cobol85.conf index a4e10f424..f80f7a693 100644 --- a/config/cobol85.conf +++ b/config/cobol85.conf @@ -271,7 +271,7 @@ assign-disk-from: unconformable vsam-status: unconformable self-call-recursive: skip record-contains-depending-clause: unconformable -defaultbyte: none # "undefined" +defaultbyte: none # initial storage is undefined picture-l: unconformable # obsolete in COBOL85 and currently not available as dialect features: diff --git a/config/default.conf b/config/default.conf index d9dbd6dea..81675dadc 100644 --- a/config/default.conf +++ b/config/default.conf @@ -1,6 +1,6 @@ # GnuCOBOL compiler configuration # -# Copyright (C) 2001-2012, 2014-2022 Free Software Foundation, Inc. +# Copyright (C) 2001-2012, 2014-2023 Free Software Foundation, Inc. # Written by Keisuke Nishida, Roger While, Simon Sobisch, Edward Hart, # Ron Norman # @@ -292,7 +292,8 @@ assign-disk-from: ok vsam-status: ignore self-call-recursive: warning record-contains-depending-clause: unconformable -defaultbyte: init +defaultbyte: init # GC inits as INITIALIZE ALL TO VALUE THEN TO DEFAULT, + # with INDEXED BY variables initialized to 1 picture-l: ok # use complete word list; synonyms and exceptions are specified below diff --git a/config/gcos-strict.conf b/config/gcos-strict.conf index 885d2e5c6..8fa4b85b0 100644 --- a/config/gcos-strict.conf +++ b/config/gcos-strict.conf @@ -258,7 +258,7 @@ record-delimiter: ok sequential-delimiters: ok record-delim-with-fixed-recs: unconformable missing-statement: error -missing-period: error #when format not in {fixed,free} +missing-period: error # when format not in {fixed,free} zero-length-literals: unconformable xml-generate-extra-phrases: unconformable continue-after: unconformable diff --git a/config/realia-strict.conf b/config/realia-strict.conf index 69045d32e..061c1b05e 100644 --- a/config/realia-strict.conf +++ b/config/realia-strict.conf @@ -1,6 +1,6 @@ # GnuCOBOL compiler configuration # -# Copyright (C) 2001-2012, 2014-2022 Free Software Foundation, Inc. +# Copyright (C) 2001-2012, 2014-2023 Free Software Foundation, Inc. # Written by Keisuke Nishida, Roger While, Simon Sobisch, Edward Hart, # Ron Norman # @@ -275,7 +275,7 @@ assign-disk-from: unconformable vsam-status: ok self-call-recursive: skip record-contains-depending-clause: unconformable -defaultbyte: " " # not verified, but possibly like ACU/MF +defaultbyte: 0 # not verified, but likely like IBM picture-l: unconformable # use fixed word list, synonyms and exceptions specified there diff --git a/configure.ac b/configure.ac index 51cdcdc3b..d2442660f 100644 --- a/configure.ac +++ b/configure.ac @@ -54,25 +54,49 @@ AC_CONFIG_FILES([tests/atlocal], [chmod +x tests/atlocal]) AC_CONFIG_FILES([tests/run_prog_manual.sh], [chmod +x tests/run_prog_manual.sh]) +# In general: don't export/setenv but pass as option to configure +# this has the benefit that re-runs will take the same and "sudo" +# or later "make" (possibly as different user) will use the same +# set of tools # Note for SUN Solaris (gcc) -# option to configure/export/setenv: CC=gcc -m64 --libdir=/usr/local/lib/sparcv9 +# options to configure: CC="gcc -m64" --libdir=/usr/local/lib/sparcv9 # or: -# option to configure/export/setenv: CFLAGS=-m64 and LDFLAGS="-m64 -L/usr/local/lib/sparcv9" +# options to configure: CFLAGS=-m64 LDFLAGS="-m64 -L/usr/local/lib/sparcv9" # # Hack for AIX 64 bit (gcc) # Required - -# option to configure/export/setenv: CC=gcc -maix64 +# options to configure: CC="gcc -maix64" / CC="xlc -q64" # or: -# option to configure/export/setenv: CFLAGS=-maix64 and LDFLAGS=-maix64 +# options to configure: CFLAGS=-maix64 and LDFLAGS=-maix64 # Note: AIX commonly uses -Lpath like GNU/Linux would use -Lpath -Rpath -if echo "$CC$CFLAGS" | grep 'aix64' 1>/dev/null 2>&1; then - if test -f /usr/ccs/bin/ar; then - AR="/usr/ccs/bin/ar -X64" - else - AR="ar -X64" +if test "x$OBJECT_MODE" = x; then + echo "$CC $CFLAGS" | grep ' -maix64' 1>/dev/null 2>&1 + check1=$$ + echo "$CC $CFLAGS" | grep ' -q64' 1>/dev/null 2>&1 + check2=$$ + if test check1 = 0 -o check2 = 0; then + OBJECT_MODE=64 # for libtool + fi + unset check1 + unset check2 +fi + +if test "$OBJECT_MODE" = "64"; then + if test "x$AR" = x; then + if test -f /usr/ccs/bin/ar; then + AR="/usr/ccs/bin/ar -X64" + else + AR="ar -X64" + fi + fi + if test "x$NM" = x; then + if test -f /usr/ccs/bin/nm; then + NM="/usr/ccs/bin/nm -X64 -B" + else + NM="nm -X64 -B" + fi fi - NM="/usr/ccs/bin/nm -X64 -B" fi dnl We don't want to have the full list of automatic defines from automake, diff --git a/libcob/ChangeLog b/libcob/ChangeLog index 1356e4d07..05f23a375 100644 --- a/libcob/ChangeLog +++ b/libcob/ChangeLog @@ -1,4 +1,8 @@ +2023-01-16 Simon Sobisch + + * statement.def (STMT_INIT_STORAGE): new internal statement + 2023-01-15 Ron Norman * screenio.c: renamed max_pairs_available as this is defined on HPUX diff --git a/libcob/coblocal.h b/libcob/coblocal.h index 26a155cad..68b72b790 100644 --- a/libcob/coblocal.h +++ b/libcob/coblocal.h @@ -398,9 +398,10 @@ struct config_tbl { /* max sizes */ -/* Maximum bytes in a single/group field, - which doesn't contain UNBOUNDED items */ - /* TODO: add compiler configuration for limiting this */ +/* Maximum bytes in a single/group field and for OCCURS, + which doesn't contain UNBOUNDED items, + along with maximum number of OCCURS; + TODO: add compiler configuration for limiting this */ #ifndef COB_64_BIT_POINTER #define COB_MAX_FIELD_SIZE 268435456 #else diff --git a/libcob/common.c b/libcob/common.c index ec6f9bed3..0a142c09c 100644 --- a/libcob/common.c +++ b/libcob/common.c @@ -5620,12 +5620,10 @@ cob_allocate (unsigned char **dataptr, cob_field *retptr, void cob_free_alloc (unsigned char **ptr1, unsigned char *ptr2) { - struct cob_alloc_cache *cache_ptr; - struct cob_alloc_cache *prev_ptr; + struct cob_alloc_cache *cache_ptr = cob_alloc_base; + struct cob_alloc_cache *prev_ptr = cob_alloc_base; cobglobptr->cob_exception_code = 0; - cache_ptr = cob_alloc_base; - prev_ptr = cob_alloc_base; if (ptr1 && *ptr1) { void *vptr1; vptr1 = *ptr1; diff --git a/libcob/common.h b/libcob/common.h index 18f5e1595..08213d228 100644 --- a/libcob/common.h +++ b/libcob/common.h @@ -626,7 +626,8 @@ only usable with COB_USE_VC2013_OR_GREATER */ /* Maximum length of COBOL program names */ #define COB_MAX_NAMELEN 31 -/* Maximum number of subscripts */ +/* Maximum number of subscripts; + TODO: add compiler configuration for limiting this */ #define COB_MAX_SUBSCRIPTS 16 /* Memory size for sorting */ diff --git a/libcob/statement.def b/libcob/statement.def index f8cb62756..3d43f5e3d 100644 --- a/libcob/statement.def +++ b/libcob/statement.def @@ -1,5 +1,5 @@ /* - Copyright (C) 2022 Free Software Foundation, Inc. + Copyright (C) 2022-2023 Free Software Foundation, Inc. Written by Simon Sobisch This file is part of GnuCOBOL. @@ -20,9 +20,10 @@ /* COB_STATEMENT (name, string representation) - the order of these definitions may not change and - new entries must always be added to the end, as - those are used as enum entries and indexes + the order of these definitions may not change and new entries + must always be added to the end, as those are used both as enums + (cobc + libcob intern) _and_ as their integer values in generated + modules: cob_trace_statement (STMT_ADD) -> cob_trace_statement (1) */ COB_STATEMENT (STMT_ADD, "ADD") @@ -164,3 +165,6 @@ COB_STATEMENT (STMT_JSON_PARSE, "JSON GENERATE") COB_STATEMENT (STMT_XML_GENERATE, "XML GENERATE") COB_STATEMENT (STMT_XML_PARSE, "XML GENERATE") + +/* codegen intern only */ +COB_STATEMENT (STMT_INIT_STORAGE, "INIT STORAGE") diff --git a/tests/testsuite.src/run_misc.at b/tests/testsuite.src/run_misc.at index 1934d4f87..ba4906f26 100644 --- a/tests/testsuite.src/run_misc.at +++ b/tests/testsuite.src/run_misc.at @@ -1,4 +1,4 @@ -## Copyright (C) 2003-2012, 2014-2022 Free Software Foundation, Inc. +## Copyright (C) 2003-2012, 2014-2023 Free Software Foundation, Inc. ## Written by Keisuke Nishida, Roger While, Simon Sobisch, Edward Hart, ## Ron Norman ## @@ -349,9 +349,11 @@ AT_SETUP([LOCAL-STORAGE (3)]) AT_KEYWORDS([runmisc OCCURS INDEX INDEXED]) # Note: this tests undefined behaviour, because the initial value -# of index values are undefined, but should be identical in principle -# for LS/WS, and in the standard explicit "... is treated as a static -# item [for WS] and as an automatic item [for LS]"; see bug #794 +# of index-names are undefined per standard; where they are +# explicit defined to be "... treated as a static item [for WS] +# and as an automatic item [for LS]"; see bug #794 +# for GnuCOBOL that is defined depending on dialect options +# init-indexed-by and defaultbyte AT_DATA([callee.cob], [ IDENTIFICATION DIVISION. @@ -367,15 +369,15 @@ AT_DATA([callee.cob], [ 01 LCL-X. 05 LCL-VAR PIC 9 VALUE 0 OCCURS 1 INDEXED BY LCL-IDX. PROCEDURE DIVISION. - DISPLAY SPACE WITH NO ADVANCING. - ADD 1 to WRK-VAR(1) WRK-IDX, - LCL-VAR(1) LCL-IDX. + DISPLAY SPACE WITH NO ADVANCING UPON SYSOUT. + ADD 1 TO WRK-VAR(1) LCL-VAR(1) + SET WRK-IDX, LCL-IDX UP BY 1 SET DISP-IDX TO WRK-IDX. MOVE WRK-VAR(1) TO DISP-VAL. - DISPLAY DISP-VALS WITH NO ADVANCING. + DISPLAY DISP-VALS WITH NO ADVANCING UPON SYSOUT. SET DISP-IDX TO LCL-IDX. MOVE LCL-VAR(1) TO DISP-VAL. - DISPLAY DISP-VALS WITH NO ADVANCING. + DISPLAY DISP-VALS WITH NO ADVANCING UPON SYSOUT. GOBACK. ]) @@ -392,6 +394,37 @@ AT_DATA([caller.cob], [ AT_CHECK([$COMPILE_MODULE callee.cob], [0], [], []) AT_CHECK([$COMPILE -o prog caller.cob], [0], [], []) AT_CHECK([$COBCRUN_DIRECT ./prog], [0], [ 1212 2312 3412], []) +AT_CHECK([$COMPILE_MODULE -fdefaultbyte=0 callee.cob], [0], [], []) +AT_CHECK([$COBCRUN_DIRECT ./prog], [0], [ 1111 2211 3311], []) + +# note: this is the tested MF result (INDEXED BY are USAGE COMP 9(08), 0-based !): +#AT_CHECK([$COMPILE_MODULE -std=mf-strict callee.cob], [0], [], []) +#AT_CHECK([$COBCRUN_DIRECT ./prog], [0], [ 1018 2117 3216], []) + +AT_DATA([callee.cob], [ + IDENTIFICATION DIVISION. + PROGRAM-ID. callee. + DATA DIVISION. + WORKING-STORAGE SECTION. + 01 DISP-VALS. + 05 DISP-VAL PIC 9 VALUE 0. + 05 DISP-IDX PIC 9 VALUE 0. + 01 WRK-X. + 05 WRK-VAR PIC 9 VALUE 0 OCCURS 1 INDEXED BY WRK-IDX. + PROCEDURE DIVISION. + DISPLAY SPACE WITH NO ADVANCING UPON SYSOUT. + ADD 1 TO WRK-VAR(1) + SET WRK-IDX UP BY 1 + SET DISP-IDX TO WRK-IDX. + MOVE WRK-VAR(1) TO DISP-VAL. + DISPLAY DISP-VALS WITH NO ADVANCING UPON SYSOUT. + GOBACK. +]) + + +AT_CHECK([$COMPILE_MODULE -std=acu-strict callee.cob], [0], [], []) +AT_CHECK([$COBCRUN_DIRECT ./prog], [0], [ 19 20 31], []) +# note: tested result with 2 byte: AT_CHECK([$COBCRUN_DIRECT ./prog], [0], [ 15 26 37], []) AT_CLEANUP @@ -11107,6 +11140,10 @@ AT_DATA([prog.cob], [ MOVE "You" TO GRP-2A (1010:3) MOVE "$$" TO FLD-5-4 (5) MOVE "Something else!" TO FLD-1-X (5). + * + * "the initial value of an index-name at runtime is undefined" + * Old OpenCOBOL/GnuCOBOL did that as "1" + SET TAB-ADR-IND TO 1. * SET P2 TO NULL SET ADDRESS OF A-TABLE TO NULL @@ -11123,7 +11160,7 @@ $COBCRUN_DIRECT ./prog "param 1" param 'param 3'], [1], GRP-3:***ABC00D99D99D99D99XXABC00D99D99D99D99XXABC00D99 00D99D99XX*** GRP-5:***Mon49eyMon49eyMon49eyMon49eyMon49eyMon49eyMon49ey ], -[libcob: prog.cob:102: error: BASED/LINKAGE item 'A-TABLE' has NULL address +[libcob: prog.cob:106: error: BASED/LINKAGE item 'A-TABLE' has NULL address dump written to dumpall.txt ]) @@ -11133,7 +11170,7 @@ AT_CAPTURE_FILE(./dumpall.txt) AT_DATA([reference_tmpl], [ Module dump due to BASED/LINKAGE item 'A-TABLE' has NULL address - Last statement of "prog" was MOVE at line 102 of prog.cob + Last statement of "prog" was MOVE at line 106 of prog.cob ENTRY prog at prog.cob:75 Started by ./prog param 1 @@ -12253,6 +12290,9 @@ AT_DATA([prog.cob], [ PROCEDURE DIVISION. MAIN. + *> "the initial value of an index-name at runtime is undefined" + *> Old OpenCOBOL/GnuCOBOL did that as "1" + SET REC-NAME-IDX TO 1. MOVE 'A-F-GEN-LEDGER-ZGL' TO REC-NAME. PERFORM FINDIT. MOVE 'JUNK' TO REC-NAME.