From f0ef1e5e4b15ee3aedc19036f5d197620783457c Mon Sep 17 00:00:00 2001
From: David Malcolm <dmalcolm@redhat.com>
Date: Fri, 2 Aug 2019 10:05:50 -0400
Subject: [PATCH 65/96] FIXME: tree-diagnostic.c: WIP on fixing events with
 UNKNOWN_LOCATION

---
 .../diagnostic-path-format-inline-events-2.c       | 149 +++++++++++++++++++++
 .../gcc.dg/plugin/diagnostic_plugin_test_paths.c   |  10 ++
 gcc/testsuite/gcc.dg/plugin/plugin.exp             |   3 +-
 gcc/tree-diagnostic.c                              |   4 +-
 4 files changed, 163 insertions(+), 3 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/plugin/diagnostic-path-format-inline-events-2.c

diff --git a/gcc/testsuite/gcc.dg/plugin/diagnostic-path-format-inline-events-2.c b/gcc/testsuite/gcc.dg/plugin/diagnostic-path-format-inline-events-2.c
new file mode 100644
index 0000000..d6c5bd9
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/plugin/diagnostic-path-format-inline-events-2.c
@@ -0,0 +1,149 @@
+/* { dg-do compile } */
+/* { dg-options "-fdiagnostics-path-format=inline-events" } */
+
+// FIXME: also test with -fdiagnostics-show-line-numbers
+
+/* Verify that 'inline-events' copes gracefully with events with an
+   unknown location.  */
+
+#include <stdlib.h>
+
+extern void missing_location ();
+
+void *wrapped_malloc (size_t size)
+{
+  return malloc (size);
+}
+
+void wrapped_free (void *ptr)
+{
+  free (ptr); /* { dg-warning "double-free of 'ptr' \\\[CWE-415\\]" } */
+  /* { dg-begin-multiline-output "" }
+  'test': events 1-2
+     |
+     | {
+     | ^
+     | |
+     | (1) entering 'test'
+     |   boxed_int *obj = make_boxed_int (i);
+     |                    ~~~~~~~~~~~~~~~~~~
+     |                    |
+     |                    (2) calling 'make_boxed_int'
+     |
+     +--> 'make_boxed_int': events 3-4
+                  |
+                  | {
+                  | ^
+                  | |
+                  | (3) entering 'make_boxed_int'
+                  |   boxed_int *result = (boxed_int *)wrapped_malloc (sizeof (boxed_int));
+                  |                                    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+                  |                                    |
+                  |                                    (4) calling 'wrapped_malloc'
+                  |
+                  +--> 'wrapped_malloc': events 5-6
+                               |
+                               | {
+                               | ^
+                               | |
+                               | (5) entering 'wrapped_malloc'
+                               |   return malloc (size);
+                               |          ~~~~~~~~~~~~~
+                               |          |
+                               |          (6) calling 'malloc'
+                               |
+     <-------------------------+
+     |
+  'test': event 7
+     |
+     |   free_boxed_int (obj);
+     |   ^~~~~~~~~~~~~~~~~~~~
+     |   |
+     |   (7) calling 'free_boxed_int'
+     |
+     +--> 'free_boxed_int': events 8-9
+                  |
+                  | {
+                  | ^
+                  | |
+                  | (8) entering 'free_boxed_int'
+                  |   wrapped_free (bi);
+                  |   ~~~~~~~~~~~~~~~~~
+                  |   |
+                  |   (9) calling 'wrapped_free'
+                  |
+                  +--> 'wrapped_free': events 10-11
+                              |
+                              | {
+                              | ^
+                              | |
+                              | (10) entering 'wrapped_free'
+                              |   free (ptr);
+                              |   ~~~~~~~~~~
+                              |   |
+                              |   (11) calling 'free'
+                              |
+     <------------------------+
+     |
+  'test': event 12
+     |
+     |   free_boxed_int (obj);
+     |   ^~~~~~~~~~~~~~~~~~~~
+     |   |
+     |   (12) calling 'free_boxed_int'
+     |
+     +--> 'free_boxed_int': events 13-14
+                  |
+                  | {
+                  | ^
+                  | |
+                  | (13) entering 'free_boxed_int'
+                  |   wrapped_free (bi);
+                  |   ~~~~~~~~~~~~~~~~~
+                  |   |
+                  |   (14) calling 'wrapped_free'
+                  |
+                  +--> 'wrapped_free': events 15-16
+                              |
+                              | {
+                              | ^
+                              | |
+                              | (15) entering 'wrapped_free'
+                              |   free (ptr);
+                              |   ~~~~~~~~~~
+                              |   |
+                              |   (16) calling 'free'
+                              |
+     { dg-end-multiline-output "" } */
+}
+
+typedef struct boxed_int
+{
+  int i;
+} boxed_int;
+
+boxed_int *
+make_boxed_int (int i)
+{
+  boxed_int *result = (boxed_int *)wrapped_malloc (sizeof (boxed_int));
+  result->i = i;
+  return result;
+}
+
+void
+free_boxed_int (boxed_int *bi)
+{
+  wrapped_free (bi);
+}
+
+void test (int i)
+{
+  boxed_int *obj = make_boxed_int (i);
+
+  free_boxed_int (obj);
+
+  missing_location ();
+
+  free_boxed_int (obj);
+}
+
diff --git a/gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_test_paths.c b/gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_test_paths.c
index 8138c8c..4eb86f5 100644
--- a/gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_test_paths.c
+++ b/gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_test_paths.c
@@ -270,6 +270,8 @@ example_2 ()
   event_location_t call_to_make_boxed_int;
   event_location_t call_to_free_boxed_int;
 
