Skip to content

Commit

Permalink
adding --coverage to cobc
Browse files Browse the repository at this point in the history
cobc:
* cobc.c, flag.def, help.c: added option --coverage internally setting -fgen-c-line-directive, ensuring to write object file with original name, passing appropriate flags to C compiler (GCC, LLVM, MSVC, Sun Solaris)
* codegen.c (output_initialize_uniform): switched to take an unsigned char
* tree.c: minor refactoring

additional for tests:
* Makefile.am (CODE_COVERAGE_IGNORE_PATTERN): add some .def files that have shown to be not useful for GnuCOBOL's own code coverage
* tests/cobol85/Makefile.am: pass appropriate flags to cobc for compiling
  • Loading branch information
sf-mensch committed Jan 6, 2023
1 parent 617c03b commit 8261f31
Show file tree
Hide file tree
Showing 12 changed files with 108 additions and 54 deletions.
7 changes: 6 additions & 1 deletion ChangeLog
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@

2023-01-05 Simon Sobisch <[email protected]>

* Makefile.am (CODE_COVERAGE_IGNORE_PATTERN): add some .def files
that have shown to be not useful for code coverage

2022-12-12 Simon Sobisch <[email protected]>

* configure.ac: check for and substitute PERL/perl
Expand Down Expand Up @@ -1481,7 +1486,7 @@
* Version 0.9 released.


Copyright 2002-2022 Free Software Foundation, Inc.
Copyright 2002-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.
7 changes: 5 additions & 2 deletions Makefile.am
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#
# Makefile gnucobol
#
# Copyright (C) 2003-2012, 2014-2020, 2022 Free Software Foundation, Inc.
# Copyright (C) 2003-2012, 2014-2020, 2023 Free Software Foundation, Inc.
# Written by Keisuke Nishida, Roger While, Simon Sobisch
#
# This file is part of GnuCOBOL.
Expand Down Expand Up @@ -41,7 +41,10 @@ clean-local: code-coverage-clean
dist-clean-local: code-coverage-dist-clean

CODE_COVERAGE_BRANCH_COVERAGE=1
CODE_COVERAGE_IGNORE_PATTERN="*/cobc/pplex.c" "*/cobc/ppparse.c" "*/cobc/scanner.c" "*/cobc/parser.c"
CODE_COVERAGE_IGNORE_PATTERN= \
"*/cobc/pplex.c" "*/cobc/ppparse.c" "*/cobc/scanner.c" "*/cobc/parser.c" \
"*/cobc/config.def" "*/cobc/warning.def" \
"*/libcob/statement.def"

# files shipped with the package that should be 755'ed:
FILES_TO_BE_EXECUTABLE = $(dist_noinst_SCRIPTS) \
Expand Down
8 changes: 8 additions & 0 deletions cobc/ChangeLog
Original file line number Diff line number Diff line change
@@ -1,4 +1,12 @@

2023-01-05 Simon Sobisch <[email protected]>

* cobc.c, flag.def, help.c: added option --coverage internally setting
-fgen-c-line-directive, ensuring to write object file with original name,
passing appropriate flags to C compiler (GCC, LLVM, MSVC, Sun Solaris)
* codegen.c (output_initialize_uniform): siwtched to take an unsigned char
* tree.c: minor refactoring

2023-01-02 Simon Sobisch <[email protected]>

* cobc.c, field.c, parser.y, reserved.c: adjustment for FLOAT-EXTENDED /
Expand Down
58 changes: 43 additions & 15 deletions cobc/cobc.c
Original file line number Diff line number Diff line change
Expand Up @@ -411,15 +411,17 @@ static enum compile_level cb_compile_level = 0;

static int iargs;

static size_t cobc_flag_module = 0;
static size_t cobc_flag_library = 0;
static size_t cobc_flag_run = 0;
static int cobc_flag_module = 0;
static int cobc_flag_library = 0;
static int cobc_flag_run = 0;
static char *cobc_run_args = NULL;
static size_t save_temps = 0;
static size_t save_all_src = 0;
static size_t save_c_src = 0;
static int save_temps = 0;
static int save_all_src = 0;
static signed int save_c_src = 0;
static signed int verbose_output = 0;
static size_t cob_optimize = 0;
static int cb_coverage_enabled = 0;
static int cob_optimize = 0;


