From 809f7cf76364350f8efc759b19cb17b75ef1c32a Mon Sep 17 00:00:00 2001
From: David Malcolm <dmalcolm@redhat.com>
Date: Fri, 16 Oct 2015 17:27:37 -0400
Subject: [PATCH 16/58] FIXME: Update set->highest_location in
 linemap_position_for_line_and_column

TODO:
  * needs ChangeLog

Ada build was failing here:

881       if (linemap_location_from_macro_expansion_p (set, line))
882         return linemap_macro_map_lookup (set, line);

(gdb) call linemap_location_from_macro_expansion_p (set, line)
$6 = true
(gdb) p /x line
$7 = 0x79abd200

...where linemap_location_from_macro_expansion_p returned true here:
1192      return (location > set->highest_location);

despite there being no macro maps, due to:

(gdb) p /x location
$8 = 0x79abd200

which is above LINE_MAP_MAX_LOCATION_WITH_COLS.

(gdb) p /x set->highest_location
$9 = 0x60a3f39b

The location value in question came from
linemap_position_for_line_and_column.

Update it to update set->highest_location (and to respect
LINE_MAP_MAX_LOCATION_WITH_COLS), which means we need to
pass in the line_table.
---
 gcc/ada/gcc-interface/trans.c                         |  3 ++-
 .../gcc.dg/plugin/diagnostic_plugin_test_show_locus.c |  3 ++-
 libcpp/include/line-map.h                             |  3 ++-
 libcpp/line-map.c                                     | 19 ++++++++++++-------
 4 files changed, 18 insertions(+), 10 deletions(-)

diff --git a/gcc/ada/gcc-interface/trans.c b/gcc/ada/gcc-interface/trans.c
index f1e2dcb..c3ff66a 100644
--- a/gcc/ada/gcc-interface/trans.c
+++ b/gcc/ada/gcc-interface/trans.c
@@ -9618,7 +9618,8 @@ Sloc_to_locus (Source_Ptr Sloc, location_t *locus, bool clear_column)
     line = 1;
 
   /* Translate the location.  */
-  *locus = linemap_position_for_line_and_column (map, line, column);
+  *locus = linemap_position_for_line_and_column (line_table, map,
+						 line, column);
 
   return true;
 }
diff --git a/gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_test_show_locus.c b/gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_test_show_locus.c
index 4c6120d..14a8d91 100644
--- a/gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_test_show_locus.c
+++ b/gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_test_show_locus.c
@@ -109,7 +109,8 @@ get_loc (unsigned int line_num, unsigned int col_num)
 
   /* Convert from 0-based column numbers to 1-based column numbers.  */
   source_location loc
-    = linemap_position_for_line_and_column (line_map,
+    = linemap_position_for_line_and_column (line_table,
+					    line_map,
 					    line_num, col_num + 1);
 
   return loc;
diff --git a/libcpp/include/line-map.h b/libcpp/include/line-map.h
index e5a78ac..7d48855 100644
--- a/libcpp/include/line-map.h
+++ b/libcpp/include/line-map.h
@@ -1008,7 +1008,8 @@ linemap_position_for_column (struct line_maps *, unsigned int);
 /* Encode and return a source location from a given line and
    column.  */
 source_location
-linemap_position_for_line_and_column (const line_map_ordinary *,
+linemap_position_for_line_and_column (line_maps *set,
+				      const line_map_ordinary *,
 				      linenum_type, unsigned int);
 
 /* Encode and return a source_location starting from location LOC and
diff --git a/libcpp/line-map.c b/libcpp/line-map.c
index e097d55..31b6f98 100644
--- a/libcpp/line-map.c
+++ b/libcpp/line-map.c
@@ -796,17 +796,22 @@ linemap_position_for_column (struct line_maps *set, unsigned int to_column)
    column.  */
 
 source_location
-linemap_position_for_line_and_column (const line_map_ordinary *ord_map,
+linemap_position_for_line_and_column (line_maps *set,
+				      const line_map_ordinary *ord_map,
 				      linenum_type line,
 				      unsigned column)
 {
   linemap_assert (ORDINARY_MAP_STARTING_LINE_NUMBER (ord_map) <= line);
 
-  return (MAP_START_LOCATION (ord_map)
-	  + ((line - ORDINARY_MAP_STARTING_LINE_NUMBER (ord_map))
-	     << ORDINARY_MAP_NUMBER_OF_COLUMN_BITS (ord_map))
-	  + ((column & ((1 << ORDINARY_MAP_NUMBER_OF_COLUMN_BITS (ord_map)) - 1))
-	     << ord_map->range_bits));
+  source_location r = MAP_START_LOCATION (ord_map);
+  r += ((line - ORDINARY_MAP_STARTING_LINE_NUMBER (ord_map))
+	<< ORDINARY_MAP_NUMBER_OF_COLUMN_BITS (ord_map));
+  if (r <= LINE_MAP_MAX_LOCATION_WITH_COLS)
+    r += ((column & ((1 << ORDINARY_MAP_NUMBER_OF_COLUMN_BITS (ord_map)) - 1))
+	  << ord_map->range_bits);
+  if (r > set->highest_location)
+    set->highest_location = r;
+  return r;
 }
 
 /* Encode and return a source_location starting from location LOC and
@@ -862,7 +867,7 @@ linemap_position_for_loc_and_offset (struct line_maps *set,
     return loc;
 
   source_location r = 
-    linemap_position_for_line_and_column (map, line, offset);
+    linemap_position_for_line_and_column (set, map, line, offset);
   if (linemap_assert_fails (r <= set->highest_location)
       || linemap_assert_fails (map == linemap_lookup (set, r)))
     return loc;
-- 
1.8.5.3

