diff options
author | Tobias Burnus <tburnus@baylibre.com> | 2024-10-12 10:48:41 +0200 |
---|---|---|
committer | Tobias Burnus <tburnus@baylibre.com> | 2024-10-12 10:48:41 +0200 |
commit | c20c9d8408f0ff4677acbd96f4803c191bd13ac6 (patch) | |
tree | 05d8eab47fc0ea5febb89264feabd44ae19ac7b8 /gcc/fortran/error.cc | |
parent | a564261245ad3002d53916e017b85939ace816a6 (diff) | |
download | gcc-c20c9d8408f0ff4677acbd96f4803c191bd13ac6.zip gcc-c20c9d8408f0ff4677acbd96f4803c191bd13ac6.tar.gz gcc-c20c9d8408f0ff4677acbd96f4803c191bd13ac6.tar.bz2 |
Fortran: Unify gfc_get_location handling; fix expr->ts bug
This commit reduces code duplication by moving gfc_get_location
from trans.cc to error.cc. The gcc_assert is now used more often
and reveald a bug in gfc_match_array_constructor where the union
expr->ts.u.derived of a derived type is partially overwritten by
the assignment expr->ts.u.cl->... as a ts.type == BT_CHARACTER check
was missing.
gcc/fortran/ChangeLog:
* array.cc (gfc_match_array_constructor): Only update the
character length if the expression is of character type.
* error.cc (gfc_get_location_with_offset): New; split off
from ...
(gfc_format_decoder): ... here; call it.
* gfortran.h (gfc_get_location_with_offset): New prototype.
(gfc_get_location): New inline function.
* trans.cc (gfc_get_location): Remove function definition.
* trans.h (gfc_get_location): Remove declaration.
Diffstat (limited to 'gcc/fortran/error.cc')
-rw-r--r-- | gcc/fortran/error.cc | 34 |
1 files changed, 24 insertions, 10 deletions
diff --git a/gcc/fortran/error.cc b/gcc/fortran/error.cc index e6c05aa..d184ffd 100644 --- a/gcc/fortran/error.cc +++ b/gcc/fortran/error.cc @@ -50,6 +50,21 @@ static gfc_error_buffer error_buffer; static output_buffer *pp_error_buffer, *pp_warning_buffer; static int warningcount_buffered, werrorcount_buffered; + +/* Return a location_t suitable for 'tree' for a gfortran locus. During + parsing in gfortran, loc->lb->location contains only the line number + and LOCATION_COLUMN is 0; hence, the column has to be added when generating + locations for 'tree'. */ + +location_t +gfc_get_location_with_offset (locus *loc, unsigned offset) +{ + gcc_checking_assert (loc->nextc >= loc->lb->line); + return linemap_position_for_loc_and_offset (line_table, loc->lb->location, + loc->nextc - loc->lb->line + + offset); +} + /* Return buffered_p. */ bool gfc_buffered_p (void) @@ -411,6 +426,7 @@ gfc_format_decoder (pretty_printer *pp, text_info *text, const char *spec, int precision, bool wide, bool set_locus, bool hash, bool *quoted, pp_token_list &formatted_token_list) { + unsigned offset = 0; switch (*spec) { case 'C': @@ -419,21 +435,19 @@ gfc_format_decoder (pretty_printer *pp, text_info *text, const char *spec, static const char *result[2] = { "(1)", "(2)" }; locus *loc; if (*spec == 'C') - loc = &gfc_current_locus; + { + loc = &gfc_current_locus; + /* Point %C first offending character not the last good one. */ + if (*loc->nextc != '\0') + offset++; + } else loc = va_arg (*text->m_args_ptr, locus *); - gcc_assert (loc->nextc - loc->lb->line >= 0); - unsigned int offset = loc->nextc - loc->lb->line; - if (*spec == 'C' && *loc->nextc != '\0') - /* Point %C first offending character not the last good one. */ - offset++; + /* If location[0] != UNKNOWN_LOCATION means that we already processed one of %C/%L. */ int loc_num = text->get_location (0) == UNKNOWN_LOCATION ? 0 : 1; - location_t src_loc - = linemap_position_for_loc_and_offset (line_table, - loc->lb->location, - offset); + location_t src_loc = gfc_get_location_with_offset (loc, offset); text->set_location (loc_num, src_loc, SHOW_RANGE_WITH_CARET); /* Colorize the markers to match the color choices of diagnostic_show_locus (the initial location has a color given |