[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