qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Eric Blake <eblake@redhat.com>
To: qemu-devel@nongnu.org
Cc: kwolf@redhat.com, berto@igalia.com, armbru@redhat.com
Subject: [Qemu-devel] [PATCH v6 38/36] qapi: Check for member name conflicts with a base class
Date: Fri, 10 Apr 2015 14:28:21 -0600	[thread overview]
Message-ID: <1428697701-31743-2-git-send-email-eblake@redhat.com> (raw)
In-Reply-To: <1428206887-7921-1-git-send-email-eblake@redhat.com>

Our type inheritance for both 'struct' and for flat 'union' merges
key/value pairs from the base class with those from the type in
question.  Although the C code currently boxes things so that there
is a distinction between which member is referred to, the QMP wire
format does not allow passing a key more than once in a single
object.  Besides, if we ever change the generated C code to not be
quite so boxy, we'd want to avoid duplicate member names there,
too.

Fix a testsuite entry added in an earlier patch, as well as adding
a couple more tests to ensure we have appropriate coverage.

Signed-off-by: Eric Blake <eblake@redhat.com>
---

v6: new patch

---
 scripts/qapi.py                                | 21 ++++++++++++++++++++-
 tests/Makefile                                 |  3 ++-
 tests/qapi-schema/flat-union-branch-clash.err  |  1 +
 tests/qapi-schema/flat-union-branch-clash.exit |  2 +-
 tests/qapi-schema/flat-union-branch-clash.json |  2 +-
 tests/qapi-schema/flat-union-branch-clash.out  |  9 ---------
 tests/qapi-schema/struct-base-clash-deep.err   |  1 +
 tests/qapi-schema/struct-base-clash-deep.exit  |  1 +
 tests/qapi-schema/struct-base-clash-deep.json  |  9 +++++++++
 tests/qapi-schema/struct-base-clash-deep.out   |  0
 tests/qapi-schema/struct-base-clash.err        |  1 +
 tests/qapi-schema/struct-base-clash.exit       |  1 +
 tests/qapi-schema/struct-base-clash.json       |  6 ++++++
 tests/qapi-schema/struct-base-clash.out        |  0
 14 files changed, 44 insertions(+), 13 deletions(-)
 create mode 100644 tests/qapi-schema/struct-base-clash-deep.err
 create mode 100644 tests/qapi-schema/struct-base-clash-deep.exit
 create mode 100644 tests/qapi-schema/struct-base-clash-deep.json
 create mode 100644 tests/qapi-schema/struct-base-clash-deep.out
 create mode 100644 tests/qapi-schema/struct-base-clash.err
 create mode 100644 tests/qapi-schema/struct-base-clash.exit
 create mode 100644 tests/qapi-schema/struct-base-clash.json
 create mode 100644 tests/qapi-schema/struct-base-clash.out

diff --git a/scripts/qapi.py b/scripts/qapi.py
index 853f9a3..281e762 100644
--- a/scripts/qapi.py
+++ b/scripts/qapi.py
@@ -429,6 +429,18 @@ def check_type(expr_info, source, value, allow_array = False,
                    allow_metas=['built-in', 'union', 'alternate', 'struct',
                                 'enum'])

+def check_member_clash(expr_info, base_name, data, source = ""):
+    base = find_struct(base_name)
+    assert base
+    base_members = base['data']
+    for key in data.keys():
+        if key in base_members:
+            raise QAPIExprError(expr_info,
+                                "Member name '%s'%s clashes with base '%s'"
+                                %(key, source, base_name))
+    if base.get('base'):
+        check_member_clash(expr_info, base['base'], data, source)
+
 def check_command(expr, expr_info):
     name = expr['command']
     allow_star = expr.has_key('gen')
@@ -518,9 +530,14 @@ def check_union(expr, expr_info):
         check_name(expr_info, "Member of union '%s'" % name, key)

         # Each value must name a known type; futhermore, in flat unions,
-        # branches must be a struct
+        # branches must be a struct with no overlapping member names
         check_type(expr_info, "Member '%s' of union '%s'" % (key, name),
                    value, allow_array=True, allow_metas=allow_metas)
+        if base:
+            branch_struct = find_struct(value)
+            assert branch_struct
+            check_member_clash(expr_info, expr['base'], branch_struct['data'],
+                               " of branch '%s'" %key)

         # If the discriminator names an enum type, then all members
         # of 'data' must also be members of the enum type.
@@ -597,6 +614,8 @@ def check_struct(expr, expr_info):
                allow_dict=True, allow_optional=True)
     check_type(expr_info, "'base' for type '%s'" % name, expr.get('base'),
                allow_metas=['struct'])
+    if expr.get('base'):
+        check_member_clash(expr_info, expr['base'], expr['data'])

 def check_exprs(schema):
     for expr_elem in schema.exprs:
