summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJonathan Wakely <jwakely@redhat.com>2022-11-16 12:22:04 +0000
committerJonathan Wakely <jwakely@redhat.com>2023-05-11 09:48:27 +0100
commit16a76499f916b5b6d11bccc03cc0d16b2b1ee31b (patch)
tree0ab0029059691f9eaa884524136fd8f477825045
parent896f43215ec8822cbcaee372009ee6768880b3cd (diff)
downloadgcc-16a76499f916b5b6d11bccc03cc0d16b2b1ee31b.tar.gz
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 specialization 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. (cherry picked from commit 3c54805d03ac1bcc3d8547ffb5e6c4e1f301a7a2)
-rw-r--r--libstdc++-v3/python/libstdcxx/v6/printers.py31
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 bb06a4959ee..d27a25bd96f 100644
--- a/libstdc++-v3/python/libstdcxx/v6/printers.py
+++ b/libstdc++-v3/python/libstdcxx/v6/printers.py
@@ -1216,9 +1216,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: