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.43.4~25 X-Git-Url: http://git.ipfire.org/gitweb/gitweb.cgi?a=commitdiff_plain;h=96857b1b83fcc3e9aef83c9896b50dcfd21e852b;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 06a4d2bb4..03a204299 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 ef11eca8b..b3d16c732 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -161,6 +161,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 \ @@ -583,6 +584,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 \ @@ -604,6 +606,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 \ @@ -651,6 +654,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 95491d352..5c9cefbe4 100644 --- a/vala/valabinaryexpression.vala +++ b/vala/valabinaryexpression.vala @@ -306,12 +306,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 331cfcc1f..67187ce76 100644 --- a/vala/valalocalvariable.vala +++ b/vala/valalocalvariable.vala @@ -132,7 +132,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 ab6d6a9dc..6690c62b7 100644 --- a/vala/valamemberaccess.vala +++ b/vala/valamemberaccess.vala @@ -788,6 +788,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 ce5e4a062..e04dcb57d 100644 --- a/vala/valaunaryexpression.vala +++ b/vala/valaunaryexpression.vala @@ -160,7 +160,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;