Skip to content

Commit fbabe70

Browse files
nordic-krchgalak
authored andcommitted
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 <[email protected]>
1 parent 56d4470 commit fbabe70

File tree

2 files changed

+84
-20
lines changed

2 files changed

+84
-20
lines changed

include/sys/cbprintf_cxx.h

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,10 @@ static inline int z_cbprintf_cxx_is_pchar(const volatile wchar_t *)
5252
template < typename T >
5353
static inline int z_cbprintf_cxx_is_pchar(T arg)
5454
{
55+
_Pragma("GCC diagnostic push")
56+
_Pragma("GCC diagnostic ignored \"-Wpointer-arith\"")
5557
return 0;
58+
_Pragma("GCC diagnostic pop")
5659
}
5760

5861
/* C++ version for calculating argument size. */
@@ -61,6 +64,11 @@ static inline size_t z_cbprintf_cxx_arg_size(float f)
6164
return sizeof(double);
6265
}
6366

67+
static inline size_t z_cbprintf_cxx_arg_size(void *p)
68+
{
69+
return sizeof(void *);
70+
}
71+
6472
template < typename T >
6573
static inline size_t z_cbprintf_cxx_arg_size(T arg)
6674
{
@@ -75,6 +83,46 @@ static inline void z_cbprintf_cxx_store_arg(uint8_t *dst, float arg)
7583
z_cbprintf_wcpy((int *)dst, (int *)&d, sizeof(d) / sizeof(int));
7684
}
7785

86+
static inline void z_cbprintf_cxx_store_arg(uint8_t *dst, void *p)
87+
{
88+
z_cbprintf_wcpy((int *)dst, (int *)&p, sizeof(p) / sizeof(int));
89+
}
90+
91+
static inline void z_cbprintf_cxx_store_arg(uint8_t *dst, char arg)
92+
{
93+
int tmp = arg + 0;
94+
95+
z_cbprintf_wcpy((int *)dst, &tmp, 1);
96+
}
97+
98+
static inline void z_cbprintf_cxx_store_arg(uint8_t *dst, unsigned char arg)
99+
{
100+
int tmp = arg + 0;
101+
102+
z_cbprintf_wcpy((int *)dst, &tmp, 1);
103+
}
104+
105+
static inline void z_cbprintf_cxx_store_arg(uint8_t *dst, signed char arg)
106+
{
107+
int tmp = arg + 0;
108+
109+
z_cbprintf_wcpy((int *)dst, &tmp, 1);
110+
}
111+
112+
static inline void z_cbprintf_cxx_store_arg(uint8_t *dst, short arg)
113+
{
114+
int tmp = arg + 0;
115+
116+
z_cbprintf_wcpy((int *)dst, &tmp, 1);
117+
}
118+
119+
static inline void z_cbprintf_cxx_store_arg(uint8_t *dst, unsigned short arg)
120+
{
121+
int tmp = arg + 0;
122+
123+
z_cbprintf_wcpy((int *)dst, &tmp, 1);
124+
}
125+
78126
template < typename T >
79127
static inline void z_cbprintf_cxx_store_arg(uint8_t *dst, T arg)
80128
{

include/sys/cbprintf_internal.h

Lines changed: 36 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -84,17 +84,18 @@ extern "C" {
8484
#ifdef __cplusplus
8585
#define Z_CBPRINTF_IS_PCHAR(x) z_cbprintf_cxx_is_pchar(x)
8686
#else
87-
#define Z_CBPRINTF_IS_PCHAR(x) _Generic((x), \
88-
char * : 1, \
89-
const char * : 1, \
90-
volatile char * : 1, \
91-
const volatile char * : 1, \
92-
wchar_t * : 1, \
93-
const wchar_t * : 1, \
94-
volatile wchar_t * : 1, \
95-
const volatile wchar_t * : 1, \
96-
default : \
97-
0)
87+
#define Z_CBPRINTF_IS_PCHAR(x) \
88+
_Generic((x) + 0, \
89+
char * : 1, \
90+
const char * : 1, \
91+
volatile char * : 1, \
92+
const volatile char * : 1, \
93+
wchar_t * : 1, \
94+
const wchar_t * : 1, \
95+
volatile wchar_t * : 1, \
96+
const volatile wchar_t * : 1, \
97+
default : \
98+
0)
9899
#endif
99100

100101
/** @brief Calculate number of char * or wchar_t * arguments in the arguments.
@@ -120,10 +121,15 @@ extern "C" {
120121
* @retval 0 if string can be statically packaged.
121122
*/
122123
#if Z_C_GENERIC
123-
#define Z_CBPRINTF_MUST_RUNTIME_PACKAGE(skip, ...) \
124-
COND_CODE_0(NUM_VA_ARGS_LESS_1(__VA_ARGS__), \
124+
#define Z_CBPRINTF_MUST_RUNTIME_PACKAGE(skip, ...) ({\
125+
_Pragma("GCC diagnostic push") \
126+
_Pragma("GCC diagnostic ignored \"-Wpointer-arith\"") \
127+
int _rv = COND_CODE_0(NUM_VA_ARGS_LESS_1(__VA_ARGS__), \
125128
(0), \
126-
(((Z_CBPRINTF_HAS_PCHAR_ARGS(__VA_ARGS__) - skip) > 0)))
129+
(((Z_CBPRINTF_HAS_PCHAR_ARGS(__VA_ARGS__) - skip) > 0))); \
130+
_Pragma("GCC diagnostic pop")\
131+
_rv; \
132+
})
127133
#else
128134
#define Z_CBPRINTF_MUST_RUNTIME_PACKAGE(skip, ...) 1
129135
#endif
@@ -140,13 +146,15 @@ extern "C" {
140146
#ifdef __cplusplus
141147
#define Z_CBPRINTF_ARG_SIZE(v) z_cbprintf_cxx_arg_size(v)
142148
#else
143-
#define Z_CBPRINTF_ARG_SIZE(v) \
144-
_Generic((v), \
149+
#define Z_CBPRINTF_ARG_SIZE(v) ({\
150+
__auto_type _v = (v) + 0; \
151+
size_t _arg_size = _Generic((v), \
145152
float : sizeof(double), \
146153
default : \
147-
/* coverity[bad_sizeof] */ \
148-
sizeof((v) + 0) \
149-
)
154+
sizeof((_v)) \
155+
); \
156+
_arg_size; \
157+
})
150158
#endif
151159

152160
/** @brief Promote and store argument in the buffer.
@@ -212,14 +220,22 @@ extern "C" {
212220
__alignof__((_arg) + 0)), VA_STACK_MIN_ALIGN)
213221
#endif
214222

215-
/** @brief Detect long double variable.
223+
/** @brief Detect long double variable as a constant expression.
224+
*
225+
* Macro is used in static assertion. On some platforms C++ static inline
226+
* template function is not a constant expression and cannot be used. In that
227+
* case long double usage will not be detected.
216228
*
217229
* @param x Argument.
218230
*
219231
* @return 1 if @p x is a long double, 0 otherwise.
220232
*/
221233
#ifdef __cplusplus
234+
#if defined(__x86_64__) || defined(__riscv) || defined(__aarch64__)
235+
#define Z_CBPRINTF_IS_LONGDOUBLE(x) 0
236+
#else
222237
#define Z_CBPRINTF_IS_LONGDOUBLE(x) z_cbprintf_cxx_is_longdouble(x)
238+
#endif
223239
#else
224240
#define Z_CBPRINTF_IS_LONGDOUBLE(x) \
225241
_Generic((x) + 0, long double : 1, default : 0)

0 commit comments

Comments
 (0)