diff --git a/include/zephyr/arch/riscv/structs.h b/include/zephyr/arch/riscv/structs.h index 11e4935a51283..691b67a922a0a 100644 --- a/include/zephyr/arch/riscv/structs.h +++ b/include/zephyr/arch/riscv/structs.h @@ -22,6 +22,15 @@ struct _cpu_arch { atomic_ptr_val_t fpu_owner; uint32_t fpu_state; #endif +#if defined(CONFIG_CPP) && !defined(CONFIG_USERSPACE) && \ + !(defined(CONFIG_SMP) || (CONFIG_MP_MAX_NUM_CPUS > 1)) && !defined(CONFIG_FPU_SHARING) + /* Empty struct has size 0 in C, size 1 in C++. Force them to be the same. */ + uint8_t unused_cpp_size_compatibility; +#endif }; +#if defined(CONFIG_CPP) +BUILD_ASSERT(sizeof(struct _cpu_arch) >= 1); +#endif + #endif /* ZEPHYR_INCLUDE_RISCV_STRUCTS_H_ */ diff --git a/include/zephyr/arch/riscv/thread.h b/include/zephyr/arch/riscv/thread.h index 08f14b61cebf7..54765550415d6 100644 --- a/include/zephyr/arch/riscv/thread.h +++ b/include/zephyr/arch/riscv/thread.h @@ -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 }; +#if defined(CONFIG_CPP) +BUILD_ASSERT(sizeof(struct _thread_arch) >= 1); +#endif + typedef struct _thread_arch _thread_arch_t; #endif /* _ASMLANGUAGE */ diff --git a/tests/lib/cpp/cxx/testcase.yaml b/tests/lib/cpp/cxx/testcase.yaml index a19802928c814..3617209b22b55 100644 --- a/tests/lib/cpp/cxx/testcase.yaml +++ b/tests/lib/cpp/cxx/testcase.yaml @@ -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: + build_only: true + extra_configs: + - CONFIG_USERSPACE=n + - CONFIG_SMP=n + - CONFIG_FPU_SHARING=n