Skip to content

cpu/avr*: Fix compilation with GCC 12.2.0 #18532

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from

Conversation

maribu
Copy link
Member

@maribu maribu commented Aug 30, 2022

Contribution description

A statement like LKPR = (1 << CLKPCE); which for the ATmega328P translates to *((volatile uint8_t *)0x61) = (1 << 7); is considered as accessing the first array element of a zero sized array by GCC 12.2.0. Assuming a zero size for memory not allocated by the compiler is quite insane, so we need to disable the diagnostics for the affected code. The most targeted approach would be using:

#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Warray-bounds"
...
#pragma GCC diagnostic pop

But adding this around every memory mapped I/O access would render the code unreadable. Adding this around the #include <avr/io.h> instead would be ideal, but since e.g. LKPR is macro, the diagnostic would be still triggered when that macro is used in RIOT's C code.

Instead, we add -Wno-array-bounds to the CFLAGS, but only for the low level AVR/ATmega/ATXmega code. As a result common code can still profit from the diagnostics, while code working with memory mapped I/O can still use the AVR libc.

Finally, the common LED initialization code needed suppression of bogus -Warray-bounds warnings.

Testing procedure

Compilation should now work with AVR GCC version 12.2.0 and still work for older versions as before. The latter is checked by Murdock, the former check I can provide:

Using master

$ make BOARD=arduino-uno -C examples/hello-world
make: Entering directory '/home/maribu/Repos/software/RIOT/examples/hello-world'
Building application "hello-world" for "arduino-uno" with MCU "atmega328p".

"make" -C /home/maribu/Repos/software/RIOT/boards/arduino-uno
"make" -C /home/maribu/Repos/software/RIOT/boards/common/arduino-atmega
"make" -C /home/maribu/Repos/software/RIOT/boards/common/atmega
"make" -C /home/maribu/Repos/software/RIOT/boards/common/init
"make" -C /home/maribu/Repos/software/RIOT/core
"make" -C /home/maribu/Repos/software/RIOT/core/lib
"make" -C /home/maribu/Repos/software/RIOT/cpu/atmega328p
"make" -C /home/maribu/Repos/software/RIOT/cpu/atmega_common
In file included from /home/maribu/Repos/software/RIOT/cpu/avr8_common/include/cpu.h:40,
                 from /home/maribu/Repos/software/RIOT/boards/common/arduino-atmega/include/board_common.h:28,
                 from /home/maribu/Repos/software/RIOT/boards/arduino-uno/include/board.h:32,
                 from /home/maribu/Repos/software/RIOT/cpu/atmega_common/atmega_cpu.c:29:
In function 'atmega_set_prescaler',
    inlined from 'avr8_clk_init' at /home/maribu/Repos/software/RIOT/cpu/atmega_common/atmega_cpu.c:70:5:
/home/maribu/Repos/software/RIOT/cpu/atmega_common/include/cpu_clock.h:67:11: error: array subscript 0 is outside array bounds of 'volatile uint8_t[0]' {aka 'volatile unsigned char[]'} [-Werror=array-bounds]
   67 |     CLKPR = (1 << CLKPCE);
      |           ^
/home/maribu/Repos/software/RIOT/cpu/atmega_common/include/cpu_clock.h:70:11: error: array subscript 0 is outside array bounds of 'volatile uint8_t[0]' {aka 'volatile unsigned char[]'} [-Werror=array-bounds]
   70 |     CLKPR = clk_scale;
      |           ^
cc1: all warnings being treated as errors
make[3]: *** [/home/maribu/Repos/software/RIOT/Makefile.base:146: /home/maribu/Repos/software/RIOT/examples/hello-world/bin/arduino-uno/atmega_common/atmega_cpu.o] Error 1
make[2]: *** [/home/maribu/Repos/software/RIOT/Makefile.base:31: ALL--/home/maribu/Repos/software/RIOT/cpu/atmega_common] Error 2
make[1]: *** [/home/maribu/Repos/software/RIOT/Makefile.base:31: ALL--/home/maribu/Repos/software/RIOT/cpu/atmega328p] Error 2
make: *** [/home/maribu/Repos/software/RIOT/examples/hello-world/../../Makefile.include:738: application_hello-world.module] Error 2
make: Leaving directory '/home/maribu/Repos/software/RIOT/examples/hello-world'

