diff --git a/src/main/build/build_config.h b/src/main/build/build_config.h index 58cbc1464..c5bd1f874 100644 --- a/src/main/build/build_config.h +++ b/src/main/build/build_config.h @@ -20,8 +20,6 @@ #pragma once -#define BUILD_BUG_ON(condition) ((void)sizeof(char[1 - 2*!!(condition)])) - #ifdef UNIT_TEST // make these visible to unit test #define STATIC_UNIT_TESTED diff --git a/src/main/common/utils.h b/src/main/common/utils.h index 95f0a3350..7e3d6f81f 100644 --- a/src/main/common/utils.h +++ b/src/main/common/utils.h @@ -59,7 +59,9 @@ #endif #define STATIC_ASSERT(condition, name) \ - typedef char assert_failed_ ## name [(condition) ? 1 : -1 ] __attribute__((unused)) + enum { assert_failed_ ## name = sizeof(char [(condition) ? 1 : -1 ]) } +// If it is decided to ditch the -Wpedantic build flag, this should be switched to: +// _Static_assert((condition), #name) #define BIT(x) (1 << (x)) diff --git a/src/main/config/config_eeprom.c b/src/main/config/config_eeprom.c index 2b8c57173..7c51f2fbc 100644 --- a/src/main/config/config_eeprom.c +++ b/src/main/config/config_eeprom.c @@ -86,12 +86,12 @@ typedef struct { void initEEPROM(void) { // Verify that this architecture packs as expected. - BUILD_BUG_ON(offsetof(packingTest_t, byte) != 0); - BUILD_BUG_ON(offsetof(packingTest_t, word) != 1); - BUILD_BUG_ON(sizeof(packingTest_t) != 5); + STATIC_ASSERT(offsetof(packingTest_t, byte) == 0, byte_packing_test_failed); + STATIC_ASSERT(offsetof(packingTest_t, word) == 1, word_packing_test_failed); + STATIC_ASSERT(sizeof(packingTest_t) == 5, overall_packing_test_failed); - BUILD_BUG_ON(sizeof(configFooter_t) != 2); - BUILD_BUG_ON(sizeof(configRecord_t) != 6); + STATIC_ASSERT(sizeof(configFooter_t) == 2, footer_size_failed); + STATIC_ASSERT(sizeof(configRecord_t) == 6, record_size_failed); } bool isEEPROMVersionValid(void) diff --git a/src/main/drivers/stm32f7xx_ll_ex.h b/src/main/drivers/stm32f7xx_ll_ex.h index d1e7ecd4e..12895e5cf 100644 --- a/src/main/drivers/stm32f7xx_ll_ex.h +++ b/src/main/drivers/stm32f7xx_ll_ex.h @@ -37,12 +37,12 @@ __STATIC_INLINE DMA_TypeDef *LL_EX_DMA_Stream_to_DMA(DMA_Stream_TypeDef *DMAx_St __STATIC_INLINE uint32_t LL_EX_DMA_Stream_to_Stream(DMA_Stream_TypeDef *DMAx_Streamy) { + STATIC_ASSERT(DMA1_Stream0_BASE - DMA1_BASE == sizeof(DMA_TypeDef), DMA_TypeDef_has_padding); + STATIC_ASSERT(DMA1_Stream1_BASE - DMA1_Stream0_BASE == sizeof(DMA_Stream_TypeDef), DMA_Stream_TypeDef_has_padding); + const size_t firstStreamOffset = sizeof(DMA_TypeDef); const size_t streamSize = sizeof(DMA_Stream_TypeDef); - STATIC_ASSERT(DMA1_Stream0_BASE - DMA1_BASE == firstStreamOffset, DMA_TypeDef_has_padding); - STATIC_ASSERT(DMA1_Stream1_BASE - DMA1_Stream0_BASE == streamSize, DMA_Stream_TypeDef_has_padding); - return (((uint32_t) DMAx_Streamy & DMA_STREAM_MASK) - firstStreamOffset) / streamSize; } diff --git a/src/main/flight/pid.c b/src/main/flight/pid.c index b5505e367..b9b4da577 100644 --- a/src/main/flight/pid.c +++ b/src/main/flight/pid.c @@ -236,7 +236,7 @@ static FAST_RAM_ZERO_INIT pt1Filter_t antiGravityThrottleLpf; void pidInitFilters(const pidProfile_t *pidProfile) { - BUILD_BUG_ON(FD_YAW != 2); // ensure yaw axis is 2 + STATIC_ASSERT(FD_YAW == 2, FD_YAW_incorrect); // ensure yaw axis is 2 if (targetPidLooptime == 0) { // no looptime set, so set all the filters to null diff --git a/src/main/interface/msp.c b/src/main/interface/msp.c index ff17c4310..a72febdd3 100644 --- a/src/main/interface/msp.c +++ b/src/main/interface/msp.c @@ -35,9 +35,10 @@ #include "common/axis.h" #include "common/bitarray.h" #include "common/color.h" +#include "common/huffman.h" #include "common/maths.h" #include "common/streambuf.h" -#include "common/huffman.h" +#include "common/utils.h" #include "config/config_eeprom.h" #include "config/feature.h" @@ -338,7 +339,7 @@ enum compressionType_e { static void serializeDataflashReadReply(sbuf_t *dst, uint32_t address, const uint16_t size, bool useLegacyFormat, bool allowCompression) { - BUILD_BUG_ON(MSP_PORT_DATAFLASH_INFO_SIZE < 16); + STATIC_ASSERT(MSP_PORT_DATAFLASH_INFO_SIZE >= 16, MSP_PORT_DATAFLASH_INFO_SIZE_invalid); uint16_t readLen = size; const int bytesRemainingInBuf = sbufBytesRemaining(dst) - MSP_PORT_DATAFLASH_INFO_SIZE; @@ -596,25 +597,27 @@ static bool mspCommonProcessOutCommand(uint8_t cmdMSP, sbuf_t *dst, mspPostProce } case MSP_VOLTAGE_METER_CONFIG: - // by using a sensor type and a sub-frame length it's possible to configure any type of voltage meter, - // e.g. an i2c/spi/can sensor or any sensor not built directly into the FC such as ESC/RX/SPort/SBus that has - // different configuration requirements. - BUILD_BUG_ON(VOLTAGE_SENSOR_ADC_VBAT != 0); // VOLTAGE_SENSOR_ADC_VBAT should be the first index, - sbufWriteU8(dst, MAX_VOLTAGE_SENSOR_ADC); // voltage meters in payload - for (int i = VOLTAGE_SENSOR_ADC_VBAT; i < MAX_VOLTAGE_SENSOR_ADC; i++) { - const uint8_t adcSensorSubframeLength = 1 + 1 + 1 + 1 + 1; // length of id, type, vbatscale, vbatresdivval, vbatresdivmultipler, in bytes - sbufWriteU8(dst, adcSensorSubframeLength); // ADC sensor sub-frame length + { + // by using a sensor type and a sub-frame length it's possible to configure any type of voltage meter, + // e.g. an i2c/spi/can sensor or any sensor not built directly into the FC such as ESC/RX/SPort/SBus that has + // different configuration requirements. + STATIC_ASSERT(VOLTAGE_SENSOR_ADC_VBAT == 0, VOLTAGE_SENSOR_ADC_VBAT_incorrect); // VOLTAGE_SENSOR_ADC_VBAT should be the first index + sbufWriteU8(dst, MAX_VOLTAGE_SENSOR_ADC); // voltage meters in payload + for (int i = VOLTAGE_SENSOR_ADC_VBAT; i < MAX_VOLTAGE_SENSOR_ADC; i++) { + const uint8_t adcSensorSubframeLength = 1 + 1 + 1 + 1 + 1; // length of id, type, vbatscale, vbatresdivval, vbatresdivmultipler, in bytes + sbufWriteU8(dst, adcSensorSubframeLength); // ADC sensor sub-frame length - sbufWriteU8(dst, voltageMeterADCtoIDMap[i]); // id of the sensor - sbufWriteU8(dst, VOLTAGE_SENSOR_TYPE_ADC_RESISTOR_DIVIDER); // indicate the type of sensor that the next part of the payload is for + sbufWriteU8(dst, voltageMeterADCtoIDMap[i]); // id of the sensor + sbufWriteU8(dst, VOLTAGE_SENSOR_TYPE_ADC_RESISTOR_DIVIDER); // indicate the type of sensor that the next part of the payload is for - sbufWriteU8(dst, voltageSensorADCConfig(i)->vbatscale); - sbufWriteU8(dst, voltageSensorADCConfig(i)->vbatresdivval); - sbufWriteU8(dst, voltageSensorADCConfig(i)->vbatresdivmultiplier); + sbufWriteU8(dst, voltageSensorADCConfig(i)->vbatscale); + sbufWriteU8(dst, voltageSensorADCConfig(i)->vbatresdivval); + sbufWriteU8(dst, voltageSensorADCConfig(i)->vbatresdivmultiplier); + } + // if we had any other voltage sensors, this is where we would output any needed configuration } - // if we had any other voltage sensors, this is where we would output any needed configuration - break; + break; case MSP_CURRENT_METER_CONFIG: { // the ADC and VIRTUAL sensors have the same configuration requirements, however this API reflects // that this situation may change and allows us to support configuration of any current sensor with diff --git a/src/main/interface/settings.c b/src/main/interface/settings.c index 2f1f444cb..b245f6c53 100644 --- a/src/main/interface/settings.c +++ b/src/main/interface/settings.c @@ -1124,5 +1124,5 @@ const clivalue_t valueTable[] = { const uint16_t valueTableEntryCount = ARRAYLEN(valueTable); void settingsBuildCheck() { - BUILD_BUG_ON(LOOKUP_TABLE_COUNT != ARRAYLEN(lookupTables)); + STATIC_ASSERT(LOOKUP_TABLE_COUNT == ARRAYLEN(lookupTables), LOOKUP_TABLE_COUNT_incorrect); } diff --git a/src/main/io/ledstrip.c b/src/main/io/ledstrip.c index 6b62a5c4b..d668c0440 100644 --- a/src/main/io/ledstrip.c +++ b/src/main/io/ledstrip.c @@ -165,7 +165,7 @@ void pgResetFn_ledStripConfig(ledStripConfig_t *ledStripConfig) memset(ledStripConfig->ledConfigs, 0, LED_MAX_STRIP_LENGTH * sizeof(ledConfig_t)); // copy hsv colors as default memset(ledStripConfig->colors, 0, ARRAYLEN(hsv) * sizeof(hsvColor_t)); - BUILD_BUG_ON(LED_CONFIGURABLE_COLOR_COUNT < ARRAYLEN(hsv)); + STATIC_ASSERT(LED_CONFIGURABLE_COLOR_COUNT >= ARRAYLEN(hsv), LED_CONFIGURABLE_COLOR_COUNT_invalid); for (unsigned colorIndex = 0; colorIndex < ARRAYLEN(hsv); colorIndex++) { ledStripConfig->colors[colorIndex] = hsv[colorIndex]; } diff --git a/src/main/io/osd.c b/src/main/io/osd.c index 623fcbd44..37863b1fe 100644 --- a/src/main/io/osd.c +++ b/src/main/io/osd.c @@ -1095,7 +1095,7 @@ void osdInit(displayPort_t *osdDisplayPortToUse) return; } - BUILD_BUG_ON(OSD_POS_MAX != OSD_POS(31,31)); + STATIC_ASSERT(OSD_POS_MAX == OSD_POS(31,31), OSD_POS_MAX_incorrect); osdDisplayPort = osdDisplayPortToUse; #ifdef USE_CMS diff --git a/src/main/rx/rx_spi.c b/src/main/rx/rx_spi.c index c8cb39d40..db1b27db5 100644 --- a/src/main/rx/rx_spi.c +++ b/src/main/rx/rx_spi.c @@ -63,7 +63,7 @@ static protocolSetRcDataFromPayloadFnPtr protocolSetRcDataFromPayload; STATIC_UNIT_TESTED uint16_t rxSpiReadRawRC(const rxRuntimeConfig_t *rxRuntimeConfig, uint8_t channel) { - BUILD_BUG_ON(NRF24L01_MAX_PAYLOAD_SIZE > RX_SPI_MAX_PAYLOAD_SIZE); + STATIC_ASSERT(NRF24L01_MAX_PAYLOAD_SIZE <= RX_SPI_MAX_PAYLOAD_SIZE, NRF24L01_MAX_PAYLOAD_SIZE_larger_than_RX_SPI_MAX_PAYLOAD_SIZE); if (channel >= rxRuntimeConfig->channelCount) { return 0;