qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Manos Pitsidianakis <manos.pitsidianakis@linaro.org>
To: qemu-devel@nongnu.org, Paolo Bonzini <pbonzini@redhat.com>
Cc: flwu@google.com, berrange@redhat.com, peter.maydell@linaro.org,
	rkir@google.com
Subject: Re: [PATCH] include: move typeof_strip_qual to compiler.h, use it in QAPI_LIST_LENGTH()
Date: Tue, 25 Jun 2024 22:12:54 +0300	[thread overview]
Message-ID: <fnhkw.xyx5xkm2lgb@linaro.org> (raw)
In-Reply-To: <20240625111848.709176-1-pbonzini@redhat.com>

On Tue, 25 Jun 2024 14:18, Paolo Bonzini <pbonzini@redhat.com> wrote:
>The typeof_strip_qual() is most useful for the atomic fetch-and-modify
>operations in atomic.h, but it can be used elsewhere as well.  For example,
>QAPI_LIST_LENGTH() assumes that the argument is not const, which is not a
>requirement.
>
>Move the macro to compiler.h and, while at it, move it under #ifndef
>__cplusplus to emphasize that it uses C-only constructs.  A C++ version
>of typeof_strip_qual() using type traits is possible[1], but beyond the
>scope of this patch because the little C++ code that is in QEMU does not
>use QAPI.
>
>The patch was tested by changing the declaration of strv_from_str_list()
>in qapi/qapi-type-helpers.c to:
>
>    char **strv_from_str_list(const strList *const list)
>
>This is valid C code, and it fails to compile without this change.
>
>[1] https://lore.kernel.org/qemu-devel/20240624205647.112034-1-flwu@google.com/
>
>Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
>---
> include/qapi/util.h     |  2 +-
> include/qemu/atomic.h   | 42 -------------------------------------
> include/qemu/compiler.h | 46 +++++++++++++++++++++++++++++++++++++++++
> 3 files changed, 47 insertions(+), 43 deletions(-)
>
>diff --git a/include/qapi/util.h b/include/qapi/util.h
>index 20dfea8a545..b8254247b8d 100644
>--- a/include/qapi/util.h
>+++ b/include/qapi/util.h
>@@ -62,7 +62,7 @@ int parse_qapi_name(const char *name, bool complete);
> #define QAPI_LIST_LENGTH(list)                                      \
>     ({                                                              \
>         size_t _len = 0;                                            \
>-        typeof(list) _tail;                                         \
>+        typeof_strip_qual(list) _tail;                              \
>         for (_tail = list; _tail != NULL; _tail = _tail->next) {    \
>             _len++;                                                 \
>         }                                                           \
>diff --git a/include/qemu/atomic.h b/include/qemu/atomic.h
>index 99110abefb3..dc4118ddd9e 100644
>--- a/include/qemu/atomic.h
>+++ b/include/qemu/atomic.h
>@@ -20,48 +20,6 @@
> /* Compiler barrier */
> #define barrier()   ({ asm volatile("" ::: "memory"); (void)0; })
> 
>-/* The variable that receives the old value of an atomically-accessed
>- * variable must be non-qualified, because atomic builtins return values
>- * through a pointer-type argument as in __atomic_load(&var, &old, MODEL).
>- *
>- * This macro has to handle types smaller than int manually, because of
>- * implicit promotion.  int and larger types, as well as pointers, can be
>- * converted to a non-qualified type just by applying a binary operator.
>- */
>-#define typeof_strip_qual(expr)                                                    \
>-  typeof(                                                                          \
>-    __builtin_choose_expr(                                                         \
>-      __builtin_types_compatible_p(typeof(expr), bool) ||                          \
>-        __builtin_types_compatible_p(typeof(expr), const bool) ||                  \
>-        __builtin_types_compatible_p(typeof(expr), volatile bool) ||               \
>-        __builtin_types_compatible_p(typeof(expr), const volatile bool),           \
>-        (bool)1,                                                                   \
>-    __builtin_choose_expr(                                                         \
>-      __builtin_types_compatible_p(typeof(expr), signed char) ||                   \
>-        __builtin_types_compatible_p(typeof(expr), const signed char) ||           \
>-        __builtin_types_compatible_p(typeof(expr), volatile signed char) ||        \
>-        __builtin_types_compatible_p(typeof(expr), const volatile signed char),    \
>-        (signed char)1,                                                            \
>-    __builtin_choose_expr(                                                         \
>-      __builtin_types_compatible_p(typeof(expr), unsigned char) ||                 \
>-        __builtin_types_compatible_p(typeof(expr), const unsigned char) ||         \
>-        __builtin_types_compatible_p(typeof(expr), volatile unsigned char) ||      \
>-        __builtin_types_compatible_p(typeof(expr), const volatile unsigned char),  \
>-        (unsigned char)1,                                                          \
>-    __builtin_choose_expr(                                                         \
>-      __builtin_types_compatible_p(typeof(expr), signed short) ||                  \
>-        __builtin_types_compatible_p(typeof(expr), const signed short) ||          \
>-        __builtin_types_compatible_p(typeof(expr), volatile signed short) ||       \
>-        __builtin_types_compatible_p(typeof(expr), const volatile signed short),   \
>-        (signed short)1,                                                           \
>-    __builtin_choose_expr(                                                         \
>-      __builtin_types_compatible_p(typeof(expr), unsigned short) ||                \
>-        __builtin_types_compatible_p(typeof(expr), const unsigned short) ||        \
>-        __builtin_types_compatible_p(typeof(expr), volatile unsigned short) ||     \
>-        __builtin_types_compatible_p(typeof(expr), const volatile unsigned short), \
>-        (unsigned short)1,                                                         \
>-      (expr)+0))))))
>-
> #ifndef __ATOMIC_RELAXED
> #error "Expecting C11 atomic ops"
> #endif
>diff --git a/include/qemu/compiler.h b/include/qemu/compiler.h
>index c797f0d4572..554c5ce7df7 100644
>--- a/include/qemu/compiler.h
>+++ b/include/qemu/compiler.h
>@@ -227,4 +227,50 @@
> #define SECOND_ARG(first, second, ...) second
> #define IS_EMPTY_(junk_maybecomma)     SECOND_ARG(junk_maybecomma 1, 0)
> 
>+#ifndef __cplusplus
>+/*
>+ * Useful in macros that need to declare temporary variables.  For example,
>+ * the variable that receives the old value of an atomically-accessed
>+ * variable must be non-qualified, because atomic builtins return values
>+ * through a pointer-type argument as in __atomic_load(&var, &old, MODEL).
>+ *
>+ * This macro has to handle types smaller than int manually, because of
>+ * implicit promotion.  int and larger types, as well as pointers, can be
>+ * converted to a non-qualified type just by applying a binary operator.
>+ */
>+#define typeof_strip_qual(expr)                                                    \
>+  typeof(                                                                          \
>+    __builtin_choose_expr(                                                         \
>+      __builtin_types_compatible_p(typeof(expr), bool) ||                          \
>+        __builtin_types_compatible_p(typeof(expr), const bool) ||                  \
>+        __builtin_types_compatible_p(typeof(expr), volatile bool) ||               \
>+        __builtin_types_compatible_p(typeof(expr), const volatile bool),           \
>+        (bool)1,                                                                   \
>+    __builtin_choose_expr(                                                         \
>+      __builtin_types_compatible_p(typeof(expr), signed char) ||                   \
>+        __builtin_types_compatible_p(typeof(expr), const signed char) ||           \
>+        __builtin_types_compatible_p(typeof(expr), volatile signed char) ||        \
>+        __builtin_types_compatible_p(typeof(expr), const volatile signed char),    \
>+        (signed char)1,                                                            \
>+    __builtin_choose_expr(                                                         \
>+      __builtin_types_compatible_p(typeof(expr), unsigned char) ||                 \
>+        __builtin_types_compatible_p(typeof(expr), const unsigned char) ||         \
>+        __builtin_types_compatible_p(typeof(expr), volatile unsigned char) ||      \
>+        __builtin_types_compatible_p(typeof(expr), const volatile unsigned char),  \
>+        (unsigned char)1,                                                          \
>+    __builtin_choose_expr(                                                         \
>+      __builtin_types_compatible_p(typeof(expr), signed short) ||                  \
>+        __builtin_types_compatible_p(typeof(expr), const signed short) ||          \
>+        __builtin_types_compatible_p(typeof(expr), volatile signed short) ||       \
>+        __builtin_types_compatible_p(typeof(expr), const volatile signed short),   \
>+        (signed short)1,                                                           \
>+    __builtin_choose_expr(                                                         \
>+      __builtin_types_compatible_p(typeof(expr), unsigned short) ||                \
>+        __builtin_types_compatible_p(typeof(expr), const unsigned short) ||        \
>+        __builtin_types_compatible_p(typeof(expr), volatile unsigned short) ||     \
>+        __builtin_types_compatible_p(typeof(expr), const volatile unsigned short), \
>+        (unsigned short)1,                                                         \
>+      (expr)+0))))))
>+#endif

Should we add an #else to provide a fallback for cplusplus until the 
alternative is merged?

-#endif
+#else /* __cpluplus */
+#define typeof_strip_qual typeof
+#endif /* __cplusplus */

>+
> #endif /* COMPILER_H */
>-- 
>2.45.2
>
>



With that comment addressed,

Tested-by: Manos Pitsidianakis <manos.pitsidianakis@linaro.org>
Reviewed-by: Manos Pitsidianakis <manos.pitsidianakis@linaro.org>


  parent reply	other threads:[~2024-06-25 21:29 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-06-25 11:18 [PATCH] include: move typeof_strip_qual to compiler.h, use it in QAPI_LIST_LENGTH() Paolo Bonzini
2024-06-25 18:31 ` Richard Henderson
2024-06-25 19:12 ` Manos Pitsidianakis [this message]
2024-06-26 21:30   ` Roman Kiryanov
2024-06-26 21:32   ` Paolo Bonzini
2024-06-27  8:34     ` Manos Pitsidianakis
2024-06-27  8:48       ` Paolo Bonzini
2024-06-27  8:53         ` Manos Pitsidianakis

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=fnhkw.xyx5xkm2lgb@linaro.org \
    --to=manos.pitsidianakis@linaro.org \
    --cc=berrange@redhat.com \
    --cc=flwu@google.com \
    --cc=pbonzini@redhat.com \
    --cc=peter.maydell@linaro.org \
    --cc=qemu-devel@nongnu.org \
    --cc=rkir@google.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).