&& type.data_type != gvariant_type);
if (type.value_owned
- && (target_type == null || !target_type.value_owned || boxing || unboxing)
+ && (target_type == null || !target_type.value_owned || boxing || unboxing || gvariant_boxing)
&& !gvalue_boxing /* gvalue can assume ownership of value, no need to free it */) {
// value leaked, destroy it
if (target_type is PointerType) {
value_type.nullable = true;
}
+ if (is_gvariant (context, inner.value_type) && !is_gvariant (context, value_type)) {
+ // GVariant unboxing returns owned value
+ value_type.value_owned = true;
+ }
+
inner.target_type = inner.value_type.copy ();
return !error;
}
+ bool is_gvariant (CodeContext context, DataType type) {
+ return type.data_type != null && type.data_type.is_subtype_of (context.analyzer.gvariant_type.data_type);
+ }
+
public override void emit (CodeGenerator codegen) {
inner.emit (codegen);