Hi David,

Here is a new version of the linemap patch (see my earlier emails for an updated
version of the test code).  I spent several days poring over the line map code,
and I think I understand it a little better now.  I also discovered
-fdump-internal-locations, and it was a big help.  If I use this switch with the
code from the test I posted with an initial offset of 0x60000001, I get the
following (I have removed some unnecessary fields for brevity):

ORDINARY MAP: 21
  source_location interval: 1610612805 <= loc < 1610612809
  file: location-overflow-test-pr83173.c
  starting at line: 3
  reason: 2 (LC_RENAME)
location-overflow-test-pr83173.c:  3|loc:1610612805|  { dg-do preprocess }
location-overflow-test-pr83173.c:  4|loc:1610612806|*/
location-overflow-test-pr83173.c:  5|loc:1610612807|
location-overflow-test-pr83173.c:  6|loc:1610612808|#include 
"location-overflow-test-pr83173.h"

ORDINARY MAP: 22
  source_location interval: 1610612809 <= loc < 1610612810
  file: location-overflow-test-pr83173.h
  starting at line: 1
  reason: 0 (LC_ENTER)
location-overflow-test-pr83173.h:  1|loc:1610612809|#include 
"location-overflow-test-pr83173-1.h"

ORDINARY MAP: 23
  source_location interval: 1610612810 <= loc < 1610612812
  file: location-overflow-test-pr83173-1.h
  starting at line: 1
  reason: 0 (LC_ENTER)
location-overflow-test-pr83173-1.h:  1|loc:1610612810|#pragma once
location-overflow-test-pr83173-1.h:  2|loc:1610612811|#define 
LOCATION_OVERFLOW_TEST_PR83173_1_H

ORDINARY MAP: 24
  source_location interval: 1610612812 <= loc < 1610612812
  file: location-overflow-test-pr83173.h
  starting at line: 2
  reason: 1 (LC_LEAVE)

ORDINARY MAP: 25
  source_location interval: 1610612812 <= loc < 1610612814
  file: location-overflow-test-pr83173-2.h
  starting at line: 1
  reason: 0 (LC_ENTER)
location-overflow-test-pr83173-2.h:  1|loc:1610612812|#pragma once
location-overflow-test-pr83173-2.h:  2|loc:1610612813|#define 
LOCATION_OVERFLOW_TEST_PR83173_2_H

ORDINARY MAP: 26
  source_location interval: 1610612814 <= loc < 1610612815
  file: location-overflow-test-pr83173.h
  starting at line: 2
  reason: 1 (LC_LEAVE)
location-overflow-test-pr83173.h:  2|loc:1610612814|#include 
"location-overflow-test-pr83173-2.h"

ORDINARY MAP: 27
  source_location interval: 1610612815 <= loc < 1610612823
  file: location-overflow-test-pr83173.c
  starting at line: 7
  reason: 1 (LC_LEAVE)

ORDINARY MAP: 28
  source_location interval: 1610612823 <= loc < 1610612825
  file: location-overflow-test-pr83173.c
  starting at line: 15
  reason: 2 (LC_RENAME)

