diff --git a/gcc/analyzer/analyzer.h b/gcc/analyzer/analyzer.h
index 208b85026fc..777293ff4b9 100644
--- a/gcc/analyzer/analyzer.h
+++ b/gcc/analyzer/analyzer.h
@@ -90,6 +90,7 @@ class reachable_regions;
 class bounded_ranges;
 class bounded_ranges_manager;
 
+struct pending_location;
 class pending_diagnostic;
 class pending_note;
 struct event_loc_info;
diff --git a/gcc/analyzer/diagnostic-manager.cc b/gcc/analyzer/diagnostic-manager.cc
index b3da2a982f2..b652e7032e9 100644
--- a/gcc/analyzer/diagnostic-manager.cc
+++ b/gcc/analyzer/diagnostic-manager.cc
@@ -664,22 +664,20 @@ epath_finder::dump_feasible_path (const exploded_node *target_enode,
 
 /* class saved_diagnostic.  */
 
-/* saved_diagnostic's ctor.
-   Take ownership of D and STMT_FINDER.  */
+/* saved_diagnostic's ctor.  */
 
 saved_diagnostic::saved_diagnostic (const state_machine *sm,
-				    const exploded_node *enode,
-				    const supernode *snode, const gimple *stmt,
-				    const stmt_finder *stmt_finder,
+				    const pending_location &ploc,
 				    tree var,
 				    const svalue *sval,
 				    state_machine::state_t state,
 				    std::unique_ptr<pending_diagnostic> d,
 				    unsigned idx)
-: m_sm (sm), m_enode (enode), m_snode (snode), m_stmt (stmt),
- /* stmt_finder could be on-stack; we want our own copy that can
-    outlive that.  */
-  m_stmt_finder (stmt_finder ? stmt_finder->clone () : NULL),
+: m_sm (sm), m_enode (ploc.m_enode), m_snode (ploc.m_snode),
+  m_stmt (ploc.m_stmt),
+  /* stmt_finder could be on-stack; we want our own copy that can
+     outlive that.  */
+  m_stmt_finder (ploc.m_finder ? ploc.m_finder->clone () : NULL),
   m_var (var), m_sval (sval), m_state (state),
   m_d (std::move (d)), m_trailing_eedge (NULL),
   m_idx (idx),
@@ -1102,9 +1100,7 @@ diagnostic_manager::diagnostic_manager (logger *logger, engine *eng,
 
 bool
 diagnostic_manager::add_diagnostic (const state_machine *sm,
-				    exploded_node *enode,
-				    const supernode *snode, const gimple *stmt,
-				    const stmt_finder *finder,
+				    const pending_location &ploc,
 				    tree var,
 				    const svalue *sval,
 				    state_machine::state_t state,
@@ -1114,15 +1110,16 @@ diagnostic_manager::add_diagnostic (const state_machine *sm,
 
   /* We must have an enode in order to be able to look for paths
      through the exploded_graph to the diagnostic.  */
-  gcc_assert (enode);
+  gcc_assert (ploc.m_enode);
 
   /* If this warning is ultimately going to be rejected by a -Wno-analyzer-*
      flag, reject it now.
      We can only do this for diagnostics where we already know the stmt,
      and thus can determine the emission location.  */
-  if (stmt)
+  if (ploc.m_stmt)
     {
-      location_t loc = get_emission_location (stmt, snode->m_fun, *d);
+      location_t loc
+	= get_emission_location (ploc.m_stmt, ploc.m_snode->m_fun, *d);
       int option = d->get_controlling_option ();
       if (!warning_enabled_at (loc, option))
 	{
@@ -1135,14 +1132,14 @@ diagnostic_manager::add_diagnostic (const state_machine *sm,
     }
 
   saved_diagnostic *sd
-    = new saved_diagnostic (sm, enode, snode, stmt, finder, var, sval,
-			    state, std::move (d), m_saved_diagnostics.length ());
+    = new saved_diagnostic (sm, ploc, var, sval, state, std::move (d),
+			    m_saved_diagnostics.length ());
   m_saved_diagnostics.safe_push (sd);
-  enode->add_diagnostic (sd);
+  ploc.m_enode->add_diagnostic (sd);
   if (get_logger ())
     log ("adding saved diagnostic %i at SN %i to EN %i: %qs",
 	 sd->get_index (),
-	 snode->m_index, enode->m_index, sd->m_d->get_kind ());
+	 ploc.m_snode->m_index, ploc.m_enode->m_index, sd->m_d->get_kind ());
   return true;
 }
 
@@ -1151,14 +1148,11 @@ diagnostic_manager::add_diagnostic (const state_machine *sm,
    Take ownership of D (or delete it).  */
 
 bool
-diagnostic_manager::add_diagnostic (exploded_node *enode,
-				    const supernode *snode, const gimple *stmt,
-				    const stmt_finder *finder,
+diagnostic_manager::add_diagnostic (const pending_location &ploc,
 				    std::unique_ptr<pending_diagnostic> d)
 {
-  gcc_assert (enode);
-  return add_diagnostic (NULL, enode, snode, stmt, finder, NULL_TREE,
-			 NULL, 0, std::move (d));
+  gcc_assert (ploc.m_enode);
+  return add_diagnostic (NULL, ploc, NULL_TREE, NULL, 0, std::move (d));
 }
 
 /* Add PN to the most recent saved_diagnostic.  */
diff --git a/gcc/analyzer/diagnostic-manager.h b/gcc/analyzer/diagnostic-manager.h
index 413ab0c90b1..f538d38298e 100644
--- a/gcc/analyzer/diagnostic-manager.h
+++ b/gcc/analyzer/diagnostic-manager.h
@@ -31,9 +31,7 @@ class saved_diagnostic
 {
 public:
   saved_diagnostic (const state_machine *sm,
-		    const exploded_node *enode,
-		    const supernode *snode, const gimple *stmt,
-		    const stmt_finder *stmt_finder,
+		    const pending_location &ploc,
 		    tree var, const svalue *sval,
 		    state_machine::state_t state,
 		    std::unique_ptr<pending_diagnostic> d,
@@ -100,6 +98,30 @@ private:
 
 class path_builder;
 
+/* A bundle of information capturing where a pending_diagnostic should
+   be emitted.  */
+
+struct pending_location
+{
+public:
+  pending_location (exploded_node *enode,
+		    const supernode *snode,
+		    const gimple *stmt,
+		    const stmt_finder *finder)
+  : m_enode (enode),
+    m_snode (snode),
+    m_stmt (stmt),
+    m_finder (finder)
+  {
+    gcc_assert (m_stmt || m_finder);
+  }
+
+  exploded_node *m_enode;
+  const supernode *m_snode;
+  const gimple *m_stmt;
+  const stmt_finder *m_finder;
+};
+
 /* A class with responsibility for saving pending diagnostics, so that
    they can be emitted after the exploded_graph is complete.
    This lets us de-duplicate diagnostics, and find the shortest path
@@ -119,17 +141,13 @@ public:
   json::object *to_json () const;
 
   bool add_diagnostic (const state_machine *sm,
-		       exploded_node *enode,
-		       const supernode *snode, const gimple *stmt,
-		       const stmt_finder *finder,
+		       const pending_location &ploc,
 		       tree var,
 		       const svalue *sval,
 		       state_machine::state_t state,
 		       std::unique_ptr<pending_diagnostic> d);
 
-  bool add_diagnostic (exploded_node *enode,
-		       const supernode *snode, const gimple *stmt,
-		       const stmt_finder *finder,
+  bool add_diagnostic (const pending_location &ploc,
 		       std::unique_ptr<pending_diagnostic> d);
 
   void add_note (std::unique_ptr<pending_note> pn);
diff --git a/gcc/analyzer/engine.cc b/gcc/analyzer/engine.cc
index 1e7750dcbdc..4861ee54e98 100644
--- a/gcc/analyzer/engine.cc
+++ b/gcc/analyzer/engine.cc
@@ -129,9 +129,12 @@ impl_region_model_context::warn (std::unique_ptr<pending_diagnostic> d,
   if (m_eg)
     {
       bool terminate_path = d->terminate_path_p ();
-      if (m_eg->get_diagnostic_manager ().add_diagnostic
-	  (m_enode_for_diag, m_enode_for_diag->get_supernode (),
-	   m_stmt, curr_stmt_finder, std::move (d)))
+      pending_location ploc (m_enode_for_diag,
+			     m_enode_for_diag->get_supernode (),
+			     m_stmt,
+			     curr_stmt_finder);
+      if (m_eg->get_diagnostic_manager ().add_diagnostic (ploc,
+							  std::move (d)))
 	{
 	  if (m_path_ctxt
 	      && terminate_path
@@ -398,8 +401,9 @@ public:
 	 ? m_old_smap->get_state (var_old_sval, m_eg.get_ext_state ())
 	 : m_old_smap->get_global_state ());
     bool terminate_path = d->terminate_path_p ();
+    pending_location ploc (m_enode_for_diag, snode, stmt, m_stmt_finder);
     m_eg.get_diagnostic_manager ().add_diagnostic
-      (&m_sm, m_enode_for_diag, snode, stmt, m_stmt_finder,
+      (&m_sm, ploc,
        var, var_old_sval, current, std::move (d));
     if (m_path_ctxt
 	&& terminate_path
@@ -418,8 +422,9 @@ public:
 	 ? m_old_smap->get_state (sval, m_eg.get_ext_state ())
 	 : m_old_smap->get_global_state ());
     bool terminate_path = d->terminate_path_p ();
+    pending_location ploc (m_enode_for_diag, snode, stmt, m_stmt_finder);
     m_eg.get_diagnostic_manager ().add_diagnostic
-      (&m_sm, m_enode_for_diag, snode, stmt, m_stmt_finder,
+      (&m_sm, ploc,
        NULL_TREE, sval, current, std::move (d));
     if (m_path_ctxt
 	&& terminate_path
@@ -898,10 +903,15 @@ impl_region_model_context::on_state_leak (const state_machine &sm,
   tree leaked_tree_for_diag = fixup_tree_for_diagnostic (leaked_tree);
   std::unique_ptr<pending_diagnostic> pd = sm.on_leak (leaked_tree_for_diag);
   if (pd)
-    m_eg->get_diagnostic_manager ().add_diagnostic
-      (&sm, m_enode_for_diag, m_enode_for_diag->get_supernode (),
-       m_stmt, &stmt_finder,
-       leaked_tree_for_diag, sval, state, std::move (pd));
+    {
+      pending_location ploc (m_enode_for_diag,
+			     m_enode_for_diag->get_supernode (),
+			     m_stmt,
+			     &stmt_finder);
+      m_eg->get_diagnostic_manager ().add_diagnostic
+	(&sm, ploc,
+	 leaked_tree_for_diag, sval, state, std::move (pd));
+    }
 }
 
 /* Implementation of region_model_context::on_condition vfunc.
diff --git a/gcc/analyzer/infinite-recursion.cc b/gcc/analyzer/infinite-recursion.cc
index 3ba316ee964..9576ff5f58d 100644
--- a/gcc/analyzer/infinite-recursion.cc
+++ b/gcc/analyzer/infinite-recursion.cc
@@ -625,8 +625,12 @@ exploded_graph::detect_infinite_recursion (exploded_node *enode)
   const supernode *caller_snode = call_string.get_top_of_stack ().m_caller;
   const supernode *snode = enode->get_supernode ();
   gcc_assert (caller_snode->m_returning_call);
+  pending_location ploc (enode,
+			 snode,
+			 caller_snode->m_returning_call,
+			 nullptr);
   get_diagnostic_manager ().add_diagnostic
-    (enode, snode, caller_snode->m_returning_call, NULL,
+    (ploc,
      make_unique<infinite_recursion_diagnostic> (prev_entry_enode,
 						 enode,
 						 fndecl));
