On 02/26/2018 05:47 PM, Martin Sebor wrote: > On 02/26/2018 12:13 PM, Jeff Law wrote: >> On 02/24/2018 05:11 PM, Martin Sebor wrote: >>> Attached is an updated patch with a fix for a bad assumption >>> exposed by building the linux kernel. >>> >>> On 02/19/2018 07:50 PM, Martin Sebor wrote: >>>> PR 84468 points out a false positive in -Wstringop-truncation >>>> in code like this: >>>> >>>> struct A { char a[4]; }; >>>> >>>> void f (struct A *p, const struct A *q) >>>> { >>>> if (p->a) >>>> strncpy (p->a, q->a, sizeof p->a - 1); // warning here >>>> >>>> p->a[3] = '\0'; >>>> } >>>> >>>> The warning is due to the code checking only the same basic block >>>> as the one with the strncpy call for an assignment to the destination >>>> to avoid it, but failing to check the successor basic block if there >>>> is no subsequent statement in the current block. (Eliminating >>>> the conditional is being tracked in PR 21474.) >>>> >>>> The attached test case adds logic to avoid this false positive. >>>> I don't know under what circumstances there could be more than >>>> one successor block here so I don't handle that case. >> So this is feeling more and more like we need to go back to the ideas >> behind checking the virtual operand chains. >> >> The patch as-written does not properly handle the case where BB has >> multiple outgoing edges. For gcc-8 you could probably get away with >> checking that you have precisely one outgoing edge without EDGE_ABNORMAL >> set in its flags in addition to the checks you're already doing. >> >> But again, it's feeling more and more like the right fix is to go back >> and walk the virtual operands. > > I intentionally kept the patch as simple as possible to minimize > risk at this late stage. > > Attached is a more robust version that handles multiple outgoing > edges and avoids those with the EDGE_ABNORMAL bit set. Retested > on x86_64 and with the Linux kernel. > > Enhancing this code to handle more complex cases is on my to-do > list for stage 1 (e.g., to handle bug 84561 where MEM_REF defeats > the detection of the nul assignment). I don't think handling multiple outgoing edges is advisable here. To do that you have to start thinking about post-dominator analysis at which point you're better off walking the memory web via VUSE/VDEFs.
Just verify the block has a single outgoing edge and that the edge is not marked with EDGE_ABNORMAL. Don't bother with the recursive call. Assuming you get a suitable block, then look inside. I glanced over the tests and I didn't see any that would benefit from handling multiple edges or the recursion (every one of the dg-bogus markers should be immediately transferring control to the null termination statement AFAICT). jeff