diff options
author | Rico Tzschichholz <ricotz@ubuntu.com> | 2020-03-13 09:11:01 +0100 |
---|---|---|
committer | Rico Tzschichholz <ricotz@ubuntu.com> | 2020-03-13 13:18:29 +0100 |
commit | c12529b7bd51640bbcc9b96bf84be7e0897c2ba1 (patch) | |
tree | d22f66ae2d7d6f91ca1e953c17ad4845be356b29 | |
parent | 4555ed66dcf5839e79e3b9a62ef5cf83bde35d4e (diff) | |
download | vala-c12529b7bd51640bbcc9b96bf84be7e0897c2ba1.tar.gz |
codegen: Correctly access captured parameter in precondition of method
Fixes https://gitlab.gnome.org/GNOME/vala/issues/144
-rw-r--r-- | codegen/valaccodebasemodule.vala | 6 | ||||
-rw-r--r-- | codegen/valaccodememberaccessmodule.vala | 2 | ||||
-rw-r--r-- | codegen/valaccodemethodmodule.vala | 3 | ||||
-rw-r--r-- | tests/Makefile.am | 1 | ||||
-rw-r--r-- | tests/methods/prepostconditions-captured.vala | 35 |
5 files changed, 46 insertions, 1 deletions
diff --git a/codegen/valaccodebasemodule.vala b/codegen/valaccodebasemodule.vala index 0bf62de07..6d021ddf3 100644 --- a/codegen/valaccodebasemodule.vala +++ b/codegen/valaccodebasemodule.vala @@ -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; diff --git a/codegen/valaccodememberaccessmodule.vala b/codegen/valaccodememberaccessmodule.vala index 3d6e34996..97e0c48fd 100644 --- a/codegen/valaccodememberaccessmodule.vala +++ b/codegen/valaccodememberaccessmodule.vala @@ -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) { diff --git a/codegen/valaccodemethodmodule.vala b/codegen/valaccodemethodmodule.vala index 1062ad408..404a6153a 100644 --- a/codegen/valaccodemethodmodule.vala +++ b/codegen/valaccodemethodmodule.vala @@ -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) { diff --git a/tests/Makefile.am b/tests/Makefile.am index 9139b02d5..dd3cb46f9 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -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 index 000000000..3e7ba95e8 --- /dev/null +++ b/tests/methods/prepostconditions-captured.vala @@ -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); +} |