https://gcc.gnu.org/bugzilla/show_bug.cgi?id=98465
--- Comment #14 from Martin Sebor <msebor at gcc dot gnu.org> --- Smallish test case independent of libstdc++ that reproduces both the false positive (due to the missing aliasing constraint) and its absence (due to a bug/limitation in tree_inlined_location). With -Wsystem-headers GCC issues two instances of the false positive, one for f() and the other for g(): $ cat pr98465.C && gcc -O2 -S -Wall -Wextra pr98465.C # 1 "pr98465.h" 1 3 typedef __SIZE_TYPE__ size_type; typedef __UINTPTR_TYPE__ uintptr_t; struct S { char *dta; size_type cap, siz; bool _M_disjunct (const char *s) const { return ((uintptr_t)s < (uintptr_t)dta || (uintptr_t)dta + siz < (uintptr_t)s); } void assign (const char *s, size_type n) { assign2 (s, n); } void assign2 (const char *s, size_type n) { _M_replace (0, siz, s, n); } void _M_replace (size_type pos, size_type len1, const char* s, const size_type len2) { const size_type old_size = siz; const size_type new_size = old_size + len2 - len1; if (new_size <= cap) { char *p = dta + pos; const size_type how_much = old_size - pos - len1; if (_M_disjunct (s)) { if (how_much && len1 != len2) __builtin_memmove (p + len2, p + len1, how_much); if (len2) __builtin_memcpy (p, s, len2); } else { if (len2 && len2 <= len1) __builtin_memmove (p, s, len2); if (how_much && len1 != len2) __builtin_memmove (p + len2, p + len1, how_much); if (len2 > len1) { if (s + len2 <= p + len1) __builtin_memmove (p, s, len2); else if (s >= p + len1) __builtin_memcpy (p, s + len2 - len1, len2); else { const size_type nleft = (p + len1) - s; __builtin_memmove (p, s, nleft); __builtin_memcpy (p + nleft, p + len2, len2 - nleft); } } } } } }; # 1 "pr98465.C" const char a[] = { 1, 2 }; void f (S &s) { s.assign (a, 2); // no warning } const char b[] = { 2, 3 }; void g (S &s) { s.assign2 (b, 2); // bogus -Wstringop-overread } In file included from pr98465.C:1: In member function ‘void S::_M_replace(size_type, size_type, const char*, size_type)’, inlined from ‘void S::assign2(const char*, size_type)’ at pr98465.h:19:16, inlined from ‘void g(S&)’ at pr98465.C:13:13: pr98465.h:50:24: warning: ‘void* __builtin_memcpy(void*, const void*, long unsigned int)’ reading 2 bytes from a region of size 1 [-Wstringop-overread] In file included from pr98465.C:1: pr98465.C: In function ‘void g(S&)’: pr98465.C:9:12: note: at offset [1, 2] into source object ‘b’ of size 2 9 | | ^