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.
This commit is contained in:
parent
f0e21cb809
commit
77c2dba3e8
5 changed files with 23 additions and 3 deletions
|
@ -1,3 +1,8 @@
|
|||
2019-10-03 Tom Tromey <tom@tromey.com>
|
||||
|
||||
PR rust/24976:
|
||||
* dwarf2read.c (quirk_rust_enum): Handle single-element unions.
|
||||
|
||||
2019-10-03 Andrew Burgess <andrew.burgess@embecosm.com>
|
||||
|
||||
* f-lang.c (f_language_defn): Use cp_get_symbol_name_matcher and
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -1,3 +1,10 @@
|
|||
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.
|
||||
|
||||
2019-10-03 Andrew Burgess <andrew.burgess@embecosm.com>
|
||||
|
||||
* gdb.fortran/nested-funcs-2.exp: Run tests with and without the
|
||||
|
|
|
@ -309,6 +309,8 @@ gdb_test_sequence "ptype/o SimpleLayout" "" {
|
|||
" }"
|
||||
}
|
||||
|
||||
gdb_test "print u2" " = simple::Union2 {name: \\\[1\\\]}"
|
||||
|
||||
# PR rust/23626 - this used to crash. Note that the results are
|
||||
# fairly lax because most existing versions of Rust (those before the
|
||||
# DW_TAG_variant patches) do not emit what gdb wants here; and there
|
||||
|
|
|
@ -85,6 +85,10 @@ union Union {
|
|||
f2: u8,
|
||||
}
|
||||
|
||||
pub union Union2 {
|
||||
pub name: [u8; 1],
|
||||
}
|
||||
|
||||
struct StringAtOffset {
|
||||
pub field1: &'static str,
|
||||
pub field2: i32,
|
||||
|
@ -180,6 +184,8 @@ fn main () {
|
|||
|
||||
let empty_enum_value: EmptyEnum;
|
||||
|
||||
let u2 = Union2 { name: [1] };
|
||||
|
||||
println!("{}, {}", x.0, x.1); // set breakpoint here
|
||||
println!("{}", diff2(92, 45));
|
||||
empty();
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue