aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPhilip Herron <philip.herron@embecosm.com>2022-01-04 16:15:26 +0000
committerPhilip Herron <philip.herron@embecosm.com>2022-01-04 16:15:26 +0000
commit5b369a61484c52ea0298cfab11858c3fff8bcc00 (patch)
treee7645e6d3c0f017d62e04917b85174fb0a2b446a
parent69f6be3ee483c9895b4b5187a44b3e1c8be2ba63 (diff)
downloadgcc-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.cc3
-rw-r--r--gcc/rust/typecheck/rust-tyty.h2
-rw-r--r--gcc/testsuite/rust/execute/torture/issue-851.rs35
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
+}