static unsigned int cb_listing_linecount;
static int cb_listing_eject = 0;
Expand Down Expand Up @@ -580,6 +582,7 @@ static const struct option long_options[] = {
{"A", CB_RQ_ARG, NULL, 'A'},
{"MT", CB_RQ_ARG, NULL, '!'},
{"MF", CB_RQ_ARG, NULL, '@'},
{"coverage", CB_NO_ARG, &cb_coverage_enabled, 1},
{"P", CB_OP_ARG, NULL, 'P'},
{"Xref", CB_NO_ARG, NULL, 'X'},
{"use-extfh", CB_RQ_ARG, NULL, 9}, /* this is used by COBOL-IT; Same is -fcallfh= */
Expand Down Expand Up @@ -2077,9 +2080,13 @@ clean_up_intermediates (struct filename *fn, const int status)
|| (cb_compile_level == CB_LEVEL_PREPROCESS && save_temps))) {
cobc_check_action (fn->preprocess);
}
/* CHECKME: we had reports of unexpected intermediate
files on the dist - it is very likely rooted in this
early exit --> recheck its use */
if (save_c_src) {
return;
}

if (fn->need_translate
&& (status
|| cb_compile_level > CB_LEVEL_TRANSLATE
Expand Down Expand Up @@ -3204,6 +3211,12 @@ process_command_line (const int argc, char **argv)
}
}

/* enabled coverage includes specifying COBOL source lines,
may be disabled manually if needed */
if (cb_coverage_enabled) {
cb_flag_c_line_directives = 1;
}

/* dump implies extra information (may still be disabled later) */
if (cb_flag_dump != COB_DUMP_NONE) {
cb_flag_source_location = 1;
Expand Down Expand Up @@ -4282,7 +4295,7 @@ process_filename (const char *filename)
if (output_name && cb_compile_level == CB_LEVEL_ASSEMBLE) {
fn->object = cobc_main_strdup (output_name);
} else
if (save_temps
if (save_temps || cb_coverage_enabled
|| cb_compile_level == CB_LEVEL_ASSEMBLE) {
fn->object = cobc_main_stradd_dup (fbasename, "." COB_OBJECT_EXT);
} else
Expand Down Expand Up @@ -8088,10 +8101,18 @@ process_module_direct (struct filename *fn)
#endif
ret = process (cobc_buffer);
#ifdef COB_STRIP_CMD
if (strip_output && ret == 0) {
cobc_chk_buff_size (strlen (COB_STRIP_CMD) + 4 + strlen (name));
sprintf (cobc_buffer, "%s \"%s\"", COB_STRIP_CMD, name);
ret = process (cobc_buffer);
if (ret == 0) {
#ifdef __SUNPRO_C
if (cb_coverage_enabled) {
sprintf (cobc_buffer, "uncover \"%s\"", name);
ret = process (cobc_buffer);
}
#endif
if (strip_output) {
cobc_chk_buff_size (strlen (COB_STRIP_CMD) + 4 + strlen (name));
sprintf (cobc_buffer, "%s \"%s\"", COB_STRIP_CMD, name);
ret = process (cobc_buffer);
}
}
#endif
#else /* _MSC_VER */
Expand Down Expand Up @@ -8612,7 +8633,14 @@ finish_setup_compiler_env (void)
}
#endif
}
if (cb_coverage_enabled) {
COBC_ADD_STR (cobc_cflags, " --coverage", NULL, NULL);
COBC_ADD_STR (cobc_ldflags, " --coverage", NULL, NULL);
}
#elif defined(_MSC_VER)
if (cb_coverage_enabled) {
COBC_ADD_STR (cobc_cflags, " /Zi", NULL, NULL);
}
/* MSC stuff reliant upon verbose option */
switch (verbose_output) {
case 0:
Expand Down Expand Up @@ -8735,8 +8763,8 @@ begin_setup_internal_and_compiler_env (void)
/* Initialize variables */
begin_setup_compiler_env ();

set_const_cobc_build_stamp();
set_cobc_defaults();
set_const_cobc_build_stamp ();
set_cobc_defaults ();

output_name = NULL;

Expand All @@ -8746,7 +8774,7 @@ begin_setup_internal_and_compiler_env (void)
#endif

/* Enable default I/O exceptions without source locations */
cobc_deciph_ec("EC-I-O", 1U);
cobc_deciph_ec ("EC-I-O", 1U);
cb_flag_source_location = 0;

#ifndef HAVE_DESIGNATED_INITS
Expand Down
12 changes: 5 additions & 7 deletions cobc/codegen.c
Original file line number Diff line number Diff line change
Expand Up @@ -4741,14 +4741,13 @@ output_initialize_fp (cb_tree x, struct cb_field *f)
}

static void
output_initialize_uniform (cb_tree x, const int c, const int size)
output_initialize_uniform (cb_tree x, const unsigned char cc, const int size)
{
struct cb_field *f = cb_code_field (x);
const unsigned char cc = c;

/* REPORT lines are cleared to SPACES */
if (f->storage == CB_STORAGE_REPORT
&& c == ' ') {
&& cc == ' ') {
return;
}

Expand Down Expand Up @@ -5347,7 +5346,7 @@ output_initialize_compound (struct cb_initialize *p, cb_tree x)
} else {
size = ff->offset + ff->size - last_field->offset;
}
output_initialize_uniform (c, last_char, size);
output_initialize_uniform (c, (unsigned char)last_char, size);
}
break;
}
Expand Down Expand Up @@ -5401,7 +5400,6 @@ output_initialize_compound (struct cb_initialize *p, cb_tree x)
init = ' ';
}
if (init != -1) {
cb_tree c = cb_build_field_reference (f, NULL);
cb_tree stmt = CB_BUILD_FUNCALL_3 ("memset",
CB_BUILD_CAST_ADDRESS (c),
cb_int (init), cb_int (f->size * f->occurs_max));
Expand Down Expand Up @@ -5539,7 +5537,7 @@ output_initialize (struct cb_initialize *p)
case INITIALIZE_DEFAULT:
c = initialize_uniform_char (f, p);
if (c != -1) {
output_initialize_uniform (p->var, c, f->occurs_max);
output_initialize_uniform (p->var, (unsigned char)c, f->occurs_max);
output_initialize_chaining (f, p);
return;
}
Expand Down Expand Up @@ -5584,7 +5582,7 @@ output_initialize (struct cb_initialize *p)
case INITIALIZE_DEFAULT:
c = initialize_uniform_char (f, p);
if (c != -1) {
output_initialize_uniform (p->var, c, f->size);
output_initialize_uniform (p->var, (unsigned char)c, f->size);
output_initialize_chaining (f, p);
return;
}
Expand Down
4 changes: 2 additions & 2 deletions cobc/flag.def
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
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, Ron Norman,
Edward Hart

Expand Down Expand Up @@ -212,7 +212,7 @@ CB_FLAG_ON (cb_flag_c_decl_for_static_call, 1, "gen-c-decl-static-call",

CB_FLAG (cb_flag_c_line_directives, 1, "gen-c-line-directives",
_(" -fgen-c-line-directives\tgenerate source location directives in C code;\n"
" * turned on by -g"))
" * turned on by -g/--coverage"))