+  event_location_t call_to_missing_location;
+
   cgraph_node *node;
   FOR_EACH_FUNCTION_WITH_GIMPLE_BODY (node)
     {
@@ -302,6 +304,12 @@ example_2 ()
 		call_to_make_boxed_int.set (call, fun);
 	      if (gcall *call = check_for_named_call (stmt, "free_boxed_int", 1))
 		call_to_free_boxed_int.set (call, fun);
+	      if (gcall *call = check_for_named_call (stmt, "missing_location", 0))
+		{
+		  call_to_missing_location.set (call, fun);
+		  /* Simulate an event that's missing a useful location_t.  */
+		  call_to_missing_location.m_loc = UNKNOWN_LOCATION;
+		}
 	    }
 	}
     }
@@ -326,6 +334,8 @@ example_2 ()
 	  path.add_call (call_to_wrapped_free, 1,
 			 entry_to_wrapped_free, "wrapped_free");
 	  path.add_leaf_call (call_to_free, 2, "free");
+	  if (i == 0 && call_to_missing_location.m_fun)
+	    path.add_leaf_call (call_to_missing_location, 0, "missing_location");
 	}
 
       richloc.set_path (&path);
diff --git a/gcc/testsuite/gcc.dg/plugin/plugin.exp b/gcc/testsuite/gcc.dg/plugin/plugin.exp
index 6adb761..4358881 100644
--- a/gcc/testsuite/gcc.dg/plugin/plugin.exp
+++ b/gcc/testsuite/gcc.dg/plugin/plugin.exp
@@ -101,7 +101,8 @@ set plugin_test_list [list \
 	  diagnostic-path-format-default.c \
 	  diagnostic-path-format-none.c \
 	  diagnostic-path-format-separate-events.c \
-	  diagnostic-path-format-inline-events.c } \
+	  diagnostic-path-format-inline-events.c \
+	  diagnostic-path-format-inline-events-2.c } \
     { location_overflow_plugin.c \
 	  location-overflow-test-1.c \
 	  location-overflow-test-2.c \
diff --git a/gcc/tree-diagnostic.c b/gcc/tree-diagnostic.c
index bcc435a..27214a0 100644
--- a/gcc/tree-diagnostic.c
+++ b/gcc/tree-diagnostic.c
@@ -523,7 +523,7 @@ print_path_summary (pretty_printer *pp,
 		    const path_summary& summary,
 		    const diagnostic_path *path,
 		    bool show_depths,
-		    bool show_events_summaries)
+		    bool show_event_summaries)
 {
   auto_vec<int> name_lengths;
 
@@ -593,7 +593,7 @@ print_path_summary (pretty_printer *pp,
 
       int midpoint = name_lengths[i] / 2;
 
-      if (show_events_summaries)
+      if (show_event_summaries)
 	{
 	  for (int event_idx = range->m_start_idx;
 	       event_idx <= range->m_end_idx; event_idx++)
-- 
1.8.5.3

