diff options
author | Tom Tromey <tom@tromey.com> | 2022-06-05 11:28:10 -0600 |
---|---|---|
committer | Tom Tromey <tom@tromey.com> | 2022-06-18 10:18:35 -0600 |
commit | 8e2da165187907a570a33eee7e56ce16fc597a40 (patch) | |
tree | bbc9dc6ea5ca71ab87c5f8de4381aae3c623ee01 /gdb | |
parent | fba1ac87dcb76e61f270d236f1e7c8aaec80f9c4 (diff) | |
download | binutils-gdb-8e2da165187907a570a33eee7e56ce16fc597a40.tar.gz |
Fix assertion failure in copy_type
PR exp/20630 points out a simple way to cause an assertion failure in
copy_type -- but this was found in the wild a few times as well.
copy_type only works for objfile-owned types, but there isn't a deep
reason for this. This patch fixes the bug by updating copy_type to
work for any sort of type.
Better would perhaps be to finally implement type GC, but I still
haven't attempted this.
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=20630
Diffstat (limited to 'gdb')
-rw-r--r-- | gdb/gdbtypes.c | 21 | ||||
-rw-r--r-- | gdb/testsuite/gdb.base/printcmds.exp | 3 |
2 files changed, 12 insertions, 12 deletions
diff --git a/gdb/gdbtypes.c b/gdb/gdbtypes.c index 2a51372a037..c8f98554859 100644 --- a/gdb/gdbtypes.c +++ b/gdb/gdbtypes.c @@ -5796,27 +5796,24 @@ copy_type_recursive (struct objfile *objfile, } /* Make a copy of the given TYPE, except that the pointer & reference - types are not preserved. - - This function assumes that the given type has an associated objfile. - This objfile is used to allocate the new type. */ + types are not preserved. */ struct type * copy_type (const struct type *type) { - struct type *new_type; - - gdb_assert (type->is_objfile_owned ()); - - new_type = alloc_type_copy (type); + struct type *new_type = alloc_type_copy (type); new_type->set_instance_flags (type->instance_flags ()); TYPE_LENGTH (new_type) = TYPE_LENGTH (type); memcpy (TYPE_MAIN_TYPE (new_type), TYPE_MAIN_TYPE (type), sizeof (struct main_type)); if (type->main_type->dyn_prop_list != NULL) - new_type->main_type->dyn_prop_list - = copy_dynamic_prop_list (&type->objfile_owner ()->objfile_obstack, - type->main_type->dyn_prop_list); + { + struct obstack *storage = (type->is_objfile_owned () + ? &type->objfile_owner ()->objfile_obstack + : gdbarch_obstack (type->arch_owner ())); + new_type->main_type->dyn_prop_list + = copy_dynamic_prop_list (storage, type->main_type->dyn_prop_list); + } return new_type; } diff --git a/gdb/testsuite/gdb.base/printcmds.exp b/gdb/testsuite/gdb.base/printcmds.exp index 04d390d3658..c0c59c5c503 100644 --- a/gdb/testsuite/gdb.base/printcmds.exp +++ b/gdb/testsuite/gdb.base/printcmds.exp @@ -794,6 +794,9 @@ proc test_print_array_constants {} { gdb_test_escape_braces "print {{0,1,2},{3,4,5}}" " = {{0, 1, 2}, {3, 4, 5}}" gdb_test "print {4,5,6}\[2\]" " = 6" gdb_test "print *&{4,5,6}\[1\]" "Attempt to take address of value not located in memory." + + # This used to cause a crash. + gdb_test "print {unsigned char[]}{65}" " = 65 'A'" } proc test_print_enums {} { |