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). Martin