Skip to content
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

util: add type checking to CONTAINER_OF #61962

Merged
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 27 additions & 2 deletions include/zephyr/sys/util.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#define ZEPHYR_INCLUDE_SYS_UTIL_H_

#include <zephyr/sys/util_macro.h>
#include <zephyr/toolchain/common.h>
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This addition just revealed a funny ZRESTRICT conflict between include/zephyr/toolchain/common.h and include/zephyr/toolchain/gcc.h when compiling C++

As a datapoint/evidence, replacing this line with #include <zephyr/toolchain/gcc.h> avoids the warning.

https://github.com/thesofproject/sof/actions/runs/6127039819/job/16632163797?pr=8175

/zep_workspace/sof/src/audio/module_adapter/iadk/module_initial_settings_concrete.cpp
In file included from /zep_workspace/zephyr/include/zephyr/toolchain.h:50,
                 from /zep_workspace/zephyr/include/zephyr/sys/time_units.h:10,
                 from /zep_workspace/zephyr/include/zephyr/sys/util.h:640,
                 from /zep_workspace/sof/src/include/sof/audio/module_adapter/iadk/adsp_stddef.h:15,
                 from /zep_workspace/sof/src/audio/module_adapter/iadk/module_initial_settings_concrete.cpp:7:
/zep_workspace/zephyr/include/zephyr/toolchain/gcc.h:87: error: "ZRESTRICT" redefined [-Werror]
   87 | #define ZRESTRICT __restrict
      | 
In file included from /zep_workspace/zephyr/include/zephyr/sys/util.h:18:
/zep_workspace/zephyr/include/zephyr/toolchain/common.h:33: note: this is the location of the previous definition
   33 | #define ZRESTRICT
      | 
cc1plus: all warnings being treated as errors


/* needs to be outside _ASMLANGUAGE so 'true' and 'false' can turn
* into '1' and '0' for asm or linker scripts
Expand Down Expand Up @@ -201,6 +202,27 @@ extern "C" {
(POINTER_TO_UINT(ptr) - POINTER_TO_UINT(array)) / sizeof((array)[0]); \
})

/**
* @brief Validate if two entities have a compatible type
*
* @param a the first entity to be compared
* @param a the second entity to be compared
* @return 1 if the two elements are compatible, 0 if they are not
*/
#define SAME_TYPE(a, b) __builtin_types_compatible_p(__typeof__(a), __typeof__(b))

/**
* @brief Validate CONTAINER_OF parameters, only applies to C mode.
*/
#ifndef __cplusplus
#define CONTAINER_OF_VALIDATE(ptr, type, field) \
BUILD_ASSERT(SAME_TYPE(*(ptr), ((type *)0)->field) || \
SAME_TYPE(*(ptr), void), \
"pointer type mismatch in CONTAINER_OF");
#else
#define CONTAINER_OF_VALIDATE(ptr, type, field)
#endif

/**
* @brief Get a pointer to a structure containing the element
*
Expand All @@ -222,8 +244,11 @@ extern "C" {
* @param field the name of the field within the struct @p ptr points to
* @return a pointer to the structure that contains @p ptr
*/
#define CONTAINER_OF(ptr, type, field) \
((type *)(((char *)(ptr)) - offsetof(type, field)))
#define CONTAINER_OF(ptr, type, field) \
({ \
CONTAINER_OF_VALIDATE(ptr, type, field) \
((type *)(((char *)(ptr)) - offsetof(type, field))); \
})

/**
* @brief Value of @p x rounded up to the next multiple of @p align.
Expand Down
Loading