aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--hw/ppc/spapr_drc.c4
-rw-r--r--include/qapi/visitor-impl.h3
-rw-r--r--include/qapi/visitor.h8
-rw-r--r--qapi/qapi-clone-visitor.c5
-rw-r--r--qapi/qapi-dealloc-visitor.c6
-rw-r--r--qapi/qapi-visit-core.c7
-rw-r--r--qapi/qobject-input-visitor.c6
-rw-r--r--qapi/qobject-output-visitor.c3
-rw-r--r--qapi/string-input-visitor.c8
-rw-r--r--qapi/string-output-visitor.c3
-rw-r--r--qapi/trace-events2
-rw-r--r--target/ppc/translate_init.c5
-rw-r--r--tests/check-qnull.c9
-rw-r--r--tests/test-qobject-input-visitor.c13
-rw-r--r--tests/test-qobject-output-visitor.c3
15 files changed, 60 insertions, 25 deletions
diff --git a/hw/ppc/spapr_drc.c b/hw/ppc/spapr_drc.c
index 0ffcec6fb2..15bae5c216 100644
--- a/hw/ppc/spapr_drc.c
+++ b/hw/ppc/spapr_drc.c
@@ -297,12 +297,14 @@ static void prop_get_fdt(Object *obj, Visitor *v, const char *name,
void *opaque, Error **errp)
{
sPAPRDRConnector *drc = SPAPR_DR_CONNECTOR(obj);
+ QNull *null = NULL;
Error *err = NULL;
int fdt_offset_next, fdt_offset, fdt_depth;
void *fdt;
if (!drc->fdt) {
- visit_type_null(v, NULL, errp);
+ visit_type_null(v, NULL, &null, errp);
+ QDECREF(null);
return;
}
diff --git a/include/qapi/visitor-impl.h b/include/qapi/visitor-impl.h
index dcd656ab76..8ccb3b6c20 100644
--- a/include/qapi/visitor-impl.h
+++ b/include/qapi/visitor-impl.h
@@ -103,7 +103,8 @@ struct Visitor
Error **errp);
/* Must be set to visit explicit null values. */
- void (*type_null)(Visitor *v, const char *name, Error **errp);
+ void (*type_null)(Visitor *v, const char *name, QNull **obj,
+ Error **errp);
/* Must be set for input visitors to visit structs, optional otherwise.
The core takes care of the return type in the public interface. */
diff --git a/include/qapi/visitor.h b/include/qapi/visitor.h
index 74768aabda..fe9faf469f 100644
--- a/include/qapi/visitor.h
+++ b/include/qapi/visitor.h
@@ -618,10 +618,10 @@ void visit_type_any(Visitor *v, const char *name, QObject **obj, Error **errp);
* @name expresses the relationship of the null value to its parent
* container; see the general description of @name above.
*
- * Unlike all other visit_type_* functions, no obj parameter is
- * needed; rather, this is a witness that an explicit null value is
- * expected rather than any other type.
+ * @obj must be non-NULL. Input visitors set *@obj to the value;
+ * other visitors ignore *@obj.
*/
-void visit_type_null(Visitor *v, const char *name, Error **errp);
+void visit_type_null(Visitor *v, const char *name, QNull **obj,
+ Error **errp);
#endif
diff --git a/qapi/qapi-clone-visitor.c b/qapi/qapi-clone-visitor.c
index ed16d3a17f..d8b62792bc 100644
--- a/qapi/qapi-clone-visitor.c
+++ b/qapi/qapi-clone-visitor.c
@@ -127,12 +127,13 @@ static void qapi_clone_type_number(Visitor *v, const char *name, double *obj,
/* Value was already cloned by g_memdup() */
}
-static void qapi_clone_type_null(Visitor *v, const char *name, Error **errp)
+static void qapi_clone_type_null(Visitor *v, const char *name, QNull **obj,
+ Error **errp)
{
QapiCloneVisitor *qcv = to_qcv(v);
assert(qcv->depth);
- /* Nothing to do */
+ *obj = qnull();
}
static void qapi_clone_free(Visitor *v)
diff --git a/qapi/qapi-dealloc-visitor.c b/qapi/qapi-dealloc-visitor.c
index fd6f9fb61c..ed70a0158b 100644
--- a/qapi/qapi-dealloc-visitor.c
+++ b/qapi/qapi-dealloc-visitor.c
@@ -103,8 +103,12 @@ static void qapi_dealloc_type_anything(Visitor *v, const char *name,
}
}
-static void qapi_dealloc_type_null(Visitor *v, const char *name, Error **errp)
+static void qapi_dealloc_type_null(Visitor *v, const char *name,
+ QNull **obj, Error **errp)
{
+ if (obj) {
+ QDECREF(*obj);
+ }
}
static void qapi_dealloc_free(Visitor *v)
diff --git a/qapi/qapi-visit-core.c b/qapi/qapi-visit-core.c
index 935a2c5bc9..ed6d2af462 100644
--- a/qapi/qapi-visit-core.c
+++ b/qapi/qapi-visit-core.c
@@ -325,10 +325,11 @@ void visit_type_any(Visitor *v, const char *name, QObject **obj, Error **errp)
error_propagate(errp, err);
}
-void visit_type_null(Visitor *v, const char *name, Error **errp)
+void visit_type_null(Visitor *v, const char *name, QNull **obj,
+ Error **errp)
{
- trace_visit_type_null(v, name);
- v->type_null(v, name, errp);
+ trace_visit_type_null(v, name, obj);
+ v->type_null(v, name, obj, errp);
}
static void output_type_enum(Visitor *v, const char *name, int *obj,
diff --git a/qapi/qobject-input-visitor.c b/qapi/qobject-input-visitor.c
index 35aff78f2b..ee9e47d911 100644
--- a/qapi/qobject-input-visitor.c
+++ b/qapi/qobject-input-visitor.c
@@ -587,11 +587,13 @@ static void qobject_input_type_any(Visitor *v, const char *name, QObject **obj,
*obj = qobj;
}
-static void qobject_input_type_null(Visitor *v, const char *name, Error **errp)
+static void qobject_input_type_null(Visitor *v, const char *name,
+ QNull **obj, Error **errp)
{
QObjectInputVisitor *qiv = to_qiv(v);
QObject *qobj = qobject_input_get_object(qiv, name, true, errp);
+ *obj = NULL;
if (!qobj) {
return;
}
@@ -599,7 +601,9 @@ static void qobject_input_type_null(Visitor *v, const char *name, Error **errp)
if (qobject_type(qobj) != QTYPE_QNULL) {
error_setg(errp, QERR_INVALID_PARAMETER_TYPE,
full_name(qiv, name), "null");
+ return;
}
+ *obj = qnull();
}
static void qobject_input_type_size_keyval(Visitor *v, const char *name,
diff --git a/qapi/qobject-output-visitor.c b/qapi/qobject-output-visitor.c
index 398dcb5cee..d325163e55 100644
--- a/qapi/qobject-output-visitor.c
+++ b/qapi/qobject-output-visitor.c
@@ -187,7 +187,8 @@ static void qobject_output_type_any(Visitor *v, const char *name,
qobject_output_add_obj(qov, name, *obj);
}
-static void qobject_output_type_null(Visitor *v, const char *name, Error **errp)
+static void qobject_output_type_null(Visitor *v, const char *name,
+ QNull **obj, Error **errp)
{
QObjectOutputVisitor *qov = to_qov(v);
qobject_output_add(qov, name, qnull());
diff --git a/qapi/string-input-visitor.c b/qapi/string-input-visitor.c
index 63ae115b2a..67a0a4a58b 100644
--- a/qapi/string-input-visitor.c
+++ b/qapi/string-input-visitor.c
@@ -326,14 +326,20 @@ static void parse_type_number(Visitor *v, const char *name, double *obj,
*obj = val;
}
-static void parse_type_null(Visitor *v, const char *name, Error **errp)
+static void parse_type_null(Visitor *v, const char *name, QNull **obj,
+ Error **errp)
{
StringInputVisitor *siv = to_siv(v);
+ *obj = NULL;
+
if (!siv->string || siv->string[0]) {
error_setg(errp, QERR_INVALID_PARAMETER_TYPE, name ? name : "null",
"null");
+ return;
}
+
+ *obj = qnull();
}
static void string_input_free(Visitor *v)
diff --git a/qapi/string-output-visitor.c b/qapi/string-output-visitor.c
index af649e1d6e..7ab64468d9 100644
--- a/qapi/string-output-visitor.c
+++ b/qapi/string-output-visitor.c
@@ -256,7 +256,8 @@ static void print_type_number(Visitor *v, const char *name, double *obj,
string_output_set(sov, g_strdup_printf("%f", *obj));
}
-static void print_type_null(Visitor *v, const char *name, Error **errp)
+static void print_type_null(Visitor *v, const char *name, QNull **obj,
+ Error **errp)
{
StringOutputVisitor *sov = to_sov(v);
char *out;
diff --git a/qapi/trace-events b/qapi/trace-events
index 3b57abaa37..9e9008a1dc 100644
--- a/qapi/trace-events
+++ b/qapi/trace-events
@@ -31,4 +31,4 @@ visit_type_bool(void *v, const char *name, bool *obj) "v=%p name=%s obj=%p"
visit_type_str(void *v, const char *name, char **obj) "v=%p name=%s obj=%p"
visit_type_number(void *v, const char *name, double *obj) "v=%p name=%s obj=%p"
visit_type_any(void *v, const char *name, void *obj) "v=%p name=%s obj=%p"
-visit_type_null(void *v, const char *name) "v=%p name=%s"
+visit_type_null(void *v, const char *name, void *obj) "v=%p name=%s obj=%p"
diff --git a/target/ppc/translate_init.c b/target/ppc/translate_init.c
index b325c2cce6..01723bdfec 100644
--- a/target/ppc/translate_init.c
+++ b/target/ppc/translate_init.c
@@ -8428,11 +8428,14 @@ POWERPC_FAMILY(POWER5P)(ObjectClass *oc, void *data)
static void getset_compat_deprecated(Object *obj, Visitor *v, const char *name,
void *opaque, Error **errp)
{
+ QNull *null = NULL;
+
if (!qtest_enabled()) {
error_report("CPU 'compat' property is deprecated and has no effect; "
"use max-cpu-compat machine property instead");
}
- visit_type_null(v, name, NULL);
+ visit_type_null(v, name, &null, NULL);
+ QDECREF(null);
}
static const PropertyInfo ppc_compat_deprecated_propinfo = {
diff --git a/tests/check-qnull.c b/tests/check-qnull.c
index 1ab7c983a5..5c6eb0adc8 100644
--- a/tests/check-qnull.c
+++ b/tests/check-qnull.c
@@ -38,6 +38,7 @@ static void qnull_visit_test(void)
{
QObject *obj;
Visitor *v;
+ QNull *null;
/*
* Most tests of interactions between QObject and visitors are in
@@ -49,13 +50,17 @@ static void qnull_visit_test(void)
obj = QOBJECT(qnull());
v = qobject_input_visitor_new(obj);
qobject_decref(obj);
- visit_type_null(v, NULL, &error_abort);
+ visit_type_null(v, NULL, &null, &error_abort);
+ g_assert(obj == QOBJECT(&qnull_));
+ QDECREF(null);
visit_free(v);
+ null = NULL;
v = qobject_output_visitor_new(&obj);
- visit_type_null(v, NULL, &error_abort);
+ visit_type_null(v, NULL, &null, &error_abort);
visit_complete(v, &obj);
g_assert(obj == QOBJECT(&qnull_));
+ QDECREF(null);
qobject_decref(obj);
visit_free(v);
diff --git a/tests/test-qobject-input-visitor.c b/tests/test-qobject-input-visitor.c
index 34bab8a913..f98caf9818 100644
--- a/tests/test-qobject-input-visitor.c
+++ b/tests/test-qobject-input-visitor.c
@@ -510,6 +510,7 @@ static void test_visitor_in_null(TestInputVisitorData *data,
{
Visitor *v;
Error *err = NULL;
+ QNull *null;
char *tmp;
/*
@@ -524,12 +525,15 @@ static void test_visitor_in_null(TestInputVisitorData *data,
v = visitor_input_test_init_full(data, false,
"{ 'a': null, 'b': '' }");
visit_start_struct(v, NULL, NULL, 0, &error_abort);
- visit_type_null(v, "a", &error_abort);
- visit_type_null(v, "b", &err);
+ visit_type_null(v, "a", &null, &error_abort);
+ g_assert(qobject_type(QOBJECT(null)) == QTYPE_QNULL);
+ QDECREF(null);
+ visit_type_null(v, "b", &null, &err);
error_free_or_abort(&err);
+ g_assert(!null);
visit_type_str(v, "c", &tmp, &err);
- g_assert(!tmp);
error_free_or_abort(&err);
+ g_assert(!tmp);
visit_check_struct(v, &error_abort);
visit_end_struct(v, NULL);
}
@@ -1087,6 +1091,7 @@ static void test_visitor_in_fail_struct_missing(TestInputVisitorData *data,
Error *err = NULL;
Visitor *v;
QObject *any;
+ QNull *null;
GenericAlternate *alt;
bool present;
int en;
@@ -1120,7 +1125,7 @@ static void test_visitor_in_fail_struct_missing(TestInputVisitorData *data,
error_free_or_abort(&err);
visit_type_any(v, "any", &any, &err);
error_free_or_abort(&err);
- visit_type_null(v, "null", &err);
+ visit_type_null(v, "null", &null, &err);
error_free_or_abort(&err);
visit_start_list(v, "sub", NULL, 0, &error_abort);
visit_start_struct(v, NULL, NULL, 0, &error_abort);
diff --git a/tests/test-qobject-output-visitor.c b/tests/test-qobject-output-visitor.c
index 749c54065f..8f1fcd49cb 100644
--- a/tests/test-qobject-output-visitor.c
+++ b/tests/test-qobject-output-visitor.c
@@ -445,11 +445,12 @@ static void test_visitor_out_alternate(TestOutputVisitorData *data,
static void test_visitor_out_null(TestOutputVisitorData *data,
const void *unused)
{
+ QNull *null = NULL;
QDict *qdict;
QObject *nil;
visit_start_struct(data->ov, NULL, NULL, 0, &error_abort);
- visit_type_null(data->ov, "a", &error_abort);
+ visit_type_null(data->ov, "a", &null, &error_abort);
visit_check_struct(data->ov, &error_abort);
visit_end_struct(data->ov, NULL);
qdict = qobject_to_qdict(visitor_get(data));