diff mbox

[committed] PR preprocessor/69985: fix ICE with long lines in -Wformat

Message ID 1456795688-4643-1-git-send-email-dmalcolm@redhat.com
State New
Headers show

Commit Message

David Malcolm March 1, 2016, 1:28 a.m. UTC
PR preprocessor/69985 reports an ICE due to the failure of:
   linemap_assert_fails (map == linemap_lookup (set, r)))

The root cause seems to be the range-packing optimization I added in
r230331; it looks like I forgot to update
linemap_position_for_loc_and_offset accordingly.  Sorry.

The following patch updates linemap_position_for_loc_and_offset, making
it clear that it accepts a *column* offset, and updating the function
to use m_range_bits of the appropiate ordinary maps accordingly.

I also found the:
  offset += column;
to be confusing, so I changed it to:
  column += offset;

Successfully bootstrapped&regrtested on x86_64-pc-linux-gnu.
Adds 2 PASS results to gcc.sum

Committed to trunk as r233836.

gcc/testsuite/ChangeLog:
	PR preprocessor/69985
	* gcc.dg/cpp/pr69985.c: New test case.

libcpp/ChangeLog:
	PR preprocessor/69985
	(linemap_position_for_loc_and_offset): Rename param from "offset"
	to "column_offset".  Right-shift the column_offset by m_range_bits
	of the pertinent ordinary map whenever offsetting a
	source_location.  For clarity, offset the column by the column
	offset, rather than the other way around.
---
 gcc/testsuite/gcc.dg/cpp/pr69985.c |  7 +++++++
 libcpp/line-map.c                  | 17 +++++++++--------
 2 files changed, 16 insertions(+), 8 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/cpp/pr69985.c
diff mbox

Patch

diff --git a/gcc/testsuite/gcc.dg/cpp/pr69985.c b/gcc/testsuite/gcc.dg/cpp/pr69985.c
new file mode 100644
index 0000000..28f17e9
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/cpp/pr69985.c
@@ -0,0 +1,7 @@ 
+/* { dg-options "-Wformat" } */
+extern int printf (const char *__restrict __format, ...);
+void test (void)
+{
+  /* A very long line, so that we start a new line map.  */
+  printf ("%llu01233456789012334567890123345678901233456789012334567890123345678901233456789012334567890123345678901233456789012334567890123345678901233456789"); /* { dg-warning "15: format .%llu. expects a matching" } */
+}
diff --git a/libcpp/line-map.c b/libcpp/line-map.c
index c05a001..264ae20 100644
--- a/libcpp/line-map.c
+++ b/libcpp/line-map.c
@@ -864,13 +864,13 @@  linemap_position_for_line_and_column (line_maps *set,
 }
 
 /* Encode and return a source_location starting from location LOC and
-   shifting it by OFFSET columns.  This function does not support
+   shifting it by COLUMN_OFFSET columns.  This function does not support
    virtual locations.  */
 
 source_location
 linemap_position_for_loc_and_offset (struct line_maps *set,
 				     source_location loc,
-				     unsigned int offset)
+				     unsigned int column_offset)
 {
   const line_map_ordinary * map = NULL;
 
@@ -882,7 +882,7 @@  linemap_position_for_loc_and_offset (struct line_maps *set,
       (!linemap_location_from_macro_expansion_p (set, loc)))
     return loc;
 
-  if (offset == 0
+  if (column_offset == 0
       /* Adding an offset to a reserved location (like
 	 UNKNOWN_LOCATION for the C/C++ FEs) does not really make
 	 sense.  So let's leave the location intact in that case.  */
@@ -894,7 +894,7 @@  linemap_position_for_loc_and_offset (struct line_maps *set,
   /* The new location (loc + offset) should be higher than the first
      location encoded by MAP.  This can fail if the line information
      is messed up because of line directives (see PR66415).  */
-  if (MAP_START_LOCATION (map) >= loc + offset)
+  if (MAP_START_LOCATION (map) >= loc + (column_offset << map->m_range_bits))
     return loc;
 
   linenum_type line = SOURCE_LINE (map, loc);
@@ -905,7 +905,8 @@  linemap_position_for_loc_and_offset (struct line_maps *set,
      the next line map of the set.  Otherwise, we try to encode the
      location in the next map.  */
   while (map != LINEMAPS_LAST_ORDINARY_MAP (set)
-	 && loc + offset >= MAP_START_LOCATION (&map[1]))
+	 && (loc + (column_offset << map->m_range_bits)
+	     >= MAP_START_LOCATION (&map[1])))
     {
       map = &map[1];
       /* If the next map starts in a higher line, we cannot encode the
@@ -914,12 +915,12 @@  linemap_position_for_loc_and_offset (struct line_maps *set,
 	return loc;
     }
 
-  offset += column;
-  if (linemap_assert_fails (offset < (1u << map->m_column_and_range_bits)))
+  column += column_offset;
+  if (linemap_assert_fails (column < (1u << map->m_column_and_range_bits)))
     return loc;
 
   source_location r = 
-    linemap_position_for_line_and_column (set, map, line, offset);
+    linemap_position_for_line_and_column (set, map, line, column);
   if (linemap_assert_fails (r <= set->highest_location)
       || linemap_assert_fails (map == linemap_lookup (set, r)))
     return loc;