diff --git a/cobc/codegen.c b/cobc/codegen.c index c9696af08..61b3ee4b6 100644 --- a/cobc/codegen.c +++ b/cobc/codegen.c @@ -1855,7 +1855,7 @@ output_call_cache (void) /* note: we explicit do _not_ initialize it directly as that will more likely lead to a non-consecutive memory layout, which makes the whole purpose of the fence useless */ - output_local ("static char\tcall_fence_pre[5];\n"); + output_local ("static char\tcall_fence_pre[8];\n"); } call_cache = call_list_reverse (call_cache); for (call = call_cache; call; call = call->next) { @@ -1869,7 +1869,7 @@ output_call_cache (void) } if ((call_cache || func_call_cache) && (cb_flag_memory_check & CB_MEMCHK_POINTER)) { - output_local ("static char\tcall_fence_post[5];\n"); + output_local ("static char\tcall_fence_post[8];\n"); } if (static_call_cache) { const char *convention_modifier; @@ -2094,10 +2094,10 @@ output_local_base_cache (void) output_local ("static "); } #ifdef HAVE_ATTRIBUTE_ALIGNED - output_local ("cob_u8_t %s%d_fence_pre[5]%s;\n", + output_local ("cob_u8_t %s%d_fence_pre[8]%s;\n", CB_PREFIX_BASE, fld->id, COB_ALIGN); #else - output_local ("%scob_u8_t%s %s%d_fence_pre[5];\n", + output_local ("%scob_u8_t%s %s%d_fence_pre[8];\n", COB_ALIGN_DECL_8, COB_ALIGN_ATTR_8, CB_PREFIX_BASE, fld->id); #endif @@ -2129,10 +2129,10 @@ output_local_base_cache (void) output_local ("static "); } #ifdef HAVE_ATTRIBUTE_ALIGNED - output_local ("cob_u8_t %s%d_fence_post[5]%s;\n", + output_local ("cob_u8_t %s%d_fence_post[8]%s;\n", CB_PREFIX_BASE, fld->id, COB_ALIGN); #else - output_local ("%scob_u8_t%s %s%d_fence_post[5];\n", + output_local ("%scob_u8_t%s %s%d_fence_post[8];\n", COB_ALIGN_DECL_8, COB_ALIGN_ATTR_8, CB_PREFIX_BASE, fld->id); #endif @@ -2165,13 +2165,13 @@ output_nonlocal_base_cache (void) if (fld->flag_used_in_call) { #ifdef HAVE_ATTRIBUTE_ALIGNED - output_storage ("static cob_u8_t %s%d_fence_pre[5]%s;\n", + output_storage ("static cob_u8_t %s%d_fence_pre[8]%s;\n", CB_PREFIX_BASE, fld->id, COB_ALIGN); #else #if defined(COB_ALIGN_PRAGMA_8) output_storage ("#pragma align 8 (%s%d_fence_pre)\n", CB_PREFIX_BASE, fld->id); #endif - output_storage ("static %scob_u8_t%s %s%d_fence_pre[5];\n", + output_storage ("static %scob_u8_t%s %s%d_fence_pre[8];\n", COB_ALIGN_DECL_8, COB_ALIGN_ATTR_8, CB_PREFIX_BASE, fld->id); #endif @@ -2200,13 +2200,13 @@ output_nonlocal_base_cache (void) output_storage ("\t/* %s */\n", fld->name); if (fld->flag_used_in_call) { #ifdef HAVE_ATTRIBUTE_ALIGNED - output_storage ("static cob_u8_t %s%d_fence_post[5]%s;\n", + output_storage ("static cob_u8_t %s%d_fence_post[8]%s;\n", CB_PREFIX_BASE, fld->id, COB_ALIGN); #else #if defined(COB_ALIGN_PRAGMA_8) output_storage ("#pragma align 8 (%s%d_fence_post)\n", CB_PREFIX_BASE, fld->id); #endif - output_storage ("static %scob_u8_t%s %s%d_fence_post[5];\n", + output_storage ("static %scob_u8_t%s %s%d_fence_post[8];\n", COB_ALIGN_DECL_8, COB_ALIGN_ATTR_8, CB_PREFIX_BASE, fld->id); #endif @@ -6462,12 +6462,12 @@ output_memory_check_call (struct cb_call *p, const enum cob_statement stmt) const struct cb_field *fchck = cb_field_founder (CB_FIELD (x)); if (fchck->flag_used_in_call) { if (stmt == STMT_BEFORE_CALL) { - output_line ("if (memcmp (%s%d_fence_pre, \"\\x00\\x00\\x00\\x00\", 5) == 0) {", + output_line ("if (memcmp (%s%d_fence_pre, \"\\x00\\x00\\x00\\x00\\x00\\x00\\x00\", 8) == 0) {", CB_PREFIX_BASE, fchck->id); output_indent_level += indent_adjust_level; - output_line ("memcpy (%s%d_fence_pre, \"\\xFF\\xFE\\xFD\\xFC\", 5);", + output_line ("memcpy (%s%d_fence_pre, \"\\xFF\\xFE\\xFD\\xFC\\xFB\\xFA\\xFF\", 8);", CB_PREFIX_BASE, fchck->id); - output_line ("memcpy (%s%d_fence_post, \"\\xFA\\xFB\\xFC\\xFD\", 5);", + output_line ("memcpy (%s%d_fence_post, \"\\xFA\\xFB\\xFC\\xFD\\xFE\\xFF\\xFA\", 8);", CB_PREFIX_BASE, fchck->id); output_indent_level -= indent_adjust_level; output_line ("} else {"); @@ -12523,8 +12523,8 @@ output_internal_function (struct cb_program *prog, cb_tree parameter_list) if ((call_cache || func_call_cache) && (cb_flag_memory_check & CB_MEMCHK_POINTER)) { output_line ("/* Initialize call-pointer memory fence */"); - output_line ("memcpy (call_fence_pre, \"\\xFF\\xFE\\xFD\\xFC\", 5);"); - output_line ("memcpy (call_fence_post, \"\\xFA\\xFB\\xFC\\xFD\", 5);"); + output_line ("memcpy (call_fence_pre, \"\\xFF\\xFE\\xFD\\xFC\\xFB\\xFA\\xFF\", 8);"); + output_line ("memcpy (call_fence_post, \"\\xFA\\xFB\\xFC\\xFD\\xFE\\xFF\\xFA\", 8);"); output_newline (); } diff --git a/cobc/codeoptim.c b/cobc/codeoptim.c index 82593ba67..ee20dffb6 100644 --- a/cobc/codeoptim.c +++ b/cobc/codeoptim.c @@ -196,8 +196,8 @@ cob_gen_optim (const enum cb_optim val) output_storage ("cob_check_fence_inline (const char *fence_pre, const char *fence_post,"); output_storage (" const enum cob_statement stmt, const char *name)"); output_storage ("{"); - output_storage (" if (memcmp (fence_pre, \"\\xFF\\xFE\\xFD\\xFC\", 5)"); - output_storage (" || memcmp (fence_post, \"\\xFA\\xFB\\xFC\\xFD\", 5)) {"); + output_storage (" if (memcmp (fence_pre, \"\\xFF\\xFE\\xFD\\xFC\\xFB\\xFA\\xFF\", 8)"); + output_storage (" || memcmp (fence_post, \"\\xFA\\xFB\\xFC\\xFD\\xFE\\xFF\\xFA\", 8)) {"); output_storage (" cob_check_fence (fence_pre, fence_post, stmt, name);"); output_storage (" }"); output_storage ("}"); diff --git a/cobc/typeck.c b/cobc/typeck.c index 183f89cb9..b557da9a3 100644 --- a/cobc/typeck.c +++ b/cobc/typeck.c @@ -8798,7 +8798,8 @@ cb_emit_call (cb_tree prog, cb_tree par_using, cb_tree returning, if ((cb_flag_memory_check & CB_MEMCHK_USING) && f->storage != CB_STORAGE_LINKAGE && f->storage != CB_STORAGE_LOCAL - && !f->flag_external) { + && !f->flag_external + && !f->flag_item_based) { f = cb_field_founder (f); if (f->redefines) { f = f->redefines; diff --git a/doc/ChangeLog b/doc/ChangeLog index 651680d66..6370af4f0 100644 --- a/doc/ChangeLog +++ b/doc/ChangeLog @@ -1,8 +1,13 @@ +2023-07-10 Simon Sobisch + + * gnucobol.texi: updated "Build target" (change of -P / -E), + updated "Debug switches" (changed -g and new memory-check) + 2023-05-24 Simon Sobisch * gnucobol.texi: document warning and optimization options - related to unreachable code; add node on core dumps + related to unreachable code; add note on core dumps 2023-01-31 Fabrice Le Fessant diff --git a/doc/gnucobol.texi b/doc/gnucobol.texi index 44b7c3231..a0ff783b6 100644 --- a/doc/gnucobol.texi +++ b/doc/gnucobol.texi @@ -353,6 +353,9 @@ The special input name @file{-} takes input from @file{stdin} which is assumed to be COBOL source, and uses a default output name of @file{a.out} (or @file{a.so/c/o/i}, selected as appropriate) for the build type. +You may also use @file{-} as output name for the listing file or the preprocessor +result, for example with @code{cobc -t - prog.cob} / @code{cobc -P- prog.cob}. + By default, the compiler builds a dynamically loadable module. The following options specify the target type produced by the compiler: @@ -361,12 +364,17 @@ The following options specify the target type produced by the compiler: @item -E Preprocess only: compiler directives are executed, comment lines are removed and @code{COPY} statements are expanded. -The output is saved in file @file{*.i}. +The output is sent to stdout, allowing you to directly use it as input for +another process. You can manually set an output file using @option{-o}. @item -C Translation only. COBOL source files are translated into C files. The output is saved in file @file{*.c}. +@item --save-temps +Normal compilation with additional storing the preprocessed files as @file{*.i} +and the translated C files as file @file{*.c}. + @item -S Compile only. Translated C files are compiled by the C compiler to assembler code. The output is saved in file @file{*.s}. @@ -878,13 +886,17 @@ Produce C debugging information in the output. @item --debug, -d Enable all run-time error checks. +@item -fmemory-check=scope +Enable checking of internal storage during CALL (implied by @option{--debug}. + @item -fec=exception-name, -fno=ec=exception-name Enable/disable specified exception checks, -@pxref{Appendix F, Exception Names, Exception Names}. +@pxref{Appendix F, Exception Names, Exception Names}; +@option{--debug} implies @option{-fec=ALL}. @item -fsource-location -Generate source location code (implied by @option{--debug}, @option{-g} and -@option{-fec}); @option{--debug} implies @option{-fec=ALL}. +Generate source location code (implied by @option{--debug}, @option{-fdump} and +@option{-fec}). @item -fstack-check Enable @code{PERFORM} stack checking (implied by @option{--debug} or @option{-g}). @@ -1692,7 +1704,7 @@ In addition, setting the option @code{binary-size} to @code{2-4-8} or The compiler option @option{--debug} can be used, especially during the development of your programs. It enables all run-time error checking, such as -subscript boundary checks and numeric data checks, and displays +subscript boundary checks and numeric data checks, and leads to display of run-time errors with source locations. Exceptions may also be enabled/disabled separately. @xref{Debug switches, Debug switches,,,}. diff --git a/libcob/common.c b/libcob/common.c index c5a6eb320..fa96bd17d 100644 --- a/libcob/common.c +++ b/libcob/common.c @@ -4150,8 +4150,8 @@ void cob_check_fence (const char *fence_pre, const char *fence_post, const enum cob_statement stmt, const char *name) { - if (memcmp (fence_pre, "\xFF\xFE\xFD\xFC", 5) - || memcmp (fence_post, "\xFA\xFB\xFC\xFD", 5)) { + if (memcmp (fence_pre, "\xFF\xFE\xFD\xFC\xFB\xFA\xFF", 8) + || memcmp (fence_post, "\xFA\xFB\xFC\xFD\xFE\xFF\xFA", 8)) { /* LCOV_EXCL_START */ if (name) { /* note: reserved, currently not generated in libcob */ diff --git a/tests/testsuite.src/run_misc.at b/tests/testsuite.src/run_misc.at index 7cab45b92..353a87061 100644 --- a/tests/testsuite.src/run_misc.at +++ b/tests/testsuite.src/run_misc.at @@ -14113,7 +14113,13 @@ AT_DATA([caller.cob], [ DATA DIVISION. WORKING-STORAGE SECTION. - 01 var PIC x. + 01 var PIC X. + + 01 varg PIC X GLOBAL. + 01 vare PIC X EXTERNAL. + 01 varb PIC X BASED. + LINKAGE SECTION. + 01 varl PIC X. PROCEDURE DIVISION. * @@ -14121,6 +14127,12 @@ AT_DATA([caller.cob], [ * without the check this second call would SIGSEGV CALL "callee" USING var + * the following are mostly in to co-test the codegen + CALL "callee" USING varg + CALL "callee" USING vare + CALL "callee" USING varb + CALL "callee" USING varl + GOBACK. ]) @@ -14147,22 +14159,22 @@ AT_DATA([callee.cob], [ AT_CHECK([$COMPILE -fno-ec=program-arg-mismatch -fmemory-check=pointer caller.cob], [0], [], []) AT_CHECK([$COMPILE_MODULE -fno-ec=program-arg-mismatch callee.cob], [0], [], []) AT_CHECK([$COBCRUN_DIRECT ./caller], [1], [], -[libcob: caller.cob:12: error: memory violation detected after CALL +[libcob: caller.cob:18: error: memory violation detected after CALL ]) AT_CHECK([$COMPILE -fno-ec=program-arg-mismatch -fmemory-check=using caller.cob], [0], [], []) AT_CHECK([$COBCRUN_DIRECT ./caller], [1], [], -[libcob: caller.cob:12: error: memory violation detected for 'var' after CALL +[libcob: caller.cob:18: error: memory violation detected for 'var' after CALL ]) AT_CHECK([$COMPILE -fno-ec=program-arg-mismatch -fmemory-check caller.cob], [0], [], []) AT_CHECK([$COBCRUN_DIRECT ./caller], [1], [], -[libcob: caller.cob:12: error: memory violation detected for 'var' after CALL +[libcob: caller.cob:18: error: memory violation detected for 'var' after CALL ]) AT_CHECK([$COMPILE -fno-ec=program-arg-mismatch -fmemory-check=all caller.cob], [0], [], []) AT_CHECK([$COBCRUN_DIRECT ./caller], [1], [], -[libcob: caller.cob:12: error: memory violation detected for 'var' after CALL +[libcob: caller.cob:18: error: memory violation detected for 'var' after CALL ]) AT_CLEANUP @@ -14184,21 +14196,22 @@ AT_DATA([prog.cob], [ DATA DIVISION. WORKING-STORAGE SECTION. + 77 PNT USAGE POINTER EXTERNAL. + 01 REC. - 03 VAR PIC X(16). - 03 VAR2 PIC X(16). - 77 PNT USAGE POINTER. + 03 VAR PIC X. + 03 VAR2 PIC X. LINKAGE SECTION. 01 LREC. - 03 LVAR PIC X(32). - 03 LVAR2 PIC X(32). + 03 LVAR PIC X(64). + 03 LVAR2 PIC X(64). PROCEDURE DIVISION. * using a (not working) call prevents the C compiler * to know that we (do not) change the pointer variable * and therefore disallows it to check - * "that points to VAR2, you only have 32 bytes" (done with gcc -O) + * "that points to VAR2, you only have 2 bytes" (done with gcc -O) SET PNT TO ADDRESS OF VAR2. CALL "notthere" USING PNT ON EXCEPTION CONTINUE. SET ADDRESS OF LREC TO PNT. @@ -14210,7 +14223,7 @@ AT_DATA([prog.cob], [ AT_CHECK([$COMPILE prog.cob], [0], [], []) AT_CHECK([$COBCRUN_DIRECT ./prog], [1], [], -[libcob: prog.cob:27: error: memory violation detected after INIT CALL +[libcob: prog.cob:28: error: memory violation detected after INIT CALL ]) AT_CLEANUP