On 14/05/19 12:17 +0100, Jonathan Wakely wrote:
* include/bits/unique_ptr.h (__uniq_ptr_impl): Add move constructor, move assignment operator. (__uniq_ptr_impl::release(), __uniq_ptr_impl::reset(pointer)): Add. (__uniq_ptr_data): New class template with conditionally deleted special members. (unique_ptr, unique_ptr<T[], D>): Change type of data member from __uniq_ptr_impl<T, D> to __uniq_ptr_data<T, D>. Define move constructor and move assignment operator as defaulted. (unique_ptr::release(), unique_ptr<T[], D>::release()): Forward to __uniq_ptr_impl::release(). (unique_ptr::reset(pointer), unique_ptr<T[], D>::reset<U>(U)): Forward to __uniq_ptr_impl::reset(pointer). * python/libstdcxx/v6/printers.py (UniquePointerPrinter.__init__): Check for new __uniq_ptr_data type. * testsuite/20_util/unique_ptr/dr2899.cc: New test.
This updates the Xmethod for the new base class. Tested x86_64-linux, committed to trunk.
commit 5b013bcaeae51850ced6eaff0c6626915565c88a Author: Jonathan Wakely <jwak...@redhat.com> Date: Sat May 18 00:05:47 2019 +0100 PR libstdc++/90520 adjust Xmethod for recent unique_ptr changes 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. diff --git a/libstdc++-v3/python/libstdcxx/v6/printers.py b/libstdc++-v3/python/libstdcxx/v6/printers.py index 162b00760e6..05143153bee 100644 --- a/libstdc++-v3/python/libstdcxx/v6/printers.py +++ b/libstdc++-v3/python/libstdcxx/v6/printers.py @@ -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) diff --git a/libstdc++-v3/python/libstdcxx/v6/xmethods.py b/libstdc++-v3/python/libstdcxx/v6/xmethods.py index c405d8a25d5..623cb80bc0e 100644 --- a/libstdc++-v3/python/libstdcxx/v6/xmethods.py +++ b/libstdc++-v3/python/libstdcxx/v6/xmethods.py @@ -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*()"