On 16/11/2022 14:49, Tudor Cretu wrote:
Some of the safe functions providing wrappers for commonly used syscalls allow specifying an optional parameter (e.g. open, openat, semctl). To access an element from an empty va_list is undefined behaviour. Introduce the macro SAFE_COND_HANDLER that takes over handling the variadicness of such wrappers by selecting the right handler for whether the optional argument has been provided or not.
The intended usage is:
#define SAFE_FN(args, ...) \ SAFE_COND_HANDLER(, ##__VA_ARGS__, \ SAFE_FN_HANDLER_1, \ SAFE_FN_HANLDER_0) ( \ (args), ##__VA_ARGS__ )
This is a smart idea, just remove variadic function wrappers altogether and use some variadic macro magic instead :)
Looking through this series made me wonder if we couldn't make it a bit simpler though. For instance:
#define __SAFE_FN(arg1, arg2, arg3, ...) \ safe_fn(arg1, arg2, arg3) #define SAFE_FN(arg1, arg2, ...) \ __SAFE_FN(arg1, arg2, ##_VA_ARGS, 0)
Wouldn't that work? This way there is no need for a wrapper and a version of a macro for each number of arguments. I might be missing something though.
Sorry for chiming in so late in the review process, I didn't manage to get a look earlier :(
Kevin
Subsequent patches would adapt the relevant SAFE_* macros to avoid the undefined behaviour in the corresponding safe_* functions.
Signed-off-by: Tudor Cretu tudor.cretu@arm.com
include/tst_safe_vararg_macros.h | 38 ++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 include/tst_safe_vararg_macros.h
diff --git a/include/tst_safe_vararg_macros.h b/include/tst_safe_vararg_macros.h new file mode 100644 index 000000000..09f614f70 --- /dev/null +++ b/include/tst_safe_vararg_macros.h @@ -0,0 +1,38 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/*
- Copyright (c) 2022 Arm Ltd.
- Internal helpers for macros that handle safe variadic wrappers for
- corresponding safe functions.
- Do not use directly in test programs.
- */
+/*
- Some safe functions are wrappers for syscalls with an optional parameter
- (e.g. open, openat, semctl). To access an element from an empty va_list is
- undefined behaviour. This macro enables handling the variadicness of such
- wrappers by selecting the right handler depending on whether the variadic
- argument has been supplied or not. The intended usage is:
- #define SAFE_FN(args, ...) \
SAFE_COND_HANDLER(, ##__VA_ARGS__, \
SAFE_FN_HANDLER_1, \
SAFE_FN_HANLDER_0) ( \
(args), ##__VA_ARGS__
)
- Where SAFE_FN_HANDLER_0 is the handler used when the optional parameter is
- not specified and SAFE_FN_HANDLER_1 is the handler used otherwise.
- The way it works is that SAFE_COND_HANDLER returns the third
- parameter passed. If SAFE_FN is called with a variadic element in __VA_ARGS__,
- then SAFE_COND_HANDLER just returns SAFE_FN_HANDLER_1. If SAFE_FN
- is called with an empty __VA_ARGS__, then the comma before the ‘##’ will be
- deleted and, as a consequence, the macro arguments will get shifted, with
- SAFE_FN_HANLDER_0 becoming the actual third argument.
- Note: this macro only handles len(__VA_ARGS__) <= 1.
- */
+#define SAFE_COND_HANDLER(empty, cond_arg, SAFE_HELPER, ...) \
- SAFE_HELPER