https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83007
Martin Sebor <msebor at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- Keywords| |diagnostic Status|UNCONFIRMED |RESOLVED Resolution|--- |WONTFIX --- Comment #1 from Martin Sebor <msebor at gcc dot gnu.org> --- A common mistake with strncat is to specify as the bound the source of the source string (instead of the remaining space in the destination), as in: char d[8] = "1234"; const char *s = "4567"; strncat (d, s, strlen (s)); where the strncat call overflows the destination. Something similar happens in the test case in comment #0, except there the amount of space in the destination isn't as obvious. The checker tries to compute the size of the destination to see if the call can overflow but that computation fails (it happens too early, before the size is available). So out of an abundance of caution, the checker points out that the bound equals the source length, before the strncat call is folded into memcpy. Unfortunately, there is no way to avoid the warning without either compromising its efficacy (i.e., causing false negatives for buggy code), or without delaying the folding into memcpy to a point where the destination size is available (delaying the folding is not a favorable solution). That being said, the intended and recommended practice is to call strncat with the amount of space remaining in the destination, e.g., like so: strncat (d, s, sizeof d - strlen (d) - 1); In the test case in comment #0, strncat is being used to do two things: either a) to append the initial portion of the string at cur without the terminating nul and b) as a shortcut to to append the full nul-terminated string string cur. (a) is the intended use case, but (b) is not. With that in mind, changing the code to separate the two use cases like so avoids the warning: if (next) strncat (plugin_name, cur, next - cur); else strcpy (plugin_name, cur); Another alternative is to use sprintf to combine all three calls into one: sprintf (plugin_name, "%s%.*s%s", prefix, next ? (int)(next - cur) : -1, cur, suffix); I would suggest either of these also makes the code clearer.