Hi Peter, Paul,
On 15.03.22 02:18, Peter Stuge wrote:
Paul Menzel wrote:
x86_64-linux-gnu-gcc-12 .. -std=gnu11 ..
..
In file included from src/include/cpu/x86/lapic.h:4, from src/cpu/x86/lapic/lapic.c:5: In function 'read32', inlined from 'xapic_read' at src/include/cpu/x86/lapic.h:13:9, inlined from 'lapic_read' at src/include/cpu/x86/lapic.h:80:10, inlined from 'lapicid' at src/include/cpu/x86/lapic.h:138:21, inlined from 'enable_lapic' at src/cpu/x86/lapic/lapic.c:41:3: src/arch/x86/include/arch/mmio.h:20:16: error: array subscript 0 is outside array bounds of 'const volatile void[0]' [-Werror=array-bounds] 20 | return *((volatile uint32_t *)(addr)); | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
..
I have no idea, if it’s valid or not
gcc-12 is technically correct that accessing element 0 (the first element) in an array with 0 elements is out of bounds.
But in practice it's not a problem for our code, because these are all uint32_t pointers to memory mapped registers (hint: volatile).
So our code is somehow incorrect since these are, in fact, not arrays with 0 elements. The question is why we use them.
in this instance, there is no literal `[0]` involved. I'm not sure why GCC makes it up. Starting to manually inline at lapicid(), this is what our code does:
unsigned int lapic_read_param_reg = 0x020 /* LAPIC_ID */; unsigned int xapic_read_param_reg = lapic_read_reg; const volatile void *read32_param_addr = (volatile void *)(uintptr_t) (0xfee00000 /* LAPIC_DEFAULT_BASE */ + xapic_read_reg);
uint32_t lapicid_local_lapicid = *((volatile uint32_t *)(read32_param_addr));
(Where I named function parameters `x` `<func>_param_<x>` and local variables `y` <func>_local_<y>`.)
IIRC, I read in some issue tracker about this or something similar before, and there the solution was to use `volatile` which we do already. I don't see what our code could do better (beside adding some more `const` and removing odd parentheses). *shrug*
Nico