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

            Bug ID: 128213
           Summary: [16/17 Regression] phiprop speculates a load wider
                    than the object it points to
           Product: gcc
           Version: 17.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: tree-optimization
          Assignee: unassigned at gcc dot gnu.org
          Reporter: lzy20000419 at outlook dot com
  Target Milestone: ---

_Alignas (int) char ch[1] = { 1 };
int iv = 7;
__attribute__((noipa)) int
f (int c, int d)
{
  int *p = c ? (int *) ch : &iv;
  if (d)
    return *p;
  return 0;
}
int
main (void)
{
  volatile int c = 1, d = 0;
  return f (c, d);
}
*p only runs when d != 0, and main passes d = 0, so the program never
dereferences p.

$ gcc -O1 -fsanitize=address t.c && ./a.out ERROR: AddressSanitizer:
global-buffer-overflow ... READ of size 4 ... 0 bytes after global variable
'ch' ... of size 1

Expected: no error, exit 0. -fno-tree-phiprop makes it go away; clang and gcc
15.3 are clean with the same flags. Without the sanitizer, trunk -O2 loads
*(int *)ch unconditionally:

f:  test edi,edi ; mov edx,OFFSET iv ; mov eax,OFFSET ch ; cmove rax,rdx
    xor edx,edx ; test esi,esi ; mov eax,DWORD PTR [rax] ; cmove eax,edx ; ret

If ch sits at the end of a page, this can fault.

It works with 14.4 and 15.3 and fails with 16.1, 16.2 and trunk.

https://godbolt.org/z/f8KKWW9Y4 (left gcc 15.3, right trunk)

Disclaimer: This test case was generated by a fuzzer, and the report was
written with LLM assistance.

Reply via email to