1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2024-12-29 04:50:03 +01:00

Merge pull request #17273 from maribu/core/IS_CT_CONSTANT

core: Add IS_CT_CONSTANT()
This commit is contained in:
Alexandre Abadie 2022-01-08 00:21:07 +01:00 committed by GitHub
commit 5083061995
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 45 additions and 0 deletions

View File

@ -236,6 +236,27 @@ extern "C" {
#define DECLARE_CONSTANT(identifier, const_expr) \
WITHOUT_PEDANTIC(enum { identifier = const_expr };)
#if DOXYGEN
/**
* @brief Check if given variable / expression is detected as compile time
* constant
* @note This might return 0 on compile time constant expressions if the
* compiler is not able to prove the constness at the given level
* of optimization.
* @details This will return 0 if the used compiler does not support this
* @warning This is intended for internal use only
*
* This allows providing two different implementations in C, with one being
* more efficient if constant folding is used.
*/
#define IS_CT_CONSTANT(expr) <IMPLEMENTATION>
#elif defined(__GNUC__)
/* both clang and gcc (which both define __GNUC__) support this */
#define IS_CT_CONSTANT(expr) __builtin_constant_p(expr)
#else
#define IS_CT_CONSTANT(expr) 0
#endif
/**
* @cond INTERNAL
*/

View File

@ -77,12 +77,36 @@ static void test_declare_constant(void)
static_assert(sizeof(test_array) == 3, "test_array should be 3 bytes long");
}
#ifdef BOARD_NATIVE
/* native compiles with -Og, which does not automatically inline functions.
* We just turn the function into a macro to get the test also passing on
* native */
#define magic_computation(...) (unsigned)(42U * 3.14159 / 1337U)
#else
static unsigned magic_computation(void)
{
return (unsigned)(42U * 3.14159 / 1337U);
}
#endif
static void test_is_compile_time_constant(void)
{
/* These test might fail on non-GCC-non-clang compilers. We don't support
* any of those (yet), but this test might need adaption in the future */
unsigned actual_constant = magic_computation();
volatile unsigned not_a_constant = actual_constant;
TEST_ASSERT(IS_CT_CONSTANT(actual_constant));
TEST_ASSERT(!IS_CT_CONSTANT(not_a_constant));
}
Test *tests_kernel_defines_tests(void)
{
EMB_UNIT_TESTFIXTURES(fixtures) {
new_TestFixture(test_kernel_version),
new_TestFixture(test_index_of),
new_TestFixture(test_declare_constant),
new_TestFixture(test_is_compile_time_constant),
};
EMB_UNIT_TESTCALLER(kernel_defines_tests, NULL, NULL, fixtures);