aboutsummaryrefslogtreecommitdiff
path: root/gdb/dwarf2read.c
diff options
context:
space:
mode:
authorTom Tromey <tom@tromey.com>2019-10-03 17:21:52 -0600
committerTom Tromey <tom@tromey.com>2019-10-03 20:56:22 -0600
commit77c2dba3e843694fae090e237ccdf1b8f65b94e6 (patch)
tree8076f2237aa8155c67f4adbad3c5e40317969d0d /gdb/dwarf2read.c
parentf0e21cb80940c065dcc373c29dc33388cf948dbc (diff)
downloadfsf-binutils-gdb-77c2dba3e843694fae090e237ccdf1b8f65b94e6.zip
fsf-binutils-gdb-77c2dba3e843694fae090e237ccdf1b8f65b94e6.tar.gz
fsf-binutils-gdb-77c2dba3e843694fae090e237ccdf1b8f65b94e6.tar.bz2
Avoid crash on single-field union in Rust
PR rust/24976 points out a crash in gdb when a single-field union is used in Rust. The immediate problem was a NULL pointer dereference in quirk_rust_enum. However, that code is also erroneously treating a single-field union as if it were a univariant enum. Looking at the output of an older Rust compiler, it turns out that univariant enums are distinguished by having a single *anonymous* field. This patch changes quirk_rust_enum to limit its fixup to this case. Tested with a new-enough version of the Rust compiler to cause the crash; plus by using an older executable that uses the old univariant encoding. gdb/ChangeLog 2019-10-03 Tom Tromey <tom@tromey.com> PR rust/24976: * dwarf2read.c (quirk_rust_enum): Handle single-element unions. gdb/testsuite/ChangeLog 2019-10-03 Tom Tromey <tom@tromey.com> PR rust/24976: * gdb.rust/simple.rs (Union2): New type. (main): Use Union2. * gdb.rust/simple.exp: Add test.
Diffstat (limited to 'gdb/dwarf2read.c')
-rw-r--r--gdb/dwarf2read.c6
1 files changed, 3 insertions, 3 deletions
diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c
index c0dd199..ee9df34 100644
--- a/gdb/dwarf2read.c
+++ b/gdb/dwarf2read.c
@@ -10076,10 +10076,10 @@ quirk_rust_enum (struct type *type, struct objfile *objfile)
SET_FIELD_BITPOS (TYPE_FIELD (type, 0), 0);
TYPE_FIELD_NAME (type, 0) = "<<variants>>";
}
- else if (TYPE_NFIELDS (type) == 1)
+ /* A union with a single anonymous field is probably an old-style
+ univariant enum. */
+ else if (TYPE_NFIELDS (type) == 1 && streq (TYPE_FIELD_NAME (type, 0), ""))
{
- /* We assume that a union with a single field is a univariant
- enum. */
/* Smash this type to be a structure type. We have to do this
because the type has already been recorded. */
TYPE_CODE (type) = TYPE_CODE_STRUCT;