selftests/rseq: Implement rseq_unqual_scalar_typeof
authorMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Tue, 27 Jun 2023 15:29:21 +0000 (11:29 -0400)
committerShuah Khan <skhan@linuxfoundation.org>
Tue, 8 Aug 2023 20:42:01 +0000 (14:42 -0600)
Allow defining variables and perform cast with a typeof which removes
the volatile and const qualifiers.

This prevents declaring a stack variable with a volatile qualifier
within a macro, which would generate sub-optimal assembler.

This is imported from the "librseq" project.

Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
Signed-off-by: Shuah Khan <skhan@linuxfoundation.org>
tools/testing/selftests/rseq/compiler.h

index f47092bddebab746057cd703b16c5e6ee0b047b0..49d62fbd6ddab2ed7d3f9c5d54f33577fb291fa6 100644 (file)
 #define RSEQ_COMBINE_TOKENS(_tokena, _tokenb)  \
        RSEQ__COMBINE_TOKENS(_tokena, _tokenb)
 
+#ifdef __cplusplus
+#define rseq_unqual_scalar_typeof(x)                                   \
+       std::remove_cv<std::remove_reference<decltype(x)>::type>::type
+#else
+#define rseq_scalar_type_to_expr(type)                                 \
+       unsigned type: (unsigned type)0,                                \
+       signed type: (signed type)0
+
+/*
+ * Use C11 _Generic to express unqualified type from expression. This removes
+ * volatile qualifier from expression type.
+ */
+#define rseq_unqual_scalar_typeof(x)                                   \
+       __typeof__(                                                     \
+               _Generic((x),                                           \
+                       char: (char)0,                                  \
+                       rseq_scalar_type_to_expr(char),                 \
+                       rseq_scalar_type_to_expr(short),                \
+                       rseq_scalar_type_to_expr(int),                  \
+                       rseq_scalar_type_to_expr(long),                 \
+                       rseq_scalar_type_to_expr(long long),            \
+                       default: (x)                                    \
+               )                                                       \
+       )
+#endif
+
 #endif  /* RSEQ_COMPILER_H_ */