summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRico Tzschichholz <ricotz@ubuntu.com>2018-08-12 21:42:47 +0200
committerRico Tzschichholz <ricotz@ubuntu.com>2018-08-13 19:55:07 +0200
commit2190d03f6668ac2d0f20d751951413e488188d1d (patch)
tree67bc30b827c016d7340527eb01cac72341ac6b97
parentc43c8716a8cba9789625ec7503b2d3e69404ce94 (diff)
downloadvala-2190d03f6668ac2d0f20d751951413e488188d1d.tar.gz
codegen: Fix floating reference regression with Variants
Let ConditionalExpression sink floating references. Fixes https://gitlab.gnome.org/GNOME/vala/issues/661
-rw-r--r--codegen/valaccodebasemodule.vala2
-rw-r--r--tests/Makefile.am1
-rw-r--r--tests/semantic/floating-reference.vala63
-rw-r--r--vala/valaconditionalexpression.vala1
4 files changed, 66 insertions, 1 deletions
diff --git a/codegen/valaccodebasemodule.vala b/codegen/valaccodebasemodule.vala
index 14886a3cc..2da65098a 100644
--- a/codegen/valaccodebasemodule.vala
+++ b/codegen/valaccodebasemodule.vala
@@ -5847,7 +5847,7 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator {
var result = ((GLibValue) value).copy ();
if (type.value_owned
- && (target_type is GenericType || (target_type is ObjectType && !target_type.floating_reference))
+ && (target_type == null || target_type is GenericType || !target_type.floating_reference)
&& type.floating_reference) {
/* floating reference, sink it.
*/
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 8d255e89d..d03e394c1 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -515,6 +515,7 @@ TESTS = \
semantic/field-namespace-owned.test \
semantic/field-non-constant.test \
semantic/field-void.test \
+ semantic/floating-reference.vala \
semantic/foreach-iterator-args.test \
semantic/foreach-iterator-void.test \
semantic/foreach-iterator-wrong-types.test \
diff --git a/tests/semantic/floating-reference.vala b/tests/semantic/floating-reference.vala
new file mode 100644
index 000000000..f690d690d
--- /dev/null
+++ b/tests/semantic/floating-reference.vala
@@ -0,0 +1,63 @@
+[CCode (returns_floating_reference = true)]
+Variant get_floating_variant () {
+ return new Variant.string ("foo");
+}
+
+void test_variant () {
+ {
+ string? @value = "bar";
+ Variant? variant = new Variant.string (@value) ?? new Variant.string (@value);
+ assert (variant.is_of_type (VariantType.STRING));
+ assert (!variant.is_floating ());
+ }
+ {
+ string? @value = "foo";
+ Variant? variant = @value == null ? null : new Variant.string (@value);
+ assert (variant.is_of_type (VariantType.STRING));
+ assert (!variant.is_floating ());
+ }
+ {
+ string? @value = "foo";
+ Variant? variant;
+ if (@value == null) {
+ variant = null;
+ } else {
+ variant = new Variant.string (@value);
+ }
+ assert (variant.is_of_type (VariantType.STRING));
+ assert (!variant.is_floating ());
+ }
+ {
+ bool @value = true;
+ Variant? variant = new Variant.boolean (@value);
+ assert (variant.is_of_type (VariantType.BOOLEAN));
+ assert (!variant.is_floating ());
+ }
+ {
+ string? @value = "manam";
+ Variant? variant = new Variant.string (@value);
+ assert (variant.is_of_type (VariantType.STRING));
+ assert (!variant.is_floating ());
+ string s = (string) variant;
+ assert (s == "manam");
+ }
+ {
+ Variant? variant = get_floating_variant ();
+ assert (!variant.is_floating ());
+ }
+}
+
+void test_variant_builder () {
+ string name = "foo";
+ string key = "bar";
+ Variant? @value = null;
+ var builder = new VariantBuilder (new VariantType ("a{smv}"));
+ builder.add ("{smv}", key, @value);
+ var variant = new Variant ("(s@a{smv})", name, builder.end ());
+ assert (!variant.is_floating ());
+}
+
+void main () {
+ test_variant ();
+ test_variant_builder ();
+}
diff --git a/vala/valaconditionalexpression.vala b/vala/valaconditionalexpression.vala
index d139caeb4..71acf6d53 100644
--- a/vala/valaconditionalexpression.vala
+++ b/vala/valaconditionalexpression.vala
@@ -165,6 +165,7 @@ public class Vala.ConditionalExpression : Expression {
}
value_type.value_owned = (true_expression.value_type.value_owned || false_expression.value_type.value_owned);
+ value_type.floating_reference = false;
local.variable_type = value_type;
decl.check (context);