[RFA] Fix crash in quirk_rust_enum

Message ID 20180329175126.30863-1-tom@tromey.com
State New, archived
Headers

Commit Message

Tom Tromey March 29, 2018, 5:51 p.m. UTC
  I noticed that quirk_rust_enum can crash when presented with a union
whose fields are all scalar types.

This patch adds a new test case and fixes the bug.

Regression tested on Fedora 26 x86-64.

2018-03-29  Tom Tromey  <tom@tromey.com>

	* dwarf2read.c (quirk_rust_enum): Handle unions correctly.

2018-03-29  Tom Tromey  <tom@tromey.com>

	* gdb.rust/simple.rs (Union): New type.
	(main): New local "u".
	* gdb.rust/simple.exp (test_one_slice): Add new test case.
---
 gdb/ChangeLog                     | 4 ++++
 gdb/dwarf2read.c                  | 8 +++++++-
 gdb/testsuite/ChangeLog           | 6 ++++++
 gdb/testsuite/gdb.rust/simple.exp | 1 +
 gdb/testsuite/gdb.rust/simple.rs  | 7 +++++++
 5 files changed, 25 insertions(+), 1 deletion(-)
  

Comments

Pedro Alves April 17, 2018, 4:10 p.m. UTC | #1
On 03/29/2018 06:51 PM, Tom Tromey wrote:
> I noticed that quirk_rust_enum can crash when presented with a union
> whose fields are all scalar types.
> 
> This patch adds a new test case and fixes the bug.
> 
> Regression tested on Fedora 26 x86-64.

Even though the code your touching is in dwarf2read.c, it is
Rust-only code, so IMHO you should be able to self-approve it.

I have nothing really useful to say about the change.
Mechanically, looks fine to me.

Thanks,
Pedro Alves
  
Tom Tromey April 17, 2018, 7:37 p.m. UTC | #2
>>>>> "Pedro" == Pedro Alves <palves@redhat.com> writes:

Pedro> Even though the code your touching is in dwarf2read.c, it is
Pedro> Rust-only code, so IMHO you should be able to self-approve it.

Thanks.  I didn't want to presume, but that does make sense.

Tom
  

Patch

diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 78f427fb7e..45e4a6f444 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,7 @@ 
+2018-03-29  Tom Tromey  <tom@tromey.com>
+
+	* dwarf2read.c (quirk_rust_enum): Handle unions correctly.
+
 2018-03-27  Tom Tromey  <tom@tromey.com>
 
 	* utils.c (prompt_for_continue): Use unique_xmalloc_ptr.
diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c
index dfa69d1dbb..772d994737 100644
--- a/gdb/dwarf2read.c
+++ b/gdb/dwarf2read.c
@@ -10078,9 +10078,15 @@  quirk_rust_enum (struct type *type, struct objfile *objfile)
 	{
 	  disr_type = TYPE_FIELD_TYPE (type, i);
 
-	  if (TYPE_NFIELDS (disr_type) == 0)
+	  if (TYPE_CODE (disr_type) != TYPE_CODE_STRUCT)
+	    {
+	      /* All fields of a true enum will be structs.  */
+	      return;
+	    }
+	  else if (TYPE_NFIELDS (disr_type) == 0)
 	    {
 	      /* Could be data-less variant, so keep going.  */
+	      disr_type = nullptr;
 	    }
 	  else if (strcmp (TYPE_FIELD_NAME (disr_type, 0),
 			   "RUST$ENUM$DISR") != 0)
diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog
index 806744dd45..3e762472ab 100644
--- a/gdb/testsuite/ChangeLog
+++ b/gdb/testsuite/ChangeLog
@@ -1,3 +1,9 @@ 
+2018-03-29  Tom Tromey  <tom@tromey.com>
+
+	* gdb.rust/simple.rs (Union): New type.
+	(main): New local "u".
+	* gdb.rust/simple.exp (test_one_slice): Add new test case.
+
 2018-03-27  Joel Brobecker  <brobecker@adacore.com>
 
 	* gdb.ada/varsize_limit: New testcase.
diff --git a/gdb/testsuite/gdb.rust/simple.exp b/gdb/testsuite/gdb.rust/simple.exp
index 2db596b932..09179575b1 100644
--- a/gdb/testsuite/gdb.rust/simple.exp
+++ b/gdb/testsuite/gdb.rust/simple.exp
@@ -274,6 +274,7 @@  gdb_test "print parametrized.next.val" \
 gdb_test "print parametrized" \
     " = simple::ParametrizedStruct<i32> \\{next: simple::ParametrizedEnum<\[a-z:\]*Box<simple::ParametrizedStruct<i32>>>::Val\\{val: $hex\\}, value: 0\\}"
 
+gdb_test "print u" " = simple::Union {f1: -1, f2: 255}"
 
 load_lib gdb-python.exp
 if {[skip_python_tests]} {
diff --git a/gdb/testsuite/gdb.rust/simple.rs b/gdb/testsuite/gdb.rust/simple.rs
index b2b5dfe0f6..e5bbe52122 100644
--- a/gdb/testsuite/gdb.rust/simple.rs
+++ b/gdb/testsuite/gdb.rust/simple.rs
@@ -80,6 +80,11 @@  struct ParametrizedStruct<T> {
     value: T
 }
 
+union Union {
+    f1: i8,
+    f2: u8,
+}
+
 fn main () {
     let a = ();
     let b : [i32; 0] = [];
@@ -153,6 +158,8 @@  fn main () {
         value: 0,
     };
 
+    let u = Union { f2: 255 };
+
     println!("{}, {}", x.0, x.1);        // set breakpoint here
     println!("{}", diff2(92, 45));
     empty();