[RFA,1/2] Conditionally drop the discriminant field in quirk_rust_enum

Message ID 20180412190756.16052-2-tom@tromey.com
State New, archived
Headers

Commit Message

Tom Tromey April 12, 2018, 7:07 p.m. UTC
  While debugging the crash that Jan reported, I noticed that in some
situations we could end up with a situation where one branch of a Rust
enum type ended up with a field count of -1.

The fix is simple: only conditionally drop the discriminant field when
rewriting the enum variants.

I couldn't find a way to test this; I only noticed it while debugging
the DWARF reader.

2018-04-12  Tom Tromey  <tom@tromey.com>

	* dwarf2read.c (quirk_rust_enum): Conditionally drop the
	discriminant field.
---
 gdb/ChangeLog    | 5 +++++
 gdb/dwarf2read.c | 9 ++++++---
 2 files changed, 11 insertions(+), 3 deletions(-)
  

Comments

Joel Brobecker April 13, 2018, 7:35 a.m. UTC | #1
Hi Tom,

> 2018-04-12  Tom Tromey  <tom@tromey.com>
> 
> 	* dwarf2read.c (quirk_rust_enum): Conditionally drop the
> 	discriminant field.

Looks good!
  

Patch

diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 649c9cea97..ceaa5f92ab 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,8 @@ 
+2018-04-12  Tom Tromey  <tom@tromey.com>
+
+	* dwarf2read.c (quirk_rust_enum): Conditionally drop the
+	discriminant field.
+
 2018-03-29  Tom Tromey  <tom@tromey.com>
 
 	* dwarf2read.c (quirk_rust_enum): Handle unions correctly.
diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c
index 0d3af00c46..4207e4c531 100644
--- a/gdb/dwarf2read.c
+++ b/gdb/dwarf2read.c
@@ -10079,10 +10079,13 @@  quirk_rust_enum (struct type *type, struct objfile *objfile)
 	  if (iter != discriminant_map.end ())
 	    disc->discriminants[i] = iter->second;
 
-	  /* Remove the discriminant field.  */
+	  /* Remove the discriminant field, if it exists.  */
 	  struct type *sub_type = TYPE_FIELD_TYPE (union_type, i);
-	  --TYPE_NFIELDS (sub_type);
-	  ++TYPE_FIELDS (sub_type);
+	  if (TYPE_NFIELDS (sub_type) > 0)
+	    {
+	      --TYPE_NFIELDS (sub_type);
+	      ++TYPE_FIELDS (sub_type);
+	    }
 	  TYPE_FIELD_NAME (union_type, i) = variant_name;
 	  TYPE_NAME (sub_type)
 	    = rust_fully_qualify (&objfile->objfile_obstack,