https://gcc.gnu.org/bugzilla/show_bug.cgi?id=44054
--- Comment #22 from Manuel López-Ibáñez <manu at gcc dot gnu.org> --- I think the two remaining issues are: 1) Multiple locations (%C/%L) in diagnostics 2) Support !GCC$ diagnostic (pragmas) For (2), I'm not planning to work on it since it seems all the common support is there, Fortran just needs to parse and handle the pragmas in the same way as the C/C++ FEs do. There may be some opportunity for code sharing (perhaps the pragmas are language specific and they should not be), but I haven't looked at the details. For (1), my plan is to add location_t location[2] to text_info and make diagnostic_context directly use those. The common part in diagnostic.c will need some refactoring to print two caret chars in the same line and to customize which caret char and which location is printed so that Fortran can print the second location on a different line with a different caret char when desired. The most tricky part is how to handle the prefix/locus_prefix difference when there is zero, one or two caret lines printed, in gfc_diagnostic_starter(). Handling two locations in gfc_format_decoder is trivial if one considers that the only way to set text->location[0] in Fortran is via gfc_format_decoder itself: --- gcc/fortran/error.c (revision 218628) +++ gcc/fortran/error.c (working copy) @@ -1056,25 +1056,26 @@ gfc_format_decoder (pretty_printer *pp, switch (*spec) { case 'C': case 'L': { - static const char *result = "(1)"; + static const char *result[2] = { "(1)", "(2)" }; locus *loc; if (*spec == 'C') loc = &gfc_current_locus; else loc = va_arg (*text->args_ptr, locus *); gcc_assert (loc->nextc - loc->lb->line >= 0); unsigned int offset = loc->nextc - loc->lb->line; - gcc_assert (text->locus); - *text->locus + /* If location[0] != UNKNOWN_LOCATION means that we already + processed one of %C/%L. */ + int loc_num = text->location[0] == UNKNOWN_LOCATION ? 0 : 1; + text->location[loc_num] = linemap_position_for_loc_and_offset (line_table, loc->lb->location, offset); - global_dc->caret_char = '1'; - pp_string (pp, result); + pp_string (pp, result[loc_num]); return true; } default: return false; }