[PATCH] PR libstdc++/80276 fix pretty printers for array smart pointers
Jonathan Wakely
jwakely@redhat.com
Sat Jan 13 00:30:00 GMT 2018
On 09/01/18 21:51 +0000, Jonathan Wakely wrote:
>This fixes unique_ptr<T[]> so it doesn't print as unique_ptr<T>, and
>fixes a problem in the type-printers that can result in a gdb.error
>exception (see https://sourceware.org/PR22686).
>
> PR libstdc++/80276
> * python/libstdcxx/v6/printers.py (SharedPointerPrinter)
> (UniquePointerPrinter): Print correct template argument, not type of
> the pointer.
> (TemplateTypePrinter._recognizer.recognize): Handle failure to lookup
> a type.
> * testsuite/libstdc++-prettyprinters/cxx11.cc: Test unique_ptr of
> array type.
> * testsuite/libstdc++-prettyprinters/cxx17.cc: Test shared_ptr and
> weak_ptr of array types.
>
>Tested x86_64-linux, committed to trunk.
That patch fixed the unhandled gdb.error exception that got raised,
but it just meant that the type printer gave up and stopped trying to
pretty-print the template arguments. That meant if a template argument
is a type that has a type printer, we don't process it.
This patch rewrites the TemplateTypePrinter to use
gdb.Type.template_arguments() and work directly with the gdb.Type
objects for the template arguments, instead of using a regex to
process strings. This means we don't have to use gdb.lookup_type() to
convert strings to types, and so can handle arrays correctly.
I also made the type printers handle the types defined in namespace
std::__cxx11, which didn't work previously.
There are two (IMHO acceptable) regressions with this change:
basic_string<signed char> and basic_string<unsigned char> will no
longer omit the default template arguments (because the type printers
for those specializations conflict with the ones for std::string,
std::wstring, std::u16string and std::u32string). I don't think this
is a a big deal, because I doubt many people are using strings of
signed/unsigned char. If necessary we could match those
specializations with TemplateTypePrinter:
for abi in ('', '__cxx11'):
for ch in ('signed char', 'unsigned char'):
string_type = abi + 'basic_string<' + ch
add_one_template_type_printer(obj, string_type,
{ 1: 'std::char_traits<{0}>', 2: 'std::allocator<{0}>'})
But do we need type printers for these specializations?
Secondly, std::experimental::optional no longer omits the
fundamentals_v1 inline namespace ... but then it didn't work properly
anyway because it displayed as "std::experimental::optional<\1>". So
arguably it's better to have no type printer than one that displays
the wrong type! I've also removed the type printer for
std::experimental::any was bogus, because it tried to match a
template, and any isn't a template!
I've considered adding a new type of printer which doesn't do anything
fancy, but just prints the type name (omitting any inline namespaces
like "__8", "__cxx11", or "fundamentals_v1"). This would mean that GDB
just shows a string like "type = std::any" instead of printing the
class definition (you could still use "ptype/r for the full output).
If nobody objects to these regressions I'll commit this to trunk.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: patch.txt
Type: text/x-patch
Size: 40212 bytes
Desc: not available
URL: <http://gcc.gnu.org/pipermail/libstdc++/attachments/20180113/1a581938/attachment.bin>
More information about the Libstdc++
mailing list