CB_FLAG (cb_flag_c_labels, 1, "gen-c-labels",
_(" -fgen-c-labels generate extra labels in C sources;\n"
Expand Down
7 changes: 4 additions & 3 deletions cobc/help.c
Original file line number Diff line number Diff line change
@@ -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, Ron Norman, Simon Sobisch,
Brian Tiffin, Edward Hart, Dave Pitts
Expand Down Expand Up @@ -115,10 +115,11 @@ cobc_print_usage_common_options (void)
puts (_(" -I <directory> add <directory> to copy/include search path"));
puts (_(" -L <directory> add <directory> to library search path"));
puts (_(" -l <lib> link the library <lib>"));
puts (_(" -D <define> define <define> for COBOL compilation"));
puts (_(" -A <options> add <options> to the C compile phase"));
puts (_(" -Q <options> add <options> to the C link phase"));
puts (_(" -D <define> define <define> for COBOL compilation"));
puts (_(" -K <entry> generate CALL to <entry> as static"));
puts (_(" -Q <options> add <options> to the C link phase"));
puts (_(" --coverage instrument generated binaries for coverage"));
puts (_(" --conf=<file> user-defined dialect configuration; see -std"));
puts (_(" --list-reserved display reserved words"));
puts (_(" --list-intrinsics display intrinsic functions"));
Expand Down
24 changes: 12 additions & 12 deletions cobc/tree.c
Original file line number Diff line number Diff line change
Expand Up @@ -1442,10 +1442,6 @@ cb_tree_category (cb_tree x)
if (f->children) {
/* CHECKME: may should be alphabetic/national/... depending on the content */
x->category = CB_CATEGORY_ALPHANUMERIC;
} else if (f->usage == CB_USAGE_POINTER && f->level != 88) {
x->category = CB_CATEGORY_DATA_POINTER;
} else if (f->usage == CB_USAGE_PROGRAM_POINTER && f->level != 88) {
x->category = CB_CATEGORY_PROGRAM_POINTER;
} else {
switch (f->level) {
case 66:
Expand All @@ -1460,7 +1456,11 @@ cb_tree_category (cb_tree x)
x->category = CB_CATEGORY_BOOLEAN;
break;
default:
if (f->pic) {
if (f->usage == CB_USAGE_POINTER) {
x->category = CB_CATEGORY_DATA_POINTER;
} else if (f->usage == CB_USAGE_PROGRAM_POINTER) {
x->category = CB_CATEGORY_PROGRAM_POINTER;
} else if (f->pic) {
x->category = f->pic->category;
/* FIXME: Hack for CGI to not abort */
} else if (f->flag_is_external_form) {
Expand Down Expand Up @@ -1636,7 +1636,7 @@ cb_fits_int (const cb_tree x)
} else {
s = "2147483647";
}
if (memcmp (p, s, (size_t)10) > 0) {
if (memcmp (p, s, 10U) > 0) {
return 0;
}
return 1;
Expand Down Expand Up @@ -1725,7 +1725,7 @@ cb_fits_long_long (const cb_tree x)
} else {
s = "9223372036854775807";
}
if (memcmp (p, s, (size_t)19) > 0) {
if (memcmp (p, s, 19U) > 0) {
return 0;
}
return 1;
Expand Down Expand Up @@ -1841,7 +1841,7 @@ cb_get_int (const cb_tree x)
if (l->scale < 0) {
size = size - l->scale;
}
check_lit_length(size, (const char *)l->data + i);
check_lit_length (size, (const char *)l->data + i);

/* Check numeric literal length matching requested output type */
#if INT_MAX >= 9223372036854775807
Expand All @@ -1851,7 +1851,7 @@ cb_get_int (const cb_tree x)
} else {
s = "9223372036854775807";
}
if (size > 19U || memcmp (&l->data[i], s, (size_t)19) > 0) {
if (size > 19U || memcmp (&l->data[i], s, 19U) > 0) {
cb_error (_("numeric literal '%s' exceeds limit '%s'"), &l->data[i], s);
return INT_MAX;
}
Expand All @@ -1863,7 +1863,7 @@ cb_get_int (const cb_tree x)
} else {
s = "2147483647";
}
if (size > 10U || memcmp (&l->data[i], s, (size_t)10) > 0) {
if (size > 10U || memcmp (&l->data[i], s, 10U) > 0) {
cb_error (_("numeric literal '%s' exceeds limit '%s'"), &l->data[i], s);
return INT_MAX;
}
Expand Down Expand Up @@ -1920,7 +1920,7 @@ cb_get_long_long (const cb_tree x)
} else {
s = "9223372036854775807";
}
if (size > 19U || memcmp (&(l->data[i]), s, (size_t)19) > 0) {
if (size > 19U || memcmp (&(l->data[i]), s, 19U) > 0) {
cb_error (_("numeric literal '%s' exceeds limit '%s'"), &l->data[i], s);
return LLONG_MAX;
}
Expand Down Expand Up @@ -1970,7 +1970,7 @@ cb_get_u_long_long (const cb_tree x)
/* Check numeric literal length matching requested output type */
if (unlikely(size >= 20U)) {
s = "18446744073709551615";
if (size > 20U || memcmp (&(l->data[i]), s, (size_t)20) > 0) {
if (size > 20U || memcmp (&(l->data[i]), s, 20U) > 0) {
cb_error (_("numeric literal '%s' exceeds limit '%s'"), &l->data[i], s);
return ULLONG_MAX;
}
Expand Down
2 changes: 1 addition & 1 deletion cobc/typeck.c
Original file line number Diff line number Diff line change
Expand Up @@ -10409,7 +10409,7 @@ cb_check_overlapping (struct cb_field *src_f, struct cb_field *dst_f,
/* Check for same parent field */
#ifdef _MSC_VER
#pragma warning(push)
#pragma warning(disable: 6011) // cb_field_founder always returns a valid pointer
#pragma warning(disable: 6011) /* cb_field_founder always returns a valid pointer */
#endif
ff1 = cb_field_founder (src_f);
ff2 = cb_field_founder (dst_f);
Expand Down
Loading

0 comments on commit 8261f31

Please sign in to comment.