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

            Bug ID: 106699
           Summary: Since gcc 12, deferencing constant literal addresses
                    triggers -Warray-bounds warning
           Product: gcc
           Version: 12.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c
          Assignee: unassigned at gcc dot gnu.org
          Reporter: yann at droneaud dot fr
  Target Milestone: ---

Since GCC 12.1, compiling memtest86+ triggers the following warning:

In function 'find_rsdp',
    inlined from 'acpi_init' at ../system/acpi.c:329:29:
../system/acpi.c:185:29: warning: array subscript 0 is outside array bounds of
'uint16_t[0]' {aka 'short unsigned int[]'} [-Warray-bounds]
  185 |         uintptr_t address = *(uint16_t *)0x40E << 4;
      |                             ^~~~~~~~~~~~~~~~~~

../system/hwctrl.c: In function 'reboot':
../system/hwctrl.c:76:9: warning: array subscript 0 is outside array bounds of
'uint16_t[0]' {aka 'short unsigned int[]'} [-Warray-bounds]
   76 |         *((uint16_t *)0x472) = 0x1234;
      |         ^~~~~~~~~~~~~~~~~~~~

In function 'find_cpus_in_floating_mp_struct',
    inlined from 'smp_init' at ../system/smp.c:543:39:
../system/smp.c:346:29: warning: array subscript 0 is outside array bounds of
'uint16_t[0]' {aka 'short unsigned int[]'} [-Warray-bounds]
  346 |         uintptr_t address = *(uint16_t *)0x40E << 4;
      |                             ^~~~~~~~~~~~~~~~~~

Sure using integer literal as a pointer is a recipe for disaster in most cases.
But it's for a freestanding environment, a bootloader, a kernel.

So -Warray-bounds should not infer an address points to a empty array.

A minimal test case:

    #include <stdint.h>

    void write(void) {
        *((uint16_t *)0x472) = 0x1234;
    }

    uint16_t read(void) {
        return *(uint16_t *)0x40E << 4;
    }

https://godbolt.org/z/c9993xx41

Reply via email to