Reproducer: ``` #include <atomic> class nsISupports { public: virtual int Release(); }; struct JSPrincipals { std::atomic<int> refcount; }; class nsJSPrincipals : nsISupports, JSPrincipals { static nsJSPrincipals* get(JSPrincipals* principals) { return static_cast<nsJSPrincipals*>(principals); } void Destroy(JSPrincipals* jsprin); }; void nsJSPrincipals::Destroy(JSPrincipals* jsprin) { nsJSPrincipals* nsjsprin = nsJSPrincipals::get(jsprin); nsjsprin->refcount.fetch_add(1, std::memory_order_acq_rel); nsjsprin->Release(); } ``` Compile with: g++ -c -O2 -Werror=stringop-overflow It says: ``` In file included from /builds/worker/fetches/gcc/include/c++/12.2.0/atomic:41, from Unified_cpp_caps0.ii.cpp:1: In member function 'std::__atomic_base<_IntTp>::__int_type std::__atomic_base<_IntTp>::fetch_add(__int_type, std::memory_order) [with _ITp = int]', inlined from 'void nsJSPrincipals::Destroy(JSPrincipals*)' at Unified_cpp_caps0.ii.cpp:19:30: /builds/worker/fetches/gcc/include/c++/12.2.0/bits/atomic_base.h:618:34: error: 'unsigned int __atomic_fetch_add_4(volatile void*, unsigned int, int)' writing 4 bytes into a region of size 0 overflows the destination [-Werror=stringop-overflow=] 618 | { return __atomic_fetch_add(&_M_i, __i, int(__m)); } | ~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~ cc1plus: some warnings being treated as errors ```
PR 109571 is basically the same here just with a different warning (and upcasting instead of downcasting). In this case if we look at: void nsJSPrincipals::Destroy(JSPrincipals* jsprin) { nsJSPrincipals* nsjsprin = nsJSPrincipals::get(jsprin); if jsprin is null, then nsjsprin needs to be null too. And since nsjsprin == jsprin-8(bytes) (if it was a valid pointer), the C++ front-end needs to add a check for null. And then the optimizations come along and does jump threading. so one way of removing this is adding an assumption which can be done via one of the following: if (!jsprin) __builtin_unreachable(); [[assume(jsprin)]]; The first one is valid for GCC all the way back in 4.7 (and before). the second one is C++23 and was only added in GCC 13.