Expose some weaknesses in the generator: we don't always forbid
the generation of structs that contain multiple members that map
to the same C name.  This has already been marked FIXME in
qapi.py in commit d90675f, but having more tests will make sure
future patches produce desired behavior.  This patch focuses on
C struct members, and does not consider collisions between commands
and events (affecting C function names), or even on collisions
between generated C type names with user type names (for things
like automatic FOOList struct representing array types).

There are two types of struct collisions we want to catch:
1) Collision that would require the QMP user to specify the
same key more than once inside a single JSON {} object (we
already prevent duplicate keys within a single type, so this
is triggered when merging multiple types into a single JSON
object via base classes or flat unions)
2) Collision between two members of the C struct that is
generated for a given qapi type:
  a) a collision occurs from two qapi names mapping to the
same C name
  b) the collision is with a C name used for another purpose
(we already fixed 'kind' in commit 0f61af3e, and one use of
'base' in commit 1e6c1616 for unions, but we have another
use of 'base' in structs, and still collide with 'data' in
unions, not to mention the tag 'type'/'kind' and the various
tag values).

Oddly enough, while commit 1e6c1616 fixed a type 2b collision
with 'base', it introduced a different collision that was not
previously possible: now that the base members are no longer
boxed behind 'base', they can collide with the enum tag members
(used as member names within the embedded C union).

Ultimately, if we need to have a flat union where an enum
value clashes with a base member name, we could change the
generator to use something like '_tag_value' instead of
'value' for the C name of union members; but until such a
need arises, it will probably be easier to just forbid these
collisions.

Some of these collisions are already caught in the old-style
parser checks, but ultimately we want all collisions to be
caught in the new-style QAPISchema*.check() methods.

Some of these negative tests will be deleted later, and positive
tests added to qapi-schema-test.json in their place, when the
generator code is reworked so that a particular collision no
longer causes failed code generation.

[git rename detection may be a bit confused by the actions of
this commit, since it both creates and renames files that are
equally small and similar in content]

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

---
v6: rework commit message, alter test names and comments to be
more descriptive, repurpose flat-union-cycle to better match its
name (and not duplicate what the renamed flat-union-clash-branch
tests), add new tests (union-clash-type, flat-union-clash-type)
that detect an assertion failures
---
 tests/Makefile                                           | 10 +++++++++-
 .../{flat-union-branch-clash.out => args-name-clash.err} |  0
 tests/qapi-schema/args-name-clash.exit                   |  1 +
 tests/qapi-schema/args-name-clash.json                   |  2 ++
 tests/qapi-schema/args-name-clash.out                    |  6 ++++++
 tests/qapi-schema/flat-union-branch-clash.err            |  1 -
 tests/qapi-schema/flat-union-clash-branch.err            |  0
 tests/qapi-schema/flat-union-clash-branch.exit           |  1 +
 tests/qapi-schema/flat-union-clash-branch.json           | 15 +++++++++++++++
 tests/qapi-schema/flat-union-clash-branch.out            | 14 ++++++++++++++
 tests/qapi-schema/flat-union-clash-member.err            |  1 +
 ...on-branch-clash.exit => flat-union-clash-member.exit} |  0
 ...on-branch-clash.json => flat-union-clash-member.json} |  2 +-
 tests/qapi-schema/flat-union-clash-member.out            |  0
 tests/qapi-schema/flat-union-clash-type.err              | 16 ++++++++++++++++
 tests/qapi-schema/flat-union-clash-type.exit             |  1 +
 tests/qapi-schema/flat-union-clash-type.json             | 11 +++++++++++
 tests/qapi-schema/flat-union-clash-type.out              |  0
 tests/qapi-schema/flat-union-cycle.err                   |  1 +
 tests/qapi-schema/flat-union-cycle.exit                  |  1 +
 tests/qapi-schema/flat-union-cycle.json                  |  7 +++++++
 tests/qapi-schema/flat-union-cycle.out                   |  0
 tests/qapi-schema/qapi-schema-test.json                  |  7 +++++--
 tests/qapi-schema/qapi-schema-test.out                   |  2 ++
 tests/qapi-schema/struct-base-clash-base.err             |  0
 tests/qapi-schema/struct-base-clash-base.exit            |  1 +
 tests/qapi-schema/struct-base-clash-base.json            |  6 ++++++
 tests/qapi-schema/struct-base-clash-base.out             |  5 +++++
 tests/qapi-schema/union-clash-data.err                   |  0
 tests/qapi-schema/union-clash-data.exit                  |  1 +
 tests/qapi-schema/union-clash-data.json                  |  4 ++++
 tests/qapi-schema/union-clash-data.out                   |  6 ++++++
 tests/qapi-schema/union-clash-members.err                |  1 +
 tests/qapi-schema/union-clash-members.exit               |  1 +
 tests/qapi-schema/union-clash-members.json               |  3 +++
 tests/qapi-schema/union-clash-members.out                |  0
 tests/qapi-schema/union-clash-type.err                   | 16 ++++++++++++++++
 tests/qapi-schema/union-clash-type.exit                  |  1 +
 tests/qapi-schema/union-clash-type.json                  |  3 +++
 tests/qapi-schema/union-clash-type.out                   |  0
 40 files changed, 142 insertions(+), 5 deletions(-)
 rename tests/qapi-schema/{flat-union-branch-clash.out => args-name-clash.err} 
