https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89689

Jeffrey A. Law <law at redhat dot com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |law at redhat dot com
   Target Milestone|7.5                         |10.0

--- Comment #3 from Jeffrey A. Law <law at redhat dot com> ---
It's almost certainly the case that we've duplicated the block with the call to
builtin_memcpy_chk so that we can thread jumps and remove the second   if (p !=
__sb_slop) test.


In .forwprop2 we have:

;;   basic block 4, loop depth 0
;;    pred:       2
;;                3
  _1 = __builtin_object_size (p_4(D), 0);
  __builtin___memcpy_chk (p_4(D), "abcd", 4, _1);
  if (p_4(D) != &__sb_slop)
    goto <bb 5>; [70.00%]
  else
    goto <bb 6>; [30.00%]

Which is exactly what we'd expect.  Then objsz2 runs resulting in:

;;   basic block 4, loop depth 0
;;    pred:       2
;;                3
  _1 = __builtin_object_size (p_4(D), 0);
  __builtin_memcpy (p_4(D), "abcd", 4);
  if (p_4(D) != &__sb_slop)
    goto <bb 5>; [70.00%]
  else
    goto <bb 6>; [30.00%]

What's happened here?  Well, objsz evaluated the _b_o_s call and determined it
was undeterminable (-1) and transformed the memcpy_chk to a standard memcpy.

The key point is we had an indeterminable size and transformed the _chk into a
standard memcpy.

Jump threading comes along and duplicates the block.  As a result on the
duplicated path we'll know that p_4 points to sb_slop and thus has a size of 1.
 That causes the memcpy of 4 bytes to trigger the warning.

I would hazard a guess that the original user code didn't have the calls to
_builtin_object_size and __builtin__memcpy_chk, but that those instead came in
via the glibc header files.

This certainly isn't going to be fixed for gcc-9 (possibly ever).

And FWIW, I think marking things with TREE_NO_WARNING at the time we convert
the memcpy_chk to a memcpy would be fundamentally wrong in the case where the
__b_o_s call returned -1 (indeterminate size).  It'll hide real bugs.

Reply via email to