This patch actually does not touch linemap but I will appreciate
Dodji's comments about the approach. The problem is that in case of
long lines, the column hint of 120 might be too small, thus we do not
have enough locations within one line to point to a higher column
(like 132 in the testcase). Giving as column hint the length of the
line seems the right fix.

The other issue that triggers with this testcase is that, even though
the column hint allows having line 6 + column 132, since we never
generate a location except for 6:0, if a new map is created for the
new line, then it will consider that the last location was 6:0 and the
new map for line 7 will start at location+1, hence, no offset within
line 6 can be represented. My fix here is to create a dummy location
for line_len -1 (the last column in the line). This forces the next
map to start after this last column's location.

I'm not sure if this latter fix is the approach we want to take. If
so, then we may want to change linemap.c itself to force new maps to
reserve enough locations for any offset in the line instead of doing
last_location+1. If not, perhaps the alternative implementation that
encodes offsets explicitly throughout the diagnostics machinery would
be better. In fact, diagnostic_info already contains an
override_column member:

struct diagnostic_info
{
  text_info message;
  location_t location;
  unsigned int override_column;
  ....

but I don't see a way to change that from within the function that
formats %L and %C:

static bool
gfc_format_decoder (pretty_printer *pp,
            text_info *text, const char *spec,
            int precision ATTRIBUTE_UNUSED, bool wide ATTRIBUTE_UNUSED,
            bool plus ATTRIBUTE_UNUSED, bool hash ATTRIBUTE_UNUSED)

unless we move override_column to text_info. In fact,
diagnostic_info.text_info already contains a locus, which is a pointer
to diagnostic_info.location.

In any case, the current patch fixes these ICEs and I couldn't trigger
new ones. Bootstrapped and regression tested.

OK for Fortran?

gcc/fortran/ChangeLog:

2014-12-02  Manuel López-Ibáñez  <m...@gcc.gnu.org>

    * scanner.c (gfc_next_char_literal): Use gfc_warning_now.
    (load_file): Use the line length as the column hint for
    linemap_line_start. Reserve a location for the highest column of
    the line.

gcc/testsuite/ChangeLog:

2014-12-02  Manuel López-Ibáñez  <m...@gcc.gnu.org>

    * gfortran.dg/line_length_5.f90: New test.
Index: gcc/testsuite/gfortran.dg/line_length_5.f90
===================================================================
--- gcc/testsuite/gfortran.dg/line_length_5.f90 (revision 0)
+++ gcc/testsuite/gfortran.dg/line_length_5.f90 (revision 0)
@@ -0,0 +1,7 @@
+! { dg-do compile }
+! { dg-options "-Wline-truncation" }
+print *, 
'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'
+end 
+
+      print *, 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'
+! { dg-warning "Line truncated" " " { target *-*-* } 3 }
Index: gcc/fortran/scanner.c
===================================================================
--- gcc/fortran/scanner.c       (revision 218192)
+++ gcc/fortran/scanner.c       (working copy)
@@ -1054,11 +1054,12 @@ restart:
          int maxlen = gfc_option.free_line_length;
          gfc_char_t *current_nextc = gfc_current_locus.nextc;
 
          gfc_current_locus.lb->truncated = 0;
          gfc_current_locus.nextc =  gfc_current_locus.lb->line + maxlen;
-         gfc_warning_now_1 ("Line truncated at %L", &gfc_current_locus);
+         gfc_warning_now (OPT_Wline_truncation,
+                          "Line truncated at %L", &gfc_current_locus);
          gfc_current_locus.nextc = current_nextc;
        }
 
       if (c != '&')
        goto done;
@@ -1192,11 +1193,12 @@ restart:
       /* Check to see if the continuation line was truncated.  */
       if (warn_line_truncation && gfc_current_locus.lb != NULL
          && gfc_current_locus.lb->truncated)
        {
          gfc_current_locus.lb->truncated = 0;
-         gfc_warning_now_1 ("Line truncated at %L", &gfc_current_locus);
+         gfc_warning_now (OPT_Wline_truncation,
+                          "Line truncated at %L", &gfc_current_locus);
        }
 
       prev_openmp_flag = openmp_flag;
       continue_flag = 1;
       old_loc = gfc_current_locus;
@@ -2041,11 +2043,17 @@ load_file (const char *realfilename, con
 
       b = XCNEWVAR (gfc_linebuf, gfc_linebuf_header_size
                    + (len + 1) * sizeof (gfc_char_t));
 
       b->location
-       = linemap_line_start (line_table, current_file->line++, 120);
+       = linemap_line_start (line_table, current_file->line++, line_len);
+      /* ??? We add the location for the maximum column possible here,
+        because otherwise if the next call creates a new line-map, it
+        will not reserve space for any offset.  */
+      gcc_assert (line_len > 0);
+      linemap_position_for_column (line_table, line_len - 1);
+
       b->file = current_file;
       b->truncated = trunc;
       wide_strcpy (b->line, line);
 
       if (line_head == NULL)

Reply via email to