For a bare metal app for a Raspberry Pi I have this code:
#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;
}
When I compile this with g++-12 I get (same for UART0_FR):
uart.cc:28:15: warning: array subscript 0 is outside array bounds of ‘volatile unsigned int [0]’ [-Warray-bounds]
28 | *UART0_DR = c;
| ^~~~~~~~~
Note: This is new in g++-12 (trunk on godbolt as of this writing) and 11.2 and before don't show it.
The pointer is not out of bounds and I know that the UART data register is at that place. So how do I tell the compiler the bounds for the pointer?
I'm actually looking for possibly 3 cases:
- pointer to a single volatile unsigned int
- pointer to an array of N volatile unsigned int
- pointer to a struct of volatile unsigned int
All 3 cases would be at a fixed address and not something returned by malloc/new where the compiler knows the bounds.
Update: The warning goes away if the pointer is global or static instead of local. So likely a compiler bug or at least inconsistent.