summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPablo Martínez <58857054+elpekenin@users.noreply.github.com>2025-05-22 15:31:15 +0200
committerGitHub <noreply@github.com>2025-05-22 23:31:15 +1000
commit955809bd5aee8b1444595b450eeeef1f42799995 (patch)
tree08da1f696605925286f681a2b738fa5f35cd0386
parentfa24b0fcce2c5f3330f2d798c3caf91a130babdb (diff)
Add `compiler_support.h` (#25274)
-rw-r--r--docs/quantum_painter_qff.md4
-rw-r--r--docs/quantum_painter_qgf.md8
-rw-r--r--drivers/lcd/st7565.c3
-rw-r--r--drivers/oled/oled_driver.c4
-rw-r--r--drivers/sensors/azoteq_iqs5xx.h7
-rw-r--r--drivers/sensors/pmw33xx_common.h5
-rw-r--r--lib/fnv/qmk_fnv_type_validation.c9
-rw-r--r--lib/python/qmk/cli/generate/community_modules.py6
-rw-r--r--platforms/atomic_util.h12
-rw-r--r--platforms/avr/drivers/i2c_slave.h4
-rw-r--r--platforms/avr/gpio.h6
-rw-r--r--platforms/chibios/chibios_config.h4
-rw-r--r--platforms/chibios/drivers/wear_leveling/wear_leveling_rp2040_flash.c6
-rw-r--r--quantum/audio/audio.h4
-rw-r--r--quantum/backlight/backlight.h4
-rw-r--r--quantum/compiler_support.h15
-rw-r--r--quantum/connection/connection.h4
-rw-r--r--quantum/haptic.h4
-rw-r--r--quantum/keycode_config.h6
-rw-r--r--quantum/keymap_introspection.c13
-rw-r--r--quantum/led_matrix/led_matrix_types.h4
-rw-r--r--quantum/nvm/eeprom/nvm_dynamic_keymap.c7
-rw-r--r--quantum/nvm/eeprom/nvm_eeprom_eeconfig_internal.h4
-rw-r--r--quantum/painter/qff.h9
-rw-r--r--quantum/painter/qgf.h17
-rw-r--r--quantum/painter/qp_draw_core.c3
-rw-r--r--quantum/painter/qp_internal.c4
-rw-r--r--quantum/painter/qp_internal_formats.h3
-rw-r--r--quantum/rgb_matrix/rgb_matrix_types.h4
-rw-r--r--quantum/rgblight/rgblight.h4
-rw-r--r--quantum/split_common/split_util.c8
-rw-r--r--quantum/split_common/transaction_id_define.h4
-rw-r--r--quantum/split_common/transport.c3
-rw-r--r--quantum/unicode/unicode.h4
-rw-r--r--quantum/wear_leveling/wear_leveling_internal.h14
-rw-r--r--tmk_core/protocol/vusb/vusb.c3
36 files changed, 142 insertions, 81 deletions
diff --git a/docs/quantum_painter_qff.md b/docs/quantum_painter_qff.md
index 3695be2c5b..198d87384a 100644
--- a/docs/quantum_painter_qff.md
+++ b/docs/quantum_painter_qff.md
@@ -44,7 +44,7 @@ typedef struct __attribute__((packed)) qff_font_descriptor_v1_t {
44 uint8_t compression_scheme; // compression scheme, see below. 44 uint8_t compression_scheme; // compression scheme, see below.
45 uint8_t transparency_index; // palette index used for transparent pixels (not yet implemented) 45 uint8_t transparency_index; // palette index used for transparent pixels (not yet implemented)
46} qff_font_descriptor_v1_t; 46} qff_font_descriptor_v1_t;
47// _Static_assert(sizeof(qff_font_descriptor_v1_t) == (sizeof(qgf_block_header_v1_t) + 20), "qff_font_descriptor_v1_t must be 25 bytes in v1 of QFF"); 47// STATIC_ASSERT(sizeof(qff_font_descriptor_v1_t) == (sizeof(qgf_block_header_v1_t) + 20), "qff_font_descriptor_v1_t must be 25 bytes in v1 of QFF");
48``` 48```
49 49
50The values for `format`, `flags`, `compression_scheme`, and `transparency_index` match [QGF's frame descriptor block](quantum_painter_qgf#qgf-frame-descriptor), with the exception that the `delta` flag is ignored by QFF. 50The values for `format`, `flags`, `compression_scheme`, and `transparency_index` match [QGF's frame descriptor block](quantum_painter_qgf#qgf-frame-descriptor), with the exception that the `delta` flag is ignored by QFF.
@@ -66,7 +66,7 @@ typedef struct __attribute__((packed)) qff_ascii_glyph_table_v1_t {
66 qgf_block_header_v1_t header; // = { .type_id = 0x01, .neg_type_id = (~0x01), .length = 285 } 66 qgf_block_header_v1_t header; // = { .type_id = 0x01, .neg_type_id = (~0x01), .length = 285 }
67 uint24_t glyph[95]; // 95 glyphs, 0x20..0x7E, see bits/masks above for values 67 uint24_t glyph[95]; // 95 glyphs, 0x20..0x7E, see bits/masks above for values
68} qff_ascii_glyph_table_v1_t; 68} qff_ascii_glyph_table_v1_t;
69// _Static_assert(sizeof(qff_ascii_glyph_table_v1_t) == (sizeof(qgf_block_header_v1_t) + 285), "qff_ascii_glyph_table_v1_t must be 290 bytes in v1 of QFF"); 69// STATIC_ASSERT(sizeof(qff_ascii_glyph_table_v1_t) == (sizeof(qgf_block_header_v1_t) + 285), "qff_ascii_glyph_table_v1_t must be 290 bytes in v1 of QFF");
70``` 70```
71 71
72## Unicode glyph table {#qff-unicode-table} 72## Unicode glyph table {#qff-unicode-table}
diff --git a/docs/quantum_painter_qgf.md b/docs/quantum_painter_qgf.md
index 700b78d105..dd525e4b83 100644
--- a/docs/quantum_painter_qgf.md
+++ b/docs/quantum_painter_qgf.md
@@ -32,7 +32,7 @@ typedef struct __attribute__((packed)) qgf_block_header_v1_t {
32 uint8_t neg_type_id; // Negated type ID, used for detecting parsing errors 32 uint8_t neg_type_id; // Negated type ID, used for detecting parsing errors
33 uint24_t length; // 24-bit blob length, allowing for block sizes of a maximum of 16MB 33 uint24_t length; // 24-bit blob length, allowing for block sizes of a maximum of 16MB
34} qgf_block_header_v1_t; 34} qgf_block_header_v1_t;
35// _Static_assert(sizeof(qgf_block_header_v1_t) == 5, "qgf_block_header_v1_t must be 5 bytes in v1 of QGF"); 35// STATIC_ASSERT(sizeof(qgf_block_header_v1_t) == 5, "qgf_block_header_v1_t must be 5 bytes in v1 of QGF");
36``` 36```
37The _length_ describes the number of octets in the data following the block header -- a block header may specify a _length_ of `0` if no blob is specified. 37The _length_ describes the number of octets in the data following the block header -- a block header may specify a _length_ of `0` if no blob is specified.
38 38
@@ -56,7 +56,7 @@ typedef struct __attribute__((packed)) qgf_graphics_descriptor_v1_t {
56 uint16_t image_height; // in pixels 56 uint16_t image_height; // in pixels
57 uint16_t frame_count; // minimum of 1 57 uint16_t frame_count; // minimum of 1
58} qgf_graphics_descriptor_v1_t; 58} qgf_graphics_descriptor_v1_t;
59// _Static_assert(sizeof(qgf_graphics_descriptor_v1_t) == (sizeof(qgf_block_header_v1_t) + 18), "qgf_graphics_descriptor_v1_t must be 23 bytes in v1 of QGF"); 59// STATIC_ASSERT(sizeof(qgf_graphics_descriptor_v1_t) == (sizeof(qgf_block_header_v1_t) + 18), "qgf_graphics_descriptor_v1_t must be 23 bytes in v1 of QGF");
60``` 60```
61 61
62## Frame offset block {#qgf-frame-offset-descriptor} 62## Frame offset block {#qgf-frame-offset-descriptor}
@@ -95,7 +95,7 @@ typedef struct __attribute__((packed)) qgf_frame_v1_t {
95 uint8_t transparency_index; // palette index used for transparent pixels (not yet implemented) 95 uint8_t transparency_index; // palette index used for transparent pixels (not yet implemented)
96 uint16_t delay; // frame delay time for animations (in units of milliseconds) 96 uint16_t delay; // frame delay time for animations (in units of milliseconds)
97} qgf_frame_v1_t; 97} qgf_frame_v1_t;
98// _Static_assert(sizeof(qgf_frame_v1_t) == (sizeof(qgf_block_header_v1_t) + 6), "qgf_frame_v1_t must be 11 bytes in v1 of QGF"); 98// STATIC_ASSERT(sizeof(qgf_frame_v1_t) == (sizeof(qgf_block_header_v1_t) + 6), "qgf_frame_v1_t must be 11 bytes in v1 of QGF");
99``` 99```
100 100
101If this frame is grayscale, the _frame descriptor block_ (or _frame delta block_ if flags denote a delta frame) is immediately followed by this frame's corresponding _frame data block_. 101If this frame is grayscale, the _frame descriptor block_ (or _frame delta block_ if flags denote a delta frame) is immediately followed by this frame's corresponding _frame data block_.
@@ -160,7 +160,7 @@ typedef struct __attribute__((packed)) qgf_delta_v1_t {
160 uint16_t right; // The right pixel location to to draw the delta image 160 uint16_t right; // The right pixel location to to draw the delta image
161 uint16_t bottom; // The bottom pixel location to to draw the delta image 161 uint16_t bottom; // The bottom pixel location to to draw the delta image
162} qgf_delta_v1_t; 162} qgf_delta_v1_t;
163// _Static_assert(sizeof(qgf_delta_v1_t) == 13, "qgf_delta_v1_t must be 13 bytes in v1 of QGF"); 163// STATIC_ASSERT(sizeof(qgf_delta_v1_t) == 13, "qgf_delta_v1_t must be 13 bytes in v1 of QGF");
164``` 164```
165 165
166## Frame data block {#qgf-frame-data-descriptor} 166## Frame data block {#qgf-frame-data-descriptor}
diff --git a/drivers/lcd/st7565.c b/drivers/lcd/st7565.c
index cf71c5e5a3..f24bb78048 100644
--- a/drivers/lcd/st7565.c
+++ b/drivers/lcd/st7565.c
@@ -19,6 +19,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
19 19
20#include <string.h> 20#include <string.h>
21 21
22#include "compiler_support.h"
22#include "keyboard.h" 23#include "keyboard.h"
23#include "progmem.h" 24#include "progmem.h"
24#include "timer.h" 25#include "timer.h"
@@ -265,7 +266,7 @@ void st7565_write_char(const char data, bool invert) {
265 static uint8_t st7565_temp_buffer[ST7565_FONT_WIDTH]; 266 static uint8_t st7565_temp_buffer[ST7565_FONT_WIDTH];
266 memcpy(&st7565_temp_buffer, st7565_cursor, ST7565_FONT_WIDTH); 267 memcpy(&st7565_temp_buffer, st7565_cursor, ST7565_FONT_WIDTH);
267 268
268 _Static_assert(sizeof(font) >= ((ST7565_FONT_END + 1 - ST7565_FONT_START) * ST7565_FONT_WIDTH), "ST7565_FONT_END references outside array"); 269 STATIC_ASSERT(sizeof(font) >= ((ST7565_FONT_END + 1 - ST7565_FONT_START) * ST7565_FONT_WIDTH), "ST7565_FONT_END references outside array");
269 270
270 // set the reder buffer data 271 // set the reder buffer data
271 uint8_t cast_data = (uint8_t)data; // font based on unsigned type for index 272 uint8_t cast_data = (uint8_t)data; // font based on unsigned type for index
diff --git a/drivers/oled/oled_driver.c b/drivers/oled/oled_driver.c
index 1d1c2a90c4..7e46bcb3f7 100644
--- a/drivers/oled/oled_driver.c
+++ b/drivers/oled/oled_driver.c
@@ -23,6 +23,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
23# include "keyboard.h" 23# include "keyboard.h"
24# endif 24# endif
25#endif 25#endif
26
27#include "compiler_support.h"
26#include "oled_driver.h" 28#include "oled_driver.h"
27#include OLED_FONT_H 29#include OLED_FONT_H
28#include "timer.h" 30#include "timer.h"
@@ -601,7 +603,7 @@ void oled_write_char(const char data, bool invert) {
601 static uint8_t oled_temp_buffer[OLED_FONT_WIDTH]; 603 static uint8_t oled_temp_buffer[OLED_FONT_WIDTH];
602 memcpy(&oled_temp_buffer, oled_cursor, OLED_FONT_WIDTH); 604 memcpy(&oled_temp_buffer, oled_cursor, OLED_FONT_WIDTH);
603 605
604 _Static_assert(sizeof(font) >= ((OLED_FONT_END + 1 - OLED_FONT_START) * OLED_FONT_WIDTH), "OLED_FONT_END references outside array"); 606 STATIC_ASSERT(sizeof(font) >= ((OLED_FONT_END + 1 - OLED_FONT_START) * OLED_FONT_WIDTH), "OLED_FONT_END references outside array");
605 607
606 // set the reder buffer data 608 // set the reder buffer data
607 uint8_t cast_data = (uint8_t)data; // font based on unsigned type for index 609 uint8_t cast_data = (uint8_t)data; // font based on unsigned type for index
diff --git a/drivers/sensors/azoteq_iqs5xx.h b/drivers/sensors/azoteq_iqs5xx.h
index e1e8b67b31..eb01903e33 100644
--- a/drivers/sensors/azoteq_iqs5xx.h
+++ b/drivers/sensors/azoteq_iqs5xx.h
@@ -4,6 +4,7 @@
4 4
5#pragma once 5#pragma once
6 6
7#include "compiler_support.h"
7#include "i2c_master.h" 8#include "i2c_master.h"
8#include "pointing_device.h" 9#include "pointing_device.h"
9#include "util.h" 10#include "util.h"
@@ -79,7 +80,7 @@ typedef struct {
79 azoteq_iqs5xx_relative_xy_t y; 80 azoteq_iqs5xx_relative_xy_t y;
80} azoteq_iqs5xx_base_data_t; 81} azoteq_iqs5xx_base_data_t;
81 82
82_Static_assert(sizeof(azoteq_iqs5xx_base_data_t) == 10, "azoteq_iqs5xx_basic_report_t should be 10 bytes"); 83STATIC_ASSERT(sizeof(azoteq_iqs5xx_base_data_t) == 10, "azoteq_iqs5xx_basic_report_t should be 10 bytes");
83 84
84typedef struct { 85typedef struct {
85 uint8_t number_of_fingers; 86 uint8_t number_of_fingers;
@@ -87,7 +88,7 @@ typedef struct {
87 azoteq_iqs5xx_relative_xy_t y; 88 azoteq_iqs5xx_relative_xy_t y;
88} azoteq_iqs5xx_report_data_t; 89} azoteq_iqs5xx_report_data_t;
89 90
90_Static_assert(sizeof(azoteq_iqs5xx_report_data_t) == 5, "azoteq_iqs5xx_report_data_t should be 5 bytes"); 91STATIC_ASSERT(sizeof(azoteq_iqs5xx_report_data_t) == 5, "azoteq_iqs5xx_report_data_t should be 5 bytes");
91 92
92typedef struct PACKED { 93typedef struct PACKED {
93 bool sw_input : 1; 94 bool sw_input : 1;
@@ -159,7 +160,7 @@ typedef struct PACKED {
159 uint16_t zoom_consecutive_distance; 160 uint16_t zoom_consecutive_distance;
160} azoteq_iqs5xx_gesture_config_t; 161} azoteq_iqs5xx_gesture_config_t;
161 162
162_Static_assert(sizeof(azoteq_iqs5xx_gesture_config_t) == 24, "azoteq_iqs5xx_gesture_config_t should be 24 bytes"); 163STATIC_ASSERT(sizeof(azoteq_iqs5xx_gesture_config_t) == 24, "azoteq_iqs5xx_gesture_config_t should be 24 bytes");
163 164
164typedef struct { 165typedef struct {
165 uint16_t x_resolution; 166 uint16_t x_resolution;
diff --git a/drivers/sensors/pmw33xx_common.h b/drivers/sensors/pmw33xx_common.h
index 22e35c3327..82303ba6d9 100644
--- a/drivers/sensors/pmw33xx_common.h
+++ b/drivers/sensors/pmw33xx_common.h
@@ -10,6 +10,7 @@
10 10
11#pragma once 11#pragma once
12 12
13#include "compiler_support.h"
13#include "keyboard.h" 14#include "keyboard.h"
14#include <stdint.h> 15#include <stdint.h>
15#include "spi_master.h" 16#include "spi_master.h"
@@ -39,8 +40,8 @@ typedef struct __attribute__((packed)) {
39 int16_t delta_y; // displacement on y directions. 40 int16_t delta_y; // displacement on y directions.
40} pmw33xx_report_t; 41} pmw33xx_report_t;
41 42
42_Static_assert(sizeof(pmw33xx_report_t) == 6, "pmw33xx_report_t must be 6 bytes in size"); 43STATIC_ASSERT(sizeof(pmw33xx_report_t) == 6, "pmw33xx_report_t must be 6 bytes in size");
43_Static_assert(sizeof((pmw33xx_report_t){0}.motion) == 1, "pmw33xx_report_t.motion must be 1 byte in size"); 44STATIC_ASSERT(sizeof((pmw33xx_report_t){0}.motion) == 1, "pmw33xx_report_t.motion must be 1 byte in size");
44 45
45#if !defined(PMW33XX_CLOCK_SPEED) 46#if !defined(PMW33XX_CLOCK_SPEED)
46# define PMW33XX_CLOCK_SPEED 2000000 47# define PMW33XX_CLOCK_SPEED 2000000
diff --git a/lib/fnv/qmk_fnv_type_validation.c b/lib/fnv/qmk_fnv_type_validation.c
index e8576617ba..5e8ef5c54c 100644
--- a/lib/fnv/qmk_fnv_type_validation.c
+++ b/lib/fnv/qmk_fnv_type_validation.c
@@ -1,14 +1,15 @@
1// Copyright 2022 Nick Brassel (@tzarc) 1// Copyright 2022 Nick Brassel (@tzarc)
2// SPDX-License-Identifier: GPL-2.0-or-later 2// SPDX-License-Identifier: GPL-2.0-or-later
3#include "fnv.h" 3#include "fnv.h"
4#include "compiler_support.h"
4 5
5// This library was originally sourced from: 6// This library was originally sourced from:
6// http://www.isthe.com/chongo/tech/comp/fnv/index.html 7// http://www.isthe.com/chongo/tech/comp/fnv/index.html
7// 8//
8// Version at the time of retrieval on 2022-06-26: v5.0.3 9// Version at the time of retrieval on 2022-06-26: v5.0.3
9 10
10_Static_assert(sizeof(long long) == 8, "long long should be 64 bits"); 11STATIC_ASSERT(sizeof(long long) == 8, "long long should be 64 bits");
11_Static_assert(sizeof(unsigned long long) == 8, "unsigned long long should be 64 bits"); 12STATIC_ASSERT(sizeof(unsigned long long) == 8, "unsigned long long should be 64 bits");
12 13
13_Static_assert(sizeof(Fnv32_t) == 4, "Fnv32_t should be 32 bits"); 14STATIC_ASSERT(sizeof(Fnv32_t) == 4, "Fnv32_t should be 32 bits");
14_Static_assert(sizeof(Fnv64_t) == 8, "Fnv64_t should be 64 bits"); 15STATIC_ASSERT(sizeof(Fnv64_t) == 8, "Fnv64_t should be 64 bits");
diff --git a/lib/python/qmk/cli/generate/community_modules.py b/lib/python/qmk/cli/generate/community_modules.py
index 1f37b760ca..a5ab61f9bd 100644
--- a/lib/python/qmk/cli/generate/community_modules.py
+++ b/lib/python/qmk/cli/generate/community_modules.py
@@ -52,7 +52,7 @@ def _render_keycodes(module_jsons):
52 lines.append('') 52 lines.append('')
53 lines.append(' LAST_COMMUNITY_MODULE_KEY') 53 lines.append(' LAST_COMMUNITY_MODULE_KEY')
54 lines.append('};') 54 lines.append('};')
55 lines.append('_Static_assert((int)LAST_COMMUNITY_MODULE_KEY <= (int)(QK_COMMUNITY_MODULE_MAX+1), "Too many community module keycodes");') 55 lines.append('STATIC_ASSERT((int)LAST_COMMUNITY_MODULE_KEY <= (int)(QK_COMMUNITY_MODULE_MAX+1), "Too many community module keycodes");')
56 return lines 56 return lines
57 57
58 58
@@ -215,9 +215,11 @@ def generate_community_modules_h(cli):
215 '#include <stdbool.h>', 215 '#include <stdbool.h>',
216 '#include <keycodes.h>', 216 '#include <keycodes.h>',
217 '', 217 '',
218 '#include "compiler_support.h"',
219 '',
218 '#define COMMUNITY_MODULES_API_VERSION_BUILDER(ver_major,ver_minor,ver_patch) (((((uint32_t)(ver_major))&0xFF) << 24) | ((((uint32_t)(ver_minor))&0xFF) << 16) | (((uint32_t)(ver_patch))&0xFF))', 220 '#define COMMUNITY_MODULES_API_VERSION_BUILDER(ver_major,ver_minor,ver_patch) (((((uint32_t)(ver_major))&0xFF) << 24) | ((((uint32_t)(ver_minor))&0xFF) << 16) | (((uint32_t)(ver_patch))&0xFF))',
219 f'#define COMMUNITY_MODULES_API_VERSION COMMUNITY_MODULES_API_VERSION_BUILDER({ver_major},{ver_minor},{ver_patch})', 221 f'#define COMMUNITY_MODULES_API_VERSION COMMUNITY_MODULES_API_VERSION_BUILDER({ver_major},{ver_minor},{ver_patch})',
220 f'#define ASSERT_COMMUNITY_MODULES_MIN_API_VERSION(ver_major,ver_minor,ver_patch) _Static_assert(COMMUNITY_MODULES_API_VERSION_BUILDER(ver_major,ver_minor,ver_patch) <= COMMUNITY_MODULES_API_VERSION, "Community module requires a newer version of QMK modules API -- needs: " #ver_major "." #ver_minor "." #ver_patch ", current: {api_version}.")', 222 f'#define ASSERT_COMMUNITY_MODULES_MIN_API_VERSION(ver_major,ver_minor,ver_patch) STATIC_ASSERT(COMMUNITY_MODULES_API_VERSION_BUILDER(ver_major,ver_minor,ver_patch) <= COMMUNITY_MODULES_API_VERSION, "Community module requires a newer version of QMK modules API -- needs: " #ver_major "." #ver_minor "." #ver_patch ", current: {api_version}.")',
221 '', 223 '',
222 'typedef struct keyrecord_t keyrecord_t; // forward declaration so we don\'t need to include quantum.h', 224 'typedef struct keyrecord_t keyrecord_t; // forward declaration so we don\'t need to include quantum.h',
223 '', 225 '',
diff --git a/platforms/atomic_util.h b/platforms/atomic_util.h
index 21286d72eb..8e81eacdb8 100644
--- a/platforms/atomic_util.h
+++ b/platforms/atomic_util.h
@@ -15,17 +15,19 @@
15 */ 15 */
16#pragma once 16#pragma once
17 17
18#include "compiler_support.h"
19
18// Macro to help make GPIO and other controls atomic. 20// Macro to help make GPIO and other controls atomic.
19 21
20#ifndef IGNORE_ATOMIC_BLOCK 22#ifndef IGNORE_ATOMIC_BLOCK
21# if __has_include_next("atomic_util.h") 23# if __has_include_next("atomic_util.h")
22# include_next "atomic_util.h" /* Include the platforms atomic.h */ 24# include_next "atomic_util.h" /* Include the platforms atomic.h */
23# else 25# else
24# define ATOMIC_BLOCK _Static_assert(0, "ATOMIC_BLOCK not implemented") 26# define ATOMIC_BLOCK STATIC_ASSERT(0, "ATOMIC_BLOCK not implemented")
25# define ATOMIC_BLOCK_RESTORESTATE _Static_assert(0, "ATOMIC_BLOCK_RESTORESTATE not implemented") 27# define ATOMIC_BLOCK_RESTORESTATE STATIC_ASSERT(0, "ATOMIC_BLOCK_RESTORESTATE not implemented")
26# define ATOMIC_BLOCK_FORCEON _Static_assert(0, "ATOMIC_BLOCK_FORCEON not implemented") 28# define ATOMIC_BLOCK_FORCEON STATIC_ASSERT(0, "ATOMIC_BLOCK_FORCEON not implemented")
27# define ATOMIC_FORCEON _Static_assert(0, "ATOMIC_FORCEON not implemented") 29# define ATOMIC_FORCEON STATIC_ASSERT(0, "ATOMIC_FORCEON not implemented")
28# define ATOMIC_RESTORESTATE _Static_assert(0, "ATOMIC_RESTORESTATE not implemented") 30# define ATOMIC_RESTORESTATE STATIC_ASSERT(0, "ATOMIC_RESTORESTATE not implemented")
29# endif 31# endif
30#else /* do nothing atomic macro */ 32#else /* do nothing atomic macro */
31# define ATOMIC_BLOCK(t) for (uint8_t __ToDo = 1; __ToDo; __ToDo = 0) 33# define ATOMIC_BLOCK(t) for (uint8_t __ToDo = 1; __ToDo; __ToDo = 0)
diff --git a/platforms/avr/drivers/i2c_slave.h b/platforms/avr/drivers/i2c_slave.h
index 178b6a29df..8614bd865a 100644
--- a/platforms/avr/drivers/i2c_slave.h
+++ b/platforms/avr/drivers/i2c_slave.h
@@ -22,6 +22,8 @@
22 22
23#pragma once 23#pragma once
24 24
25#include "compiler_support.h"
26
25#ifndef I2C_SLAVE_REG_COUNT 27#ifndef I2C_SLAVE_REG_COUNT
26 28
27# if defined(USE_I2C) && defined(SPLIT_COMMON_TRANSACTIONS) 29# if defined(USE_I2C) && defined(SPLIT_COMMON_TRANSACTIONS)
@@ -33,7 +35,7 @@
33 35
34#endif // I2C_SLAVE_REG_COUNT 36#endif // I2C_SLAVE_REG_COUNT
35 37
36_Static_assert(I2C_SLAVE_REG_COUNT < 256, "I2C target registers must be single byte"); 38STATIC_ASSERT(I2C_SLAVE_REG_COUNT < 256, "I2C target registers must be single byte");
37 39
38extern volatile uint8_t i2c_slave_reg[I2C_SLAVE_REG_COUNT]; 40extern volatile uint8_t i2c_slave_reg[I2C_SLAVE_REG_COUNT];
39 41
diff --git a/platforms/avr/gpio.h b/platforms/avr/gpio.h
index 6f089bc663..4c09619772 100644
--- a/platforms/avr/gpio.h
+++ b/platforms/avr/gpio.h
@@ -16,6 +16,8 @@
16#pragma once 16#pragma once
17 17
18#include <avr/io.h> 18#include <avr/io.h>
19
20#include "compiler_support.h"
19#include "pin_defs.h" 21#include "pin_defs.h"
20 22
21typedef uint8_t pin_t; 23typedef uint8_t pin_t;
@@ -24,9 +26,9 @@ typedef uint8_t pin_t;
24 26
25#define gpio_set_pin_input(pin) (DDRx_ADDRESS(pin) &= ~_BV((pin)&0xF), PORTx_ADDRESS(pin) &= ~_BV((pin)&0xF)) 27#define gpio_set_pin_input(pin) (DDRx_ADDRESS(pin) &= ~_BV((pin)&0xF), PORTx_ADDRESS(pin) &= ~_BV((pin)&0xF))
26#define gpio_set_pin_input_high(pin) (DDRx_ADDRESS(pin) &= ~_BV((pin)&0xF), PORTx_ADDRESS(pin) |= _BV((pin)&0xF)) 28#define gpio_set_pin_input_high(pin) (DDRx_ADDRESS(pin) &= ~_BV((pin)&0xF), PORTx_ADDRESS(pin) |= _BV((pin)&0xF))
27#define gpio_set_pin_input_low(pin) _Static_assert(0, "GPIO pulldowns in input mode are not available on AVR") 29#define gpio_set_pin_input_low(pin) STATIC_ASSERT(0, "GPIO pulldowns in input mode are not available on AVR")
28#define gpio_set_pin_output_push_pull(pin) (DDRx_ADDRESS(pin) |= _BV((pin)&0xF)) 30#define gpio_set_pin_output_push_pull(pin) (DDRx_ADDRESS(pin) |= _BV((pin)&0xF))
29#define gpio_set_pin_output_open_drain(pin) _Static_assert(0, "Open-drain outputs are not available on AVR") 31#define gpio_set_pin_output_open_drain(pin) STATIC_ASSERT(0, "Open-drain outputs are not available on AVR")
30#define gpio_set_pin_output(pin) gpio_set_pin_output_push_pull(pin) 32#define gpio_set_pin_output(pin) gpio_set_pin_output_push_pull(pin)
31 33
32#define gpio_write_pin_high(pin) (PORTx_ADDRESS(pin) |= _BV((pin)&0xF)) 34#define gpio_write_pin_high(pin) (PORTx_ADDRESS(pin) |= _BV((pin)&0xF))
diff --git a/platforms/chibios/chibios_config.h b/platforms/chibios/chibios_config.h
index 9ef8e9b4fe..41546e3e50 100644
--- a/platforms/chibios/chibios_config.h
+++ b/platforms/chibios/chibios_config.h
@@ -15,6 +15,8 @@
15 */ 15 */
16#pragma once 16#pragma once
17 17
18#include "compiler_support.h"
19
18#ifndef USB_VBUS_PIN 20#ifndef USB_VBUS_PIN
19# define SPLIT_USB_DETECT // Force this on when dedicated pin is not used 21# define SPLIT_USB_DETECT // Force this on when dedicated pin is not used
20#endif 22#endif
@@ -26,7 +28,7 @@
26# define REALTIME_COUNTER_CLOCK 1000000 28# define REALTIME_COUNTER_CLOCK 1000000
27 29
28# define USE_GPIOV1 30# define USE_GPIOV1
29# define PAL_OUTPUT_TYPE_OPENDRAIN _Static_assert(0, "RP2040 has no Open Drain GPIO configuration, setting this is not possible"); 31# define PAL_OUTPUT_TYPE_OPENDRAIN STATIC_ASSERT(0, "RP2040 has no Open Drain GPIO configuration, setting this is not possible");
30 32
31/* Aliases for GPIO PWM channels - every pin has at least one PWM channel 33/* Aliases for GPIO PWM channels - every pin has at least one PWM channel
32 * assigned */ 34 * assigned */
diff --git a/platforms/chibios/drivers/wear_leveling/wear_leveling_rp2040_flash.c b/platforms/chibios/drivers/wear_leveling/wear_leveling_rp2040_flash.c
index 9bfc68f9d2..2f3c7c58ca 100644
--- a/platforms/chibios/drivers/wear_leveling/wear_leveling_rp2040_flash.c
+++ b/platforms/chibios/drivers/wear_leveling/wear_leveling_rp2040_flash.c
@@ -6,13 +6,15 @@
6 * SPDX-License-Identifier: BSD-3-Clause 6 * SPDX-License-Identifier: BSD-3-Clause
7 */ 7 */
8 8
9#include <stdbool.h>
10
9#include "pico/bootrom.h" 11#include "pico/bootrom.h"
10#include "hardware/flash.h" 12#include "hardware/flash.h"
11#include "hardware/sync.h" 13#include "hardware/sync.h"
12#include "hardware/structs/ssi.h" 14#include "hardware/structs/ssi.h"
13#include "hardware/structs/ioqspi.h" 15#include "hardware/structs/ioqspi.h"
14 16
15#include <stdbool.h> 17#include "compiler_support.h"
16#include "timer.h" 18#include "timer.h"
17#include "wear_leveling.h" 19#include "wear_leveling.h"
18#include "wear_leveling_rp2040_flash_config.h" 20#include "wear_leveling_rp2040_flash_config.h"
@@ -178,7 +180,7 @@ bool backing_store_erase(void) {
178#endif 180#endif
179 181
180 // Ensure the backing size can be cleanly subtracted from the flash size without alignment issues. 182 // Ensure the backing size can be cleanly subtracted from the flash size without alignment issues.
181 _Static_assert((WEAR_LEVELING_BACKING_SIZE) % (FLASH_SECTOR_SIZE) == 0, "Backing size must be a multiple of FLASH_SECTOR_SIZE"); 183 STATIC_ASSERT((WEAR_LEVELING_BACKING_SIZE) % (FLASH_SECTOR_SIZE) == 0, "Backing size must be a multiple of FLASH_SECTOR_SIZE");
182 184
183 interrupts = save_and_disable_interrupts(); 185 interrupts = save_and_disable_interrupts();
184 flash_range_erase((WEAR_LEVELING_RP2040_FLASH_BASE), (WEAR_LEVELING_BACKING_SIZE)); 186 flash_range_erase((WEAR_LEVELING_RP2040_FLASH_BASE), (WEAR_LEVELING_BACKING_SIZE));
diff --git a/quantum/audio/audio.h b/quantum/audio/audio.h
index 93dc6f62b1..647744a686 100644
--- a/quantum/audio/audio.h
+++ b/quantum/audio/audio.h
@@ -18,6 +18,8 @@
18 18
19#include <stdint.h> 19#include <stdint.h>
20#include <stdbool.h> 20#include <stdbool.h>
21
22#include "compiler_support.h"
21#include "musical_notes.h" 23#include "musical_notes.h"
22#include "song_list.h" 24#include "song_list.h"
23#include "voices.h" 25#include "voices.h"
@@ -38,7 +40,7 @@ typedef union audio_config_t {
38 }; 40 };
39} audio_config_t; 41} audio_config_t;
40 42
41_Static_assert(sizeof(audio_config_t) == sizeof(uint8_t), "Audio EECONFIG out of spec."); 43STATIC_ASSERT(sizeof(audio_config_t) == sizeof(uint8_t), "Audio EECONFIG out of spec.");
42 44
43/* 45/*
44 * a 'musical note' is represented by pitch and duration; a 'musical tone' adds intensity and timbre 46 * a 'musical note' is represented by pitch and duration; a 'musical tone' adds intensity and timbre
diff --git a/quantum/backlight/backlight.h b/quantum/backlight/backlight.h
index 561c7f8a94..2faa8fc4f2 100644
--- a/quantum/backlight/backlight.h
+++ b/quantum/backlight/backlight.h
@@ -20,6 +20,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
20#include <stdint.h> 20#include <stdint.h>
21#include <stdbool.h> 21#include <stdbool.h>
22 22
23#include "compiler_support.h"
24
23#ifndef BACKLIGHT_LEVELS 25#ifndef BACKLIGHT_LEVELS
24# define BACKLIGHT_LEVELS 3 26# define BACKLIGHT_LEVELS 3
25#elif BACKLIGHT_LEVELS > 31 27#elif BACKLIGHT_LEVELS > 31
@@ -44,7 +46,7 @@ typedef union backlight_config_t {
44 }; 46 };
45} backlight_config_t; 47} backlight_config_t;
46 48
47_Static_assert(sizeof(backlight_config_t) == sizeof(uint8_t), "Backlight EECONFIG out of spec."); 49STATIC_ASSERT(sizeof(backlight_config_t) == sizeof(uint8_t), "Backlight EECONFIG out of spec.");
48 50
49void backlight_init(void); 51void backlight_init(void);
50void backlight_toggle(void); 52void backlight_toggle(void);
diff --git a/quantum/compiler_support.h b/quantum/compiler_support.h
new file mode 100644
index 0000000000..5c0c4d2835
--- /dev/null
+++ b/quantum/compiler_support.h
@@ -0,0 +1,15 @@
1// Copyright 2025 QMK Contributors
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4/**
5 * @brief Perfom an assertion at compile time.
6 *
7 * `_Static_assert` is C<23, while `static_assert` is C++/C23.
8 */
9#if !defined(STATIC_ASSERT)
10# ifdef __cplusplus
11# define STATIC_ASSERT static_assert
12# else
13# define STATIC_ASSERT _Static_assert
14# endif
15#endif
diff --git a/quantum/connection/connection.h b/quantum/connection/connection.h
index e403141fae..b25160c759 100644
--- a/quantum/connection/connection.h
+++ b/quantum/connection/connection.h
@@ -3,6 +3,8 @@
3#pragma once 3#pragma once
4 4
5#include <stdint.h> 5#include <stdint.h>
6
7#include "compiler_support.h"
6#include "util.h" 8#include "util.h"
7 9
8/** 10/**
@@ -29,7 +31,7 @@ typedef union connection_config_t {
29 connection_host_t desired_host : 8; 31 connection_host_t desired_host : 8;
30} PACKED connection_config_t; 32} PACKED connection_config_t;
31 33
32_Static_assert(sizeof(connection_config_t) == sizeof(uint8_t), "Connection EECONFIG out of spec."); 34STATIC_ASSERT(sizeof(connection_config_t) == sizeof(uint8_t), "Connection EECONFIG out of spec.");
33 35
34/** 36/**
35 * \brief Initialize the subsystem. 37 * \brief Initialize the subsystem.
diff --git a/quantum/haptic.h b/quantum/haptic.h
index e27f546d40..f854c75ec3 100644
--- a/quantum/haptic.h
+++ b/quantum/haptic.h
@@ -20,6 +20,8 @@
20#include <stdint.h> 20#include <stdint.h>
21#include <stdbool.h> 21#include <stdbool.h>
22 22
23#include "compiler_support.h"
24
23#ifndef HAPTIC_DEFAULT_FEEDBACK 25#ifndef HAPTIC_DEFAULT_FEEDBACK
24# define HAPTIC_DEFAULT_FEEDBACK 0 26# define HAPTIC_DEFAULT_FEEDBACK 0
25#endif 27#endif
@@ -42,7 +44,7 @@ typedef union haptic_config_t {
42 }; 44 };
43} haptic_config_t; 45} haptic_config_t;
44 46
45_Static_assert(sizeof(haptic_config_t) == sizeof(uint32_t), "Haptic EECONFIG out of spec."); 47STATIC_ASSERT(sizeof(haptic_config_t) == sizeof(uint32_t), "Haptic EECONFIG out of spec.");
46 48
47typedef enum HAPTIC_FEEDBACK { 49typedef enum HAPTIC_FEEDBACK {
48 KEY_PRESS, 50 KEY_PRESS,
diff --git a/quantum/keycode_config.h b/quantum/keycode_config.h
index 529cd0e127..804f1381d0 100644
--- a/quantum/keycode_config.h
+++ b/quantum/keycode_config.h
@@ -16,9 +16,7 @@
16 16
17#pragma once 17#pragma once
18 18
19#ifdef __cplusplus 19#include "compiler_support.h"
20# define _Static_assert static_assert
21#endif
22 20
23#include "eeconfig.h" 21#include "eeconfig.h"
24#include "keycode.h" 22#include "keycode.h"
@@ -47,6 +45,6 @@ typedef union keymap_config_t {
47 }; 45 };
48} keymap_config_t; 46} keymap_config_t;
49 47
50_Static_assert(sizeof(keymap_config_t) == sizeof(uint16_t), "Keycode (magic) EECONFIG out of spec."); 48STATIC_ASSERT(sizeof(keymap_config_t) == sizeof(uint16_t), "Keycode (magic) EECONFIG out of spec.");
51 49
52extern keymap_config_t keymap_config; 50extern keymap_config_t keymap_config;
diff --git a/quantum/keymap_introspection.c b/quantum/keymap_introspection.c
index 23e842353a..99fd3f929e 100644
--- a/quantum/keymap_introspection.c
+++ b/quantum/keymap_introspection.c
@@ -13,6 +13,7 @@
13# include INTROSPECTION_KEYMAP_C 13# include INTROSPECTION_KEYMAP_C
14#endif // INTROSPECTION_KEYMAP_C 14#endif // INTROSPECTION_KEYMAP_C
15 15
16#include "compiler_support.h"
16#include "keymap_introspection.h" 17#include "keymap_introspection.h"
17#include "util.h" 18#include "util.h"
18 19
@@ -30,9 +31,9 @@ __attribute__((weak)) uint8_t keymap_layer_count(void) {
30} 31}
31 32
32#ifdef DYNAMIC_KEYMAP_ENABLE 33#ifdef DYNAMIC_KEYMAP_ENABLE
33_Static_assert(NUM_KEYMAP_LAYERS_RAW <= MAX_LAYER, "Number of keymap layers exceeds maximum set by DYNAMIC_KEYMAP_LAYER_COUNT"); 34STATIC_ASSERT(NUM_KEYMAP_LAYERS_RAW <= MAX_LAYER, "Number of keymap layers exceeds maximum set by DYNAMIC_KEYMAP_LAYER_COUNT");
34#else 35#else
35_Static_assert(NUM_KEYMAP_LAYERS_RAW <= MAX_LAYER, "Number of keymap layers exceeds maximum set by LAYER_STATE_(8|16|32)BIT"); 36STATIC_ASSERT(NUM_KEYMAP_LAYERS_RAW <= MAX_LAYER, "Number of keymap layers exceeds maximum set by LAYER_STATE_(8|16|32)BIT");
36#endif 37#endif
37 38
38uint16_t keycode_at_keymap_location_raw(uint8_t layer_num, uint8_t row, uint8_t column) { 39uint16_t keycode_at_keymap_location_raw(uint8_t layer_num, uint8_t row, uint8_t column) {
@@ -61,7 +62,7 @@ __attribute__((weak)) uint8_t encodermap_layer_count(void) {
61 return encodermap_layer_count_raw(); 62 return encodermap_layer_count_raw();
62} 63}
63 64
64_Static_assert(NUM_KEYMAP_LAYERS_RAW == NUM_ENCODERMAP_LAYERS_RAW, "Number of encoder_map layers doesn't match the number of keymap layers"); 65STATIC_ASSERT(NUM_KEYMAP_LAYERS_RAW == NUM_ENCODERMAP_LAYERS_RAW, "Number of encoder_map layers doesn't match the number of keymap layers");
65 66
66uint16_t keycode_at_encodermap_location_raw(uint8_t layer_num, uint8_t encoder_idx, bool clockwise) { 67uint16_t keycode_at_encodermap_location_raw(uint8_t layer_num, uint8_t encoder_idx, bool clockwise) {
67 if (layer_num < NUM_ENCODERMAP_LAYERS_RAW && encoder_idx < NUM_ENCODERS) { 68 if (layer_num < NUM_ENCODERMAP_LAYERS_RAW && encoder_idx < NUM_ENCODERS) {
@@ -106,7 +107,7 @@ __attribute__((weak)) uint16_t combo_count(void) {
106 return combo_count_raw(); 107 return combo_count_raw();
107} 108}
108 109
109_Static_assert(ARRAY_SIZE(key_combos) <= (QK_KB), "Number of combos is abnormally high. Are you using SAFE_RANGE in an enum for combos?"); 110STATIC_ASSERT(ARRAY_SIZE(key_combos) <= (QK_KB), "Number of combos is abnormally high. Are you using SAFE_RANGE in an enum for combos?");
110 111
111combo_t* combo_get_raw(uint16_t combo_idx) { 112combo_t* combo_get_raw(uint16_t combo_idx) {
112 if (combo_idx >= combo_count_raw()) { 113 if (combo_idx >= combo_count_raw()) {
@@ -133,7 +134,7 @@ __attribute__((weak)) uint16_t tap_dance_count(void) {
133 return tap_dance_count_raw(); 134 return tap_dance_count_raw();
134} 135}
135 136
136_Static_assert(ARRAY_SIZE(tap_dance_actions) <= (QK_TAP_DANCE_MAX - QK_TAP_DANCE), "Number of tap dance actions exceeds maximum. Are you using SAFE_RANGE in tap dance enum?"); 137STATIC_ASSERT(ARRAY_SIZE(tap_dance_actions) <= (QK_TAP_DANCE_MAX - QK_TAP_DANCE), "Number of tap dance actions exceeds maximum. Are you using SAFE_RANGE in tap dance enum?");
137 138
138tap_dance_action_t* tap_dance_get_raw(uint16_t tap_dance_idx) { 139tap_dance_action_t* tap_dance_get_raw(uint16_t tap_dance_idx) {
139 if (tap_dance_idx >= tap_dance_count_raw()) { 140 if (tap_dance_idx >= tap_dance_count_raw()) {
@@ -161,7 +162,7 @@ __attribute__((weak)) uint16_t key_override_count(void) {
161 return key_override_count_raw(); 162 return key_override_count_raw();
162} 163}
163 164
164_Static_assert(ARRAY_SIZE(key_overrides) <= (QK_KB), "Number of key overrides is abnormally high. Are you using SAFE_RANGE in an enum for key overrides?"); 165STATIC_ASSERT(ARRAY_SIZE(key_overrides) <= (QK_KB), "Number of key overrides is abnormally high. Are you using SAFE_RANGE in an enum for key overrides?");
165 166
166const key_override_t* key_override_get_raw(uint16_t key_override_idx) { 167const key_override_t* key_override_get_raw(uint16_t key_override_idx) {
167 if (key_override_idx >= key_override_count_raw()) { 168 if (key_override_idx >= key_override_count_raw()) {
diff --git a/quantum/led_matrix/led_matrix_types.h b/quantum/led_matrix/led_matrix_types.h
index 810420f46f..26a199701e 100644
--- a/quantum/led_matrix/led_matrix_types.h
+++ b/quantum/led_matrix/led_matrix_types.h
@@ -18,6 +18,8 @@
18 18
19#include <stdint.h> 19#include <stdint.h>
20#include <stdbool.h> 20#include <stdbool.h>
21
22#include "compiler_support.h"
21#include "util.h" 23#include "util.h"
22 24
23#if defined(LED_MATRIX_KEYPRESSES) || defined(LED_MATRIX_KEYRELEASES) 25#if defined(LED_MATRIX_KEYPRESSES) || defined(LED_MATRIX_KEYRELEASES)
@@ -82,4 +84,4 @@ typedef union led_eeconfig_t {
82 }; 84 };
83} led_eeconfig_t; 85} led_eeconfig_t;
84 86
85_Static_assert(sizeof(led_eeconfig_t) == sizeof(uint32_t), "LED Matrix EECONFIG out of spec."); 87STATIC_ASSERT(sizeof(led_eeconfig_t) == sizeof(uint32_t), "LED Matrix EECONFIG out of spec.");
diff --git a/quantum/nvm/eeprom/nvm_dynamic_keymap.c b/quantum/nvm/eeprom/nvm_dynamic_keymap.c
index 5f514acc1a..3e315f2bcb 100644
--- a/quantum/nvm/eeprom/nvm_dynamic_keymap.c
+++ b/quantum/nvm/eeprom/nvm_dynamic_keymap.c
@@ -1,6 +1,7 @@
1// Copyright 2024 Nick Brassel (@tzarc) 1// Copyright 2024 Nick Brassel (@tzarc)
2// SPDX-License-Identifier: GPL-2.0-or-later 2// SPDX-License-Identifier: GPL-2.0-or-later
3 3
4#include "compiler_support.h"
4#include "keycodes.h" 5#include "keycodes.h"
5#include "eeprom.h" 6#include "eeprom.h"
6#include "dynamic_keymap.h" 7#include "dynamic_keymap.h"
@@ -25,10 +26,10 @@
25# define DYNAMIC_KEYMAP_EEPROM_MAX_ADDR (TOTAL_EEPROM_BYTE_COUNT - 1) 26# define DYNAMIC_KEYMAP_EEPROM_MAX_ADDR (TOTAL_EEPROM_BYTE_COUNT - 1)
26#endif 27#endif
27 28
28_Static_assert(DYNAMIC_KEYMAP_EEPROM_MAX_ADDR <= (TOTAL_EEPROM_BYTE_COUNT - 1), "DYNAMIC_KEYMAP_EEPROM_MAX_ADDR is configured to use more space than what is available for the selected EEPROM driver"); 29STATIC_ASSERT(DYNAMIC_KEYMAP_EEPROM_MAX_ADDR <= (TOTAL_EEPROM_BYTE_COUNT - 1), "DYNAMIC_KEYMAP_EEPROM_MAX_ADDR is configured to use more space than what is available for the selected EEPROM driver");
29 30
30// Due to usage of uint16_t check for max 65535 31// Due to usage of uint16_t check for max 65535
31_Static_assert(DYNAMIC_KEYMAP_EEPROM_MAX_ADDR <= 65535, "DYNAMIC_KEYMAP_EEPROM_MAX_ADDR must be less than 65536"); 32STATIC_ASSERT(DYNAMIC_KEYMAP_EEPROM_MAX_ADDR <= 65535, "DYNAMIC_KEYMAP_EEPROM_MAX_ADDR must be less than 65536");
32 33
33// If DYNAMIC_KEYMAP_EEPROM_ADDR not explicitly defined in config.h, 34// If DYNAMIC_KEYMAP_EEPROM_ADDR not explicitly defined in config.h,
34#ifndef DYNAMIC_KEYMAP_EEPROM_ADDR 35#ifndef DYNAMIC_KEYMAP_EEPROM_ADDR
@@ -56,7 +57,7 @@ _Static_assert(DYNAMIC_KEYMAP_EEPROM_MAX_ADDR <= 65535, "DYNAMIC_KEYMAP_EEPROM_M
56// The keyboard should override DYNAMIC_KEYMAP_LAYER_COUNT to reduce it, 57// The keyboard should override DYNAMIC_KEYMAP_LAYER_COUNT to reduce it,
57// or DYNAMIC_KEYMAP_EEPROM_MAX_ADDR to increase it, *only if* the microcontroller has 58// or DYNAMIC_KEYMAP_EEPROM_MAX_ADDR to increase it, *only if* the microcontroller has
58// more than the default. 59// more than the default.
59_Static_assert((DYNAMIC_KEYMAP_EEPROM_MAX_ADDR) - (DYNAMIC_KEYMAP_MACRO_EEPROM_ADDR) >= 100, "Dynamic keymaps are configured to use more EEPROM than is available."); 60STATIC_ASSERT((DYNAMIC_KEYMAP_EEPROM_MAX_ADDR) - (DYNAMIC_KEYMAP_MACRO_EEPROM_ADDR) >= 100, "Dynamic keymaps are configured to use more EEPROM than is available.");
60 61
61#ifndef TOTAL_EEPROM_BYTE_COUNT 62#ifndef TOTAL_EEPROM_BYTE_COUNT
62# error Unknown total EEPROM size. Cannot derive maximum for dynamic keymaps. 63# error Unknown total EEPROM size. Cannot derive maximum for dynamic keymaps.
diff --git a/quantum/nvm/eeprom/nvm_eeprom_eeconfig_internal.h b/quantum/nvm/eeprom/nvm_eeprom_eeconfig_internal.h
index 41b76f1f65..78b8190eaf 100644
--- a/quantum/nvm/eeprom/nvm_eeprom_eeconfig_internal.h
+++ b/quantum/nvm/eeprom/nvm_eeprom_eeconfig_internal.h
@@ -4,6 +4,8 @@
4 4
5#include <stdint.h> 5#include <stdint.h>
6#include <stddef.h> // offsetof 6#include <stddef.h> // offsetof
7
8#include "compiler_support.h"
7#include "eeconfig.h" 9#include "eeconfig.h"
8#include "util.h" 10#include "util.h"
9 11
@@ -58,4 +60,4 @@ typedef struct PACKED {
58// Size of EEPROM being used, other code can refer to this for available EEPROM 60// Size of EEPROM being used, other code can refer to this for available EEPROM
59#define EECONFIG_SIZE ((EECONFIG_BASE_SIZE) + (EECONFIG_KB_DATA_SIZE) + (EECONFIG_USER_DATA_SIZE)) 61#define EECONFIG_SIZE ((EECONFIG_BASE_SIZE) + (EECONFIG_KB_DATA_SIZE) + (EECONFIG_USER_DATA_SIZE))
60 62
61_Static_assert((intptr_t)EECONFIG_HANDEDNESS == 14, "EEPROM handedness offset is incorrect"); 63STATIC_ASSERT((intptr_t)EECONFIG_HANDEDNESS == 14, "EEPROM handedness offset is incorrect");
diff --git a/quantum/painter/qff.h b/quantum/painter/qff.h
index c3b831da17..ed88508d73 100644
--- a/quantum/painter/qff.h
+++ b/quantum/painter/qff.h
@@ -9,6 +9,7 @@
9#include <stdint.h> 9#include <stdint.h>
10#include <stdbool.h> 10#include <stdbool.h>
11 11
12#include "compiler_support.h"
12#include "qp_stream.h" 13#include "qp_stream.h"
13#include "qp_internal.h" 14#include "qp_internal.h"
14#include "qgf.h" 15#include "qgf.h"
@@ -36,7 +37,7 @@ typedef struct QP_PACKED qff_font_descriptor_v1_t {
36 uint8_t transparency_index; // palette index used for transparent pixels (not yet implemented) 37 uint8_t transparency_index; // palette index used for transparent pixels (not yet implemented)
37} qff_font_descriptor_v1_t; 38} qff_font_descriptor_v1_t;
38 39
39_Static_assert(sizeof(qff_font_descriptor_v1_t) == (sizeof(qgf_block_header_v1_t) + 20), "qff_font_descriptor_v1_t must be 25 bytes in v1 of QFF"); 40STATIC_ASSERT(sizeof(qff_font_descriptor_v1_t) == (sizeof(qgf_block_header_v1_t) + 20), "qff_font_descriptor_v1_t must be 25 bytes in v1 of QFF");
40 41
41#define QFF_MAGIC 0x464651 42#define QFF_MAGIC 0x464651
42 43
@@ -54,14 +55,14 @@ typedef struct QP_PACKED qff_ascii_glyph_v1_t {
54 uint32_t value : 24; // Uses QFF_GLYPH_*_(BITS|MASK) as bitfield ordering is compiler-defined 55 uint32_t value : 24; // Uses QFF_GLYPH_*_(BITS|MASK) as bitfield ordering is compiler-defined
55} qff_ascii_glyph_v1_t; 56} qff_ascii_glyph_v1_t;
56 57
57_Static_assert(sizeof(qff_ascii_glyph_v1_t) == 3, "qff_ascii_glyph_v1_t must be 3 bytes in v1 of QFF"); 58STATIC_ASSERT(sizeof(qff_ascii_glyph_v1_t) == 3, "qff_ascii_glyph_v1_t must be 3 bytes in v1 of QFF");
58 59
59typedef struct QP_PACKED qff_ascii_glyph_table_v1_t { 60typedef struct QP_PACKED qff_ascii_glyph_table_v1_t {
60 qgf_block_header_v1_t header; // = { .type_id = 0x01, .neg_type_id = (~0x01), .length = 285 } 61 qgf_block_header_v1_t header; // = { .type_id = 0x01, .neg_type_id = (~0x01), .length = 285 }
61 qff_ascii_glyph_v1_t glyph[95]; // 95 glyphs, 0x20..0x7E 62 qff_ascii_glyph_v1_t glyph[95]; // 95 glyphs, 0x20..0x7E
62} qff_ascii_glyph_table_v1_t; 63} qff_ascii_glyph_table_v1_t;
63 64
64_Static_assert(sizeof(qff_ascii_glyph_table_v1_t) == (sizeof(qgf_block_header_v1_t) + (95 * sizeof(qff_ascii_glyph_v1_t))), "qff_ascii_glyph_table_v1_t must be 290 bytes in v1 of QFF"); 65STATIC_ASSERT(sizeof(qff_ascii_glyph_table_v1_t) == (sizeof(qgf_block_header_v1_t) + (95 * sizeof(qff_ascii_glyph_v1_t))), "qff_ascii_glyph_table_v1_t must be 290 bytes in v1 of QFF");
65 66
66///////////////////////////////////////// 67/////////////////////////////////////////
67// Unicode glyph table descriptor 68// Unicode glyph table descriptor
@@ -73,7 +74,7 @@ typedef struct QP_PACKED qff_unicode_glyph_v1_t {
73 uint32_t value : 24; // Uses QFF_GLYPH_*_(BITS|MASK) as bitfield ordering is compiler-defined 74 uint32_t value : 24; // Uses QFF_GLYPH_*_(BITS|MASK) as bitfield ordering is compiler-defined
74} qff_unicode_glyph_v1_t; 75} qff_unicode_glyph_v1_t;
75 76
76_Static_assert(sizeof(qff_unicode_glyph_v1_t) == 6, "qff_unicode_glyph_v1_t must be 6 bytes in v1 of QFF"); 77STATIC_ASSERT(sizeof(qff_unicode_glyph_v1_t) == 6, "qff_unicode_glyph_v1_t must be 6 bytes in v1 of QFF");
77 78
78typedef struct QP_PACKED qff_unicode_glyph_table_v1_t { 79typedef struct QP_PACKED qff_unicode_glyph_table_v1_t {
79 qgf_block_header_v1_t header; // = { .type_id = 0x02, .neg_type_id = (~0x02), .length = (N * 6) } 80 qgf_block_header_v1_t header; // = { .type_id = 0x02, .neg_type_id = (~0x02), .length = (N * 6) }
diff --git a/quantum/painter/qgf.h b/quantum/painter/qgf.h
index 33a37709e6..a1e245f15d 100644
--- a/quantum/painter/qgf.h
+++ b/quantum/painter/qgf.h
@@ -9,6 +9,7 @@
9#include <stdint.h> 9#include <stdint.h>
10#include <stdbool.h> 10#include <stdbool.h>
11 11
12#include "compiler_support.h"
12#include "qp_stream.h" 13#include "qp_stream.h"
13#include "qp_internal.h" 14#include "qp_internal.h"
14 15
@@ -24,7 +25,7 @@ typedef struct QP_PACKED qgf_block_header_v1_t {
24 uint32_t length : 24; // 24-bit blob length, allowing for block sizes of a maximum of 16MB. 25 uint32_t length : 24; // 24-bit blob length, allowing for block sizes of a maximum of 16MB.
25} qgf_block_header_v1_t; 26} qgf_block_header_v1_t;
26 27
27_Static_assert(sizeof(qgf_block_header_v1_t) == 5, "qgf_block_header_v1_t must be 5 bytes in v1 of QGF"); 28STATIC_ASSERT(sizeof(qgf_block_header_v1_t) == 5, "qgf_block_header_v1_t must be 5 bytes in v1 of QGF");
28 29
29///////////////////////////////////////// 30/////////////////////////////////////////
30// Graphics descriptor 31// Graphics descriptor
@@ -42,7 +43,7 @@ typedef struct QP_PACKED qgf_graphics_descriptor_v1_t {
42 uint16_t frame_count; // minimum of 1 43 uint16_t frame_count; // minimum of 1
43} qgf_graphics_descriptor_v1_t; 44} qgf_graphics_descriptor_v1_t;
44 45
45_Static_assert(sizeof(qgf_graphics_descriptor_v1_t) == (sizeof(qgf_block_header_v1_t) + 18), "qgf_graphics_descriptor_v1_t must be 23 bytes in v1 of QGF"); 46STATIC_ASSERT(sizeof(qgf_graphics_descriptor_v1_t) == (sizeof(qgf_block_header_v1_t) + 18), "qgf_graphics_descriptor_v1_t must be 23 bytes in v1 of QGF");
46 47
47#define QGF_MAGIC 0x464751 48#define QGF_MAGIC 0x464751
48 49
@@ -56,7 +57,7 @@ typedef struct QP_PACKED qgf_frame_offsets_v1_t {
56 uint32_t offset[0]; // '0' signifies that this struct is immediately followed by the frame offsets 57 uint32_t offset[0]; // '0' signifies that this struct is immediately followed by the frame offsets
57} qgf_frame_offsets_v1_t; 58} qgf_frame_offsets_v1_t;
58 59
59_Static_assert(sizeof(qgf_frame_offsets_v1_t) == sizeof(qgf_block_header_v1_t), "qgf_frame_offsets_v1_t must only contain qgf_block_header_v1_t in v1 of QGF"); 60STATIC_ASSERT(sizeof(qgf_frame_offsets_v1_t) == sizeof(qgf_block_header_v1_t), "qgf_frame_offsets_v1_t must only contain qgf_block_header_v1_t in v1 of QGF");
60 61
61///////////////////////////////////////// 62/////////////////////////////////////////
62// Frame descriptor 63// Frame descriptor
@@ -72,7 +73,7 @@ typedef struct QP_PACKED qgf_frame_v1_t {
72 uint16_t delay; // frame delay time for animations (in units of milliseconds) 73 uint16_t delay; // frame delay time for animations (in units of milliseconds)
73} qgf_frame_v1_t; 74} qgf_frame_v1_t;
74 75
75_Static_assert(sizeof(qgf_frame_v1_t) == (sizeof(qgf_block_header_v1_t) + 6), "qgf_frame_v1_t must be 11 bytes in v1 of QGF"); 76STATIC_ASSERT(sizeof(qgf_frame_v1_t) == (sizeof(qgf_block_header_v1_t) + 6), "qgf_frame_v1_t must be 11 bytes in v1 of QGF");
76 77
77#define QGF_FRAME_FLAG_DELTA 0x02 78#define QGF_FRAME_FLAG_DELTA 0x02
78#define QGF_FRAME_FLAG_TRANSPARENT 0x01 79#define QGF_FRAME_FLAG_TRANSPARENT 0x01
@@ -88,14 +89,14 @@ typedef struct QP_PACKED qgf_palette_entry_v1_t {
88 uint8_t v; // value component: `[0,1]` is mapped to `[0,255]` uint8_t. 89 uint8_t v; // value component: `[0,1]` is mapped to `[0,255]` uint8_t.
89} qgf_palette_entry_v1_t; 90} qgf_palette_entry_v1_t;
90 91
91_Static_assert(sizeof(qgf_palette_entry_v1_t) == 3, "Palette entry is not 3 bytes in size"); 92STATIC_ASSERT(sizeof(qgf_palette_entry_v1_t) == 3, "Palette entry is not 3 bytes in size");
92 93
93typedef struct QP_PACKED qgf_palette_v1_t { 94typedef struct QP_PACKED qgf_palette_v1_t {
94 qgf_block_header_v1_t header; // = { .type_id = 0x03, .neg_type_id = (~0x03), .length = (N * 3 * sizeof(uint8_t)) } 95 qgf_block_header_v1_t header; // = { .type_id = 0x03, .neg_type_id = (~0x03), .length = (N * 3 * sizeof(uint8_t)) }
95 qgf_palette_entry_v1_t hsv[0]; // N * hsv, where N is the number of palette entries depending on the frame format in the descriptor 96 qgf_palette_entry_v1_t hsv[0]; // N * hsv, where N is the number of palette entries depending on the frame format in the descriptor
96} qgf_palette_v1_t; 97} qgf_palette_v1_t;
97 98
98_Static_assert(sizeof(qgf_palette_v1_t) == sizeof(qgf_block_header_v1_t), "qgf_palette_v1_t must only contain qgf_block_header_v1_t in v1 of QGF"); 99STATIC_ASSERT(sizeof(qgf_palette_v1_t) == sizeof(qgf_block_header_v1_t), "qgf_palette_v1_t must only contain qgf_block_header_v1_t in v1 of QGF");
99 100
100///////////////////////////////////////// 101/////////////////////////////////////////
101// Frame delta descriptor 102// Frame delta descriptor
@@ -110,7 +111,7 @@ typedef struct QP_PACKED qgf_delta_v1_t {
110 uint16_t bottom; // The bottom pixel location to to draw the delta image 111 uint16_t bottom; // The bottom pixel location to to draw the delta image
111} qgf_delta_v1_t; 112} qgf_delta_v1_t;
112 113
113_Static_assert(sizeof(qgf_delta_v1_t) == (sizeof(qgf_block_header_v1_t) + 8), "qgf_delta_v1_t must be 13 bytes in v1 of QGF"); 114STATIC_ASSERT(sizeof(qgf_delta_v1_t) == (sizeof(qgf_block_header_v1_t) + 8), "qgf_delta_v1_t must be 13 bytes in v1 of QGF");
114 115
115///////////////////////////////////////// 116/////////////////////////////////////////
116// Frame data descriptor 117// Frame data descriptor
@@ -122,7 +123,7 @@ typedef struct QP_PACKED qgf_data_v1_t {
122 uint8_t data[0]; // 0 signifies that this struct is immediately followed by the length of data specified in the header 123 uint8_t data[0]; // 0 signifies that this struct is immediately followed by the length of data specified in the header
123} qgf_data_v1_t; 124} qgf_data_v1_t;
124 125
125_Static_assert(sizeof(qgf_data_v1_t) == sizeof(qgf_block_header_v1_t), "qgf_data_v1_t must only contain qgf_block_header_v1_t in v1 of QGF"); 126STATIC_ASSERT(sizeof(qgf_data_v1_t) == sizeof(qgf_block_header_v1_t), "qgf_data_v1_t must only contain qgf_block_header_v1_t in v1 of QGF");
126 127
127//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 128////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
128// QGF API 129// QGF API
diff --git a/quantum/painter/qp_draw_core.c b/quantum/painter/qp_draw_core.c
index aa5fa4aa76..852abb19e8 100644
--- a/quantum/painter/qp_draw_core.c
+++ b/quantum/painter/qp_draw_core.c
@@ -2,12 +2,13 @@
2// Copyright 2021 Paul Cotter (@gr1mr3aver) 2// Copyright 2021 Paul Cotter (@gr1mr3aver)
3// SPDX-License-Identifier: GPL-2.0-or-later 3// SPDX-License-Identifier: GPL-2.0-or-later
4 4
5#include "compiler_support.h"
5#include "qp_internal.h" 6#include "qp_internal.h"
6#include "qp_comms.h" 7#include "qp_comms.h"
7#include "qp_draw.h" 8#include "qp_draw.h"
8#include "qgf.h" 9#include "qgf.h"
9 10
10_Static_assert((QUANTUM_PAINTER_PIXDATA_BUFFER_SIZE > 0) && (QUANTUM_PAINTER_PIXDATA_BUFFER_SIZE % 16) == 0, "QUANTUM_PAINTER_PIXDATA_BUFFER_SIZE needs to be a non-zero multiple of 16"); 11STATIC_ASSERT((QUANTUM_PAINTER_PIXDATA_BUFFER_SIZE > 0) && (QUANTUM_PAINTER_PIXDATA_BUFFER_SIZE % 16) == 0, "QUANTUM_PAINTER_PIXDATA_BUFFER_SIZE needs to be a non-zero multiple of 16");
11 12
12//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 13////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
13// Global variables 14// Global variables
diff --git a/quantum/painter/qp_internal.c b/quantum/painter/qp_internal.c
index 24b881bd09..fe0c598d78 100644
--- a/quantum/painter/qp_internal.c
+++ b/quantum/painter/qp_internal.c
@@ -3,6 +3,8 @@
3 3
4#include "qp_internal.h" 4#include "qp_internal.h"
5 5
6#include "compiler_support.h"
7
6//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 8////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7// Quantum Painter Core API: device registration 9// Quantum Painter Core API: device registration
8 10
@@ -67,7 +69,7 @@ static void qp_internal_display_timeout_task(void) {
67//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 69////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
68// Quantum Painter Core API: qp_internal_task 70// Quantum Painter Core API: qp_internal_task
69 71
70_Static_assert((QUANTUM_PAINTER_TASK_THROTTLE) > 0 && (QUANTUM_PAINTER_TASK_THROTTLE) < 1000, "QUANTUM_PAINTER_TASK_THROTTLE must be between 1 and 999"); 72STATIC_ASSERT((QUANTUM_PAINTER_TASK_THROTTLE) > 0 && (QUANTUM_PAINTER_TASK_THROTTLE) < 1000, "QUANTUM_PAINTER_TASK_THROTTLE must be between 1 and 999");
71 73
72void qp_internal_task(void) { 74void qp_internal_task(void) {
73 // Perform throttling of the internal processing of Quantum Painter 75 // Perform throttling of the internal processing of Quantum Painter
diff --git a/quantum/painter/qp_internal_formats.h b/quantum/painter/qp_internal_formats.h
index 1beb604b9e..bd7105cab2 100644
--- a/quantum/painter/qp_internal_formats.h
+++ b/quantum/painter/qp_internal_formats.h
@@ -3,6 +3,7 @@
3 3
4#pragma once 4#pragma once
5 5
6#include "compiler_support.h"
6#include "qp_internal.h" 7#include "qp_internal.h"
7 8
8//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 9////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -29,7 +30,7 @@ typedef union QP_PACKED qp_pixel_t {
29 30
30 uint32_t dummy; 31 uint32_t dummy;
31} qp_pixel_t; 32} qp_pixel_t;
32_Static_assert(sizeof(qp_pixel_t) == 4, "Invalid size for qp_pixel_t"); 33STATIC_ASSERT(sizeof(qp_pixel_t) == 4, "Invalid size for qp_pixel_t");
33 34
34//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 35////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
35// Quantum Painter image format 36// Quantum Painter image format
diff --git a/quantum/rgb_matrix/rgb_matrix_types.h b/quantum/rgb_matrix/rgb_matrix_types.h
index 62005ebea9..0115edee6a 100644
--- a/quantum/rgb_matrix/rgb_matrix_types.h
+++ b/quantum/rgb_matrix/rgb_matrix_types.h
@@ -18,6 +18,8 @@
18 18
19#include <stdint.h> 19#include <stdint.h>
20#include <stdbool.h> 20#include <stdbool.h>
21
22#include "compiler_support.h"
21#include "color.h" 23#include "color.h"
22#include "util.h" 24#include "util.h"
23 25
@@ -84,4 +86,4 @@ typedef union rgb_config_t {
84 }; 86 };
85} rgb_config_t; 87} rgb_config_t;
86 88
87_Static_assert(sizeof(rgb_config_t) == sizeof(uint64_t), "RGB Matrix EECONFIG out of spec."); 89STATIC_ASSERT(sizeof(rgb_config_t) == sizeof(uint64_t), "RGB Matrix EECONFIG out of spec.");
diff --git a/quantum/rgblight/rgblight.h b/quantum/rgblight/rgblight.h
index f5fd450d4c..c061e71895 100644
--- a/quantum/rgblight/rgblight.h
+++ b/quantum/rgblight/rgblight.h
@@ -16,6 +16,8 @@
16 16
17#pragma once 17#pragma once
18 18
19#include "compiler_support.h"
20
19// DEPRECATED DEFINES - DO NOT USE 21// DEPRECATED DEFINES - DO NOT USE
20#if defined(RGBLED_NUM) 22#if defined(RGBLED_NUM)
21# define RGBLIGHT_LED_COUNT RGBLED_NUM 23# define RGBLIGHT_LED_COUNT RGBLED_NUM
@@ -260,7 +262,7 @@ typedef union rgblight_config_t {
260 }; 262 };
261} rgblight_config_t; 263} rgblight_config_t;
262 264
263_Static_assert(sizeof(rgblight_config_t) == sizeof(uint64_t), "RGB Light EECONFIG out of spec."); 265STATIC_ASSERT(sizeof(rgblight_config_t) == sizeof(uint64_t), "RGB Light EECONFIG out of spec.");
264 266
265typedef struct _rgblight_status_t { 267typedef struct _rgblight_status_t {
266 uint8_t base_mode; 268 uint8_t base_mode;
diff --git a/quantum/split_common/split_util.c b/quantum/split_common/split_util.c
index 9af3c29d75..59b6009ec4 100644
--- a/quantum/split_common/split_util.c
+++ b/quantum/split_common/split_util.c
@@ -13,6 +13,8 @@
13 * You should have received a copy of the GNU General Public License 13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>. 14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */ 15 */
16
17#include "compiler_support.h"
16#include "split_util.h" 18#include "split_util.h"
17#include "matrix.h" 19#include "matrix.h"
18#include "keyboard.h" 20#include "keyboard.h"
@@ -62,7 +64,7 @@ static struct {
62} split_config; 64} split_config;
63 65
64#if defined(SPLIT_USB_DETECT) 66#if defined(SPLIT_USB_DETECT)
65_Static_assert((SPLIT_USB_TIMEOUT / SPLIT_USB_TIMEOUT_POLL) <= UINT16_MAX, "Please lower SPLIT_USB_TIMEOUT and/or increase SPLIT_USB_TIMEOUT_POLL."); 67STATIC_ASSERT((SPLIT_USB_TIMEOUT / SPLIT_USB_TIMEOUT_POLL) <= UINT16_MAX, "Please lower SPLIT_USB_TIMEOUT and/or increase SPLIT_USB_TIMEOUT_POLL.");
66static bool usb_bus_detected(void) { 68static bool usb_bus_detected(void) {
67 for (uint16_t i = 0; i < (SPLIT_USB_TIMEOUT / SPLIT_USB_TIMEOUT_POLL); i++) { 69 for (uint16_t i = 0; i < (SPLIT_USB_TIMEOUT / SPLIT_USB_TIMEOUT_POLL); i++) {
68 // This will return true if a USB connection has been established 70 // This will return true if a USB connection has been established
@@ -88,9 +90,9 @@ static inline bool usb_bus_detected(void) {
88# endif 90# endif
89# endif 91# endif
90# if defined(SPLIT_USB_DETECT) 92# if defined(SPLIT_USB_DETECT)
91_Static_assert(SPLIT_USB_TIMEOUT < SPLIT_WATCHDOG_TIMEOUT, "SPLIT_WATCHDOG_TIMEOUT should not be below SPLIT_USB_TIMEOUT."); 93STATIC_ASSERT(SPLIT_USB_TIMEOUT < SPLIT_WATCHDOG_TIMEOUT, "SPLIT_WATCHDOG_TIMEOUT should not be below SPLIT_USB_TIMEOUT.");
92# endif 94# endif
93_Static_assert(SPLIT_MAX_CONNECTION_ERRORS > 0, "SPLIT_WATCHDOG_ENABLE requires SPLIT_MAX_CONNECTION_ERRORS be above 0 for a functioning disconnection check."); 95STATIC_ASSERT(SPLIT_MAX_CONNECTION_ERRORS > 0, "SPLIT_WATCHDOG_ENABLE requires SPLIT_MAX_CONNECTION_ERRORS be above 0 for a functioning disconnection check.");
94 96
95static uint32_t split_watchdog_started = 0; 97static uint32_t split_watchdog_started = 0;
96static bool split_watchdog_done = false; 98static bool split_watchdog_done = false;
diff --git a/quantum/split_common/transaction_id_define.h b/quantum/split_common/transaction_id_define.h
index 5bfbe2aec7..694737868a 100644
--- a/quantum/split_common/transaction_id_define.h
+++ b/quantum/split_common/transaction_id_define.h
@@ -16,6 +16,8 @@
16 16
17#pragma once 17#pragma once
18 18
19#include "compiler_support.h"
20
19enum serial_transaction_id { 21enum serial_transaction_id {
20#ifdef USE_I2C 22#ifdef USE_I2C
21 I2C_EXECUTE_CALLBACK, 23 I2C_EXECUTE_CALLBACK,
@@ -122,4 +124,4 @@ enum serial_transaction_id {
122}; 124};
123 125
124// Ensure we only use 5 bits for transaction 126// Ensure we only use 5 bits for transaction
125_Static_assert(NUM_TOTAL_TRANSACTIONS <= (1 << 5), "Max number of usable transactions exceeded"); 127STATIC_ASSERT(NUM_TOTAL_TRANSACTIONS <= (1 << 5), "Max number of usable transactions exceeded");
diff --git a/quantum/split_common/transport.c b/quantum/split_common/transport.c
index 83edc34859..ea687af1c2 100644
--- a/quantum/split_common/transport.c
+++ b/quantum/split_common/transport.c
@@ -17,6 +17,7 @@
17#include <string.h> 17#include <string.h>
18#include <debug.h> 18#include <debug.h>
19 19
20#include "compiler_support.h"
20#include "transactions.h" 21#include "transactions.h"
21#include "transport.h" 22#include "transport.h"
22#include "transaction_id_define.h" 23#include "transaction_id_define.h"
@@ -36,7 +37,7 @@
36# include "i2c_slave.h" 37# include "i2c_slave.h"
37 38
38// Ensure the I2C buffer has enough space 39// Ensure the I2C buffer has enough space
39_Static_assert(sizeof(split_shared_memory_t) <= I2C_SLAVE_REG_COUNT, "split_shared_memory_t too large for I2C_SLAVE_REG_COUNT"); 40STATIC_ASSERT(sizeof(split_shared_memory_t) <= I2C_SLAVE_REG_COUNT, "split_shared_memory_t too large for I2C_SLAVE_REG_COUNT");
40 41
41split_shared_memory_t *const split_shmem = (split_shared_memory_t *)i2c_slave_reg; 42split_shared_memory_t *const split_shmem = (split_shared_memory_t *)i2c_slave_reg;
42 43
diff --git a/quantum/unicode/unicode.h b/quantum/unicode/unicode.h
index f19d803335..7cddc78b7a 100644
--- a/quantum/unicode/unicode.h
+++ b/quantum/unicode/unicode.h
@@ -17,6 +17,8 @@
17#pragma once 17#pragma once
18 18
19#include <stdint.h> 19#include <stdint.h>
20
21#include "compiler_support.h"
20#include "unicode_keycodes.h" 22#include "unicode_keycodes.h"
21 23
22/** 24/**
@@ -33,7 +35,7 @@ typedef union unicode_config_t {
33 }; 35 };
34} unicode_config_t; 36} unicode_config_t;
35 37
36_Static_assert(sizeof(unicode_config_t) == sizeof(uint8_t), "Unicode EECONFIG out of spec."); 38STATIC_ASSERT(sizeof(unicode_config_t) == sizeof(uint8_t), "Unicode EECONFIG out of spec.");
37 39
38extern unicode_config_t unicode_config; 40extern unicode_config_t unicode_config;
39 41
diff --git a/quantum/wear_leveling/wear_leveling_internal.h b/quantum/wear_leveling/wear_leveling_internal.h
index e83f9b22ea..c590f42235 100644
--- a/quantum/wear_leveling/wear_leveling_internal.h
+++ b/quantum/wear_leveling/wear_leveling_internal.h
@@ -2,9 +2,7 @@
2// SPDX-License-Identifier: GPL-2.0-or-later 2// SPDX-License-Identifier: GPL-2.0-or-later
3#pragma once 3#pragma once
4 4
5#ifdef __cplusplus 5#include "compiler_support.h"
6# define _Static_assert static_assert
7#endif
8 6
9#include <stdint.h> 7#include <stdint.h>
10#include <string.h> 8#include <string.h>
@@ -62,9 +60,9 @@ typedef uint64_t backing_store_int_t;
62#endif // WEAR_LEVELING_ASSERTS 60#endif // WEAR_LEVELING_ASSERTS
63 61
64// Compile-time validation of configurable options 62// Compile-time validation of configurable options
65_Static_assert(WEAR_LEVELING_BACKING_SIZE >= (WEAR_LEVELING_LOGICAL_SIZE * 2), "Total backing size must be at least twice the size of the logical size"); 63STATIC_ASSERT(WEAR_LEVELING_BACKING_SIZE >= (WEAR_LEVELING_LOGICAL_SIZE * 2), "Total backing size must be at least twice the size of the logical size");
66_Static_assert(WEAR_LEVELING_LOGICAL_SIZE % BACKING_STORE_WRITE_SIZE == 0, "Logical size must be a multiple of write size"); 64STATIC_ASSERT(WEAR_LEVELING_LOGICAL_SIZE % BACKING_STORE_WRITE_SIZE == 0, "Logical size must be a multiple of write size");
67_Static_assert(WEAR_LEVELING_BACKING_SIZE % WEAR_LEVELING_LOGICAL_SIZE == 0, "Backing size must be a multiple of logical size"); 65STATIC_ASSERT(WEAR_LEVELING_BACKING_SIZE % WEAR_LEVELING_LOGICAL_SIZE == 0, "Backing size must be a multiple of logical size");
68 66
69// Backing Store API, to be implemented elsewhere by flash driver etc. 67// Backing Store API, to be implemented elsewhere by flash driver etc.
70bool backing_store_init(void); 68bool backing_store_init(void);
@@ -86,7 +84,7 @@ typedef union write_log_entry_t {
86 uint8_t raw8[8]; 84 uint8_t raw8[8];
87} write_log_entry_t; 85} write_log_entry_t;
88 86
89_Static_assert(sizeof(write_log_entry_t) == 8, "Wear leveling write log entry size was not 8"); 87STATIC_ASSERT(sizeof(write_log_entry_t) == 8, "Wear leveling write log entry size was not 8");
90 88
91/** 89/**
92 * Log entry type discriminator. 90 * Log entry type discriminator.
@@ -104,7 +102,7 @@ enum {
104 LOG_ENTRY_TYPES 102 LOG_ENTRY_TYPES
105}; 103};
106 104
107_Static_assert(LOG_ENTRY_TYPES <= (1 << 2), "Too many log entry types to fit into 2 bits of storage"); 105STATIC_ASSERT(LOG_ENTRY_TYPES <= (1 << 2), "Too many log entry types to fit into 2 bits of storage");
108 106
109#define BITMASK_FOR_BITCOUNT(n) ((1 << (n)) - 1) 107#define BITMASK_FOR_BITCOUNT(n) ((1 << (n)) - 1)
110 108
diff --git a/tmk_core/protocol/vusb/vusb.c b/tmk_core/protocol/vusb/vusb.c
index 43cce6eb2f..1f0f82664b 100644
--- a/tmk_core/protocol/vusb/vusb.c
+++ b/tmk_core/protocol/vusb/vusb.c
@@ -21,6 +21,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
21 21
22#include <usbdrv/usbdrv.h> 22#include <usbdrv/usbdrv.h>
23 23
24#include "compiler_support.h"
24#include "usbconfig.h" 25#include "usbconfig.h"
25#include "host.h" 26#include "host.h"
26#include "report.h" 27#include "report.h"
@@ -80,7 +81,7 @@ enum usb_interfaces {
80 81
81#define MAX_INTERFACES 3 82#define MAX_INTERFACES 3
82 83
83_Static_assert(TOTAL_INTERFACES <= MAX_INTERFACES, "There are not enough available interfaces to support all functions. Please disable one or more of the following: Mouse Keys, Extra Keys, Raw HID, Console."); 84STATIC_ASSERT(TOTAL_INTERFACES <= MAX_INTERFACES, "There are not enough available interfaces to support all functions. Please disable one or more of the following: Mouse Keys, Extra Keys, Raw HID, Console.");
84 85
85#if (defined(MOUSE_ENABLE) || defined(EXTRAKEY_ENABLE)) && CONSOLE_ENABLE 86#if (defined(MOUSE_ENABLE) || defined(EXTRAKEY_ENABLE)) && CONSOLE_ENABLE
86# error Mouse/Extra Keys share an endpoint with Console. Please disable one of the two. 87# error Mouse/Extra Keys share an endpoint with Console. Please disable one of the two.