]> git.ipfire.org Git - thirdparty/vala.git/commitdiff
codegen: Correctly access captured parameter in precondition of method c12529b7bd51640bbcc9b96bf84be7e0897c2ba1
authorRico Tzschichholz <ricotz@ubuntu.com>
Fri, 13 Mar 2020 08:11:01 +0000 (09:11 +0100)
committerRico Tzschichholz <ricotz@ubuntu.com>
Fri, 13 Mar 2020 12:18:29 +0000 (13:18 +0100)
Fixes https://gitlab.gnome.org/GNOME/vala/issues/144

codegen/valaccodebasemodule.vala
codegen/valaccodememberaccessmodule.vala
codegen/valaccodemethodmodule.vala
tests/Makefile.am
tests/methods/prepostconditions-captured.vala [new file with mode: 0644]

index 0bf62de07ccb7840790350e3667567a8d38d9cae..6d021ddf373b31ff4804f24e4b7a8db8cbf63c15 100644 (file)
@@ -45,6 +45,7 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator {
                public Map<string,string> variable_name_map = new HashMap<string,string> (str_hash, str_equal);
                public Map<string,int> closure_variable_count_map = new HashMap<string,int> (str_hash, str_equal);
                public Map<LocalVariable,int> closure_variable_clash_map = new HashMap<LocalVariable,int> ();
+               public bool is_in_method_precondition;
 
                public EmitContext (Symbol? symbol = null) {
                        current_symbol = symbol;
@@ -99,6 +100,11 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator {
                set { emit_context.current_inner_error_id = value; }
        }
 
+       public bool is_in_method_precondition {
+               get { return emit_context.is_in_method_precondition; }
+               set { emit_context.is_in_method_precondition = value; }
+       }
+
        public TypeSymbol? current_type_symbol {
                get {
                        var sym = current_symbol;
index 3d6e349968f59df1805672db93a4ba973c946cff..97e0c48fda0c4047b22d7c4d4f511668eb71473d 100644 (file)
@@ -482,7 +482,7 @@ public abstract class Vala.CCodeMemberAccessModule : CCodeControlFlowModule {
                } else {
                        string name = get_ccode_name (param);
 
-                       if (param.captured) {
+                       if (param.captured && !is_in_method_precondition) {
                                // captured variables are stored on the heap
                                var block = param.parent_symbol as Block;
                                if (block == null) {
index 1062ad408b50901ee10de375776d8389076f7a44..404a6153acbf2d5ae279b005dc3bede9223980b2 100644 (file)
@@ -1152,6 +1152,8 @@ public abstract class Vala.CCodeMethodModule : CCodeStructModule {
        }
 
        private void create_precondition_statement (Method m, DataType ret_type, Expression precondition) {
+               is_in_method_precondition = true;
+
                var ccheck = new CCodeFunctionCall ();
 
                precondition.emit (this);
@@ -1191,6 +1193,7 @@ public abstract class Vala.CCodeMethodModule : CCodeStructModule {
                ccode.add_expression (ccheck);
 
                current_method_return = true;
+               is_in_method_precondition = false;
        }
 
        public override void visit_creation_method (CreationMethod m) {
index 9139b02d573e3f034b09a4c44b488a74f09a43b1..dd3cb46f9bb32e3808296659e785d034cfde3ac2 100644 (file)
@@ -120,6 +120,7 @@ TESTS = \
        methods/iterator.vala \
        methods/parameter-ref-array-resize.vala \
        methods/prepostconditions.vala \
+       methods/prepostconditions-captured.vala \
        methods/postconditions.vala \
        methods/same-name.vala \
        methods/symbolresolution.vala \
diff --git a/tests/methods/prepostconditions-captured.vala b/tests/methods/prepostconditions-captured.vala
new file mode 100644 (file)
index 0000000..3e7ba95
--- /dev/null
@@ -0,0 +1,35 @@
+delegate void Func ();
+
+int bar (int i) requires (i == 23) ensures (i == 42) {
+       Func f = () => {
+               assert (i == 23);
+               i = 42;
+       };
+       f ();
+
+       return i;
+}
+
+void baz (int i) requires (i == 42) ensures (i == 23) {
+       Func f = () => {
+               assert (i == 42);
+               i = 23;
+       };
+       f ();
+}
+
+async int foo (int i) requires (i == 23) ensures (i == 42) {
+       Func f = () => {
+               assert (i == 23);
+               i = 42;
+       };
+       f ();
+
+       return i;
+}
+
+void main () {
+       assert (bar (23) == 42);
+       baz (42);
+       foo.begin (23);
+}