GCC 12.1 Released
GCC 12.1 Released
Posted May 9, 2022 10:08 UTC (Mon) by excors (subscriber, #95769)In reply to: GCC 12.1 Released by wtarreau
Parent article: GCC 12.1 Released
You could remove the length check and do "if (snprintf(...) >= sizeof(fullpath)) return -1;", because -Wformat-truncation=1 only warns if it heuristically estimates that truncation is likely *and* the return value is unused. That would make the code simpler and more robust, since it no longer relies on you manually replicating snprintf's length calculation, and would eliminate the warning.
> if I lower the limit on the sump of strlen() in the first check to sizeof/2, it accepts to pass!
I suspect the compiler is converting the check into "strlen(dir) + strlen(file) > 4096/2-2", and both values are unsigned so it can deduce strlen(dir) <= 2046 and strlen(file) <= 2046, but it forgets the relationship between them because it doesn't support multi-variable constraints on string lengths - it just has an integer upper/lower bound for each string independently (I think?). Then it knows the snprintf won't need more than 4094 bytes and can't overflow. In the original code, all it can deduce is strlen(dir) <= 4096 etc, which isn't sufficient to prove it won't overflow.
It appears this only fixes the warning at -O2, not -O1, seemingly because -O1 doesn't deduce string length constraints from strlen comparisons and it just uses the declared length instead.
The GCC documentation says:
> When the exact number of bytes written by a format directive cannot be determined at compile-time it is estimated based on heuristics that depend on the level argument and on optimization. While enabling optimization will in most cases improve the accuracy of the warning, it may also result in false positives.
so it's behaving as advertised (i.e. not stable or precise). And -Wall says:
> This enables all the warnings about constructions that some users consider questionable, and that are easy to avoid (or modify to prevent the warning), even in conjunction with macros.
which is also behaving as advertised, because C string functions are always questionable, and it's easy to avoid the warning by checking snprintf's return value.
