https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104746
--- Comment #8 from Martin Sebor <msebor at gcc dot gnu.org> --- Andrew, quoting from the documentation for the warning: Unknown string arguments whose length cannot be assumed to be bounded either by the directive’s precision, or by a finite set of string literals they may evaluate to, or the character array they may point to, are assumed to be 1 character long. The length of the second string argument to the second sprintf call is assumed to be bounded by the size of the array allocated by the first call to malloc. The malloc argument is at most 2147483654 (INT_MAX + strlen (".mount") + 1), so the maximum length of the string is 2147483653. That's also what the warning prints. The ability to determine and use the maximum length was added in r12-7033 to avoid the warning reported in PR 104119. Because GCC 11 doesn't have this ability, it assumes the length of the string argument is 1, and so the warning doesn't trigger there. That could be considered a bug or limitation in GCC 11. The instance of the warning in the test case in comment #3 is designed point out directives whose output may exceed the environmental limit of 4095 bytes (the minimum the C standard requires implementations to support). It's working as designed and as intended. If you don't like the design and want to propose a change I suggest you submit a concrete proposal and we can discuss it. As for my integer test from comment #7, you're right that if each argument was in the range [0, 9] that the warning would be avoided. I didn't get the limits quite right. A test case that should better illustrate the point I was making about the constraints derived from relationships might go something like this: char a[4]; void f (int i, int j) { if (i < 0 || j < 0 || i + j > 19) return; __builtin_sprintf (a, "%u%u", i, j); } Here, setting the range of each of i and j on its own to [0, 19] isn't enough to rule out a possible overflow; we also need to capture the constraint that if one is two digits the other must be just one. At the moment there is no logic to determine that. I think the corresponding test case for a possible optimization is this: void f (int i, int j) { if (i < 0 || j < 0 || i + j > 19) return; if (i * j > 90) // fold to false __builtin_abort (); }