]> git.ipfire.org Git - thirdparty/vala.git/commitdiff
vala: Report invalid instance member access to property
authorRico Tzschichholz <ricotz@ubuntu.com>
Mon, 31 Dec 2018 13:48:08 +0000 (14:48 +0100)
committerRico Tzschichholz <ricotz@ubuntu.com>
Thu, 10 Jan 2019 20:50:59 +0000 (21:50 +0100)
See https://gitlab.gnome.org/GNOME/vala/issues/605

12 files changed:
codegen/valaccodememberaccessmodule.vala
tests/Makefile.am
tests/control-flow/bug790903-2.test [new file with mode: 0644]
tests/semantic/field-static-instance-access.test [new file with mode: 0644]
tests/semantic/localvariable-var-static-access-instance-property.test [new file with mode: 0644]
tests/semantic/property-static-instance-access.test [new file with mode: 0644]
vala/Makefile.am
vala/valabinaryexpression.vala
vala/valalocalvariable.vala
vala/valamemberaccess.vala
vala/valapropertyprototype.vala [new file with mode: 0644]
vala/valaunaryexpression.vala

index 4004486439d1c63de307f42c9b726e2046c95ce6..f3e56481ce9348398ef77944cce0ab1c1d4a5fba 100644 (file)
@@ -174,6 +174,13 @@ public abstract class Vala.CCodeMemberAccessModule : CCodeControlFlowModule {
                                }
                        }
 