(100%)
 create mode 100644 tests/qapi-schema/args-name-clash.exit
 create mode 100644 tests/qapi-schema/args-name-clash.json
 create mode 100644 tests/qapi-schema/args-name-clash.out
 delete mode 100644 tests/qapi-schema/flat-union-branch-clash.err
 create mode 100644 tests/qapi-schema/flat-union-clash-branch.err
 create mode 100644 tests/qapi-schema/flat-union-clash-branch.exit
 create mode 100644 tests/qapi-schema/flat-union-clash-branch.json
 create mode 100644 tests/qapi-schema/flat-union-clash-branch.out
 create mode 100644 tests/qapi-schema/flat-union-clash-member.err
 rename tests/qapi-schema/{flat-union-branch-clash.exit => 
flat-union-clash-member.exit} (100%)
 rename tests/qapi-schema/{flat-union-branch-clash.json => 
flat-union-clash-member.json} (85%)
 create mode 100644 tests/qapi-schema/flat-union-clash-member.out
 create mode 100644 tests/qapi-schema/flat-union-clash-type.err
 create mode 100644 tests/qapi-schema/flat-union-clash-type.exit
 create mode 100644 tests/qapi-schema/flat-union-clash-type.json
 create mode 100644 tests/qapi-schema/flat-union-clash-type.out
 create mode 100644 tests/qapi-schema/flat-union-cycle.err
 create mode 100644 tests/qapi-schema/flat-union-cycle.exit
 create mode 100644 tests/qapi-schema/flat-union-cycle.json
 create mode 100644 tests/qapi-schema/flat-union-cycle.out
 create mode 100644 tests/qapi-schema/struct-base-clash-base.err
 create mode 100644 tests/qapi-schema/struct-base-clash-base.exit
 create mode 100644 tests/qapi-schema/struct-base-clash-base.json
 create mode 100644 tests/qapi-schema/struct-base-clash-base.out
 create mode 100644 tests/qapi-schema/union-clash-data.err
 create mode 100644 tests/qapi-schema/union-clash-data.exit
 create mode 100644 tests/qapi-schema/union-clash-data.json
 create mode 100644 tests/qapi-schema/union-clash-data.out
 create mode 100644 tests/qapi-schema/union-clash-members.err
 create mode 100644 tests/qapi-schema/union-clash-members.exit
 create mode 100644 tests/qapi-schema/union-clash-members.json
 create mode 100644 tests/qapi-schema/union-clash-members.out
 create mode 100644 tests/qapi-schema/union-clash-type.err
 create mode 100644 tests/qapi-schema/union-clash-type.exit
 create mode 100644 tests/qapi-schema/union-clash-type.json
 create mode 100644 tests/qapi-schema/union-clash-type.out

diff --git a/tests/Makefile b/tests/Makefile
index 6fd5885..d43b8e9 100644
--- a/tests/Makefile
+++ b/tests/Makefile
@@ -238,6 +238,7 @@ qapi-schema += args-invalid.json
 qapi-schema += args-member-array-bad.json
 qapi-schema += args-member-array.json
 qapi-schema += args-member-unknown.json
+qapi-schema += args-name-clash.json
 qapi-schema += args-union.json
 qapi-schema += args-unknown.json
 qapi-schema += bad-base.json
