Skip to content
New issue

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

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

Already on GitHub? # to your account

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

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

# for free to join this conversation on GitHub. Already have an account? # 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