diff options
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/rust/backend/rust-compile-type.cc | 12 | ||||
-rw-r--r-- | gcc/rust/backend/rust-compile-type.h | 7 | ||||
-rw-r--r-- | gcc/rust/lang.opt | 4 | ||||
-rw-r--r-- | 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 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 ¶m) { - // 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) |