From: James K. Lowden Date: Mon, 16 Jun 2025 15:43:35 +0000 (-0400) Subject: cobol: Some 1000 small changes in answer to cppcheck diagnostics. X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=f298fabf3f10bcc426b41c23f90a5b90d694730d;p=thirdparty%2Fgcc.git cobol: Some 1000 small changes in answer to cppcheck diagnostics. constification per cppcheck. Use STRICT_WARN and fix reported diagnostics. Ignore [shadowVariable] in general. Use std::vector to avoid exposing arrays as raw pointers. PR cobol/120621 gcc/cobol/ChangeLog: * Make-lang.in: Use STRICT_WARN. * cbldiag.h (location_dump): suppress shadowVariable. * cdf-copy.cc (esc): Fix shadowVariable. (copybook_elem_t::open_file): Do not use %m. * cdf.y: suppress invalidPrintfArgType for target format. * cdfval.h (struct cdfval_t): Suppress noExplicitConstructor. * cobol1.cc (cobol_name_mangler): Use C++ cast. * copybook.h (class copybook_elem_t): Same. * dts.h: Fixes and suppressions due to cppcheck. * except.cc (cbl_enabled_exceptions_t::status): Suppress useStlAlgorithm. (cbl_enabled_exceptions_t::turn_on_off): Const parameter. (class choose_declarative): Removed. * genapi.cc (struct called_tree_t): Explicit constructor. (parser_compile_ecs): Cast to void * for %p. (parser_compile_dcls): Same. (parser_statement_begin): Same. (initialize_variable_internal): Use std::vector for subscripts. (parser_initialize): Constification. (get_string_from): Same. (combined_name): Same. (parser_perform): Same. (psa_FldLiteralN): Same. (is_figconst): Const parameter. (is_figconst_t): Same. (parser_exit): Same. (parser_division): Const pointer. (parser_perform_conditional): Whitespace. (parser_set_conditional88): Const parameter. (inspect_tally): Use std::vector. (inspect_replacing): Same. (parser_inspect): Same. (parser_intrinsic_subst): Use std::vector (constuct elements). (parser_intrinsic_call_1): Use std::vector for subscripts. (is_ascending_key): Const pointer. (parser_sort): Use std::vector. (parser_file_sort): Same. (parser_file_merge): Same. (parser_unstring): Same. (parser_string): Same. (parser_call): Const pointer. (parser_program_hierarchy): Use std::vector. (conditional_abs): Const paraemeter. (float_type_of): Same. (initial_from_initial): Set value, quoted or not. (parser_symbol_add): Remove redundant nested test. * genapi.h (parser_add): Const parameters. (parser_subtract): Same. (parser_multiply): Same. (parser_divide): Same. (parser_perform): Same. (parser_exit): Same. (parser_initialize): Same. (parser_set_conditional88): Same. (parser_sort): Same. (parser_file_sort): Same. (parser_file_merge): Same. (parser_string): Same. (is_ascending_key): Same. * genmath.cc (arithmetic_operation): Use std::vector. (is_somebody_float): Const parameter. (all_results_binary): Const parameter. (fast_multiply): Remove redundant nested test. (parser_add): Const parameter. (parser_multiply): Remove redundant nested test. (parser_divide): Const parameter. (parser_subtract): Same. * genutil.cc (get_depending_on_value): Use std::vector. (get_data_offset): Same. (tree_type_from_field): Const parameter. (refer_has_depends): Const pointers. (get_literal_string): RAII. (refer_is_clean): Use std::vector. (get_time_nanoseconds): Newline at EOF. * genutil.h (tree_type_from_field): Remove declaration. * inspect.h (struct cbx_inspect_qual_t): Use std::vector. (struct cbl_inspect_qual_t): Same. (struct cbx_inspect_match_t): Same. (class cbl_inspect_match_t): Same. (struct cbx_inspect_replace_t): Same. (struct cbl_inspect_replace_t): Same. (struct cbx_inspect_oper_t): Same. (struct cbl_inspect_oper_t): Same. (struct cbx_inspect_t): Same. (struct cbl_inspect_t): Same. (parser_inspect): Same. * lexio.cc (indicated): Const pointer. (remove_inline_comment): Scope reduction. (maybe_add_space): Const pointer. (recognize_replacements): C++ cast. (check_source_format_directive): Same. (struct replacing_term_t): Explicit constructor. (parse_replace_pairs): Const reference. (location_in): Const reference. (parse_copy_directive): C++ cast. (parse_replace_last_off): Const parameter. (parse_replace_text): Const reference. (parse_replace_directive): C++ cast. (cdftext::lex_open): Const reference. (cdftext::open_output): Scope reduction. (cdftext::free_form_reference_format): Remove unused variable. (cdftext::process_file): Simplify. * lexio.h (struct bytespan_t): Use nullptr. (struct filespan_t): Initialize icol in constructor. (struct span_t): Suppress confused operatorEqRetRefThis. (struct replace_t): Eliminate single-value constructor. * parse.y: Many const cppcheck reports, and portable bit-shift. * parse_ante.h (reject_refmod): Const parameter. (require_pointer): Same. (require_integer): Same. (struct evaluate_elem_t): Explicit constructor. (struct arith_t): Use std::vector. (class eval_subject_t): Const parameter. (dump_inspect_match): Declare. (struct perform_t): Explicit constructor. (list_add): Const parameter. (class tokenset_t): Avoid negative array index. (struct file_list_t): Explicit constructor. (struct field_list_t): Same. (struct refer_list_t): Same. (struct refer_marked_list_t): Const parameter. (struct refer_collection_t): Explicit constructor. (struct ast_inspect_oper_t): Remove class. (ast_inspect_oper_t): Same. (struct ast_inspect_t): Same. (struct ast_inspect_list_t): Same. (ast_inspect): Add location. (struct elem_list_t): Explicit constructor. (struct unstring_tgt_t): Same. (struct unstring_tgt_list_t): Same. (struct unstring_into_t): Same. (struct ffi_args_t): Same. (struct file_sort_io_t): Same. (merge_t): Same. (struct vargs_t): Same. (class prog_descr_t): Eliminate single-value constructor. (class program_stack_t): Suppress useStlAlgorithm. (struct rel_part_t): Eliminate single-value constructor. (class log_expr_t): Explicit constructor. (add_debugging_declarative): Rename local variable. (intrinsic_call_2): Const parameter. (invalid_key): Use std::find_if. (parser_add2): Const parameter. (parser_subtract2): Same. (stringify): Same. (unstringify): Same. (anybody_redefines): Same. (ast_call): Same. * parse_util.h (class cname_cmp): Explicit constructor. (intrinsic_inconsistent_parameter): Same. * scan_ante.h (struct cdf_status_t): Eliminate single-value constructor. (class enter_leave_t): Explicit constructor. (update_location): Const pointer, explicit constructor. (symbol_function_token): Const pointer. (typed_name): Same. * scan_post.h (datetime_format_of): Scope reduction. * show_parse.h (class ANALYZE): Use std::vector, explicit consstructor. * symbols.cc (symbol_table_extend): Scope reduction. (cbl_ffi_arg_t::cbl_ffi_arg_t): Define default constructor. (end_of_group): Const pointer. (symbol_find_odo): Const parameter. (rename_not_ok): Same. (field_str): Use %u instead of %d. (struct capacity_of): Const pointer. (symbols_update): Same. (symbol_field_parent_set): Same. (symbol_file_add): Same. (symbol_typedef_add): Same. (symbol_field_add): Use new operator=(). (symbol_field): Suppress CastIntegerToAddressAtReturn. (symbol_register): Same. (symbol_file): Suppress knownConditionTrueFalse. (next_program): Const parameter. (symbol_file_record): Same. (class is_section): Explicit constructor. (cbl_file_t::no_key): Remove. (cbl_prog_hier_t::cbl_prog_hier_t): Use std::vector. (symbol_label_add): Assert pointer is not NULL. (symbol_label_section_exists): Const reference in lambda. (expand_picture): Use C++ cast. (symbol_program_callables): Const pointer. (symbol_currency_add): Suppress nullPointerRedundantCheck. (cbl_key_t): Use std::vector. (cbl_occurs_t::field_add): Const parameter. (cbl_occurs_t::index_add): Explicit constructor. (class is_field_at): Same. (cbl_file_key_t::deforward): Scope reduction. (cbl_file_t::keys_str): Use allocated memory only. (file_status_status_of): Const pointer. (is_register_field): Const parameter. * symbols.h (struct cbl_field_data_t): Eliminate single-value constructor. (struct cbl_occurs_bounds_t): Same. (struct cbl_refer_t): Use std::vector. (valid_move): Const parameter. (is_register_field): Same. (struct cbl_key_t): Use std::vector. (struct cbl_substitute_t): Eliminate single-value constructor. (refer_of): Return const reference (struct cbl_ffi_arg_t): Eliminate single-value constructor. (class temporaries_t): Same. (struct cbl_file_key_t): Define default constructor. (struct cbl_file_lock_t): Define copy constructor and operator=(). (struct cbl_file_t): Complete default constructor. (struct symbol_elem_t): Explicit constructor. (symbol_elem_of): Suppress cstyleCast. (symbol_redefines): Const parameter. (struct cbl_field_t): Same. (cbl_section_of): Test for NULL pointer. (cbl_field_of): Same. (cbl_label_of): Same. (cbl_special_name_of): Same. (cbl_alphabet_of): Same. (cbl_file_of): Same. (is_figconst): Delete extra "struct" keyword. (is_figconst_low): Same. (is_figconst_zero): Same. (is_figconst_space): Same. (is_figconst_quote): Same. (is_figconst_high): Same. (is_space_value): Same. (is_quoted): Same. (symbol_index): Const parameter. (struct cbl_prog_hier_t): Suppress noExplicitConstructor. (struct cbl_perform_vary_t): Eliminate single-value constructor. (is_signable): Const parameter. (is_temporary): Same. (rename_not_ok): Same. (field_at): Test for NULL pointer. (class procref_base_t): Eliminate single-value constructor. * symfind.cc (is_data_field): Const pointer. (finalize_symbol_map2): Same. (class in_scope): Same. (symbol_match2): Same. * token_names.h: Suppress useInitializationList. * util.cc (normalize_picture): Whitespace and remove extra "continue". (redefine_field): Const pointer. (cbl_field_t::report_invalid_initial_value): Same. (literal_subscript_oob): Rename shadow variable. (cbl_refer_t::subscripts_set): Use std::vector. (cbl_refer_t::str): Same. (cbl_refer_t::deref_str): Same. (locally_unique): Use explicit constructor. (ambiguous_reference): Same. (class unique_stack): Use const reference. (cobol_filename): Const pointer. (verify_format): Scope reduction. (class temp_loc_t): Do not derive from YYLTYPE. (cobol_parse_files): Const pointer. * util.h (as_voidp): Define convenient converter. libgcobol/ChangeLog: * common-defs.h (class cbl_enabled_exceptions_t): Const parameter. --- diff --git a/gcc/cobol/Make-lang.in b/gcc/cobol/Make-lang.in index 5f293e1f987..bec81a6acc0 100644 --- a/gcc/cobol/Make-lang.in +++ b/gcc/cobol/Make-lang.in @@ -34,6 +34,9 @@ # - the compiler proper (eg: cc1plus) # - define the names for selecting the language in LANGUAGES. +# Use strict warnings for this front end. +cobol-warn = $(STRICT_WARN) + GCOBOL_INSTALL_NAME := $(shell echo gcobol|sed '$(program_transform_name)') GCOBOLIO_INSTALL_NAME := $(shell echo gcobol-io|sed '$(program_transform_name)') GCOBOL_TARGET_INSTALL_NAME := $(target_noncanonical)-$(shell echo gcobol|sed '$(program_transform_name)') diff --git a/gcc/cobol/cbldiag.h b/gcc/cobol/cbldiag.h index 2d2ff4c05f9..6b371eb0817 100644 --- a/gcc/cobol/cbldiag.h +++ b/gcc/cobol/cbldiag.h @@ -106,7 +106,7 @@ void gcc_location_set( const YYLTYPE& loc ); template static void location_dump( const char func[], int line, const char tag[], const LOC& loc) { - extern int yy_flex_debug; + extern int yy_flex_debug; // cppcheck-suppress shadowVariable if( yy_flex_debug && gcobol_getenv("update_location") ) fprintf(stderr, "%s:%d: %s location (%d,%d) to (%d,%d)\n", func, line, tag, diff --git a/gcc/cobol/cdf-copy.cc b/gcc/cobol/cdf-copy.cc index 3f5ae30a61c..f45c4669372 100644 --- a/gcc/cobol/cdf-copy.cc +++ b/gcc/cobol/cdf-copy.cc @@ -124,13 +124,13 @@ verify_bounds( size_t pos, size_t size, const char input[] ) { */ const char * esc( size_t len, const char input[] ) { - static char spaces[] = "([,;]?[[:space:]])+"; - static char spaceD[] = "(\n {6}D" "|" "[,;]?[[:space:]])+"; + static const char space[] = "([,;]?[[:space:]])+"; + static const char spaceD[] = "(\n {6}D" "|" "[,;]?[[:space:]])+"; static char buffer[64 * 1024]; char *p = buffer; const char *eoinput = input + len; - const char *spacex = is_reference_format()? spaceD : spaces; + const char *spacex = is_reference_format()? spaceD : space; for( const char *s=input; *s && s < eoinput; s++ ) { *p = '\0'; @@ -279,7 +279,7 @@ copybook_elem_t::open_file( const char directory[], bool literally ) { dbgmsg("copybook_elem_t::open_file: trying %s", path); if( (this->fd = open(path, O_RDONLY)) == -1 ) { - dbgmsg("could not open %s: %m", path); + dbgmsg("could not open %s: %s", path, xstrerror(errno)); return fd; } this->source.name = path; diff --git a/gcc/cobol/cdf.y b/gcc/cobol/cdf.y index e4d2feaaf52..7e7d226b53f 100644 --- a/gcc/cobol/cdf.y +++ b/gcc/cobol/cdf.y @@ -185,6 +185,7 @@ apply_cdf_turn( const exception_turn_t& turn ) { %printer { fprintf(yyo, "%s '%s'", keyword_str($$.token), $$.string? $$.string : "" ); } +/* cppcheck-suppress invalidPrintfArgType_sint */ %printer { fprintf(yyo, HOST_SIZE_T_PRINT_DEC " '%s'", (fmt_size_t)$$.number, $$.string? $$.string : "" ); } @@ -891,9 +892,9 @@ verify_integer( const YDFLTYPE& loc, const cdfval_base_t& val ) { return true; } -// cppcheck-suppress returnTempReference const cdfval_base_t& cdfval_base_t::operator()( const YDFLTYPE& loc ) { static cdfval_t zero(0); + // cppcheck-suppress returnTempReference return verify_integer(loc, *this) ? *this : zero; } diff --git a/gcc/cobol/cdfval.h b/gcc/cobol/cdfval.h index c4387b08066..465bdbb4d1a 100644 --- a/gcc/cobol/cdfval.h +++ b/gcc/cobol/cdfval.h @@ -73,28 +73,28 @@ struct cdfval_t : public cdfval_base_t { cdfval_base_t::string = NULL; cdfval_base_t::number = 0; } - cdfval_t( const char value[] ) + cdfval_t( const char value[] ) // cppcheck-suppress noExplicitConstructor : lineno(yylineno), filename(cobol_filename()) { cdfval_base_t::off = false; cdfval_base_t::string = value; cdfval_base_t::number = 0; } - cdfval_t( long long value ) + cdfval_t( long long value ) // cppcheck-suppress noExplicitConstructor : lineno(yylineno), filename(cobol_filename()) { cdfval_base_t::off = false; cdfval_base_t::string = NULL; cdfval_base_t::number = value; } - cdfval_t( long value ) + cdfval_t( long value ) // cppcheck-suppress noExplicitConstructor : lineno(yylineno), filename(cobol_filename()) { cdfval_base_t::off = false; cdfval_base_t::string = NULL; cdfval_base_t::number = value; } - cdfval_t( int value ) + cdfval_t( int value ) // cppcheck-suppress noExplicitConstructor : lineno(yylineno), filename(cobol_filename()) { cdfval_base_t::off = false; @@ -109,7 +109,7 @@ struct cdfval_t : public cdfval_base_t { HOST_WIDE_INT value = real_to_integer(&r); cdfval_base_t::number = value; } - cdfval_t( const cdfval_base_t& value ) + cdfval_t( const cdfval_base_t& value ) // cppcheck-suppress noExplicitConstructor : lineno(yylineno), filename(cobol_filename()) { cdfval_base_t *self(this); diff --git a/gcc/cobol/cobol1.cc b/gcc/cobol/cobol1.cc index 63f2b37816d..4bd79f1f605 100644 --- a/gcc/cobol/cobol1.cc +++ b/gcc/cobol/cobol1.cc @@ -571,7 +571,7 @@ cobol_name_mangler(const char *cobol_name_) } // Allocate enough space for a prepended underscore and a final '\0' - char *cobol_name = (char *)xmalloc(strlen(cobol_name_)+2); + char *cobol_name = static_cast(xmalloc(strlen(cobol_name_)+2)); size_t n = 0; if( cobol_name_[0] >= '0' && cobol_name_[0] <= '9' ) { diff --git a/gcc/cobol/copybook.h b/gcc/cobol/copybook.h index fa91fe56600..ff8c6d0ca27 100644 --- a/gcc/cobol/copybook.h +++ b/gcc/cobol/copybook.h @@ -100,7 +100,7 @@ class copybook_elem_t { } static char * dequote( const char orig[] ) { gcc_assert(quoted(orig)); - auto name = (char*)xcalloc(1, strlen(orig)); + auto name = static_cast(xcalloc(1, strlen(orig))); gcc_assert(name); char *tgt = name; diff --git a/gcc/cobol/dts.h b/gcc/cobol/dts.h index dfd7c4c24f7..aa3fa585096 100644 --- a/gcc/cobol/dts.h +++ b/gcc/cobol/dts.h @@ -35,13 +35,13 @@ namespace dts { { static regmatch_t empty; empty.rm_so = empty.rm_eo = -1; - regmatch_t& self(*this); + regmatch_t& self(*this); // cppcheck-suppress constVariableReference self = empty; } csub_match( const char input[], const regmatch_t& m ) : input(input) { - regmatch_t& self(*this); + regmatch_t& self(*this); // cppcheck-suppress constVariableReference self = m; matched = rm_so != -1; first = rm_so == -1? NULL : input + rm_so; @@ -68,7 +68,6 @@ namespace dts { #if __cpp_exceptions throw std::logic_error(msg); #else - pattern = NULL; cbl_errx("%s", msg); #endif } @@ -78,7 +77,7 @@ namespace dts { size_t size() const { return nsubexpr; } bool ready() const { return pattern != NULL; } private: - regex( const regex& ) {} + regex( const regex& ) = default; }; inline bool regex_search( const char input[], const char *eoinput, @@ -88,10 +87,10 @@ namespace dts { static const char msg[] = "input not NUL-terminated"; throw std::domain_error( msg ); #else - eoinput = strchr(input, '\0'); + // eoinput terminates input + eoinput = strchr(input, '\0'); // cppcheck-suppress uselessAssignmentPtrArg #endif } - if( eoinput == NULL ) eoinput = strchr(input, '\0'); auto ncm = re.size(); cm.resize(ncm); std::vector cms(ncm); diff --git a/gcc/cobol/except.cc b/gcc/cobol/except.cc index d2bc24a6cff..e50fa618f4a 100644 --- a/gcc/cobol/except.cc +++ b/gcc/cobol/except.cc @@ -108,14 +108,16 @@ cbl_enabled_exceptions_t::dump() const { std::swap(debug, yydebug); } +// cppcheck-suppress-begin [useStlAlgorithm] because why? uint32_t cbl_enabled_exceptions_t::status() const { uint32_t status_word = 0; for( const auto& ena : *this ) { status_word |= (EC_ALL_E & ena.ec ); - } + } return status_word; } +// cppcheck-suppress-end useStlAlgorithm std::vector cbl_enabled_exceptions_t::encode() const { @@ -133,13 +135,13 @@ void cbl_enabled_exceptions_t::turn_on_off( bool enabled, bool location, ec_type_t type, - std::set files ) + const std::set& files ) { // Update current enabled ECs tree on leaving this function. class update_parser_t { const cbl_enabled_exceptions_t& ecs; public: - update_parser_t(const cbl_enabled_exceptions_t& ecs) : ecs(ecs) {} + explicit update_parser_t(const cbl_enabled_exceptions_t& ecs) : ecs(ecs) {} ~update_parser_t() { tree ena = parser_compile_ecs(ecs.encode()); current_enabled_ecs(ena); @@ -244,16 +246,6 @@ cbl_enabled_exceptions_t::match( ec_type_t type, size_t file ) const { return output != end()? &*output : NULL; } -class choose_declarative { - size_t program; - public: - choose_declarative( size_t program ) : program(program) {} - - bool operator()( const cbl_declarative_t& dcl ) { - return dcl.global || program == symbol_at(dcl.section)->program; - } -}; - bool sort_supers_last( const cbl_declarative_t& a, const cbl_declarative_t& b ) { if( symbol_at(a.section)->program == symbol_at(b.section)->program ) { diff --git a/gcc/cobol/genapi.cc b/gcc/cobol/genapi.cc index 595aa61e25e..f2a5d0ea438 100644 --- a/gcc/cobol/genapi.cc +++ b/gcc/cobol/genapi.cc @@ -694,7 +694,7 @@ struct called_tree_t { tree node; public: - match_tree( tree node ) : node(node) {} + explicit match_tree( tree node ) : node(node) {} bool operator()( const called_tree_t& that ) const { return this->node == that.node; } @@ -957,7 +957,8 @@ parser_compile_ecs( const std::vector& ecs ) { SHOW_PARSE_HEADER char ach[64]; - snprintf(ach, sizeof(ach), " Size is %ld; retval is %p", ecs.size(), retval); + snprintf(ach, sizeof(ach), " Size is %ld; retval is %p", + ecs.size(), as_voidp(retval)); SHOW_PARSE_TEXT(ach) SHOW_PARSE_END } @@ -965,7 +966,8 @@ parser_compile_ecs( const std::vector& ecs ) { TRACE1_HEADER char ach[64]; - snprintf(ach, sizeof(ach), " Size is %ld; retval is %p", ecs.size(), retval); + snprintf(ach, sizeof(ach), " Size is %ld; retval is %p", + ecs.size(), as_voidp(retval)); TRACE1_TEXT_ABC("", ach, ""); TRACE1_END } @@ -1004,7 +1006,8 @@ parser_compile_dcls( const std::vector& dcls ) { SHOW_PARSE_HEADER char ach[64]; - snprintf(ach, sizeof(ach), " Size is %ld; retval is %p", dcls.size(), retval); + snprintf(ach, sizeof(ach), " Size is %ld; retval is %p", + dcls.size(), as_voidp(retval)); SHOW_PARSE_TEXT(ach); SHOW_PARSE_END } @@ -1012,7 +1015,8 @@ parser_compile_dcls( const std::vector& dcls ) { TRACE1_HEADER char ach[64]; - snprintf(ach, sizeof(ach), " Size is %ld; retval is %p", dcls.size(), retval); + snprintf(ach, sizeof(ach), " Size is %ld; retval is %p", + dcls.size(), as_voidp(retval)); TRACE1_TEXT_ABC("", ach, ""); TRACE1_END } @@ -1091,7 +1095,7 @@ parser_statement_begin( const cbl_name_t statement_name, { SHOW_PARSE_INDENT snprintf( ach, sizeof(ach), - "Sending ecs/dcls %p / %p", ecs, dcls); + "Sending ecs/dcls %p / %p", as_voidp(ecs), as_voidp(dcls)); SHOW_PARSE_TEXT(ach); } SHOW_PARSE_END @@ -1100,7 +1104,7 @@ parser_statement_begin( const cbl_name_t statement_name, { TRACE1_HEADER char ach[64]; - snprintf(ach, sizeof(ach), " ecs/dcls %p / %p", ecs, dcls); + snprintf(ach, sizeof(ach), " ecs/dcls %p / %p", as_voidp(ecs), as_voidp(dcls)); TRACE1_TEXT_ABC("", ach, ""); TRACE1_END } @@ -1315,7 +1319,7 @@ initialize_variable_internal( cbl_refer_t refer, bool is_redefined = false; - cbl_field_t *family_tree = parsed_var; + const cbl_field_t *family_tree = parsed_var; while(family_tree) { if( symbol_redefines(family_tree) ) @@ -1336,7 +1340,7 @@ initialize_variable_internal( cbl_refer_t refer, if( parsed_var->data.initial ) { bool a_parent_initialized = false; - cbl_field_t *parent = parent_of(parsed_var); + const cbl_field_t *parent = parent_of(parsed_var); while( parent ) { if( parent->attr & has_value_e ) @@ -1366,7 +1370,7 @@ initialize_variable_internal( cbl_refer_t refer, flag_bits |= wsclear() ? DEFAULTBYTE_BIT + (*wsclear() & DEFAULT_BYTE_MASK) : 0; - flag_bits |= (refer.nsubscript << NSUBSCRIPT_SHIFT) & NSUBSCRIPT_MASK; + flag_bits |= (refer.nsubscript() << NSUBSCRIPT_SHIFT) & NSUBSCRIPT_MASK; flag_bits |= just_once ? JUST_ONCE_BIT : 0 ; suppress_dest_depends = false; // Set this to false so that refer_is_clean is valid @@ -1531,7 +1535,7 @@ initialize_variable_internal( cbl_refer_t refer, // } void -parser_initialize(cbl_refer_t refer, bool like_parser_symbol_add) +parser_initialize(const cbl_refer_t& refer, bool like_parser_symbol_add) { //gg_printf("parser_initialize %s\n", gg_string_literal(refer.field->name), NULL_TREE); if( like_parser_symbol_add ) @@ -2475,7 +2479,7 @@ get_string_from(cbl_field_t *field) gg_cast(CHAR_P, gg_malloc(build_int_cst_type(SIZE_T, field->data.capacity+1)))); - char *litstring = get_literal_string(field); + const char *litstring = get_literal_string(field); gg_memcpy(psz, gg_string_literal(litstring), build_int_cst_type(SIZE_T, field->data.capacity+1)); @@ -2527,8 +2531,8 @@ combined_name(cbl_label_t *label) { // This routine returns a pointer to a static, so make sure you use the result // before calling the routine again - char *para_name = nullptr; - char *sect_name = nullptr; + const char *para_name = nullptr; + const char *sect_name = nullptr; const char *program_name = current_function->our_unmangled_name; if( label->type == LblParagraph ) @@ -2551,7 +2555,7 @@ combined_name(cbl_label_t *label) static char *retval= (char *)xmalloc(retval_size); char *paragraph = cobol_name_mangler(para_name); - char *section = cobol_name_mangler(sect_name); + char *section = cobol_name_mangler(sect_name); char *mangled_program_name = cobol_name_mangler(program_name); while( retval_size < (paragraph ? strlen(paragraph) : 0 ) @@ -3267,8 +3271,8 @@ parser_perform(cbl_label_t *label, bool suppress_nexting) // pairs were created, the locations of the goto instruction and the label // were not known. - char *para_name = nullptr; - char *sect_name = nullptr; + const char *para_name = nullptr; + const char *sect_name = nullptr; const char *program_name = current_function->our_unmangled_name; size_t deconflictor = symbol_label_id(label); @@ -4095,7 +4099,7 @@ psa_FldLiteralN(struct cbl_field_t *field ) int rdigit_delta = 0; int exponent = 0; - char *exp = strchr(p, 'E'); + const char *exp = strchr(p, 'E'); if( !exp ) { exp = strchr(p, 'e'); @@ -5659,16 +5663,16 @@ parser_assign( size_t nC, cbl_num_result_t *C, } static cbl_figconst_t -is_figconst(cbl_field_t *field) +is_figconst_t(const cbl_field_t *field) { cbl_figconst_t figconst = (cbl_figconst_t)(field->attr & FIGCONST_MASK); return figconst; } static cbl_figconst_t -is_figconst(cbl_refer_t &sourceref) +is_figconst(const cbl_refer_t &sourceref) { - return is_figconst(sourceref.field); + return is_figconst_t(sourceref.field); } void @@ -6213,7 +6217,7 @@ pe_stuff(cbl_refer_t refer, ec_type_t ec) } void -parser_exit( cbl_refer_t refer, ec_type_t ec ) +parser_exit( const cbl_refer_t& refer, ec_type_t ec ) { Analyze(); SHOW_PARSE @@ -6777,7 +6781,7 @@ parser_division(cbl_division_t division, // gg_printf("Somebody wants to cancel %s\n", // gg_string_literal(current_function->our_unmangled_name), // NULL_TREE); - cbl_label_t *prog = cbl_label_of(symbol_at(current_program_index())); + const cbl_label_t *prog = cbl_label_of(symbol_at(current_program_index())); size_t initializer_index = prog->initial_section; cbl_label_t *initializer = cbl_label_of(symbol_at(initializer_index)); parser_perform(initializer, true); // true means suppress nexting @@ -7770,9 +7774,9 @@ parser_classify( cbl_field_t *tgt, } void -parser_perform(struct cbl_perform_tgt_t *tgt, struct cbl_refer_t how_many) +parser_perform(const cbl_perform_tgt_t *tgt, cbl_refer_t how_many) { - cbl_field_t *N = how_many.field; + const cbl_field_t *N = how_many.field; // No SHOW_PARSE here; we want to fall through: if( !tgt->to() ) { @@ -7914,8 +7918,8 @@ parser_perform_conditional( struct cbl_perform_tgt_t *tgt ) if( !(i < MAXIMUM_UNTILS) ) { cbl_internal_error("%s:%d: %u exceeds MAXIMUM_UNTILS of %d, line %d", - __func__, __LINE__, - i, MAXIMUM_UNTILS, CURRENT_LINE_NUMBER); + __func__, __LINE__, + i, MAXIMUM_UNTILS, CURRENT_LINE_NUMBER); } gcc_assert(i < MAXIMUM_UNTILS); @@ -9035,7 +9039,7 @@ parser_perform_inline_times(struct cbl_perform_tgt_t *tgt, } void -parser_set_conditional88( struct cbl_refer_t refer, bool which_way ) +parser_set_conditional88( const cbl_refer_t& refer, bool which_way ) { Analyze(); struct cbl_field_t *tgt = refer.field; @@ -9917,14 +9921,51 @@ parser_file_start(struct cbl_file_t *file, static void inspect_tally(bool backward, cbl_refer_t identifier_1, - unsigned long n_identifier_2, - cbx_inspect_t* identifier_2) + cbl_inspect_opers_t& identifier_2) { Analyze(); // This is an INSPECT FORMAT 1 SHOW_PARSE { SHOW_PARSE_HEADER + char ach[128]; + sprintf(ach, "There are %lu identifier_2", identifier_2.size()); + SHOW_PARSE_TEXT(ach); + for(size_t i=0; i pcbl_refers(n_resolveds); // Now we make a second pass, populating those arrays: int_index = 0; @@ -10019,34 +10060,42 @@ inspect_tally(bool backward, pcbl_refers[pcbl_index++] = identifier_2[i].tally; // For each FOR there is a count of the loops after the FOR gg_assign( gg_array_value(integers, int_index++), - build_int_cst_type(SIZE_T, identifier_2[i].nbound) ); - for(size_t j=0; j* operations) + cbl_inspect_opers_t& operations) { Analyze(); // This is an INSPECT FORMAT 2 @@ -10086,6 +10131,7 @@ inspect_replacing(int backward, } // For REPLACING, unlike TALLY, there can be but one operation + unsigned long n_ops = operations.size(); gcc_assert(n_ops == 1); size_t n_id_3 = 0; @@ -10096,9 +10142,9 @@ inspect_replacing(int backward, // Make one pass through the inputs to count up the sizes of the arrays // we will be passing to the library routines: - for( size_t j=0; j pcbl_refers(n_resolveds); // Now we make a second pass, populating those arrays: size_t int_index = 0; @@ -10165,28 +10211,28 @@ inspect_replacing(int backward, // The first integer is the all-important controlling count: gg_assign( gg_array_value(integers, int_index++), - build_int_cst_type(SIZE_T, operations[0].nbound) ); + build_int_cst_type(SIZE_T, operations[0].nbound()) ); // The first refer is for identifier-1 pcbl_refers[pcbl_index++] = identifier_1; - for( size_t j=0; j* operations) + cbl_inspect_opers_t& operations) { Analyze(); - gcc_assert(n_operations); + gcc_assert(! operations.empty()); /* Operating philosophy: We are going to minimize the amount of GENERIC tag creation here at compile time, mainly by eliminating @@ -10290,12 +10335,12 @@ parser_inspect(cbl_refer_t identifier_1, if( operations[0].tally.field ) { // This is a FORMAT 1 "TALLYING" - inspect_tally(backward, identifier_1, n_operations, operations); + inspect_tally(backward, identifier_1, operations); } else { // This is a FORMAT 2 "REPLACING" - inspect_replacing(backward, identifier_1, n_operations, operations); + inspect_replacing(backward, identifier_1, operations); } } @@ -10441,8 +10486,8 @@ parser_intrinsic_subst( cbl_field_t *f, sv_is_i_o = true; store_location_stuff("SUBSTITUTE"); unsigned char *control_bytes = (unsigned char *)xmalloc(argc * sizeof(unsigned char)); - cbl_refer_t *arg1 = (cbl_refer_t *)xmalloc(argc * sizeof(cbl_refer_t)); - cbl_refer_t *arg2 = (cbl_refer_t *)xmalloc(argc * sizeof(cbl_refer_t)); + std::vector arg1(argc); + std::vector arg2(argc); for(size_t i=0; ioccurs.bounds.upper ? ref1.field->occurs.bounds.upper : 1; - if( ref1.nsubscript ) + if( ref1.nsubscript() ) { upper = 1; } - if( is_table(ref1.field) && !ref1.nsubscript ) + if( is_table(ref1.field) && !ref1.nsubscript() ) { static tree depending_on = gg_define_variable(LONG, "..pic1_dep"); depending_on_value(depending_on, ref1.field); @@ -11269,7 +11312,7 @@ parser_bsearch_conditional( cbl_label_t* name ) } bool -is_ascending_key(cbl_refer_t key) +is_ascending_key(const cbl_refer_t& key) { bool retval = true; @@ -11290,7 +11333,7 @@ is_ascending_key(cbl_refer_t key) { size_t index_of_field = family_tree->occurs.keys[i].field_list.fields[j]; - cbl_field_t *key_field = cbl_field_of(symbol_at(index_of_field)); + const cbl_field_t *key_field = cbl_field_of(symbol_at(index_of_field)); if( strcmp( key_field->name, key.field->name ) == 0 ) @@ -11416,8 +11459,7 @@ void parser_sort(cbl_refer_t tableref, bool duplicates, cbl_alphabet_t *alphabet, - size_t nkeys, - cbl_key_t *keys ) + const std::vector& keys ) { Analyze(); SHOW_PARSE @@ -11439,18 +11481,18 @@ parser_sort(cbl_refer_t tableref, __func__, tableref.field->name); } - size_t total_keys = 0; - for( size_t i=0; i(flattened_fields)); // Create the array of integers that are the flags for ASCENDING: tree ascending = gg_array_of_size_t( total_keys, flattened_ascending ); @@ -11498,8 +11541,7 @@ void parser_file_sort( cbl_file_t *workfile, bool duplicates, cbl_alphabet_t *alphabet, - size_t nkeys, - cbl_key_t *keys, + const std::vector& keys, size_t ninput, cbl_file_t **inputs, size_t noutput, @@ -11576,18 +11618,18 @@ parser_file_sort( cbl_file_t *workfile, // clone of the code for handling multiple keys, each of which can have // multiple fields. - size_t total_keys = 0; - for( size_t i=0; i(flattened_fields)); // Create the array of integers that are the flags for ASCENDING: tree ascending = gg_array_of_size_t( total_keys, flattened_ascending ); @@ -11898,8 +11941,7 @@ gg_array_of_file_pointers( size_t N, void parser_file_merge( cbl_file_t *workfile, cbl_alphabet_t *alphabet, - size_t nkeys, - cbl_key_t *keys, + const std::vector& keys, size_t ninputs, cbl_file_t **inputs, size_t noutputs, @@ -11922,20 +11964,19 @@ parser_file_merge( cbl_file_t *workfile, build_int_cst_type(INT, file_sequential_e)); } - size_t total_keys = 0; - for( size_t i=0; i(flattened_fields)); // Create the array of integers that are the flags for ASCENDING: tree ascending = gg_array_of_size_t(total_keys, flattened_ascending); @@ -12011,7 +12053,7 @@ parser_file_merge( cbl_file_t *workfile, gg_call(VOID, "__gg__merge_files", gg_get_address_of(workfile->var_decl_node), - build_int_cst_type(SIZE_T, nkeys), + build_int_cst_type(SIZE_T, keys.size()), all_keys, ascending, build_int_cst_type(SIZE_T, ninputs), @@ -12183,7 +12225,7 @@ parser_unstring(cbl_refer_t src, gg_append_statement(not_overflow->structs.unstring->over.label); } - cbl_refer_t *delims = (cbl_refer_t *)xmalloc(ndelimited * sizeof(cbl_refer_t)); + std::vector delims(ndelimited); char *alls = (char *)xmalloc(ndelimited+1); for(size_t i=0; i refers(cblc_count); size_t index_int = 0; size_t index_cblc = 0; @@ -12311,7 +12352,7 @@ parser_string( cbl_refer_t tgt, tree pintegers = build_array_of_size_t( index_int, integers); - build_array_of_treeplets(1, index_cblc, refers); + build_array_of_treeplets(1, index_cblc, refers.data()); tree t_overflow = gg_define_int(); gg_assign(t_overflow, gg_call_expr( INT, @@ -12321,7 +12362,6 @@ parser_string( cbl_refer_t tgt, gg_free(pintegers); free(integers); - free(refers); if( overflow ) { @@ -12813,7 +12853,7 @@ parser_call( cbl_refer_t name, SHOW_PARSE_TEXT(" (") for(size_t i=0; i &uncles) } void -parser_program_hierarchy( const struct cbl_prog_hier_t& hier ) +parser_program_hierarchy( const cbl_prog_hier_t& hier ) { Analyze(); /* This routine gets called near the end of every program-id. It keeps @@ -13265,7 +13306,7 @@ parser_program_hierarchy( const struct cbl_prog_hier_t& hier ) } else { - for( size_t i=0; iattr & signable_e) ) @@ -14071,7 +14112,7 @@ tree float_type_of(int n) } static tree -float_type_of(cbl_field_t *field) +float_type_of(const cbl_field_t *field) { gcc_assert(field->type == FldFloat); return float_type_of(field->data.capacity); @@ -15554,7 +15595,7 @@ initial_from_initial(cbl_field_t *field) digits_from_float128(ach, field, field->data.digits, rdigits, value); - char *digits = ach; + const char *digits = ach; if( (field->attr & signable_e) && (field->attr & separate_e) && (field->attr & leading_e ) ) @@ -15643,7 +15684,7 @@ initial_from_initial(cbl_field_t *field) : field->data.capacity * 2 - 1; digits_from_float128(ach, field, ndigits, rdigits, value); - char *digits = ach; + const char *digits = ach; for(size_t i=0; idata.capacity+1); if( field->data.initial && field->attr & quoted_e ) { - if( field->attr & quoted_e ) + // What the programmer says the value is, the value becomes, no + // matter how wrong it might be. + size_t length = std::min( (size_t)field->data.capacity, + strlen(field->data.initial)); + for(size_t i=0; idata.capacity, - strlen(field->data.initial)); - for(size_t i=0; idata.initial[i]); - } - if( length < (size_t)field->data.capacity ) - { - memset( retval+length, - internal_space, - (size_t)field->data.capacity - length); - } + retval[i] = ascii_to_internal(field->data.initial[i]); + } + if( length < (size_t)field->data.capacity ) + { + memset( retval+length, + internal_space, + (size_t)field->data.capacity - length); } } else @@ -16333,7 +16371,7 @@ parser_symbol_add(struct cbl_field_t *new_var ) fprintf(stderr," OCCURS:" HOST_SIZE_T_PRINT_DEC, (fmt_size_t)new_var->occurs.ntimes()); } - cbl_field_t *parent = parent_of(new_var); + const cbl_field_t *parent = parent_of(new_var); if( parent ) { fprintf(stderr, @@ -16347,7 +16385,7 @@ parser_symbol_add(struct cbl_field_t *new_var ) size_t parent_index = new_var->parent; if( parent_index ) { - symbol_elem_t *e = symbol_at(parent_index); + const symbol_elem_t *e = symbol_at(parent_index); if( e->type == SymFile ) { fprintf(stderr, @@ -16747,10 +16785,7 @@ parser_symbol_add(struct cbl_field_t *new_var ) if( *external_record_base ) { char achDataName[256]; - if( *external_record_base ) - { - sprintf(achDataName, "__%s_vardata", external_record_base); - } + sprintf(achDataName, "__%s_vardata", external_record_base); tree array_type = build_array_type_nelts(UCHAR, new_var->data.capacity); new_var->data_decl_node = gg_define_variable( array_type, diff --git a/gcc/cobol/genapi.h b/gcc/cobol/genapi.h index 26944572d62..0c2887dc930 100644 --- a/gcc/cobol/genapi.h +++ b/gcc/cobol/genapi.h @@ -119,26 +119,26 @@ parser_divide(size_t nC, cbl_num_result_t *C, void *compute_error = NULL); // This has to be cast to a tree pointer to int void -parser_add( struct cbl_refer_t tgt, - struct cbl_refer_t a, struct cbl_refer_t b, +parser_add( const cbl_refer_t& tgt, + const cbl_refer_t& a, const cbl_refer_t& b, enum cbl_round_t = truncation_e ); void -parser_subtract( struct cbl_refer_t tgt, - struct cbl_refer_t a, struct cbl_refer_t b, +parser_subtract( const cbl_refer_t& tgt, + const cbl_refer_t& a, const cbl_refer_t& b, enum cbl_round_t = truncation_e ); void -parser_multiply( struct cbl_refer_t tgt, - struct cbl_refer_t a, struct cbl_refer_t b, +parser_multiply( const cbl_refer_t& tgt, + const cbl_refer_t& a, const cbl_refer_t& b, enum cbl_round_t = truncation_e ); void -parser_divide( struct cbl_refer_t quotient, - struct cbl_refer_t divisor, - struct cbl_refer_t dividend, +parser_divide( const cbl_refer_t& quotient, + const cbl_refer_t& divisor, + const cbl_refer_t& dividend, enum cbl_round_t = truncation_e, - struct cbl_refer_t remainder = cbl_refer_t()); + const cbl_refer_t& remainder = cbl_refer_t()); // void // parser_exponentiation( cbl_refer_t cref, @@ -225,7 +225,7 @@ parser_perform_conditional_end( struct cbl_perform_tgt_t *tgt ); * For an in-line loop body, tgt->from.type == LblLoop, and tgt->to is NULL. */ void -parser_perform( struct cbl_perform_tgt_t *tgt, struct cbl_refer_t N ); +parser_perform( const cbl_perform_tgt_t *tgt, cbl_refer_t N ); /* * A simple UNTIL loop uses 1 varys element. For VARY loops, the @@ -255,7 +255,7 @@ parser_end_program(const char *name=NULL); void parser_sleep(cbl_refer_t seconds); -void parser_exit( cbl_refer_t refer, ec_type_t = ec_none_e ); +void parser_exit( const cbl_refer_t& refer, ec_type_t = ec_none_e ); void parser_exit_section(void); void parser_exit_paragraph(void); void parser_exit_perform( struct cbl_perform_tgt_t *tgt, bool cycle ); @@ -297,7 +297,7 @@ void parser_symbol_add(struct cbl_field_t *field); void -parser_initialize(struct cbl_refer_t refer, bool like_parser_symbol_add=false); +parser_initialize(const cbl_refer_t& refer, bool like_parser_symbol_add=false); void parser_initialize_programs(size_t nprog, struct cbl_refer_t *progs); @@ -315,7 +315,7 @@ void parser_alter( cbl_perform_tgt_t *tgt ); void -parser_set_conditional88( struct cbl_refer_t tgt, bool which_way ); +parser_set_conditional88( const cbl_refer_t& tgt, bool which_way ); void parser_set_numeric(struct cbl_field_t *tgt, ssize_t value); @@ -406,14 +406,12 @@ void parser_sort(cbl_refer_t table, bool duplicates, cbl_alphabet_t *alphabet, - size_t nkey, - cbl_key_t *keys ); + const std::vector& keys ); void parser_file_sort( cbl_file_t *file, bool duplicates, cbl_alphabet_t *alphabet, - size_t nkey, - cbl_key_t *keys, + const std::vector& keys, size_t ninput, cbl_file_t **inputs, size_t noutput, @@ -423,8 +421,7 @@ parser_file_sort( cbl_file_t *file, void parser_file_merge( cbl_file_t *file, cbl_alphabet_t *alphabet, - size_t nkey, - cbl_key_t *keys, + const std::vector& keys, size_t ninput, cbl_file_t **inputs, size_t noutput, @@ -492,12 +489,12 @@ void parser_string_overflow_end( cbl_label_t *name ); void -parser_string( cbl_refer_t tgt, - cbl_refer_t pointer, - size_t nsource, - cbl_string_src_t *sources, - cbl_label_t *overflow, - cbl_label_t *not_overflow ); +parser_string(const cbl_refer_t& tgt, + const cbl_refer_t& pointer, + size_t nsource, + cbl_string_src_t *sources, + cbl_label_t *overflow, + cbl_label_t *not_overflow ); void parser_unstring( cbl_refer_t src, @@ -552,7 +549,7 @@ void parser_entry_activate( size_t iprog, const cbl_label_t *declarative ); void parser_entry( cbl_field_t *name, size_t narg = 0, cbl_ffi_arg_t args[] = NULL); -bool is_ascending_key(cbl_refer_t key); +bool is_ascending_key(const cbl_refer_t& key); void register_main_switch(const char *main_string); diff --git a/gcc/cobol/genmath.cc b/gcc/cobol/genmath.cc index edf3f22f68e..bf3885bcf6d 100644 --- a/gcc/cobol/genmath.cc +++ b/gcc/cobol/genmath.cc @@ -95,8 +95,8 @@ arithmetic_operation(size_t nC, cbl_num_result_t *C, size_t nA, cbl_refer_t *A, size_t nB, cbl_refer_t *B, cbl_arith_format_t format, - cbl_label_t *error, - cbl_label_t *not_error, + const cbl_label_t *error, + const cbl_label_t *not_error, tree compute_error, // Pointer to int const char *operation, cbl_refer_t *remainder = NULL) @@ -137,7 +137,7 @@ arithmetic_operation(size_t nC, cbl_num_result_t *C, // Allocate nC+1 in case this is a divide with a REMAINDER - cbl_refer_t *results = (cbl_refer_t *)xmalloc((nC+1) * sizeof( cbl_refer_t )); + std::vector results(nC + 1); int ncount = 0; if( nC+1 <= MIN_FIELD_BLOCK_SIZE ) @@ -207,7 +207,7 @@ arithmetic_operation(size_t nC, cbl_num_result_t *C, build_array_of_treeplets(1, nA, A); build_array_of_treeplets(2, nB, B); - build_array_of_treeplets(3, ncount, results); + build_array_of_treeplets(3, ncount, results.data()); gg_call(VOID, operation, @@ -253,9 +253,6 @@ arithmetic_operation(size_t nC, cbl_num_result_t *C, { SHOW_PARSE_END } - - // We need to release all of the refers we allocated: - free(results); } static void @@ -307,7 +304,7 @@ arithmetic_error_handler( cbl_label_t *error, } static bool -is_somebody_float(size_t nA, cbl_refer_t *A) +is_somebody_float(size_t nA, const cbl_refer_t *A) { bool retval = false; for(size_t i=0; insubscript is an unsigned value - for(size_t i=refer.nsubscript-1; idata.capacity, field->attr & signable_e); @@ -1559,7 +1561,7 @@ tree_type_from_size(size_t bytes, int signable) static bool -refer_has_depends(cbl_refer_t &refer, refer_type_t refer_type) +refer_has_depends(const cbl_refer_t &refer, refer_type_t refer_type) { if( suppress_dest_depends ) { @@ -1577,7 +1579,7 @@ refer_has_depends(cbl_refer_t &refer, refer_type_t refer_type) // Check if there there is an occurs with a depending_on in the hierarchy bool proceed = false; - cbl_field_t *odo = symbol_find_odo(refer.field); + const cbl_field_t *odo = symbol_find_odo(refer.field); cbl_field_t *depending_on; if( odo && odo != refer.field ) { @@ -1603,7 +1605,7 @@ refer_has_depends(cbl_refer_t &refer, refer_type_t refer_type) { parent1 = p; } - cbl_field_t *parent2 = depending_on; + const cbl_field_t *parent2 = depending_on; while( (p = parent_of(parent2)) ) { parent2 = p; @@ -1912,18 +1914,14 @@ char * get_literal_string(cbl_field_t *field) { assert(field->type == FldLiteralA); - char *buffer = NULL; - size_t buffer_length = 0; - if( buffer_length < field->data.capacity+1 ) - { - buffer_length = field->data.capacity+1; - buffer = (char *)xrealloc(buffer, buffer_length); - } + size_t buffer_length = field->data.capacity+1; + char *buffer = static_cast(xcalloc(1, buffer_length)); + for(size_t i=0; idata.capacity; i++) { buffer[i] = ascii_to_internal(field->data.initial[i]); } - buffer[field->data.capacity] = '\0'; + return buffer; } @@ -1943,7 +1941,7 @@ refer_is_clean(cbl_refer_t &refer) return !refer.all && !refer.addr_of - && !refer.nsubscript + && !refer.nsubscript() && !refer.refmod.from && !refer.refmod.len && !refer_has_depends(refer, refer_source) @@ -2141,4 +2139,4 @@ get_time_nanoseconds() return retval; #endif return retval; -} \ No newline at end of file +} diff --git a/gcc/cobol/genutil.h b/gcc/cobol/genutil.h index fb582e5a493..0d9028e035c 100644 --- a/gcc/cobol/genutil.h +++ b/gcc/cobol/genutil.h @@ -92,7 +92,7 @@ int get_scaled_rdigits(cbl_field_t *field); int get_scaled_digits(cbl_field_t *field); tree tree_type_from_digits(size_t digits, int signable); tree tree_type_from_size(size_t bytes, int signable); -tree tree_type_from_field(cbl_field_t *field); + void get_binary_value( tree value, tree rdigits, cbl_field_t *field, diff --git a/gcc/cobol/inspect.h b/gcc/cobol/inspect.h index fb8fda42163..96399f5dc01 100644 --- a/gcc/cobol/inspect.h +++ b/gcc/cobol/inspect.h @@ -53,181 +53,162 @@ static inline bool is_active( const cbl_refer_t& refer ) { return NULL != refer.field; } -template -struct cbx_inspect_qual_t { +struct cbl_inspect_qual_t { bool initial; - DATA identifier_4; + cbl_refer_t identifier_4; - cbx_inspect_qual_t() : initial(false), identifier_4(DATA()) {} - cbx_inspect_qual_t( bool initial, const DATA& identifier_4 ) + cbl_inspect_qual_t() : initial(false), identifier_4(cbl_refer_t()) {} + cbl_inspect_qual_t( bool initial, const cbl_refer_t& identifier_4 ) : initial(initial), identifier_4(identifier_4) - { - //if( identifier_4.field ) yywarn("%s:qualifying field is '%s'", __func__, identifier_4.field->name); - } - cbx_inspect_qual_t( const cbx_inspect_qual_t& that ) + {} + cbl_inspect_qual_t( const cbl_inspect_qual_t& that ) : initial(that.initial) , identifier_4(that.identifier_4) - { - //if( identifier_4.field ) yywarn("%s:qualifying field is '%s'", __func__, identifier_4.field->name); - } + {} - cbx_inspect_qual_t& operator=( const cbx_inspect_qual_t& that ) { + cbl_inspect_qual_t& operator=( const cbl_inspect_qual_t& that ) { initial = that.initial; identifier_4 = that.identifier_4; - //if( identifier_4.field ) yywarn("%s:qualifying field is '%s'", __func__, identifier_4.field->name); return *this; } bool active() const { return is_active(identifier_4); } - - void clear() { - initial = false; - identifier_4.clear(); - } }; -typedef cbx_inspect_qual_t cbl_inspect_qual_t; - /* * Data for INSPECT X TALLYING Y FOR. Captures information for operands of * CHARACTERS/ALL/LEADING. The CHARACTERS/ALL/LEADING control is kept at the * next higher level, and may be repeated for each tally. * - * cbx_inspect_match_t::matching is not used with CHARACTERS + * cbl_inspect_match_t::matching is not used with CHARACTERS */ -template -struct cbx_inspect_match_t { - DATA matching; // identifier-3/5 or literal-1/3 - cbx_inspect_qual_t before, after; // phrase 1 - - cbx_inspect_match_t( - const DATA& matching = DATA(), - const cbx_inspect_qual_t& before = cbx_inspect_qual_t(), - const cbx_inspect_qual_t& after = cbx_inspect_qual_t() - ) - : matching(matching) + +class cbl_inspect_match_t { + friend void dump_inspect_match( const cbl_inspect_match_t& M ); + cbl_refer_t match; // identifier-3/5 or literal-1/3 + cbl_refer_t tally; // collected too soon, belongs to next phrase + public: + cbl_inspect_qual_t before, after; // phrase 1 + + cbl_inspect_match_t() {} + explicit + cbl_inspect_match_t( const cbl_refer_t& matching, + const cbl_inspect_qual_t& before = cbl_inspect_qual_t(), + const cbl_inspect_qual_t& after = cbl_inspect_qual_t() ) + : match(matching) , before(before) , after(after) {} // match all characters bool match_any() const { return !(before.active() || after.active()); } -}; -typedef cbx_inspect_match_t cbl_inspect_match_t; + void save_premature_tally( const cbl_refer_t& tally ) { + this->tally = tally; // put it here temporarily + } + cbl_refer_t premature_tally() { + if( !tally.field ) { std::swap(match, tally); } + return tally; + } + + const cbl_refer_t& matching( const cbl_refer_t& match ) { + return this->match = match; + } + const cbl_refer_t& matching() const { return match; } + + bool empty() const { + return !is_active(match) && !before.active() && !after.active(); + } +}; /* * Data for INSPECT X REPLACING. The CHARACTERS/ALL/LEADING/FIRST control is * kept at the next higher level, and may be repeated. */ -template -struct cbx_inspect_replace_t : public cbx_inspect_match_t { - DATA replacement; - - cbx_inspect_replace_t( const DATA& matching = DATA(), - const DATA& replacement = DATA() ) - : cbx_inspect_match_t(matching) - , replacement(replacement) - {} - cbx_inspect_replace_t( const DATA& matching, - const DATA& replacement, - const cbx_inspect_qual_t& before, - const cbx_inspect_qual_t& after ) - : cbx_inspect_match_t(matching, before, after) +struct cbl_inspect_replace_t : public cbl_inspect_match_t { + cbl_refer_t replacement; + + cbl_inspect_replace_t() {} + cbl_inspect_replace_t( const cbl_refer_t& matching, + const cbl_refer_t& replacement, + const cbl_inspect_qual_t& before, + const cbl_inspect_qual_t& after ) + : cbl_inspect_match_t(matching, before, after) , replacement(replacement) {} }; -typedef cbx_inspect_replace_t cbl_inspect_replace_t; - // One partial tally or substitution. -template -struct cbx_inspect_oper_t { +struct cbl_inspect_oper_t { cbl_inspect_bound_t bound; // CHARACTERS/ALL/LEADING/FIRST - size_t n_identifier_3; // N matches/replaces - // either tallies or replaces is NULL - cbx_inspect_match_t *matches; - cbx_inspect_replace_t *replaces; + // either tallies or replaces is empty + std::vector matches; + std::vector replaces; - cbx_inspect_oper_t( cbl_inspect_bound_t bound, - std::list> matches ) + cbl_inspect_oper_t() : bound(bound_characters_e) {} + + explicit cbl_inspect_oper_t( const cbl_inspect_match_t& match, + cbl_inspect_bound_t bound = bound_characters_e ) : bound(bound) - , n_identifier_3( matches.size()) - , matches(NULL) - , replaces(NULL) - { - this->matches = new cbx_inspect_match_t[n_identifier_3]; - std::copy( matches.begin(), matches.end(), this->matches ); - } - - cbx_inspect_oper_t( cbl_inspect_bound_t bound, - std::list> replaces ) + { + matches.push_back(match); + } + explicit cbl_inspect_oper_t( const cbl_inspect_replace_t& replace, + cbl_inspect_bound_t bound = bound_characters_e ) : bound(bound) - , n_identifier_3( replaces.size() ) - , matches(NULL) - , replaces(NULL) - { - this->replaces = new cbx_inspect_replace_t[n_identifier_3]; - std::copy( replaces.begin(), replaces.end(), this->replaces ); - } - - cbx_inspect_oper_t() - : bound(bound_characters_e) - , n_identifier_3(0) - , matches(NULL) - , replaces(NULL) - { - assert( is_valid() ); - } - - bool is_valid() const { - if( matches && replaces ) return false; - if( matches || replaces ) return n_identifier_3 > 0; - return n_identifier_3 == 0; + { + replaces.push_back(replace); } -}; -typedef cbx_inspect_oper_t cbl_inspect_oper_t; + cbl_inspect_oper_t( cbl_inspect_bound_t bound, + const std::vector& matches ) + : bound(bound) + , matches(matches) + {} -// One whole tally or substitution. For REPLACING, nbound == 1 -template -struct cbx_inspect_t { - DATA tally; // identifier-2: NULL without a tally - size_t nbound; // FOR and REPLACING start with a cbl_inspect_bound_t - cbx_inspect_oper_t *opers; - - cbx_inspect_t( const DATA& tally = DATA() ) - : tally(tally) - , nbound(0) - , opers(NULL) + cbl_inspect_oper_t( cbl_inspect_bound_t bound, + const std::vector& replaces ) + : bound(bound) + , replaces(replaces) {} - cbx_inspect_t( const DATA& tally, const cbx_inspect_oper_t& oper ) - : tally(tally) - , nbound(1) - , opers(NULL) - { - this->opers = new cbx_inspect_oper_t[1]; - this->opers[0] = oper; - } - cbx_inspect_t( const DATA& tally, - const std::list>& opers ) - : tally(tally) - , nbound( opers.size() ) - , opers(NULL) - { - this->opers = new cbx_inspect_oper_t[nbound]; - std::copy( opers.begin(), opers.end(), this->opers ); - } + + // N matches/replaces + size_t n_identifier_3() const { + return std::max( matches.size(), replaces.size() ); + } + + bool is_valid() const { // only one or the other, never both + bool invalid = !matches.empty() && !replaces.empty(); + return ! invalid; + } }; -typedef cbx_inspect_t cbl_inspect_t; +// One whole tally or substitution. For REPLACING, nbound == 1 +// FOR and REPLACING start with a cbl_inspect_bound_t +struct cbl_inspect_t : public std::vector { + cbl_refer_t tally; // field is NULL for REPLACING + cbl_inspect_t() {} + cbl_inspect_t( size_t n, const cbl_inspect_oper_t& oper ) + : std::vector(n, oper) + {} + cbl_inspect_t( const cbl_refer_t& tally, + const std::vector& opers ) + : std::vector(opers) + , tally(tally) + {} + + size_t nbound() const { return size(); } +}; +typedef std::vector cbl_inspect_opers_t; /* * Runtime */ -void parser_inspect( cbl_refer_t input, bool backward, - size_t ninspect, cbl_inspect_t *inspects ); +void parser_inspect( const cbl_refer_t& input, + bool backward, + cbl_inspect_opers_t& inspects ); + void parser_inspect_conv( cbl_refer_t input, bool backward, cbl_refer_t original, cbl_refer_t replacement, diff --git a/gcc/cobol/lexio.cc b/gcc/cobol/lexio.cc index 13de5b6b6c2..888cce159c4 100644 --- a/gcc/cobol/lexio.cc +++ b/gcc/cobol/lexio.cc @@ -123,7 +123,7 @@ continues_at( char *bol, char *eol ) { // Return pointer to indicator column. Test ch if provided. // NULL means no indicator column or tested value not present. static inline char * -indicated( char *bol, char *eol, char ch = '\0' ) { +indicated( char *bol, const char *eol, char ch = '\0' ) { if( indicator.column == 0 && *bol != '*' ) { return NULL; // no indicator column in free format, except for comments } @@ -140,10 +140,10 @@ indicated( char *bol, char *eol, char ch = '\0' ) { static char * remove_inline_comment( char *bol, char *eol ) { - static char ends = '\0'; char *nl = std::find(bol, eol, '\n'); if( bol < nl ) { + static char ends = '\0'; std::swap(*nl, ends); char *comment = strstr(bol, "*>"); if( comment ) { @@ -208,10 +208,10 @@ maybe_add_space(const span_t& pattern, replace_t& recognized) { } if( befter[0] == blank || befter[1] == blank ) { - char *s = xasprintf( "%s%.*s%s", - befter[0], - recognized.after.size(), recognized.after.p, - befter[1] ); + const char *s = xasprintf( "%s%.*s%s", + befter[0], + recognized.after.size(), recognized.after.p, + befter[1] ); recognized.after = span_t(s, s + strlen(s)); } } @@ -266,7 +266,9 @@ recognize_replacements( filespan_t mfile, std::list& pending_replacem span_t found(mfile.eodata, mfile.eodata); - if( regex_search( mfile.ccur(), (const char *)mfile.eodata, cm, re) ) { + if( regex_search( mfile.ccur(), + const_cast(mfile.eodata), + cm, re) ) { gcc_assert(cm[1].matched); found = span_t( cm[1].first, cm[1].second ); if( yy_flex_debug ) { @@ -301,7 +303,8 @@ recognize_replacements( filespan_t mfile, std::list& pending_replacem bol = next.found.pend; if( yy_flex_debug ) { - size_t n = std::count((const char *)mfile.data, recognized.before.p, '\n'); + size_t n = std::count(const_cast(mfile.data), + recognized.before.p, '\n'); dbgmsg( "%s:%d: line " HOST_SIZE_T_PRINT_UNSIGNED " @ " HOST_SIZE_T_PRINT_UNSIGNED ": '%s'\n/%.*s/%.*s/", __func__, __LINE__, @@ -317,10 +320,11 @@ recognize_replacements( filespan_t mfile, std::list& pending_replacem next.found = span_t(mfile.eodata, mfile.eodata); regex re(next.directive.before.p, extended_icase); - if( regex_search(bol, (const char *)mfile.eodata, cm, re) ) { + if( regex_search(bol, const_cast(mfile.eodata), cm, re) ) { gcc_assert(cm[1].matched); next.found = span_t( cm[1].first, cm[1].second ); - size_t n = std::count((const char *)mfile.data, next.found.p, '\n'); + size_t n = std::count(const_cast(mfile.data), + next.found.p, '\n'); if( false ) dbgmsg("%s:%d next '%.*s' will be on line " HOST_SIZE_T_PRINT_UNSIGNED " (offset " HOST_SIZE_T_PRINT_UNSIGNED ")", __func__, __LINE__, @@ -345,7 +349,7 @@ check_source_format_directive( filespan_t& mfile ) { // show contents of marked subexpressions within each match cmatch cm; - if( regex_search(p, (const char *)mfile.eol, cm, re) ) { + if( regex_search(p, const_cast(mfile.eol), cm, re) ) { gcc_assert(cm.size() > 1); switch( cm[3].length() ) { case 4: @@ -459,9 +463,9 @@ struct replacing_term_t { bool matched, done; span_t leading_trailing, term, stmt; - replacing_term_t(const char input[]) : matched(false), done(false) { - stmt = span_t(input, input); - } + explicit replacing_term_t(const char input[]) + : matched(false), done(false), stmt(span_t(input, input)) + {} }; extern YYLTYPE yylloc; @@ -809,7 +813,7 @@ parse_replace_pairs( const char *stmt, const char *estmt, bool is_copy_stmt ) { } span_t& before(parsed.replace.before); - span_t& after(parsed.replace.after); + const span_t& after(parsed.replace.after); const char *befter[2] = { nonword_ch, nonword_ch }; gcc_assert(before.p < before.pend); @@ -877,7 +881,7 @@ struct copy_descr_t { }; static YYLTYPE -location_in( const filespan_t& mfile, const csub_match cm ) { +location_in( const filespan_t& mfile, const csub_match& cm ) { YYLTYPE loc { int(mfile.lineno() + 1), int(mfile.colno() + 1), int(mfile.lineno() + 1), int(mfile.colno() + 1) @@ -928,7 +932,7 @@ parse_copy_directive( filespan_t& mfile ) { copy_stmt.p = mfile.eodata; if( regex_search(mfile.ccur(), - (const char *)mfile.eodata, cm, re) ) { + const_cast(mfile.eodata), cm, re) ) { copy_stmt = span_t( cm[0].first, cm[0].second ); if( yy_flex_debug ) { size_t nnl = 1 + count_newlines(mfile.data, copy_stmt.p); @@ -981,7 +985,7 @@ parse_copy_directive( filespan_t& mfile ) { std::pair, char*> result = parse_replace_pairs( cm[0].second, mfile.eodata, true ); - std::list& replacements(result.first); + const std::list& replacements(result.first); outcome.parsed = (outcome.nreplace = replacements.size()) > 0; if( outcome.parsed ) { replace_directives.push(replacements); @@ -1008,7 +1012,7 @@ parse_copy_directive( filespan_t& mfile ) { } static char * -parse_replace_last_off( filespan_t& mfile ) { +parse_replace_last_off( const filespan_t& mfile ) { static const char pattern[] = "REPLACE" "[[:space:]]+" "(LAST[[:space:]]+)?OFF[[:space:]]*[.]" @@ -1018,7 +1022,7 @@ parse_replace_last_off( filespan_t& mfile ) { // REPLACE [LAST] OFF? bool found = regex_search(mfile.ccur(), - (const char *)mfile.eodata, cm, re); + const_cast(mfile.eodata), cm, re); gcc_assert(found); // caller ensures gcc_assert(cm.size() == 2); @@ -1073,7 +1077,7 @@ parse_replace_text( filespan_t& mfile ) { (fmt_size_t)current_lineno, len, mfile.cur); } - if( ! regex_search(mfile.ccur(), (const char *)mfile.eodata, cm, re) ) { + if( ! regex_search(mfile.ccur(), mfile.eodata, cm, re) ) { dbgmsg( "%s:%d: line " HOST_SIZE_T_PRINT_UNSIGNED ": not a REPLACE statement:\n'%.*s'", __func__, __LINE__, (fmt_size_t)current_lineno, @@ -1109,7 +1113,7 @@ parse_replace_text( filespan_t& mfile ) { std::pair, char*> result = parse_replace_pairs(replace_stmt.p, replace_stmt.pend, false); - std::list& replacements(result.first); + const std::list& replacements(result.first); replace_directives.push( replacements ); if( yy_flex_debug ) { @@ -1147,7 +1151,7 @@ parse_replace_directive( filespan_t& mfile ) { next_directive = mfile.eodata; if( regex_search(mfile.ccur(), - (const char *)mfile.eodata, cm, re) ) { + const_cast(mfile.eodata), cm, re) ) { gcc_assert(cm[1].matched); next_directive = cm[0].first; @@ -1491,7 +1495,7 @@ cdftext::lex_open( const char filename[] ) { argv[0] = filter; auto last_argv = std::transform( options.begin(), options.end(), argv.begin() + 1, - []( std::string& opt ) { + []( const std::string& opt ) { return xstrdup(opt.c_str()); } ); *last_argv = NULL; @@ -1556,9 +1560,9 @@ cdftext::open_input( const char filename[] ) { int cdftext::open_output() { char *name = getenv("GCOBOL_TEMPDIR"); - int fd; if( name && 0 != strcmp(name, "/") ) { + int fd; char * stem = xasprintf("%sXXXXXX", name); if( -1 == (fd = mkstemp(stem)) ) { cbl_err( "could not open temporary file '%s' (%s)", @@ -1685,7 +1689,7 @@ cdftext::free_form_reference_format( int input ) { size_t lineno; bytespan_t line; // construct with length zero - current_line_t( char data[] ) : lineno(0), line(data, data) {} + explicit current_line_t( char data[] ) : lineno(0), line(data, data) {} } current( mfile.data ); /* @@ -1825,7 +1829,6 @@ cdftext::free_form_reference_format( int input ) { void cdftext::process_file( filespan_t mfile, int output, bool second_pass ) { static size_t nfiles = 0; - std::list replacements; __gnu_cxx::stdio_filebuf outbuf(fdopen(output, "w"), std::ios::out); std::ostream out(&outbuf); @@ -1890,34 +1893,12 @@ cdftext::process_file( filespan_t mfile, int output, bool second_pass ) { continue; // No active REPLACE directive. } - std::list segments = segment_line(mfile); // no replace yields - // // 1 segment + // 1 segment for COPY, 2 for REPLACE + std::list segments = segment_line(mfile); for( const auto& segment : segments ) { std::copy(segment.p, segment.pend, ofs); } - - if( segments.size() == 2 ) { - struct { - size_t before, after; - int delta() const { return before - after; } } nlines; - nlines.before = std::count(segments.front().p, - segments.front().pend, '\n'); - nlines.after = std::count(segments.back().p, segments.back().pend, '\n'); - if( nlines.delta() < 0 ) { - yywarn("line %lu: REPLACED %lu lines with %lu lines, " - "line count off by %d", - gb4(mfile.lineno()), - gb4(nlines.before), - gb4(nlines.after), - nlines.delta()); - } - int nnl = nlines.delta(); - while( nnl-- > 0 ) { - static const char nl[] = "\n"; - std::copy(nl, nl + 1, ofs); - } - } out.flush(); } // end of file diff --git a/gcc/cobol/lexio.h b/gcc/cobol/lexio.h index a7d2b7283cc..96b365491ce 100644 --- a/gcc/cobol/lexio.h +++ b/gcc/cobol/lexio.h @@ -69,7 +69,9 @@ erase_source( char *src, char *esrc ) { struct bytespan_t { char *data, *eodata; - bytespan_t( char *data = NULL, char *eodata = NULL ) + bytespan_t() : data( nullptr), eodata(nullptr) {} + + bytespan_t( char *data, char *eodata ) : data(data), eodata(eodata) { if( eodata < data ) { @@ -124,7 +126,7 @@ struct filespan_t : public bytespan_t { {} filespan_t(void *p, size_t len) : bytespan_t( static_cast(p), static_cast(p) + len ) - , cur(data), eol(data), quote(NULL), iline(0), line_quote72(0) + , cur(data), eol(data), quote(NULL), iline(0), icol(0), line_quote72(0) {} size_t lineno() const { return iline; } @@ -224,6 +226,7 @@ struct span_t { span_t( const char *data, const char *eodata ) : p(data), pend(eodata) { verify(); } + // cppcheck-suppress operatorEqRetRefThis span_t& operator=( const csub_match& cm ) { p = cm.first; pend = cm.second; @@ -246,8 +249,8 @@ struct span_t { struct replace_t { struct span_t before, after; - replace_t( span_t before = span_t(), - span_t after = span_t() ) + replace_t() : before(span_t()), after(span_t()) {} + replace_t( span_t before, span_t after ) : before(before), after(after) {} replace_t& reset() { diff --git a/gcc/cobol/parse.y b/gcc/cobol/parse.y index 719b94dbdc7..3afa20ff5fd 100644 --- a/gcc/cobol/parse.y +++ b/gcc/cobol/parse.y @@ -188,14 +188,14 @@ data_category_t category; category_map_t replacement; - init_statement_t( category_map_t replacement ) + explicit init_statement_t( const category_map_t& replacement ) : to_value(false) , category(data_category_none) , replacement(replacement) {} - init_statement_t( bool to_value = false ) + explicit init_statement_t( bool to_value = false ) : to_value(to_value) , category(data_category_none) , replacement(category_map_t()) @@ -242,7 +242,7 @@ struct Elem_list_t { std::list elems; Elem_list_t() {} - Elem_list_t( E elem ) { + explicit Elem_list_t( E elem ) { elems.push_back(elem); } Elem_list_t * push_back( E elem ) { @@ -732,7 +732,7 @@ %type inspected %type insp_qual -%type insp_quals insp_mtquals tally_match +%type insp_quals insp_mtqual tally_match %type x_by_y %type replace_oper x_by_ys %type tally_forth tally_matches @@ -880,9 +880,9 @@ struct arith_t *arith; struct { size_t ntgt; cbl_num_result_t *tgts; cbl_refer_t *expr; } compute_body_t; - struct ast_inspect_t *insp_one; - struct ast_inspect_list_t *insp_all; - struct ast_inspect_oper_t *insp_oper; + struct cbl_inspect_t *insp_one; + cbl_inspect_opers_t *insp_all; + struct cbl_inspect_oper_t *insp_oper; struct { bool before; cbl_inspect_qual_t *qual; } insp_qual; cbl_inspect_t *inspect; cbl_inspect_match_t *insp_match; @@ -1320,7 +1320,7 @@ return ok; } - static void initialize_allocated( cbl_refer_t input ); + static void initialize_allocated( const cbl_refer_t& input ); static void initialize_statement( std::list& tgts, bool with_filler, @@ -1949,7 +1949,7 @@ select_clauses: select_clause { $$.clauses = $1.clause; $$.file = $1.file; } if( $$.file->nkey++ == 0 ) { // If no key yet exists, create room for it and the // present alternate. - assert($$.file->keys == &cbl_file_t::no_key); + assert($$.file->keys == nullptr); $$.file->keys = new cbl_file_key_t[++$$.file->nkey]; } { @@ -1961,8 +1961,7 @@ select_clauses: select_clause { $$.clauses = $1.clause; $$.file = $1.file; } // Assign the alternate key to the last element, // and update the pointer. *alt = $part.file->keys[0]; - delete[] $$.file->keys; - $$.file->keys = keys; + $$.file->keys_update(keys); } break; case assign_clause_e: @@ -2031,11 +2030,11 @@ select_clauses: select_clause { $$.clauses = $1.clause; $$.file = $1.file; } YYERROR; } if( $$.file->nkey == 0 ) { + assert( 1 == $part.file->nkey ); $$.file->nkey = $part.file->nkey; - $$.file->keys = $part.file->keys; - } else { - $$.file->keys[0] = $part.file->keys[0]; - } + $$.file->keys = new cbl_file_key_t[1]; + } + $$.file->keys[0] = $part.file->keys[0]; break; /* case password_clause_e: */ case file_status_clause_e: @@ -2391,7 +2390,7 @@ repo_program: PROGRAM_kw NAME repo_as assert(program); prog.data.initial = program->name; } - auto e = symbol_field_add(PROGRAM, &prog); + const auto e = symbol_field_add(PROGRAM, &prog); symbol_field_location(symbol_index(e), @NAME); } ; @@ -2593,7 +2592,8 @@ alphabet_seqs: alphabet_seq[seq] YYERROR; } $$->add_sequence(@seq, $seq.low); - size_t len = $seq.low == nul_string()? 1 : strlen((const char*)$seq.low); + size_t len = $seq.low == nul_string()? + 1 : strlen((const char*)$seq.low); assert(len > 0); $$->add_interval(@seq, $seq.low[--len], $seq.high[0]); $$->add_sequence(@seq, $seq.high); @@ -2652,11 +2652,13 @@ alphabet_etc: alphabet_lit $$ = (unsigned char)$1.data[0]; } | spaces_etc { - // For figurative constants, pass the synmbol table index, + // For figurative constants, pass the symbol table index, // marked with the high bit. static const auto bits = sizeof($$) * 8 - 1; - $$ = 1; - $$ = $$ << bits; + unsigned int high_bit = 1L << bits; + static_assert(sizeof($$) == sizeof(high_bit), + "adjust high_bit to match size of nonterminal target"); + memcpy(&$$, &high_bit, sizeof($$)); $$ |= constant_index($1); } ; @@ -2830,7 +2832,7 @@ domain: all LITERAL[a] if( ! string_of($value) ) { yywarn("'%s' has embedded NUL", $value.data); } - char *dom = $value.data; + const char *dom = $value.data; $$ = new cbl_domain_t(@value, false, $value.len, dom); } | when_set_to FALSE_kw is reserved_value @@ -3290,9 +3292,9 @@ index_field1: ctx_name[name] auto symbol = symbol_field(PROGRAM, field.parent, $name); if( symbol ) { - auto field( cbl_field_of(symbol) ); + auto f( cbl_field_of(symbol) ); error_msg(@name, "'%s' already defined on line %d", - field->name, field->line ); + f->name, f->line ); YYERROR; } @@ -3385,7 +3387,7 @@ value78: literalism } | reserved_value[value] { - auto field = constant_of(constant_index($value)); + const auto field = constant_of(constant_index($value)); $$ = new cbl_field_data_t(field->data); } @@ -3756,7 +3758,7 @@ data_descr1: level_name $field->report_invalid_initial_value(@data_clauses); // verify REDEFINES - auto parent = parent_of($field); + const auto parent = parent_of($field); if( parent && $field->level == parent->level ) { valid_redefine(@field, $field, parent); // calls yyerror } @@ -4698,7 +4700,7 @@ same_clause: SAME AS name YYERROR; } - auto e = symbol_field_same_as( field, other ); + const auto e = symbol_field_same_as( field, other ); symbol_field_location( symbol_index(e), @name ); } ; @@ -4747,7 +4749,7 @@ type_clause: TYPE to typename { cbl_field_t *field = current_field(); if( $typename ) { - auto e = symbol_field_same_as(field, $typename); + const auto e = symbol_field_same_as(field, $typename); symbol_field_location( symbol_index(e), @typename ); } } @@ -4759,7 +4761,7 @@ type_clause: TYPE to typename } cbl_field_t *field = current_field(); if( $typename ) { - auto e = symbol_field_same_as(field, $typename); + const auto e = symbol_field_same_as(field, $typename); symbol_field_location( symbol_index(e), @typename ); } } @@ -5401,16 +5403,13 @@ name88: NAME88 { scalar88: name88 subscripts[subs] refmod[ref] { - size_t n = $subs->size(); - auto subscripts = new cbl_refer_t[n]; - $subs->use_list(subscripts); if( $ref.from->is_reference() || $ref.len->is_reference() ) { error_msg(@subs, "subscripts on start:len refmod " "parameters are unsupported"); YYERROR; } cbl_span_t span( $ref.from, $ref.len ); - $$ = new cbl_refer_t($1, n, subscripts, span); + $$ = new cbl_refer_t($1, $subs->vectorize(), span); } | name88 refmod[ref] { @@ -5439,7 +5438,7 @@ allocate: ALLOCATE expr[size] CHARACTERS initialized RETURNING scalar[retu { statement_begin(@1, ALLOCATE); if( $size->field->type == FldLiteralN ) { - auto size = TREE_REAL_CST_PTR ($size->field->data.value_of()); + const auto size = TREE_REAL_CST_PTR ($size->field->data.value_of()); if( real_isneg(size) || real_iszero(size) ) { error_msg(@size, "size must be greater than 0"); YYERROR; @@ -5526,7 +5525,7 @@ display: disp_body end_display if( $1.vargs->args.size() != 1 ) { error_msg(@1, "ARGUMENT-NUMBER can be set to only one value"); } - cbl_refer_t& src( $1.vargs->args.front() ); + const cbl_refer_t& src( $1.vargs->args.front() ); cbl_field_t *dst = register_find("_ARGI"); parser_move( dst, src ); } else { @@ -5545,7 +5544,7 @@ display: disp_body end_display if( $1.vargs->args.size() != 1 ) { error_msg(@1, "ARGUMENT-NUMBER can be set to only one value"); } - cbl_refer_t& src( $1.vargs->args.front() ); + const cbl_refer_t& src( $1.vargs->args.front() ); cbl_field_t *dst = register_find("_ARGI"); parser_move( dst, src ); } else { @@ -5705,7 +5704,7 @@ end_program: end_program1[end] '.' } std::set externals = current.end_program(); if( !externals.empty() ) { - for( auto name : externals ) { + for( const auto& name : externals ) { yywarn("%s calls external symbol '%s'", prog->name, name.c_str()); } YYERROR; @@ -5800,7 +5799,7 @@ exit_with: %empty static cbl_refer_t status(rt); $$ = &status; } - auto prog = cbl_label_of(symbol_at(current_program_index())); + const auto prog = cbl_label_of(symbol_at(current_program_index())); if( prog->returning ) { $$ = new cbl_refer_t( cbl_field_of(symbol_at(prog->returning)) ); } @@ -6489,7 +6488,7 @@ true_false: TRUE_kw { $$ = TRUE_kw; } scalar: tableref { // Check for missing subscript; others already checked. - if( $1->nsubscript == 0 && 0 < dimensions($1->field) ) { + if( $1->nsubscript() == 0 && 0 < dimensions($1->field) ) { subscript_dimension_error(@1, 0, $$); } } @@ -6500,8 +6499,8 @@ tableref: tableish { $$ = $1; $$->loc = @1; if( $$->is_table_reference() ) { - if( $$->nsubscript != dimensions($$->field) ) { - subscript_dimension_error(@1, $$->nsubscript, $$); + if( $$->nsubscript() != dimensions($$->field) ) { + subscript_dimension_error(@1, $$->nsubscript(), $$); YYERROR; } } @@ -7173,7 +7172,7 @@ section_kw: SECTION } else { if( dialect_ibm() ) { int sectno; - sscanf($1, "%u", §no); + sscanf($1, "%d", §no); if( ! (0 <= sectno && sectno <= 99) ) { error_msg(@1, "SECTION segment %<%s%> must be 0-99", $1); } else { @@ -7593,7 +7592,7 @@ perform_when1: WHEN perform_ec { std::transform( $perform_ec->elems.begin(), $perform_ec->elems.end(), std::back_inserter(perf->dcls), - []( cbl_declarative_t *p ) { + []( const cbl_declarative_t *p ) { return *p; } ); ast_enter_paragraph(when); @@ -7683,12 +7682,12 @@ except_files: except_name[ec] FILE_KW filenames { perform_ec_other: %empty %prec WHEN { - auto& ec_labels( perform_current()->ec_labels ); + const auto& ec_labels( perform_current()->ec_labels ); ast_enter_paragraph(ec_labels.other); parser_exit_paragraph(); } | WHEN OTHER { - auto& ec_labels( perform_current()->ec_labels ); + const auto& ec_labels( perform_current()->ec_labels ); ast_enter_paragraph(ec_labels.other); } exception statements %prec WHEN { @@ -7697,12 +7696,12 @@ perform_ec_other: ; perform_ec_common: %empty { - auto& ec_labels( perform_current()->ec_labels ); + const auto& ec_labels( perform_current()->ec_labels ); ast_enter_paragraph(ec_labels.common); parser_exit_paragraph(); } | WHEN COMMON { - auto& ec_labels( perform_current()->ec_labels ); + const auto& ec_labels( perform_current()->ec_labels ); ast_enter_paragraph(ec_labels.common); } exception statements { @@ -7711,18 +7710,18 @@ perform_ec_common: ; perform_ec_finally: %empty { - auto& ec_labels( perform_current()->ec_labels ); + const auto& ec_labels( perform_current()->ec_labels ); ast_enter_paragraph(ec_labels.finally); parser_exit_paragraph(); parser_label_goto(ec_labels.fini); } | FINALLY { - auto& ec_labels( perform_current()->ec_labels ); + const auto& ec_labels( perform_current()->ec_labels ); ast_enter_paragraph(ec_labels.finally); } exception statements { parser_exit_paragraph(); - auto& ec_labels( perform_current()->ec_labels ); + const auto& ec_labels( perform_current()->ec_labels ); parser_label_goto(ec_labels.fini); } ; @@ -8000,10 +7999,6 @@ read_body: NAME read_next read_into read_key error_msg(@1, "syntax error? invalid file record name"); YYERROR; } - if( 0 && $$->access == file_access_dyn_e && $read_next >= 0 ) { - error_msg(@1, "sequential DYNAMIC access requires NEXT RECORD"); - YYERROR; - } if( $read_key->field && is_sequential($$) ) { error_msg(@1, "SEQUENTIAL file %s has no KEY", $$->name); YYERROR; @@ -8451,8 +8446,8 @@ merge: MERGE { statement_begin(@1, MERGE); } USING filenames[inputs] sort_output { std::vector keys($sort_keys->key_list.size()); - std::copy( $sort_keys->key_list.begin(), - $sort_keys->key_list.end(), keys.begin() ); + std::copy( $sort_keys->key_list.begin(), + $sort_keys->key_list.end(), keys.begin() ); size_t ninput = $inputs->files.size(); size_t noutput = $sort_output->nfile(); @@ -8471,8 +8466,7 @@ merge: MERGE { statement_begin(@1, MERGE); } out_proc = &$sort_output->tgt; } - parser_file_merge( $file, $sort_seq, - keys.size(), keys.empty()? NULL : keys.data(), + parser_file_merge( $file, $sort_seq, keys, ninput, inputs, noutput, outputs, out_proc ); @@ -8638,7 +8632,7 @@ set: SET set_tgts[tgts] TO set_operand[src] class set_conditional { bool tf; public: - set_conditional( int token ) : tf(token == TRUE_kw) {} + explicit set_conditional( int token ) : tf(token == TRUE_kw) {} void operator()(cbl_refer_t& refer) { if( refer.field->data.false_value_of() == NULL && !tf ) { auto loc = symbol_field_location(field_index(refer.field)); @@ -8663,7 +8657,7 @@ set_switches: switches TO on_off { struct switcheroo { bitop_t op; - switcheroo( bool tf ) : op( tf? bit_set_op : bit_clear_op ) {} + explicit switcheroo( bool tf ) : op( tf? bit_set_op : bit_clear_op ) {} switcheroo& operator()(cbl_field_t* sw) { assert(sw->type == FldSwitch); assert(sw->data.initial); // not a switch condition @@ -8803,14 +8797,14 @@ search_terms: search_term ; search_term: scalar[key] '=' search_expr[sarg] { - if( $key->nsubscript == 0 ) { + if( $key->nsubscript() == 0 ) { error_msg(@1, "no index for key"); YYERROR; } - if( dimensions($key->field) < $key->nsubscript ) { + if( dimensions($key->field) < $key->nsubscript() ) { error_msg(@1, "too many subscripts: " "%zu for table of %zu dimensions", - $key->nsubscript, dimensions($key->field) ); + $key->nsubscript(), dimensions($key->field) ); YYERROR; } @@ -8849,8 +8843,7 @@ sort_table: SORT tableref[table] sort_keys sort_dup sort_seq { keys.at(i++) = cbl_key_t(k); } - parser_sort( *$table, $sort_dup, $sort_seq, - keys.size(), keys.empty()? NULL : keys.data() ); + parser_sort( *$table, $sort_dup, $sort_seq, keys ); } | SORT tableref[table] sort_dup sort_seq { statement_begin(@1, SORT); @@ -8860,9 +8853,10 @@ sort_table: SORT tableref[table] sort_keys sort_dup sort_seq { cbl_key_t key = cbl_key_t($table->field->occurs.keys[0]), guess(1, &$table->field); - ; - if( key.nfield == 0 ) key = guess; - parser_sort( *$table, $sort_dup, $sort_seq, 1, &key ); + + if( key.fields.empty() ) key = guess; + std::vector keys(1, key); + parser_sort( *$table, $sort_dup, $sort_seq, keys ); } ; @@ -8903,7 +8897,7 @@ sort_file: SORT FILENAME[file] sort_keys sort_dup sort_seq parser_file_sort( file, $sort_dup, $sort_seq, - keys.size(), keys.empty()? NULL : keys.data(), + keys, ninput, inputs, noutput, outputs, in_proc, out_proc ); @@ -9095,7 +9089,7 @@ backward: %empty { $$ = false; } inspect: INSPECT backward inspected TALLYING tallies { statement_begin(@1, INSPECT); - ast_inspect( *$inspected, $backward, *$tallies ); + ast_inspect( @$, *$inspected, $backward, *$tallies ); } | INSPECT backward inspected TALLYING tallies REPLACING replacements { @@ -9107,8 +9101,8 @@ inspect: INSPECT backward inspected TALLYING tallies } statement_begin(@1, INSPECT); // All tallying is done before any replacing - ast_inspect( *$inspected, $backward, *$tallies ); - ast_inspect( *$inspected, $backward, *$replacements ); + ast_inspect( @$, *$inspected, $backward, *$tallies ); + ast_inspect( @$, *$inspected, $backward, *$replacements ); } | INSPECT backward inspected REPLACING replacements { @@ -9119,11 +9113,11 @@ inspect: INSPECT backward inspected TALLYING tallies YYERROR; } statement_begin(@1, INSPECT); - ast_inspect( *$inspected, $backward, *$replacements ); + ast_inspect( @$, *$inspected, $backward, *$replacements ); } | INSPECT backward inspected CONVERTING alpha_val[match] TO all alpha_val[replace_oper] - insp_mtquals[qual] + insp_mtqual[qual] { if( $all ) { $replace_oper->all = true; @@ -9169,7 +9163,7 @@ inspect: INSPECT backward inspected TALLYING tallies tallies: { need_nume_set(); } tally { - $$ = new ast_inspect_list_t( *$tally ); + $$ = new cbl_inspect_opers_t( 1, *$tally ); } | tallies { need_nume_set(); } tally { @@ -9179,12 +9173,17 @@ tallies: { need_nume_set(); } tally if( !next.tally.field ) { // prior tally swallowed one too many cbl_inspect_t& prior = $$->back(); - assert(prior.nbound > 0); - assert(prior.opers); - cbl_inspect_oper_t& prior_op = prior.opers[prior.nbound - 1]; - - assert(prior_op.n_identifier_3 > 0 ); - next.tally = prior_op.matches[--prior_op.n_identifier_3].matching; + assert(prior.nbound() > 0); + cbl_inspect_oper_t& prior_op = prior.back(); + assert(! prior_op.matches.empty() ); + assert(prior_op.n_identifier_3() > 0 ); + cbl_inspect_match_t wrong_match = prior_op.matches.back(); + dbgmsg("moving overeager tally to next clause"); + dump_inspect_match(wrong_match); + next.tally = wrong_match.premature_tally(); + if( wrong_match.empty() ) { + prior_op.matches.pop_back(); + } } if( !next.tally.field ) { error_msg(@$, "missing summation field before FOR"); @@ -9196,44 +9195,37 @@ tallies: { need_nume_set(); } tally /* * numref might be "empty" only because it was consumed by a - * prior insp_mtquals, which can end in a scalar. If that + * prior insp_mtqual, which can end in a scalar. If that * happens, the tallies target, above, takes back the borrowed * scalar and assigns it to be the tally total, as the user * intended. */ tally: numeref[total] FOR tally_fors[fors] - { // reduce ast_inspect_t to cbl_inspect_t + { if( yydebug && !$total ) { - error_msg(@FOR, "caution: missing summation field before FOR"); + dbgmsg("tally: caution: missing summation field before FOR"); } - cbl_refer_t total( $total? *$total : cbl_refer_t() ); - $$ = new cbl_inspect_t( total, $fors->opers() ); + $$ = $fors; + if( $total ) $$->tally = *$total; } ; -tally_fors: tally_forth - { // reduce ast_inspect_oper_t to cbl_inspect_oper_t - cbl_inspect_oper_t oper( $1->bound, $1->matches ); - $$ = new ast_inspect_t; - $$ ->push_back(oper); - } - | tally_fors tally_forth - { - cbl_inspect_oper_t oper( $2->bound, $2->matches ); - $1 ->push_back(oper); - } +tally_fors: tally_forth { $$ = new cbl_inspect_t(1, *$1); } + | tally_fors tally_forth { $$->push_back(*$2); $$ = $1; } ; -tally_forth: CHARACTERS insp_mtquals[q] scalar[next_tally] +tally_forth: CHARACTERS insp_mtqual[q] scalar[next_tally] { // Add ensuing scalar as if it were an argument to CHARACTERS. // It will be moved to the succeeding FOR as its tally. - $q->matching = *$next_tally; - $$ = new ast_inspect_oper_t(*$q); + dbgmsg("saving overeager tally for next clause"); + $q->save_premature_tally(*$next_tally); + $$ = new cbl_inspect_oper_t(*$q); + dump_inspect_match($$->matches.back()); } - | CHARACTERS insp_mtquals[q] + | CHARACTERS insp_mtqual[q] { - $$ = new ast_inspect_oper_t(*$q); + $$ = new cbl_inspect_oper_t(*$q); } | ALL tally_matches[q] { $q->bound = bound_all_e; @@ -9252,26 +9244,23 @@ tally_forth: CHARACTERS insp_mtquals[q] scalar[next_tally] } ; -tally_matches: tally_match { $$ = new ast_inspect_oper_t(*$1); } +tally_matches: tally_match { $$ = new cbl_inspect_oper_t(*$1); } | tally_matches tally_match { // add to the list of matches for an operand $1->matches.push_back(*$2); } ; -tally_match: alpha_val[matching] insp_mtquals[q] +tally_match: alpha_val[matching] insp_mtqual[q] { // include the matching field with the qualifiers $$ = $q; - $$->matching = *$matching; + $$->matching(*$matching); } ; numeref: %empty { $$ = NULL; need_nume_set(false); } | nume[name] subscripts[subs] { - size_t n = $subs->size(); - auto offsets = new cbl_refer_t[n]; - std::copy( $subs->begin(), $subs->end(), offsets ); - $$ = new cbl_refer_t($name, n, offsets); + $$ = new cbl_refer_t($name, $subs->vectorize()); } | nume { $$ = new cbl_refer_t($nume); } ; @@ -9301,13 +9290,13 @@ qnume: NUME { name_queue.qualify(@1, $1); } replacements: replacement { - cbl_inspect_t inspect( cbl_refer_t(), $1->opers() ); - $$ = new ast_inspect_list_t(inspect); + cbl_inspect_t inspect( cbl_refer_t(), *$1 ); + $$ = new cbl_inspect_opers_t(1, inspect); } ; replacement: replace_oper { - $$ = new ast_inspect_t; + $$ = new cbl_inspect_t; $$->push_back( cbl_inspect_oper_t($1->bound, $1->replaces) ); } | replacement replace_oper @@ -9315,9 +9304,9 @@ replacement: replace_oper $$->push_back( cbl_inspect_oper_t($2->bound, $2->replaces) ); } ; -replace_oper: CHARACTERS BY alpha_val[replace] insp_mtquals[q] +replace_oper: CHARACTERS BY alpha_val[replace] insp_mtqual[q] { - $$ = new ast_inspect_oper_t( cbl_inspect_replace_t(NULL, + $$ = new cbl_inspect_oper_t( cbl_inspect_replace_t(NULL, *$replace, $q->before, $q->after) ); @@ -9331,21 +9320,22 @@ replace_oper: CHARACTERS BY alpha_val[replace] insp_mtquals[q] x_by_ys: x_by_y { - $$ = new ast_inspect_oper_t(*$1); + $$ = new cbl_inspect_oper_t(*$1); } | x_by_ys x_by_y { $$->replaces.push_back(*$2); } ; -x_by_y: alpha_val[matching] BY alpha_val[replace] insp_mtquals[q] +x_by_y: alpha_val[matching] BY alpha_val[replace] insp_mtqual[q] { $$ = new cbl_inspect_replace_t(*$matching, *$replace, $q->before, $q->after); } ; -insp_mtquals: %empty { $$ = new cbl_inspect_match_t; } + /* mt may be "empty": match may have no qualifiers */ +insp_mtqual: %empty { $$ = new cbl_inspect_match_t; } | insp_quals ; insp_quals: insp_qual { @@ -9355,6 +9345,7 @@ insp_quals: insp_qual { } else { $$->after = *$insp_qual.qual; } + dump_inspect_match(*$$); } | insp_quals insp_qual { @@ -9774,7 +9765,7 @@ alter_tgt: label_1[old] alter_to label_1[new] cbl_perform_tgt_t tgt( $old, $new ); parser_alter(&tgt); - auto prog = cbl_label_of( symbol_at(symbol_elem_of($old)->program)); + const auto prog = cbl_label_of( symbol_at(symbol_elem_of($old)->program)); if( prog->initial ) { cbl_unimplemented("ALTER %s", $old->name); } @@ -10172,7 +10163,7 @@ function_udf: FUNCTION_UDF '(' arg_list[args] ')' { size_t i = 0; // Pass parameters as defined by the function. std::transform( $args->refers.begin(), $args->refers.end(), args.begin(), - [params, &i]( cbl_refer_t& arg ) { + [params, &i]( const cbl_refer_t& arg ) { function_descr_arg_t param = params.at(i++); auto ar = new cbl_refer_t(arg); cbl_ffi_arg_t actual(param.crv, ar); @@ -11315,7 +11306,7 @@ first_line_of( YYLTYPE loc ) { return loc; } -void ast_call( const YYLTYPE& loc, cbl_refer_t name, cbl_refer_t returning, +void ast_call( const YYLTYPE& loc, cbl_refer_t name, const cbl_refer_t& returning, size_t narg, cbl_ffi_arg_t args[], cbl_label_t *except, cbl_label_t *not_except, @@ -11407,7 +11398,7 @@ statement_begin( const YYLTYPE& loc, int token ) { struct string_match { const char *name; - string_match( const char name[] ) : name(name) {} + explicit string_match( const char name[] ) : name(name) {} bool operator()( const char input[] ) const { return strlen(name) == strlen(input) && 0 == strcasecmp(name, input); } @@ -11415,9 +11406,13 @@ struct string_match { const char * keyword_str( int token ) { - if( token == YYEOF ) return "YYEOF"; - if( token == YYEMPTY ) return "YYEMPTY"; - + switch( token ) { + case YYEOF: return "YYEOF"; + case YYEMPTY: return "YYEMPTY"; + case YYerror: return "YYerror"; + case YYUNDEF: return "invalid token"; + } + if( token < 256 ) { static char ascii[2]; ascii[0] = token; @@ -11461,9 +11456,9 @@ tokenset_t::find( const cbl_name_t name, bool include_intrinsics ) { if( dialect_ibm() ) { static const cbl_name_t ibm_non_names[] = { "RESUME", - }, * const eonames = ibm_non_names + COUNT_OF(ibm_non_names); + }, * const eoibm = ibm_non_names + COUNT_OF(ibm_non_names); - if( std::any_of(ibm_non_names, eonames, + if( std::any_of(ibm_non_names, eoibm, [candidate=name](const cbl_name_t non_name) { return 0 == strcasecmp(non_name, candidate) && strlen(non_name) == strlen(candidate); @@ -11500,7 +11495,7 @@ keyword_tok( const char * text, bool include_intrinsics ) { static inline size_t verify_figconst( enum cbl_figconst_t figconst , size_t pos ) { - cbl_field_t *f = cbl_field_of(symbol_at(pos)); + const cbl_field_t *f = cbl_field_of(symbol_at(pos)); assert((f->attr & FIGCONST_MASK) == figconst); return pos; } @@ -11792,7 +11787,7 @@ current_t::udf_update( const ffi_args_t *ffi_args ) { if( ! ffi_args ) return; assert(ffi_args->elems.size() < sizeof(function_descr_t::types)); - auto returning = cbl_field_of(symbol_at(L->returning)); + const auto returning = cbl_field_of(symbol_at(L->returning)); auto key = function_descr_t::init(L->name); auto func = udfs.find(key); assert(func != udfs.end()); @@ -11834,7 +11829,7 @@ current_t::udf_args_valid( const cbl_label_t *L, } size_t i = 0; - for( cbl_refer_t arg : args ) { + for( const cbl_refer_t& arg : args ) { if( arg.field ) { // else omitted auto tgt = cbl_field_of(symbol_at(udf.linkage_fields.at(i).isym)); if( ! valid_move(tgt, arg.field) ) { @@ -11891,7 +11886,7 @@ function_descr_t function_descr_t::init( int isym ) { function_descr_t descr = { FUNCTION_UDF_0 }; descr.ret_type = FldInvalid; - auto L = cbl_label_of(symbol_at(isym)); + const auto L = cbl_label_of(symbol_at(isym)); bool ok = namcpy(YYLTYPE(), descr.name, L->name); gcc_assert(ok); return descr; @@ -11905,16 +11900,16 @@ arith_t::arith_t( cbl_arith_format_t format, refer_list_t * refers ) delete refers; } - -cbl_key_t::cbl_key_t( const sort_key_t& that ) +cbl_key_t::cbl_key_t( sort_key_t that ) : ascending(that.ascending) - , nfield(that.fields.size()) - , fields(NULL) -{ - if( nfield > 0 ) { - fields = new cbl_field_t* [nfield]; - std::copy(that.fields.begin(), that.fields.end(), fields); - } + , fields( that.fields.begin(), that.fields.end() ) +{} + +cbl_key_t& +cbl_key_t::operator=( const sort_key_t& that ) { + ascending = that.ascending; + fields = that.as_vector(); + return *this; } static cbl_refer_t * @@ -12020,10 +12015,10 @@ ast_divide( arith_t *arith ) { * the convenience of the parser. */ struct stringify_src_t : public cbl_string_src_t { - stringify_src_t( const refer_marked_list_t& marked = refer_marked_list_t() ) - : cbl_string_src_t( marked.marker? *marked.marker : null_reference, - marked.refers.size(), - new cbl_refer_t[marked.refers.size()] ) + stringify_src_t( const refer_marked_list_t& marked = refer_marked_list_t() ) + : cbl_string_src_t( marked.marker? *marked.marker : null_reference, + marked.refers.size(), + new cbl_refer_t[marked.refers.size()] ) { std::copy( marked.refers.begin(), marked.refers.end(), inputs ); } @@ -12043,7 +12038,7 @@ struct stringify_src_t : public cbl_string_src_t { void stringify( refer_collection_t *inputs, - cbl_refer_t into, cbl_refer_t pointer, + const cbl_refer_t& into, const cbl_refer_t& pointer, cbl_label_t *on_error, cbl_label_t *not_error ) { @@ -12058,7 +12053,7 @@ stringify( refer_collection_t *inputs, } void -unstringify( cbl_refer_t& src, +unstringify( const cbl_refer_t& src, refer_list_t *delimited, unstring_into_t * into, cbl_label_t *on_error, @@ -12066,6 +12061,7 @@ unstringify( cbl_refer_t& src, { size_t ndelimited = delimited? delimited->size() : 0; cbl_refer_t *pdelimited = NULL; + // cppcheck-suppress [variableScope] pdelimited points to delimiteds.data() std::vector delimiteds(ndelimited); if( ndelimited > 0 ) { pdelimited = use_any( delimited->refers, delimiteds ); @@ -12177,15 +12173,19 @@ lang_check_failed (const char* file, int line, const char* function) {} #pragma GCC diagnostic pop -void ast_inspect( cbl_refer_t& input, bool backward, ast_inspect_list_t& inspects ) { +void +ast_inspect( YYLTYPE loc, cbl_refer_t& input, bool backward, + cbl_inspect_opers_t& inspects ) +{ if( yydebug ) { - dbgmsg("%s:%d: INSPECT " HOST_SIZE_T_PRINT_UNSIGNED " operations on %s, line %d", - __func__, __LINE__, (fmt_size_t)inspects.size(), input.field->name, yylineno); + dbgmsg("%s:%d: INSPECT " HOST_SIZE_T_PRINT_UNSIGNED " operations on %s, " + "lines %d:%d - %d:%d", + __func__, __LINE__, + (fmt_size_t)inspects.size(), input.field->name, + loc.first_line, loc.first_column, loc.last_line, loc.last_column ); } std::for_each(inspects.begin(), inspects.end(), dump_inspect); - auto array = inspects.as_array(); - parser_inspect( input, backward, inspects.size(), array ); - delete[] array; + parser_inspect( input, backward, inspects ); } static const char * @@ -12197,28 +12197,29 @@ cbl_refer_str( char output[], const cbl_refer_t& R ) { return output; } -static void +void dump_inspect_match( const cbl_inspect_match_t& M ) { - static char fields[3][4 * 64]; - cbl_refer_str(fields[0], M.matching); - cbl_refer_str(fields[1], M.before.identifier_4); - cbl_refer_str(fields[2], M.after.identifier_4); - - yywarn( "matching %s \n\t\tbefore %s%s \n\t\tafter %s%s", - fields[0], - M.before.initial? "initial " : "", fields[1], - M.after.initial? "initial " : "", fields[2] ); + static char fields[4][4 * 64]; + cbl_refer_str(fields[0], M.match); + cbl_refer_str(fields[1], M.tally); + cbl_refer_str(fields[2], M.before.identifier_4); + cbl_refer_str(fields[3], M.after.identifier_4); + + dbgmsg( "matching %s [tally %s]\n\t\tbefore %s%s \n\t\tafter %s%s", + fields[0], fields[1], + M.before.initial? "initial " : "", fields[2], + M.after.initial? "initial " : "", fields[3] ); } static void dump_inspect_replace( const cbl_inspect_replace_t& R ) { static char fields[4][4 * 64]; - cbl_refer_str(fields[0], R.matching); + cbl_refer_str(fields[0], R.matching()); cbl_refer_str(fields[1], R.before.identifier_4); cbl_refer_str(fields[2], R.after.identifier_4); cbl_refer_str(fields[3], R.replacement); - yywarn( "matching %s \n\treplacement %s\n\t\tbefore %s%s \n\t\tafter %s%s", + dbgmsg( "matching %s \n\treplacement %s\n\t\tbefore %s%s \n\t\tafter %s%s", fields[0], fields[3], R.before.initial? "initial " : "", fields[1], R.after.initial? "initial " : "", fields[2] ); @@ -12334,7 +12335,7 @@ numstr2i( const char input[], radix_t radix ) { break; case hexadecimal_e: erc = sscanf(input, "%" GCC_PRISZ "x", &integerf); - integer = integer; + integer = integerf; real_from_integer (&output, VOIDmode, integer, UNSIGNED); break; case boolean_e: @@ -12384,7 +12385,7 @@ new_literal( const char initial[], enum radix_t radix ) { class is_elementary_type { // for INITIALIZE purposes bool with_filler; public: - is_elementary_type( bool with_filler ) : with_filler(with_filler) {} + explicit is_elementary_type( bool with_filler ) : with_filler(with_filler) {} bool operator()( const symbol_elem_t& elem ) const { if( elem.type != SymField ) return false; @@ -12398,7 +12399,7 @@ public: size_t end_of_group( size_t igroup ); static std::list -symbol_group_data_members( cbl_refer_t refer, bool with_filler ) { +symbol_group_data_members( const cbl_refer_t& refer, bool with_filler ) { std::list refers; refers.push_front( refer ); @@ -12406,7 +12407,7 @@ symbol_group_data_members( cbl_refer_t refer, bool with_filler ) { class refer_of : public cbl_refer_t { public: - refer_of( const cbl_refer_t& refer ) : cbl_refer_t(refer) {} + explicit refer_of( const cbl_refer_t& refer ) : cbl_refer_t(refer) {} cbl_refer_t operator()( symbol_elem_t& elem ) { this->field = cbl_field_of(&elem); // preserve subscript/refmod return *this; @@ -12430,7 +12431,7 @@ struct expand_group : public std::list { return cbl_refer_t(field); } bool with_filler; - expand_group( bool with_filler ) : with_filler(with_filler) {} + explicit expand_group( bool with_filler ) : with_filler(with_filler) {} void operator()( const cbl_refer_t& refer ) { assert(refer.field); @@ -12456,7 +12457,7 @@ wsclear( char ch ) { } static void -initialize_allocated( cbl_refer_t input ) { +initialize_allocated( const cbl_refer_t& input ) { cbl_num_result_t result = { truncation_e, input }; std::list results; results.push_back(result); @@ -12465,13 +12466,14 @@ initialize_allocated( cbl_refer_t input ) { } static int -initialize_with( cbl_refer_t tgt ) { +initialize_with( const cbl_refer_t& tgt ) { if( tgt.field->type == FldPointer ) return ZERO; if( tgt.is_refmod_reference() ) return SPACES; return is_numeric(tgt.field)? ZERO : SPACES; } static bool +// cppcheck-suppress [passedByValue] target.refer.field is modified initialize_one( cbl_num_result_t target, bool with_filler, data_category_t value_category, const category_map_t& replacements, @@ -12541,11 +12543,11 @@ typedef std::pair cbl_bytespan_t; * After the 1st record is initialized, copy it to the others. */ static bool -initialize_table( cbl_num_result_t target, +initialize_table( const cbl_num_result_t& target, size_t nspan, const cbl_bytespan_t spans[], const std::list& subtables ) { - assert( target.refer.nsubscript == dimensions(target.refer.field) ); + assert( target.refer.nsubscript() == dimensions(target.refer.field) ); const cbl_refer_t& src( target.refer ); size_t n( src.field->occurs.ntimes()); assert( 0 < n ); @@ -12561,17 +12563,17 @@ static cbl_refer_t synthesize_table_refer( cbl_refer_t tgt ) { // For a table, use supplied subscripts or start with 1. auto ndim( dimensions(tgt.field) ); - if( tgt.nsubscript < ndim ) { // it's an incomplete table + if( tgt.nsubscript() < ndim ) { // it's an incomplete table std::vector subscripts(ndim); for( size_t i=0; i < ndim; i++ ) { - if( i < tgt.nsubscript ) { + if( i < tgt.nsubscript() ) { subscripts[i] = tgt.subscripts[i]; continue; } subscripts[i].field = new_tempnumeric(); parser_set_numeric(subscripts[i].field, 1); } - return cbl_refer_t( tgt.field, subscripts.size(), subscripts.data() ); + return cbl_refer_t( tgt.field, subscripts ); } return tgt; } @@ -12581,7 +12583,7 @@ group_offset( const cbl_field_t *field ) { if( field->parent ) { auto e = symbol_at(field->parent); if( e->type == SymField ) { - auto parent = cbl_field_of(e); + const auto parent = cbl_field_of(e); return field->offset - parent->offset; } } @@ -12595,7 +12597,7 @@ initialize_statement( const cbl_num_result_t& target, bool with_filler, size_t depth = 0 ) { const cbl_refer_t& tgt( target.refer ); - assert(dimensions(tgt.field) == tgt.nsubscript || 0 < depth); + assert(dimensions(tgt.field) == tgt.nsubscript() || 0 < depth); assert(!is_literal(tgt.field)); if( tgt.field->type == FldGroup ) { @@ -12632,7 +12634,7 @@ initialize_statement( const cbl_num_result_t& target, bool with_filler, if( fOK && is_table(tgt.field) ) { cbl_num_result_t output = { target.rounded, synthesize_table_refer(tgt) }; - if( tgt.nsubscript < output.refer.nsubscript ) { // tgt is whole table + if( tgt.nsubscript() < output.refer.nsubscript() ) { // tgt is whole table std::list field_spans; static const field_span_t empty_span = { NULL, NULL }; field_span_t span = empty_span; @@ -12743,17 +12745,7 @@ static void initialize_statement( std::list& tgts, bool with_filler, data_category_t value_category, const category_map_t& replacements) { - - bool is_refmod = std::any_of( tgts.begin(), tgts.end(), - []( const auto& tgt ) { - return tgt.refer.is_refmod_reference(); - } ); - if( false && is_refmod ) { // refmod seems valid per ISO - dbgmsg("INITIALIZE cannot initialize a refmod"); - return; - } - - for( auto tgt : tgts ) { + for( const auto& tgt : tgts ) { initialize_statement( tgt, with_filler, value_category, replacements ); } @@ -12764,13 +12756,11 @@ static void dump_inspect_oper( const cbl_inspect_oper_t& op ) { dbgmsg("\t%s: " HOST_SIZE_T_PRINT_UNSIGNED " \"matches\", " HOST_SIZE_T_PRINT_UNSIGNED " \"replaces\"", - bound_str(op.bound), - op.matches? (fmt_size_t)op.n_identifier_3 : 0, - op.replaces? (fmt_size_t)op.n_identifier_3 : 0); - if( op.matches ) - std::for_each(op.matches, op.matches + op.n_identifier_3, dump_inspect_match); - if( op.replaces ) - std::for_each(op.replaces, op.replaces + op.n_identifier_3, dump_inspect_replace); + bound_str(op.bound), + (fmt_size_t)op.matches.size(), + (fmt_size_t)op.replaces.size()); + std::for_each(op.matches.begin(), op.matches.end(), dump_inspect_match); + std::for_each(op.replaces.begin(), op.replaces.end(), dump_inspect_replace); } #pragma GCC diagnostic push @@ -12787,14 +12777,14 @@ dump_inspect( const cbl_inspect_t& I ) { } else { fprintf( stderr, "\tREPLACING:\n" ); } - std::for_each( I.opers, I.opers + I.nbound, dump_inspect_oper ); + std::for_each( I.begin(), I.end(), dump_inspect_oper ); } #pragma GCC diagnostic pop #include struct declarative_file_list_t : protected cbl_declarative_t { - declarative_file_list_t( const cbl_declarative_t& d ) + explicit declarative_file_list_t( const cbl_declarative_t& d ) : cbl_declarative_t(d) { if( nfile > 0 ) @@ -12819,7 +12809,7 @@ operator<<( std::ostream& os, const declarative_file_list_t& dcl ) { static declarative_file_list_t file_list_of( const cbl_declarative_t& dcl ) { - return dcl; + return declarative_file_list_t(dcl); } std::ostream& @@ -12891,7 +12881,7 @@ cbl_file_t::validate_key( const cbl_file_key_t& key ) const { bool cbl_file_t::validate() const { - size_t members[] = { user_status, vsam_status, record_length }; + const size_t members[] = { user_status, vsam_status, record_length }; bool tf = true; for( auto isym : members ) { @@ -13102,7 +13092,7 @@ literal_refmod_valid( YYLTYPE loc, const cbl_refer_t& r ) { if( --edge < r.field->data.capacity ) return true; } // len < 0 or not: 0 < from + len <= capacity - auto loc = symbol_field_location(field_index(r.field)); + loc = symbol_field_location(field_index(r.field)); error_msg(loc, "%s(%zu:%zu) out of bounds, " "size is %u", r.field->name, @@ -13125,19 +13115,22 @@ literal_subscript_oob( const cbl_refer_t& r, size_t& isub ); static bool literal_subscripts_valid( YYLTYPE loc, const cbl_refer_t& name ) { - static char subs[ 7 * 32 ], *esub = subs + sizeof(subs); - char *p = subs; size_t isub; - // Find subscript in the supplied refer + // Report any out-of-bound subscript. const cbl_field_t *oob = literal_subscript_oob(name, isub); if( oob ) { - const char *sep = ""; - for( auto r = name.subscripts; r < name.subscripts + name.nsubscript; r++ ) { - snprintf( p, esub - p, "%s%s", sep, nice_name_of(r->field) ); - sep = " "; - } - + std::string sep(""); + std::string subscript_names = + std::accumulate( name.subscripts.begin(), + name.subscripts.end(), + std::string(), + [&sep]( std::string acc, const auto& sub ) { + acc += sep; + sep = " "; + return acc + nice_name_of(sub.field); + } ); + const char *upper_phrase = ""; if( ! oob->occurs.bounds.fixed_size() ) { static char ub[32] = "boo"; @@ -13149,7 +13142,7 @@ literal_subscripts_valid( YYLTYPE loc, const cbl_refer_t& name ) { // X(0): subscript 1 of for out of range for 02 X OCCURS 4 to 6 error_msg(loc, "%s(%s): subscript %zu out of range " "for %s %s OCCURS %lu%s", - oob->name, subs, 1 + isub, + oob->name, subscript_names.c_str(), 1 + isub, oob->level_str(), oob->name, oob->occurs.bounds.lower, upper_phrase ); return false; @@ -13171,14 +13164,14 @@ subscript_dimension_error( YYLTYPE loc, size_t nsub, const cbl_refer_t *scalar ) } static void -reject_refmod( YYLTYPE loc, cbl_refer_t scalar ) { +reject_refmod( YYLTYPE loc, const cbl_refer_t& scalar ) { if( scalar.is_refmod_reference() ) { error_msg(loc, "%s cannot be reference-modified here", scalar.name()); } } static bool -require_pointer( YYLTYPE loc, cbl_refer_t scalar ) { +require_pointer( YYLTYPE loc, const cbl_refer_t& scalar ) { if( scalar.field->type != FldPointer ) { error_msg(loc, "%s must have USAGE POINTER", scalar.name()); return false; @@ -13187,7 +13180,7 @@ require_pointer( YYLTYPE loc, cbl_refer_t scalar ) { } static bool -require_numeric( YYLTYPE loc, cbl_refer_t scalar ) { +require_numeric( YYLTYPE loc, const cbl_refer_t& scalar ) { if( ! is_numeric(scalar.field) ) { error_msg(loc, "%s must have numeric USAGE", scalar.name()); return false; @@ -13196,7 +13189,7 @@ require_numeric( YYLTYPE loc, cbl_refer_t scalar ) { } static bool -require_integer( YYLTYPE loc, cbl_refer_t scalar ) { +require_integer( YYLTYPE loc, const cbl_refer_t& scalar ) { if( is_literal(scalar.field) ) { if( ! is_integer_literal(scalar.field) ) { error_msg(loc, "numeric literal '%s' must be an integer", diff --git a/gcc/cobol/parse_ante.h b/gcc/cobol/parse_ante.h index 22ce612a2e8..ffb4c986aa6 100644 --- a/gcc/cobol/parse_ante.h +++ b/gcc/cobol/parse_ante.h @@ -244,9 +244,9 @@ new_reference_like( const cbl_field_t& skel ) { return new cbl_refer_t( new_temporary_like(skel) ); } -static void reject_refmod( YYLTYPE loc, cbl_refer_t ); -static bool require_pointer( YYLTYPE loc, cbl_refer_t ); -static bool require_integer( YYLTYPE loc, cbl_refer_t ); +static void reject_refmod( YYLTYPE loc, const cbl_refer_t& ); +static bool require_pointer( YYLTYPE loc, const cbl_refer_t& ); +static bool require_integer( YYLTYPE loc, const cbl_refer_t& ); struct cbl_field_t * constant_of( size_t isym ); @@ -289,7 +289,7 @@ struct evaluate_elem_t { relop_t oper; public: cbl_field_t *subject, *object, *cond; - case_t( cbl_field_t * subject ) + explicit case_t( cbl_field_t * subject ) : oper(eq_op) , subject(subject) , object(NULL) @@ -328,11 +328,10 @@ struct evaluate_elem_t { explicit evaluate_elem_t( const char skel[] ) : nother(0) + , label{LblEvaluate} , result( keep_temporary(FldConditional) ) , pcase( cases.end() ) { - static const cbl_label_t protolabel = { LblEvaluate }; - label = protolabel; label.line = yylineno; if( -1 == snprintf(label.name, sizeof(label.name), "%.*s_%d", (int)sizeof(label.name)-6, skel, yylineno) ) { @@ -367,13 +366,14 @@ struct evaluate_elem_t { static class file_delete_args_t { cbl_file_t *file; public: + file_delete_args_t() : file(nullptr) {} void init( cbl_file_t *file ) { this->file = file; } - bool ready() const { return file != NULL; } + bool ready() const { return file != nullptr; } void call_parser_file_delete( bool sequentially ) { parser_file_delete(file, sequentially); - file = NULL; + file = nullptr; } } file_delete_args; @@ -389,7 +389,7 @@ static struct file_read_args_t { void init( struct cbl_file_t *file, - cbl_refer_t record, + const cbl_refer_t& record, cbl_refer_t *read_into, int where ) { this->file = file; @@ -438,7 +438,7 @@ public: this->file = file; } bool ready() const { return file != NULL; } - void call_parser_return_start(cbl_refer_t into = cbl_refer_t() ) { + void call_parser_return_start(const cbl_refer_t& into = cbl_refer_t() ) { parser_return_start(file, into); file = NULL; } @@ -448,17 +448,18 @@ static class file_rewrite_args_t { cbl_file_t *file; cbl_field_t *record; public: + file_rewrite_args_t() : file(nullptr), record(nullptr) {} void init( cbl_file_t *file, cbl_field_t *record ) { this->file = file; this->record = record; } - bool ready() const { return file != NULL; } + bool ready() const { return file != nullptr; } void call_parser_file_rewrite( bool sequentially ) { sequentially = sequentially || file->access == file_access_seq_e; if( file->access == file_access_rnd_e ) sequentially = false; parser_file_rewrite(file, record, sequentially); - file = NULL; - record = NULL; + file = nullptr; + record = nullptr; } } file_rewrite_args; @@ -487,21 +488,22 @@ static class file_write_args_t { cbl_refer_t *advance; public: file_write_args_t() - : file(NULL) + : file(nullptr) + , data_source(nullptr) , after(false) - , advance(NULL) + , advance(nullptr) {} cbl_file_t * init( cbl_file_t *file, cbl_field_t *data_source, bool after, - cbl_refer_t *advance ) { + const cbl_refer_t *advance ) { this->file = file; this->data_source = data_source; this->after = after; this->advance = new cbl_refer_t(*advance); return this->file; } - bool ready() const { return file != NULL; } + bool ready() const { return file != nullptr; } void call_parser_file_write( bool sequentially ) { sequentially = sequentially || file->access == file_access_seq_e; parser_file_write(file, data_source, after, *advance, sequentially); @@ -535,7 +537,7 @@ struct arith_t { cbl_refer_t remainder; cbl_label_t *on_error, *not_error; - arith_t( cbl_arith_format_t format ) + explicit arith_t( cbl_arith_format_t format ) : format(format), on_error(NULL), not_error(NULL) {} arith_t( cbl_arith_format_t format, refer_list_t * refers ); @@ -619,7 +621,7 @@ class eval_subject_t { void new_object_labels(); public: eval_subject_t(); - void append( cbl_refer_t field ) { + void append( const cbl_refer_t& field ) { columns.push_back(field); pcol = columns.begin(); } @@ -750,6 +752,7 @@ public: static void dump_inspect( const cbl_inspect_t& i ); +void dump_inspect_match( const cbl_inspect_match_t& M ); struct perform_t { struct cbl_perform_tgt_t tgt; @@ -789,11 +792,10 @@ struct perform_t { cbl_refer_t table; } search; - perform_t( cbl_label_t *from, cbl_label_t *to = NULL ) + explicit perform_t( cbl_label_t *from, cbl_label_t *to = NULL ) : tgt( from, to ), before(true) - { - search = {}; - } + , search() + {} ~perform_t() { varys.clear(); } cbl_field_t * until() { assert(!varys.empty()); @@ -892,7 +894,7 @@ static struct cbl_label_t * paragraph_reference( const char name[], size_t section ); static inline void -list_add( list& list, cbl_refer_t refer, int round ) { +list_add( list& list, const cbl_refer_t& refer, int round ) { struct cbl_num_result_t arg = { static_cast(round), refer }; list.push_back(arg); } @@ -1027,7 +1029,7 @@ class tokenset_t { const char * name_of( int tok ) const { tok -= (255 + 3); gcc_assert(0 <= tok && size_t(tok) < token_names.size()); - return token_names[tok]; + return tok < 0? "???" : token_names[tok]; } }; @@ -1094,7 +1096,7 @@ redefined_token( const cbl_name_t name ) { struct file_list_t { list files; file_list_t() {} - file_list_t( cbl_file_t* file ) { + explicit file_list_t( cbl_file_t* file ) { files.push_back(file); } file_list_t( file_list_t& that ) : files(that.files.size()) { @@ -1108,10 +1110,15 @@ struct file_list_t { struct field_list_t { list fields; - field_list_t( cbl_field_t *field ) { + field_list_t() {} + explicit field_list_t( cbl_field_t *field ) { fields.push_back(field); } - explicit field_list_t() {} + std::vector + as_vector() const { + std::vector output( fields.begin(), fields.end() ); + return output; + } }; cbl_field_t ** @@ -1138,7 +1145,7 @@ cbl_file_t ** struct refer_list_t { list refers; - refer_list_t( cbl_refer_t *refer ) { + explicit refer_list_t( cbl_refer_t *refer ) { if( refer ) { refers.push_back(*refer); delete refer; @@ -1160,13 +1167,20 @@ struct refer_list_t { refers.clear(); return tgt; } + std::vector + vectorize() { + std::vector tgt(refers.size()); + std::copy(refers.begin(), refers.end(), tgt.begin()); + refers.clear(); + return tgt; + } }; struct refer_marked_list_t : public refer_list_t { cbl_refer_t *marker; refer_marked_list_t() : refer_list_t(NULL), marker(NULL) {} - refer_marked_list_t( cbl_refer_t *marker, refer_list_t *refers ) + refer_marked_list_t( cbl_refer_t *marker, const refer_list_t *refers ) : refer_list_t(*refers), marker(marker) {} refer_marked_list_t( cbl_refer_t *marker, cbl_refer_t *input ) : refer_list_t(input) @@ -1186,7 +1200,7 @@ struct refer_marked_list_t : public refer_list_t { struct refer_collection_t { list lists; - refer_collection_t( const refer_marked_list_t& marked_list ) + explicit refer_collection_t( const refer_marked_list_t& marked_list ) { lists.push_back( marked_list ); } @@ -1212,48 +1226,13 @@ struct refer_collection_t { } }; -struct ast_inspect_oper_t { - cbl_inspect_bound_t bound; // CHARACTERS/ALL/LEADING/FIRST - std::list matches; - std::list replaces; - -ast_inspect_oper_t( const cbl_inspect_match_t& match, - cbl_inspect_bound_t bound = bound_characters_e ) - : bound(bound) - { - matches.push_back(match); - } - ast_inspect_oper_t( const cbl_inspect_replace_t& replace, - cbl_inspect_bound_t bound = bound_characters_e ) - : bound(bound) - { - replaces.push_back(replace); - } -}; - -struct ast_inspect_t : public std::list { - cbl_refer_t tally; // field is NULL for REPLACING - const std::list& opers() const { return *this; } -}; - -struct ast_inspect_list_t : public std::list { - ast_inspect_list_t( const cbl_inspect_t& insp ) { - push_back(insp); - } - - cbl_inspect_t * as_array() { - cbl_inspect_t *output = new cbl_inspect_t[ size() ]; - std::copy( begin(), end(), output ); - return output; - } -}; - -void ast_inspect( cbl_refer_t& input, bool backward, ast_inspect_list_t& inspects ); +void ast_inspect( YYLTYPE loc, cbl_refer_t& input, bool backward, + cbl_inspect_opers_t& inspects ); template struct elem_list_t { list elems; - elem_list_t( E *elem ) { + explicit elem_list_t( E *elem ) { elems.push_back(elem); } void clear() { @@ -1278,7 +1257,7 @@ template struct unstring_tgt_t { cbl_refer_t *tgt, *delimiter, *count; - unstring_tgt_t( cbl_refer_t *tgt, + explicit unstring_tgt_t( cbl_refer_t *tgt, cbl_refer_t *delimiter = NULL, cbl_refer_t *count = NULL ) : tgt(tgt), delimiter(delimiter), count(count) @@ -1302,7 +1281,7 @@ private: struct unstring_tgt_list_t { list unstring_tgts; - unstring_tgt_list_t( unstring_tgt_t *unstring_tgt ) { + explicit unstring_tgt_list_t( unstring_tgt_t *unstring_tgt ) { unstring_tgts.push_back(*unstring_tgt); delete unstring_tgt; } @@ -1324,7 +1303,7 @@ struct unstring_tgt_list_t { struct unstring_into_t : public unstring_tgt_list_t { cbl_refer_t pointer, tally; - unstring_into_t( unstring_tgt_list_t *tgt_list, + explicit unstring_into_t( unstring_tgt_list_t *tgt_list, cbl_refer_t *pointer = NULL, cbl_refer_t *tally = NULL ) : unstring_tgt_list_t(*tgt_list) @@ -1340,7 +1319,7 @@ struct unstring_into_t : public unstring_tgt_list_t { struct ffi_args_t { list elems; - ffi_args_t( cbl_ffi_arg_t *arg ) { + explicit ffi_args_t( cbl_ffi_arg_t *arg ) { this->push_back(arg); } @@ -1416,8 +1395,8 @@ struct file_sort_io_t { file_list_t file_list; cbl_perform_tgt_t tgt; - file_sort_io_t( file_list_t& files ) : file_list(files) {} - file_sort_io_t( cbl_perform_tgt_t& tgt ) : tgt(tgt.from(), tgt.to()) {} + explicit file_sort_io_t( file_list_t& files ) : file_list(files) {} + explicit file_sort_io_t( cbl_perform_tgt_t& tgt ) : tgt(tgt.from(), tgt.to()) {} size_t nfile() const { return file_list.files.size(); } }; @@ -1432,14 +1411,14 @@ struct merge_t { cbl_perform_tgt_t tgt; list outputs; - merge_t( cbl_file_t *input ) : master(input), type(output_unknown_e) {} + explicit merge_t( cbl_file_t *input ) : master(input), type(output_unknown_e) {} }; static list merges; static inline merge_t& merge_alloc( cbl_file_t *file ) { - merges.push_back(file); + merges.push_back(merge_t(file)); return merges.back(); } @@ -1460,7 +1439,7 @@ static list lhs; struct vargs_t { std::list args; vargs_t() {} - vargs_t( struct cbl_refer_t *p ) { args.push_back(*p); delete p; } + explicit vargs_t( struct cbl_refer_t *p ) { args.push_back(*p); delete p; } void push_back( cbl_refer_t *p ) { args.push_back(*p); delete p; } }; @@ -1484,7 +1463,8 @@ class prog_descr_t { const char *collating_sequence; struct locale_t { cbl_name_t name; const char *os_name; - locale_t(const cbl_name_t name = NULL, const char *os_name = NULL) + locale_t() : name(""), os_name(nullptr) {} + locale_t(const cbl_name_t name, const char *os_name) : name(""), os_name(os_name) { if( name ) { bool ok = namcpy(YYLTYPE(), this->name, name); @@ -1495,7 +1475,7 @@ class prog_descr_t { cbl_call_convention_t call_convention; cbl_options_t options; - prog_descr_t( size_t isymbol ) + explicit prog_descr_t( size_t isymbol ) : program_index(isymbol) , declaratives_eval(NULL) , paragraph(NULL) @@ -1607,9 +1587,9 @@ class program_stack_t : protected std::stack { bool pending_initial() { return pending.initial = true; } void push( prog_descr_t descr ) { - cbl_call_convention_t current_call_convention = cbl_call_cobol_e; - if( !empty() ) current_call_convention = top().call_convention; - descr.call_convention = current_call_convention; + cbl_call_convention_t call_convention = cbl_call_cobol_e; + if( !empty() ) call_convention = top().call_convention; + descr.call_convention = call_convention; std::stack& me(*this); me.push(descr); } @@ -1645,11 +1625,12 @@ class program_stack_t : protected std::stack { } } + // cppcheck-suppress-begin useStlAlgorithm cbl_label_t *first_declarative() { auto eval = top().declaratives_eval; if( eval ) return eval; // scan stack container for declaratives - for( auto& prog : c ) { + for( const auto& prog : c ) { if( prog.declaratives_eval ) { eval = prog.declaratives_eval; break; @@ -1657,6 +1638,7 @@ class program_stack_t : protected std::stack { } return eval; } + // cppcheck-suppress-end useStlAlgorithm }; struct rel_part_t { @@ -1664,9 +1646,13 @@ struct rel_part_t { bool has_relop, invert; relop_t relop; - rel_part_t( cbl_refer_t *operand = NULL, - relop_t relop = relop_t(-1), - bool invert = false ) + rel_part_t() + : operand(nullptr), + has_relop(false), + invert(false), + relop(relop_t(-1)) + {} + rel_part_t( cbl_refer_t *operand, relop_t relop, bool invert ) : operand(operand), has_relop(relop != -1), invert(invert), @@ -1700,7 +1686,7 @@ struct rel_part_t { class log_expr_t { cbl_field_t *orable, *andable; public: - log_expr_t( cbl_field_t *init ) : orable(NULL), andable(init) { + explicit log_expr_t( cbl_field_t *init ) : orable(NULL), andable(init) { if( ! is_conditional(init) ) { dbgmsg("%s:%d: logic error: %s is not a truth value", __func__, __LINE__, name_of(init)); @@ -1859,6 +1845,10 @@ static class current_t { class declaratives_t : protected declaratives_list_t { struct file_exception_t { ec_type_t type; uint32_t file; + file_exception_t() : type(ec_none_e), file(0) {} + file_exception_t(ec_type_t type, uint32_t file) + : type(type), file(file) + {} bool operator<( const file_exception_t& that ) const { if( type == that.type ) return file < that.file; return type < that.type; @@ -1866,9 +1856,11 @@ static class current_t { }; std::set file_exceptions; public: + declaratives_t() {} // current compiled data for enabled ECs and Declaratives, used by library. struct runtime_t { tree ena, dcl; + runtime_t() : ena(nullptr), dcl(nullptr) {} } runtime; bool empty() const { @@ -1888,7 +1880,7 @@ static class current_t { } for( auto f = declarative.files; f && f < declarative.files + declarative.nfile; f++ ) { - file_exception_t ex = { declarative.type, *f }; + file_exception_t ex( declarative.type, *f ); auto result = file_exceptions.insert(ex); if( ! result.second ) { yyerror("%s defined twice for %s", @@ -1901,6 +1893,7 @@ static class current_t { return true; } + // cppcheck-suppress-begin useStlAlgorithm uint32_t status() const { uint32_t status_word = 0; for( auto dcl : *this ) { @@ -1908,6 +1901,7 @@ static class current_t { } return status_word; } + // cppcheck-suppress-end useStlAlgorithm bool has_format_1() const { return std::any_of( begin(), end(), @@ -1947,7 +1941,6 @@ static class current_t { const cbl_field_t * has_typedef( const cbl_field_t *field ) { auto found = typedefs.find(field); return found == typedefs.end()? NULL : *found; - return found == typedefs.end()? NULL : *found; } void udf_add( size_t isym ) { @@ -2003,12 +1996,12 @@ static class current_t { std::list& debugging_declaratives(bool all) const { const char *para = programs.top().paragraph->name; - auto declaratives = debugging_clients.find(all? ":all:" : para); - if( declaratives == debugging_clients.end() ) { + auto client = debugging_clients.find(all? ":all:" : para); + if( client == debugging_clients.end() ) { static std::list empty; return empty; } - return declaratives->second; + return client->second; } bool @@ -2079,7 +2072,7 @@ static class current_t { const cbl_label_t *L; if( (L = symbol_program_add(parent, &label)) == NULL ) return false; - programs.push( symbol_index(symbol_elem_of(L))); + programs.push( prog_descr_t(symbol_index(symbol_elem_of(L))) ); programs.apply_pending(); bool fOK = symbol_at(programs.top().program_index) + 1 == symbols_end(); @@ -2147,7 +2140,7 @@ static class current_t { assert(!programs.empty()); - procref_t *ref = ambiguous_reference(program_index()); + const procref_t *ref = ambiguous_reference(program_index()); std::set externals = programs.top().external_targets(); /* @@ -2371,11 +2364,12 @@ void current_enabled_ecs( tree ena ) { static void add_debugging_declarative( const cbl_label_t * label ) { + // cppcheck-suppress [unreadVariable] obviously not true const char *section = current.declarative_section_name(); if( section ) { debugging_clients[label->name].push_back(section); } -}; +} cbl_options_t current_options() { return current.options_paragraph; @@ -2611,7 +2605,7 @@ intrinsic_call_1( cbl_field_t *output, int token, } static bool -intrinsic_call_2( cbl_field_t *tgt, int token, cbl_refer_t *r1, cbl_refer_t *r2 ) { +intrinsic_call_2( cbl_field_t *tgt, int token, const cbl_refer_t *r1, cbl_refer_t *r2 ) { std::vector args { *r1, r2? *r2 : cbl_refer_t() }; size_t n = intrinsic_invalid_parameter(token, args); if( n < args.size() ) { @@ -2689,18 +2683,14 @@ table_primary_index( cbl_field_t *table ) { NULL : cbl_field_of(symbol_at(table->occurs.indexes.fields[0])); } -static inline const cbl_refer_t // & // Removed the '&' to stop a weird compiler error +static inline const cbl_refer_t // return copy, not element reference invalid_key( const cbl_refer_t& ref ) { assert(ref.field); - - if( ref.nsubscript == 0 ) return ref; - - for( size_t i=0; i < ref.nsubscript; i++ ) { - if( ref.subscripts[i].field->parent != ref.field->parent ) { - return ref.subscripts[i]; - } - } - return NULL; + auto p = std::find_if( ref.subscripts.begin(), ref.subscripts.end(), + [parent = ref.field->parent]( const auto &sub ) { + return sub.field->parent == parent; + } ); + return p != ref.subscripts.end() ? *p : nullptr; } static inline symbol_elem_t * @@ -3186,14 +3176,14 @@ cmd_or_env_special_of( std::string name ) { } static inline void -parser_add2( struct cbl_num_result_t& to, - struct cbl_refer_t from ) { +parser_add2( const cbl_num_result_t& to, + const cbl_refer_t& from ) { parser_add(to.refer, to.refer, from, to.rounded); } static inline void -parser_subtract2( struct cbl_num_result_t to, - struct cbl_refer_t from ) { +parser_subtract2( const cbl_num_result_t& to, + const cbl_refer_t& from ) { parser_subtract(to.refer, to.refer, from, to.rounded); } @@ -3277,11 +3267,11 @@ ast_set_pointers( const list& tgts, cbl_refer_t src ) { void stringify( refer_collection_t *inputs, - cbl_refer_t into, cbl_refer_t pointer, + const cbl_refer_t& into, const cbl_refer_t& pointer, cbl_label_t *on_error = NULL, cbl_label_t *not_error = NULL); -void unstringify( cbl_refer_t& src, refer_list_t *delimited, +void unstringify( const cbl_refer_t& src, refer_list_t *delimited, unstring_into_t * into, cbl_label_t *on_error = NULL, cbl_label_t *not_error = NULL ); @@ -3306,6 +3296,7 @@ implicit_section() } static void +// cppcheck-suppress constParameterPointer ast_enter_exit_section( cbl_label_t * section ) { auto implicit = section? implicit_paragraph() : NULL; @@ -3385,7 +3376,7 @@ data_division_ready() { static bool -anybody_redefines(cbl_field_t *tree) +anybody_redefines( const cbl_field_t *tree ) { bool retval = false; while(tree) @@ -3395,7 +3386,8 @@ anybody_redefines(cbl_field_t *tree) retval = true; break; } - tree = parent_of(tree); + // cppcheck-suppress [unreadVariable] obviously not true + tree = parent_of(tree); } return retval; } @@ -3615,14 +3607,14 @@ file_section_parent_set( cbl_field_t *field ) { field->data.capacity); field->file = file_section_fd; - auto redefined = symbol_redefines(record_area); + const auto redefined = symbol_redefines(record_area); field->parent = redefined? record_area->parent : file->default_record; } return file_section_fd > 0; } void ast_call(const YYLTYPE& loc, cbl_refer_t name, - cbl_refer_t returning, + const cbl_refer_t& returning, size_t narg, cbl_ffi_arg_t args[], cbl_label_t *except, cbl_label_t *not_except, diff --git a/gcc/cobol/parse_util.h b/gcc/cobol/parse_util.h index e504f46ee40..11b86a3d446 100644 --- a/gcc/cobol/parse_util.h +++ b/gcc/cobol/parse_util.h @@ -271,7 +271,7 @@ function_descr_t *function_descrs_end = function_descrs + COUNT_OF(function_desc class cname_cmp { const char *cname; public: - cname_cmp( const char *cname ) : cname(cname) {} + explicit cname_cmp( const char *cname ) : cname(cname) {} bool operator()( const function_descr_t& descr ) { return strlen(cname) == strlen(descr.cname) && @@ -293,8 +293,8 @@ intrinsic_inconsistent_parameter( size_t n, cbl_refer_t *args ) { class commensurate_type { cbl_refer_t first; public: - commensurate_type( const cbl_refer_t& first ) : first(first) {} - bool operator()( cbl_refer_t& arg ) const { + explicit commensurate_type( const cbl_refer_t& first ) : first(first) {} + bool operator()( const cbl_refer_t& arg ) const { return is_numeric(first.field) == is_numeric(arg.field); } }; diff --git a/gcc/cobol/scan_ante.h b/gcc/cobol/scan_ante.h index 7f1153248af..21e89e40f0a 100644 --- a/gcc/cobol/scan_ante.h +++ b/gcc/cobol/scan_ante.h @@ -214,7 +214,11 @@ struct cdf_status_t { const char *filename; int token; bool parsing; - cdf_status_t( int token = 0, bool parsing = true ) + cdf_status_t() + : lineno(yylineno), filename(cobol_filename()) + , token(0), parsing(true) + {} + cdf_status_t( int token, bool parsing ) : lineno(yylineno), filename(cobol_filename()) , token(token), parsing(parsing) {} @@ -371,7 +375,7 @@ class enter_leave_t { enter_leave_t() : entering(NULL), leaving(NULL), filename(NULL) {} enter_leave_t( parser_enter_file_f *entering, const char *filename ) : entering(entering), leaving(NULL), filename(filename) {} - enter_leave_t(parser_leave_file_f *leaving) + explicit enter_leave_t(parser_leave_file_f *leaving) : entering(NULL), leaving(leaving), filename(NULL) {} void notify( unsigned int newlines = 0 ) { @@ -405,7 +409,7 @@ static class input_file_status_t { trailing_newlines = std::count(yytext, yytext + yyleng, '\n'); if( trailing_newlines && yy_flex_debug ) dbgmsg("adding %u lines after POP", trailing_newlines); - inputs.push( parser_leave_file ); + inputs.push( enter_leave_t(parser_leave_file) ); } void notify() { while( ! inputs.empty() ) { @@ -429,7 +433,7 @@ update_location() { auto nline = std::count(yytext, yytext + yyleng, '\n'); if( nline ) { - char *p = static_cast(memrchr(yytext, '\n', yyleng)); + const char *p = static_cast(memrchr(yytext, '\n', yyleng)); loc.last_column = (yytext + yyleng) - p; } @@ -666,7 +670,7 @@ bool need_nume_set( bool tf ) { static int datetime_format_of( const char input[] ); static int symbol_function_token( const char name[] ) { - auto e = symbol_function( 0, name ); + const auto e = symbol_function( 0, name ); return e ? symbol_index(e) : 0; } @@ -754,7 +758,7 @@ typed_name( const char name[] ) { __attribute__((fallthrough)); case FldLiteralN: { - auto f = cbl_field_of(e); + const auto f = cbl_field_of(e); if( type == FldLiteralN ) { yylval.numstr.radix = f->has_attr(hex_encoded_e)? hexadecimal_e : decimal_e; diff --git a/gcc/cobol/scan_post.h b/gcc/cobol/scan_post.h index dc315191362..385ea67299a 100644 --- a/gcc/cobol/scan_post.h +++ b/gcc/cobol/scan_post.h @@ -116,10 +116,10 @@ datetime_format_of( const char input[] ) { for( auto p = patterns; p < eopatterns; p++ ) { static const int cflags = REG_EXTENDED | REG_ICASE; - static char msg[80]; int erc; if( 0 != (erc = regcomp(&p->re, p->regex, cflags)) ) { + static char msg[80]; regerror(erc, &p->re, msg, sizeof(msg)); yywarn("%s:%d: %s: %s", __func__, __LINE__, keyword_str(p->token), msg); } diff --git a/gcc/cobol/show_parse.h b/gcc/cobol/show_parse.h index f7ab98220a5..d417af3fd2c 100644 --- a/gcc/cobol/show_parse.h +++ b/gcc/cobol/show_parse.h @@ -147,10 +147,10 @@ extern bool cursor_at_sol; fprintf(stderr, "<%s>", cbl_field_type_str((b).field->type)); \ } \ } \ - if( (b).nsubscript) \ + if( (b).nsubscript()) \ { \ fprintf(stderr,"("); \ - for(size_t jjj=0; jjj<(b).nsubscript; jjj++) \ + for(size_t jjj=0; jjj<(b).nsubscript(); jjj++) \ { \ if(jjj) \ { \ @@ -337,13 +337,13 @@ extern bool cursor_at_sol; else \ { \ gg_fprintf(trace_handle, 1, "%s", gg_string_literal( (b).field->name ? (b).field->name:"")); \ - if( b.nsubscript ) \ + if( b.nsubscript() ) \ { \ gg_fprintf(trace_handle, 0, "("); \ - for(unsigned int i=0; iname ? b.subscripts[i].field->name : "" )); \ - if( ifield; } cbl_field_t * cbl_span_t::len_field() { assert(len); return len->field; } +cbl_ffi_arg_t::cbl_ffi_arg_t() + : optional(false) + , crv(by_reference_e) + , attr(none_of_e) +{} + cbl_ffi_arg_t:: cbl_ffi_arg_t( cbl_refer_t* refer, cbl_ffi_arg_attr_t attr ) : optional(false) @@ -927,7 +931,7 @@ end_of_group( size_t igroup ) { if( e->program != group->program ) return isym; if( e->type == SymLabel ) return isym; // end of data division if( e->type == SymField ) { - auto f = cbl_field_of(e); + const auto f = cbl_field_of(e); if( f->level == LEVEL77 || f->level == 66 ) return isym; if( f->level == 1 && f->parent != igroup ) { return isym; @@ -938,7 +942,7 @@ end_of_group( size_t igroup ) { } eog_t eog(symbol_at(igroup)); - symbol_elem_t *e = std::find_if( symbols_begin(++igroup), symbols_end(), eog ); + const symbol_elem_t *e = std::find_if( symbols_begin(++igroup), symbols_end(), eog ); return e - symbols_begin(); } @@ -993,7 +997,7 @@ symbol_find_odo_debug( cbl_field_t * field ) { // Return OCCURS DEPENDING ON table subordinate to field, if any. struct cbl_field_t * -symbol_find_odo( cbl_field_t * field ) { +symbol_find_odo( const cbl_field_t * field ) { size_t bog = field_index(field), eog = end_of_group(bog); auto e = std::find_if( symbol_at(bog), symbol_at_impl(eog, true), has_odo ); return e == symbol_at_impl(eog, true)? NULL : cbl_field_of(e); @@ -1170,7 +1174,7 @@ static struct symbol_elem_t * // If an 01 record exists for the FD/SD, use its capacity as the // default_record capacity. if( p != symbols_end() ) { - auto record = cbl_field_of(p); + const auto record = cbl_field_of(p); assert(record->level == 1); e = calculate_capacity(p); auto record_size = std::max(record->data.memsize, @@ -1362,7 +1366,7 @@ is_variable_length( const cbl_field_t *field ) { * occurs-depending table." */ cbl_field_t * -rename_not_ok( cbl_field_t *first, cbl_field_t *last) { +rename_not_ok( const cbl_field_t *first, const cbl_field_t *last) { symbol_elem_t *beg = symbol_at(field_index(first)), *end = symbol_at(field_index(last)); @@ -1463,7 +1467,7 @@ field_str( const cbl_field_t *field ) { } pend += snprintf(pend, string + sizeof(string) - pend, - "%02d %-20s ", field->level, name); + "%02u %-20s ", field->level, name); char offset[32] = ""; if( field->level > 1 ) { @@ -1574,7 +1578,7 @@ struct capacity_of { capacity_of operator()( symbol_elem_t& elem ) { if( elem.type == SymField ) { - cbl_field_t *f = cbl_field_of(&elem); + const cbl_field_t *f = cbl_field_of(&elem); if( is_elementary(f->type) ) { capacity += field_size(f); } @@ -1741,7 +1745,7 @@ symbols_update( size_t first, bool parsed_ok ) { bool size_invalid = field->data.memsize > 0 && symbol_redefines(field); if( size_invalid ) { // redefine of record area is ok - auto redefined = symbol_redefines(field); + const auto redefined = symbol_redefines(field); size_invalid = ! is_record_area(redefined); } if( !field->is_valid() || size_invalid ) @@ -1824,7 +1828,7 @@ symbols_update( size_t first, bool parsed_ok ) { } // Verify REDEFINing field has no ODO components - auto parent = symbol_redefines(field); + const auto parent = symbol_redefines(field); if( parent && !is_record_area(parent) && is_variable_length(field) ) { ERROR_FIELD(field, "line %d: REDEFINES field %s cannot be variable length", field->line, field->name); @@ -2014,15 +2018,15 @@ symbol_in_file( symbol_elem_t *e ) { } #endif -static struct cbl_field_t * -symbol_field_parent_set( struct cbl_field_t *field ) +static cbl_field_t * +symbol_field_parent_set( cbl_field_t *field ) { if( field->level == 01 ) return NULL; if( field->level == 77 ) return NULL; if( field->level == 78 ) return NULL; struct symbol_elem_t *e = symbols.elems + symbols.nelem - 1; - struct symbol_elem_t *first = symbols.elems + symbols.first_program; + const struct symbol_elem_t *first = symbols.elems + symbols.first_program; for( ; field->parent == 0 && e >= first; e-- ) { if( ! (e->type == SymField && cbl_field_of(e)->level > 0) ) { @@ -2404,7 +2408,7 @@ symbol_file_add( size_t program, cbl_file_t *file ) { return NULL; } - struct symbol_elem_t sym = { SymFile, program }; + symbol_elem_t sym{ SymFile, program }; sym.elem.file = *file; e = symbol_add(&sym); @@ -2462,7 +2466,7 @@ symbol_typedef_add( size_t program, struct cbl_field_t *field ) { auto e = symbols_end() - 1; assert( symbols_begin() < e ); if( e->type == SymField ) { - auto f = cbl_field_of(e); + const auto f = cbl_field_of(e); if( f == field ) return e; } @@ -2500,7 +2504,7 @@ struct symbol_elem_t * symbol_field_add( size_t program, struct cbl_field_t *field ) { field->our_index = symbols.nelem; - cbl_field_t *parent = symbol_field_parent_set( field ); + const cbl_field_t *parent = symbol_field_parent_set( field ); if( parent && parent->type == FldGroup) { // Inherit effects of parent's USAGE, as though it appeared 1st in the // member's definition. @@ -2512,7 +2516,7 @@ symbol_field_add( size_t program, struct cbl_field_t *field ) if( is_numeric(parent->usage) && parent->data.capacity > 0 ) { field->type = parent->usage; field->data = parent->data; - field->data = 0.0; + field->data = 0; field->data.initial = NULL; } } @@ -2631,6 +2635,7 @@ symbol_field( size_t program, size_t parent, const char name[] ) return p != end? &*p : NULL; } +// cppcheck-suppress-begin [CastIntegerToAddressAtReturn] obviously not true symbol_elem_t * symbol_register( const char name[] ) { @@ -2646,6 +2651,7 @@ symbol_register( const char name[] ) return p; } +// cppcheck-suppress-end [CastIntegerToAddressAtReturn] // Find current 01 record during Level 66 construction. const symbol_elem_t * @@ -2708,11 +2714,12 @@ symbol_literalA( size_t program, const char name[] ) struct symbol_elem_t * symbol_file( size_t program, const char name[] ) { size_t nelem = symbols.nelem; - struct symbol_elem_t key = { SymFile, program }, *e = &key; + symbol_elem_t key{ SymFile, program }, *e = &key; assert(strlen(name) < sizeof(key.elem.file.name)); strcpy(key.elem.file.name, name); + // cppcheck-suppress-begin [knownConditionTrueFalse] do { e = static_cast(lfind( &key, symbols.elems, &nelem, sizeof(*e), @@ -2721,6 +2728,7 @@ symbol_file( size_t program, const char name[] ) { key.program = cbl_label_of(symbol_at(key.program))->parent; if( key.program == 0 ) break; // no file without a program } while( !e ); + // cppcheck-suppress-end [knownConditionTrueFalse] if( e ) { assert(e->type == SymFile); @@ -2914,7 +2922,7 @@ symbol_file_same_record_area( std::list& files ) { } static symbol_elem_t * -next_program( symbol_elem_t *elem ) { +next_program( const symbol_elem_t *elem ) { size_t start = elem? symbol_index(elem) : 0; symbol_elem_t * e = std::find_if( symbols_begin(start), symbols_end(), is_program ); @@ -2952,14 +2960,14 @@ is_numeric_constant( const char name[] ) { // get default record layout for a file struct cbl_field_t * -symbol_file_record( struct cbl_file_t *file ) { +symbol_file_record( const cbl_file_t *file ) { return cbl_field_of(symbol_at(file->default_record)); } class is_section { cbl_section_type_t section_type; public: - is_section( cbl_section_type_t sect ) : section_type(sect) {} + explicit is_section( cbl_section_type_t sect ) : section_type(sect) {} bool operator()( symbol_elem_t& e ) const { return e.type == SymDataSection && cbl_section_of(&e)->type == section_type; } @@ -2970,8 +2978,6 @@ static bool fd_record_size_cmp( const symbol_elem_t& a, const symbol_elem_t& b ) return cbl_field_of(&a)->data.capacity < cbl_field_of(&b)->data.capacity; } -cbl_file_key_t cbl_file_t::no_key; - /* * Find largest and smallest record defined for a file. The rule is: * cbl_file_t::varies() returns true if the record size varies, @@ -3604,12 +3610,9 @@ cbl_label_t::explicit_parent() const { } cbl_prog_hier_t::cbl_prog_hier_t() { - nlabel = std::count_if( symbols_begin(), symbols_end(), is_program ); - assert(nlabel >0); - labels = new cbl_prog_hier_t::program_label_t[nlabel]; - std::copy_if( symbols_begin(), symbols_end(), - labels, is_program ); + std::back_inserter(labels), is_program ); + assert(! labels.empty()); } /* @@ -3702,7 +3705,8 @@ symbol_label_add( size_t program, cbl_label_t *input ) if( (e = symbol_add(&elem)) == NULL ) { cbl_errx("%s:%d: could not add '%s'", __func__, __LINE__, label->name); } - + assert(e); + common_callables_update( symbol_index(e) ); // restore munged line number unless symbol_add returned an existing label @@ -3723,7 +3727,7 @@ symbol_label_section_exists( size_t eval_label_index ) { bool has_section = std::any_of( ++eval, symbols_end(), [program = eval->program]( const auto& sym ) { if( program == sym.program && sym.type == SymLabel ) { - auto& L(sym.elem.label); + const auto& L(sym.elem.label); // true if the symbol is an explicit label. return L.type == LblSection && L.name[0] != '_'; } @@ -3875,7 +3879,7 @@ expand_picture(const char *picture) { assert(strlen(picture) < PICTURE_MAX); // guaranteed by picset() in scanner size_t retval_length = PICTURE_MAX; - char *retval = (char *)xmalloc(retval_length); + char *retval = static_cast(xmalloc(retval_length)); size_t index = 0; int ch; @@ -3904,7 +3908,7 @@ expand_picture(const char *picture) if( index + repeat >= retval_length ) { retval_length <<= 1; - retval = (char *)xrealloc(retval, retval_length); + retval = static_cast(xrealloc(retval, retval_length)); } while(repeat--) @@ -3917,7 +3921,7 @@ expand_picture(const char *picture) if( index >= retval_length ) { retval_length <<= 1; - retval = (char *)xrealloc(retval, retval_length); + retval = static_cast(xrealloc(retval, retval_length)); } retval[index++] = ch; } @@ -3926,7 +3930,7 @@ expand_picture(const char *picture) if( index >= retval_length ) { retval_length <<= 1; - retval = (char *)xrealloc(retval, retval_length); + retval = static_cast(xrealloc(retval, retval_length)); } retval[index++] = '\0'; @@ -3949,7 +3953,6 @@ expand_picture(const char *picture) { pcurrency[i] = 'B'; } - dest_length += sign_length; } } @@ -4180,7 +4183,7 @@ symbol_program_callables( size_t program ) { if( e->type != SymLabel ) continue; if( e->elem.label.type != LblProgram ) continue; - auto prog = cbl_label_of(e); + const auto prog = cbl_label_of(e); if( program == symbol_index(e) && !prog->recursive ) continue; if( (self->parent == prog->parent && prog->common) || @@ -4214,6 +4217,7 @@ symbol_program_local( const char tgt_name[] ) { */ std::map currencies; +// cppcheck-suppress-begin [nullPointerRedundantCheck] bool symbol_currency_add( const char symbol[], const char sign[] ) { // In service of CURRENCY sign PICTURE SYMBOL symbol @@ -4225,6 +4229,7 @@ symbol_currency_add( const char symbol[], const char sign[] ) { currencies[*symbol] = sign; return true; } +// cppcheck-suppress-end [nullPointerRedundantCheck] const char * symbol_currency( char sign ) { @@ -4247,24 +4252,19 @@ bool decimal_is_comma() { return decimal_point == ','; } /* * A cbl_occurs_key_t is part of a field definition, and comprises * size_t symbol indexes. A cbl_key_t is a list of field pointers, - * and can be created ad hoc to describe a sort. We can construct a + * and can be created ad hoc to describe a sort. We construct a * cbl_key_t from cbl_occurs_key_t. */ cbl_key_t:: cbl_key_t( const cbl_occurs_key_t& that ) : ascending(that.ascending) { - if( that.field_list.nfield == 0 ) { - *this = cbl_key_t(); - return; - } - - nfield = that.field_list.nfield; - fields = static_cast( xcalloc(nfield, - sizeof(*fields)) ); - for( size_t i=0; i < that.field_list.nfield; i++ ) { - fields[i] = cbl_field_of(symbol_at(that.field_list.fields[i])); - } + std::transform( that.field_list.fields, + that.field_list.fields + that.field_list.nfield, + std::back_inserter(fields), + []( size_t isym ) { + return cbl_field_of(symbol_at(isym)); + } ); } void @@ -4277,7 +4277,7 @@ cbl_occurs_t::key_alloc( bool ascending ) { } void -cbl_occurs_t::field_add( cbl_field_list_t& field_list, cbl_field_t *field ) { +cbl_occurs_t::field_add( cbl_field_list_t& field_list, const cbl_field_t *field ) { cbl_field_list_t list = field_list; size_t ifield = field_index(field); auto nbytes = sizeof(list.fields[0]) * (list.nfield + 1); @@ -4295,14 +4295,14 @@ cbl_occurs_t::key_field_add( cbl_field_t *field ) { } void -cbl_occurs_t::index_add( cbl_field_t *field ) { +cbl_occurs_t::index_add( const cbl_field_t *field ) { field_add(indexes, field); } class is_field_at { cbl_field_t *field; public: - is_field_at( cbl_field_t *field ) : field(field) {} + explicit is_field_at( cbl_field_t *field ) : field(field) {} bool operator()( size_t isym ) const { return field == field_at(isym); } @@ -4470,11 +4470,11 @@ cbl_file_key_t::deforward( size_t ifile ) { const auto file = cbl_file_of(symbol_at(ifile)); std::transform( fields, fields + nfield, fields, [ifile, file]( size_t fwd ) { - static std::map keys; auto ifield = symbol_forward_to(fwd); const auto field = cbl_field_of(symbol_at(ifield)); if( is_forward(field) && yydebug ) { + static std::map keys; dbgmsg("%s:%d: key %d: #" HOST_SIZE_T_PRINT_UNSIGNED " %s of %s is %s", "deforward", __LINE__, keys[ifile]++, (fmt_size_t)ifield, field->name, file->name, @@ -4561,27 +4561,12 @@ cbl_file_t::deforward() { char * cbl_file_t::keys_str() const { - std::vector ks(nkey); - std::transform(keys, keys + nkey, ks.begin(), - []( const cbl_file_key_t& key ) { - return key.str(); - } ); - size_t n = 4 * nkey + std::accumulate(ks.begin(), ks.end(), 0, - []( int n, const char *s ) { - return n + strlen(s); - } ); - char *output = static_cast( xcalloc(1, n) ), *p = output; - const char *sep = ""; - - *p++ = '['; - for( auto k : ks ) { - p = stpcpy(p, sep); - p = stpcpy(p, k); - sep = ", "; - free(k); + std::string names = "["; + for( cbl_file_key_t *p = keys; p < keys + nkey; p++ ) { + names += p->str(); + names += p + 1 < keys + nkey ? "," : "]"; } - *p++ = ']'; - return output; + return xasprintf("%s", names.c_str()); } /* @@ -4643,7 +4628,7 @@ cbl_file_status_cmp( const void *K, const void *E ) { static long file_status_status_of( file_status_t status ) { size_t n = COUNT_OF(file_status_fields); - file_status_field_t *fs, key { status }; + const file_status_field_t *fs, key { status }; fs = (file_status_field_t*)lfind( &key, file_status_fields, &n, sizeof(*fs), cbl_file_status_cmp ); @@ -4673,7 +4658,7 @@ ast_file_status_between( file_status_t lower, file_status_t upper ) { } bool -is_register_field(cbl_field_t *field) +is_register_field(const cbl_field_t *field) { // TRUE when the field is an executable-level global variable of the type we // are calling a "register", like RETURN-CODE or UPSI or the like: diff --git a/gcc/cobol/symbols.h b/gcc/cobol/symbols.h index 154c9fe67f0..84a984e6ba6 100644 --- a/gcc/cobol/symbols.h +++ b/gcc/cobol/symbols.h @@ -264,7 +264,18 @@ struct cbl_field_data_t { explicit etc_t( tree v = build_zero_cst (float128_type_node)) : value(v) {} } etc; - cbl_field_data_t( uint32_t memsize=0, uint32_t capacity=0 ) + cbl_field_data_t() + : memsize(0) + , capacity(0) + , digits(0) + , rdigits(0) + , initial(0) + , picture(0) + , etc_type(value_e) + , etc() + {} + + cbl_field_data_t( uint32_t memsize, uint32_t capacity ) : memsize(memsize) , capacity(capacity) , digits(0) @@ -327,6 +338,10 @@ struct cbl_field_data_t { etc_type = value_e; return etc.value = v; } + tree& operator=(int i) { + etc_type = value_e; + return etc.value = build_int_cst_type(integer_type_node, i); + } void set_real_from_capacity( REAL_VALUE_TYPE *r ) const { real_from_integer (r, VOIDmode, capacity, SIGNED); @@ -412,8 +427,11 @@ struct cbl_occurs_bounds_t { // variable size table. lower can be zero. size_t lower, upper; - cbl_occurs_bounds_t(size_t lower=0, size_t upper=0) + cbl_occurs_bounds_t() + : lower(0), upper(0) {} + explicit cbl_occurs_bounds_t(size_t lower, size_t upper=0) : lower(lower), upper(upper) {} + size_t ntimes() const { return upper; } @@ -446,12 +464,12 @@ struct cbl_occurs_t { void key_alloc( bool ascending ); void key_field_add( cbl_field_t *field ); - void index_add( cbl_field_t *field ); + void index_add( const cbl_field_t *field ); cbl_occurs_key_t * key_of( cbl_field_t *field ); bool subscript_ok( const cbl_field_t *subscript ) const; protected: - void field_add( cbl_field_list_t& fields, cbl_field_t *field ); + void field_add( cbl_field_list_t& fields, const cbl_field_t *field ); }; /* @@ -655,50 +673,64 @@ struct cbl_refer_t { cbl_field_t *field; cbl_label_t *prog_func; bool all, addr_of; - uint32_t nsubscript; - cbl_refer_t *subscripts; // indices + std::vector subscripts; // indices cbl_span_t refmod; // substring bounds cbl_refer_t() : loc(), field(NULL), prog_func(NULL) , all(NULL), addr_of(false) - , nsubscript(0), subscripts(NULL), refmod(NULL) + , refmod(NULL) {} + // cppcheck-suppress noExplicitConstructor cbl_refer_t( cbl_field_t *field, bool all = false ) : loc(), field(field), prog_func(NULL) , all(all), addr_of(false) - , nsubscript(0), subscripts(NULL), refmod(NULL) + , refmod(NULL) {} cbl_refer_t( const YYLTYPE& loc, cbl_field_t *field, bool all = false ) : loc(loc), field(field), prog_func(NULL) , all(all), addr_of(false) - , nsubscript(0), subscripts(NULL), refmod(NULL) + , refmod(NULL) {} cbl_refer_t( cbl_field_t *field, cbl_span_t& refmod ) : loc(), field(field), prog_func(NULL) , all(false), addr_of(false) - , nsubscript(0), subscripts(NULL), refmod(refmod) + , refmod(refmod) {} cbl_refer_t( cbl_field_t *field, - size_t nsubscript, cbl_refer_t *subscripts, + const std::vector& subscripts, cbl_span_t refmod = cbl_span_t(NULL) ) : loc(), field(field), prog_func(NULL) , all(false), addr_of(false) - , nsubscript(nsubscript) , subscripts( new cbl_refer_t[nsubscript] ) + , subscripts(subscripts) , refmod(refmod) - { - std::copy(subscripts, subscripts + nsubscript, this->subscripts); - } + {} explicit cbl_refer_t( cbl_label_t *prog_func, bool addr_of = true ) : loc(), field(NULL), prog_func(prog_func) , all(false), addr_of(addr_of) - , nsubscript(0), subscripts(NULL), refmod(cbl_span_t(NULL)) + , refmod(cbl_span_t(NULL)) {} + cbl_refer_t( const cbl_refer_t& that ) = default; + + cbl_refer_t& operator=( const cbl_refer_t& that ) { + loc = that.loc; + field = that.field; + prog_func = that.prog_func; + all = that.all; + addr_of = that.addr_of; + subscripts = that.subscripts; + refmod = that.refmod; + return *this; + } + + cbl_refer_t duplicate() const { - return cbl_refer_t( field, nsubscript, subscripts, refmod ); + return cbl_refer_t( field, subscripts, refmod ); } + uint32_t nsubscript() const { return subscripts.size(); } + static cbl_refer_t *empty(); cbl_refer_t * name( const char name[] ) { @@ -709,8 +741,8 @@ struct cbl_refer_t { } bool is_pointer() const { return addr_of || field->type == FldPointer; } - bool is_reference() const { return nsubscript > 0 || refmod.is_active(); } - bool is_table_reference() const { return nsubscript > 0; } + bool is_reference() const { return nsubscript() > 0 || refmod.is_active(); } + bool is_table_reference() const { return nsubscript() > 0; } bool is_refmod_reference() const { return refmod.is_active(); } size_t subscripts_set( const std::list& subs ); @@ -775,7 +807,7 @@ struct field_key_t { } }; -bool valid_move( const struct cbl_field_t *tgt, const struct cbl_field_t *src ); +bool valid_move( const cbl_field_t *tgt, const cbl_field_t *src ); #define record_area_name_stem "_ra_" @@ -785,8 +817,7 @@ is_record_area( const cbl_field_t *field ) { return 0 == memcmp(field->name, stem, sizeof(stem)-1); } -bool -is_register_field(cbl_field_t *field); +bool is_register_field( const cbl_field_t *field ); static inline bool is_constant( const cbl_field_t *field ) { @@ -804,17 +835,20 @@ symbol_field_type_update( cbl_field_t *field, cbl_field_type_t type, bool is_usage ); struct sort_key_t; +struct sort_key_t; struct cbl_key_t { bool ascending; - size_t nfield; - cbl_field_t **fields; + std::vector fields; - cbl_key_t() : ascending(false), nfield(0), fields(0) {} - cbl_key_t( size_t nfield, cbl_field_t **fields, bool ascending = true ) - : ascending(ascending), nfield(nfield), fields(fields) {} - cbl_key_t( const sort_key_t& src ); + cbl_key_t() : ascending(true) {} + explicit cbl_key_t( sort_key_t src ); explicit cbl_key_t( const cbl_occurs_key_t& that ); + cbl_key_t( size_t nfield, cbl_field_t **fields, bool ascending = true ) + : ascending(ascending) + , fields(fields, fields + nfield) + {} + cbl_key_t& operator=( const sort_key_t& that ); }; enum cbl_label_type_t { @@ -911,8 +945,12 @@ struct cbl_substitute_t { subst_fl_t first_last; cbl_refer_t orig, replacement; - cbl_substitute_t( bool anycase = false, char first_last = 0, - cbl_refer_t *orig = NULL, cbl_refer_t *replacement = NULL ) + cbl_substitute_t() + : anycase(false) + , first_last(subst_all_e) + {} + cbl_substitute_t( bool anycase, char first_last, + cbl_refer_t *orig, cbl_refer_t *replacement ) : anycase(anycase) , first_last(subst_fl_t(first_last)) , orig( orig? *orig : cbl_refer_t() ) @@ -945,7 +983,10 @@ struct cbl_num_result_t { enum cbl_round_t rounded; struct cbl_refer_t refer; - static cbl_refer_t refer_of( const cbl_num_result_t& res ) { return res.refer; } + static const cbl_refer_t& + refer_of( const cbl_num_result_t& res ) { + return res.refer; + } }; void parser_symbol_add( struct cbl_field_t *new_var ); @@ -957,8 +998,9 @@ struct cbl_ffi_arg_t { cbl_ffi_arg_attr_t attr; cbl_refer_t refer; // refer::field == NULL is OMITTED - cbl_ffi_arg_t( cbl_refer_t* refer = NULL, - cbl_ffi_arg_attr_t attr = none_of_e ); + cbl_ffi_arg_t(); + cbl_ffi_arg_t( cbl_refer_t* refer, + cbl_ffi_arg_attr_t attr ); cbl_ffi_arg_t( cbl_ffi_crv_t crv, cbl_refer_t* refer, cbl_ffi_arg_attr_t attr = none_of_e ); @@ -1171,7 +1213,8 @@ class temporaries_t { struct literal_an { bool is_quoted; std::string value; - literal_an( const char value[] = "???", bool is_quoted = false ) + literal_an() : is_quoted(false), value("???") {} + literal_an( const char value[], bool is_quoted ) : is_quoted(is_quoted), value(value) {} literal_an& operator=( const literal_an& that ) { is_quoted = that.is_quoted; @@ -1513,9 +1556,19 @@ struct cbl_file_key_t { cbl_name_t name; size_t leftmost; // START or READ named leftmost field in key size_t nfield; - size_t *fields; + size_t *fields; // cppcheck-suppress unsafeClassCanLeak + + cbl_file_key_t() + : unique(true) + , leftmost(0) + , nfield(0) + , fields(nullptr) + { + memset(name, '\0', sizeof(name)); + } - cbl_file_key_t( size_t field = 0, bool unique = true ) + // Construct a key of length 1 having a single field. + explicit cbl_file_key_t( size_t field, bool unique = true ) : unique(unique) , leftmost(0) , nfield(1) @@ -1529,6 +1582,29 @@ struct cbl_file_key_t { const std::list& fields, bool is_unique ); + // The copy constructor and assignment operator exist to quell reports from + // cppcheck. When these objects are copied, the copy still points to the + // original data. + cbl_file_key_t( const cbl_file_key_t& that ) + : unique(that.unique) + , leftmost(that.leftmost) + , nfield(that.nfield) + // cppcheck-suppress copyCtorPointerCopying + , fields(that.fields) + { + strcpy(name, that.name); + } + ~cbl_file_key_t() {} + cbl_file_key_t& operator=( const cbl_file_key_t& that ) { + unique = that.unique; + leftmost = that.leftmost; + nfield = that.nfield; + // cppcheck-suppress copyCtorPointerCopying + fields = that.fields; + strcpy(name, that.name); + return *this; + } + uint32_t size(); void deforward( size_t ifile ); char * str() const; @@ -1542,12 +1618,12 @@ struct cbl_file_key_t { struct cbl_file_lock_t { bool multiple; enum lock_mode_t { unlocked_e, manual_e, record_e, automatic_e } mode; + cbl_file_lock_t() : multiple(false), mode(unlocked_e) {} bool mode_set( int token ); bool locked() const { return mode != unlocked_e; } }; struct cbl_file_t { - static cbl_file_key_t no_key; enum cbl_file_org_t org; enum file_entry_type_t entry_type; uint32_t attr; @@ -1574,15 +1650,32 @@ struct cbl_file_t { tree var_decl_node; // GENERIC tag for the run-time FIELD structure cbl_file_t() - : org(file_disorganized_e), - access(file_access_seq_e) + : org(file_disorganized_e) + , entry_type(fd_e) + , attr(0), reserve(0), same_record_as(0) + , padding('\0') + , optional(false) + , varying_size{ false, 0, 0 } + , access(file_access_seq_e) + , filename(0) + , default_record(0) + , nkey(0) + , keys(nullptr) + , password(0), user_status(0), vsam_status(0), record_length(0) + , line(0) + , addresses(nullptr) + , var_decl_node(nullptr) { - keys = &no_key; + memset(name, '\0', sizeof(name)); } bool varies() const { return varying_size.min != varying_size.max; } bool validate() const; void deforward(); + cbl_file_key_t * keys_update( cbl_file_key_t * keys ) { + if( this->keys ) delete[] this->keys; + return this->keys = keys; + } char * keys_str() const; int key_one( cbl_field_t *field ) const { auto ekey = keys + nkey, p = ekey; @@ -1630,7 +1723,8 @@ struct symbol_elem_t { symbol_elem_u() : field() {} } elem; - symbol_elem_t( symbol_type_t type = SymField, size_t program = 0 ) + symbol_elem_t() : type(SymField), program(0) {} + explicit symbol_elem_t( symbol_type_t type, size_t program = 0 ) : type(type), program(program) {} @@ -1700,6 +1794,7 @@ static inline symbol_elem_t * symbol_elem_of( cbl_label_t *label ) { size_t n = offsetof(struct symbol_elem_t, elem.label); return + // cppcheck-suppress cstyleCast reinterpret_cast((char*)label - n); } @@ -1707,6 +1802,7 @@ static inline const symbol_elem_t * symbol_elem_of( const cbl_label_t *label ) { size_t n = offsetof(symbol_elem_t, elem.label); return + // cppcheck-suppress cstyleCast reinterpret_cast((const char*)label - n); } @@ -1714,6 +1810,7 @@ static inline symbol_elem_t * symbol_elem_of( cbl_special_name_t *special ) { size_t n = offsetof(symbol_elem_t, elem.special); return + // cppcheck-suppress cstyleCast reinterpret_cast((char*)special - n); } @@ -1721,6 +1818,7 @@ static inline symbol_elem_t * symbol_elem_of( cbl_alphabet_t *alphabet ) { size_t n = offsetof(symbol_elem_t, elem.alphabet); return + // cppcheck-suppress cstyleCast reinterpret_cast((char*)alphabet - n); } @@ -1728,12 +1826,14 @@ static inline symbol_elem_t * symbol_elem_of( cbl_file_t *file ) { size_t n = offsetof(struct symbol_elem_t, elem.file); return + // cppcheck-suppress cstyleCast reinterpret_cast((char*)file - n); } static inline const symbol_elem_t * symbol_elem_of( const cbl_file_t *file ) { size_t n = offsetof(symbol_elem_t, elem.file); return + // cppcheck-suppress cstyleCast reinterpret_cast((const char*)file - n); } @@ -1741,18 +1841,20 @@ static inline symbol_elem_t * symbol_elem_of( cbl_field_t *field ) { size_t n = offsetof(struct symbol_elem_t, elem.field); return + // cppcheck-suppress cstyleCast reinterpret_cast((char*)field - n); } static inline const symbol_elem_t * symbol_elem_of( const cbl_field_t *field ) { size_t n = offsetof(symbol_elem_t, elem.field); return + // cppcheck-suppress cstyleCast reinterpret_cast((const char*)field - n); } symbol_elem_t * symbols_begin( size_t first = 0 ); symbol_elem_t * symbols_end(void); -cbl_field_t * symbol_redefines( const struct cbl_field_t *field ); +cbl_field_t * symbol_redefines( const cbl_field_t *field ); void build_symbol_map(); bool update_symbol_map( symbol_elem_t *e ); @@ -1768,7 +1870,7 @@ symbol_find( size_t program, std::list names ); symbol_elem_t * symbol_find_of( size_t program, std::list names, size_t group ); -struct cbl_field_t *symbol_find_odo( cbl_field_t * field ); +struct cbl_field_t *symbol_find_odo( const cbl_field_t * field ); size_t dimensions( const cbl_field_t *field ); const symbol_elem_t * symbol_field_current_record(); @@ -1792,54 +1894,54 @@ bool redefine_field( cbl_field_t *field ); static inline struct cbl_section_t * cbl_section_of( struct symbol_elem_t *e ) { - assert(e->type == SymDataSection); + assert(e && e->type == SymDataSection); return &e->elem.section; } static inline struct cbl_field_t * cbl_field_of( struct symbol_elem_t *e ) { - assert(e->type == SymField); + assert(e && e->type == SymField); return &e->elem.field; } -static inline const struct cbl_field_t * -cbl_field_of( const struct symbol_elem_t *e ) { - assert(e->type == SymField); +static inline const cbl_field_t * +cbl_field_of( const symbol_elem_t *e ) { + assert(e && e->type == SymField); return &e->elem.field; } static inline struct cbl_label_t * cbl_label_of( struct symbol_elem_t *e ) { - assert(e->type == SymLabel); + assert(e && e->type == SymLabel); return &e->elem.label; } -static inline const struct cbl_label_t * -cbl_label_of( const struct symbol_elem_t *e ) { - assert(e->type == SymLabel); +static inline const cbl_label_t * +cbl_label_of( const symbol_elem_t *e ) { + assert(e && e->type == SymLabel); return &e->elem.label; } static inline struct cbl_special_name_t * cbl_special_name_of( struct symbol_elem_t *e ) { - assert(e->type == SymSpecial); + assert(e && e->type == SymSpecial); return &e->elem.special; } static inline struct cbl_alphabet_t * cbl_alphabet_of( struct symbol_elem_t *e ) { - assert(e->type == SymAlphabet); + assert(e && e->type == SymAlphabet); return &e->elem.alphabet; } static inline struct cbl_file_t * cbl_file_of( struct symbol_elem_t *e ) { - assert(e->type == SymFile); + assert(e && e->type == SymFile); return &e->elem.file; } -static inline const struct cbl_file_t * -cbl_file_of( const struct symbol_elem_t *e ) { - assert(e->type == SymFile); +static inline const cbl_file_t * +cbl_file_of( const symbol_elem_t *e ) { + assert(e && e->type == SymFile); return &e->elem.file; } @@ -1858,43 +1960,43 @@ is_procedure( const symbol_elem_t& e ) { } static inline bool -is_figconst(const struct cbl_field_t *field ) { - return ((field->attr & FIGCONST_MASK) != 0 ); +is_figconst(const cbl_field_t *field ) { + return (field->attr & FIGCONST_MASK) != 0; } static inline bool -is_figconst_low( const struct cbl_field_t *field ) { - return ((field->attr & FIGCONST_MASK) == low_value_e ); +is_figconst_low( const cbl_field_t *field ) { + return (field->attr & FIGCONST_MASK) == low_value_e; } static inline bool -is_figconst_zero( const struct cbl_field_t *field ) { - return ((field->attr & FIGCONST_MASK) == zero_value_e ); +is_figconst_zero( const cbl_field_t *field ) { + return (field->attr & FIGCONST_MASK) == zero_value_e; } static inline bool -is_figconst_space( const struct cbl_field_t *field ) { - return ((field->attr & FIGCONST_MASK) == space_value_e ); +is_figconst_space( const cbl_field_t *field ) { + return (field->attr & FIGCONST_MASK) == space_value_e; } static inline bool -is_figconst_quote( const struct cbl_field_t *field ) { - return ((field->attr & FIGCONST_MASK) == quote_value_e ); +is_figconst_quote( const cbl_field_t *field ) { + return (field->attr & FIGCONST_MASK) == quote_value_e; } static inline bool -is_figconst_high( const struct cbl_field_t *field ) { - return ((field->attr & FIGCONST_MASK) == high_value_e ); +is_figconst_high( const cbl_field_t *field ) { + return (field->attr & FIGCONST_MASK) == high_value_e; } static inline bool -is_space_value( const struct cbl_field_t *field ) { - return( (strcmp(field->name, "SPACE") == 0) - || (strcmp(field->name, "SPACES") == 0) ); +is_space_value( const cbl_field_t *field ) { + return (strcmp(field->name, "SPACE") == 0) + || (strcmp(field->name, "SPACES") == 0); } static inline bool -is_quoted( const struct cbl_field_t *field ) { +is_quoted( const cbl_field_t *field ) { return field->has_attr(quoted_e); } @@ -1922,7 +2024,7 @@ struct cbl_until_addresses_t { }; size_t symbol_index(); // nth after first program symbol -size_t symbol_index( const struct symbol_elem_t *e ); +size_t symbol_index( const symbol_elem_t *e ); struct symbol_elem_t * symbol_at( size_t index ); struct cbl_options_t { @@ -1974,17 +2076,20 @@ symbol_field_forward_add( size_t program, size_t parent, struct cbl_field_t * symbol_field_forward( size_t index ); struct cbl_prog_hier_t { - size_t nlabel; struct program_label_t { size_t ordinal; cbl_label_t label; program_label_t() : ordinal(0), label() {} - program_label_t( const symbol_elem_t& e ) { + // because std::copy_if: + // cppcheck-suppress noExplicitConstructor + program_label_t( const symbol_elem_t& e ) { + assert(is_program(e)); ordinal = symbol_index(&e); label = e.elem.label; } - } *labels; - + }; + std::vector labels; + cbl_prog_hier_t(); }; @@ -2038,10 +2143,11 @@ struct cbl_perform_vary_t { struct cbl_refer_t by; // numeric struct cbl_field_t *until; // FldConditional - cbl_perform_vary_t( const cbl_refer_t& varying = cbl_refer_t(), - const cbl_refer_t& from = cbl_refer_t(), - const cbl_refer_t& by = cbl_refer_t(), - cbl_field_t *until = NULL ) + cbl_perform_vary_t() : until(nullptr) {} + cbl_perform_vary_t( const cbl_refer_t& varying, + const cbl_refer_t& from, + const cbl_refer_t& by, + cbl_field_t *until ) : varying(varying) , from(from) , by(by) @@ -2063,12 +2169,12 @@ is_literal( const cbl_field_t *field ) { } static inline bool -is_signable( const struct cbl_field_t *field ) { +is_signable( const cbl_field_t *field ) { return field->attr & signable_e; } static inline bool -is_temporary( const struct cbl_field_t *field ) { +is_temporary( const cbl_field_t *field ) { return field->attr & intermediate_e; } @@ -2203,7 +2309,7 @@ struct symbol_elem_t * symbol_special( size_t program, const char name[] ); struct symbol_elem_t * symbol_alphabet( size_t program, const char name[] ); struct symbol_elem_t * symbol_file( size_t program, const char name[] ); -struct cbl_field_t * symbol_file_record( struct cbl_file_t *file ); +struct cbl_field_t * symbol_file_record( const cbl_file_t *file ); cbl_file_t::varying_t symbol_file_record_sizes( struct cbl_file_t *file ); struct cbl_section_t * symbol_section( size_t program, struct cbl_section_t *section ); @@ -2213,7 +2319,7 @@ size_t symbol_label_id( const cbl_label_t *label ); struct cbl_field_t * parent_of( const cbl_field_t *f ); const cbl_field_t * occurs_in( const cbl_field_t *f ); -cbl_field_t *rename_not_ok( cbl_field_t *first, cbl_field_t *last); +cbl_field_t *rename_not_ok( const cbl_field_t *first, const cbl_field_t *last); bool immediately_follows( const cbl_field_t *first ); bool is_variable_length( const cbl_field_t *field ); @@ -2226,7 +2332,7 @@ uint64_t numeric_group_attrs( const cbl_field_t *field ); static inline struct cbl_field_t * field_at( size_t index ) { struct symbol_elem_t *e = symbol_at(index); - assert(e->type == SymField); + assert(e && e->type == SymField); return &e->elem.field; } @@ -2288,8 +2394,9 @@ class procref_base_t { private: const char *section_name, *paragraph_name; public: - procref_base_t( const char *section_name = NULL, - const char *paragraph_name = NULL ) + procref_base_t() : section_name(nullptr) , paragraph_name(nullptr) {} + procref_base_t( const char *section_name, + const char *paragraph_name ) : section_name(section_name) , paragraph_name(paragraph_name) {} @@ -2356,7 +2463,7 @@ refer_type_str( const cbl_refer_t *r ) { enum cbl_field_type_t symbol_field_type( size_t program, const char name[] ); -struct symbol_elem_t * symbol_parent( const struct symbol_elem_t *e ); +struct symbol_elem_t * symbol_parent( const symbol_elem_t *e ); int length_of_picture(const char *picture); int rdigits_of_picture(const char *picture); diff --git a/gcc/cobol/symfind.cc b/gcc/cobol/symfind.cc index 224f3ff6cf9..39df2a0390e 100644 --- a/gcc/cobol/symfind.cc +++ b/gcc/cobol/symfind.cc @@ -48,7 +48,7 @@ extern int yydebug; static bool is_data_field( symbol_elem_t& e ) { if( e.type != SymField ) return false; - auto f = cbl_field_of(&e); + const auto f = cbl_field_of(&e); if( f->name[0] == '\0' ) return false; if( is_filler(f) ) return false; @@ -129,7 +129,7 @@ finalize_symbol_map2() { for( auto& elem : symbol_map2 ) { auto& fields( elem.second ); fields.remove_if( []( auto isym ) { - auto f = cbl_field_of(symbol_at(isym)); + const auto f = cbl_field_of(symbol_at(isym)); return f->type == FldInvalid; } ); if( fields.empty() ) empties.insert(elem.first); @@ -341,7 +341,7 @@ class in_scope { size_t program; static size_t prog_of( size_t program ) { - auto L = cbl_label_of(symbol_at(program)); + const auto L = cbl_label_of(symbol_at(program)); return L->parent; } @@ -350,7 +350,7 @@ public: // A symbol is in scope if it's defined by this program or by an ancestor. bool operator()( const symbol_map_t::value_type& item ) const { - symbol_elem_t *e = symbol_at(item.second.front()); + const symbol_elem_t *e = symbol_at(item.second.front()); for( size_t prog = this->program; prog != 0; prog = prog_of(prog) ) { if( e->program == prog ) return true; } @@ -430,7 +430,7 @@ symbol_match2( size_t program, auto plist = symbol_map2.find(key); if( plist != symbol_map2.end() ) { for( auto candidate : plist->second ) { - auto e = symbol_at(candidate); + const auto e = symbol_at(candidate); if( name_has_names( e, names, local ) ) { fields.push_back( symbol_index(e) ); } diff --git a/gcc/cobol/token_names.h b/gcc/cobol/token_names.h index 682d68df2dc..4b24fc67769 100644 --- a/gcc/cobol/token_names.h +++ b/gcc/cobol/token_names.h @@ -691,6 +691,7 @@ tokens = { { "neg", NEG }, // 939 }; +// cppcheck-suppress useInitializationList token_names = { "IDENTIFICATION", // 0 (258) "ENVIRONMENT", // 1 (259) diff --git a/gcc/cobol/util.cc b/gcc/cobol/util.cc index 82a72f5f00a..b6c92802c79 100644 --- a/gcc/cobol/util.cc +++ b/gcc/cobol/util.cc @@ -365,51 +365,50 @@ normalize_picture( char picture[] ) regmatch_t pmatch[4]; if( (erc = regcomp(preg, regex, cflags)) != 0 ) { - regerror(erc, preg, regexmsg, sizeof(regexmsg)); - dbgmsg( "%s:%d: could not compile regex: %s", __func__, __LINE__, regexmsg ); - return picture; + regerror(erc, preg, regexmsg, sizeof(regexmsg)); + dbgmsg( "%s:%d: could not compile regex: %s", __func__, __LINE__, regexmsg ); + return picture; } while( (erc = regexec(preg, picture, COUNT_OF(pmatch), pmatch, 0)) == 0 ) { - assert(pmatch[1].rm_so != -1 && pmatch[1].rm_so < pmatch[1].rm_eo); - size_t len = pmatch[1].rm_eo - pmatch[1].rm_so; - assert(len == 1); - const char *start = picture + pmatch[1].rm_so; - - assert(pmatch[2].rm_so != -2 && pmatch[2].rm_so < pmatch[2].rm_eo); - len = pmatch[2].rm_eo - pmatch[2].rm_so; - assert(len > 0); - - /* - * Overwrite e.g. A(4) with AAAA. - */ - assert(pmatch[2].rm_so == pmatch[1].rm_eo + 1); // character paren number - p = picture + pmatch[2].rm_so; - len = 0; - fmt_size_t lenf = 0; - if( 1 != sscanf(p, "%" GCC_PRISZ "u", &lenf) ) { - dbgmsg("%s:%d: no number found in '%s'", __func__, __LINE__, p); - goto irregular; - } - len = lenf; - if( len == 0 ) { - dbgmsg("%s:%d: ZERO length found in '%s'", __func__, __LINE__, p); - goto irregular; - } + assert(pmatch[1].rm_so != -1 && pmatch[1].rm_so < pmatch[1].rm_eo); + size_t len = pmatch[1].rm_eo - pmatch[1].rm_so; + assert(len == 1); + const char *start = picture + pmatch[1].rm_so; + + assert(pmatch[2].rm_so != -2 && pmatch[2].rm_so < pmatch[2].rm_eo); + len = pmatch[2].rm_eo - pmatch[2].rm_so; + assert(len > 0); + + /* + * Overwrite e.g. A(4) with AAAA. + */ + assert(pmatch[2].rm_so == pmatch[1].rm_eo + 1); // character paren number + p = picture + pmatch[2].rm_so; + len = 0; + fmt_size_t lenf = 0; + if( 1 != sscanf(p, "%" GCC_PRISZ "u", &lenf) ) { + dbgmsg("%s:%d: no number found in '%s'", __func__, __LINE__, p); + goto irregular; + } + len = lenf; + if( len == 0 ) { + dbgmsg("%s:%d: ZERO length found in '%s'", __func__, __LINE__, p); + goto irregular; + } - std::vector pic(len + 1, '\0'); - memset(pic.data(), *start, len); - const char *finish = picture + pmatch[2].rm_eo, - *eopicture = picture + strlen(picture); + std::vector pic(len + 1, '\0'); + memset(pic.data(), *start, len); + const char *finish = picture + pmatch[2].rm_eo, + *eopicture = picture + strlen(picture); - p = xasprintf( "%*s%s%*s", - (int)(start - picture), picture, - pic.data(), - (int)(eopicture - finish), finish ); + p = xasprintf( "%*s%s%*s", + (int)(start - picture), picture, + pic.data(), + (int)(eopicture - finish), finish ); - free(picture); - picture = p; - continue; + free(picture); + picture = p; } assert(erc == REG_NOMATCH); @@ -792,7 +791,7 @@ symbol_field_type_update( cbl_field_t *field, bool redefine_field( cbl_field_t *field ) { - cbl_field_t *primary = symbol_redefines(field); + const cbl_field_t *primary = symbol_redefines(field); bool fOK = true; if( !primary ) return false; @@ -840,7 +839,7 @@ cbl_field_t::report_invalid_initial_value(const YYLTYPE& loc) const { // 8 or more, we need do no further testing because we assume // everything fits. if( data.capacity < 8 ) { - auto p = strchr(data.initial, symbol_decimal_point()); + const auto p = strchr(data.initial, symbol_decimal_point()); if( p && atoll(p+1) != 0 ) { error_msg(loc, "integer type %s VALUE '%s' " "requires integer VALUE", @@ -962,8 +961,7 @@ const cbl_field_t * literal_subscript_oob( const cbl_refer_t& r, size_t& isub /* output */) { // Verify literal subscripts if dimensions are correct. size_t ndim(dimensions(r.field)); - if( ndim == 0 || ndim != r.nsubscript ) return NULL; - cbl_refer_t *esub = r.subscripts + r.nsubscript; + if( ndim == 0 || ndim != r.nsubscript() ) return NULL; std::vector dims( ndim, NULL ); auto pdim = dims.end(); @@ -981,22 +979,20 @@ literal_subscript_oob( const cbl_refer_t& r, size_t& isub /* output */) { * for the corresponding dimension. Return the first subscript not * meeting those criteria, if any. */ - auto p = std::find_if( r.subscripts, esub, - [&pdim]( const cbl_refer_t& r ) { + auto psub = std::find_if( r.subscripts.begin(), r.subscripts.end(), + [pdim]( const cbl_refer_t& r ) mutable { const auto& occurs((*pdim)->occurs); pdim++; return ! occurs.subscript_ok(r.field); } ); - isub = p - r.subscripts; - return p == esub? NULL : dims[isub]; + isub = psub - r.subscripts.begin(); + return psub == r.subscripts.end()? NULL : dims[isub]; } size_t cbl_refer_t::subscripts_set( const std::list& subs ) { - nsubscript = subs.size(); - subscripts = new cbl_refer_t[nsubscript]; - std::copy( subs.begin(), subs.end(), subscripts ); - + subscripts.clear(); + std::copy( subs.begin(), subs.end(), std::back_inserter(subscripts) ); return dimensions(field); } @@ -1004,7 +1000,7 @@ const char * cbl_refer_t::str() const { static char subscripts[64]; sprintf(subscripts, "(%u of " HOST_SIZE_T_PRINT_UNSIGNED " dimensions)", - nsubscript, (fmt_size_t)dimensions(field)); + nsubscript(), (fmt_size_t)dimensions(field)); char *output = xasprintf("%s %s %s", field? field_str(field) : "(none)", 0 < dimensions(field)? subscripts : "", @@ -1020,18 +1016,18 @@ cbl_refer_t::name() const { const char * cbl_refer_t::deref_str() const { - std::vector dimstr(nsubscript * 16, '\0'); + std::vector dimstr(nsubscript() * 16, '\0'); dimstr.at(0) = '('; auto p = dimstr.begin() + 1; if( !field ) return name(); - for( auto sub = subscripts; sub < subscripts + nsubscript; sub++ ) { - auto initial = sub->field->data.initial ? sub->field->data.initial : "?"; + for( const auto& sub : subscripts ) { + auto initial = sub.field->data.initial ? sub.field->data.initial : "?"; size_t len = dimstr.end() - p; p += snprintf( &*p, len, "%s ", initial ); } - if( 0 < nsubscript ) { + if( ! subscripts.empty() ) { *--p = ')'; } char *output = xasprintf("%s%s", field->name, dimstr.data()); @@ -1383,7 +1379,7 @@ public: { assert(isym); } - procdef_t( const procref_base_t& ref ) + explicit procdef_t( const procref_base_t& ref ) : procref_base_t(ref) , isym(0) {} @@ -1392,13 +1388,6 @@ public: return procref_base_t(*this) < procref_base_t(that); } - bool operator<( const procref_base_t& that ) const { - if( that.has_section() ) { - return procref_base_t(*this) < that; - } - return strcasecmp(paragraph(), that.paragraph()) < 0; - } - cbl_label_t * label_of() const { return isym == 0? NULL : cbl_label_of(symbol_at(isym)); } @@ -1429,7 +1418,7 @@ static procedures_t::iterator current_procedure = programs.end()->second.end(); class procedure_match { const procref_base_t& ref; public: - procedure_match( const procref_base_t& ref ) : ref(ref) {} + explicit procedure_match( const procref_base_t& ref ) : ref(ref) {} // Match a 2-name reference to section & paragraph, else to one or the other. bool operator()( procedures_t::const_reference elem ) { const procdef_t& key = elem.first; @@ -1457,7 +1446,7 @@ locally_unique( size_t program, const procdef_t& key, const procref_t& ref ) { const char *section_name = ref.has_section()? ref.section() : key.section(); procref_base_t full_ref(section_name, ref.paragraph()); - return 1 == procedures.count(full_ref); + return 1 == procedures.count(procdef_t(full_ref)); } // Add each section and paragraph to the map as it occurs in the Cobol text. @@ -1519,9 +1508,9 @@ ambiguous_reference( size_t program ) { if( proc.second.end() != ambiguous ) { if( yydebug ) { dbgmsg("%s: %s of '%s' has " HOST_SIZE_T_PRINT_UNSIGNED - "potential matches", __func__, - ambiguous->paragraph(), ambiguous->section(), - (fmt_size_t)procedures.count(*ambiguous)); + "potential matches", __func__, + ambiguous->paragraph(), ambiguous->section(), + (fmt_size_t)procedures.count(procdef_t(*ambiguous))); } return new procref_t(*ambiguous); } @@ -1548,7 +1537,7 @@ intradeclarative_reference() { class next_group { size_t isym; public: - next_group( symbol_elem_t *group ) : isym(symbol_index(group)) {} + explicit next_group( const symbol_elem_t *group ) : isym(symbol_index(group)) {} // return true if elem is not a member of the group bool operator()( const symbol_elem_t& elem ) { @@ -1595,7 +1584,7 @@ public: static bool any_redefines( const cbl_field_t& field, const symbol_elem_t *group ) { for( const cbl_field_t *f = &field; f && f->parent > 0; f = parent_of(f) ) { - symbol_elem_t *e = symbol_at(f->parent); + const symbol_elem_t *e = symbol_at(f->parent); if( e == group || e->type != SymField ) break; if( symbol_redefines(f) ) return true; } @@ -1796,7 +1785,7 @@ class unique_stack : public std::stack bool push( const value_type& value ) { auto ok = std::none_of( c.cbegin(), c.cend(), - [value]( auto& that ) { + [value]( const auto& that ) { return value == that; } ); if( ok ) { @@ -1834,7 +1823,7 @@ class unique_stack : public std::stack void print() const { std::string input( top().name ); printf( "%s: ", input.c_str() ); - for( auto name : all_names ) { + for( const auto& name : all_names ) { if( name != input ) printf( "\\\n\t%s ", name.c_str() ); } @@ -1863,7 +1852,7 @@ void cobol_set_pp_option(int opt) { * to enforce uniqueness, and the scanner to maintain line numbers. */ bool cobol_filename( const char *name, ino_t inode ) { - line_map *lines = NULL; + const line_map *lines = NULL; if( inode == 0 ) { auto p = old_filenames.find(name); if( p == old_filenames.end() ) { @@ -1943,11 +1932,9 @@ verify_format( const char gmsgid[] ) { static regex_t re; static int cflags = REG_EXTENDED; static int status = regcomp( &re, pattern, cflags ); - static char errbuf[80]; - - if( status != 0 ) { + static char errbuf[80]; int n = regerror(status, &re, errbuf, sizeof(errbuf)); gcc_assert(size_t(n) < sizeof(errbuf)); fprintf(stderr, "%s:%d: %s", __func__, __LINE__, errbuf); @@ -1988,7 +1975,7 @@ extern YYLTYPE yylloc; * the global token_location, which is passed to the diagnostic framework. The * original value is restored when the instantiated variable goes out of scope. */ -class temp_loc_t : protected YYLTYPE { +class temp_loc_t { location_t orig; public: temp_loc_t() : orig(token_location) { @@ -1996,10 +1983,10 @@ class temp_loc_t : protected YYLTYPE { gcc_location_set(yylloc); // use lookahead location } - temp_loc_t( const YYLTYPE& loc) : orig(token_location) { + explicit temp_loc_t( const YYLTYPE& loc) : orig(token_location) { gcc_location_set(loc); } - temp_loc_t( const YDFLTYPE& loc) : orig(token_location) { + explicit temp_loc_t( const YDFLTYPE& loc) : orig(token_location) { YYLTYPE lloc = { loc.first_line, loc.first_column, loc.last_line, loc.last_column }; @@ -2246,7 +2233,7 @@ os_locale_t os_locale = { "UTF-8", xstrdup("C.UTF-8") }; void cobol_parse_files (int nfile, const char **files) { - char * opaque = setlocale(LC_CTYPE, ""); + const char * opaque = setlocale(LC_CTYPE, ""); if( ! opaque ) { yywarn("setlocale: unable to initialize LOCALE"); } else { diff --git a/gcc/cobol/util.h b/gcc/cobol/util.h index 44db645f140..54d3930100e 100644 --- a/gcc/cobol/util.h +++ b/gcc/cobol/util.h @@ -50,4 +50,11 @@ const char * cobol_lineno_save(); unsigned long gb4( size_t input ); +template +static inline const void * +as_voidp( P p ) { + return static_cast(p); +} + + #endif diff --git a/libgcobol/common-defs.h b/libgcobol/common-defs.h index 7336b15fcf7..a78022ae124 100644 --- a/libgcobol/common-defs.h +++ b/libgcobol/common-defs.h @@ -570,7 +570,7 @@ class cbl_enabled_exceptions_t : protected std::set : std::set(ecs, ecs + nec) {} void turn_on_off( bool enabled, bool location, ec_type_t type, - std::set files ); + const std::set& files ); const cbl_enabled_exception_t * match( ec_type_t ec, size_t file = 0 ) const;