aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc')
-rw-r--r--gcc/rust/backend/rust-compile-type.cc12
-rw-r--r--gcc/rust/backend/rust-compile-type.h7
-rw-r--r--gcc/rust/lang.opt4
-rw-r--r--gcc/rust/typecheck/rust-tyty.cc62
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 3874027..102bc0a 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 3e1f903..262b8fc 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 a6dabbf..58ec9a7 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 d0e8b76..f03bc82 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)