[Bug tree-optimization/94015] New: [10 Regression] Another assignment incorrectly omitted by -foptimize-strlen

nate at thatsmathematics dot com gcc-bugzilla@gcc.gnu.org
Tue Mar 3 14:51:00 GMT 2020


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.


More information about the Gcc-bugs mailing list