[Bug c/89678] Bogus -Wstringop-truncation on strncat with bound that depends on strlen of source

2019-03-12 Thread msebor at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89678

Martin Sebor  changed:

   What|Removed |Added

 Status|NEW |ASSIGNED
   Assignee|unassigned at gcc dot gnu.org  |msebor at gcc dot 
gnu.org

[Bug c/89678] Bogus -Wstringop-truncation on strncat with bound that depends on strlen of source

2019-03-12 Thread msebor at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89678

Martin Sebor  changed:

   What|Removed |Added

 Status|UNCONFIRMED |NEW
   See Also||https://gcc.gnu.org/bugzill
   ||a/show_bug.cgi?id=88780
Summary|Bogus -Wstringop-truncation |Bogus -Wstringop-truncation
   |error   |on strncat with bound that
   ||depends on strlen of source
 Ever confirmed|0   |1

--- Comment #1 from Martin Sebor  ---
The test case boils down to this:

  void f (char *p, char *q)
  {
unsigned m = __builtin_strlen (p);
unsigned n = __builtin_strlen (q);

__builtin_strncat (p, q, n);
p[m + n] = '\0';
  }

The warning in these cases is by design: it points out that the bound in the
strncat call depends on the length of the source string (which is usually a
bug).  The use case the warning is designed not to trigger for is the one
described in the CERT strncpy and strncat article:
https://www.us-cert.gov/bsi/articles/knowledge/coding-practices/strncpy-and-strncat,
i.e.,

  strncat (dest, source, dest_size - strlen (dest) - 1);

In general, the warning assumes that strncpy and strncat are used in meaningful
(though perhaps incorrect) ways.  In the test case in comment #0, the use of
strncat is correct but pointless.  It's clear that the size of the buffer is
sufficient for the concatenation of the two strings, so there is no point in
using strncat to constrain the copy.  The code would be more clearly and also
more efficiently written like so:

  if ((dst = __builtin_realloc(dst, dstlen + retlen + 1)) != 0) {
strcpy(dst + dstlen, ret);

That said, a patch I'm testing for pr88780 relaxes the warning to avoid
triggering for code like this.