Notice that map 24 and 25 have the same start_location.  This is because
line_table->highest_location is being decremented when it should not be.  This
new patch uses a more robust method to check whether the source line that
highest_location refers to is greater than loc (which is the source_location of
the #include).  Instead of comparing the source_location values directly, I use
linemap_get_expansion_line to map the source location to a line number, and then
compare the line numbers.  This handles the case that loc is an adhoc location.
I noticed that after updating the filenames in the test to be
'location-overflow-test-pr83173-1.h', the source locations passed into
_cpp_stack_include were adhoc locations when I wasn't using the location offset
plugin.  This is because these filenames are now 34 characters long, which is
longer than the 5 range bits that an ordinary source_location allows.

I spent a lot of time comparing the -fdump-internal-locations output when this
patch is in use to the unpatched version.  The only differences occur when a
#include is the last line in the file.  For the case where the source location >
LINE_MAP_MAX_SOURCE_LOCATION, the ordinary map 25 (see above) now starts at
1610612813 instead of 1610612812.  For the case where the source location <
LINE_MAP_MAX_LOCATION_WITH_COLS, the start location of that map has increased by
32 (which is effectively one column).  For the case where the source location is
between LINE_MAP_MAX_LOCATION_WITH_COLS and LINE_MAP_MAX_SOURCE_LOCATION (so
that there are no range bits), the output was unchanged.  I can post these
location map dumps if you would like to see them.

There are no regressions in the gcc test suite from this patch.

The other addition in this version if the patch is a small improvement to the
-fdump-internal-locations output to include the reason and included_from fields
from the line_map_ordinary data structure.  I aos fixed an issue with the output
alignment.  I found this useful when evaluating these changes.

Thanks,
Mike
From e3f23f66ad18598fc21a9223b7f29572a14d1588 Mon Sep 17 00:00:00 2001
From: Mike Gulick <mgul...@mathworks.com>
Date: Fri, 1 Dec 2017 09:43:22 -0500
Subject: [PATCH v2] PR preprocessor/83173: Additional check before
 decrementing highest_location

2017-12-01  Mike Gulick  <mgul...@mathworks.com>

	PR preprocessor/83173
	* libcpp/files.c (_cpp_stack_include): Check if
	line_table->highest_location is past current line before
	decrementing.

	* gcc/input.c (dump_location_info): Dump reason and
	included_from fields from line_map_ordinary struct.  Fix
	indentation when location > 5 digits.

	* libcpp/location-example.txt: Update example
	-fdump-internal-locations output.
---
 gcc/input.c                 |  43 +++++++-
 libcpp/files.c              |  32 ++++--
 libcpp/location-example.txt | 261 +++++++++++++++++++++++++-------------------
 3 files changed, 214 insertions(+), 122 deletions(-)

diff --git a/gcc/input.c b/gcc/input.c
index 081e7856916..c7619703625 100644
--- a/gcc/input.c
+++ b/gcc/input.c
@@ -1077,6 +1077,17 @@ dump_labelled_location_range (FILE *stream,
   fprintf (stream, "\n");
 }
 
+#define NUM_DIGITS(x) ((x) >= 1000000000 ? 10 : \
+		       (x) >= 100000000 ? 9 : \
+		       (x) >= 10000000 ? 8 : \
+		       (x) >= 1000000 ? 7 : \
+		       (x) >= 100000 ? 6 : \
+		       (x) >= 10000 ? 5 : \
+		       (x) >= 1000 ? 4 : \
+		       (x) >= 100 ? 3 : \
+		       (x) >= 10 ? 2 : \
+		       1)
+
 /* Write a visualization of the locations in the line_table to STREAM.  */
 
 void
@@ -1106,6 +1117,29 @@ dump_location_info (FILE *stream)
 	       map->m_column_and_range_bits - map->m_range_bits);
       fprintf (stream, "  range bits: %i\n",
 	       map->m_range_bits);
