-
Notifications
You must be signed in to change notification settings - Fork 8k
arch: riscv: Fix warning when C++ is enabled #88734
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -84,8 +84,17 @@ struct _thread_arch { | |
unsigned long m_mode_pmpaddr_regs[PMP_M_MODE_SLOTS]; | ||
unsigned long m_mode_pmpcfg_regs[PMP_M_MODE_SLOTS / sizeof(unsigned long)]; | ||
#endif | ||
#if defined(CONFIG_CPP) && !defined(CONFIG_FPU_SHARING) && !defined(CONFIG_USERSPACE) && \ | ||
!defined(CONFIG_PMP_STACK_GUARD) | ||
/* Empty struct has size 0 in C, size 1 in C++. Force them to be the same. */ | ||
uint8_t unused_cpp_size_compatibility; | ||
#endif | ||
Comment on lines
+87
to
+91
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I wonder if we should have something like the following defined somewhere #ifdef __cplusplus
#define CPP_DUMMY_STRUCT_MEMBER int __dummy__
#else
#define CPP_DUMMY_STRUCT_MEMBER
#endif and used in structs that can be empty struct _thread_arch {
#ifdef CONFIG_FPU_SHARING
struct z_riscv_fp_context saved_fp_context;
bool fpu_recently_used;
uint8_t exception_depth;
#endif
#ifdef CONFIG_USERSPACE
unsigned long priv_stack_start;
unsigned long u_mode_pmpaddr_regs[CONFIG_PMP_SLOTS];
unsigned long u_mode_pmpcfg_regs[CONFIG_PMP_SLOTS / sizeof(unsigned long)];
unsigned int u_mode_pmp_domain_offset;
unsigned int u_mode_pmp_end_index;
unsigned int u_mode_pmp_update_nr;
#endif
#ifdef CONFIG_PMP_STACK_GUARD
unsigned int m_mode_pmp_end_index;
unsigned long m_mode_pmpaddr_regs[PMP_M_MODE_SLOTS];
unsigned long m_mode_pmpcfg_regs[PMP_M_MODE_SLOTS / sizeof(unsigned long)];
#endif
CPP_DUMMY_STRUCT_MEMBER;
} so that the code looks cleaner, at the expense of an extra There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I like the idea of the dummy struct member, but I think you got the condition backwards? Plus, the dummy member should probably be a We could avoid the dummy member this way: #ifdef __cplusplus
#define C_DUMMY_STRUCT_MEMBER
#else
#define C_DUMMY_STRUCT_MEMBER char __dummy__
#endif
struct foobar {
#ifdef CONFIG_FOO
int foo;
#endif
#ifdef CONFIG_BAR
int bar;
#endif
#if !(CONFIG_FOO || CONFIG_BAR)
C_DUMMY_STRUCT_MEMBER;
#endif
}; There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. How about I implement something like this in a followup PR? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Not really, I think we are talking about different idea - I'm proposing an alternative where we always have a dummy variable in every struct that might be empty when #ifdef __cplusplus
#define CPP_DUMMY_STRUCT_MEMBER char __dummy__ <- make sure that a struct can never be empty when CONFIG_CPP=y
#else
#define CPP_DUMMY_STRUCT_MEMBER
#endif and whenever we have a struct that can be empty due to Kconfigs, simply append #if !(CONFIG_FOO || CONFIG_BAR)
CPP_DUMMY_STRUCT_MEMBER;
#endif |
||
}; | ||
|
||
#if defined(CONFIG_CPP) | ||
BUILD_ASSERT(sizeof(struct _thread_arch) >= 1); | ||
#endif | ||
|
||
typedef struct _thread_arch _thread_arch_t; | ||
|
||
#endif /* _ASMLANGUAGE */ | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -73,3 +73,11 @@ tests: | |
build_only: true | ||
extra_configs: | ||
- CONFIG_STD_CPP2B=y | ||
# Verify struct _cpu_arch struct _thread_arch are compatible with C++ when | ||
# specific configs are enabled. | ||
cpp.main.empty_struct_size: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The test is arch agnostic, but the configs required to trigger the empty struct are architecture dependent. We could put an There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The issue of empty struct can happen in all archs under different configurations, but keeping the test updated to track all possible scenarios seems tedious, I wonder if we should just drop the test and resort to PR review / static code analysis (can sonarqube detect possibly empty C structs?) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
I agree, but I don't think we need to track all possible scenarios. We can add cases as we find ones that people care about. I don't think the empty struct issue is going to be caught in PR review; it's too easy to miss. |
||
build_only: true | ||
extra_configs: | ||
- CONFIG_USERSPACE=n | ||
- CONFIG_SMP=n | ||
- CONFIG_FPU_SHARING=n |
Uh oh!
There was an error while loading. Please reload this page.