Closed mdavidsaver closed 11 months ago
As far as I can tell, the compiler appears to be triggering on a code path in __shared_count(_Ptr __p, _Deleter __d, _Alloc __a)
where std::bad_alloc
is thrown while allocating the ref. counter. And then only when the element type has a non-trivial destructor. This code does not appear to change between G++ 12 and 13.
#include <memory>
template<typename E>
struct sa_default_delete {
void operator()(E* e) const { delete[] e; }
};
int x(int z) {
typedef std::unique_ptr<int> T;
std::shared_ptr<T> y(new T[2], sa_default_delete<T>());
y.get()[0] = T(new int(z));
return *y.get()[0];
}
The trigger seems to be a non-trivial destructor looking at *this
.
Omitting -Wall
suppresses the error. Then g++ 12 and 13 generate identical code. So, this I am going to conclude that this is a bug in the warning logic, not code generation. Now to find a workaround...
I find some references to GCC 12 specific errors involving -Wuse-after-free
. Although none exactly match this situation.
Apparently, only the case in testshared
w/ std::unique_ptr
triggers this issue. The usage with Value
(built around std::shared_ptr
) does not. 88f09659e46497c353832aaa77f87dfb491702c2 changes that case to a simpler non-copyable element type, which was my original intent.
Another (maybe) similar situation
size_t len = regerror(err, &ex, nullptr, 0u);
std::vector<char> msg(len+1);
(void)regerror(err, &ex, msg.data(), len);
Here g++ 12 complains that msg.data()
may be null while len
is not. However, I don't believe this is possible as msg.size()
will always be at least 1. In this case, I could workaround by inserting if(!msg.data()) { __builtin_unreachable(); }
. However, this code is normally only used with G++ 4.9 and 4.10 when std::regexp
was defined, but non-functional.
G++ 12 (default w/ debian 12) gives the following error with
-O2 -Wall
. This appears to be spurious. G++ 11.x and 13.x do not complain.