All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH v2 00/45] qobject/qapi: add uint type
@ 2017-05-31 13:56 Marc-André Lureau
  2017-05-31 13:56 ` [Qemu-devel] [PATCH v2 01/45] qobject-input-visitor: Reject non-finite numbers with keyval Marc-André Lureau
                   ` (46 more replies)
  0 siblings, 47 replies; 80+ messages in thread
From: Marc-André Lureau @ 2017-05-31 13:56 UTC (permalink / raw)
  To: qemu-devel; +Cc: armbru, Marc-André Lureau

Hi,

In previously sent series "[PATCH 00/21] WIP: dump: add kaslr support
(for after 2.9)", I proposed changes to accept uint64 values from
json, by adding a QUint type. During review, it was suggested to
introduce a QNum type to hold various number representations.

This series introduces the QNum type, adds uint representation to it,
and make uint64 values over json possible (while keeping json negative
int for values >INT64_MAX to unsigned cast compatibility). It also
improves some int vs uint usage for object properties and other
QObject related clean-ups.

The series includes previously sent "qapi: Handle some keyval fallout"
series to help with automated testing.

v2:
- add set_default_value() callback in PropertyInfo
- use Markus version of "remove alt num-int cases"
- add more int/number ranges visitor checks
- replace Error usage for success bool return value in get_int/uint()
- various updated comments, patch and code reorganization
- avoid temporary regression from patch "json: learn to parse uint64
  numbers", drop related patch
- split get_mmcfg_size() fix in a seperate patch
- added "apic-common: make "id" property a uint32" patch
- split the qdev uint proprety patch
- split "Use uint property getter/setter where appropriate" in various
  patches
- add some qdict tests
- dropped s3/s4 bool patch
- add some r-b tags

Marc-André Lureau (40):
  qdev: remove PropertyInfo.qtype field
  object: fix potential leak in getters
  tests: add more int/number ranges checks
  qapi: merge QInt and QFloat in QNum
  qapi: Remove visit_start_alternate() parameter promote_int
  tests: remove /qnum/destroy test
  qnum: add uint type
  json: learn to parse uint64 numbers
  qapi: update the qobject visitor to use QNUM_U64
  object: add uint property setter/getter
  q35: fix get_mmcfg_size to use uint64 visitor
  object: use more specific property type names
  qdev: make default property int
  qdev: add unsigned properties
  apic-common: make "id" property a uint32
  qdev: use appropriate getter/setters type
  isa: use get_uint() for "io-base"
  pc-dimm: use get_uint() for dimm properties
  pc-dimm: make "size" property uint64
  pcihp: use get_uint() for "bsel" property
  aspeed: use {set,get}_uint() for "ram-size" property
  bcm2835_fb: use {get,set}_uint() for "vcram-size" and "vcram-base"
  platform-bus: use get_uint() for "addr" property
  acpi: use get_uint() for "acpi-pcihp-io*" properties
  acpi: use get_uint() for various acpi properties
  acpi: use get_uint() for "pci-hole*" properties
  pc: use get_uint() for "iobase" property
  pc: use get_uint() for "apic-id" property
  pc: use get_uint() for "hpet-intcap" property
  xen: use get_uint() for "max-ram-below-4g" property
  arm: use get_uint() for "mp-affinity" property
  auxbus: use get_uint() for "addr" property
  pvpanic: use get_uint() for "ioport" property
  pnv-core: use get_uint() for "core-pir" property
  numa: use get_uint() for "size" property
  i386/cpu: use get_uint() for "min-level"/"min-xlevel" properties
  console: use get_uint() for "head" property
  tests/qdict: check more get_try_int() cases
  RFC: qdict: add uint
  qobject: move dump_qobject() from block/ to qobject/

Markus Armbruster (5):
  qobject-input-visitor: Reject non-finite numbers with keyval
  qapi: Document visit_type_any() issues with keyval input
  tests/qapi-schema: Avoid 'str' in alternate test cases
  qapi: Reject alternates that can't work with keyval_parse()
  tests: remove alt num-int cases

 include/qapi/visitor.h                             |   8 +-
 include/qapi/visitor-impl.h                        |   2 +-
 scripts/qapi.py                                    |  47 +++--
 scripts/qapi-visit.py                              |  12 +-
 include/hw/isa/isa.h                               |   2 +-
 include/hw/qdev-core.h                             |   7 +-
 include/hw/qdev-properties.h                       |  72 ++++----
 include/qapi/qmp/qdict.h                           |  10 +-
 include/qapi/qmp/qfloat.h                          |  29 ----
 include/qapi/qmp/qint.h                            |  28 ---
 include/qapi/qmp/qlist.h                           |   5 +-
 include/qapi/qmp/qnum.h                            |  48 ++++++
 include/qapi/qmp/qobject.h                         |   7 +
 include/qapi/qmp/types.h                           |   3 +-
 include/qapi/qobject-input-visitor.h               |   6 +-
 include/qapi/qobject-output-visitor.h              |   8 +-
 include/qom/object.h                               |  23 +++
 qapi/qapi-visit-core.c                             |   6 +-
 backends/cryptodev.c                               |   2 +-
 block/blkdebug.c                                   |   1 -
 block/nbd.c                                        |   1 -
 block/nfs.c                                        |   1 -
 block/qapi.c                                       |  93 +---------
 block/quorum.c                                     |   1 -
 block/sheepdog.c                                   |   1 -
 block/ssh.c                                        |   1 -
 block/vvfat.c                                      |   1 -
 blockdev.c                                         |   8 +-
 hw/acpi/memory_hotplug.c                           |  12 +-
 hw/acpi/nvdimm.c                                   |  18 +-
 hw/acpi/pcihp.c                                    |   7 +-
 hw/arm/aspeed.c                                    |   8 +-
 hw/arm/bcm2835_peripherals.c                       |   9 +-
 hw/arm/raspi.c                                     |   4 +-
 hw/block/fdc.c                                     |  54 +++---
 hw/core/platform-bus.c                             |   2 +-
 hw/core/qdev-properties.c                          |  40 ++++-
 hw/core/qdev.c                                     |  13 +-
 hw/i386/acpi-build.c                               |  95 ++++++----
 hw/i386/pc.c                                       |   6 +-
 hw/i386/xen/xen-hvm.c                              |   6 +-
 hw/intc/apic_common.c                              |  10 +-
 hw/intc/arm_gicv3_common.c                         |   2 +-
 hw/mem/pc-dimm.c                                   |  23 +--
 hw/misc/auxbus.c                                   |   2 +-
 hw/misc/pvpanic.c                                  |   2 +-
 hw/net/e1000e.c                                    |  14 +-
 hw/pci-host/gpex.c                                 |   2 +-
 hw/pci-host/piix.c                                 |   8 +-
 hw/pci-host/q35.c                                  |  15 +-
 hw/pci-host/xilinx-pcie.c                          |   2 +-
 hw/ppc/pnv.c                                       |   2 +-
 hw/ppc/pnv_core.c                                  |   2 +-
 hw/ppc/spapr.c                                     |   7 +-
 hw/usb/xen-usb.c                                   |   1 -
 monitor.c                                          |   2 +-
 net/dump.c                                         |   2 +-
 net/filter-buffer.c                                |   2 +-
 numa.c                                             |   6 +-
 qapi/qapi-clone-visitor.c                          |   2 +-
 qapi/qapi-dealloc-visitor.c                        |   2 +-
 qapi/qobject-input-visitor.c                       |  57 +++---
 qapi/qobject-output-visitor.c                      |   7 +-
 qga/commands.c                                     |   2 +-
 qga/main.c                                         |   1 -
 qobject/json-lexer.c                               |   4 +
 qobject/json-parser.c                              |  53 ++++--
 qobject/qdict.c                                    | 112 +++++++++---
 qobject/qfloat.c                                   |  62 -------
 qobject/qint.c                                     |  61 -------
 qobject/qjson.c                                    |  37 +---
 qobject/qlist.c                                    |  23 +++
 qobject/qnum.c                                     | 192 +++++++++++++++++++++
 qobject/qobject.c                                  |  22 ++-
 qom/object.c                                       |  51 ++++--
 target/i386/cpu.c                                  |  10 +-
 tests/check-qdict.c                                |  76 ++++++--
 tests/check-qfloat.c                               |  53 ------
 tests/check-qint.c                                 |  87 ----------
 tests/check-qjson.c                                | 147 +++++++++++-----
 tests/check-qlist.c                                |  18 +-
 tests/check-qnum.c                                 | 166 ++++++++++++++++++
 tests/test-clone-visitor.c                         |  23 ++-
 tests/test-keyval.c                                |  20 ++-
 tests/test-qmp-commands.c                          |   8 +-
 tests/test-qmp-event.c                             |   9 +-
 tests/test-qobject-input-visitor.c                 | 164 ++++++++++--------
 tests/test-qobject-output-visitor.c                |  96 +++++++----
 tests/test-x86-cpuid-compat.c                      |  20 ++-
 ui/console.c                                       |   4 +-
 ui/spice-core.c                                    |   1 -
 ui/vnc-enc-tight.c                                 |   1 -
 util/keyval.c                                      |  10 +-
 util/qemu-option.c                                 |  20 +--
 MAINTAINERS                                        |   3 +-
 qapi/trace-events                                  |   2 +-
 qobject/Makefile.objs                              |   2 +-
 scripts/coccinelle/qobject.cocci                   |   4 +-
 tests/.gitignore                                   |   3 +-
 tests/Makefile.include                             |  15 +-
 tests/qapi-schema/alternate-clash.json             |   2 +-
 tests/qapi-schema/alternate-conflict-dict.json     |   2 +-
 tests/qapi-schema/alternate-conflict-enum-bool.err |   1 +
 .../qapi-schema/alternate-conflict-enum-bool.exit  |   1 +
 .../qapi-schema/alternate-conflict-enum-bool.json  |   6 +
 tests/qapi-schema/alternate-conflict-enum-bool.out |   0
 tests/qapi-schema/alternate-conflict-enum-int.err  |   1 +
 tests/qapi-schema/alternate-conflict-enum-int.exit |   1 +
 tests/qapi-schema/alternate-conflict-enum-int.json |   6 +
 tests/qapi-schema/alternate-conflict-enum-int.out  |   0
 tests/qapi-schema/alternate-conflict-string.err    |   2 +-
 tests/qapi-schema/alternate-conflict-string.json   |   6 +-
 tests/qapi-schema/alternate-nested.json            |   2 +-
 tests/qapi-schema/args-alternate.json              |   2 +-
 tests/qapi-schema/comments.out                     |   2 +-
 tests/qapi-schema/doc-bad-alternate-member.json    |   2 +-
 tests/qapi-schema/doc-good.out                     |   2 +-
 tests/qapi-schema/empty.out                        |   2 +-
 tests/qapi-schema/event-case.out                   |   2 +-
 tests/qapi-schema/ident-with-escape.out            |   2 +-
 tests/qapi-schema/include-relpath.out              |   2 +-
 tests/qapi-schema/include-repetition.out           |   2 +-
 tests/qapi-schema/include-simple.out               |   2 +-
 tests/qapi-schema/indented-expr.out                |   2 +-
 tests/qapi-schema/qapi-schema-test.json            |  15 +-
 tests/qapi-schema/qapi-schema-test.out             |  32 ++--
 tests/qapi-schema/returns-alternate.json           |   2 +-
 127 files changed, 1475 insertions(+), 1087 deletions(-)
 delete mode 100644 include/qapi/qmp/qfloat.h
 delete mode 100644 include/qapi/qmp/qint.h
 create mode 100644 include/qapi/qmp/qnum.h
 delete mode 100644 qobject/qfloat.c
 delete mode 100644 qobject/qint.c
 create mode 100644 qobject/qnum.c
 delete mode 100644 tests/check-qfloat.c
 delete mode 100644 tests/check-qint.c
 create mode 100644 tests/check-qnum.c
 create mode 100644 tests/qapi-schema/alternate-conflict-enum-bool.err
 create mode 100644 tests/qapi-schema/alternate-conflict-enum-bool.exit
 create mode 100644 tests/qapi-schema/alternate-conflict-enum-bool.json
 create mode 100644 tests/qapi-schema/alternate-conflict-enum-bool.out
 create mode 100644 tests/qapi-schema/alternate-conflict-enum-int.err
 create mode 100644 tests/qapi-schema/alternate-conflict-enum-int.exit
 create mode 100644 tests/qapi-schema/alternate-conflict-enum-int.json
 create mode 100644 tests/qapi-schema/alternate-conflict-enum-int.out

-- 
2.13.0.91.g00982b8dd

^ permalink raw reply	[flat|nested] 80+ messages in thread

* [Qemu-devel] [PATCH v2 01/45] qobject-input-visitor: Reject non-finite numbers with keyval
  2017-05-31 13:56 [Qemu-devel] [PATCH v2 00/45] qobject/qapi: add uint type Marc-André Lureau
@ 2017-05-31 13:56 ` Marc-André Lureau
  2017-05-31 13:56 ` [Qemu-devel] [PATCH v2 02/45] qapi: Document visit_type_any() issues with keyval input Marc-André Lureau
                   ` (45 subsequent siblings)
  46 siblings, 0 replies; 80+ messages in thread
From: Marc-André Lureau @ 2017-05-31 13:56 UTC (permalink / raw)
  To: qemu-devel; +Cc: armbru

From: Markus Armbruster <armbru@redhat.com>

The QObject input visitor can produce only finite numbers when its
input comes out of the JSON parser, because the the JSON parser
implements RFC 7159, which provides no syntax for infinity and NaN.

However, it can produce infinity and NaN when its input comes out of
keyval_parse(), because we parse with strtod() then.

The keyval variant should not be able to express things the JSON
variant can't.  Rejecting non-finite numbers there is the conservative
fix.  It's also minimally invasive.

We could instead extend our JSON dialect to provide for infinity and
NaN.  Not today.

Note that the JSON formatter can emit non-finite numbers (marked FIXME
in commit 6e8e5cb).

Signed-off-by: Markus Armbruster <armbru@redhat.com>
Message-Id: <1495471335-23707-2-git-send-email-armbru@redhat.com>
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
---
 qapi/qobject-input-visitor.c       | 3 ++-
 tests/test-qobject-input-visitor.c | 6 ++++++
 2 files changed, 8 insertions(+), 1 deletion(-)

diff --git a/qapi/qobject-input-visitor.c b/qapi/qobject-input-visitor.c
index d0f0002317..eac40f618a 100644
--- a/qapi/qobject-input-visitor.c
+++ b/qapi/qobject-input-visitor.c
@@ -13,6 +13,7 @@
  */
 
 #include "qemu/osdep.h"
+#include <math.h>
 #include "qapi/error.h"
 #include "qapi/qobject-input-visitor.h"
 #include "qapi/visitor-impl.h"
@@ -568,7 +569,7 @@ static void qobject_input_type_number_keyval(Visitor *v, const char *name,
 
     errno = 0;
     *obj = strtod(str, &endp);
-    if (errno || endp == str || *endp) {
+    if (errno || endp == str || *endp || !isfinite(*obj)) {
         /* TODO report -ERANGE more nicely */
         error_setg(errp, QERR_INVALID_PARAMETER_TYPE,
                    full_name(qiv, name), "number");
diff --git a/tests/test-qobject-input-visitor.c b/tests/test-qobject-input-visitor.c
index f965743b6e..e2aabbe972 100644
--- a/tests/test-qobject-input-visitor.c
+++ b/tests/test-qobject-input-visitor.c
@@ -278,11 +278,17 @@ static void test_visitor_in_number_str_keyval(TestInputVisitorData *data,
 {
     double res = 0, value = 3.14;
     Visitor *v;
+    Error *err = NULL;
 
     v = visitor_input_test_init_full(data, true, "\"3.14\"");
 
     visit_type_number(v, NULL, &res, &error_abort);
     g_assert_cmpfloat(res, ==, value);
+
+    v = visitor_input_test_init_full(data, true, "\"inf\"");
+
+    visit_type_number(v, NULL, &res, &err);
+    error_free_or_abort(&err);
 }
 
 static void test_visitor_in_number_str_fail(TestInputVisitorData *data,
-- 
2.13.0.91.g00982b8dd

^ permalink raw reply related	[flat|nested] 80+ messages in thread

* [Qemu-devel] [PATCH v2 02/45] qapi: Document visit_type_any() issues with keyval input
  2017-05-31 13:56 [Qemu-devel] [PATCH v2 00/45] qobject/qapi: add uint type Marc-André Lureau
  2017-05-31 13:56 ` [Qemu-devel] [PATCH v2 01/45] qobject-input-visitor: Reject non-finite numbers with keyval Marc-André Lureau
@ 2017-05-31 13:56 ` Marc-André Lureau
  2017-05-31 13:56 ` [Qemu-devel] [PATCH v2 03/45] tests/qapi-schema: Avoid 'str' in alternate test cases Marc-André Lureau
                   ` (44 subsequent siblings)
  46 siblings, 0 replies; 80+ messages in thread
From: Marc-André Lureau @ 2017-05-31 13:56 UTC (permalink / raw)
  To: qemu-devel; +Cc: armbru

From: Markus Armbruster <armbru@redhat.com>

It's already documented in keyval.c (commit 0ee9ae7), but visitor.h
can use a note, too.

Signed-off-by: Markus Armbruster <armbru@redhat.com>
Message-Id: <1495471335-23707-3-git-send-email-armbru@redhat.com>
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
---
 include/qapi/visitor.h | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/include/qapi/visitor.h b/include/qapi/visitor.h
index b0e233df76..4721c39ae3 100644
--- a/include/qapi/visitor.h
+++ b/include/qapi/visitor.h
@@ -607,6 +607,10 @@ void visit_type_number(Visitor *v, const char *name, double *obj,
  * @obj must be non-NULL.  Input visitors set *@obj to the value;
  * other visitors will leave *@obj unchanged.  *@obj must be non-NULL
  * for output visitors.
+ *
+ * Note that some kinds of input can't express arbitrary QObject.
+ * E.g. the visitor returned by qobject_input_visitor_new_keyval()
+ * can't create numbers or booleans, only strings.
  */
 void visit_type_any(Visitor *v, const char *name, QObject **obj, Error **errp);
 
-- 
2.13.0.91.g00982b8dd

^ permalink raw reply related	[flat|nested] 80+ messages in thread

* [Qemu-devel] [PATCH v2 03/45] tests/qapi-schema: Avoid 'str' in alternate test cases
  2017-05-31 13:56 [Qemu-devel] [PATCH v2 00/45] qobject/qapi: add uint type Marc-André Lureau
  2017-05-31 13:56 ` [Qemu-devel] [PATCH v2 01/45] qobject-input-visitor: Reject non-finite numbers with keyval Marc-André Lureau
  2017-05-31 13:56 ` [Qemu-devel] [PATCH v2 02/45] qapi: Document visit_type_any() issues with keyval input Marc-André Lureau
@ 2017-05-31 13:56 ` Marc-André Lureau
  2017-05-31 13:56 ` [Qemu-devel] [PATCH v2 04/45] qapi: Reject alternates that can't work with keyval_parse() Marc-André Lureau
                   ` (43 subsequent siblings)
  46 siblings, 0 replies; 80+ messages in thread
From: Marc-André Lureau @ 2017-05-31 13:56 UTC (permalink / raw)
  To: qemu-devel; +Cc: armbru

From: Markus Armbruster <armbru@redhat.com>

The next commit is going to make alternate members of type 'str'
conflict with other scalar types.  Would break a few test cases that
don't actually require 'str'.  Flip them from 'str' to 'bool' or
'EnumOne'.

Signed-off-by: Markus Armbruster <armbru@redhat.com>
Message-Id: <1495471335-23707-4-git-send-email-armbru@redhat.com>
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
---
 tests/test-clone-visitor.c                      | 23 +++++-----
 tests/test-qobject-input-visitor.c              | 56 ++++++++++++-------------
 tests/test-qobject-output-visitor.c             |  4 +-
 tests/qapi-schema/alternate-clash.json          |  2 +-
 tests/qapi-schema/alternate-nested.json         |  2 +-
 tests/qapi-schema/args-alternate.json           |  2 +-
 tests/qapi-schema/doc-bad-alternate-member.json |  2 +-
 tests/qapi-schema/qapi-schema-test.json         |  9 ++--
 tests/qapi-schema/qapi-schema-test.out          | 30 +++++++------
 tests/qapi-schema/returns-alternate.json        |  2 +-
 10 files changed, 68 insertions(+), 64 deletions(-)

diff --git a/tests/test-clone-visitor.c b/tests/test-clone-visitor.c
index df0c045512..96982163e4 100644
--- a/tests/test-clone-visitor.c
+++ b/tests/test-clone-visitor.c
@@ -42,29 +42,28 @@ static void test_clone_struct(void)
 
 static void test_clone_alternate(void)
 {
-    AltStrBool *b_src, *s_src, *b_dst, *s_dst;
+    AltEnumBool *b_src, *s_src, *b_dst, *s_dst;
 
-    b_src = g_new0(AltStrBool, 1);
+    b_src = g_new0(AltEnumBool, 1);
     b_src->type = QTYPE_QBOOL;
     b_src->u.b = true;
-    s_src = g_new0(AltStrBool, 1);
+    s_src = g_new0(AltEnumBool, 1);
     s_src->type = QTYPE_QSTRING;
-    s_src->u.s = g_strdup("World");
+    s_src->u.e = ENUM_ONE_VALUE1;
 
-    b_dst = QAPI_CLONE(AltStrBool, b_src);
+    b_dst = QAPI_CLONE(AltEnumBool, b_src);
     g_assert(b_dst);
     g_assert_cmpint(b_dst->type, ==, b_src->type);
     g_assert_cmpint(b_dst->u.b, ==, b_src->u.b);
-    s_dst = QAPI_CLONE(AltStrBool, s_src);
+    s_dst = QAPI_CLONE(AltEnumBool, s_src);
     g_assert(s_dst);
     g_assert_cmpint(s_dst->type, ==, s_src->type);
-    g_assert_cmpstr(s_dst->u.s, ==, s_src->u.s);
-    g_assert(s_dst->u.s != s_src->u.s);
+    g_assert_cmpint(s_dst->u.e, ==, s_src->u.e);
 
-    qapi_free_AltStrBool(b_src);
-    qapi_free_AltStrBool(s_src);
-    qapi_free_AltStrBool(b_dst);
-    qapi_free_AltStrBool(s_dst);
+    qapi_free_AltEnumBool(b_src);
+    qapi_free_AltEnumBool(s_src);
+    qapi_free_AltEnumBool(b_dst);
+    qapi_free_AltEnumBool(s_dst);
 }
 
 static void test_clone_native_list(void)
diff --git a/tests/test-qobject-input-visitor.c b/tests/test-qobject-input-visitor.c
index e2aabbe972..6b997a177d 100644
--- a/tests/test-qobject-input-visitor.c
+++ b/tests/test-qobject-input-visitor.c
@@ -537,10 +537,10 @@ static void test_visitor_in_alternate(TestInputVisitorData *data,
     g_assert_cmpint(tmp->u.i, ==, 42);
     qapi_free_UserDefAlternate(tmp);
 
-    v = visitor_input_test_init(data, "'string'");
+    v = visitor_input_test_init(data, "'value1'");
     visit_type_UserDefAlternate(v, NULL, &tmp, &error_abort);
     g_assert_cmpint(tmp->type, ==, QTYPE_QSTRING);
-    g_assert_cmpstr(tmp->u.s, ==, "string");
+    g_assert_cmpint(tmp->u.e, ==, ENUM_ONE_VALUE1);
     qapi_free_UserDefAlternate(tmp);
 
     v = visitor_input_test_init(data, "{'integer':1, 'string':'str', "
@@ -565,10 +565,10 @@ static void test_visitor_in_alternate(TestInputVisitorData *data,
     g_assert_cmpint(wrap->alt->u.i, ==, 42);
     qapi_free_WrapAlternate(wrap);
 
-    v = visitor_input_test_init(data, "{ 'alt': 'string' }");
+    v = visitor_input_test_init(data, "{ 'alt': 'value1' }");
     visit_type_WrapAlternate(v, NULL, &wrap, &error_abort);
     g_assert_cmpint(wrap->alt->type, ==, QTYPE_QSTRING);
-    g_assert_cmpstr(wrap->alt->u.s, ==, "string");
+    g_assert_cmpint(wrap->alt->u.e, ==, ENUM_ONE_VALUE1);
     qapi_free_WrapAlternate(wrap);
 
     v = visitor_input_test_init(data, "{ 'alt': {'integer':1, 'string':'str', "
@@ -588,37 +588,37 @@ static void test_visitor_in_alternate_number(TestInputVisitorData *data,
 {
     Visitor *v;
     Error *err = NULL;
-    AltStrBool *asb;
-    AltStrNum *asn;
-    AltNumStr *ans;
-    AltStrInt *asi;
+    AltEnumBool *aeb;
+    AltEnumNum *aen;
+    AltNumEnum *ans;
+    AltEnumInt *asi;
     AltIntNum *ain;
     AltNumInt *ani;
 
     /* Parsing an int */
 
     v = visitor_input_test_init(data, "42");
-    visit_type_AltStrBool(v, NULL, &asb, &err);
+    visit_type_AltEnumBool(v, NULL, &aeb, &err);
     error_free_or_abort(&err);
-    qapi_free_AltStrBool(asb);
+    qapi_free_AltEnumBool(aeb);
 
     v = visitor_input_test_init(data, "42");
-    visit_type_AltStrNum(v, NULL, &asn, &error_abort);
-    g_assert_cmpint(asn->type, ==, QTYPE_QFLOAT);
-    g_assert_cmpfloat(asn->u.n, ==, 42);
-    qapi_free_AltStrNum(asn);
+    visit_type_AltEnumNum(v, NULL, &aen, &error_abort);
+    g_assert_cmpint(aen->type, ==, QTYPE_QFLOAT);
+    g_assert_cmpfloat(aen->u.n, ==, 42);
+    qapi_free_AltEnumNum(aen);
 
     v = visitor_input_test_init(data, "42");
-    visit_type_AltNumStr(v, NULL, &ans, &error_abort);
+    visit_type_AltNumEnum(v, NULL, &ans, &error_abort);
     g_assert_cmpint(ans->type, ==, QTYPE_QFLOAT);
     g_assert_cmpfloat(ans->u.n, ==, 42);
-    qapi_free_AltNumStr(ans);
+    qapi_free_AltNumEnum(ans);
 
     v = visitor_input_test_init(data, "42");
-    visit_type_AltStrInt(v, NULL, &asi, &error_abort);
+    visit_type_AltEnumInt(v, NULL, &asi, &error_abort);
     g_assert_cmpint(asi->type, ==, QTYPE_QINT);
     g_assert_cmpint(asi->u.i, ==, 42);
-    qapi_free_AltStrInt(asi);
+    qapi_free_AltEnumInt(asi);
 
     v = visitor_input_test_init(data, "42");
     visit_type_AltIntNum(v, NULL, &ain, &error_abort);
@@ -635,26 +635,26 @@ static void test_visitor_in_alternate_number(TestInputVisitorData *data,
     /* Parsing a double */
 
     v = visitor_input_test_init(data, "42.5");
-    visit_type_AltStrBool(v, NULL, &asb, &err);
+    visit_type_AltEnumBool(v, NULL, &aeb, &err);
     error_free_or_abort(&err);
-    qapi_free_AltStrBool(asb);
+    qapi_free_AltEnumBool(aeb);
 
     v = visitor_input_test_init(data, "42.5");
-    visit_type_AltStrNum(v, NULL, &asn, &error_abort);
-    g_assert_cmpint(asn->type, ==, QTYPE_QFLOAT);
-    g_assert_cmpfloat(asn->u.n, ==, 42.5);
-    qapi_free_AltStrNum(asn);
+    visit_type_AltEnumNum(v, NULL, &aen, &error_abort);
+    g_assert_cmpint(aen->type, ==, QTYPE_QFLOAT);
+    g_assert_cmpfloat(aen->u.n, ==, 42.5);
+    qapi_free_AltEnumNum(aen);
 
     v = visitor_input_test_init(data, "42.5");
-    visit_type_AltNumStr(v, NULL, &ans, &error_abort);
+    visit_type_AltNumEnum(v, NULL, &ans, &error_abort);
     g_assert_cmpint(ans->type, ==, QTYPE_QFLOAT);
     g_assert_cmpfloat(ans->u.n, ==, 42.5);
-    qapi_free_AltNumStr(ans);
+    qapi_free_AltNumEnum(ans);
 
     v = visitor_input_test_init(data, "42.5");
-    visit_type_AltStrInt(v, NULL, &asi, &err);
+    visit_type_AltEnumInt(v, NULL, &asi, &err);
     error_free_or_abort(&err);
-    qapi_free_AltStrInt(asi);
+    qapi_free_AltEnumInt(asi);
 
     v = visitor_input_test_init(data, "42.5");
     visit_type_AltIntNum(v, NULL, &ain, &error_abort);
diff --git a/tests/test-qobject-output-visitor.c b/tests/test-qobject-output-visitor.c
index 94b9518e40..4e8fdf1397 100644
--- a/tests/test-qobject-output-visitor.c
+++ b/tests/test-qobject-output-visitor.c
@@ -406,12 +406,12 @@ static void test_visitor_out_alternate(TestOutputVisitorData *data,
     visitor_reset(data);
     tmp = g_new0(UserDefAlternate, 1);
     tmp->type = QTYPE_QSTRING;
-    tmp->u.s = g_strdup("hello");
+    tmp->u.e = ENUM_ONE_VALUE1;
 
     visit_type_UserDefAlternate(data->ov, NULL, &tmp, &error_abort);
     qstr = qobject_to_qstring(visitor_get(data));
     g_assert(qstr);
-    g_assert_cmpstr(qstring_get_str(qstr), ==, "hello");
+    g_assert_cmpstr(qstring_get_str(qstr), ==, "value1");
 
     qapi_free_UserDefAlternate(tmp);
 
diff --git a/tests/qapi-schema/alternate-clash.json b/tests/qapi-schema/alternate-clash.json
index 6d73bc527b..9a59b88ced 100644
--- a/tests/qapi-schema/alternate-clash.json
+++ b/tests/qapi-schema/alternate-clash.json
@@ -5,4 +5,4 @@
 # the implicit Alt1Kind enum, we would still have a collision with the
 # resulting C union trying to have two members named 'a_b'.
 { 'alternate': 'Alt1',
-  'data': { 'a-b': 'str', 'a_b': 'int' } }
+  'data': { 'a-b': 'bool', 'a_b': 'int' } }
diff --git a/tests/qapi-schema/alternate-nested.json b/tests/qapi-schema/alternate-nested.json
index 8e22186491..f2b9632f75 100644
--- a/tests/qapi-schema/alternate-nested.json
+++ b/tests/qapi-schema/alternate-nested.json
@@ -1,5 +1,5 @@
 # we reject a nested alternate branch
 { 'alternate': 'Alt1',
-  'data': { 'name': 'str', 'value': 'int' } }
+  'data': { 'name': 'bool', 'value': 'int' } }
 { 'alternate': 'Alt2',
   'data': { 'nested': 'Alt1', 'b': 'bool' } }
diff --git a/tests/qapi-schema/args-alternate.json b/tests/qapi-schema/args-alternate.json
index 69e94d4819..824d69c1d5 100644
--- a/tests/qapi-schema/args-alternate.json
+++ b/tests/qapi-schema/args-alternate.json
@@ -1,3 +1,3 @@
 # we do not allow alternate arguments
-{ 'alternate': 'Alt', 'data': { 'case1': 'int', 'case2': 'str' } }
+{ 'alternate': 'Alt', 'data': { 'case1': 'int', 'case2': 'bool' } }
 { 'command': 'oops', 'data': 'Alt' }
diff --git a/tests/qapi-schema/doc-bad-alternate-member.json b/tests/qapi-schema/doc-bad-alternate-member.json
index 738635ca8f..fa4143da4c 100644
--- a/tests/qapi-schema/doc-bad-alternate-member.json
+++ b/tests/qapi-schema/doc-bad-alternate-member.json
@@ -6,4 +6,4 @@
 # @bb: b
 ##
 { 'alternate': 'AorB',
-  'data': { 'a': 'str', 'b': 'int' } }
+  'data': { 'a': 'bool', 'b': 'int' } }
diff --git a/tests/qapi-schema/qapi-schema-test.json b/tests/qapi-schema/qapi-schema-test.json
index 842ea3c5e3..303f2b23cd 100644
--- a/tests/qapi-schema/qapi-schema-test.json
+++ b/tests/qapi-schema/qapi-schema-test.json
@@ -93,16 +93,17 @@
 { 'struct': 'WrapAlternate',
   'data': { 'alt': 'UserDefAlternate' } }
 { 'alternate': 'UserDefAlternate',
-  'data': { 'udfu': 'UserDefFlatUnion', 's': 'str', 'i': 'int' } }
+  'data': { 'udfu': 'UserDefFlatUnion', 'e': 'EnumOne', 'i': 'int' } }
 
 { 'struct': 'UserDefC',
   'data': { 'string1': 'str', 'string2': 'str' } }
 
 # for testing use of 'number' within alternates
-{ 'alternate': 'AltStrBool', 'data': { 's': 'str', 'b': 'bool' } }
-{ 'alternate': 'AltStrNum', 'data': { 's': 'str', 'n': 'number' } }
+{ 'alternate': 'AltEnumBool', 'data': { 'e': 'EnumOne', 'b': 'bool' } }
+{ 'alternate': 'AltEnumNum', 'data': { 'e': 'EnumOne', 'n': 'number' } }
 { 'alternate': 'AltNumStr', 'data': { 'n': 'number', 's': 'str' } }
-{ 'alternate': 'AltStrInt', 'data': { 's': 'str', 'i': 'int' } }
+{ 'alternate': 'AltNumEnum', 'data': { 'n': 'number', 'e': 'EnumOne' } }
+{ 'alternate': 'AltEnumInt', 'data': { 'e': 'EnumOne', 'i': 'int' } }
 { 'alternate': 'AltIntNum', 'data': { 'i': 'int', 'n': 'number' } }
 { 'alternate': 'AltNumInt', 'data': { 'n': 'number', 'i': 'int' } }
 
diff --git a/tests/qapi-schema/qapi-schema-test.out b/tests/qapi-schema/qapi-schema-test.out
index 9d99c4eebb..3081091818 100644
--- a/tests/qapi-schema/qapi-schema-test.out
+++ b/tests/qapi-schema/qapi-schema-test.out
@@ -1,7 +1,23 @@
+alternate AltEnumBool
+    tag type
+    case e: EnumOne
+    case b: bool
+alternate AltEnumInt
+    tag type
+    case e: EnumOne
+    case i: int
+alternate AltEnumNum
+    tag type
+    case e: EnumOne
+    case n: number
 alternate AltIntNum
     tag type
     case i: int
     case n: number
+alternate AltNumEnum
+    tag type
+    case n: number
+    case e: EnumOne
 alternate AltNumInt
     tag type
     case n: number
@@ -10,18 +26,6 @@ alternate AltNumStr
     tag type
     case n: number
     case s: str
-alternate AltStrBool
-    tag type
-    case s: str
-    case b: bool
-alternate AltStrInt
-    tag type
-    case s: str
-    case i: int
-alternate AltStrNum
-    tag type
-    case s: str
-    case n: number
 event EVENT_A None
    boxed=False
 event EVENT_B None
@@ -66,7 +70,7 @@ object UserDefA
 alternate UserDefAlternate
     tag type
     case udfu: UserDefFlatUnion
-    case s: str
+    case e: EnumOne
     case i: int
 object UserDefB
     member intb: int optional=False
diff --git a/tests/qapi-schema/returns-alternate.json b/tests/qapi-schema/returns-alternate.json
index 972390c06b..f87371811b 100644
--- a/tests/qapi-schema/returns-alternate.json
+++ b/tests/qapi-schema/returns-alternate.json
@@ -1,3 +1,3 @@
 # we reject returns if it is an alternate type
-{ 'alternate': 'Alt', 'data': { 'a': 'int', 'b': 'str' } }
+{ 'alternate': 'Alt', 'data': { 'a': 'int', 'b': 'bool' } }
 { 'command': 'oops', 'returns': 'Alt' }
-- 
2.13.0.91.g00982b8dd

^ permalink raw reply related	[flat|nested] 80+ messages in thread

* [Qemu-devel] [PATCH v2 04/45] qapi: Reject alternates that can't work with keyval_parse()
  2017-05-31 13:56 [Qemu-devel] [PATCH v2 00/45] qobject/qapi: add uint type Marc-André Lureau
                   ` (2 preceding siblings ...)
  2017-05-31 13:56 ` [Qemu-devel] [PATCH v2 03/45] tests/qapi-schema: Avoid 'str' in alternate test cases Marc-André Lureau
@ 2017-05-31 13:56 ` Marc-André Lureau
  2017-05-31 13:56 ` [Qemu-devel] [PATCH v2 05/45] qdev: remove PropertyInfo.qtype field Marc-André Lureau
                   ` (42 subsequent siblings)
  46 siblings, 0 replies; 80+ messages in thread
From: Marc-André Lureau @ 2017-05-31 13:56 UTC (permalink / raw)
  To: qemu-devel; +Cc: armbru

From: Markus Armbruster <armbru@redhat.com>

Alternates are sum types like unions, but use the JSON type on the
wire / QType in QObject instead of an explicit tag.  That's why we
require alternate members to have distinct QTypes.

The recently introduced keyval_parse() (commit d454dbe) can only
produce string scalars.  The qobject_input_visitor_new_keyval() input
visitor mostly hides the difference, so code using a QObject input
visitor doesn't have to care whether its input was parsed from JSON or
KEY=VALUE,...  The difference leaks for alternates, as noted in commit
0ee9ae7: an non-string, non-enum scalar alternate value can't
currently be expressed.

In part, this is just our insufficiently sophisticated implementation.
Consider alternate type 'GuestFileWhence'.  It has an integer member
and a 'QGASeek' member.  The latter is an enumeration with values
'set', 'cur', 'end'.  The meaning of b=set, b=cur, b=end, b=0, b=1 and
so forth is perfectly obvious.  However, our current implementation
falls apart at run time for b=0, b=1, and so forth.  Fixable, but not
today; add a test case and a TODO comment.

Now consider an alternate type with a string and an integer member.
What's the meaning of a=42?  Is it the string "42" or the integer 42?
Whichever meaning you pick makes the other inexpressible.  This isn't
just an implementation problem, it's fundamental.  Our current
implementation will pick string.

So far, we haven't needed such alternates.  To make sure we stop and
think before we add one that cannot sanely work with keyval_parse(),
let's require alternate members to have sufficiently district
representation in KEY=VALUE,... syntax:

* A string member clashes with any other scalar member

* An enumeration member clashes with bool members when it has value
  'on' or 'off'.

* An enumeration member clashes with numeric members when it has a
  value that starts with '-', '+', '0' or '9'.  This is a rather lazy
  approximation of the actual number syntax accepted by the visitor.

  Note that enumeration values starting with '-' and '+' are rejected
  elsewhere already, but better safe than sorry.

Signed-off-by: Markus Armbruster <armbru@redhat.com>
Message-Id: <1495471335-23707-5-git-send-email-armbru@redhat.com>
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
 scripts/qapi.py                                     | 19 +++++++++++++++++--
 tests/test-keyval.c                                 | 18 +++++++++++-------
 util/keyval.c                                       | 10 +++++-----
 tests/Makefile.include                              |  2 ++
 tests/qapi-schema/alternate-conflict-dict.json      |  2 +-
 tests/qapi-schema/alternate-conflict-enum-bool.err  |  1 +
 tests/qapi-schema/alternate-conflict-enum-bool.exit |  1 +
 tests/qapi-schema/alternate-conflict-enum-bool.json |  6 ++++++
 tests/qapi-schema/alternate-conflict-enum-bool.out  |  0
 tests/qapi-schema/alternate-conflict-enum-int.err   |  1 +
 tests/qapi-schema/alternate-conflict-enum-int.exit  |  1 +
 tests/qapi-schema/alternate-conflict-enum-int.json  |  6 ++++++
 tests/qapi-schema/alternate-conflict-enum-int.out   |  0
 tests/qapi-schema/alternate-conflict-string.err     |  2 +-
 tests/qapi-schema/alternate-conflict-string.json    |  6 ++----
 tests/qapi-schema/qapi-schema-test.json             |  4 +++-
 tests/qapi-schema/qapi-schema-test.out              |  4 ++--
 17 files changed, 60 insertions(+), 23 deletions(-)
 create mode 100644 tests/qapi-schema/alternate-conflict-enum-bool.err
 create mode 100644 tests/qapi-schema/alternate-conflict-enum-bool.exit
 create mode 100644 tests/qapi-schema/alternate-conflict-enum-bool.json
 create mode 100644 tests/qapi-schema/alternate-conflict-enum-bool.out
 create mode 100644 tests/qapi-schema/alternate-conflict-enum-int.err
 create mode 100644 tests/qapi-schema/alternate-conflict-enum-int.exit
 create mode 100644 tests/qapi-schema/alternate-conflict-enum-int.json
 create mode 100644 tests/qapi-schema/alternate-conflict-enum-int.out

diff --git a/scripts/qapi.py b/scripts/qapi.py
index 6c4d554165..b7a25e4759 100644
--- a/scripts/qapi.py
+++ b/scripts/qapi.py
@@ -812,11 +812,26 @@ def check_alternate(expr, info):
         if not qtype:
             raise QAPISemError(info, "Alternate '%s' member '%s' cannot use "
                                "type '%s'" % (name, key, value))
-        if qtype in types_seen:
+        conflicting = set([qtype])
+        if qtype == 'QTYPE_QSTRING':
+            enum_expr = enum_types.get(value)
+            if enum_expr:
+                for v in enum_expr['data']:
+                    if v in ['on', 'off']:
+                        conflicting.add('QTYPE_QBOOL')
+                    if re.match(r'[-+0-9.]', v): # lazy, could be tightened
+                        conflicting.add('QTYPE_QINT')
+                        conflicting.add('QTYPE_QFLOAT')
+            else:
+                conflicting.add('QTYPE_QINT')
+                conflicting.add('QTYPE_QFLOAT')
+                conflicting.add('QTYPE_QBOOL')
+        if conflicting & set(types_seen):
             raise QAPISemError(info, "Alternate '%s' member '%s' can't "
                                "be distinguished from member '%s'"
                                % (name, key, types_seen[qtype]))
-        types_seen[qtype] = key
+        for qt in conflicting:
+            types_seen[qt] = key
 
 
 def check_enum(expr, info):
diff --git a/tests/test-keyval.c b/tests/test-keyval.c
index c556b1b117..c3be00524c 100644
--- a/tests/test-keyval.c
+++ b/tests/test-keyval.c
@@ -614,22 +614,26 @@ static void test_keyval_visit_alternate(void)
     Error *err = NULL;
     Visitor *v;
     QDict *qdict;
-    AltNumStr *ans;
+    AltStrObj *aso;
     AltNumInt *ani;
+    AltEnumBool *aeb;
 
     /*
      * Can't do scalar alternate variants other than string.  You get
      * the string variant if there is one, else an error.
+     * TODO make it work for unambiguous cases like AltEnumBool below
      */
-    qdict = keyval_parse("a=1,b=2", NULL, &error_abort);
+    qdict = keyval_parse("a=1,b=2,c=on", NULL, &error_abort);
     v = qobject_input_visitor_new_keyval(QOBJECT(qdict));
     QDECREF(qdict);
     visit_start_struct(v, NULL, NULL, 0, &error_abort);
-    visit_type_AltNumStr(v, "a", &ans, &error_abort);
-    g_assert_cmpint(ans->type, ==, QTYPE_QSTRING);
-    g_assert_cmpstr(ans->u.s, ==, "1");
-    qapi_free_AltNumStr(ans);
-    visit_type_AltNumInt(v, "a", &ani, &err);
+    visit_type_AltStrObj(v, "a", &aso, &error_abort);
+    g_assert_cmpint(aso->type, ==, QTYPE_QSTRING);
+    g_assert_cmpstr(aso->u.s, ==, "1");
+    qapi_free_AltStrObj(aso);
+    visit_type_AltNumInt(v, "b", &ani, &err);
+    error_free_or_abort(&err);
+    visit_type_AltEnumBool(v, "c", &aeb, &err);
     error_free_or_abort(&err);
     visit_end_struct(v, NULL);
     visit_free(v);
diff --git a/util/keyval.c b/util/keyval.c
index 93d5db6b59..7dbda62305 100644
--- a/util/keyval.c
+++ b/util/keyval.c
@@ -65,11 +65,11 @@
  * denote numbers, true, false or null.  The special QObject input
  * visitor returned by qobject_input_visitor_new_keyval() mostly hides
  * this by automatically converting strings to the type the visitor
- * expects.  Breaks down for alternate types and type 'any', where the
- * visitor's expectation isn't clear.  Code visiting such types needs
- * to do the conversion itself, but only when using this keyval
- * visitor.  Awkward.  Alternate types without a string member don't
- * work at all.
+ * expects.  Breaks down for type 'any', where the visitor's
+ * expectation isn't clear.  Code visiting 'any' needs to do the
+ * conversion itself, but only when using this keyval visitor.
+ * Awkward.  Note that we carefully restrict alternate types to avoid
+ * similar ambiguity.
  *
  * Additional syntax for use with an implied key:
  *
diff --git a/tests/Makefile.include b/tests/Makefile.include
index 75893838e5..f42f3dfa72 100644
--- a/tests/Makefile.include
+++ b/tests/Makefile.include
@@ -342,6 +342,8 @@ qapi-schema += alternate-array.json
 qapi-schema += alternate-base.json
 qapi-schema += alternate-clash.json
 qapi-schema += alternate-conflict-dict.json
+qapi-schema += alternate-conflict-enum-bool.json
+qapi-schema += alternate-conflict-enum-int.json
 qapi-schema += alternate-conflict-string.json
 qapi-schema += alternate-empty.json
 qapi-schema += alternate-nested.json
diff --git a/tests/qapi-schema/alternate-conflict-dict.json b/tests/qapi-schema/alternate-conflict-dict.json
index d566cca816..3d7881279c 100644
--- a/tests/qapi-schema/alternate-conflict-dict.json
+++ b/tests/qapi-schema/alternate-conflict-dict.json
@@ -1,4 +1,4 @@
-# we reject alternates with multiple object branches
+# alternate branches of object type conflict with each other
 { 'struct': 'One',
   'data': { 'name': 'str' } }
 { 'struct': 'Two',
diff --git a/tests/qapi-schema/alternate-conflict-enum-bool.err b/tests/qapi-schema/alternate-conflict-enum-bool.err
new file mode 100644
index 0000000000..0dfc00242d
--- /dev/null
+++ b/tests/qapi-schema/alternate-conflict-enum-bool.err
@@ -0,0 +1 @@
+tests/qapi-schema/alternate-conflict-enum-bool.json:4: Alternate 'Alt' member 'two' can't be distinguished from member 'one'
diff --git a/tests/qapi-schema/alternate-conflict-enum-bool.exit b/tests/qapi-schema/alternate-conflict-enum-bool.exit
new file mode 100644
index 0000000000..d00491fd7e
--- /dev/null
+++ b/tests/qapi-schema/alternate-conflict-enum-bool.exit
@@ -0,0 +1 @@
+1
diff --git a/tests/qapi-schema/alternate-conflict-enum-bool.json b/tests/qapi-schema/alternate-conflict-enum-bool.json
new file mode 100644
index 0000000000..bff25c3147
--- /dev/null
+++ b/tests/qapi-schema/alternate-conflict-enum-bool.json
@@ -0,0 +1,6 @@
+# alternate branch of 'enum' type that conflicts with bool
+{ 'enum': 'Enum',
+  'data': [ 'aus', 'off' ] }
+{ 'alternate': 'Alt',
+  'data': { 'one': 'Enum',
+            'two': 'bool' } }
diff --git a/tests/qapi-schema/alternate-conflict-enum-bool.out b/tests/qapi-schema/alternate-conflict-enum-bool.out
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/tests/qapi-schema/alternate-conflict-enum-int.err b/tests/qapi-schema/alternate-conflict-enum-int.err
new file mode 100644
index 0000000000..2cc8e7b9aa
--- /dev/null
+++ b/tests/qapi-schema/alternate-conflict-enum-int.err
@@ -0,0 +1 @@
+tests/qapi-schema/alternate-conflict-enum-int.json:4: Alternate 'Alt' member 'two' can't be distinguished from member 'one'
diff --git a/tests/qapi-schema/alternate-conflict-enum-int.exit b/tests/qapi-schema/alternate-conflict-enum-int.exit
new file mode 100644
index 0000000000..d00491fd7e
--- /dev/null
+++ b/tests/qapi-schema/alternate-conflict-enum-int.exit
@@ -0,0 +1 @@
+1
diff --git a/tests/qapi-schema/alternate-conflict-enum-int.json b/tests/qapi-schema/alternate-conflict-enum-int.json
new file mode 100644
index 0000000000..beb428c10b
--- /dev/null
+++ b/tests/qapi-schema/alternate-conflict-enum-int.json
@@ -0,0 +1,6 @@
+# alternate branches of 'enum' type that conflicts with numbers
+{ 'enum': 'Enum',
+  'data': [ '1', '2', '3' ] }
+{ 'alternate': 'Alt',
+  'data': { 'one': 'Enum',
+            'two': 'int' } }
diff --git a/tests/qapi-schema/alternate-conflict-enum-int.out b/tests/qapi-schema/alternate-conflict-enum-int.out
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/tests/qapi-schema/alternate-conflict-string.err b/tests/qapi-schema/alternate-conflict-string.err
index fc523b0879..fe2f188295 100644
--- a/tests/qapi-schema/alternate-conflict-string.err
+++ b/tests/qapi-schema/alternate-conflict-string.err
@@ -1 +1 @@
-tests/qapi-schema/alternate-conflict-string.json:4: Alternate 'Alt' member 'two' can't be distinguished from member 'one'
+tests/qapi-schema/alternate-conflict-string.json:2: Alternate 'Alt' member 'two' can't be distinguished from member 'one'
diff --git a/tests/qapi-schema/alternate-conflict-string.json b/tests/qapi-schema/alternate-conflict-string.json
index 72f04a820a..85adbd4adc 100644
--- a/tests/qapi-schema/alternate-conflict-string.json
+++ b/tests/qapi-schema/alternate-conflict-string.json
@@ -1,6 +1,4 @@
-# we reject alternates with multiple string-like branches
-{ 'enum': 'Enum',
-  'data': [ 'hello', 'world' ] }
+# alternate branches of 'str' type conflict with all scalar types
 { 'alternate': 'Alt',
   'data': { 'one': 'str',
-            'two': 'Enum' } }
+            'two': 'int' } }
diff --git a/tests/qapi-schema/qapi-schema-test.json b/tests/qapi-schema/qapi-schema-test.json
index 303f2b23cd..17649c6398 100644
--- a/tests/qapi-schema/qapi-schema-test.json
+++ b/tests/qapi-schema/qapi-schema-test.json
@@ -101,12 +101,14 @@
 # for testing use of 'number' within alternates
 { 'alternate': 'AltEnumBool', 'data': { 'e': 'EnumOne', 'b': 'bool' } }
 { 'alternate': 'AltEnumNum', 'data': { 'e': 'EnumOne', 'n': 'number' } }
-{ 'alternate': 'AltNumStr', 'data': { 'n': 'number', 's': 'str' } }
 { 'alternate': 'AltNumEnum', 'data': { 'n': 'number', 'e': 'EnumOne' } }
 { 'alternate': 'AltEnumInt', 'data': { 'e': 'EnumOne', 'i': 'int' } }
 { 'alternate': 'AltIntNum', 'data': { 'i': 'int', 'n': 'number' } }
 { 'alternate': 'AltNumInt', 'data': { 'n': 'number', 'i': 'int' } }
 
+# for testing use of 'str' within alternates
+{ 'alternate': 'AltStrObj', 'data': { 's': 'str', 'o': 'TestStruct' } }
+
 # for testing native lists
 { 'union': 'UserDefNativeListUnion',
   'data': { 'integer': ['int'],
diff --git a/tests/qapi-schema/qapi-schema-test.out b/tests/qapi-schema/qapi-schema-test.out
index 3081091818..9f68610dc2 100644
--- a/tests/qapi-schema/qapi-schema-test.out
+++ b/tests/qapi-schema/qapi-schema-test.out
@@ -22,10 +22,10 @@ alternate AltNumInt
     tag type
     case n: number
     case i: int
-alternate AltNumStr
+alternate AltStrObj
     tag type
-    case n: number
     case s: str
+    case o: TestStruct
 event EVENT_A None
    boxed=False
 event EVENT_B None
-- 
2.13.0.91.g00982b8dd

^ permalink raw reply related	[flat|nested] 80+ messages in thread

* [Qemu-devel] [PATCH v2 05/45] qdev: remove PropertyInfo.qtype field
  2017-05-31 13:56 [Qemu-devel] [PATCH v2 00/45] qobject/qapi: add uint type Marc-André Lureau
                   ` (3 preceding siblings ...)
  2017-05-31 13:56 ` [Qemu-devel] [PATCH v2 04/45] qapi: Reject alternates that can't work with keyval_parse() Marc-André Lureau
@ 2017-05-31 13:56 ` Marc-André Lureau
  2017-06-01 11:19   ` Markus Armbruster
  2017-05-31 13:56 ` [Qemu-devel] [PATCH v2 06/45] object: fix potential leak in getters Marc-André Lureau
                   ` (41 subsequent siblings)
  46 siblings, 1 reply; 80+ messages in thread
From: Marc-André Lureau @ 2017-05-31 13:56 UTC (permalink / raw)
  To: qemu-devel; +Cc: armbru, Marc-André Lureau

Remove dependency on qapi qtype, replace a field by a few PropertyInfo
callbacks to set the default value type (introduced in commit 4f2d3d7).

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
 include/hw/qdev-core.h       |  2 +-
 include/hw/qdev-properties.h |  5 -----
 hw/core/qdev-properties.c    | 35 ++++++++++++++++++++++++++++++++++-
 hw/core/qdev.c               | 13 ++-----------
 4 files changed, 37 insertions(+), 18 deletions(-)

diff --git a/include/hw/qdev-core.h b/include/hw/qdev-core.h
index e69489ec6c..9523339762 100644
--- a/include/hw/qdev-core.h
+++ b/include/hw/qdev-core.h
@@ -226,7 +226,6 @@ struct Property {
     PropertyInfo *info;
     ptrdiff_t    offset;
     uint8_t      bitnr;
-    QType        qtype;
     int64_t      defval;
     int          arrayoffset;
     PropertyInfo *arrayinfo;
@@ -238,6 +237,7 @@ struct PropertyInfo {
     const char *description;
     const char * const *enum_table;
     int (*print)(DeviceState *dev, Property *prop, char *dest, size_t len);
+    void (*set_default_value)(Object *obj, const Property *prop);
     ObjectPropertyAccessor *get;
     ObjectPropertyAccessor *set;
     ObjectPropertyRelease *release;
diff --git a/include/hw/qdev-properties.h b/include/hw/qdev-properties.h
index d206fc93dd..85e68998a9 100644
--- a/include/hw/qdev-properties.h
+++ b/include/hw/qdev-properties.h
@@ -42,7 +42,6 @@ extern PropertyInfo qdev_prop_arraylen;
         .info      = &(_prop),                                          \
         .offset    = offsetof(_state, _field)                           \
             + type_check(_type,typeof_field(_state, _field)),           \
-        .qtype     = QTYPE_QINT,                                        \
         .defval    = (_type)_defval,                                    \
         }
 #define DEFINE_PROP_BIT(_name, _state, _field, _bit, _defval) {  \
@@ -51,7 +50,6 @@ extern PropertyInfo qdev_prop_arraylen;
         .bitnr    = (_bit),                                      \
         .offset    = offsetof(_state, _field)                    \
             + type_check(uint32_t,typeof_field(_state, _field)), \
-        .qtype     = QTYPE_QBOOL,                                \
         .defval    = (bool)_defval,                              \
         }
 #define DEFINE_PROP_BIT64(_name, _state, _field, _bit, _defval) {       \
@@ -60,7 +58,6 @@ extern PropertyInfo qdev_prop_arraylen;
         .bitnr    = (_bit),                                             \
         .offset    = offsetof(_state, _field)                           \
             + type_check(uint64_t, typeof_field(_state, _field)),       \
-        .qtype     = QTYPE_QBOOL,                                       \
         .defval    = (bool)_defval,                                     \
         }
 
@@ -69,7 +66,6 @@ extern PropertyInfo qdev_prop_arraylen;
         .info      = &(qdev_prop_bool),                          \
         .offset    = offsetof(_state, _field)                    \
             + type_check(bool, typeof_field(_state, _field)),    \
-        .qtype     = QTYPE_QBOOL,                                \
         .defval    = (bool)_defval,                              \
         }
 
@@ -105,7 +101,6 @@ extern PropertyInfo qdev_prop_arraylen;
         .info = &(qdev_prop_arraylen),                                  \
         .offset = offsetof(_state, _field)                              \
             + type_check(uint32_t, typeof_field(_state, _field)),       \
-        .qtype = QTYPE_QINT,                                            \
         .arrayinfo = &(_arrayprop),                                     \
         .arrayfieldsize = sizeof(_arraytype),                           \
         .arrayoffset = offsetof(_state, _arrayfield),                   \
diff --git a/hw/core/qdev-properties.c b/hw/core/qdev-properties.c
index fa3617db2d..482efb2683 100644
--- a/hw/core/qdev-properties.c
+++ b/hw/core/qdev-properties.c
@@ -69,6 +69,12 @@ static void set_enum(Object *obj, Visitor *v, const char *name, void *opaque,
     visit_type_enum(v, prop->name, ptr, prop->info->enum_table, errp);
 }
 
+static void set_default_value_enum(Object *obj, const Property *prop)
+{
+    object_property_set_str(obj, prop->info->enum_table[prop->defval],
+                            prop->name, &error_abort);
+}
+
 /* Bit */
 
 static uint32_t qdev_get_prop_mask(Property *prop)
@@ -120,11 +126,17 @@ static void prop_set_bit(Object *obj, Visitor *v, const char *name,
     bit_prop_set(dev, prop, value);
 }
 
+static void set_default_value_bool(Object *obj, const Property *prop)
+{
+    object_property_set_bool(obj, prop->defval, prop->name, &error_abort);
+}
+
 PropertyInfo qdev_prop_bit = {
     .name  = "bool",
     .description = "on/off",
     .get   = prop_get_bit,
     .set   = prop_set_bit,
+    .set_default_value = set_default_value_bool,
 };
 
 /* Bit64 */
@@ -183,6 +195,7 @@ PropertyInfo qdev_prop_bit64 = {
     .description = "on/off",
     .get   = prop_get_bit64,
     .set   = prop_set_bit64,
+    .set_default_value = set_default_value_bool,
 };
 
 /* --- bool --- */
@@ -216,6 +229,7 @@ PropertyInfo qdev_prop_bool = {
     .name  = "bool",
     .get   = get_bool,
     .set   = set_bool,
+    .set_default_value = set_default_value_bool,
 };
 
 /* --- 8bit integer --- */
@@ -245,10 +259,16 @@ static void set_uint8(Object *obj, Visitor *v, const char *name, void *opaque,
     visit_type_uint8(v, name, ptr, errp);
 }
 
+static void set_default_value_int(Object *obj, const Property *prop)
+{
+    object_property_set_int(obj, prop->defval, prop->name, &error_abort);
+}
+
 PropertyInfo qdev_prop_uint8 = {
     .name  = "uint8",
     .get   = get_uint8,
     .set   = set_uint8,
+    .set_default_value = set_default_value_int,
 };
 
 /* --- 16bit integer --- */
@@ -282,6 +302,7 @@ PropertyInfo qdev_prop_uint16 = {
     .name  = "uint16",
     .get   = get_uint16,
     .set   = set_uint16,
+    .set_default_value = set_default_value_int,
 };
 
 /* --- 32bit integer --- */
@@ -340,12 +361,14 @@ PropertyInfo qdev_prop_uint32 = {
     .name  = "uint32",
     .get   = get_uint32,
     .set   = set_uint32,
+    .set_default_value = set_default_value_int,
 };
 
 PropertyInfo qdev_prop_int32 = {
     .name  = "int32",
     .get   = get_int32,
     .set   = set_int32,
+    .set_default_value = set_default_value_int,
 };
 
 /* --- 64bit integer --- */
@@ -379,6 +402,7 @@ PropertyInfo qdev_prop_uint64 = {
     .name  = "uint64",
     .get   = get_uint64,
     .set   = set_uint64,
+    .set_default_value = set_default_value_int,
 };
 
 /* --- string --- */
@@ -526,6 +550,7 @@ PropertyInfo qdev_prop_on_off_auto = {
     .enum_table = OnOffAuto_lookup,
     .get = get_enum,
     .set = set_enum,
+    .set_default_value = set_default_value_enum,
 };
 
 /* --- lost tick policy --- */
@@ -537,6 +562,7 @@ PropertyInfo qdev_prop_losttickpolicy = {
     .enum_table  = LostTickPolicy_lookup,
     .get   = get_enum,
     .set   = set_enum,
+    .set_default_value = set_default_value_enum,
 };
 
 /* --- Block device error handling policy --- */
@@ -550,6 +576,7 @@ PropertyInfo qdev_prop_blockdev_on_error = {
     .enum_table = BlockdevOnError_lookup,
     .get = get_enum,
     .set = set_enum,
+    .set_default_value = set_default_value_enum,
 };
 
 /* --- BIOS CHS translation */
@@ -563,6 +590,7 @@ PropertyInfo qdev_prop_bios_chs_trans = {
     .enum_table = BiosAtaTranslation_lookup,
     .get = get_enum,
     .set = set_enum,
+    .set_default_value = set_default_value_enum,
 };
 
 /* --- FDC default drive types */
@@ -573,7 +601,8 @@ PropertyInfo qdev_prop_fdc_drive_type = {
                    "144/288/120/none/auto",
     .enum_table = FloppyDriveType_lookup,
     .get = get_enum,
-    .set = set_enum
+    .set = set_enum,
+    .set_default_value = set_default_value_enum,
 };
 
 /* --- pci address --- */
@@ -648,6 +677,7 @@ PropertyInfo qdev_prop_pci_devfn = {
     .print = print_pci_devfn,
     .get   = get_int32,
     .set   = set_pci_devfn,
+    .set_default_value = set_default_value_int,
 };
 
 /* --- blocksize --- */
@@ -695,6 +725,7 @@ PropertyInfo qdev_prop_blocksize = {
     .description = "A power of two between 512 and 32768",
     .get   = get_uint16,
     .set   = set_blocksize,
+    .set_default_value = set_default_value_int,
 };
 
 /* --- pci host address --- */
@@ -917,6 +948,7 @@ PropertyInfo qdev_prop_arraylen = {
     .name = "uint32",
     .get = get_uint32,
     .set = set_prop_arraylen,
+    .set_default_value = set_default_value_int,
 };
 
 /* --- public helpers --- */
@@ -1153,4 +1185,5 @@ PropertyInfo qdev_prop_size = {
     .name  = "size",
     .get = get_size,
     .set = set_size,
+    .set_default_value = set_default_value_int,
 };
diff --git a/hw/core/qdev.c b/hw/core/qdev.c
index 71ff95fd71..6674e11840 100644
--- a/hw/core/qdev.c
+++ b/hw/core/qdev.c
@@ -794,17 +794,8 @@ void qdev_property_add_static(DeviceState *dev, Property *prop,
                                     prop->info->description,
                                     &error_abort);
 
-    if (prop->qtype == QTYPE_NONE) {
-        return;
-    }
-
-    if (prop->qtype == QTYPE_QBOOL) {
-        object_property_set_bool(obj, prop->defval, prop->name, &error_abort);
-    } else if (prop->info->enum_table) {
-        object_property_set_str(obj, prop->info->enum_table[prop->defval],
-                                prop->name, &error_abort);
-    } else if (prop->qtype == QTYPE_QINT) {
-        object_property_set_int(obj, prop->defval, prop->name, &error_abort);
+    if (prop->info->set_default_value) {
+        prop->info->set_default_value(obj, prop);
     }
 }
 
-- 
2.13.0.91.g00982b8dd

^ permalink raw reply related	[flat|nested] 80+ messages in thread

* [Qemu-devel] [PATCH v2 06/45] object: fix potential leak in getters
  2017-05-31 13:56 [Qemu-devel] [PATCH v2 00/45] qobject/qapi: add uint type Marc-André Lureau
                   ` (4 preceding siblings ...)
  2017-05-31 13:56 ` [Qemu-devel] [PATCH v2 05/45] qdev: remove PropertyInfo.qtype field Marc-André Lureau
@ 2017-05-31 13:56 ` Marc-André Lureau
  2017-06-01 11:32   ` Markus Armbruster
  2017-05-31 13:56 ` [Qemu-devel] [PATCH v2 07/45] tests: remove alt num-int cases Marc-André Lureau
                   ` (40 subsequent siblings)
  46 siblings, 1 reply; 80+ messages in thread
From: Marc-André Lureau @ 2017-05-31 13:56 UTC (permalink / raw)
  To: qemu-devel; +Cc: armbru, Marc-André Lureau

If the property is not of the requested type, the getters will leak a
QObject.

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
 qom/object.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/qom/object.c b/qom/object.c
index eb4bc924ff..c7b8079df6 100644
--- a/qom/object.c
+++ b/qom/object.c
@@ -1122,7 +1122,7 @@ char *object_property_get_str(Object *obj, const char *name,
         retval = g_strdup(qstring_get_str(qstring));
     }
 
-    QDECREF(qstring);
+    qobject_decref(ret);
     return retval;
 }
 
@@ -1183,7 +1183,7 @@ bool object_property_get_bool(Object *obj, const char *name,
         retval = qbool_get_bool(qbool);
     }
 
-    QDECREF(qbool);
+    qobject_decref(ret);
     return retval;
 }
 
@@ -1214,7 +1214,7 @@ int64_t object_property_get_int(Object *obj, const char *name,
         retval = qint_get_int(qint);
     }
 
-    QDECREF(qint);
+    qobject_decref(ret);
     return retval;
 }
 
-- 
2.13.0.91.g00982b8dd

^ permalink raw reply related	[flat|nested] 80+ messages in thread

* [Qemu-devel] [PATCH v2 07/45] tests: remove alt num-int cases
  2017-05-31 13:56 [Qemu-devel] [PATCH v2 00/45] qobject/qapi: add uint type Marc-André Lureau
                   ` (5 preceding siblings ...)
  2017-05-31 13:56 ` [Qemu-devel] [PATCH v2 06/45] object: fix potential leak in getters Marc-André Lureau
@ 2017-05-31 13:56 ` Marc-André Lureau
  2017-06-01 11:58   ` Markus Armbruster
  2017-05-31 13:56 ` [Qemu-devel] [PATCH v2 08/45] tests: add more int/number ranges checks Marc-André Lureau
                   ` (39 subsequent siblings)
  46 siblings, 1 reply; 80+ messages in thread
From: Marc-André Lureau @ 2017-05-31 13:56 UTC (permalink / raw)
  To: qemu-devel; +Cc: armbru

From: Markus Armbruster <armbru@redhat.com>

Marc-André Lureau <marcandre.lureau@redhat.com> writes:

> There are no real users of this case, and it's going to be invalid after
> merging of QFloat and QInt use the same QNum type in the following patch.

Invalid because our alternate code is insufficiently sophisticated.  In
other words fixable.  See "[PATCH 4/4] qapi: Reject alternates that
can't work with keyval_parse()" I just posted.

My patch's commit message describes two related issues, one fixable and
one unfixable.  The fixable one already exists, but only in QGA.  I
intend to fix it, but it's not a priority.

Fixing the issue you describe seems even less important.  I considered
outlawing it in my series (patch appended for your reading pleasure),
but decided to leave it to yours.  I don't expect you to replace your
patch.  Perhaps my patch helps you with rebasing yours should that
become necessary.

Message-Id: <87tw4cn7sh.fsf@dusky.pond.sub.org>
---
 scripts/qapi.py                         |  4 ++++
 tests/test-keyval.c                     |  4 ++--
 tests/test-qobject-input-visitor.c      | 26 --------------------------
 tests/qapi-schema/qapi-schema-test.json |  2 --
 tests/qapi-schema/qapi-schema-test.out  |  8 --------
 5 files changed, 6 insertions(+), 38 deletions(-)

diff --git a/scripts/qapi.py b/scripts/qapi.py
index b7a25e4759..06e583d8c3 100644
--- a/scripts/qapi.py
+++ b/scripts/qapi.py
@@ -826,6 +826,10 @@ def check_alternate(expr, info):
                 conflicting.add('QTYPE_QINT')
                 conflicting.add('QTYPE_QFLOAT')
                 conflicting.add('QTYPE_QBOOL')
+        elif qtype == 'QTYPE_QINT':
+            conflicting.add('QTYPE_QFLOAT')
+        elif qtype == 'QTYPE_QFLOAT':
+            conflicting.add('QTYPE_QINT')
         if conflicting & set(types_seen):
             raise QAPISemError(info, "Alternate '%s' member '%s' can't "
                                "be distinguished from member '%s'"
diff --git a/tests/test-keyval.c b/tests/test-keyval.c
index c3be00524c..baf7e339ab 100644
--- a/tests/test-keyval.c
+++ b/tests/test-keyval.c
@@ -615,7 +615,7 @@ static void test_keyval_visit_alternate(void)
     Visitor *v;
     QDict *qdict;
     AltStrObj *aso;
-    AltNumInt *ani;
+    AltNumEnum *ane;
     AltEnumBool *aeb;
 
     /*
@@ -631,7 +631,7 @@ static void test_keyval_visit_alternate(void)
     g_assert_cmpint(aso->type, ==, QTYPE_QSTRING);
     g_assert_cmpstr(aso->u.s, ==, "1");
     qapi_free_AltStrObj(aso);
-    visit_type_AltNumInt(v, "b", &ani, &err);
+    visit_type_AltNumEnum(v, "b", &ane, &err);
     error_free_or_abort(&err);
     visit_type_AltEnumBool(v, "c", &aeb, &err);
     error_free_or_abort(&err);
diff --git a/tests/test-qobject-input-visitor.c b/tests/test-qobject-input-visitor.c
index 6b997a177d..83d663d11d 100644
--- a/tests/test-qobject-input-visitor.c
+++ b/tests/test-qobject-input-visitor.c
@@ -592,8 +592,6 @@ static void test_visitor_in_alternate_number(TestInputVisitorData *data,
     AltEnumNum *aen;
     AltNumEnum *ans;
     AltEnumInt *asi;
-    AltIntNum *ain;
-    AltNumInt *ani;
 
     /* Parsing an int */
 
@@ -620,18 +618,6 @@ static void test_visitor_in_alternate_number(TestInputVisitorData *data,
     g_assert_cmpint(asi->u.i, ==, 42);
     qapi_free_AltEnumInt(asi);
 
-    v = visitor_input_test_init(data, "42");
-    visit_type_AltIntNum(v, NULL, &ain, &error_abort);
-    g_assert_cmpint(ain->type, ==, QTYPE_QINT);
-    g_assert_cmpint(ain->u.i, ==, 42);
-    qapi_free_AltIntNum(ain);
-
-    v = visitor_input_test_init(data, "42");
-    visit_type_AltNumInt(v, NULL, &ani, &error_abort);
-    g_assert_cmpint(ani->type, ==, QTYPE_QINT);
-    g_assert_cmpint(ani->u.i, ==, 42);
-    qapi_free_AltNumInt(ani);
-
     /* Parsing a double */
 
     v = visitor_input_test_init(data, "42.5");
@@ -655,18 +641,6 @@ static void test_visitor_in_alternate_number(TestInputVisitorData *data,
     visit_type_AltEnumInt(v, NULL, &asi, &err);
     error_free_or_abort(&err);
     qapi_free_AltEnumInt(asi);
-
-    v = visitor_input_test_init(data, "42.5");
-    visit_type_AltIntNum(v, NULL, &ain, &error_abort);
-    g_assert_cmpint(ain->type, ==, QTYPE_QFLOAT);
-    g_assert_cmpfloat(ain->u.n, ==, 42.5);
-    qapi_free_AltIntNum(ain);
-
-    v = visitor_input_test_init(data, "42.5");
-    visit_type_AltNumInt(v, NULL, &ani, &error_abort);
-    g_assert_cmpint(ani->type, ==, QTYPE_QFLOAT);
-    g_assert_cmpfloat(ani->u.n, ==, 42.5);
-    qapi_free_AltNumInt(ani);
 }
 
 static void test_native_list_integer_helper(TestInputVisitorData *data,
diff --git a/tests/qapi-schema/qapi-schema-test.json b/tests/qapi-schema/qapi-schema-test.json
index 17649c6398..91ffb2648c 100644
--- a/tests/qapi-schema/qapi-schema-test.json
+++ b/tests/qapi-schema/qapi-schema-test.json
@@ -103,8 +103,6 @@
 { 'alternate': 'AltEnumNum', 'data': { 'e': 'EnumOne', 'n': 'number' } }
 { 'alternate': 'AltNumEnum', 'data': { 'n': 'number', 'e': 'EnumOne' } }
 { 'alternate': 'AltEnumInt', 'data': { 'e': 'EnumOne', 'i': 'int' } }
-{ 'alternate': 'AltIntNum', 'data': { 'i': 'int', 'n': 'number' } }
-{ 'alternate': 'AltNumInt', 'data': { 'n': 'number', 'i': 'int' } }
 
 # for testing use of 'str' within alternates
 { 'alternate': 'AltStrObj', 'data': { 's': 'str', 'o': 'TestStruct' } }
diff --git a/tests/qapi-schema/qapi-schema-test.out b/tests/qapi-schema/qapi-schema-test.out
index 9f68610dc2..e727a5a84c 100644
--- a/tests/qapi-schema/qapi-schema-test.out
+++ b/tests/qapi-schema/qapi-schema-test.out
@@ -10,18 +10,10 @@ alternate AltEnumNum
     tag type
     case e: EnumOne
     case n: number
-alternate AltIntNum
-    tag type
-    case i: int
-    case n: number
 alternate AltNumEnum
     tag type
     case n: number
     case e: EnumOne
-alternate AltNumInt
-    tag type
-    case n: number
-    case i: int
 alternate AltStrObj
     tag type
     case s: str
-- 
2.13.0.91.g00982b8dd

^ permalink raw reply related	[flat|nested] 80+ messages in thread

* [Qemu-devel] [PATCH v2 08/45] tests: add more int/number ranges checks
  2017-05-31 13:56 [Qemu-devel] [PATCH v2 00/45] qobject/qapi: add uint type Marc-André Lureau
                   ` (6 preceding siblings ...)
  2017-05-31 13:56 ` [Qemu-devel] [PATCH v2 07/45] tests: remove alt num-int cases Marc-André Lureau
@ 2017-05-31 13:56 ` Marc-André Lureau
  2017-06-01 14:09   ` Markus Armbruster
  2017-05-31 13:56 ` [Qemu-devel] [PATCH v2 09/45] qapi: merge QInt and QFloat in QNum Marc-André Lureau
                   ` (38 subsequent siblings)
  46 siblings, 1 reply; 80+ messages in thread
From: Marc-André Lureau @ 2017-05-31 13:56 UTC (permalink / raw)
  To: qemu-devel; +Cc: armbru, Marc-André Lureau

Suggested by Markus Armbruster:

We should systematically cover the integers, in particular the
boundaries (because that's where bugs like to hide):

* Integers in [-2^63,0) can be visited with visit_type_int() and
  visit_type_number().

* Integers in [0,2^63) can be visited with visit_type_int(),
  visit_type_uint64() and visit_type_number().

* Integers in [2^63,2^64) can be visited with visit_type_uint64() and
  visit_type_number().

* Integers outside [-2^63,2^53) can be visited with visit_type_number().

In any case, visit_type_number() loses precision beyond 53 bits.

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
 tests/test-qobject-input-visitor.c | 38 ++++++++++++++++++++++++++++++++++++--
 1 file changed, 36 insertions(+), 2 deletions(-)

diff --git a/tests/test-qobject-input-visitor.c b/tests/test-qobject-input-visitor.c
index 83d663d11d..f2ed3161af 100644
--- a/tests/test-qobject-input-visitor.c
+++ b/tests/test-qobject-input-visitor.c
@@ -102,11 +102,11 @@ static Visitor *visitor_input_test_init_raw(TestInputVisitorData *data,
 {
     return visitor_input_test_init_internal(data, false, json_string, NULL);
 }
-
 static void test_visitor_in_int(TestInputVisitorData *data,
                                 const void *unused)
 {
     int64_t res = 0;
+    double dbl;
     int value = -42;
     Visitor *v;
 
@@ -114,6 +114,9 @@ static void test_visitor_in_int(TestInputVisitorData *data,
 
     visit_type_int(v, NULL, &res, &error_abort);
     g_assert_cmpint(res, ==, value);
+
+    visit_type_number(v, NULL, &dbl, &error_abort);
+    g_assert_cmpfloat(dbl, ==, -42.0);
 }
 
 static void test_visitor_in_uint(TestInputVisitorData *data,
@@ -121,6 +124,8 @@ static void test_visitor_in_uint(TestInputVisitorData *data,
 {
     Error *err = NULL;
     uint64_t res = 0;
+    int64_t i64;
+    double dbl;
     int value = 42;
     Visitor *v;
 
@@ -129,8 +134,13 @@ static void test_visitor_in_uint(TestInputVisitorData *data,
     visit_type_uint64(v, NULL, &res, &error_abort);
     g_assert_cmpuint(res, ==, (uint64_t)value);
 
-    /* BUG: value between INT64_MIN and -1 accepted modulo 2^64 */
+    visit_type_int(v, NULL, &i64, &error_abort);
+    g_assert_cmpint(i64, ==, value);
 
+    visit_type_number(v, NULL, &dbl, &error_abort);
+    g_assert_cmpfloat(dbl, ==, value);
+
+    /* BUG: value between INT64_MIN and -1 accepted modulo 2^64 */
     v = visitor_input_test_init(data, "%d", -value);
 
     visit_type_uint64(v, NULL, &res, &error_abort);
@@ -142,6 +152,8 @@ static void test_visitor_in_uint(TestInputVisitorData *data,
 
     visit_type_uint64(v, NULL, &res, &err);
     error_free_or_abort(&err);
+
+    visit_type_number(v, NULL, &dbl, &error_abort);
 }
 
 static void test_visitor_in_int_overflow(TestInputVisitorData *data,
@@ -260,6 +272,26 @@ static void test_visitor_in_number(TestInputVisitorData *data,
     g_assert_cmpfloat(res, ==, value);
 }
 
+static void test_visitor_in_large_number(TestInputVisitorData *data,
+                                         const void *unused)
+{
+    Error *err = NULL;
+    double res = 0;
+    int64_t i64;
+    uint64_t u64;
+    Visitor *v;
+
+    v = visitor_input_test_init(data, "-18446744073709551616"); /* -2^64 */
+
+    visit_type_number(v, NULL, &res, &error_abort);
+
+    visit_type_int(v, NULL, &i64, &err);
+    error_free_or_abort(&err);
+
+    visit_type_uint64(v, NULL, &u64, &err);
+    error_free_or_abort(&err);
+}
+
 static void test_visitor_in_number_keyval(TestInputVisitorData *data,
                                           const void *unused)
 {
@@ -1253,6 +1285,8 @@ int main(int argc, char **argv)
                            NULL, test_visitor_in_bool_str_fail);
     input_visitor_test_add("/visitor/input/number",
                            NULL, test_visitor_in_number);
+    input_visitor_test_add("/visitor/input/large_number",
+                           NULL, test_visitor_in_large_number);
     input_visitor_test_add("/visitor/input/number_keyval",
                            NULL, test_visitor_in_number_keyval);
     input_visitor_test_add("/visitor/input/number_str_keyval",
-- 
2.13.0.91.g00982b8dd

^ permalink raw reply related	[flat|nested] 80+ messages in thread

* [Qemu-devel] [PATCH v2 09/45] qapi: merge QInt and QFloat in QNum
  2017-05-31 13:56 [Qemu-devel] [PATCH v2 00/45] qobject/qapi: add uint type Marc-André Lureau
                   ` (7 preceding siblings ...)
  2017-05-31 13:56 ` [Qemu-devel] [PATCH v2 08/45] tests: add more int/number ranges checks Marc-André Lureau
@ 2017-05-31 13:56 ` Marc-André Lureau
  2017-06-02  7:03   ` Markus Armbruster
  2017-05-31 13:56 ` [Qemu-devel] [PATCH v2 10/45] qapi: Remove visit_start_alternate() parameter promote_int Marc-André Lureau
                   ` (37 subsequent siblings)
  46 siblings, 1 reply; 80+ messages in thread
From: Marc-André Lureau @ 2017-05-31 13:56 UTC (permalink / raw)
  To: qemu-devel; +Cc: armbru, Marc-André Lureau

We would like to use a same QObject type to represent numbers, whether
they are int, uint, or floats. Getters will allow some compatibility
between the various types if the number fits other representations.

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
 scripts/qapi.py                          |  40 ++++-----
 scripts/qapi-visit.py                    |   2 +-
 include/qapi/qmp/qdict.h                 |   3 +-
 include/qapi/qmp/qfloat.h                |  29 -------
 include/qapi/qmp/qint.h                  |  28 ------
 include/qapi/qmp/qlist.h                 |   3 +-
 include/qapi/qmp/qnum.h                  |  44 ++++++++++
 include/qapi/qmp/types.h                 |   3 +-
 include/qapi/qobject-input-visitor.h     |   6 +-
 include/qapi/qobject-output-visitor.h    |   8 +-
 block/blkdebug.c                         |   1 -
 block/nbd.c                              |   1 -
 block/nfs.c                              |   1 -
 block/qapi.c                             |  13 ++-
 block/quorum.c                           |   1 -
 block/sheepdog.c                         |   1 -
 block/ssh.c                              |   1 -
 block/vvfat.c                            |   1 -
 blockdev.c                               |   8 +-
 hw/acpi/pcihp.c                          |   1 -
 hw/i386/acpi-build.c                     |  41 +++++++--
 hw/usb/xen-usb.c                         |   1 -
 monitor.c                                |   2 +-
 qapi/qobject-input-visitor.c             |  41 +++------
 qapi/qobject-output-visitor.c            |   6 +-
 qga/commands.c                           |   2 +-
 qga/main.c                               |   1 -
 qobject/json-parser.c                    |  29 +++----
 qobject/qdict.c                          |  43 +++++-----
 qobject/qfloat.c                         |  62 --------------
 qobject/qint.c                           |  61 -------------
 qobject/qjson.c                          |  37 +-------
 qobject/qnum.c                           | 141 +++++++++++++++++++++++++++++++
 qobject/qobject.c                        |   3 +-
 qom/object.c                             |  16 ++--
 target/i386/cpu.c                        |   6 +-
 tests/check-qdict.c                      |  30 ++++---
 tests/check-qfloat.c                     |  53 ------------
 tests/check-qint.c                       |  87 -------------------
 tests/check-qjson.c                      |  91 +++++++++++---------
 tests/check-qlist.c                      |  18 ++--
 tests/check-qnum.c                       | 133 +++++++++++++++++++++++++++++
 tests/test-qmp-commands.c                |   8 +-
 tests/test-qmp-event.c                   |   9 +-
 tests/test-qobject-input-visitor.c       |  33 ++++----
 tests/test-qobject-output-visitor.c      |  66 +++++++++------
 tests/test-x86-cpuid-compat.c            |  20 +++--
 ui/spice-core.c                          |   1 -
 ui/vnc-enc-tight.c                       |   1 -
 util/qemu-option.c                       |  20 ++---
 MAINTAINERS                              |   3 +-
 qobject/Makefile.objs                    |   2 +-
 scripts/coccinelle/qobject.cocci         |   4 +-
 tests/.gitignore                         |   3 +-
 tests/Makefile.include                   |  13 ++-
 tests/qapi-schema/comments.out           |   2 +-
 tests/qapi-schema/doc-good.out           |   2 +-
 tests/qapi-schema/empty.out              |   2 +-
 tests/qapi-schema/event-case.out         |   2 +-
 tests/qapi-schema/ident-with-escape.out  |   2 +-
 tests/qapi-schema/include-relpath.out    |   2 +-
 tests/qapi-schema/include-repetition.out |   2 +-
 tests/qapi-schema/include-simple.out     |   2 +-
 tests/qapi-schema/indented-expr.out      |   2 +-
 tests/qapi-schema/qapi-schema-test.out   |   2 +-
 65 files changed, 637 insertions(+), 665 deletions(-)
 delete mode 100644 include/qapi/qmp/qfloat.h
 delete mode 100644 include/qapi/qmp/qint.h
 create mode 100644 include/qapi/qmp/qnum.h
 delete mode 100644 qobject/qfloat.c
 delete mode 100644 qobject/qint.c
 create mode 100644 qobject/qnum.c
 delete mode 100644 tests/check-qfloat.c
 delete mode 100644 tests/check-qint.c
 create mode 100644 tests/check-qnum.c

diff --git a/scripts/qapi.py b/scripts/qapi.py
index 06e583d8c3..0de809f56b 100644
--- a/scripts/qapi.py
+++ b/scripts/qapi.py
@@ -21,18 +21,18 @@ from ordereddict import OrderedDict
 
 builtin_types = {
     'str':      'QTYPE_QSTRING',
-    'int':      'QTYPE_QINT',
-    'number':   'QTYPE_QFLOAT',
+    'int':      'QTYPE_QNUM',
+    'number':   'QTYPE_QNUM',
     'bool':     'QTYPE_QBOOL',
-    'int8':     'QTYPE_QINT',
-    'int16':    'QTYPE_QINT',
-    'int32':    'QTYPE_QINT',
-    'int64':    'QTYPE_QINT',
-    'uint8':    'QTYPE_QINT',
-    'uint16':   'QTYPE_QINT',
-    'uint32':   'QTYPE_QINT',
-    'uint64':   'QTYPE_QINT',
-    'size':     'QTYPE_QINT',
+    'int8':     'QTYPE_QNUM',
+    'int16':    'QTYPE_QNUM',
+    'int32':    'QTYPE_QNUM',
+    'int64':    'QTYPE_QNUM',
+    'uint8':    'QTYPE_QNUM',
+    'uint16':   'QTYPE_QNUM',
+    'uint32':   'QTYPE_QNUM',
+    'uint64':   'QTYPE_QNUM',
+    'size':     'QTYPE_QNUM',
     'any':      None,           # any QType possible, actually
     'QType':    'QTYPE_QSTRING',
 }
@@ -820,16 +820,10 @@ def check_alternate(expr, info):
                     if v in ['on', 'off']:
                         conflicting.add('QTYPE_QBOOL')
                     if re.match(r'[-+0-9.]', v): # lazy, could be tightened
-                        conflicting.add('QTYPE_QINT')
-                        conflicting.add('QTYPE_QFLOAT')
+                        conflicting.add('QTYPE_QNUM')
             else:
-                conflicting.add('QTYPE_QINT')
-                conflicting.add('QTYPE_QFLOAT')
+                conflicting.add('QTYPE_QNUM')
                 conflicting.add('QTYPE_QBOOL')
-        elif qtype == 'QTYPE_QINT':
-            conflicting.add('QTYPE_QFLOAT')
-        elif qtype == 'QTYPE_QFLOAT':
-            conflicting.add('QTYPE_QINT')
         if conflicting & set(types_seen):
             raise QAPISemError(info, "Alternate '%s' member '%s' can't "
                                "be distinguished from member '%s'"
@@ -1063,8 +1057,8 @@ class QAPISchemaType(QAPISchemaEntity):
     def alternate_qtype(self):
         json2qtype = {
             'string':  'QTYPE_QSTRING',
-            'number':  'QTYPE_QFLOAT',
-            'int':     'QTYPE_QINT',
+            'number':  'QTYPE_QNUM',
+            'int':     'QTYPE_QNUM',
             'boolean': 'QTYPE_QBOOL',
             'object':  'QTYPE_QDICT'
         }
@@ -1526,9 +1520,9 @@ class QAPISchema(object):
         self.the_empty_object_type = QAPISchemaObjectType(
             'q_empty', None, None, None, [], None)
         self._def_entity(self.the_empty_object_type)
-        qtype_values = self._make_enum_members(['none', 'qnull', 'qint',
+        qtype_values = self._make_enum_members(['none', 'qnull', 'qnum',
                                                 'qstring', 'qdict', 'qlist',
-                                                'qfloat', 'qbool'])
+                                                'qbool'])
         self._def_entity(QAPISchemaEnumType('QType', None, None,
                                             qtype_values, 'QTYPE'))
 
diff --git a/scripts/qapi-visit.py b/scripts/qapi-visit.py
index 5737aefa05..cc447ecacc 100644
--- a/scripts/qapi-visit.py
+++ b/scripts/qapi-visit.py
@@ -164,7 +164,7 @@ def gen_visit_alternate(name, variants):
     promote_int = 'true'
     ret = ''
     for var in variants.variants:
-        if var.type.alternate_qtype() == 'QTYPE_QINT':
+        if var.type.alternate_qtype() == 'QTYPE_QNUM':
             promote_int = 'false'
 
     ret += mcgen('''
diff --git a/include/qapi/qmp/qdict.h b/include/qapi/qmp/qdict.h
index 188440a6a8..363e431106 100644
--- a/include/qapi/qmp/qdict.h
+++ b/include/qapi/qmp/qdict.h
@@ -15,6 +15,7 @@
 
 #include "qapi/qmp/qobject.h"
 #include "qapi/qmp/qlist.h"
+#include "qapi/qmp/qnum.h"
 #include "qemu/queue.h"
 
 #define QDICT_BUCKET_MAX 512
@@ -54,7 +55,7 @@ void qdict_destroy_obj(QObject *obj);
 
 /* Helpers for int, bool, and string */
 #define qdict_put_int(qdict, key, value) \
-        qdict_put(qdict, key, qint_from_int(value))
+        qdict_put(qdict, key, qnum_from_int(value))
 #define qdict_put_bool(qdict, key, value) \
         qdict_put(qdict, key, qbool_from_bool(value))
 #define qdict_put_str(qdict, key, value) \
diff --git a/include/qapi/qmp/qfloat.h b/include/qapi/qmp/qfloat.h
deleted file mode 100644
index b5d15836b5..0000000000
--- a/include/qapi/qmp/qfloat.h
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * QFloat Module
- *
- * Copyright IBM, Corp. 2009
- *
- * Authors:
- *  Anthony Liguori   <aliguori@us.ibm.com>
- *
- * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
- * See the COPYING.LIB file in the top-level directory.
- *
- */
-
-#ifndef QFLOAT_H
-#define QFLOAT_H
-
-#include "qapi/qmp/qobject.h"
-
-typedef struct QFloat {
-    QObject base;
-    double value;
-} QFloat;
-
-QFloat *qfloat_from_double(double value);
-double qfloat_get_double(const QFloat *qi);
-QFloat *qobject_to_qfloat(const QObject *obj);
-void qfloat_destroy_obj(QObject *obj);
-
-#endif /* QFLOAT_H */
diff --git a/include/qapi/qmp/qint.h b/include/qapi/qmp/qint.h
deleted file mode 100644
index 3aaff768dd..0000000000
--- a/include/qapi/qmp/qint.h
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * QInt Module
- *
- * Copyright (C) 2009 Red Hat Inc.
- *
- * Authors:
- *  Luiz Capitulino <lcapitulino@redhat.com>
- *
- * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
- * See the COPYING.LIB file in the top-level directory.
- */
-
-#ifndef QINT_H
-#define QINT_H
-
-#include "qapi/qmp/qobject.h"
-
-typedef struct QInt {
-    QObject base;
-    int64_t value;
-} QInt;
-
-QInt *qint_from_int(int64_t value);
-int64_t qint_get_int(const QInt *qi);
-QInt *qobject_to_qint(const QObject *obj);
-void qint_destroy_obj(QObject *obj);
-
-#endif /* QINT_H */
diff --git a/include/qapi/qmp/qlist.h b/include/qapi/qmp/qlist.h
index 5dc4ed9616..c4b5fdad9b 100644
--- a/include/qapi/qmp/qlist.h
+++ b/include/qapi/qmp/qlist.h
@@ -14,6 +14,7 @@
 #define QLIST_H
 
 #include "qapi/qmp/qobject.h"
+#include "qapi/qmp/qnum.h"
 #include "qemu/queue.h"
 
 typedef struct QListEntry {
@@ -31,7 +32,7 @@ typedef struct QList {
 
 /* Helpers for int, bool, and string */
 #define qlist_append_int(qlist, value) \
-        qlist_append(qlist, qint_from_int(value))
+        qlist_append(qlist, qnum_from_int(value))
 #define qlist_append_bool(qlist, value) \
         qlist_append(qlist, qbool_from_bool(value))
 #define qlist_append_str(qlist, value) \
diff --git a/include/qapi/qmp/qnum.h b/include/qapi/qmp/qnum.h
new file mode 100644
index 0000000000..cc636fac5f
--- /dev/null
+++ b/include/qapi/qmp/qnum.h
@@ -0,0 +1,44 @@
+/*
+ * QNum Module
+ *
+ * Copyright (C) 2009 Red Hat Inc.
+ *
+ * Authors:
+ *  Luiz Capitulino <lcapitulino@redhat.com>
+ *  Marc-André Lureau <marcandre.lureau@redhat.com>
+ *
+ * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
+ * See the COPYING.LIB file in the top-level directory.
+ */
+
+#ifndef QNUM_H
+#define QNUM_H
+
+#include "qapi/qmp/qobject.h"
+
+typedef enum {
+    QNUM_I64,
+    QNUM_DOUBLE
+} QNumKind;
+
+typedef struct QNum {
+    QObject base;
+    QNumKind kind;
+    union {
+        int64_t i64;
+        double dbl;
+    } u;
+} QNum;
+
+QNum *qnum_from_int(int64_t value);
+QNum *qnum_from_double(double value);
+
+bool qnum_get_int(const QNum *qn, int64_t *val);
+double qnum_get_double(QNum *qn);
+
+char *qnum_to_string(QNum *qn);
+
+QNum *qobject_to_qnum(const QObject *obj);
+void qnum_destroy_obj(QObject *obj);
+
+#endif /* QNUM_H */
diff --git a/include/qapi/qmp/types.h b/include/qapi/qmp/types.h
index 27cfbd84e5..a4bc662bfb 100644
--- a/include/qapi/qmp/types.h
+++ b/include/qapi/qmp/types.h
@@ -14,8 +14,7 @@
 #define QAPI_QMP_TYPES_H
 
 #include "qapi/qmp/qobject.h"
-#include "qapi/qmp/qint.h"
-#include "qapi/qmp/qfloat.h"
+#include "qapi/qmp/qnum.h"
 #include "qapi/qmp/qbool.h"
 #include "qapi/qmp/qstring.h"
 #include "qapi/qmp/qdict.h"
diff --git a/include/qapi/qobject-input-visitor.h b/include/qapi/qobject-input-visitor.h
index b399285c43..daee18c6ac 100644
--- a/include/qapi/qobject-input-visitor.h
+++ b/include/qapi/qobject-input-visitor.h
@@ -30,9 +30,9 @@ typedef struct QObjectInputVisitor QObjectInputVisitor;
  * visit_type_FOO() creates an instance of QAPI type FOO.  The visited
  * QObject must match FOO.  QDict matches struct/union types, QList
  * matches list types, QString matches type 'str' and enumeration
- * types, QInt matches integer types, QFloat matches type 'number',
- * QBool matches type 'bool'.  Type 'any' is matched by QObject.  A
- * QAPI alternate type is matched when one of its member types is.
+ * types, QNum matches integer and float types, QBool matches type
+ * 'bool'.  Type 'any' is matched by QObject.  A QAPI alternate type
+ * is matched when one of its member types is.
  *
  * visit_start_struct() ... visit_end_struct() visits a QDict and
  * creates a QAPI struct/union.  Visits in between visit the
diff --git a/include/qapi/qobject-output-visitor.h b/include/qapi/qobject-output-visitor.h
index 9b990c318e..e5a3490812 100644
--- a/include/qapi/qobject-output-visitor.h
+++ b/include/qapi/qobject-output-visitor.h
@@ -28,10 +28,10 @@ typedef struct QObjectOutputVisitor QObjectOutputVisitor;
  *
  * visit_type_FOO() creates a QObject for QAPI type FOO.  It creates a
  * QDict for struct/union types, a QList for list types, QString for
- * type 'str' and enumeration types, QInt for integer types, QFloat
- * for type 'number', QBool for type 'bool'.  For type 'any', it
- * increments the QObject's reference count.  For QAPI alternate
- * types, it creates the QObject for the member that is in use.
+ * type 'str' and enumeration types, QNum for integer and float
+ * types, QBool for type 'bool'.  For type 'any', it increments the
+ * QObject's reference count.  For QAPI alternate types, it creates
+ * the QObject for the member that is in use.
  *
  * visit_start_struct() ... visit_end_struct() visits a QAPI
  * struct/union and creates a QDict.  Visits in between visit the
diff --git a/block/blkdebug.c b/block/blkdebug.c
index a5196e889d..0618fc71c6 100644
--- a/block/blkdebug.c
+++ b/block/blkdebug.c
@@ -31,7 +31,6 @@
 #include "qemu/module.h"
 #include "qapi/qmp/qbool.h"
 #include "qapi/qmp/qdict.h"
-#include "qapi/qmp/qint.h"
 #include "qapi/qmp/qstring.h"
 #include "sysemu/qtest.h"
 
diff --git a/block/nbd.c b/block/nbd.c
index 975faab2c5..e946ea944d 100644
--- a/block/nbd.c
+++ b/block/nbd.c
@@ -37,7 +37,6 @@
 #include "qapi/qobject-output-visitor.h"
 #include "qapi/qmp/qdict.h"
 #include "qapi/qmp/qjson.h"
-#include "qapi/qmp/qint.h"
 #include "qapi/qmp/qstring.h"
 #include "qemu/cutils.h"
 
diff --git a/block/nfs.c b/block/nfs.c
index 848b2c0bb0..decefd15f1 100644
--- a/block/nfs.c
+++ b/block/nfs.c
@@ -36,7 +36,6 @@
 #include "qemu/cutils.h"
 #include "sysemu/sysemu.h"
 #include "qapi/qmp/qdict.h"
-#include "qapi/qmp/qint.h"
 #include "qapi/qmp/qstring.h"
 #include "qapi-visit.h"
 #include "qapi/qobject-input-visitor.h"
diff --git a/block/qapi.c b/block/qapi.c
index a40922ea26..2050df29e4 100644
--- a/block/qapi.c
+++ b/block/qapi.c
@@ -595,9 +595,11 @@ static void dump_qobject(fprintf_function func_fprintf, void *f,
                          int comp_indent, QObject *obj)
 {
     switch (qobject_type(obj)) {
-        case QTYPE_QINT: {
-            QInt *value = qobject_to_qint(obj);
-            func_fprintf(f, "%" PRId64, qint_get_int(value));
+        case QTYPE_QNUM: {
+            QNum *value = qobject_to_qnum(obj);
+            char *tmp = qnum_to_string(value);
+            func_fprintf(f, "%s", tmp);
+            g_free(tmp);
             break;
         }
         case QTYPE_QSTRING: {
@@ -615,11 +617,6 @@ static void dump_qobject(fprintf_function func_fprintf, void *f,
             dump_qlist(func_fprintf, f, comp_indent, value);
             break;
         }
-        case QTYPE_QFLOAT: {
-            QFloat *value = qobject_to_qfloat(obj);
-            func_fprintf(f, "%g", qfloat_get_double(value));
-            break;
-        }
         case QTYPE_QBOOL: {
             QBool *value = qobject_to_qbool(obj);
             func_fprintf(f, "%s", qbool_get_bool(value) ? "true" : "false");
diff --git a/block/quorum.c b/block/quorum.c
index 1b2a8c3937..55ba916655 100644
--- a/block/quorum.c
+++ b/block/quorum.c
@@ -19,7 +19,6 @@
 #include "qapi/qmp/qbool.h"
 #include "qapi/qmp/qdict.h"
 #include "qapi/qmp/qerror.h"
-#include "qapi/qmp/qint.h"
 #include "qapi/qmp/qjson.h"
 #include "qapi/qmp/qlist.h"
 #include "qapi/qmp/qstring.h"
diff --git a/block/sheepdog.c b/block/sheepdog.c
index a18315a1ca..dea9000bdd 100644
--- a/block/sheepdog.c
+++ b/block/sheepdog.c
@@ -16,7 +16,6 @@
 #include "qapi-visit.h"
 #include "qapi/error.h"
 #include "qapi/qmp/qdict.h"
-#include "qapi/qmp/qint.h"
 #include "qapi/qobject-input-visitor.h"
 #include "qemu/uri.h"
 #include "qemu/error-report.h"
diff --git a/block/ssh.c b/block/ssh.c
index 11203fc5a2..bac3453c3e 100644
--- a/block/ssh.c
+++ b/block/ssh.c
@@ -34,7 +34,6 @@
 #include "qemu/sockets.h"
 #include "qemu/uri.h"
 #include "qapi-visit.h"
-#include "qapi/qmp/qint.h"
 #include "qapi/qmp/qstring.h"
 #include "qapi/qobject-input-visitor.h"
 #include "qapi/qobject-output-visitor.h"
diff --git a/block/vvfat.c b/block/vvfat.c
index 426ca70e35..8ab647c0c6 100644
--- a/block/vvfat.c
+++ b/block/vvfat.c
@@ -29,7 +29,6 @@
 #include "qemu/module.h"
 #include "qemu/bswap.h"
 #include "migration/blocker.h"
-#include "qapi/qmp/qint.h"
 #include "qapi/qmp/qbool.h"
 #include "qapi/qmp/qstring.h"
 #include "qemu/cutils.h"
diff --git a/blockdev.c b/blockdev.c
index 892d768574..be18271c11 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -334,9 +334,11 @@ static bool parse_stats_intervals(BlockAcctStats *stats, QList *intervals,
             break;
         }
 
-        case QTYPE_QINT: {
-            int64_t length = qint_get_int(qobject_to_qint(entry->value));
-            if (length > 0 && length <= UINT_MAX) {
+        case QTYPE_QNUM: {
+            int64_t length;
+
+            if (qnum_get_int(qobject_to_qnum(entry->value), &length) &&
+                length > 0 && length <= UINT_MAX) {
                 block_acct_add_interval(stats, (unsigned) length);
             } else {
                 error_setg(errp, "Invalid interval length: %" PRId64, length);
diff --git a/hw/acpi/pcihp.c b/hw/acpi/pcihp.c
index 2b0f3e1bfb..3a531a4416 100644
--- a/hw/acpi/pcihp.c
+++ b/hw/acpi/pcihp.c
@@ -37,7 +37,6 @@
 #include "hw/pci/pci_bus.h"
 #include "qapi/error.h"
 #include "qom/qom-qobject.h"
-#include "qapi/qmp/qint.h"
 
 //#define DEBUG
 
diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
index 82bd44f38e..1709efdf1c 100644
--- a/hw/i386/acpi-build.c
+++ b/hw/i386/acpi-build.c
@@ -57,7 +57,6 @@
 
 #include "hw/acpi/aml-build.h"
 
-#include "qapi/qmp/qint.h"
 #include "qom/qom-qobject.h"
 #include "hw/i386/amd_iommu.h"
 #include "hw/i386/intel_iommu.h"
@@ -129,6 +128,7 @@ static void acpi_get_pm_info(AcpiPmInfo *pm)
     Object *lpc = ich9_lpc_find();
     Object *obj = NULL;
     QObject *o;
+    int64_t val;
 
     pm->cpu_hp_io_base = 0;
     pm->pcihp_io_base = 0;
@@ -150,21 +150,30 @@ static void acpi_get_pm_info(AcpiPmInfo *pm)
     /* Fill in optional s3/s4 related properties */
     o = object_property_get_qobject(obj, ACPI_PM_PROP_S3_DISABLED, NULL);
     if (o) {
-        pm->s3_disabled = qint_get_int(qobject_to_qint(o));
+        if (!qnum_get_int(qobject_to_qnum(o), &val)) {
+            g_assert_not_reached();
+        }
+        pm->s3_disabled = val;
     } else {
         pm->s3_disabled = false;
     }
     qobject_decref(o);
     o = object_property_get_qobject(obj, ACPI_PM_PROP_S4_DISABLED, NULL);
     if (o) {
-        pm->s4_disabled = qint_get_int(qobject_to_qint(o));
+        if (!qnum_get_int(qobject_to_qnum(o), &val)) {
+            g_assert_not_reached();
+        }
+        pm->s4_disabled = val;
     } else {
         pm->s4_disabled = false;
     }
     qobject_decref(o);
     o = object_property_get_qobject(obj, ACPI_PM_PROP_S4_VAL, NULL);
     if (o) {
-        pm->s4_val = qint_get_int(qobject_to_qint(o));
+        if (!qnum_get_int(qobject_to_qnum(o), &val)) {
+            g_assert_not_reached();
+        }
+        pm->s4_val = val;
     } else {
         pm->s4_val = false;
     }
@@ -529,7 +538,11 @@ static void build_append_pci_bus_devices(Aml *parent_scope, PCIBus *bus,
 
     bsel = object_property_get_qobject(OBJECT(bus), ACPI_PCIHP_PROP_BSEL, NULL);
     if (bsel) {
-        int64_t bsel_val = qint_get_int(qobject_to_qint(bsel));
+        int64_t bsel_val;
+
+        if (!qnum_get_int(qobject_to_qnum(bsel), &bsel_val)) {
+            g_assert_not_reached();
+        }
 
         aml_append(parent_scope, aml_name_decl("BSEL", aml_int(bsel_val)));
         notify_method = aml_method("DVNT", 2, AML_NOTSERIALIZED);
@@ -639,7 +652,12 @@ static void build_append_pci_bus_devices(Aml *parent_scope, PCIBus *bus,
 
     /* If bus supports hotplug select it and notify about local events */
     if (bsel) {
-        int64_t bsel_val = qint_get_int(qobject_to_qint(bsel));
+        int64_t bsel_val;
+
+        if (!qnum_get_int(qobject_to_qnum(bsel), &bsel_val)) {
+            g_assert_not_reached();
+        }
+
         aml_append(method, aml_store(aml_int(bsel_val), aml_name("BNUM")));
         aml_append(method,
             aml_call2("DVNT", aml_name("PCIU"), aml_int(1) /* Device Check */)
@@ -2607,6 +2625,7 @@ static bool acpi_get_mcfg(AcpiMcfgInfo *mcfg)
 {
     Object *pci_host;
     QObject *o;
+    int64_t val;
 
     pci_host = acpi_get_i386_pci_host();
     g_assert(pci_host);
@@ -2615,12 +2634,18 @@ static bool acpi_get_mcfg(AcpiMcfgInfo *mcfg)
     if (!o) {
         return false;
     }
-    mcfg->mcfg_base = qint_get_int(qobject_to_qint(o));
+    if (!qnum_get_int(qobject_to_qnum(o), &val)) {
+        g_assert_not_reached();
+    }
+    mcfg->mcfg_base = val;
     qobject_decref(o);
 
     o = object_property_get_qobject(pci_host, PCIE_HOST_MCFG_SIZE, NULL);
     assert(o);
-    mcfg->mcfg_size = qint_get_int(qobject_to_qint(o));
+    if (!qnum_get_int(qobject_to_qnum(o), &val)) {
+        g_assert_not_reached();
+    }
+    mcfg->mcfg_size = val;
     qobject_decref(o);
     return true;
 }
diff --git a/hw/usb/xen-usb.c b/hw/usb/xen-usb.c
index fe62183fe3..584a6f2442 100644
--- a/hw/usb/xen-usb.c
+++ b/hw/usb/xen-usb.c
@@ -30,7 +30,6 @@
 #include "hw/xen/xen_backend.h"
 #include "monitor/qdev.h"
 #include "qapi/qmp/qbool.h"
-#include "qapi/qmp/qint.h"
 #include "qapi/qmp/qstring.h"
 
 #include "hw/xen/io/ring.h"
diff --git a/monitor.c b/monitor.c
index baa73c98b7..a8ac971015 100644
--- a/monitor.c
+++ b/monitor.c
@@ -2971,7 +2971,7 @@ static QDict *monitor_parse_arguments(Monitor *mon,
                     monitor_printf(mon, "Unknown unit suffix\n");
                     goto fail;
                 }
-                qdict_put(qdict, key, qfloat_from_double(val));
+                qdict_put(qdict, key, qnum_from_double(val));
             }
             break;
         case 'b':
diff --git a/qapi/qobject-input-visitor.c b/qapi/qobject-input-visitor.c
index eac40f618a..b32318c352 100644
--- a/qapi/qobject-input-visitor.c
+++ b/qapi/qobject-input-visitor.c
@@ -378,9 +378,6 @@ static void qobject_input_start_alternate(Visitor *v, const char *name,
     }
     *obj = g_malloc0(size);
     (*obj)->type = qobject_type(qobj);
-    if (promote_int && (*obj)->type == QTYPE_QINT) {
-        (*obj)->type = QTYPE_QFLOAT;
-    }
 }
 
 static void qobject_input_type_int64(Visitor *v, const char *name, int64_t *obj,
@@ -388,22 +385,18 @@ static void qobject_input_type_int64(Visitor *v, const char *name, int64_t *obj,
 {
     QObjectInputVisitor *qiv = to_qiv(v);
     QObject *qobj = qobject_input_get_object(qiv, name, true, errp);
-    QInt *qint;
+    QNum *qnum;
 
     if (!qobj) {
         return;
     }
-    qint = qobject_to_qint(qobj);
-    if (!qint) {
+    qnum = qobject_to_qnum(qobj);
+    if (!qnum || !qnum_get_int(qnum, obj)) {
         error_setg(errp, QERR_INVALID_PARAMETER_TYPE,
                    full_name(qiv, name), "integer");
-        return;
     }
-
-    *obj = qint_get_int(qint);
 }
 
-
 static void qobject_input_type_int64_keyval(Visitor *v, const char *name,
                                             int64_t *obj, Error **errp)
 {
@@ -424,22 +417,21 @@ static void qobject_input_type_int64_keyval(Visitor *v, const char *name,
 static void qobject_input_type_uint64(Visitor *v, const char *name,
                                       uint64_t *obj, Error **errp)
 {
-    /* FIXME: qobject_to_qint mishandles values over INT64_MAX */
+    /* FIXME: qobject_to_qnum mishandles values over INT64_MAX */
     QObjectInputVisitor *qiv = to_qiv(v);
     QObject *qobj = qobject_input_get_object(qiv, name, true, errp);
-    QInt *qint;
+    QNum *qnum;
+    int64_t val;
 
     if (!qobj) {
         return;
     }
-    qint = qobject_to_qint(qobj);
-    if (!qint) {
+    qnum = qobject_to_qnum(qobj);
+    if (!qnum || !qnum_get_int(qnum, &val)) {
         error_setg(errp, QERR_INVALID_PARAMETER_TYPE,
                    full_name(qiv, name), "integer");
-        return;
     }
-
-    *obj = qint_get_int(qint);
+    *obj = val;
 }
 
 static void qobject_input_type_uint64_keyval(Visitor *v, const char *name,
@@ -534,21 +526,14 @@ static void qobject_input_type_number(Visitor *v, const char *name, double *obj,
 {
     QObjectInputVisitor *qiv = to_qiv(v);
     QObject *qobj = qobject_input_get_object(qiv, name, true, errp);
-    QInt *qint;
-    QFloat *qfloat;
+    QNum *qnum;
 
     if (!qobj) {
         return;
     }
-    qint = qobject_to_qint(qobj);
-    if (qint) {
-        *obj = qint_get_int(qobject_to_qint(qobj));
-        return;
-    }
-
-    qfloat = qobject_to_qfloat(qobj);
-    if (qfloat) {
-        *obj = qfloat_get_double(qobject_to_qfloat(qobj));
+    qnum = qobject_to_qnum(qobj);
+    if (qnum) {
+        *obj = qnum_get_double(qnum);
         return;
     }
 
diff --git a/qapi/qobject-output-visitor.c b/qapi/qobject-output-visitor.c
index 871127079d..2ca5093b22 100644
--- a/qapi/qobject-output-visitor.c
+++ b/qapi/qobject-output-visitor.c
@@ -144,7 +144,7 @@ static void qobject_output_type_int64(Visitor *v, const char *name,
                                       int64_t *obj, Error **errp)
 {
     QObjectOutputVisitor *qov = to_qov(v);
-    qobject_output_add(qov, name, qint_from_int(*obj));
+    qobject_output_add(qov, name, qnum_from_int(*obj));
 }
 
 static void qobject_output_type_uint64(Visitor *v, const char *name,
@@ -152,7 +152,7 @@ static void qobject_output_type_uint64(Visitor *v, const char *name,
 {
     /* FIXME values larger than INT64_MAX become negative */
     QObjectOutputVisitor *qov = to_qov(v);
-    qobject_output_add(qov, name, qint_from_int(*obj));
+    qobject_output_add(qov, name, qnum_from_int(*obj));
 }
 
 static void qobject_output_type_bool(Visitor *v, const char *name, bool *obj,
@@ -177,7 +177,7 @@ static void qobject_output_type_number(Visitor *v, const char *name,
                                        double *obj, Error **errp)
 {
     QObjectOutputVisitor *qov = to_qov(v);
-    qobject_output_add(qov, name, qfloat_from_double(*obj));
+    qobject_output_add(qov, name, qnum_from_double(*obj));
 }
 
 static void qobject_output_type_any(Visitor *v, const char *name,
diff --git a/qga/commands.c b/qga/commands.c
index 3333ed50b2..ff89e805cf 100644
--- a/qga/commands.c
+++ b/qga/commands.c
@@ -485,7 +485,7 @@ int ga_parse_whence(GuestFileWhence *whence, Error **errp)
 {
     /* Exploit the fact that we picked values to match QGA_SEEK_*. */
     if (whence->type == QTYPE_QSTRING) {
-        whence->type = QTYPE_QINT;
+        whence->type = QTYPE_QNUM;
         whence->u.value = whence->u.name;
     }
     switch (whence->u.value) {
diff --git a/qga/main.c b/qga/main.c
index cc58d2b53d..405c1290f8 100644
--- a/qga/main.c
+++ b/qga/main.c
@@ -19,7 +19,6 @@
 #endif
 #include "qapi/qmp/json-streamer.h"
 #include "qapi/qmp/json-parser.h"
-#include "qapi/qmp/qint.h"
 #include "qapi/qmp/qjson.h"
 #include "qga/guest-agent-core.h"
 #include "qemu/module.h"
diff --git a/qobject/json-parser.c b/qobject/json-parser.c
index c18e48ab94..b90b2fb45a 100644
--- a/qobject/json-parser.c
+++ b/qobject/json-parser.c
@@ -466,16 +466,16 @@ static QObject *parse_escape(JSONParserContext *ctxt, va_list *ap)
     } else if (!strcmp(token->str, "%i")) {
         return QOBJECT(qbool_from_bool(va_arg(*ap, int)));
     } else if (!strcmp(token->str, "%d")) {
-        return QOBJECT(qint_from_int(va_arg(*ap, int)));
+        return QOBJECT(qnum_from_int(va_arg(*ap, int)));
     } else if (!strcmp(token->str, "%ld")) {
-        return QOBJECT(qint_from_int(va_arg(*ap, long)));
+        return QOBJECT(qnum_from_int(va_arg(*ap, long)));
     } else if (!strcmp(token->str, "%lld") ||
                !strcmp(token->str, "%I64d")) {
-        return QOBJECT(qint_from_int(va_arg(*ap, long long)));
+        return QOBJECT(qnum_from_int(va_arg(*ap, long long)));
     } else if (!strcmp(token->str, "%s")) {
         return QOBJECT(qstring_from_str(va_arg(*ap, const char *)));
     } else if (!strcmp(token->str, "%f")) {
-        return QOBJECT(qfloat_from_double(va_arg(*ap, double)));
+        return QOBJECT(qnum_from_double(va_arg(*ap, double)));
     }
     return NULL;
 }
@@ -491,24 +491,21 @@ static QObject *parse_literal(JSONParserContext *ctxt)
     case JSON_STRING:
         return QOBJECT(qstring_from_escaped_str(ctxt, token));
     case JSON_INTEGER: {
-        /* A possibility exists that this is a whole-valued float where the
-         * fractional part was left out due to being 0 (.0). It's not a big
-         * deal to treat these as ints in the parser, so long as users of the
-         * resulting QObject know to expect a QInt in place of a QFloat in
-         * cases like these.
+        /*
+         * Represent JSON_INTEGER as QNUM_I64 if possible, else as
+         * QNUM_DOUBLE. Note that strtoll() fails with ERANGE when
+         * it's not possible.
          *
-         * However, in some cases these values will overflow/underflow a
-         * QInt/int64 container, thus we should assume these are to be handled
-         * as QFloats/doubles rather than silently changing their values.
-         *
-         * strtoll() indicates these instances by setting errno to ERANGE
+         * qnum_get_int() will then work for any signed 64-bit
+         * JSON_INTEGER, and qnum_get_double both for any JSON_INTEGER
+         * and any JSON_FLOAT.
          */
         int64_t value;
 
         errno = 0; /* strtoll doesn't set errno on success */
         value = strtoll(token->str, NULL, 10);
         if (errno != ERANGE) {
-            return QOBJECT(qint_from_int(value));
+            return QOBJECT(qnum_from_int(value));
         }
         /* fall through to JSON_FLOAT */
     }
@@ -516,7 +513,7 @@ static QObject *parse_literal(JSONParserContext *ctxt)
         /* FIXME dependent on locale; a pervasive issue in QEMU */
         /* FIXME our lexer matches RFC 7159 in forbidding Inf or NaN,
          * but those might be useful extensions beyond JSON */
-        return QOBJECT(qfloat_from_double(strtod(token->str, NULL)));
+        return QOBJECT(qnum_from_double(strtod(token->str, NULL)));
     default:
         abort();
     }
diff --git a/qobject/qdict.c b/qobject/qdict.c
index 88e2ecd658..f62625cbd6 100644
--- a/qobject/qdict.c
+++ b/qobject/qdict.c
@@ -11,8 +11,7 @@
  */
 
 #include "qemu/osdep.h"
-#include "qapi/qmp/qint.h"
-#include "qapi/qmp/qfloat.h"
+#include "qapi/qmp/qnum.h"
 #include "qapi/qmp/qdict.h"
 #include "qapi/qmp/qbool.h"
 #include "qapi/qmp/qstring.h"
@@ -180,37 +179,32 @@ size_t qdict_size(const QDict *qdict)
 /**
  * qdict_get_double(): Get an number mapped by 'key'
  *
- * This function assumes that 'key' exists and it stores a
- * QFloat or QInt object.
+ * This function assumes that 'key' exists and it stores a QNum.
  *
  * Return number mapped by 'key'.
  */
 double qdict_get_double(const QDict *qdict, const char *key)
 {
-    QObject *obj = qdict_get(qdict, key);
-
-    assert(obj);
-    switch (qobject_type(obj)) {
-    case QTYPE_QFLOAT:
-        return qfloat_get_double(qobject_to_qfloat(obj));
-    case QTYPE_QINT:
-        return qint_get_int(qobject_to_qint(obj));
-    default:
-        abort();
-    }
+    return qnum_get_double(qobject_to_qnum(qdict_get(qdict, key)));
 }
 
 /**
  * qdict_get_int(): Get an integer mapped by 'key'
  *
  * This function assumes that 'key' exists and it stores a
- * QInt object.
+ * QNum representable as int.
  *
  * Return integer mapped by 'key'.
  */
 int64_t qdict_get_int(const QDict *qdict, const char *key)
 {
-    return qint_get_int(qobject_to_qint(qdict_get(qdict, key)));
+    int64_t val;
+
+    if (!qnum_get_int(qobject_to_qnum(qdict_get(qdict, key)), &val)) {
+        g_assert_not_reached();
+    }
+
+    return val;
 }
 
 /**
@@ -259,16 +253,21 @@ const char *qdict_get_str(const QDict *qdict, const char *key)
 /**
  * qdict_get_try_int(): Try to get integer mapped by 'key'
  *
- * Return integer mapped by 'key', if it is not present in
- * the dictionary or if the stored object is not of QInt type
- * 'def_value' will be returned.
+ * Return integer mapped by 'key', if it is not present in the
+ * dictionary or if the stored object is not a QNum representing an
+ * integer, 'def_value' will be returned.
  */
 int64_t qdict_get_try_int(const QDict *qdict, const char *key,
                           int64_t def_value)
 {
-    QInt *qint = qobject_to_qint(qdict_get(qdict, key));
+    QNum *qnum = qobject_to_qnum(qdict_get(qdict, key));
+    int64_t val;
+
+    if (!qnum || !qnum_get_int(qnum, &val)) {
+        return def_value;
+    }
 
-    return qint ? qint_get_int(qint) : def_value;
+    return val;
 }
 
 /**
diff --git a/qobject/qfloat.c b/qobject/qfloat.c
deleted file mode 100644
index d5da847701..0000000000
--- a/qobject/qfloat.c
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * QFloat Module
- *
- * Copyright IBM, Corp. 2009
- *
- * Authors:
- *  Anthony Liguori   <aliguori@us.ibm.com>
- *
- * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
- * See the COPYING.LIB file in the top-level directory.
- *
- */
-
-#include "qemu/osdep.h"
-#include "qapi/qmp/qfloat.h"
-#include "qapi/qmp/qobject.h"
-#include "qemu-common.h"
-
-/**
- * qfloat_from_int(): Create a new QFloat from a float
- *
- * Return strong reference.
- */
-QFloat *qfloat_from_double(double value)
-{
-    QFloat *qf;
-
-    qf = g_malloc(sizeof(*qf));
-    qobject_init(QOBJECT(qf), QTYPE_QFLOAT);
-    qf->value = value;
-
-    return qf;
-}
-
-/**
- * qfloat_get_double(): Get the stored float
- */
-double qfloat_get_double(const QFloat *qf)
-{
-    return qf->value;
-}
-
-/**
- * qobject_to_qfloat(): Convert a QObject into a QFloat
- */
-QFloat *qobject_to_qfloat(const QObject *obj)
-{
-    if (!obj || qobject_type(obj) != QTYPE_QFLOAT) {
-        return NULL;
-    }
-    return container_of(obj, QFloat, base);
-}
-
-/**
- * qfloat_destroy_obj(): Free all memory allocated by a
- * QFloat object
- */
-void qfloat_destroy_obj(QObject *obj)
-{
-    assert(obj != NULL);
-    g_free(qobject_to_qfloat(obj));
-}
diff --git a/qobject/qint.c b/qobject/qint.c
deleted file mode 100644
index d7d1b3021f..0000000000
--- a/qobject/qint.c
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * QInt Module
- *
- * Copyright (C) 2009 Red Hat Inc.
- *
- * Authors:
- *  Luiz Capitulino <lcapitulino@redhat.com>
- *
- * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
- * See the COPYING.LIB file in the top-level directory.
- */
-
-#include "qemu/osdep.h"
-#include "qapi/qmp/qint.h"
-#include "qapi/qmp/qobject.h"
-#include "qemu-common.h"
-
-/**
- * qint_from_int(): Create a new QInt from an int64_t
- *
- * Return strong reference.
- */
-QInt *qint_from_int(int64_t value)
-{
-    QInt *qi;
-
-    qi = g_malloc(sizeof(*qi));
-    qobject_init(QOBJECT(qi), QTYPE_QINT);
-    qi->value = value;
-
-    return qi;
-}
-
-/**
- * qint_get_int(): Get the stored integer
- */
-int64_t qint_get_int(const QInt *qi)
-{
-    return qi->value;
-}
-
-/**
- * qobject_to_qint(): Convert a QObject into a QInt
- */
-QInt *qobject_to_qint(const QObject *obj)
-{
-    if (!obj || qobject_type(obj) != QTYPE_QINT) {
-        return NULL;
-    }
-    return container_of(obj, QInt, base);
-}
-
-/**
- * qint_destroy_obj(): Free all memory allocated by a
- * QInt object
- */
-void qint_destroy_obj(QObject *obj)
-{
-    assert(obj != NULL);
-    g_free(qobject_to_qint(obj));
-}
diff --git a/qobject/qjson.c b/qobject/qjson.c
index b2f3bfec53..2e0930884e 100644
--- a/qobject/qjson.c
+++ b/qobject/qjson.c
@@ -132,12 +132,11 @@ static void to_json(const QObject *obj, QString *str, int pretty, int indent)
     case QTYPE_QNULL:
         qstring_append(str, "null");
         break;
-    case QTYPE_QINT: {
-        QInt *val = qobject_to_qint(obj);
-        char buffer[1024];
-
-        snprintf(buffer, sizeof(buffer), "%" PRId64, qint_get_int(val));
+    case QTYPE_QNUM: {
+        QNum *val = qobject_to_qnum(obj);
+        char *buffer = qnum_to_string(val);
         qstring_append(str, buffer);
+        g_free(buffer);
         break;
     }
     case QTYPE_QSTRING: {
@@ -234,34 +233,6 @@ static void to_json(const QObject *obj, QString *str, int pretty, int indent)
         qstring_append(str, "]");
         break;
     }
-    case QTYPE_QFLOAT: {
-        QFloat *val = qobject_to_qfloat(obj);
-        char buffer[1024];
-        int len;
-
-        /* FIXME: snprintf() is locale dependent; but JSON requires
-         * numbers to be formatted as if in the C locale. Dependence
-         * on C locale is a pervasive issue in QEMU. */
-        /* FIXME: This risks printing Inf or NaN, which are not valid
-         * JSON values. */
-        /* FIXME: the default precision of 6 for %f often causes
-         * rounding errors; we should be using DBL_DECIMAL_DIG (17),
-         * and only rounding to a shorter number if the result would
-         * still produce the same floating point value.  */
-        len = snprintf(buffer, sizeof(buffer), "%f", qfloat_get_double(val));
-        while (len > 0 && buffer[len - 1] == '0') {
-            len--;
-        }
-
-        if (len && buffer[len - 1] == '.') {
-            buffer[len - 1] = 0;
-        } else {
-            buffer[len] = 0;
-        }
-
-        qstring_append(str, buffer);
-        break;
-    }
     case QTYPE_QBOOL: {
         QBool *val = qobject_to_qbool(obj);
 
diff --git a/qobject/qnum.c b/qobject/qnum.c
new file mode 100644
index 0000000000..f16864160a
--- /dev/null
+++ b/qobject/qnum.c
@@ -0,0 +1,141 @@
+/*
+ * QNum Module
+ *
+ * Copyright (C) 2009 Red Hat Inc.
+ *
+ * Authors:
+ *  Luiz Capitulino <lcapitulino@redhat.com>
+ *  Marc-André Lureau <marcandre.lureau@redhat.com>
+ *
+ * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
+ * See the COPYING.LIB file in the top-level directory.
+ */
+
+#include "qemu/osdep.h"
+#include "qapi/error.h"
+#include "qapi/qmp/qnum.h"
+#include "qapi/qmp/qobject.h"
+#include "qemu-common.h"
+
+/**
+ * qnum_from_int(): Create a new QNum from an int64_t
+ *
+ * Return strong reference.
+ */
+QNum *qnum_from_int(int64_t value)
+{
+    QNum *qn = g_new(QNum, 1);
+
+    qobject_init(QOBJECT(qn), QTYPE_QNUM);
+    qn->kind = QNUM_I64;
+    qn->u.i64 = value;
+
+    return qn;
+}
+
+/**
+ * qnum_from_double(): Create a new QNum from a double
+ *
+ * Return strong reference.
+ */
+QNum *qnum_from_double(double value)
+{
+    QNum *qn = g_new(QNum, 1);
+
+    qobject_init(QOBJECT(qn), QTYPE_QNUM);
+    qn->kind = QNUM_DOUBLE;
+    qn->u.dbl = value;
+
+    return qn;
+}
+
+/**
+ * qnum_get_int(): Get an integer representation of the number
+ *
+ * Return true on success.
+ */
+bool qnum_get_int(const QNum *qn, int64_t *val)
+{
+    switch (qn->kind) {
+    case QNUM_I64:
+        *val = qn->u.i64;
+        return true;
+    case QNUM_DOUBLE:
+        return false;
+    }
+
+    g_assert_not_reached();
+    return false;
+}
+
+/**
+ * qnum_get_double(): Get a float representation of the number
+ */
+double qnum_get_double(QNum *qn)
+{
+    switch (qn->kind) {
+    case QNUM_I64:
+        return qn->u.i64;
+    case QNUM_DOUBLE:
+        return qn->u.dbl;
+    }
+
+    g_assert_not_reached();
+}
+
+char *qnum_to_string(QNum *qn)
+{
+    char *buffer;
+    int len;
+
+    switch (qn->kind) {
+    case QNUM_I64:
+        return g_strdup_printf("%" PRId64, qn->u.i64);
+    case QNUM_DOUBLE:
+        /* FIXME: snprintf() is locale dependent; but JSON requires
+         * numbers to be formatted as if in the C locale. Dependence
+         * on C locale is a pervasive issue in QEMU. */
+        /* FIXME: This risks printing Inf or NaN, which are not valid
+         * JSON values. */
+        /* FIXME: the default precision of 6 for %f often causes
+         * rounding errors; we should be using DBL_DECIMAL_DIG (17),
+         * and only rounding to a shorter number if the result would
+         * still produce the same floating point value.  */
+        buffer = g_strdup_printf("%f" , qn->u.dbl);
+        len = strlen(buffer);
+        while (len > 0 && buffer[len - 1] == '0') {
+            len--;
+        }
+
+        if (len && buffer[len - 1] == '.') {
+            buffer[len - 1] = 0;
+        } else {
+            buffer[len] = 0;
+        }
+
+        return buffer;
+    }
+
+    g_assert_not_reached();
+}
+
+/**
+ * qobject_to_qnum(): Convert a QObject into a QNum
+ */
+QNum *qobject_to_qnum(const QObject *obj)
+{
+    if (!obj || qobject_type(obj) != QTYPE_QNUM) {
+        return NULL;
+    }
+    return container_of(obj, QNum, base);
+}
+
+/**
+ * qnum_destroy_obj(): Free all memory allocated by a
+ * QNum object
+ */
+void qnum_destroy_obj(QObject *obj)
+{
+    assert(obj != NULL);
+    g_free(qobject_to_qnum(obj));
+}
diff --git a/qobject/qobject.c b/qobject/qobject.c
index fe4fa10989..b0cafb66f1 100644
--- a/qobject/qobject.c
+++ b/qobject/qobject.c
@@ -14,11 +14,10 @@
 static void (*qdestroy[QTYPE__MAX])(QObject *) = {
     [QTYPE_NONE] = NULL,               /* No such object exists */
     [QTYPE_QNULL] = NULL,              /* qnull_ is indestructible */
-    [QTYPE_QINT] = qint_destroy_obj,
+    [QTYPE_QNUM] = qnum_destroy_obj,
     [QTYPE_QSTRING] = qstring_destroy_obj,
     [QTYPE_QDICT] = qdict_destroy_obj,
     [QTYPE_QLIST] = qlist_destroy_obj,
-    [QTYPE_QFLOAT] = qfloat_destroy_obj,
     [QTYPE_QBOOL] = qbool_destroy_obj,
 };
 
diff --git a/qom/object.c b/qom/object.c
index c7b8079df6..cf0e64a625 100644
--- a/qom/object.c
+++ b/qom/object.c
@@ -27,7 +27,6 @@
 #include "qom/qom-qobject.h"
 #include "qapi/qmp/qobject.h"
 #include "qapi/qmp/qbool.h"
-#include "qapi/qmp/qint.h"
 #include "qapi/qmp/qstring.h"
 
 #define MAX_INTERFACES 32
@@ -1190,28 +1189,27 @@ bool object_property_get_bool(Object *obj, const char *name,
 void object_property_set_int(Object *obj, int64_t value,
                              const char *name, Error **errp)
 {
-    QInt *qint = qint_from_int(value);
-    object_property_set_qobject(obj, QOBJECT(qint), name, errp);
+    QNum *qnum = qnum_from_int(value);
+    object_property_set_qobject(obj, QOBJECT(qnum), name, errp);
 
-    QDECREF(qint);
+    QDECREF(qnum);
 }
 
 int64_t object_property_get_int(Object *obj, const char *name,
                                 Error **errp)
 {
     QObject *ret = object_property_get_qobject(obj, name, errp);
-    QInt *qint;
+    QNum *qnum;
     int64_t retval;
 
     if (!ret) {
         return -1;
     }
-    qint = qobject_to_qint(ret);
-    if (!qint) {
+
+    qnum = qobject_to_qnum(ret);
+    if (!qnum || !qnum_get_int(qnum, &retval)) {
         error_setg(errp, QERR_INVALID_PARAMETER_TYPE, name, "int");
         retval = -1;
-    } else {
-        retval = qint_get_int(qint);
     }
 
     qobject_decref(ret);
diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index a41d595c23..12882f0774 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -29,11 +29,7 @@
 #include "qemu/option.h"
 #include "qemu/config-file.h"
 #include "qapi/qmp/qerror.h"
-#include "qapi/qmp/qstring.h"
-#include "qapi/qmp/qdict.h"
-#include "qapi/qmp/qbool.h"
-#include "qapi/qmp/qint.h"
-#include "qapi/qmp/qfloat.h"
+#include "qapi/qmp/types.h"
 
 #include "qapi-types.h"
 #include "qapi-visit.h"
diff --git a/tests/check-qdict.c b/tests/check-qdict.c
index be8d81f07b..5c70490e83 100644
--- a/tests/check-qdict.c
+++ b/tests/check-qdict.c
@@ -11,7 +11,6 @@
  */
 #include "qemu/osdep.h"
 
-#include "qapi/qmp/qint.h"
 #include "qapi/qmp/qdict.h"
 #include "qapi/qmp/qstring.h"
 #include "qapi/error.h"
@@ -39,10 +38,11 @@ static void qdict_new_test(void)
 
 static void qdict_put_obj_test(void)
 {
-    QInt *qi;
+    QNum *qi;
     QDict *qdict;
     QDictEntry *ent;
     const int num = 42;
+    int64_t val;
 
     qdict = qdict_new();
 
@@ -51,8 +51,9 @@ static void qdict_put_obj_test(void)
 
     g_assert(qdict_size(qdict) == 1);
     ent = QLIST_FIRST(&qdict->table[12345 % QDICT_BUCKET_MAX]);
-    qi = qobject_to_qint(ent->value);
-    g_assert(qint_get_int(qi) == num);
+    qi = qobject_to_qnum(ent->value);
+    g_assert(qnum_get_int(qi, &val));
+    g_assert_cmpint(val, ==, num);
 
     // destroy doesn't exit yet
     QDECREF(qi);
@@ -74,19 +75,21 @@ static void qdict_destroy_simple_test(void)
 
 static void qdict_get_test(void)
 {
-    QInt *qi;
+    QNum *qi;
     QObject *obj;
     const int value = -42;
     const char *key = "test";
     QDict *tests_dict = qdict_new();
+    int64_t val;
 
     qdict_put_int(tests_dict, key, value);
 
     obj = qdict_get(tests_dict, key);
     g_assert(obj != NULL);
 
-    qi = qobject_to_qint(obj);
-    g_assert(qint_get_int(qi) == value);
+    qi = qobject_to_qnum(obj);
+    g_assert(qnum_get_int(qi, &val));
+    g_assert_cmpint(val, ==, value);
 
     QDECREF(tests_dict);
 }
@@ -329,8 +332,9 @@ static void qdict_array_split_test(void)
 {
     QDict *test_dict = qdict_new();
     QDict *dict1, *dict2;
-    QInt *int1;
+    QNum *int1;
     QList *test_list;
+    int64_t val;
 
     /*
      * Test the split of
@@ -380,7 +384,7 @@ static void qdict_array_split_test(void)
 
     dict1 = qobject_to_qdict(qlist_pop(test_list));
     dict2 = qobject_to_qdict(qlist_pop(test_list));
-    int1 = qobject_to_qint(qlist_pop(test_list));
+    int1 = qobject_to_qnum(qlist_pop(test_list));
 
     g_assert(dict1);
     g_assert(dict2);
@@ -402,7 +406,8 @@ static void qdict_array_split_test(void)
 
     QDECREF(dict2);
 
-    g_assert(qint_get_int(int1) == 66);
+    g_assert(qnum_get_int(int1, &val));
+    g_assert_cmpint(val, ==, 66);
 
     QDECREF(int1);
 
@@ -447,14 +452,15 @@ static void qdict_array_split_test(void)
 
     qdict_array_split(test_dict, &test_list);
 
-    int1 = qobject_to_qint(qlist_pop(test_list));
+    int1 = qobject_to_qnum(qlist_pop(test_list));
 
     g_assert(int1);
     g_assert(qlist_empty(test_list));
 
     QDECREF(test_list);
 
-    g_assert(qint_get_int(int1) == 42);
+    g_assert(qnum_get_int(int1, &val));
+    g_assert_cmpint(val, ==, 42);
 
     QDECREF(int1);
 
diff --git a/tests/check-qfloat.c b/tests/check-qfloat.c
deleted file mode 100644
index 1da2cdae08..0000000000
--- a/tests/check-qfloat.c
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * QFloat unit-tests.
- *
- * Copyright IBM, Corp. 2009
- *
- * Authors:
- *  Anthony Liguori   <aliguori@us.ibm.com>
- *
- * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
- * See the COPYING.LIB file in the top-level directory.
- *
- */
-#include "qemu/osdep.h"
-
-#include "qapi/qmp/qfloat.h"
-#include "qemu-common.h"
-
-/*
- * Public Interface test-cases
- *
- * (with some violations to access 'private' data)
- */
-
-static void qfloat_from_double_test(void)
-{
-    QFloat *qf;
-    const double value = -42.23423;
-
-    qf = qfloat_from_double(value);
-    g_assert(qf != NULL);
-    g_assert(qf->value == value);
-    g_assert(qf->base.refcnt == 1);
-    g_assert(qobject_type(QOBJECT(qf)) == QTYPE_QFLOAT);
-
-    // destroy doesn't exit yet
-    g_free(qf);
-}
-
-static void qfloat_destroy_test(void)
-{
-    QFloat *qf = qfloat_from_double(0.0);
-    QDECREF(qf);
-}
-
-int main(int argc, char **argv)
-{
-    g_test_init(&argc, &argv, NULL);
-
-    g_test_add_func("/public/from_double", qfloat_from_double_test);
-    g_test_add_func("/public/destroy", qfloat_destroy_test);
-
-    return g_test_run();
-}
diff --git a/tests/check-qint.c b/tests/check-qint.c
deleted file mode 100644
index b6e4555115..0000000000
--- a/tests/check-qint.c
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * QInt unit-tests.
- *
- * Copyright (C) 2009 Red Hat Inc.
- *
- * Authors:
- *  Luiz Capitulino <lcapitulino@redhat.com>
- *
- * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
- * See the COPYING.LIB file in the top-level directory.
- */
-#include "qemu/osdep.h"
-
-#include "qapi/qmp/qint.h"
-#include "qemu-common.h"
-
-/*
- * Public Interface test-cases
- *
- * (with some violations to access 'private' data)
- */
-
-static void qint_from_int_test(void)
-{
-    QInt *qi;
-    const int value = -42;
-
-    qi = qint_from_int(value);
-    g_assert(qi != NULL);
-    g_assert(qi->value == value);
-    g_assert(qi->base.refcnt == 1);
-    g_assert(qobject_type(QOBJECT(qi)) == QTYPE_QINT);
-
-    // destroy doesn't exit yet
-    g_free(qi);
-}
-
-static void qint_destroy_test(void)
-{
-    QInt *qi = qint_from_int(0);
-    QDECREF(qi);
-}
-
-static void qint_from_int64_test(void)
-{
-    QInt *qi;
-    const int64_t value = 0x1234567890abcdefLL;
-
-    qi = qint_from_int(value);
-    g_assert((int64_t) qi->value == value);
-
-    QDECREF(qi);
-}
-
-static void qint_get_int_test(void)
-{
-    QInt *qi;
-    const int value = 123456;
-
-    qi = qint_from_int(value);
-    g_assert(qint_get_int(qi) == value);
-
-    QDECREF(qi);
-}
-
-static void qobject_to_qint_test(void)
-{
-    QInt *qi;
-
-    qi = qint_from_int(0);
-    g_assert(qobject_to_qint(QOBJECT(qi)) == qi);
-
-    QDECREF(qi);
-}
-
-int main(int argc, char **argv)
-{
-    g_test_init(&argc, &argv, NULL);
-
-    g_test_add_func("/public/from_int", qint_from_int_test);
-    g_test_add_func("/public/destroy", qint_destroy_test);
-    g_test_add_func("/public/from_int64", qint_from_int64_test);
-    g_test_add_func("/public/get_int", qint_get_int_test);
-    g_test_add_func("/public/to_qint", qobject_to_qint_test);
-
-    return g_test_run();
-}
diff --git a/tests/check-qjson.c b/tests/check-qjson.c
index 963dd46f07..8ec728a702 100644
--- a/tests/check-qjson.c
+++ b/tests/check-qjson.c
@@ -886,21 +886,23 @@ static void simple_number(void)
     };
 
     for (i = 0; test_cases[i].encoded; i++) {
-        QInt *qint;
+        QNum *qnum;
+        int64_t val;
 
-        qint = qobject_to_qint(qobject_from_json(test_cases[i].encoded,
+        qnum = qobject_to_qnum(qobject_from_json(test_cases[i].encoded,
                                                  &error_abort));
-        g_assert(qint);
-        g_assert(qint_get_int(qint) == test_cases[i].decoded);
+        g_assert(qnum);
+        g_assert(qnum_get_int(qnum, &val));
+        g_assert_cmpint(val, ==, test_cases[i].decoded);
         if (test_cases[i].skip == 0) {
             QString *str;
 
-            str = qobject_to_json(QOBJECT(qint));
+            str = qobject_to_json(QOBJECT(qnum));
             g_assert(strcmp(qstring_get_str(str), test_cases[i].encoded) == 0);
             QDECREF(str);
         }
 
-        QDECREF(qint);
+        QDECREF(qnum);
     }
 }
 
@@ -921,12 +923,12 @@ static void float_number(void)
 
     for (i = 0; test_cases[i].encoded; i++) {
         QObject *obj;
-        QFloat *qfloat;
+        QNum *qnum;
 
         obj = qobject_from_json(test_cases[i].encoded, &error_abort);
-        qfloat = qobject_to_qfloat(obj);
-        g_assert(qfloat);
-        g_assert(qfloat_get_double(qfloat) == test_cases[i].decoded);
+        qnum = qobject_to_qnum(obj);
+        g_assert(qnum);
+        g_assert(qnum_get_double(qnum) == test_cases[i].decoded);
 
         if (test_cases[i].skip == 0) {
             QString *str;
@@ -936,29 +938,31 @@ static void float_number(void)
             QDECREF(str);
         }
 
-        QDECREF(qfloat);
+        QDECREF(qnum);
     }
 }
 
 static void vararg_number(void)
 {
-    QInt *qint;
-    QFloat *qfloat;
+    QNum *qnum;
     int value = 0x2342;
     long long value_ll = 0x2342342343LL;
     double valuef = 2.323423423;
+    int64_t val;
 
-    qint = qobject_to_qint(qobject_from_jsonf("%d", value));
-    g_assert(qint_get_int(qint) == value);
-    QDECREF(qint);
+    qnum = qobject_to_qnum(qobject_from_jsonf("%d", value));
+    g_assert(qnum_get_int(qnum, &val));
+    g_assert_cmpint(val, ==, value);
+    QDECREF(qnum);
 
-    qint = qobject_to_qint(qobject_from_jsonf("%lld", value_ll));
-    g_assert(qint_get_int(qint) == value_ll);
-    QDECREF(qint);
+    qnum = qobject_to_qnum(qobject_from_jsonf("%lld", value_ll));
+    g_assert(qnum_get_int(qnum, &val));
+    g_assert_cmpint(val, ==, value_ll);
+    QDECREF(qnum);
 
-    qfloat = qobject_to_qfloat(qobject_from_jsonf("%f", valuef));
-    g_assert(qfloat_get_double(qfloat) == valuef);
-    QDECREF(qfloat);
+    qnum = qobject_to_qnum(qobject_from_jsonf("%f", valuef));
+    g_assert(qnum_get_double(qnum) == valuef);
+    QDECREF(qnum);
 }
 
 static void keyword_literal(void)
@@ -1019,7 +1023,7 @@ struct LiteralQObject
 {
     int type;
     union {
-        int64_t qint;
+        int64_t qnum;
         const char *qstr;
         LiteralQDictEntry *qdict;
         LiteralQObject *qlist;
@@ -1032,7 +1036,7 @@ struct LiteralQDictEntry
     LiteralQObject value;
 };
 
-#define QLIT_QINT(val) (LiteralQObject){.type = QTYPE_QINT, .value.qint = (val)}
+#define QLIT_QNUM(val) (LiteralQObject){.type = QTYPE_QNUM, .value.qnum = (val)}
 #define QLIT_QSTR(val) (LiteralQObject){.type = QTYPE_QSTRING, .value.qstr = (val)}
 #define QLIT_QDICT(val) (LiteralQObject){.type = QTYPE_QDICT, .value.qdict = (val)}
 #define QLIT_QLIST(val) (LiteralQObject){.type = QTYPE_QLIST, .value.qlist = (val)}
@@ -1064,13 +1068,16 @@ static void compare_helper(QObject *obj, void *opaque)
 
 static int compare_litqobj_to_qobj(LiteralQObject *lhs, QObject *rhs)
 {
+    int64_t val;
+
     if (!rhs || lhs->type != qobject_type(rhs)) {
         return 0;
     }
 
     switch (lhs->type) {
-    case QTYPE_QINT:
-        return lhs->value.qint == qint_get_int(qobject_to_qint(rhs));
+    case QTYPE_QNUM:
+        g_assert(qnum_get_int(qobject_to_qnum(rhs), &val));
+        return lhs->value.qnum == val;
     case QTYPE_QSTRING:
         return (strcmp(lhs->value.qstr, qstring_get_str(qobject_to_qstring(rhs))) == 0);
     case QTYPE_QDICT: {
@@ -1114,7 +1121,7 @@ static void simple_dict(void)
         {
             .encoded = "{\"foo\": 42, \"bar\": \"hello world\"}",
             .decoded = QLIT_QDICT(((LiteralQDictEntry[]){
-                        { "foo", QLIT_QINT(42) },
+                        { "foo", QLIT_QNUM(42) },
                         { "bar", QLIT_QSTR("hello world") },
                         { }
                     })),
@@ -1126,7 +1133,7 @@ static void simple_dict(void)
         }, {
             .encoded = "{\"foo\": 43}",
             .decoded = QLIT_QDICT(((LiteralQDictEntry[]){
-                        { "foo", QLIT_QINT(43) },
+                        { "foo", QLIT_QNUM(43) },
                         { }
                     })),
         },
@@ -1212,15 +1219,15 @@ static void simple_list(void)
         {
             .encoded = "[43,42]",
             .decoded = QLIT_QLIST(((LiteralQObject[]){
-                        QLIT_QINT(43),
-                        QLIT_QINT(42),
+                        QLIT_QNUM(43),
+                        QLIT_QNUM(42),
                         { }
                     })),
         },
         {
             .encoded = "[43]",
             .decoded = QLIT_QLIST(((LiteralQObject[]){
-                        QLIT_QINT(43),
+                        QLIT_QNUM(43),
                         { }
                     })),
         },
@@ -1269,35 +1276,35 @@ static void simple_whitespace(void)
         {
             .encoded = " [ 43 , 42 ]",
             .decoded = QLIT_QLIST(((LiteralQObject[]){
-                        QLIT_QINT(43),
-                        QLIT_QINT(42),
+                        QLIT_QNUM(43),
+                        QLIT_QNUM(42),
                         { }
                     })),
         },
         {
             .encoded = " [ 43 , { 'h' : 'b' }, [ ], 42 ]",
             .decoded = QLIT_QLIST(((LiteralQObject[]){
-                        QLIT_QINT(43),
+                        QLIT_QNUM(43),
                         QLIT_QDICT(((LiteralQDictEntry[]){
                                     { "h", QLIT_QSTR("b") },
                                     { }})),
                         QLIT_QLIST(((LiteralQObject[]){
                                     { }})),
-                        QLIT_QINT(42),
+                        QLIT_QNUM(42),
                         { }
                     })),
         },
         {
             .encoded = " [ 43 , { 'h' : 'b' , 'a' : 32 }, [ ], 42 ]",
             .decoded = QLIT_QLIST(((LiteralQObject[]){
-                        QLIT_QINT(43),
+                        QLIT_QNUM(43),
                         QLIT_QDICT(((LiteralQDictEntry[]){
                                     { "h", QLIT_QSTR("b") },
-                                    { "a", QLIT_QINT(32) },
+                                    { "a", QLIT_QNUM(32) },
                                     { }})),
                         QLIT_QLIST(((LiteralQObject[]){
                                     { }})),
-                        QLIT_QINT(42),
+                        QLIT_QNUM(42),
                         { }
                     })),
         },
@@ -1327,11 +1334,11 @@ static void simple_varargs(void)
     QObject *embedded_obj;
     QObject *obj;
     LiteralQObject decoded = QLIT_QLIST(((LiteralQObject[]){
-            QLIT_QINT(1),
-            QLIT_QINT(2),
+            QLIT_QNUM(1),
+            QLIT_QNUM(2),
             QLIT_QLIST(((LiteralQObject[]){
-                        QLIT_QINT(32),
-                        QLIT_QINT(42),
+                        QLIT_QNUM(32),
+                        QLIT_QNUM(42),
                         {}})),
             {}}));
 
diff --git a/tests/check-qlist.c b/tests/check-qlist.c
index 4983867c27..5bc8bb6756 100644
--- a/tests/check-qlist.c
+++ b/tests/check-qlist.c
@@ -11,8 +11,8 @@
  */
 #include "qemu/osdep.h"
 
-#include "qapi/qmp/qint.h"
-#include "qapi/qmp/qlist.h"
+#include "qapi/error.h"
+#include "qapi/qmp/types.h"
 
 /*
  * Public Interface test-cases
@@ -35,11 +35,11 @@ static void qlist_new_test(void)
 
 static void qlist_append_test(void)
 {
-    QInt *qi;
+    QNum *qi;
     QList *qlist;
     QListEntry *entry;
 
-    qi = qint_from_int(42);
+    qi = qnum_from_int(42);
 
     qlist = qlist_new();
     qlist_append(qlist, qi);
@@ -84,13 +84,17 @@ static const int iter_max = 42;
 
 static void iter_func(QObject *obj, void *opaque)
 {
-    QInt *qi;
+    QNum *qi;
+    int64_t val;
 
     g_assert(opaque == NULL);
 
-    qi = qobject_to_qint(obj);
+    qi = qobject_to_qnum(obj);
     g_assert(qi != NULL);
-    g_assert((qint_get_int(qi) >= 0) && (qint_get_int(qi) <= iter_max));
+
+    g_assert(qnum_get_int(qi, &val));
+    g_assert_cmpint(val, >=, 0);
+    g_assert_cmpint(val, <=, iter_max);
 
     iter_called++;
 }
diff --git a/tests/check-qnum.c b/tests/check-qnum.c
new file mode 100644
index 0000000000..4b3fec050e
--- /dev/null
+++ b/tests/check-qnum.c
@@ -0,0 +1,133 @@
+/*
+ * QNum unit-tests.
+ *
+ * Copyright (C) 2009 Red Hat Inc.
+ *
+ * Authors:
+ *  Luiz Capitulino <lcapitulino@redhat.com>
+ *
+ * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
+ * See the COPYING.LIB file in the top-level directory.
+ */
+#include "qemu/osdep.h"
+
+#include "qapi/qmp/qnum.h"
+#include "qapi/error.h"
+#include "qemu-common.h"
+
+/*
+ * Public Interface test-cases
+ *
+ * (with some violations to access 'private' data)
+ */
+
+static void qnum_from_int_test(void)
+{
+    QNum *qi;
+    const int value = -42;
+
+    qi = qnum_from_int(value);
+    g_assert(qi != NULL);
+    g_assert_cmpint(qi->u.i64, ==, value);
+    g_assert_cmpint(qi->base.refcnt, ==, 1);
+    g_assert_cmpint(qobject_type(QOBJECT(qi)), ==, QTYPE_QNUM);
+
+    // destroy doesn't exit yet
+    g_free(qi);
+}
+
+static void qnum_from_double_test(void)
+{
+    QNum *qf;
+    const double value = -42.23423;
+
+    qf = qnum_from_double(value);
+    g_assert(qf != NULL);
+    g_assert_cmpfloat(qf->u.dbl, ==, value);
+    g_assert_cmpint(qf->base.refcnt, ==, 1);
+    g_assert_cmpint(qobject_type(QOBJECT(qf)), ==, QTYPE_QNUM);
+
+    // destroy doesn't exit yet
+    g_free(qf);
+}
+
+static void qnum_from_int64_test(void)
+{
+    QNum *qi;
+    const int64_t value = 0x1234567890abcdefLL;
+
+    qi = qnum_from_int(value);
+    g_assert_cmpint((int64_t) qi->u.i64, ==, value);
+
+    QDECREF(qi);
+}
+
+static void qnum_get_int_test(void)
+{
+    QNum *qi;
+    const int value = 123456;
+    int64_t val;
+
+    qi = qnum_from_int(value);
+    g_assert(qnum_get_int(qi, &val));
+    g_assert_cmpint(val, ==, value);
+
+    QDECREF(qi);
+}
+
+static void qobject_to_qnum_test(void)
+{
+    QNum *qn;
+
+    qn = qnum_from_int(0);
+    g_assert(qobject_to_qnum(QOBJECT(qn)) == qn);
+    QDECREF(qn);
+
+    qn = qnum_from_double(0);
+    g_assert(qobject_to_qnum(QOBJECT(qn)) == qn);
+    QDECREF(qn);
+}
+
+static void qnum_to_string_test(void)
+{
+    QNum *qn;
+    char *tmp;
+
+    qn = qnum_from_int(123456);
+    tmp = qnum_to_string(qn);
+    g_assert_cmpstr(tmp, ==, "123456");
+    g_free(tmp);
+    QDECREF(qn);
+
+    qn = qnum_from_double(0.42);
+    tmp = qnum_to_string(qn);
+    g_assert_cmpstr(tmp, ==, "0.42");
+    g_free(tmp);
+    QDECREF(qn);
+}
+
+static void qnum_destroy_test(void)
+{
+    QNum *qn;
+
+    qn = qnum_from_int(0);
+    QDECREF(qn);
+
+    qn = qnum_from_double(0.42);
+    QDECREF(qn);
+}
+
+int main(int argc, char **argv)
+{
+    g_test_init(&argc, &argv, NULL);
+
+    g_test_add_func("/qnum/from_int", qnum_from_int_test);
+    g_test_add_func("/qnum/from_double", qnum_from_double_test);
+    g_test_add_func("/qnum/destroy", qnum_destroy_test);
+    g_test_add_func("/qnum/from_int64", qnum_from_int64_test);
+    g_test_add_func("/qnum/get_int", qnum_get_int_test);
+    g_test_add_func("/qnum/to_qnum", qobject_to_qnum_test);
+    g_test_add_func("/qnum/to_string", qnum_to_string_test);
+
+    return g_test_run();
+}
diff --git a/tests/test-qmp-commands.c b/tests/test-qmp-commands.c
index acdded4d67..9c69c98781 100644
--- a/tests/test-qmp-commands.c
+++ b/tests/test-qmp-commands.c
@@ -162,7 +162,8 @@ static void test_dispatch_cmd_io(void)
     QDict *ud1b = qdict_new();
     QDict *ret, *ret_dict, *ret_dict_dict, *ret_dict_dict_userdef;
     QDict *ret_dict_dict2, *ret_dict_dict2_userdef;
-    QInt *ret3;
+    QNum *ret3;
+    int64_t val;
 
     qdict_put_int(ud1a, "integer", 42);
     qdict_put_str(ud1a, "string", "hello");
@@ -194,8 +195,9 @@ static void test_dispatch_cmd_io(void)
     qdict_put(req, "arguments", args3);
     qdict_put_str(req, "execute", "guest-get-time");
 
-    ret3 = qobject_to_qint(test_qmp_dispatch(req));
-    assert(qint_get_int(ret3) == 66);
+    ret3 = qobject_to_qnum(test_qmp_dispatch(req));
+    g_assert(qnum_get_int(ret3, &val));
+    g_assert_cmpint(val, ==, 66);
     QDECREF(ret3);
 
     QDECREF(req);
diff --git a/tests/test-qmp-event.c b/tests/test-qmp-event.c
index 4c0f09601d..c6a5ff38d0 100644
--- a/tests/test-qmp-event.c
+++ b/tests/test-qmp-event.c
@@ -18,7 +18,6 @@
 #include "test-qapi-visit.h"
 #include "test-qapi-event.h"
 #include "qapi/qmp/types.h"
-#include "qapi/qmp/qint.h"
 #include "qapi/qmp/qobject.h"
 #include "qapi/qmp-event.h"
 
@@ -41,6 +40,7 @@ void qdict_cmp_do_simple(const char *key, QObject *obj1, void *opaque)
 {
     QObject *obj2;
     QDictCmpData d_new, *d = opaque;
+    int64_t val1, val2;
 
     if (!d->result) {
         return;
@@ -62,9 +62,10 @@ void qdict_cmp_do_simple(const char *key, QObject *obj1, void *opaque)
         d->result = (qbool_get_bool(qobject_to_qbool(obj1)) ==
                      qbool_get_bool(qobject_to_qbool(obj2)));
         return;
-    case QTYPE_QINT:
-        d->result = (qint_get_int(qobject_to_qint(obj1)) ==
-                     qint_get_int(qobject_to_qint(obj2)));
+    case QTYPE_QNUM:
+        g_assert(qnum_get_int(qobject_to_qnum(obj1), &val1));
+        g_assert(qnum_get_int(qobject_to_qnum(obj2), &val2));
+        d->result = val1 == val2;
         return;
     case QTYPE_QSTRING:
         d->result = g_strcmp0(qstring_get_str(qobject_to_qstring(obj1)),
diff --git a/tests/test-qobject-input-visitor.c b/tests/test-qobject-input-visitor.c
index f2ed3161af..e6757727fd 100644
--- a/tests/test-qobject-input-visitor.c
+++ b/tests/test-qobject-input-visitor.c
@@ -164,7 +164,7 @@ static void test_visitor_in_int_overflow(TestInputVisitorData *data,
     Visitor *v;
 
     /* this will overflow a Qint/int64, so should be deserialized into
-     * a QFloat/double field instead, leading to an error if we pass it
+     * a QNum/double field instead, leading to an error if we pass it
      * to visit_type_int. confirm this.
      */
     v = visitor_input_test_init(data, "%f", DBL_MAX);
@@ -466,17 +466,19 @@ static void test_visitor_in_any(TestInputVisitorData *data,
 {
     QObject *res = NULL;
     Visitor *v;
-    QInt *qint;
+    QNum *qnum;
     QBool *qbool;
     QString *qstring;
     QDict *qdict;
     QObject *qobj;
+    int64_t val;
 
     v = visitor_input_test_init(data, "-42");
     visit_type_any(v, NULL, &res, &error_abort);
-    qint = qobject_to_qint(res);
-    g_assert(qint);
-    g_assert_cmpint(qint_get_int(qint), ==, -42);
+    qnum = qobject_to_qnum(res);
+    g_assert(qnum);
+    g_assert(qnum_get_int(qnum, &val));
+    g_assert_cmpint(val, ==, -42);
     qobject_decref(res);
 
     v = visitor_input_test_init(data, "{ 'integer': -42, 'boolean': true, 'string': 'foo' }");
@@ -485,9 +487,10 @@ static void test_visitor_in_any(TestInputVisitorData *data,
     g_assert(qdict && qdict_size(qdict) == 3);
     qobj = qdict_get(qdict, "integer");
     g_assert(qobj);
-    qint = qobject_to_qint(qobj);
-    g_assert(qint);
-    g_assert_cmpint(qint_get_int(qint), ==, -42);
+    qnum = qobject_to_qnum(qobj);
+    g_assert(qnum);
+    g_assert(qnum_get_int(qnum, &val));
+    g_assert_cmpint(val, ==, -42);
     qobj = qdict_get(qdict, "boolean");
     g_assert(qobj);
     qbool = qobject_to_qbool(qobj);
@@ -565,7 +568,7 @@ static void test_visitor_in_alternate(TestInputVisitorData *data,
 
     v = visitor_input_test_init(data, "42");
     visit_type_UserDefAlternate(v, NULL, &tmp, &error_abort);
-    g_assert_cmpint(tmp->type, ==, QTYPE_QINT);
+    g_assert_cmpint(tmp->type, ==, QTYPE_QNUM);
     g_assert_cmpint(tmp->u.i, ==, 42);
     qapi_free_UserDefAlternate(tmp);
 
@@ -593,7 +596,7 @@ static void test_visitor_in_alternate(TestInputVisitorData *data,
 
     v = visitor_input_test_init(data, "{ 'alt': 42 }");
     visit_type_WrapAlternate(v, NULL, &wrap, &error_abort);
-    g_assert_cmpint(wrap->alt->type, ==, QTYPE_QINT);
+    g_assert_cmpint(wrap->alt->type, ==, QTYPE_QNUM);
     g_assert_cmpint(wrap->alt->u.i, ==, 42);
     qapi_free_WrapAlternate(wrap);
 
@@ -634,19 +637,19 @@ static void test_visitor_in_alternate_number(TestInputVisitorData *data,
 
     v = visitor_input_test_init(data, "42");
     visit_type_AltEnumNum(v, NULL, &aen, &error_abort);
-    g_assert_cmpint(aen->type, ==, QTYPE_QFLOAT);
+    g_assert_cmpint(aen->type, ==, QTYPE_QNUM);
     g_assert_cmpfloat(aen->u.n, ==, 42);
     qapi_free_AltEnumNum(aen);
 
     v = visitor_input_test_init(data, "42");
     visit_type_AltNumEnum(v, NULL, &ans, &error_abort);
-    g_assert_cmpint(ans->type, ==, QTYPE_QFLOAT);
+    g_assert_cmpint(ans->type, ==, QTYPE_QNUM);
     g_assert_cmpfloat(ans->u.n, ==, 42);
     qapi_free_AltNumEnum(ans);
 
     v = visitor_input_test_init(data, "42");
     visit_type_AltEnumInt(v, NULL, &asi, &error_abort);
-    g_assert_cmpint(asi->type, ==, QTYPE_QINT);
+    g_assert_cmpint(asi->type, ==, QTYPE_QNUM);
     g_assert_cmpint(asi->u.i, ==, 42);
     qapi_free_AltEnumInt(asi);
 
@@ -659,13 +662,13 @@ static void test_visitor_in_alternate_number(TestInputVisitorData *data,
 
     v = visitor_input_test_init(data, "42.5");
     visit_type_AltEnumNum(v, NULL, &aen, &error_abort);
-    g_assert_cmpint(aen->type, ==, QTYPE_QFLOAT);
+    g_assert_cmpint(aen->type, ==, QTYPE_QNUM);
     g_assert_cmpfloat(aen->u.n, ==, 42.5);
     qapi_free_AltEnumNum(aen);
 
     v = visitor_input_test_init(data, "42.5");
     visit_type_AltNumEnum(v, NULL, &ans, &error_abort);
-    g_assert_cmpint(ans->type, ==, QTYPE_QFLOAT);
+    g_assert_cmpint(ans->type, ==, QTYPE_QNUM);
     g_assert_cmpfloat(ans->u.n, ==, 42.5);
     qapi_free_AltNumEnum(ans);
 
diff --git a/tests/test-qobject-output-visitor.c b/tests/test-qobject-output-visitor.c
index 4e8fdf1397..3180d8cbde 100644
--- a/tests/test-qobject-output-visitor.c
+++ b/tests/test-qobject-output-visitor.c
@@ -58,13 +58,15 @@ static void test_visitor_out_int(TestOutputVisitorData *data,
                                  const void *unused)
 {
     int64_t value = -42;
-    QInt *qint;
+    int64_t val;
+    QNum *qnum;
 
     visit_type_int(data->ov, NULL, &value, &error_abort);
 
-    qint = qobject_to_qint(visitor_get(data));
-    g_assert(qint);
-    g_assert_cmpint(qint_get_int(qint), ==, value);
+    qnum = qobject_to_qnum(visitor_get(data));
+    g_assert(qnum);
+    g_assert(qnum_get_int(qnum, &val));
+    g_assert_cmpint(val, ==, value);
 }
 
 static void test_visitor_out_bool(TestOutputVisitorData *data,
@@ -84,13 +86,13 @@ static void test_visitor_out_number(TestOutputVisitorData *data,
                                     const void *unused)
 {
     double value = 3.14;
-    QFloat *qfloat;
+    QNum *qnum;
 
     visit_type_number(data->ov, NULL, &value, &error_abort);
 
-    qfloat = qobject_to_qfloat(visitor_get(data));
-    g_assert(qfloat);
-    g_assert(qfloat_get_double(qfloat) == value);
+    qnum = qobject_to_qnum(visitor_get(data));
+    g_assert(qnum);
+    g_assert(qnum_get_double(qnum) == value);
 }
 
 static void test_visitor_out_string(TestOutputVisitorData *data,
@@ -329,16 +331,18 @@ static void test_visitor_out_any(TestOutputVisitorData *data,
                                  const void *unused)
 {
     QObject *qobj;
-    QInt *qint;
+    QNum *qnum;
     QBool *qbool;
     QString *qstring;
     QDict *qdict;
+    int64_t val;
 
-    qobj = QOBJECT(qint_from_int(-42));
+    qobj = QOBJECT(qnum_from_int(-42));
     visit_type_any(data->ov, NULL, &qobj, &error_abort);
-    qint = qobject_to_qint(visitor_get(data));
-    g_assert(qint);
-    g_assert_cmpint(qint_get_int(qint), ==, -42);
+    qnum = qobject_to_qnum(visitor_get(data));
+    g_assert(qnum);
+    g_assert(qnum_get_int(qnum, &val));
+    g_assert_cmpint(val, ==, -42);
     qobject_decref(qobj);
 
     visitor_reset(data);
@@ -351,9 +355,10 @@ static void test_visitor_out_any(TestOutputVisitorData *data,
     qobject_decref(qobj);
     qdict = qobject_to_qdict(visitor_get(data));
     g_assert(qdict);
-    qint = qobject_to_qint(qdict_get(qdict, "integer"));
-    g_assert(qint);
-    g_assert_cmpint(qint_get_int(qint), ==, -42);
+    qnum = qobject_to_qnum(qdict_get(qdict, "integer"));
+    g_assert(qnum);
+    g_assert(qnum_get_int(qnum, &val));
+    g_assert_cmpint(val, ==, -42);
     qbool = qobject_to_qbool(qdict_get(qdict, "boolean"));
     g_assert(qbool);
     g_assert(qbool_get_bool(qbool) == true);
@@ -388,18 +393,20 @@ static void test_visitor_out_alternate(TestOutputVisitorData *data,
                                        const void *unused)
 {
     UserDefAlternate *tmp;
-    QInt *qint;
+    QNum *qnum;
     QString *qstr;
     QDict *qdict;
+    int64_t val;
 
     tmp = g_new0(UserDefAlternate, 1);
-    tmp->type = QTYPE_QINT;
+    tmp->type = QTYPE_QNUM;
     tmp->u.i = 42;
 
     visit_type_UserDefAlternate(data->ov, NULL, &tmp, &error_abort);
-    qint = qobject_to_qint(visitor_get(data));
-    g_assert(qint);
-    g_assert_cmpint(qint_get_int(qint), ==, 42);
+    qnum = qobject_to_qnum(visitor_get(data));
+    g_assert(qnum);
+    g_assert(qnum_get_int(qnum, &val));
+    g_assert_cmpint(val, ==, 42);
 
     qapi_free_UserDefAlternate(tmp);
 
@@ -603,18 +610,21 @@ static void check_native_list(QObject *qobj,
     case USER_DEF_NATIVE_LIST_UNION_KIND_U16:
     case USER_DEF_NATIVE_LIST_UNION_KIND_U32:
     case USER_DEF_NATIVE_LIST_UNION_KIND_U64:
-        /* all integer elements in JSON arrays get stored into QInts when
+        /* all integer elements in JSON arrays get stored into QNums when
          * we convert to QObjects, so we can check them all in the same
          * fashion, so simply fall through here
          */
     case USER_DEF_NATIVE_LIST_UNION_KIND_INTEGER:
         for (i = 0; i < 32; i++) {
             QObject *tmp;
-            QInt *qvalue;
+            QNum *qvalue;
+            int64_t val;
+
             tmp = qlist_peek(qlist);
             g_assert(tmp);
-            qvalue = qobject_to_qint(tmp);
-            g_assert_cmpint(qint_get_int(qvalue), ==, i);
+            qvalue = qobject_to_qnum(tmp);
+            g_assert(qnum_get_int(qvalue, &val));
+            g_assert_cmpint(val, ==, i);
             qobject_decref(qlist_pop(qlist));
         }
         break;
@@ -645,15 +655,15 @@ static void check_native_list(QObject *qobj,
     case USER_DEF_NATIVE_LIST_UNION_KIND_NUMBER:
         for (i = 0; i < 32; i++) {
             QObject *tmp;
-            QFloat *qvalue;
+            QNum *qvalue;
             GString *double_expected = g_string_new("");
             GString *double_actual = g_string_new("");
 
             tmp = qlist_peek(qlist);
             g_assert(tmp);
-            qvalue = qobject_to_qfloat(tmp);
+            qvalue = qobject_to_qnum(tmp);
             g_string_printf(double_expected, "%.6f", (double)i / 3);
-            g_string_printf(double_actual, "%.6f", qfloat_get_double(qvalue));
+            g_string_printf(double_actual, "%.6f", qnum_get_double(qvalue));
             g_assert_cmpstr(double_actual->str, ==, double_expected->str);
 
             qobject_decref(qlist_pop(qlist));
diff --git a/tests/test-x86-cpuid-compat.c b/tests/test-x86-cpuid-compat.c
index 6c71e46391..f30f2030a8 100644
--- a/tests/test-x86-cpuid-compat.c
+++ b/tests/test-x86-cpuid-compat.c
@@ -1,10 +1,7 @@
 #include "qemu/osdep.h"
 #include "qemu-common.h"
-#include "qapi/qmp/qlist.h"
-#include "qapi/qmp/qstring.h"
-#include "qapi/qmp/qdict.h"
-#include "qapi/qmp/qint.h"
-#include "qapi/qmp/qbool.h"
+#include "qapi/error.h"
+#include "qapi/qmp/types.h"
 #include "libqtest.h"
 
 static char *get_cpu0_qom_path(void)
@@ -57,12 +54,14 @@ static void test_cpuid_prop(const void *data)
 {
     const CpuidTestArgs *args = data;
     char *path;
-    QInt *value;
+    QNum *value;
+    int64_t val;
 
     qtest_start(args->cmdline);
     path = get_cpu0_qom_path();
-    value = qobject_to_qint(qom_get(path, args->property));
-    g_assert_cmpint(qint_get_int(value), ==, args->expected_value);
+    value = qobject_to_qnum(qom_get(path, args->property));
+    g_assert(qnum_get_int(value, &val));
+    g_assert_cmpint(val, ==, args->expected_value);
     qtest_end();
 
     QDECREF(value);
@@ -109,12 +108,15 @@ static uint32_t get_feature_word(QList *features, uint32_t eax, uint32_t ecx,
         uint32_t reax = qdict_get_int(w, "cpuid-input-eax");
         bool has_ecx = qdict_haskey(w, "cpuid-input-ecx");
         uint32_t recx = 0;
+        int64_t val;
 
         if (has_ecx) {
             recx = qdict_get_int(w, "cpuid-input-ecx");
         }
         if (eax == reax && (!has_ecx || ecx == recx) && !strcmp(rreg, reg)) {
-            return qint_get_int(qobject_to_qint(qdict_get(w, "features")));
+            g_assert(qnum_get_int(qobject_to_qnum(qdict_get(w, "features")),
+                                  &val));
+            return val;
         }
     }
     return 0;
diff --git a/ui/spice-core.c b/ui/spice-core.c
index 804abc5c0f..561d0649cf 100644
--- a/ui/spice-core.c
+++ b/ui/spice-core.c
@@ -30,7 +30,6 @@
 #include "qemu-x509.h"
 #include "qemu/sockets.h"
 #include "qmp-commands.h"
-#include "qapi/qmp/qint.h"
 #include "qapi/qmp/qbool.h"
 #include "qapi/qmp/qstring.h"
 #include "qapi/qmp/qjson.h"
diff --git a/ui/vnc-enc-tight.c b/ui/vnc-enc-tight.c
index 1e53b1cf84..89ab12c0d8 100644
--- a/ui/vnc-enc-tight.c
+++ b/ui/vnc-enc-tight.c
@@ -44,7 +44,6 @@
 #endif
 
 #include "qemu/bswap.h"
-#include "qapi/qmp/qint.h"
 #include "vnc.h"
 #include "vnc-enc-tight.h"
 #include "vnc-palette.h"
diff --git a/util/qemu-option.c b/util/qemu-option.c
index 5977bfc3e9..39b1e06225 100644
--- a/util/qemu-option.c
+++ b/util/qemu-option.c
@@ -941,9 +941,8 @@ typedef struct OptsFromQDictState {
 static void qemu_opts_from_qdict_1(const char *key, QObject *obj, void *opaque)
 {
     OptsFromQDictState *state = opaque;
-    char buf[32];
+    char buf[32], *tmp = NULL;
     const char *value;
-    int n;
 
     if (!strcmp(key, "id") || *state->errp) {
         return;
@@ -953,17 +952,9 @@ static void qemu_opts_from_qdict_1(const char *key, QObject *obj, void *opaque)
     case QTYPE_QSTRING:
         value = qstring_get_str(qobject_to_qstring(obj));
         break;
-    case QTYPE_QINT:
-        n = snprintf(buf, sizeof(buf), "%" PRId64,
-                     qint_get_int(qobject_to_qint(obj)));
-        assert(n < sizeof(buf));
-        value = buf;
-        break;
-    case QTYPE_QFLOAT:
-        n = snprintf(buf, sizeof(buf), "%.17g",
-                     qfloat_get_double(qobject_to_qfloat(obj)));
-        assert(n < sizeof(buf));
-        value = buf;
+    case QTYPE_QNUM:
+        tmp = qnum_to_string(qobject_to_qnum(obj));
+        value = tmp;
         break;
     case QTYPE_QBOOL:
         pstrcpy(buf, sizeof(buf),
@@ -975,12 +966,13 @@ static void qemu_opts_from_qdict_1(const char *key, QObject *obj, void *opaque)
     }
 
     qemu_opt_set(state->opts, key, value, state->errp);
+    g_free(tmp);
 }
 
 /*
  * Create QemuOpts from a QDict.
  * Use value of key "id" as ID if it exists and is a QString.
- * Only QStrings, QInts, QFloats and QBools are copied.  Entries with
+ * Only QStrings, QNums and QBools are copied.  Entries with
  * other types are silently ignored.
  */
 QemuOpts *qemu_opts_from_qdict(QemuOptsList *list, const QDict *qdict,
diff --git a/MAINTAINERS b/MAINTAINERS
index 7df088259b..b53054111a 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1412,8 +1412,7 @@ F: include/qapi/qmp/
 X: include/qapi/qmp/dispatch.h
 F: scripts/coccinelle/qobject.cocci
 F: tests/check-qdict.c
-F: tests/check-qfloat.c
-F: tests/check-qint.c
+F: tests/check-qnum.c
 F: tests/check-qjson.c
 F: tests/check-qlist.c
 F: tests/check-qstring.c
diff --git a/qobject/Makefile.objs b/qobject/Makefile.objs
index bed55084bb..fc8885c9a4 100644
--- a/qobject/Makefile.objs
+++ b/qobject/Makefile.objs
@@ -1,2 +1,2 @@
-util-obj-y = qnull.o qint.o qstring.o qdict.o qlist.o qfloat.o qbool.o
+util-obj-y = qnull.o qnum.o qstring.o qdict.o qlist.o qbool.o
 util-obj-y += qjson.o qobject.o json-lexer.o json-streamer.o json-parser.o
diff --git a/scripts/coccinelle/qobject.cocci b/scripts/coccinelle/qobject.cocci
index 97703a438b..c3253deb1b 100644
--- a/scripts/coccinelle/qobject.cocci
+++ b/scripts/coccinelle/qobject.cocci
@@ -6,7 +6,7 @@ expression Obj, Key, E;
 - qdict_put_obj(Obj, Key, QOBJECT(E));
 + qdict_put(Obj, Key, E);
 |
-- qdict_put(Obj, Key, qint_from_int(E));
+- qdict_put(Obj, Key, qnum_from_int(E));
 + qdict_put_int(Obj, Key, E);
 |
 - qdict_put(Obj, Key, qbool_from_bool(E));
@@ -24,7 +24,7 @@ expression Obj, E;
 - qlist_append_obj(Obj, QOBJECT(E));
 + qlist_append(Obj, E);
 |
-- qlist_append(Obj, qint_from_int(E));
+- qlist_append(Obj, qnum_from_int(E));
 + qlist_append_int(Obj, E);
 |
 - qlist_append(Obj, qbool_from_bool(E));
diff --git a/tests/.gitignore b/tests/.gitignore
index 40c2e3e757..8e01b004f1 100644
--- a/tests/.gitignore
+++ b/tests/.gitignore
@@ -1,7 +1,6 @@
 atomic_add-bench
 check-qdict
-check-qfloat
-check-qint
+check-qnum
 check-qjson
 check-qlist
 check-qnull
diff --git a/tests/Makefile.include b/tests/Makefile.include
index f42f3dfa72..fec5af765a 100644
--- a/tests/Makefile.include
+++ b/tests/Makefile.include
@@ -10,10 +10,8 @@ check-unit-y = tests/check-qdict$(EXESUF)
 gcov-files-check-qdict-y = qobject/qdict.c
 check-unit-y += tests/test-char$(EXESUF)
 gcov-files-check-qdict-y = chardev/char.c
-check-unit-y += tests/check-qfloat$(EXESUF)
-gcov-files-check-qfloat-y = qobject/qfloat.c
-check-unit-y += tests/check-qint$(EXESUF)
-gcov-files-check-qint-y = qobject/qint.c
+check-unit-y += tests/check-qnum$(EXESUF)
+gcov-files-check-qnum-y = qobject/qnum.c
 check-unit-y += tests/check-qstring$(EXESUF)
 gcov-files-check-qstring-y = qobject/qstring.c
 check-unit-y += tests/check-qlist$(EXESUF)
@@ -506,8 +504,8 @@ GENERATED_FILES += tests/test-qapi-types.h tests/test-qapi-visit.h \
 	tests/test-qmp-commands.h tests/test-qapi-event.h \
 	tests/test-qmp-introspect.h
 
-test-obj-y = tests/check-qint.o tests/check-qstring.o tests/check-qdict.o \
-	tests/check-qlist.o tests/check-qfloat.o tests/check-qnull.o \
+test-obj-y = tests/check-qnum.o tests/check-qstring.o tests/check-qdict.o \
+	tests/check-qlist.o tests/check-qnull.o \
 	tests/check-qjson.o \
 	tests/test-coroutine.o tests/test-string-output-visitor.o \
 	tests/test-string-input-visitor.o tests/test-qobject-output-visitor.o \
@@ -535,11 +533,10 @@ test-crypto-obj-y = $(crypto-obj-y) $(test-qom-obj-y)
 test-io-obj-y = $(io-obj-y) $(test-crypto-obj-y)
 test-block-obj-y = $(block-obj-y) $(test-io-obj-y) tests/iothread.o
 
-tests/check-qint$(EXESUF): tests/check-qint.o $(test-util-obj-y)
+tests/check-qnum$(EXESUF): tests/check-qnum.o $(test-util-obj-y)
 tests/check-qstring$(EXESUF): tests/check-qstring.o $(test-util-obj-y)
 tests/check-qdict$(EXESUF): tests/check-qdict.o $(test-util-obj-y)
 tests/check-qlist$(EXESUF): tests/check-qlist.o $(test-util-obj-y)
-tests/check-qfloat$(EXESUF): tests/check-qfloat.o $(test-util-obj-y)
 tests/check-qnull$(EXESUF): tests/check-qnull.o $(test-util-obj-y)
 tests/check-qjson$(EXESUF): tests/check-qjson.o $(test-util-obj-y)
 tests/check-qom-interface$(EXESUF): tests/check-qom-interface.o $(test-qom-obj-y)
diff --git a/tests/qapi-schema/comments.out b/tests/qapi-schema/comments.out
index 5d7c13cad1..17e652535c 100644
--- a/tests/qapi-schema/comments.out
+++ b/tests/qapi-schema/comments.out
@@ -1,4 +1,4 @@
-enum QType ['none', 'qnull', 'qint', 'qstring', 'qdict', 'qlist', 'qfloat', 'qbool']
+enum QType ['none', 'qnull', 'qnum', 'qstring', 'qdict', 'qlist', 'qbool']
     prefix QTYPE
 enum Status ['good', 'bad', 'ugly']
 object q_empty
diff --git a/tests/qapi-schema/doc-good.out b/tests/qapi-schema/doc-good.out
index 70c1252408..63ca25a8b9 100644
--- a/tests/qapi-schema/doc-good.out
+++ b/tests/qapi-schema/doc-good.out
@@ -6,7 +6,7 @@ object Object
     tag base1
     case one: Variant1
     case two: Variant2
-enum QType ['none', 'qnull', 'qint', 'qstring', 'qdict', 'qlist', 'qfloat', 'qbool']
+enum QType ['none', 'qnull', 'qnum', 'qstring', 'qdict', 'qlist', 'qbool']
     prefix QTYPE
 object SugaredUnion
     member type: SugaredUnionKind optional=False
diff --git a/tests/qapi-schema/empty.out b/tests/qapi-schema/empty.out
index 8a5b034424..40b886ddae 100644
--- a/tests/qapi-schema/empty.out
+++ b/tests/qapi-schema/empty.out
@@ -1,3 +1,3 @@
-enum QType ['none', 'qnull', 'qint', 'qstring', 'qdict', 'qlist', 'qfloat', 'qbool']
+enum QType ['none', 'qnull', 'qnum', 'qstring', 'qdict', 'qlist', 'qbool']
     prefix QTYPE
 object q_empty
diff --git a/tests/qapi-schema/event-case.out b/tests/qapi-schema/event-case.out
index 5a0f2bf805..313c0fe7be 100644
--- a/tests/qapi-schema/event-case.out
+++ b/tests/qapi-schema/event-case.out
@@ -1,4 +1,4 @@
-enum QType ['none', 'qnull', 'qint', 'qstring', 'qdict', 'qlist', 'qfloat', 'qbool']
+enum QType ['none', 'qnull', 'qnum', 'qstring', 'qdict', 'qlist', 'qbool']
     prefix QTYPE
 event oops None
    boxed=False
diff --git a/tests/qapi-schema/ident-with-escape.out b/tests/qapi-schema/ident-with-escape.out
index 1d2722c02e..b5637cb2e0 100644
--- a/tests/qapi-schema/ident-with-escape.out
+++ b/tests/qapi-schema/ident-with-escape.out
@@ -1,4 +1,4 @@
-enum QType ['none', 'qnull', 'qint', 'qstring', 'qdict', 'qlist', 'qfloat', 'qbool']
+enum QType ['none', 'qnull', 'qnum', 'qstring', 'qdict', 'qlist', 'qbool']
     prefix QTYPE
 command fooA q_obj_fooA-arg -> None
    gen=True success_response=True boxed=False
diff --git a/tests/qapi-schema/include-relpath.out b/tests/qapi-schema/include-relpath.out
index 5d7c13cad1..17e652535c 100644
--- a/tests/qapi-schema/include-relpath.out
+++ b/tests/qapi-schema/include-relpath.out
@@ -1,4 +1,4 @@
-enum QType ['none', 'qnull', 'qint', 'qstring', 'qdict', 'qlist', 'qfloat', 'qbool']
+enum QType ['none', 'qnull', 'qnum', 'qstring', 'qdict', 'qlist', 'qbool']
     prefix QTYPE
 enum Status ['good', 'bad', 'ugly']
 object q_empty
diff --git a/tests/qapi-schema/include-repetition.out b/tests/qapi-schema/include-repetition.out
index 5d7c13cad1..17e652535c 100644
--- a/tests/qapi-schema/include-repetition.out
+++ b/tests/qapi-schema/include-repetition.out
@@ -1,4 +1,4 @@
-enum QType ['none', 'qnull', 'qint', 'qstring', 'qdict', 'qlist', 'qfloat', 'qbool']
+enum QType ['none', 'qnull', 'qnum', 'qstring', 'qdict', 'qlist', 'qbool']
     prefix QTYPE
 enum Status ['good', 'bad', 'ugly']
 object q_empty
diff --git a/tests/qapi-schema/include-simple.out b/tests/qapi-schema/include-simple.out
index 5d7c13cad1..17e652535c 100644
--- a/tests/qapi-schema/include-simple.out
+++ b/tests/qapi-schema/include-simple.out
@@ -1,4 +1,4 @@
-enum QType ['none', 'qnull', 'qint', 'qstring', 'qdict', 'qlist', 'qfloat', 'qbool']
+enum QType ['none', 'qnull', 'qnum', 'qstring', 'qdict', 'qlist', 'qbool']
     prefix QTYPE
 enum Status ['good', 'bad', 'ugly']
 object q_empty
diff --git a/tests/qapi-schema/indented-expr.out b/tests/qapi-schema/indented-expr.out
index e8171c935f..586795f44d 100644
--- a/tests/qapi-schema/indented-expr.out
+++ b/tests/qapi-schema/indented-expr.out
@@ -1,4 +1,4 @@
-enum QType ['none', 'qnull', 'qint', 'qstring', 'qdict', 'qlist', 'qfloat', 'qbool']
+enum QType ['none', 'qnull', 'qnum', 'qstring', 'qdict', 'qlist', 'qbool']
     prefix QTYPE
 command eins None -> None
    gen=True success_response=True boxed=False
diff --git a/tests/qapi-schema/qapi-schema-test.out b/tests/qapi-schema/qapi-schema-test.out
index e727a5a84c..b88b8aae6f 100644
--- a/tests/qapi-schema/qapi-schema-test.out
+++ b/tests/qapi-schema/qapi-schema-test.out
@@ -50,7 +50,7 @@ object NestedEnumsOne
     member enum4: EnumOne optional=True
 enum QEnumTwo ['value1', 'value2']
     prefix QENUM_TWO
-enum QType ['none', 'qnull', 'qint', 'qstring', 'qdict', 'qlist', 'qfloat', 'qbool']
+enum QType ['none', 'qnull', 'qnum', 'qstring', 'qdict', 'qlist', 'qbool']
     prefix QTYPE
 object TestStruct
     member integer: int optional=False
-- 
2.13.0.91.g00982b8dd

^ permalink raw reply related	[flat|nested] 80+ messages in thread

* [Qemu-devel] [PATCH v2 10/45] qapi: Remove visit_start_alternate() parameter promote_int
  2017-05-31 13:56 [Qemu-devel] [PATCH v2 00/45] qobject/qapi: add uint type Marc-André Lureau
                   ` (8 preceding siblings ...)
  2017-05-31 13:56 ` [Qemu-devel] [PATCH v2 09/45] qapi: merge QInt and QFloat in QNum Marc-André Lureau
@ 2017-05-31 13:56 ` Marc-André Lureau
  2017-06-02  7:57   ` Markus Armbruster
  2017-05-31 13:56 ` [Qemu-devel] [PATCH v2 11/45] tests: remove /qnum/destroy test Marc-André Lureau
                   ` (36 subsequent siblings)
  46 siblings, 1 reply; 80+ messages in thread
From: Marc-André Lureau @ 2017-05-31 13:56 UTC (permalink / raw)
  To: qemu-devel; +Cc: armbru, Marc-André Lureau

Before the previous commit, parameter promote_int = true made
visit_start_alternate() with an input visitor avoid QTYPE_QINT
variants and create QTYPE_QFLOAT variants instead.  This was used
where QTYPE_QINT variants were invalid.

The previous commit fused QTYPE_QINT with QTYPE_QFLOAT, rendering
rendering promote_int useless and unused.

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
 include/qapi/visitor.h             |  4 +---
 include/qapi/visitor-impl.h        |  2 +-
 scripts/qapi-visit.py              | 12 +++---------
 qapi/qapi-visit-core.c             |  6 +++---
 qapi/qapi-clone-visitor.c          |  2 +-
 qapi/qapi-dealloc-visitor.c        |  2 +-
 qapi/qobject-input-visitor.c       |  2 +-
 tests/test-qobject-input-visitor.c |  2 +-
 qapi/trace-events                  |  2 +-
 9 files changed, 13 insertions(+), 21 deletions(-)

diff --git a/include/qapi/visitor.h b/include/qapi/visitor.h
index 4721c39ae3..74768aabda 100644
--- a/include/qapi/visitor.h
+++ b/include/qapi/visitor.h
@@ -410,15 +410,13 @@ void visit_end_list(Visitor *v, void **list);
  * the qtype of the next thing to be visited, stored in (*@obj)->type.
  * Other visitors will leave @obj unchanged.
  *
- * If @promote_int, treat integers as QTYPE_FLOAT.
- *
  * If successful, this must be paired with visit_end_alternate() with
  * the same @obj to clean up, even if visiting the contents of the
  * alternate fails.
  */
 void visit_start_alternate(Visitor *v, const char *name,
                            GenericAlternate **obj, size_t size,
-                           bool promote_int, Error **errp);
+                           Error **errp);
 
 /*
  * Finish visiting an alternate type.
diff --git a/include/qapi/visitor-impl.h b/include/qapi/visitor-impl.h
index e87709db5c..dcd656ab76 100644
--- a/include/qapi/visitor-impl.h
+++ b/include/qapi/visitor-impl.h
@@ -71,7 +71,7 @@ struct Visitor
      * optional for output visitors. */
     void (*start_alternate)(Visitor *v, const char *name,
                             GenericAlternate **obj, size_t size,
-                            bool promote_int, Error **errp);
+                            Error **errp);
 
     /* Optional, needed for dealloc visitor */
     void (*end_alternate)(Visitor *v, void **obj);
diff --git a/scripts/qapi-visit.py b/scripts/qapi-visit.py
index cc447ecacc..bd0b742236 100644
--- a/scripts/qapi-visit.py
+++ b/scripts/qapi-visit.py
@@ -161,20 +161,14 @@ void visit_type_%(c_name)s(Visitor *v, const char *name, %(c_name)s *obj, Error
 
 
 def gen_visit_alternate(name, variants):
-    promote_int = 'true'
-    ret = ''
-    for var in variants.variants:
-        if var.type.alternate_qtype() == 'QTYPE_QNUM':
-            promote_int = 'false'
-
-    ret += mcgen('''
+    ret = mcgen('''
 
 void visit_type_%(c_name)s(Visitor *v, const char *name, %(c_name)s **obj, Error **errp)
 {
     Error *err = NULL;
 
     visit_start_alternate(v, name, (GenericAlternate **)obj, sizeof(**obj),
-                          %(promote_int)s, &err);
+                          &err);
     if (err) {
         goto out;
     }
@@ -183,7 +177,7 @@ void visit_type_%(c_name)s(Visitor *v, const char *name, %(c_name)s **obj, Error
     }
     switch ((*obj)->type) {
 ''',
-                 c_name=c_name(name), promote_int=promote_int)
+                 c_name=c_name(name))
 
     for var in variants.variants:
         ret += mcgen('''
diff --git a/qapi/qapi-visit-core.c b/qapi/qapi-visit-core.c
index 43a09d147d..935a2c5bc9 100644
--- a/qapi/qapi-visit-core.c
+++ b/qapi/qapi-visit-core.c
@@ -106,15 +106,15 @@ void visit_end_list(Visitor *v, void **obj)
 
 void visit_start_alternate(Visitor *v, const char *name,
                            GenericAlternate **obj, size_t size,
-                           bool promote_int, Error **errp)
+                           Error **errp)
 {
     Error *err = NULL;
 
     assert(obj && size >= sizeof(GenericAlternate));
     assert(!(v->type & VISITOR_OUTPUT) || *obj);
-    trace_visit_start_alternate(v, name, obj, size, promote_int);
+    trace_visit_start_alternate(v, name, obj, size);
     if (v->start_alternate) {
-        v->start_alternate(v, name, obj, size, promote_int, &err);
+        v->start_alternate(v, name, obj, size, &err);
     }
     if (v->type & VISITOR_INPUT) {
         assert(v->start_alternate && !err != !*obj);
diff --git a/qapi/qapi-clone-visitor.c b/qapi/qapi-clone-visitor.c
index de756bfb33..ed16d3a17f 100644
--- a/qapi/qapi-clone-visitor.c
+++ b/qapi/qapi-clone-visitor.c
@@ -70,7 +70,7 @@ static GenericList *qapi_clone_next_list(Visitor *v, GenericList *tail,
 
 static void qapi_clone_start_alternate(Visitor *v, const char *name,
                                        GenericAlternate **obj, size_t size,
-                                       bool promote_int, Error **errp)
+                                       Error **errp)
 {
     qapi_clone_start_struct(v, name, (void **)obj, size, errp);
 }
diff --git a/qapi/qapi-dealloc-visitor.c b/qapi/qapi-dealloc-visitor.c
index e39457bc79..fd6f9fb61c 100644
--- a/qapi/qapi-dealloc-visitor.c
+++ b/qapi/qapi-dealloc-visitor.c
@@ -38,7 +38,7 @@ static void qapi_dealloc_end_struct(Visitor *v, void **obj)
 
 static void qapi_dealloc_start_alternate(Visitor *v, const char *name,
                                          GenericAlternate **obj, size_t size,
-                                         bool promote_int, Error **errp)
+                                         Error **errp)
 {
 }
 
diff --git a/qapi/qobject-input-visitor.c b/qapi/qobject-input-visitor.c
index b32318c352..74835ba339 100644
--- a/qapi/qobject-input-visitor.c
+++ b/qapi/qobject-input-visitor.c
@@ -367,7 +367,7 @@ static void qobject_input_end_list(Visitor *v, void **obj)
 
 static void qobject_input_start_alternate(Visitor *v, const char *name,
                                           GenericAlternate **obj, size_t size,
-                                          bool promote_int, Error **errp)
+                                          Error **errp)
 {
     QObjectInputVisitor *qiv = to_qiv(v);
     QObject *qobj = qobject_input_get_object(qiv, name, false, errp);
diff --git a/tests/test-qobject-input-visitor.c b/tests/test-qobject-input-visitor.c
index e6757727fd..983c59c474 100644
--- a/tests/test-qobject-input-visitor.c
+++ b/tests/test-qobject-input-visitor.c
@@ -1101,7 +1101,7 @@ static void test_visitor_in_fail_struct_missing(TestInputVisitorData *data,
     error_free_or_abort(&err);
     visit_start_list(v, "list", NULL, 0, &err);
     error_free_or_abort(&err);
-    visit_start_alternate(v, "alternate", &alt, sizeof(*alt), false, &err);
+    visit_start_alternate(v, "alternate", &alt, sizeof(*alt), &err);
     error_free_or_abort(&err);
     visit_optional(v, "optional", &present);
     g_assert(!present);
diff --git a/qapi/trace-events b/qapi/trace-events
index 339cacf0ad..3b57abaa37 100644
--- a/qapi/trace-events
+++ b/qapi/trace-events
@@ -11,7 +11,7 @@ visit_next_list(void *v, void *tail, size_t size) "v=%p tail=%p size=%zu"
 visit_check_list(void *v) "v=%p"
 visit_end_list(void *v, void *obj) "v=%p obj=%p"
 
-visit_start_alternate(void *v, const char *name, void *obj, size_t size, bool promote_int) "v=%p name=%s obj=%p size=%zu promote_int=%d"
+visit_start_alternate(void *v, const char *name, void *obj, size_t size) "v=%p name=%s obj=%p size=%zu"
 visit_end_alternate(void *v, void *obj) "v=%p obj=%p"
 
 visit_optional(void *v, const char *name, bool *present) "v=%p name=%s present=%p"
-- 
2.13.0.91.g00982b8dd

^ permalink raw reply related	[flat|nested] 80+ messages in thread

* [Qemu-devel] [PATCH v2 11/45] tests: remove /qnum/destroy test
  2017-05-31 13:56 [Qemu-devel] [PATCH v2 00/45] qobject/qapi: add uint type Marc-André Lureau
                   ` (9 preceding siblings ...)
  2017-05-31 13:56 ` [Qemu-devel] [PATCH v2 10/45] qapi: Remove visit_start_alternate() parameter promote_int Marc-André Lureau
@ 2017-05-31 13:56 ` Marc-André Lureau
  2017-06-02  8:00   ` Markus Armbruster
  2017-05-31 13:56 ` [Qemu-devel] [PATCH v2 12/45] qnum: add uint type Marc-André Lureau
                   ` (35 subsequent siblings)
  46 siblings, 1 reply; 80+ messages in thread
From: Marc-André Lureau @ 2017-05-31 13:56 UTC (permalink / raw)
  To: qemu-devel; +Cc: armbru, Marc-André Lureau

The test isn't really useful.

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
 tests/check-qnum.c | 18 ++----------------
 1 file changed, 2 insertions(+), 16 deletions(-)

diff --git a/tests/check-qnum.c b/tests/check-qnum.c
index 4b3fec050e..7cc4262ee7 100644
--- a/tests/check-qnum.c
+++ b/tests/check-qnum.c
@@ -32,8 +32,7 @@ static void qnum_from_int_test(void)
     g_assert_cmpint(qi->base.refcnt, ==, 1);
     g_assert_cmpint(qobject_type(QOBJECT(qi)), ==, QTYPE_QNUM);
 
-    // destroy doesn't exit yet
-    g_free(qi);
+    QDECREF(qi);
 }
 
 static void qnum_from_double_test(void)
@@ -47,8 +46,7 @@ static void qnum_from_double_test(void)
     g_assert_cmpint(qf->base.refcnt, ==, 1);
     g_assert_cmpint(qobject_type(QOBJECT(qf)), ==, QTYPE_QNUM);
 
-    // destroy doesn't exit yet
-    g_free(qf);
+    QDECREF(qf);
 }
 
 static void qnum_from_int64_test(void)
@@ -106,24 +104,12 @@ static void qnum_to_string_test(void)
     QDECREF(qn);
 }
 
-static void qnum_destroy_test(void)
-{
-    QNum *qn;
-
-    qn = qnum_from_int(0);
-    QDECREF(qn);
-
-    qn = qnum_from_double(0.42);
-    QDECREF(qn);
-}
-
 int main(int argc, char **argv)
 {
     g_test_init(&argc, &argv, NULL);
 
     g_test_add_func("/qnum/from_int", qnum_from_int_test);
     g_test_add_func("/qnum/from_double", qnum_from_double_test);
-    g_test_add_func("/qnum/destroy", qnum_destroy_test);
     g_test_add_func("/qnum/from_int64", qnum_from_int64_test);
     g_test_add_func("/qnum/get_int", qnum_get_int_test);
     g_test_add_func("/qnum/to_qnum", qobject_to_qnum_test);
-- 
2.13.0.91.g00982b8dd

^ permalink raw reply related	[flat|nested] 80+ messages in thread

* [Qemu-devel] [PATCH v2 12/45] qnum: add uint type
  2017-05-31 13:56 [Qemu-devel] [PATCH v2 00/45] qobject/qapi: add uint type Marc-André Lureau
                   ` (10 preceding siblings ...)
  2017-05-31 13:56 ` [Qemu-devel] [PATCH v2 11/45] tests: remove /qnum/destroy test Marc-André Lureau
@ 2017-05-31 13:56 ` Marc-André Lureau
  2017-06-02  8:05   ` Markus Armbruster
  2017-05-31 13:56 ` [Qemu-devel] [PATCH v2 13/45] json: learn to parse uint64 numbers Marc-André Lureau
                   ` (34 subsequent siblings)
  46 siblings, 1 reply; 80+ messages in thread
From: Marc-André Lureau @ 2017-05-31 13:56 UTC (permalink / raw)
  To: qemu-devel; +Cc: armbru, Marc-André Lureau

In order to store integer values superior to INT64_MAX, add a u64
internal representation.

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
 include/qapi/qmp/qnum.h |  4 ++++
 qobject/qnum.c          | 51 +++++++++++++++++++++++++++++++++++++++++++++++++
 tests/check-qnum.c      | 47 +++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 102 insertions(+)

diff --git a/include/qapi/qmp/qnum.h b/include/qapi/qmp/qnum.h
index cc636fac5f..549b2117ec 100644
--- a/include/qapi/qmp/qnum.h
+++ b/include/qapi/qmp/qnum.h
@@ -18,6 +18,7 @@
 
 typedef enum {
     QNUM_I64,
+    QNUM_U64,
     QNUM_DOUBLE
 } QNumKind;
 
@@ -26,14 +27,17 @@ typedef struct QNum {
     QNumKind kind;
     union {
         int64_t i64;
+        uint64_t u64;
         double dbl;
     } u;
 } QNum;
 
 QNum *qnum_from_int(int64_t value);
+QNum *qnum_from_uint(uint64_t value);
 QNum *qnum_from_double(double value);
 
 bool qnum_get_int(const QNum *qn, int64_t *val);
+bool qnum_get_uint(const QNum *qn, uint64_t *val);
 double qnum_get_double(QNum *qn);
 
 char *qnum_to_string(QNum *qn);
diff --git a/qobject/qnum.c b/qobject/qnum.c
index f16864160a..4ad37ed5bc 100644
--- a/qobject/qnum.c
+++ b/qobject/qnum.c
@@ -34,6 +34,22 @@ QNum *qnum_from_int(int64_t value)
 }
 
 /**
+ * qnum_from_uint(): Create a new QNum from an uint64_t
+ *
+ * Return strong reference.
+ */
+QNum *qnum_from_uint(uint64_t value)
+{
+    QNum *qn = g_new(QNum, 1);
+
+    qobject_init(QOBJECT(qn), QTYPE_QNUM);
+    qn->kind = QNUM_U64;
+    qn->u.u64 = value;
+
+    return qn;
+}
+
+/**
  * qnum_from_double(): Create a new QNum from a double
  *
  * Return strong reference.
@@ -60,6 +76,37 @@ bool qnum_get_int(const QNum *qn, int64_t *val)
     case QNUM_I64:
         *val = qn->u.i64;
         return true;
+    case QNUM_U64:
+        if (qn->u.u64 > INT64_MAX) {
+            return false;
+        }
+        *val = qn->u.u64;
+        return true;
+    case QNUM_DOUBLE:
+        return false;
+    }
+
+    g_assert_not_reached();
+    return false;
+}
+
+/**
+ * qnum_get_uint(): Get an unsigned integer from the number
+ *
+ * Return true on success.
+ */
+bool qnum_get_uint(const QNum *qn, uint64_t *val)
+{
+    switch (qn->kind) {
+    case QNUM_I64:
+        if (qn->u.i64 < 0) {
+            return false;
+        }
+        *val = qn->u.i64;
+        return true;
+    case QNUM_U64:
+        *val = qn->u.u64;
+        return true;
     case QNUM_DOUBLE:
         return false;
     }
@@ -76,6 +123,8 @@ double qnum_get_double(QNum *qn)
     switch (qn->kind) {
     case QNUM_I64:
         return qn->u.i64;
+    case QNUM_U64:
+        return qn->u.u64;
     case QNUM_DOUBLE:
         return qn->u.dbl;
     }
@@ -91,6 +140,8 @@ char *qnum_to_string(QNum *qn)
     switch (qn->kind) {
     case QNUM_I64:
         return g_strdup_printf("%" PRId64, qn->u.i64);
+    case QNUM_U64:
+        return g_strdup_printf("%" PRIu64, qn->u.u64);
     case QNUM_DOUBLE:
         /* FIXME: snprintf() is locale dependent; but JSON requires
          * numbers to be formatted as if in the C locale. Dependence
diff --git a/tests/check-qnum.c b/tests/check-qnum.c
index 7cc4262ee7..234fd7fc82 100644
--- a/tests/check-qnum.c
+++ b/tests/check-qnum.c
@@ -35,6 +35,20 @@ static void qnum_from_int_test(void)
     QDECREF(qi);
 }
 
+static void qnum_from_uint_test(void)
+{
+    QNum *qu;
+    const int value = UINT_MAX;
+
+    qu = qnum_from_int(value);
+    g_assert(qu != NULL);
+    g_assert(qu->u.u64 == value);
+    g_assert(qu->base.refcnt == 1);
+    g_assert(qobject_type(QOBJECT(qu)) == QTYPE_QNUM);
+
+    QDECREF(qu);
+}
+
 static void qnum_from_double_test(void)
 {
     QNum *qf;
@@ -73,6 +87,37 @@ static void qnum_get_int_test(void)
     QDECREF(qi);
 }
 
+static void qnum_get_uint_test(void)
+{
+    QNum *qn;
+    const int value = 123456;
+    uint64_t val;
+    int64_t ival;
+
+    qn = qnum_from_uint(value);
+    g_assert(qnum_get_uint(qn, &val));
+    g_assert_cmpuint(val, ==, value);
+    QDECREF(qn);
+
+    qn = qnum_from_int(value);
+    g_assert(qnum_get_uint(qn, &val));
+    g_assert_cmpuint(val, ==, value);
+    QDECREF(qn);
+
+    /* invalid cases */
+    qn = qnum_from_int(-1);
+    g_assert(!qnum_get_uint(qn, &val));
+    QDECREF(qn);
+
+    qn = qnum_from_uint(-1ULL);
+    g_assert(!qnum_get_int(qn, &ival));
+    QDECREF(qn);
+
+    qn = qnum_from_double(0.42);
+    g_assert(!qnum_get_uint(qn, &val));
+    QDECREF(qn);
+}
+
 static void qobject_to_qnum_test(void)
 {
     QNum *qn;
@@ -109,9 +154,11 @@ int main(int argc, char **argv)
     g_test_init(&argc, &argv, NULL);
 
     g_test_add_func("/qnum/from_int", qnum_from_int_test);
+    g_test_add_func("/qnum/from_uint", qnum_from_uint_test);
     g_test_add_func("/qnum/from_double", qnum_from_double_test);
     g_test_add_func("/qnum/from_int64", qnum_from_int64_test);
     g_test_add_func("/qnum/get_int", qnum_get_int_test);
+    g_test_add_func("/qnum/get_uint", qnum_get_uint_test);
     g_test_add_func("/qnum/to_qnum", qobject_to_qnum_test);
     g_test_add_func("/qnum/to_string", qnum_to_string_test);
 
-- 
2.13.0.91.g00982b8dd

^ permalink raw reply related	[flat|nested] 80+ messages in thread

* [Qemu-devel] [PATCH v2 13/45] json: learn to parse uint64 numbers
  2017-05-31 13:56 [Qemu-devel] [PATCH v2 00/45] qobject/qapi: add uint type Marc-André Lureau
                   ` (11 preceding siblings ...)
  2017-05-31 13:56 ` [Qemu-devel] [PATCH v2 12/45] qnum: add uint type Marc-André Lureau
@ 2017-05-31 13:56 ` Marc-André Lureau
  2017-06-02  8:24   ` Markus Armbruster
  2017-05-31 13:56 ` [Qemu-devel] [PATCH v2 14/45] qapi: update the qobject visitor to use QNUM_U64 Marc-André Lureau
                   ` (33 subsequent siblings)
  46 siblings, 1 reply; 80+ messages in thread
From: Marc-André Lureau @ 2017-05-31 13:56 UTC (permalink / raw)
  To: qemu-devel; +Cc: armbru, Marc-André Lureau

Switch strtoll() usage to qemu_strtoi64() helper while at it.

Add a few tests for large numbers.

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
 qobject/json-lexer.c  |  4 ++++
 qobject/json-parser.c | 30 ++++++++++++++++++++++++------
 tests/check-qjson.c   | 37 +++++++++++++++++++++++++++++++++++++
 3 files changed, 65 insertions(+), 6 deletions(-)

diff --git a/qobject/json-lexer.c b/qobject/json-lexer.c
index af4a75e05b..980ba159d6 100644
--- a/qobject/json-lexer.c
+++ b/qobject/json-lexer.c
@@ -227,15 +227,18 @@ static const uint8_t json_lexer[][256] =  {
     /* escape */
     [IN_ESCAPE_LL] = {
         ['d'] = JSON_ESCAPE,
+        ['u'] = JSON_ESCAPE,
     },
 
     [IN_ESCAPE_L] = {
         ['d'] = JSON_ESCAPE,
         ['l'] = IN_ESCAPE_LL,
+        ['u'] = JSON_ESCAPE,
     },
 
     [IN_ESCAPE_I64] = {
         ['d'] = JSON_ESCAPE,
+        ['u'] = JSON_ESCAPE,
     },
 
     [IN_ESCAPE_I6] = {
@@ -251,6 +254,7 @@ static const uint8_t json_lexer[][256] =  {
         ['i'] = JSON_ESCAPE,
         ['p'] = JSON_ESCAPE,
         ['s'] = JSON_ESCAPE,
+        ['u'] = JSON_ESCAPE,
         ['f'] = JSON_ESCAPE,
         ['l'] = IN_ESCAPE_L,
         ['I'] = IN_ESCAPE_I,
diff --git a/qobject/json-parser.c b/qobject/json-parser.c
index b90b2fb45a..62dcac8128 100644
--- a/qobject/json-parser.c
+++ b/qobject/json-parser.c
@@ -12,6 +12,7 @@
  */
 
 #include "qemu/osdep.h"
+#include "qemu/cutils.h"
 #include "qapi/error.h"
 #include "qemu-common.h"
 #include "qapi/qmp/types.h"
@@ -472,6 +473,13 @@ static QObject *parse_escape(JSONParserContext *ctxt, va_list *ap)
     } else if (!strcmp(token->str, "%lld") ||
                !strcmp(token->str, "%I64d")) {
         return QOBJECT(qnum_from_int(va_arg(*ap, long long)));
+    } else if (!strcmp(token->str, "%u")) {
+        return QOBJECT(qnum_from_uint(va_arg(*ap, unsigned int)));
+    } else if (!strcmp(token->str, "%lu")) {
+        return QOBJECT(qnum_from_uint(va_arg(*ap, unsigned long)));
+    } else if (!strcmp(token->str, "%llu") ||
+               !strcmp(token->str, "%I64u")) {
+        return QOBJECT(qnum_from_uint(va_arg(*ap, unsigned long long)));
     } else if (!strcmp(token->str, "%s")) {
         return QOBJECT(qstring_from_str(va_arg(*ap, const char *)));
     } else if (!strcmp(token->str, "%f")) {
@@ -493,20 +501,30 @@ static QObject *parse_literal(JSONParserContext *ctxt)
     case JSON_INTEGER: {
         /*
          * Represent JSON_INTEGER as QNUM_I64 if possible, else as
-         * QNUM_DOUBLE. Note that strtoll() fails with ERANGE when
-         * it's not possible.
+         * QNUM_U64, else as QNUM_DOUBLE.  Note that qemu_strtoi64()
+         * and qemu_strtou64 fail with ERANGE when it's not possible.
          *
          * qnum_get_int() will then work for any signed 64-bit
-         * JSON_INTEGER, and qnum_get_double both for any JSON_INTEGER
+         * JSON_INTEGER, qnum_get_uint() for any unsigned 64-bit
+         * integer, and qnum_get_double() both for any JSON_INTEGER
          * and any JSON_FLOAT.
          */
+        int ret;
         int64_t value;
+        uint64_t uvalue;
 
-        errno = 0; /* strtoll doesn't set errno on success */
-        value = strtoll(token->str, NULL, 10);
-        if (errno != ERANGE) {
+        ret = qemu_strtoi64(token->str, NULL, 10, &value);
+        if (!ret) {
             return QOBJECT(qnum_from_int(value));
         }
+        assert(ret == -ERANGE);
+
+        if (token->str[0] != '-') {
+            ret = qemu_strtou64(token->str, NULL, 10, &uvalue);
+            if (!ret) {
+                return QOBJECT(qnum_from_uint(uvalue));
+            }
+        }
         /* fall through to JSON_FLOAT */
     }
     case JSON_FLOAT:
diff --git a/tests/check-qjson.c b/tests/check-qjson.c
index 8ec728a702..6fb14445a3 100644
--- a/tests/check-qjson.c
+++ b/tests/check-qjson.c
@@ -906,6 +906,42 @@ static void simple_number(void)
     }
 }
 
+static void large_number(void)
+{
+    const char *maxu64 = "18446744073709551615"; /* 2^64-1 */
+    const char *gtu64 = "18446744073709551616"; /* 2^64 */
+    const char *range = "-9223372036854775809";
+    QNum *qnum;
+    QString *str;
+    uint64_t val;
+
+    qnum = qobject_to_qnum(qobject_from_json(maxu64, &error_abort));
+    g_assert(qnum);
+    g_assert(qnum_get_uint(qnum, &val));
+    g_assert_cmpuint(val, ==, 18446744073709551615U);
+
+    str = qobject_to_json(QOBJECT(qnum));
+    g_assert_cmpstr(qstring_get_str(str), ==, maxu64);
+    QDECREF(str);
+    QDECREF(qnum);
+
+    qnum = qobject_to_qnum(qobject_from_json(gtu64, &error_abort));
+    g_assert(qnum);
+    g_assert_cmpfloat(qnum_get_double(qnum), >, 0);
+    g_assert(!qnum_get_uint(qnum, &val));
+
+    str = qobject_to_json(QOBJECT(qnum));
+    g_assert_cmpstr(qstring_get_str(str), ==, gtu64);
+    QDECREF(str);
+    QDECREF(qnum);
+
+    qnum = qobject_to_qnum(qobject_from_json(range, &error_abort));
+    g_assert(qnum);
+    g_assert_cmpfloat(qnum_get_double(qnum), <, 0);
+    g_assert(!qnum_get_uint(qnum, &val));
+    QDECREF(qnum);
+}
+
 static void float_number(void)
 {
     int i;
@@ -1475,6 +1511,7 @@ int main(int argc, char **argv)
     g_test_add_func("/literals/string/vararg", vararg_string);
 
     g_test_add_func("/literals/number/simple", simple_number);
+    g_test_add_func("/literals/number/large", large_number);
     g_test_add_func("/literals/number/float", float_number);
     g_test_add_func("/literals/number/vararg", vararg_number);
 
-- 
2.13.0.91.g00982b8dd

^ permalink raw reply related	[flat|nested] 80+ messages in thread

* [Qemu-devel] [PATCH v2 14/45] qapi: update the qobject visitor to use QNUM_U64
  2017-05-31 13:56 [Qemu-devel] [PATCH v2 00/45] qobject/qapi: add uint type Marc-André Lureau
                   ` (12 preceding siblings ...)
  2017-05-31 13:56 ` [Qemu-devel] [PATCH v2 13/45] json: learn to parse uint64 numbers Marc-André Lureau
@ 2017-05-31 13:56 ` Marc-André Lureau
  2017-06-02 11:18   ` Markus Armbruster
  2017-06-02 11:20   ` Markus Armbruster
  2017-05-31 13:56 ` [Qemu-devel] [PATCH v2 15/45] object: add uint property setter/getter Marc-André Lureau
                   ` (32 subsequent siblings)
  46 siblings, 2 replies; 80+ messages in thread
From: Marc-André Lureau @ 2017-05-31 13:56 UTC (permalink / raw)
  To: qemu-devel; +Cc: armbru, Marc-André Lureau

Switch to use QNum/uint where appropriate to remove i64 limitation.

The input visitor will cast i64 input to u64 for compatibility
reasons (existing json QMP client already use negative i64 for large
u64, and expect an implicit cast in qemu).

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
 hw/i386/acpi-build.c                |  3 +--
 qapi/qobject-input-visitor.c        | 21 ++++++++++++++++-----
 qapi/qobject-output-visitor.c       |  3 +--
 tests/test-qobject-input-visitor.c  |  7 ++-----
 tests/test-qobject-output-visitor.c | 28 +++++++++++++++++++++-------
 5 files changed, 41 insertions(+), 21 deletions(-)

diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
index 1709efdf1c..ba2be1e9da 100644
--- a/hw/i386/acpi-build.c
+++ b/hw/i386/acpi-build.c
@@ -2634,10 +2634,9 @@ static bool acpi_get_mcfg(AcpiMcfgInfo *mcfg)
     if (!o) {
         return false;
     }
-    if (!qnum_get_int(qobject_to_qnum(o), &val)) {
+    if (!qnum_get_uint(qobject_to_qnum(o), &mcfg->mcfg_base)) {
         g_assert_not_reached();
     }
-    mcfg->mcfg_base = val;
     qobject_decref(o);
 
     o = object_property_get_qobject(pci_host, PCIE_HOST_MCFG_SIZE, NULL);
diff --git a/qapi/qobject-input-visitor.c b/qapi/qobject-input-visitor.c
index 74835ba339..7f9d6f57a1 100644
--- a/qapi/qobject-input-visitor.c
+++ b/qapi/qobject-input-visitor.c
@@ -417,7 +417,6 @@ static void qobject_input_type_int64_keyval(Visitor *v, const char *name,
 static void qobject_input_type_uint64(Visitor *v, const char *name,
                                       uint64_t *obj, Error **errp)
 {
-    /* FIXME: qobject_to_qnum mishandles values over INT64_MAX */
     QObjectInputVisitor *qiv = to_qiv(v);
     QObject *qobj = qobject_input_get_object(qiv, name, true, errp);
     QNum *qnum;
@@ -427,11 +426,23 @@ static void qobject_input_type_uint64(Visitor *v, const char *name,
         return;
     }
     qnum = qobject_to_qnum(qobj);
-    if (!qnum || !qnum_get_int(qnum, &val)) {
-        error_setg(errp, QERR_INVALID_PARAMETER_TYPE,
-                   full_name(qiv, name), "integer");
+    if (!qnum) {
+        goto err;
+    }
+
+    if (qnum_get_uint(qnum, obj)) {
+        return;
     }
-    *obj = val;
+
+    /* Need to accept negative values for backward compatibility */
+    if (qnum_get_int(qnum, &val)) {
+        *obj = val;
+        return;
+    }
+
+err:
+    error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
+               full_name(qiv, name), "uint64");
 }
 
 static void qobject_input_type_uint64_keyval(Visitor *v, const char *name,
diff --git a/qapi/qobject-output-visitor.c b/qapi/qobject-output-visitor.c
index 2ca5093b22..70be84ccb5 100644
--- a/qapi/qobject-output-visitor.c
+++ b/qapi/qobject-output-visitor.c
@@ -150,9 +150,8 @@ static void qobject_output_type_int64(Visitor *v, const char *name,
 static void qobject_output_type_uint64(Visitor *v, const char *name,
                                        uint64_t *obj, Error **errp)
 {
-    /* FIXME values larger than INT64_MAX become negative */
     QObjectOutputVisitor *qov = to_qov(v);
-    qobject_output_add(qov, name, qnum_from_int(*obj));
+    qobject_output_add(qov, name, qnum_from_uint(*obj));
 }
 
 static void qobject_output_type_bool(Visitor *v, const char *name, bool *obj,
diff --git a/tests/test-qobject-input-visitor.c b/tests/test-qobject-input-visitor.c
index 983c59c474..6f94fc677c 100644
--- a/tests/test-qobject-input-visitor.c
+++ b/tests/test-qobject-input-visitor.c
@@ -122,7 +122,6 @@ static void test_visitor_in_int(TestInputVisitorData *data,
 static void test_visitor_in_uint(TestInputVisitorData *data,
                                 const void *unused)
 {
-    Error *err = NULL;
     uint64_t res = 0;
     int64_t i64;
     double dbl;
@@ -146,12 +145,10 @@ static void test_visitor_in_uint(TestInputVisitorData *data,
     visit_type_uint64(v, NULL, &res, &error_abort);
     g_assert_cmpuint(res, ==, (uint64_t)-value);
 
-    /* BUG: value between INT64_MAX+1 and UINT64_MAX rejected */
-
     v = visitor_input_test_init(data, "18446744073709551574");
 
-    visit_type_uint64(v, NULL, &res, &err);
-    error_free_or_abort(&err);
+    visit_type_uint64(v, NULL, &res, &error_abort);
+    g_assert_cmpuint(res, ==, 18446744073709551574U);
 
     visit_type_number(v, NULL, &dbl, &error_abort);
 }
diff --git a/tests/test-qobject-output-visitor.c b/tests/test-qobject-output-visitor.c
index 3180d8cbde..d9f106d52e 100644
--- a/tests/test-qobject-output-visitor.c
+++ b/tests/test-qobject-output-visitor.c
@@ -602,17 +602,31 @@ static void check_native_list(QObject *qobj,
     qlist = qlist_copy(qobject_to_qlist(qdict_get(qdict, "data")));
 
     switch (kind) {
-    case USER_DEF_NATIVE_LIST_UNION_KIND_S8:
-    case USER_DEF_NATIVE_LIST_UNION_KIND_S16:
-    case USER_DEF_NATIVE_LIST_UNION_KIND_S32:
-    case USER_DEF_NATIVE_LIST_UNION_KIND_S64:
     case USER_DEF_NATIVE_LIST_UNION_KIND_U8:
     case USER_DEF_NATIVE_LIST_UNION_KIND_U16:
     case USER_DEF_NATIVE_LIST_UNION_KIND_U32:
     case USER_DEF_NATIVE_LIST_UNION_KIND_U64:
-        /* all integer elements in JSON arrays get stored into QNums when
-         * we convert to QObjects, so we can check them all in the same
-         * fashion, so simply fall through here
+        for (i = 0; i < 32; i++) {
+            QObject *tmp;
+            QNum *qvalue;
+            uint64_t val;
+
+            tmp = qlist_peek(qlist);
+            g_assert(tmp);
+            qvalue = qobject_to_qnum(tmp);
+            g_assert(qnum_get_uint(qvalue, &val));
+            g_assert_cmpuint(val, ==, i);
+            qobject_decref(qlist_pop(qlist));
+        }
+        break;
+
+    case USER_DEF_NATIVE_LIST_UNION_KIND_S8:
+    case USER_DEF_NATIVE_LIST_UNION_KIND_S16:
+    case USER_DEF_NATIVE_LIST_UNION_KIND_S32:
+    case USER_DEF_NATIVE_LIST_UNION_KIND_S64:
+        /* All signed integer elements in JSON arrays get stored into
+         * QInts when we convert to QObjects, so we can check them all
+         * in the same fashion, so simply fall through here.
          */
     case USER_DEF_NATIVE_LIST_UNION_KIND_INTEGER:
         for (i = 0; i < 32; i++) {
-- 
2.13.0.91.g00982b8dd

^ permalink raw reply related	[flat|nested] 80+ messages in thread

* [Qemu-devel] [PATCH v2 15/45] object: add uint property setter/getter
  2017-05-31 13:56 [Qemu-devel] [PATCH v2 00/45] qobject/qapi: add uint type Marc-André Lureau
                   ` (13 preceding siblings ...)
  2017-05-31 13:56 ` [Qemu-devel] [PATCH v2 14/45] qapi: update the qobject visitor to use QNUM_U64 Marc-André Lureau
@ 2017-05-31 13:56 ` Marc-André Lureau
  2017-05-31 13:56 ` [Qemu-devel] [PATCH v2 16/45] q35: fix get_mmcfg_size to use uint64 visitor Marc-André Lureau
                   ` (31 subsequent siblings)
  46 siblings, 0 replies; 80+ messages in thread
From: Marc-André Lureau @ 2017-05-31 13:56 UTC (permalink / raw)
  To: qemu-devel; +Cc: armbru, Marc-André Lureau

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Reviewed-by: Markus Armbruster <armbru@redhat.com>
---
 include/qom/object.h | 23 +++++++++++++++++++++++
 qom/object.c         | 29 +++++++++++++++++++++++++++++
 2 files changed, 52 insertions(+)

diff --git a/include/qom/object.h b/include/qom/object.h
index cd0f412ce9..abaeb8cf4e 100644
--- a/include/qom/object.h
+++ b/include/qom/object.h
@@ -1094,6 +1094,29 @@ int64_t object_property_get_int(Object *obj, const char *name,
                                 Error **errp);
 
 /**
+ * object_property_set_uint:
+ * @value: the value to be written to the property
+ * @name: the name of the property
+ * @errp: returns an error if this function fails
+ *
+ * Writes an unsigned integer value to a property.
+ */
+void object_property_set_uint(Object *obj, uint64_t value,
+                              const char *name, Error **errp);
+
+/**
+ * object_property_get_uint:
+ * @obj: the object
+ * @name: the name of the property
+ * @errp: returns an error if this function fails
+ *
+ * Returns: the value of the property, converted to an unsigned integer, or 0
+ * an error occurs (including when the property value is not an integer).
+ */
+uint64_t object_property_get_uint(Object *obj, const char *name,
+                                  Error **errp);
+
+/**
  * object_property_get_enum:
  * @obj: the object
  * @name: the name of the property
diff --git a/qom/object.c b/qom/object.c
index cf0e64a625..3adeb762ea 100644
--- a/qom/object.c
+++ b/qom/object.c
@@ -1216,6 +1216,35 @@ int64_t object_property_get_int(Object *obj, const char *name,
     return retval;
 }
 
+void object_property_set_uint(Object *obj, uint64_t value,
+                              const char *name, Error **errp)
+{
+    QNum *qnum = qnum_from_uint(value);
+
+    object_property_set_qobject(obj, QOBJECT(qnum), name, errp);
+    QDECREF(qnum);
+}
+
+uint64_t object_property_get_uint(Object *obj, const char *name,
+                                  Error **errp)
+{
+    QObject *ret = object_property_get_qobject(obj, name, errp);
+    QNum *qnum;
+    uint64_t retval;
+
+    if (!ret) {
+        return 0;
+    }
+    qnum = qobject_to_qnum(ret);
+    if (!qnum || !qnum_get_uint(qnum, &retval)) {
+        error_setg(errp, QERR_INVALID_PARAMETER_TYPE, name, "uint");
+        retval = 0;
+    }
+
+    qobject_decref(ret);
+    return retval;
+}
+
 typedef struct EnumProperty {
     const char * const *strings;
     int (*get)(Object *, Error **);
-- 
2.13.0.91.g00982b8dd

^ permalink raw reply related	[flat|nested] 80+ messages in thread

* [Qemu-devel] [PATCH v2 16/45] q35: fix get_mmcfg_size to use uint64 visitor
  2017-05-31 13:56 [Qemu-devel] [PATCH v2 00/45] qobject/qapi: add uint type Marc-André Lureau
                   ` (14 preceding siblings ...)
  2017-05-31 13:56 ` [Qemu-devel] [PATCH v2 15/45] object: add uint property setter/getter Marc-André Lureau
@ 2017-05-31 13:56 ` Marc-André Lureau
  2017-06-02 11:34   ` Markus Armbruster
  2017-05-31 13:56 ` [Qemu-devel] [PATCH v2 17/45] object: use more specific property type names Marc-André Lureau
                   ` (30 subsequent siblings)
  46 siblings, 1 reply; 80+ messages in thread
From: Marc-André Lureau @ 2017-05-31 13:56 UTC (permalink / raw)
  To: qemu-devel; +Cc: armbru, Marc-André Lureau

e->size is hwaddr, i.e. uint64_t. We silently truncate.
Fix suggested by Markus Armbruster.

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
 hw/pci-host/q35.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/hw/pci-host/q35.c b/hw/pci-host/q35.c
index cd5c49616e..e8a04d31d1 100644
--- a/hw/pci-host/q35.c
+++ b/hw/pci-host/q35.c
@@ -129,9 +129,8 @@ static void q35_host_get_mmcfg_size(Object *obj, Visitor *v, const char *name,
                                     void *opaque, Error **errp)
 {
     PCIExpressHost *e = PCIE_HOST_BRIDGE(obj);
-    uint32_t value = e->size;
 
-    visit_type_uint32(v, name, &value, errp);
+    visit_type_uint64(v, name, &e->size, errp);
 }
 
 static Property mch_props[] = {
-- 
2.13.0.91.g00982b8dd

^ permalink raw reply related	[flat|nested] 80+ messages in thread

* [Qemu-devel] [PATCH v2 17/45] object: use more specific property type names
  2017-05-31 13:56 [Qemu-devel] [PATCH v2 00/45] qobject/qapi: add uint type Marc-André Lureau
                   ` (15 preceding siblings ...)
  2017-05-31 13:56 ` [Qemu-devel] [PATCH v2 16/45] q35: fix get_mmcfg_size to use uint64 visitor Marc-André Lureau
@ 2017-05-31 13:56 ` Marc-André Lureau
  2017-06-02 13:38   ` Markus Armbruster
  2017-05-31 13:56 ` [Qemu-devel] [PATCH v2 18/45] qdev: make default property int Marc-André Lureau
                   ` (29 subsequent siblings)
  46 siblings, 1 reply; 80+ messages in thread
From: Marc-André Lureau @ 2017-05-31 13:56 UTC (permalink / raw)
  To: qemu-devel; +Cc: armbru, Marc-André Lureau

Use the actual unsigned integer type name (this should't break since
property type aren't directly accessed from outside it seems).

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
 backends/cryptodev.c |  2 +-
 hw/pci-host/piix.c   |  8 ++++----
 hw/pci-host/q35.c    | 10 +++++-----
 hw/ppc/pnv.c         |  2 +-
 net/dump.c           |  2 +-
 net/filter-buffer.c  |  2 +-
 6 files changed, 13 insertions(+), 13 deletions(-)

diff --git a/backends/cryptodev.c b/backends/cryptodev.c
index 832f056266..1764c179fe 100644
--- a/backends/cryptodev.c
+++ b/backends/cryptodev.c
@@ -222,7 +222,7 @@ cryptodev_backend_can_be_deleted(UserCreatable *uc, Error **errp)
 
 static void cryptodev_backend_instance_init(Object *obj)
 {
-    object_property_add(obj, "queues", "int",
+    object_property_add(obj, "queues", "uint32",
                           cryptodev_backend_get_queues,
                           cryptodev_backend_set_queues,
                           NULL, NULL, NULL);
diff --git a/hw/pci-host/piix.c b/hw/pci-host/piix.c
index 4ce201ea65..a2c1033dbe 100644
--- a/hw/pci-host/piix.c
+++ b/hw/pci-host/piix.c
@@ -273,19 +273,19 @@ static void i440fx_pcihost_initfn(Object *obj)
     memory_region_init_io(&s->data_mem, obj, &pci_host_data_le_ops, s,
                           "pci-conf-data", 4);
 
-    object_property_add(obj, PCI_HOST_PROP_PCI_HOLE_START, "int",
+    object_property_add(obj, PCI_HOST_PROP_PCI_HOLE_START, "uint32",
                         i440fx_pcihost_get_pci_hole_start,
                         NULL, NULL, NULL, NULL);
 
-    object_property_add(obj, PCI_HOST_PROP_PCI_HOLE_END, "int",
+    object_property_add(obj, PCI_HOST_PROP_PCI_HOLE_END, "uint32",
                         i440fx_pcihost_get_pci_hole_end,
                         NULL, NULL, NULL, NULL);
 
-    object_property_add(obj, PCI_HOST_PROP_PCI_HOLE64_START, "int",
+    object_property_add(obj, PCI_HOST_PROP_PCI_HOLE64_START, "uint64",
                         i440fx_pcihost_get_pci_hole64_start,
                         NULL, NULL, NULL, NULL);
 
-    object_property_add(obj, PCI_HOST_PROP_PCI_HOLE64_END, "int",
+    object_property_add(obj, PCI_HOST_PROP_PCI_HOLE64_END, "uint64",
                         i440fx_pcihost_get_pci_hole64_end,
                         NULL, NULL, NULL, NULL);
 }
diff --git a/hw/pci-host/q35.c b/hw/pci-host/q35.c
index e8a04d31d1..c2f2af5d9a 100644
--- a/hw/pci-host/q35.c
+++ b/hw/pci-host/q35.c
@@ -175,23 +175,23 @@ static void q35_host_initfn(Object *obj)
     qdev_prop_set_uint32(DEVICE(&s->mch), "addr", PCI_DEVFN(0, 0));
     qdev_prop_set_bit(DEVICE(&s->mch), "multifunction", false);
 
-    object_property_add(obj, PCI_HOST_PROP_PCI_HOLE_START, "int",
+    object_property_add(obj, PCI_HOST_PROP_PCI_HOLE_START, "uint32",
                         q35_host_get_pci_hole_start,
                         NULL, NULL, NULL, NULL);
 
-    object_property_add(obj, PCI_HOST_PROP_PCI_HOLE_END, "int",
+    object_property_add(obj, PCI_HOST_PROP_PCI_HOLE_END, "uint32",
                         q35_host_get_pci_hole_end,
                         NULL, NULL, NULL, NULL);
 
-    object_property_add(obj, PCI_HOST_PROP_PCI_HOLE64_START, "int",
+    object_property_add(obj, PCI_HOST_PROP_PCI_HOLE64_START, "uint64",
                         q35_host_get_pci_hole64_start,
                         NULL, NULL, NULL, NULL);
 
-    object_property_add(obj, PCI_HOST_PROP_PCI_HOLE64_END, "int",
+    object_property_add(obj, PCI_HOST_PROP_PCI_HOLE64_END, "uint64",
                         q35_host_get_pci_hole64_end,
                         NULL, NULL, NULL, NULL);
 
-    object_property_add(obj, PCIE_HOST_MCFG_SIZE, "int",
+    object_property_add(obj, PCIE_HOST_MCFG_SIZE, "uint64",
                         q35_host_get_mmcfg_size,
                         NULL, NULL, NULL, NULL);
 
diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c
index 231ed9735b..f2f2e98687 100644
--- a/hw/ppc/pnv.c
+++ b/hw/ppc/pnv.c
@@ -1110,7 +1110,7 @@ static void powernv_machine_initfn(Object *obj)
 
 static void powernv_machine_class_props_init(ObjectClass *oc)
 {
-    object_class_property_add(oc, "num-chips", "uint32_t",
+    object_class_property_add(oc, "num-chips", "uint32",
                               pnv_get_num_chips, pnv_set_num_chips,
                               NULL, NULL, NULL);
     object_class_property_set_description(oc, "num-chips",
diff --git a/net/dump.c b/net/dump.c
index 442eb532f9..15df9a4973 100644
--- a/net/dump.c
+++ b/net/dump.c
@@ -328,7 +328,7 @@ static void filter_dump_instance_init(Object *obj)
 
     nfds->maxlen = 65536;
 
-    object_property_add(obj, "maxlen", "int", filter_dump_get_maxlen,
+    object_property_add(obj, "maxlen", "uint32", filter_dump_get_maxlen,
                         filter_dump_set_maxlen, NULL, NULL, NULL);
     object_property_add_str(obj, "file", file_dump_get_filename,
                             file_dump_set_filename, NULL);
diff --git a/net/filter-buffer.c b/net/filter-buffer.c
index cc6bd94445..9ce96aaa35 100644
--- a/net/filter-buffer.c
+++ b/net/filter-buffer.c
@@ -191,7 +191,7 @@ out:
 
 static void filter_buffer_init(Object *obj)
 {
-    object_property_add(obj, "interval", "int",
+    object_property_add(obj, "interval", "uint32",
                         filter_buffer_get_interval,
                         filter_buffer_set_interval, NULL, NULL, NULL);
 }
-- 
2.13.0.91.g00982b8dd

^ permalink raw reply related	[flat|nested] 80+ messages in thread

* [Qemu-devel] [PATCH v2 18/45] qdev: make default property int
  2017-05-31 13:56 [Qemu-devel] [PATCH v2 00/45] qobject/qapi: add uint type Marc-André Lureau
                   ` (16 preceding siblings ...)
  2017-05-31 13:56 ` [Qemu-devel] [PATCH v2 17/45] object: use more specific property type names Marc-André Lureau
@ 2017-05-31 13:56 ` Marc-André Lureau
  2017-06-02 13:49   ` Markus Armbruster
  2017-05-31 13:56 ` [Qemu-devel] [PATCH v2 19/45] qdev: add unsigned properties Marc-André Lureau
                   ` (28 subsequent siblings)
  46 siblings, 1 reply; 80+ messages in thread
From: Marc-André Lureau @ 2017-05-31 13:56 UTC (permalink / raw)
  To: qemu-devel; +Cc: armbru, Marc-André Lureau

The following patch will add uint properties.

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
 include/hw/qdev-core.h       |  4 +++-
 include/hw/qdev-properties.h | 34 ++++++++++++++--------------
 hw/block/fdc.c               | 54 ++++++++++++++++++++++----------------------
 hw/core/qdev-properties.c    |  6 ++---
 hw/net/e1000e.c              | 14 ++++++------
 5 files changed, 57 insertions(+), 55 deletions(-)

diff --git a/include/hw/qdev-core.h b/include/hw/qdev-core.h
index 9523339762..784971b8d8 100644
--- a/include/hw/qdev-core.h
+++ b/include/hw/qdev-core.h
@@ -226,7 +226,9 @@ struct Property {
     PropertyInfo *info;
     ptrdiff_t    offset;
     uint8_t      bitnr;
-    int64_t      defval;
+    union {
+        int64_t i;
+    } defval;
     int          arrayoffset;
     PropertyInfo *arrayinfo;
     int          arrayfieldsize;
diff --git a/include/hw/qdev-properties.h b/include/hw/qdev-properties.h
index 85e68998a9..6663a547ea 100644
--- a/include/hw/qdev-properties.h
+++ b/include/hw/qdev-properties.h
@@ -37,12 +37,12 @@ extern PropertyInfo qdev_prop_arraylen;
         .offset    = offsetof(_state, _field)                    \
             + type_check(_type, typeof_field(_state, _field)),   \
         }
-#define DEFINE_PROP_DEFAULT(_name, _state, _field, _defval, _prop, _type) { \
+#define DEFINE_PROP_INT(_name, _state, _field, _defval, _prop, _type) { \
         .name      = (_name),                                           \
         .info      = &(_prop),                                          \
         .offset    = offsetof(_state, _field)                           \
             + type_check(_type,typeof_field(_state, _field)),           \
-        .defval    = (_type)_defval,                                    \
+        .defval.i  = (_type)_defval,                                    \
         }
 #define DEFINE_PROP_BIT(_name, _state, _field, _bit, _defval) {  \
         .name      = (_name),                                    \
@@ -50,7 +50,7 @@ extern PropertyInfo qdev_prop_arraylen;
         .bitnr    = (_bit),                                      \
         .offset    = offsetof(_state, _field)                    \
             + type_check(uint32_t,typeof_field(_state, _field)), \
-        .defval    = (bool)_defval,                              \
+        .defval.i  = (bool)_defval,                              \
         }
 #define DEFINE_PROP_BIT64(_name, _state, _field, _bit, _defval) {       \
         .name      = (_name),                                           \
@@ -58,7 +58,7 @@ extern PropertyInfo qdev_prop_arraylen;
         .bitnr    = (_bit),                                             \
         .offset    = offsetof(_state, _field)                           \
             + type_check(uint64_t, typeof_field(_state, _field)),       \
-        .defval    = (bool)_defval,                                     \
+        .defval.i  = (bool)_defval,                                     \
         }
 
 #define DEFINE_PROP_BOOL(_name, _state, _field, _defval) {       \
@@ -66,7 +66,7 @@ extern PropertyInfo qdev_prop_arraylen;
         .info      = &(qdev_prop_bool),                          \
         .offset    = offsetof(_state, _field)                    \
             + type_check(bool, typeof_field(_state, _field)),    \
-        .defval    = (bool)_defval,                              \
+        .defval.i  = (bool)_defval,                              \
         }
 
 #define PROP_ARRAY_LEN_PREFIX "len-"
@@ -107,19 +107,19 @@ extern PropertyInfo qdev_prop_arraylen;
         }
 
 #define DEFINE_PROP_UINT8(_n, _s, _f, _d)                       \
-    DEFINE_PROP_DEFAULT(_n, _s, _f, _d, qdev_prop_uint8, uint8_t)
+    DEFINE_PROP_INT(_n, _s, _f, _d, qdev_prop_uint8, uint8_t)
 #define DEFINE_PROP_UINT16(_n, _s, _f, _d)                      \
-    DEFINE_PROP_DEFAULT(_n, _s, _f, _d, qdev_prop_uint16, uint16_t)
+    DEFINE_PROP_INT(_n, _s, _f, _d, qdev_prop_uint16, uint16_t)
 #define DEFINE_PROP_UINT32(_n, _s, _f, _d)                      \
-    DEFINE_PROP_DEFAULT(_n, _s, _f, _d, qdev_prop_uint32, uint32_t)
+    DEFINE_PROP_INT(_n, _s, _f, _d, qdev_prop_uint32, uint32_t)
 #define DEFINE_PROP_INT32(_n, _s, _f, _d)                      \
-    DEFINE_PROP_DEFAULT(_n, _s, _f, _d, qdev_prop_int32, int32_t)
+    DEFINE_PROP_INT(_n, _s, _f, _d, qdev_prop_int32, int32_t)
 #define DEFINE_PROP_UINT64(_n, _s, _f, _d)                      \
-    DEFINE_PROP_DEFAULT(_n, _s, _f, _d, qdev_prop_uint64, uint64_t)
+    DEFINE_PROP_INT(_n, _s, _f, _d, qdev_prop_uint64, uint64_t)
 #define DEFINE_PROP_SIZE(_n, _s, _f, _d)                       \
-    DEFINE_PROP_DEFAULT(_n, _s, _f, _d, qdev_prop_size, uint64_t)
+    DEFINE_PROP_INT(_n, _s, _f, _d, qdev_prop_size, uint64_t)
 #define DEFINE_PROP_PCI_DEVFN(_n, _s, _f, _d)                   \
-    DEFINE_PROP_DEFAULT(_n, _s, _f, _d, qdev_prop_pci_devfn, int32_t)
+    DEFINE_PROP_INT(_n, _s, _f, _d, qdev_prop_pci_devfn, int32_t)
 
 /*
  * Please avoid pointer properties.  If you must use them, you must
@@ -153,17 +153,17 @@ extern PropertyInfo qdev_prop_arraylen;
 #define DEFINE_PROP_MACADDR(_n, _s, _f)         \
     DEFINE_PROP(_n, _s, _f, qdev_prop_macaddr, MACAddr)
 #define DEFINE_PROP_ON_OFF_AUTO(_n, _s, _f, _d) \
-    DEFINE_PROP_DEFAULT(_n, _s, _f, _d, qdev_prop_on_off_auto, OnOffAuto)
+    DEFINE_PROP_INT(_n, _s, _f, _d, qdev_prop_on_off_auto, OnOffAuto)
 #define DEFINE_PROP_LOSTTICKPOLICY(_n, _s, _f, _d) \
-    DEFINE_PROP_DEFAULT(_n, _s, _f, _d, qdev_prop_losttickpolicy, \
+    DEFINE_PROP_INT(_n, _s, _f, _d, qdev_prop_losttickpolicy, \
                         LostTickPolicy)
 #define DEFINE_PROP_BLOCKDEV_ON_ERROR(_n, _s, _f, _d) \
-    DEFINE_PROP_DEFAULT(_n, _s, _f, _d, qdev_prop_blockdev_on_error, \
+    DEFINE_PROP_INT(_n, _s, _f, _d, qdev_prop_blockdev_on_error, \
                         BlockdevOnError)
 #define DEFINE_PROP_BIOS_CHS_TRANS(_n, _s, _f, _d) \
-    DEFINE_PROP_DEFAULT(_n, _s, _f, _d, qdev_prop_bios_chs_trans, int)
+    DEFINE_PROP_INT(_n, _s, _f, _d, qdev_prop_bios_chs_trans, int)
 #define DEFINE_PROP_BLOCKSIZE(_n, _s, _f) \
-    DEFINE_PROP_DEFAULT(_n, _s, _f, 0, qdev_prop_blocksize, uint16_t)
+    DEFINE_PROP_INT(_n, _s, _f, 0, qdev_prop_blocksize, uint16_t)
 #define DEFINE_PROP_PCI_HOST_DEVADDR(_n, _s, _f) \
     DEFINE_PROP(_n, _s, _f, qdev_prop_pci_host_devaddr, PCIHostDeviceAddress)
 
diff --git a/hw/block/fdc.c b/hw/block/fdc.c
index 2e629b398b..07ce4a0d20 100644
--- a/hw/block/fdc.c
+++ b/hw/block/fdc.c
@@ -511,9 +511,9 @@ typedef struct FloppyDrive {
 static Property floppy_drive_properties[] = {
     DEFINE_PROP_UINT32("unit", FloppyDrive, unit, -1),
     DEFINE_BLOCK_PROPERTIES(FloppyDrive, conf),
-    DEFINE_PROP_DEFAULT("drive-type", FloppyDrive, type,
-                        FLOPPY_DRIVE_TYPE_AUTO, qdev_prop_fdc_drive_type,
-                        FloppyDriveType),
+    DEFINE_PROP_INT("drive-type", FloppyDrive, type,
+                    FLOPPY_DRIVE_TYPE_AUTO, qdev_prop_fdc_drive_type,
+                    FloppyDriveType),
     DEFINE_PROP_END_OF_LIST(),
 };
 
@@ -2805,15 +2805,15 @@ static Property isa_fdc_properties[] = {
     DEFINE_PROP_DRIVE("driveB", FDCtrlISABus, state.qdev_for_drives[1].blk),
     DEFINE_PROP_BIT("check_media_rate", FDCtrlISABus, state.check_media_rate,
                     0, true),
-    DEFINE_PROP_DEFAULT("fdtypeA", FDCtrlISABus, state.qdev_for_drives[0].type,
-                        FLOPPY_DRIVE_TYPE_AUTO, qdev_prop_fdc_drive_type,
-                        FloppyDriveType),
-    DEFINE_PROP_DEFAULT("fdtypeB", FDCtrlISABus, state.qdev_for_drives[1].type,
-                        FLOPPY_DRIVE_TYPE_AUTO, qdev_prop_fdc_drive_type,
-                        FloppyDriveType),
-    DEFINE_PROP_DEFAULT("fallback", FDCtrlISABus, state.fallback,
-                        FLOPPY_DRIVE_TYPE_288, qdev_prop_fdc_drive_type,
-                        FloppyDriveType),
+    DEFINE_PROP_INT("fdtypeA", FDCtrlISABus, state.qdev_for_drives[0].type,
+                    FLOPPY_DRIVE_TYPE_AUTO, qdev_prop_fdc_drive_type,
+                    FloppyDriveType),
+    DEFINE_PROP_INT("fdtypeB", FDCtrlISABus, state.qdev_for_drives[1].type,
+                    FLOPPY_DRIVE_TYPE_AUTO, qdev_prop_fdc_drive_type,
+                    FloppyDriveType),
+    DEFINE_PROP_INT("fallback", FDCtrlISABus, state.fallback,
+                    FLOPPY_DRIVE_TYPE_288, qdev_prop_fdc_drive_type,
+                    FloppyDriveType),
     DEFINE_PROP_END_OF_LIST(),
 };
 
@@ -2862,15 +2862,15 @@ static const VMStateDescription vmstate_sysbus_fdc ={
 static Property sysbus_fdc_properties[] = {
     DEFINE_PROP_DRIVE("driveA", FDCtrlSysBus, state.qdev_for_drives[0].blk),
     DEFINE_PROP_DRIVE("driveB", FDCtrlSysBus, state.qdev_for_drives[1].blk),
-    DEFINE_PROP_DEFAULT("fdtypeA", FDCtrlSysBus, state.qdev_for_drives[0].type,
-                        FLOPPY_DRIVE_TYPE_AUTO, qdev_prop_fdc_drive_type,
-                        FloppyDriveType),
-    DEFINE_PROP_DEFAULT("fdtypeB", FDCtrlSysBus, state.qdev_for_drives[1].type,
-                        FLOPPY_DRIVE_TYPE_AUTO, qdev_prop_fdc_drive_type,
-                        FloppyDriveType),
-    DEFINE_PROP_DEFAULT("fallback", FDCtrlISABus, state.fallback,
-                        FLOPPY_DRIVE_TYPE_144, qdev_prop_fdc_drive_type,
-                        FloppyDriveType),
+    DEFINE_PROP_INT("fdtypeA", FDCtrlSysBus, state.qdev_for_drives[0].type,
+                    FLOPPY_DRIVE_TYPE_AUTO, qdev_prop_fdc_drive_type,
+                    FloppyDriveType),
+    DEFINE_PROP_INT("fdtypeB", FDCtrlSysBus, state.qdev_for_drives[1].type,
+                    FLOPPY_DRIVE_TYPE_AUTO, qdev_prop_fdc_drive_type,
+                    FloppyDriveType),
+    DEFINE_PROP_INT("fallback", FDCtrlISABus, state.fallback,
+                    FLOPPY_DRIVE_TYPE_144, qdev_prop_fdc_drive_type,
+                    FloppyDriveType),
     DEFINE_PROP_END_OF_LIST(),
 };
 
@@ -2891,12 +2891,12 @@ static const TypeInfo sysbus_fdc_info = {
 
 static Property sun4m_fdc_properties[] = {
     DEFINE_PROP_DRIVE("drive", FDCtrlSysBus, state.qdev_for_drives[0].blk),
-    DEFINE_PROP_DEFAULT("fdtype", FDCtrlSysBus, state.qdev_for_drives[0].type,
-                        FLOPPY_DRIVE_TYPE_AUTO, qdev_prop_fdc_drive_type,
-                        FloppyDriveType),
-    DEFINE_PROP_DEFAULT("fallback", FDCtrlISABus, state.fallback,
-                        FLOPPY_DRIVE_TYPE_144, qdev_prop_fdc_drive_type,
-                        FloppyDriveType),
+    DEFINE_PROP_INT("fdtype", FDCtrlSysBus, state.qdev_for_drives[0].type,
+                    FLOPPY_DRIVE_TYPE_AUTO, qdev_prop_fdc_drive_type,
+                    FloppyDriveType),
+    DEFINE_PROP_INT("fallback", FDCtrlISABus, state.fallback,
+                    FLOPPY_DRIVE_TYPE_144, qdev_prop_fdc_drive_type,
+                    FloppyDriveType),
     DEFINE_PROP_END_OF_LIST(),
 };
 
diff --git a/hw/core/qdev-properties.c b/hw/core/qdev-properties.c
index 482efb2683..952cda7758 100644
--- a/hw/core/qdev-properties.c
+++ b/hw/core/qdev-properties.c
@@ -71,7 +71,7 @@ static void set_enum(Object *obj, Visitor *v, const char *name, void *opaque,
 
 static void set_default_value_enum(Object *obj, const Property *prop)
 {
-    object_property_set_str(obj, prop->info->enum_table[prop->defval],
+    object_property_set_str(obj, prop->info->enum_table[prop->defval.i],
                             prop->name, &error_abort);
 }
 
@@ -128,7 +128,7 @@ static void prop_set_bit(Object *obj, Visitor *v, const char *name,
 
 static void set_default_value_bool(Object *obj, const Property *prop)
 {
-    object_property_set_bool(obj, prop->defval, prop->name, &error_abort);
+    object_property_set_bool(obj, prop->defval.i, prop->name, &error_abort);
 }
 
 PropertyInfo qdev_prop_bit = {
@@ -261,7 +261,7 @@ static void set_uint8(Object *obj, Visitor *v, const char *name, void *opaque,
 
 static void set_default_value_int(Object *obj, const Property *prop)
 {
-    object_property_set_int(obj, prop->defval, prop->name, &error_abort);
+    object_property_set_int(obj, prop->defval.i, prop->name, &error_abort);
 }
 
 PropertyInfo qdev_prop_uint8 = {
diff --git a/hw/net/e1000e.c b/hw/net/e1000e.c
index 6e234938db..4e4cc9b52f 100644
--- a/hw/net/e1000e.c
+++ b/hw/net/e1000e.c
@@ -645,13 +645,13 @@ static PropertyInfo e1000e_prop_disable_vnet,
 
 static Property e1000e_properties[] = {
     DEFINE_NIC_PROPERTIES(E1000EState, conf),
-    DEFINE_PROP_DEFAULT("disable_vnet_hdr", E1000EState, disable_vnet, false,
-                        e1000e_prop_disable_vnet, bool),
-    DEFINE_PROP_DEFAULT("subsys_ven", E1000EState, subsys_ven,
-                        PCI_VENDOR_ID_INTEL,
-                        e1000e_prop_subsys_ven, uint16_t),
-    DEFINE_PROP_DEFAULT("subsys", E1000EState, subsys, 0,
-                        e1000e_prop_subsys, uint16_t),
+    DEFINE_PROP_INT("disable_vnet_hdr", E1000EState, disable_vnet, false,
+                    e1000e_prop_disable_vnet, bool),
+    DEFINE_PROP_INT("subsys_ven", E1000EState, subsys_ven,
+                    PCI_VENDOR_ID_INTEL,
+                    e1000e_prop_subsys_ven, uint16_t),
+    DEFINE_PROP_INT("subsys", E1000EState, subsys, 0,
+                    e1000e_prop_subsys, uint16_t),
     DEFINE_PROP_END_OF_LIST(),
 };
 
-- 
2.13.0.91.g00982b8dd

^ permalink raw reply related	[flat|nested] 80+ messages in thread

* [Qemu-devel] [PATCH v2 19/45] qdev: add unsigned properties
  2017-05-31 13:56 [Qemu-devel] [PATCH v2 00/45] qobject/qapi: add uint type Marc-André Lureau
                   ` (17 preceding siblings ...)
  2017-05-31 13:56 ` [Qemu-devel] [PATCH v2 18/45] qdev: make default property int Marc-André Lureau
@ 2017-05-31 13:56 ` Marc-André Lureau
  2017-06-02 13:55   ` Markus Armbruster
  2017-05-31 13:56 ` [Qemu-devel] [PATCH v2 20/45] apic-common: make "id" property a uint32 Marc-André Lureau
                   ` (27 subsequent siblings)
  46 siblings, 1 reply; 80+ messages in thread
From: Marc-André Lureau @ 2017-05-31 13:56 UTC (permalink / raw)
  To: qemu-devel; +Cc: armbru, Marc-André Lureau

Add and use unsigned type for various properties.

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
 include/hw/qdev-core.h       |  1 +
 include/hw/qdev-properties.h | 51 +++++++++++++++++++++++++++-----------------
 hw/core/qdev-properties.c    | 23 ++++++++++++--------
 3 files changed, 46 insertions(+), 29 deletions(-)

diff --git a/include/hw/qdev-core.h b/include/hw/qdev-core.h
index 784971b8d8..9d7c1c0e9b 100644
--- a/include/hw/qdev-core.h
+++ b/include/hw/qdev-core.h
@@ -228,6 +228,7 @@ struct Property {
     uint8_t      bitnr;
     union {
         int64_t i;
+        uint64_t u;
     } defval;
     int          arrayoffset;
     PropertyInfo *arrayinfo;
diff --git a/include/hw/qdev-properties.h b/include/hw/qdev-properties.h
index 6663a547ea..16d3ada8df 100644
--- a/include/hw/qdev-properties.h
+++ b/include/hw/qdev-properties.h
@@ -37,6 +37,7 @@ extern PropertyInfo qdev_prop_arraylen;
         .offset    = offsetof(_state, _field)                    \
             + type_check(_type, typeof_field(_state, _field)),   \
         }
+
 #define DEFINE_PROP_INT(_name, _state, _field, _defval, _prop, _type) { \
         .name      = (_name),                                           \
         .info      = &(_prop),                                          \
@@ -44,29 +45,39 @@ extern PropertyInfo qdev_prop_arraylen;
             + type_check(_type,typeof_field(_state, _field)),           \
         .defval.i  = (_type)_defval,                                    \
         }
-#define DEFINE_PROP_BIT(_name, _state, _field, _bit, _defval) {  \
-        .name      = (_name),                                    \
-        .info      = &(qdev_prop_bit),                           \
-        .bitnr    = (_bit),                                      \
-        .offset    = offsetof(_state, _field)                    \
-            + type_check(uint32_t,typeof_field(_state, _field)), \
-        .defval.i  = (bool)_defval,                              \
+
+#define DEFINE_PROP_BIT(_name, _state, _field, _bit, _defval) {         \
+        .name      = (_name),                                           \
+        .info      = &(qdev_prop_bit),                                  \
+        .bitnr    = (_bit),                                             \
+        .offset    = offsetof(_state, _field)                           \
+            + type_check(uint32_t, typeof_field(_state, _field)),        \
+        .defval.u   = (bool)_defval,                                    \
         }
+
+#define DEFINE_PROP_UINT(_name, _state, _field, _defval, _prop, _type) { \
+        .name      = (_name),                                           \
+        .info      = &(_prop),                                          \
+        .offset    = offsetof(_state, _field)                           \
+            + type_check(_type, typeof_field(_state, _field)),          \
+        .defval.u  = (_type)_defval,                                    \
+        }
+
 #define DEFINE_PROP_BIT64(_name, _state, _field, _bit, _defval) {       \
         .name      = (_name),                                           \
         .info      = &(qdev_prop_bit64),                                \
         .bitnr    = (_bit),                                             \
         .offset    = offsetof(_state, _field)                           \
             + type_check(uint64_t, typeof_field(_state, _field)),       \
-        .defval.i  = (bool)_defval,                                     \
+        .defval.u  = (bool)_defval,                                     \
         }
 
-#define DEFINE_PROP_BOOL(_name, _state, _field, _defval) {       \
-        .name      = (_name),                                    \
-        .info      = &(qdev_prop_bool),                          \
-        .offset    = offsetof(_state, _field)                    \
-            + type_check(bool, typeof_field(_state, _field)),    \
-        .defval.i  = (bool)_defval,                              \
+#define DEFINE_PROP_BOOL(_name, _state, _field, _defval) {      \
+        .name      = (_name),                                   \
+        .info      = &(qdev_prop_bool),                         \
+        .offset    = offsetof(_state, _field)                   \
+            + type_check(bool, typeof_field(_state, _field)),   \
+        .defval.u    = (bool)_defval,                           \
         }
 
 #define PROP_ARRAY_LEN_PREFIX "len-"
@@ -107,17 +118,17 @@ extern PropertyInfo qdev_prop_arraylen;
         }
 
 #define DEFINE_PROP_UINT8(_n, _s, _f, _d)                       \
-    DEFINE_PROP_INT(_n, _s, _f, _d, qdev_prop_uint8, uint8_t)
+    DEFINE_PROP_UINT(_n, _s, _f, _d, qdev_prop_uint8, uint8_t)
 #define DEFINE_PROP_UINT16(_n, _s, _f, _d)                      \
-    DEFINE_PROP_INT(_n, _s, _f, _d, qdev_prop_uint16, uint16_t)
+    DEFINE_PROP_UINT(_n, _s, _f, _d, qdev_prop_uint16, uint16_t)
 #define DEFINE_PROP_UINT32(_n, _s, _f, _d)                      \
-    DEFINE_PROP_INT(_n, _s, _f, _d, qdev_prop_uint32, uint32_t)
+    DEFINE_PROP_UINT(_n, _s, _f, _d, qdev_prop_uint32, uint32_t)
 #define DEFINE_PROP_INT32(_n, _s, _f, _d)                      \
     DEFINE_PROP_INT(_n, _s, _f, _d, qdev_prop_int32, int32_t)
 #define DEFINE_PROP_UINT64(_n, _s, _f, _d)                      \
-    DEFINE_PROP_INT(_n, _s, _f, _d, qdev_prop_uint64, uint64_t)
+    DEFINE_PROP_UINT(_n, _s, _f, _d, qdev_prop_uint64, uint64_t)
 #define DEFINE_PROP_SIZE(_n, _s, _f, _d)                       \
-    DEFINE_PROP_INT(_n, _s, _f, _d, qdev_prop_size, uint64_t)
+    DEFINE_PROP_UINT(_n, _s, _f, _d, qdev_prop_size, uint64_t)
 #define DEFINE_PROP_PCI_DEVFN(_n, _s, _f, _d)                   \
     DEFINE_PROP_INT(_n, _s, _f, _d, qdev_prop_pci_devfn, int32_t)
 
@@ -163,7 +174,7 @@ extern PropertyInfo qdev_prop_arraylen;
 #define DEFINE_PROP_BIOS_CHS_TRANS(_n, _s, _f, _d) \
     DEFINE_PROP_INT(_n, _s, _f, _d, qdev_prop_bios_chs_trans, int)
 #define DEFINE_PROP_BLOCKSIZE(_n, _s, _f) \
-    DEFINE_PROP_INT(_n, _s, _f, 0, qdev_prop_blocksize, uint16_t)
+    DEFINE_PROP_UINT(_n, _s, _f, 0, qdev_prop_blocksize, uint16_t)
 #define DEFINE_PROP_PCI_HOST_DEVADDR(_n, _s, _f) \
     DEFINE_PROP(_n, _s, _f, qdev_prop_pci_host_devaddr, PCIHostDeviceAddress)
 
diff --git a/hw/core/qdev-properties.c b/hw/core/qdev-properties.c
index 952cda7758..92fb43cb0d 100644
--- a/hw/core/qdev-properties.c
+++ b/hw/core/qdev-properties.c
@@ -71,7 +71,7 @@ static void set_enum(Object *obj, Visitor *v, const char *name, void *opaque,
 
 static void set_default_value_enum(Object *obj, const Property *prop)
 {
-    object_property_set_str(obj, prop->info->enum_table[prop->defval.i],
+    object_property_set_str(obj, prop->info->enum_table[prop->defval.u],
                             prop->name, &error_abort);
 }
 
@@ -128,7 +128,7 @@ static void prop_set_bit(Object *obj, Visitor *v, const char *name,
 
 static void set_default_value_bool(Object *obj, const Property *prop)
 {
-    object_property_set_bool(obj, prop->defval.i, prop->name, &error_abort);
+    object_property_set_bool(obj, prop->defval.u, prop->name, &error_abort);
 }
 
 PropertyInfo qdev_prop_bit = {
@@ -264,11 +264,16 @@ static void set_default_value_int(Object *obj, const Property *prop)
     object_property_set_int(obj, prop->defval.i, prop->name, &error_abort);
 }
 
+static void set_default_value_uint(Object *obj, const Property *prop)
+{
+    object_property_set_uint(obj, prop->defval.u, prop->name, &error_abort);
+}
+
 PropertyInfo qdev_prop_uint8 = {
     .name  = "uint8",
     .get   = get_uint8,
     .set   = set_uint8,
-    .set_default_value = set_default_value_int,
+    .set_default_value = set_default_value_uint,
 };
 
 /* --- 16bit integer --- */
@@ -302,7 +307,7 @@ PropertyInfo qdev_prop_uint16 = {
     .name  = "uint16",
     .get   = get_uint16,
     .set   = set_uint16,
-    .set_default_value = set_default_value_int,
+    .set_default_value = set_default_value_uint,
 };
 
 /* --- 32bit integer --- */
@@ -361,7 +366,7 @@ PropertyInfo qdev_prop_uint32 = {
     .name  = "uint32",
     .get   = get_uint32,
     .set   = set_uint32,
-    .set_default_value = set_default_value_int,
+    .set_default_value = set_default_value_uint,
 };
 
 PropertyInfo qdev_prop_int32 = {
@@ -402,7 +407,7 @@ PropertyInfo qdev_prop_uint64 = {
     .name  = "uint64",
     .get   = get_uint64,
     .set   = set_uint64,
-    .set_default_value = set_default_value_int,
+    .set_default_value = set_default_value_uint,
 };
 
 /* --- string --- */
@@ -725,7 +730,7 @@ PropertyInfo qdev_prop_blocksize = {
     .description = "A power of two between 512 and 32768",
     .get   = get_uint16,
     .set   = set_blocksize,
-    .set_default_value = set_default_value_int,
+    .set_default_value = set_default_value_uint,
 };
 
 /* --- pci host address --- */
@@ -948,7 +953,7 @@ PropertyInfo qdev_prop_arraylen = {
     .name = "uint32",
     .get = get_uint32,
     .set = set_prop_arraylen,
-    .set_default_value = set_default_value_int,
+    .set_default_value = set_default_value_uint,
 };
 
 /* --- public helpers --- */
@@ -1185,5 +1190,5 @@ PropertyInfo qdev_prop_size = {
     .name  = "size",
     .get = get_size,
     .set = set_size,
-    .set_default_value = set_default_value_int,
+    .set_default_value = set_default_value_uint,
 };
-- 
2.13.0.91.g00982b8dd

^ permalink raw reply related	[flat|nested] 80+ messages in thread

* [Qemu-devel] [PATCH v2 20/45] apic-common: make "id" property a uint32
  2017-05-31 13:56 [Qemu-devel] [PATCH v2 00/45] qobject/qapi: add uint type Marc-André Lureau
                   ` (18 preceding siblings ...)
  2017-05-31 13:56 ` [Qemu-devel] [PATCH v2 19/45] qdev: add unsigned properties Marc-André Lureau
@ 2017-05-31 13:56 ` Marc-André Lureau
  2017-06-02 14:05   ` Markus Armbruster
  2017-05-31 13:56 ` [Qemu-devel] [PATCH v2 21/45] qdev: use appropriate getter/setters type Marc-André Lureau
                   ` (26 subsequent siblings)
  46 siblings, 1 reply; 80+ messages in thread
From: Marc-André Lureau @ 2017-05-31 13:56 UTC (permalink / raw)
  To: qemu-devel; +Cc: armbru, Marc-André Lureau

Change suggested by Markus Armbruster:

This one's a bit of a mess.

The getter and setter of TYPE_APIC_COMMON property "id" are
apic_common_get_id() and apic_common_set_id().

apic_common_get_id() reads either APICCommonState member uint32_t
initial_apic_id or uint8_t id into an int64_t local variable.  It then
passes this variable to visit_type_int().

apic_common_set_id() uses visit_type_int() to read the value into a
local variable, which it then assigns both to initial_apic_id and id.

While the state backing the property is two unsigned members, 8 and 32
bits wide, the actual visitor is 64 bits signed.

cpu->apic_id is uint32_t.

qdev_prop_set_uint32() isn't really wrong, because any uint32_t value is
also a valid int64_t value.

qdev_prop_set_int32() implicitly converts cpu->apic_id from uint32_t
to int32_t.  Perhaps that's even okay, but I don't care, I want this
mess cleaned up

Change getter and setter to use visit_type_uint32().  Then everything's
uint32_t, except for @id.

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
 hw/intc/apic_common.c | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/hw/intc/apic_common.c b/hw/intc/apic_common.c
index 1ef56f8d10..e1ac33042f 100644
--- a/hw/intc/apic_common.c
+++ b/hw/intc/apic_common.c
@@ -450,10 +450,10 @@ static void apic_common_get_id(Object *obj, Visitor *v, const char *name,
                                void *opaque, Error **errp)
 {
     APICCommonState *s = APIC_COMMON(obj);
-    int64_t value;
+    uint32_t value;
 
     value = s->apicbase & MSR_IA32_APICBASE_EXTD ? s->initial_apic_id : s->id;
-    visit_type_int(v, name, &value, errp);
+    visit_type_uint32(v, name, &value, errp);
 }
 
 static void apic_common_set_id(Object *obj, Visitor *v, const char *name,
@@ -462,14 +462,14 @@ static void apic_common_set_id(Object *obj, Visitor *v, const char *name,
     APICCommonState *s = APIC_COMMON(obj);
     DeviceState *dev = DEVICE(obj);
     Error *local_err = NULL;
-    int64_t value;
+    uint32_t value;
 
     if (dev->realized) {
         qdev_prop_set_after_realize(dev, name, errp);
         return;
     }
 
-    visit_type_int(v, name, &value, &local_err);
+    visit_type_uint32(v, name, &value, &local_err);
     if (local_err) {
         error_propagate(errp, local_err);
         return;
@@ -484,7 +484,7 @@ static void apic_common_initfn(Object *obj)
     APICCommonState *s = APIC_COMMON(obj);
 
     s->id = s->initial_apic_id = -1;
-    object_property_add(obj, "id", "int",
+    object_property_add(obj, "id", "uint32",
                         apic_common_get_id,
                         apic_common_set_id, NULL, NULL, NULL);
 }
-- 
2.13.0.91.g00982b8dd

^ permalink raw reply related	[flat|nested] 80+ messages in thread

* [Qemu-devel] [PATCH v2 21/45] qdev: use appropriate getter/setters type
  2017-05-31 13:56 [Qemu-devel] [PATCH v2 00/45] qobject/qapi: add uint type Marc-André Lureau
                   ` (19 preceding siblings ...)
  2017-05-31 13:56 ` [Qemu-devel] [PATCH v2 20/45] apic-common: make "id" property a uint32 Marc-André Lureau
@ 2017-05-31 13:56 ` Marc-André Lureau
  2017-06-02 14:51   ` Markus Armbruster
  2017-05-31 13:56 ` [Qemu-devel] [PATCH v2 22/45] isa: use get_uint() for "io-base" Marc-André Lureau
                   ` (25 subsequent siblings)
  46 siblings, 1 reply; 80+ messages in thread
From: Marc-André Lureau @ 2017-05-31 13:56 UTC (permalink / raw)
  To: qemu-devel; +Cc: armbru, Marc-André Lureau

Based on underlying property type, use the appropriate getters/setters.

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
 hw/i386/acpi-build.c      | 20 ++++++++++----------
 hw/pci-host/gpex.c        |  2 +-
 hw/pci-host/q35.c         |  2 +-
 hw/pci-host/xilinx-pcie.c |  2 +-
 4 files changed, 13 insertions(+), 13 deletions(-)

diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
index ba2be1e9da..ba163e6df2 100644
--- a/hw/i386/acpi-build.c
+++ b/hw/i386/acpi-build.c
@@ -128,7 +128,7 @@ static void acpi_get_pm_info(AcpiPmInfo *pm)
     Object *lpc = ich9_lpc_find();
     Object *obj = NULL;
     QObject *o;
-    int64_t val;
+    uint64_t val;
 
     pm->cpu_hp_io_base = 0;
     pm->pcihp_io_base = 0;
@@ -150,7 +150,7 @@ static void acpi_get_pm_info(AcpiPmInfo *pm)
     /* Fill in optional s3/s4 related properties */
     o = object_property_get_qobject(obj, ACPI_PM_PROP_S3_DISABLED, NULL);
     if (o) {
-        if (!qnum_get_int(qobject_to_qnum(o), &val)) {
+        if (!qnum_get_uint(qobject_to_qnum(o), &val)) {
             g_assert_not_reached();
         }
         pm->s3_disabled = val;
@@ -160,7 +160,7 @@ static void acpi_get_pm_info(AcpiPmInfo *pm)
     qobject_decref(o);
     o = object_property_get_qobject(obj, ACPI_PM_PROP_S4_DISABLED, NULL);
     if (o) {
-        if (!qnum_get_int(qobject_to_qnum(o), &val)) {
+        if (!qnum_get_uint(qobject_to_qnum(o), &val)) {
             g_assert_not_reached();
         }
         pm->s4_disabled = val;
@@ -170,7 +170,7 @@ static void acpi_get_pm_info(AcpiPmInfo *pm)
     qobject_decref(o);
     o = object_property_get_qobject(obj, ACPI_PM_PROP_S4_VAL, NULL);
     if (o) {
-        if (!qnum_get_int(qobject_to_qnum(o), &val)) {
+        if (!qnum_get_uint(qobject_to_qnum(o), &val)) {
             g_assert_not_reached();
         }
         pm->s4_val = val;
@@ -538,9 +538,9 @@ static void build_append_pci_bus_devices(Aml *parent_scope, PCIBus *bus,
 
     bsel = object_property_get_qobject(OBJECT(bus), ACPI_PCIHP_PROP_BSEL, NULL);
     if (bsel) {
-        int64_t bsel_val;
+        uint64_t bsel_val;
 
-        if (!qnum_get_int(qobject_to_qnum(bsel), &bsel_val)) {
+        if (!qnum_get_uint(qobject_to_qnum(bsel), &bsel_val)) {
             g_assert_not_reached();
         }
 
@@ -652,9 +652,9 @@ static void build_append_pci_bus_devices(Aml *parent_scope, PCIBus *bus,
 
     /* If bus supports hotplug select it and notify about local events */
     if (bsel) {
-        int64_t bsel_val;
+        uint64_t bsel_val;
 
-        if (!qnum_get_int(qobject_to_qnum(bsel), &bsel_val)) {
+        if (!qnum_get_uint(qobject_to_qnum(bsel), &bsel_val)) {
             g_assert_not_reached();
         }
 
@@ -2625,7 +2625,7 @@ static bool acpi_get_mcfg(AcpiMcfgInfo *mcfg)
 {
     Object *pci_host;
     QObject *o;
-    int64_t val;
+    uint64_t val;
 
     pci_host = acpi_get_i386_pci_host();
     g_assert(pci_host);
@@ -2641,7 +2641,7 @@ static bool acpi_get_mcfg(AcpiMcfgInfo *mcfg)
 
     o = object_property_get_qobject(pci_host, PCIE_HOST_MCFG_SIZE, NULL);
     assert(o);
-    if (!qnum_get_int(qobject_to_qnum(o), &val)) {
+    if (!qnum_get_uint(qobject_to_qnum(o), &val)) {
         g_assert_not_reached();
     }
     mcfg->mcfg_size = val;
diff --git a/hw/pci-host/gpex.c b/hw/pci-host/gpex.c
index e2629ce70d..83084b9aab 100644
--- a/hw/pci-host/gpex.c
+++ b/hw/pci-host/gpex.c
@@ -94,7 +94,7 @@ static void gpex_host_initfn(Object *obj)
 
     object_initialize(root, sizeof(*root), TYPE_GPEX_ROOT_DEVICE);
     object_property_add_child(obj, "gpex_root", OBJECT(root), NULL);
-    qdev_prop_set_uint32(DEVICE(root), "addr", PCI_DEVFN(0, 0));
+    qdev_prop_set_int32(DEVICE(root), "addr", PCI_DEVFN(0, 0));
     qdev_prop_set_bit(DEVICE(root), "multifunction", false);
 }
 
diff --git a/hw/pci-host/q35.c b/hw/pci-host/q35.c
index c2f2af5d9a..564f6cbb14 100644
--- a/hw/pci-host/q35.c
+++ b/hw/pci-host/q35.c
@@ -172,7 +172,7 @@ static void q35_host_initfn(Object *obj)
 
     object_initialize(&s->mch, sizeof(s->mch), TYPE_MCH_PCI_DEVICE);
     object_property_add_child(OBJECT(s), "mch", OBJECT(&s->mch), NULL);
-    qdev_prop_set_uint32(DEVICE(&s->mch), "addr", PCI_DEVFN(0, 0));
+    qdev_prop_set_int32(DEVICE(&s->mch), "addr", PCI_DEVFN(0, 0));
     qdev_prop_set_bit(DEVICE(&s->mch), "multifunction", false);
 
     object_property_add(obj, PCI_HOST_PROP_PCI_HOLE_START, "uint32",
diff --git a/hw/pci-host/xilinx-pcie.c b/hw/pci-host/xilinx-pcie.c
index a968cea2af..2c78dcfc26 100644
--- a/hw/pci-host/xilinx-pcie.c
+++ b/hw/pci-host/xilinx-pcie.c
@@ -150,7 +150,7 @@ static void xilinx_pcie_host_init(Object *obj)
 
     object_initialize(root, sizeof(*root), TYPE_XILINX_PCIE_ROOT);
     object_property_add_child(obj, "root", OBJECT(root), NULL);
-    qdev_prop_set_uint32(DEVICE(root), "addr", PCI_DEVFN(0, 0));
+    qdev_prop_set_int32(DEVICE(root), "addr", PCI_DEVFN(0, 0));
     qdev_prop_set_bit(DEVICE(root), "multifunction", false);
 }
 
-- 
2.13.0.91.g00982b8dd

^ permalink raw reply related	[flat|nested] 80+ messages in thread

* [Qemu-devel] [PATCH v2 22/45] isa: use get_uint() for "io-base"
  2017-05-31 13:56 [Qemu-devel] [PATCH v2 00/45] qobject/qapi: add uint type Marc-André Lureau
                   ` (20 preceding siblings ...)
  2017-05-31 13:56 ` [Qemu-devel] [PATCH v2 21/45] qdev: use appropriate getter/setters type Marc-André Lureau
@ 2017-05-31 13:56 ` Marc-André Lureau
  2017-05-31 13:56 ` [Qemu-devel] [PATCH v2 23/45] pc-dimm: use get_uint() for dimm properties Marc-André Lureau
                   ` (24 subsequent siblings)
  46 siblings, 0 replies; 80+ messages in thread
From: Marc-André Lureau @ 2017-05-31 13:56 UTC (permalink / raw)
  To: qemu-devel; +Cc: armbru, Marc-André Lureau

The property is defined with DEFINE_PROP_UINT32().

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
 include/hw/isa/isa.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/include/hw/isa/isa.h b/include/hw/isa/isa.h
index c2fdd70cdc..95593408ef 100644
--- a/include/hw/isa/isa.h
+++ b/include/hw/isa/isa.h
@@ -29,7 +29,7 @@ static inline uint16_t applesmc_port(void)
     Object *obj = object_resolve_path_type("", TYPE_APPLE_SMC, NULL);
 
     if (obj) {
-        return object_property_get_int(obj, APPLESMC_PROP_IO_BASE, NULL);
+        return object_property_get_uint(obj, APPLESMC_PROP_IO_BASE, NULL);
     }
     return 0;
 }
-- 
2.13.0.91.g00982b8dd

^ permalink raw reply related	[flat|nested] 80+ messages in thread

* [Qemu-devel] [PATCH v2 23/45] pc-dimm: use get_uint() for dimm properties
  2017-05-31 13:56 [Qemu-devel] [PATCH v2 00/45] qobject/qapi: add uint type Marc-André Lureau
                   ` (21 preceding siblings ...)
  2017-05-31 13:56 ` [Qemu-devel] [PATCH v2 22/45] isa: use get_uint() for "io-base" Marc-André Lureau
@ 2017-05-31 13:56 ` Marc-André Lureau
  2017-05-31 13:56 ` [Qemu-devel] [PATCH v2 24/45] pc-dimm: make "size" property uint64 Marc-André Lureau
                   ` (23 subsequent siblings)
  46 siblings, 0 replies; 80+ messages in thread
From: Marc-André Lureau @ 2017-05-31 13:56 UTC (permalink / raw)
  To: qemu-devel; +Cc: armbru, Marc-André Lureau

TYPE_PC_DIMM's property PC_DIMM_ADDR_PROP is defined with
DEFINE_PROP_UINT64().

TYPE_PC_DIMM's property PC_DIMM_NODE_PROP is defined with
DEFINE_PROP_UINT32().

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
 hw/acpi/memory_hotplug.c |  7 ++++---
 hw/acpi/nvdimm.c         | 10 +++++-----
 hw/mem/pc-dimm.c         |  5 +++--
 hw/ppc/spapr.c           |  7 ++++---
 4 files changed, 16 insertions(+), 13 deletions(-)

diff --git a/hw/acpi/memory_hotplug.c b/hw/acpi/memory_hotplug.c
index 210073d283..d2a96569ba 100644
--- a/hw/acpi/memory_hotplug.c
+++ b/hw/acpi/memory_hotplug.c
@@ -83,11 +83,12 @@ static uint64_t acpi_memory_hotplug_read(void *opaque, hwaddr addr,
     o = OBJECT(mdev->dimm);
     switch (addr) {
     case 0x0: /* Lo part of phys address where DIMM is mapped */
-        val = o ? object_property_get_int(o, PC_DIMM_ADDR_PROP, NULL) : 0;
+        val = o ? object_property_get_uint(o, PC_DIMM_ADDR_PROP, NULL) : 0;
         trace_mhp_acpi_read_addr_lo(mem_st->selector, val);
         break;
     case 0x4: /* Hi part of phys address where DIMM is mapped */
-        val = o ? object_property_get_int(o, PC_DIMM_ADDR_PROP, NULL) >> 32 : 0;
+        val =
+            o ? object_property_get_uint(o, PC_DIMM_ADDR_PROP, NULL) >> 32 : 0;
         trace_mhp_acpi_read_addr_hi(mem_st->selector, val);
         break;
     case 0x8: /* Lo part of DIMM size */
@@ -99,7 +100,7 @@ static uint64_t acpi_memory_hotplug_read(void *opaque, hwaddr addr,
         trace_mhp_acpi_read_size_hi(mem_st->selector, val);
         break;
     case 0x10: /* node proximity for _PXM method */
-        val = o ? object_property_get_int(o, PC_DIMM_NODE_PROP, NULL) : 0;
+        val = o ? object_property_get_uint(o, PC_DIMM_NODE_PROP, NULL) : 0;
         trace_mhp_acpi_read_pxm(mem_st->selector, val);
         break;
     case 0x14: /* pack and return is_* fields */
diff --git a/hw/acpi/nvdimm.c b/hw/acpi/nvdimm.c
index 8e7d6ec034..e57027149d 100644
--- a/hw/acpi/nvdimm.c
+++ b/hw/acpi/nvdimm.c
@@ -236,14 +236,14 @@ static void
 nvdimm_build_structure_spa(GArray *structures, DeviceState *dev)
 {
     NvdimmNfitSpa *nfit_spa;
-    uint64_t addr = object_property_get_int(OBJECT(dev), PC_DIMM_ADDR_PROP,
-                                            NULL);
+    uint64_t addr = object_property_get_uint(OBJECT(dev), PC_DIMM_ADDR_PROP,
+                                             NULL);
     uint64_t size = object_property_get_int(OBJECT(dev), PC_DIMM_SIZE_PROP,
                                             NULL);
-    uint32_t node = object_property_get_int(OBJECT(dev), PC_DIMM_NODE_PROP,
-                                            NULL);
+    uint32_t node = object_property_get_uint(OBJECT(dev), PC_DIMM_NODE_PROP,
+                                             NULL);
     int slot = object_property_get_int(OBJECT(dev), PC_DIMM_SLOT_PROP,
-                                            NULL);
+                                       NULL);
 
     nfit_spa = acpi_data_push(structures, sizeof(*nfit_spa));
 
diff --git a/hw/mem/pc-dimm.c b/hw/mem/pc-dimm.c
index 9e8dab0e89..f6def8c239 100644
--- a/hw/mem/pc-dimm.c
+++ b/hw/mem/pc-dimm.c
@@ -46,7 +46,8 @@ void pc_dimm_memory_plug(DeviceState *dev, MemoryHotplugState *hpms,
     uint64_t existing_dimms_capacity = 0;
     uint64_t addr;
 
-    addr = object_property_get_int(OBJECT(dimm), PC_DIMM_ADDR_PROP, &local_err);
+    addr = object_property_get_uint(OBJECT(dimm),
+                                    PC_DIMM_ADDR_PROP, &local_err);
     if (local_err) {
         goto out;
     }
@@ -73,7 +74,7 @@ void pc_dimm_memory_plug(DeviceState *dev, MemoryHotplugState *hpms,
         goto out;
     }
 
-    object_property_set_int(OBJECT(dev), addr, PC_DIMM_ADDR_PROP, &local_err);
+    object_property_set_uint(OBJECT(dev), addr, PC_DIMM_ADDR_PROP, &local_err);
     if (local_err) {
         goto out;
     }
diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index ab3aab1279..e87de730c7 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -2585,7 +2585,8 @@ static void spapr_memory_plug(HotplugHandler *hotplug_dev, DeviceState *dev,
         goto out;
     }
 
-    addr = object_property_get_int(OBJECT(dimm), PC_DIMM_ADDR_PROP, &local_err);
+    addr = object_property_get_uint(OBJECT(dimm),
+                                    PC_DIMM_ADDR_PROP, &local_err);
     if (local_err) {
         pc_dimm_memory_unplug(dev, &ms->hotplug_memory, mr);
         goto out;
@@ -2744,7 +2745,7 @@ static void spapr_memory_unplug_request(HotplugHandler *hotplug_dev,
     sPAPRDRConnectorClass *drck;
     sPAPRDIMMState *ds;
 
-    addr_start = object_property_get_int(OBJECT(dimm), PC_DIMM_ADDR_PROP,
+    addr_start = object_property_get_uint(OBJECT(dimm), PC_DIMM_ADDR_PROP,
                                          &local_err);
     if (local_err) {
         goto out;
@@ -2999,7 +3000,7 @@ static void spapr_machine_device_plug(HotplugHandler *hotplug_dev,
             error_setg(errp, "Memory hotplug not supported for this machine");
             return;
         }
-        node = object_property_get_int(OBJECT(dev), PC_DIMM_NODE_PROP, errp);
+        node = object_property_get_uint(OBJECT(dev), PC_DIMM_NODE_PROP, errp);
         if (*errp) {
             return;
         }
-- 
2.13.0.91.g00982b8dd

^ permalink raw reply related	[flat|nested] 80+ messages in thread

* [Qemu-devel] [PATCH v2 24/45] pc-dimm: make "size" property uint64
  2017-05-31 13:56 [Qemu-devel] [PATCH v2 00/45] qobject/qapi: add uint type Marc-André Lureau
                   ` (22 preceding siblings ...)
  2017-05-31 13:56 ` [Qemu-devel] [PATCH v2 23/45] pc-dimm: use get_uint() for dimm properties Marc-André Lureau
@ 2017-05-31 13:56 ` Marc-André Lureau
  2017-05-31 13:56 ` [Qemu-devel] [PATCH v2 25/45] pcihp: use get_uint() for "bsel" property Marc-André Lureau
                   ` (22 subsequent siblings)
  46 siblings, 0 replies; 80+ messages in thread
From: Marc-André Lureau @ 2017-05-31 13:56 UTC (permalink / raw)
  To: qemu-devel; +Cc: armbru, Marc-André Lureau

This carries the memory_region_size() value without implicit cast.

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
 hw/acpi/memory_hotplug.c |  5 +++--
 hw/acpi/nvdimm.c         |  8 ++++----
 hw/mem/pc-dimm.c         | 18 +++++++++---------
 3 files changed, 16 insertions(+), 15 deletions(-)

diff --git a/hw/acpi/memory_hotplug.c b/hw/acpi/memory_hotplug.c
index d2a96569ba..cda2c9dd06 100644
--- a/hw/acpi/memory_hotplug.c
+++ b/hw/acpi/memory_hotplug.c
@@ -92,11 +92,12 @@ static uint64_t acpi_memory_hotplug_read(void *opaque, hwaddr addr,
         trace_mhp_acpi_read_addr_hi(mem_st->selector, val);
         break;
     case 0x8: /* Lo part of DIMM size */
-        val = o ? object_property_get_int(o, PC_DIMM_SIZE_PROP, NULL) : 0;
+        val = o ? object_property_get_uint(o, PC_DIMM_SIZE_PROP, NULL) : 0;
         trace_mhp_acpi_read_size_lo(mem_st->selector, val);
         break;
     case 0xc: /* Hi part of DIMM size */
-        val = o ? object_property_get_int(o, PC_DIMM_SIZE_PROP, NULL) >> 32 : 0;
+        val =
+            o ? object_property_get_uint(o, PC_DIMM_SIZE_PROP, NULL) >> 32 : 0;
         trace_mhp_acpi_read_size_hi(mem_st->selector, val);
         break;
     case 0x10: /* node proximity for _PXM method */
diff --git a/hw/acpi/nvdimm.c b/hw/acpi/nvdimm.c
index e57027149d..4e4cf1472f 100644
--- a/hw/acpi/nvdimm.c
+++ b/hw/acpi/nvdimm.c
@@ -238,8 +238,8 @@ nvdimm_build_structure_spa(GArray *structures, DeviceState *dev)
     NvdimmNfitSpa *nfit_spa;
     uint64_t addr = object_property_get_uint(OBJECT(dev), PC_DIMM_ADDR_PROP,
                                              NULL);
-    uint64_t size = object_property_get_int(OBJECT(dev), PC_DIMM_SIZE_PROP,
-                                            NULL);
+    uint64_t size = object_property_get_uint(OBJECT(dev), PC_DIMM_SIZE_PROP,
+                                             NULL);
     uint32_t node = object_property_get_uint(OBJECT(dev), PC_DIMM_NODE_PROP,
                                              NULL);
     int slot = object_property_get_int(OBJECT(dev), PC_DIMM_SLOT_PROP,
@@ -284,8 +284,8 @@ static void
 nvdimm_build_structure_memdev(GArray *structures, DeviceState *dev)
 {
     NvdimmNfitMemDev *nfit_memdev;
-    uint64_t size = object_property_get_int(OBJECT(dev), PC_DIMM_SIZE_PROP,
-                                            NULL);
+    uint64_t size = object_property_get_uint(OBJECT(dev), PC_DIMM_SIZE_PROP,
+                                             NULL);
     int slot = object_property_get_int(OBJECT(dev), PC_DIMM_SLOT_PROP,
                                             NULL);
     uint32_t handle = nvdimm_slot_to_handle(slot);
diff --git a/hw/mem/pc-dimm.c b/hw/mem/pc-dimm.c
index f6def8c239..b72258e28f 100644
--- a/hw/mem/pc-dimm.c
+++ b/hw/mem/pc-dimm.c
@@ -136,7 +136,7 @@ static int pc_existing_dimms_capacity_internal(Object *obj, void *opaque)
         DeviceState *dev = DEVICE(obj);
 
         if (dev->realized) {
-            (*size) += object_property_get_int(obj, PC_DIMM_SIZE_PROP,
+            (*size) += object_property_get_uint(obj, PC_DIMM_SIZE_PROP,
                 cap->errp);
         }
 
@@ -182,8 +182,8 @@ int qmp_pc_dimm_device_list(Object *obj, void *opaque)
             di->addr = dimm->addr;
             di->slot = dimm->slot;
             di->node = dimm->node;
-            di->size = object_property_get_int(OBJECT(dimm), PC_DIMM_SIZE_PROP,
-                                               NULL);
+            di->size = object_property_get_uint(OBJECT(dimm), PC_DIMM_SIZE_PROP,
+                                                NULL);
             di->memdev = object_get_canonical_path(OBJECT(dimm->hostmem));
 
             info->u.dimm.data = di;
@@ -314,9 +314,9 @@ uint64_t pc_dimm_get_free_addr(uint64_t address_space_start,
     /* find address range that will fit new DIMM */
     for (item = list; item; item = g_slist_next(item)) {
         PCDIMMDevice *dimm = item->data;
-        uint64_t dimm_size = object_property_get_int(OBJECT(dimm),
-                                                     PC_DIMM_SIZE_PROP,
-                                                     errp);
+        uint64_t dimm_size = object_property_get_uint(OBJECT(dimm),
+                                                      PC_DIMM_SIZE_PROP,
+                                                      errp);
         if (errp && *errp) {
             goto out;
         }
@@ -356,7 +356,7 @@ static Property pc_dimm_properties[] = {
 static void pc_dimm_get_size(Object *obj, Visitor *v, const char *name,
                              void *opaque, Error **errp)
 {
-    int64_t value;
+    uint64_t value;
     MemoryRegion *mr;
     PCDIMMDevice *dimm = PC_DIMM(obj);
     PCDIMMDeviceClass *ddc = PC_DIMM_GET_CLASS(obj);
@@ -364,7 +364,7 @@ static void pc_dimm_get_size(Object *obj, Visitor *v, const char *name,
     mr = ddc->get_memory_region(dimm);
     value = memory_region_size(mr);
 
-    visit_type_int(v, name, &value, errp);
+    visit_type_uint64(v, name, &value, errp);
 }
 
 static void pc_dimm_check_memdev_is_busy(Object *obj, const char *name,
@@ -387,7 +387,7 @@ static void pc_dimm_init(Object *obj)
 {
     PCDIMMDevice *dimm = PC_DIMM(obj);
 
-    object_property_add(obj, PC_DIMM_SIZE_PROP, "int", pc_dimm_get_size,
+    object_property_add(obj, PC_DIMM_SIZE_PROP, "uint64", pc_dimm_get_size,
                         NULL, NULL, NULL, &error_abort);
     object_property_add_link(obj, PC_DIMM_MEMDEV_PROP, TYPE_MEMORY_BACKEND,
                              (Object **)&dimm->hostmem,
-- 
2.13.0.91.g00982b8dd

^ permalink raw reply related	[flat|nested] 80+ messages in thread

* [Qemu-devel] [PATCH v2 25/45] pcihp: use get_uint() for "bsel" property
  2017-05-31 13:56 [Qemu-devel] [PATCH v2 00/45] qobject/qapi: add uint type Marc-André Lureau
                   ` (23 preceding siblings ...)
  2017-05-31 13:56 ` [Qemu-devel] [PATCH v2 24/45] pc-dimm: make "size" property uint64 Marc-André Lureau
@ 2017-05-31 13:56 ` Marc-André Lureau
  2017-05-31 13:56 ` [Qemu-devel] [PATCH v2 26/45] aspeed: use {set, get}_uint() for "ram-size" property Marc-André Lureau
                   ` (21 subsequent siblings)
  46 siblings, 0 replies; 80+ messages in thread
From: Marc-André Lureau @ 2017-05-31 13:56 UTC (permalink / raw)
  To: qemu-devel; +Cc: armbru, Marc-André Lureau

The property is defined with object_property_add_uint32_ptr()

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
 hw/acpi/pcihp.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/hw/acpi/pcihp.c b/hw/acpi/pcihp.c
index 3a531a4416..c420a388ea 100644
--- a/hw/acpi/pcihp.c
+++ b/hw/acpi/pcihp.c
@@ -62,10 +62,10 @@ typedef struct AcpiPciHpFind {
 static int acpi_pcihp_get_bsel(PCIBus *bus)
 {
     Error *local_err = NULL;
-    int64_t bsel = object_property_get_int(OBJECT(bus), ACPI_PCIHP_PROP_BSEL,
-                                           &local_err);
+    uint64_t bsel = object_property_get_uint(OBJECT(bus), ACPI_PCIHP_PROP_BSEL,
+                                             &local_err);
 
-    if (local_err || bsel < 0 || bsel >= ACPI_PCIHP_MAX_HOTPLUG_BUS) {
+    if (local_err || bsel >= ACPI_PCIHP_MAX_HOTPLUG_BUS) {
         if (local_err) {
             error_free(local_err);
         }
-- 
2.13.0.91.g00982b8dd

^ permalink raw reply related	[flat|nested] 80+ messages in thread

* [Qemu-devel] [PATCH v2 26/45] aspeed: use {set, get}_uint() for "ram-size" property
  2017-05-31 13:56 [Qemu-devel] [PATCH v2 00/45] qobject/qapi: add uint type Marc-André Lureau
                   ` (24 preceding siblings ...)
  2017-05-31 13:56 ` [Qemu-devel] [PATCH v2 25/45] pcihp: use get_uint() for "bsel" property Marc-André Lureau
@ 2017-05-31 13:56 ` Marc-André Lureau
  2017-05-31 13:56 ` [Qemu-devel] [PATCH v2 27/45] bcm2835_fb: use {get, set}_uint() for "vcram-size" and "vcram-base" Marc-André Lureau
                   ` (20 subsequent siblings)
  46 siblings, 0 replies; 80+ messages in thread
From: Marc-André Lureau @ 2017-05-31 13:56 UTC (permalink / raw)
  To: qemu-devel; +Cc: armbru, Marc-André Lureau

This property is an alias for device TYPE_ASPEED_SDMC's property
"ram-size", which is defined with DEFINE_PROP_UINT64().

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
 hw/arm/aspeed.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/hw/arm/aspeed.c b/hw/arm/aspeed.c
index 283c038814..0c6cd17d0d 100644
--- a/hw/arm/aspeed.c
+++ b/hw/arm/aspeed.c
@@ -174,8 +174,8 @@ static void aspeed_board_init(MachineState *machine,
 
     sc = ASPEED_SOC_GET_CLASS(&bmc->soc);
 
-    object_property_set_int(OBJECT(&bmc->soc), ram_size, "ram-size",
-                           &error_abort);
+    object_property_set_uint(OBJECT(&bmc->soc), ram_size, "ram-size",
+                             &error_abort);
     object_property_set_int(OBJECT(&bmc->soc), cfg->hw_strap1, "hw-strap1",
                             &error_abort);
     object_property_set_int(OBJECT(&bmc->soc), cfg->num_cs, "num-cs",
@@ -187,8 +187,8 @@ static void aspeed_board_init(MachineState *machine,
      * Allocate RAM after the memory controller has checked the size
      * was valid. If not, a default value is used.
      */
-    ram_size = object_property_get_int(OBJECT(&bmc->soc), "ram-size",
-                                       &error_abort);
+    ram_size = object_property_get_uint(OBJECT(&bmc->soc), "ram-size",
+                                        &error_abort);
 
     memory_region_allocate_system_memory(&bmc->ram, NULL, "ram", ram_size);
     memory_region_add_subregion(get_system_memory(), sc->info->sdram_base,
-- 
2.13.0.91.g00982b8dd

^ permalink raw reply related	[flat|nested] 80+ messages in thread

* [Qemu-devel] [PATCH v2 27/45] bcm2835_fb: use {get, set}_uint() for "vcram-size" and "vcram-base"
  2017-05-31 13:56 [Qemu-devel] [PATCH v2 00/45] qobject/qapi: add uint type Marc-André Lureau
                   ` (25 preceding siblings ...)
  2017-05-31 13:56 ` [Qemu-devel] [PATCH v2 26/45] aspeed: use {set, get}_uint() for "ram-size" property Marc-André Lureau
@ 2017-05-31 13:56 ` Marc-André Lureau
  2017-05-31 13:56 ` [Qemu-devel] [PATCH v2 28/45] platform-bus: use get_uint() for "addr" property Marc-André Lureau
                   ` (19 subsequent siblings)
  46 siblings, 0 replies; 80+ messages in thread
From: Marc-André Lureau @ 2017-05-31 13:56 UTC (permalink / raw)
  To: qemu-devel; +Cc: armbru, Marc-André Lureau

Both properties are defined with DEFINE_PROP_UINT32().

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
 hw/arm/bcm2835_peripherals.c | 9 ++++-----
 hw/arm/raspi.c               | 4 ++--
 2 files changed, 6 insertions(+), 7 deletions(-)

diff --git a/hw/arm/bcm2835_peripherals.c b/hw/arm/bcm2835_peripherals.c
index 369ef1e3bd..b168c6f83e 100644
--- a/hw/arm/bcm2835_peripherals.c
+++ b/hw/arm/bcm2835_peripherals.c
@@ -126,7 +126,7 @@ static void bcm2835_peripherals_realize(DeviceState *dev, Error **errp)
     Object *obj;
     MemoryRegion *ram;
     Error *err = NULL;
-    uint32_t ram_size, vcram_size;
+    uint64_t ram_size, vcram_size;
     int n;
 
     obj = object_property_get_link(OBJECT(dev), "ram", &err);
@@ -208,15 +208,14 @@ static void bcm2835_peripherals_realize(DeviceState *dev, Error **errp)
                                INTERRUPT_ARM_MAILBOX));
 
     /* Framebuffer */
-    vcram_size = (uint32_t)object_property_get_int(OBJECT(s), "vcram-size",
-                                                   &err);
+    vcram_size = object_property_get_uint(OBJECT(s), "vcram-size", &err);
     if (err) {
         error_propagate(errp, err);
         return;
     }
 
-    object_property_set_int(OBJECT(&s->fb), ram_size - vcram_size,
-                            "vcram-base", &err);
+    object_property_set_uint(OBJECT(&s->fb), ram_size - vcram_size,
+                             "vcram-base", &err);
     if (err) {
         error_propagate(errp, err);
         return;
diff --git a/hw/arm/raspi.c b/hw/arm/raspi.c
index 2b295f14c4..32cdc98c6d 100644
--- a/hw/arm/raspi.c
+++ b/hw/arm/raspi.c
@@ -153,8 +153,8 @@ static void raspi2_init(MachineState *machine)
     qdev_prop_set_drive(carddev, "drive", blk, &error_fatal);
     object_property_set_bool(OBJECT(carddev), true, "realized", &error_fatal);
 
-    vcram_size = object_property_get_int(OBJECT(&s->soc), "vcram-size",
-                                         &error_abort);
+    vcram_size = object_property_get_uint(OBJECT(&s->soc), "vcram-size",
+                                          &error_abort);
     setup_boot(machine, 2, machine->ram_size - vcram_size);
 }
 
-- 
2.13.0.91.g00982b8dd

^ permalink raw reply related	[flat|nested] 80+ messages in thread

* [Qemu-devel] [PATCH v2 28/45] platform-bus: use get_uint() for "addr" property
  2017-05-31 13:56 [Qemu-devel] [PATCH v2 00/45] qobject/qapi: add uint type Marc-André Lureau
                   ` (26 preceding siblings ...)
  2017-05-31 13:56 ` [Qemu-devel] [PATCH v2 27/45] bcm2835_fb: use {get, set}_uint() for "vcram-size" and "vcram-base" Marc-André Lureau
@ 2017-05-31 13:56 ` Marc-André Lureau
  2017-05-31 13:56 ` [Qemu-devel] [PATCH v2 29/45] acpi: use get_uint() for "acpi-pcihp-io*" properties Marc-André Lureau
                   ` (18 subsequent siblings)
  46 siblings, 0 replies; 80+ messages in thread
From: Marc-André Lureau @ 2017-05-31 13:56 UTC (permalink / raw)
  To: qemu-devel; +Cc: armbru, Marc-André Lureau

This is TYPE_MEMORY_REGION's property.  Its getter
memory_region_get_addr() uses visit_type_uint64().

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
 hw/core/platform-bus.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/core/platform-bus.c b/hw/core/platform-bus.c
index 329ac670c0..33d32fbf22 100644
--- a/hw/core/platform-bus.c
+++ b/hw/core/platform-bus.c
@@ -71,7 +71,7 @@ hwaddr platform_bus_get_mmio_addr(PlatformBusDevice *pbus, SysBusDevice *sbdev,
         return -1;
     }
 
-    return object_property_get_int(OBJECT(sbdev_mr), "addr", NULL);
+    return object_property_get_uint(OBJECT(sbdev_mr), "addr", NULL);
 }
 
 static void platform_bus_count_irqs(SysBusDevice *sbdev, void *opaque)
-- 
2.13.0.91.g00982b8dd

^ permalink raw reply related	[flat|nested] 80+ messages in thread

* [Qemu-devel] [PATCH v2 29/45] acpi: use get_uint() for "acpi-pcihp-io*" properties
  2017-05-31 13:56 [Qemu-devel] [PATCH v2 00/45] qobject/qapi: add uint type Marc-André Lureau
                   ` (27 preceding siblings ...)
  2017-05-31 13:56 ` [Qemu-devel] [PATCH v2 28/45] platform-bus: use get_uint() for "addr" property Marc-André Lureau
@ 2017-05-31 13:56 ` Marc-André Lureau
  2017-05-31 13:56 ` [Qemu-devel] [PATCH v2 30/45] acpi: use get_uint() for various acpi properties Marc-André Lureau
                   ` (17 subsequent siblings)
  46 siblings, 0 replies; 80+ messages in thread
From: Marc-André Lureau @ 2017-05-31 13:56 UTC (permalink / raw)
  To: qemu-devel; +Cc: armbru, Marc-André Lureau

Those are defined with object_property_add_uint16_ptr()

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
 hw/i386/acpi-build.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
index ba163e6df2..78cee47d39 100644
--- a/hw/i386/acpi-build.c
+++ b/hw/i386/acpi-build.c
@@ -137,9 +137,9 @@ static void acpi_get_pm_info(AcpiPmInfo *pm)
         obj = piix;
         pm->cpu_hp_io_base = PIIX4_CPU_HOTPLUG_IO_BASE;
         pm->pcihp_io_base =
-            object_property_get_int(obj, ACPI_PCIHP_IO_BASE_PROP, NULL);
+            object_property_get_uint(obj, ACPI_PCIHP_IO_BASE_PROP, NULL);
         pm->pcihp_io_len =
-            object_property_get_int(obj, ACPI_PCIHP_IO_LEN_PROP, NULL);
+            object_property_get_uint(obj, ACPI_PCIHP_IO_LEN_PROP, NULL);
     }
     if (lpc) {
         obj = lpc;
-- 
2.13.0.91.g00982b8dd

^ permalink raw reply related	[flat|nested] 80+ messages in thread

* [Qemu-devel] [PATCH v2 30/45] acpi: use get_uint() for various acpi properties
  2017-05-31 13:56 [Qemu-devel] [PATCH v2 00/45] qobject/qapi: add uint type Marc-André Lureau
                   ` (28 preceding siblings ...)
  2017-05-31 13:56 ` [Qemu-devel] [PATCH v2 29/45] acpi: use get_uint() for "acpi-pcihp-io*" properties Marc-André Lureau
@ 2017-05-31 13:56 ` Marc-André Lureau
  2017-05-31 13:56 ` [Qemu-devel] [PATCH v2 31/45] acpi: use get_uint() for "pci-hole*" properties Marc-André Lureau
                   ` (16 subsequent siblings)
  46 siblings, 0 replies; 80+ messages in thread
From: Marc-André Lureau @ 2017-05-31 13:56 UTC (permalink / raw)
  To: qemu-devel; +Cc: armbru, Marc-André Lureau

PIIX4: piix4_pm_add_propeties() defines these with
object_property_add_uint*_ptr().

Q35: ich9_lpc_add_properties() and ich9_pm_add_properties() define them
similarly, except for ACPI_PM_PROP_GPE0_BLK().  That one's getter
ich9_pm_get_gpe0_blk() uses visit_type_uint32().

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
 hw/i386/acpi-build.c | 27 ++++++++++++++-------------
 1 file changed, 14 insertions(+), 13 deletions(-)

diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
index 78cee47d39..8ae0373541 100644
--- a/hw/i386/acpi-build.c
+++ b/hw/i386/acpi-build.c
@@ -180,20 +180,21 @@ static void acpi_get_pm_info(AcpiPmInfo *pm)
     qobject_decref(o);
 
     /* Fill in mandatory properties */
-    pm->sci_int = object_property_get_int(obj, ACPI_PM_PROP_SCI_INT, NULL);
-
-    pm->acpi_enable_cmd = object_property_get_int(obj,
-                                                  ACPI_PM_PROP_ACPI_ENABLE_CMD,
-                                                  NULL);
-    pm->acpi_disable_cmd = object_property_get_int(obj,
-                                                  ACPI_PM_PROP_ACPI_DISABLE_CMD,
-                                                  NULL);
-    pm->io_base = object_property_get_int(obj, ACPI_PM_PROP_PM_IO_BASE,
-                                          NULL);
-    pm->gpe0_blk = object_property_get_int(obj, ACPI_PM_PROP_GPE0_BLK,
+    pm->sci_int = object_property_get_uint(obj, ACPI_PM_PROP_SCI_INT, NULL);
+
+    pm->acpi_enable_cmd = object_property_get_uint(obj,
+                                                   ACPI_PM_PROP_ACPI_ENABLE_CMD,
+                                                   NULL);
+    pm->acpi_disable_cmd =
+        object_property_get_uint(obj,
+                                 ACPI_PM_PROP_ACPI_DISABLE_CMD,
+                                 NULL);
+    pm->io_base = object_property_get_uint(obj, ACPI_PM_PROP_PM_IO_BASE,
                                            NULL);
-    pm->gpe0_blk_len = object_property_get_int(obj, ACPI_PM_PROP_GPE0_BLK_LEN,
-                                               NULL);
+    pm->gpe0_blk = object_property_get_uint(obj, ACPI_PM_PROP_GPE0_BLK,
+                                            NULL);
+    pm->gpe0_blk_len = object_property_get_uint(obj, ACPI_PM_PROP_GPE0_BLK_LEN,
+                                                NULL);
     pm->pcihp_bridge_en =
         object_property_get_bool(obj, "acpi-pci-hotplug-with-bridge-support",
                                  NULL);
-- 
2.13.0.91.g00982b8dd

^ permalink raw reply related	[flat|nested] 80+ messages in thread

* [Qemu-devel] [PATCH v2 31/45] acpi: use get_uint() for "pci-hole*" properties
  2017-05-31 13:56 [Qemu-devel] [PATCH v2 00/45] qobject/qapi: add uint type Marc-André Lureau
                   ` (29 preceding siblings ...)
  2017-05-31 13:56 ` [Qemu-devel] [PATCH v2 30/45] acpi: use get_uint() for various acpi properties Marc-André Lureau
@ 2017-05-31 13:56 ` Marc-André Lureau
  2017-06-06 12:24   ` Markus Armbruster
  2017-05-31 13:56 ` [Qemu-devel] [PATCH v2 32/45] pc: use get_uint() for "iobase" property Marc-André Lureau
                   ` (15 subsequent siblings)
  46 siblings, 1 reply; 80+ messages in thread
From: Marc-André Lureau @ 2017-05-31 13:56 UTC (permalink / raw)
  To: qemu-devel; +Cc: armbru, Marc-André Lureau

Those properties use visit_type_uint*()

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
 hw/i386/acpi-build.c | 24 ++++++++++++------------
 1 file changed, 12 insertions(+), 12 deletions(-)

diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
index 8ae0373541..64a277b974 100644
--- a/hw/i386/acpi-build.c
+++ b/hw/i386/acpi-build.c
@@ -247,19 +247,19 @@ static void acpi_get_pci_holes(Range *hole, Range *hole64)
     g_assert(pci_host);
 
     range_set_bounds1(hole,
-                      object_property_get_int(pci_host,
-                                              PCI_HOST_PROP_PCI_HOLE_START,
-                                              NULL),
-                      object_property_get_int(pci_host,
-                                              PCI_HOST_PROP_PCI_HOLE_END,
-                                              NULL));
+                      object_property_get_uint(pci_host,
+                                               PCI_HOST_PROP_PCI_HOLE_START,
+                                               NULL),
+                      object_property_get_uint(pci_host,
+                                               PCI_HOST_PROP_PCI_HOLE_END,
+                                               NULL));
     range_set_bounds1(hole64,
-                      object_property_get_int(pci_host,
-                                              PCI_HOST_PROP_PCI_HOLE64_START,
-                                              NULL),
-                      object_property_get_int(pci_host,
-                                              PCI_HOST_PROP_PCI_HOLE64_END,
-                                              NULL));
+                      object_property_get_uint(pci_host,
+                                               PCI_HOST_PROP_PCI_HOLE64_START,
+                                               NULL),
+                      object_property_get_uint(pci_host,
+                                               PCI_HOST_PROP_PCI_HOLE64_END,
+                                               NULL));
 }
 
 #define ACPI_PORT_SMI_CMD           0x00b2 /* TODO: this is APM_CNT_IOPORT */
-- 
2.13.0.91.g00982b8dd

^ permalink raw reply related	[flat|nested] 80+ messages in thread

* [Qemu-devel] [PATCH v2 32/45] pc: use get_uint() for "iobase" property
  2017-05-31 13:56 [Qemu-devel] [PATCH v2 00/45] qobject/qapi: add uint type Marc-André Lureau
                   ` (30 preceding siblings ...)
  2017-05-31 13:56 ` [Qemu-devel] [PATCH v2 31/45] acpi: use get_uint() for "pci-hole*" properties Marc-André Lureau
@ 2017-05-31 13:56 ` Marc-André Lureau
  2017-05-31 13:56 ` [Qemu-devel] [PATCH v2 33/45] pc: use get_uint() for "apic-id" property Marc-André Lureau
                   ` (14 subsequent siblings)
  46 siblings, 0 replies; 80+ messages in thread
From: Marc-André Lureau @ 2017-05-31 13:56 UTC (permalink / raw)
  To: qemu-devel; +Cc: armbru, Marc-André Lureau

TYPE_ISA_FDC's property "iobase" is defined with DEFINE_PROP_UINT32().

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
 hw/i386/pc.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index 107a34125b..3e8f8e83b2 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -347,7 +347,7 @@ static int check_fdc(Object *obj, void *opaque)
         return 0;
     }
 
-    iobase = object_property_get_int(obj, "iobase", &local_err);
+    iobase = object_property_get_uint(obj, "iobase", &local_err);
     if (local_err || iobase != 0x3f0) {
         error_free(local_err);
         return 0;
-- 
2.13.0.91.g00982b8dd

^ permalink raw reply related	[flat|nested] 80+ messages in thread

* [Qemu-devel] [PATCH v2 33/45] pc: use get_uint() for "apic-id" property
  2017-05-31 13:56 [Qemu-devel] [PATCH v2 00/45] qobject/qapi: add uint type Marc-André Lureau
                   ` (31 preceding siblings ...)
  2017-05-31 13:56 ` [Qemu-devel] [PATCH v2 32/45] pc: use get_uint() for "iobase" property Marc-André Lureau
@ 2017-05-31 13:56 ` Marc-André Lureau
  2017-05-31 13:56 ` [Qemu-devel] [PATCH v2 34/45] pc: use get_uint() for "hpet-intcap" property Marc-André Lureau
                   ` (13 subsequent siblings)
  46 siblings, 0 replies; 80+ messages in thread
From: Marc-André Lureau @ 2017-05-31 13:56 UTC (permalink / raw)
  To: qemu-devel; +Cc: armbru, Marc-André Lureau

TYPE_X86_CPU's property "apic-id" is defined with DEFINE_PROP_UINT32().

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
 hw/i386/pc.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index 3e8f8e83b2..c31115a8f0 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -1100,7 +1100,7 @@ static void pc_new_cpu(const char *typename, int64_t apic_id, Error **errp)
 
     cpu = object_new(typename);
 
-    object_property_set_int(cpu, apic_id, "apic-id", &local_err);
+    object_property_set_uint(cpu, apic_id, "apic-id", &local_err);
     object_property_set_bool(cpu, true, "realized", &local_err);
 
     object_unref(cpu);
-- 
2.13.0.91.g00982b8dd

^ permalink raw reply related	[flat|nested] 80+ messages in thread

* [Qemu-devel] [PATCH v2 34/45] pc: use get_uint() for "hpet-intcap" property
  2017-05-31 13:56 [Qemu-devel] [PATCH v2 00/45] qobject/qapi: add uint type Marc-André Lureau
                   ` (32 preceding siblings ...)
  2017-05-31 13:56 ` [Qemu-devel] [PATCH v2 33/45] pc: use get_uint() for "apic-id" property Marc-André Lureau
@ 2017-05-31 13:56 ` Marc-André Lureau
  2017-05-31 13:56 ` [Qemu-devel] [PATCH v2 35/45] xen: use get_uint() for "max-ram-below-4g" property Marc-André Lureau
                   ` (12 subsequent siblings)
  46 siblings, 0 replies; 80+ messages in thread
From: Marc-André Lureau @ 2017-05-31 13:56 UTC (permalink / raw)
  To: qemu-devel; +Cc: armbru, Marc-André Lureau

TYPE_HPET's property HPET_INTCAP is defined with DEFINE_PROP_UINT32().

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
 hw/i386/pc.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index c31115a8f0..e970d0c4e2 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -1560,7 +1560,7 @@ void pc_basic_device_init(ISABus *isa_bus, qemu_irq *gsi,
              * and earlier, use IRQ2 for compat. Otherwise, use IRQ16~23,
              * IRQ8 and IRQ2.
              */
-            uint8_t compat = object_property_get_int(OBJECT(hpet),
+            uint8_t compat = object_property_get_uint(OBJECT(hpet),
                     HPET_INTCAP, NULL);
             if (!compat) {
                 qdev_prop_set_uint32(hpet, HPET_INTCAP, hpet_irqs);
-- 
2.13.0.91.g00982b8dd

^ permalink raw reply related	[flat|nested] 80+ messages in thread

* [Qemu-devel] [PATCH v2 35/45] xen: use get_uint() for "max-ram-below-4g" property
  2017-05-31 13:56 [Qemu-devel] [PATCH v2 00/45] qobject/qapi: add uint type Marc-André Lureau
                   ` (33 preceding siblings ...)
  2017-05-31 13:56 ` [Qemu-devel] [PATCH v2 34/45] pc: use get_uint() for "hpet-intcap" property Marc-André Lureau
@ 2017-05-31 13:56 ` Marc-André Lureau
  2017-05-31 13:57 ` [Qemu-devel] [PATCH v2 36/45] arm: use get_uint() for "mp-affinity" property Marc-André Lureau
                   ` (11 subsequent siblings)
  46 siblings, 0 replies; 80+ messages in thread
From: Marc-André Lureau @ 2017-05-31 13:56 UTC (permalink / raw)
  To: qemu-devel; +Cc: armbru, Marc-André Lureau

TYPE_PC_MACHINE's property PC_MACHINE_MAX_RAM_BELOW_4G's getter and
setter pc_machine_get_max_ram_below_4g() and
pc_machine_set_max_ram_below_4g() use visit_type_size()

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
 hw/i386/xen/xen-hvm.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/hw/i386/xen/xen-hvm.c b/hw/i386/xen/xen-hvm.c
index 919f09b694..b9981b257b 100644
--- a/hw/i386/xen/xen-hvm.c
+++ b/hw/i386/xen/xen-hvm.c
@@ -183,9 +183,9 @@ static void xen_ram_init(PCMachineState *pcms,
 {
     MemoryRegion *sysmem = get_system_memory();
     ram_addr_t block_len;
-    uint64_t user_lowmem = object_property_get_int(qdev_get_machine(),
-                                                   PC_MACHINE_MAX_RAM_BELOW_4G,
-                                                   &error_abort);
+    uint64_t user_lowmem = object_property_get_uint(qdev_get_machine(),
+                                                    PC_MACHINE_MAX_RAM_BELOW_4G,
+                                                    &error_abort);
 
     /* Handle the machine opt max-ram-below-4g.  It is basically doing
      * min(xen limit, user limit).
-- 
2.13.0.91.g00982b8dd

^ permalink raw reply related	[flat|nested] 80+ messages in thread

* [Qemu-devel] [PATCH v2 36/45] arm: use get_uint() for "mp-affinity" property
  2017-05-31 13:56 [Qemu-devel] [PATCH v2 00/45] qobject/qapi: add uint type Marc-André Lureau
                   ` (34 preceding siblings ...)
  2017-05-31 13:56 ` [Qemu-devel] [PATCH v2 35/45] xen: use get_uint() for "max-ram-below-4g" property Marc-André Lureau
@ 2017-05-31 13:57 ` Marc-André Lureau
  2017-05-31 13:57 ` [Qemu-devel] [PATCH v2 37/45] auxbus: use get_uint() for "addr" property Marc-André Lureau
                   ` (10 subsequent siblings)
  46 siblings, 0 replies; 80+ messages in thread
From: Marc-André Lureau @ 2017-05-31 13:57 UTC (permalink / raw)
  To: qemu-devel; +Cc: armbru, Marc-André Lureau

TYPE_ARM_CPU's property "mp-affinity" is defined with
DEFINE_PROP_UINT64().

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
 hw/intc/arm_gicv3_common.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/intc/arm_gicv3_common.c b/hw/intc/arm_gicv3_common.c
index c6493d6c07..e2064cd8c5 100644
--- a/hw/intc/arm_gicv3_common.c
+++ b/hw/intc/arm_gicv3_common.c
@@ -267,7 +267,7 @@ static void arm_gicv3_common_realize(DeviceState *dev, Error **errp)
          *  VLPIS == 0 (virtual LPIs not supported)
          *  PLPIS == 0 (physical LPIs not supported)
          */
-        cpu_affid = object_property_get_int(OBJECT(cpu), "mp-affinity", NULL);
+        cpu_affid = object_property_get_uint(OBJECT(cpu), "mp-affinity", NULL);
         last = (i == s->num_cpu - 1);
 
         /* The CPU mp-affinity property is in MPIDR register format; squash
-- 
2.13.0.91.g00982b8dd

^ permalink raw reply related	[flat|nested] 80+ messages in thread

* [Qemu-devel] [PATCH v2 37/45] auxbus: use get_uint() for "addr" property
  2017-05-31 13:56 [Qemu-devel] [PATCH v2 00/45] qobject/qapi: add uint type Marc-André Lureau
                   ` (35 preceding siblings ...)
  2017-05-31 13:57 ` [Qemu-devel] [PATCH v2 36/45] arm: use get_uint() for "mp-affinity" property Marc-André Lureau
@ 2017-05-31 13:57 ` Marc-André Lureau
  2017-05-31 13:57 ` [Qemu-devel] [PATCH v2 38/45] pvpanic: use get_uint() for "ioport" property Marc-André Lureau
                   ` (9 subsequent siblings)
  46 siblings, 0 replies; 80+ messages in thread
From: Marc-André Lureau @ 2017-05-31 13:57 UTC (permalink / raw)
  To: qemu-devel; +Cc: armbru, Marc-André Lureau

This is TYPE_MEMORY_REGION's property.  Its getter
memory_region_get_addr() uses visit_type_uint64().

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
 hw/misc/auxbus.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/misc/auxbus.c b/hw/misc/auxbus.c
index e4a7ba41de..8a90ddda84 100644
--- a/hw/misc/auxbus.c
+++ b/hw/misc/auxbus.c
@@ -244,7 +244,7 @@ static void aux_slave_dev_print(Monitor *mon, DeviceState *dev, int indent)
 
     monitor_printf(mon, "%*smemory " TARGET_FMT_plx "/" TARGET_FMT_plx "\n",
                    indent, "",
-                   object_property_get_int(OBJECT(s->mmio), "addr", NULL),
+                   object_property_get_uint(OBJECT(s->mmio), "addr", NULL),
                    memory_region_size(s->mmio));
 }
 
-- 
2.13.0.91.g00982b8dd

^ permalink raw reply related	[flat|nested] 80+ messages in thread

* [Qemu-devel] [PATCH v2 38/45] pvpanic: use get_uint() for "ioport" property
  2017-05-31 13:56 [Qemu-devel] [PATCH v2 00/45] qobject/qapi: add uint type Marc-André Lureau
                   ` (36 preceding siblings ...)
  2017-05-31 13:57 ` [Qemu-devel] [PATCH v2 37/45] auxbus: use get_uint() for "addr" property Marc-André Lureau
@ 2017-05-31 13:57 ` Marc-André Lureau
  2017-05-31 13:57 ` [Qemu-devel] [PATCH v2 39/45] pnv-core: use get_uint() for "core-pir" property Marc-André Lureau
                   ` (8 subsequent siblings)
  46 siblings, 0 replies; 80+ messages in thread
From: Marc-André Lureau @ 2017-05-31 13:57 UTC (permalink / raw)
  To: qemu-devel; +Cc: armbru, Marc-André Lureau

TYPE_ISA_PVPANIC_DEVICE's property PVPANIC_IOPORT_PROP is defined with
DEFINE_PROP_UINT16().

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
 hw/misc/pvpanic.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/misc/pvpanic.c b/hw/misc/pvpanic.c
index 57da7f2199..2b1e9a6450 100644
--- a/hw/misc/pvpanic.c
+++ b/hw/misc/pvpanic.c
@@ -111,7 +111,7 @@ uint16_t pvpanic_port(void)
     if (!o) {
         return 0;
     }
-    return object_property_get_int(o, PVPANIC_IOPORT_PROP, NULL);
+    return object_property_get_uint(o, PVPANIC_IOPORT_PROP, NULL);
 }
 
 static Property pvpanic_isa_properties[] = {
-- 
2.13.0.91.g00982b8dd

^ permalink raw reply related	[flat|nested] 80+ messages in thread

* [Qemu-devel] [PATCH v2 39/45] pnv-core: use get_uint() for "core-pir" property
  2017-05-31 13:56 [Qemu-devel] [PATCH v2 00/45] qobject/qapi: add uint type Marc-André Lureau
                   ` (37 preceding siblings ...)
  2017-05-31 13:57 ` [Qemu-devel] [PATCH v2 38/45] pvpanic: use get_uint() for "ioport" property Marc-André Lureau
@ 2017-05-31 13:57 ` Marc-André Lureau
  2017-05-31 13:57 ` [Qemu-devel] [PATCH v2 40/45] numa: use get_uint() for "size" property Marc-André Lureau
                   ` (7 subsequent siblings)
  46 siblings, 0 replies; 80+ messages in thread
From: Marc-André Lureau @ 2017-05-31 13:57 UTC (permalink / raw)
  To: qemu-devel; +Cc: armbru, Marc-André Lureau

This is an alias of TYPE_PNV_CORE's property "pir", which is defined
with DEFINE_PROP_UINT32()

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
 hw/ppc/pnv_core.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/ppc/pnv_core.c b/hw/ppc/pnv_core.c
index 1b7ec70f03..142bad1e57 100644
--- a/hw/ppc/pnv_core.c
+++ b/hw/ppc/pnv_core.c
@@ -51,7 +51,7 @@ static void powernv_cpu_init(PowerPCCPU *cpu, Error **errp)
     int thread_index = 0; /* TODO: TCG supports only one thread */
     ppc_spr_t *pir = &env->spr_cb[SPR_PIR];
 
-    core_pir = object_property_get_int(OBJECT(cpu), "core-pir", &error_abort);
+    core_pir = object_property_get_uint(OBJECT(cpu), "core-pir", &error_abort);
 
     /*
      * The PIR of a thread is the core PIR + the thread index. We will
-- 
2.13.0.91.g00982b8dd

^ permalink raw reply related	[flat|nested] 80+ messages in thread

* [Qemu-devel] [PATCH v2 40/45] numa: use get_uint() for "size" property
  2017-05-31 13:56 [Qemu-devel] [PATCH v2 00/45] qobject/qapi: add uint type Marc-André Lureau
                   ` (38 preceding siblings ...)
  2017-05-31 13:57 ` [Qemu-devel] [PATCH v2 39/45] pnv-core: use get_uint() for "core-pir" property Marc-André Lureau
@ 2017-05-31 13:57 ` Marc-André Lureau
  2017-05-31 13:57 ` [Qemu-devel] [PATCH v2 41/45] i386/cpu: use get_uint() for "min-level"/"min-xlevel" properties Marc-André Lureau
                   ` (6 subsequent siblings)
  46 siblings, 0 replies; 80+ messages in thread
From: Marc-André Lureau @ 2017-05-31 13:57 UTC (permalink / raw)
  To: qemu-devel; +Cc: armbru, Marc-André Lureau

"size" is a property of TYPE_MEMORY_BACKEND.
host_memory_backend_get_size() and host_memory_backend_set_size() use
visit_type_size().

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
 numa.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/numa.c b/numa.c
index ca731455e9..853f51d143 100644
--- a/numa.c
+++ b/numa.c
@@ -216,7 +216,7 @@ static void parse_numa_node(MachineState *ms, NumaNodeOptions *node,
         }
 
         object_ref(o);
-        numa_info[nodenr].node_mem = object_property_get_int(o, "size", NULL);
+        numa_info[nodenr].node_mem = object_property_get_uint(o, "size", NULL);
         numa_info[nodenr].node_memdev = MEMORY_BACKEND(o);
     }
     numa_info[nodenr].present = true;
@@ -651,8 +651,8 @@ static int query_memdev(Object *obj, void *opaque)
         m->value->id = object_property_get_str(obj, "id", NULL);
         m->value->has_id = !!m->value->id;
 
-        m->value->size = object_property_get_int(obj, "size",
-                                                 &error_abort);
+        m->value->size = object_property_get_uint(obj, "size",
+                                                  &error_abort);
         m->value->merge = object_property_get_bool(obj, "merge",
                                                    &error_abort);
         m->value->dump = object_property_get_bool(obj, "dump",
-- 
2.13.0.91.g00982b8dd

^ permalink raw reply related	[flat|nested] 80+ messages in thread

* [Qemu-devel] [PATCH v2 41/45] i386/cpu: use get_uint() for "min-level"/"min-xlevel" properties
  2017-05-31 13:56 [Qemu-devel] [PATCH v2 00/45] qobject/qapi: add uint type Marc-André Lureau
                   ` (39 preceding siblings ...)
  2017-05-31 13:57 ` [Qemu-devel] [PATCH v2 40/45] numa: use get_uint() for "size" property Marc-André Lureau
@ 2017-05-31 13:57 ` Marc-André Lureau
  2017-05-31 13:57 ` [Qemu-devel] [PATCH v2 42/45] console: use get_uint() for "head" property Marc-André Lureau
                   ` (5 subsequent siblings)
  46 siblings, 0 replies; 80+ messages in thread
From: Marc-André Lureau @ 2017-05-31 13:57 UTC (permalink / raw)
  To: qemu-devel; +Cc: armbru, Marc-André Lureau

These are properties of TYPE_X86_CPU, defined with DEFINE_PROP_UINT32()

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
 target/i386/cpu.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index 12882f0774..f9dba1bd62 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -2324,8 +2324,8 @@ static void x86_cpu_load_def(X86CPU *cpu, X86CPUDefinition *def, Error **errp)
      */
 
     /* CPU models only set _minimum_ values for level/xlevel: */
-    object_property_set_int(OBJECT(cpu), def->level, "min-level", errp);
-    object_property_set_int(OBJECT(cpu), def->xlevel, "min-xlevel", errp);
+    object_property_set_uint(OBJECT(cpu), def->level, "min-level", errp);
+    object_property_set_uint(OBJECT(cpu), def->xlevel, "min-xlevel", errp);
 
     object_property_set_int(OBJECT(cpu), def->family, "family", errp);
     object_property_set_int(OBJECT(cpu), def->model, "model", errp);
-- 
2.13.0.91.g00982b8dd

^ permalink raw reply related	[flat|nested] 80+ messages in thread

* [Qemu-devel] [PATCH v2 42/45] console: use get_uint() for "head" property
  2017-05-31 13:56 [Qemu-devel] [PATCH v2 00/45] qobject/qapi: add uint type Marc-André Lureau
                   ` (40 preceding siblings ...)
  2017-05-31 13:57 ` [Qemu-devel] [PATCH v2 41/45] i386/cpu: use get_uint() for "min-level"/"min-xlevel" properties Marc-André Lureau
@ 2017-05-31 13:57 ` Marc-André Lureau
  2017-05-31 13:57 ` [Qemu-devel] [PATCH v2 43/45] tests/qdict: check more get_try_int() cases Marc-André Lureau
                   ` (4 subsequent siblings)
  46 siblings, 0 replies; 80+ messages in thread
From: Marc-André Lureau @ 2017-05-31 13:57 UTC (permalink / raw)
  To: qemu-devel; +Cc: armbru, Marc-André Lureau

TYPE_QEMU_CONSOLE property "head" is defined with
object_property_add_uint*_ptr().

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
 ui/console.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/ui/console.c b/ui/console.c
index ac66b3c910..ad3f7c6a2c 100644
--- a/ui/console.c
+++ b/ui/console.c
@@ -1872,8 +1872,8 @@ QemuConsole *qemu_console_lookup_by_device(DeviceState *dev, uint32_t head)
         if (DEVICE(obj) != dev) {
             continue;
         }
-        h = object_property_get_int(OBJECT(consoles[i]),
-                                    "head", &error_abort);
+        h = object_property_get_uint(OBJECT(consoles[i]),
+                                     "head", &error_abort);
         if (h != head) {
             continue;
         }
-- 
2.13.0.91.g00982b8dd

^ permalink raw reply related	[flat|nested] 80+ messages in thread

* [Qemu-devel] [PATCH v2 43/45] tests/qdict: check more get_try_int() cases
  2017-05-31 13:56 [Qemu-devel] [PATCH v2 00/45] qobject/qapi: add uint type Marc-André Lureau
                   ` (41 preceding siblings ...)
  2017-05-31 13:57 ` [Qemu-devel] [PATCH v2 42/45] console: use get_uint() for "head" property Marc-André Lureau
@ 2017-05-31 13:57 ` Marc-André Lureau
  2017-06-06 12:26   ` Markus Armbruster
  2017-05-31 13:57 ` [Qemu-devel] [PATCH v2 44/45] RFC: qdict: add uint Marc-André Lureau
                   ` (3 subsequent siblings)
  46 siblings, 1 reply; 80+ messages in thread
From: Marc-André Lureau @ 2017-05-31 13:57 UTC (permalink / raw)
  To: qemu-devel; +Cc: armbru, Marc-André Lureau

Suggested by Markus Armbruster.

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
 tests/check-qdict.c | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/tests/check-qdict.c b/tests/check-qdict.c
index 5c70490e83..889b43b57d 100644
--- a/tests/check-qdict.c
+++ b/tests/check-qdict.c
@@ -117,10 +117,17 @@ static void qdict_get_try_int_test(void)
     QDict *tests_dict = qdict_new();
 
     qdict_put_int(tests_dict, key, value);
+    qdict_put_str(tests_dict, "string", "test");
 
     ret = qdict_get_try_int(tests_dict, key, 0);
     g_assert(ret == value);
 
+    ret = qdict_get_try_int(tests_dict, "missing", -42);
+    g_assert_cmpuint(ret, ==, -42);
+
+    ret = qdict_get_try_int(tests_dict, "string", -42);
+    g_assert_cmpuint(ret, ==, -42);
+
     QDECREF(tests_dict);
 }
 
-- 
2.13.0.91.g00982b8dd

^ permalink raw reply related	[flat|nested] 80+ messages in thread

* [Qemu-devel] [PATCH v2 44/45] RFC: qdict: add uint
  2017-05-31 13:56 [Qemu-devel] [PATCH v2 00/45] qobject/qapi: add uint type Marc-André Lureau
                   ` (42 preceding siblings ...)
  2017-05-31 13:57 ` [Qemu-devel] [PATCH v2 43/45] tests/qdict: check more get_try_int() cases Marc-André Lureau
@ 2017-05-31 13:57 ` Marc-André Lureau
  2017-06-06 12:28   ` Markus Armbruster
  2017-05-31 13:57 ` [Qemu-devel] [PATCH v2 45/45] qobject: move dump_qobject() from block/ to qobject/ Marc-André Lureau
                   ` (2 subsequent siblings)
  46 siblings, 1 reply; 80+ messages in thread
From: Marc-André Lureau @ 2017-05-31 13:57 UTC (permalink / raw)
  To: qemu-devel; +Cc: armbru, Marc-André Lureau

Similar to int support, add uint support.

Note this is RFC because this is currently unused in qemu, I haven't
found a good user for it yet (kaslr qemu-ga code did use it though).

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
 include/qapi/qmp/qdict.h |  5 +++++
 qobject/qdict.c          | 39 +++++++++++++++++++++++++++++++++++++++
 tests/check-qdict.c      | 39 +++++++++++++++++++++++++++++++++++++++
 3 files changed, 83 insertions(+)

diff --git a/include/qapi/qmp/qdict.h b/include/qapi/qmp/qdict.h
index 363e431106..8c7c2b762b 100644
--- a/include/qapi/qmp/qdict.h
+++ b/include/qapi/qmp/qdict.h
@@ -56,6 +56,8 @@ void qdict_destroy_obj(QObject *obj);
 /* Helpers for int, bool, and string */
 #define qdict_put_int(qdict, key, value) \
         qdict_put(qdict, key, qnum_from_int(value))
+#define qdict_put_uint(qdict, key, value)        \
+        qdict_put(qdict, key, qnum_from_uint(value))
 #define qdict_put_bool(qdict, key, value) \
         qdict_put(qdict, key, qbool_from_bool(value))
 #define qdict_put_str(qdict, key, value) \
@@ -64,12 +66,15 @@ void qdict_destroy_obj(QObject *obj);
 /* High level helpers */
 double qdict_get_double(const QDict *qdict, const char *key);
 int64_t qdict_get_int(const QDict *qdict, const char *key);
+uint64_t qdict_get_uint(const QDict *qdict, const char *key);
 bool qdict_get_bool(const QDict *qdict, const char *key);
 QList *qdict_get_qlist(const QDict *qdict, const char *key);
 QDict *qdict_get_qdict(const QDict *qdict, const char *key);
 const char *qdict_get_str(const QDict *qdict, const char *key);
 int64_t qdict_get_try_int(const QDict *qdict, const char *key,
                           int64_t def_value);
+uint64_t qdict_get_try_uint(const QDict *qdict, const char *key,
+                            uint64_t def_value);
 bool qdict_get_try_bool(const QDict *qdict, const char *key, bool def_value);
 const char *qdict_get_try_str(const QDict *qdict, const char *key);
 
diff --git a/qobject/qdict.c b/qobject/qdict.c
index f62625cbd6..b02dc6b745 100644
--- a/qobject/qdict.c
+++ b/qobject/qdict.c
@@ -208,6 +208,25 @@ int64_t qdict_get_int(const QDict *qdict, const char *key)
 }
 
 /**
+ * qdict_get_uint(): Get an unsigned integer mapped by 'key'
+ *
+ * This function assumes that 'key' exists and it stores a
+ * QNum int object.
+ *
+ * Return unsigned integer mapped by 'key'.
+ */
+uint64_t qdict_get_uint(const QDict *qdict, const char *key)
+{
+    uint64_t val;
+
+    if (!qnum_get_uint(qobject_to_qnum(qdict_get(qdict, key)), &val)) {
+        g_assert_not_reached();
+    }
+
+    return val;
+}
+
+/**
  * qdict_get_bool(): Get a bool mapped by 'key'
  *
  * This function assumes that 'key' exists and it stores a
@@ -271,6 +290,26 @@ int64_t qdict_get_try_int(const QDict *qdict, const char *key,
 }
 
 /**
+ * qdict_get_try_uint(): Try to get usigned integer mapped by 'key'
+ *
+ * Return unsigned integer mapped by 'key', if it is not present in
+ * the dictionary or if the stored object is not of QNum type
+ * 'def_value' will be returned.
+ */
+uint64_t qdict_get_try_uint(const QDict *qdict, const char *key,
+                            uint64_t def_value)
+{
+    QNum *qnum = qobject_to_qnum(qdict_get(qdict, key));
+    uint64_t val;
+
+    if (!qnum || !qnum_get_uint(qnum, &val)) {
+        val = def_value;
+    }
+
+    return val;
+}
+
+/**
  * qdict_get_try_bool(): Try to get a bool mapped by 'key'
  *
  * Return bool mapped by 'key', if it is not present in the
diff --git a/tests/check-qdict.c b/tests/check-qdict.c
index 889b43b57d..2a5b322509 100644
--- a/tests/check-qdict.c
+++ b/tests/check-qdict.c
@@ -109,6 +109,21 @@ static void qdict_get_int_test(void)
     QDECREF(tests_dict);
 }
 
+static void qdict_get_uint_test(void)
+{
+    uint64_t ret;
+    const uint64_t value = UINT64_MAX;
+    const char *key = "uint";
+    QDict *tests_dict = qdict_new();
+
+    qdict_put_uint(tests_dict, key, value);
+
+    ret = qdict_get_uint(tests_dict, key);
+    g_assert(ret == value);
+
+    QDECREF(tests_dict);
+}
+
 static void qdict_get_try_int_test(void)
 {
     int ret;
@@ -131,6 +146,28 @@ static void qdict_get_try_int_test(void)
     QDECREF(tests_dict);
 }
 
+static void qdict_get_try_uint_test(void)
+{
+    uint64_t ret;
+    const uint64_t value = UINT64_MAX;
+    const char *key = "uint";
+    QDict *tests_dict = qdict_new();
+
+    qdict_put_uint(tests_dict, key, value);
+    qdict_put_str(tests_dict, "string", "test");
+
+    ret = qdict_get_try_uint(tests_dict, key, 0);
+    g_assert_cmpuint(ret, ==, value);
+
+    ret = qdict_get_try_uint(tests_dict, "missing", 42);
+    g_assert_cmpuint(ret, ==, 42);
+
+    ret = qdict_get_try_uint(tests_dict, "string", 42);
+    g_assert_cmpuint(ret, ==, 42);
+
+    QDECREF(tests_dict);
+}
+
 static void qdict_get_str_test(void)
 {
     const char *p;
@@ -866,7 +903,9 @@ int main(int argc, char **argv)
     /* Continue, but now with fixtures */
     g_test_add_func("/public/get", qdict_get_test);
     g_test_add_func("/public/get_int", qdict_get_int_test);
+    g_test_add_func("/public/get_uint", qdict_get_uint_test);
     g_test_add_func("/public/get_try_int", qdict_get_try_int_test);
+    g_test_add_func("/public/get_try_uint", qdict_get_try_uint_test);
     g_test_add_func("/public/get_str", qdict_get_str_test);
     g_test_add_func("/public/get_try_str", qdict_get_try_str_test);
     g_test_add_func("/public/defaults", qdict_defaults_test);
-- 
2.13.0.91.g00982b8dd

^ permalink raw reply related	[flat|nested] 80+ messages in thread

* [Qemu-devel] [PATCH v2 45/45] qobject: move dump_qobject() from block/ to qobject/
  2017-05-31 13:56 [Qemu-devel] [PATCH v2 00/45] qobject/qapi: add uint type Marc-André Lureau
                   ` (43 preceding siblings ...)
  2017-05-31 13:57 ` [Qemu-devel] [PATCH v2 44/45] RFC: qdict: add uint Marc-André Lureau
@ 2017-05-31 13:57 ` Marc-André Lureau
  2017-05-31 20:06 ` [Qemu-devel] [PATCH v2 00/45] qobject/qapi: add uint type no-reply
  2017-06-06 12:36 ` Markus Armbruster
  46 siblings, 0 replies; 80+ messages in thread
From: Marc-André Lureau @ 2017-05-31 13:57 UTC (permalink / raw)
  To: qemu-devel; +Cc: armbru, Marc-André Lureau

The dump functions could be generally useful for any qobject user or for
debugging etc.

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
 include/qapi/qmp/qdict.h   |  2 ++
 include/qapi/qmp/qlist.h   |  2 ++
 include/qapi/qmp/qobject.h |  7 ++++
 block/qapi.c               | 90 +++-------------------------------------------
 qobject/qdict.c            | 30 ++++++++++++++++
 qobject/qlist.c            | 23 ++++++++++++
 qobject/qobject.c          | 19 ++++++++++
 tests/check-qjson.c        | 19 ++++++++++
 8 files changed, 106 insertions(+), 86 deletions(-)

diff --git a/include/qapi/qmp/qdict.h b/include/qapi/qmp/qdict.h
index 8c7c2b762b..1ef3bc8cda 100644
--- a/include/qapi/qmp/qdict.h
+++ b/include/qapi/qmp/qdict.h
@@ -91,4 +91,6 @@ QObject *qdict_crumple(const QDict *src, Error **errp);
 
 void qdict_join(QDict *dest, QDict *src, bool overwrite);
 
+char *qdict_to_string(QDict *dict, int indent);
+
 #endif /* QDICT_H */
diff --git a/include/qapi/qmp/qlist.h b/include/qapi/qmp/qlist.h
index c4b5fdad9b..c93ac3e15b 100644
--- a/include/qapi/qmp/qlist.h
+++ b/include/qapi/qmp/qlist.h
@@ -60,6 +60,8 @@ size_t qlist_size(const QList *qlist);
 QList *qobject_to_qlist(const QObject *obj);
 void qlist_destroy_obj(QObject *obj);
 
+char *qlist_to_string(QList *list, int indent);
+
 static inline const QListEntry *qlist_first(const QList *qlist)
 {
     return QTAILQ_FIRST(&qlist->head);
diff --git a/include/qapi/qmp/qobject.h b/include/qapi/qmp/qobject.h
index b8ddbca405..0d6ae5048a 100644
--- a/include/qapi/qmp/qobject.h
+++ b/include/qapi/qmp/qobject.h
@@ -101,4 +101,11 @@ static inline QObject *qnull(void)
     return &qnull_;
 }
 
+char *qobject_to_string_indent(QObject *obj, int indent);
+
+static inline char *qobject_to_string(QObject *obj)
+{
+    return qobject_to_string_indent(obj, 0);
+}
+
 #endif /* QOBJECT_H */
diff --git a/block/qapi.c b/block/qapi.c
index 2050df29e4..9b7d42e50a 100644
--- a/block/qapi.c
+++ b/block/qapi.c
@@ -586,101 +586,19 @@ void bdrv_snapshot_dump(fprintf_function func_fprintf, void *f,
     }
 }
 
-static void dump_qdict(fprintf_function func_fprintf, void *f, int indentation,
-                       QDict *dict);
-static void dump_qlist(fprintf_function func_fprintf, void *f, int indentation,
-                       QList *list);
-
-static void dump_qobject(fprintf_function func_fprintf, void *f,
-                         int comp_indent, QObject *obj)
-{
-    switch (qobject_type(obj)) {
-        case QTYPE_QNUM: {
-            QNum *value = qobject_to_qnum(obj);
-            char *tmp = qnum_to_string(value);
-            func_fprintf(f, "%s", tmp);
-            g_free(tmp);
-            break;
-        }
-        case QTYPE_QSTRING: {
-            QString *value = qobject_to_qstring(obj);
-            func_fprintf(f, "%s", qstring_get_str(value));
-            break;
-        }
-        case QTYPE_QDICT: {
-            QDict *value = qobject_to_qdict(obj);
-            dump_qdict(func_fprintf, f, comp_indent, value);
-            break;
-        }
-        case QTYPE_QLIST: {
-            QList *value = qobject_to_qlist(obj);
-            dump_qlist(func_fprintf, f, comp_indent, value);
-            break;
-        }
-        case QTYPE_QBOOL: {
-            QBool *value = qobject_to_qbool(obj);
-            func_fprintf(f, "%s", qbool_get_bool(value) ? "true" : "false");
-            break;
-        }
-        default:
-            abort();
-    }
-}
-
-static void dump_qlist(fprintf_function func_fprintf, void *f, int indentation,
-                       QList *list)
-{
-    const QListEntry *entry;
-    int i = 0;
-
-    for (entry = qlist_first(list); entry; entry = qlist_next(entry), i++) {
-        QType type = qobject_type(entry->value);
-        bool composite = (type == QTYPE_QDICT || type == QTYPE_QLIST);
-        func_fprintf(f, "%*s[%i]:%c", indentation * 4, "", i,
-                     composite ? '\n' : ' ');
-        dump_qobject(func_fprintf, f, indentation + 1, entry->value);
-        if (!composite) {
-            func_fprintf(f, "\n");
-        }
-    }
-}
-
-static void dump_qdict(fprintf_function func_fprintf, void *f, int indentation,
-                       QDict *dict)
-{
-    const QDictEntry *entry;
-
-    for (entry = qdict_first(dict); entry; entry = qdict_next(dict, entry)) {
-        QType type = qobject_type(entry->value);
-        bool composite = (type == QTYPE_QDICT || type == QTYPE_QLIST);
-        char *key = g_malloc(strlen(entry->key) + 1);
-        int i;
-
-        /* replace dashes with spaces in key (variable) names */
-        for (i = 0; entry->key[i]; i++) {
-            key[i] = entry->key[i] == '-' ? ' ' : entry->key[i];
-        }
-        key[i] = 0;
-        func_fprintf(f, "%*s%s:%c", indentation * 4, "", key,
-                     composite ? '\n' : ' ');
-        dump_qobject(func_fprintf, f, indentation + 1, entry->value);
-        if (!composite) {
-            func_fprintf(f, "\n");
-        }
-        g_free(key);
-    }
-}
-
 void bdrv_image_info_specific_dump(fprintf_function func_fprintf, void *f,
                                    ImageInfoSpecific *info_spec)
 {
     QObject *obj, *data;
     Visitor *v = qobject_output_visitor_new(&obj);
+    char *tmp;
 
     visit_type_ImageInfoSpecific(v, NULL, &info_spec, &error_abort);
     visit_complete(v, &obj);
     data = qdict_get(qobject_to_qdict(obj), "data");
-    dump_qobject(func_fprintf, f, 1, data);
+    tmp = qobject_to_string_indent(data, 1);
+    func_fprintf(f, "%s", tmp);
+    g_free(tmp);
     qobject_decref(obj);
     visit_free(v);
 }
diff --git a/qobject/qdict.c b/qobject/qdict.c
index b02dc6b745..e2cde1255a 100644
--- a/qobject/qdict.c
+++ b/qobject/qdict.c
@@ -1067,3 +1067,33 @@ void qdict_join(QDict *dest, QDict *src, bool overwrite)
         entry = next;
     }
 }
+
+char *qdict_to_string(QDict *dict, int indent)
+{
+    const QDictEntry *entry;
+    GString *str = g_string_new(NULL);
+
+    for (entry = qdict_first(dict); entry; entry = qdict_next(dict, entry)) {
+        QType type = qobject_type(entry->value);
+        bool composite = (type == QTYPE_QDICT || type == QTYPE_QLIST);
+        char *key = g_malloc(strlen(entry->key) + 1);
+        char *val = qobject_to_string_indent(entry->value, indent + 1);
+        int i;
+
+        /* replace dashes with spaces in key (variable) names */
+        for (i = 0; entry->key[i]; i++) {
+            key[i] = entry->key[i] == '-' ? ' ' : entry->key[i];
+        }
+        key[i] = 0;
+        g_string_append_printf(str, "%*s%s:", indent * 4, "", key);
+        g_string_append_c(str, composite ? '\n' : ' ');
+        g_string_append(str, val);
+        if (!composite) {
+            g_string_append_c(str, '\n');
+        }
+        g_free(val);
+        g_free(key);
+    }
+
+    return g_string_free(str, false);
+}
diff --git a/qobject/qlist.c b/qobject/qlist.c
index 86b60cb88c..b769248290 100644
--- a/qobject/qlist.c
+++ b/qobject/qlist.c
@@ -158,3 +158,26 @@ void qlist_destroy_obj(QObject *obj)
 
     g_free(qlist);
 }
+
+char *qlist_to_string(QList *list, int indent)
+{
+    GString *str = g_string_new(NULL);
+    const QListEntry *entry;
+    int i = 0;
+
+    for (entry = qlist_first(list); entry; entry = qlist_next(entry), i++) {
+        QType type = qobject_type(entry->value);
+        bool composite = (type == QTYPE_QDICT || type == QTYPE_QLIST);
+        char *val = qobject_to_string_indent(entry->value, indent + 1);
+
+        g_string_append_printf(str, "%*s[%i]:", indent * 4, "", i);
+        g_string_append_c(str, composite ? '\n' : ' ');
+        g_string_append(str, val);
+        if (!composite) {
+            g_string_append_c(str, '\n');
+        }
+        g_free(val);
+    }
+
+    return g_string_free(str, false);
+}
diff --git a/qobject/qobject.c b/qobject/qobject.c
index b0cafb66f1..64e959c54f 100644
--- a/qobject/qobject.c
+++ b/qobject/qobject.c
@@ -27,3 +27,22 @@ void qobject_destroy(QObject *obj)
     assert(QTYPE_QNULL < obj->type && obj->type < QTYPE__MAX);
     qdestroy[obj->type](obj);
 }
+
+char *qobject_to_string_indent(QObject *obj, int indent)
+{
+    switch (qobject_type(obj)) {
+    case QTYPE_QNUM:
+        return qnum_to_string(qobject_to_qnum(obj));
+    case QTYPE_QSTRING:
+        return g_strdup(qstring_get_str(qobject_to_qstring(obj)));
+    case QTYPE_QDICT:
+        return qdict_to_string(qobject_to_qdict(obj), indent);
+    case QTYPE_QLIST:
+        return qlist_to_string(qobject_to_qlist(obj), indent);
+    case QTYPE_QBOOL:
+        return g_strdup(qbool_get_bool(qobject_to_qbool(obj)) ?
+                        "true" : "false");
+    default:
+        abort();
+    }
+}
diff --git a/tests/check-qjson.c b/tests/check-qjson.c
index 6fb14445a3..d12daf39e9 100644
--- a/tests/check-qjson.c
+++ b/tests/check-qjson.c
@@ -1365,6 +1365,23 @@ static void simple_whitespace(void)
     }
 }
 
+static void qobject_to_string_test(void)
+{
+    QObject *obj;
+    char *tmp;
+
+    obj = qobject_from_json("[ 43, { 'c': { 'd' : 12 } }, [ 1, 2 ], 42 ]",
+                            &error_abort);
+    tmp = qobject_to_string(obj);
+    g_assert_cmpstr(tmp, ==,
+                    "[0]: 43\n"
+                    "[1]:\n    c:\n        d: 12\n"
+                    "[2]:\n    [0]: 1\n    [1]: 2\n"
+                    "[3]: 42\n");
+    g_free(tmp);
+    qobject_decref(obj);
+}
+
 static void simple_varargs(void)
 {
     QObject *embedded_obj;
@@ -1538,5 +1555,7 @@ int main(int argc, char **argv)
     g_test_add_func("/errors/unterminated/literal", unterminated_literal);
     g_test_add_func("/errors/limits/nesting", limits_nesting);
 
+    g_test_add_func("/qobject/to_string", qobject_to_string_test);
+
     return g_test_run();
 }
-- 
2.13.0.91.g00982b8dd

^ permalink raw reply related	[flat|nested] 80+ messages in thread

* Re: [Qemu-devel] [PATCH v2 00/45] qobject/qapi: add uint type
  2017-05-31 13:56 [Qemu-devel] [PATCH v2 00/45] qobject/qapi: add uint type Marc-André Lureau
                   ` (44 preceding siblings ...)
  2017-05-31 13:57 ` [Qemu-devel] [PATCH v2 45/45] qobject: move dump_qobject() from block/ to qobject/ Marc-André Lureau
@ 2017-05-31 20:06 ` no-reply
  2017-06-06 12:36 ` Markus Armbruster
  46 siblings, 0 replies; 80+ messages in thread
From: no-reply @ 2017-05-31 20:06 UTC (permalink / raw)
  To: marcandre.lureau; +Cc: famz, qemu-devel, armbru

Hi,

This series seems to have some coding style problems. See output below for
more information:

Message-id: 20170531135709.345-1-marcandre.lureau@redhat.com
Type: series
Subject: [Qemu-devel] [PATCH v2 00/45] qobject/qapi: add uint type

=== TEST SCRIPT BEGIN ===
#!/bin/bash

BASE=base
n=1
total=$(git log --oneline $BASE.. | wc -l)
failed=0

git config --local diff.renamelimit 0
git config --local diff.renames True

commits="$(git log --format=%H --reverse $BASE..)"
for c in $commits; do
    echo "Checking PATCH $n/$total: $(git log -n 1 --format=%s $c)..."
    if ! git show $c --format=email | ./scripts/checkpatch.pl --mailback -; then
        failed=1
        echo
    fi
    n=$((n+1))
done

exit $failed
=== TEST SCRIPT END ===

Updating 3c8cf5a9c21ff8782164d1def7f44bd888713384
From https://github.com/patchew-project/qemu
 - [tag update]      patchew/1496152683-102751-1-git-send-email-anton.nefedov@virtuozzo.com -> patchew/1496152683-102751-1-git-send-email-anton.nefedov@virtuozzo.com
 * [new tag]         patchew/20170531192836.7187-1-jsnow@redhat.com -> patchew/20170531192836.7187-1-jsnow@redhat.com
 * [new tag]         patchew/20170531193434.6918-1-david@redhat.com -> patchew/20170531193434.6918-1-david@redhat.com
Switched to a new branch 'test'
44ac08a qobject: move dump_qobject() from block/ to qobject/
4f36884 RFC: qdict: add uint
ef45589 tests/qdict: check more get_try_int() cases
a9c6698 console: use get_uint() for "head" property
d4c67e9 i386/cpu: use get_uint() for "min-level"/"min-xlevel" properties
10de204 numa: use get_uint() for "size" property
7f367eb pnv-core: use get_uint() for "core-pir" property
6279c33 pvpanic: use get_uint() for "ioport" property
6f0b197 auxbus: use get_uint() for "addr" property
3268fdb arm: use get_uint() for "mp-affinity" property
508afeb xen: use get_uint() for "max-ram-below-4g" property
b3a2677 pc: use get_uint() for "hpet-intcap" property
53fff2c pc: use get_uint() for "apic-id" property
86f858d pc: use get_uint() for "iobase" property
7281251 acpi: use get_uint() for "pci-hole*" properties
cdae6bd acpi: use get_uint() for various acpi properties
2c1168c acpi: use get_uint() for "acpi-pcihp-io*" properties
db85018 platform-bus: use get_uint() for "addr" property
83701a9 bcm2835_fb: use {get, set}_uint() for "vcram-size" and "vcram-base"
3636325 aspeed: use {set, get}_uint() for "ram-size" property
d45270e pcihp: use get_uint() for "bsel" property
a9e4942 pc-dimm: make "size" property uint64
72501db pc-dimm: use get_uint() for dimm properties
7bcc518 isa: use get_uint() for "io-base"
617b690 qdev: use appropriate getter/setters type
67ef86a apic-common: make "id" property a uint32
46b7af7 qdev: add unsigned properties
f5b425c qdev: make default property int
6ef348c object: use more specific property type names
f505764 q35: fix get_mmcfg_size to use uint64 visitor
cae2768 object: add uint property setter/getter
6981ce5 qapi: update the qobject visitor to use QNUM_U64
ee2fc88 json: learn to parse uint64 numbers
08280db qnum: add uint type
9d558cd tests: remove /qnum/destroy test
cbdb7b5 qapi: Remove visit_start_alternate() parameter promote_int
eaa6ee5 qapi: merge QInt and QFloat in QNum
8f5c108 tests: add more int/number ranges checks
29d8de7 tests: remove alt num-int cases
b2ad700 object: fix potential leak in getters
94718f3 qdev: remove PropertyInfo.qtype field
edf34ae qapi: Reject alternates that can't work with keyval_parse()
bc54967 tests/qapi-schema: Avoid 'str' in alternate test cases
1ac82cc qapi: Document visit_type_any() issues with keyval input
b117faf qobject-input-visitor: Reject non-finite numbers with keyval

=== OUTPUT BEGIN ===
Checking PATCH 1/45: qobject-input-visitor: Reject non-finite numbers with keyval...
Checking PATCH 2/45: qapi: Document visit_type_any() issues with keyval input...
Checking PATCH 3/45: tests/qapi-schema: Avoid 'str' in alternate test cases...
Checking PATCH 4/45: qapi: Reject alternates that can't work with keyval_parse()...
Checking PATCH 5/45: qdev: remove PropertyInfo.qtype field...
Checking PATCH 6/45: object: fix potential leak in getters...
Checking PATCH 7/45: tests: remove alt num-int cases...
Checking PATCH 8/45: tests: add more int/number ranges checks...
Checking PATCH 9/45: qapi: merge QInt and QFloat in QNum...
ERROR: do not use C99 // comments
#2002: FILE: tests/check-qnum.c:35:
+    // destroy doesn't exit yet

ERROR: do not use C99 // comments
#2017: FILE: tests/check-qnum.c:50:
+    // destroy doesn't exit yet

total: 2 errors, 0 warnings, 1918 lines checked

Your patch has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.

Checking PATCH 10/45: qapi: Remove visit_start_alternate() parameter promote_int...
Checking PATCH 11/45: tests: remove /qnum/destroy test...
Checking PATCH 12/45: qnum: add uint type...
Checking PATCH 13/45: json: learn to parse uint64 numbers...
Checking PATCH 14/45: qapi: update the qobject visitor to use QNUM_U64...
Checking PATCH 15/45: object: add uint property setter/getter...
Checking PATCH 16/45: q35: fix get_mmcfg_size to use uint64 visitor...
Checking PATCH 17/45: object: use more specific property type names...
Checking PATCH 18/45: qdev: make default property int...
Checking PATCH 19/45: qdev: add unsigned properties...
Checking PATCH 20/45: apic-common: make "id" property a uint32...
Checking PATCH 21/45: qdev: use appropriate getter/setters type...
Checking PATCH 22/45: isa: use get_uint() for "io-base"...
Checking PATCH 23/45: pc-dimm: use get_uint() for dimm properties...
Checking PATCH 24/45: pc-dimm: make "size" property uint64...
Checking PATCH 25/45: pcihp: use get_uint() for "bsel" property...
Checking PATCH 26/45: aspeed: use {set, get}_uint() for "ram-size" property...
Checking PATCH 27/45: bcm2835_fb: use {get, set}_uint() for "vcram-size" and "vcram-base"...
Checking PATCH 28/45: platform-bus: use get_uint() for "addr" property...
Checking PATCH 29/45: acpi: use get_uint() for "acpi-pcihp-io*" properties...
Checking PATCH 30/45: acpi: use get_uint() for various acpi properties...
Checking PATCH 31/45: acpi: use get_uint() for "pci-hole*" properties...
Checking PATCH 32/45: pc: use get_uint() for "iobase" property...
Checking PATCH 33/45: pc: use get_uint() for "apic-id" property...
Checking PATCH 34/45: pc: use get_uint() for "hpet-intcap" property...
Checking PATCH 35/45: xen: use get_uint() for "max-ram-below-4g" property...
Checking PATCH 36/45: arm: use get_uint() for "mp-affinity" property...
Checking PATCH 37/45: auxbus: use get_uint() for "addr" property...
Checking PATCH 38/45: pvpanic: use get_uint() for "ioport" property...
Checking PATCH 39/45: pnv-core: use get_uint() for "core-pir" property...
Checking PATCH 40/45: numa: use get_uint() for "size" property...
Checking PATCH 41/45: i386/cpu: use get_uint() for "min-level"/"min-xlevel" properties...
Checking PATCH 42/45: console: use get_uint() for "head" property...
Checking PATCH 43/45: tests/qdict: check more get_try_int() cases...
Checking PATCH 44/45: RFC: qdict: add uint...
Checking PATCH 45/45: qobject: move dump_qobject() from block/ to qobject/...
=== OUTPUT END ===

Test command exited with code: 1


---
Email generated automatically by Patchew [http://patchew.org/].
Please send your feedback to patchew-devel@freelists.org

^ permalink raw reply	[flat|nested] 80+ messages in thread

* Re: [Qemu-devel] [PATCH v2 05/45] qdev: remove PropertyInfo.qtype field
  2017-05-31 13:56 ` [Qemu-devel] [PATCH v2 05/45] qdev: remove PropertyInfo.qtype field Marc-André Lureau
@ 2017-06-01 11:19   ` Markus Armbruster
  2017-06-07 12:31     ` Peter Maydell
  0 siblings, 1 reply; 80+ messages in thread
From: Markus Armbruster @ 2017-06-01 11:19 UTC (permalink / raw)
  To: Marc-André Lureau; +Cc: qemu-devel

Marc-André Lureau <marcandre.lureau@redhat.com> writes:

> Remove dependency on qapi qtype, replace a field by a few PropertyInfo
> callbacks to set the default value type (introduced in commit 4f2d3d7).
>
> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
> ---
>  include/hw/qdev-core.h       |  2 +-
>  include/hw/qdev-properties.h |  5 -----
>  hw/core/qdev-properties.c    | 35 ++++++++++++++++++++++++++++++++++-
>  hw/core/qdev.c               | 13 ++-----------
>  4 files changed, 37 insertions(+), 18 deletions(-)
>
> diff --git a/include/hw/qdev-core.h b/include/hw/qdev-core.h
> index e69489ec6c..9523339762 100644
> --- a/include/hw/qdev-core.h
> +++ b/include/hw/qdev-core.h
> @@ -226,7 +226,6 @@ struct Property {
>      PropertyInfo *info;
>      ptrdiff_t    offset;
>      uint8_t      bitnr;
> -    QType        qtype;
>      int64_t      defval;
>      int          arrayoffset;
>      PropertyInfo *arrayinfo;
> @@ -238,6 +237,7 @@ struct PropertyInfo {
>      const char *description;
>      const char * const *enum_table;
>      int (*print)(DeviceState *dev, Property *prop, char *dest, size_t len);
> +    void (*set_default_value)(Object *obj, const Property *prop);
>      ObjectPropertyAccessor *get;
>      ObjectPropertyAccessor *set;
>      ObjectPropertyRelease *release;
> diff --git a/include/hw/qdev-properties.h b/include/hw/qdev-properties.h
> index d206fc93dd..85e68998a9 100644
> --- a/include/hw/qdev-properties.h
> +++ b/include/hw/qdev-properties.h
> @@ -42,7 +42,6 @@ extern PropertyInfo qdev_prop_arraylen;
>          .info      = &(_prop),                                          \
>          .offset    = offsetof(_state, _field)                           \
>              + type_check(_type,typeof_field(_state, _field)),           \
> -        .qtype     = QTYPE_QINT,                                        \
>          .defval    = (_type)_defval,                                    \
>          }
>  #define DEFINE_PROP_BIT(_name, _state, _field, _bit, _defval) {  \
> @@ -51,7 +50,6 @@ extern PropertyInfo qdev_prop_arraylen;
>          .bitnr    = (_bit),                                      \
>          .offset    = offsetof(_state, _field)                    \
>              + type_check(uint32_t,typeof_field(_state, _field)), \
> -        .qtype     = QTYPE_QBOOL,                                \
>          .defval    = (bool)_defval,                              \
>          }
>  #define DEFINE_PROP_BIT64(_name, _state, _field, _bit, _defval) {       \
> @@ -60,7 +58,6 @@ extern PropertyInfo qdev_prop_arraylen;
>          .bitnr    = (_bit),                                             \
>          .offset    = offsetof(_state, _field)                           \
>              + type_check(uint64_t, typeof_field(_state, _field)),       \
> -        .qtype     = QTYPE_QBOOL,                                       \
>          .defval    = (bool)_defval,                                     \
>          }
>  
> @@ -69,7 +66,6 @@ extern PropertyInfo qdev_prop_arraylen;
>          .info      = &(qdev_prop_bool),                          \
>          .offset    = offsetof(_state, _field)                    \
>              + type_check(bool, typeof_field(_state, _field)),    \
> -        .qtype     = QTYPE_QBOOL,                                \
>          .defval    = (bool)_defval,                              \
>          }
>  
> @@ -105,7 +101,6 @@ extern PropertyInfo qdev_prop_arraylen;
>          .info = &(qdev_prop_arraylen),                                  \
>          .offset = offsetof(_state, _field)                              \
>              + type_check(uint32_t, typeof_field(_state, _field)),       \
> -        .qtype = QTYPE_QINT,                                            \
>          .arrayinfo = &(_arrayprop),                                     \
>          .arrayfieldsize = sizeof(_arraytype),                           \
>          .arrayoffset = offsetof(_state, _arrayfield),                   \
> diff --git a/hw/core/qdev-properties.c b/hw/core/qdev-properties.c
> index fa3617db2d..482efb2683 100644
> --- a/hw/core/qdev-properties.c
> +++ b/hw/core/qdev-properties.c
> @@ -69,6 +69,12 @@ static void set_enum(Object *obj, Visitor *v, const char *name, void *opaque,
>      visit_type_enum(v, prop->name, ptr, prop->info->enum_table, errp);
>  }
>  
> +static void set_default_value_enum(Object *obj, const Property *prop)
> +{
> +    object_property_set_str(obj, prop->info->enum_table[prop->defval],
> +                            prop->name, &error_abort);
> +}
> +
>  /* Bit */
>  
>  static uint32_t qdev_get_prop_mask(Property *prop)
> @@ -120,11 +126,17 @@ static void prop_set_bit(Object *obj, Visitor *v, const char *name,
>      bit_prop_set(dev, prop, value);
>  }
>  
> +static void set_default_value_bool(Object *obj, const Property *prop)
> +{
> +    object_property_set_bool(obj, prop->defval, prop->name, &error_abort);
> +}
> +
>  PropertyInfo qdev_prop_bit = {
>      .name  = "bool",
>      .description = "on/off",
>      .get   = prop_get_bit,
>      .set   = prop_set_bit,
> +    .set_default_value = set_default_value_bool,
>  };
>  
>  /* Bit64 */
> @@ -183,6 +195,7 @@ PropertyInfo qdev_prop_bit64 = {
>      .description = "on/off",
>      .get   = prop_get_bit64,
>      .set   = prop_set_bit64,
> +    .set_default_value = set_default_value_bool,
>  };
>  
>  /* --- bool --- */
> @@ -216,6 +229,7 @@ PropertyInfo qdev_prop_bool = {
>      .name  = "bool",
>      .get   = get_bool,
>      .set   = set_bool,
> +    .set_default_value = set_default_value_bool,
>  };
>  
>  /* --- 8bit integer --- */
> @@ -245,10 +259,16 @@ static void set_uint8(Object *obj, Visitor *v, const char *name, void *opaque,
>      visit_type_uint8(v, name, ptr, errp);
>  }
>  
> +static void set_default_value_int(Object *obj, const Property *prop)
> +{
> +    object_property_set_int(obj, prop->defval, prop->name, &error_abort);
> +}
> +
>  PropertyInfo qdev_prop_uint8 = {
>      .name  = "uint8",
>      .get   = get_uint8,
>      .set   = set_uint8,
> +    .set_default_value = set_default_value_int,
>  };
>  
>  /* --- 16bit integer --- */
> @@ -282,6 +302,7 @@ PropertyInfo qdev_prop_uint16 = {
>      .name  = "uint16",
>      .get   = get_uint16,
>      .set   = set_uint16,
> +    .set_default_value = set_default_value_int,
>  };
>  
>  /* --- 32bit integer --- */
> @@ -340,12 +361,14 @@ PropertyInfo qdev_prop_uint32 = {
>      .name  = "uint32",
>      .get   = get_uint32,
>      .set   = set_uint32,
> +    .set_default_value = set_default_value_int,
>  };
>  
>  PropertyInfo qdev_prop_int32 = {
>      .name  = "int32",
>      .get   = get_int32,
>      .set   = set_int32,
> +    .set_default_value = set_default_value_int,
>  };
>  
>  /* --- 64bit integer --- */
> @@ -379,6 +402,7 @@ PropertyInfo qdev_prop_uint64 = {
>      .name  = "uint64",
>      .get   = get_uint64,
>      .set   = set_uint64,
> +    .set_default_value = set_default_value_int,
>  };
>  
>  /* --- string --- */
> @@ -526,6 +550,7 @@ PropertyInfo qdev_prop_on_off_auto = {
>      .enum_table = OnOffAuto_lookup,
>      .get = get_enum,
>      .set = set_enum,
> +    .set_default_value = set_default_value_enum,
>  };
>  
>  /* --- lost tick policy --- */
> @@ -537,6 +562,7 @@ PropertyInfo qdev_prop_losttickpolicy = {
>      .enum_table  = LostTickPolicy_lookup,
>      .get   = get_enum,
>      .set   = set_enum,
> +    .set_default_value = set_default_value_enum,
>  };
>  
>  /* --- Block device error handling policy --- */
> @@ -550,6 +576,7 @@ PropertyInfo qdev_prop_blockdev_on_error = {
>      .enum_table = BlockdevOnError_lookup,
>      .get = get_enum,
>      .set = set_enum,
> +    .set_default_value = set_default_value_enum,
>  };
>  
>  /* --- BIOS CHS translation */
> @@ -563,6 +590,7 @@ PropertyInfo qdev_prop_bios_chs_trans = {
>      .enum_table = BiosAtaTranslation_lookup,
>      .get = get_enum,
>      .set = set_enum,
> +    .set_default_value = set_default_value_enum,
>  };
>  
>  /* --- FDC default drive types */
> @@ -573,7 +601,8 @@ PropertyInfo qdev_prop_fdc_drive_type = {
>                     "144/288/120/none/auto",
>      .enum_table = FloppyDriveType_lookup,
>      .get = get_enum,
> -    .set = set_enum
> +    .set = set_enum,
> +    .set_default_value = set_default_value_enum,
>  };
>  
>  /* --- pci address --- */
> @@ -648,6 +677,7 @@ PropertyInfo qdev_prop_pci_devfn = {
>      .print = print_pci_devfn,
>      .get   = get_int32,
>      .set   = set_pci_devfn,
> +    .set_default_value = set_default_value_int,
>  };
>  
>  /* --- blocksize --- */
> @@ -695,6 +725,7 @@ PropertyInfo qdev_prop_blocksize = {
>      .description = "A power of two between 512 and 32768",
>      .get   = get_uint16,
>      .set   = set_blocksize,
> +    .set_default_value = set_default_value_int,
>  };
>  
>  /* --- pci host address --- */
> @@ -917,6 +948,7 @@ PropertyInfo qdev_prop_arraylen = {
>      .name = "uint32",
>      .get = get_uint32,
>      .set = set_prop_arraylen,
> +    .set_default_value = set_default_value_int,
>  };
>  
>  /* --- public helpers --- */
> @@ -1153,4 +1185,5 @@ PropertyInfo qdev_prop_size = {
>      .name  = "size",
>      .get = get_size,
>      .set = set_size,
> +    .set_default_value = set_default_value_int,
>  };
> diff --git a/hw/core/qdev.c b/hw/core/qdev.c
> index 71ff95fd71..6674e11840 100644
> --- a/hw/core/qdev.c
> +++ b/hw/core/qdev.c
> @@ -794,17 +794,8 @@ void qdev_property_add_static(DeviceState *dev, Property *prop,
>                                      prop->info->description,
>                                      &error_abort);
>  
> -    if (prop->qtype == QTYPE_NONE) {
> -        return;
> -    }
> -
> -    if (prop->qtype == QTYPE_QBOOL) {
> -        object_property_set_bool(obj, prop->defval, prop->name, &error_abort);
> -    } else if (prop->info->enum_table) {
> -        object_property_set_str(obj, prop->info->enum_table[prop->defval],
> -                                prop->name, &error_abort);
> -    } else if (prop->qtype == QTYPE_QINT) {
> -        object_property_set_int(obj, prop->defval, prop->name, &error_abort);
> +    if (prop->info->set_default_value) {
> +        prop->info->set_default_value(obj, prop);
>      }
>  }

Lovely cleanup.

The interesting part is the move of the bits controlling use of ->defval
from Property member .qtype (set only by DEFINE_PROP_foo() macros) to
its PropertyInfo method .info->set_default_value().  No functional
change if (1) we preserve existing use of ->defval and (2) we don't add
new uses of ->defval, or at least not uses that matter.

Direction (1) is obvious for DEFINE_PROP_BIT(), DEFINE_PROP_BIT64(),
DEFINE_PROP_BOOL().  They set .info to &qdev_prop_bit, &qdev_prop_bit64,
&qdev_prop_bool, respectively.  These all get .set_default_value =
set_default_value_bool, which preserves the effect of .qtype =
QTYPE_BOOL.  Good.

DEFINE_PROP_DEFAULT() sets .info to point to its argument _prop.  The
following arguments occur:

* In include/hw/qdev-properties.h: qdev_prop_uint8, qdev_prop_uint16,
  qdev_prop_uint32, qdev_prop_int32, qdev_prop_uint64, qdev_prop_size,
  qdev_prop_pci_devfn, qdev_prop_on_off_auto, qdev_prop_losttickpolicy,
  qdev_prop_blockdev_on_error, qdev_prop_bios_chs_trans,
  qdev_prop_blocksize

* In hw/block/fdc.c: qdev_prop_fdc_drive_type

* In hw/net/e1000e.c: local copies of qdev_prop_uint8, qdev_prop_uint16.

To preserve the effect of .qtype = QTYPE_QINT, these PropertyInfo need
.set_default_value = set_default_value_int or .set_default_value =
set_default_value_enum, depending on .enum_table.  They get it.  Good.

DEFINE_PROP_ARRAY() sets .info to &qdev_prop_arraylen.  Needs and gets
.set_default_value = set_default_value_int.  Good.

DEFINE_PROP_ARRAY() also takes a PropertyInfo argument, but it's not
relevant here, as the .qtype you remove doesn't apply to it.  I'm
mentioning this, because it confused me briefly.

Direction (2) isn't as visible in the patch.  For each PropertyInfo you
change, we need to find and check stores into .info not wrapped in the
DEFINE_PROP_foo() macros you change.

I can't find any.  Good.

Reviewed-by: Markus Armbruster <armbru@redhat.com>

^ permalink raw reply	[flat|nested] 80+ messages in thread

* Re: [Qemu-devel] [PATCH v2 06/45] object: fix potential leak in getters
  2017-05-31 13:56 ` [Qemu-devel] [PATCH v2 06/45] object: fix potential leak in getters Marc-André Lureau
@ 2017-06-01 11:32   ` Markus Armbruster
  0 siblings, 0 replies; 80+ messages in thread
From: Markus Armbruster @ 2017-06-01 11:32 UTC (permalink / raw)
  To: Marc-André Lureau; +Cc: qemu-devel

Marc-André Lureau <marcandre.lureau@redhat.com> writes:

> If the property is not of the requested type, the getters will leak a
> QObject.
>
> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>

Missing
Reviewed-by: Eric Blake <eblake@redhat.com>

> ---
>  qom/object.c | 6 +++---
>  1 file changed, 3 insertions(+), 3 deletions(-)
>
> diff --git a/qom/object.c b/qom/object.c
> index eb4bc924ff..c7b8079df6 100644
> --- a/qom/object.c
> +++ b/qom/object.c
> @@ -1122,7 +1122,7 @@ char *object_property_get_str(Object *obj, const char *name,
>          retval = g_strdup(qstring_get_str(qstring));
>      }
>  
> -    QDECREF(qstring);
> +    qobject_decref(ret);
>      return retval;
>  }
>  
> @@ -1183,7 +1183,7 @@ bool object_property_get_bool(Object *obj, const char *name,
>          retval = qbool_get_bool(qbool);
>      }
>  
> -    QDECREF(qbool);
> +    qobject_decref(ret);
>      return retval;
>  }
>  
> @@ -1214,7 +1214,7 @@ int64_t object_property_get_int(Object *obj, const char *name,
>          retval = qint_get_int(qint);
>      }
>  
> -    QDECREF(qint);
> +    qobject_decref(ret);
>      return retval;
>  }

Reviewed-by: Markus Armbruster <armbru@redhat.com>

^ permalink raw reply	[flat|nested] 80+ messages in thread

* Re: [Qemu-devel] [PATCH v2 07/45] tests: remove alt num-int cases
  2017-05-31 13:56 ` [Qemu-devel] [PATCH v2 07/45] tests: remove alt num-int cases Marc-André Lureau
@ 2017-06-01 11:58   ` Markus Armbruster
  0 siblings, 0 replies; 80+ messages in thread
From: Markus Armbruster @ 2017-06-01 11:58 UTC (permalink / raw)
  To: Marc-André Lureau; +Cc: qemu-devel

Marc-André Lureau <marcandre.lureau@redhat.com> writes:

> From: Markus Armbruster <armbru@redhat.com>
>
> Marc-André Lureau <marcandre.lureau@redhat.com> writes:
>
>> There are no real users of this case, and it's going to be invalid after
>> merging of QFloat and QInt use the same QNum type in the following patch.
>
> Invalid because our alternate code is insufficiently sophisticated.  In
> other words fixable.  See "[PATCH 4/4] qapi: Reject alternates that
> can't work with keyval_parse()" I just posted.
>
> My patch's commit message describes two related issues, one fixable and
> one unfixable.  The fixable one already exists, but only in QGA.  I
> intend to fix it, but it's not a priority.
>
> Fixing the issue you describe seems even less important.  I considered
> outlawing it in my series (patch appended for your reading pleasure),
> but decided to leave it to yours.  I don't expect you to replace your
> patch.  Perhaps my patch helps you with rebasing yours should that
> become necessary.
>
> Message-Id: <87tw4cn7sh.fsf@dusky.pond.sub.org>

Uh, this got a bit messed up :)

Your original patch only dropped test cases that will become invalid.

In my review, I elaborated a bit on "invalid", and mentioned that I had
considered outlawing such alternates independently of this series, but
refrained.  I appended a patch for reference, and in the hope that it
helps you rebasing your patch.

It looks like you replaced your patch by mine, and the commit message by
my review.  The resulting patch does more than just "tests: remove alt
num-int cases".  It also lacks your S-o-b.

I recommend to drop the change to qapi.py, and restore your original
commit message.  Should effectively be a rebase of your v1.

I further suggest a bit more detail in the commit message, perhaps like
this:

    tests: Remove test cases for alternates of 'number' and 'int'

    Alternates with both a 'number' and an 'int' branch will become
    invalid when the next patch merges of QFloat and QInt into QNum.
    More sophisticated alternate code could keep them valid, but since
    we have no users outside tests, simply drop the tests.

    Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>

You can then add
Reviewed-by: Markus Armbruster <armbru@redhat.com>

^ permalink raw reply	[flat|nested] 80+ messages in thread

* Re: [Qemu-devel] [PATCH v2 08/45] tests: add more int/number ranges checks
  2017-05-31 13:56 ` [Qemu-devel] [PATCH v2 08/45] tests: add more int/number ranges checks Marc-André Lureau
@ 2017-06-01 14:09   ` Markus Armbruster
  2017-06-06 16:14     ` Marc-André Lureau
  0 siblings, 1 reply; 80+ messages in thread
From: Markus Armbruster @ 2017-06-01 14:09 UTC (permalink / raw)
  To: Marc-André Lureau; +Cc: qemu-devel

Marc-André Lureau <marcandre.lureau@redhat.com> writes:

> Suggested by Markus Armbruster:
>
> We should systematically cover the integers, in particular the
> boundaries (because that's where bugs like to hide):
>
> * Integers in [-2^63,0) can be visited with visit_type_int() and
>   visit_type_number().
>
> * Integers in [0,2^63) can be visited with visit_type_int(),
>   visit_type_uint64() and visit_type_number().
>
> * Integers in [2^63,2^64) can be visited with visit_type_uint64() and
>   visit_type_number().
>
> * Integers outside [-2^63,2^53) can be visited with visit_type_number().
>
> In any case, visit_type_number() loses precision beyond 53 bits.
>
> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
> ---
>  tests/test-qobject-input-visitor.c | 38 ++++++++++++++++++++++++++++++++++++--
>  1 file changed, 36 insertions(+), 2 deletions(-)
>
> diff --git a/tests/test-qobject-input-visitor.c b/tests/test-qobject-input-visitor.c
> index 83d663d11d..f2ed3161af 100644
> --- a/tests/test-qobject-input-visitor.c
> +++ b/tests/test-qobject-input-visitor.c
> @@ -102,11 +102,11 @@ static Visitor *visitor_input_test_init_raw(TestInputVisitorData *data,
>  {
>      return visitor_input_test_init_internal(data, false, json_string, NULL);
>  }
> -

Whoops.

>  static void test_visitor_in_int(TestInputVisitorData *data,
>                                  const void *unused)
>  {
>      int64_t res = 0;
> +    double dbl;
>      int value = -42;
>      Visitor *v;
>  
> @@ -114,6 +114,9 @@ static void test_visitor_in_int(TestInputVisitorData *data,
>  
>      visit_type_int(v, NULL, &res, &error_abort);
>      g_assert_cmpint(res, ==, value);
> +
> +    visit_type_number(v, NULL, &dbl, &error_abort);
> +    g_assert_cmpfloat(dbl, ==, -42.0);
>  }
>  
>  static void test_visitor_in_uint(TestInputVisitorData *data,
> @@ -121,6 +124,8 @@ static void test_visitor_in_uint(TestInputVisitorData *data,
>  {
>      Error *err = NULL;
>      uint64_t res = 0;
> +    int64_t i64;
> +    double dbl;
>      int value = 42;
>      Visitor *v;
>  
> @@ -129,8 +134,13 @@ static void test_visitor_in_uint(TestInputVisitorData *data,
>      visit_type_uint64(v, NULL, &res, &error_abort);
>      g_assert_cmpuint(res, ==, (uint64_t)value);
>  
> -    /* BUG: value between INT64_MIN and -1 accepted modulo 2^64 */
> +    visit_type_int(v, NULL, &i64, &error_abort);
> +    g_assert_cmpint(i64, ==, value);
>  
> +    visit_type_number(v, NULL, &dbl, &error_abort);
> +    g_assert_cmpfloat(dbl, ==, value);
> +
> +    /* BUG: value between INT64_MIN and -1 accepted modulo 2^64 */
>      v = visitor_input_test_init(data, "%d", -value);
>  
>      visit_type_uint64(v, NULL, &res, &error_abort);
> @@ -142,6 +152,8 @@ static void test_visitor_in_uint(TestInputVisitorData *data,
>  
>      visit_type_uint64(v, NULL, &res, &err);
>      error_free_or_abort(&err);
> +
> +    visit_type_number(v, NULL, &dbl, &error_abort);
>  }
>  
>  static void test_visitor_in_int_overflow(TestInputVisitorData *data,
> @@ -260,6 +272,26 @@ static void test_visitor_in_number(TestInputVisitorData *data,
>      g_assert_cmpfloat(res, ==, value);
>  }
>  
> +static void test_visitor_in_large_number(TestInputVisitorData *data,
> +                                         const void *unused)
> +{
> +    Error *err = NULL;
> +    double res = 0;
> +    int64_t i64;
> +    uint64_t u64;
> +    Visitor *v;
> +
> +    v = visitor_input_test_init(data, "-18446744073709551616"); /* -2^64 */
> +
> +    visit_type_number(v, NULL, &res, &error_abort);

Shouldn't we check res has the expected value?

> +
> +    visit_type_int(v, NULL, &i64, &err);
> +    error_free_or_abort(&err);
> +
> +    visit_type_uint64(v, NULL, &u64, &err);
> +    error_free_or_abort(&err);
> +}

Not sure this is worth its own test.  But then I'm never sure whether to
write heaps of small tests, or few larger ones.  You decide.

> +
>  static void test_visitor_in_number_keyval(TestInputVisitorData *data,
>                                            const void *unused)
>  {
> @@ -1253,6 +1285,8 @@ int main(int argc, char **argv)
>                             NULL, test_visitor_in_bool_str_fail);
>      input_visitor_test_add("/visitor/input/number",
>                             NULL, test_visitor_in_number);
> +    input_visitor_test_add("/visitor/input/large_number",
> +                           NULL, test_visitor_in_large_number);
>      input_visitor_test_add("/visitor/input/number_keyval",
>                             NULL, test_visitor_in_number_keyval);
>      input_visitor_test_add("/visitor/input/number_str_keyval",

The new tests are welcome, but they don't "systematically cover the
integers".  The easiest fix is to adjust the commit message's claims
down:

    tests: Add more int/number ranges checks

    Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>

^ permalink raw reply	[flat|nested] 80+ messages in thread

* Re: [Qemu-devel] [PATCH v2 09/45] qapi: merge QInt and QFloat in QNum
  2017-05-31 13:56 ` [Qemu-devel] [PATCH v2 09/45] qapi: merge QInt and QFloat in QNum Marc-André Lureau
@ 2017-06-02  7:03   ` Markus Armbruster
  0 siblings, 0 replies; 80+ messages in thread
From: Markus Armbruster @ 2017-06-02  7:03 UTC (permalink / raw)
  To: Marc-André Lureau; +Cc: qemu-devel

Marc-André Lureau <marcandre.lureau@redhat.com> writes:

> We would like to use a same QObject type to represent numbers, whether
> they are int, uint, or floats. Getters will allow some compatibility
> between the various types if the number fits other representations.
>
> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
> ---
>  scripts/qapi.py                          |  40 ++++-----
>  scripts/qapi-visit.py                    |   2 +-
>  include/qapi/qmp/qdict.h                 |   3 +-
>  include/qapi/qmp/qfloat.h                |  29 -------
>  include/qapi/qmp/qint.h                  |  28 ------
>  include/qapi/qmp/qlist.h                 |   3 +-
>  include/qapi/qmp/qnum.h                  |  44 ++++++++++
>  include/qapi/qmp/types.h                 |   3 +-
>  include/qapi/qobject-input-visitor.h     |   6 +-
>  include/qapi/qobject-output-visitor.h    |   8 +-
>  block/blkdebug.c                         |   1 -
>  block/nbd.c                              |   1 -
>  block/nfs.c                              |   1 -
>  block/qapi.c                             |  13 ++-
>  block/quorum.c                           |   1 -
>  block/sheepdog.c                         |   1 -
>  block/ssh.c                              |   1 -
>  block/vvfat.c                            |   1 -
>  blockdev.c                               |   8 +-
>  hw/acpi/pcihp.c                          |   1 -
>  hw/i386/acpi-build.c                     |  41 +++++++--
>  hw/usb/xen-usb.c                         |   1 -
>  monitor.c                                |   2 +-
>  qapi/qobject-input-visitor.c             |  41 +++------
>  qapi/qobject-output-visitor.c            |   6 +-
>  qga/commands.c                           |   2 +-
>  qga/main.c                               |   1 -
>  qobject/json-parser.c                    |  29 +++----
>  qobject/qdict.c                          |  43 +++++-----
>  qobject/qfloat.c                         |  62 --------------
>  qobject/qint.c                           |  61 -------------
>  qobject/qjson.c                          |  37 +-------
>  qobject/qnum.c                           | 141 +++++++++++++++++++++++++++++++
>  qobject/qobject.c                        |   3 +-
>  qom/object.c                             |  16 ++--
>  target/i386/cpu.c                        |   6 +-
>  tests/check-qdict.c                      |  30 ++++---
>  tests/check-qfloat.c                     |  53 ------------
>  tests/check-qint.c                       |  87 -------------------
>  tests/check-qjson.c                      |  91 +++++++++++---------
>  tests/check-qlist.c                      |  18 ++--
>  tests/check-qnum.c                       | 133 +++++++++++++++++++++++++++++
>  tests/test-qmp-commands.c                |   8 +-
>  tests/test-qmp-event.c                   |   9 +-
>  tests/test-qobject-input-visitor.c       |  33 ++++----
>  tests/test-qobject-output-visitor.c      |  66 +++++++++------
>  tests/test-x86-cpuid-compat.c            |  20 +++--
>  ui/spice-core.c                          |   1 -
>  ui/vnc-enc-tight.c                       |   1 -
>  util/qemu-option.c                       |  20 ++---
>  MAINTAINERS                              |   3 +-
>  qobject/Makefile.objs                    |   2 +-
>  scripts/coccinelle/qobject.cocci         |   4 +-
>  tests/.gitignore                         |   3 +-
>  tests/Makefile.include                   |  13 ++-
>  tests/qapi-schema/comments.out           |   2 +-
>  tests/qapi-schema/doc-good.out           |   2 +-
>  tests/qapi-schema/empty.out              |   2 +-
>  tests/qapi-schema/event-case.out         |   2 +-
>  tests/qapi-schema/ident-with-escape.out  |   2 +-
>  tests/qapi-schema/include-relpath.out    |   2 +-
>  tests/qapi-schema/include-repetition.out |   2 +-
>  tests/qapi-schema/include-simple.out     |   2 +-
>  tests/qapi-schema/indented-expr.out      |   2 +-
>  tests/qapi-schema/qapi-schema-test.out   |   2 +-
>  65 files changed, 637 insertions(+), 665 deletions(-)
>  delete mode 100644 include/qapi/qmp/qfloat.h
>  delete mode 100644 include/qapi/qmp/qint.h
>  create mode 100644 include/qapi/qmp/qnum.h
>  delete mode 100644 qobject/qfloat.c
>  delete mode 100644 qobject/qint.c
>  create mode 100644 qobject/qnum.c
>  delete mode 100644 tests/check-qfloat.c
>  delete mode 100644 tests/check-qint.c
>  create mode 100644 tests/check-qnum.c
>
> diff --git a/scripts/qapi.py b/scripts/qapi.py
> index 06e583d8c3..0de809f56b 100644
> --- a/scripts/qapi.py
> +++ b/scripts/qapi.py
> @@ -21,18 +21,18 @@ from ordereddict import OrderedDict
>  
>  builtin_types = {
>      'str':      'QTYPE_QSTRING',
> -    'int':      'QTYPE_QINT',
> -    'number':   'QTYPE_QFLOAT',
> +    'int':      'QTYPE_QNUM',
> +    'number':   'QTYPE_QNUM',
>      'bool':     'QTYPE_QBOOL',
> -    'int8':     'QTYPE_QINT',
> -    'int16':    'QTYPE_QINT',
> -    'int32':    'QTYPE_QINT',
> -    'int64':    'QTYPE_QINT',
> -    'uint8':    'QTYPE_QINT',
> -    'uint16':   'QTYPE_QINT',
> -    'uint32':   'QTYPE_QINT',
> -    'uint64':   'QTYPE_QINT',
> -    'size':     'QTYPE_QINT',
> +    'int8':     'QTYPE_QNUM',
> +    'int16':    'QTYPE_QNUM',
> +    'int32':    'QTYPE_QNUM',
> +    'int64':    'QTYPE_QNUM',
> +    'uint8':    'QTYPE_QNUM',
> +    'uint16':   'QTYPE_QNUM',
> +    'uint32':   'QTYPE_QNUM',
> +    'uint64':   'QTYPE_QNUM',
> +    'size':     'QTYPE_QNUM',
>      'any':      None,           # any QType possible, actually
>      'QType':    'QTYPE_QSTRING',
>  }
> @@ -820,16 +820,10 @@ def check_alternate(expr, info):
>                      if v in ['on', 'off']:
>                          conflicting.add('QTYPE_QBOOL')
>                      if re.match(r'[-+0-9.]', v): # lazy, could be tightened
> -                        conflicting.add('QTYPE_QINT')
> -                        conflicting.add('QTYPE_QFLOAT')
> +                        conflicting.add('QTYPE_QNUM')
>              else:
> -                conflicting.add('QTYPE_QINT')
> -                conflicting.add('QTYPE_QFLOAT')
> +                conflicting.add('QTYPE_QNUM')
>                  conflicting.add('QTYPE_QBOOL')
> -        elif qtype == 'QTYPE_QINT':
> -            conflicting.add('QTYPE_QFLOAT')
> -        elif qtype == 'QTYPE_QFLOAT':
> -            conflicting.add('QTYPE_QINT')
>          if conflicting & set(types_seen):
>              raise QAPISemError(info, "Alternate '%s' member '%s' can't "
>                                 "be distinguished from member '%s'"
> @@ -1063,8 +1057,8 @@ class QAPISchemaType(QAPISchemaEntity):
>      def alternate_qtype(self):
>          json2qtype = {
>              'string':  'QTYPE_QSTRING',
> -            'number':  'QTYPE_QFLOAT',
> -            'int':     'QTYPE_QINT',
> +            'number':  'QTYPE_QNUM',
> +            'int':     'QTYPE_QNUM',
>              'boolean': 'QTYPE_QBOOL',
>              'object':  'QTYPE_QDICT'
>          }
> @@ -1526,9 +1520,9 @@ class QAPISchema(object):
>          self.the_empty_object_type = QAPISchemaObjectType(
>              'q_empty', None, None, None, [], None)
>          self._def_entity(self.the_empty_object_type)
> -        qtype_values = self._make_enum_members(['none', 'qnull', 'qint',
> +        qtype_values = self._make_enum_members(['none', 'qnull', 'qnum',
>                                                  'qstring', 'qdict', 'qlist',
> -                                                'qfloat', 'qbool'])
> +                                                'qbool'])
>          self._def_entity(QAPISchemaEnumType('QType', None, None,
>                                              qtype_values, 'QTYPE'))
>  
> diff --git a/scripts/qapi-visit.py b/scripts/qapi-visit.py
> index 5737aefa05..cc447ecacc 100644
> --- a/scripts/qapi-visit.py
> +++ b/scripts/qapi-visit.py
> @@ -164,7 +164,7 @@ def gen_visit_alternate(name, variants):
>      promote_int = 'true'
>      ret = ''
>      for var in variants.variants:
> -        if var.type.alternate_qtype() == 'QTYPE_QINT':
> +        if var.type.alternate_qtype() == 'QTYPE_QNUM':
>              promote_int = 'false'
>  
>      ret += mcgen('''
> diff --git a/include/qapi/qmp/qdict.h b/include/qapi/qmp/qdict.h
> index 188440a6a8..363e431106 100644
> --- a/include/qapi/qmp/qdict.h
> +++ b/include/qapi/qmp/qdict.h
> @@ -15,6 +15,7 @@
>  
>  #include "qapi/qmp/qobject.h"
>  #include "qapi/qmp/qlist.h"
> +#include "qapi/qmp/qnum.h"
>  #include "qemu/queue.h"
>  
>  #define QDICT_BUCKET_MAX 512
> @@ -54,7 +55,7 @@ void qdict_destroy_obj(QObject *obj);
>  
>  /* Helpers for int, bool, and string */
>  #define qdict_put_int(qdict, key, value) \
> -        qdict_put(qdict, key, qint_from_int(value))
> +        qdict_put(qdict, key, qnum_from_int(value))
>  #define qdict_put_bool(qdict, key, value) \
>          qdict_put(qdict, key, qbool_from_bool(value))
>  #define qdict_put_str(qdict, key, value) \
> diff --git a/include/qapi/qmp/qfloat.h b/include/qapi/qmp/qfloat.h
> deleted file mode 100644
> index b5d15836b5..0000000000
> --- a/include/qapi/qmp/qfloat.h
> +++ /dev/null
> @@ -1,29 +0,0 @@
> -/*
> - * QFloat Module
> - *
> - * Copyright IBM, Corp. 2009
> - *
> - * Authors:
> - *  Anthony Liguori   <aliguori@us.ibm.com>
> - *
> - * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
> - * See the COPYING.LIB file in the top-level directory.
> - *
> - */
> -
> -#ifndef QFLOAT_H
> -#define QFLOAT_H
> -
> -#include "qapi/qmp/qobject.h"
> -
> -typedef struct QFloat {
> -    QObject base;
> -    double value;
> -} QFloat;
> -
> -QFloat *qfloat_from_double(double value);
> -double qfloat_get_double(const QFloat *qi);
> -QFloat *qobject_to_qfloat(const QObject *obj);
> -void qfloat_destroy_obj(QObject *obj);
> -
> -#endif /* QFLOAT_H */
> diff --git a/include/qapi/qmp/qint.h b/include/qapi/qmp/qint.h
> deleted file mode 100644
> index 3aaff768dd..0000000000
> --- a/include/qapi/qmp/qint.h
> +++ /dev/null
> @@ -1,28 +0,0 @@
> -/*
> - * QInt Module
> - *
> - * Copyright (C) 2009 Red Hat Inc.
> - *
> - * Authors:
> - *  Luiz Capitulino <lcapitulino@redhat.com>
> - *
> - * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
> - * See the COPYING.LIB file in the top-level directory.
> - */
> -
> -#ifndef QINT_H
> -#define QINT_H
> -
> -#include "qapi/qmp/qobject.h"
> -
> -typedef struct QInt {
> -    QObject base;
> -    int64_t value;
> -} QInt;
> -
> -QInt *qint_from_int(int64_t value);
> -int64_t qint_get_int(const QInt *qi);
> -QInt *qobject_to_qint(const QObject *obj);
> -void qint_destroy_obj(QObject *obj);
> -
> -#endif /* QINT_H */
> diff --git a/include/qapi/qmp/qlist.h b/include/qapi/qmp/qlist.h
> index 5dc4ed9616..c4b5fdad9b 100644
> --- a/include/qapi/qmp/qlist.h
> +++ b/include/qapi/qmp/qlist.h
> @@ -14,6 +14,7 @@
>  #define QLIST_H
>  
>  #include "qapi/qmp/qobject.h"
> +#include "qapi/qmp/qnum.h"
>  #include "qemu/queue.h"
>  
>  typedef struct QListEntry {
> @@ -31,7 +32,7 @@ typedef struct QList {
>  
>  /* Helpers for int, bool, and string */
>  #define qlist_append_int(qlist, value) \
> -        qlist_append(qlist, qint_from_int(value))
> +        qlist_append(qlist, qnum_from_int(value))
>  #define qlist_append_bool(qlist, value) \
>          qlist_append(qlist, qbool_from_bool(value))
>  #define qlist_append_str(qlist, value) \
> diff --git a/include/qapi/qmp/qnum.h b/include/qapi/qmp/qnum.h
> new file mode 100644
> index 0000000000..cc636fac5f
> --- /dev/null
> +++ b/include/qapi/qmp/qnum.h
> @@ -0,0 +1,44 @@
> +/*
> + * QNum Module
> + *
> + * Copyright (C) 2009 Red Hat Inc.
> + *
> + * Authors:
> + *  Luiz Capitulino <lcapitulino@redhat.com>
> + *  Marc-André Lureau <marcandre.lureau@redhat.com>
> + *
> + * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
> + * See the COPYING.LIB file in the top-level directory.
> + */
> +
> +#ifndef QNUM_H
> +#define QNUM_H
> +
> +#include "qapi/qmp/qobject.h"
> +
> +typedef enum {
> +    QNUM_I64,
> +    QNUM_DOUBLE
> +} QNumKind;
> +
> +typedef struct QNum {
> +    QObject base;
> +    QNumKind kind;
> +    union {
> +        int64_t i64;
> +        double dbl;
> +    } u;
> +} QNum;
> +
> +QNum *qnum_from_int(int64_t value);
> +QNum *qnum_from_double(double value);
> +
> +bool qnum_get_int(const QNum *qn, int64_t *val);
> +double qnum_get_double(QNum *qn);

Your new qnum_get_int() interface makes sense, but the asymmetry bothers
me.  Hmm.

> +
> +char *qnum_to_string(QNum *qn);
> +
> +QNum *qobject_to_qnum(const QObject *obj);
> +void qnum_destroy_obj(QObject *obj);
> +
> +#endif /* QNUM_H */
> diff --git a/include/qapi/qmp/types.h b/include/qapi/qmp/types.h
> index 27cfbd84e5..a4bc662bfb 100644
> --- a/include/qapi/qmp/types.h
> +++ b/include/qapi/qmp/types.h
> @@ -14,8 +14,7 @@
>  #define QAPI_QMP_TYPES_H
>  
>  #include "qapi/qmp/qobject.h"
> -#include "qapi/qmp/qint.h"
> -#include "qapi/qmp/qfloat.h"
> +#include "qapi/qmp/qnum.h"
>  #include "qapi/qmp/qbool.h"
>  #include "qapi/qmp/qstring.h"
>  #include "qapi/qmp/qdict.h"
> diff --git a/include/qapi/qobject-input-visitor.h b/include/qapi/qobject-input-visitor.h
> index b399285c43..daee18c6ac 100644
> --- a/include/qapi/qobject-input-visitor.h
> +++ b/include/qapi/qobject-input-visitor.h
> @@ -30,9 +30,9 @@ typedef struct QObjectInputVisitor QObjectInputVisitor;
>   * visit_type_FOO() creates an instance of QAPI type FOO.  The visited
>   * QObject must match FOO.  QDict matches struct/union types, QList
>   * matches list types, QString matches type 'str' and enumeration
> - * types, QInt matches integer types, QFloat matches type 'number',
> - * QBool matches type 'bool'.  Type 'any' is matched by QObject.  A
> - * QAPI alternate type is matched when one of its member types is.
> + * types, QNum matches integer and float types, QBool matches type
> + * 'bool'.  Type 'any' is matched by QObject.  A QAPI alternate type
> + * is matched when one of its member types is.
>   *
>   * visit_start_struct() ... visit_end_struct() visits a QDict and
>   * creates a QAPI struct/union.  Visits in between visit the
> diff --git a/include/qapi/qobject-output-visitor.h b/include/qapi/qobject-output-visitor.h
> index 9b990c318e..e5a3490812 100644
> --- a/include/qapi/qobject-output-visitor.h
> +++ b/include/qapi/qobject-output-visitor.h
> @@ -28,10 +28,10 @@ typedef struct QObjectOutputVisitor QObjectOutputVisitor;
>   *
>   * visit_type_FOO() creates a QObject for QAPI type FOO.  It creates a
>   * QDict for struct/union types, a QList for list types, QString for
> - * type 'str' and enumeration types, QInt for integer types, QFloat
> - * for type 'number', QBool for type 'bool'.  For type 'any', it
> - * increments the QObject's reference count.  For QAPI alternate
> - * types, it creates the QObject for the member that is in use.
> + * type 'str' and enumeration types, QNum for integer and float
> + * types, QBool for type 'bool'.  For type 'any', it increments the
> + * QObject's reference count.  For QAPI alternate types, it creates
> + * the QObject for the member that is in use.
>   *
>   * visit_start_struct() ... visit_end_struct() visits a QAPI
>   * struct/union and creates a QDict.  Visits in between visit the
> diff --git a/block/blkdebug.c b/block/blkdebug.c
> index a5196e889d..0618fc71c6 100644
> --- a/block/blkdebug.c
> +++ b/block/blkdebug.c
> @@ -31,7 +31,6 @@
>  #include "qemu/module.h"
>  #include "qapi/qmp/qbool.h"
>  #include "qapi/qmp/qdict.h"
> -#include "qapi/qmp/qint.h"
>  #include "qapi/qmp/qstring.h"
>  #include "sysemu/qtest.h"
>  
> diff --git a/block/nbd.c b/block/nbd.c
> index 975faab2c5..e946ea944d 100644
> --- a/block/nbd.c
> +++ b/block/nbd.c
> @@ -37,7 +37,6 @@
>  #include "qapi/qobject-output-visitor.h"
>  #include "qapi/qmp/qdict.h"
>  #include "qapi/qmp/qjson.h"
> -#include "qapi/qmp/qint.h"
>  #include "qapi/qmp/qstring.h"
>  #include "qemu/cutils.h"
>  
> diff --git a/block/nfs.c b/block/nfs.c
> index 848b2c0bb0..decefd15f1 100644
> --- a/block/nfs.c
> +++ b/block/nfs.c
> @@ -36,7 +36,6 @@
>  #include "qemu/cutils.h"
>  #include "sysemu/sysemu.h"
>  #include "qapi/qmp/qdict.h"
> -#include "qapi/qmp/qint.h"
>  #include "qapi/qmp/qstring.h"
>  #include "qapi-visit.h"
>  #include "qapi/qobject-input-visitor.h"
> diff --git a/block/qapi.c b/block/qapi.c
> index a40922ea26..2050df29e4 100644
> --- a/block/qapi.c
> +++ b/block/qapi.c
> @@ -595,9 +595,11 @@ static void dump_qobject(fprintf_function func_fprintf, void *f,
>                           int comp_indent, QObject *obj)
>  {
>      switch (qobject_type(obj)) {
> -        case QTYPE_QINT: {
> -            QInt *value = qobject_to_qint(obj);
> -            func_fprintf(f, "%" PRId64, qint_get_int(value));
> +        case QTYPE_QNUM: {
> +            QNum *value = qobject_to_qnum(obj);
> +            char *tmp = qnum_to_string(value);
> +            func_fprintf(f, "%s", tmp);
> +            g_free(tmp);
>              break;
>          }
>          case QTYPE_QSTRING: {
> @@ -615,11 +617,6 @@ static void dump_qobject(fprintf_function func_fprintf, void *f,
>              dump_qlist(func_fprintf, f, comp_indent, value);
>              break;
>          }
> -        case QTYPE_QFLOAT: {
> -            QFloat *value = qobject_to_qfloat(obj);
> -            func_fprintf(f, "%g", qfloat_get_double(value));
> -            break;
> -        }
>          case QTYPE_QBOOL: {
>              QBool *value = qobject_to_qbool(obj);
>              func_fprintf(f, "%s", qbool_get_bool(value) ? "true" : "false");
> diff --git a/block/quorum.c b/block/quorum.c
> index 1b2a8c3937..55ba916655 100644
> --- a/block/quorum.c
> +++ b/block/quorum.c
> @@ -19,7 +19,6 @@
>  #include "qapi/qmp/qbool.h"
>  #include "qapi/qmp/qdict.h"
>  #include "qapi/qmp/qerror.h"
> -#include "qapi/qmp/qint.h"
>  #include "qapi/qmp/qjson.h"
>  #include "qapi/qmp/qlist.h"
>  #include "qapi/qmp/qstring.h"
> diff --git a/block/sheepdog.c b/block/sheepdog.c
> index a18315a1ca..dea9000bdd 100644
> --- a/block/sheepdog.c
> +++ b/block/sheepdog.c
> @@ -16,7 +16,6 @@
>  #include "qapi-visit.h"
>  #include "qapi/error.h"
>  #include "qapi/qmp/qdict.h"
> -#include "qapi/qmp/qint.h"
>  #include "qapi/qobject-input-visitor.h"
>  #include "qemu/uri.h"
>  #include "qemu/error-report.h"
> diff --git a/block/ssh.c b/block/ssh.c
> index 11203fc5a2..bac3453c3e 100644
> --- a/block/ssh.c
> +++ b/block/ssh.c
> @@ -34,7 +34,6 @@
>  #include "qemu/sockets.h"
>  #include "qemu/uri.h"
>  #include "qapi-visit.h"
> -#include "qapi/qmp/qint.h"
>  #include "qapi/qmp/qstring.h"
>  #include "qapi/qobject-input-visitor.h"
>  #include "qapi/qobject-output-visitor.h"
> diff --git a/block/vvfat.c b/block/vvfat.c
> index 426ca70e35..8ab647c0c6 100644
> --- a/block/vvfat.c
> +++ b/block/vvfat.c
> @@ -29,7 +29,6 @@
>  #include "qemu/module.h"
>  #include "qemu/bswap.h"
>  #include "migration/blocker.h"
> -#include "qapi/qmp/qint.h"
>  #include "qapi/qmp/qbool.h"
>  #include "qapi/qmp/qstring.h"
>  #include "qemu/cutils.h"
> diff --git a/blockdev.c b/blockdev.c
> index 892d768574..be18271c11 100644
> --- a/blockdev.c
> +++ b/blockdev.c
> @@ -334,9 +334,11 @@ static bool parse_stats_intervals(BlockAcctStats *stats, QList *intervals,
>              break;
>          }
>  
> -        case QTYPE_QINT: {
> -            int64_t length = qint_get_int(qobject_to_qint(entry->value));
> -            if (length > 0 && length <= UINT_MAX) {
> +        case QTYPE_QNUM: {
> +            int64_t length;
> +
> +            if (qnum_get_int(qobject_to_qnum(entry->value), &length) &&
> +                length > 0 && length <= UINT_MAX) {
>                  block_acct_add_interval(stats, (unsigned) length);
>              } else {
>                  error_setg(errp, "Invalid interval length: %" PRId64, length);

No longer crashes when entr->value is a floating-point number.  Still
crashes when it isn't a number.  Since neither can happen, there's no
real need to note this in the commit message.  Okay.

> diff --git a/hw/acpi/pcihp.c b/hw/acpi/pcihp.c
> index 2b0f3e1bfb..3a531a4416 100644
> --- a/hw/acpi/pcihp.c
> +++ b/hw/acpi/pcihp.c
> @@ -37,7 +37,6 @@
>  #include "hw/pci/pci_bus.h"
>  #include "qapi/error.h"
>  #include "qom/qom-qobject.h"
> -#include "qapi/qmp/qint.h"
>  
>  //#define DEBUG
>  
> diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
> index 82bd44f38e..1709efdf1c 100644
> --- a/hw/i386/acpi-build.c
> +++ b/hw/i386/acpi-build.c
> @@ -57,7 +57,6 @@
>  
>  #include "hw/acpi/aml-build.h"
>  
> -#include "qapi/qmp/qint.h"
>  #include "qom/qom-qobject.h"
>  #include "hw/i386/amd_iommu.h"
>  #include "hw/i386/intel_iommu.h"
> @@ -129,6 +128,7 @@ static void acpi_get_pm_info(AcpiPmInfo *pm)
>      Object *lpc = ich9_lpc_find();
>      Object *obj = NULL;
>      QObject *o;
> +    int64_t val;
>  
>      pm->cpu_hp_io_base = 0;
>      pm->pcihp_io_base = 0;
> @@ -150,21 +150,30 @@ static void acpi_get_pm_info(AcpiPmInfo *pm)
>      /* Fill in optional s3/s4 related properties */
>      o = object_property_get_qobject(obj, ACPI_PM_PROP_S3_DISABLED, NULL);
>      if (o) {
> -        pm->s3_disabled = qint_get_int(qobject_to_qint(o));
> +        if (!qnum_get_int(qobject_to_qnum(o), &val)) {
> +            g_assert_not_reached();
> +        }
> +        pm->s3_disabled = val;
>      } else {
>          pm->s3_disabled = false;
>      }
>      qobject_decref(o);
>      o = object_property_get_qobject(obj, ACPI_PM_PROP_S4_DISABLED, NULL);
>      if (o) {
> -        pm->s4_disabled = qint_get_int(qobject_to_qint(o));
> +        if (!qnum_get_int(qobject_to_qnum(o), &val)) {
> +            g_assert_not_reached();
> +        }
> +        pm->s4_disabled = val;
>      } else {
>          pm->s4_disabled = false;
>      }
>      qobject_decref(o);
>      o = object_property_get_qobject(obj, ACPI_PM_PROP_S4_VAL, NULL);
>      if (o) {
> -        pm->s4_val = qint_get_int(qobject_to_qint(o));
> +        if (!qnum_get_int(qobject_to_qnum(o), &val)) {
> +            g_assert_not_reached();
> +        }
> +        pm->s4_val = val;
>      } else {
>          pm->s4_val = false;
>      }
> @@ -529,7 +538,11 @@ static void build_append_pci_bus_devices(Aml *parent_scope, PCIBus *bus,
>  
>      bsel = object_property_get_qobject(OBJECT(bus), ACPI_PCIHP_PROP_BSEL, NULL);
>      if (bsel) {
> -        int64_t bsel_val = qint_get_int(qobject_to_qint(bsel));
> +        int64_t bsel_val;
> +
> +        if (!qnum_get_int(qobject_to_qnum(bsel), &bsel_val)) {
> +            g_assert_not_reached();
> +        }
>  
>          aml_append(parent_scope, aml_name_decl("BSEL", aml_int(bsel_val)));
>          notify_method = aml_method("DVNT", 2, AML_NOTSERIALIZED);
> @@ -639,7 +652,12 @@ static void build_append_pci_bus_devices(Aml *parent_scope, PCIBus *bus,
>  
>      /* If bus supports hotplug select it and notify about local events */
>      if (bsel) {
> -        int64_t bsel_val = qint_get_int(qobject_to_qint(bsel));
> +        int64_t bsel_val;
> +
> +        if (!qnum_get_int(qobject_to_qnum(bsel), &bsel_val)) {
> +            g_assert_not_reached();
> +        }
> +
>          aml_append(method, aml_store(aml_int(bsel_val), aml_name("BNUM")));
>          aml_append(method,
>              aml_call2("DVNT", aml_name("PCIU"), aml_int(1) /* Device Check */)
> @@ -2607,6 +2625,7 @@ static bool acpi_get_mcfg(AcpiMcfgInfo *mcfg)
>  {
>      Object *pci_host;
>      QObject *o;
> +    int64_t val;
>  
>      pci_host = acpi_get_i386_pci_host();
>      g_assert(pci_host);
> @@ -2615,12 +2634,18 @@ static bool acpi_get_mcfg(AcpiMcfgInfo *mcfg)
>      if (!o) {
>          return false;
>      }
> -    mcfg->mcfg_base = qint_get_int(qobject_to_qint(o));
> +    if (!qnum_get_int(qobject_to_qnum(o), &val)) {
> +        g_assert_not_reached();
> +    }
> +    mcfg->mcfg_base = val;
>      qobject_decref(o);
>  
>      o = object_property_get_qobject(pci_host, PCIE_HOST_MCFG_SIZE, NULL);
>      assert(o);
> -    mcfg->mcfg_size = qint_get_int(qobject_to_qint(o));
> +    if (!qnum_get_int(qobject_to_qnum(o), &val)) {
> +        g_assert_not_reached();
> +    }
> +    mcfg->mcfg_size = val;
>      qobject_decref(o);
>      return true;
>  }

We've seen this pattern

       if (!qnum_get_int(qobject_to_qnum(src), &tmp)) {
           g_assert_not_reached();
       }
       dst = tmp;

quite a few times now.  Enough to justify a helper, I think.

Hmm, we could reduce the asymmetry that bothers me this way:

   bool qnum_get_try_int(const QNum *qn, int64_t *val);
   int64_t qnum_get_int(const QNum *qn);
   double qnum_get_double(QNum *qn);

Bonus: less churn:
   
       o = object_property_get_qobject(pci_host, PCIE_HOST_MCFG_SIZE, NULL);
       assert(o);
  -    mcfg->mcfg_size = qint_get_int(qobject_to_qint(o));
  +    mcfg->mcfg_size = qnum_get_int(qobject_to_qint(o));
       qobject_decref(o);
       return true;

What do you think?

Speaking of patterns.  A substantial part of the patch is a mechanical
transformation

    - qobject_to_qint(E)
    + qobject_to_qnum(E)

    - qint_get_int(E)
    + qnum_get_int(E)

    - LHS = qint_get_int(E)
    + if (!qnum_get_int(E, &TMP)
    +     g_assert_not_reached();
    + }
    + LHS = TMP;
    // plus several more variations of this pattern

    - qobject_to_qfloat(E)
    + qobject_to_qnum(E)

    - qfloat_get_double(E)
    + qnum_get_double(E)

plus replacement / merge of QInt / QFloat variables.  Did you do it
entirely by hand or with help from Coccinelle?

Other patterns that might justify helpers:

    qnum_get_double(qobject_to_qnum(OBJ))
    qnum_get_int(qobject_to_qnum(OBJ), ERR)
    qnum_get_int(qobject_to_qnum(OBJ), &error_abort)

Idea, not demand.

> diff --git a/hw/usb/xen-usb.c b/hw/usb/xen-usb.c
> index fe62183fe3..584a6f2442 100644
> --- a/hw/usb/xen-usb.c
> +++ b/hw/usb/xen-usb.c
> @@ -30,7 +30,6 @@
>  #include "hw/xen/xen_backend.h"
>  #include "monitor/qdev.h"
>  #include "qapi/qmp/qbool.h"
> -#include "qapi/qmp/qint.h"
>  #include "qapi/qmp/qstring.h"
>  
>  #include "hw/xen/io/ring.h"
> diff --git a/monitor.c b/monitor.c
> index baa73c98b7..a8ac971015 100644
> --- a/monitor.c
> +++ b/monitor.c
> @@ -2971,7 +2971,7 @@ static QDict *monitor_parse_arguments(Monitor *mon,
>                      monitor_printf(mon, "Unknown unit suffix\n");
>                      goto fail;
>                  }
> -                qdict_put(qdict, key, qfloat_from_double(val));
> +                qdict_put(qdict, key, qnum_from_double(val));
>              }
>              break;
>          case 'b':
> diff --git a/qapi/qobject-input-visitor.c b/qapi/qobject-input-visitor.c
> index eac40f618a..b32318c352 100644
> --- a/qapi/qobject-input-visitor.c
> +++ b/qapi/qobject-input-visitor.c
> @@ -378,9 +378,6 @@ static void qobject_input_start_alternate(Visitor *v, const char *name,
>      }
>      *obj = g_malloc0(size);
>      (*obj)->type = qobject_type(qobj);
> -    if (promote_int && (*obj)->type == QTYPE_QINT) {
> -        (*obj)->type = QTYPE_QFLOAT;
> -    }
>  }
>  
>  static void qobject_input_type_int64(Visitor *v, const char *name, int64_t *obj,
> @@ -388,22 +385,18 @@ static void qobject_input_type_int64(Visitor *v, const char *name, int64_t *obj,
>  {
>      QObjectInputVisitor *qiv = to_qiv(v);
>      QObject *qobj = qobject_input_get_object(qiv, name, true, errp);
> -    QInt *qint;
> +    QNum *qnum;
>  
>      if (!qobj) {
>          return;
>      }
> -    qint = qobject_to_qint(qobj);
> -    if (!qint) {
> +    qnum = qobject_to_qnum(qobj);
> +    if (!qnum || !qnum_get_int(qnum, obj)) {
>          error_setg(errp, QERR_INVALID_PARAMETER_TYPE,
>                     full_name(qiv, name), "integer");
> -        return;
>      }
> -
> -    *obj = qint_get_int(qint);
>  }
>  
> -
>  static void qobject_input_type_int64_keyval(Visitor *v, const char *name,
>                                              int64_t *obj, Error **errp)
>  {
> @@ -424,22 +417,21 @@ static void qobject_input_type_int64_keyval(Visitor *v, const char *name,
>  static void qobject_input_type_uint64(Visitor *v, const char *name,
>                                        uint64_t *obj, Error **errp)
>  {
> -    /* FIXME: qobject_to_qint mishandles values over INT64_MAX */
> +    /* FIXME: qobject_to_qnum mishandles values over INT64_MAX */
>      QObjectInputVisitor *qiv = to_qiv(v);
>      QObject *qobj = qobject_input_get_object(qiv, name, true, errp);
> -    QInt *qint;
> +    QNum *qnum;
> +    int64_t val;
>  
>      if (!qobj) {
>          return;
>      }
> -    qint = qobject_to_qint(qobj);
> -    if (!qint) {
> +    qnum = qobject_to_qnum(qobj);
> +    if (!qnum || !qnum_get_int(qnum, &val)) {
>          error_setg(errp, QERR_INVALID_PARAMETER_TYPE,
>                     full_name(qiv, name), "integer");
> -        return;
>      }
> -
> -    *obj = qint_get_int(qint);
> +    *obj = val;
>  }
>  
>  static void qobject_input_type_uint64_keyval(Visitor *v, const char *name,
> @@ -534,21 +526,14 @@ static void qobject_input_type_number(Visitor *v, const char *name, double *obj,
>  {
>      QObjectInputVisitor *qiv = to_qiv(v);
>      QObject *qobj = qobject_input_get_object(qiv, name, true, errp);
> -    QInt *qint;
> -    QFloat *qfloat;
> +    QNum *qnum;
>  
>      if (!qobj) {
>          return;
>      }
> -    qint = qobject_to_qint(qobj);
> -    if (qint) {
> -        *obj = qint_get_int(qobject_to_qint(qobj));
> -        return;
> -    }
> -
> -    qfloat = qobject_to_qfloat(qobj);
> -    if (qfloat) {
> -        *obj = qfloat_get_double(qobject_to_qfloat(qobj));
> +    qnum = qobject_to_qnum(qobj);
> +    if (qnum) {
> +        *obj = qnum_get_double(qnum);
>          return;
>      }
>  
       error_setg(errp, QERR_INVALID_PARAMETER_TYPE,
                  full_name(qiv, name), "number");
   }


Let's clean this up to the more common

       if (!qnum) {
          error_setg(errp, QERR_INVALID_PARAMETER_TYPE,
                     full_name(qiv, name), "number");
          return;
       }

       *obj = qnum_get_double(qnum);

Preferrably in another patch, though.

> diff --git a/qapi/qobject-output-visitor.c b/qapi/qobject-output-visitor.c
> index 871127079d..2ca5093b22 100644
> --- a/qapi/qobject-output-visitor.c
> +++ b/qapi/qobject-output-visitor.c
> @@ -144,7 +144,7 @@ static void qobject_output_type_int64(Visitor *v, const char *name,
>                                        int64_t *obj, Error **errp)
>  {
>      QObjectOutputVisitor *qov = to_qov(v);
> -    qobject_output_add(qov, name, qint_from_int(*obj));
> +    qobject_output_add(qov, name, qnum_from_int(*obj));
>  }
>  
>  static void qobject_output_type_uint64(Visitor *v, const char *name,
> @@ -152,7 +152,7 @@ static void qobject_output_type_uint64(Visitor *v, const char *name,
>  {
>      /* FIXME values larger than INT64_MAX become negative */
>      QObjectOutputVisitor *qov = to_qov(v);
> -    qobject_output_add(qov, name, qint_from_int(*obj));
> +    qobject_output_add(qov, name, qnum_from_int(*obj));
>  }
>  
>  static void qobject_output_type_bool(Visitor *v, const char *name, bool *obj,
> @@ -177,7 +177,7 @@ static void qobject_output_type_number(Visitor *v, const char *name,
>                                         double *obj, Error **errp)
>  {
>      QObjectOutputVisitor *qov = to_qov(v);
> -    qobject_output_add(qov, name, qfloat_from_double(*obj));
> +    qobject_output_add(qov, name, qnum_from_double(*obj));
>  }
>  
>  static void qobject_output_type_any(Visitor *v, const char *name,
> diff --git a/qga/commands.c b/qga/commands.c
> index 3333ed50b2..ff89e805cf 100644
> --- a/qga/commands.c
> +++ b/qga/commands.c
> @@ -485,7 +485,7 @@ int ga_parse_whence(GuestFileWhence *whence, Error **errp)
>  {
>      /* Exploit the fact that we picked values to match QGA_SEEK_*. */
>      if (whence->type == QTYPE_QSTRING) {
> -        whence->type = QTYPE_QINT;
> +        whence->type = QTYPE_QNUM;
>          whence->u.value = whence->u.name;
>      }
>      switch (whence->u.value) {
> diff --git a/qga/main.c b/qga/main.c
> index cc58d2b53d..405c1290f8 100644
> --- a/qga/main.c
> +++ b/qga/main.c
> @@ -19,7 +19,6 @@
>  #endif
>  #include "qapi/qmp/json-streamer.h"
>  #include "qapi/qmp/json-parser.h"
> -#include "qapi/qmp/qint.h"
>  #include "qapi/qmp/qjson.h"
>  #include "qga/guest-agent-core.h"
>  #include "qemu/module.h"
> diff --git a/qobject/json-parser.c b/qobject/json-parser.c
> index c18e48ab94..b90b2fb45a 100644
> --- a/qobject/json-parser.c
> +++ b/qobject/json-parser.c
> @@ -466,16 +466,16 @@ static QObject *parse_escape(JSONParserContext *ctxt, va_list *ap)
>      } else if (!strcmp(token->str, "%i")) {
>          return QOBJECT(qbool_from_bool(va_arg(*ap, int)));
>      } else if (!strcmp(token->str, "%d")) {
> -        return QOBJECT(qint_from_int(va_arg(*ap, int)));
> +        return QOBJECT(qnum_from_int(va_arg(*ap, int)));
>      } else if (!strcmp(token->str, "%ld")) {
> -        return QOBJECT(qint_from_int(va_arg(*ap, long)));
> +        return QOBJECT(qnum_from_int(va_arg(*ap, long)));
>      } else if (!strcmp(token->str, "%lld") ||
>                 !strcmp(token->str, "%I64d")) {
> -        return QOBJECT(qint_from_int(va_arg(*ap, long long)));
> +        return QOBJECT(qnum_from_int(va_arg(*ap, long long)));
>      } else if (!strcmp(token->str, "%s")) {
>          return QOBJECT(qstring_from_str(va_arg(*ap, const char *)));
>      } else if (!strcmp(token->str, "%f")) {
> -        return QOBJECT(qfloat_from_double(va_arg(*ap, double)));
> +        return QOBJECT(qnum_from_double(va_arg(*ap, double)));
>      }
>      return NULL;
>  }
> @@ -491,24 +491,21 @@ static QObject *parse_literal(JSONParserContext *ctxt)
>      case JSON_STRING:
>          return QOBJECT(qstring_from_escaped_str(ctxt, token));
>      case JSON_INTEGER: {
> -        /* A possibility exists that this is a whole-valued float where the
> -         * fractional part was left out due to being 0 (.0). It's not a big
> -         * deal to treat these as ints in the parser, so long as users of the
> -         * resulting QObject know to expect a QInt in place of a QFloat in
> -         * cases like these.
> +        /*
> +         * Represent JSON_INTEGER as QNUM_I64 if possible, else as
> +         * QNUM_DOUBLE. Note that strtoll() fails with ERANGE when

Two spaces after the period, for consistency with existing comments
around here.  Hmm, you fix it in PATCH 13.

> +         * it's not possible.
>           *
> -         * However, in some cases these values will overflow/underflow a
> -         * QInt/int64 container, thus we should assume these are to be handled
> -         * as QFloats/doubles rather than silently changing their values.
> -         *
> -         * strtoll() indicates these instances by setting errno to ERANGE
> +         * qnum_get_int() will then work for any signed 64-bit
> +         * JSON_INTEGER, and qnum_get_double both for any JSON_INTEGER

qnum_get_double()

> +         * and any JSON_FLOAT.
>           */

Worth mentioning that qnum_get_double() loses precision for integers
beyond 53 bits?

>          int64_t value;
>  
>          errno = 0; /* strtoll doesn't set errno on success */
>          value = strtoll(token->str, NULL, 10);
>          if (errno != ERANGE) {
> -            return QOBJECT(qint_from_int(value));
> +            return QOBJECT(qnum_from_int(value));
>          }
>          /* fall through to JSON_FLOAT */
>      }
> @@ -516,7 +513,7 @@ static QObject *parse_literal(JSONParserContext *ctxt)
>          /* FIXME dependent on locale; a pervasive issue in QEMU */
>          /* FIXME our lexer matches RFC 7159 in forbidding Inf or NaN,
>           * but those might be useful extensions beyond JSON */
> -        return QOBJECT(qfloat_from_double(strtod(token->str, NULL)));
> +        return QOBJECT(qnum_from_double(strtod(token->str, NULL)));
>      default:
>          abort();
>      }
> diff --git a/qobject/qdict.c b/qobject/qdict.c
> index 88e2ecd658..f62625cbd6 100644
> --- a/qobject/qdict.c
> +++ b/qobject/qdict.c
> @@ -11,8 +11,7 @@
>   */
>  
>  #include "qemu/osdep.h"
> -#include "qapi/qmp/qint.h"
> -#include "qapi/qmp/qfloat.h"
> +#include "qapi/qmp/qnum.h"
>  #include "qapi/qmp/qdict.h"
>  #include "qapi/qmp/qbool.h"
>  #include "qapi/qmp/qstring.h"
> @@ -180,37 +179,32 @@ size_t qdict_size(const QDict *qdict)
>  /**
>   * qdict_get_double(): Get an number mapped by 'key'
>   *
> - * This function assumes that 'key' exists and it stores a
> - * QFloat or QInt object.
> + * This function assumes that 'key' exists and it stores a QNum.
>   *
>   * Return number mapped by 'key'.
>   */
>  double qdict_get_double(const QDict *qdict, const char *key)
>  {
> -    QObject *obj = qdict_get(qdict, key);
> -
> -    assert(obj);
> -    switch (qobject_type(obj)) {
> -    case QTYPE_QFLOAT:
> -        return qfloat_get_double(qobject_to_qfloat(obj));
> -    case QTYPE_QINT:
> -        return qint_get_int(qobject_to_qint(obj));
> -    default:
> -        abort();
> -    }
> +    return qnum_get_double(qobject_to_qnum(qdict_get(qdict, key)));
>  }
>  
>  /**
>   * qdict_get_int(): Get an integer mapped by 'key'
>   *
>   * This function assumes that 'key' exists and it stores a
> - * QInt object.
> + * QNum representable as int.
>   *
>   * Return integer mapped by 'key'.
>   */
>  int64_t qdict_get_int(const QDict *qdict, const char *key)
>  {
> -    return qint_get_int(qobject_to_qint(qdict_get(qdict, key)));
> +    int64_t val;
> +
> +    if (!qnum_get_int(qobject_to_qnum(qdict_get(qdict, key)), &val)) {
> +        g_assert_not_reached();
> +    }
> +
> +    return val;
>  }
>  
>  /**
> @@ -259,16 +253,21 @@ const char *qdict_get_str(const QDict *qdict, const char *key)
>  /**
>   * qdict_get_try_int(): Try to get integer mapped by 'key'
>   *
> - * Return integer mapped by 'key', if it is not present in
> - * the dictionary or if the stored object is not of QInt type
> - * 'def_value' will be returned.
> + * Return integer mapped by 'key', if it is not present in the
> + * dictionary or if the stored object is not a QNum representing an
> + * integer, 'def_value' will be returned.
>   */
>  int64_t qdict_get_try_int(const QDict *qdict, const char *key,
>                            int64_t def_value)
>  {
> -    QInt *qint = qobject_to_qint(qdict_get(qdict, key));
> +    QNum *qnum = qobject_to_qnum(qdict_get(qdict, key));
> +    int64_t val;
> +
> +    if (!qnum || !qnum_get_int(qnum, &val)) {
> +        return def_value;
> +    }
>  
> -    return qint ? qint_get_int(qint) : def_value;
> +    return val;
>  }

Let me copy a remark from the previous review I'd like to remember going
forward.  I don't expect you to do anything about it right now.

The function does the right thing for QNums created by the JSON parser,
which picks the QNumType carefully, in parse_literal():

* if the JSON number has neither a fractional nor an exponent part, and

  - fits into int64_t, use qnum_from_int()
  - fits into uint64_t, use qnum_from_uint()

  (if it fits both, qnum_from_int(), but that should not matter)

* else, use qnum_from_double().

For such a QNum, rejecting QNUM_DOUBLE here is correct, because the
value either had a fractional part, an exponent part, or didn't fit
int64_t.

Other code using qnum_from_int() and qnum_from_double() needs to be
similarly careful.

>  
>  /**
> diff --git a/qobject/qfloat.c b/qobject/qfloat.c
> deleted file mode 100644
> index d5da847701..0000000000
> --- a/qobject/qfloat.c
> +++ /dev/null
> @@ -1,62 +0,0 @@
> -/*
> - * QFloat Module
> - *
> - * Copyright IBM, Corp. 2009
> - *
> - * Authors:
> - *  Anthony Liguori   <aliguori@us.ibm.com>
> - *
> - * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
> - * See the COPYING.LIB file in the top-level directory.
> - *
> - */
> -
> -#include "qemu/osdep.h"
> -#include "qapi/qmp/qfloat.h"
> -#include "qapi/qmp/qobject.h"
> -#include "qemu-common.h"
> -
> -/**
> - * qfloat_from_int(): Create a new QFloat from a float
> - *
> - * Return strong reference.
> - */
> -QFloat *qfloat_from_double(double value)
> -{
> -    QFloat *qf;
> -
> -    qf = g_malloc(sizeof(*qf));
> -    qobject_init(QOBJECT(qf), QTYPE_QFLOAT);
> -    qf->value = value;
> -
> -    return qf;
> -}
> -
> -/**
> - * qfloat_get_double(): Get the stored float
> - */
> -double qfloat_get_double(const QFloat *qf)
> -{
> -    return qf->value;
> -}
> -
> -/**
> - * qobject_to_qfloat(): Convert a QObject into a QFloat
> - */
> -QFloat *qobject_to_qfloat(const QObject *obj)
> -{
> -    if (!obj || qobject_type(obj) != QTYPE_QFLOAT) {
> -        return NULL;
> -    }
> -    return container_of(obj, QFloat, base);
> -}
> -
> -/**
> - * qfloat_destroy_obj(): Free all memory allocated by a
> - * QFloat object
> - */
> -void qfloat_destroy_obj(QObject *obj)
> -{
> -    assert(obj != NULL);
> -    g_free(qobject_to_qfloat(obj));
> -}
> diff --git a/qobject/qint.c b/qobject/qint.c
> deleted file mode 100644
> index d7d1b3021f..0000000000
> --- a/qobject/qint.c
> +++ /dev/null
> @@ -1,61 +0,0 @@
> -/*
> - * QInt Module
> - *
> - * Copyright (C) 2009 Red Hat Inc.
> - *
> - * Authors:
> - *  Luiz Capitulino <lcapitulino@redhat.com>
> - *
> - * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
> - * See the COPYING.LIB file in the top-level directory.
> - */
> -
> -#include "qemu/osdep.h"
> -#include "qapi/qmp/qint.h"
> -#include "qapi/qmp/qobject.h"
> -#include "qemu-common.h"
> -
> -/**
> - * qint_from_int(): Create a new QInt from an int64_t
> - *
> - * Return strong reference.
> - */
> -QInt *qint_from_int(int64_t value)
> -{
> -    QInt *qi;
> -
> -    qi = g_malloc(sizeof(*qi));
> -    qobject_init(QOBJECT(qi), QTYPE_QINT);
> -    qi->value = value;
> -
> -    return qi;
> -}
> -
> -/**
> - * qint_get_int(): Get the stored integer
> - */
> -int64_t qint_get_int(const QInt *qi)
> -{
> -    return qi->value;
> -}
> -
> -/**
> - * qobject_to_qint(): Convert a QObject into a QInt
> - */
> -QInt *qobject_to_qint(const QObject *obj)
> -{
> -    if (!obj || qobject_type(obj) != QTYPE_QINT) {
> -        return NULL;
> -    }
> -    return container_of(obj, QInt, base);
> -}
> -
> -/**
> - * qint_destroy_obj(): Free all memory allocated by a
> - * QInt object
> - */
> -void qint_destroy_obj(QObject *obj)
> -{
> -    assert(obj != NULL);
> -    g_free(qobject_to_qint(obj));
> -}
> diff --git a/qobject/qjson.c b/qobject/qjson.c
> index b2f3bfec53..2e0930884e 100644
> --- a/qobject/qjson.c
> +++ b/qobject/qjson.c
> @@ -132,12 +132,11 @@ static void to_json(const QObject *obj, QString *str, int pretty, int indent)
>      case QTYPE_QNULL:
>          qstring_append(str, "null");
>          break;
> -    case QTYPE_QINT: {
> -        QInt *val = qobject_to_qint(obj);
> -        char buffer[1024];
> -
> -        snprintf(buffer, sizeof(buffer), "%" PRId64, qint_get_int(val));
> +    case QTYPE_QNUM: {
> +        QNum *val = qobject_to_qnum(obj);
> +        char *buffer = qnum_to_string(val);
>          qstring_append(str, buffer);
> +        g_free(buffer);
>          break;
>      }
>      case QTYPE_QSTRING: {
> @@ -234,34 +233,6 @@ static void to_json(const QObject *obj, QString *str, int pretty, int indent)
>          qstring_append(str, "]");
>          break;
>      }
> -    case QTYPE_QFLOAT: {
> -        QFloat *val = qobject_to_qfloat(obj);
> -        char buffer[1024];
> -        int len;
> -
> -        /* FIXME: snprintf() is locale dependent; but JSON requires
> -         * numbers to be formatted as if in the C locale. Dependence
> -         * on C locale is a pervasive issue in QEMU. */
> -        /* FIXME: This risks printing Inf or NaN, which are not valid
> -         * JSON values. */
> -        /* FIXME: the default precision of 6 for %f often causes
> -         * rounding errors; we should be using DBL_DECIMAL_DIG (17),
> -         * and only rounding to a shorter number if the result would
> -         * still produce the same floating point value.  */
> -        len = snprintf(buffer, sizeof(buffer), "%f", qfloat_get_double(val));
> -        while (len > 0 && buffer[len - 1] == '0') {
> -            len--;
> -        }
> -
> -        if (len && buffer[len - 1] == '.') {
> -            buffer[len - 1] = 0;
> -        } else {
> -            buffer[len] = 0;
> -        }
> -
> -        qstring_append(str, buffer);
> -        break;
> -    }
>      case QTYPE_QBOOL: {
>          QBool *val = qobject_to_qbool(obj);
>  
> diff --git a/qobject/qnum.c b/qobject/qnum.c
> new file mode 100644
> index 0000000000..f16864160a
> --- /dev/null
> +++ b/qobject/qnum.c
> @@ -0,0 +1,141 @@
> +/*
> + * QNum Module
> + *
> + * Copyright (C) 2009 Red Hat Inc.
> + *
> + * Authors:
> + *  Luiz Capitulino <lcapitulino@redhat.com>
> + *  Marc-André Lureau <marcandre.lureau@redhat.com>
> + *
> + * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
> + * See the COPYING.LIB file in the top-level directory.
> + */
> +
> +#include "qemu/osdep.h"
> +#include "qapi/error.h"
> +#include "qapi/qmp/qnum.h"
> +#include "qapi/qmp/qobject.h"
> +#include "qemu-common.h"
> +
> +/**
> + * qnum_from_int(): Create a new QNum from an int64_t
> + *
> + * Return strong reference.
> + */
> +QNum *qnum_from_int(int64_t value)
> +{
> +    QNum *qn = g_new(QNum, 1);
> +
> +    qobject_init(QOBJECT(qn), QTYPE_QNUM);
> +    qn->kind = QNUM_I64;
> +    qn->u.i64 = value;
> +
> +    return qn;
> +}
> +
> +/**
> + * qnum_from_double(): Create a new QNum from a double
> + *
> + * Return strong reference.
> + */
> +QNum *qnum_from_double(double value)
> +{
> +    QNum *qn = g_new(QNum, 1);
> +
> +    qobject_init(QOBJECT(qn), QTYPE_QNUM);
> +    qn->kind = QNUM_DOUBLE;
> +    qn->u.dbl = value;
> +
> +    return qn;
> +}
> +
> +/**
> + * qnum_get_int(): Get an integer representation of the number
> + *
> + * Return true on success.
> + */
> +bool qnum_get_int(const QNum *qn, int64_t *val)
> +{
> +    switch (qn->kind) {
> +    case QNUM_I64:
> +        *val = qn->u.i64;
> +        return true;
> +    case QNUM_DOUBLE:
> +        return false;
> +    }
> +
> +    g_assert_not_reached();

Please stick to plain assert() in qapi/ for now.

> +    return false;
> +}
> +
> +/**
> + * qnum_get_double(): Get a float representation of the number
> + */
> +double qnum_get_double(QNum *qn)
> +{
> +    switch (qn->kind) {
> +    case QNUM_I64:
> +        return qn->u.i64;
> +    case QNUM_DOUBLE:
> +        return qn->u.dbl;
> +    }
> +
> +    g_assert_not_reached();
> +}
> +
> +char *qnum_to_string(QNum *qn)
> +{
> +    char *buffer;
> +    int len;
> +
> +    switch (qn->kind) {
> +    case QNUM_I64:
> +        return g_strdup_printf("%" PRId64, qn->u.i64);
> +    case QNUM_DOUBLE:
> +        /* FIXME: snprintf() is locale dependent; but JSON requires
> +         * numbers to be formatted as if in the C locale. Dependence
> +         * on C locale is a pervasive issue in QEMU. */
> +        /* FIXME: This risks printing Inf or NaN, which are not valid
> +         * JSON values. */
> +        /* FIXME: the default precision of 6 for %f often causes
> +         * rounding errors; we should be using DBL_DECIMAL_DIG (17),
> +         * and only rounding to a shorter number if the result would
> +         * still produce the same floating point value.  */
> +        buffer = g_strdup_printf("%f" , qn->u.dbl);
> +        len = strlen(buffer);
> +        while (len > 0 && buffer[len - 1] == '0') {
> +            len--;
> +        }
> +
> +        if (len && buffer[len - 1] == '.') {
> +            buffer[len - 1] = 0;
> +        } else {
> +            buffer[len] = 0;
> +        }
> +
> +        return buffer;
> +    }
> +
> +    g_assert_not_reached();
> +}
> +
> +/**
> + * qobject_to_qnum(): Convert a QObject into a QNum
> + */
> +QNum *qobject_to_qnum(const QObject *obj)
> +{
> +    if (!obj || qobject_type(obj) != QTYPE_QNUM) {
> +        return NULL;
> +    }
> +    return container_of(obj, QNum, base);
> +}
> +
> +/**
> + * qnum_destroy_obj(): Free all memory allocated by a
> + * QNum object
> + */
> +void qnum_destroy_obj(QObject *obj)
> +{
> +    assert(obj != NULL);
> +    g_free(qobject_to_qnum(obj));
> +}
> diff --git a/qobject/qobject.c b/qobject/qobject.c
> index fe4fa10989..b0cafb66f1 100644
> --- a/qobject/qobject.c
> +++ b/qobject/qobject.c
> @@ -14,11 +14,10 @@
>  static void (*qdestroy[QTYPE__MAX])(QObject *) = {
>      [QTYPE_NONE] = NULL,               /* No such object exists */
>      [QTYPE_QNULL] = NULL,              /* qnull_ is indestructible */
> -    [QTYPE_QINT] = qint_destroy_obj,
> +    [QTYPE_QNUM] = qnum_destroy_obj,
>      [QTYPE_QSTRING] = qstring_destroy_obj,
>      [QTYPE_QDICT] = qdict_destroy_obj,
>      [QTYPE_QLIST] = qlist_destroy_obj,
> -    [QTYPE_QFLOAT] = qfloat_destroy_obj,
>      [QTYPE_QBOOL] = qbool_destroy_obj,
>  };
>  
> diff --git a/qom/object.c b/qom/object.c
> index c7b8079df6..cf0e64a625 100644
> --- a/qom/object.c
> +++ b/qom/object.c
> @@ -27,7 +27,6 @@
>  #include "qom/qom-qobject.h"
>  #include "qapi/qmp/qobject.h"
>  #include "qapi/qmp/qbool.h"
> -#include "qapi/qmp/qint.h"
>  #include "qapi/qmp/qstring.h"
>  
>  #define MAX_INTERFACES 32
> @@ -1190,28 +1189,27 @@ bool object_property_get_bool(Object *obj, const char *name,
>  void object_property_set_int(Object *obj, int64_t value,
>                               const char *name, Error **errp)
>  {
> -    QInt *qint = qint_from_int(value);
> -    object_property_set_qobject(obj, QOBJECT(qint), name, errp);
> +    QNum *qnum = qnum_from_int(value);
> +    object_property_set_qobject(obj, QOBJECT(qnum), name, errp);
>  
> -    QDECREF(qint);
> +    QDECREF(qnum);
>  }
>  
>  int64_t object_property_get_int(Object *obj, const char *name,
>                                  Error **errp)
>  {
>      QObject *ret = object_property_get_qobject(obj, name, errp);
> -    QInt *qint;
> +    QNum *qnum;
>      int64_t retval;
>  
>      if (!ret) {
>          return -1;
>      }
> -    qint = qobject_to_qint(ret);
> -    if (!qint) {
> +
> +    qnum = qobject_to_qnum(ret);
> +    if (!qnum || !qnum_get_int(qnum, &retval)) {
>          error_setg(errp, QERR_INVALID_PARAMETER_TYPE, name, "int");
>          retval = -1;
> -    } else {
> -        retval = qint_get_int(qint);
>      }
>  
>      qobject_decref(ret);
> diff --git a/target/i386/cpu.c b/target/i386/cpu.c
> index a41d595c23..12882f0774 100644
> --- a/target/i386/cpu.c
> +++ b/target/i386/cpu.c
> @@ -29,11 +29,7 @@
>  #include "qemu/option.h"
>  #include "qemu/config-file.h"
>  #include "qapi/qmp/qerror.h"
> -#include "qapi/qmp/qstring.h"
> -#include "qapi/qmp/qdict.h"
> -#include "qapi/qmp/qbool.h"
> -#include "qapi/qmp/qint.h"
> -#include "qapi/qmp/qfloat.h"
> +#include "qapi/qmp/types.h"
>  
>  #include "qapi-types.h"
>  #include "qapi-visit.h"

You seem to have missed the second part of my review,
Message-ID: <874lwqjzjl.fsf@dusky.pond.sub.org>.  No big deal, I simply
copy the comments that still apply.

> diff --git a/tests/check-qdict.c b/tests/check-qdict.c
> index be8d81f07b..5c70490e83 100644
> --- a/tests/check-qdict.c
> +++ b/tests/check-qdict.c
> @@ -11,7 +11,6 @@
>   */
>  #include "qemu/osdep.h"
>  
> -#include "qapi/qmp/qint.h"
>  #include "qapi/qmp/qdict.h"
>  #include "qapi/qmp/qstring.h"
>  #include "qapi/error.h"
> @@ -39,10 +38,11 @@ static void qdict_new_test(void)
>  
>  static void qdict_put_obj_test(void)
>  {
> -    QInt *qi;
> +    QNum *qi;
>      QDict *qdict;
>      QDictEntry *ent;
>      const int num = 42;
> +    int64_t val;
>  
>      qdict = qdict_new();
>  
> @@ -51,8 +51,9 @@ static void qdict_put_obj_test(void)
>  
>      g_assert(qdict_size(qdict) == 1);
>      ent = QLIST_FIRST(&qdict->table[12345 % QDICT_BUCKET_MAX]);
> -    qi = qobject_to_qint(ent->value);
> -    g_assert(qint_get_int(qi) == num);
> +    qi = qobject_to_qnum(ent->value);
> +    g_assert(qnum_get_int(qi, &val));
> +    g_assert_cmpint(val, ==, num);

This is a variation of the pattern I noted above.  It occurs many, many
times.  I believe the proposed helper would ease review.

>  
>      // destroy doesn't exit yet
>      QDECREF(qi);

Since you're touching three out of four lines containing @qi anyway:
rename it to @qn?  You rename like that in some places, but not all.

> @@ -74,19 +75,21 @@ static void qdict_destroy_simple_test(void)
>  
>  static void qdict_get_test(void)
>  {
> -    QInt *qi;
> +    QNum *qi;
>      QObject *obj;
>      const int value = -42;
>      const char *key = "test";
>      QDict *tests_dict = qdict_new();
> +    int64_t val;
>  
>      qdict_put_int(tests_dict, key, value);
>  
>      obj = qdict_get(tests_dict, key);
>      g_assert(obj != NULL);
>  
> -    qi = qobject_to_qint(obj);
> -    g_assert(qint_get_int(qi) == value);
> +    qi = qobject_to_qnum(obj);
> +    g_assert(qnum_get_int(qi, &val));
> +    g_assert_cmpint(val, ==, value);
>  
>      QDECREF(tests_dict);
>  }
> @@ -329,8 +332,9 @@ static void qdict_array_split_test(void)
>  {
>      QDict *test_dict = qdict_new();
>      QDict *dict1, *dict2;
> -    QInt *int1;
> +    QNum *int1;
>      QList *test_list;
> +    int64_t val;
>  
>      /*
>       * Test the split of
> @@ -380,7 +384,7 @@ static void qdict_array_split_test(void)
>  
>      dict1 = qobject_to_qdict(qlist_pop(test_list));
>      dict2 = qobject_to_qdict(qlist_pop(test_list));
> -    int1 = qobject_to_qint(qlist_pop(test_list));
> +    int1 = qobject_to_qnum(qlist_pop(test_list));
>  
>      g_assert(dict1);
>      g_assert(dict2);
> @@ -402,7 +406,8 @@ static void qdict_array_split_test(void)
>  
>      QDECREF(dict2);
>  
> -    g_assert(qint_get_int(int1) == 66);
> +    g_assert(qnum_get_int(int1, &val));
> +    g_assert_cmpint(val, ==, 66);
>  
>      QDECREF(int1);
>  
> @@ -447,14 +452,15 @@ static void qdict_array_split_test(void)
>  
>      qdict_array_split(test_dict, &test_list);
>  
> -    int1 = qobject_to_qint(qlist_pop(test_list));
> +    int1 = qobject_to_qnum(qlist_pop(test_list));
>  
>      g_assert(int1);
>      g_assert(qlist_empty(test_list));
>  
>      QDECREF(test_list);
>  
> -    g_assert(qint_get_int(int1) == 42);
> +    g_assert(qnum_get_int(int1, &val));
> +    g_assert_cmpint(val, ==, 42);
>  
>      QDECREF(int1);
>  
> diff --git a/tests/check-qfloat.c b/tests/check-qfloat.c
> deleted file mode 100644
> index 1da2cdae08..0000000000
> --- a/tests/check-qfloat.c
> +++ /dev/null
> @@ -1,53 +0,0 @@
> -/*
> - * QFloat unit-tests.
> - *
> - * Copyright IBM, Corp. 2009
> - *
> - * Authors:
> - *  Anthony Liguori   <aliguori@us.ibm.com>
> - *
> - * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
> - * See the COPYING.LIB file in the top-level directory.
> - *
> - */
> -#include "qemu/osdep.h"
> -
> -#include "qapi/qmp/qfloat.h"
> -#include "qemu-common.h"
> -
> -/*
> - * Public Interface test-cases
> - *
> - * (with some violations to access 'private' data)
> - */
> -
> -static void qfloat_from_double_test(void)
> -{
> -    QFloat *qf;
> -    const double value = -42.23423;
> -
> -    qf = qfloat_from_double(value);
> -    g_assert(qf != NULL);
> -    g_assert(qf->value == value);
> -    g_assert(qf->base.refcnt == 1);
> -    g_assert(qobject_type(QOBJECT(qf)) == QTYPE_QFLOAT);
> -
> -    // destroy doesn't exit yet
> -    g_free(qf);
> -}
> -
> -static void qfloat_destroy_test(void)
> -{
> -    QFloat *qf = qfloat_from_double(0.0);
> -    QDECREF(qf);
> -}
> -
> -int main(int argc, char **argv)
> -{
> -    g_test_init(&argc, &argv, NULL);
> -
> -    g_test_add_func("/public/from_double", qfloat_from_double_test);
> -    g_test_add_func("/public/destroy", qfloat_destroy_test);
> -
> -    return g_test_run();
> -}
> diff --git a/tests/check-qint.c b/tests/check-qint.c
> deleted file mode 100644
> index b6e4555115..0000000000
> --- a/tests/check-qint.c
> +++ /dev/null
> @@ -1,87 +0,0 @@
> -/*
> - * QInt unit-tests.
> - *
> - * Copyright (C) 2009 Red Hat Inc.
> - *
> - * Authors:
> - *  Luiz Capitulino <lcapitulino@redhat.com>
> - *
> - * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
> - * See the COPYING.LIB file in the top-level directory.
> - */
> -#include "qemu/osdep.h"
> -
> -#include "qapi/qmp/qint.h"
> -#include "qemu-common.h"
> -
> -/*
> - * Public Interface test-cases
> - *
> - * (with some violations to access 'private' data)
> - */
> -
> -static void qint_from_int_test(void)
> -{
> -    QInt *qi;
> -    const int value = -42;
> -
> -    qi = qint_from_int(value);
> -    g_assert(qi != NULL);
> -    g_assert(qi->value == value);
> -    g_assert(qi->base.refcnt == 1);
> -    g_assert(qobject_type(QOBJECT(qi)) == QTYPE_QINT);
> -
> -    // destroy doesn't exit yet
> -    g_free(qi);
> -}
> -
> -static void qint_destroy_test(void)
> -{
> -    QInt *qi = qint_from_int(0);
> -    QDECREF(qi);
> -}
> -
> -static void qint_from_int64_test(void)
> -{
> -    QInt *qi;
> -    const int64_t value = 0x1234567890abcdefLL;
> -
> -    qi = qint_from_int(value);
> -    g_assert((int64_t) qi->value == value);
> -
> -    QDECREF(qi);
> -}
> -
> -static void qint_get_int_test(void)
> -{
> -    QInt *qi;
> -    const int value = 123456;
> -
> -    qi = qint_from_int(value);
> -    g_assert(qint_get_int(qi) == value);
> -
> -    QDECREF(qi);
> -}
> -
> -static void qobject_to_qint_test(void)
> -{
> -    QInt *qi;
> -
> -    qi = qint_from_int(0);
> -    g_assert(qobject_to_qint(QOBJECT(qi)) == qi);
> -
> -    QDECREF(qi);
> -}
> -
> -int main(int argc, char **argv)
> -{
> -    g_test_init(&argc, &argv, NULL);
> -
> -    g_test_add_func("/public/from_int", qint_from_int_test);
> -    g_test_add_func("/public/destroy", qint_destroy_test);
> -    g_test_add_func("/public/from_int64", qint_from_int64_test);
> -    g_test_add_func("/public/get_int", qint_get_int_test);
> -    g_test_add_func("/public/to_qint", qobject_to_qint_test);
> -
> -    return g_test_run();
> -}
> diff --git a/tests/check-qjson.c b/tests/check-qjson.c
> index 963dd46f07..8ec728a702 100644
> --- a/tests/check-qjson.c
> +++ b/tests/check-qjson.c
> @@ -886,21 +886,23 @@ static void simple_number(void)
>      };
>  
>      for (i = 0; test_cases[i].encoded; i++) {
> -        QInt *qint;
> +        QNum *qnum;
> +        int64_t val;
>  
> -        qint = qobject_to_qint(qobject_from_json(test_cases[i].encoded,
> +        qnum = qobject_to_qnum(qobject_from_json(test_cases[i].encoded,
>                                                   &error_abort));
> -        g_assert(qint);
> -        g_assert(qint_get_int(qint) == test_cases[i].decoded);
> +        g_assert(qnum);
> +        g_assert(qnum_get_int(qnum, &val));
> +        g_assert_cmpint(val, ==, test_cases[i].decoded);
>          if (test_cases[i].skip == 0) {
>              QString *str;
>  
> -            str = qobject_to_json(QOBJECT(qint));
> +            str = qobject_to_json(QOBJECT(qnum));
>              g_assert(strcmp(qstring_get_str(str), test_cases[i].encoded) == 0);
>              QDECREF(str);
>          }
>  
> -        QDECREF(qint);
> +        QDECREF(qnum);
>      }
>  }
>  
> @@ -921,12 +923,12 @@ static void float_number(void)
>  
>      for (i = 0; test_cases[i].encoded; i++) {
>          QObject *obj;
> -        QFloat *qfloat;
> +        QNum *qnum;
>  
>          obj = qobject_from_json(test_cases[i].encoded, &error_abort);
> -        qfloat = qobject_to_qfloat(obj);
> -        g_assert(qfloat);
> -        g_assert(qfloat_get_double(qfloat) == test_cases[i].decoded);
> +        qnum = qobject_to_qnum(obj);
> +        g_assert(qnum);
> +        g_assert(qnum_get_double(qnum) == test_cases[i].decoded);
>  
>          if (test_cases[i].skip == 0) {
>              QString *str;
> @@ -936,29 +938,31 @@ static void float_number(void)
>              QDECREF(str);
>          }
>  
> -        QDECREF(qfloat);
> +        QDECREF(qnum);
>      }
>  }
>  
>  static void vararg_number(void)
>  {
> -    QInt *qint;
> -    QFloat *qfloat;
> +    QNum *qnum;
>      int value = 0x2342;
>      long long value_ll = 0x2342342343LL;
>      double valuef = 2.323423423;
> +    int64_t val;
>  
> -    qint = qobject_to_qint(qobject_from_jsonf("%d", value));
> -    g_assert(qint_get_int(qint) == value);
> -    QDECREF(qint);
> +    qnum = qobject_to_qnum(qobject_from_jsonf("%d", value));
> +    g_assert(qnum_get_int(qnum, &val));
> +    g_assert_cmpint(val, ==, value);
> +    QDECREF(qnum);
>  
> -    qint = qobject_to_qint(qobject_from_jsonf("%lld", value_ll));
> -    g_assert(qint_get_int(qint) == value_ll);
> -    QDECREF(qint);
> +    qnum = qobject_to_qnum(qobject_from_jsonf("%lld", value_ll));
> +    g_assert(qnum_get_int(qnum, &val));
> +    g_assert_cmpint(val, ==, value_ll);
> +    QDECREF(qnum);
>  
> -    qfloat = qobject_to_qfloat(qobject_from_jsonf("%f", valuef));
> -    g_assert(qfloat_get_double(qfloat) == valuef);
> -    QDECREF(qfloat);
> +    qnum = qobject_to_qnum(qobject_from_jsonf("%f", valuef));
> +    g_assert(qnum_get_double(qnum) == valuef);
> +    QDECREF(qnum);
>  }
>  
>  static void keyword_literal(void)
> @@ -1019,7 +1023,7 @@ struct LiteralQObject
>  {
>      int type;
>      union {
> -        int64_t qint;
> +        int64_t qnum;
>          const char *qstr;
>          LiteralQDictEntry *qdict;
>          LiteralQObject *qlist;
> @@ -1032,7 +1036,7 @@ struct LiteralQDictEntry
>      LiteralQObject value;
>  };
>  
> -#define QLIT_QINT(val) (LiteralQObject){.type = QTYPE_QINT, .value.qint = (val)}
> +#define QLIT_QNUM(val) (LiteralQObject){.type = QTYPE_QNUM, .value.qnum = (val)}
>  #define QLIT_QSTR(val) (LiteralQObject){.type = QTYPE_QSTRING, .value.qstr = (val)}
>  #define QLIT_QDICT(val) (LiteralQObject){.type = QTYPE_QDICT, .value.qdict = (val)}
>  #define QLIT_QLIST(val) (LiteralQObject){.type = QTYPE_QLIST, .value.qlist = (val)}

Aside: yet another private way to compare actual QObjects to expected
ones.  We should pick *one* way to compare, and stick to it.

> @@ -1064,13 +1068,16 @@ static void compare_helper(QObject *obj, void *opaque)
>  
>  static int compare_litqobj_to_qobj(LiteralQObject *lhs, QObject *rhs)
>  {
> +    int64_t val;
> +
>      if (!rhs || lhs->type != qobject_type(rhs)) {
>          return 0;
>      }
>  
>      switch (lhs->type) {
> -    case QTYPE_QINT:
> -        return lhs->value.qint == qint_get_int(qobject_to_qint(rhs));
> +    case QTYPE_QNUM:
> +        g_assert(qnum_get_int(qobject_to_qnum(rhs), &val));
> +        return lhs->value.qnum == val;
>      case QTYPE_QSTRING:
>          return (strcmp(lhs->value.qstr, qstring_get_str(qobject_to_qstring(rhs))) == 0);
>      case QTYPE_QDICT: {
> @@ -1114,7 +1121,7 @@ static void simple_dict(void)
>          {
>              .encoded = "{\"foo\": 42, \"bar\": \"hello world\"}",
>              .decoded = QLIT_QDICT(((LiteralQDictEntry[]){
> -                        { "foo", QLIT_QINT(42) },
> +                        { "foo", QLIT_QNUM(42) },
>                          { "bar", QLIT_QSTR("hello world") },
>                          { }
>                      })),
> @@ -1126,7 +1133,7 @@ static void simple_dict(void)
>          }, {
>              .encoded = "{\"foo\": 43}",
>              .decoded = QLIT_QDICT(((LiteralQDictEntry[]){
> -                        { "foo", QLIT_QINT(43) },
> +                        { "foo", QLIT_QNUM(43) },
>                          { }
>                      })),
>          },
> @@ -1212,15 +1219,15 @@ static void simple_list(void)
>          {
>              .encoded = "[43,42]",
>              .decoded = QLIT_QLIST(((LiteralQObject[]){
> -                        QLIT_QINT(43),
> -                        QLIT_QINT(42),
> +                        QLIT_QNUM(43),
> +                        QLIT_QNUM(42),
>                          { }
>                      })),
>          },
>          {
>              .encoded = "[43]",
>              .decoded = QLIT_QLIST(((LiteralQObject[]){
> -                        QLIT_QINT(43),
> +                        QLIT_QNUM(43),
>                          { }
>                      })),
>          },
> @@ -1269,35 +1276,35 @@ static void simple_whitespace(void)
>          {
>              .encoded = " [ 43 , 42 ]",
>              .decoded = QLIT_QLIST(((LiteralQObject[]){
> -                        QLIT_QINT(43),
> -                        QLIT_QINT(42),
> +                        QLIT_QNUM(43),
> +                        QLIT_QNUM(42),
>                          { }
>                      })),
>          },
>          {
>              .encoded = " [ 43 , { 'h' : 'b' }, [ ], 42 ]",
>              .decoded = QLIT_QLIST(((LiteralQObject[]){
> -                        QLIT_QINT(43),
> +                        QLIT_QNUM(43),
>                          QLIT_QDICT(((LiteralQDictEntry[]){
>                                      { "h", QLIT_QSTR("b") },
>                                      { }})),
>                          QLIT_QLIST(((LiteralQObject[]){
>                                      { }})),
> -                        QLIT_QINT(42),
> +                        QLIT_QNUM(42),
>                          { }
>                      })),
>          },
>          {
>              .encoded = " [ 43 , { 'h' : 'b' , 'a' : 32 }, [ ], 42 ]",
>              .decoded = QLIT_QLIST(((LiteralQObject[]){
> -                        QLIT_QINT(43),
> +                        QLIT_QNUM(43),
>                          QLIT_QDICT(((LiteralQDictEntry[]){
>                                      { "h", QLIT_QSTR("b") },
> -                                    { "a", QLIT_QINT(32) },
> +                                    { "a", QLIT_QNUM(32) },
>                                      { }})),
>                          QLIT_QLIST(((LiteralQObject[]){
>                                      { }})),
> -                        QLIT_QINT(42),
> +                        QLIT_QNUM(42),
>                          { }
>                      })),
>          },
> @@ -1327,11 +1334,11 @@ static void simple_varargs(void)
>      QObject *embedded_obj;
>      QObject *obj;
>      LiteralQObject decoded = QLIT_QLIST(((LiteralQObject[]){
> -            QLIT_QINT(1),
> -            QLIT_QINT(2),
> +            QLIT_QNUM(1),
> +            QLIT_QNUM(2),
>              QLIT_QLIST(((LiteralQObject[]){
> -                        QLIT_QINT(32),
> -                        QLIT_QINT(42),
> +                        QLIT_QNUM(32),
> +                        QLIT_QNUM(42),
>                          {}})),
>              {}}));
>  
> diff --git a/tests/check-qlist.c b/tests/check-qlist.c
> index 4983867c27..5bc8bb6756 100644
> --- a/tests/check-qlist.c
> +++ b/tests/check-qlist.c
> @@ -11,8 +11,8 @@
>   */
>  #include "qemu/osdep.h"
>  
> -#include "qapi/qmp/qint.h"
> -#include "qapi/qmp/qlist.h"
> +#include "qapi/error.h"
> +#include "qapi/qmp/types.h"

qapi/qmp/types.h is a lazy way to increase compile times by including
more than you need.  One day I'll kill it.  Until then, I tolerate it in
.c, but not in .h.  But I'd stick to just qlist.h and qnum.h here.

>  /*
>   * Public Interface test-cases
> @@ -35,11 +35,11 @@ static void qlist_new_test(void)
>  
>  static void qlist_append_test(void)
>  {
> -    QInt *qi;
> +    QNum *qi;
>      QList *qlist;
>      QListEntry *entry;
>  
> -    qi = qint_from_int(42);
> +    qi = qnum_from_int(42);
>  
>      qlist = qlist_new();
>      qlist_append(qlist, qi);
> @@ -84,13 +84,17 @@ static const int iter_max = 42;
>  
>  static void iter_func(QObject *obj, void *opaque)
>  {
> -    QInt *qi;
> +    QNum *qi;
> +    int64_t val;
>  
>      g_assert(opaque == NULL);
>  
> -    qi = qobject_to_qint(obj);
> +    qi = qobject_to_qnum(obj);
>      g_assert(qi != NULL);
> -    g_assert((qint_get_int(qi) >= 0) && (qint_get_int(qi) <= iter_max));
> +
> +    g_assert(qnum_get_int(qi, &val));
> +    g_assert_cmpint(val, >=, 0);
> +    g_assert_cmpint(val, <=, iter_max);
>  
>      iter_called++;
>  }
> diff --git a/tests/check-qnum.c b/tests/check-qnum.c
> new file mode 100644
> index 0000000000..4b3fec050e
> --- /dev/null
> +++ b/tests/check-qnum.c

Let's compare to the old check-qint.c and check-qfloat.c.

> @@ -0,0 +1,133 @@
> +/*
> + * QNum unit-tests.
> + *
> + * Copyright (C) 2009 Red Hat Inc.

Also merge check-qfloat.c's

    * Copyright IBM, Corp. 2009

here, and

> + *
> + * Authors:
> + *  Luiz Capitulino <lcapitulino@redhat.com>

    *  Anthony Liguori   <aliguori@us.ibm.com>

here.

> + *
> + * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
> + * See the COPYING.LIB file in the top-level directory.
> + */

Blank line here, please.

> +#include "qemu/osdep.h"
> +
> +#include "qapi/qmp/qnum.h"
> +#include "qapi/error.h"
> +#include "qemu-common.h"
> +
> +/*
> + * Public Interface test-cases
> + *
> + * (with some violations to access 'private' data)
> + */

I consider this comment close to useless.

> +
> +static void qnum_from_int_test(void)
> +{
> +    QNum *qi;
> +    const int value = -42;
> +
> +    qi = qnum_from_int(value);
> +    g_assert(qi != NULL);

       g_assert_cmpint(qi->type, ==, QNUM_I64);

> +    g_assert_cmpint(qi->u.i64, ==, value);
> +    g_assert_cmpint(qi->base.refcnt, ==, 1);
> +    g_assert_cmpint(qobject_type(QOBJECT(qi)), ==, QTYPE_QNUM);
> +
> +    // destroy doesn't exit yet
> +    g_free(qi);
> +}
> +
> +static void qnum_from_double_test(void)
> +{
> +    QNum *qf;
> +    const double value = -42.23423;
> +
> +    qf = qnum_from_double(value);
> +    g_assert(qf != NULL);

       g_assert_cmpint(qf->type, ==, QNUM_DOUBLE);

> +    g_assert_cmpfloat(qf->u.dbl, ==, value);
> +    g_assert_cmpint(qf->base.refcnt, ==, 1);
> +    g_assert_cmpint(qobject_type(QOBJECT(qf)), ==, QTYPE_QNUM);
> +
> +    // destroy doesn't exit yet
> +    g_free(qf);
> +}

Let's rename @qi and @qf to @qn.

> +
> +static void qnum_from_int64_test(void)
> +{
> +    QNum *qi;
> +    const int64_t value = 0x1234567890abcdefLL;
> +
> +    qi = qnum_from_int(value);
> +    g_assert_cmpint((int64_t) qi->u.i64, ==, value);
> +
> +    QDECREF(qi);
> +}
> +
> +static void qnum_get_int_test(void)
> +{
> +    QNum *qi;
> +    const int value = 123456;
> +    int64_t val;
> +
> +    qi = qnum_from_int(value);
> +    g_assert(qnum_get_int(qi, &val));
> +    g_assert_cmpint(val, ==, value);
> +
> +    QDECREF(qi);
> +}
> +
> +static void qobject_to_qnum_test(void)
> +{
> +    QNum *qn;
> +
> +    qn = qnum_from_int(0);
> +    g_assert(qobject_to_qnum(QOBJECT(qn)) == qn);
> +    QDECREF(qn);
> +
> +    qn = qnum_from_double(0);
> +    g_assert(qobject_to_qnum(QOBJECT(qn)) == qn);
> +    QDECREF(qn);
> +}

You added this one.  Makes sense, but announcing in the commit message
that you're also adding test cases wouldn't hurt.

> +
> +static void qnum_to_string_test(void)
> +{
> +    QNum *qn;
> +    char *tmp;
> +
> +    qn = qnum_from_int(123456);
> +    tmp = qnum_to_string(qn);
> +    g_assert_cmpstr(tmp, ==, "123456");
> +    g_free(tmp);
> +    QDECREF(qn);
> +
> +    qn = qnum_from_double(0.42);
> +    tmp = qnum_to_string(qn);
> +    g_assert_cmpstr(tmp, ==, "0.42");
> +    g_free(tmp);
> +    QDECREF(qn);
> +}

Also new.  Good.

Test coverage could use further improvement, but this will do for now.

> +
> +static void qnum_destroy_test(void)
> +{
> +    QNum *qn;
> +
> +    qn = qnum_from_int(0);
> +    QDECREF(qn);
> +
> +    qn = qnum_from_double(0.42);
> +    QDECREF(qn);
> +}
> +
> +int main(int argc, char **argv)
> +{
> +    g_test_init(&argc, &argv, NULL);
> +
> +    g_test_add_func("/qnum/from_int", qnum_from_int_test);
> +    g_test_add_func("/qnum/from_double", qnum_from_double_test);
> +    g_test_add_func("/qnum/destroy", qnum_destroy_test);
> +    g_test_add_func("/qnum/from_int64", qnum_from_int64_test);
> +    g_test_add_func("/qnum/get_int", qnum_get_int_test);
> +    g_test_add_func("/qnum/to_qnum", qobject_to_qnum_test);
> +    g_test_add_func("/qnum/to_string", qnum_to_string_test);
> +
> +    return g_test_run();
> +}
> diff --git a/tests/test-qmp-commands.c b/tests/test-qmp-commands.c
> index acdded4d67..9c69c98781 100644
> --- a/tests/test-qmp-commands.c
> +++ b/tests/test-qmp-commands.c
> @@ -162,7 +162,8 @@ static void test_dispatch_cmd_io(void)
>      QDict *ud1b = qdict_new();
>      QDict *ret, *ret_dict, *ret_dict_dict, *ret_dict_dict_userdef;
>      QDict *ret_dict_dict2, *ret_dict_dict2_userdef;
> -    QInt *ret3;
> +    QNum *ret3;
> +    int64_t val;
>  
>      qdict_put_int(ud1a, "integer", 42);
>      qdict_put_str(ud1a, "string", "hello");
> @@ -194,8 +195,9 @@ static void test_dispatch_cmd_io(void)
>      qdict_put(req, "arguments", args3);
>      qdict_put_str(req, "execute", "guest-get-time");
>  
> -    ret3 = qobject_to_qint(test_qmp_dispatch(req));
> -    assert(qint_get_int(ret3) == 66);
> +    ret3 = qobject_to_qnum(test_qmp_dispatch(req));
> +    g_assert(qnum_get_int(ret3, &val));
> +    g_assert_cmpint(val, ==, 66);
>      QDECREF(ret3);
>  
>      QDECREF(req);
> diff --git a/tests/test-qmp-event.c b/tests/test-qmp-event.c
> index 4c0f09601d..c6a5ff38d0 100644
> --- a/tests/test-qmp-event.c
> +++ b/tests/test-qmp-event.c
> @@ -18,7 +18,6 @@
>  #include "test-qapi-visit.h"
>  #include "test-qapi-event.h"
>  #include "qapi/qmp/types.h"
> -#include "qapi/qmp/qint.h"
>  #include "qapi/qmp/qobject.h"
>  #include "qapi/qmp-event.h"
>  
> @@ -41,6 +40,7 @@ void qdict_cmp_do_simple(const char *key, QObject *obj1, void *opaque)
>  {
>      QObject *obj2;
>      QDictCmpData d_new, *d = opaque;
> +    int64_t val1, val2;
>  
>      if (!d->result) {
>          return;
> @@ -62,9 +62,10 @@ void qdict_cmp_do_simple(const char *key, QObject *obj1, void *opaque)
>          d->result = (qbool_get_bool(qobject_to_qbool(obj1)) ==
>                       qbool_get_bool(qobject_to_qbool(obj2)));
>          return;
> -    case QTYPE_QINT:
> -        d->result = (qint_get_int(qobject_to_qint(obj1)) ==
> -                     qint_get_int(qobject_to_qint(obj2)));
> +    case QTYPE_QNUM:
> +        g_assert(qnum_get_int(qobject_to_qnum(obj1), &val1));
> +        g_assert(qnum_get_int(qobject_to_qnum(obj2), &val2));
> +        d->result = val1 == val2;
>          return;
>      case QTYPE_QSTRING:
>          d->result = g_strcmp0(qstring_get_str(qobject_to_qstring(obj1)),
> diff --git a/tests/test-qobject-input-visitor.c b/tests/test-qobject-input-visitor.c
> index f2ed3161af..e6757727fd 100644
> --- a/tests/test-qobject-input-visitor.c
> +++ b/tests/test-qobject-input-visitor.c
> @@ -164,7 +164,7 @@ static void test_visitor_in_int_overflow(TestInputVisitorData *data,
>      Visitor *v;
>  
>      /* this will overflow a Qint/int64, so should be deserialized into

s#a Qint/int64#an int64_t#
s#a QNum/double field#a double#

Or perhaps explain using QNUM_I64 and QNUM_DOUBLE.  Your choice.

> -     * a QFloat/double field instead, leading to an error if we pass it
> +     * a QNum/double field instead, leading to an error if we pass it
>       * to visit_type_int. confirm this.
>       */
>      v = visitor_input_test_init(data, "%f", DBL_MAX);
> @@ -466,17 +466,19 @@ static void test_visitor_in_any(TestInputVisitorData *data,
>  {
>      QObject *res = NULL;
>      Visitor *v;
> -    QInt *qint;
> +    QNum *qnum;
>      QBool *qbool;
>      QString *qstring;
>      QDict *qdict;
>      QObject *qobj;
> +    int64_t val;
>  
>      v = visitor_input_test_init(data, "-42");
>      visit_type_any(v, NULL, &res, &error_abort);
> -    qint = qobject_to_qint(res);
> -    g_assert(qint);
> -    g_assert_cmpint(qint_get_int(qint), ==, -42);
> +    qnum = qobject_to_qnum(res);
> +    g_assert(qnum);
> +    g_assert(qnum_get_int(qnum, &val));
> +    g_assert_cmpint(val, ==, -42);
>      qobject_decref(res);
>  
>      v = visitor_input_test_init(data, "{ 'integer': -42, 'boolean': true, 'string': 'foo' }");
> @@ -485,9 +487,10 @@ static void test_visitor_in_any(TestInputVisitorData *data,
>      g_assert(qdict && qdict_size(qdict) == 3);
>      qobj = qdict_get(qdict, "integer");
>      g_assert(qobj);
> -    qint = qobject_to_qint(qobj);
> -    g_assert(qint);
> -    g_assert_cmpint(qint_get_int(qint), ==, -42);
> +    qnum = qobject_to_qnum(qobj);
> +    g_assert(qnum);
> +    g_assert(qnum_get_int(qnum, &val));
> +    g_assert_cmpint(val, ==, -42);
>      qobj = qdict_get(qdict, "boolean");
>      g_assert(qobj);
>      qbool = qobject_to_qbool(qobj);
> @@ -565,7 +568,7 @@ static void test_visitor_in_alternate(TestInputVisitorData *data,
>  
>      v = visitor_input_test_init(data, "42");
>      visit_type_UserDefAlternate(v, NULL, &tmp, &error_abort);
> -    g_assert_cmpint(tmp->type, ==, QTYPE_QINT);
> +    g_assert_cmpint(tmp->type, ==, QTYPE_QNUM);
>      g_assert_cmpint(tmp->u.i, ==, 42);
>      qapi_free_UserDefAlternate(tmp);
>  
> @@ -593,7 +596,7 @@ static void test_visitor_in_alternate(TestInputVisitorData *data,
>  
>      v = visitor_input_test_init(data, "{ 'alt': 42 }");
>      visit_type_WrapAlternate(v, NULL, &wrap, &error_abort);
> -    g_assert_cmpint(wrap->alt->type, ==, QTYPE_QINT);
> +    g_assert_cmpint(wrap->alt->type, ==, QTYPE_QNUM);
>      g_assert_cmpint(wrap->alt->u.i, ==, 42);
>      qapi_free_WrapAlternate(wrap);
>  
> @@ -634,19 +637,19 @@ static void test_visitor_in_alternate_number(TestInputVisitorData *data,
>  
>      v = visitor_input_test_init(data, "42");
>      visit_type_AltEnumNum(v, NULL, &aen, &error_abort);
> -    g_assert_cmpint(aen->type, ==, QTYPE_QFLOAT);
> +    g_assert_cmpint(aen->type, ==, QTYPE_QNUM);
>      g_assert_cmpfloat(aen->u.n, ==, 42);
>      qapi_free_AltEnumNum(aen);
>  
>      v = visitor_input_test_init(data, "42");
>      visit_type_AltNumEnum(v, NULL, &ans, &error_abort);
> -    g_assert_cmpint(ans->type, ==, QTYPE_QFLOAT);
> +    g_assert_cmpint(ans->type, ==, QTYPE_QNUM);
>      g_assert_cmpfloat(ans->u.n, ==, 42);
>      qapi_free_AltNumEnum(ans);
>  
>      v = visitor_input_test_init(data, "42");
>      visit_type_AltEnumInt(v, NULL, &asi, &error_abort);
> -    g_assert_cmpint(asi->type, ==, QTYPE_QINT);
> +    g_assert_cmpint(asi->type, ==, QTYPE_QNUM);
>      g_assert_cmpint(asi->u.i, ==, 42);
>      qapi_free_AltEnumInt(asi);
>  
> @@ -659,13 +662,13 @@ static void test_visitor_in_alternate_number(TestInputVisitorData *data,
>  
>      v = visitor_input_test_init(data, "42.5");
>      visit_type_AltEnumNum(v, NULL, &aen, &error_abort);
> -    g_assert_cmpint(aen->type, ==, QTYPE_QFLOAT);
> +    g_assert_cmpint(aen->type, ==, QTYPE_QNUM);
>      g_assert_cmpfloat(aen->u.n, ==, 42.5);
>      qapi_free_AltEnumNum(aen);
>  
>      v = visitor_input_test_init(data, "42.5");
>      visit_type_AltNumEnum(v, NULL, &ans, &error_abort);
> -    g_assert_cmpint(ans->type, ==, QTYPE_QFLOAT);
> +    g_assert_cmpint(ans->type, ==, QTYPE_QNUM);
>      g_assert_cmpfloat(ans->u.n, ==, 42.5);
>      qapi_free_AltNumEnum(ans);
>  
> diff --git a/tests/test-qobject-output-visitor.c b/tests/test-qobject-output-visitor.c
> index 4e8fdf1397..3180d8cbde 100644
> --- a/tests/test-qobject-output-visitor.c
> +++ b/tests/test-qobject-output-visitor.c
> @@ -58,13 +58,15 @@ static void test_visitor_out_int(TestOutputVisitorData *data,
>                                   const void *unused)
>  {
>      int64_t value = -42;
> -    QInt *qint;
> +    int64_t val;
> +    QNum *qnum;
>  
>      visit_type_int(data->ov, NULL, &value, &error_abort);
>  
> -    qint = qobject_to_qint(visitor_get(data));
> -    g_assert(qint);
> -    g_assert_cmpint(qint_get_int(qint), ==, value);
> +    qnum = qobject_to_qnum(visitor_get(data));
> +    g_assert(qnum);
> +    g_assert(qnum_get_int(qnum, &val));
> +    g_assert_cmpint(val, ==, value);
>  }
>  
>  static void test_visitor_out_bool(TestOutputVisitorData *data,
> @@ -84,13 +86,13 @@ static void test_visitor_out_number(TestOutputVisitorData *data,
>                                      const void *unused)
>  {
>      double value = 3.14;
> -    QFloat *qfloat;
> +    QNum *qnum;
>  
>      visit_type_number(data->ov, NULL, &value, &error_abort);
>  
> -    qfloat = qobject_to_qfloat(visitor_get(data));
> -    g_assert(qfloat);
> -    g_assert(qfloat_get_double(qfloat) == value);
> +    qnum = qobject_to_qnum(visitor_get(data));
> +    g_assert(qnum);
> +    g_assert(qnum_get_double(qnum) == value);
>  }
>  
>  static void test_visitor_out_string(TestOutputVisitorData *data,
> @@ -329,16 +331,18 @@ static void test_visitor_out_any(TestOutputVisitorData *data,
>                                   const void *unused)
>  {
>      QObject *qobj;
> -    QInt *qint;
> +    QNum *qnum;
>      QBool *qbool;
>      QString *qstring;
>      QDict *qdict;
> +    int64_t val;
>  
> -    qobj = QOBJECT(qint_from_int(-42));
> +    qobj = QOBJECT(qnum_from_int(-42));
>      visit_type_any(data->ov, NULL, &qobj, &error_abort);
> -    qint = qobject_to_qint(visitor_get(data));
> -    g_assert(qint);
> -    g_assert_cmpint(qint_get_int(qint), ==, -42);
> +    qnum = qobject_to_qnum(visitor_get(data));
> +    g_assert(qnum);
> +    g_assert(qnum_get_int(qnum, &val));
> +    g_assert_cmpint(val, ==, -42);
>      qobject_decref(qobj);
>  
>      visitor_reset(data);
> @@ -351,9 +355,10 @@ static void test_visitor_out_any(TestOutputVisitorData *data,
>      qobject_decref(qobj);
>      qdict = qobject_to_qdict(visitor_get(data));
>      g_assert(qdict);
> -    qint = qobject_to_qint(qdict_get(qdict, "integer"));
> -    g_assert(qint);
> -    g_assert_cmpint(qint_get_int(qint), ==, -42);
> +    qnum = qobject_to_qnum(qdict_get(qdict, "integer"));
> +    g_assert(qnum);
> +    g_assert(qnum_get_int(qnum, &val));
> +    g_assert_cmpint(val, ==, -42);
>      qbool = qobject_to_qbool(qdict_get(qdict, "boolean"));
>      g_assert(qbool);
>      g_assert(qbool_get_bool(qbool) == true);
> @@ -388,18 +393,20 @@ static void test_visitor_out_alternate(TestOutputVisitorData *data,
>                                         const void *unused)
>  {
>      UserDefAlternate *tmp;
> -    QInt *qint;
> +    QNum *qnum;
>      QString *qstr;
>      QDict *qdict;
> +    int64_t val;
>  
>      tmp = g_new0(UserDefAlternate, 1);
> -    tmp->type = QTYPE_QINT;
> +    tmp->type = QTYPE_QNUM;
>      tmp->u.i = 42;
>  
>      visit_type_UserDefAlternate(data->ov, NULL, &tmp, &error_abort);
> -    qint = qobject_to_qint(visitor_get(data));
> -    g_assert(qint);
> -    g_assert_cmpint(qint_get_int(qint), ==, 42);
> +    qnum = qobject_to_qnum(visitor_get(data));
> +    g_assert(qnum);
> +    g_assert(qnum_get_int(qnum, &val));
> +    g_assert_cmpint(val, ==, 42);
>  
>      qapi_free_UserDefAlternate(tmp);
>  
> @@ -603,18 +610,21 @@ static void check_native_list(QObject *qobj,
>      case USER_DEF_NATIVE_LIST_UNION_KIND_U16:
>      case USER_DEF_NATIVE_LIST_UNION_KIND_U32:
>      case USER_DEF_NATIVE_LIST_UNION_KIND_U64:
> -        /* all integer elements in JSON arrays get stored into QInts when
> +        /* all integer elements in JSON arrays get stored into QNums when


Please use the opportunity to wing the comment at both ends and start
with a capital letter:

           /*
            * All integer ...

>           * we convert to QObjects, so we can check them all in the same
>           * fashion, so simply fall through here
>           */
>      case USER_DEF_NATIVE_LIST_UNION_KIND_INTEGER:
>          for (i = 0; i < 32; i++) {
>              QObject *tmp;
> -            QInt *qvalue;
> +            QNum *qvalue;
> +            int64_t val;
> +
>              tmp = qlist_peek(qlist);
>              g_assert(tmp);
> -            qvalue = qobject_to_qint(tmp);
> -            g_assert_cmpint(qint_get_int(qvalue), ==, i);
> +            qvalue = qobject_to_qnum(tmp);
> +            g_assert(qnum_get_int(qvalue, &val));
> +            g_assert_cmpint(val, ==, i);
>              qobject_decref(qlist_pop(qlist));
>          }
>          break;
> @@ -645,15 +655,15 @@ static void check_native_list(QObject *qobj,
>      case USER_DEF_NATIVE_LIST_UNION_KIND_NUMBER:
>          for (i = 0; i < 32; i++) {
>              QObject *tmp;
> -            QFloat *qvalue;
> +            QNum *qvalue;
>              GString *double_expected = g_string_new("");
>              GString *double_actual = g_string_new("");
>  
>              tmp = qlist_peek(qlist);
>              g_assert(tmp);
> -            qvalue = qobject_to_qfloat(tmp);
> +            qvalue = qobject_to_qnum(tmp);
>              g_string_printf(double_expected, "%.6f", (double)i / 3);
> -            g_string_printf(double_actual, "%.6f", qfloat_get_double(qvalue));
> +            g_string_printf(double_actual, "%.6f", qnum_get_double(qvalue));
>              g_assert_cmpstr(double_actual->str, ==, double_expected->str);
>  
>              qobject_decref(qlist_pop(qlist));
> diff --git a/tests/test-x86-cpuid-compat.c b/tests/test-x86-cpuid-compat.c
> index 6c71e46391..f30f2030a8 100644
> --- a/tests/test-x86-cpuid-compat.c
> +++ b/tests/test-x86-cpuid-compat.c
> @@ -1,10 +1,7 @@
>  #include "qemu/osdep.h"
>  #include "qemu-common.h"
> -#include "qapi/qmp/qlist.h"
> -#include "qapi/qmp/qstring.h"
> -#include "qapi/qmp/qdict.h"
> -#include "qapi/qmp/qint.h"
> -#include "qapi/qmp/qbool.h"
> +#include "qapi/error.h"
> +#include "qapi/qmp/types.h"

Previous note on qapi/qmp/types.h applies.

>  #include "libqtest.h"
>  
>  static char *get_cpu0_qom_path(void)
> @@ -57,12 +54,14 @@ static void test_cpuid_prop(const void *data)
>  {
>      const CpuidTestArgs *args = data;
>      char *path;
> -    QInt *value;
> +    QNum *value;
> +    int64_t val;
>  
>      qtest_start(args->cmdline);
>      path = get_cpu0_qom_path();
> -    value = qobject_to_qint(qom_get(path, args->property));
> -    g_assert_cmpint(qint_get_int(value), ==, args->expected_value);
> +    value = qobject_to_qnum(qom_get(path, args->property));
> +    g_assert(qnum_get_int(value, &val));
> +    g_assert_cmpint(val, ==, args->expected_value);
>      qtest_end();
>  
>      QDECREF(value);
> @@ -109,12 +108,15 @@ static uint32_t get_feature_word(QList *features, uint32_t eax, uint32_t ecx,
>          uint32_t reax = qdict_get_int(w, "cpuid-input-eax");
>          bool has_ecx = qdict_haskey(w, "cpuid-input-ecx");
>          uint32_t recx = 0;
> +        int64_t val;
>  
>          if (has_ecx) {
>              recx = qdict_get_int(w, "cpuid-input-ecx");
>          }
>          if (eax == reax && (!has_ecx || ecx == recx) && !strcmp(rreg, reg)) {
> -            return qint_get_int(qobject_to_qint(qdict_get(w, "features")));
> +            g_assert(qnum_get_int(qobject_to_qnum(qdict_get(w, "features")),
> +                                  &val));
> +            return val;
>          }
>      }
>      return 0;
> diff --git a/ui/spice-core.c b/ui/spice-core.c
> index 804abc5c0f..561d0649cf 100644
> --- a/ui/spice-core.c
> +++ b/ui/spice-core.c
> @@ -30,7 +30,6 @@
>  #include "qemu-x509.h"
>  #include "qemu/sockets.h"
>  #include "qmp-commands.h"
> -#include "qapi/qmp/qint.h"
>  #include "qapi/qmp/qbool.h"
>  #include "qapi/qmp/qstring.h"
>  #include "qapi/qmp/qjson.h"
> diff --git a/ui/vnc-enc-tight.c b/ui/vnc-enc-tight.c
> index 1e53b1cf84..89ab12c0d8 100644
> --- a/ui/vnc-enc-tight.c
> +++ b/ui/vnc-enc-tight.c
> @@ -44,7 +44,6 @@
>  #endif
>  
>  #include "qemu/bswap.h"
> -#include "qapi/qmp/qint.h"
>  #include "vnc.h"
>  #include "vnc-enc-tight.h"
>  #include "vnc-palette.h"
> diff --git a/util/qemu-option.c b/util/qemu-option.c
> index 5977bfc3e9..39b1e06225 100644
> --- a/util/qemu-option.c
> +++ b/util/qemu-option.c
> @@ -941,9 +941,8 @@ typedef struct OptsFromQDictState {
>  static void qemu_opts_from_qdict_1(const char *key, QObject *obj, void *opaque)
>  {
>      OptsFromQDictState *state = opaque;
> -    char buf[32];
> +    char buf[32], *tmp = NULL;
>      const char *value;
> -    int n;
>  
>      if (!strcmp(key, "id") || *state->errp) {
>          return;
> @@ -953,17 +952,9 @@ static void qemu_opts_from_qdict_1(const char *key, QObject *obj, void *opaque)
>      case QTYPE_QSTRING:
>          value = qstring_get_str(qobject_to_qstring(obj));
>          break;
> -    case QTYPE_QINT:
> -        n = snprintf(buf, sizeof(buf), "%" PRId64,
> -                     qint_get_int(qobject_to_qint(obj)));
> -        assert(n < sizeof(buf));
> -        value = buf;
> -        break;
> -    case QTYPE_QFLOAT:
> -        n = snprintf(buf, sizeof(buf), "%.17g",
> -                     qfloat_get_double(qobject_to_qfloat(obj)));
> -        assert(n < sizeof(buf));
> -        value = buf;
> +    case QTYPE_QNUM:
> +        tmp = qnum_to_string(qobject_to_qnum(obj));
> +        value = tmp;
>          break;
>      case QTYPE_QBOOL:
>          pstrcpy(buf, sizeof(buf),
> @@ -975,12 +966,13 @@ static void qemu_opts_from_qdict_1(const char *key, QObject *obj, void *opaque)
>      }
>  
>      qemu_opt_set(state->opts, key, value, state->errp);
> +    g_free(tmp);
>  }
>  
>  /*
>   * Create QemuOpts from a QDict.
>   * Use value of key "id" as ID if it exists and is a QString.
> - * Only QStrings, QInts, QFloats and QBools are copied.  Entries with
> + * Only QStrings, QNums and QBools are copied.  Entries with
>   * other types are silently ignored.
>   */

Refill the sentence, please.

>  QemuOpts *qemu_opts_from_qdict(QemuOptsList *list, const QDict *qdict,
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 7df088259b..b53054111a 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -1412,8 +1412,7 @@ F: include/qapi/qmp/
>  X: include/qapi/qmp/dispatch.h
>  F: scripts/coccinelle/qobject.cocci
>  F: tests/check-qdict.c
> -F: tests/check-qfloat.c
> -F: tests/check-qint.c
> +F: tests/check-qnum.c
>  F: tests/check-qjson.c
>  F: tests/check-qlist.c
>  F: tests/check-qstring.c
> diff --git a/qobject/Makefile.objs b/qobject/Makefile.objs
> index bed55084bb..fc8885c9a4 100644
> --- a/qobject/Makefile.objs
> +++ b/qobject/Makefile.objs
> @@ -1,2 +1,2 @@
> -util-obj-y = qnull.o qint.o qstring.o qdict.o qlist.o qfloat.o qbool.o
> +util-obj-y = qnull.o qnum.o qstring.o qdict.o qlist.o qbool.o
>  util-obj-y += qjson.o qobject.o json-lexer.o json-streamer.o json-parser.o
> diff --git a/scripts/coccinelle/qobject.cocci b/scripts/coccinelle/qobject.cocci
> index 97703a438b..c3253deb1b 100644
> --- a/scripts/coccinelle/qobject.cocci
> +++ b/scripts/coccinelle/qobject.cocci
> @@ -6,7 +6,7 @@ expression Obj, Key, E;
>  - qdict_put_obj(Obj, Key, QOBJECT(E));
>  + qdict_put(Obj, Key, E);
>  |
> -- qdict_put(Obj, Key, qint_from_int(E));
> +- qdict_put(Obj, Key, qnum_from_int(E));
>  + qdict_put_int(Obj, Key, E);
>  |
>  - qdict_put(Obj, Key, qbool_from_bool(E));
> @@ -24,7 +24,7 @@ expression Obj, E;
>  - qlist_append_obj(Obj, QOBJECT(E));
>  + qlist_append(Obj, E);
>  |
> -- qlist_append(Obj, qint_from_int(E));
> +- qlist_append(Obj, qnum_from_int(E));
>  + qlist_append_int(Obj, E);
>  |
>  - qlist_append(Obj, qbool_from_bool(E));
> diff --git a/tests/.gitignore b/tests/.gitignore
> index 40c2e3e757..8e01b004f1 100644
> --- a/tests/.gitignore
> +++ b/tests/.gitignore
> @@ -1,7 +1,6 @@
>  atomic_add-bench
>  check-qdict
> -check-qfloat
> -check-qint
> +check-qnum
>  check-qjson
>  check-qlist
>  check-qnull
> diff --git a/tests/Makefile.include b/tests/Makefile.include
> index f42f3dfa72..fec5af765a 100644
> --- a/tests/Makefile.include
> +++ b/tests/Makefile.include
> @@ -10,10 +10,8 @@ check-unit-y = tests/check-qdict$(EXESUF)
>  gcov-files-check-qdict-y = qobject/qdict.c
>  check-unit-y += tests/test-char$(EXESUF)
>  gcov-files-check-qdict-y = chardev/char.c
> -check-unit-y += tests/check-qfloat$(EXESUF)
> -gcov-files-check-qfloat-y = qobject/qfloat.c
> -check-unit-y += tests/check-qint$(EXESUF)
> -gcov-files-check-qint-y = qobject/qint.c
> +check-unit-y += tests/check-qnum$(EXESUF)
> +gcov-files-check-qnum-y = qobject/qnum.c
>  check-unit-y += tests/check-qstring$(EXESUF)
>  gcov-files-check-qstring-y = qobject/qstring.c
>  check-unit-y += tests/check-qlist$(EXESUF)
> @@ -506,8 +504,8 @@ GENERATED_FILES += tests/test-qapi-types.h tests/test-qapi-visit.h \
>  	tests/test-qmp-commands.h tests/test-qapi-event.h \
>  	tests/test-qmp-introspect.h
>  
> -test-obj-y = tests/check-qint.o tests/check-qstring.o tests/check-qdict.o \
> -	tests/check-qlist.o tests/check-qfloat.o tests/check-qnull.o \
> +test-obj-y = tests/check-qnum.o tests/check-qstring.o tests/check-qdict.o \
> +	tests/check-qlist.o tests/check-qnull.o \
>  	tests/check-qjson.o \
>  	tests/test-coroutine.o tests/test-string-output-visitor.o \
>  	tests/test-string-input-visitor.o tests/test-qobject-output-visitor.o \
> @@ -535,11 +533,10 @@ test-crypto-obj-y = $(crypto-obj-y) $(test-qom-obj-y)
>  test-io-obj-y = $(io-obj-y) $(test-crypto-obj-y)
>  test-block-obj-y = $(block-obj-y) $(test-io-obj-y) tests/iothread.o
>  
> -tests/check-qint$(EXESUF): tests/check-qint.o $(test-util-obj-y)
> +tests/check-qnum$(EXESUF): tests/check-qnum.o $(test-util-obj-y)
>  tests/check-qstring$(EXESUF): tests/check-qstring.o $(test-util-obj-y)
>  tests/check-qdict$(EXESUF): tests/check-qdict.o $(test-util-obj-y)
>  tests/check-qlist$(EXESUF): tests/check-qlist.o $(test-util-obj-y)
> -tests/check-qfloat$(EXESUF): tests/check-qfloat.o $(test-util-obj-y)
>  tests/check-qnull$(EXESUF): tests/check-qnull.o $(test-util-obj-y)
>  tests/check-qjson$(EXESUF): tests/check-qjson.o $(test-util-obj-y)
>  tests/check-qom-interface$(EXESUF): tests/check-qom-interface.o $(test-qom-obj-y)
> diff --git a/tests/qapi-schema/comments.out b/tests/qapi-schema/comments.out
> index 5d7c13cad1..17e652535c 100644
> --- a/tests/qapi-schema/comments.out
> +++ b/tests/qapi-schema/comments.out
> @@ -1,4 +1,4 @@
> -enum QType ['none', 'qnull', 'qint', 'qstring', 'qdict', 'qlist', 'qfloat', 'qbool']
> +enum QType ['none', 'qnull', 'qnum', 'qstring', 'qdict', 'qlist', 'qbool']
>      prefix QTYPE
>  enum Status ['good', 'bad', 'ugly']
>  object q_empty
> diff --git a/tests/qapi-schema/doc-good.out b/tests/qapi-schema/doc-good.out
> index 70c1252408..63ca25a8b9 100644
> --- a/tests/qapi-schema/doc-good.out
> +++ b/tests/qapi-schema/doc-good.out
> @@ -6,7 +6,7 @@ object Object
>      tag base1
>      case one: Variant1
>      case two: Variant2
> -enum QType ['none', 'qnull', 'qint', 'qstring', 'qdict', 'qlist', 'qfloat', 'qbool']
> +enum QType ['none', 'qnull', 'qnum', 'qstring', 'qdict', 'qlist', 'qbool']
>      prefix QTYPE
>  object SugaredUnion
>      member type: SugaredUnionKind optional=False
> diff --git a/tests/qapi-schema/empty.out b/tests/qapi-schema/empty.out
> index 8a5b034424..40b886ddae 100644
> --- a/tests/qapi-schema/empty.out
> +++ b/tests/qapi-schema/empty.out
> @@ -1,3 +1,3 @@
> -enum QType ['none', 'qnull', 'qint', 'qstring', 'qdict', 'qlist', 'qfloat', 'qbool']
> +enum QType ['none', 'qnull', 'qnum', 'qstring', 'qdict', 'qlist', 'qbool']
>      prefix QTYPE
>  object q_empty
> diff --git a/tests/qapi-schema/event-case.out b/tests/qapi-schema/event-case.out
> index 5a0f2bf805..313c0fe7be 100644
> --- a/tests/qapi-schema/event-case.out
> +++ b/tests/qapi-schema/event-case.out
> @@ -1,4 +1,4 @@
> -enum QType ['none', 'qnull', 'qint', 'qstring', 'qdict', 'qlist', 'qfloat', 'qbool']
> +enum QType ['none', 'qnull', 'qnum', 'qstring', 'qdict', 'qlist', 'qbool']
>      prefix QTYPE
>  event oops None
>     boxed=False
> diff --git a/tests/qapi-schema/ident-with-escape.out b/tests/qapi-schema/ident-with-escape.out
> index 1d2722c02e..b5637cb2e0 100644
> --- a/tests/qapi-schema/ident-with-escape.out
> +++ b/tests/qapi-schema/ident-with-escape.out
> @@ -1,4 +1,4 @@
> -enum QType ['none', 'qnull', 'qint', 'qstring', 'qdict', 'qlist', 'qfloat', 'qbool']
> +enum QType ['none', 'qnull', 'qnum', 'qstring', 'qdict', 'qlist', 'qbool']
>      prefix QTYPE
>  command fooA q_obj_fooA-arg -> None
>     gen=True success_response=True boxed=False
> diff --git a/tests/qapi-schema/include-relpath.out b/tests/qapi-schema/include-relpath.out
> index 5d7c13cad1..17e652535c 100644
> --- a/tests/qapi-schema/include-relpath.out
> +++ b/tests/qapi-schema/include-relpath.out
> @@ -1,4 +1,4 @@
> -enum QType ['none', 'qnull', 'qint', 'qstring', 'qdict', 'qlist', 'qfloat', 'qbool']
> +enum QType ['none', 'qnull', 'qnum', 'qstring', 'qdict', 'qlist', 'qbool']
>      prefix QTYPE
>  enum Status ['good', 'bad', 'ugly']
>  object q_empty
> diff --git a/tests/qapi-schema/include-repetition.out b/tests/qapi-schema/include-repetition.out
> index 5d7c13cad1..17e652535c 100644
> --- a/tests/qapi-schema/include-repetition.out
> +++ b/tests/qapi-schema/include-repetition.out
> @@ -1,4 +1,4 @@
> -enum QType ['none', 'qnull', 'qint', 'qstring', 'qdict', 'qlist', 'qfloat', 'qbool']
> +enum QType ['none', 'qnull', 'qnum', 'qstring', 'qdict', 'qlist', 'qbool']
>      prefix QTYPE
>  enum Status ['good', 'bad', 'ugly']
>  object q_empty
> diff --git a/tests/qapi-schema/include-simple.out b/tests/qapi-schema/include-simple.out
> index 5d7c13cad1..17e652535c 100644
> --- a/tests/qapi-schema/include-simple.out
> +++ b/tests/qapi-schema/include-simple.out
> @@ -1,4 +1,4 @@
> -enum QType ['none', 'qnull', 'qint', 'qstring', 'qdict', 'qlist', 'qfloat', 'qbool']
> +enum QType ['none', 'qnull', 'qnum', 'qstring', 'qdict', 'qlist', 'qbool']
>      prefix QTYPE
>  enum Status ['good', 'bad', 'ugly']
>  object q_empty
> diff --git a/tests/qapi-schema/indented-expr.out b/tests/qapi-schema/indented-expr.out
> index e8171c935f..586795f44d 100644
> --- a/tests/qapi-schema/indented-expr.out
> +++ b/tests/qapi-schema/indented-expr.out
> @@ -1,4 +1,4 @@
> -enum QType ['none', 'qnull', 'qint', 'qstring', 'qdict', 'qlist', 'qfloat', 'qbool']
> +enum QType ['none', 'qnull', 'qnum', 'qstring', 'qdict', 'qlist', 'qbool']
>      prefix QTYPE
>  command eins None -> None
>     gen=True success_response=True boxed=False
> diff --git a/tests/qapi-schema/qapi-schema-test.out b/tests/qapi-schema/qapi-schema-test.out
> index e727a5a84c..b88b8aae6f 100644
> --- a/tests/qapi-schema/qapi-schema-test.out
> +++ b/tests/qapi-schema/qapi-schema-test.out
> @@ -50,7 +50,7 @@ object NestedEnumsOne
>      member enum4: EnumOne optional=True
>  enum QEnumTwo ['value1', 'value2']
>      prefix QENUM_TWO
> -enum QType ['none', 'qnull', 'qint', 'qstring', 'qdict', 'qlist', 'qfloat', 'qbool']
> +enum QType ['none', 'qnull', 'qnum', 'qstring', 'qdict', 'qlist', 'qbool']
>      prefix QTYPE
>  object TestStruct
>      member integer: int optional=False

^ permalink raw reply	[flat|nested] 80+ messages in thread

* Re: [Qemu-devel] [PATCH v2 10/45] qapi: Remove visit_start_alternate() parameter promote_int
  2017-05-31 13:56 ` [Qemu-devel] [PATCH v2 10/45] qapi: Remove visit_start_alternate() parameter promote_int Marc-André Lureau
@ 2017-06-02  7:57   ` Markus Armbruster
  0 siblings, 0 replies; 80+ messages in thread
From: Markus Armbruster @ 2017-06-02  7:57 UTC (permalink / raw)
  To: Marc-André Lureau; +Cc: qemu-devel

Marc-André Lureau <marcandre.lureau@redhat.com> writes:

> Before the previous commit, parameter promote_int = true made
> visit_start_alternate() with an input visitor avoid QTYPE_QINT
> variants and create QTYPE_QFLOAT variants instead.  This was used
> where QTYPE_QINT variants were invalid.
>
> The previous commit fused QTYPE_QINT with QTYPE_QFLOAT, rendering
> rendering promote_int useless and unused.

Scratch one of two "rendering".

> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>

With that tidied up:
Reviewed-by: Markus Armbruster <armbru@redhat.com>

^ permalink raw reply	[flat|nested] 80+ messages in thread

* Re: [Qemu-devel] [PATCH v2 11/45] tests: remove /qnum/destroy test
  2017-05-31 13:56 ` [Qemu-devel] [PATCH v2 11/45] tests: remove /qnum/destroy test Marc-André Lureau
@ 2017-06-02  8:00   ` Markus Armbruster
  0 siblings, 0 replies; 80+ messages in thread
From: Markus Armbruster @ 2017-06-02  8:00 UTC (permalink / raw)
  To: Marc-André Lureau; +Cc: qemu-devel

Marc-André Lureau <marcandre.lureau@redhat.com> writes:

> The test isn't really useful.
>
> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>

Same in check-qdict.c check-qlist.c check-qstring.c.  Please drop them, too.

^ permalink raw reply	[flat|nested] 80+ messages in thread

* Re: [Qemu-devel] [PATCH v2 12/45] qnum: add uint type
  2017-05-31 13:56 ` [Qemu-devel] [PATCH v2 12/45] qnum: add uint type Marc-André Lureau
@ 2017-06-02  8:05   ` Markus Armbruster
  0 siblings, 0 replies; 80+ messages in thread
From: Markus Armbruster @ 2017-06-02  8:05 UTC (permalink / raw)
  To: Marc-André Lureau; +Cc: qemu-devel

Marc-André Lureau <marcandre.lureau@redhat.com> writes:

> In order to store integer values superior to INT64_MAX, add a u64

"superior" sounds odd.  What about "above"?  Or perhaps "between
INT64_MAX and UINT64_MAX".

s/a u64/a uint64_t/

> internal representation.
>
> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>

With the commit message tidied up:
Reviewed-by: Markus Armbruster <armbru@redhat.com>

^ permalink raw reply	[flat|nested] 80+ messages in thread

* Re: [Qemu-devel] [PATCH v2 13/45] json: learn to parse uint64 numbers
  2017-05-31 13:56 ` [Qemu-devel] [PATCH v2 13/45] json: learn to parse uint64 numbers Marc-André Lureau
@ 2017-06-02  8:24   ` Markus Armbruster
  0 siblings, 0 replies; 80+ messages in thread
From: Markus Armbruster @ 2017-06-02  8:24 UTC (permalink / raw)
  To: Marc-André Lureau; +Cc: qemu-devel

Marc-André Lureau <marcandre.lureau@redhat.com> writes:

> Switch strtoll() usage to qemu_strtoi64() helper while at it.
>
> Add a few tests for large numbers.
>
> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
> ---
>  qobject/json-lexer.c  |  4 ++++
>  qobject/json-parser.c | 30 ++++++++++++++++++++++++------
>  tests/check-qjson.c   | 37 +++++++++++++++++++++++++++++++++++++
>  3 files changed, 65 insertions(+), 6 deletions(-)
>
> diff --git a/qobject/json-lexer.c b/qobject/json-lexer.c
> index af4a75e05b..980ba159d6 100644
> --- a/qobject/json-lexer.c
> +++ b/qobject/json-lexer.c
> @@ -227,15 +227,18 @@ static const uint8_t json_lexer[][256] =  {
>      /* escape */
>      [IN_ESCAPE_LL] = {
>          ['d'] = JSON_ESCAPE,
> +        ['u'] = JSON_ESCAPE,
>      },
>  
>      [IN_ESCAPE_L] = {
>          ['d'] = JSON_ESCAPE,
>          ['l'] = IN_ESCAPE_LL,
> +        ['u'] = JSON_ESCAPE,
>      },
>  
>      [IN_ESCAPE_I64] = {
>          ['d'] = JSON_ESCAPE,
> +        ['u'] = JSON_ESCAPE,
>      },
>  
>      [IN_ESCAPE_I6] = {
> @@ -251,6 +254,7 @@ static const uint8_t json_lexer[][256] =  {
>          ['i'] = JSON_ESCAPE,
>          ['p'] = JSON_ESCAPE,
>          ['s'] = JSON_ESCAPE,
> +        ['u'] = JSON_ESCAPE,
>          ['f'] = JSON_ESCAPE,
>          ['l'] = IN_ESCAPE_L,
>          ['I'] = IN_ESCAPE_I,
> diff --git a/qobject/json-parser.c b/qobject/json-parser.c
> index b90b2fb45a..62dcac8128 100644
> --- a/qobject/json-parser.c
> +++ b/qobject/json-parser.c
> @@ -12,6 +12,7 @@
>   */
>  
>  #include "qemu/osdep.h"
> +#include "qemu/cutils.h"
>  #include "qapi/error.h"
>  #include "qemu-common.h"
>  #include "qapi/qmp/types.h"
> @@ -472,6 +473,13 @@ static QObject *parse_escape(JSONParserContext *ctxt, va_list *ap)
>      } else if (!strcmp(token->str, "%lld") ||
>                 !strcmp(token->str, "%I64d")) {
>          return QOBJECT(qnum_from_int(va_arg(*ap, long long)));
> +    } else if (!strcmp(token->str, "%u")) {
> +        return QOBJECT(qnum_from_uint(va_arg(*ap, unsigned int)));
> +    } else if (!strcmp(token->str, "%lu")) {
> +        return QOBJECT(qnum_from_uint(va_arg(*ap, unsigned long)));
> +    } else if (!strcmp(token->str, "%llu") ||
> +               !strcmp(token->str, "%I64u")) {
> +        return QOBJECT(qnum_from_uint(va_arg(*ap, unsigned long long)));
>      } else if (!strcmp(token->str, "%s")) {
>          return QOBJECT(qstring_from_str(va_arg(*ap, const char *)));
>      } else if (!strcmp(token->str, "%f")) {
> @@ -493,20 +501,30 @@ static QObject *parse_literal(JSONParserContext *ctxt)
>      case JSON_INTEGER: {
>          /*
>           * Represent JSON_INTEGER as QNUM_I64 if possible, else as
> -         * QNUM_DOUBLE. Note that strtoll() fails with ERANGE when
> -         * it's not possible.
> +         * QNUM_U64, else as QNUM_DOUBLE.  Note that qemu_strtoi64()
> +         * and qemu_strtou64 fail with ERANGE when it's not possible.

qemu_strtou64(), please.

>           *
>           * qnum_get_int() will then work for any signed 64-bit
> -         * JSON_INTEGER, and qnum_get_double both for any JSON_INTEGER
> +         * JSON_INTEGER, qnum_get_uint() for any unsigned 64-bit
> +         * integer, and qnum_get_double() both for any JSON_INTEGER
>           * and any JSON_FLOAT.
>           */
> +        int ret;
>          int64_t value;
> +        uint64_t uvalue;
>  
> -        errno = 0; /* strtoll doesn't set errno on success */
> -        value = strtoll(token->str, NULL, 10);
> -        if (errno != ERANGE) {
> +        ret = qemu_strtoi64(token->str, NULL, 10, &value);
> +        if (!ret) {
>              return QOBJECT(qnum_from_int(value));
>          }
> +        assert(ret == -ERANGE);
> +
> +        if (token->str[0] != '-') {
> +            ret = qemu_strtou64(token->str, NULL, 10, &uvalue);
> +            if (!ret) {
> +                return QOBJECT(qnum_from_uint(uvalue));
> +            }

assert(ret == -ERANGE), please.

> +        }
>          /* fall through to JSON_FLOAT */
>      }
>      case JSON_FLOAT:
> diff --git a/tests/check-qjson.c b/tests/check-qjson.c
> index 8ec728a702..6fb14445a3 100644
> --- a/tests/check-qjson.c
> +++ b/tests/check-qjson.c
> @@ -906,6 +906,42 @@ static void simple_number(void)
>      }
>  }
>  
> +static void large_number(void)
> +{
> +    const char *maxu64 = "18446744073709551615"; /* 2^64-1 */
> +    const char *gtu64 = "18446744073709551616"; /* 2^64 */
> +    const char *range = "-9223372036854775809";

Why is this called @range?

Let's add /* -2^63-1 */.

> +    QNum *qnum;
> +    QString *str;
> +    uint64_t val;
> +
> +    qnum = qobject_to_qnum(qobject_from_json(maxu64, &error_abort));
> +    g_assert(qnum);
> +    g_assert(qnum_get_uint(qnum, &val));
> +    g_assert_cmpuint(val, ==, 18446744073709551615U);
> +
> +    str = qobject_to_json(QOBJECT(qnum));
> +    g_assert_cmpstr(qstring_get_str(str), ==, maxu64);
> +    QDECREF(str);
> +    QDECREF(qnum);
> +
> +    qnum = qobject_to_qnum(qobject_from_json(gtu64, &error_abort));
> +    g_assert(qnum);
> +    g_assert_cmpfloat(qnum_get_double(qnum), >, 0);

Why not check for the exact expected number?

> +    g_assert(!qnum_get_uint(qnum, &val));
> +
> +    str = qobject_to_json(QOBJECT(qnum));
> +    g_assert_cmpstr(qstring_get_str(str), ==, gtu64);
> +    QDECREF(str);
> +    QDECREF(qnum);
> +
> +    qnum = qobject_to_qnum(qobject_from_json(range, &error_abort));
> +    g_assert(qnum);
> +    g_assert_cmpfloat(qnum_get_double(qnum), <, 0);

Likewise.

> +    g_assert(!qnum_get_uint(qnum, &val));

Shouldn't we check the result of qobject_to_json() here?

> +    QDECREF(qnum);
> +}
> +
>  static void float_number(void)
>  {
>      int i;
> @@ -1475,6 +1511,7 @@ int main(int argc, char **argv)
>      g_test_add_func("/literals/string/vararg", vararg_string);
>  
>      g_test_add_func("/literals/number/simple", simple_number);
> +    g_test_add_func("/literals/number/large", large_number);
>      g_test_add_func("/literals/number/float", float_number);
>      g_test_add_func("/literals/number/vararg", vararg_number);

^ permalink raw reply	[flat|nested] 80+ messages in thread

* Re: [Qemu-devel] [PATCH v2 14/45] qapi: update the qobject visitor to use QNUM_U64
  2017-05-31 13:56 ` [Qemu-devel] [PATCH v2 14/45] qapi: update the qobject visitor to use QNUM_U64 Marc-André Lureau
@ 2017-06-02 11:18   ` Markus Armbruster
  2017-06-02 11:20   ` Markus Armbruster
  1 sibling, 0 replies; 80+ messages in thread
From: Markus Armbruster @ 2017-06-02 11:18 UTC (permalink / raw)
  To: Marc-André Lureau; +Cc: qemu-devel

Marc-André Lureau <marcandre.lureau@redhat.com> writes:

> Switch to use QNum/uint where appropriate to remove i64 limitation.
>
> The input visitor will cast i64 input to u64 for compatibility
> reasons (existing json QMP client already use negative i64 for large
> u64, and expect an implicit cast in qemu).
>
> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
> ---
>  hw/i386/acpi-build.c                |  3 +--
>  qapi/qobject-input-visitor.c        | 21 ++++++++++++++++-----
>  qapi/qobject-output-visitor.c       |  3 +--
>  tests/test-qobject-input-visitor.c  |  7 ++-----
>  tests/test-qobject-output-visitor.c | 28 +++++++++++++++++++++-------
>  5 files changed, 41 insertions(+), 21 deletions(-)
>
> diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
> index 1709efdf1c..ba2be1e9da 100644
> --- a/hw/i386/acpi-build.c
> +++ b/hw/i386/acpi-build.c
> @@ -2634,10 +2634,9 @@ static bool acpi_get_mcfg(AcpiMcfgInfo *mcfg)
>      if (!o) {
>          return false;
>      }
> -    if (!qnum_get_int(qobject_to_qnum(o), &val)) {
> +    if (!qnum_get_uint(qobject_to_qnum(o), &mcfg->mcfg_base)) {
>          g_assert_not_reached();
>      }
> -    mcfg->mcfg_base = val;
>      qobject_decref(o);
>  
>      o = object_property_get_qobject(pci_host, PCIE_HOST_MCFG_SIZE, NULL);
> diff --git a/qapi/qobject-input-visitor.c b/qapi/qobject-input-visitor.c
> index 74835ba339..7f9d6f57a1 100644
> --- a/qapi/qobject-input-visitor.c
> +++ b/qapi/qobject-input-visitor.c
> @@ -417,7 +417,6 @@ static void qobject_input_type_int64_keyval(Visitor *v, const char *name,
>  static void qobject_input_type_uint64(Visitor *v, const char *name,
>                                        uint64_t *obj, Error **errp)
>  {
> -    /* FIXME: qobject_to_qnum mishandles values over INT64_MAX */
>      QObjectInputVisitor *qiv = to_qiv(v);
>      QObject *qobj = qobject_input_get_object(qiv, name, true, errp);
>      QNum *qnum;
> @@ -427,11 +426,23 @@ static void qobject_input_type_uint64(Visitor *v, const char *name,
>          return;
>      }
>      qnum = qobject_to_qnum(qobj);
> -    if (!qnum || !qnum_get_int(qnum, &val)) {
> -        error_setg(errp, QERR_INVALID_PARAMETER_TYPE,
> -                   full_name(qiv, name), "integer");
> +    if (!qnum) {
> +        goto err;
> +    }
> +
> +    if (qnum_get_uint(qnum, obj)) {
> +        return;
>      }
> -    *obj = val;
> +
> +    /* Need to accept negative values for backward compatibility */
> +    if (qnum_get_int(qnum, &val)) {
> +        *obj = val;
> +        return;
> +    }
> +
> +err:
> +    error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
> +               full_name(qiv, name), "uint64");
>  }
>  
>  static void qobject_input_type_uint64_keyval(Visitor *v, const char *name,
> diff --git a/qapi/qobject-output-visitor.c b/qapi/qobject-output-visitor.c
> index 2ca5093b22..70be84ccb5 100644
> --- a/qapi/qobject-output-visitor.c
> +++ b/qapi/qobject-output-visitor.c
> @@ -150,9 +150,8 @@ static void qobject_output_type_int64(Visitor *v, const char *name,
>  static void qobject_output_type_uint64(Visitor *v, const char *name,
>                                         uint64_t *obj, Error **errp)
>  {
> -    /* FIXME values larger than INT64_MAX become negative */
>      QObjectOutputVisitor *qov = to_qov(v);
> -    qobject_output_add(qov, name, qnum_from_int(*obj));
> +    qobject_output_add(qov, name, qnum_from_uint(*obj));
>  }
>  

Before the patch, uint64_t values above INT64_MAX are sent as negative
values, e.g. UINT64_MAX is sent as -1.

After the patch, they are sent unmodified.  Clearly a bug fix, but we
have to consider compatibility issues anyway.  You wrote that libvirt
should cope fine, because its parsing of unsigned integers accepts
negative values modulo 2^64.  There's hope that other clients will, too.

There's one thing left to do: please document the incompatible bug fix
in the commit message.

>  static void qobject_output_type_bool(Visitor *v, const char *name, bool *obj,
> diff --git a/tests/test-qobject-input-visitor.c b/tests/test-qobject-input-visitor.c
> index 983c59c474..6f94fc677c 100644
> --- a/tests/test-qobject-input-visitor.c
> +++ b/tests/test-qobject-input-visitor.c
> @@ -122,7 +122,6 @@ static void test_visitor_in_int(TestInputVisitorData *data,
>  static void test_visitor_in_uint(TestInputVisitorData *data,
>                                  const void *unused)
>  {
> -    Error *err = NULL;
>      uint64_t res = 0;
>      int64_t i64;
>      double dbl;
> @@ -146,12 +145,10 @@ static void test_visitor_in_uint(TestInputVisitorData *data,
>      visit_type_uint64(v, NULL, &res, &error_abort);
>      g_assert_cmpuint(res, ==, (uint64_t)-value);
>  
> -    /* BUG: value between INT64_MAX+1 and UINT64_MAX rejected */
> -
>      v = visitor_input_test_init(data, "18446744073709551574");
>  
> -    visit_type_uint64(v, NULL, &res, &err);
> -    error_free_or_abort(&err);
> +    visit_type_uint64(v, NULL, &res, &error_abort);
> +    g_assert_cmpuint(res, ==, 18446744073709551574U);
>  
>      visit_type_number(v, NULL, &dbl, &error_abort);
>  }
> diff --git a/tests/test-qobject-output-visitor.c b/tests/test-qobject-output-visitor.c
> index 3180d8cbde..d9f106d52e 100644
> --- a/tests/test-qobject-output-visitor.c
> +++ b/tests/test-qobject-output-visitor.c
> @@ -602,17 +602,31 @@ static void check_native_list(QObject *qobj,
>      qlist = qlist_copy(qobject_to_qlist(qdict_get(qdict, "data")));
>  
>      switch (kind) {
> -    case USER_DEF_NATIVE_LIST_UNION_KIND_S8:
> -    case USER_DEF_NATIVE_LIST_UNION_KIND_S16:
> -    case USER_DEF_NATIVE_LIST_UNION_KIND_S32:
> -    case USER_DEF_NATIVE_LIST_UNION_KIND_S64:
>      case USER_DEF_NATIVE_LIST_UNION_KIND_U8:
>      case USER_DEF_NATIVE_LIST_UNION_KIND_U16:
>      case USER_DEF_NATIVE_LIST_UNION_KIND_U32:
>      case USER_DEF_NATIVE_LIST_UNION_KIND_U64:
> -        /* all integer elements in JSON arrays get stored into QNums when
> -         * we convert to QObjects, so we can check them all in the same
> -         * fashion, so simply fall through here
> +        for (i = 0; i < 32; i++) {
> +            QObject *tmp;
> +            QNum *qvalue;
> +            uint64_t val;
> +
> +            tmp = qlist_peek(qlist);
> +            g_assert(tmp);
> +            qvalue = qobject_to_qnum(tmp);
> +            g_assert(qnum_get_uint(qvalue, &val));
> +            g_assert_cmpuint(val, ==, i);
> +            qobject_decref(qlist_pop(qlist));
> +        }
> +        break;
> +
> +    case USER_DEF_NATIVE_LIST_UNION_KIND_S8:
> +    case USER_DEF_NATIVE_LIST_UNION_KIND_S16:
> +    case USER_DEF_NATIVE_LIST_UNION_KIND_S32:
> +    case USER_DEF_NATIVE_LIST_UNION_KIND_S64:
> +        /* All signed integer elements in JSON arrays get stored into
> +         * QInts when we convert to QObjects, so we can check them all
> +         * in the same fashion, so simply fall through here.
>           */
>      case USER_DEF_NATIVE_LIST_UNION_KIND_INTEGER:
>          for (i = 0; i < 32; i++) {

With the incompatible fix explained in the commit message:
Reviewed-by: Markus Armbruster <armbru@redhat.com>

^ permalink raw reply	[flat|nested] 80+ messages in thread

* Re: [Qemu-devel] [PATCH v2 14/45] qapi: update the qobject visitor to use QNUM_U64
  2017-05-31 13:56 ` [Qemu-devel] [PATCH v2 14/45] qapi: update the qobject visitor to use QNUM_U64 Marc-André Lureau
  2017-06-02 11:18   ` Markus Armbruster
@ 2017-06-02 11:20   ` Markus Armbruster
  2017-06-02 11:34     ` Marc-André Lureau
  1 sibling, 1 reply; 80+ messages in thread
From: Markus Armbruster @ 2017-06-02 11:20 UTC (permalink / raw)
  To: Marc-André Lureau; +Cc: qemu-devel

One more nitpick:

Marc-André Lureau <marcandre.lureau@redhat.com> writes:

> Switch to use QNum/uint where appropriate to remove i64 limitation.
>
> The input visitor will cast i64 input to u64 for compatibility
> reasons (existing json QMP client already use negative i64 for large
> u64, and expect an implicit cast in qemu).
>
> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
[...]
> diff --git a/tests/test-qobject-output-visitor.c b/tests/test-qobject-output-visitor.c
> index 3180d8cbde..d9f106d52e 100644
> --- a/tests/test-qobject-output-visitor.c
> +++ b/tests/test-qobject-output-visitor.c
> @@ -602,17 +602,31 @@ static void check_native_list(QObject *qobj,
>      qlist = qlist_copy(qobject_to_qlist(qdict_get(qdict, "data")));
>  
>      switch (kind) {
> -    case USER_DEF_NATIVE_LIST_UNION_KIND_S8:
> -    case USER_DEF_NATIVE_LIST_UNION_KIND_S16:
> -    case USER_DEF_NATIVE_LIST_UNION_KIND_S32:
> -    case USER_DEF_NATIVE_LIST_UNION_KIND_S64:
>      case USER_DEF_NATIVE_LIST_UNION_KIND_U8:
>      case USER_DEF_NATIVE_LIST_UNION_KIND_U16:
>      case USER_DEF_NATIVE_LIST_UNION_KIND_U32:
>      case USER_DEF_NATIVE_LIST_UNION_KIND_U64:
> -        /* all integer elements in JSON arrays get stored into QNums when
> -         * we convert to QObjects, so we can check them all in the same
> -         * fashion, so simply fall through here
> +        for (i = 0; i < 32; i++) {
> +            QObject *tmp;
> +            QNum *qvalue;
> +            uint64_t val;
> +
> +            tmp = qlist_peek(qlist);
> +            g_assert(tmp);
> +            qvalue = qobject_to_qnum(tmp);
> +            g_assert(qnum_get_uint(qvalue, &val));
> +            g_assert_cmpuint(val, ==, i);
> +            qobject_decref(qlist_pop(qlist));
> +        }
> +        break;
> +
> +    case USER_DEF_NATIVE_LIST_UNION_KIND_S8:
> +    case USER_DEF_NATIVE_LIST_UNION_KIND_S16:
> +    case USER_DEF_NATIVE_LIST_UNION_KIND_S32:
> +    case USER_DEF_NATIVE_LIST_UNION_KIND_S64:
> +        /* All signed integer elements in JSON arrays get stored into
> +         * QInts when we convert to QObjects, so we can check them all
> +         * in the same fashion, so simply fall through here.
>           */
>      case USER_DEF_NATIVE_LIST_UNION_KIND_INTEGER:
>          for (i = 0; i < 32; i++) {

Wing both ends of the comment, please.

^ permalink raw reply	[flat|nested] 80+ messages in thread

* Re: [Qemu-devel] [PATCH v2 14/45] qapi: update the qobject visitor to use QNUM_U64
  2017-06-02 11:20   ` Markus Armbruster
@ 2017-06-02 11:34     ` Marc-André Lureau
  2017-06-02 12:36       ` Markus Armbruster
  0 siblings, 1 reply; 80+ messages in thread
From: Marc-André Lureau @ 2017-06-02 11:34 UTC (permalink / raw)
  To: Markus Armbruster; +Cc: qemu-devel



----- Original Message -----
> One more nitpick:
> 
> Marc-André Lureau <marcandre.lureau@redhat.com> writes:
> 
> > Switch to use QNum/uint where appropriate to remove i64 limitation.
> >
> > The input visitor will cast i64 input to u64 for compatibility
> > reasons (existing json QMP client already use negative i64 for large
> > u64, and expect an implicit cast in qemu).
> >
> > Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
> [...]
> > diff --git a/tests/test-qobject-output-visitor.c
> > b/tests/test-qobject-output-visitor.c
> > index 3180d8cbde..d9f106d52e 100644
> > --- a/tests/test-qobject-output-visitor.c
> > +++ b/tests/test-qobject-output-visitor.c
> > @@ -602,17 +602,31 @@ static void check_native_list(QObject *qobj,
> >      qlist = qlist_copy(qobject_to_qlist(qdict_get(qdict, "data")));
> >  
> >      switch (kind) {
> > -    case USER_DEF_NATIVE_LIST_UNION_KIND_S8:
> > -    case USER_DEF_NATIVE_LIST_UNION_KIND_S16:
> > -    case USER_DEF_NATIVE_LIST_UNION_KIND_S32:
> > -    case USER_DEF_NATIVE_LIST_UNION_KIND_S64:
> >      case USER_DEF_NATIVE_LIST_UNION_KIND_U8:
> >      case USER_DEF_NATIVE_LIST_UNION_KIND_U16:
> >      case USER_DEF_NATIVE_LIST_UNION_KIND_U32:
> >      case USER_DEF_NATIVE_LIST_UNION_KIND_U64:
> > -        /* all integer elements in JSON arrays get stored into QNums when
> > -         * we convert to QObjects, so we can check them all in the same
> > -         * fashion, so simply fall through here
> > +        for (i = 0; i < 32; i++) {
> > +            QObject *tmp;
> > +            QNum *qvalue;
> > +            uint64_t val;
> > +
> > +            tmp = qlist_peek(qlist);
> > +            g_assert(tmp);
> > +            qvalue = qobject_to_qnum(tmp);
> > +            g_assert(qnum_get_uint(qvalue, &val));
> > +            g_assert_cmpuint(val, ==, i);
> > +            qobject_decref(qlist_pop(qlist));
> > +        }
> > +        break;
> > +
> > +    case USER_DEF_NATIVE_LIST_UNION_KIND_S8:
> > +    case USER_DEF_NATIVE_LIST_UNION_KIND_S16:
> > +    case USER_DEF_NATIVE_LIST_UNION_KIND_S32:
> > +    case USER_DEF_NATIVE_LIST_UNION_KIND_S64:
> > +        /* All signed integer elements in JSON arrays get stored into
> > +         * QInts when we convert to QObjects, so we can check them all
> > +         * in the same fashion, so simply fall through here.
> >           */
> >      case USER_DEF_NATIVE_LIST_UNION_KIND_INTEGER:
> >          for (i = 0; i < 32; i++) {
> 
> Wing both ends of the comment, please.

You want this: ?

/* All signed integer elements in JSON arrays get stored into */
/* QInts when we convert to QObjects, so we can check them all */
...

I think this is quite annoying for refilling with emacs

Perhaps rather

/* All signed integer elements in JSON arrays get stored into
 * QInts when we convert to QObjects, so we can check them all */

quite uglier to me, but I don't care

However, I'd prefer if either we have a common rule in qemu or we don't bike-sched over that...

(even better would be to have this somehow automated with tools like git-clang-format)

^ permalink raw reply	[flat|nested] 80+ messages in thread

* Re: [Qemu-devel] [PATCH v2 16/45] q35: fix get_mmcfg_size to use uint64 visitor
  2017-05-31 13:56 ` [Qemu-devel] [PATCH v2 16/45] q35: fix get_mmcfg_size to use uint64 visitor Marc-André Lureau
@ 2017-06-02 11:34   ` Markus Armbruster
  0 siblings, 0 replies; 80+ messages in thread
From: Markus Armbruster @ 2017-06-02 11:34 UTC (permalink / raw)
  To: Marc-André Lureau; +Cc: qemu-devel

Marc-André Lureau <marcandre.lureau@redhat.com> writes:

> e->size is hwaddr, i.e. uint64_t. We silently truncate.
> Fix suggested by Markus Armbruster.

I'd prefer

  Suggested-by: Markus Armbruster <armbru@redhat.com>

> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
> ---
>  hw/pci-host/q35.c | 3 +--
>  1 file changed, 1 insertion(+), 2 deletions(-)
>
> diff --git a/hw/pci-host/q35.c b/hw/pci-host/q35.c
> index cd5c49616e..e8a04d31d1 100644
> --- a/hw/pci-host/q35.c
> +++ b/hw/pci-host/q35.c
> @@ -129,9 +129,8 @@ static void q35_host_get_mmcfg_size(Object *obj, Visitor *v, const char *name,
>                                      void *opaque, Error **errp)
>  {
>      PCIExpressHost *e = PCIE_HOST_BRIDGE(obj);
> -    uint32_t value = e->size;
>  
> -    visit_type_uint32(v, name, &value, errp);
> +    visit_type_uint64(v, name, &e->size, errp);
>  }
>  
>  static Property mch_props[] = {

Reviewed-by: Markus Armbruster <armbru@redhat.com>

^ permalink raw reply	[flat|nested] 80+ messages in thread

* Re: [Qemu-devel] [PATCH v2 14/45] qapi: update the qobject visitor to use QNUM_U64
  2017-06-02 11:34     ` Marc-André Lureau
@ 2017-06-02 12:36       ` Markus Armbruster
  0 siblings, 0 replies; 80+ messages in thread
From: Markus Armbruster @ 2017-06-02 12:36 UTC (permalink / raw)
  To: Marc-André Lureau; +Cc: qemu-devel

Marc-André Lureau <marcandre.lureau@redhat.com> writes:

> ----- Original Message -----
>> One more nitpick:
>> 
>> Marc-André Lureau <marcandre.lureau@redhat.com> writes:
>> 
>> > Switch to use QNum/uint where appropriate to remove i64 limitation.
>> >
>> > The input visitor will cast i64 input to u64 for compatibility
>> > reasons (existing json QMP client already use negative i64 for large
>> > u64, and expect an implicit cast in qemu).
>> >
>> > Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
>> [...]
>> > diff --git a/tests/test-qobject-output-visitor.c
>> > b/tests/test-qobject-output-visitor.c
>> > index 3180d8cbde..d9f106d52e 100644
>> > --- a/tests/test-qobject-output-visitor.c
>> > +++ b/tests/test-qobject-output-visitor.c
>> > @@ -602,17 +602,31 @@ static void check_native_list(QObject *qobj,
>> >      qlist = qlist_copy(qobject_to_qlist(qdict_get(qdict, "data")));
>> >  
>> >      switch (kind) {
>> > -    case USER_DEF_NATIVE_LIST_UNION_KIND_S8:
>> > -    case USER_DEF_NATIVE_LIST_UNION_KIND_S16:
>> > -    case USER_DEF_NATIVE_LIST_UNION_KIND_S32:
>> > -    case USER_DEF_NATIVE_LIST_UNION_KIND_S64:
>> >      case USER_DEF_NATIVE_LIST_UNION_KIND_U8:
>> >      case USER_DEF_NATIVE_LIST_UNION_KIND_U16:
>> >      case USER_DEF_NATIVE_LIST_UNION_KIND_U32:
>> >      case USER_DEF_NATIVE_LIST_UNION_KIND_U64:
>> > -        /* all integer elements in JSON arrays get stored into QNums when
>> > -         * we convert to QObjects, so we can check them all in the same
>> > -         * fashion, so simply fall through here
>> > +        for (i = 0; i < 32; i++) {
>> > +            QObject *tmp;
>> > +            QNum *qvalue;
>> > +            uint64_t val;
>> > +
>> > +            tmp = qlist_peek(qlist);
>> > +            g_assert(tmp);
>> > +            qvalue = qobject_to_qnum(tmp);
>> > +            g_assert(qnum_get_uint(qvalue, &val));
>> > +            g_assert_cmpuint(val, ==, i);
>> > +            qobject_decref(qlist_pop(qlist));
>> > +        }
>> > +        break;
>> > +
>> > +    case USER_DEF_NATIVE_LIST_UNION_KIND_S8:
>> > +    case USER_DEF_NATIVE_LIST_UNION_KIND_S16:
>> > +    case USER_DEF_NATIVE_LIST_UNION_KIND_S32:
>> > +    case USER_DEF_NATIVE_LIST_UNION_KIND_S64:
>> > +        /* All signed integer elements in JSON arrays get stored into
>> > +         * QInts when we convert to QObjects, so we can check them all
>> > +         * in the same fashion, so simply fall through here.
>> >           */
>> >      case USER_DEF_NATIVE_LIST_UNION_KIND_INTEGER:
>> >          for (i = 0; i < 32; i++) {
>> 
>> Wing both ends of the comment, please.
>
> You want this: ?
>
> /* All signed integer elements in JSON arrays get stored into */
> /* QInts when we convert to QObjects, so we can check them all */
> ...

Ewww!

> I think this is quite annoying for refilling with emacs

Yup.

> Perhaps rather
>
> /* All signed integer elements in JSON arrays get stored into
>  * QInts when we convert to QObjects, so we can check them all */
>
> quite uglier to me, but I don't care

I'm asking for this:

              /*
               * All signed integer elements in JSON arrays get stored into
               * QInts when we convert to QObjects, so we can check them all
               * in the same fashion, so simply fall through here.
               */

This comment style is commonly called "winged".  It's fairly widespread
in QEMU.

> However, I'd prefer if either we have a common rule in qemu or we don't bike-sched over that...
>
> (even better would be to have this somehow automated with tools like git-clang-format)

Tool support would be easier if we didn't insist on inventing our very
own coding style, then fail to enforce it uniformly.  Oh well, we'll
muddle on.

^ permalink raw reply	[flat|nested] 80+ messages in thread

* Re: [Qemu-devel] [PATCH v2 17/45] object: use more specific property type names
  2017-05-31 13:56 ` [Qemu-devel] [PATCH v2 17/45] object: use more specific property type names Marc-André Lureau
@ 2017-06-02 13:38   ` Markus Armbruster
  0 siblings, 0 replies; 80+ messages in thread
From: Markus Armbruster @ 2017-06-02 13:38 UTC (permalink / raw)
  To: Marc-André Lureau; +Cc: qemu-devel

Marc-André Lureau <marcandre.lureau@redhat.com> writes:

> Use the actual unsigned integer type name (this should't break since
> property type aren't directly accessed from outside it seems).

I checked.  Uses of Object member @type outside qom/object.c:

* vl.c's machine_help_func() puts it in help for -machine NAME,help.
  Fine.

* QMP command qom-list exposes it in ObjectPropertyInfo member @type.
  Your commit message is wrong :)

* QMP command device-list-properties exposes it in DevicePropertyInfo
  member @type.

* spapr_drc_populate_dt() compares it to "link<", which may or may not
  be a good idea, but isn't affected by your patch.

Uses in qom/object.c:

* object_property_is_child() compares it to "child<".  Not affected by
  your patch.

* object_property_get_enum() takes it as argument.  Shouldn't be
  affected by your patch, as only enumeration type names should occur
  here.  Double-checking: I can see "HostMemPolicy", "DummyAnimal",
  "BadAnimal" (the latter two in tests/, don't worry).  Okay.

* object_property_get_type() returns it.

  - qdev_print_props() only checks whether it succeeds.  Not affected by
    your patch.

  - object_resolve_link() requires it to be of the form "link<%s>".  Not
    affected by your patch unless we violate this precondition (and then
    we have worse problems).

* object_property_add_alias() copies it, possibly rewriting "child<%s>"
  to "link<%s>".  Shouldn't be affected by your patch.

> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>

Rewrite the commit message to explain impact on -machine, qom-list and
device-list-properties, and you may add

Reviewed-by: Markus Armbruster <armbru@redhat.com>

^ permalink raw reply	[flat|nested] 80+ messages in thread

* Re: [Qemu-devel] [PATCH v2 18/45] qdev: make default property int
  2017-05-31 13:56 ` [Qemu-devel] [PATCH v2 18/45] qdev: make default property int Marc-André Lureau
@ 2017-06-02 13:49   ` Markus Armbruster
  0 siblings, 0 replies; 80+ messages in thread
From: Markus Armbruster @ 2017-06-02 13:49 UTC (permalink / raw)
  To: Marc-André Lureau; +Cc: qemu-devel

Marc-André Lureau <marcandre.lureau@redhat.com> writes:

> The following patch will add uint properties.
>
> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>

"Make default property int" doesn't make sense to me.  The patch does
two things:

1. Rename DEFINE_PROP_DEFAULT() to DEFINE_PROP_INT(), to prepare for the
next patch's DEFINE_PROP_UINT().

2. Wrap the Property default value (an int64_t) in a union, to prepare
for the next patch adding a uint64_t.

If you split the patch accordingly, the commit messages will write
themselves :)

I'd use DEFINE_PROP_SIGNED() to avoid misleading readers into making a
connection to type int, and DEFINE_PROP_UNSIGNED() to match.

Other than that, the patch looks good.

^ permalink raw reply	[flat|nested] 80+ messages in thread

* Re: [Qemu-devel] [PATCH v2 19/45] qdev: add unsigned properties
  2017-05-31 13:56 ` [Qemu-devel] [PATCH v2 19/45] qdev: add unsigned properties Marc-André Lureau
@ 2017-06-02 13:55   ` Markus Armbruster
  2017-06-02 14:00     ` Marc-André Lureau
  0 siblings, 1 reply; 80+ messages in thread
From: Markus Armbruster @ 2017-06-02 13:55 UTC (permalink / raw)
  To: Marc-André Lureau; +Cc: qemu-devel

Marc-André Lureau <marcandre.lureau@redhat.com> writes:

> Add and use unsigned type for various properties.
>
> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>

The commit message is a bit misleading.  We don't "add unsigned
properties", we clean up the property code to avoid type casts between
signed and unsigned.

I'm not sure that's worth the churn by itself.  But perhaps it helps
later in this series.  If yes, can you give me a hint?

> ---
>  include/hw/qdev-core.h       |  1 +
>  include/hw/qdev-properties.h | 51 +++++++++++++++++++++++++++-----------------
>  hw/core/qdev-properties.c    | 23 ++++++++++++--------
>  3 files changed, 46 insertions(+), 29 deletions(-)
>
> diff --git a/include/hw/qdev-core.h b/include/hw/qdev-core.h
> index 784971b8d8..9d7c1c0e9b 100644
> --- a/include/hw/qdev-core.h
> +++ b/include/hw/qdev-core.h
> @@ -228,6 +228,7 @@ struct Property {
>      uint8_t      bitnr;
>      union {
>          int64_t i;
> +        uint64_t u;
>      } defval;
>      int          arrayoffset;
>      PropertyInfo *arrayinfo;
> diff --git a/include/hw/qdev-properties.h b/include/hw/qdev-properties.h
> index 6663a547ea..16d3ada8df 100644
> --- a/include/hw/qdev-properties.h
> +++ b/include/hw/qdev-properties.h
> @@ -37,6 +37,7 @@ extern PropertyInfo qdev_prop_arraylen;
>          .offset    = offsetof(_state, _field)                    \
>              + type_check(_type, typeof_field(_state, _field)),   \
>          }
> +
>  #define DEFINE_PROP_INT(_name, _state, _field, _defval, _prop, _type) { \
>          .name      = (_name),                                           \
>          .info      = &(_prop),                                          \
> @@ -44,29 +45,39 @@ extern PropertyInfo qdev_prop_arraylen;
>              + type_check(_type,typeof_field(_state, _field)),           \
>          .defval.i  = (_type)_defval,                                    \
>          }
> -#define DEFINE_PROP_BIT(_name, _state, _field, _bit, _defval) {  \
> -        .name      = (_name),                                    \
> -        .info      = &(qdev_prop_bit),                           \
> -        .bitnr    = (_bit),                                      \
> -        .offset    = offsetof(_state, _field)                    \
> -            + type_check(uint32_t,typeof_field(_state, _field)), \
> -        .defval.i  = (bool)_defval,                              \
> +
> +#define DEFINE_PROP_BIT(_name, _state, _field, _bit, _defval) {         \
> +        .name      = (_name),                                           \
> +        .info      = &(qdev_prop_bit),                                  \
> +        .bitnr    = (_bit),                                             \
> +        .offset    = offsetof(_state, _field)                           \
> +            + type_check(uint32_t, typeof_field(_state, _field)),        \
> +        .defval.u   = (bool)_defval,                                    \
>          }

Let's keep the backslashes where they are to reduce churn.

> +
> +#define DEFINE_PROP_UINT(_name, _state, _field, _defval, _prop, _type) { \
> +        .name      = (_name),                                           \
> +        .info      = &(_prop),                                          \
> +        .offset    = offsetof(_state, _field)                           \
> +            + type_check(_type, typeof_field(_state, _field)),          \
> +        .defval.u  = (_type)_defval,                                    \
> +        }
> +
>  #define DEFINE_PROP_BIT64(_name, _state, _field, _bit, _defval) {       \
>          .name      = (_name),                                           \
>          .info      = &(qdev_prop_bit64),                                \
>          .bitnr    = (_bit),                                             \
>          .offset    = offsetof(_state, _field)                           \
>              + type_check(uint64_t, typeof_field(_state, _field)),       \
> -        .defval.i  = (bool)_defval,                                     \
> +        .defval.u  = (bool)_defval,                                     \
>          }
>  
> -#define DEFINE_PROP_BOOL(_name, _state, _field, _defval) {       \
> -        .name      = (_name),                                    \
> -        .info      = &(qdev_prop_bool),                          \
> -        .offset    = offsetof(_state, _field)                    \
> -            + type_check(bool, typeof_field(_state, _field)),    \
> -        .defval.i  = (bool)_defval,                              \
> +#define DEFINE_PROP_BOOL(_name, _state, _field, _defval) {      \
> +        .name      = (_name),                                   \
> +        .info      = &(qdev_prop_bool),                         \
> +        .offset    = offsetof(_state, _field)                   \
> +            + type_check(bool, typeof_field(_state, _field)),   \
> +        .defval.u    = (bool)_defval,                           \
>          }

Likewise.

>  
>  #define PROP_ARRAY_LEN_PREFIX "len-"
> @@ -107,17 +118,17 @@ extern PropertyInfo qdev_prop_arraylen;
>          }
>  
>  #define DEFINE_PROP_UINT8(_n, _s, _f, _d)                       \
> -    DEFINE_PROP_INT(_n, _s, _f, _d, qdev_prop_uint8, uint8_t)
> +    DEFINE_PROP_UINT(_n, _s, _f, _d, qdev_prop_uint8, uint8_t)
>  #define DEFINE_PROP_UINT16(_n, _s, _f, _d)                      \
> -    DEFINE_PROP_INT(_n, _s, _f, _d, qdev_prop_uint16, uint16_t)
> +    DEFINE_PROP_UINT(_n, _s, _f, _d, qdev_prop_uint16, uint16_t)
>  #define DEFINE_PROP_UINT32(_n, _s, _f, _d)                      \
> -    DEFINE_PROP_INT(_n, _s, _f, _d, qdev_prop_uint32, uint32_t)
> +    DEFINE_PROP_UINT(_n, _s, _f, _d, qdev_prop_uint32, uint32_t)
>  #define DEFINE_PROP_INT32(_n, _s, _f, _d)                      \
>      DEFINE_PROP_INT(_n, _s, _f, _d, qdev_prop_int32, int32_t)
>  #define DEFINE_PROP_UINT64(_n, _s, _f, _d)                      \
> -    DEFINE_PROP_INT(_n, _s, _f, _d, qdev_prop_uint64, uint64_t)
> +    DEFINE_PROP_UINT(_n, _s, _f, _d, qdev_prop_uint64, uint64_t)
>  #define DEFINE_PROP_SIZE(_n, _s, _f, _d)                       \
> -    DEFINE_PROP_INT(_n, _s, _f, _d, qdev_prop_size, uint64_t)
> +    DEFINE_PROP_UINT(_n, _s, _f, _d, qdev_prop_size, uint64_t)
>  #define DEFINE_PROP_PCI_DEVFN(_n, _s, _f, _d)                   \
>      DEFINE_PROP_INT(_n, _s, _f, _d, qdev_prop_pci_devfn, int32_t)
>  
> @@ -163,7 +174,7 @@ extern PropertyInfo qdev_prop_arraylen;
>  #define DEFINE_PROP_BIOS_CHS_TRANS(_n, _s, _f, _d) \
>      DEFINE_PROP_INT(_n, _s, _f, _d, qdev_prop_bios_chs_trans, int)
>  #define DEFINE_PROP_BLOCKSIZE(_n, _s, _f) \
> -    DEFINE_PROP_INT(_n, _s, _f, 0, qdev_prop_blocksize, uint16_t)
> +    DEFINE_PROP_UINT(_n, _s, _f, 0, qdev_prop_blocksize, uint16_t)
>  #define DEFINE_PROP_PCI_HOST_DEVADDR(_n, _s, _f) \
>      DEFINE_PROP(_n, _s, _f, qdev_prop_pci_host_devaddr, PCIHostDeviceAddress)
>  
> diff --git a/hw/core/qdev-properties.c b/hw/core/qdev-properties.c
> index 952cda7758..92fb43cb0d 100644
> --- a/hw/core/qdev-properties.c
> +++ b/hw/core/qdev-properties.c
> @@ -71,7 +71,7 @@ static void set_enum(Object *obj, Visitor *v, const char *name, void *opaque,
>  
>  static void set_default_value_enum(Object *obj, const Property *prop)
>  {
> -    object_property_set_str(obj, prop->info->enum_table[prop->defval.i],
> +    object_property_set_str(obj, prop->info->enum_table[prop->defval.u],
>                              prop->name, &error_abort);
>  }
>  
> @@ -128,7 +128,7 @@ static void prop_set_bit(Object *obj, Visitor *v, const char *name,
>  
>  static void set_default_value_bool(Object *obj, const Property *prop)
>  {
> -    object_property_set_bool(obj, prop->defval.i, prop->name, &error_abort);
> +    object_property_set_bool(obj, prop->defval.u, prop->name, &error_abort);
>  }
>  
>  PropertyInfo qdev_prop_bit = {
> @@ -264,11 +264,16 @@ static void set_default_value_int(Object *obj, const Property *prop)
>      object_property_set_int(obj, prop->defval.i, prop->name, &error_abort);
>  }
>  
> +static void set_default_value_uint(Object *obj, const Property *prop)
> +{
> +    object_property_set_uint(obj, prop->defval.u, prop->name, &error_abort);
> +}
> +
>  PropertyInfo qdev_prop_uint8 = {
>      .name  = "uint8",
>      .get   = get_uint8,
>      .set   = set_uint8,
> -    .set_default_value = set_default_value_int,
> +    .set_default_value = set_default_value_uint,
>  };
>  
>  /* --- 16bit integer --- */
> @@ -302,7 +307,7 @@ PropertyInfo qdev_prop_uint16 = {
>      .name  = "uint16",
>      .get   = get_uint16,
>      .set   = set_uint16,
> -    .set_default_value = set_default_value_int,
> +    .set_default_value = set_default_value_uint,
>  };
>  
>  /* --- 32bit integer --- */
> @@ -361,7 +366,7 @@ PropertyInfo qdev_prop_uint32 = {
>      .name  = "uint32",
>      .get   = get_uint32,
>      .set   = set_uint32,
> -    .set_default_value = set_default_value_int,
> +    .set_default_value = set_default_value_uint,
>  };
>  
>  PropertyInfo qdev_prop_int32 = {
> @@ -402,7 +407,7 @@ PropertyInfo qdev_prop_uint64 = {
>      .name  = "uint64",
>      .get   = get_uint64,
>      .set   = set_uint64,
> -    .set_default_value = set_default_value_int,
> +    .set_default_value = set_default_value_uint,
>  };
>  
>  /* --- string --- */
> @@ -725,7 +730,7 @@ PropertyInfo qdev_prop_blocksize = {
>      .description = "A power of two between 512 and 32768",
>      .get   = get_uint16,
>      .set   = set_blocksize,
> -    .set_default_value = set_default_value_int,
> +    .set_default_value = set_default_value_uint,
>  };
>  
>  /* --- pci host address --- */
> @@ -948,7 +953,7 @@ PropertyInfo qdev_prop_arraylen = {
>      .name = "uint32",
>      .get = get_uint32,
>      .set = set_prop_arraylen,
> -    .set_default_value = set_default_value_int,
> +    .set_default_value = set_default_value_uint,
>  };
>  
>  /* --- public helpers --- */
> @@ -1185,5 +1190,5 @@ PropertyInfo qdev_prop_size = {
>      .name  = "size",
>      .get = get_size,
>      .set = set_size,
> -    .set_default_value = set_default_value_int,
> +    .set_default_value = set_default_value_uint,
>  };

^ permalink raw reply	[flat|nested] 80+ messages in thread

* Re: [Qemu-devel] [PATCH v2 19/45] qdev: add unsigned properties
  2017-06-02 13:55   ` Markus Armbruster
@ 2017-06-02 14:00     ` Marc-André Lureau
  2017-06-02 14:05       ` Marc-André Lureau
  0 siblings, 1 reply; 80+ messages in thread
From: Marc-André Lureau @ 2017-06-02 14:00 UTC (permalink / raw)
  To: Markus Armbruster; +Cc: qemu-devel

On Fri, Jun 2, 2017 at 5:55 PM Markus Armbruster <armbru@redhat.com> wrote:

> Marc-André Lureau <marcandre.lureau@redhat.com> writes:
>
> > Add and use unsigned type for various properties.
> >
> > Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
>
> The commit message is a bit misleading.  We don't "add unsigned
> properties", we clean up the property code to avoid type casts between
> signed and unsigned.
>

That in itself is imho a good reason for the cleanup :)

>
> I'm not sure that's worth the churn by itself.  But perhaps it helps
> later in this series.  If yes, can you give me a hint?
>

Churn is quite minimal though.


>
> > ---
> >  include/hw/qdev-core.h       |  1 +
> >  include/hw/qdev-properties.h | 51
> +++++++++++++++++++++++++++-----------------
> >  hw/core/qdev-properties.c    | 23 ++++++++++++--------
> >  3 files changed, 46 insertions(+), 29 deletions(-)
> >
> > diff --git a/include/hw/qdev-core.h b/include/hw/qdev-core.h
> > index 784971b8d8..9d7c1c0e9b 100644
> > --- a/include/hw/qdev-core.h
> > +++ b/include/hw/qdev-core.h
> > @@ -228,6 +228,7 @@ struct Property {
> >      uint8_t      bitnr;
> >      union {
> >          int64_t i;
> > +        uint64_t u;
> >      } defval;
> >      int          arrayoffset;
> >      PropertyInfo *arrayinfo;
> > diff --git a/include/hw/qdev-properties.h b/include/hw/qdev-properties.h
> > index 6663a547ea..16d3ada8df 100644
> > --- a/include/hw/qdev-properties.h
> > +++ b/include/hw/qdev-properties.h
> > @@ -37,6 +37,7 @@ extern PropertyInfo qdev_prop_arraylen;
> >          .offset    = offsetof(_state, _field)                    \
> >              + type_check(_type, typeof_field(_state, _field)),   \
> >          }
> > +
> >  #define DEFINE_PROP_INT(_name, _state, _field, _defval, _prop, _type) {
> \
> >          .name      = (_name),
>  \
> >          .info      = &(_prop),
> \
> > @@ -44,29 +45,39 @@ extern PropertyInfo qdev_prop_arraylen;
> >              + type_check(_type,typeof_field(_state, _field)),
>  \
> >          .defval.i  = (_type)_defval,
> \
> >          }
> > -#define DEFINE_PROP_BIT(_name, _state, _field, _bit, _defval) {  \
> > -        .name      = (_name),                                    \
> > -        .info      = &(qdev_prop_bit),                           \
> > -        .bitnr    = (_bit),                                      \
> > -        .offset    = offsetof(_state, _field)                    \
> > -            + type_check(uint32_t,typeof_field(_state, _field)), \
> > -        .defval.i  = (bool)_defval,                              \
> > +
> > +#define DEFINE_PROP_BIT(_name, _state, _field, _bit, _defval) {
>  \
> > +        .name      = (_name),
>  \
> > +        .info      = &(qdev_prop_bit),
> \
> > +        .bitnr    = (_bit),
>  \
> > +        .offset    = offsetof(_state, _field)
>  \
> > +            + type_check(uint32_t, typeof_field(_state, _field)),
>   \
> > +        .defval.u   = (bool)_defval,
> \
> >          }
>
> Let's keep the backslashes where they are to reduce churn.
>
> > +
> > +#define DEFINE_PROP_UINT(_name, _state, _field, _defval, _prop, _type)
> { \
> > +        .name      = (_name),
>  \
> > +        .info      = &(_prop),
> \
> > +        .offset    = offsetof(_state, _field)
>  \
> > +            + type_check(_type, typeof_field(_state, _field)),
> \
> > +        .defval.u  = (_type)_defval,
> \
> > +        }
> > +
> >  #define DEFINE_PROP_BIT64(_name, _state, _field, _bit, _defval) {
>  \
> >          .name      = (_name),
>  \
> >          .info      = &(qdev_prop_bit64),
> \
> >          .bitnr    = (_bit),
>  \
> >          .offset    = offsetof(_state, _field)
>  \
> >              + type_check(uint64_t, typeof_field(_state, _field)),
>  \
> > -        .defval.i  = (bool)_defval,
>  \
> > +        .defval.u  = (bool)_defval,
>  \
> >          }
> >
> > -#define DEFINE_PROP_BOOL(_name, _state, _field, _defval) {       \
> > -        .name      = (_name),                                    \
> > -        .info      = &(qdev_prop_bool),                          \
> > -        .offset    = offsetof(_state, _field)                    \
> > -            + type_check(bool, typeof_field(_state, _field)),    \
> > -        .defval.i  = (bool)_defval,                              \
> > +#define DEFINE_PROP_BOOL(_name, _state, _field, _defval) {      \
> > +        .name      = (_name),                                   \
> > +        .info      = &(qdev_prop_bool),                         \
> > +        .offset    = offsetof(_state, _field)                   \
> > +            + type_check(bool, typeof_field(_state, _field)),   \
> > +        .defval.u    = (bool)_defval,                           \
> >          }
>
> Likewise.
>
> >
> >  #define PROP_ARRAY_LEN_PREFIX "len-"
> > @@ -107,17 +118,17 @@ extern PropertyInfo qdev_prop_arraylen;
> >          }
> >
> >  #define DEFINE_PROP_UINT8(_n, _s, _f, _d)                       \
> > -    DEFINE_PROP_INT(_n, _s, _f, _d, qdev_prop_uint8, uint8_t)
> > +    DEFINE_PROP_UINT(_n, _s, _f, _d, qdev_prop_uint8, uint8_t)
> >  #define DEFINE_PROP_UINT16(_n, _s, _f, _d)                      \
> > -    DEFINE_PROP_INT(_n, _s, _f, _d, qdev_prop_uint16, uint16_t)
> > +    DEFINE_PROP_UINT(_n, _s, _f, _d, qdev_prop_uint16, uint16_t)
> >  #define DEFINE_PROP_UINT32(_n, _s, _f, _d)                      \
> > -    DEFINE_PROP_INT(_n, _s, _f, _d, qdev_prop_uint32, uint32_t)
> > +    DEFINE_PROP_UINT(_n, _s, _f, _d, qdev_prop_uint32, uint32_t)
> >  #define DEFINE_PROP_INT32(_n, _s, _f, _d)                      \
> >      DEFINE_PROP_INT(_n, _s, _f, _d, qdev_prop_int32, int32_t)
> >  #define DEFINE_PROP_UINT64(_n, _s, _f, _d)                      \
> > -    DEFINE_PROP_INT(_n, _s, _f, _d, qdev_prop_uint64, uint64_t)
> > +    DEFINE_PROP_UINT(_n, _s, _f, _d, qdev_prop_uint64, uint64_t)
> >  #define DEFINE_PROP_SIZE(_n, _s, _f, _d)                       \
> > -    DEFINE_PROP_INT(_n, _s, _f, _d, qdev_prop_size, uint64_t)
> > +    DEFINE_PROP_UINT(_n, _s, _f, _d, qdev_prop_size, uint64_t)
> >  #define DEFINE_PROP_PCI_DEVFN(_n, _s, _f, _d)                   \
> >      DEFINE_PROP_INT(_n, _s, _f, _d, qdev_prop_pci_devfn, int32_t)
> >
> > @@ -163,7 +174,7 @@ extern PropertyInfo qdev_prop_arraylen;
> >  #define DEFINE_PROP_BIOS_CHS_TRANS(_n, _s, _f, _d) \
> >      DEFINE_PROP_INT(_n, _s, _f, _d, qdev_prop_bios_chs_trans, int)
> >  #define DEFINE_PROP_BLOCKSIZE(_n, _s, _f) \
> > -    DEFINE_PROP_INT(_n, _s, _f, 0, qdev_prop_blocksize, uint16_t)
> > +    DEFINE_PROP_UINT(_n, _s, _f, 0, qdev_prop_blocksize, uint16_t)
> >  #define DEFINE_PROP_PCI_HOST_DEVADDR(_n, _s, _f) \
> >      DEFINE_PROP(_n, _s, _f, qdev_prop_pci_host_devaddr,
> PCIHostDeviceAddress)
> >
> > diff --git a/hw/core/qdev-properties.c b/hw/core/qdev-properties.c
> > index 952cda7758..92fb43cb0d 100644
> > --- a/hw/core/qdev-properties.c
> > +++ b/hw/core/qdev-properties.c
> > @@ -71,7 +71,7 @@ static void set_enum(Object *obj, Visitor *v, const
> char *name, void *opaque,
> >
> >  static void set_default_value_enum(Object *obj, const Property *prop)
> >  {
> > -    object_property_set_str(obj, prop->info->enum_table[prop->defval.i],
> > +    object_property_set_str(obj, prop->info->enum_table[prop->defval.u],
> >                              prop->name, &error_abort);
> >  }
> >
> > @@ -128,7 +128,7 @@ static void prop_set_bit(Object *obj, Visitor *v,
> const char *name,
> >
> >  static void set_default_value_bool(Object *obj, const Property *prop)
> >  {
> > -    object_property_set_bool(obj, prop->defval.i, prop->name,
> &error_abort);
> > +    object_property_set_bool(obj, prop->defval.u, prop->name,
> &error_abort);
> >  }
> >
> >  PropertyInfo qdev_prop_bit = {
> > @@ -264,11 +264,16 @@ static void set_default_value_int(Object *obj,
> const Property *prop)
> >      object_property_set_int(obj, prop->defval.i, prop->name,
> &error_abort);
> >  }
> >
> > +static void set_default_value_uint(Object *obj, const Property *prop)
> > +{
> > +    object_property_set_uint(obj, prop->defval.u, prop->name,
> &error_abort);
> > +}
> > +
> >  PropertyInfo qdev_prop_uint8 = {
> >      .name  = "uint8",
> >      .get   = get_uint8,
> >      .set   = set_uint8,
> > -    .set_default_value = set_default_value_int,
> > +    .set_default_value = set_default_value_uint,
> >  };
> >
> >  /* --- 16bit integer --- */
> > @@ -302,7 +307,7 @@ PropertyInfo qdev_prop_uint16 = {
> >      .name  = "uint16",
> >      .get   = get_uint16,
> >      .set   = set_uint16,
> > -    .set_default_value = set_default_value_int,
> > +    .set_default_value = set_default_value_uint,
> >  };
> >
> >  /* --- 32bit integer --- */
> > @@ -361,7 +366,7 @@ PropertyInfo qdev_prop_uint32 = {
> >      .name  = "uint32",
> >      .get   = get_uint32,
> >      .set   = set_uint32,
> > -    .set_default_value = set_default_value_int,
> > +    .set_default_value = set_default_value_uint,
> >  };
> >
> >  PropertyInfo qdev_prop_int32 = {
> > @@ -402,7 +407,7 @@ PropertyInfo qdev_prop_uint64 = {
> >      .name  = "uint64",
> >      .get   = get_uint64,
> >      .set   = set_uint64,
> > -    .set_default_value = set_default_value_int,
> > +    .set_default_value = set_default_value_uint,
> >  };
> >
> >  /* --- string --- */
> > @@ -725,7 +730,7 @@ PropertyInfo qdev_prop_blocksize = {
> >      .description = "A power of two between 512 and 32768",
> >      .get   = get_uint16,
> >      .set   = set_blocksize,
> > -    .set_default_value = set_default_value_int,
> > +    .set_default_value = set_default_value_uint,
> >  };
> >
> >  /* --- pci host address --- */
> > @@ -948,7 +953,7 @@ PropertyInfo qdev_prop_arraylen = {
> >      .name = "uint32",
> >      .get = get_uint32,
> >      .set = set_prop_arraylen,
> > -    .set_default_value = set_default_value_int,
> > +    .set_default_value = set_default_value_uint,
> >  };
> >
> >  /* --- public helpers --- */
> > @@ -1185,5 +1190,5 @@ PropertyInfo qdev_prop_size = {
> >      .name  = "size",
> >      .get = get_size,
> >      .set = set_size,
> > -    .set_default_value = set_default_value_int,
> > +    .set_default_value = set_default_value_uint,
> >  };
>
> --
Marc-André Lureau

^ permalink raw reply	[flat|nested] 80+ messages in thread

* Re: [Qemu-devel] [PATCH v2 19/45] qdev: add unsigned properties
  2017-06-02 14:00     ` Marc-André Lureau
@ 2017-06-02 14:05       ` Marc-André Lureau
  2017-06-06 12:33         ` Markus Armbruster
  0 siblings, 1 reply; 80+ messages in thread
From: Marc-André Lureau @ 2017-06-02 14:05 UTC (permalink / raw)
  To: Markus Armbruster; +Cc: qemu-devel

On Fri, Jun 2, 2017 at 6:00 PM Marc-André Lureau <marcandre.lureau@gmail.com>
wrote:

> On Fri, Jun 2, 2017 at 5:55 PM Markus Armbruster <armbru@redhat.com>
> wrote:
>
>> Marc-André Lureau <marcandre.lureau@redhat.com> writes:
>>
>> > Add and use unsigned type for various properties.
>> >
>> > Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
>>
>> The commit message is a bit misleading.  We don't "add unsigned
>> properties", we clean up the property code to avoid type casts between
>> signed and unsigned.
>>
>
> That in itself is imho a good reason for the cleanup :)
>

There might be other reason, as if a value is stored as negative QNum/i64
after cast, and later retrieve with get_uint(), it will fail.


>> I'm not sure that's worth the churn by itself.  But perhaps it helps
>> later in this series.  If yes, can you give me a hint?
>>
>
> Churn is quite minimal though.
>
>
>>
>> > ---
>> >  include/hw/qdev-core.h       |  1 +
>> >  include/hw/qdev-properties.h | 51
>> +++++++++++++++++++++++++++-----------------
>> >  hw/core/qdev-properties.c    | 23 ++++++++++++--------
>> >  3 files changed, 46 insertions(+), 29 deletions(-)
>> >
>> > diff --git a/include/hw/qdev-core.h b/include/hw/qdev-core.h
>> > index 784971b8d8..9d7c1c0e9b 100644
>> > --- a/include/hw/qdev-core.h
>> > +++ b/include/hw/qdev-core.h
>> > @@ -228,6 +228,7 @@ struct Property {
>> >      uint8_t      bitnr;
>> >      union {
>> >          int64_t i;
>> > +        uint64_t u;
>> >      } defval;
>> >      int          arrayoffset;
>> >      PropertyInfo *arrayinfo;
>> > diff --git a/include/hw/qdev-properties.h b/include/hw/qdev-properties.h
>> > index 6663a547ea..16d3ada8df 100644
>> > --- a/include/hw/qdev-properties.h
>> > +++ b/include/hw/qdev-properties.h
>> > @@ -37,6 +37,7 @@ extern PropertyInfo qdev_prop_arraylen;
>> >          .offset    = offsetof(_state, _field)                    \
>> >              + type_check(_type, typeof_field(_state, _field)),   \
>> >          }
>> > +
>> >  #define DEFINE_PROP_INT(_name, _state, _field, _defval, _prop, _type)
>> { \
>> >          .name      = (_name),
>>  \
>> >          .info      = &(_prop),
>>   \
>> > @@ -44,29 +45,39 @@ extern PropertyInfo qdev_prop_arraylen;
>> >              + type_check(_type,typeof_field(_state, _field)),
>>  \
>> >          .defval.i  = (_type)_defval,
>>   \
>> >          }
>> > -#define DEFINE_PROP_BIT(_name, _state, _field, _bit, _defval) {  \
>> > -        .name      = (_name),                                    \
>> > -        .info      = &(qdev_prop_bit),                           \
>> > -        .bitnr    = (_bit),                                      \
>> > -        .offset    = offsetof(_state, _field)                    \
>> > -            + type_check(uint32_t,typeof_field(_state, _field)), \
>> > -        .defval.i  = (bool)_defval,                              \
>> > +
>> > +#define DEFINE_PROP_BIT(_name, _state, _field, _bit, _defval) {
>>  \
>> > +        .name      = (_name),
>>  \
>> > +        .info      = &(qdev_prop_bit),
>>   \
>> > +        .bitnr    = (_bit),
>>  \
>> > +        .offset    = offsetof(_state, _field)
>>  \
>> > +            + type_check(uint32_t, typeof_field(_state, _field)),
>>   \
>> > +        .defval.u   = (bool)_defval,
>>   \
>> >          }
>>
>> Let's keep the backslashes where they are to reduce churn.
>>
>> > +
>> > +#define DEFINE_PROP_UINT(_name, _state, _field, _defval, _prop, _type)
>> { \
>> > +        .name      = (_name),
>>  \
>> > +        .info      = &(_prop),
>>   \
>> > +        .offset    = offsetof(_state, _field)
>>  \
>> > +            + type_check(_type, typeof_field(_state, _field)),
>>   \
>> > +        .defval.u  = (_type)_defval,
>>   \
>> > +        }
>> > +
>> >  #define DEFINE_PROP_BIT64(_name, _state, _field, _bit, _defval) {
>>  \
>> >          .name      = (_name),
>>  \
>> >          .info      = &(qdev_prop_bit64),
>>   \
>> >          .bitnr    = (_bit),
>>  \
>> >          .offset    = offsetof(_state, _field)
>>  \
>> >              + type_check(uint64_t, typeof_field(_state, _field)),
>>  \
>> > -        .defval.i  = (bool)_defval,
>>  \
>> > +        .defval.u  = (bool)_defval,
>>  \
>> >          }
>> >
>> > -#define DEFINE_PROP_BOOL(_name, _state, _field, _defval) {       \
>> > -        .name      = (_name),                                    \
>> > -        .info      = &(qdev_prop_bool),                          \
>> > -        .offset    = offsetof(_state, _field)                    \
>> > -            + type_check(bool, typeof_field(_state, _field)),    \
>> > -        .defval.i  = (bool)_defval,                              \
>> > +#define DEFINE_PROP_BOOL(_name, _state, _field, _defval) {      \
>> > +        .name      = (_name),                                   \
>> > +        .info      = &(qdev_prop_bool),                         \
>> > +        .offset    = offsetof(_state, _field)                   \
>> > +            + type_check(bool, typeof_field(_state, _field)),   \
>> > +        .defval.u    = (bool)_defval,                           \
>> >          }
>>
>> Likewise.
>>
>> >
>> >  #define PROP_ARRAY_LEN_PREFIX "len-"
>> > @@ -107,17 +118,17 @@ extern PropertyInfo qdev_prop_arraylen;
>> >          }
>> >
>> >  #define DEFINE_PROP_UINT8(_n, _s, _f, _d)                       \
>> > -    DEFINE_PROP_INT(_n, _s, _f, _d, qdev_prop_uint8, uint8_t)
>> > +    DEFINE_PROP_UINT(_n, _s, _f, _d, qdev_prop_uint8, uint8_t)
>> >  #define DEFINE_PROP_UINT16(_n, _s, _f, _d)                      \
>> > -    DEFINE_PROP_INT(_n, _s, _f, _d, qdev_prop_uint16, uint16_t)
>> > +    DEFINE_PROP_UINT(_n, _s, _f, _d, qdev_prop_uint16, uint16_t)
>> >  #define DEFINE_PROP_UINT32(_n, _s, _f, _d)                      \
>> > -    DEFINE_PROP_INT(_n, _s, _f, _d, qdev_prop_uint32, uint32_t)
>> > +    DEFINE_PROP_UINT(_n, _s, _f, _d, qdev_prop_uint32, uint32_t)
>> >  #define DEFINE_PROP_INT32(_n, _s, _f, _d)                      \
>> >      DEFINE_PROP_INT(_n, _s, _f, _d, qdev_prop_int32, int32_t)
>> >  #define DEFINE_PROP_UINT64(_n, _s, _f, _d)                      \
>> > -    DEFINE_PROP_INT(_n, _s, _f, _d, qdev_prop_uint64, uint64_t)
>> > +    DEFINE_PROP_UINT(_n, _s, _f, _d, qdev_prop_uint64, uint64_t)
>> >  #define DEFINE_PROP_SIZE(_n, _s, _f, _d)                       \
>> > -    DEFINE_PROP_INT(_n, _s, _f, _d, qdev_prop_size, uint64_t)
>> > +    DEFINE_PROP_UINT(_n, _s, _f, _d, qdev_prop_size, uint64_t)
>> >  #define DEFINE_PROP_PCI_DEVFN(_n, _s, _f, _d)                   \
>> >      DEFINE_PROP_INT(_n, _s, _f, _d, qdev_prop_pci_devfn, int32_t)
>> >
>> > @@ -163,7 +174,7 @@ extern PropertyInfo qdev_prop_arraylen;
>> >  #define DEFINE_PROP_BIOS_CHS_TRANS(_n, _s, _f, _d) \
>> >      DEFINE_PROP_INT(_n, _s, _f, _d, qdev_prop_bios_chs_trans, int)
>> >  #define DEFINE_PROP_BLOCKSIZE(_n, _s, _f) \
>> > -    DEFINE_PROP_INT(_n, _s, _f, 0, qdev_prop_blocksize, uint16_t)
>> > +    DEFINE_PROP_UINT(_n, _s, _f, 0, qdev_prop_blocksize, uint16_t)
>> >  #define DEFINE_PROP_PCI_HOST_DEVADDR(_n, _s, _f) \
>> >      DEFINE_PROP(_n, _s, _f, qdev_prop_pci_host_devaddr,
>> PCIHostDeviceAddress)
>> >
>> > diff --git a/hw/core/qdev-properties.c b/hw/core/qdev-properties.c
>> > index 952cda7758..92fb43cb0d 100644
>> > --- a/hw/core/qdev-properties.c
>> > +++ b/hw/core/qdev-properties.c
>> > @@ -71,7 +71,7 @@ static void set_enum(Object *obj, Visitor *v, const
>> char *name, void *opaque,
>> >
>> >  static void set_default_value_enum(Object *obj, const Property *prop)
>> >  {
>> > -    object_property_set_str(obj,
>> prop->info->enum_table[prop->defval.i],
>> > +    object_property_set_str(obj,
>> prop->info->enum_table[prop->defval.u],
>> >                              prop->name, &error_abort);
>> >  }
>> >
>> > @@ -128,7 +128,7 @@ static void prop_set_bit(Object *obj, Visitor *v,
>> const char *name,
>> >
>> >  static void set_default_value_bool(Object *obj, const Property *prop)
>> >  {
>> > -    object_property_set_bool(obj, prop->defval.i, prop->name,
>> &error_abort);
>> > +    object_property_set_bool(obj, prop->defval.u, prop->name,
>> &error_abort);
>> >  }
>> >
>> >  PropertyInfo qdev_prop_bit = {
>> > @@ -264,11 +264,16 @@ static void set_default_value_int(Object *obj,
>> const Property *prop)
>> >      object_property_set_int(obj, prop->defval.i, prop->name,
>> &error_abort);
>> >  }
>> >
>> > +static void set_default_value_uint(Object *obj, const Property *prop)
>> > +{
>> > +    object_property_set_uint(obj, prop->defval.u, prop->name,
>> &error_abort);
>> > +}
>> > +
>> >  PropertyInfo qdev_prop_uint8 = {
>> >      .name  = "uint8",
>> >      .get   = get_uint8,
>> >      .set   = set_uint8,
>> > -    .set_default_value = set_default_value_int,
>> > +    .set_default_value = set_default_value_uint,
>> >  };
>> >
>> >  /* --- 16bit integer --- */
>> > @@ -302,7 +307,7 @@ PropertyInfo qdev_prop_uint16 = {
>> >      .name  = "uint16",
>> >      .get   = get_uint16,
>> >      .set   = set_uint16,
>> > -    .set_default_value = set_default_value_int,
>> > +    .set_default_value = set_default_value_uint,
>> >  };
>> >
>> >  /* --- 32bit integer --- */
>> > @@ -361,7 +366,7 @@ PropertyInfo qdev_prop_uint32 = {
>> >      .name  = "uint32",
>> >      .get   = get_uint32,
>> >      .set   = set_uint32,
>> > -    .set_default_value = set_default_value_int,
>> > +    .set_default_value = set_default_value_uint,
>> >  };
>> >
>> >  PropertyInfo qdev_prop_int32 = {
>> > @@ -402,7 +407,7 @@ PropertyInfo qdev_prop_uint64 = {
>> >      .name  = "uint64",
>> >      .get   = get_uint64,
>> >      .set   = set_uint64,
>> > -    .set_default_value = set_default_value_int,
>> > +    .set_default_value = set_default_value_uint,
>> >  };
>> >
>> >  /* --- string --- */
>> > @@ -725,7 +730,7 @@ PropertyInfo qdev_prop_blocksize = {
>> >      .description = "A power of two between 512 and 32768",
>> >      .get   = get_uint16,
>> >      .set   = set_blocksize,
>> > -    .set_default_value = set_default_value_int,
>> > +    .set_default_value = set_default_value_uint,
>> >  };
>> >
>> >  /* --- pci host address --- */
>> > @@ -948,7 +953,7 @@ PropertyInfo qdev_prop_arraylen = {
>> >      .name = "uint32",
>> >      .get = get_uint32,
>> >      .set = set_prop_arraylen,
>> > -    .set_default_value = set_default_value_int,
>> > +    .set_default_value = set_default_value_uint,
>> >  };
>> >
>> >  /* --- public helpers --- */
>> > @@ -1185,5 +1190,5 @@ PropertyInfo qdev_prop_size = {
>> >      .name  = "size",
>> >      .get = get_size,
>> >      .set = set_size,
>> > -    .set_default_value = set_default_value_int,
>> > +    .set_default_value = set_default_value_uint,
>> >  };
>>
>> --
> Marc-André Lureau
>
-- 
Marc-André Lureau

^ permalink raw reply	[flat|nested] 80+ messages in thread

* Re: [Qemu-devel] [PATCH v2 20/45] apic-common: make "id" property a uint32
  2017-05-31 13:56 ` [Qemu-devel] [PATCH v2 20/45] apic-common: make "id" property a uint32 Marc-André Lureau
@ 2017-06-02 14:05   ` Markus Armbruster
  0 siblings, 0 replies; 80+ messages in thread
From: Markus Armbruster @ 2017-06-02 14:05 UTC (permalink / raw)
  To: Marc-André Lureau; +Cc: qemu-devel

Marc-André Lureau <marcandre.lureau@redhat.com> writes:

> Change suggested by Markus Armbruster:
>
> This one's a bit of a mess.

Drop these two lines, and append
Suggested-by: Markus Armbruster <armbru@redhat.com>

> The getter and setter of TYPE_APIC_COMMON property "id" are
> apic_common_get_id() and apic_common_set_id().
>
> apic_common_get_id() reads either APICCommonState member uint32_t
> initial_apic_id or uint8_t id into an int64_t local variable.  It then
> passes this variable to visit_type_int().
>
> apic_common_set_id() uses visit_type_int() to read the value into a
> local variable, which it then assigns both to initial_apic_id and id.
>
> While the state backing the property is two unsigned members, 8 and 32
> bits wide, the actual visitor is 64 bits signed.
>
> cpu->apic_id is uint32_t.
>
> qdev_prop_set_uint32() isn't really wrong, because any uint32_t value is
> also a valid int64_t value.
>
> qdev_prop_set_int32() implicitly converts cpu->apic_id from uint32_t
> to int32_t.  Perhaps that's even okay, but I don't care, I want this
> mess cleaned up

I think the previous three paragraphs only apply to your PATCH v1 13/17,
not here.  Drop?

> Change getter and setter to use visit_type_uint32().  Then everything's
> uint32_t, except for @id.
>
> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
> ---
>  hw/intc/apic_common.c | 10 +++++-----
>  1 file changed, 5 insertions(+), 5 deletions(-)
>
> diff --git a/hw/intc/apic_common.c b/hw/intc/apic_common.c
> index 1ef56f8d10..e1ac33042f 100644
> --- a/hw/intc/apic_common.c
> +++ b/hw/intc/apic_common.c
> @@ -450,10 +450,10 @@ static void apic_common_get_id(Object *obj, Visitor *v, const char *name,
>                                 void *opaque, Error **errp)
>  {
>      APICCommonState *s = APIC_COMMON(obj);
> -    int64_t value;
> +    uint32_t value;
>  
>      value = s->apicbase & MSR_IA32_APICBASE_EXTD ? s->initial_apic_id : s->id;
> -    visit_type_int(v, name, &value, errp);
> +    visit_type_uint32(v, name, &value, errp);
>  }
>  
>  static void apic_common_set_id(Object *obj, Visitor *v, const char *name,
> @@ -462,14 +462,14 @@ static void apic_common_set_id(Object *obj, Visitor *v, const char *name,
>      APICCommonState *s = APIC_COMMON(obj);
>      DeviceState *dev = DEVICE(obj);
>      Error *local_err = NULL;
> -    int64_t value;
> +    uint32_t value;
>  
>      if (dev->realized) {
>          qdev_prop_set_after_realize(dev, name, errp);
>          return;
>      }
>  
> -    visit_type_int(v, name, &value, &local_err);
> +    visit_type_uint32(v, name, &value, &local_err);
>      if (local_err) {
>          error_propagate(errp, local_err);
>          return;
> @@ -484,7 +484,7 @@ static void apic_common_initfn(Object *obj)
>      APICCommonState *s = APIC_COMMON(obj);
>  
>      s->id = s->initial_apic_id = -1;
> -    object_property_add(obj, "id", "int",
> +    object_property_add(obj, "id", "uint32",
>                          apic_common_get_id,
>                          apic_common_set_id, NULL, NULL, NULL);
>  }

^ permalink raw reply	[flat|nested] 80+ messages in thread

* Re: [Qemu-devel] [PATCH v2 21/45] qdev: use appropriate getter/setters type
  2017-05-31 13:56 ` [Qemu-devel] [PATCH v2 21/45] qdev: use appropriate getter/setters type Marc-André Lureau
@ 2017-06-02 14:51   ` Markus Armbruster
  0 siblings, 0 replies; 80+ messages in thread
From: Markus Armbruster @ 2017-06-02 14:51 UTC (permalink / raw)
  To: Marc-André Lureau; +Cc: qemu-devel

Marc-André Lureau <marcandre.lureau@redhat.com> writes:

> Based on underlying property type, use the appropriate getters/setters.

Well, the getter and setter is the closest thing to a property type QOM
has.  Do you mean the type of the data accessed by the getter and
setter?

> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>

Patch looks okay.

^ permalink raw reply	[flat|nested] 80+ messages in thread

* Re: [Qemu-devel] [PATCH v2 31/45] acpi: use get_uint() for "pci-hole*" properties
  2017-05-31 13:56 ` [Qemu-devel] [PATCH v2 31/45] acpi: use get_uint() for "pci-hole*" properties Marc-André Lureau
@ 2017-06-06 12:24   ` Markus Armbruster
  0 siblings, 0 replies; 80+ messages in thread
From: Markus Armbruster @ 2017-06-06 12:24 UTC (permalink / raw)
  To: Marc-André Lureau; +Cc: qemu-devel

Marc-André Lureau <marcandre.lureau@redhat.com> writes:

> Those properties use visit_type_uint*()
>
> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
> ---
>  hw/i386/acpi-build.c | 24 ++++++++++++------------
>  1 file changed, 12 insertions(+), 12 deletions(-)
>
> diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
> index 8ae0373541..64a277b974 100644
> --- a/hw/i386/acpi-build.c
> +++ b/hw/i386/acpi-build.c
> @@ -247,19 +247,19 @@ static void acpi_get_pci_holes(Range *hole, Range *hole64)
>      g_assert(pci_host);
>  
>      range_set_bounds1(hole,
> -                      object_property_get_int(pci_host,
> -                                              PCI_HOST_PROP_PCI_HOLE_START,
> -                                              NULL),
> -                      object_property_get_int(pci_host,
> -                                              PCI_HOST_PROP_PCI_HOLE_END,
> -                                              NULL));
> +                      object_property_get_uint(pci_host,
> +                                               PCI_HOST_PROP_PCI_HOLE_START,
> +                                               NULL),
> +                      object_property_get_uint(pci_host,
> +                                               PCI_HOST_PROP_PCI_HOLE_END,
> +                                               NULL));
>      range_set_bounds1(hole64,
> -                      object_property_get_int(pci_host,
> -                                              PCI_HOST_PROP_PCI_HOLE64_START,
> -                                              NULL),
> -                      object_property_get_int(pci_host,
> -                                              PCI_HOST_PROP_PCI_HOLE64_END,
> -                                              NULL));
> +                      object_property_get_uint(pci_host,
> +                                               PCI_HOST_PROP_PCI_HOLE64_START,
> +                                               NULL),
> +                      object_property_get_uint(pci_host,
> +                                               PCI_HOST_PROP_PCI_HOLE64_END,
> +                                               NULL));
>  }
>  
>  #define ACPI_PORT_SMI_CMD           0x00b2 /* TODO: this is APM_CNT_IOPORT */

Related to the hw/pci-host/ part of PATCH 17.  Reshuffling stuff to ease
review is almost certainly not worth the trouble.

I like how PATCH 22-42 justify each change in the commit message.

^ permalink raw reply	[flat|nested] 80+ messages in thread

* Re: [Qemu-devel] [PATCH v2 43/45] tests/qdict: check more get_try_int() cases
  2017-05-31 13:57 ` [Qemu-devel] [PATCH v2 43/45] tests/qdict: check more get_try_int() cases Marc-André Lureau
@ 2017-06-06 12:26   ` Markus Armbruster
  0 siblings, 0 replies; 80+ messages in thread
From: Markus Armbruster @ 2017-06-06 12:26 UTC (permalink / raw)
  To: Marc-André Lureau; +Cc: qemu-devel

Marc-André Lureau <marcandre.lureau@redhat.com> writes:

> Suggested by Markus Armbruster.

Prefer

  Suggested-by: Markus Armbruster <armbru@redhat.com>

> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>

Reviewed-by: Markus Armbruster <armbru@redhat.com>

^ permalink raw reply	[flat|nested] 80+ messages in thread

* Re: [Qemu-devel] [PATCH v2 44/45] RFC: qdict: add uint
  2017-05-31 13:57 ` [Qemu-devel] [PATCH v2 44/45] RFC: qdict: add uint Marc-André Lureau
@ 2017-06-06 12:28   ` Markus Armbruster
  0 siblings, 0 replies; 80+ messages in thread
From: Markus Armbruster @ 2017-06-06 12:28 UTC (permalink / raw)
  To: Marc-André Lureau; +Cc: qemu-devel

Marc-André Lureau <marcandre.lureau@redhat.com> writes:

> Similar to int support, add uint support.
>
> Note this is RFC because this is currently unused in qemu, I haven't
> found a good user for it yet (kaslr qemu-ga code did use it though).
>
> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>

Reviewed-by: Markus Armbruster <armbru@redhat.com>

^ permalink raw reply	[flat|nested] 80+ messages in thread

* Re: [Qemu-devel] [PATCH v2 19/45] qdev: add unsigned properties
  2017-06-02 14:05       ` Marc-André Lureau
@ 2017-06-06 12:33         ` Markus Armbruster
  0 siblings, 0 replies; 80+ messages in thread
From: Markus Armbruster @ 2017-06-06 12:33 UTC (permalink / raw)
  To: Marc-André Lureau; +Cc: qemu-devel

Marc-André Lureau <marcandre.lureau@gmail.com> writes:

> On Fri, Jun 2, 2017 at 6:00 PM Marc-André Lureau <marcandre.lureau@gmail.com>
> wrote:
>
>> On Fri, Jun 2, 2017 at 5:55 PM Markus Armbruster <armbru@redhat.com>
>> wrote:
>>
>>> Marc-André Lureau <marcandre.lureau@redhat.com> writes:
>>>
>>> > Add and use unsigned type for various properties.
>>> >
>>> > Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
>>>
>>> The commit message is a bit misleading.  We don't "add unsigned
>>> properties", we clean up the property code to avoid type casts between
>>> signed and unsigned.
>>>
>>
>> That in itself is imho a good reason for the cleanup :)

I could accept that with a commit message that says so :)

> There might be other reason, as if a value is stored as negative QNum/i64
> after cast, and later retrieve with get_uint(), it will fail.

I see.

>>> I'm not sure that's worth the churn by itself.  But perhaps it helps
>>> later in this series.  If yes, can you give me a hint?
>>>
>>
>> Churn is quite minimal though.

^ permalink raw reply	[flat|nested] 80+ messages in thread

* Re: [Qemu-devel] [PATCH v2 00/45] qobject/qapi: add uint type
  2017-05-31 13:56 [Qemu-devel] [PATCH v2 00/45] qobject/qapi: add uint type Marc-André Lureau
                   ` (45 preceding siblings ...)
  2017-05-31 20:06 ` [Qemu-devel] [PATCH v2 00/45] qobject/qapi: add uint type no-reply
@ 2017-06-06 12:36 ` Markus Armbruster
  46 siblings, 0 replies; 80+ messages in thread
From: Markus Armbruster @ 2017-06-06 12:36 UTC (permalink / raw)
  To: Marc-André Lureau; +Cc: qemu-devel

Marc-André Lureau <marcandre.lureau@redhat.com> writes:

> Hi,
>
> In previously sent series "[PATCH 00/21] WIP: dump: add kaslr support
> (for after 2.9)", I proposed changes to accept uint64 values from
> json, by adding a QUint type. During review, it was suggested to
> introduce a QNum type to hold various number representations.
>
> This series introduces the QNum type, adds uint representation to it,
> and make uint64 values over json possible (while keeping json negative
> int for values >INT64_MAX to unsigned cast compatibility). It also
> improves some int vs uint usage for object properties and other
> QObject related clean-ups.
>
> The series includes previously sent "qapi: Handle some keyval fallout"
> series to help with automated testing.

PATCH 09 hasn't quite converged, but the rest looks pretty close now.
I hope we can wrap this up without trouble :)

^ permalink raw reply	[flat|nested] 80+ messages in thread

* Re: [Qemu-devel] [PATCH v2 08/45] tests: add more int/number ranges checks
  2017-06-01 14:09   ` Markus Armbruster
@ 2017-06-06 16:14     ` Marc-André Lureau
  2017-06-06 19:08       ` Markus Armbruster
  0 siblings, 1 reply; 80+ messages in thread
From: Marc-André Lureau @ 2017-06-06 16:14 UTC (permalink / raw)
  To: Markus Armbruster; +Cc: qemu-devel

Hi

On Thu, Jun 1, 2017 at 6:10 PM Markus Armbruster <armbru@redhat.com> wrote:

> Marc-André Lureau <marcandre.lureau@redhat.com> writes:
>
> > Suggested by Markus Armbruster:
> >
> > We should systematically cover the integers, in particular the
> > boundaries (because that's where bugs like to hide):
> >
> > * Integers in [-2^63,0) can be visited with visit_type_int() and
> >   visit_type_number().
> >
> > * Integers in [0,2^63) can be visited with visit_type_int(),
> >   visit_type_uint64() and visit_type_number().
> >
> > * Integers in [2^63,2^64) can be visited with visit_type_uint64() and
> >   visit_type_number().
> >
> > * Integers outside [-2^63,2^53) can be visited with visit_type_number().
> >
> > In any case, visit_type_number() loses precision beyond 53 bits.
> >
> > Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
> > ---
> >  tests/test-qobject-input-visitor.c | 38
> ++++++++++++++++++++++++++++++++++++--
> >  1 file changed, 36 insertions(+), 2 deletions(-)
> >
> > diff --git a/tests/test-qobject-input-visitor.c
> b/tests/test-qobject-input-visitor.c
> > index 83d663d11d..f2ed3161af 100644
> > --- a/tests/test-qobject-input-visitor.c
> > +++ b/tests/test-qobject-input-visitor.c
> > @@ -102,11 +102,11 @@ static Visitor
> *visitor_input_test_init_raw(TestInputVisitorData *data,
> >  {
> >      return visitor_input_test_init_internal(data, false, json_string,
> NULL);
> >  }
> > -
>
> Whoops.
>
> >  static void test_visitor_in_int(TestInputVisitorData *data,
> >                                  const void *unused)
> >  {
> >      int64_t res = 0;
> > +    double dbl;
> >      int value = -42;
> >      Visitor *v;
> >
> > @@ -114,6 +114,9 @@ static void test_visitor_in_int(TestInputVisitorData
> *data,
> >
> >      visit_type_int(v, NULL, &res, &error_abort);
> >      g_assert_cmpint(res, ==, value);
> > +
> > +    visit_type_number(v, NULL, &dbl, &error_abort);
> > +    g_assert_cmpfloat(dbl, ==, -42.0);
> >  }
> >
> >  static void test_visitor_in_uint(TestInputVisitorData *data,
> > @@ -121,6 +124,8 @@ static void
> test_visitor_in_uint(TestInputVisitorData *data,
> >  {
> >      Error *err = NULL;
> >      uint64_t res = 0;
> > +    int64_t i64;
> > +    double dbl;
> >      int value = 42;
> >      Visitor *v;
> >
> > @@ -129,8 +134,13 @@ static void
> test_visitor_in_uint(TestInputVisitorData *data,
> >      visit_type_uint64(v, NULL, &res, &error_abort);
> >      g_assert_cmpuint(res, ==, (uint64_t)value);
> >
> > -    /* BUG: value between INT64_MIN and -1 accepted modulo 2^64 */
> > +    visit_type_int(v, NULL, &i64, &error_abort);
> > +    g_assert_cmpint(i64, ==, value);
> >
> > +    visit_type_number(v, NULL, &dbl, &error_abort);
> > +    g_assert_cmpfloat(dbl, ==, value);
> > +
> > +    /* BUG: value between INT64_MIN and -1 accepted modulo 2^64 */
> >      v = visitor_input_test_init(data, "%d", -value);
> >
> >      visit_type_uint64(v, NULL, &res, &error_abort);
> > @@ -142,6 +152,8 @@ static void
> test_visitor_in_uint(TestInputVisitorData *data,
> >
> >      visit_type_uint64(v, NULL, &res, &err);
> >      error_free_or_abort(&err);
> > +
> > +    visit_type_number(v, NULL, &dbl, &error_abort);
> >  }
> >
> >  static void test_visitor_in_int_overflow(TestInputVisitorData *data,
> > @@ -260,6 +272,26 @@ static void
> test_visitor_in_number(TestInputVisitorData *data,
> >      g_assert_cmpfloat(res, ==, value);
> >  }
> >
> > +static void test_visitor_in_large_number(TestInputVisitorData *data,
> > +                                         const void *unused)
> > +{
> > +    Error *err = NULL;
> > +    double res = 0;
> > +    int64_t i64;
> > +    uint64_t u64;
> > +    Visitor *v;
> > +
> > +    v = visitor_input_test_init(data, "-18446744073709551616"); /*
> -2^64 */
> > +
> > +    visit_type_number(v, NULL, &res, &error_abort);
>
> Shouldn't we check res has the expected value?
>
>
Is the precision loss during conversion  going to be the same on all archs?
-- 
Marc-André Lureau

^ permalink raw reply	[flat|nested] 80+ messages in thread

* Re: [Qemu-devel] [PATCH v2 08/45] tests: add more int/number ranges checks
  2017-06-06 16:14     ` Marc-André Lureau
@ 2017-06-06 19:08       ` Markus Armbruster
  0 siblings, 0 replies; 80+ messages in thread
From: Markus Armbruster @ 2017-06-06 19:08 UTC (permalink / raw)
  To: Marc-André Lureau; +Cc: qemu-devel

Marc-André Lureau <marcandre.lureau@gmail.com> writes:

> Hi
>
> On Thu, Jun 1, 2017 at 6:10 PM Markus Armbruster <armbru@redhat.com> wrote:
>
>> Marc-André Lureau <marcandre.lureau@redhat.com> writes:
>>
>> > Suggested by Markus Armbruster:
>> >
>> > We should systematically cover the integers, in particular the
>> > boundaries (because that's where bugs like to hide):
>> >
>> > * Integers in [-2^63,0) can be visited with visit_type_int() and
>> >   visit_type_number().
>> >
>> > * Integers in [0,2^63) can be visited with visit_type_int(),
>> >   visit_type_uint64() and visit_type_number().
>> >
>> > * Integers in [2^63,2^64) can be visited with visit_type_uint64() and
>> >   visit_type_number().
>> >
>> > * Integers outside [-2^63,2^53) can be visited with visit_type_number().
>> >
>> > In any case, visit_type_number() loses precision beyond 53 bits.
>> >
>> > Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
[...]
>> > @@ -260,6 +272,26 @@ static void test_visitor_in_number(TestInputVisitorData *data,
>> >      g_assert_cmpfloat(res, ==, value);
>> >  }
>> >
>> > +static void test_visitor_in_large_number(TestInputVisitorData *data,
>> > +                                         const void *unused)
>> > +{
>> > +    Error *err = NULL;
>> > +    double res = 0;
>> > +    int64_t i64;
>> > +    uint64_t u64;
>> > +    Visitor *v;
>> > +
>> > +    v = visitor_input_test_init(data, "-18446744073709551616"); /* -2^64 */
>> > +
>> > +    visit_type_number(v, NULL, &res, &error_abort);
>>
>> Shouldn't we check res has the expected value?
>>
>>
> Is the precision loss during conversion  going to be the same on all archs?

Yes.  Precision is 53 bits on all hosts that matter, because double is
IEEE 754 / IEC 60559 double precision on all hosts that matter.

For pedantic portability, you may guard with #ifdef __STDC_IEC_559__.
ISO/IEC 9899 §6.8.10 Predefined macro names:

       __STDC_IEC_559__ The   integer   constant   1,  intended  to
                indicate conformance to the specifications in annex
                F (IEC 60559 floating-point arithmetic).

Annex F (normative) section F.2 Types:

         -- The double type matches the IEC 60559 double format.

I wouldn't bother.

^ permalink raw reply	[flat|nested] 80+ messages in thread

* Re: [Qemu-devel] [PATCH v2 05/45] qdev: remove PropertyInfo.qtype field
  2017-06-01 11:19   ` Markus Armbruster
@ 2017-06-07 12:31     ` Peter Maydell
  2017-06-07 13:09       ` Markus Armbruster
  0 siblings, 1 reply; 80+ messages in thread
From: Peter Maydell @ 2017-06-07 12:31 UTC (permalink / raw)
  To: Markus Armbruster; +Cc: Marc-André Lureau, QEMU Developers

On 1 June 2017 at 12:19, Markus Armbruster <armbru@redhat.com> wrote:
> Lovely cleanup.
>
> The interesting part is the move of the bits controlling use of ->defval
> from Property member .qtype (set only by DEFINE_PROP_foo() macros) to
> its PropertyInfo method .info->set_default_value().  No functional
> change if (1) we preserve existing use of ->defval and (2) we don't add
> new uses of ->defval, or at least not uses that matter.
>
> Direction (1) is obvious for DEFINE_PROP_BIT(), DEFINE_PROP_BIT64(),
> DEFINE_PROP_BOOL().  They set .info to &qdev_prop_bit, &qdev_prop_bit64,
> &qdev_prop_bool, respectively.  These all get .set_default_value =
> set_default_value_bool, which preserves the effect of .qtype =
> QTYPE_BOOL.  Good.
>
> DEFINE_PROP_DEFAULT() sets .info to point to its argument _prop.  The
> following arguments occur:
>
> * In include/hw/qdev-properties.h: qdev_prop_uint8, qdev_prop_uint16,
>   qdev_prop_uint32, qdev_prop_int32, qdev_prop_uint64, qdev_prop_size,
>   qdev_prop_pci_devfn, qdev_prop_on_off_auto, qdev_prop_losttickpolicy,
>   qdev_prop_blockdev_on_error, qdev_prop_bios_chs_trans,
>   qdev_prop_blocksize
>
> * In hw/block/fdc.c: qdev_prop_fdc_drive_type
>
> * In hw/net/e1000e.c: local copies of qdev_prop_uint8, qdev_prop_uint16.
>
> To preserve the effect of .qtype = QTYPE_QINT, these PropertyInfo need
> .set_default_value = set_default_value_int or .set_default_value =
> set_default_value_enum, depending on .enum_table.  They get it.  Good.
>
> DEFINE_PROP_ARRAY() sets .info to &qdev_prop_arraylen.  Needs and gets
> .set_default_value = set_default_value_int.  Good.
>
> DEFINE_PROP_ARRAY() also takes a PropertyInfo argument, but it's not
> relevant here, as the .qtype you remove doesn't apply to it.  I'm
> mentioning this, because it confused me briefly.
>
> Direction (2) isn't as visible in the patch.  For each PropertyInfo you
> change, we need to find and check stores into .info not wrapped in the
> DEFINE_PROP_foo() macros you change.
>
> I can't find any.  Good.

I think this is going to break a patch I was halfway through
writing :-(

What I want is "DEFINE_PROP_UINT32, but don't set the default value"
(because the default value in this case (a) isn't constant and
(b) is already in the struct field that the property modifies).
My plan for doing this was:
 static Property arm_cpu_pmsav7_dregion_property =
    DEFINE_PROP("pmsav7-dregion", ARMCPU, pmsav7_dregion,
                qdev_prop_uint32, uint32_t);

This won't work any more if qdev_property_add_static
assumes that "qdev_prop_uint32" implies "always set the default value".
So how should I obtain those semantics with this cleanup in place ?

thanks
-- PMM

^ permalink raw reply	[flat|nested] 80+ messages in thread

* Re: [Qemu-devel] [PATCH v2 05/45] qdev: remove PropertyInfo.qtype field
  2017-06-07 12:31     ` Peter Maydell
@ 2017-06-07 13:09       ` Markus Armbruster
  2017-06-07 13:44         ` Peter Maydell
  0 siblings, 1 reply; 80+ messages in thread
From: Markus Armbruster @ 2017-06-07 13:09 UTC (permalink / raw)
  To: Peter Maydell; +Cc: Marc-André Lureau, QEMU Developers

Peter Maydell <peter.maydell@linaro.org> writes:

> On 1 June 2017 at 12:19, Markus Armbruster <armbru@redhat.com> wrote:
>> Lovely cleanup.
>>
>> The interesting part is the move of the bits controlling use of ->defval
>> from Property member .qtype (set only by DEFINE_PROP_foo() macros) to
>> its PropertyInfo method .info->set_default_value().  No functional
>> change if (1) we preserve existing use of ->defval and (2) we don't add
>> new uses of ->defval, or at least not uses that matter.
>>
>> Direction (1) is obvious for DEFINE_PROP_BIT(), DEFINE_PROP_BIT64(),
>> DEFINE_PROP_BOOL().  They set .info to &qdev_prop_bit, &qdev_prop_bit64,
>> &qdev_prop_bool, respectively.  These all get .set_default_value =
>> set_default_value_bool, which preserves the effect of .qtype =
>> QTYPE_BOOL.  Good.
>>
>> DEFINE_PROP_DEFAULT() sets .info to point to its argument _prop.  The
>> following arguments occur:
>>
>> * In include/hw/qdev-properties.h: qdev_prop_uint8, qdev_prop_uint16,
>>   qdev_prop_uint32, qdev_prop_int32, qdev_prop_uint64, qdev_prop_size,
>>   qdev_prop_pci_devfn, qdev_prop_on_off_auto, qdev_prop_losttickpolicy,
>>   qdev_prop_blockdev_on_error, qdev_prop_bios_chs_trans,
>>   qdev_prop_blocksize
>>
>> * In hw/block/fdc.c: qdev_prop_fdc_drive_type
>>
>> * In hw/net/e1000e.c: local copies of qdev_prop_uint8, qdev_prop_uint16.
>>
>> To preserve the effect of .qtype = QTYPE_QINT, these PropertyInfo need
>> .set_default_value = set_default_value_int or .set_default_value =
>> set_default_value_enum, depending on .enum_table.  They get it.  Good.
>>
>> DEFINE_PROP_ARRAY() sets .info to &qdev_prop_arraylen.  Needs and gets
>> .set_default_value = set_default_value_int.  Good.
>>
>> DEFINE_PROP_ARRAY() also takes a PropertyInfo argument, but it's not
>> relevant here, as the .qtype you remove doesn't apply to it.  I'm
>> mentioning this, because it confused me briefly.
>>
>> Direction (2) isn't as visible in the patch.  For each PropertyInfo you
>> change, we need to find and check stores into .info not wrapped in the
>> DEFINE_PROP_foo() macros you change.
>>
>> I can't find any.  Good.
>
> I think this is going to break a patch I was halfway through
> writing :-(
>
> What I want is "DEFINE_PROP_UINT32, but don't set the default value"
> (because the default value in this case (a) isn't constant and
> (b) is already in the struct field that the property modifies).
> My plan for doing this was:
>  static Property arm_cpu_pmsav7_dregion_property =
>     DEFINE_PROP("pmsav7-dregion", ARMCPU, pmsav7_dregion,
>                 qdev_prop_uint32, uint32_t);
>
> This won't work any more if qdev_property_add_static
> assumes that "qdev_prop_uint32" implies "always set the default value".

After this patch, qdev_property_add_static() delegates assigning a
default value to prop->info->set_default_value(obj, prop).

qdev_prop_uint32.set_default_value() assigns prop->defval.

> So how should I obtain those semantics with this cleanup in place ?

Two ways come to mind:

* Define a PropertyInfo like qdev_prop_uint32 with a null
  set_default_value(), and use that.

* Add a flag to Property that makes qdev_property_add_static() skip
  prop->info->set_default_value(), set it for your property.

  Actually, I'd probably do it the other way: call ->set_default_value()
  only when the flag is set.  No need to check it's non-null then.
  Setting the flag when it's null is a programming error.

Could one of these two work for you?

^ permalink raw reply	[flat|nested] 80+ messages in thread

* Re: [Qemu-devel] [PATCH v2 05/45] qdev: remove PropertyInfo.qtype field
  2017-06-07 13:09       ` Markus Armbruster
@ 2017-06-07 13:44         ` Peter Maydell
  2017-06-07 17:37           ` Markus Armbruster
  0 siblings, 1 reply; 80+ messages in thread
From: Peter Maydell @ 2017-06-07 13:44 UTC (permalink / raw)
  To: Markus Armbruster; +Cc: Marc-André Lureau, QEMU Developers

On 7 June 2017 at 14:09, Markus Armbruster <armbru@redhat.com> wrote:
> Peter Maydell <peter.maydell@linaro.org> writes:
>> So how should I obtain those semantics with this cleanup in place ?
>
> Two ways come to mind:
>
> * Define a PropertyInfo like qdev_prop_uint32 with a null
>   set_default_value(), and use that.
>
> * Add a flag to Property that makes qdev_property_add_static() skip
>   prop->info->set_default_value(), set it for your property.
>
>   Actually, I'd probably do it the other way: call ->set_default_value()
>   only when the flag is set.  No need to check it's non-null then.
>   Setting the flag when it's null is a programming error.
>
> Could one of these two work for you?

The former would work but duplicates a pile of code from the
qdev_prop_uint32 implementation. The latter would be cleaner
but introduces a dependency on this series -- how close is it
to hitting master?

thanks
-- PMM

^ permalink raw reply	[flat|nested] 80+ messages in thread

* Re: [Qemu-devel] [PATCH v2 05/45] qdev: remove PropertyInfo.qtype field
  2017-06-07 13:44         ` Peter Maydell
@ 2017-06-07 17:37           ` Markus Armbruster
  2017-06-09 14:04             ` Markus Armbruster
  0 siblings, 1 reply; 80+ messages in thread
From: Markus Armbruster @ 2017-06-07 17:37 UTC (permalink / raw)
  To: Peter Maydell; +Cc: Marc-André Lureau, QEMU Developers

Peter Maydell <peter.maydell@linaro.org> writes:

> On 7 June 2017 at 14:09, Markus Armbruster <armbru@redhat.com> wrote:
>> Peter Maydell <peter.maydell@linaro.org> writes:
>>> So how should I obtain those semantics with this cleanup in place ?
>>
>> Two ways come to mind:
>>
>> * Define a PropertyInfo like qdev_prop_uint32 with a null
>>   set_default_value(), and use that.
>>
>> * Add a flag to Property that makes qdev_property_add_static() skip
>>   prop->info->set_default_value(), set it for your property.
>>
>>   Actually, I'd probably do it the other way: call ->set_default_value()
>>   only when the flag is set.  No need to check it's non-null then.
>>   Setting the flag when it's null is a programming error.
>>
>> Could one of these two work for you?
>
> The former would work but duplicates a pile of code from the
> qdev_prop_uint32 implementation. The latter would be cleaner
> but introduces a dependency on this series -- how close is it
> to hitting master?

v2 was close, v3 just hit the list, but I'll be on vacation next week.
Wrapping it up this week seems unrealistic.  Soon after I'm back is my
best estimate.

^ permalink raw reply	[flat|nested] 80+ messages in thread

* Re: [Qemu-devel] [PATCH v2 05/45] qdev: remove PropertyInfo.qtype field
  2017-06-07 17:37           ` Markus Armbruster
@ 2017-06-09 14:04             ` Markus Armbruster
  0 siblings, 0 replies; 80+ messages in thread
From: Markus Armbruster @ 2017-06-09 14:04 UTC (permalink / raw)
  To: Peter Maydell; +Cc: Marc-André Lureau, QEMU Developers

Markus Armbruster <armbru@redhat.com> writes:

> Peter Maydell <peter.maydell@linaro.org> writes:
>
>> On 7 June 2017 at 14:09, Markus Armbruster <armbru@redhat.com> wrote:
>>> Peter Maydell <peter.maydell@linaro.org> writes:
>>>> So how should I obtain those semantics with this cleanup in place ?
>>>
>>> Two ways come to mind:
>>>
>>> * Define a PropertyInfo like qdev_prop_uint32 with a null
>>>   set_default_value(), and use that.
>>>
>>> * Add a flag to Property that makes qdev_property_add_static() skip
>>>   prop->info->set_default_value(), set it for your property.
>>>
>>>   Actually, I'd probably do it the other way: call ->set_default_value()
>>>   only when the flag is set.  No need to check it's non-null then.
>>>   Setting the flag when it's null is a programming error.
>>>
>>> Could one of these two work for you?
>>
>> The former would work but duplicates a pile of code from the
>> qdev_prop_uint32 implementation. The latter would be cleaner
>> but introduces a dependency on this series -- how close is it
>> to hitting master?
>
> v2 was close, v3 just hit the list, but I'll be on vacation next week.
> Wrapping it up this week seems unrealistic.  Soon after I'm back is my
> best estimate.

Review of v3 went swimmingly, pull request is on the list.

^ permalink raw reply	[flat|nested] 80+ messages in thread

end of thread, other threads:[~2017-06-09 14:04 UTC | newest]

Thread overview: 80+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-05-31 13:56 [Qemu-devel] [PATCH v2 00/45] qobject/qapi: add uint type Marc-André Lureau
2017-05-31 13:56 ` [Qemu-devel] [PATCH v2 01/45] qobject-input-visitor: Reject non-finite numbers with keyval Marc-André Lureau
2017-05-31 13:56 ` [Qemu-devel] [PATCH v2 02/45] qapi: Document visit_type_any() issues with keyval input Marc-André Lureau
2017-05-31 13:56 ` [Qemu-devel] [PATCH v2 03/45] tests/qapi-schema: Avoid 'str' in alternate test cases Marc-André Lureau
2017-05-31 13:56 ` [Qemu-devel] [PATCH v2 04/45] qapi: Reject alternates that can't work with keyval_parse() Marc-André Lureau
2017-05-31 13:56 ` [Qemu-devel] [PATCH v2 05/45] qdev: remove PropertyInfo.qtype field Marc-André Lureau
2017-06-01 11:19   ` Markus Armbruster
2017-06-07 12:31     ` Peter Maydell
2017-06-07 13:09       ` Markus Armbruster
2017-06-07 13:44         ` Peter Maydell
2017-06-07 17:37           ` Markus Armbruster
2017-06-09 14:04             ` Markus Armbruster
2017-05-31 13:56 ` [Qemu-devel] [PATCH v2 06/45] object: fix potential leak in getters Marc-André Lureau
2017-06-01 11:32   ` Markus Armbruster
2017-05-31 13:56 ` [Qemu-devel] [PATCH v2 07/45] tests: remove alt num-int cases Marc-André Lureau
2017-06-01 11:58   ` Markus Armbruster
2017-05-31 13:56 ` [Qemu-devel] [PATCH v2 08/45] tests: add more int/number ranges checks Marc-André Lureau
2017-06-01 14:09   ` Markus Armbruster
2017-06-06 16:14     ` Marc-André Lureau
2017-06-06 19:08       ` Markus Armbruster
2017-05-31 13:56 ` [Qemu-devel] [PATCH v2 09/45] qapi: merge QInt and QFloat in QNum Marc-André Lureau
2017-06-02  7:03   ` Markus Armbruster
2017-05-31 13:56 ` [Qemu-devel] [PATCH v2 10/45] qapi: Remove visit_start_alternate() parameter promote_int Marc-André Lureau
2017-06-02  7:57   ` Markus Armbruster
2017-05-31 13:56 ` [Qemu-devel] [PATCH v2 11/45] tests: remove /qnum/destroy test Marc-André Lureau
2017-06-02  8:00   ` Markus Armbruster
2017-05-31 13:56 ` [Qemu-devel] [PATCH v2 12/45] qnum: add uint type Marc-André Lureau
2017-06-02  8:05   ` Markus Armbruster
2017-05-31 13:56 ` [Qemu-devel] [PATCH v2 13/45] json: learn to parse uint64 numbers Marc-André Lureau
2017-06-02  8:24   ` Markus Armbruster
2017-05-31 13:56 ` [Qemu-devel] [PATCH v2 14/45] qapi: update the qobject visitor to use QNUM_U64 Marc-André Lureau
2017-06-02 11:18   ` Markus Armbruster
2017-06-02 11:20   ` Markus Armbruster
2017-06-02 11:34     ` Marc-André Lureau
2017-06-02 12:36       ` Markus Armbruster
2017-05-31 13:56 ` [Qemu-devel] [PATCH v2 15/45] object: add uint property setter/getter Marc-André Lureau
2017-05-31 13:56 ` [Qemu-devel] [PATCH v2 16/45] q35: fix get_mmcfg_size to use uint64 visitor Marc-André Lureau
2017-06-02 11:34   ` Markus Armbruster
2017-05-31 13:56 ` [Qemu-devel] [PATCH v2 17/45] object: use more specific property type names Marc-André Lureau
2017-06-02 13:38   ` Markus Armbruster
2017-05-31 13:56 ` [Qemu-devel] [PATCH v2 18/45] qdev: make default property int Marc-André Lureau
2017-06-02 13:49   ` Markus Armbruster
2017-05-31 13:56 ` [Qemu-devel] [PATCH v2 19/45] qdev: add unsigned properties Marc-André Lureau
2017-06-02 13:55   ` Markus Armbruster
2017-06-02 14:00     ` Marc-André Lureau
2017-06-02 14:05       ` Marc-André Lureau
2017-06-06 12:33         ` Markus Armbruster
2017-05-31 13:56 ` [Qemu-devel] [PATCH v2 20/45] apic-common: make "id" property a uint32 Marc-André Lureau
2017-06-02 14:05   ` Markus Armbruster
2017-05-31 13:56 ` [Qemu-devel] [PATCH v2 21/45] qdev: use appropriate getter/setters type Marc-André Lureau
2017-06-02 14:51   ` Markus Armbruster
2017-05-31 13:56 ` [Qemu-devel] [PATCH v2 22/45] isa: use get_uint() for "io-base" Marc-André Lureau
2017-05-31 13:56 ` [Qemu-devel] [PATCH v2 23/45] pc-dimm: use get_uint() for dimm properties Marc-André Lureau
2017-05-31 13:56 ` [Qemu-devel] [PATCH v2 24/45] pc-dimm: make "size" property uint64 Marc-André Lureau
2017-05-31 13:56 ` [Qemu-devel] [PATCH v2 25/45] pcihp: use get_uint() for "bsel" property Marc-André Lureau
2017-05-31 13:56 ` [Qemu-devel] [PATCH v2 26/45] aspeed: use {set, get}_uint() for "ram-size" property Marc-André Lureau
2017-05-31 13:56 ` [Qemu-devel] [PATCH v2 27/45] bcm2835_fb: use {get, set}_uint() for "vcram-size" and "vcram-base" Marc-André Lureau
2017-05-31 13:56 ` [Qemu-devel] [PATCH v2 28/45] platform-bus: use get_uint() for "addr" property Marc-André Lureau
2017-05-31 13:56 ` [Qemu-devel] [PATCH v2 29/45] acpi: use get_uint() for "acpi-pcihp-io*" properties Marc-André Lureau
2017-05-31 13:56 ` [Qemu-devel] [PATCH v2 30/45] acpi: use get_uint() for various acpi properties Marc-André Lureau
2017-05-31 13:56 ` [Qemu-devel] [PATCH v2 31/45] acpi: use get_uint() for "pci-hole*" properties Marc-André Lureau
2017-06-06 12:24   ` Markus Armbruster
2017-05-31 13:56 ` [Qemu-devel] [PATCH v2 32/45] pc: use get_uint() for "iobase" property Marc-André Lureau
2017-05-31 13:56 ` [Qemu-devel] [PATCH v2 33/45] pc: use get_uint() for "apic-id" property Marc-André Lureau
2017-05-31 13:56 ` [Qemu-devel] [PATCH v2 34/45] pc: use get_uint() for "hpet-intcap" property Marc-André Lureau
2017-05-31 13:56 ` [Qemu-devel] [PATCH v2 35/45] xen: use get_uint() for "max-ram-below-4g" property Marc-André Lureau
2017-05-31 13:57 ` [Qemu-devel] [PATCH v2 36/45] arm: use get_uint() for "mp-affinity" property Marc-André Lureau
2017-05-31 13:57 ` [Qemu-devel] [PATCH v2 37/45] auxbus: use get_uint() for "addr" property Marc-André Lureau
2017-05-31 13:57 ` [Qemu-devel] [PATCH v2 38/45] pvpanic: use get_uint() for "ioport" property Marc-André Lureau
2017-05-31 13:57 ` [Qemu-devel] [PATCH v2 39/45] pnv-core: use get_uint() for "core-pir" property Marc-André Lureau
2017-05-31 13:57 ` [Qemu-devel] [PATCH v2 40/45] numa: use get_uint() for "size" property Marc-André Lureau
2017-05-31 13:57 ` [Qemu-devel] [PATCH v2 41/45] i386/cpu: use get_uint() for "min-level"/"min-xlevel" properties Marc-André Lureau
2017-05-31 13:57 ` [Qemu-devel] [PATCH v2 42/45] console: use get_uint() for "head" property Marc-André Lureau
2017-05-31 13:57 ` [Qemu-devel] [PATCH v2 43/45] tests/qdict: check more get_try_int() cases Marc-André Lureau
2017-06-06 12:26   ` Markus Armbruster
2017-05-31 13:57 ` [Qemu-devel] [PATCH v2 44/45] RFC: qdict: add uint Marc-André Lureau
2017-06-06 12:28   ` Markus Armbruster
2017-05-31 13:57 ` [Qemu-devel] [PATCH v2 45/45] qobject: move dump_qobject() from block/ to qobject/ Marc-André Lureau
2017-05-31 20:06 ` [Qemu-devel] [PATCH v2 00/45] qobject/qapi: add uint type no-reply
2017-06-06 12:36 ` Markus Armbruster

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.