On Tue, May 06, 2025 at 05:11:51PM -0400, Jason Merrill wrote:
> Well, that's all very complicated but seems to make sense.  Can you also add
> short rationale comments to the changes in linemap_add and plugin_init?

So like this?

2025-05-07  Jakub Jelinek  <ja...@redhat.com>

        PR preprocessor/108900
        PR preprocessor/116047
        PR preprocessor/120061
        * files.cc (_cpp_stack_file): Revert 2025-03-28 change.
        * line-map.cc (linemap_add): Use
        SOURCE_LINE (from, linemap_included_from (map - 1)) + 1; instead of
        SOURCE_LINE (from, from[1].start_location); to compute to_line
        for LC_LEAVE.  For LC_ENTER included_from computation, look at
        map[-2] or even lower if map[-1] has the same start_location as
        map[0].

        * gcc.dg/plugin/plugin.exp: Add location-overflow-test-pr116047.c
        and location-overflow-test-pr120061.c.
        * gcc.dg/plugin/location_overflow_plugin.c (plugin_init): Don't error
        on unknown values, instead just break.  Handle 0x4fHHHHHH arguments
        differently.
        * gcc.dg/plugin/location-overflow-test-pr116047.c: New test.
        * gcc.dg/plugin/location-overflow-test-pr116047-1.h: New test.
        * gcc.dg/plugin/location-overflow-test-pr116047-2.h: New test.
        * gcc.dg/plugin/location-overflow-test-pr120061.c: New test.
        * gcc.dg/plugin/location-overflow-test-pr120061-1.h: New test.
        * gcc.dg/plugin/location-overflow-test-pr120061-2.h: New test.

--- libcpp/files.cc.jj  2025-05-03 11:02:02.502647404 +0200
+++ libcpp/files.cc     2025-05-05 21:09:18.042680877 +0200
@@ -1006,14 +1006,6 @@ _cpp_stack_file (cpp_reader *pfile, _cpp
                    && (pfile->line_table->highest_location
                        != LINE_MAP_MAX_LOCATION - 1));
 
-  if (decrement && LINEMAPS_ORDINARY_USED (pfile->line_table))
-    {
-      const line_map_ordinary *map
-       = LINEMAPS_LAST_ORDINARY_MAP (pfile->line_table);
-      if (map && map->start_location == pfile->line_table->highest_location)
-       decrement = false;
-    }
-
   if (decrement)
     pfile->line_table->highest_location--;
 