@@ -273,7 +274,10 @@ qapi-schema += flat-union-bad-base.json
 qapi-schema += flat-union-bad-discriminator.json
 qapi-schema += flat-union-base-any.json
 qapi-schema += flat-union-base-union.json
-qapi-schema += flat-union-branch-clash.json
+qapi-schema += flat-union-clash-branch.json
+qapi-schema += flat-union-clash-member.json
+qapi-schema += flat-union-clash-type.json
+qapi-schema += flat-union-cycle.json
 qapi-schema += flat-union-inline.json
 qapi-schema += flat-union-int-branch.json
 qapi-schema += flat-union-invalid-branch-key.json
@@ -315,6 +319,7 @@ qapi-schema += returns-dict.json
 qapi-schema += returns-int.json
 qapi-schema += returns-unknown.json
 qapi-schema += returns-whitelist.json
+qapi-schema += struct-base-clash-base.json
 qapi-schema += struct-base-clash-deep.json
 qapi-schema += struct-base-clash.json
 qapi-schema += struct-data-invalid.json
@@ -328,6 +333,9 @@ qapi-schema += unclosed-string.json
 qapi-schema += unicode-str.json
 qapi-schema += union-bad-branch.json
 qapi-schema += union-base-no-discriminator.json
+qapi-schema += union-clash-data.json
+qapi-schema += union-clash-members.json
+qapi-schema += union-clash-type.json
 qapi-schema += union-invalid-base.json
 qapi-schema += union-max.json
 qapi-schema += union-optional-branch.json
