From: Eric Blake <eblake@redhat.com>
To: qemu-devel@nongnu.org
Cc: Michael Roth <mdroth@linux.vnet.ibm.com>,
marcandre.lureau@redhat.com, armbru@redhat.com,
ehabkost@redhat.com
Subject: [Qemu-devel] [PATCH v7 06/18] qapi: Avoid assertion failure on union 'type' collision
Date: Tue, 29 Sep 2015 16:21:04 -0600 [thread overview]
Message-ID: <1443565276-4535-7-git-send-email-eblake@redhat.com> (raw)
In-Reply-To: <1443565276-4535-1-git-send-email-eblake@redhat.com>
The previous commit added two tests that triggered an assertion
failure. It's fairly straightforward to avoid the failure by
just outright forbidding the collision between a union's tag
values and its discriminator name (including the implicit name
'kind' supplied for simple unions [*]). Ultimately, we'd like
to move the collision detection into QAPISchema*.check(), but
for now it is easier just to enhance the existing checks.
[*] Of course, down the road, we have plans to rename the simple
union tag name to 'type' to match the QMP wire name, but the
idea of the collision will still be present even then.
Technically, we could avoid the collision by naming the C union
members representing each enum value as '_case_value' rather
than 'value'; but until we have an actual qapi client (and not
just our testsuite) that has a legitimate reason to match a
case label to the name of a QMP key and needs the name munging
to satisfy the compiler, it's easier to just reject the qapi
as invalid.
Signed-off-by: Eric Blake <eblake@redhat.com>
---
v7: rebase to testsuite changes in previous patch
v6: new patch
---
scripts/qapi.py | 10 ++++++++--
tests/qapi-schema/flat-union-clash-type.err | 17 +----------------
tests/qapi-schema/flat-union-clash-type.json | 7 +++----
tests/qapi-schema/union-clash-type.err | 17 +----------------
tests/qapi-schema/union-clash-type.json | 7 +++----
5 files changed, 16 insertions(+), 42 deletions(-)
diff --git a/scripts/qapi.py b/scripts/qapi.py
index 4b5d574..8d2681b 100644
--- a/scripts/qapi.py
+++ b/scripts/qapi.py
@@ -544,7 +544,7 @@ def check_union(expr, expr_info):
base = expr.get('base')
discriminator = expr.get('discriminator')
members = expr['data']
- values = {'MAX': '(automatic)'}
+ values = {'MAX': '(automatic)', 'KIND': '(automatic)'}
# Two types of unions, determined by discriminator.
@@ -603,13 +603,19 @@ def check_union(expr, expr_info):
" of branch '%s'" % key)
# If the discriminator names an enum type, then all members
- # of 'data' must also be members of the enum type.
+ # of 'data' must also be members of the enum type, which in turn
+ # must not collide with the discriminator name.
if enum_define:
if key not in enum_define['enum_values']:
raise QAPIExprError(expr_info,
"Discriminator value '%s' is not found in "
"enum '%s'" %
(key, enum_define["enum_name"]))
+ if discriminator in enum_define['enum_values']:
+ raise QAPIExprError(expr_info,
+ "Discriminator name '%s' collides with "
+ "enum value in '%s'" %
+ (discriminator, enum_define["enum_name"]))
# Otherwise, check for conflicts in the generated enum
else:
diff --git a/tests/qapi-schema/flat-union-clash-type.err b/tests/qapi-schema/flat-union-clash-type.err
index 6e64d1d..b44dd40 100644
--- a/tests/qapi-schema/flat-union-clash-type.err
+++ b/tests/qapi-schema/flat-union-clash-type.err
@@ -1,16 +1 @@
-Traceback (most recent call last):
- File "tests/qapi-schema/test-qapi.py", line 55, in <module>
- schema = QAPISchema(sys.argv[1])
- File "scripts/qapi.py", line 1116, in __init__
- self.check()
- File "scripts/qapi.py", line 1299, in check
- ent.check(self)
- File "scripts/qapi.py", line 962, in check
- self.variants.check(schema, members, seen)
- File "scripts/qapi.py", line 1024, in check
- v.check(schema, self.tag_member.type, vseen)
- File "scripts/qapi.py", line 1032, in check
- QAPISchemaObjectTypeMember.check(self, schema, [], seen)
- File "scripts/qapi.py", line 994, in check
- assert self.name not in seen
-AssertionError
+tests/qapi-schema/flat-union-clash-type.json:11: Discriminator name 'type' collides with enum value in 'TestEnum'
diff --git a/tests/qapi-schema/flat-union-clash-type.json b/tests/qapi-schema/flat-union-clash-type.json
index eac51a4..8f710f0 100644
--- a/tests/qapi-schema/flat-union-clash-type.json
+++ b/tests/qapi-schema/flat-union-clash-type.json
@@ -1,8 +1,7 @@
# Flat union branch 'type'
-# FIXME: this triggers an assertion failure. But even with that fixed, we
-# would have a clash in generated C, between the outer tag 'type' and
-# the branch name 'type' within the union. We should either reject this,
-# or munge the generated C to let it compile.
+# Reject this, because we would have a clash in generated C, between the
+# outer tag 'type' and the branch name 'type' within the union.
+# TODO: We could munge the generated C branch name to let it compile.
{ 'enum': 'TestEnum',
'data': [ 'type' ] }
{ 'struct': 'Base',
diff --git a/tests/qapi-schema/union-clash-type.err b/tests/qapi-schema/union-clash-type.err
index 6e64d1d..b1de417 100644
--- a/tests/qapi-schema/union-clash-type.err
+++ b/tests/qapi-schema/union-clash-type.err
@@ -1,16 +1 @@
-Traceback (most recent call last):
- File "tests/qapi-schema/test-qapi.py", line 55, in <module>
- schema = QAPISchema(sys.argv[1])
- File "scripts/qapi.py", line 1116, in __init__
- self.check()
- File "scripts/qapi.py", line 1299, in check
- ent.check(self)
- File "scripts/qapi.py", line 962, in check
- self.variants.check(schema, members, seen)
- File "scripts/qapi.py", line 1024, in check
- v.check(schema, self.tag_member.type, vseen)
- File "scripts/qapi.py", line 1032, in check
- QAPISchemaObjectTypeMember.check(self, schema, [], seen)
- File "scripts/qapi.py", line 994, in check
- assert self.name not in seen
-AssertionError
+tests/qapi-schema/union-clash-type.json:7: Union 'TestUnion' member 'kind' clashes with '(automatic)'
diff --git a/tests/qapi-schema/union-clash-type.json b/tests/qapi-schema/union-clash-type.json
index 38330b5..453fd6d 100644
--- a/tests/qapi-schema/union-clash-type.json
+++ b/tests/qapi-schema/union-clash-type.json
@@ -1,9 +1,8 @@
# Union branch 'type'
-# FIXME: this triggers an assertion failure. But even with that fixed, we
-# would have a clash in generated C, between the outer union tag 'kind' and
-# the branch name 'kind' within the union. We should either reject this,
-# or munge the generated C to let it compile.
+# Reject this, because we would have a clash in generated C, between the
+# outer union tag 'kind' and the branch name 'kind' within the union.
# TODO: Even when the generated C is switched to use 'type' rather than
# 'kind', to match the QMP spelling, the collision should still be detected.
+# Or, we could munge the branch name to allow compilation.
{ 'union': 'TestUnion',
'data': { 'kind': 'int', 'type': 'str' } }
--
2.4.3
next prev parent reply other threads:[~2015-09-29 22:21 UTC|newest]
Thread overview: 34+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-09-29 22:20 [Qemu-devel] [PATCH v7 00/18] post-introspection cleanups, subset A Eric Blake
2015-09-29 22:20 ` [Qemu-devel] [PATCH v7 01/18] qapi: Sort qapi-schema tests Eric Blake
2015-09-29 22:21 ` [Qemu-devel] [PATCH v7 02/18] qapi: Improve 'include' error message Eric Blake
2015-09-29 22:21 ` [Qemu-devel] [PATCH v7 03/18] qapi: Invoke exception superclass initializer Eric Blake
2015-09-29 22:21 ` [Qemu-devel] [PATCH v7 04/18] qapi: Clean up qapi.py per pep8 Eric Blake
2015-09-29 22:21 ` [Qemu-devel] [PATCH v7 05/18] qapi: Test for various name collisions Eric Blake
2015-10-01 3:30 ` Eric Blake
2015-10-01 12:57 ` Markus Armbruster
2015-10-01 11:51 ` Markus Armbruster
2015-10-01 13:10 ` Eric Blake
2015-10-01 15:34 ` Markus Armbruster
2015-10-01 15:41 ` Eric Blake
2015-10-01 17:39 ` Markus Armbruster
2015-10-01 18:51 ` Eric Blake
2015-10-01 20:27 ` Markus Armbruster
2015-09-29 22:21 ` Eric Blake [this message]
2015-10-01 12:10 ` [Qemu-devel] [PATCH v7 06/18] qapi: Avoid assertion failure on union 'type' collision Markus Armbruster
2015-09-29 22:21 ` [Qemu-devel] [PATCH v7 07/18] qapi: Add tests for empty unions Eric Blake
2015-09-29 22:21 ` [Qemu-devel] [PATCH v7 08/18] qapi: Test use of 'number' within alternates Eric Blake
2015-10-05 22:45 ` Eric Blake
2015-10-06 7:24 ` Markus Armbruster
2015-09-29 22:21 ` [Qemu-devel] [PATCH v7 09/18] qapi: Reuse code for flat union base validation Eric Blake
2015-09-29 22:21 ` [Qemu-devel] [PATCH v7 10/18] qapi: Consistent generated code: prefer error 'err' Eric Blake
2015-09-29 22:21 ` [Qemu-devel] [PATCH v7 11/18] qapi: Consistent generated code: prefer visitor 'v' Eric Blake
2015-09-29 22:21 ` [Qemu-devel] [PATCH v7 12/18] qapi: Consistent generated code: prefer common labels Eric Blake
2015-09-29 22:21 ` [Qemu-devel] [PATCH v7 13/18] qapi: Consistent generated code: prefer common indentation Eric Blake
2015-09-29 22:21 ` [Qemu-devel] [PATCH v7 14/18] qapi: Consistent generated code: minimize push_indent() usage Eric Blake
2015-09-29 22:21 ` [Qemu-devel] [PATCH v7 15/18] qapi: Share gen_err_check() Eric Blake
2015-10-01 12:40 ` Markus Armbruster
2015-10-01 13:01 ` Eric Blake
2015-09-29 22:21 ` [Qemu-devel] [PATCH v7 16/18] qapi: Share gen_visit_fields() Eric Blake
2015-09-29 22:21 ` [Qemu-devel] [RFC PATCH v7 17/18] qapi: Simplify gen_visit_fields() error handling Eric Blake
2015-10-01 12:49 ` Markus Armbruster
2015-09-29 22:21 ` [Qemu-devel] [RFC PATCH v7 18/18] qapi: Use gen_err_check() in more places Eric Blake
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=1443565276-4535-7-git-send-email-eblake@redhat.com \
--to=eblake@redhat.com \
--cc=armbru@redhat.com \
--cc=ehabkost@redhat.com \
--cc=marcandre.lureau@redhat.com \
--cc=mdroth@linux.vnet.ibm.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).