diff --git a/scripts/qapi.py b/scripts/qapi.py
index 9421431..800e8e4 100644
--- a/scripts/qapi.py
+++ b/scripts/qapi.py
@@ -321,13 +321,14 @@ def check_name(expr_info, source, name, allow_optional = False):
                             "%s uses invalid name '%s'" % (source, name))

 def check_type(expr_info, source, data, allow_array = False,
-               allowed_metas = [], allow_dict = True, allow_optional = False):
+               allowed_metas = [], allow_dict = True, allow_optional = False,
+               allow_star = False):
     global all_names

     if data is None:
         return

-    if data == '**':
+    if allow_star and data == '**':
         return

     # Check if array type for data is okay
@@ -343,6 +344,10 @@ def check_type(expr_info, source, data, allow_array = False,

     # Check if type name for data is okay
     if isinstance(data, str):
+        if data == '**':
+            raise QAPIExprError(expr_info,
+                                "%s uses '**' but did not request 'gen':false"
+                                % source)
         if not data in all_names:
             raise QAPIExprError(expr_info,
                                 "%s uses unknown type '%s'"
@@ -367,19 +372,23 @@ def check_type(expr_info, source, data, allow_array = False,
                    allow_array=True,
                    allowed_metas=['built-in', 'union', 'alternate', 'struct',
                                   'enum'],
-                   allow_dict=True, allow_optional=True)
+                   allow_dict=True, allow_optional=True, allow_star=allow_star)

 def check_command(expr, expr_info):
     name = expr['command']
+    allow_star = expr.has_key('gen')
+
     check_type(expr_info, "'data' for command '%s'" % name,
                expr.get('data'),
-               allowed_metas=['union', 'struct'], allow_optional=True)
+               allowed_metas=['union', 'struct'], allow_optional=True,
+               allow_star=allow_star)
     returns_meta = ['union', 'struct']
     if name in returns_whitelist:
         returns_meta += ['built-in', 'alternate', 'enum']
     check_type(expr_info, "'returns' for command '%s'" % name,
                expr.get('returns'), allow_array=True,
-               allowed_metas=returns_meta, allow_optional=True)
+               allowed_metas=returns_meta, allow_optional=True,
+               allow_star=allow_star)

 def check_event(expr, expr_info):
     global events
@@ -574,6 +583,10 @@ def check_keys(expr_elem, meta, required, optional=[]):
             raise QAPIExprError(info,
                                 "%s '%s' has unknown key '%s'"
                                 % (meta, name, key))
+        if (key == 'gen' or key == 'success-response') and value != False:
+            raise QAPIExprError(info,
+                                "'%s' of %s '%s' should only use false value"
+                                % (key, meta, name))
     for key in required:
         if not expr.has_key(key):
             raise QAPIExprError(info,
diff --git a/tests/qapi-schema/type-bypass-bad-gen.err b/tests/qapi-schema/type-bypass-bad-gen.err
index e69de29..a83c3c6 100644
--- a/tests/qapi-schema/type-bypass-bad-gen.err
+++ b/tests/qapi-schema/type-bypass-bad-gen.err
@@ -0,0 +1 @@
+tests/qapi-schema/type-bypass-bad-gen.json:2: 'gen' of command 'foo' should only use false value
diff --git a/tests/qapi-schema/type-bypass-bad-gen.exit b/tests/qapi-schema/type-bypass-bad-gen.exit
index 573541a..d00491f 100644
--- a/tests/qapi-schema/type-bypass-bad-gen.exit
+++ b/tests/qapi-schema/type-bypass-bad-gen.exit
@@ -1 +1 @@
-0
+1
diff --git a/tests/qapi-schema/type-bypass-bad-gen.json b/tests/qapi-schema/type-bypass-bad-gen.json
index bb70bee..e8dec34 100644
--- a/tests/qapi-schema/type-bypass-bad-gen.json
+++ b/tests/qapi-schema/type-bypass-bad-gen.json
@@ -1,2 +1,2 @@
-# FIXME: 'gen' should only appear with value false
+# 'gen' should only appear with value false
 { 'command': 'foo', 'gen': 'whatever' }
diff --git a/tests/qapi-schema/type-bypass-bad-gen.out b/tests/qapi-schema/type-bypass-bad-gen.out
index e678f2c..e69de29 100644
--- a/tests/qapi-schema/type-bypass-bad-gen.out
+++ b/tests/qapi-schema/type-bypass-bad-gen.out
@@ -1,3 +0,0 @@
-[OrderedDict([('command', 'foo'), ('gen', 'whatever')])]
-[]
-[]
diff --git a/tests/qapi-schema/type-bypass-no-gen.err b/tests/qapi-schema/type-bypass-no-gen.err
index e69de29..20cef0a 100644
--- a/tests/qapi-schema/type-bypass-no-gen.err
+++ b/tests/qapi-schema/type-bypass-no-gen.err
@@ -0,0 +1 @@
+tests/qapi-schema/type-bypass-no-gen.json:2: Member 'arg' of 'data' for command 'unsafe' uses '**' but did not request 'gen':false
diff --git a/tests/qapi-schema/type-bypass-no-gen.exit b/tests/qapi-schema/type-bypass-no-gen.exit
index 573541a..d00491f 100644
--- a/tests/qapi-schema/type-bypass-no-gen.exit
+++ b/tests/qapi-schema/type-bypass-no-gen.exit
@@ -1 +1 @@
-0
+1
diff --git a/tests/qapi-schema/type-bypass-no-gen.json b/tests/qapi-schema/type-bypass-no-gen.json
index af87c19..49b5742 100644
--- a/tests/qapi-schema/type-bypass-no-gen.json
+++ b/tests/qapi-schema/type-bypass-no-gen.json
@@ -1,2 +1,2 @@
-# FIXME: type bypass should only work with 'gen':false
+# type bypass only works with 'gen':'no'
 { 'command': 'unsafe', 'data': { 'arg': '**' }, 'returns': '**' }
diff --git a/tests/qapi-schema/type-bypass-no-gen.out b/tests/qapi-schema/type-bypass-no-gen.out
index 8b2a9ac..e69de29 100644
--- a/tests/qapi-schema/type-bypass-no-gen.out
+++ b/tests/qapi-schema/type-bypass-no-gen.out
@@ -1,3 +0,0 @@
-[OrderedDict([('command', 'unsafe'), ('data', OrderedDict([('arg', '**')])), ('returns', '**')])]
-[]
-[]
