diff --git a/gcc/cobol/ChangeLog b/gcc/cobol/ChangeLog index 51874c6e28777802b3bbfd1dbbacb227a3c97a0f..9e47d3161cb89121513b547a8ae2af84749a046e 100644 --- a/gcc/cobol/ChangeLog +++ b/gcc/cobol/ChangeLog @@ -20,3 +20,6 @@ trimmed .h files in structs.cc * Eliminate vestigial unused code from the PERFORM-PROC-AS_CALL experiment + * Introduce cbl_warning, cbl_error, cbl_internal_error. + convert genapi.cc to cbl_warning and cbl_internal_error + diff --git a/gcc/cobol/failures/playpen/playpen.cbl b/gcc/cobol/failures/playpen/playpen.cbl index 7cadc755138fbbd69d2c08e0dd1a2e8b80150fcb..8e17a1593460188fd5ebbbd258297773c101014b 100644 --- a/gcc/cobol/failures/playpen/playpen.cbl +++ b/gcc/cobol/failures/playpen/playpen.cbl @@ -6,7 +6,7 @@ use after exception condition ec-all. display " declarative for ec-all". end declaratives. - *>main section. + main section. display "hello". end program prog. diff --git a/gcc/cobol/genapi.cc b/gcc/cobol/genapi.cc index 3f5eb94b619ea8ba4abb29e2202e090067f24d59..8d0fc965ed409995763e51ee67214068a4939afc 100644 --- a/gcc/cobol/genapi.cc +++ b/gcc/cobol/genapi.cc @@ -34,6 +34,7 @@ #include "tree.h" #include "tree-iterator.h" #include "stringpool.h" +#include "diagnostic-core.h" #define HOWEVER_GCC_DEFINES_TREE 1 #include "symbols.h" @@ -46,6 +47,7 @@ #include "charmaps.h" #include "valconv.h" #include "show_parse.h" +#include "util.h" #define TSI_BACK (tsi_last(current_function->statement_list_stack.back())) @@ -558,8 +560,7 @@ get_class_condition_string(cbl_field_t *var) { if( strlen(ach) > sizeof(ach) - 1000 ) { - warnx("Nice try, but you can't fire me. I quit!"); - exit(1); + cbl_internal_error("Nice try, but you can't fire me. I quit!"); } // We are working with unquoted strings that contain the values 1 through @@ -726,7 +727,7 @@ parser_call_target_convention( tree func ) void parser_call_targets_dump() { - warnx( "call targets for #%zu", current_program_index() ); + cbl_warning( "call targets for #%zu", current_program_index() ); for( const auto& elem : call_targets ) { const auto& k = elem.first; const auto& v = elem.second; @@ -1470,11 +1471,10 @@ get_bytes_needed(cbl_field_t *field) } default: - warnx("%s(): Knows not the variable type %s for %s", + cbl_internal_error("%s(): Knows not the variable type %s for %s", __func__, cbl_field_type_str(field->type), field->name ); - gcc_assert(false); break; } return retval; @@ -2157,12 +2157,11 @@ move_tree( cbl_field_t *dest, if( !moved ) { - warnx("###### %10s in %s:%d\n", __func__, __FILE__, __LINE__ ); - warnx( "I don't know how to MOVE an alphabetical string to %s(%s) \n", + cbl_warning("###### %10s in %s:%d\n", __func__, __FILE__, __LINE__ ); + cbl_internal_error( "I don't know how to MOVE an alphabetical string to %s(%s) \n", cbl_field_type_str(dest->type), dest->name ); - gcc_assert(false); return; } } @@ -2226,9 +2225,10 @@ get_string_from(cbl_field_t *field) } default: - warnx( "%s(): field->type %s must be literal or alphanumeric", + cbl_internal_error( + "%s(): field->type %s must be literal or alphanumeric", __func__, cbl_field_type_str(field->type)); - gcc_assert(false); + break; } } else @@ -4138,8 +4138,8 @@ parser_accept( struct cbl_refer_t refer, case SYSIN_e: break; default: - warnx("%s(): We don't know what to do with special_name_t %d,", __func__, special_e); - warnx("%s(): so we are ignoring it.", __func__); + cbl_warning("%s(): We don't know what to do with special_name_t %d,", __func__, special_e); + cbl_warning("%s(): so we are ignoring it.", __func__); return; break; } @@ -5771,10 +5771,9 @@ tree_type_from_field_type(cbl_field_t *field, size_t &nbytes) break; default: - warnx( "%s(): Invalid field type %s:", + cbl_internal_error( "%s(): Invalid field type %s:", __func__, cbl_field_type_str(field->type)); - gcc_assert(false); break; } } @@ -5828,7 +5827,7 @@ is_valuable( cbl_field_type_t type ) { case FldPointer: return true; } - warnx( "%s:%d: invalid symbol_type_t %d", __func__, __LINE__, type ); + cbl_internal_error( "%s:%d: invalid symbol_type_t %d", __func__, __LINE__, type ); return false; } @@ -6985,24 +6984,21 @@ parser_logop( struct cbl_field_t *tgt, if( tgt->type != FldConditional ) { - warnx("parser_logop() was called with variable %s on line %d" + cbl_internal_error("parser_logop() was called with variable %s on line %d" ", which is not a FldConditional\n", tgt->name, cobol_location().first_line); - gcc_assert(false); } if( a && a->type != FldConditional ) { - warnx("parser_logop() was called with variable %s on line %d" + cbl_internal_error("parser_logop() was called with variable %s on line %d" ", which is not a FldConditional\n", a->name, cobol_location().first_line); - gcc_assert(false); } if( b && b->type != FldConditional ) { - warnx("parser_logop() was called with variable %s on line %d" + cbl_internal_error("parser_logop() was called with variable %s on line %d" ", which is not a FldConditional\n", b->name, cobol_location().first_line); - gcc_assert(false); } switch( logop ) @@ -7107,10 +7103,9 @@ parser_relop( cbl_field_t *tgt, if( tgt->type != FldConditional ) { - warnx("parser_relop() was called with variable %s, " + cbl_internal_error("parser_relop() was called with variable %s, " "which is not a FldConditional\n", tgt->name); - gcc_assert(false); } static tree comp_res = gg_define_variable(INT, "..pr_comp_res", vs_file_static); @@ -7172,10 +7167,9 @@ parser_relop_long(cbl_field_t *tgt, if( tgt->type != FldConditional ) { - warnx("parser_relop() was called with variable %s, " + cbl_internal_error("parser_relop() was called with variable %s, " "which is not a FldConditional\n", tgt->name); - gcc_assert(false); } tree tree_a = build_int_cst_type(LONG, avalue); @@ -7219,10 +7213,9 @@ parser_if( struct cbl_field_t *conditional ) if( conditional->type != FldConditional ) { - warnx("parser_if() was called with variable %s, " + cbl_internal_error("parser_if() was called with variable %s, " "which is not a FldConditional\n", conditional->name); - gcc_assert(false); } TRACE1 @@ -7471,8 +7464,9 @@ parser_setop( struct cbl_field_t *tgt, integer_zero_node)); break; default: - warnx("###### %10s in %s:%d\n", __func__, __FILE__, __LINE__ ); - warnx("###### candidate %s has unimplemented CVT_type %d(%s)\n", + cbl_warning("###### %10s in %s:%d\n", __func__, __FILE__, __LINE__ ); + cbl_internal_error( + "###### candidate %s has unimplemented CVT_type %d(%s)\n", candidate->name, candidate->type, cbl_field_type_str(candidate->type)); @@ -7482,8 +7476,8 @@ parser_setop( struct cbl_field_t *tgt, break; default: - warnx("###### %10s in %s:%d\n", __func__, __FILE__, __LINE__ ); - warnx("###### unknown setop_t code %d\n", op); + cbl_warning("###### %10s in %s:%d\n", __func__, __FILE__, __LINE__ ); + cbl_internal_error("###### unknown setop_t code %d\n", op); gcc_assert(false); break; } @@ -7679,7 +7673,7 @@ parser_perform_conditional( struct cbl_perform_tgt_t *tgt ) if( !(i < MAXIMUM_UNTILS) ) { - warnx("%s:%d: %zu exceeds MAXIMUM_UNTILS of %d, line %d", + cbl_internal_error("%s:%d: %zu exceeds MAXIMUM_UNTILS of %d, line %d", __func__, __LINE__, i, MAXIMUM_UNTILS, CURRENT_LINE_NUMBER); } gcc_assert(i < MAXIMUM_UNTILS); @@ -8685,7 +8679,7 @@ parser_perform_inline_times(struct cbl_perform_tgt_t *tgt, cbl_field_t *count = how_many.field; if( how_many.is_reference() ) { - warnx("%s:%d: ignoring subscripts", __func__, __LINE__); + cbl_internal_error("%s:%d: ignoring subscripts", __func__, __LINE__); } CHECK_FIELD(count); @@ -8903,7 +8897,7 @@ parser_file_add(struct cbl_file_t *file) if( !file ) { - warnx("%s(): called with NULL *file", __func__); + cbl_internal_error("%s(): called with NULL *file", __func__); gcc_assert(file); } @@ -9027,7 +9021,8 @@ parser_file_add(struct cbl_file_t *file) if(file->access == file_inaccessible_e) { - warnx("%s:%d file %s access mode is 'file_inaccessible_e' in %s", + cbl_internal_error( + "%s:%d file %s access mode is 'file_inaccessible_e' in %s", current_filename.back().c_str(), CURRENT_LINE_NUMBER, file->name, @@ -9100,20 +9095,17 @@ parser_file_open( struct cbl_file_t *file, int mode_char ) if( !file ) { - warnx("parser_file_open called with NULL *file"); - gcc_assert(file); + cbl_internal_error("parser_file_open called with NULL *file"); } if( !file->var_decl_node ) { - warnx("parser_file_open for %s called with NULL var_decl_node", file->name); - gcc_assert(file); + cbl_internal_error("parser_file_open for %s called with NULL var_decl_node", file->name); } if( mode_char == 'a' && (file->access != file_access_seq_e) ) { - warnx("EXTEND can only be used where %s is ACCESS MODE SEQUENTIAL", file->name); - gcc_assert(file); + cbl_internal_error("EXTEND can only be used where %s is ACCESS MODE SEQUENTIAL", file->name); } TRACE1 @@ -9181,14 +9173,12 @@ parser_file_close( struct cbl_file_t *file, file_close_how_t how ) if( !file ) { - warnx("parser_file_close called with NULL *file"); - gcc_assert(file); + cbl_internal_error("parser_file_close called with NULL *file"); } if( !file->var_decl_node ) { - warnx("parser_file_close for %s called with NULL file->var_decl_node", file->name); - gcc_assert(file); + cbl_internal_error("parser_file_close for %s called with NULL file->var_decl_node", file->name); } TRACE1 @@ -9241,7 +9231,7 @@ parser_file_read( struct cbl_file_t *file, if( where == 0 ) { - warnx("%s:%d file %s 'where' is zero in %s", + cbl_internal_error("%s:%d file %s 'where' is zero in %s", current_filename.back().c_str(), CURRENT_LINE_NUMBER, file->name, @@ -9251,31 +9241,27 @@ parser_file_read( struct cbl_file_t *file, if( !file ) { - warnx("parser_file_read called with NULL *file"); - gcc_assert(file); + cbl_internal_error("parser_file_read called with NULL *file"); } if( !file->var_decl_node ) { - warnx("parser_file_read for %s called with NULL file->var_decl_node", file->name); - gcc_assert(file); + cbl_internal_error("parser_file_read for %s called with NULL file->var_decl_node", file->name); } if( !file ) { - warnx("parser_file_read called with NULL *field"); - gcc_assert(file); + cbl_internal_error("parser_file_read called with NULL *field"); } if( !file->var_decl_node ) { - warnx("parser_file_read for %s called with NULL field->var_decl_node", file->name); - gcc_assert(file); + cbl_internal_error("parser_file_read for %s called with NULL field->var_decl_node", file->name); } if( file->access == file_access_seq_e && where >= 0) { - warnx("%s:%d file %s is RELATIVE/SEQUENTIAL, but 'where' >= 0", + cbl_internal_error("%s:%d file %s is RELATIVE/SEQUENTIAL, but 'where' >= 0", current_filename.back().c_str(), CURRENT_LINE_NUMBER, file->name); @@ -9284,7 +9270,7 @@ parser_file_read( struct cbl_file_t *file, if( file->access == file_access_rnd_e && where < 0) { - warnx("%s:%d file %s is RELATIVE/RANDOM, but 'where' < 0", + cbl_internal_error("%s:%d file %s is RELATIVE/RANDOM, but 'where' < 0", current_filename.back().c_str(), CURRENT_LINE_NUMBER, file->name); @@ -9327,7 +9313,7 @@ parser_file_write( cbl_file_t *file, if( (is_random ? 1 : 0) != (sequentially ? 0 : 1) ) { - warnx("%s:%d file %s 'sequentially' is %d in %s", + cbl_internal_error("%s:%d file %s 'sequentially' is %d in %s", current_filename.back().c_str(), CURRENT_LINE_NUMBER, file->name, @@ -9371,26 +9357,25 @@ parser_file_write( cbl_file_t *file, if( !file ) { - warnx("%s(): called with NULL *file", __func__); - gcc_assert(file); + cbl_internal_error("%s(): called with NULL *file", __func__); } if( !file->var_decl_node ) { - warnx("%s(): for %s called with NULL file->var_decl_node", __func__, file->name); - gcc_assert(file); + cbl_internal_error("%s(): for %s called with NULL file->var_decl_node", + __func__, file->name); } if( !file ) { - warnx("%s(): called with NULL *field", __func__); - gcc_assert(file); + cbl_internal_error("%s(): called with NULL *field", __func__); } if( !file->var_decl_node ) { - warnx("%s(): for %s called with NULL field->var_decl_node", __func__, file->name); - gcc_assert(file); + cbl_internal_error( "%s(): for %s called with NULL field->var_decl_node", + __func__, + file->name); } static tree t_advance = gg_define_variable(INT, "..pfw_advance", vs_file_static); @@ -9522,7 +9507,8 @@ parser_file_rewrite(cbl_file_t *file, && file->access == file_access_seq_e && !sequentially ) { - warnx("%s:%d file %s is INDEXED/SEQUENTIAL, but 'sequentially' is false", + cbl_internal_error( + "%s:%d file %s is INDEXED/SEQUENTIAL, but 'sequentially' is false", current_filename.back().c_str(), CURRENT_LINE_NUMBER, file->name); @@ -11174,10 +11160,9 @@ parser_sort(cbl_refer_t tableref, gcc_assert(table->var_decl_node); if( !is_table(table) ) { - warnx( "%s(): asked to sort %s, but it's not a table", + cbl_internal_error( "%s(): asked to sort %s, but it's not a table", __func__, tableref.field->name); - gcc_assert(false); } size_t total_keys = 0; for( size_t i=0; i<nkeys; i++ ) @@ -11303,10 +11288,9 @@ parser_file_sort( cbl_file_t *workfile, else { // Having both or neither violates SORT syntax - warnx("%s(): syntax error -- both (or neither) USING " + cbl_internal_error("%s(): syntax error -- both (or neither) USING " "and input-proc are specified", __func__); - gcc_assert(false); } parser_file_close(workfile); @@ -11433,9 +11417,8 @@ parser_file_sort( cbl_file_t *workfile, } else { - warnx("%s(): syntax error -- both (or neither) GIVING " + cbl_internal_error("%s(): syntax error -- both (or neither) GIVING " "and output-proc are specified", __func__); - gcc_assert(false); } } @@ -11851,9 +11834,8 @@ parser_file_merge( cbl_file_t *workfile, } else { - warnx("%s(): syntax error -- both (or neither) " + cbl_internal_error("%s(): syntax error -- both (or neither) " "files and output-proc are specified", __func__); - gcc_assert(false); } } @@ -12527,9 +12509,9 @@ create_and_call(size_t narg, } else { - warnx("%s(): What in the name of Nero's fiddle are we doing here?", + cbl_internal_error( + "%s(): What in the name of Nero's fiddle are we doing here?", __func__); - gcc_assert(false); } } else @@ -14151,11 +14133,12 @@ mh_source_is_literalN(cbl_refer_t &destref, } default: - warnx("In parser_move(%s to %s), the move of FldLiteralN to %s hasn't been implemented", + cbl_internal_error( + "In parser_move(%s to %s), the move of FldLiteralN to %s " + "hasn't been implemented", sourceref.field->name, destref.field->name, cbl_field_type_str(destref.field->type)); - gcc_assert(false); break; } } @@ -14387,13 +14370,12 @@ mh_dest_is_float( cbl_refer_t &destref, } default: - warnx("In mh_dest_is_float(%s to %s), the " - "move of %s to %s hasn't been implemented", + cbl_internal_error("In mh_dest_is_float(%s to %s), the " + "move of %s to %s hasn't been implemented", sourceref.field->name, destref.field->name, cbl_field_type_str(sourceref.field->type), cbl_field_type_str(destref.field->type)); - gcc_assert(false); break; } } @@ -16571,8 +16553,7 @@ parser_symbol_add(struct cbl_field_t *new_var ) // Make sure we have a new variable to work with. if( !new_var ) { - warnx("parser_symbol_add() was called with a NULL new_var\n"); - gcc_assert(false); + cbl_internal_error("parser_symbol_add() was called with a NULL new_var\n"); } TRACE1 @@ -16580,7 +16561,10 @@ parser_symbol_add(struct cbl_field_t *new_var ) TRACE1_HEADER if( new_var->level ) { - gg_fprintf(trace_handle, 1, "%2.2d ", build_int_cst_type(INT, new_var->level)); + gg_fprintf( trace_handle, + 1, + "%2.2d ", + build_int_cst_type(INT, new_var->level)); } TRACE1_TEXT(new_var->name) TRACE1_TEXT_ABC(" (", cbl_field_type_str(new_var->type) ,")") @@ -16588,18 +16572,19 @@ parser_symbol_add(struct cbl_field_t *new_var ) { gg_fprintf( trace_handle, 1, " [%ld]", - build_int_cst_type(LONG, *(const long *)new_var->data.initial)); + build_int_cst_type(LONG, + *(const long *)new_var->data.initial)); } TRACE1_END } if( is_table(new_var) && new_var->data.capacity == 0) { - warnx( "%s(): %2.2d %s is a table, but it improperly has a capacity of zero", - __func__, - new_var->level, - new_var->name); - gcc_assert(false); + cbl_internal_error( + "%s(): %2.2d %s is a table, but it improperly has a capacity of zero", + __func__, + new_var->level, + new_var->name); } cbl_field_t *ancestor = NULL; @@ -16636,13 +16621,13 @@ parser_symbol_add(struct cbl_field_t *new_var ) if( ancestor == new_var ) { - warnx("parser_symbol_add(): %s is its own ancestor", new_var->name); - gcc_assert(false); + cbl_internal_error("parser_symbol_add(): %s is its own ancestor", + new_var->name); } if( !ancestor && (new_var->level > LEVEL01 && new_var->level <= LEVEL49 ) ) { - warnx("parser_symbol_add(): %2.2d %s has null ancestor", + cbl_internal_error("parser_symbol_add(): %2.2d %s has null ancestor", new_var->level, new_var->name); } @@ -16650,10 +16635,9 @@ parser_symbol_add(struct cbl_field_t *new_var ) // new_var's var_decl_node should be NULL at this point if( new_var->var_decl_node ) { - warnx( "parser_symbol_add( %s ) improperly has a non-null " + cbl_internal_error( "parser_symbol_add( %s ) improperly has a non-null " "var_decl_node\n", new_var->name); - gcc_assert(false); } switch( new_var->type ) @@ -16856,12 +16840,11 @@ parser_symbol_add(struct cbl_field_t *new_var ) && new_var->type != FldLiteralN && new_var->type != FldLiteralA ) { - warnx( "%s(): %2.2d %s<%s> improperly has a data.capacity of zero", + cbl_internal_error( "%s(): %2.2d %s<%s> improperly has a data.capacity of zero", __func__, new_var->level, new_var->name, cbl_field_type_str(new_var->type)); - gcc_assert(false); } new_var->var_decl_node = new_var_decl; diff --git a/gcc/cobol/util.cc b/gcc/cobol/util.cc index 662a17ca8c42b47296d651021a03eff8a70f4c6c..fcda77bfc3fa02d362d2dad1e10fb1a1ed7e9c84 100644 --- a/gcc/cobol/util.cc +++ b/gcc/cobol/util.cc @@ -2212,3 +2212,33 @@ cobol_parse_files (int nfile, const char **files) } } + +void +cbl_warning(const char *format_string, ...) + { + va_list ap; + char *ostring = xvasprintf(format_string, ap); + va_end(ap); + warning(0, "%s", ostring); + free(ostring); + } + +void +cbl_error(const char *format_string, ...) + { + va_list ap; + char *ostring = xvasprintf(format_string, ap); + va_end(ap); + error("%s", ostring); + free(ostring); + } + +void +cbl_internal_error(const char *format_string, ...) + { + va_list ap; + char *ostring = xvasprintf(format_string, ap); + va_end(ap); + internal_error("%s", ostring); + free(ostring); + } diff --git a/gcc/cobol/util.h b/gcc/cobol/util.h new file mode 100644 index 0000000000000000000000000000000000000000..c4ca3aea238ef74f29b6862cba68440ea60b8cd1 --- /dev/null +++ b/gcc/cobol/util.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2021-2024 Symas Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of the Symas Corporation nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _UTIL_H_ +#define _UTIL_H_ + +void cbl_warning(const char *format_string, ...); +void cbl_error(const char *format_string, ...); +void cbl_internal_error(const char *format_string, ...); + +#endif \ No newline at end of file