+                       if (pub_inst == null && prop.binding == MemberBinding.INSTANCE) {
+                               // FIXME Report this with proper source-reference on the vala side!
+                               Report.error (prop.source_reference, "Invalid access to instance member `%s'".printf (prop.get_full_name ()));
+                               set_cvalue (expr, new CCodeInvalidExpression ());
+                               return;
+                       }
+
                        if (expr.inner is BaseAccess) {
                                var base_prop = prop;
                                if (prop.base_property != null) {
@@ -312,6 +319,7 @@ public abstract class Vala.CCodeMemberAccessModule : CCodeControlFlowModule {
                                ccode.add_expression (ccall);
                                set_cvalue (expr, ctemp);
                        }
+
                        expr.target_value.value_type = expr.value_type;
                        expr.target_value = store_temp_value (expr.target_value, expr);
                } else if (expr.symbol_reference is LocalVariable) {
index 45c98086eb4b97cb7ee72a9bc48ab9ffe3d9704b..77888eab5bb3c1f6023763db07d11ab3575a1b83 100644 (file)
@@ -159,6 +159,7 @@ TESTS = \
        control-flow/bug736774-1.vala \
        control-flow/bug736774-2.vala \
        control-flow/bug790903.test \
+       control-flow/bug790903-2.test \
        control-semantic/argument-extra.test \
        control-semantic/argument-incompatible-type-out.test \
        control-semantic/argument-incompatible-type-ref.test \
@@ -563,6 +564,7 @@ TESTS = \
        semantic/field-namespace-owned.test \
        semantic/field-non-constant.test \
        semantic/field-owned-to-unowned.test \
+       semantic/field-static-instance-access.test \
        semantic/field-void.test \
        semantic/floating-reference.vala \
        semantic/foreach-iterator-args.test \
@@ -584,6 +586,7 @@ TESTS = \
        semantic/localvariable-owned-to-unowned.test \
        semantic/localvariable-var-static-access-instance-field.test \
        semantic/localvariable-var-static-access-instance-method.test \
+       semantic/localvariable-var-static-access-instance-property.test \
        semantic/localvariable-var-without-initializer.test \
        semantic/localvariable-void.test \
        semantic/method-abstract.test \
@@ -631,6 +634,7 @@ TESTS = \
        semantic/property-override.test \
        semantic/property-override-class.test \
        semantic/property-override-interface.test \
+       semantic/property-static-instance-access.test \
        semantic/property-struct-abstract.test \
        semantic/property-struct-override.test \
        semantic/property-struct-protected.test \
diff --git a/tests/control-flow/bug790903-2.test b/tests/control-flow/bug790903-2.test
new file mode 100644 (file)
index 0000000..5935f15
--- /dev/null
@@ -0,0 +1,9 @@
+Invalid Code
+
+class Foo {
+       public string prop { get; set; }
+}
+
+void main () {
+       var foo = (string) Foo.prop;
+}
diff --git a/tests/semantic/field-static-instance-access.test b/tests/semantic/field-static-instance-access.test
new file mode 100644 (file)
index 0000000..e0b045a
--- /dev/null
@@ -0,0 +1,13 @@
+Invalid Code
+
+class Foo {
+       string? field;
+
+       static void foo () {
+               if (field == null) {
+               }
+       }
+}
+
+void main() {
+}
diff --git a/tests/semantic/localvariable-var-static-access-instance-property.test b/tests/semantic/localvariable-var-static-access-instance-property.test
new file mode 100644 (file)
index 0000000..a288596
--- /dev/null
@@ -0,0 +1,12 @@
+Invalid Code
+
+class Foo {
+       int prop { get; set; }
+
+       static void bar () {
+               var p = prop;
+       }
+}
+
+void main () {
+}
diff --git a/tests/semantic/property-static-instance-access.test b/tests/semantic/property-static-instance-access.test
new file mode 100644 (file)
index 0000000..7987a10
--- /dev/null
@@ -0,0 +1,13 @@
+Invalid Code
+
+class Foo {
+       string? prop { get; set; }
+
+       static void foo () {
+               if (prop == null) {
+               }
+       }
+}
+
+void main() {
+}
index 585f10426e401d460d40e8e45c3443036e61ca59..6be70557d38e5db0d8c0dfeec59e5e3dcd385e2b 100644 (file)
@@ -126,6 +126,7 @@ libvala_la_VALASOURCES = \
        valaprofile.vala \
        valapropertyaccessor.vala \
        valaproperty.vala \
+       valapropertyprototype.vala \
        valarealliteral.vala \
        valareferencetransferexpression.vala \
        valareferencetype.vala \
index 531d78a71e1c0fb6f4b408b9386b9776bf8b1040..beebe118dea89a349bee9592662b78d68b98b221 100644 (file)
@@ -327,12 +327,12 @@ public class Vala.BinaryExpression : Expression {
                        return false;
                }
 
-               if (left.value_type is FieldPrototype) {
+               if (left.value_type is FieldPrototype || left.value_type is PropertyPrototype) {
                        error = true;
                        Report.error (left.source_reference, "Access to instance member `%s' denied".printf (left.symbol_reference.get_full_name ()));
                        return false;
                }
-               if (right.value_type is FieldPrototype) {
+               if (right.value_type is FieldPrototype || right.value_type is PropertyPrototype) {
                        error = true;
                        Report.error (right.source_reference, "Access to instance member `%s' denied".printf (right.symbol_reference.get_full_name ()));
                        return false;
index 22d7c6991835302b7cd0b6b7f57aec4f38c46c30..99f15a238d01abd94399cbb3dcb3bd8bcfca2d2c 100644 (file)
@@ -116,7 +116,7 @@ public class Vala.LocalVariable : Variable {
                                Report.error (source_reference, "var declaration not allowed with non-typed initializer");
                                return false;
                        }
-                       if (initializer.value_type is FieldPrototype) {
+                       if (initializer.value_type is FieldPrototype || initializer.value_type is PropertyPrototype) {
                                error = true;
                                Report.error (initializer.source_reference, "Access to instance member `%s' denied".printf (initializer.symbol_reference.get_full_name ()));
                                return false;
index cef8d7d40012b87ea4564ac48219531c94bb85ae..1bcdea8e0f93fc1b4734decc1cce380f6f436530 100644 (file)
@@ -782,6 +782,8 @@ public class Vala.MemberAccess : Expression {
                                value_type = context.analyzer.get_value_type_for_symbol (symbol_reference, lvalue);
                        } else if (symbol_reference is Field) {
                                value_type = new FieldPrototype ((Field) symbol_reference);
+                       } else if (symbol_reference is Property) {
+                               value_type = new PropertyPrototype ((Property) symbol_reference);
                        } else {
                                value_type = new InvalidType ();
                        }
diff --git a/vala/valapropertyprototype.vala b/vala/valapropertyprototype.vala
new file mode 100644 (file)
index 0000000..62306cd
--- /dev/null
@@ -0,0 +1,41 @@
+/* valafieldprototype.vala
+ *
+ * Copyright (C) 2018  Rico Tzschichholz
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA
+ *
+ * Author:
+ *     Rico Tzschichholz <ricotz@ubuntu.com>
+ */
+
+/**
+ * A reference to an instance property without a specific instance.
+ */
+public class Vala.PropertyPrototype : DataType {
+       public weak Property property_symbol { get; set; }
+
+       public PropertyPrototype (Property property_symbol) {
+               this.property_symbol = property_symbol;
+       }
+
+       public override DataType copy () {
+               var result = new PropertyPrototype (property_symbol);
+               return result;
+       }
+
+       public override string to_qualified_string (Scope? scope) {
+               return property_symbol.get_full_name ();
+       }
+}
index 87f4032efc192496153bbe9c56eb032815df7cdc..11bc732570804a311ee0de09f572981b2eb2a8e6 100644 (file)
@@ -170,7 +170,7 @@ public class Vala.UnaryExpression : Expression {
                        return false;
                }
 
-               if (inner.value_type is FieldPrototype) {
+               if (inner.value_type is FieldPrototype || inner.value_type is PropertyPrototype) {
                        error = true;
                        Report.error (inner.source_reference, "Access to instance member `%s' denied".printf (inner.symbol_reference.get_full_name ()));
                        return false;