-stringop-truncation works as expected with statically allocated arrays but fails to detect the same problem involving dynamically allocated arrays. $ cat t.c && gcc -O2 -S -Wall t.c void sink (void*); void f0 (const char *s) { char a[7]; __builtin_strncpy (a, s, sizeof a); // -Wstringop-truncation (good) sink (a); } void f1 (const char *s, unsigned n) { if (n > 256) n = 256; char a[n]; __builtin_strncpy (a, s, n); // missing warning sink (a); } void f2 (const char *s, unsigned n) { if (n > 256) n = 256; char *p = __builtin_alloca (n); // missing warning __builtin_strncpy (p, s, n); sink (p); } void f3 (const char *s, unsigned n) { if (n > 256) n = 256; char *p = __builtin_malloc (n); __builtin_strncpy (p, s, n); // missing warning sink (p); } t.c: In function ‘f0’: t.c:6:3: warning: ‘__builtin_strncpy’ specified bound 7 equals destination size [-Wstringop-truncation] __builtin_strncpy (a, s, sizeof a); // -Wstringop-truncation (good) ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~