https://gcc.gnu.org/bugzilla/show_bug.cgi?id=68919

            Bug ID: 68919
           Summary: Null-pointer store not removed
           Product: gcc
           Version: 6.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: tree-optimization
          Assignee: unassigned at gcc dot gnu.org
          Reporter: vries at gcc dot gnu.org
  Target Milestone: ---

Consider test-case test.c (based on
src/gcc/testsuite/c-c++-common/asan/null-deref-1.c):
...
__attribute__((noinline, noclone))
static void
NullDeref(int *ptr)
{
  ptr[10]++;
}

__attribute__((noinline, noclone))
static void
NullDeref2 (void)
{
  int *ptr = (int*)0;
  ptr[10]++;
}

int
main (void)
{
  NullDeref ((int*)0);
  NullDeref2 ();
  return 0;
}
...

Compile with:
...
$ gcc test.c -o test.exe -O2 -flto -flto-partition=none -fipa-pta
...

At test.exe.optimized, we see:
...
__attribute__((noclone, noinline))
NullDeref (int * ptr)
{
  <bb 2>:
  return;

}

__attribute__((noclone, noinline))
NullDeref2 ()
{
  int _2;
  int _3;

  <bb 2>:
  _2 = MEM[(int *)40B];
  _3 = _2 + 1;
  MEM[(int *)40B] = _3;
  return;

}

main ()
{
  <bb 2>:
  NullDeref2 ();
  return 0;

}
...

In the ipa-case, we removed the store to the NULL pointer. In the local case,
we don't.

This seems to be a missing optimization in the local case.

When compiling with "-fno-tree-ccp -fno-tree-fre -fno-tree-forwprop" in
addition, we see at ealias:
...
NullDeref2 ()
{
  intD.6 * ptrD.1761;
  intD.6 * _2;
  intD.6 _4;
  intD.6 _5;

  # PT = null
  ptr_1 = 0B;
  # PT = null
  _2 = ptr_1 + 40;
  # VUSE <.MEM_3(D)>
  _4 = *_2;
  _5 = _4 + 1;
  # .MEM_6 = VDEF <.MEM_3(D)>
  *_2 = _5;
  # VUSE <.MEM_6>
  return;
}
...

And subsequently at cddce1:
...
__attribute__((noclone, noinline))
NullDeref2 ()
{
  intD.6 * ptrD.1761;

  # VUSE <.MEM_3(D)>
  return;
}
...

Reply via email to