lib: os: cbprintf: Fixes for c++ and coverity
Fixes for C++ includes: - avoid calling static inline template function in static assert on certain platforms which consider it non const expression - Add 0 to variable before calling C++ argument storing function to promote a variable. Fix for coverity: - avoid using sizeof(n + 0) by using local variable (gcc extension) Signed-off-by: Krzysztof Chruscinski <krzysztof.chruscinski@nordicsemi.no>
This commit is contained in:
parent
56d44705a0
commit
fbabe70063
2 changed files with 84 additions and 20 deletions
|
@ -52,7 +52,10 @@ static inline int z_cbprintf_cxx_is_pchar(const volatile wchar_t *)
|
||||||
template < typename T >
|
template < typename T >
|
||||||
static inline int z_cbprintf_cxx_is_pchar(T arg)
|
static inline int z_cbprintf_cxx_is_pchar(T arg)
|
||||||
{
|
{
|
||||||
|
_Pragma("GCC diagnostic push")
|
||||||
|
_Pragma("GCC diagnostic ignored \"-Wpointer-arith\"")
|
||||||
return 0;
|
return 0;
|
||||||
|
_Pragma("GCC diagnostic pop")
|
||||||
}
|
}
|
||||||
|
|
||||||
/* C++ version for calculating argument size. */
|
/* C++ version for calculating argument size. */
|
||||||
|
@ -61,6 +64,11 @@ static inline size_t z_cbprintf_cxx_arg_size(float f)
|
||||||
return sizeof(double);
|
return sizeof(double);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline size_t z_cbprintf_cxx_arg_size(void *p)
|
||||||
|
{
|
||||||
|
return sizeof(void *);
|
||||||
|
}
|
||||||
|
|
||||||
template < typename T >
|
template < typename T >
|
||||||
static inline size_t z_cbprintf_cxx_arg_size(T arg)
|
static inline size_t z_cbprintf_cxx_arg_size(T arg)
|
||||||
{
|
{
|
||||||
|
@ -75,6 +83,46 @@ static inline void z_cbprintf_cxx_store_arg(uint8_t *dst, float arg)
|
||||||
z_cbprintf_wcpy((int *)dst, (int *)&d, sizeof(d) / sizeof(int));
|
z_cbprintf_wcpy((int *)dst, (int *)&d, sizeof(d) / sizeof(int));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline void z_cbprintf_cxx_store_arg(uint8_t *dst, void *p)
|
||||||
|
{
|
||||||
|
z_cbprintf_wcpy((int *)dst, (int *)&p, sizeof(p) / sizeof(int));
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void z_cbprintf_cxx_store_arg(uint8_t *dst, char arg)
|
||||||
|
{
|
||||||
|
int tmp = arg + 0;
|
||||||
|
|
||||||
|
z_cbprintf_wcpy((int *)dst, &tmp, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void z_cbprintf_cxx_store_arg(uint8_t *dst, unsigned char arg)
|
||||||
|
{
|
||||||
|
int tmp = arg + 0;
|
||||||
|
|
||||||
|
z_cbprintf_wcpy((int *)dst, &tmp, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void z_cbprintf_cxx_store_arg(uint8_t *dst, signed char arg)
|
||||||
|
{
|
||||||
|
int tmp = arg + 0;
|
||||||
|
|
||||||
|
z_cbprintf_wcpy((int *)dst, &tmp, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void z_cbprintf_cxx_store_arg(uint8_t *dst, short arg)
|
||||||
|
{
|
||||||
|
int tmp = arg + 0;
|
||||||
|
|
||||||
|
z_cbprintf_wcpy((int *)dst, &tmp, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void z_cbprintf_cxx_store_arg(uint8_t *dst, unsigned short arg)
|
||||||
|
{
|
||||||
|
int tmp = arg + 0;
|
||||||
|
|
||||||
|
z_cbprintf_wcpy((int *)dst, &tmp, 1);
|
||||||
|
}
|
||||||
|
|
||||||
template < typename T >
|
template < typename T >
|
||||||
static inline void z_cbprintf_cxx_store_arg(uint8_t *dst, T arg)
|
static inline void z_cbprintf_cxx_store_arg(uint8_t *dst, T arg)
|
||||||
{
|
{
|
||||||
|
|
|
@ -84,17 +84,18 @@ extern "C" {
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
#define Z_CBPRINTF_IS_PCHAR(x) z_cbprintf_cxx_is_pchar(x)
|
#define Z_CBPRINTF_IS_PCHAR(x) z_cbprintf_cxx_is_pchar(x)
|
||||||
#else
|
#else
|
||||||
#define Z_CBPRINTF_IS_PCHAR(x) _Generic((x), \
|
#define Z_CBPRINTF_IS_PCHAR(x) \
|
||||||
char * : 1, \
|
_Generic((x) + 0, \
|
||||||
const char * : 1, \
|
char * : 1, \
|
||||||
volatile char * : 1, \
|
const char * : 1, \
|
||||||
const volatile char * : 1, \
|
volatile char * : 1, \
|
||||||
wchar_t * : 1, \
|
const volatile char * : 1, \
|
||||||
const wchar_t * : 1, \
|
wchar_t * : 1, \
|
||||||
volatile wchar_t * : 1, \
|
const wchar_t * : 1, \
|
||||||
const volatile wchar_t * : 1, \
|
volatile wchar_t * : 1, \
|
||||||
default : \
|
const volatile wchar_t * : 1, \
|
||||||
0)
|
default : \
|
||||||
|
0)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/** @brief Calculate number of char * or wchar_t * arguments in the arguments.
|
/** @brief Calculate number of char * or wchar_t * arguments in the arguments.
|
||||||
|
@ -120,10 +121,15 @@ extern "C" {
|
||||||
* @retval 0 if string can be statically packaged.
|
* @retval 0 if string can be statically packaged.
|
||||||
*/
|
*/
|
||||||
#if Z_C_GENERIC
|
#if Z_C_GENERIC
|
||||||
#define Z_CBPRINTF_MUST_RUNTIME_PACKAGE(skip, ...) \
|
#define Z_CBPRINTF_MUST_RUNTIME_PACKAGE(skip, ...) ({\
|
||||||
COND_CODE_0(NUM_VA_ARGS_LESS_1(__VA_ARGS__), \
|
_Pragma("GCC diagnostic push") \
|
||||||
|
_Pragma("GCC diagnostic ignored \"-Wpointer-arith\"") \
|
||||||
|
int _rv = COND_CODE_0(NUM_VA_ARGS_LESS_1(__VA_ARGS__), \
|
||||||
(0), \
|
(0), \
|
||||||
(((Z_CBPRINTF_HAS_PCHAR_ARGS(__VA_ARGS__) - skip) > 0)))
|
(((Z_CBPRINTF_HAS_PCHAR_ARGS(__VA_ARGS__) - skip) > 0))); \
|
||||||
|
_Pragma("GCC diagnostic pop")\
|
||||||
|
_rv; \
|
||||||
|
})
|
||||||
#else
|
#else
|
||||||
#define Z_CBPRINTF_MUST_RUNTIME_PACKAGE(skip, ...) 1
|
#define Z_CBPRINTF_MUST_RUNTIME_PACKAGE(skip, ...) 1
|
||||||
#endif
|
#endif
|
||||||
|
@ -140,13 +146,15 @@ extern "C" {
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
#define Z_CBPRINTF_ARG_SIZE(v) z_cbprintf_cxx_arg_size(v)
|
#define Z_CBPRINTF_ARG_SIZE(v) z_cbprintf_cxx_arg_size(v)
|
||||||
#else
|
#else
|
||||||
#define Z_CBPRINTF_ARG_SIZE(v) \
|
#define Z_CBPRINTF_ARG_SIZE(v) ({\
|
||||||
_Generic((v), \
|
__auto_type _v = (v) + 0; \
|
||||||
|
size_t _arg_size = _Generic((v), \
|
||||||
float : sizeof(double), \
|
float : sizeof(double), \
|
||||||
default : \
|
default : \
|
||||||
/* coverity[bad_sizeof] */ \
|
sizeof((_v)) \
|
||||||
sizeof((v) + 0) \
|
); \
|
||||||
)
|
_arg_size; \
|
||||||
|
})
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/** @brief Promote and store argument in the buffer.
|
/** @brief Promote and store argument in the buffer.
|
||||||
|
@ -212,14 +220,22 @@ extern "C" {
|
||||||
__alignof__((_arg) + 0)), VA_STACK_MIN_ALIGN)
|
__alignof__((_arg) + 0)), VA_STACK_MIN_ALIGN)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/** @brief Detect long double variable.
|
/** @brief Detect long double variable as a constant expression.
|
||||||
|
*
|
||||||
|
* Macro is used in static assertion. On some platforms C++ static inline
|
||||||
|
* template function is not a constant expression and cannot be used. In that
|
||||||
|
* case long double usage will not be detected.
|
||||||
*
|
*
|
||||||
* @param x Argument.
|
* @param x Argument.
|
||||||
*
|
*
|
||||||
* @return 1 if @p x is a long double, 0 otherwise.
|
* @return 1 if @p x is a long double, 0 otherwise.
|
||||||
*/
|
*/
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
#if defined(__x86_64__) || defined(__riscv) || defined(__aarch64__)
|
||||||
|
#define Z_CBPRINTF_IS_LONGDOUBLE(x) 0
|
||||||
|
#else
|
||||||
#define Z_CBPRINTF_IS_LONGDOUBLE(x) z_cbprintf_cxx_is_longdouble(x)
|
#define Z_CBPRINTF_IS_LONGDOUBLE(x) z_cbprintf_cxx_is_longdouble(x)
|
||||||
|
#endif
|
||||||
#else
|
#else
|
||||||
#define Z_CBPRINTF_IS_LONGDOUBLE(x) \
|
#define Z_CBPRINTF_IS_LONGDOUBLE(x) \
|
||||||
_Generic((x) + 0, long double : 1, default : 0)
|
_Generic((x) + 0, long double : 1, default : 0)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue