qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Marcel Apfelbaum <marcel.apfelbaum@gmail.com>
To: Markus Armbruster <armbru@redhat.com>,
	Paolo Bonzini <pbonzini@redhat.com>
Cc: qemu-trivial@nongnu.org, peter.maydell@linaro.org, qemu-devel@nongnu.org
Subject: Re: [Qemu-devel] [Qemu-trivial] [PATCH v2] add macro file for coccinelle
Date: Tue, 8 Sep 2015 16:31:44 +0300	[thread overview]
Message-ID: <55EEE340.10607@gmail.com> (raw)
In-Reply-To: <87h9n5p3ou.fsf@blackfin.pond.sub.org>

On 09/08/2015 02:10 PM, Markus Armbruster wrote:
> Paolo Bonzini <pbonzini@redhat.com> writes:
>
>> Coccinelle chokes on some idioms from compiler.h and queue.h.
>> Extract those in a macro file, to be used with "--macro-file
>> scripts/cocci-macro-file.h".
>>
>> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
>
> I tested this as follows.  Coccinelle can report on its parsing
> difficulties:
>
> $ spatch --parse-c `git-ls-files | grep '\.c$'
>
> Requires a generous ulimit -s, and produces tons of output.  The
> interesting part here is the summary at the end:
>
>      NB total files = 1923; perfect = 1377; pbs = 545; timeout = 0; =========> 71%
>      nb good = 964472,  nb passed = 14824 =========> 1.48% passed
>      nb good = 964472,  nb bad = 23759 =========> 97.63% good or passed
>
>
> Repeat with --macro-file scripts/cocci-macro-file.h.
>
>      NB total files = 1923; perfect = 1463; pbs = 459; timeout = 0; =========> 76%
>      nb good = 910559,  nb passed = 15352 =========> 1.53% passed
>      nb good = 910559,  nb bad = 77610 =========> 92.27% good or passed
>
> The first line shows clear improvement: 86 more files are now deemed
> "perfect".  I'm not sure how to read the remaining two lines.
>
> Also interesting are the "maybe 10 most problematic tokens".  Before:
>
>      -----------------------------------------------------------------------
>      maybe 10 most problematic tokens
>      -----------------------------------------------------------------------
>      glue: present in 620 parsing errors
>      example:
>
>             #define OP_32_64(x)                             \
>                     glue(glue(case INDEX_op_, x), _i32):    \
>                     glue(glue(case INDEX_op_, x), _i64)
>      NULL: present in 507 parsing errors
>      example:
>                 vs->dev = (QVirtioDevice *)dev;
>                 g_assert(dev != NULL);
>                 g_assert_cmphex(vs->dev->device_type, ==, QVIRTIO_SCSI_DEVICE_ID);
>
>      VMStateField: present in 502 parsing errors
>      example:
>                 .version_id = 1,
>                 .minimum_version_id = 1,
>                 .fields = (VMStateField[]) {
>                     VMSTATE_VBUFFER_UINT32(data, Fifo8, 1, NULL, 0, capacity),

Hi Markus,

I talked to coccinelle maintainer some time ago about
the above C construct (fields = (VMStateField[]) {)
and sadly is not yet supported by the C parser.

If we want this we need to do it by ourselves :(

Thanks,
Marcel


>      fields: present in 502 parsing errors
>      example:
>                 .version_id = 1,
>                 .minimum_version_id = 1,
>                 .fields = (VMStateField[]) {
>                     VMSTATE_VBUFFER_UINT32(data, Fifo8, 1, NULL, 0, capacity),
>      minimum_version_id: present in 433 parsing errors
>      example:
>                 .version_id = 1,
>                 .minimum_version_id = 1,
>                 .fields = (VMStateField[]) {
>                     VMSTATE_VBUFFER_UINT32(data, Fifo8, 1, NULL, 0, capacity),
>      uint32_t: present in 414 parsing errors
>      example:
>                                         uint32_t *bg, uint32_t *fg,                 \
>                                         VncPalette **palette) {                     \
>                     uint##bpp##_t *data;                                            \
>                     uint##bpp##_t c0, c1, ci;                                       \
>      env: present in 400 parsing errors
>      example:
>                 int v = float32_compare_quiet(a, b, &env->fp_status);
>                 set_br(env, v != float_relation_greater, br);
>             }
>      version_id: present in 308 parsing errors
>      example:
>                 .version_id = 1,
>                 .minimum_version_id = 1,
>                 .fields = (VMStateField[]) {
>                     VMSTATE_VBUFFER_UINT32(data, Fifo8, 1, NULL, 0, capacity),
>      x: present in 221 parsing errors
>      example:
>                 Int128 a = expand(x);
>                 Int128 r = int128_rshift(a, n);
>                 g_assert_cmpuint(r.lo, ==, l);
>                 g_assert_cmpuint(r.hi, ==, h);
>      a: present in 197 parsing errors
>      example:
>                 vmstate_load_state(loading, &vmstate_skipping, &obj, 2);
>                 g_assert(!qemu_file_get_error(loading));
>                 g_assert_cmpint(obj.a, ==, 10);
>                 g_assert_cmpint(obj.b, ==, 20);
>
> After:
>
>      -----------------------------------------------------------------------
>      maybe 10 most problematic tokens
>      -----------------------------------------------------------------------
>      NULL: present in 506 parsing errors
>      example:
>                 vs->dev = (QVirtioDevice *)dev;
>                 g_assert(dev != NULL);
>                 g_assert_cmphex(vs->dev->device_type, ==, QVIRTIO_SCSI_DEVICE_ID);
>
>      VMStateField: present in 502 parsing errors
>      example:
>                 .version_id = 1,
>                 .minimum_version_id = 1,
>                 .fields = (VMStateField[]) {
>                     VMSTATE_VBUFFER_UINT32(data, Fifo8, 1, NULL, 0, capacity),
>      fields: present in 502 parsing errors
>      example:
>                 .version_id = 1,
>                 .minimum_version_id = 1,
>                 .fields = (VMStateField[]) {
>                     VMSTATE_VBUFFER_UINT32(data, Fifo8, 1, NULL, 0, capacity),
>      minimum_version_id: present in 433 parsing errors
>      example:
>                 .version_id = 1,
>                 .minimum_version_id = 1,
>                 .fields = (VMStateField[]) {
>                     VMSTATE_VBUFFER_UINT32(data, Fifo8, 1, NULL, 0, capacity),
>      env: present in 376 parsing errors
>      example:
>                 int v = float32_compare_quiet(a, b, &env->fp_status);
>                 set_br(env, v != float_relation_greater, br);
>             }
>      version_id: present in 308 parsing errors
>      example:
>                 .version_id = 1,
>                 .minimum_version_id = 1,
>                 .fields = (VMStateField[]) {
>                     VMSTATE_VBUFFER_UINT32(data, Fifo8, 1, NULL, 0, capacity),
>      x: present in 221 parsing errors
>      example:
>                 Int128 a = expand(x);
>                 Int128 r = int128_rshift(a, n);
>                 g_assert_cmpuint(r.lo, ==, l);
>                 g_assert_cmpuint(r.hi, ==, h);
>      a: present in 197 parsing errors
>      example:
>                 vmstate_load_state(loading, &vmstate_skipping, &obj, 2);
>                 g_assert(!qemu_file_get_error(loading));
>                 g_assert_cmpint(obj.a, ==, 10);
>                 g_assert_cmpint(obj.b, ==, 20);
>      b: present in 164 parsing errors
>      example:
>                     uint64_t rl, rh;
>                     muls64(&rl, &rh, test_s_data[i].a, test_s_data[i].b);
>                     g_assert_cmpuint(rl, ==, test_s_data[i].rl);
>                     g_assert_cmpint(rh, ==, test_s_data[i].rh);
>      name: present in 150 parsing errors
>      example:
>                 g_assert(list != NULL);
>                 g_assert(QTAILQ_EMPTY(&list->head));
>                 g_assert_cmpstr(list->name, ==, "opts_list_01");
>
>      -----------------------------------------------------------------------
>
> Clearly visible is the effect of your cocci-macro-file.h's glue() .
>
>> ---
>>   scripts/cocci-macro-file.h | 119 +++++++++++++++++++++++++++++++++++++++++++++
>>   1 file changed, 119 insertions(+)
>>   create mode 100644 scripts/cocci-macro-file.h
>>
>> diff --git a/scripts/cocci-macro-file.h b/scripts/cocci-macro-file.h
>> new file mode 100644
>> index 0000000..eceb4be
>> --- /dev/null
>> +++ b/scripts/cocci-macro-file.h
>> @@ -0,0 +1,119 @@
>> +/* Macro file for Coccinelle
>> + *
>> + * Copyright (C) 2015 Red Hat, Inc.
>> + *
>> + * Authors:
>> + *  Paolo Bonzini <pbonzini@redhat.com>
>> + *
>> + * This work is licensed under the terms of the GNU GPL, version 2 or, at your
>> + * option, any later version.  See the COPYING file in the top-level directory.
>> + */
>> +
>> +/* Coccinelle only does limited parsing of headers, and chokes on some idioms
>> + * defined in compiler.h and queue.h.  Macros that Coccinelle must know about
>> + * in order to parse .c files must be in a separate macro file---which is
>> + * exactly what you're staring at now.
>> + *
>> + * To use this file, add the "--macro-file scripts/cocci-macro-file.h" to the
>> + * Coccinelle command line.
>> + */
>> +
>> +/* From qemu/compiler.h */
>> +#define QEMU_GNUC_PREREQ(maj, min) 1
>> +#define QEMU_NORETURN __attribute__ ((__noreturn__))
>> +#define QEMU_WARN_UNUSED_RESULT __attribute__((warn_unused_result))
>> +#define QEMU_SENTINEL __attribute__((sentinel))
>> +#define QEMU_ARTIFICIAL __attribute__((always_inline, artificial))
>> +#define QEMU_PACKED __attribute__((gcc_struct, packed))
>> +
>> +#define cat(x,y) x ## y
>> +#define cat2(x,y) cat(x,y)
>
> Why not reuse glue()?
>
>> +#define QEMU_BUILD_BUG_ON(x) \
>> + typedef char cat2(qemu_build_bug_on__,__LINE__)[(x)?-1:1]
>> __attribute__((unused));
>> +
>> +#define GCC_FMT_ATTR(n, m) __attribute__((format(gnu_printf, n, m)))
>> +
>> +#define xglue(x, y) x ## y
>> +#define glue(x, y) xglue(x, y)
>> +#define stringify(s)	tostring(s)
>> +#define tostring(s)	#s
>> +
>> +#define typeof_field(type, field) typeof(((type *)0)->field)
>> +#define type_check(t1,t2) ((t1*)0 - (t2*)0)
>> +
> [...]
>
> Preferably with cat2() replaced by glue():
> Reviewed-by: Markus Armbruster <armbru@redhat.com>
>

  parent reply	other threads:[~2015-09-08 13:31 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-09-07 10:21 [Qemu-devel] [PATCH v2] add macro file for coccinelle Paolo Bonzini
2015-09-08 11:10 ` Markus Armbruster
2015-09-08 12:44   ` Paolo Bonzini
2015-09-08 13:08     ` Markus Armbruster
2015-09-08 13:31   ` Marcel Apfelbaum [this message]
2015-09-08 17:30 ` John Snow
2015-09-08 18:35   ` Markus Armbruster
2015-09-09  9:51     ` Paolo Bonzini
2015-09-10 21:23       ` John Snow
2015-09-15 17:55 ` Michael Tokarev

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=55EEE340.10607@gmail.com \
    --to=marcel.apfelbaum@gmail.com \
    --cc=armbru@redhat.com \
    --cc=marcel@redhat.com \
    --cc=pbonzini@redhat.com \
    --cc=peter.maydell@linaro.org \
    --cc=qemu-devel@nongnu.org \
    --cc=qemu-trivial@nongnu.org \
    /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).