public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug libstdc++/103086] New: [11/12 Regression] std::unique_ptr printer gets confused by [[no_unique_address]] in tuple
@ 2021-11-04 17:29 redi at gcc dot gnu.org
  2021-11-04 17:29 ` [Bug libstdc++/103086] " redi at gcc dot gnu.org
                   ` (12 more replies)
  0 siblings, 13 replies; 14+ messages in thread
From: redi at gcc dot gnu.org @ 2021-11-04 17:29 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103086

            Bug ID: 103086
           Summary: [11/12 Regression] std::unique_ptr printer gets
                    confused by [[no_unique_address]] in tuple
           Product: gcc
           Version: 11.2.1
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: libstdc++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: redi at gcc dot gnu.org
  Target Milestone: ---

When using GDB 11 or 12 and GCC 11 or 12 the pretty printer for std::unique_ptr
shows the value of the deleter instead of the pointer:

$1 = std::unique_ptr<datum> = {get() = {<No data fields>}}

I filed this as https://sourceware.org/bugzilla/show_bug.cgi?id=28480 but with
Bruno's help we realised it's actually a libstdc++ printer bug.

The problem is that since std::tuple started using [[no_unique_address]] the
tuple<T*, default_delete<T>> object has two _M_head_impl subobjects, in
different base classes. That means this printer code is ambiguous:

        tuple_head_type = tuple_impl_type.fields()[1].type   # _Head_base
        head_field = tuple_head_type.fields()[0]
        if head_field.name == '_M_head_impl':
            self.pointer = tuple_member['_M_head_impl']

In older versions of GDB it happened to work by chance, because GDB returned
the last _M_head_impl member and std::tuple's base classes are stored in
reverse order, so the last one was the T* element of the tuple. Since GDB 11 it
returns the first _M_head_impl, which is probably more sensible, but now the
printer gets the default_delete<T> element.

The fix is for the printer to stop using an ambiguous field name and cast the
tuple to the right base class before accessing the _M_head_impl member:

--- a/libstdc++-v3/python/libstdcxx/v6/printers.py
+++ b/libstdc++-v3/python/libstdcxx/v6/printers.py
@@ -258,7 +258,7 @@ class UniquePointerPrinter:
         tuple_head_type = tuple_impl_type.fields()[1].type   # _Head_base
         head_field = tuple_head_type.fields()[0]
         if head_field.name == '_M_head_impl':
-            self.pointer = tuple_member['_M_head_impl']
+            self.pointer = tuple_member.cast(tuple_head_type)['_M_head_impl']
         elif head_field.is_base_class:
             self.pointer = tuple_member.cast(head_field.type)
         else:

^ permalink raw reply	[flat|nested] 14+ messages in thread

end of thread, other threads:[~2022-01-05 17:56 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-11-04 17:29 [Bug libstdc++/103086] New: [11/12 Regression] std::unique_ptr printer gets confused by [[no_unique_address]] in tuple redi at gcc dot gnu.org
2021-11-04 17:29 ` [Bug libstdc++/103086] " redi at gcc dot gnu.org
2021-11-04 21:30 ` redi at gcc dot gnu.org
2021-11-04 23:06 ` cvs-commit at gcc dot gnu.org
2021-11-04 23:10 ` redi at gcc dot gnu.org
2021-11-05  7:24 ` [Bug libstdc++/103086] [11 " rguenth at gcc dot gnu.org
2021-11-23 17:33 ` redi at gcc dot gnu.org
2021-11-23 21:18 ` cvs-commit at gcc dot gnu.org
2021-11-23 21:18 ` redi at gcc dot gnu.org
2021-11-23 21:41 ` cvs-commit at gcc dot gnu.org
2021-11-24 11:50 ` cvs-commit at gcc dot gnu.org
2022-01-05 17:53 ` cvs-commit at gcc dot gnu.org
2022-01-05 17:53 ` cvs-commit at gcc dot gnu.org
2022-01-05 17:56 ` redi at gcc dot gnu.org

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).