From 63355df94c7dd2b6f2a923f1c832923ba94cbbba Mon Sep 17 00:00:00 2001
From: David Malcolm <dmalcolm@redhat.com>
Date: Fri, 18 Sep 2015 13:25:48 -0400
Subject: [PATCH 28/35] FIXME: semi-working attempt to suppress range-printing
 for macro expansion

This filters out "awkward" ranges in diagnostic_show_locus; doing
so involved reworking it only work on ranges within m_per_range_vec.

It does reject printing the caret though, since it rejects range 0.

Conflicts:
	gcc/diagnostic-show-locus.c
---
 gcc/diagnostic-show-locus.c                        | 32 ++++++++++++
 .../gcc.dg/plugin/diagnostic-test-expressions-1.c  | 60 ++++++++++++++++++++++
 libcpp/include/line-map.h                          |  1 +
 libcpp/line-map.c                                  |  3 ++
 4 files changed, 96 insertions(+)

diff --git a/gcc/diagnostic-show-locus.c b/gcc/diagnostic-show-locus.c
index 072f3a5..12887b2 100644
--- a/gcc/diagnostic-show-locus.c
+++ b/gcc/diagnostic-show-locus.c
@@ -440,6 +440,10 @@ layout::layout (diagnostic_context * context,
   m_x_offset (0)
 {
   rich_location *richloc = diagnostic->richloc;
+
+  const line_map *loc_linemap = linemap_lookup (line_table,
+						richloc->get_loc ());
+
   for (unsigned int idx = 0; idx < richloc->get_num_locations (); idx++)
     {
       /* This diagnostic printer can only cope with "sufficiently sane" ranges.
@@ -456,6 +460,34 @@ layout::layout (diagnostic_context * context,
 	if (loc_range->m_caret.file != m_exploc.file)
 	  continue;
 
+#if 0
+      /* If the primary location is within a macro expansion, reject all ranges
+	 for now.
+	 Doing so fixes some crazy output, but drops the caret from the output
+	 if the range is range 0.  */
+      if (linemap_location_from_macro_expansion_p (line_table,
+						   m_richloc->get_loc ()))
+	continue;
+
+      /* Ignore ranges that start/finish within a macro expansion.  */
+      if (linemap_location_from_macro_expansion_p (line_table,
+						   loc_range->m_src_range.m_start))
+	continue;
+      if (linemap_location_from_macro_expansion_p (line_table,
+						   loc_range->m_src_range.m_finish))
+	continue;
+#endif
+
+#if 0
+      /* If they're not all in the same line-map, ignore the range.  */
+      if (linemap_lookup (line_table, loc_range->m_src_range.m_start)
+	  != loc_linemap)
+	continue;
+      if (linemap_lookup (line_table, loc_range->m_src_range.m_finish)
+	  != loc_linemap)
+	continue;
+#endif
+
       /* Passed all the tests; add the range to m_layout_ranges so that
 	 it will be printed.  */
       layout_range ri (loc_range);
diff --git a/gcc/testsuite/gcc.dg/plugin/diagnostic-test-expressions-1.c b/gcc/testsuite/gcc.dg/plugin/diagnostic-test-expressions-1.c
index 0d8c7c5..9451ac1 100644
--- a/gcc/testsuite/gcc.dg/plugin/diagnostic-test-expressions-1.c
+++ b/gcc/testsuite/gcc.dg/plugin/diagnostic-test-expressions-1.c
@@ -541,3 +541,63 @@ void test_quadratic (double a, double b, double c)
    { dg-end-multiline-output "" } */
 
 }
+
+/* Examples of macros.  *******************************************/
+
+#if 1
+#define EXPECT(EXPR, RES) __builtin_expect ((expr), res)
+
+void test_expect (int expr, int res)
+{
+  __emit_expression_range (0, EXPECT (expr, res)); /* { dg-warning "range" } */
+/* { dg-begin-multiline-output "" }
+ #define EXPECT(EXPR, RES) __builtin_expect ((expr), res)
+                           ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+   { dg-end-multiline-output "" } */
+/* { dg-begin-multiline-output "" }
+   __emit_expression_range (0, EXPECT (expr, res));
+                               ^
+   { dg-end-multiline-output "" } */
+
+}
+#endif
+
+
+#if  __GNUC__ >= 3
+# define _IO_BE(expr, res) __builtin_expect ((expr), res)
+#else
+# define _IO_BE(expr, res) (expr)
+#endif
+
+typedef struct _FILE
+{
+  unsigned char *_IO_write_ptr;
+  unsigned char *_IO_write_end;
+} FILE;
+
+extern unsigned char __overflow (FILE *__fp, unsigned char ch);
+
+#define _IO_putc_unlocked(_ch, _fp) \
+  ( _IO_BE ((_fp)->_IO_write_ptr >= (_fp)->_IO_write_end, 0) \
+    ? __overflow (_fp, (unsigned char) (_ch)) \
+    : (unsigned char) (*(_fp)->_IO_write_ptr++ = (_ch)))
+
+void
+fputc_unlocked (int __c, FILE *__stream)
+{
+  __emit_expression_range (0, _IO_putc_unlocked (__c, __stream)); /* { dg-warning "range" } */
+/* { dg-begin-multiline-output "" }
+   { dg-end-multiline-output "" } */
+
+  __emit_expression_range (0, (_IO_putc_unlocked (__c, __stream) + 1)); /* { dg-warning "range" } */
+/* { dg-begin-multiline-output "" }
+   __emit_expression_range (0, _IO_putc_unlocked (__c, __stream));
+                               ^
+   { dg-end-multiline-output "" } */
+/* { dg-begin-multiline-output "" }
+   __emit_expression_range (0, (_IO_putc_unlocked (__c, __stream) + 1));
+                               ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~
+   { dg-end-multiline-output "" } */
+
+}
diff --git a/libcpp/include/line-map.h b/libcpp/include/line-map.h
index 0c97a6d..9194a7a 100644
--- a/libcpp/include/line-map.h
+++ b/libcpp/include/line-map.h
@@ -1255,6 +1255,7 @@ typedef struct
    m_finish is the last location within the range.  */
 struct location_range
 {
+  source_range m_src_range;
   expanded_location m_start;
   expanded_location m_finish;
 
diff --git a/libcpp/line-map.c b/libcpp/line-map.c
index 4284303..c1fd1d9 100644
--- a/libcpp/line-map.c
+++ b/libcpp/line-map.c
@@ -2040,6 +2040,8 @@ rich_location::add_range (source_location start, source_location finish,
   linemap_assert (m_num_ranges < MAX_RANGES);
 
   location_range *range = &m_ranges[m_num_ranges++];
+  range->m_src_range.m_start = start;
+  range->m_src_range.m_finish = finish;
   range->m_start = linemap_client_expand_location_to_spelling_point (start);
   range->m_finish = linemap_client_expand_location_to_spelling_point (finish);
   range->m_caret = range->m_start;
@@ -2089,6 +2091,7 @@ rich_location::set_range (unsigned int idx, source_range src_range,
   linemap_assert (idx <= m_num_ranges);
 
   location_range *locrange = &m_ranges[idx];
+  locrange->m_src_range = src_range;
   locrange->m_start
     = linemap_client_expand_location_to_spelling_point (src_range.m_start);
   locrange->m_finish
-- 
1.8.5.3

