qemu/include/qapi/qmp
Markus Armbruster bb71846325 qobject atomics osdep: Make a few macros more hygienic
Variables declared in macros can shadow other variables.  Much of the
time, this is harmless, e.g.:

    #define _FDT(exp)                                                  \
        do {                                                           \
            int ret = (exp);                                           \
            if (ret < 0) {                                             \
                error_report("error creating device tree: %s: %s",   \
                        #exp, fdt_strerror(ret));                      \
                exit(1);                                               \
            }                                                          \
        } while (0)

Harmless shadowing in h_client_architecture_support():

        target_ulong ret;

        [...]

        ret = do_client_architecture_support(cpu, spapr, vec, fdt_bufsize);
        if (ret == H_SUCCESS) {
            _FDT((fdt_pack(spapr->fdt_blob)));
            [...]
        }

        return ret;

However, we can get in trouble when the shadowed variable is used in a
macro argument:

    #define QOBJECT(obj) ({                                 \
        typeof(obj) o = (obj);                              \
        o ? container_of(&(o)->base, QObject, base) : NULL; \
     })

QOBJECT(o) expands into

    ({
--->    typeof(o) o = (o);
        o ? container_of(&(o)->base, QObject, base) : NULL;
    })

Unintended variable name capture at --->.  We'd be saved by
-Winit-self.  But I could certainly construct more elaborate death
traps that don't trigger it.

To reduce the risk of trapping ourselves, we use variable names in
macros that no sane person would use elsewhere.  Here's our actual
definition of QOBJECT():

    #define QOBJECT(obj) ({                                         \
        typeof(obj) _obj = (obj);                                   \
        _obj ? container_of(&(_obj)->base, QObject, base) : NULL;   \
    })

Works well enough until we nest macro calls.  For instance, with

    #define qobject_ref(obj) ({                     \
        typeof(obj) _obj = (obj);                   \
        qobject_ref_impl(QOBJECT(_obj));            \
        _obj;                                       \
    })

the expression qobject_ref(obj) expands into

    ({
        typeof(obj) _obj = (obj);
        qobject_ref_impl(
            ({
--->            typeof(_obj) _obj = (_obj);
                _obj ? container_of(&(_obj)->base, QObject, base) : NULL;
            }));
        _obj;
    })

Unintended variable name capture at --->.

The only reliable way to prevent unintended variable name capture is
-Wshadow.

One blocker for enabling it is shadowing hiding in function-like
macros like

     qdict_put(dict, "name", qobject_ref(...))

qdict_put() wraps its last argument in QOBJECT(), and the last
argument here contains another QOBJECT().

Use dark preprocessor sorcery to make the macros that give us this
problem use different variable names on every call.

Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Message-ID: <20230921121312.1301864-8-armbru@redhat.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
2023-09-29 08:13:57 +02:00
..
dispatch.h monitor: mark mixed functions that can suspend 2023-04-20 11:17:35 +02:00
json-parser.h json: Clean up headers 2018-08-24 20:26:37 +02:00
json-writer.h migration: Replace migration's JSON writer by the general one 2020-12-19 10:39:16 +01:00
qbool.h include/qapi: add g_autoptr support for qobject types 2022-04-06 10:50:38 +02:00
qdict.h include: move qdict_{crumple,flatten} declarations 2022-04-21 17:03:51 +04:00
qerror.h rocker: Tweak stubbed out monitor commands' error messages 2023-02-23 14:10:17 +01:00
qjson.h Replace GCC_FMT_ATTR with G_GNUC_PRINTF 2022-03-22 14:40:51 +04:00
qlist.h include/qapi: add g_autoptr support for qobject types 2022-04-06 10:50:38 +02:00
qlit.h qlit: add qobject_from_qlit() 2018-03-19 10:00:14 -05:00
qnull.h include/qapi: add g_autoptr support for qobject types 2022-04-06 10:50:38 +02:00
qnum.h include/qapi: add g_autoptr support for qobject types 2022-04-06 10:50:38 +02:00
qobject.h qobject atomics osdep: Make a few macros more hygienic 2023-09-29 08:13:57 +02:00
qstring.h include/qapi: add g_autoptr support for qobject types 2022-04-06 10:50:38 +02:00