https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93627
Bug ID: 93627 Summary: inconsistencies between sprintf and strcpy overflow warnings Product: gcc Version: 10.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: middle-end Assignee: unassigned at gcc dot gnu.org Reporter: msebor at gcc dot gnu.org Target Milestone: --- -Wformat-overflow diagnoses sprintf calls that might overflow the destination based solely on the size of the array where the string argument to a %s directive is stored, as in f() below. (-Wformat-truncation then diagnoses the possible truncation of the argument.) But -Wstringop-overflow doesn't diagnose the equivalent potential overflow in calls to strcpy (and -Wstringop-truncation likewise doesn't diagnose the truncation in calls to strncpy -- its interpretation of truncation is different from -Wformat-truncation: a missing nul rather than cutting off the trailing part of the source string). This is inconsistent and probably not terribly helpful to users, especially when they're dealing with a warning for code that's in reality safe (but GCC doesn't see it). $ cat z.c && gcc -O2 -S -Wall -Wextra -Wpedantic z.c char a[8], b[16]; void f (void) { __builtin_sprintf (a, "%s", b); // -Wformat-overflow } void fn (void) { __builtin_snprintf (a, sizeof a, "%s", b); // -Wformat-truncation } void g (void) { __builtin_strcpy (a, b); // missing warning } void gn (void) { __builtin_strncpy (a, b, sizeof a - 1); // no warning (?) a[sizeof a - 1] = 0; } z.c: In function ‘f’: z.c:5:26: warning: ‘%s’ directive writing up to 15 bytes into a region of size 8 [-Wformat-overflow=] 5 | __builtin_sprintf (a, "%s", b); // -Wformat-overflow | ^~ ~ z.c:5:3: note: ‘__builtin_sprintf’ output between 1 and 16 bytes into a destination of size 8 5 | __builtin_sprintf (a, "%s", b); // -Wformat-overflow | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ z.c: In function ‘fn’: z.c:10:37: warning: ‘%s’ directive output may be truncated writing up to 15 bytes into a region of size 8 [-Wformat-truncation=] 10 | __builtin_snprintf (a, sizeof a, "%s", b); // -Wformat-truncation | ^~ ~ z.c:10:3: note: ‘__builtin_snprintf’ output between 1 and 16 bytes into a destination of size 8 10 | __builtin_snprintf (a, sizeof a, "%s", b); // -Wformat-truncation | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~