From: Rico Tzschichholz Date: Mon, 31 Dec 2018 13:48:08 +0000 (+0100) Subject: vala: Report invalid instance member access to property X-Git-Tag: 0.42.5~31 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=1cb17fbfc99d72d0df91fd26b8bd5b2fe13be6fb;p=thirdparty%2Fvala.git vala: Report invalid instance member access to property See https://gitlab.gnome.org/GNOME/vala/issues/605 --- diff --git a/codegen/valaccodememberaccessmodule.vala b/codegen/valaccodememberaccessmodule.vala index 400448643..f3e56481c 100644 --- a/codegen/valaccodememberaccessmodule.vala +++ b/codegen/valaccodememberaccessmodule.vala @@ -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) { diff --git a/tests/Makefile.am b/tests/Makefile.am index 45c98086e..77888eab5 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -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 index 000000000..5935f159a --- /dev/null +++ b/tests/control-flow/bug790903-2.test @@ -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 index 000000000..e0b045a3c --- /dev/null +++ b/tests/semantic/field-static-instance-access.test @@ -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 index 000000000..a28859687 --- /dev/null +++ b/tests/semantic/localvariable-var-static-access-instance-property.test @@ -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 index 000000000..7987a10ac --- /dev/null +++ b/tests/semantic/property-static-instance-access.test @@ -0,0 +1,13 @@ +Invalid Code + +class Foo { + string? prop { get; set; } + + static void foo () { + if (prop == null) { + } + } +} + +void main() { +} diff --git a/vala/Makefile.am b/vala/Makefile.am index 585f10426..6be70557d 100644 --- a/vala/Makefile.am +++ b/vala/Makefile.am @@ -126,6 +126,7 @@ libvala_la_VALASOURCES = \ valaprofile.vala \ valapropertyaccessor.vala \ valaproperty.vala \ + valapropertyprototype.vala \ valarealliteral.vala \ valareferencetransferexpression.vala \ valareferencetype.vala \ diff --git a/vala/valabinaryexpression.vala b/vala/valabinaryexpression.vala index 531d78a71..beebe118d 100644 --- a/vala/valabinaryexpression.vala +++ b/vala/valabinaryexpression.vala @@ -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; diff --git a/vala/valalocalvariable.vala b/vala/valalocalvariable.vala index 22d7c6991..99f15a238 100644 --- a/vala/valalocalvariable.vala +++ b/vala/valalocalvariable.vala @@ -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; diff --git a/vala/valamemberaccess.vala b/vala/valamemberaccess.vala index cef8d7d40..1bcdea8e0 100644 --- a/vala/valamemberaccess.vala +++ b/vala/valamemberaccess.vala @@ -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 index 000000000..62306cd6c --- /dev/null +++ b/vala/valapropertyprototype.vala @@ -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 + */ + +/** + * 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 (); + } +} diff --git a/vala/valaunaryexpression.vala b/vala/valaunaryexpression.vala index 87f4032ef..11bc73257 100644 --- a/vala/valaunaryexpression.vala +++ b/vala/valaunaryexpression.vala @@ -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;