diff --git a/tests/Makefile b/tests/Makefile
index 0cd114f..eb5655e 100644
--- a/tests/Makefile
+++ b/tests/Makefile
@@ -242,7 +242,8 @@ check-qapi-schema-y := $(addprefix tests/qapi-schema/, \
 	include-simple.json include-relpath.json include-format-err.json \
 	include-non-file.json include-no-file.json include-before-err.json \
 	include-nested-err.json include-self-cycle.json include-cycle.json \
-	include-repetition.json event-nest-struct.json event-case.json)
+	include-repetition.json event-nest-struct.json event-case.json \
+	struct-base-clash.json struct-base-clash-deep.json )

 GENERATED_HEADERS += tests/test-qapi-types.h tests/test-qapi-visit.h \
 		     tests/test-qmp-commands.h tests/test-qapi-event.h
diff --git a/tests/qapi-schema/flat-union-branch-clash.err b/tests/qapi-schema/flat-union-branch-clash.err
index e69de29..f112766 100644
--- a/tests/qapi-schema/flat-union-branch-clash.err
+++ b/tests/qapi-schema/flat-union-branch-clash.err
@@ -0,0 +1 @@
+tests/qapi-schema/flat-union-branch-clash.json:10: Member name 'name' of branch 'value1' clashes with base 'Base'
diff --git a/tests/qapi-schema/flat-union-branch-clash.exit b/tests/qapi-schema/flat-union-branch-clash.exit
index 573541a..d00491f 100644
--- a/tests/qapi-schema/flat-union-branch-clash.exit
+++ b/tests/qapi-schema/flat-union-branch-clash.exit
@@ -1 +1 @@
-0
+1
diff --git a/tests/qapi-schema/flat-union-branch-clash.json b/tests/qapi-schema/flat-union-branch-clash.json
index 8b0b807..b3c6ffe 100644
--- a/tests/qapi-schema/flat-union-branch-clash.json
+++ b/tests/qapi-schema/flat-union-branch-clash.json
@@ -1,4 +1,4 @@
-# FIXME: we should check for no duplicate keys between branches and base
+# we check for no duplicate keys between branches and base
 { 'enum': 'TestEnum',
   'data': [ 'value1', 'value2' ] }
 { 'struct': 'Base',
diff --git a/tests/qapi-schema/flat-union-branch-clash.out b/tests/qapi-schema/flat-union-branch-clash.out
index 04c2395..e69de29 100644
--- a/tests/qapi-schema/flat-union-branch-clash.out
+++ b/tests/qapi-schema/flat-union-branch-clash.out
@@ -1,9 +0,0 @@
-[OrderedDict([('enum', 'TestEnum'), ('data', ['value1', 'value2'])]),
- OrderedDict([('struct', 'Base'), ('data', OrderedDict([('enum1', 'TestEnum'), ('name', 'str')]))]),
- OrderedDict([('struct', 'Branch1'), ('data', OrderedDict([('name', 'str')]))]),
- OrderedDict([('struct', 'Branch2'), ('data', OrderedDict([('value', 'int')]))]),
- OrderedDict([('union', 'TestUnion'), ('base', 'Base'), ('discriminator', 'enum1'), ('data', OrderedDict([('value1', 'Branch1'), ('value2', 'Branch2')]))])]
-[{'enum_name': 'TestEnum', 'enum_values': ['value1', 'value2']}]
-[OrderedDict([('struct', 'Base'), ('data', OrderedDict([('enum1', 'TestEnum'), ('name', 'str')]))]),
- OrderedDict([('struct', 'Branch1'), ('data', OrderedDict([('name', 'str')]))]),
- OrderedDict([('struct', 'Branch2'), ('data', OrderedDict([('value', 'int')]))])]
diff --git a/tests/qapi-schema/struct-base-clash-deep.err b/tests/qapi-schema/struct-base-clash-deep.err
new file mode 100644
index 0000000..e3e9f8d
--- /dev/null
+++ b/tests/qapi-schema/struct-base-clash-deep.err
@@ -0,0 +1 @@
+tests/qapi-schema/struct-base-clash-deep.json:7: Member name 'name' clashes with base 'Base'
diff --git a/tests/qapi-schema/struct-base-clash-deep.exit b/tests/qapi-schema/struct-base-clash-deep.exit
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/tests/qapi-schema/struct-base-clash-deep.exit
@@ -0,0 +1 @@
+1
diff --git a/tests/qapi-schema/struct-base-clash-deep.json b/tests/qapi-schema/struct-base-clash-deep.json
new file mode 100644
index 0000000..08c8c9c
--- /dev/null
+++ b/tests/qapi-schema/struct-base-clash-deep.json
@@ -0,0 +1,9 @@
+# we check for no duplicate keys with indirect base
+{ 'struct': 'Base',
+  'data': { 'name': 'str' } }
+{ 'struct': 'Mid',
+  'base': 'Base',
+  'data': { 'value': 'int' } }
+{ 'struct': 'Sub',
+  'base': 'Mid',
+  'data': { 'name': 'str' } }
diff --git a/tests/qapi-schema/struct-base-clash-deep.out b/tests/qapi-schema/struct-base-clash-deep.out
new file mode 100644
index 0000000..e69de29
diff --git a/tests/qapi-schema/struct-base-clash.err b/tests/qapi-schema/struct-base-clash.err
new file mode 100644
index 0000000..3ac37fb
--- /dev/null
+++ b/tests/qapi-schema/struct-base-clash.err
@@ -0,0 +1 @@
+tests/qapi-schema/struct-base-clash.json:4: Member name 'name' clashes with base 'Base'
diff --git a/tests/qapi-schema/struct-base-clash.exit b/tests/qapi-schema/struct-base-clash.exit
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/tests/qapi-schema/struct-base-clash.exit
@@ -0,0 +1 @@
+1
diff --git a/tests/qapi-schema/struct-base-clash.json b/tests/qapi-schema/struct-base-clash.json
new file mode 100644
index 0000000..f2afc9b
--- /dev/null
+++ b/tests/qapi-schema/struct-base-clash.json
@@ -0,0 +1,6 @@
+# we check for no duplicate keys with base
+{ 'struct': 'Base',
+  'data': { 'name': 'str' } }
+{ 'struct': 'Sub',
+  'base': 'Base',
+  'data': { 'name': 'str' } }
diff --git a/tests/qapi-schema/struct-base-clash.out b/tests/qapi-schema/struct-base-clash.out
new file mode 100644
index 0000000..e69de29
-- 
2.1.0

  parent reply	other threads:[~2015-04-10 20:28 UTC|newest]

Thread overview: 72+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-04-05  4:07 [Qemu-devel] [PATCH v6 00/36] drop qapi nested structs Eric Blake
2015-04-05  4:07 ` [Qemu-devel] [PATCH v6 01/36] qapi: Add copyright declaration on docs Eric Blake
2015-04-27 14:42   ` Markus Armbruster
2015-04-05  4:07 ` [Qemu-devel] [PATCH v6 02/36] qapi: Document type-safety considerations Eric Blake
2015-04-08 16:50   ` Eric Blake
2015-04-27 15:42   ` Markus Armbruster
2015-04-28 19:42   ` Eric Blake
2015-04-05  4:07 ` [Qemu-devel] [PATCH v6 03/36] qapi: Simplify builtin type handling Eric Blake
2015-04-05  4:07 ` [Qemu-devel] [PATCH v6 04/36] qapi: Fix generation of 'size' builtin type Eric Blake
2015-04-05  4:07 ` [Qemu-devel] [PATCH v6 05/36] qapi: Require ASCII in schema Eric Blake
2015-04-05  4:07 ` [Qemu-devel] [PATCH v6 06/36] qapi: Add some enum tests Eric Blake
2015-04-27 16:00   ` Markus Armbruster
2015-04-05  4:07 ` [Qemu-devel] [PATCH v6 07/36] qapi: Better error messages for bad enums Eric Blake
2015-04-28 23:08   ` Eric Blake
2015-04-05  4:07 ` [Qemu-devel] [PATCH v6 08/36] qapi: Add some union tests Eric Blake
2015-04-27 16:18   ` Markus Armbruster
2015-04-05  4:07 ` [Qemu-devel] [PATCH v6 09/36] qapi: Clean up test coverage of simple unions Eric Blake
2015-04-05  4:07 ` [Qemu-devel] [PATCH v6 10/36] qapi: Forbid base without discriminator in unions Eric Blake
2015-04-27 17:36   ` Markus Armbruster
2015-04-05  4:07 ` [Qemu-devel] [PATCH v6 11/36] qapi: Tighten checking of unions Eric Blake
2015-04-27 18:15   ` Markus Armbruster
2015-04-27 18:32     ` Eric Blake
2015-04-29  2:51       ` Eric Blake
2015-04-05  4:07 ` [Qemu-devel] [PATCH v6 12/36] qapi: Prepare for catching more semantic parse errors Eric Blake
2015-04-05  4:07 ` [Qemu-devel] [PATCH v6 13/36] qapi: Segregate anonymous unions into alternates in generator Eric Blake
2015-04-05  4:07 ` [Qemu-devel] [PATCH v6 14/36] qapi: Rename anonymous union type in test Eric Blake
2015-04-05  4:07 ` [Qemu-devel] [PATCH v6 15/36] qapi: Document new 'alternate' meta-type Eric Blake
2015-04-28  8:27   ` Markus Armbruster
2015-04-05  4:07 ` [Qemu-devel] [PATCH v6 16/36] qapi: Use 'alternate' to replace anonymous union Eric Blake
2015-04-28  8:41   ` Markus Armbruster
2015-04-28 17:29     ` Eric Blake
2015-04-05  4:07 ` [Qemu-devel] [PATCH v6 17/36] qapi: Add some expr tests Eric Blake
2015-04-28 11:01   ` Markus Armbruster
2015-04-05  4:07 ` [Qemu-devel] [PATCH v6 18/36] qapi: Better error messages for bad expressions Eric Blake
2015-04-05  4:07 ` [Qemu-devel] [PATCH v6 19/36] qapi: Add tests of redefined expressions Eric Blake
2015-04-05  4:07 ` [Qemu-devel] [PATCH v6 20/36] qapi: Better error messages for duplicated expressions Eric Blake
2015-04-05  4:07 ` [Qemu-devel] [PATCH v6 21/36] qapi: Allow true, false and null in schema json Eric Blake
2015-04-05  4:07 ` [Qemu-devel] [PATCH v6 22/36] qapi: Unify type bypass and add tests Eric Blake
2015-04-05  4:07 ` [Qemu-devel] [PATCH v6 23/36] qapi: Add some type check tests Eric Blake
2015-04-05  4:07 ` [Qemu-devel] [PATCH v6 24/36] qapi: More rigourous checking of types Eric Blake
2015-04-28 11:30   ` Markus Armbruster
2015-04-05  4:07 ` [Qemu-devel] [PATCH v6 25/36] qapi: Require valid names Eric Blake
2015-04-28 11:46   ` Markus Armbruster
2015-04-05  4:07 ` [Qemu-devel] [PATCH v6 26/36] qapi: Whitelist commands that don't return dictionary Eric Blake
2015-04-05  4:07 ` [Qemu-devel] [PATCH v6 27/36] qapi: More rigorous checking for type safety bypass Eric Blake
2015-04-27 17:02   ` Eric Blake
2015-04-05  4:07 ` [Qemu-devel] [PATCH v6 28/36] qapi: Prefer 'struct' over 'type' in generator Eric Blake
2015-04-28 12:04   ` Markus Armbruster
2015-04-05  4:08 ` [Qemu-devel] [PATCH v6 29/36] qapi: Document 'struct' metatype Eric Blake
2015-04-28 12:12   ` Markus Armbruster
2015-04-05  4:08 ` [Qemu-devel] [PATCH v6 30/36] qapi: Use 'struct' instead of 'type' in schema Eric Blake
2015-04-28 12:23   ` Markus Armbruster
2015-04-05  4:08 ` [Qemu-devel] [PATCH v6 31/36] qapi: Merge UserDefTwo and UserDefNested in tests Eric Blake
2015-04-28 12:28   ` Markus Armbruster
2015-04-05  4:08 ` [Qemu-devel] [PATCH v6 32/36] qapi: Drop tests for inline nested structs Eric Blake
2015-04-28 13:00   ` Markus Armbruster
2015-04-28 17:29     ` Eric Blake
2015-04-05  4:08 ` [Qemu-devel] [PATCH v6 33/36] qapi: Drop inline nested struct in query-version Eric Blake
2015-04-05  4:08 ` [Qemu-devel] [PATCH v6 34/36] qapi: Drop inline nested structs in query-pci Eric Blake
2015-04-05  4:08 ` [Qemu-devel] [PATCH v6 35/36] qapi: Drop support for inline nested types Eric Blake
2015-04-05  4:08 ` [Qemu-devel] [PATCH v6 36/36] qapi: Tweak doc references to QMP when QGA is also meant Eric Blake
2015-04-06 13:13 ` [Qemu-devel] [PATCH v6 00/36] drop qapi nested structs Eric Blake
2015-04-08  7:35   ` Alberto Garcia
2015-04-10 20:28 ` [Qemu-devel] [PATCH v6 37/36] qapi: Support (subset of) \u escapes in strings Eric Blake
2015-04-28 13:23   ` Markus Armbruster
2015-04-10 20:28 ` Eric Blake [this message]
2015-04-28 13:35   ` [Qemu-devel] [PATCH v6 38/36] qapi: Check for member name conflicts with a base class Markus Armbruster
2015-04-28 14:02 ` [Qemu-devel] [PATCH v6 00/36] drop qapi nested structs Markus Armbruster
2015-04-28 17:51   ` Eric Blake
2015-04-29  6:48     ` Markus Armbruster
2015-04-29 12:34       ` Eric Blake
2015-04-29 12:40         ` Luiz Capitulino

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=1428697701-31743-2-git-send-email-eblake@redhat.com \
    --to=eblake@redhat.com \
    --cc=armbru@redhat.com \
    --cc=berto@igalia.com \
    --cc=kwolf@redhat.com \
    --cc=qemu-devel@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).