[vala/0.40] codegen: Emit postconditions before free'ing local variables
- From: Rico Tzschichholz <ricotz src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [vala/0.40] codegen: Emit postconditions before free'ing local variables
- Date: Tue, 21 Apr 2020 07:47:48 +0000 (UTC)
commit 5def33354bba0136f1f84e86dac6bb5b0b13564f
Author: Rico Tzschichholz <ricotz ubuntu com>
Date: Fri Mar 13 00:01:09 2020 +0100
codegen: Emit postconditions before free'ing local variables
It was possible to cause segmentation-faults or use-after-free errors.
codegen/valaccodebasemodule.vala | 18 ++++++++------
tests/Makefile.am | 1 +
tests/methods/postconditions.vala | 51 +++++++++++++++++++++++++++++++++++++++
3 files changed, 63 insertions(+), 7 deletions(-)
---
diff --git a/codegen/valaccodebasemodule.vala b/codegen/valaccodebasemodule.vala
index d1eff062b..7a0a63953 100644
--- a/codegen/valaccodebasemodule.vala
+++ b/codegen/valaccodebasemodule.vala
@@ -2304,6 +2304,14 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator {
pop_line ();
}
+ if (b.parent_symbol is Method) {
+ unowned Method m = (Method) b.parent_symbol;
+ // check postconditions
+ foreach (var postcondition in m.get_postconditions ()) {
+ create_postcondition_statement (postcondition);
+ }
+ }
+
// free in reverse order
for (int i = local_vars.size - 1; i >= 0; i--) {
var local = local_vars[i];
@@ -2328,10 +2336,6 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator {
return_out_parameter (param);
}
}
- // check postconditions
- foreach (var postcondition in m.get_postconditions ()) {
- create_postcondition_statement (postcondition);
- }
} else if (!unreachable_exit_block && b.parent_symbol is PropertyAccessor) {
var acc = (PropertyAccessor) b.parent_symbol;
if (acc.value_parameter != null && !acc.value_parameter.captured && requires_destroy
(acc.value_parameter.variable_type)) {
@@ -3894,9 +3898,6 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator {
ccode.add_assignment (result_lhs, get_cvalue (stmt.return_expression));
}
- // free local variables
- append_local_free (current_symbol);
-
if (current_method != null) {
// check postconditions
foreach (Expression postcondition in current_method.get_postconditions ()) {
@@ -3904,6 +3905,9 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator {
}
}
+ // free local variables
+ append_local_free (current_symbol);
+
if (current_method != null && !current_method.coroutine) {
// assign values to output parameters if they are not NULL
// otherwise, free the value if necessary
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 75e00fa97..da814a173 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -108,6 +108,7 @@ TESTS = \
methods/iterator.vala \
methods/parameter-ref-array-resize.vala \
methods/prepostconditions.vala \
+ methods/postconditions.vala \
methods/same-name.vala \
methods/symbolresolution.vala \
methods/bug540483.vala \
diff --git a/tests/methods/postconditions.vala b/tests/methods/postconditions.vala
new file mode 100644
index 000000000..5cd9c5929
--- /dev/null
+++ b/tests/methods/postconditions.vala
@@ -0,0 +1,51 @@
+void foo (owned string[] a) ensures (a[1] == "bar") {
+}
+
+void foz (ref string[] a) ensures (a[1] == "bar") {
+ a = { "foo", "bar" };
+}
+
+void fom (out string[] a) ensures (a[1] == "bar") {
+ a = { "foo", "bar" };
+}
+
+string[] bar (owned string[] a) ensures (result[0] == "manam" && a[1] == "foo") {
+ return { "manam" };
+}
+
+string[] baz (ref string[] a) ensures (result[0] == "manam" && a[1] == "foo") {
+ a = { "bar", "foo" };
+ return { "manam" };
+}
+
+string[] bam (out string[] a) ensures (result[0] == "manam" && a[1] == "foo") {
+ a = { "bar", "foo" };
+ return { "manam" };
+}
+
+void main () {
+ {
+ foo ({ "foo", "bar" });
+ }
+ {
+ string[] a = {};
+ foz (ref a);
+ assert (a[0] == "foo");
+ }
+ {
+ string[] a;
+ fom (out a);
+ assert (a[0] == "foo");
+ }
+ {
+ assert (bar ({ "bar", "foo" })[0] == "manam");
+ }
+ {
+ string[] a = {};
+ assert (baz (ref a)[0] == "manam");
+ }
+ {
+ string[] a;
+ assert (bam (out a)[0] == "manam");
+ }
+}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]