From e27ac1fea338620f65f46b85eb7de7fa73f6093e Mon Sep 17 00:00:00 2001
From: Arthur Cohen <arthur.cohen@embecosm.com>
Date: Fri, 20 Dec 2024 18:00:48 +0000
Subject: [PATCH] hir-dump: Fix more segfaults in the HIR dump

gcc/rust/ChangeLog:

	* hir/rust-hir-dump.cc: Check unique_ptr members are present before
	visiting them.
	* hir/tree/rust-hir-path.h: Add `has_{type, trait}` methods to
	QualifiedPathInType.
---
 gcc/rust/hir/rust-hir-dump.cc     | 28 ++++++++++++++++++++++++----
 gcc/rust/hir/tree/rust-hir-path.h |  9 ++++++++-
 2 files changed, 32 insertions(+), 5 deletions(-)

diff --git a/gcc/rust/hir/rust-hir-dump.cc b/gcc/rust/hir/rust-hir-dump.cc
index a6a880121a1d..56b5f40e2090 100644
--- a/gcc/rust/hir/rust-hir-dump.cc
+++ b/gcc/rust/hir/rust-hir-dump.cc
@@ -315,6 +315,14 @@ Dump::do_functionparam (FunctionParam &e)
 void
 Dump::do_pathpattern (PathPattern &e)
 {
+  if (e.get_path_kind () == PathPattern::Kind::LangItem)
+    {
+      put_field ("segments", "#[lang = \""
+			       + LangItem::ToString (e.get_lang_item_kind ())
+			       + "\"]");
+      return;
+    }
+
   std::string str = "";
 
   for (const auto &segment : e.get_segments ())
@@ -402,9 +410,15 @@ void
 Dump::do_qualifiedpathtype (QualifiedPathType &e)
 {
   do_mappings (e.get_mappings ());
-  visit_field ("type", e.get_type ());
+  if (e.has_type ())
+    visit_field ("type", e.get_type ());
+  else
+    put_field ("type", "none");
 
-  visit_field ("trait", e.get_trait ());
+  if (e.has_trait ())
+    visit_field ("trait", e.get_trait ());
+  else
+    put_field ("trait", "none");
 }
 
 void
@@ -521,7 +535,10 @@ Dump::do_traitfunctiondecl (TraitFunctionDecl &e)
   else
     put_field ("function_params", "empty");
 
-  visit_field ("return_type", e.get_return_type ());
+  if (e.has_return_type ())
+    visit_field ("return_type", e.get_return_type ());
+  else
+    put_field ("return_type", "none");
 
   if (e.has_where_clause ())
     put_field ("where_clause", e.get_where_clause ().as_string ());
@@ -1295,7 +1312,10 @@ Dump::visit (BreakExpr &e)
   else
     put_field ("label", "none");
 
-  visit_field ("break_expr ", e.get_expr ());
+  if (e.has_break_expr ())
+    visit_field ("break_expr ", e.get_expr ());
+  else
+    put_field ("break_expr", "none");
 
   end ("BreakExpr");
 }
diff --git a/gcc/rust/hir/tree/rust-hir-path.h b/gcc/rust/hir/tree/rust-hir-path.h
index df5fd0c4e469..fa8dc3bb45cf 100644
--- a/gcc/rust/hir/tree/rust-hir-path.h
+++ b/gcc/rust/hir/tree/rust-hir-path.h
@@ -641,13 +641,20 @@ class QualifiedPathType
 
   Analysis::NodeMapping get_mappings () const { return mappings; }
 
+  bool has_type () { return type != nullptr; }
+  bool has_trait () { return trait != nullptr; }
+
   Type &get_type ()
   {
     rust_assert (type);
     return *type;
   }
 
-  TypePath &get_trait () { return *trait; }
+  TypePath &get_trait ()
+  {
+    rust_assert (trait);
+    return *trait;
+  }
 
   bool trait_has_generic_args () const;