[Bug middle-end/102731] New: inconsistent handling of dereferncing a null pointer

msebor at gcc dot gnu.org gcc-bugzilla@gcc.gnu.org
Wed Oct 13 16:13:01 GMT 2021


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

            Bug ID: 102731
           Summary: inconsistent handling of dereferncing a null pointer
           Product: gcc
           Version: 12.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: middle-end
          Assignee: unassigned at gcc dot gnu.org
          Reporter: msebor at gcc dot gnu.org
  Target Milestone: ---

The test case below shows that GCC doesn't handle null pointer dereferences
consistently or as helpfully as it could or should.  Of the three equivalent
functions, GCC only issues a warning pointing out the invalid access only for
the first.  For the other two it doesn't warn even though it clearly detects
the invalid access and injects a trap after it.

$ cat x.c && gcc -O2 -S -Wall -fdump-tree-optimized=/dev/stdout x.c
struct A { char n, a[4]; };

void f (struct A *p)
{
  if (p)
    return;
  __builtin_memset (p->a, 0, 4);   // warning, no trap
}

void g (struct A *p)
{
  if (p)
    return;

  p->a[0] = 0;                     // trap, no warning
  p->a[1] = 0;
  p->a[2] = 0;
  p->a[3] = 0;
}

void h (struct A *p)
{
  if (p)
    return;

  for (int i = 0; i != 4; ++i)
    p->a[i] = 0;                   // trap, no warning
}

x.c: In function ‘f’:
x.c:7:3: warning: ‘__builtin_memset’ offset [0, 3] is out of the bounds [0, 0]
[-Warray-bounds]
    7 |   __builtin_memset (p->a, 0, 4);   // warning, no trap
      |   ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~

;; Function f (f, funcdef_no=0, decl_uid=1981, cgraph_uid=1, symbol_order=0)

Removing basic block 5
void f (struct A * p)
{
  <bb 2> [local count: 1073741824]:
  if (p_3(D) != 0B)
    goto <bb 4>; [70.93%]
  else
    goto <bb 3>; [29.07%]

  <bb 3> [local count: 312136752]:
  __builtin_memset (1B, 0, 4); [tail call]

  <bb 4> [local count: 1073741824]:
  return;

}



;; Function g (g, funcdef_no=1, decl_uid=1984, cgraph_uid=2, symbol_order=1)

void g (struct A * p)
{
  <bb 2> [local count: 1073741824]:
  if (p_2(D) != 0B)
    goto <bb 4>; [54.59%]
  else
    goto <bb 3>; [45.41%]

  <bb 3> [local count: 487586160]:
  MEM[(struct A *)0B].a[0] ={v} 0;
  __builtin_trap ();

  <bb 4> [local count: 1073741824]:
  return;

}



;; Function h (h, funcdef_no=2, decl_uid=1987, cgraph_uid=3, symbol_order=2)

void h (struct A * p)
{
  <bb 2> [local count: 472909864]:
  if (p_4(D) != 0B)
    goto <bb 4>; [54.59%]
  else
    goto <bb 3>; [45.41%]

  <bb 3> [local count: 214748368]:
  MEM[(struct A *)0B].a[0] ={v} 0;
  __builtin_trap ();

  <bb 4> [local count: 472909864]:
  return;

}


More information about the Gcc-bugs mailing list