diff --git a/tests/qapi-schema/flat-union-branch-clash.out 
b/tests/qapi-schema/args-name-clash.err
similarity index 100%
rename from tests/qapi-schema/flat-union-branch-clash.out
rename to tests/qapi-schema/args-name-clash.err
diff --git a/tests/qapi-schema/args-name-clash.exit 
b/tests/qapi-schema/args-name-clash.exit
new file mode 100644
index 0000000..573541a
--- /dev/null
+++ b/tests/qapi-schema/args-name-clash.exit
@@ -0,0 +1 @@
+0
diff --git a/tests/qapi-schema/args-name-clash.json 
b/tests/qapi-schema/args-name-clash.json
new file mode 100644
index 0000000..19bf792
--- /dev/null
+++ b/tests/qapi-schema/args-name-clash.json
@@ -0,0 +1,2 @@
+# FIXME - we should reject data with members that clash when mapped to C names
+{ 'command': 'oops', 'data': { 'a-b': 'str', 'a_b': 'str' } }
diff --git a/tests/qapi-schema/args-name-clash.out 
b/tests/qapi-schema/args-name-clash.out
new file mode 100644
index 0000000..9b2f6e4
--- /dev/null
+++ b/tests/qapi-schema/args-name-clash.out
@@ -0,0 +1,6 @@
+object :empty
+object :obj-oops-arg
+    member a-b: str optional=False
+    member a_b: str optional=False
+command oops :obj-oops-arg -> None
+   gen=True success_response=True
diff --git a/tests/qapi-schema/flat-union-branch-clash.err 
b/tests/qapi-schema/flat-union-branch-clash.err
deleted file mode 100644
index f112766..0000000
--- a/tests/qapi-schema/flat-union-branch-clash.err
+++ /dev/null
@@ -1 +0,0 @@
-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-clash-branch.err 
b/tests/qapi-schema/flat-union-clash-branch.err
new file mode 100644
index 0000000..e69de29
diff --git a/tests/qapi-schema/flat-union-clash-branch.exit 
b/tests/qapi-schema/flat-union-clash-branch.exit
new file mode 100644
index 0000000..573541a
--- /dev/null
+++ b/tests/qapi-schema/flat-union-clash-branch.exit
@@ -0,0 +1 @@
+0
diff --git a/tests/qapi-schema/flat-union-clash-branch.json 
b/tests/qapi-schema/flat-union-clash-branch.json
new file mode 100644
index 0000000..cda3af5
--- /dev/null
+++ b/tests/qapi-schema/flat-union-clash-branch.json
@@ -0,0 +1,15 @@
+# FIXME: this parses, but then fails to compile due to a duplicate 'c_d'
+# we should either detect the collision or allow this to compile
+{ 'enum': 'TestEnum',
+  'data': [ 'base', 'c-d' ] }
+{ 'struct': 'Base',
+  'data': { 'enum1': 'TestEnum', '*c_d': 'str' } }
+{ 'struct': 'Branch1',
+  'data': { 'string': 'str' } }
+{ 'struct': 'Branch2',
+  'data': { 'value': 'int' } }
+{ 'union': 'TestUnion',
+  'base': 'Base',
+  'discriminator': 'enum1',
+  'data': { 'base': 'Branch1',
+            'c-d': 'Branch2' } }
diff --git a/tests/qapi-schema/flat-union-clash-branch.out 
b/tests/qapi-schema/flat-union-clash-branch.out
new file mode 100644
index 0000000..8e0da73
--- /dev/null
+++ b/tests/qapi-schema/flat-union-clash-branch.out
@@ -0,0 +1,14 @@
+object :empty
+object Base
+    member enum1: TestEnum optional=False
+    member c_d: str optional=True
+object Branch1
+    member string: str optional=False
+object Branch2
+    member value: int optional=False
+enum TestEnum ['base', 'c-d']
+object TestUnion
+    base Base
+    tag enum1
+    case base: Branch1
+    case c-d: Branch2
diff --git a/tests/qapi-schema/flat-union-clash-member.err 
b/tests/qapi-schema/flat-union-clash-member.err
new file mode 100644
index 0000000..152d402
--- /dev/null
+++ b/tests/qapi-schema/flat-union-clash-member.err
@@ -0,0 +1 @@
+tests/qapi-schema/flat-union-clash-member.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-clash-member.exit
similarity index 100%
rename from tests/qapi-schema/flat-union-branch-clash.exit
rename to tests/qapi-schema/flat-union-clash-member.exit
diff --git a/tests/qapi-schema/flat-union-branch-clash.json 
b/tests/qapi-schema/flat-union-clash-member.json
similarity index 85%
rename from tests/qapi-schema/flat-union-branch-clash.json
rename to tests/qapi-schema/flat-union-clash-member.json
index 8fb054f..3d7e6c6 100644
--- a/tests/qapi-schema/flat-union-branch-clash.json
+++ b/tests/qapi-schema/flat-union-clash-member.json
@@ -1,4 +1,4 @@
-# we check for no duplicate keys between branches and base
+# we check for no duplicate keys between branch members and base
 { 'enum': 'TestEnum',
   'data': [ 'value1', 'value2' ] }
 { 'struct': 'Base',
diff --git a/tests/qapi-schema/flat-union-clash-member.out 
b/tests/qapi-schema/flat-union-clash-member.out
new file mode 100644
index 0000000..e69de29
diff --git a/tests/qapi-schema/flat-union-clash-type.err 
b/tests/qapi-schema/flat-union-clash-type.err
new file mode 100644
index 0000000..6e64d1d
--- /dev/null
+++ b/tests/qapi-schema/flat-union-clash-type.err
@@ -0,0 +1,16 @@
+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
diff --git a/tests/qapi-schema/flat-union-clash-type.exit 
b/tests/qapi-schema/flat-union-clash-type.exit
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/tests/qapi-schema/flat-union-clash-type.exit
@@ -0,0 +1 @@
+1
diff --git a/tests/qapi-schema/flat-union-clash-type.json 
b/tests/qapi-schema/flat-union-clash-type.json
new file mode 100644
index 0000000..87e5fd8
--- /dev/null
+++ b/tests/qapi-schema/flat-union-clash-type.json
@@ -0,0 +1,11 @@
+# FIXME: detect this collision, rather than triggering an assertion failure
+{ 'enum': 'TestEnum',
+  'data': [ 'type' ] }
+{ 'struct': 'Base',
+  'data': { 'type': 'TestEnum' } }
+{ 'struct': 'Branch1',
+  'data': { 'string': 'str' } }
+{ 'union': 'TestUnion',
+  'base': 'Base',
+  'discriminator': 'type',
+  'data': { 'type': 'Branch1' } }
diff --git a/tests/qapi-schema/flat-union-clash-type.out 
b/tests/qapi-schema/flat-union-clash-type.out
new file mode 100644
index 0000000..e69de29
diff --git a/tests/qapi-schema/flat-union-cycle.err 
b/tests/qapi-schema/flat-union-cycle.err
new file mode 100644
index 0000000..d4f2a09
--- /dev/null
+++ b/tests/qapi-schema/flat-union-cycle.err
@@ -0,0 +1 @@
+tests/qapi-schema/flat-union-cycle.json:6: Base 'Union' is not a valid struct
diff --git a/tests/qapi-schema/flat-union-cycle.exit 
b/tests/qapi-schema/flat-union-cycle.exit
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/tests/qapi-schema/flat-union-cycle.exit
@@ -0,0 +1 @@
+1
diff --git a/tests/qapi-schema/flat-union-cycle.json 
b/tests/qapi-schema/flat-union-cycle.json
new file mode 100644
index 0000000..7414277
--- /dev/null
+++ b/tests/qapi-schema/flat-union-cycle.json
@@ -0,0 +1,7 @@
+# ensure that we have a sane error message for attempts at self-inheritance
+# (this test currently fails because we don't permit a union base, but
+# even if we relax things to allow that in the future, this should still fail)
+{ 'enum': 'Enum', 'data': [ 'okay' ] }
+{ 'struct': 'Okay', 'data': { 'int': 'int' } }
+{ 'union': 'Union', 'base': 'Union', 'discriminator': 'switch',
+  'data': { 'okay': 'Okay' } }
diff --git a/tests/qapi-schema/flat-union-cycle.out 
b/tests/qapi-schema/flat-union-cycle.out
new file mode 100644
index 0000000..e69de29
diff --git a/tests/qapi-schema/qapi-schema-test.json 
b/tests/qapi-schema/qapi-schema-test.json
index 6897a6e..c511338 100644
--- a/tests/qapi-schema/qapi-schema-test.json
+++ b/tests/qapi-schema/qapi-schema-test.json
@@ -32,11 +32,14 @@
             'dict1': 'UserDefTwoDict' } }

 # for testing unions