+      const char * reason;
+      switch (map->reason) {
+      case LC_ENTER:
+	reason = "LC_ENTER";
+	break;
+      case LC_LEAVE:
+	reason = "LC_LEAVE";
+	break;
+      case LC_RENAME:
+	reason = "LC_RENAME";
+	break;
+      case LC_RENAME_VERBATIM:
+	reason = "LC_RENAME_VERBATIM";
+	break;
+      case LC_ENTER_MACRO:
+	reason = "LC_RENAME_MACRO";
+	break;
+      default:
+	reason = "Unknown";
+      }
+      fprintf (stream, "  reason: %d (%s)\n", map->reason, reason);
+      fprintf (stream, "  included from idx: %d\n",
+	       ORDINARY_MAP_INCLUDER_FILE_INDEX (map));
 
       /* Render the span of source lines that this "map" covers.  */
       for (source_location loc = MAP_START_LOCATION (map);
@@ -1141,7 +1175,14 @@ dump_location_info (FILE *stream)
 	      if (max_col > line_size)
 		max_col = line_size + 1;
 
-	      int indent = 14 + strlen (exploc.file);
+	      int len_lnum = NUM_DIGITS (exploc.line);
+	      if (len_lnum < 3)
+		len_lnum = 3;
+	      int len_loc = NUM_DIGITS (loc);
+	      if (len_loc < 5)
+		len_loc = 5;
+
+	      int indent = 6 + strlen (exploc.file) + len_lnum + len_loc;
 
 	      /* Thousands.  */
 	      if (end_location > 999)
diff --git a/libcpp/files.c b/libcpp/files.c
index e8d21b28e62..543730b9267 100644
--- a/libcpp/files.c
+++ b/libcpp/files.c
@@ -1012,6 +1012,7 @@ _cpp_stack_include (cpp_reader *pfile, const char *fname, int angle_brackets,
   struct cpp_dir *dir;
   _cpp_file *file;
   bool stacked;
+  bool decremented = false;
 
   /* For -include command-line flags we have type == IT_CMDLINE.
      When the first -include file is processed we have the case, where
@@ -1035,20 +1036,33 @@ _cpp_stack_include (cpp_reader *pfile, const char *fname, int angle_brackets,
     return false;
 
   /* Compensate for the increment in linemap_add that occurs if
-      _cpp_stack_file actually stacks the file.  In the case of a
-     normal #include, we're currently at the start of the line
-     *following* the #include.  A separate source_location for this
-     location makes no sense (until we do the LC_LEAVE), and
-     complicates LAST_SOURCE_LINE_LOCATION.  This does not apply if we
-     found a PCH file (in which case linemap_add is not called) or we
-     were included from the command-line.  */
+     _cpp_stack_file actually stacks the file.  In the case of a normal
+     #include, we're currently at the start of the line *following* the
+     #include.  A separate source_location for this location makes no
+     sense (until we do the LC_LEAVE), and complicates
+     LAST_SOURCE_LINE_LOCATION.  This does not apply if we found a PCH
+     file (in which case linemap_add is not called) or we were included
+     from the command-line.  In the case that the #include is the last
+     line in the file, highest_location still points to the current
+     line, not the start of the next line, so we do not decrement in
+     this case.  See plugin/location-overflow-test-pr83173.h for an
+     example.  */
   if (file->pchname == NULL && file->err_no == 0
       && type != IT_CMDLINE && type != IT_DEFAULT)
-    pfile->line_table->highest_location--;
+    {
+      int highest_line = linemap_get_expansion_line (pfile->line_table,
+						     pfile->line_table->highest_location);
+      int source_line = linemap_get_expansion_line (pfile->line_table, loc);
+      if (highest_line > source_line)
+	{
+	  pfile->line_table->highest_location--;
+	  decremented = true;
+	}
+    }
 
   stacked = _cpp_stack_file (pfile, file, type == IT_IMPORT, loc);
 
-  if (!stacked)
+  if (decremented && !stacked)
     /* _cpp_stack_file didn't stack the file, so let's rollback the
        compensation dance we performed above.  */
     pfile->line_table->highest_location++;
diff --git a/libcpp/location-example.txt b/libcpp/location-example.txt
index 14b5c2e284a..c6b8f7be881 100644
--- a/libcpp/location-example.txt
+++ b/libcpp/location-example.txt
@@ -33,8 +33,11 @@ ORDINARY MAP: 0
   source_location interval: 32 <= loc < 64
   file: test.c
   starting at line: 1
-  column bits: 12
+  column and range bits: 12
+  column bits: 7
   range bits: 5
+  reason: 0 (LC_ENTER)
+  included from idx: -1
 test.c:  1|loc:   32|#include "test.h"
                     |69269258258148147
                     |46802468024680246
@@ -43,186 +46,220 @@ ORDINARY MAP: 1
   source_location interval: 64 <= loc < 96
   file: <built-in>
   starting at line: 0
+  column and range bits: 0
   column bits: 0
   range bits: 0
+  reason: 2 (LC_RENAME)
+  included from idx: -1
 
 ORDINARY MAP: 2
   source_location interval: 96 <= loc < 128
   file: <command-line>
   starting at line: 0
+  column and range bits: 0
   column bits: 0
   range bits: 0
+  reason: 2 (LC_RENAME)
+  included from idx: -1
 
 ORDINARY MAP: 3
-  source_location interval: 128 <= loc < 160128
+  source_location interval: 128 <= loc < 250240
   file: /usr/include/stdc-predef.h
   starting at line: 1
-  column bits: 12
+  column and range bits: 12
+  column bits: 7
   range bits: 5
+  reason: 0 (LC_ENTER)
+  included from idx: 2
 (contents of /usr/include/stdc-predef.h snipped for brevity)
 
 ORDINARY MAP: 4
-  source_location interval: 160128 <= loc < 160160
+  source_location interval: 250240 <= loc < 250272
   file: <command-line>
   starting at line: 32
-  column bits: 12
+  column and range bits: 12
+  column bits: 7
   range bits: 5
+  reason: 1 (LC_LEAVE)
+  included from idx: -1
 
 ORDINARY MAP: 5
-  source_location interval: 160160 <= loc < 164256
+  source_location interval: 250272 <= loc < 254368
   file: test.c
   starting at line: 1
-  column bits: 12
+  column and range bits: 12
+  column bits: 7
   range bits: 5
-test.c:  1|loc:160160|#include "test.h"
-                    |00000000000000000
-                    |12223334445556667
-                    |92582581481470470
-                    |24680246802468024
+  reason: 2 (LC_RENAME)
+  included from idx: -1
+test.c:  1|loc:250272|#include "test.h"
+                     |00000000000000000
+                     |33344445556667778
+                     |03603692692582581
+                     |46802468024680246
 
 ORDINARY MAP: 6
-  source_location interval: 164256 <= loc < 173280
+  source_location interval: 254368 <= loc < 263392
   file: test.h
   starting at line: 1
-  column bits: 12
+  column and range bits: 12
+  column bits: 7
   range bits: 5
-test.h:  1|loc:164256|extern int foo ();
-                    |444444444444444444
-                    |233344455566677788
-                    |825814814704703603
-                    |802468024680246802
-test.h:  2|loc:168352|
-                    |
-                    |
-                    |
-                    |
-test.h:  3|loc:172448|#define PLUS(A, B) A + B
-                    |222222222222222223333333
-                    |455566677788889990001112
-                    |814704703603692692582581
-                    |024680246802468024680246
+  reason: 0 (LC_ENTER)
+  included from idx: 5
+test.h:  1|loc:254368|extern int foo ();
+                     |444444444444444444
+                     |444455566677788899
+                     |036926925825814814
+                     |024680246802468024
+test.h:  2|loc:258464|
+                     |
+                     |
+                     |
+                     |
+test.h:  3|loc:262560|#define PLUS(A, B) A + B
+                     |222222222222233333333333
+                     |566677788899900011122223
+                     |925825814814704703603692
+                     |246802468024680246802468
 
 ORDINARY MAP: 7
-  source_location interval: 173280 <= loc < 202016
+  source_location interval: 263392 <= loc < 292128
   file: test.c
   starting at line: 2
-  column bits: 12
+  column and range bits: 12
+  column bits: 7
   range bits: 5
-test.c:  2|loc:173280|
-                    |
-                    |
-                    |
-                    |
-test.c:  3|loc:177376|int
-                    |777
-                    |444
-                    |047
-                    |802
-test.c:  4|loc:181472|main (int argc, char **argv)
-                    |1111111111111111222222222222
-                    |5556666777888999000111222333
-                    |0360369269258258148147047036
-                    |4680246802468024680246802468
-test.c:  5|loc:185568|{
-                    |5
-                    |6
-                    |0
-                    |0
-test.c:  6|loc:189664|  int a = PLUS (1,2);
-                    |999999999900000000000
-                    |677788899900011122233
-                    |926925825814814704703
-                    |680246802468024680246
-test.c:  7|loc:193760|  int b = PLUS (3,4);
-                    |333333344444444444444
-                    |788899900011122233344
-                    |925825814814704703603
-                    |246802468024680246802
-test.c:  8|loc:197856|  return 0;
-                    |77778888888
-                    |89990001112
-                    |82581481470
-                    |80246802468
-test.c:  9|loc:201952|}
-                    |1
-                    |9
-                    |8
-                    |4
+  reason: 1 (LC_LEAVE)
+  included from idx: -1
+test.c:  2|loc:263392|
+                     |
+                     |
+                     |
+                     |
+test.c:  3|loc:267488|int
+                     |777
+                     |555
+                     |258
+                     |024
+test.c:  4|loc:271584|main (int argc, char **argv)
+                     |1111111111112222222222222222
+                     |6667778889990000111222333444
+                     |1481470470360369269258258148
+                     |6802468024680246802468024680
+test.c:  5|loc:275680|{
+                     |5
+                     |7
+                     |1
+                     |2
+test.c:  6|loc:279776|  int a = PLUS (1,2);
+                     |999999000000000000000
+                     |888999000011122233344
+                     |047036036926925825814
+                     |802468024680246802468
+test.c:  7|loc:283872|  int b = PLUS (3,4);
+                     |333444444444444444444
+                     |999000011122233344455
+                     |036036926925825814814
+                     |468024680246802468024
+test.c:  8|loc:287968|  return 0;
+                     |88888888888
+                     |00001112223
+                     |03692692582
+                     |02468024680
+test.c:  9|loc:292064|}
+                     |2
+                     |0
+                     |9
+                     |6
 
 UNALLOCATED LOCATIONS
-  source_location interval: 202016 <= loc < 2147483633
+  source_location interval: 292128 <= loc < 2147483631
 
-MACRO 1: PLUS (7 tokens)
-  source_location interval: 2147483633 <= loc < 2147483640
-test.c:7:11: note: expansion point is location 194115
+MACRO 3: PLUS (7 tokens)
+  source_location interval: 2147483631 <= loc < 2147483638
+test.c:7:11: note: expansion point is location 284227
    int b = PLUS (3,4);
            ^~~~
-
-  map->start_location: 2147483633
+  map->start_location: 2147483631
   macro_locations:
-    0: 194304, 173088
-test.c:7:17: note: token 0 has x-location == 194304
+    0: 284416, 263200
+test.c:7:17: note: token 0 has x-location == 284416
    int b = PLUS (3,4);
                  ^
-
-test.c:7:17: note: token 0 has y-location == 173088
-    1: 173152, 173152
-In file included from test.c:1:0:
-test.h:3:22: note: token 1 has x-location == y-location == 173152
+test.c:7:17: note: token 0 has y-location == 263200
+    1: 263264, 263264
+In file included from test.c:1:
+test.h:3:22: note: token 1 has x-location == y-location == 263264
  #define PLUS(A, B) A + B
                       ^
-
-    2: 194368, 173216
-test.c:7:19: note: token 2 has x-location == 194368
+    2: 284480, 263328
+test.c:7:19: note: token 2 has x-location == 284480
    int b = PLUS (3,4);
                    ^
-
-test.c:7:19: note: token 2 has y-location == 173216
+test.c:7:19: note: token 2 has y-location == 263328
     3: 0, 2947526575
 cc1: note: token 3 has x-location == 0
 cc1: note: token 3 has y-location == 2947526575
     4: 2947526575, 2947526575
-x-location == y-location == 2947526575 encodes token # 800042942
+x-location == y-location == 2947526575 encodes token # 800042944
     5: 2947526575, 2947526575
-x-location == y-location == 2947526575 encodes token # 800042942
+x-location == y-location == 2947526575 encodes token # 800042944
     6: 2947526575, 2947526575
-x-location == y-location == 2947526575 encodes token # 800042942
+x-location == y-location == 2947526575 encodes token # 800042944
 
-MACRO 0: PLUS (7 tokens)
-  source_location interval: 2147483640 <= loc < 2147483647
-test.c:6:11: note: expansion point is location 190019
+MACRO 2: PLUS (7 tokens)
+  source_location interval: 2147483638 <= loc < 2147483645
+test.c:6:11: note: expansion point is location 280131
    int a = PLUS (1,2);
            ^~~~
-
-  map->start_location: 2147483640
+  map->start_location: 2147483638
   macro_locations:
-    0: 190208, 173088
-test.c:6:17: note: token 0 has x-location == 190208
+    0: 280320, 263200
+test.c:6:17: note: token 0 has x-location == 280320
    int a = PLUS (1,2);
                  ^
-
-test.c:6:17: note: token 0 has y-location == 173088
-    1: 173152, 173152
-In file included from test.c:1:0:
-test.h:3:22: note: token 1 has x-location == y-location == 173152
+test.c:6:17: note: token 0 has y-location == 263200
+    1: 263264, 263264
+In file included from test.c:1:
+test.h:3:22: note: token 1 has x-location == y-location == 263264
  #define PLUS(A, B) A + B
                       ^
-
-    2: 190272, 173216
-test.c:6:19: note: token 2 has x-location == 190272
+    2: 280384, 263328
+test.c:6:19: note: token 2 has x-location == 280384
    int a = PLUS (1,2);
                    ^
-
-test.c:6:19: note: token 2 has y-location == 173216
+test.c:6:19: note: token 2 has y-location == 263328
     3: 0, 2947526575
 cc1: note: token 3 has x-location == 0
 cc1: note: token 3 has y-location == 2947526575
     4: 2947526575, 2947526575
-x-location == y-location == 2947526575 encodes token # 800042935
+x-location == y-location == 2947526575 encodes token # 800042937
     5: 2947526575, 2947526575
-x-location == y-location == 2947526575 encodes token # 800042935
+x-location == y-location == 2947526575 encodes token # 800042937
     6: 2947526575, 2947526575
-x-location == y-location == 2947526575 encodes token # 800042935
+x-location == y-location == 2947526575 encodes token # 800042937
+
+MACRO 1: __GCC_IEC_559_COMPLEX (1 tokens)
+  source_location interval: 2147483645 <= loc < 2147483646
+In file included from <command-line>:31:
+/usr/include/stdc-predef.h:45:6: note: expansion point is location 180564
+ # if __GCC_IEC_559_COMPLEX > 0
+      ^~~~~~~~~~~~~~~~~~~~~
+  map->start_location: 2147483645
+  macro_locations:
+    0: 1, 1
+<built-in>: note: token 0 has x-location == y-location == 1
+
+MACRO 0: __GCC_IEC_559 (1 tokens)
+  source_location interval: 2147483646 <= loc < 2147483647
+/usr/include/stdc-predef.h:37:6: note: expansion point is location 147788
+ # if __GCC_IEC_559 > 0
+      ^~~~~~~~~~~~~
+  map->start_location: 2147483646
+  macro_locations:
+    0: 1, 1
+<built-in>: note: token 0 has x-location == y-location == 1
 
 MAX_SOURCE_LOCATION
   source_location interval: 2147483647 <= loc < 2147483648
-- 
2.11.0

Reply via email to