Using this PR

$ make BOARD=arduino-uno -C examples/hello-world
make: Entering directory '/home/maribu/Repos/software/RIOT/examples/hello-world'
Building application "hello-world" for "arduino-uno" with MCU "atmega328p".

"make" -C /home/maribu/Repos/software/RIOT/boards/arduino-uno
"make" -C /home/maribu/Repos/software/RIOT/boards/common/arduino-atmega
"make" -C /home/maribu/Repos/software/RIOT/boards/common/atmega
"make" -C /home/maribu/Repos/software/RIOT/boards/common/init
"make" -C /home/maribu/Repos/software/RIOT/core
"make" -C /home/maribu/Repos/software/RIOT/core/lib
"make" -C /home/maribu/Repos/software/RIOT/cpu/atmega328p
"make" -C /home/maribu/Repos/software/RIOT/cpu/atmega_common
"make" -C /home/maribu/Repos/software/RIOT/cpu/atmega_common/periph
"make" -C /home/maribu/Repos/software/RIOT/cpu/avr8_common
"make" -C /home/maribu/Repos/software/RIOT/cpu/avr8_common/avr_libc_extra
"make" -C /home/maribu/Repos/software/RIOT/drivers
"make" -C /home/maribu/Repos/software/RIOT/drivers/periph_common
"make" -C /home/maribu/Repos/software/RIOT/sys
"make" -C /home/maribu/Repos/software/RIOT/sys/auto_init
"make" -C /home/maribu/Repos/software/RIOT/sys/malloc_thread_safe
"make" -C /home/maribu/Repos/software/RIOT/sys/stdio_uart
   text	  data	   bss	   dec	   hex	filename
   4628	   320	   897	  5845	  16d5	/home/maribu/Repos/software/RIOT/examples/hello-world/bin/arduino-uno/hello-world.elf
make: Leaving directory '/home/maribu/Repos/software/RIOT/examples/hello-world'

Issues/PRs references

None

A statement like `LKPR = (1 << CLKPCE);` which for the ATmega328P
translates to `*((volatile uint8_t *)0x61) = (1 << 7);` is considered
as accessing the first array element of a zero sized array by
GCC 12.2.0. Assuming a zero size for memory not allocated by the
compiler is quite insane, so we need to disable the diagnostics for
the affected code. The most targeted approach would be using:

```
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Warray-bounds"
...
#pragma GCC diagnostic pop
```

But adding this around every memory mapped I/O access would render the
code unreadable. Adding this around the `#include <avr/io.h>` instead
would be ideal, but since e.g. `LKPR` is macro, the diagnostic would
be still triggered when that macro is used in RIOT's C code.

Instead, we add `-Wno-array-bounds` to the `CFLAGS`, but only for the
low level AVR/ATmega/ATXmega code. As a result common code can still
profit from the diagnostics, while code working with memory mapped I/O
can still use the AVR libc.
@maribu maribu requested a review from kYc0o as a code owner August 30, 2022 12:04
@github-actions github-actions bot added Area: cpu Area: CPU/MCU ports Platform: AVR Platform: This PR/issue effects AVR-based platforms labels Aug 30, 2022
@maribu maribu requested review from benpicco and kfessel August 30, 2022 12:04
@maribu maribu added CI: ready for build If set, CI server will compile all applications for all available boards for the labeled PR Platform: AVR Platform: This PR/issue effects AVR-based platforms Area: cpu Area: CPU/MCU ports and removed Platform: AVR Platform: This PR/issue effects AVR-based platforms Area: cpu Area: CPU/MCU ports labels Aug 30, 2022
@maribu
Copy link
Member Author

maribu commented Aug 30, 2022

Closing in favor of #18533

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Area: cpu Area: CPU/MCU ports CI: ready for build If set, CI server will compile all applications for all available boards for the labeled PR Platform: AVR Platform: This PR/issue effects AVR-based platforms
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant