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.