Re: gcc-9.2.0 and spurious warnings

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On 12/12/19 11:54 PM, Josef Wolf wrote:
Thanks for the explanation, Martin!

On Thu, Dec 12, 2019 at 05:20:43PM -0700, Martin Sebor wrote:
I don't see it with
fresh trunk, either natively or with an m68k-unknown-elf cross, so
I can't really say why GCC 9 thinks the two pointers are equal.

Thus there's a chance that the warning will go away with one of the next GCC
releases?

I don't see it even with a cross built from 9.x so it's likely still
there, and something is causing my cross to optimize code differently
than yours.  (The warning depends on optimization.)


You
can tell by looking at the optimization dumps (use -ftree-dump-all
and grep the output for strncpy with a zero argument).

Hmmm. No -ftree-dump-XXX options here.

Sorry, it's -fdump-tree-all.  There will be one file for each
optimization pass.  Of interest in the first one that shows strncpy
being called with a literal zero as the last argument.  The file
name suffix encodes the name of the optimizing pass that either
introduced the call.  It's likely the result of an optimization like
jump threading that runs before then and that introduces an additional
call to strncpy into which the zero is propagated.  So I'd expect
the first relevant dump file to be the first one with two calls to
strncpy.  (This will just help confirm what causes the warning, not
necessarily come up with a fix.)


What I can say is that strncpy isn't really meant to be used this
way: to copy exactly as many bytes as the third argument says.
That's what memcpy is for.

I tend to use memXXX() family of functions when I am dealing with binary data.

Here, I am dealing with zero terminated strings. Thus, the strXXX() family of
functions should be used. IMHO, of course!

Yes, that's a reasonable rule of thumb, and GCC does try to avoid
the warning in this case (it looks for the nul termination after
the call).  But since the implementation is less than perfect it's
prone to false positives.  We'd obviously like to avoid those when
we can, but ideally without missing the real bugs.  It's a tradeoff,
and a judgment call where to draw the line.

The only other string function that comes to mind that avoids
the warning is snprintf:

  sprintf (*r, "%.*s", (int)(q-p), p);

but I mention it just for completeness.  I wouldn't recommend using
it in this case.

If rewriting the code is not an option, individual instances of
warnings can usually be suppressed by #pragma GCC diagnostic:

  #pragma GCC diagnostic push
  #pragma GCC diagnostic ignored "-Wstringop-truncation"
    strncpy (*r, p, q-p);         /* copy */
  #pragma GCC diagnostic pop

(Unfortunately, the pragma doesn't work as well as it should either
for warnings that depend on optimization, due to inlining and code
motion, so you might need to tweak the placement a bit to make it
have the expected effect.  Putting the pragmas before and after
the out-of-line function should work.)


The warning was added because strncpy
is frequently misused and a common source of bugs.

I am not sure I understand which kind of misuse you are talking about.

I see there's a pitfall with strncpy() failing to add the terminating NUL
charachter. But this terminating NUL is added explicitly in this case.

Using the result of the function as a "bounded string copy", as if
it was guaranteed to be a nul-terminated string, is the most common
misuse.  There are many discussions of the risks online.  A couple
of examples are CWE-170 and the strncpy() and strncat() article on
the US CERT Build Security In site:
https://www.us-cert.gov/bsi/articles/knowledge/coding-practices/strncpy-and-strncat

Martin



[Index of Archives]     [Linux C Programming]     [Linux Kernel]     [eCos]     [Fedora Development]     [Fedora Announce]     [Autoconf]     [The DWARVES Debugging Tools]     [Yosemite Campsites]     [Yosemite News]     [Linux GCC]

  Powered by Linux