mirror of
https://github.com/gcc-mirror/gcc.git
synced 2026-05-06 06:49:09 +02:00
libstdc++: Fix std::shared_ptr pretty printer for GDB 11
This pretty printer was updated for GCC 16 to match a change to std::atomic<shared_ptr<T>>. But the gdb.Type.is_scalar property was added in GDB 12.1, so we get an error for older GDB versions. This adds a workaround for older GDB versions. The gdb.Type.tag property is None for scalar types, and should always be defined for the std::atomic class template. Another option would be to use the is_specialization_of function defined in printers.py, but just checking for the tag is simpler. libstdc++-v3/ChangeLog: * python/libstdcxx/v6/printers.py (SharedPointerPrinter): Only use gdb.Type.is_scalar if supported. * testsuite/libstdc++-prettyprinters/compat.cc: Test printer for old implementation of std::atomic<std::shared_ptr<T>>. Reviewed-by: Tomasz Kamiński <tkaminsk@redhat.com>
This commit is contained in:
committed by
Jonathan Wakely
parent
1be41ad752
commit
2e4e58bb43
@@ -292,9 +292,15 @@ class SharedPointerPrinter(printer_base):
|
||||
if self._typename == 'std::atomic':
|
||||
# A tagged pointer is stored as uintptr_t.
|
||||
val = self._val['_M_refcount']['_M_val']
|
||||
if val.type.is_scalar: # GCC 16 stores uintptr_t
|
||||
# GCC 16 stores it directly as uintptr_t
|
||||
# GCC 12-15 stores std::atomic<uintptr_t>
|
||||
if hasattr(val.type, 'is_scalar'): # Added in GDB 12.1
|
||||
val_is_uintptr = val.type.is_scalar
|
||||
else:
|
||||
val_is_uintptr = val.type.tag is None
|
||||
if val_is_uintptr:
|
||||
ptr_val = val
|
||||
else: # GCC 12-15 stores std::atomic<uintptr_t>
|
||||
else:
|
||||
ptr_val = val['_M_i']
|
||||
ptr_val = ptr_val - (ptr_val % 2) # clear lock bit
|
||||
ptr_type = find_type(self._val['_M_refcount'].type, 'pointer')
|
||||
|
||||
@@ -88,6 +88,30 @@ namespace std
|
||||
this->_M_payload._M_engaged = true;
|
||||
}
|
||||
};
|
||||
|
||||
using uintptr_t = __UINTPTR_TYPE__;
|
||||
template<typename T> struct shared_ptr;
|
||||
template<typename T> struct atomic;
|
||||
template<> struct atomic<uintptr_t> { uintptr_t _M_i; };
|
||||
template<typename T> struct sp_atomic;
|
||||
struct sp_counts { int _M_use_count; int _M_weak_count; };
|
||||
|
||||
// Old representation of std::atomic<std::shared_ptr<T>>, before GCC 16
|
||||
template<typename T>
|
||||
struct sp_atomic<shared_ptr<T>>
|
||||
{
|
||||
T* _M_ptr = nullptr;
|
||||
struct Impl {
|
||||
atomic<uintptr_t> _M_val;
|
||||
using pointer = sp_counts*;
|
||||
} _M_refcount;
|
||||
};
|
||||
template<typename T>
|
||||
struct atomic<shared_ptr<T>>
|
||||
{
|
||||
sp_atomic<shared_ptr<T>> _M_impl;
|
||||
};
|
||||
|
||||
} // namespace std
|
||||
|
||||
int
|
||||
@@ -110,6 +134,16 @@ main()
|
||||
optional<void*> op{nullptr};
|
||||
// { dg-final { note-test op {std::optional = {[contained value] = 0x0}} } }
|
||||
|
||||
std::atomic<std::shared_ptr<int>> aspe{};
|
||||
// { dg-final { note-test aspe {std::atomic<std::shared_ptr<int>> (empty) = {get() = 0x0}} } }
|
||||
|
||||
std::sp_counts counts{ 1, 3 };
|
||||
std::sp_atomic<std::shared_ptr<int>>::Impl::pointer p = &counts;
|
||||
std::atomic<std::shared_ptr<int>> asp{};
|
||||
asp._M_impl._M_ptr = reinterpret_cast<int*>(0x1234abcd);
|
||||
asp._M_impl._M_refcount._M_val._M_i = reinterpret_cast<std::uintptr_t>(p);
|
||||
// { dg-final { note-test asp {std::atomic<std::shared_ptr<int>> (use count 1, weak count 2) = {get() = 0x1234abcd}} } }
|
||||
|
||||
__builtin_puts("");
|
||||
return 0; // Mark SPOT
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user