diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index dbf1a8865f6..c7b20f10dc5 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,12 @@ +2019-05-18 Jonathan Wakely + + 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 * include/bits/stl_deque.h 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::operator*()"