+# Among other things, test that a name collision between branches does
+# not cause any problems (since only one branch can be in use at a time),
+# by intentionally using two branches that both have a C member 'a_b'
 { 'struct': 'UserDefA',
-  'data': { 'boolean': 'bool' } }
+  'data': { 'boolean': 'bool', '*a_b': 'int' } }

 { 'struct': 'UserDefB',
-  'data': { 'intb': 'int' } }
+  'data': { 'intb': 'int', '*a-b': 'bool' } }

 { 'union': 'UserDefFlatUnion',
   'base': 'UserDefUnionBase',   # intentional forward reference
diff --git a/tests/qapi-schema/qapi-schema-test.out 
b/tests/qapi-schema/qapi-schema-test.out
index 1f6e858..28a0b3c 100644
--- a/tests/qapi-schema/qapi-schema-test.out
+++ b/tests/qapi-schema/qapi-schema-test.out
@@ -71,6 +71,7 @@ enum QEnumTwo ['value1', 'value2']
     prefix QENUM_TWO
 object UserDefA
     member boolean: bool optional=False
+    member a_b: int optional=True
 alternate UserDefAlternate
     case uda: UserDefA
     case s: str
@@ -78,6 +79,7 @@ alternate UserDefAlternate
 enum UserDefAlternateKind ['uda', 's', 'i']
 object UserDefB
     member intb: int optional=False
+    member a-b: bool optional=True
 object UserDefC
     member string1: str optional=False
     member string2: str optional=False
diff --git a/tests/qapi-schema/struct-base-clash-base.err 
b/tests/qapi-schema/struct-base-clash-base.err
new file mode 100644
index 0000000..e69de29
diff --git a/tests/qapi-schema/struct-base-clash-base.exit 
b/tests/qapi-schema/struct-base-clash-base.exit
new file mode 100644
index 0000000..573541a
--- /dev/null
+++ b/tests/qapi-schema/struct-base-clash-base.exit
@@ -0,0 +1 @@
+0
diff --git a/tests/qapi-schema/struct-base-clash-base.json 
b/tests/qapi-schema/struct-base-clash-base.json
new file mode 100644
index 0000000..fb25128
--- /dev/null
+++ b/tests/qapi-schema/struct-base-clash-base.json
@@ -0,0 +1,6 @@
+# FIXME: this parses, but then fails to compile due to a duplicate 'base'
+# we should either detect the collision or allow this to compile
+{ 'struct': 'Base', 'data': {} }
+{ 'struct': 'Sub',
+  'base': 'Base',
+  'data': { 'base': 'str' } }
diff --git a/tests/qapi-schema/struct-base-clash-base.out 
b/tests/qapi-schema/struct-base-clash-base.out
new file mode 100644
index 0000000..e69a416
--- /dev/null
+++ b/tests/qapi-schema/struct-base-clash-base.out
@@ -0,0 +1,5 @@
+object :empty
+object Base
+object Sub
+    base Base
+    member base: str optional=False
diff --git a/tests/qapi-schema/union-clash-data.err 
b/tests/qapi-schema/union-clash-data.err
new file mode 100644
index 0000000..e69de29
diff --git a/tests/qapi-schema/union-clash-data.exit 
b/tests/qapi-schema/union-clash-data.exit
new file mode 100644
index 0000000..573541a
--- /dev/null
+++ b/tests/qapi-schema/union-clash-data.exit
@@ -0,0 +1 @@
+0
diff --git a/tests/qapi-schema/union-clash-data.json 
b/tests/qapi-schema/union-clash-data.json
new file mode 100644
index 0000000..322f61b
--- /dev/null
+++ b/tests/qapi-schema/union-clash-data.json
@@ -0,0 +1,4 @@
+# FIXME: this parses, but then fails to compile due to a duplicate 'data'
+# we should either detect the collision or allow this to compile
+{ 'union': 'TestUnion',
+  'data': { 'data': 'int' } }
diff --git a/tests/qapi-schema/union-clash-data.out 
b/tests/qapi-schema/union-clash-data.out
new file mode 100644
index 0000000..6277239
--- /dev/null
+++ b/tests/qapi-schema/union-clash-data.out
@@ -0,0 +1,6 @@
+object :empty
+object :obj-int-wrapper
+    member data: int optional=False
+object TestUnion
+    case data: :obj-int-wrapper
+enum TestUnionKind ['data']
diff --git a/tests/qapi-schema/union-clash-members.err 
b/tests/qapi-schema/union-clash-members.err
new file mode 100644
index 0000000..b77aeb8
--- /dev/null
+++ b/tests/qapi-schema/union-clash-members.err
@@ -0,0 +1 @@
+tests/qapi-schema/union-clash-members.json:2: Union 'TestUnion' member 'a_b' 
clashes with 'a-b'
diff --git a/tests/qapi-schema/union-clash-members.exit 
b/tests/qapi-schema/union-clash-members.exit
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/tests/qapi-schema/union-clash-members.exit
@@ -0,0 +1 @@
+1
diff --git a/tests/qapi-schema/union-clash-members.json 
b/tests/qapi-schema/union-clash-members.json
new file mode 100644
index 0000000..0393ed8
--- /dev/null
+++ b/tests/qapi-schema/union-clash-members.json
@@ -0,0 +1,3 @@
+# we reject unions where branch names clash when mapped to C
+{ 'union': 'TestUnion',
+  'data': { 'a-b': 'int', 'a_b': 'str' } }
diff --git a/tests/qapi-schema/union-clash-members.out 
b/tests/qapi-schema/union-clash-members.out
new file mode 100644
index 0000000..e69de29
diff --git a/tests/qapi-schema/union-clash-type.err 
b/tests/qapi-schema/union-clash-type.err
new file mode 100644
index 0000000..6e64d1d
--- /dev/null
+++ b/tests/qapi-schema/union-clash-type.err
@@ -0,0 +1,16 @@
+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
diff --git a/tests/qapi-schema/union-clash-type.exit 
b/tests/qapi-schema/union-clash-type.exit
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/tests/qapi-schema/union-clash-type.exit
@@ -0,0 +1 @@
+1
diff --git a/tests/qapi-schema/union-clash-type.json 
b/tests/qapi-schema/union-clash-type.json
new file mode 100644
index 0000000..2294f4f
--- /dev/null
+++ b/tests/qapi-schema/union-clash-type.json
@@ -0,0 +1,3 @@
+# FIXME: detect this collision, rather than triggering an assertion failure
+{ 'union': 'TestUnion',
+  'data': { 'kind': 'int', 'type': 'str' } }
diff --git a/tests/qapi-schema/union-clash-type.out 
b/tests/qapi-schema/union-clash-type.out
new file mode 100644
index 0000000..e69de29
-- 
2.4.3


Reply via email to