]> git.ipfire.org Git - thirdparty/vala.git/commitdiff
vala: Property must be writable when invoking ReturnsModifiedPointer method
authorRico Tzschichholz <ricotz@ubuntu.com>
Sat, 4 Jul 2020 07:07:06 +0000 (09:07 +0200)
committerRico Tzschichholz <ricotz@ubuntu.com>
Sat, 4 Jul 2020 12:02:36 +0000 (14:02 +0200)
Fixes https://gitlab.gnome.org/GNOME/vala/issues/1023

tests/Makefile.am
tests/semantic/property-method-returns-modified-pointer.test [new file with mode: 0644]
vala/valamethodcall.vala

index da440e24886bae620a99a5389fe26f4874f5568f..b6f9574e82d6429b194eda9d3aac860b3b71f75e 100644 (file)
@@ -911,6 +911,7 @@ TESTS = \
        semantic/property-accessibility.test \
        semantic/property-construct.test \
        semantic/property-initializer-type.test \
+       semantic/property-method-returns-modified-pointer.test \
        semantic/property-override.test \
        semantic/property-override-class.test \
        semantic/property-override-interface.test \
diff --git a/tests/semantic/property-method-returns-modified-pointer.test b/tests/semantic/property-method-returns-modified-pointer.test
new file mode 100644 (file)
index 0000000..ae8ebbe
--- /dev/null
@@ -0,0 +1,10 @@
+Invalid Code
+
+class Foo {
+       public List<string> bar { get; }
+}
+
+void main () {
+       var foo = new Foo ();
+       foo.bar.append ("foo");
+}
index baf704f450563800de4d5cb36a7c914ad3821057..2416e5b9fdc22e89e07ba40187a03d0bd720eb95 100644 (file)
@@ -527,7 +527,13 @@ public class Vala.MethodCall : Expression {
                                value_type.floating_reference = true;
                        }
                        if (m.returns_modified_pointer) {
-                               ((MemberAccess) call).inner.lvalue = true;
+                               unowned Expression inner = ((MemberAccess) call).inner;
+                               inner.lvalue = true;
+                               unowned Property? prop = inner.symbol_reference as Property;
+                               if (prop != null && (prop.set_accessor == null || !prop.set_accessor.writable)) {
+                                       error = true;
+                                       Report.error (inner.source_reference, "Property `%s' is read-only".printf (prop.get_full_name ()));
+                               }
                        }
                        // avoid passing possible null to ref_sink_function without checking
                        if (tree_can_fail && !value_type.nullable && value_type.floating_reference && ret_type is ObjectType) {