From 7b2a5c2f9a52c4a08630fa741052f03fe5d3cc8a Mon Sep 17 00:00:00 2001 From: Eric Blake Date: Tue, 29 Sep 2015 16:21:04 -0600 Subject: qapi: Avoid assertion failure on union 'type' collision 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 Message-Id: <1443565276-4535-7-git-send-email-eblake@redhat.com> [Polished a few comments] Signed-off-by: Markus Armbruster --- tests/qapi-schema/flat-union-clash-type.err | 17 +---------------- tests/qapi-schema/flat-union-clash-type.json | 8 +++----- tests/qapi-schema/union-clash-type.err | 17 +---------------- tests/qapi-schema/union-clash-type.json | 9 ++++----- 4 files changed, 9 insertions(+), 42 deletions(-) (limited to 'tests/qapi-schema') diff --git a/tests/qapi-schema/flat-union-clash-type.err b/tests/qapi-schema/flat-union-clash-type.err index 6e64d1d819..b44dd4005c 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 - 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 3db6ea07a8..8f710f08aa 100644 --- a/tests/qapi-schema/flat-union-clash-type.json +++ b/tests/qapi-schema/flat-union-clash-type.json @@ -1,9 +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 member 'type' -# inherited from 'Base' 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 6e64d1d819..a5dead128d 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 - 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:8: 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 52c21f77ea..cfc256b04d 100644 --- a/tests/qapi-schema/union-clash-type.json +++ b/tests/qapi-schema/union-clash-type.json @@ -1,10 +1,9 @@ # Union branch 'type' -# FIXME: this triggers an assertion failure. But even with that fixed, -# we would have a clash in generated C, between the simple union's -# implicit tag member '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 +# simple union's implicit tag member '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' } } -- cgit v1.2.3