https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94015
Bug ID: 94015 Summary: [10 Regression] Another assignment incorrectly omitted by -foptimize-strlen Product: gcc Version: 10.0 Status: UNCONFIRMED Keywords: wrong-code Severity: normal Priority: P3 Component: tree-optimization Assignee: unassigned at gcc dot gnu.org Reporter: nate at thatsmathematics dot com CC: dmalcolm at gcc dot gnu.org, jakub at gcc dot gnu.org, law at redhat dot com, marxin at gcc dot gnu.org, msebor at gcc dot gnu.org, nate at thatsmathematics dot com Target Milestone: --- Created attachment 47957 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=47957&action=edit Test case This is apparently the same bug as in bug 93982, which I don't think has been fixed completely. I am using trunk, commit 9b4f00dd (not sure how to make that a link?). It includes f26688fb which was supposed to fix bug 93982. This is again a regression from 9.2.0. If the attached testcase is compiled with `-O1 -foptimize-strlen -fpie', or -O2, on amd64, the function foo is miscompiled: the assignment to s[7] is omitted. The generated assembly is: This bug is somewhat similar to bug 93213. It is a regression from 9.2.0. The generated assembly is: foo: subq $8, %rsp call alloc leaq .LC0(%rip), %rdx movq %rdx, (%rax) addq $8, %rsp ret 9.2.0 adds `movb $0, 7(%rax)' as it should. I wasn't able to create a test that failed at runtime on Linux, since by default everything is loaded in the low half of memory, so the address of the string literal has zero in its high byte and s[7] gets set to zero anyway. But the compiler can't know that will happen. There is probably a linker or loader option to change this, but I could not immediately figure out the correct incantation. I can try harder if it would help. -fdump-tree-all shows that the statement is deleted by the strlen pass, as before. The output of the preceding pass looks like: foo () { char * s; <bb 2> [local count: 1073741824]: s_3 = alloc (); MEM[(char * *)s_3] = "1234567"; MEM[(char *)s_3 + 7B] = 0; return; } I didn't single step the compiler code this time, but I presume the issue is that although the strlen pass now knows that the store in `MEM[(char * *)s_3] = "1234567";' is the size of a pointer (8 bytes), it still thinks those 8 bytes are the string "1234567\0" rather than its address. So it still thinks it will result in a null byte stored at `s_3 + 7B`, making the following line redundant.