From: Rico Tzschichholz Date: Sat, 4 Jul 2020 14:04:22 +0000 (+0200) Subject: vala: Recursive check of assignment target to recognize constants X-Git-Tag: 0.46.12~32 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=2e792a8c5acb5d3b8aece9b905c75403dd00c902;p=thirdparty%2Fvala.git vala: Recursive check of assignment target to recognize constants See https://gitlab.gnome.org/GNOME/vala/issues/944 --- diff --git a/tests/Makefile.am b/tests/Makefile.am index 87830dd49..630757d69 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -763,6 +763,8 @@ TESTS = \ semantic/class-too-many-type-arguments.test \ semantic/constant-extern.test \ semantic/constant-pointer.test \ + semantic/constant-reassignment-element.test \ + semantic/constant-reassignment-member.test \ semantic/constant-value.test \ semantic/constant-value-missing.test \ semantic/constant-value-type.test \ diff --git a/tests/semantic/constant-reassignment-element.test b/tests/semantic/constant-reassignment-element.test new file mode 100644 index 000000000..4a87d7d6c --- /dev/null +++ b/tests/semantic/constant-reassignment-element.test @@ -0,0 +1,10 @@ +Invalid Code + +struct Foo { + int i; +} + +void main () { + const Foo[] foo = { { 23 } }; + foo[0].i = 42; +} diff --git a/tests/semantic/constant-reassignment-member.test b/tests/semantic/constant-reassignment-member.test new file mode 100644 index 000000000..bc53cd3fd --- /dev/null +++ b/tests/semantic/constant-reassignment-member.test @@ -0,0 +1,10 @@ +Invalid Code + +struct Foo { + int i; +} + +void main () { + const Foo foo = { 23 }; + foo.i = 42; +} diff --git a/vala/valaassignment.vala b/vala/valaassignment.vala index e8b619e9f..c59ea345b 100644 --- a/vala/valaassignment.vala +++ b/vala/valaassignment.vala @@ -158,11 +158,7 @@ public class Vala.Assignment : Expression { if (left is MemberAccess) { var ma = (MemberAccess) left; - if (ma.symbol_reference is Constant) { - error = true; - Report.error (source_reference, "Assignment to constant after initialization"); - return false; - } + check_constant_assignment (ma); if ((!(ma.symbol_reference is DynamicProperty) && ma.value_type == null) || (ma.inner == null && ma.member_name == "this" && context.analyzer.is_in_instance_method ())) { @@ -191,6 +187,8 @@ public class Vala.Assignment : Expression { } else if (left is ElementAccess) { var ea = (ElementAccess) left; + check_constant_assignment (ea.container as MemberAccess); + if (ea.container.value_type.data_type == context.analyzer.string_type.data_type) { error = true; Report.error (ea.source_reference, "strings are immutable"); @@ -440,6 +438,23 @@ public class Vala.Assignment : Expression { return false; } + void check_constant_assignment (MemberAccess? inner) { + while (inner != null) { + if (inner.symbol_reference is Constant) { + error = true; + Report.error (source_reference, "Assignment to constant after initialization"); + break; + } + if (inner.inner is MemberAccess) { + inner = (MemberAccess) inner.inner; + } else if (inner.inner is ElementAccess) { + inner = ((ElementAccess) inner.inner).container as MemberAccess; + } else { + inner = null; + } + } + } + public override void emit (CodeGenerator codegen) { var ma = left as MemberAccess; var ea = left as ElementAccess;