diff options
author | Philip Herron <philip.herron@embecosm.com> | 2022-01-04 16:15:26 +0000 |
---|---|---|
committer | Philip Herron <philip.herron@embecosm.com> | 2022-01-04 16:15:26 +0000 |
commit | 5b369a61484c52ea0298cfab11858c3fff8bcc00 (patch) | |
tree | e7645e6d3c0f017d62e04917b85174fb0a2b446a | |
parent | 69f6be3ee483c9895b4b5187a44b3e1c8be2ba63 (diff) | |
download | gcc-5b369a61484c52ea0298cfab11858c3fff8bcc00.zip gcc-5b369a61484c52ea0298cfab11858c3fff8bcc00.tar.gz gcc-5b369a61484c52ea0298cfab11858c3fff8bcc00.tar.bz2 |
Fix ICE in generic subsitution of enums containing dataless variants
Dataless variants do not contain fields that can be substituted, which then
hits an assertion on access of the fields for the variant. This patch adds
a guard against the substitution of dataless variants. We could have
removed the assertion which would have also been a good fix but keeping the
assertion for now is very helpful in debugging issues.
Fixs #851
-rw-r--r-- | gcc/rust/typecheck/rust-tyty.cc | 3 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-tyty.h | 2 | ||||
-rw-r--r-- | gcc/testsuite/rust/execute/torture/issue-851.rs | 35 |
3 files changed, 40 insertions, 0 deletions
diff --git a/gcc/rust/typecheck/rust-tyty.cc b/gcc/rust/typecheck/rust-tyty.cc index 25fdfa9..f141a41 100644 --- a/gcc/rust/typecheck/rust-tyty.cc +++ b/gcc/rust/typecheck/rust-tyty.cc @@ -822,6 +822,9 @@ ADTType::handle_substitions (SubstitutionArgumentMappings subst_mappings) for (auto &variant : adt->get_variants ()) { + if (variant->is_dataless_variant ()) + continue; + for (auto &field : variant->get_fields ()) { bool ok = ::Rust::TyTy::handle_substitions (subst_mappings, field); diff --git a/gcc/rust/typecheck/rust-tyty.h b/gcc/rust/typecheck/rust-tyty.h index 012e846..40c06a5 100644 --- a/gcc/rust/typecheck/rust-tyty.h +++ b/gcc/rust/typecheck/rust-tyty.h @@ -1069,6 +1069,8 @@ public: HirId get_id () const { return id; } VariantType get_variant_type () const { return type; } + bool is_data_variant () const { return type != VariantType::NUM; } + bool is_dataless_variant () const { return type == VariantType::NUM; } std::string get_identifier () const { return identifier; } int get_discriminant () const { return discriminant; } diff --git a/gcc/testsuite/rust/execute/torture/issue-851.rs b/gcc/testsuite/rust/execute/torture/issue-851.rs new file mode 100644 index 0000000..3881c7a --- /dev/null +++ b/gcc/testsuite/rust/execute/torture/issue-851.rs @@ -0,0 +1,35 @@ +/* { dg-output "Result: 123\n" } */ +extern "C" { + fn printf(s: *const i8, ...); +} + +enum Foo<T> { + A, + B(T), +} + +fn inspect(a: Foo<i32>) { + match a { + Foo::A => unsafe { + let a = "A\n\0"; + let b = a as *const str; + let c = b as *const i8; + + printf(c); + }, + Foo::B(x) => unsafe { + let a = "Result: %i\n\0"; + let b = a as *const str; + let c = b as *const i8; + + printf(c, x); + }, + } +} + +fn main() -> i32 { + let a = Foo::B(123); + inspect(a); + + 0 +} |