Fix shadowing in recursive ASSERT macros 39/270439/3
authorMichal Bloch <m.bloch@samsung.com>
Wed, 2 Feb 2022 17:55:53 +0000 (18:55 +0100)
committerHyotaek Shim <hyotaek.shim@samsung.com>
Tue, 8 Feb 2022 04:55:37 +0000 (04:55 +0000)
Change-Id: I509e0e481ba147fa5a29a0e1e83e6458dea41d5e

tests/kdbus/kdbus-test.h

index 6d3034d..41f854e 100644 (file)
@@ -38,23 +38,33 @@ enum {
 #define PRINTF_ARG(...) (_Generic((__VA_ARGS__),\
        default: (__VA_ARGS__)))
 
-#define _ASSERT_REL_(val0, val0s, relop, val1, val1s, onfailure) do {\
-       __auto_type const _ASSERT_RETURN_VAL_val0_ = (val0);\
-       __auto_type const _ASSERT_RETURN_VAL_val1_ = (val1);\
-       if (!(_ASSERT_RETURN_VAL_val0_ relop _ASSERT_RETURN_VAL_val1_)) {                       \
+/* Uses a counter to ensure unique var names and prevent shadowing,
+ * for when the macro is used recursively (e.g. inside the `onfailure` block) */
+#define _ASSERT_REL_COUNTER_(counter, val0, val0s, relop, val1, val1s, onfailure) do {\
+       __auto_type const _ASSERT_RETURN_VAL_val0_##counter = (val0);\
+       __auto_type const _ASSERT_RETURN_VAL_val1_##counter = (val1);\
+       if (!(_ASSERT_RETURN_VAL_val0_##counter relop _ASSERT_RETURN_VAL_val1_##counter)) {\
                /* must assemble format string in runtime because _Generic does not play well with string constant concatenation */\
                char _ASSERT_REL_fmt_[sizeof("[tid %u] Assertion '(")+4+sizeof("=%s) %s (")+4+sizeof("=%s)' failed in %s(), %s:%d\n")];\
                strncpy(_ASSERT_REL_fmt_, "[tid %u] Assertion '(", 22);\
-               strncat(_ASSERT_REL_fmt_, PRINTF_FMT(_ASSERT_RETURN_VAL_val0_), 4);\
+               strncat(_ASSERT_REL_fmt_, PRINTF_FMT(_ASSERT_RETURN_VAL_val0_##counter), 4);\
                strncat(_ASSERT_REL_fmt_, "=%s) %s (", 9);\
-               strncat(_ASSERT_REL_fmt_, PRINTF_FMT(_ASSERT_RETURN_VAL_val1_), 4);\
+               strncat(_ASSERT_REL_fmt_, PRINTF_FMT(_ASSERT_RETURN_VAL_val1_##counter), 4);\
                strncat(_ASSERT_REL_fmt_, "=%s)' failed in %s(), %s:%d\n", 29);\
-               print(_ASSERT_REL_fmt_, syscall(SYS_gettid), PRINTF_ARG(_ASSERT_RETURN_VAL_val0_), val0s, #relop, PRINTF_ARG(_ASSERT_RETURN_VAL_val1_), val1s, __func__, __FILE__, __LINE__);\
+               print(_ASSERT_REL_fmt_, syscall(SYS_gettid), PRINTF_ARG(_ASSERT_RETURN_VAL_val0_##counter), val0s, #relop, PRINTF_ARG(_ASSERT_RETURN_VAL_val1_##counter), val1s, __func__, __FILE__, __LINE__);\
                onfailure;\
        }\
                else print_assert_success("Assertion '%s' SUCCEEDED in %s(), %s:%d\n", val0s " " #relop " " val1s, __func__, __FILE__, __LINE__);\
 } while (0)
 
+/* Looks like a no-op, but expands macros (so that `val##counter`
+ * in the macro above becomes `val123` instead of `val__COUNTER__`). */
+#define _ASSERT_REL_COUNTER_EXPAND_MACROS_(a,b,c,d,e,f,g) \
+       _ASSERT_REL_COUNTER_(a,b,c,d,e,f,g)
+
+#define _ASSERT_REL_(val0, val0s, relop, val1, val1s, onfailure) \
+       _ASSERT_REL_COUNTER_EXPAND_MACROS_(__COUNTER__, val0, val0s, relop, val1, val1s, onfailure)
+
 #define ASSERT_RETURN_VAL(val0, relop, val1, retval) _ASSERT_REL_(val0, #val0, relop, val1, #val1, return retval)
 #define ASSERT_EXIT_VAL(val0, relop, val1, retval)   _ASSERT_REL_(val0, #val0, relop, val1, #val1, exit(retval))