summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRico Tzschichholz <ricotz@ubuntu.com>2020-03-13 09:11:01 +0100
committerRico Tzschichholz <ricotz@ubuntu.com>2020-03-13 13:18:29 +0100
commitc12529b7bd51640bbcc9b96bf84be7e0897c2ba1 (patch)
treed22f66ae2d7d6f91ca1e953c17ad4845be356b29
parent4555ed66dcf5839e79e3b9a62ef5cf83bde35d4e (diff)
downloadvala-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.vala6
-rw-r--r--codegen/valaccodememberaccessmodule.vala2
-rw-r--r--codegen/valaccodemethodmodule.vala3
-rw-r--r--tests/Makefile.am1
-rw-r--r--tests/methods/prepostconditions-captured.vala35
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);
+}