The pretty printer for std::any fails when the contained value is a
locally-defined type, because the name in the debuginfo has
cv-qualifiers and ptr-declarators in different positions. The unexpected
format confuses the printer. This makes the printer's regex handle
either format.

This isn't a complete fix because looking up the contained type fails
when there are two types with the same name (defined in different local
scopes). This applies to all closure types defined in a given function,
as they all appear as "func()::lambda" in the debuginfo names.

        PR libstdc++/87308 (partial)
        * python/libstdcxx/v6/printers.py (StdExpAnyPrinter): Adjust regex to
        work around PR 88166.
        * testsuite/libstdc++-prettyprinters/cxx17.cc: Test std::any
        containing a local type.

Tested x86_64-linux, committed to trunk. Backports also needed.


commit d3b7f2bad0e8f5424d78eaae6d97a27b86989fb7
Author: Jonathan Wakely <jwak...@redhat.com>
Date:   Fri Nov 23 13:35:33 2018 +0000

    PR libstdc++/87308 adjust regex used in std::any pretty printer
    
    The pretty printer for std::any fails when the contained value is a
    locally-defined type, because the name in the debuginfo has
    cv-qualifiers and ptr-declarators in different positions. The unexpected
    format confuses the printer. This makes the printer's regex handle
    either format.
    
    This isn't a complete fix because looking up the contained type fails
    when there are two types with the same name (defined in different local
    scopes). This applies to all closure types defined in a given function,
    as they all appear as "func()::lambda" in the debuginfo names.
    
            PR libstdc++/87308 (partial)
            * python/libstdcxx/v6/printers.py (StdExpAnyPrinter): Adjust regex 
to
            work around PR 88166.
            * testsuite/libstdc++-prettyprinters/cxx17.cc: Test std::any
            containing a local type.

diff --git a/libstdc++-v3/python/libstdcxx/v6/printers.py 
b/libstdc++-v3/python/libstdcxx/v6/printers.py
index 827c87b70ea..28733385dc9 100644
--- a/libstdc++-v3/python/libstdcxx/v6/printers.py
+++ b/libstdc++-v3/python/libstdcxx/v6/printers.py
@@ -1051,7 +1051,7 @@ class StdExpAnyPrinter(SingleObjContainerPrinter):
             func = gdb.block_for_pc(int(mgr.cast(gdb.lookup_type('intptr_t'))))
             if not func:
                 raise ValueError("Invalid function pointer in %s" % 
self.typename)
-            rx = r"""({0}::_Manager_\w+<.*>)::_S_manage\({0}::_Op, {0} 
const\*, {0}::_Arg\*\)""".format(typename)
+            rx = r"""({0}::_Manager_\w+<.*>)::_S_manage\((enum )?{0}::_Op, 
(const {0}|{0} const) ?\*, (union )?{0}::_Arg ?\*\)""".format(typename)
             m = re.match(rx, func.function.name)
             if not m:
                 raise ValueError("Unknown manager function in %s" % 
self.typename)
diff --git a/libstdc++-v3/testsuite/libstdc++-prettyprinters/cxx17.cc 
b/libstdc++-v3/testsuite/libstdc++-prettyprinters/cxx17.cc
index 0c7cb4c9bb6..d3cd77c74db 100644
--- a/libstdc++-v3/testsuite/libstdc++-prettyprinters/cxx17.cc
+++ b/libstdc++-v3/testsuite/libstdc++-prettyprinters/cxx17.cc
@@ -75,6 +75,9 @@ main()
 // { dg-final { regexp-test as2 {std::any containing const char \* = 
{\[contained value\] = 0x[[:xdigit:]]+ "stringiest"}} } }
   any am = *om;
 // { dg-final { note-test am {std::any containing std::map with 3 elements = 
{[1] = 2, [3] = 4, [5] = 6}} } }
+  struct local_type { int i = 99; };
+  any al = local_type{};
+// { dg-final { note-test al {std::any containing local_type = {[contained 
value] = {i = 99}}} } }
 
   struct S { operator int() { throw 42; }};
   variant<float, int, string_view> v0;

Reply via email to