aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbors[bot] <26634292+bors[bot]@users.noreply.github.com>2022-05-23 11:03:46 +0000
committerGitHub <noreply@github.com>2022-05-23 11:03:46 +0000
commitc7008d3e254786b5e752aa61e067f62c38042b81 (patch)
tree7c197b54d3e150c643b46ebfadb709ef83befa73
parent9204e7a1ac617126b65c27668524aebf8f65f134 (diff)
parenta647c005908d79bc6b50739c43b7ac105bc193a9 (diff)
downloadgcc-c7008d3e254786b5e752aa61e067f62c38042b81.zip
gcc-c7008d3e254786b5e752aa61e067f62c38042b81.tar.gz
gcc-c7008d3e254786b5e752aa61e067f62c38042b81.tar.bz2
Merge #1266
1266: Make TyTy::BaseType::destructure recursive r=philberty a=philberty 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. Co-authored-by: Philip Herron <philip.herron@embecosm.com>
-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)