--- libcpp/line-map.cc.jj       2024-04-26 11:47:02.244168816 +0200
+++ libcpp/line-map.cc  2025-05-07 07:44:14.351845653 +0200
@@ -621,8 +621,8 @@ linemap_add (line_maps *set, enum lc_rea
         #include "included", inside the same "includer" file.  */
 
       linemap_assert (!MAIN_FILE_P (map - 1));
-      /* (MAP - 1) points to the map we are leaving. The
-        map from which (MAP - 1) got included should be the map
+      /* (MAP - 1) points to the map we are leaving.  The
+        map from which (MAP - 1) got included should be usually the map
         that comes right before MAP in the same file.  */
       from = linemap_included_from_linemap (set, map - 1);
 
@@ -630,7 +630,24 @@ linemap_add (line_maps *set, enum lc_rea
       if (to_file == NULL)
        {
          to_file = ORDINARY_MAP_FILE_NAME (from);
-         to_line = SOURCE_LINE (from, from[1].start_location);
+         /* Compute the line on which the map resumes, for #include this
+            should be the line after the #include line.  Usually FROM is
+            the map right before LC_ENTER map - the first map of the included
+            file, and in that case SOURCE_LINE (from, from[1].start_location);
+            computes the right line (and does handle even some special cases
+            (e.g. where for returning from <command line> we still want to
+            be at line 0 or some -traditional-cpp cases).  In rare cases
+            FROM can be followed by LC_RENAME created by linemap_line_start
+            for line right after #include line.  If that happens,
+            start_location of the FROM[1] map will be the same as
+            start_location of FROM[2] LC_ENTER, but FROM[1] start_location
+            might not have advance enough for moving to a full next line.
+            In that case compute the line of #include line and add 1 to it
+            to advance to the next line.  See PR120061.  */
+         if (from[1].reason == LC_RENAME)
+           to_line = SOURCE_LINE (from, linemap_included_from (map - 1)) + 1;
+         else
+           to_line = SOURCE_LINE (from, from[1].start_location);
          sysp = ORDINARY_MAP_IN_SYSTEM_HEADER_P (from);
        }
       else
@@ -660,11 +677,26 @@ linemap_add (line_maps *set, enum lc_rea
       if (set->depth == 0)
        map->included_from = 0;
       else
-       /* The location of the end of the just-closed map.  */
-       map->included_from
-         = (((map[0].start_location - 1 - map[-1].start_location)
-             & ~((loc_one << map[-1].m_column_and_range_bits) - 1))
-            + map[-1].start_location);
+       {
+         /* Compute location from whence this line map was included.
+            For #include this should be preferrably column 0 of the
+            line on which #include directive appears.
+            map[-1] is the just closed map and usually included_from
+            falls within that map.  In rare cases linemap_line_start
+            can insert a new LC_RENAME map for the line immediately
+            after #include line, in that case map[-1] will have the
+            same start_location as the new one and so included_from
+            would not be from map[-1] but likely map[-2].  If that
+            happens, mask off map[-2] m_column_and_range_bits bits
+            instead of map[-1].  See PR120061.  */
+         int i = -1;
+         while (map[i].start_location == map[0].start_location)
+           --i;
+         map->included_from
+           = (((map[0].start_location - 1 - map[i].start_location)
+               & ~((loc_one << map[i].m_column_and_range_bits) - 1))
+              + map[i].start_location);
+       }
       set->depth++;
       if (set->trace_includes)
        trace_include (set, map);
--- gcc/testsuite/gcc.dg/plugin/plugin.exp.jj   2025-01-02 20:54:32.508124675 
+0100
+++ gcc/testsuite/gcc.dg/plugin/plugin.exp      2025-05-06 10:49:48.768350236 
+0200
@@ -138,7 +138,9 @@ set plugin_test_list [list \
     { location_overflow_plugin.cc \
          location-overflow-test-1.c \
          location-overflow-test-2.c \
-         location-overflow-test-pr83173.c } \
+         location-overflow-test-pr83173.c \
+         location-overflow-test-pr116047.c \
+         location-overflow-test-pr120061.c } \
     { must_tail_call_plugin.cc \
          must-tail-call-1.c \
          must-tail-call-2.c } \
--- gcc/testsuite/gcc.dg/plugin/location_overflow_plugin.cc.jj  2024-12-09 
21:04:17.059805398 +0100
+++ gcc/testsuite/gcc.dg/plugin/location_overflow_plugin.cc     2025-05-07 
07:47:28.042198082 +0200
@@ -85,9 +85,18 @@ plugin_init (struct plugin_name_args *pl
     error_at (UNKNOWN_LOCATION, "missing plugin argument");
 
   /* With 64-bit locations, the thresholds are larger, so shift the base
-     location argument accordingly.  */
+     location argument accordingly, basically remap the GCC 14 32-bit
+     location_t argument values to 64-bit location_t counterparts.  There
+     is one exception for values slightly before the 32-bit location_t
+     LINE_MAP_MAX_LOCATION_WITH_PACKED_RANGES (0x50000000).  In that case
+     remap them to the same amount before the 64-bit location_t
+     LINE_MAP_MAX_LOCATION_WITH_PACKED_RANGES -
+     ((location_t) 0x50000000) << 31.  */
   gcc_assert (sizeof (location_t) == sizeof (uint64_t));
-  base_location = 1 + ((base_location - 1) << 31);
+  if (base_location >= 0x4f000000 && base_location <= 0x4fffffff)
+    base_location += (((location_t) 0x50000000) << 31) - 0x50000000;
+  else
+    base_location = 1 + ((base_location - 1) << 31);
 
   register_callback (plugin_info->base_name,
                     PLUGIN_PRAGMAS,
@@ -107,7 +116,7 @@ plugin_init (struct plugin_name_args *pl
       break;
 
     default:
-      error_at (UNKNOWN_LOCATION, "unrecognized value for plugin argument");
+      break;
     }
 
   return 0;
--- gcc/testsuite/gcc.dg/plugin/location-overflow-test-pr116047.c.jj    
2025-05-06 10:46:29.431071847 +0200
+++ gcc/testsuite/gcc.dg/plugin/location-overflow-test-pr116047.c       
2025-05-06 11:27:06.003811731 +0200
@@ -0,0 +1,5 @@
+/* PR preprocessor/116047 */
+/* { dg-do preprocess } */
+/* { dg-options "-nostdinc -std=c23 
-fplugin-arg-location_overflow_plugin-value=0x4ffe0180" } */
+#include "location-overflow-test-pr116047-1.h"
+/* { dg-final { scan-file location-overflow-test-pr116047.i 
"static_assert\[^\n\r]\*6\[^\n\r]\*== 6" } } */
--- gcc/testsuite/gcc.dg/plugin/location-overflow-test-pr116047-1.h.jj  
2025-05-06 10:46:29.431071847 +0200
+++ gcc/testsuite/gcc.dg/plugin/location-overflow-test-pr116047-1.h     
2025-05-06 11:21:54.172065679 +0200
@@ -0,0 +1,6 @@
+
+
+
+
+#include "location-overflow-test-pr116047-2.h"
+static_assert (__LINE__ == 6, "");
--- gcc/testsuite/gcc.dg/plugin/location-overflow-test-pr116047-2.h.jj  
2025-05-06 10:46:29.431071847 +0200
+++ gcc/testsuite/gcc.dg/plugin/location-overflow-test-pr116047-2.h     
2025-05-06 10:46:29.431071847 +0200
@@ -0,0 +1 @@
+int i;
--- gcc/testsuite/gcc.dg/plugin/location-overflow-test-pr120061.c.jj    
2025-05-06 10:46:29.432071833 +0200
+++ gcc/testsuite/gcc.dg/plugin/location-overflow-test-pr120061.c       
2025-05-06 10:46:29.432071833 +0200
@@ -0,0 +1,6 @@
+/* PR preprocessor/120061 */
+/* { dg-do preprocess } */
+/* { dg-options "-nostdinc -std=c23 
-fplugin-arg-location_overflow_plugin-value=0x61000000" } */
+#include "location-overflow-test-pr120061-1.h"
+static_assert (__LINE__ == 5, "");
+/* { dg-final { scan-file location-overflow-test-pr120061.i 
"static_assert\[^\n\r]\*5\[^\n\r]\*== 5" } } */
--- gcc/testsuite/gcc.dg/plugin/location-overflow-test-pr120061-1.h.jj  
2025-05-06 10:46:29.429071874 +0200
+++ gcc/testsuite/gcc.dg/plugin/location-overflow-test-pr120061-1.h     
2025-05-06 10:46:29.429071874 +0200
@@ -0,0 +1,6 @@
+
+
+
+
+#include "location-overflow-test-pr120061-2.h"
+
--- gcc/testsuite/gcc.dg/plugin/location-overflow-test-pr120061-2.h.jj  
2025-05-06 10:46:29.431071847 +0200
+++ gcc/testsuite/gcc.dg/plugin/location-overflow-test-pr120061-2.h     
2025-05-06 10:46:29.431071847 +0200
@@ -0,0 +1 @@
+int i;


        Jakub

Reply via email to