PR libstdc++/90520 adjust Xmethod for recent unique_ptr changes
authorJonathan Wakely <jwakely@redhat.com>
Fri, 17 May 2019 23:08:00 +0000 (00:08 +0100)
committerJonathan Wakely <redi@gcc.gnu.org>
Fri, 17 May 2019 23:08:00 +0000 (00:08 +0100)
PR libstdc++/90520
* python/libstdcxx/v6/printers.py (UniquePointerPrinter.__init__):
Raise exception if unique_ptr tuple member has unknown structure.
* python/libstdcxx/v6/xmethods.py (UniquePtrGetWorker.__call__):
Adjust worker to support new __uniq_ptr_data base class. Do not
assume field called _M_head_impl is the first tuple element.

From-SVN: r271363

libstdc++-v3/ChangeLog
libstdc++-v3/python/libstdcxx/v6/printers.py
libstdc++-v3/python/libstdcxx/v6/xmethods.py

index dbf1a8865f6a6dc89c6080ad84de9ad0e95c8f80..c7b20f10dc52d8840f98ec972f7831a6660895fa 100644 (file)
@@ -1,3 +1,12 @@
+2019-05-18  Jonathan Wakely  <jwakely@redhat.com>
+
+       PR libstdc++/90520
+       * python/libstdcxx/v6/printers.py (UniquePointerPrinter.__init__):
+       Raise exception if unique_ptr tuple member has unknown structure.
+       * python/libstdcxx/v6/xmethods.py (UniquePtrGetWorker.__call__):
+       Adjust worker to support new __uniq_ptr_data base class. Do not
+       assume field called _M_head_impl is the first tuple element.
+
 2019-05-17  François Dumont  <fdumont@gcc.gnu.org>
 
        * include/bits/stl_deque.h
index 162b00760e65e358d33836ababea8e855313d76a..05143153bee285bb34447d32e77c835ca2b6d575 100644 (file)
@@ -197,6 +197,8 @@ class UniquePointerPrinter:
             self.pointer = tuple_member['_M_head_impl']
         elif head_field.is_base_class:
             self.pointer = tuple_member.cast(head_field.type)
+        else:
+            raise ValueError("Unsupported implementation for tuple in unique_ptr: %s" % impl_type)
 
     def children (self):
         return SmartPtrIterator(self.pointer)
index c405d8a25d535f34f036fc4763156a04a198d376..623cb80bc0e5e439e1662b11659ce77f506a83a4 100644 (file)
@@ -586,11 +586,22 @@ class UniquePtrGetWorker(gdb.xmethod.XMethodWorker):
 
     def __call__(self, obj):
         impl_type = obj.dereference().type.fields()[0].type.tag
-        if re.match('^std::(__\d+::)?__uniq_ptr_impl<.*>$', impl_type): # New implementation
-            return obj['_M_t']['_M_t']['_M_head_impl']
+        # Check for new implementations first:
+        if re.match('^std::(__\d+::)?__uniq_ptr_(data|impl)<.*>$', impl_type):
+            tuple_member = obj['_M_t']['_M_t']
         elif re.match('^std::(__\d+::)?tuple<.*>$', impl_type):
-            return obj['_M_t']['_M_head_impl']
-        return None
+            tuple_member = obj['_M_t']
+        else:
+            return None
+        tuple_impl_type = tuple_member.type.fields()[0].type # _Tuple_impl
+        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':
+            return tuple_member['_M_head_impl']
+        elif head_field.is_base_class:
+            return tuple_member.cast(head_field.type)
+        else:
+            return None
 
 class UniquePtrDerefWorker(UniquePtrGetWorker):
     "Implements std::unique_ptr<T>::operator*()"