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.