diff options
author | Jonathan Wakely <jwakely@redhat.com> | 2022-11-16 12:22:04 +0000 |
---|---|---|
committer | Jonathan Wakely <jwakely@redhat.com> | 2022-11-16 13:37:38 +0000 |
commit | 3c54805d03ac1bcc3d8547ffb5e6c4e1f301a7a2 (patch) | |
tree | fe996f1a3c2f9c230f8f478495f5112ec2bb06a3 /libstdc++-v3/python/libstdcxx | |
parent | 922816220210c53eb889733b5832cbd39353ff8c (diff) | |
download | gcc-3c54805d03ac1bcc3d8547ffb5e6c4e1f301a7a2.zip gcc-3c54805d03ac1bcc3d8547ffb5e6c4e1f301a7a2.tar.gz gcc-3c54805d03ac1bcc3d8547ffb5e6c4e1f301a7a2.tar.bz2 |
libstdc++: Fix std::any pretty printer
The recent changes to FilteringTypePrinter affect the result of
gdb.lookup_type('std::string') in StdExpAnyPrinter, causing it to always
return the std::__cxx11::basic_string specialization. This then causes a
gdb.error exception when trying to lookup the std::any manager type for
a specliaization using that string, but that manager was never
instantiated in the program. This causes FAILs when running the tests
with -D_GLIBCXX_USE_CXX11_ABI=0:
FAIL: libstdc++-prettyprinters/libfundts.cc print as
FAIL: libstdc++-prettyprinters/libfundts.cc print as
The ugly solution used in this patch is to repeat the lookup for every
type that std::string could be a typedef for, and hope it only works for
one of them.
libstdc++-v3/ChangeLog:
* python/libstdcxx/v6/printers.py (StdExpAnyPrinter): Make
expansion of std::string in manager name more robust.
Diffstat (limited to 'libstdc++-v3/python/libstdcxx')
-rw-r--r-- | libstdc++-v3/python/libstdcxx/v6/printers.py | 31 |
1 files changed, 28 insertions, 3 deletions
diff --git a/libstdc++-v3/python/libstdcxx/v6/printers.py b/libstdc++-v3/python/libstdcxx/v6/printers.py index 19c70d1..1abf0a4 100644 --- a/libstdc++-v3/python/libstdcxx/v6/printers.py +++ b/libstdc++-v3/python/libstdcxx/v6/printers.py @@ -1272,9 +1272,34 @@ class StdExpAnyPrinter(SingleObjContainerPrinter): mgrname = m.group(1) # FIXME need to expand 'std::string' so that gdb.lookup_type works if 'std::string' in mgrname: - mgrname = re.sub("std::string(?!\w)", str(gdb.lookup_type('std::string').strip_typedefs()), m.group(1)) - - mgrtype = gdb.lookup_type(mgrname) + # This lookup for std::string might return the __cxx11 version, + # but that's not necessarily the one used by the std::any + # manager function we're trying to find. + strings = {str(gdb.lookup_type('std::string').strip_typedefs())} + # So also consider all the other possible std::string types! + s = 'basic_string<char, std::char_traits<char>, std::allocator<char> >' + quals = ['std::', 'std::__cxx11::', 'std::' + _versioned_namespace] + strings |= {q+s for q in quals} # set of unique strings + mgrtypes = [] + for s in strings: + try: + x = re.sub("std::string(?!\w)", s, m.group(1)) + # The following lookup might raise gdb.error if the + # manager function was never instantiated for 's' in the + # program, because there will be no such type. + mgrtypes.append(gdb.lookup_type(x)) + except gdb.error: + pass + if len(mgrtypes) != 1: + # FIXME: this is unlikely in practice, but possible for + # programs that use both old and new string types with + # std::any in a single program. Can we do better? + # Maybe find the address of each type's _S_manage and + # compare to the address stored in _M_manager? + raise ValueError('Cannot uniquely determine std::string type used in std::any') + mgrtype = mgrtypes[0] + else: + mgrtype = gdb.lookup_type(mgrname) self.contained_type = mgrtype.template_argument(0) valptr = None if '::_Manager_internal' in mgrname: |