public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc/devel/rust/master] Make TyTy::BaseType::destructure recursive
@ 2022-06-08 12:49 Thomas Schwinge
  0 siblings, 0 replies; only message in thread
From: Thomas Schwinge @ 2022-06-08 12:49 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:a647c005908d79bc6b50739c43b7ac105bc193a9

commit a647c005908d79bc6b50739c43b7ac105bc193a9
Author: Philip Herron <philip.herron@embecosm.com>
Date:   Fri May 20 17:35:35 2022 +0100

    Make TyTy::BaseType::destructure recursive
    
    In the case of Generic Associated Types we end up
    
      placeholders->projections->generic-param->i32
    
    This means we need to keep destructuring the TyTy object until we finally
    get the real type at the end. In order to do this safely we need to ensure
    we add in recursion limits and apply this where it matters such as
    compiling types in general too.

Diff:
---
 gcc/rust/backend/rust-compile-type.cc | 12 +++++--
 gcc/rust/backend/rust-compile-type.h  |  7 ++--
 gcc/rust/lang.opt                     |  4 +++
 gcc/rust/typecheck/rust-tyty.cc       | 62 ++++++++++++++++++++++-------------
 4 files changed, 54 insertions(+), 31 deletions(-)

diff --git a/gcc/rust/backend/rust-compile-type.cc b/gcc/rust/backend/rust-compile-type.cc
index 38740274a44..102bc0a3f65 100644
--- a/gcc/rust/backend/rust-compile-type.cc
+++ b/gcc/rust/backend/rust-compile-type.cc
@@ -112,9 +112,15 @@ TyTyResolveCompile::visit (const TyTy::PlaceholderType &type)
 void
 TyTyResolveCompile::visit (const TyTy::ParamType &param)
 {
-  // FIXME make this reuse the same machinery from constexpr code
-  recursion_count++;
-  rust_assert (recursion_count < kDefaultRecusionLimit);
+  if (recurisve_ops++ >= rust_max_recursion_depth)
+    {
+      rust_error_at (Location (),
+		     "%<recursion depth%> count exceeds limit of %i (use "
+		     "%<frust-max-recursion-depth=%> to increase the limit)",
+		     rust_max_recursion_depth);
+      translated = error_mark_node;
+      return;
+    }
 
   param.resolve ()->accept_vis (*this);
 }
diff --git a/gcc/rust/backend/rust-compile-type.h b/gcc/rust/backend/rust-compile-type.h
index 3e1f903f761..262b8fc51a0 100644
--- a/gcc/rust/backend/rust-compile-type.h
+++ b/gcc/rust/backend/rust-compile-type.h
@@ -63,16 +63,13 @@ public:
 private:
   TyTyResolveCompile (Context *ctx, bool trait_object_mode)
     : ctx (ctx), trait_object_mode (trait_object_mode),
-      translated (error_mark_node), recursion_count (0)
+      translated (error_mark_node), recurisve_ops (0)
   {}
 
   Context *ctx;
   bool trait_object_mode;
   tree translated;
-
-  // FIXME this needs to be derived from the gcc config option
-  size_t recursion_count;
-  static const size_t kDefaultRecusionLimit = 5;
+  int recurisve_ops;
 };
 
 } // namespace Compile
diff --git a/gcc/rust/lang.opt b/gcc/rust/lang.opt
index a6dabbfd727..58ec9a75e9a 100644
--- a/gcc/rust/lang.opt
+++ b/gcc/rust/lang.opt
@@ -66,6 +66,10 @@ frust-dump-
 Rust Joined RejectNegative
 -frust-dump-<type>	Dump Rust frontend internal information.
 
+frust-max-recursion-depth=
+Rust RejectNegative Type(int) Var(rust_max_recursion_depth) Init(64)
+-frust-max-recursion-depth=integer
+
 frust-mangling=
 Rust Joined RejectNegative Enum(frust_mangling) Var(flag_rust_mangling)
 -frust-mangling=[legacy|v0]     Choose which version to use for name mangling
diff --git a/gcc/rust/typecheck/rust-tyty.cc b/gcc/rust/typecheck/rust-tyty.cc
index d0e8b761622..f03bc8234c8 100644
--- a/gcc/rust/typecheck/rust-tyty.cc
+++ b/gcc/rust/typecheck/rust-tyty.cc
@@ -252,33 +252,49 @@ BaseType::get_root () const
 const BaseType *
 BaseType::destructure () const
 {
-  switch (get_kind ())
+  int recurisve_ops = 0;
+  const BaseType *x = this;
+  while (true)
     {
-      case TyTy::TypeKind::PARAM: {
-	const TyTy::ParamType *p = static_cast<const TyTy::ParamType *> (this);
-	return p->resolve ();
-      }
-      break;
-
-      case TyTy::TypeKind::PLACEHOLDER: {
-	const TyTy::PlaceholderType *p
-	  = static_cast<const TyTy::PlaceholderType *> (this);
-	rust_assert (p->can_resolve ());
-	return p->resolve ();
-      }
-      break;
-
-      case TyTy::TypeKind::PROJECTION: {
-	const TyTy::ProjectionType *p
-	  = static_cast<const TyTy::ProjectionType *> (this);
-	return p->get ();
-      }
+      if (recurisve_ops++ >= rust_max_recursion_depth)
+	{
+	  rust_error_at (
+	    Location (),
+	    "%<recursion depth%> count exceeds limit of %i (use "
+	    "%<frust-max-recursion-depth=%> to increase the limit)",
+	    rust_max_recursion_depth);
+	  return new ErrorType (get_ref ());
+	}
 
-    default:
-      return this;
+      switch (x->get_kind ())
+	{
+	  case TyTy::TypeKind::PARAM: {
+	    const TyTy::ParamType *p = static_cast<const TyTy::ParamType *> (x);
+	    x = p->resolve ();
+	  }
+	  break;
+
+	  case TyTy::TypeKind::PLACEHOLDER: {
+	    const TyTy::PlaceholderType *p
+	      = static_cast<const TyTy::PlaceholderType *> (x);
+	    rust_assert (p->can_resolve ());
+	    x = p->resolve ();
+	  }
+	  break;
+
+	  case TyTy::TypeKind::PROJECTION: {
+	    const TyTy::ProjectionType *p
+	      = static_cast<const TyTy::ProjectionType *> (x);
+	    x = p->get ();
+	  }
+	  break;
+
+	default:
+	  return x;
+	}
     }
 
-  return this;
+  return x;
 }
 
 TyVar::TyVar (HirId ref) : ref (ref)


^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2022-06-08 12:49 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-06-08 12:49 [gcc/devel/rust/master] Make TyTy::BaseType::destructure recursive Thomas Schwinge

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).