https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104828
Bug ID: 104828 Summary: Wrong out-of-bounds array access warning on literal pointers Product: gcc Version: 12.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c Assignee: unassigned at gcc dot gnu.org Reporter: goswin-v-b at web dot de Target Milestone: --- Trying to access a pointer cast from an integer literal gives a out of bounds warning: -------------------------------------------------------------------------- #define UART0_BASE 0x3F201000 void putc(char c) { volatile unsigned int *UART0_DR = (volatile unsigned int *)(UART0_BASE); volatile unsigned int *UART0_FR = (volatile unsigned int *)(UART0_BASE + 0x18); while (*UART0_FR & (1 << 5) ) { } *UART0_DR = c; } -------------------------------------------------------------------------- <source>:5:3: warning: array subscript 0 is outside array bounds of 'volatile unsigned int [0]' [-Warray-bounds] 5 | *UART0_DR = c; | ^~~~~~~~~ The error goes away if the pointer is global or static. The error remains if the pointer is returned from a function with alloc_size attribute: -------------------------------------------------------------------------- #include <unistd.h> #include <cstdint> #define UART0_BASE 0x3F201000 volatile uint32_t * make(uintptr_t addr, size_t size = 4) __attribute__ ((alloc_size (2))); volatile uint32_t * make(uintptr_t addr, size_t size) { (void)size; return (volatile uint32_t *)addr; } void putc(char c) { volatile uint32_t *UART0_DR = make(UART0_BASE); volatile uint32_t *UART0_FR = make(UART0_BASE + 0x18); while (*UART0_FR & (1 << 5) ) { } *UART0_DR = c; } -------------------------------------------------------------------------- <source>:16:3: warning: array subscript 0 is outside array bounds of 'volatile uint32_t [0]' [-Warray-bounds] 16 | *UART0_DR = c; | ^~~~~~~~~ The warning goes away if the "make" helper is extern and can't be inlined. Gcc 11.2 and before do not give this warning.